diff --git a/ChangeLog b/ChangeLog index f14bb47ca2dd..eba060804d59 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +2025-07-07 Tamar Christina + + * MAINTAINERS: Add myself to AArch64 pot. + +2025-07-04 Andrew Pinski + + * MAINTAINERS: Replace tabs with spaces. + +2025-07-04 Alex Coplan + + * MAINTAINERS (Reviewers): Add myself for the aarch64 port. + +2025-07-03 Andrew Pinski + + * MAINTAINERS: Add myself as an aarch64 port reviewer. + +2025-06-22 Nicolas Boulenguez + + PR ada/120106 + * Makefile.tpl: Add GNATMAKE_FOR_BUILD to {HOST,BASE_TARGET}_EXPORTS + * Makefile.in: Regenerate. + * configure.ac: Set the default and substitute the variable. + * configure: Regenerate. + +2025-06-09 Kugan Vivekanandarajah + + * configure.ac: Special case cpu_type for x86_64. + * configure: Regenerate. + +2025-06-09 Peter Bergner + + * MAINTAINERS: Update my email address and add myself to DCO. + 2025-05-28 Kugan Vivekanandarajah * Makefile.def: Fix typo in cpu_type diff --git a/MAINTAINERS b/MAINTAINERS index e473c01ef4bb..2cd2ec650b6f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -57,6 +57,7 @@ docs, and the testsuite related to that. aarch64 ldp/stp Alex Coplan aarch64 port Richard Earnshaw aarch64 port Richard Sandiford +aarch64 port Tamar Christina aarch64 port Kyrylo Tkachov alpha port Richard Henderson amdgcn port Julian Brown @@ -274,6 +275,8 @@ check in changes outside of the parts of the compiler they maintain. Reviewers +aarch64 port Alex Coplan +aarch64 port Andrew Pinski arm port (MVE) Christophe Lyon callgraph Martin Jambor C front end Marek Polacek @@ -308,7 +311,7 @@ loop optimizer Zdenek Dvorak LTO Richard Biener LTO plugin Cary Coutant Plugin Le-Chun Wu -register allocation Peter Bergner +register allocation Peter Bergner register allocation Kenneth Zadeck register allocation Seongbae Park riscv port Robin Dapp @@ -358,7 +361,7 @@ Serge Belyshev - Jon Beniston jbeniston Andrew Bennett - Andrew Benson abensonca -Peter Bergner bergner +Peter Bergner bergner Daniel Berlin dberlin Pat Bernardi - Jan Beulich - @@ -934,6 +937,7 @@ information. Soumya AR +Peter Bergner Dhruv Chawla Juergen Christ Giuseppe D'Angelo diff --git a/Makefile.in b/Makefile.in index 931507c32703..12d4395d8e2f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -207,6 +207,7 @@ HOST_EXPORTS = \ GOC="$(GOC)"; export GOC; \ GDC="$(GDC)"; export GDC; \ GM2="$(GM2)"; export GM2; \ + GNATMAKE_FOR_BUILD="$(GNATMAKE_FOR_BUILD)"; export GNATMAKE_FOR_BUILD; \ AR="$(AR)"; export AR; \ AS="$(AS)"; export AS; \ CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \ @@ -312,6 +313,7 @@ BASE_TARGET_EXPORTS = \ GOC="$(GOC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export GOC; \ GDC="$(GDC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export GDC; \ GM2="$(GM2_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export GM2; \ + GNATMAKE_FOR_BUILD="$(GNATMAKE_FOR_BUILD)"; export GNATMAKE_FOR_BUILD; \ DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \ DSYMUTIL="$(DSYMUTIL_FOR_TARGET)"; export DSYMUTIL; \ LD="$(COMPILER_LD_FOR_TARGET)"; export LD; \ @@ -381,6 +383,7 @@ GFORTRAN_FOR_BUILD = @GFORTRAN_FOR_BUILD@ GOC_FOR_BUILD = @GOC_FOR_BUILD@ GDC_FOR_BUILD = @GDC_FOR_BUILD@ GM2_FOR_BUILD = @GM2_FOR_BUILD@ +GNATMAKE_FOR_BUILD = @GNATMAKE_FOR_BUILD@ LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ LD_FOR_BUILD = @LD_FOR_BUILD@ NM_FOR_BUILD = @NM_FOR_BUILD@ diff --git a/Makefile.tpl b/Makefile.tpl index b164a17e700a..ddcca5589137 100644 --- a/Makefile.tpl +++ b/Makefile.tpl @@ -210,6 +210,7 @@ HOST_EXPORTS = \ GOC="$(GOC)"; export GOC; \ GDC="$(GDC)"; export GDC; \ GM2="$(GM2)"; export GM2; \ + GNATMAKE_FOR_BUILD="$(GNATMAKE_FOR_BUILD)"; export GNATMAKE_FOR_BUILD; \ AR="$(AR)"; export AR; \ AS="$(AS)"; export AS; \ CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \ @@ -315,6 +316,7 @@ BASE_TARGET_EXPORTS = \ GOC="$(GOC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export GOC; \ GDC="$(GDC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export GDC; \ GM2="$(GM2_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export GM2; \ + GNATMAKE_FOR_BUILD="$(GNATMAKE_FOR_BUILD)"; export GNATMAKE_FOR_BUILD; \ DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \ DSYMUTIL="$(DSYMUTIL_FOR_TARGET)"; export DSYMUTIL; \ LD="$(COMPILER_LD_FOR_TARGET)"; export LD; \ @@ -384,6 +386,7 @@ GFORTRAN_FOR_BUILD = @GFORTRAN_FOR_BUILD@ GOC_FOR_BUILD = @GOC_FOR_BUILD@ GDC_FOR_BUILD = @GDC_FOR_BUILD@ GM2_FOR_BUILD = @GM2_FOR_BUILD@ +GNATMAKE_FOR_BUILD = @GNATMAKE_FOR_BUILD@ LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ LD_FOR_BUILD = @LD_FOR_BUILD@ NM_FOR_BUILD = @NM_FOR_BUILD@ diff --git a/configure b/configure index ed1e5a4e8187..ccec3f21cd85 100755 --- a/configure +++ b/configure @@ -653,6 +653,7 @@ RANLIB_FOR_BUILD NM_FOR_BUILD LD_FOR_BUILD LDFLAGS_FOR_BUILD +GNATMAKE_FOR_BUILD GDC_FOR_BUILD GOC_FOR_BUILD GFORTRAN_FOR_BUILD @@ -3397,6 +3398,10 @@ case "${target}" in esac cpu_type=`echo ${host} | sed 's/-.*$//'` +# Special case cpu_type for x86_64 as it shares AUTO_PROFILE from i386. +if test "${cpu_type}" = "x86_64" ; then + cpu_type="i386" +fi # Disable libssp for some systems. @@ -4249,11 +4254,12 @@ if test "${build}" != "${host}" ; then CC_FOR_BUILD=${CC_FOR_BUILD-gcc} CPP_FOR_BUILD="${CPP_FOR_BUILD-\$(CC_FOR_BUILD) -E}" CXX_FOR_BUILD=${CXX_FOR_BUILD-g++} + DLLTOOL_FOR_BUILD=${DLLTOOL_FOR_BUILD-dlltool} DSYMUTIL_FOR_BUILD=${DSYMUTIL_FOR_BUILD-dsymutil} GFORTRAN_FOR_BUILD=${GFORTRAN_FOR_BUILD-gfortran} GOC_FOR_BUILD=${GOC_FOR_BUILD-gccgo} GDC_FOR_BUILD=${GDC_FOR_BUILD-gdc} - DLLTOOL_FOR_BUILD=${DLLTOOL_FOR_BUILD-dlltool} + GNATMAKE_FOR_BUILD=${GNATMAKE_FOR_BUILD-gnatmake} LD_FOR_BUILD=${LD_FOR_BUILD-ld} NM_FOR_BUILD=${NM_FOR_BUILD-nm} RANLIB_FOR_BUILD=${RANLIB_FOR_BUILD-ranlib} @@ -4264,11 +4270,12 @@ else AS_FOR_BUILD="\$(AS)" CC_FOR_BUILD="\$(CC)" CXX_FOR_BUILD="\$(CXX)" + DLLTOOL_FOR_BUILD="\$(DLLTOOL)" DSYMUTIL_FOR_BUILD="\$(DSYMUTIL)" GFORTRAN_FOR_BUILD="\$(GFORTRAN)" GOC_FOR_BUILD="\$(GOC)" GDC_FOR_BUILD="\$(GDC)" - DLLTOOL_FOR_BUILD="\$(DLLTOOL)" + GNATMAKE_FOR_BUILD="\$(GNATMAKE)" LD_FOR_BUILD="\$(LD)" NM_FOR_BUILD="\$(NM)" RANLIB_FOR_BUILD="\$(RANLIB)" @@ -11691,6 +11698,7 @@ done + # Generate default definitions for YACC, M4, LEX and other programs that run # on the build machine. These are used if the Makefile can't locate these diff --git a/configure.ac b/configure.ac index 33c130f4e02a..89ebe4041b61 100644 --- a/configure.ac +++ b/configure.ac @@ -622,6 +622,10 @@ case "${target}" in esac cpu_type=`echo ${host} | sed 's/-.*$//'` +# Special case cpu_type for x86_64 as it shares AUTO_PROFILE from i386. +if test "${cpu_type}" = "x86_64" ; then + cpu_type="i386" +fi AC_SUBST(cpu_type) # Disable libssp for some systems. @@ -1446,11 +1450,12 @@ if test "${build}" != "${host}" ; then CC_FOR_BUILD=${CC_FOR_BUILD-gcc} CPP_FOR_BUILD="${CPP_FOR_BUILD-\$(CC_FOR_BUILD) -E}" CXX_FOR_BUILD=${CXX_FOR_BUILD-g++} + DLLTOOL_FOR_BUILD=${DLLTOOL_FOR_BUILD-dlltool} DSYMUTIL_FOR_BUILD=${DSYMUTIL_FOR_BUILD-dsymutil} GFORTRAN_FOR_BUILD=${GFORTRAN_FOR_BUILD-gfortran} GOC_FOR_BUILD=${GOC_FOR_BUILD-gccgo} GDC_FOR_BUILD=${GDC_FOR_BUILD-gdc} - DLLTOOL_FOR_BUILD=${DLLTOOL_FOR_BUILD-dlltool} + GNATMAKE_FOR_BUILD=${GNATMAKE_FOR_BUILD-gnatmake} LD_FOR_BUILD=${LD_FOR_BUILD-ld} NM_FOR_BUILD=${NM_FOR_BUILD-nm} RANLIB_FOR_BUILD=${RANLIB_FOR_BUILD-ranlib} @@ -1461,11 +1466,12 @@ else AS_FOR_BUILD="\$(AS)" CC_FOR_BUILD="\$(CC)" CXX_FOR_BUILD="\$(CXX)" + DLLTOOL_FOR_BUILD="\$(DLLTOOL)" DSYMUTIL_FOR_BUILD="\$(DSYMUTIL)" GFORTRAN_FOR_BUILD="\$(GFORTRAN)" GOC_FOR_BUILD="\$(GOC)" GDC_FOR_BUILD="\$(GDC)" - DLLTOOL_FOR_BUILD="\$(DLLTOOL)" + GNATMAKE_FOR_BUILD="\$(GNATMAKE)" LD_FOR_BUILD="\$(LD)" NM_FOR_BUILD="\$(NM)" RANLIB_FOR_BUILD="\$(RANLIB)" @@ -3911,6 +3917,7 @@ AC_SUBST(DSYMUTIL_FOR_BUILD) AC_SUBST(GFORTRAN_FOR_BUILD) AC_SUBST(GOC_FOR_BUILD) AC_SUBST(GDC_FOR_BUILD) +AC_SUBST(GNATMAKE_FOR_BUILD) AC_SUBST(LDFLAGS_FOR_BUILD) AC_SUBST(LD_FOR_BUILD) AC_SUBST(NM_FOR_BUILD) diff --git a/contrib/ChangeLog b/contrib/ChangeLog index 276ce745a98b..f32cb2b84147 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,3 +1,54 @@ +2025-07-16 David Malcolm + + * gcc.doxy (INPUT): Add directory "gcc/text-art". + +2025-07-11 Richard Biener + + * gcc-changelog/git_update_version.py: Stop updating gcc-12 + branch. + +2025-07-08 Pierre-Emmanuel Patry + + * prepare-commit-msg: Force default git prefixes. + +2025-07-07 Martin Jambor + + * filter-clang-warnings.py (skip_warning): Also ignore + -Woverloaded-shift-op-parentheses, -Wunused-function, + -Wunneeded-internal-declaration, -Wvla-cxx-extension', and + -Wunused-command-line-argument everywhere and a warning about + m_logical_loc_mgr in diagnostic-path-output.cc. Adjust gimple-match + and generic-match "filenames." Ignore -Wnontrivial-memcall warnings + in wide-int.h, all warnings about unused stuff in files under + m2/gm2-compiler-boot, all -Wunused-private-field in rust FE, in + analyzer/ana-state-to-diagnostic-state.h and c-family/c-format.cc, all + Warnings in avr-mmcu.texi, install.texi and libgccjit.texi and all + -Wc23-extensions warnings in libiberty/sha1.c. Ignore + -Wunused-parameter in analyzer/sm.cc. Reorder entries. + +2025-06-29 Filip Kastl + + * mklog.py: In 'main()', specify variable 'root' as global. + +2025-06-26 Alex Coplan + + * mklog.py (main): New. + +2025-06-23 David Malcolm + + PR other/116792 + PR testsuite/116163 + PR sarif-replay/120792 + * dg-lint/dg-lint: Add -fdiagnostics-add-output. + * dg-lint/libgdiagnostics.py: Add + diagnostic_manager_add_sink_from_spec. + (Manager.add_sink_from_spec): New. + +2025-06-23 Andrew Burgess + + * dg-extract-results.py: Handle GDB's unexpected core file count. + * dg-extract-results.sh: Likewise. + 2025-05-27 Jan Hubicka * gen_autofdo_event.py: Add support for AMD Zen 3 and diff --git a/contrib/dg-extract-results.py b/contrib/dg-extract-results.py index f539275ba03c..c5bfbcaa0202 100644 --- a/contrib/dg-extract-results.py +++ b/contrib/dg-extract-results.py @@ -146,7 +146,8 @@ def __init__ (self): '# of unresolved testcases\t', '# of unsupported tests\t\t', '# of paths in test names\t', - '# of duplicate test names\t' + '# of duplicate test names\t', + '# of unexpected core files\t' ] self.runs = dict() diff --git a/contrib/dg-extract-results.sh b/contrib/dg-extract-results.sh index c2f760498da4..d64ba2558388 100755 --- a/contrib/dg-extract-results.sh +++ b/contrib/dg-extract-results.sh @@ -403,7 +403,7 @@ BEGIN { variant="$VAR" tool="$TOOL" passcnt=0; failcnt=0; untstcnt=0; xpasscnt=0; xfailcnt=0; kpasscnt=0; kfailcnt=0; unsupcnt=0; unrescnt=0; dgerrorcnt=0; - pathcnt=0; dupcnt=0 + pathcnt=0; dupcnt=0; corecnt=0 curvar=""; insummary=0 } /^Running target / { curvar = \$3; next } @@ -420,6 +420,7 @@ BEGIN { /^# of unsupported tests/ { if (insummary == 1) unsupcnt += \$5; next; } /^# of paths in test names/ { if (insummary == 1) pathcnt += \$7; next; } /^# of duplicate test names/ { if (insummary == 1) dupcnt += \$6; next; } +/^# of unexpected core files/ { if (insummary == 1) corecnt += \$6; next; } /^$/ { if (insummary == 1) { insummary = 0; curvar = "" } next @@ -439,6 +440,7 @@ END { if (unsupcnt != 0) printf ("# of unsupported tests\t\t%d\n", unsupcnt) if (pathcnt != 0) printf ("# of paths in test names\t%d\n", pathcnt) if (dupcnt != 0) printf ("# of duplicate test names\t%d\n", dupcnt) + if (corecnt != 0) printf ("# of unexpected core files\t%d\n", corecnt) } EOF @@ -460,7 +462,7 @@ cat << EOF > $TOTAL_AWK BEGIN { tool="$TOOL" passcnt=0; failcnt=0; untstcnt=0; xpasscnt=0; xfailcnt=0; kfailcnt=0; unsupcnt=0; unrescnt=0; dgerrorcnt=0 - pathcnt=0; dupcnt=0 + pathcnt=0; dupcnt=0; corecnt=0 } /^# of DejaGnu errors/ { dgerrorcnt += \$5 } /^# of expected passes/ { passcnt += \$5 } @@ -474,6 +476,7 @@ BEGIN { /^# of unsupported tests/ { unsupcnt += \$5 } /^# of paths in test names/ { pathcnt += \$7 } /^# of duplicate test names/ { dupcnt += \$6 } +/^# of unexpected core files/ { corecnt += \$6 } END { printf ("\n\t\t=== %s Summary ===\n\n", tool) if (dgerrorcnt != 0) printf ("# of DejaGnu errors\t\t%d\n", dgerrorcnt) @@ -488,6 +491,7 @@ END { if (unsupcnt != 0) printf ("# of unsupported tests\t\t%d\n", unsupcnt) if (pathcnt != 0) printf ("# of paths in test names\t%d\n", pathcnt) if (dupcnt != 0) printf ("# of duplicate test names\t%d\n", dupcnt) + if (corecnt != 0) printf ("# of unexpected core files\t%d\n", corecnt) } EOF diff --git a/contrib/dg-lint/dg-lint b/contrib/dg-lint/dg-lint index 01d58d7a3e95..4ae0686b975b 100755 --- a/contrib/dg-lint/dg-lint +++ b/contrib/dg-lint/dg-lint @@ -380,9 +380,17 @@ def skip_file(filename): def main(argv): parser = argparse.ArgumentParser()#usage=__doc__) parser.add_argument('paths', nargs='+', type=pathlib.Path) + parser.add_argument('-fdiagnostics-add-output', action='append') opts = parser.parse_args(argv[1:]) ctxt = Context() + control_mgr = libgdiagnostics.Manager() + control_mgr.add_text_sink() + for scheme in opts.fdiagnostics_add_output: + ctxt.mgr.add_sink_from_spec("-fdiagnostics-add-output=", + scheme, + control_mgr) + for path in opts.paths: if path.is_dir(): for dirpath, dirnames, filenames in os.walk(path): diff --git a/contrib/dg-lint/libgdiagnostics.py b/contrib/dg-lint/libgdiagnostics.py index 03a6440a3e3c..8c8cc4887cd2 100644 --- a/contrib/dg-lint/libgdiagnostics.py +++ b/contrib/dg-lint/libgdiagnostics.py @@ -124,6 +124,13 @@ class c_diagnostic_physical_location(ctypes.Structure): ctypes.c_char_p] cdll.diagnostic_add_fix_it_hint_replace.restype = None +cdll.diagnostic_manager_add_sink_from_spec.argtypes \ + = [c_diagnostic_manager_ptr, + ctypes.c_char_p, + ctypes.c_char_p, + c_diagnostic_manager_ptr] +cdll.diagnostic_manager_add_sink_from_spec.restype = ctypes.c_int + # Helper functions def _to_utf8(s: str): @@ -156,6 +163,16 @@ def add_text_sink(self): c_stderr, DIAGNOSTIC_COLORIZE_IF_TTY) + def add_sink_from_spec(self, option_name: str, scheme: str, control_mgr): + assert self.c_mgr + assert control_mgr.c_mgr + res = cdll.diagnostic_manager_add_sink_from_spec (self.c_mgr, + _to_utf8(option_name), + _to_utf8(scheme), + control_mgr.c_mgr) + if res: + raise RuntimeError() + def get_file(self, path: str, sarif_lang: str = None): assert self.c_mgr assert path diff --git a/contrib/filter-clang-warnings.py b/contrib/filter-clang-warnings.py index 2ea7c710163a..b1b881eec3e2 100755 --- a/contrib/filter-clang-warnings.py +++ b/contrib/filter-clang-warnings.py @@ -41,22 +41,43 @@ def skip_warning(filename, message): '-Wignored-attributes', '-Wgnu-zero-variadic-macro-arguments', '-Wformat-security', '-Wundefined-internal', '-Wunknown-warning-option', '-Wc++20-extensions', - '-Wbitwise-instead-of-logical', 'egrep is obsolescent'], + '-Wbitwise-instead-of-logical', 'egrep is obsolescent', + '-Woverloaded-shift-op-parentheses', + '-Wunused-function', '-Wunneeded-internal-declaration', + '-Wvla-cxx-extension', '-Wunused-command-line-argument'], + + 'diagnostic-path-output.cc': ['m_logical_loc_mgr'], + 'fold-const-call.cc': ['-Wreturn-type'], + 'gimple-match': ['-Wunused-', '-Wtautological-compare'], + 'generic-match': ['-Wunused-', '-Wtautological-compare'], + 'genautomata.cc': ['-Wstring-plus-int'], + # Perhaps revisit when ATTR_FNSPEC_DECONST_WATERMARK ifdef case is + # made default or removed: + 'ipa-strub.cc': ['-Wunused-but-set-variable'], 'insn-modes.cc': ['-Wshift-count-overflow'], 'insn-emit.cc': ['-Wtautological-compare'], 'insn-attrtab.cc': ['-Wparentheses-equality'], - 'gimple-match.cc': ['-Wunused-', '-Wtautological-compare'], - 'generic-match.cc': ['-Wunused-', '-Wtautological-compare'], + 'omp-builtins.def': ['-Wc++11-narrowing'], + 'wide-int.h': ['-Wnontrivial-memcall'], 'i386.md': ['-Wparentheses-equality', '-Wtautological-compare', '-Wtautological-overlap-compare'], 'sse.md': ['-Wparentheses-equality', '-Wtautological-compare', '-Wconstant-logical-operand'], 'mmx.md': ['-Wtautological-compare'], - 'genautomata.cc': ['-Wstring-plus-int'], - 'fold-const-call.cc': ['-Wreturn-type'], - 'gfortran.texi': [''], - 'libtool': [''], 'lex.cc': ['-Wc++20-attribute-extensions'], + # Perhaps remove once PR 120960 is resolved: + 'analyzer/ana-state-to-diagnostic-state.h': ['-Wunused-private-field'], + 'analyzer/sm.cc': ['-Wunused-parameter'], + 'c-family/c-format.cc': ['-Wunused-private-field'], + 'm2/gm2-compiler-boot': ['-Wunused-'], + # Rust peopel promised to clean these warnings too + 'rust/': ['-Wunused-private-field'], + 'libiberty/sha1.c': ['-Wc23-extensions'], + 'avr-mmcu.texi': [''], + 'gfortran.texi': [''], + 'install.texi': [''], + 'libgccjit.texi': [''], + 'libtool': [''] } for name, ignore in ignores.items(): diff --git a/contrib/gcc-changelog/git_update_version.py b/contrib/gcc-changelog/git_update_version.py index aa9adee58fef..b3ea33bb5161 100755 --- a/contrib/gcc-changelog/git_update_version.py +++ b/contrib/gcc-changelog/git_update_version.py @@ -85,7 +85,7 @@ def prepend_to_changelog_files(repo, folder, git_commit, add_to_git): repo.git.add(full_path) -active_refs = ['master', 'releases/gcc-12', +active_refs = ['master', 'releases/gcc-13', 'releases/gcc-14', 'releases/gcc-15'] parser = argparse.ArgumentParser(description='Update DATESTAMP and generate ' diff --git a/contrib/gcc.doxy b/contrib/gcc.doxy index 9e0a1af0e20c..cf3281fe0f46 100644 --- a/contrib/gcc.doxy +++ b/contrib/gcc.doxy @@ -478,7 +478,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = gcc gcc/analyzer +INPUT = gcc gcc/analyzer gcc/text-art # This tag can be used to specify the character encoding of the source files that # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default diff --git a/contrib/mklog.py b/contrib/mklog.py index dcf7dde63336..b841ef0ae97e 100755 --- a/contrib/mklog.py +++ b/contrib/mklog.py @@ -360,7 +360,7 @@ def skip_line_in_changelog(line): return FIRST_LINE_OF_END_RE.match(line) is None -if __name__ == '__main__': +def main(): extra_args = os.getenv('GCC_MKLOG_ARGS') if extra_args: sys.argv += json.loads(extra_args) @@ -389,6 +389,7 @@ def skip_line_in_changelog(line): if args.input == '-': args.input = None if args.directory: + global root root = args.directory data = open(args.input, newline='\n') if args.input else sys.stdin @@ -447,3 +448,6 @@ def skip_line_in_changelog(line): f.write('\n'.join(end)) else: print(output, end='') + +if __name__ == '__main__': + main() diff --git a/contrib/prepare-commit-msg b/contrib/prepare-commit-msg index 1b878772dcc4..75d102559c78 100755 --- a/contrib/prepare-commit-msg +++ b/contrib/prepare-commit-msg @@ -78,4 +78,4 @@ else tee="cat" fi -git $cmd | $tee | git gcc-mklog -c "$COMMIT_MSG_FILE" +git $cmd --default-prefix | $tee | git gcc-mklog -c "$COMMIT_MSG_FILE" diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 921d621f889a..f3e4ba1c716e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,5288 @@ +2025-07-21 Jeff Law + + * config/riscv/mips-p8700.md: Add support for "ghost" insn types. + * config/riscv/xiangshan.md: Add support for "sf_vc" and "sf_vc_se" + insn types. + +2025-07-21 Andrew Pinski + + PR tree-optimization/110949 + PR tree-optimization/95906 + * match.pd (cmp - 1): New pattern. + +2025-07-21 Andreas Schwab + + PR target/121121 + * config/riscv/riscv.cc (riscv_allocate_and_probe_stack_space): + Use temp2 instead of temp1 for the CFA note. + +2025-07-21 Pan Li + + * config/riscv/vector.md: Allow VLS DImode for sat_op vx pattern. + +2025-07-21 Pan Li + + * config/riscv/autovec-opt.md (*uavg_floor_vx_): Add + pattern for vaaddu.vx combine. + * config/riscv/riscv.cc (get_vector_binary_rtx_cost): Add UNSPEC + handling for UNSPEC_VAADDU. + (riscv_rtx_costs): Ditto. + +2025-07-21 Kyrylo Tkachov + + * config/aarch64/aarch64-simd.md (aarch64_simd_vec_set_zero): + Enable only when optimizing for size. + +2025-07-21 Kyrylo Tkachov + + * config/aarch64/aarch64.cc (aarch64_rtx_costs): Add extra_cost values + only when speed is true for CONST_VECTOR, VEC_DUPLICATE, VEC_SELECT + cases. + * config/aarch64/aarch64-cost-tables.h (qdf24xx_extra_costs, + thunderx_extra_costs, thunderx2t99_extra_costs, + thunderx3t110_extra_costs, tsv110_extra_costs, a64fx_extra_costs, + ampere1_extra_costs, ampere1a_extra_costs, ampere1b_extra_costs): + Reduce cost of movi, dup, extract fields by COSTS_N_INSNS (1). + * config/arm/aarch-cost-tables.h (generic_extra_costs, + cortexa53_extra_costs, cortexa57_extra_costs, cortexa76_extra_costs, + exynosm1_extra_costs, xgene1_extra_costs): Likewise. + +2025-07-21 Richard Biener + + PR tree-optimization/121194 + * tree-vect-loop.cc (vectorizable_lc_phi): Verify + vector types are compatible. + +2025-07-21 Andrew Stubbs + + * config/gcn/gcn-valu.md (gather_load): New. + (scatter_store): New. + (mask_gather_load): New. + (mask_scatter_store): New. + * config/gcn/gcn.cc (gcn_expand_scaled_offsets): Support DImode. + +2025-07-21 Andrew Stubbs + + * config/gcn/gcn.cc (GEN_VNM_NOEXEC): Use USE_QHF. + (GEN_VNM): Likewise, and call for new ashl and mul variants. + +2025-07-21 Andrew Stubbs + + * config/gcn/gcn-valu.md (add3_dup): New. + (add3_dup_exec): New. + (mul3_highpart_dup): New. + (mul3_dup): Move the vec_duplicate to operand 1. + (mul3_dup_exec): New. + (vec_series): Adjust call to gen_mul3_dup. + * config/gcn/gcn.cc (gcn_expand_vector_init): Likewise. + +2025-07-21 Stefan Schulze Frielinghaus + + * genoutput.cc (main): Emit function + verify_reg_names_in_constraints() for run-time validation. + (mdep_constraint_len): Deal with hard register constraints. + * output.h (verify_reg_names_in_constraints): New function + declaration. + * toplev.cc (backend_init): If checking is enabled, call into + verify_reg_names_in_constraints(). + +2025-07-21 Stefan Schulze Frielinghaus + + * cfgexpand.cc (n_occurrences): Move this ... + (check_operand_nalternatives): and this ... + (expand_asm_stmt): and the call to gimplify.cc. + * config/s390/s390.cc (s390_md_asm_adjust): Pass null pointer to + parse_{input,output}_constraint(). + * gimple-walk.cc (walk_gimple_asm): Pass null pointer to + parse_{input,output}_constraint(). + (walk_stmt_load_store_addr_ops): Ditto. + * gimplify-me.cc (gimple_regimplify_operands): Ditto. + * gimplify.cc (num_occurrences): Moved from cfgexpand.cc. + (num_alternatives): Ditto. + (gimplify_asm_expr): Deal with hard register constraints. + * stmt.cc (eliminable_regno_p): New helper. + (hardreg_ok_p): Perform a similar check as done in + make_decl_rtl(). + (parse_output_constraint): Add parameter for gimplify_reg_info + and validate hard register constrained operands. + (parse_input_constraint): Ditto. + * stmt.h (class gimplify_reg_info): Forward declaration. + (parse_output_constraint): Add parameter. + (parse_input_constraint): Ditto. + * tree-ssa-operands.cc + (operands_scanner::get_asm_stmt_operands): Pass null pointer + to parse_{input,output}_constraint(). + * tree-ssa-structalias.cc (find_func_aliases): Pass null pointer + to parse_{input,output}_constraint(). + * varasm.cc (assemble_asm): Pass null pointer to + parse_{input,output}_constraint(). + * gimplify_reg_info.h: New file. + +2025-07-21 Stefan Schulze Frielinghaus + + * config/cris/cris.cc (cris_md_asm_adjust): Deal with hard + register constraint. + * config/i386/i386.cc (map_egpr_constraints): Ditto. + * config/s390/s390.cc (f_constraint_p): Ditto. + * doc/extend.texi: Document hard register constraints. + * doc/md.texi: Ditto. + * function.cc (match_asm_constraints_2): Have a unique pseudo + for each operand with a hard register constraint. + (pass_match_asm_constraints::execute): Calling into new helper + match_asm_constraints_2(). + * genoutput.cc (mdep_constraint_len): Return the length of a + hard register constraint. + * genpreds.cc (write_insn_constraint_len): Support hard register + constraints for insn_constraint_len(). + * ira.cc (valid_replacement_for_asm_input_p_1): New helper. + (valid_replacement_for_asm_input_p): New helper. + (decrease_live_ranges_number): Similar to + match_asm_constraints_2() ensure that each operand has a unique + pseudo if constrained by a hard register. + * lra-constraints.cc (process_alt_operands): Install hard + register filter according to constraint. + * recog.cc (asm_operand_ok): Accept register type for hard + register constrained asm operands. + (constrain_operands): Validate hard register constraints. + * stmt.cc (decode_hard_reg_constraint): Parse a hard register + constraint into the corresponding register number or bail out. + (parse_output_constraint): Parse hard register constraint and + set *ALLOWS_REG. + (parse_input_constraint): Ditto. + * stmt.h (decode_hard_reg_constraint): Declaration of new + function. + +2025-07-21 Richard Biener + + * tree-vectorizer.h (vect_analyze_data_refs): Remove min_vf + output. + * tree-vect-data-refs.cc (vect_analyze_data_refs): Likewise. + * tree-vect-loop.cc (vect_analyze_loop_2): Remove early + out based on bogus min_vf. + * tree-vect-slp.cc (vect_slp_analyze_bb_1): Adjust. + +2025-07-20 Pan Li + + * config/riscv/autovec.md: Add (const_int 1) as the op2 of + ashiftrt. + +2025-07-19 Dimitar Dimitrov + + PR target/121124 + * config/pru/pru-pragma.cc (pru_pragma_ctable_entry): Handle the + ctable base address as signed 32-bit value, and sign-extend to + HOST_WIDE_INT. + * config/pru/pru-protos.h (struct pru_ctable_entry): Store the + ctable base address as signed. + (pru_get_ctable_exact_base_index): Pass base address as signed. + (pru_get_ctable_base_index): Ditto. + (pru_get_ctable_base_offset): Ditto. + * config/pru/pru.cc (pru_get_ctable_exact_base_index): Ditto. + (pru_get_ctable_base_index): Ditto. + (pru_get_ctable_base_offset): Ditto. + (pru_print_operand_address): Ditto. + +2025-07-19 Paul-Antoine Arras + + PR target/119100 + * config/riscv/autovec-opt.md (*vfwnmacc_vf_): New pattern. + (*vfwnmsac_vf_): New pattern. + * config/riscv/riscv.cc (get_vector_binary_rtx_cost): Add support for a + vec_duplicate in a neg. + +2025-07-19 Artemiy Volkov + + * config/riscv/riscv.cc (riscv_macro_fusion_pair_p): Protect + from a NULL PREV_SET or CURR_SET. + +2025-07-19 Georg-Johann Lay + + * config/avr/avr-passes.cc (avr_optimize_casesi): Fuse + get_insns() with end_sequence(). + +2025-07-18 Pan Li + + * config/riscv/autovec.md (avg3_ceil): Add new pattern + of avg3_ceil for RVV DImode + +2025-07-18 Martin Jambor + + PR tree-optimization/117423 + * tree-sra.cc (analyze_access_subtree): Fix computation of grp_covered + flag. + +2025-07-18 Richard Biener + + PR tree-optimization/121126 + * tree-vect-stmts.cc (vect_analyze_stmt): Analyze the + live lane extract for LC PHIs that are vect_internal_def. + +2025-07-18 Richard Biener + + * tree-vect-loop.cc (vectorizable_live_operation_1): + Remove stmt_info and ncopies parameters. Remove !slp_node + paths. + (vectorizable_live_operation): Remove !slp_node paths. + +2025-07-18 Richard Biener + + PR tree-optimization/120924 + * params.opt (uninit-max-chain-len): Up from 8 to 12. + +2025-07-18 Richard Biener + + PR tree-optimization/121048 + * tree-vect-loop.cc (vect_determine_vectype_for_stmt_1): + Remove rejecting vector(1) vector types. + (vect_set_stmts_vectype): Likewise. + * tree-vect-slp.cc (vect_make_slp_decision): Only + count instances with non-vector(1) root towards whether + we have any interesting instances to vectorize. + +2025-07-18 Jakub Jelinek + + PR tree-optimization/121131 + * gimple-fold.cc (fold_nonarray_ctor_reference): Use + TREE_INT_CST_LOW (TYPE_SIZE ()) instead of + GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE ()) for BLKmode BITINT_TYPEs. + Don't compute encoding_size at all for little endian targets. + +2025-07-17 Andrew Pinski + + PR middle-end/121095 + * gcse.cc (execute_hardreg_pre): Skip if the hardreg which is never live. + +2025-07-17 Filip Kastl + + * tree-ssa-structalias.cc (lookup_vi_for_tree): Fix GNU style. + (process_constraint): Fix GNU style. + (get_constraint_for_component_ref): Fix GNU style. + (get_constraint_for_1): Fix GNU style. + (get_function_part_constraint): Fix GNU style. + (handle_lhs_call): Fix GNU style. + (find_func_aliases_for_builtin_call): Fix GNU style. + (find_func_aliases): Fix GNU style. + (find_func_clobbers): Fix GNU style. + (struct shared_bitmap_hasher): Fix GNU style. + (shared_bitmap_hasher::hash): Fix GNU style. + (pt_solution_includes_global): Fix GNU style. + (init_base_vars): Fix GNU style. + (visit_loadstore): Fix GNU style. + (compute_dependence_clique): Fix GNU style. + (struct pt_solution): Fix GNU style. + (ipa_pta_execute): Fix GNU style. + +2025-07-17 Filip Kastl + + * pta-andersen.cc (struct constraint_graph): Fix GNU style. + (constraint_equal): Fix GNU style. + (set_union_with_increment): Fix GNU style. + (insert_into_complex): Fix GNU style. + (merge_node_constraints): Fix GNU style. + (unify_nodes): Fix GNU style. + (do_ds_constraint): Fix GNU style. + (scc_info::scc_info): Fix GNU style. + (find_indirect_cycles): Fix GNU style. + (equiv_class_lookup_or_add): Fix GNU style. + (label_visit): Fix GNU style. + (dump_pred_graph): Fix GNU style. + (perform_var_substitution): Fix GNU style. + (eliminate_indirect_cycles): Fix GNU style. + (solve_graph): Fix GNU style. + (solve_constraints): Fix GNU style. + * tree-ssa-structalias.cc (first_vi_for_offset): Fix GNU style. + (debug_constraint): Fix GNU style. + * tree-ssa-structalias.h (struct constraint_expr): Fix GNU + style. + (struct variable_info): Fix GNU style. + +2025-07-17 H.J. Lu + + * config/i386/i386-expand.cc (ix86_expand_ternlog): Don't change + mode for XOR. + +2025-07-17 Filip Kastl + + * Makefile.in: Add pta-andersen.o. + * tree-ssa-structalias.cc (create_variable_info_for): Just move + around. + (unify_nodes): Move to pta-andersen.cc. + (struct constraint): Move to tree-ssa-structalias.h. + (EXECUTE_IF_IN_NONNULL_BITMAP): Move to pta-andersen.cc. + (struct variable_info): Move to tree-ssa-structalias.h. + (struct constraint_stats): Move to tree-ssa-structalias.h. + (first_vi_for_offset): External linkage, move to namespace + pointer_analysis. + (first_or_preceding_vi_for_offset): External linkage, move to namespace + pointer_analysis. + (dump_constraint): External linkage, move to namespace + pointer_analysis. + (debug_constraint): External linkage, move to namespace + pointer_analysis. + (dump_constraints): External linkage, move to namespace + pointer_analysis. + (debug_constraints): External linkage, move to namespace + pointer_analysis. + (lookup_vi_for_tree): Move around inside tree-ssa-structalias.cc. + (type_can_have_subvars): Move around inside tree-ssa-structalias.cc. + (make_param_constraints): Move around inside tree-ssa-structalias.cc. + (dump_solution_for_var): External linkage, move to namespace + pointer_analysis. find (...) -> var_rep[...]. + (get_varinfo): Move to tree-ssa-structalias.h. + (debug_solution_for_var): External linkage, move to namespace + pointer_analysis. + (vi_next): Move to tree-ssa-structalias.h. + (dump_sa_stats): External linkage, move to namespace pointer_analysis. + (new_var_info): Just move around. + (dump_sa_points_to_info): External linkage, move to namespace + pointer_analysis. + (debug_sa_points_to_info): External linkage, move to namespace + pointer_analysis. + (get_call_vi): Just move around. + (dump_varinfo): External linkage, move to namespace pointer_analysis. + (lookup_call_use_vi): Just move around. + (lookup_call_clobber_vi): Just move around. + (get_call_use_vi): Just move around. + (get_call_clobber_vi): Just move around. + (enum constraint_expr_type): Move to tree-ssa-structalias.h. + (struct constraint_expr): Move to tree-ssa-structalias.h. + (UNKNOWN_OFFSET): Move to tree-ssa-structalias.h. + (get_constraint_for_1): Just move around. + (get_constraint_for): Just move around. + (get_constraint_for_rhs): Just move around. + (do_deref): Just move around. + (constraint_pool): Just move around. + (struct constraint_graph): Move to pta-andersen.h. + (FIRST_REF_NODE): Move to pta-andersen.cc. + (LAST_REF_NODE): Move to pta-andersen.cc. + (find): Move to pta-andersen.cc. + (unite): Move to pta-andersen.cc. + (new_constraint): Just move around. + (debug_constraint_graph): External linkage, move to namespace + pointer_analysis. + (debug_varinfo): External linkage, move to namespace pointer_analysis. + (debug_varmap): External linkage, move to namespace pointer_analysis. + (dump_constraint_graph): External linkage, move to namespace + pointer_analysis. + (constraint_expr_equal): Move to pta-andersen.cc. + (constraint_expr_less): Move to pta-andersen.cc. + (constraint_less): Move to pta-andersen.cc. + (constraint_equal): Move to pta-andersen.cc. + (constraint_vec_find): Move to pta-andersen.cc. + (constraint_set_union): Move to pta-andersen.cc. + (solution_set_expand): Move to pta-andersen.cc. + (set_union_with_increment): Move to pta-andersen.cc. + (insert_into_complex): Move to pta-andersen.cc. + (merge_node_constraints): Move to pta-andersen.cc. + (clear_edges_for_node): Move to pta-andersen.cc. + (merge_graph_nodes): Move to pta-andersen.cc. + (add_implicit_graph_edge): Move to pta-andersen.cc. + (add_pred_graph_edge): Move to pta-andersen.cc. + (add_graph_edge): Move to pta-andersen.cc. + (init_graph): Move to pta-andersen.cc. Initialize + predbitmap_obstack here. + (build_pred_graph): Move to pta-andersen.cc. + (build_succ_graph): Move to pta-andersen.cc. + (class scc_info): Move to pta-andersen.cc. + (scc_visit): Move to pta-andersen.cc. + (solve_add_graph_edge): Move to pta-andersen.cc. + (do_sd_constraint): Move to pta-andersen.cc. + (do_ds_constraint): Move to pta-andersen.cc. + (do_complex_constraint): Move to pta-andersen.cc. + (scc_info::scc_info): Move to pta-andersen.cc. + (scc_info::~scc_info): Move to pta-andersen.cc. + (find_indirect_cycles): Move to pta-andersen.cc. + (topo_visit): Move to pta-andersen.cc. + (compute_topo_order): Move to pta-andersen.cc. + (struct equiv_class_hasher): Move to pta-andersen.cc. + (equiv_class_hasher::hash): Move to pta-andersen.cc. + (equiv_class_hasher::equal): Move to pta-andersen.cc. + (equiv_class_lookup_or_add): Move to pta-andersen.cc. + (condense_visit): Move to pta-andersen.cc. + (label_visit): Move to pta-andersen.cc. + (dump_pred_graph): External linkage, move to namespace + pointer_analysis. + (dump_varmap): External linkage, move to namespace pointer_analysis. + (perform_var_substitution): Move to pta-andersen.cc. + (free_var_substitution_info): Move to pta-andersen.cc. + (find_equivalent_node): Move to pta-andersen.cc. + (unite_pointer_equivalences): Move to pta-andersen.cc. + (move_complex_constraints): Move to pta-andersen.cc. + (rewrite_constraints): Move to pta-andersen.cc. + (eliminate_indirect_cycles): Move to pta-andersen.cc. + (solve_graph): Move to pta-andersen.cc. + (set_uids_in_ptset): find (...) -> var_rep[...]. + (find_what_var_points_to): find (...) -> var_rep[...]. + (init_alias_vars): Don't initialize predbitmap_obstack here. + (remove_preds_and_fake_succs): Move to pta-andersen.cc. + (solve_constraints): Move to pta-andersen.cc. Call + delete_graph() at the end. + (delete_points_to_sets): Don't delete graph here. Delete var_rep here. + (visit_loadstore): find (...) -> var_rep[...]. + (compute_dependence_clique): find (...) -> var_rep[...]. + (ipa_pta_execute): find (...) -> var_rep[...]. + * pta-andersen.cc: New file. + * pta-andersen.h: New file. + * tree-ssa-structalias.h: New file. + +2025-07-17 Richard Sandiford + Yury Khrustalev + + * doc/sourcebuild.texi (aarch64_sme_hw): Document. + +2025-07-17 Stefan Schulze Frielinghaus + + * config/s390/s390.md (signbit_tdc): Rename expander. + (signbit2): New expander. + (signbit2_z10): New expander. + +2025-07-17 Stefan Schulze Frielinghaus + + * config/s390/s390.cc (s390_register_move_cost): Add costing for + vlvg/vlgv. + +2025-07-17 Stefan Schulze Frielinghaus + + * config/s390/vector.md (bhfgq): Add scalar modes. + (*movdi_zero_extend_A): New insn. + (*movsi_zero_extend_A): New insn. + (*movdi_zero_extend_B): New insn. + (*movsi_zero_extend_B): New insn. + +2025-07-17 Xi Ruoyao + + PR target/121064 + * config/loongarch/lsx.md (lsx_vshuf_): Add '@' to + generate a mode-aware helper. Use as the mode of the + operand 1 (selector). + * config/loongarch/lasx.md (lasx_xvshuf_): Likewise. + * config/loongarch/loongarch.cc + (loongarch_try_expand_lsx_vshuf_const): Create a new pseudo for + the selector. Use the mode-aware helper to simplify the code. + (loongarch_expand_vec_perm_const): Likewise. + +2025-07-17 Richard Biener + + * tree-vect-slp.cc (vect_build_slp_tree_1): Reject + single-lane vector types. + +2025-07-17 Richard Biener + + PR tree-optimization/121035 + * tree-ssa-pre.cc (find_or_generate_expression): Handle + values without expression. + +2025-07-16 David Malcolm + + * diagnostic-state-to-dot.cc (state_diagram::m_show_tags): Drop + unused field. + +2025-07-16 Kwok Cheung Yeung + + * gimplify.cc (gimplify_omp_affinity): Use OMP_ITERATOR_DECL_P. + (compute_omp_iterator_count): New. + (build_omp_iterator_loop): New. + (gimplify_omp_depend): Use OMP_ITERATOR_DECL_P, + compute_omp_iterator_count and build_omp_iterator_loop. + * tree-inline.cc (copy_tree_body_r): Use OMP_ITERATOR_DECL_P. + * tree-pretty-print.cc (dump_omp_clause): Likewise. + * tree.h (OMP_ITERATOR_DECL_P): New macro. + +2025-07-16 Uros Bizjak + + PR target/121062 + * config/i386/i386.cc (ix86_convert_const_vector_to_integer): + Handle E_V1SImode and E_V1DImode. + * config/i386/mmx.md (V_16_32_64): Add V1SI, V2BF and V1DI. + (mmxinsnmode): Add V1DI and V1SI. + Add V_16_32_64 splitter for constant vector loads from constant + vector pool. + (V_16_32_64:*mov_imm): Moved after V_16_32_64 splitter. + Replace lowpart_subreg with adjust_address. + +2025-07-16 H.J. Lu + + PR target/120881 + PR testsuite/121078 + * config/i386/i386-options.cc (ix86_option_override_internal): + Warn -pg without -mfentry only on glibc targets. + +2025-07-16 Uros Bizjak + + * config/i386/i386-expand.cc (ix86_expand_move): + Use MEM_P predicate instead of open coding it. + (ix86_erase_embedded_rounding): + Use NONJUMP_INSN_P predicate instead of open coding it. + * config/i386/i386-features.cc (convertible_comparison_p): + Use REG_P predicate instead of open coding it. + * config/i386/i386.cc (ix86_rtx_costs): + Use SUBREG_P predicate instead of open coding it. + +2025-07-16 Uros Bizjak + + * config/i386/i386.cc (symbolic_reference_mentioned_p): + Use LABEL_REF_P predicate instead of open coding it. + (ix86_legitimate_constant_p): Ditto. + (legitimate_pic_address_disp_p): Ditto. + (ix86_legitimate_address_p): Ditto. + (legitimize_pic_address): Ditto. + (ix86_print_operand): Ditto. + (ix86_print_operand_address_as): Ditto. + (ix86_rip_relative_addr_p): Ditto. + * config/i386/i386.h (SYMBOLIC_CONST): Ditto. + * config/i386/i386.md (*anddi_1 to *andsi_1_zext splitter): Ditto. + * config/i386/predicates.md (symbolic_operand): Ditto. + (local_symbolic_operand): Ditto. + (vsib_address_operand): Ditto. + +2025-07-16 Uros Bizjak + + * config/i386/i386-expand.cc (ix86_expand_move): + Use SYMBOL_REF_P predicate instead of open coding it. + (ix86_split_long_move): Ditto. + (construct_plt_address): Ditto. + (ix86_expand_call): Ditto. + (ix86_notrack_prefixed_insn_p): Ditto. + * config/i386/i386-features.cc + (rest_of_insert_endbr_and_patchable_area): Ditto. + * config/i386/i386.cc (symbolic_reference_mentioned_p): Ditto. + (ix86_force_load_from_GOT_p): Ditto. + (ix86_legitimate_constant_p): Ditto. + (legitimate_pic_operand_p): Ditto. + (legitimate_pic_address_disp_p): Ditto. + (ix86_legitimate_address_p): Ditto. + (legitimize_pic_address): Ditto. + (ix86_legitimize_address): Ditto. + (ix86_delegitimize_tls_address): Ditto. + (ix86_print_operand): Ditto. + (ix86_print_operand_address_as): Ditto. + (ix86_rip_relative_addr_p): Ditto. + (symbolic_base_address_p): Ditto. + * config/i386/i386.h (SYMBOLIC_CONST): Ditto. + * config/i386/i386.md (*anddi_1 to *andsi_1_zext splitter): Ditto. + * config/i386/predicates.md (symbolic_operand): Ditto. + (local_symbolic_operand): Ditto. + (local_func_symbolic_operand): Ditto. + +2025-07-16 Uros Bizjak + + * config/i386/i386-expand.cc (ix86_expand_vector_logical_operator): + Use CONST_VECTOR_P instead of open coding it. + (ix86_expand_int_sse_cmp): Ditto. + (ix86_extract_perm_from_pool_constant): Ditto. + (ix86_split_to_parts): Ditto. + (const_vector_equal_evenodd_p): Ditto. + * config/i386/i386.cc (ix86_print_operand): Ditto. + * config/i386/predicates.md (zero_extended_scalar_load_operand): Ditto. + (float_vector_all_ones_operand): Ditto. + * config/i386/sse.md (avx512vl_vextractf128): Ditto. + +2025-07-16 Richard Biener + + PR tree-optimization/121049 + * internal-fn.h (widening_evenodd_fn_p): Declare. + * internal-fn.cc (widening_evenodd_fn_p): New function. + * tree-vect-stmts.cc (vectorizable_conversion): When using + an even/odd widening function disable loop masking. + +2025-07-16 Andrew Pinski + + PR tree-optimization/119920 + PR tree-optimization/112324 + PR tree-optimization/110015 + * tree-if-conv.cc (find_different_opnum): New function. + (factor_out_operators): New function. + (predicate_scalar_phi): Call factor_out_operators when + there is only 2 elements of a phi. + +2025-07-16 Andrew Pinski + + * tree-if-conv.cc (fold_build_cond_expr): Return early if lhs and rhs + are the same. + +2025-07-16 Andrew Pinski + + * tree-if-conv.cc (combine_blocks): Remove predicated + dynamic array. + +2025-07-16 Richard Biener + + PR tree-optimization/121116 + * tree-vect-loop.cc (vectorizable_induction): Use the + step vector element type for further processing. + +2025-07-16 Andrew Stubbs + + * config/gcn/gcn-valu.md (add3_vcc_dup): Change + operand 2 to allow gcn_alu_operand. Swap the operands in the VCC + update RTL. + (add3_vcc_zext_dup): Likewise. + (add3_vcc_zext_dup_exec): Likewise. + (add3_vcc_zext_dup2): Likewise. + (add3_vcc_zext_dup2_exec): Likewise. + +2025-07-16 Spencer Abson + + PR target/117850 + * config/aarch64/aarch64-builtins.cc (LO_HI_PAIRINGS): New, group the + lo/hi pairs from aarch64-builtin-pairs.def. + (aarch64_get_highpart_builtin): New function. + (aarch64_v128_highpart_ref): New function, helper to look for vector + highparts. + (aarch64_build_vector_cst): New function, helper to build duplicated + VECTOR_CSTs. + (aarch64_fold_lo_call_to_hi): New function. + (aarch64_general_gimple_fold_builtin): Add cases for the lo builtins + in aarch64-builtin-pairs.def. + * config/aarch64/aarch64-builtin-pairs.def: New file, declare the + parirs of lowpart-operating and highpart-operating builtins. + +2025-07-16 Alfie Richards + + * tree.cc (get_clone_versions): New function. + (get_clone_attr_versions): New function. + (get_version): New function. + * tree.h (get_clone_versions): New function. + (get_clone_attr_versions): New function. + (get_target_version): New function. + +2025-07-16 Alfie Richards + + * attribs.cc (make_attribute): Change arguments. + * attribs.h (make_attribute): Change arguments. + +2025-07-16 Alfie Richards + + * pretty-print.cc (format_phase_2): Add support for string_slice. + * vec.cc (string_slice::tokenize): New static method. + (string_slice::strcmp): New static method. + (string_slice::strip): New method. + (test_string_slice_initializers): New test. + (test_string_slice_tokenize): Ditto. + (test_string_slice_strcmp): Ditto. + (test_string_slice_equality): Ditto. + (test_string_slice_inequality): Ditto. + (test_string_slice_invalid): Ditto. + (test_string_slice_strip): Ditto. + (vec_cc_tests): Add new tests. + * vec.h (class string_slice): New class. + +2025-07-16 Robin Dapp + + PR middle-end/121065 + * cfgexpand.cc (expand_debug_expr): Allow fixed-point modes for + RDIV_EXPR. + * optabs-tree.cc (optab_for_tree_code): Ditto. + +2025-07-16 Robin Dapp + + PR target/120297 + * config/riscv/riscv-vsetvl.def: Do not forget ratio demand of + previous vsetvl. + +2025-07-16 Kyrylo Tkachov + + * config/aarch64/aarch64-sve2.md (*aarch64_sve2_bsl2n_eon): + New pattern. + (*aarch64_sve2_eon_bsl2n_unpred): Likewise. + +2025-07-16 Kyrylo Tkachov + + * config/aarch64/aarch64-sve2.md (*aarch64_sve2_unpred_nor): + New define_insn. + (*aarch64_sve2_nand_unpred): Likewise. + +2025-07-16 Jeremy Rifkin + + PR c/82134 + * gimplify.cc (gimplify_modify_expr): Add suppress_warning + * tree-cfg.cc (do_warn_unused_result): Check warning_suppressed_p + +2025-07-16 Haochen Jiang + + * common/config/i386/i386-common.cc + (OPTION_MASK_ISA2_AMX_AVX512_SET): Do not set AVX10.2. + (OPTION_MASK_ISA2_AVX10_2_UNSET): Remove AMX-AVX512 unset. + (OPTION_MASK_ISA2_AVX512F_UNSET): Unset AMX-AVX512. + (ix86_handle_option): Imply AVX512F for AMX-AVX512. + +2025-07-16 Pan Li + + * config/riscv/autovec.md (avg3_floor): Add new + pattern of avg3_floor for rvv DImode. + +2025-07-15 David Malcolm + + * spellcheck.cc: Define INCLUDE_ALGORITHM. + (CASE_COST, BASE_COST): Convert to... + (case_cost, base_cost): ...these, in an anonymous namespace. + (get_edit_distance): Update for above. Use std::min rather than + MIN. + (get_edit_distance_cutoff): Likewise. Use std::max rather than + MAX. + (selftest::test_edit_distances): Update for BASE_COST renaming. + (selftest::get_old_cutoff): Likewise. Use std::max. + (selftest::assert_not_suggested_for): Use nullptr. + (selftest::test_find_closest_string): Likewise. + * spellcheck.h: Replace TYPE with StringLikeType in templates, + and use CamelCase. + +2025-07-15 David Malcolm + + PR sarif-replay/120792 + * auto-obstack.h: New file, based on material taken from + pretty-print.cc. + * diagnostic-digraphs.h + (diagnostics::digraphs::digraph::set_description): New. + (diagnostics::digraphs::node::set_label): New. + * doc/libgdiagnostics/topics/compatibility.rst: Add + LIBGDIAGNOSTICS_ABI_4. + * doc/libgdiagnostics/topics/diagnostics.rst + (diagnostic_finish_via_msg_buf): Document new entrypoint. + * doc/libgdiagnostics/topics/execution-paths.rst + (diagnostic_execution_path_add_event_via_msg_buf): Document new + entrypoint. + * doc/libgdiagnostics/topics/index.rst: Add message-buffers.rst. + * doc/libgdiagnostics/topics/message-buffers.rst: New file. + * doc/libgdiagnostics/topics/message-formatting.rst: Add note + about message buffers. + * doc/libgdiagnostics/topics/physical-locations.rst + (diagnostic_add_location_with_label_via_msg_buf): Add. + * doc/libgdiagnostics/tutorial/07-execution-paths.rst: Link to + next section. + * doc/libgdiagnostics/tutorial/08-message-buffers.rst: New file. + * doc/libgdiagnostics/tutorial/index.rst: Add + 08-message-buffers.rst. + * libgdiagnostics++.h (libgdiagnostics::message_buffer): New + class. + (libgdiagnostics::execution_path::add_event_via_msg_buf): New. + (libgdiagnostics::diagnostic::add_location_with_label): New. + (libgdiagnostics::diagnostic::finish_via_msg_buf): New. + (libgdiagnostics::graph::set_description): New overload. + (libgdiagnostics::graph::add_edge): New overload. + (libgdiagnostics::node::set_label): New overload. + * libgdiagnostics-private.h + (private_diagnostic_execution_path_add_event_2): Drop decl. + (private_diagnostic_execution_path_add_event_3): New decl. + * libgdiagnostics.cc: Include "pretty-print-format-impl.h", + "pretty-print-markup.h", and "auto-obstack.h". + (class copying_token_printer): New. + (struct diagnostic_message_buffer): New. + (class pp_element_message_buffer): New. + (libgdiagnostics_path_event::libgdiagnostics_path_event): Replace + params "gmsgid" and "args" with "msg_buf". + (libgdiagnostics_path_event::print_desc): Reimplement using + pp_element_message_buffer to replay m_msg_buf into "pp". + (libgdiagnostics_path_event::m_desc_uncolored): Drop field. + (libgdiagnostics_path_event::m_desc_colored): Drop field. + (libgdiagnostics_path_event::msg_buf): New field. + (diagnostic_execution_path::add_event_va): Reimplement. + (diagnostic_execution_path::add_event_via_msg_buf): New. + (diagnostic::add_location_with_label): New overload, using + msg_buf. + (diagnostic_manager::emit): Reimplement with... + (diagnostic_manager::emit_va): ...this. + (diagnostic_manager::emit_msg_buf): New. + (FAIL_IF_NULL): Rename "p" to "ptr_arg". + (diagnostic_finish_va): Update to use diagnostic_manager::emit_va. + (diagnostic_graph::add_node_with_id): Rename "id" to "node_id". + (diagnostic_graph_add_node): Likewise. + (diagnostic_graph_add_edge): Rename "id" to "edge_id". + (diagnostic_graph_get_node_by_id): Rename "id" to "node_id". + (diagnostic_graph_get_edge_by_id): Rename "id" to "edge_id". + (private_diagnostic_execution_path_add_event_2): Delete. + (diagnostic_message_buffer_new): New public entrypoint. + (diagnostic_message_buffer_release): Likewise. + (diagnostic_message_buffer_append_str): Likewise. + (diagnostic_message_buffer_append_text): Likewise. + (diagnostic_message_buffer_append_byte): Likewise. + (diagnostic_message_buffer_append_printf): Likewise. + (diagnostic_message_buffer_append_event_id): Likewise. + (diagnostic_message_buffer_begin_url): Likewise. + (diagnostic_message_buffer_end_url): Likewise. + (diagnostic_message_buffer_begin_quote): Likewise. + (diagnostic_message_buffer_end_quote): Likewise. + (diagnostic_message_buffer_begin_color): Likewise. + (diagnostic_message_buffer_end_color): Likewise. + (diagnostic_message_buffer_dump): Likewise. + (diagnostic_finish_via_msg_buf): Likewise. + (diagnostic_add_location_with_label_via_msg_buf): Likewise. + (diagnostic_execution_path_add_event_via_msg_buf): Likewise. + (diagnostic_graph_set_description_via_msg_buf): Likewise. + (diagnostic_graph_add_edge_via_msg_buf): Likewise. + (diagnostic_node_set_label_via_msg_buf): Likewise. + (private_diagnostic_execution_path_add_event_3): New private + entrypoint. + * libgdiagnostics.h (LIBGDIAGNOSTICS_PARAM_FORMAT_STRING): New macro. + (LIBGDIAGNOSTICS_PARAM_PRINTF_FORMAT_STRING): New macro. + (diagnostic_message_buffer): New typedef. + (LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer): New define. + (diagnostic_message_buffer_new): New decl. + (diagnostic_message_buffer_release): New decl. + (diagnostic_message_buffer_append_str): New decl. + (diagnostic_message_buffer_append_text): New decl. + (diagnostic_message_buffer_append_byte): New decl. + (diagnostic_message_buffer_append_printf): New decl. + (diagnostic_message_buffer_append_event_id): New decl. + (diagnostic_message_buffer_begin_url): New decl. + (diagnostic_message_buffer_end_url): New decl. + (diagnostic_message_buffer_begin_quote): New decl. + (diagnostic_message_buffer_end_quote): New decl. + (diagnostic_message_buffer_begin_color): New decl. + (diagnostic_message_buffer_end_color): New decl. + (diagnostic_message_buffer_dump): New decl. + (diagnostic_finish_via_msg_buf): New decl. + (diagnostic_add_location_with_label_via_msg_buf): New decl. + (diagnostic_execution_path_add_event_via_msg_buf): New decl. + (diagnostic_graph_set_description_via_msg_buf): New decl. + (diagnostic_graph_add_edge_via_msg_buf): New decl. + (diagnostic_node_set_label_via_msg_buf): New decl. + * libgdiagnostics.map (LIBGDIAGNOSTICS_ABI_3): Drop + private_diagnostic_execution_path_add_event_2. + (LIBGDIAGNOSTICS_ABI_4): New. + * libsarifreplay.cc (class annotation): Use + libgdiagnostics::message_buffer rather than label_text. + (add_any_annotations): Likewise. + (sarif_replayer::handle_result_obj): Likewise. + (make_plain_text_within_result_message): Likewise. + (handle_thread_flow_location_object): Likewise. + (handle_location_object): Likewise. + (sarif_replayer::handle_graph_object): Likewise. + (sarif_replayer::handle_node_object): Likewise. + (sarif_replayer::handle_edge_object): Likewise. + * pretty-print-format-impl.h (pp_token_list::push_back_byte): New + decl. + * pretty-print-markup.h (pp_markup::context::begin_url): New decl. + (pp_markup::context::end_url): New decl. + (pp_markup::context::add_event_id): New decl. + * pretty-print.cc: Include "auto-obstack.h". + (pp_token_list::push_back_byte): New. + (struct auto_obstack): Move to auto-obstack.h. + (default_token_printer): Make non-static. + (pp_markup::context::begin_url): New. + (pp_markup::context::end_url): New. + (pp_markup::context::add_event_id): New. + +2025-07-15 Umesh Kalappa + + * config/riscv/riscv-cores.def (RISCV_CORE): Updated the supported march. + * config/riscv/riscv-ext-mips.def (DEFINE_RISCV_EXT): + New file added for mips conditional mov extension. + * config/riscv/riscv-ext.def: Likewise. + * config/riscv/t-riscv: Generates riscv-ext.opt + * config/riscv/riscv-ext.opt: Generated file. + * config/riscv/riscv.cc (riscv_expand_conditional_move): Updated for mips cmov + and outlined some code that handle arch cond move. + * config/riscv/riscv.md (movcc): updated expand for MIPS CCMOV. + * config/riscv/mips-insn.md: New file for mips-p8700 ccmov insn. + * doc/riscv-ext.texi: Updated for mips cmov. + +2025-07-15 Konstantinos Eleftheriou + + * avoid-store-forwarding.cc (generate_bit_insert_sequence): + Remove adjustment of bitfield insertion's starting position + when BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN. + (process_store_forwarding): Update offset check in base reg + initialization to take into account the target's endianness. + +2025-07-15 Soumya AR + + * config/aarch64/aarch64-tuning-flags.def (AARCH64_EXTRA_TUNING_OPTION): + Add AVOID_LDAPUR tuning flag. + * config/aarch64/aarch64.cc (aarch64_adjust_generic_arch_tuning): + Set AVOID_LDAPUR for architectures before armv8.8-a. + (aarch64_override_options_internal): Apply generic tuning adjustments + to generic_armv8_a_tunings and generic_armv9_a_tunings. + * config/aarch64/aarch64.h (TARGET_ENABLE_LDAPUR): New macro to + control LDAPUR usage based on RCPC2 and tuning flags. + * config/aarch64/aarch64.md: Add enable_ldapur attribute. + * config/aarch64/atomics.md (aarch64_atomic_load_rcpc): Modify + to emit LDAPUR for cores with RCPC2. + (*aarch64_atomic_load_rcpc_zext): Likewise. + (*aarch64_atomic_load_rcpc_sext): Update constraint to Ust. + * config/aarch64/tuning_models/cortexx925.h: Add AVOID_LDAPUR flag. + * config/aarch64/tuning_models/neoversev2.h: Likewise. + * config/aarch64/tuning_models/neoversev3.h: Likewise. + * config/aarch64/tuning_models/neoversev3ae.h: Likewise. + +2025-07-15 Richard Biener + Richard Sandiford + + PR tree-optimization/121059 + * tree-vect-stmts.cc (vectorizable_operation): Query + scalar_cond_masked_set with the correct number of masks. + +2025-07-15 Jakub Jelinek + Jason Merrill + + PR c/44677 + * common.opt (Wunused-but-set-parameter=, Wunused-but-set-variable=): + New options. + (Wunused-but-set-parameter, Wunused-but-set-variable): Turn into + aliases. + * common.opt.urls: Regenerate. + * diagnostic-spec.cc (nowarn_spec_t::nowarn_spec_t): Use + OPT_Wunused_but_set_variable_ instead of OPT_Wunused_but_set_variable + and OPT_Wunused_but_set_parameter_ instead of + OPT_Wunused_but_set_parameter. + * gimple-ssa-store-merging.cc (find_bswap_or_nop_1): Remove unused + but set variable tmp. + * ipa-strub.cc (pass_ipa_strub::execute): Cast named_args to + (void) if ATTR_FNSPEC_DECONST_WATERMARK is not defined. + * doc/invoke.texi (Wunused-but-set-parameter=, + Wunused-but-set-variable=): Document new options. + (Wunused-but-set-parameter, Wunused-but-set-variable): Adjust + documentation now that they are just aliases. + +2025-07-15 Alfie Richards + + * config/aarch64/aarch64-sme.md (@aarch64_sme_): + Change gating and comment. + +2025-07-15 Kyrylo Tkachov + + Revert: + 2025-07-11 Kyrylo Tkachov + + * config/aarch64/aarch64-simd.md (*eor3qdi4): New + define_insn_and_split. + +2025-07-15 Spencer Abson + + * config/aarch64/aarch64-sve.md (*fcm_and_combine): + Extend from SVE_FULL_F to SVE_F. + (*fcmuo_and_combine): Likewise. + (*fcm_bic_combine): Likewise. + (*fcm_nor_combine): Likewise. + (*fcmuo_bic_combine): Likewise. + (*fcmuo_nor_combine): Likewise. Move the comment here to + above fcmuo_bic_combine, since it applies to both patterns. + +2025-07-15 Rainer Orth + + * tree.cc: Include memmodel.h. + +2025-07-14 Andrew Stubbs + + * config/gcn/gcn-valu.md (vec_cmpudi_exec): Call gen_vec_cmp*, + not gen_vec_cmpu*. + +2025-07-14 Richard Biener + + Revert: + 2025-07-14 Richard Biener + + PR tree-optimization/121059 + * tree-vect-stmts.cc (vectorizable_operation): Record a + loop mask for mask AND operations. + +2025-07-14 Juergen Christ + + * config/s390/vector.md (reduc_plus_scal_): Implement. + (reduc_plus_scal_v2df): Implement. + (reduc_plus_scal_v4sf): Implement. + (REDUC_FMINMAX): New int iterator. + (reduc_fminmax_name): New int attribute. + (reduc_minmax): New code iterator. + (reduc_minmax_name): New code attribute. + (reduc__scal_v2df): Implement. + (reduc__scal_v4sf): Implement. + (reduc__scal_v2df): Implement. + (reduc__scal_v4sf): Implement. + (REDUCBIN): New code iterator. + (reduc_bin_insn): New code attribute. + (reduc__scal_v2di): Implement. + (reduc__scal_v4si): Implement. + (reduc__scal_v8hi): Implement. + (reduc__scal_v16qi): Implement. + +2025-07-14 Juergen Christ + + * config/s390/s390.cc (s390_option_override_internal): Remove override. + +2025-07-14 Andrew Stubbs + + * config/gcn/gcn-valu.md (add3): Rename ... + (add3): ... to this, remove the clobber, and change the + instruction from v_add_co_u32 to v_add_u32. + (add3_dup): Rename ... + (add3_dup): ... to this, and likewise. + (sub3): Rename ... + (sub3): ... to this, and likewise + * config/gcn/gcn.md (addsi3): Remove the DI clobber, and change the + instruction from v_add_co_u32 to v_add_u32. + (addsi3_scc): Likewise. + (subsi3): Likewise, but for v_sub_co_u32. + (muldi3): Likewise. + +2025-07-14 Richard Biener + + PR tree-optimization/121059 + * tree-vect-stmts.cc (vectorizable_operation): Record a + loop mask for mask AND operations. + +2025-07-14 Pan Li + + * match.pd: Make sure widen mul has twice bitsize + of the inputs in SAT_MUL pattern. + +2025-07-14 Uros Bizjak + + PR target/121015 + * config/i386/i386-features.cc (ix86_broadcast_inner): Check all + 0s/1s vectors with standard_sse_constant_p. + +2025-07-14 H.J. Lu + + PR target/120881 + * config.in: Regenerated. + * configure: Likewise. + * configure.ac: Add --enable-x86-64-mfentry. + * config/i386/i386-options.cc (ix86_option_override_internal): + Enable __fentry__ in 64-bit mode if ENABLE_X86_64_MFENTRY is set + to 1. Warn -pg without -mfentry with shrink wrapping enabled. + * doc/install.texi: Document --enable-x86-64-mfentry. + +2025-07-14 François-Xavier Coudert + + PR target/120645 + * config/darwin-driver.cc: Account for latest macOS numbering + scheme. + +2025-07-14 Paul-Antoine Arras + + PR target/119100 + * config/riscv/autovec-opt.md (*vfwmacc_vf_): New pattern to + handle both vfwmacc and vfwmsac. + (*extend_vf_): New pattern that serves as an intermediate combine + step. + * config/riscv/vector-iterators.md (vsubel): New mode attribute. This is + just the lower-case version of VSUBEL. + * config/riscv/vector.md (@pred_widen_mul__scalar): Reorder + and swap operands to match the RTL emitted by expand, i.e. first + float_extend then vec_duplicate. + +2025-07-14 Alfie Richards + + * config/aarch64/aarch64-sme.md (@aarch64_sme_): + New patterns. + * config/aarch64/aarch64-sve-builtins-sme.def (svamin): New intrinsics. + (svamax): New intrinsics. + * config/aarch64/aarch64-sve-builtins-sve2.cc (class faminmaximpl): New + class. + (svamin): New function. + (svamax): New function. + +2025-07-14 Haochen Jiang + + * config/i386/i386.h (PTA_PANTHERLAKE): Revmoe KL and WIDEKL. + (PTA_CLEARWATERFOREST): Ditto. + * doc/invoke.texi: Revise documentation. + +2025-07-13 Andrew Pinski + + PR middle-end/120866 + * tree.cc: Add include to tm_p.h. + +2025-07-13 Benjamin Wu + + * gimple.h (GTMA_DOES_GO_IRREVOCABLE): Fix typo. + +2025-07-12 Jan Hubicka + + * auto-profile.cc (function_instance::~function_instance): + Move down in source. + (string_table::get_cgraph_node): New member function with + logic broken out from ... + (function_instance::get_cgraph_node): ... here. + (match_with_target): Fix formating. + (function_instance::match): Fix formating; do not use iterators + after modifying map; remove incorrect set of warned flag. + (autofdo_source_profile::offline_external_functions): Keep + seen set up to date. + (function_instance::read_function_instance): Fix formating. + +2025-07-12 Uros Bizjak + + * config/i386/mmx.md (mov): + Use nonimm_or_0_operand predicate for operand 1. + (*mov_internal): Ditto. + (movv2qi): Ditto. + (*movv2qi_internal): Ditto. Use ix86_hardreg_mov_ok + in insn condition. + +2025-07-12 Xi Ruoyao + + PR rtl-optimization/120983 + * lra-constraints.cc (process_alt_operands): Allow reloading + user hard registers unless the insn is an asm. + +2025-07-11 David Malcolm + + * diagnostic-format-html.cc: Include "diagnostic-format-sarif.h", + Replace include of "diagnostic-state.h" with includes of + "diagnostic-digraphs.h" and "diagnostic-state-graphs.h". + (html_generation_options::html_generation_options): Update for + field renaming. + (html_builder::m_body_element): New field. + (html_builder::html_builder): Initialize m_body_element. + (html_builder::maybe_make_state_diagram): Port from XML + implementation to state graph implementation. + (html_builder::make_element_for_diagnostic): Add any + per-diagnostic graphs. + (html_builder::add_graph): New. + (html_builder::emit_global_graph): New. + (html_output_format::report_global_digraph): New. + * diagnostic-format-html.h + (html_generation_options::m_show_state_diagram_xml): Replace + with... + (html_generation_options::m_show_state_diagrams_sarif): ...this. + (html_generation_options::m_show_state_diagram_dot_src): Rename + to... + (html_generation_options::m_show_state_diagrams_dot_src): ...this. + * diagnostic-format-sarif.cc: Include "diagnostic-digraphs.h" and + "diagnostic-state-graphs.h". + (sarif_builder::m_run_graphs): New field. + (sarif_result::on_nested_diagnostic): Update call to + make_location_object to pass arg by pointer. + (sarif_builder::sarif_builder): Initialize m_run_graphs. + (sarif_builder::report_global_digraph): New. + (sarif_builder::make_result_object): Add any graphs to + the result object. + (sarif_builder::make_locations_arr): Update call to + make_location_object to pass arg by pointer. + (sarif_builder::make_location_object): Pass param "loc_mgr" by + pointer rather than by reference so that it can be null, and + handle this case. + (copy_any_property_bag): New. + (make_sarif_graph): New. + (make_sarif_node): New. + (make_sarif_edge): New. + (sarif_property_bag::set_graph): New. + (populate_thread_flow_location_object): Port from XML + implementation to state graph implementation. + (make_run_object): Store any graphs. + (sarif_output_format::report_global_digraph): New. + (sarif_generation_options::sarif_generation_options): Rename + m_xml_state to m_state_graph. + (selftest::test_make_location_object): Update for change to + make_location_object. + * diagnostic-format-sarif.h: + (sarif_generation_options::m_xml_state): Replace with... + (sarif_generation_options::m_state_graph): ...this. + (class sarif_location_manager): Add forward decl. + (diagnostics::digraphs::digraph): New forward decl. + (diagnostics::digraphs::node): New forward decl. + (diagnostics::digraphs::edge): New forward decl. + (sarif_property_bag::set_graph): New decl. + (class sarif_graph): New. + (class sarif_node): New. + (class sarif_edge): New. + (make_sarif_graph): New decl. + (make_sarif_node): New decl. + (make_sarif_edge): New decl. + * diagnostic-format-text.h + (diagnostic_text_output_format::report_global_digraph): New. + * diagnostic-format.h + (diagnostic_output_format::report_global_digraph): New vfunc. + * diagnostic-digraphs.cc: New file. + * diagnostic-digraphs.h: New file. + * diagnostic-metadata.h (diagnostics::digraphs::lazy_digraphs): + New forward decl. + (diagnostic_metadata::diagnostic_metadata): Initialize + m_lazy_digraphs. + (diagnostic_metadata::set_lazy_digraphs): New. + (diagnostic_metadata::get_lazy_digraphs): New. + (diagnostic_metadata::m_lazy_digraphs): New field. + * diagnostic-output-spec.cc (sarif_scheme_handler::make_sink): + Update for XML to state graph changes. + (sarif_scheme_handler::make_sarif_gen_opts): Likewise. + (html_scheme_handler::make_sink): Rename "show-state-diagram-xml" + to "show-state-diagrams-sarif" and use pluralization consistently. + * diagnostic-path.cc: Replace include of "xml.h" with + "diagnostic-state-graphs.h". + (diagnostic_event::maybe_make_xml_state): Replace with... + (diagnostic_event::maybe_make_diagnostic_state_graph): ...this. + * diagnostic-path.h (diagnostics::digraphs::digraph): New forward + decl. + (diagnostic_event::maybe_make_xml_state): Replace with... + (diagnostic_event::maybe_make_diagnostic_state_graph): ...this. + * diagnostic-state-graphs.cc: New file. + * diagnostic-state-graphs.h: New file. + * diagnostic-state-to-dot.cc: Port implementation from XML to + state graphs. + * diagnostic-state.h: Deleted file. + * diagnostic.cc (diagnostic_context::report_global_digraph): New. + * diagnostic.h (diagnostics::digraphs::lazy_digraph): New forward + decl. + (diagnostic_context::report_global_digraph): New decl. + * doc/analyzer.texi (Debugging the Analyzer): Update to reflect + change from XML to state graphs. + * doc/invoke.texi ("sarif" diagnostics sink): Replace "xml-state" + with "state-graphs". + ("experimental-html" diagnostics sink): Replace + "show-state-diagrams-xml" with "show-state-diagrams-sarif" + * doc/libgdiagnostics/topics/compatibility.rst + (LIBGDIAGNOSTICS_ABI_3): New. + * doc/libgdiagnostics/topics/graphs.rst: New file. + * doc/libgdiagnostics/topics/index.rst: Add graphs.rst. + * graphviz.h (node_id::operator=): New. + * json.h (json::value::dyn_cast_string): New. + (json::object::get_num_keys): New accessor. + (json::object::get_key): New accessor. + (json::string::dyn_cast_string): New. + * libgdiagnostics++.h (class libgdiagnostics::graph): New. + (class libgdiagnostics::node): New. + (class libgdiagnostics::edge): New. + (class libgdiagnostics::diagnostic::take_graph): New. + (class libgdiagnostics::manager::take_global_graph): New. + (class libgdiagnostics::graph::set_description): New. + (class libgdiagnostics::graph::get_node_by_id): New. + (class libgdiagnostics::graph::get_edge_by_id): New. + (class libgdiagnostics::graph::add_edge): New. + (class libgdiagnostics::node::set_label): New. + (class libgdiagnostics::node::set_location): New. + (class libgdiagnostics::node::set_logical_location): New. + * libgdiagnostics-private.h: New file. + * libgdiagnostics.cc: Define INCLUDE_STRING. Include + "diagnostic-digraphs.h", "diagnostic-state-graphs.h", and + "libgdiagnostics-private.h". + (struct diagnostic_graph): New. + (struct diagnostic_node): New. + (struct diagnostic_edge): New. + (libgdiagnostics_path_event::libgdiagnostics_path_event): Add + state_graph param. + (libgdiagnostics_path_event::maybe_make_diagnostic_state_graph): + New. + (libgdiagnostics_path_event::m_state_graph): New field. + (diagnostic_execution_path::add_event_va): Add state_graph param. + (class prebuilt_digraphs): New. + (diagnostic::diagnostic): Use m_graphs in m_metadata. + (diagnostic::take_graph): New. + (diagnostic::get_graphs): New accessor. + (diagnostic::m_graphs): New field. + (diagnostic_manager::take_global_graph): New. + (diagnostic_execution_path_add_event): Update for new param to + add_event_va. + (diagnostic_execution_path_add_event_va): Likewise. + (diagnostic_graph::add_node_with_id): New public entrypoint. + (diagnostic_graph::add_edge_with_label): New public entrypoint. + (diagnostic_manager_new_graph): New public entrypoint. + (diagnostic_manager_take_global_graph): New public entrypoint. + (diagnostic_take_graph): New public entrypoint. + (diagnostic_graph_release): New public entrypoint. + (diagnostic_graph_set_description): New public entrypoint. + (diagnostic_graph_add_node): New public entrypoint. + (diagnostic_graph_add_edge): New public entrypoint. + (diagnostic_graph_get_node_by_id): New public entrypoint. + (diagnostic_graph_get_edge_by_id): New public entrypoint. + (diagnostic_node_set_location): New public entrypoint. + (diagnostic_node_set_label): New public entrypoint. + (diagnostic_node_set_logical_location): New public entrypoint. + (private_diagnostic_execution_path_add_event_2): New private + entrypoint. + (private_diagnostic_graph_set_property_bag): New private + entrypoint. + (private_diagnostic_node_set_property_bag): New private + entrypoint. + (private_diagnostic_edge_set_property_bag): New private + entrypoint. + * libgdiagnostics.h (diagnostic_graph): New typedef. + (diagnostic_node): New typedef. + (diagnostic_edge): New typedef. + (diagnostic_manager_new_graph): New decl. + (diagnostic_manager_take_global_graph): New decl. + (diagnostic_take_graph): New decl. + (diagnostic_graph_release): New decl. + (diagnostic_graph_set_description): New decl. + (diagnostic_graph_add_node): New decl. + (diagnostic_graph_add_edge): New decl. + (diagnostic_graph_get_node_by_id): New decl. + (diagnostic_graph_get_edge_by_id): New decl. + (diagnostic_node_set_label): New decl. + (diagnostic_node_set_location): New decl. + (diagnostic_node_set_logical_location): New decl. + * libgdiagnostics.map (LIBGDIAGNOSTICS_ABI_3): New. + * libsarifreplay.cc: Include "libgdiagnostics-private.h". + (id_map): New "using". + (sarif_replayer::report_invalid_sarif): Update for change to + report_problem params. + (sarif_replayer::report_unhandled_sarif): Likewise. + (sarif_replayer::report_note): New. + (sarif_replayer::report_problem): Pass param "ref" by + pointer rather than reference and handle it being null. + (sarif_replayer::maybe_get_property_bag): New. + (sarif_replayer::maybe_get_property_bag_value): New. + (sarif_replayer::handle_run_obj): Handle run-level "graphs" as per + §3.14.20. + (sarif_replayer::handle_result_obj): Handle result-level "graphs" + as per §3.27.19. + (handle_thread_flow_location_object): Optionally handle graphs + stored in property "gcc/diagnostic_event/state_graph" as state + graphs. + (sarif_replayer::handle_graph_object): New. + (sarif_replayer::handle_node_object): New. + (sarif_replayer::handle_edge_object): New. + (sarif_replayer::get_graph_node_by_id_property): New. + * selftest-run-tests.cc (selftest::run_tests): Call + selftest::diagnostic_graph_cc_tests and + selftest::diagnostic_state_graph_cc_tests. + * selftest.h (selftest::diagnostic_graph_cc_tests): New decl. + (selftest::diagnostic_state_graph_cc_tests): New decl. + +2025-07-11 David Malcolm + + * Makefile.in (OBJS-libcommon): Add diagnostic-digraphs.o and + diagnostic-state-graphs.o. + +2025-07-11 David Malcolm + + * json.cc (json::object::clone): New. + (json::object::clone_as_object): New. + (json::array::clone): New. + (json::float_number::clone): New. + (json::integer_number::clone): New. + (json::string::clone): New. + (json::literal::clone): New. + (selftest::test_cloning): New test. + (selftest::json_cc_tests): Call it. + * json.h (json::value::clone): New vfunc. + (json::object::clone): New decl. + (json::object::clone_as_object): New decl. + (json::array::clone): New decl. + (json::float_number::clone): New decl. + (json::integer_number::clone): New decl. + (json::string::clone): New decl. + (json::literal::clone): New decl. + +2025-07-11 David Malcolm + + * json.cc (string::string): When constructing from pointer and + length, ensure the new buffer is null-terminated. + (selftest::test_strcmp): New. + (selftest::json_cc_tests): Likewise. + +2025-07-11 David Malcolm + + * doc/libgdiagnostics/topics/compatibility.rst + (_LIBGDIAGNOSTICS_ABI_2): Add missing anchor. + * doc/libgdiagnostics/topics/diagnostic-manager.rst + (diagnostic_manager_add_sink_from_spec): Add links to GCC's + documentation of "-fdiagnostics-add-output=". Fix parameter + markup. + (diagnostic_manager_set_analysis_target): Fix parameter markup. + Add link to SARIF spec. + * doc/libgdiagnostics/topics/logical-locations.rst: Markup fix. + * doc/libgdiagnostics/tutorial/02-physical-locations.rst: Clarify + wording of what "the source file" means, and that a range can't + have multiple files. + +2025-07-11 Vladimir N. Makarov + + * lra-constraints.cc (process_address_1): When changing base reg + on a reg of the base class, fall back to reload of whole inner address. + (process_address): Constrain the iteration number. + +2025-07-11 Jakub Jelinek + + PR c++/119064 + * doc/invoke.texi (Wc++26-compat): Document. + +2025-07-11 Richard Sandiford + + PR target/121027 + * config/aarch64/aarch64.cc (aarch64_evpc_sve_tbl): Punt on 2-input + operations that can be handled by vec_perm. + +2025-07-11 Kyrylo Tkachov + + * config/aarch64/aarch64-simd.md (*eor3qdi4): New + define_insn_and_split. + +2025-07-11 Kyrylo Tkachov + + * config/aarch64/aarch64-simd.md (*bcaxqdi4): New + define_insn_and_split. + +2025-07-11 Kyrylo Tkachov + + * config/aarch64/aarch64-simd.md (eor3q4): Use VDQ_I mode + iterator. + +2025-07-11 Kyrylo Tkachov + + * config/aarch64/aarch64-simd.md (bcaxq4): Use VDQ_I mode + iterator. + +2025-07-11 Richard Biener + + PR tree-optimization/121034 + * tree-vect-loop.cc (vectorizable_reduction): Cleanup + reduction chain following code. + +2025-07-11 Jan Hubicka + + * opts.cc (finish_options): Enable debug_nonbind_markers_p for + auto-profile. + * tree-cfg.cc (struct locus_discrim_map): Remove. + (struct locus_discrim_hasher): Remove. + (locus_discrim_hasher::hash): Remove. + (locus_discrim_hasher::equal): Remove. + (first_non_label_nondebug_stmt): Remove. + (build_gimple_cfg): Do not allocate discriminator tables. + (next_discriminator_for_locus): Remove. + (same_line_p): Remove. + (struct discrim_entry): New structure. + (assign_discriminator): Rewrite. + (assign_discriminators): Rewrite. + +2025-07-11 Jan Hubicka + + PR ipa/114790 + * cgraph.cc (cgraph_update_edges_for_call_stmt_node): Resolve devirtualization + if call statement was optimized out or turned to direct call. + +2025-07-11 Jakub Jelinek + Martin Jambor + + PR ipa/121023 + * ipa-fnsummary.cc (compute_fn_summary): Disallow signature changes + on cfun->has_musttail functions. + +2025-07-11 Hu, Lin1 + + PR target/91384 + * config/i386/i386.md: Add new peeophole2 for optimize *negsi_1 + followed by *cmpsi_ccno_1 with APX_F. + +2025-07-11 Richard Biener + + * config/i386/i386.cc (ix86_vector_costs::add_stmt_cost): Use + the LHS of a scalar stmt to determine mode and whether it is FP. + +2025-07-10 Richard Sandiford + + * config/aarch64/aarch64.cc (aarch64_vector_costs::add_stmt_cost): + Guard VF-based costing with !m_costing_for_scalar. + +2025-07-10 Qing Zhao + + * internal-fn.cc (expand_ACCESS_WITH_SIZE): Update comments. + * internal-fn.def (ACCESS_WITH_SIZE): Update comments. + * tree-object-size.cc (access_with_size_object_size): Update comments. + Adjust the arguments per the new design. + +2025-07-10 Qing Zhao + + PR middle-end/121000 + * internal-fn.cc (expand_ACCESS_WITH_SIZE): Update comments. + * internal-fn.def (ACCESS_WITH_SIZE): Update comments. + * tree-object-size.cc (access_with_size_object_size): Update comments. + Get the element_size from the 6th argument directly. + +2025-07-10 Richard Sandiford + + * config/aarch64/aarch64-sve2.md (aarch64_gather_ld1q): Replace with... + (@aarch64_gather_ld1q): ...this, parameterizing based on mode. + * config/aarch64/aarch64-sve-builtins-sve2.cc + (svld1q_gather_impl::expand): Update accordingly. + (svst1q_scatter_impl::expand): Use aarch64_sve_reinterpret + instead of force_lowpart_subreg. + +2025-07-10 Jan Hubicka + + * auto-profile.cc: Include output.h. + (function_instance::set_call_location): Also sanity check + that location is known. + (raw_symbol_name): Two new static functions. + (dump_inline_stack): Use it. + (string_table::get_index_by_decl): Likewise. + (function_instance::get_cgraph_node): Likewise. + (function_instance::get_function_instance_by_decl): Fix typo + in warning; use raw names; fix lineno decoding. + (match_with_target): Add containing funciton parameter; + correctly output function and call location in warning. + (function_instance::lookup_count): Fix warning locations. + (function_instance::match): Fix warning locations; avoid + crash with mismatched callee; do not warn about broken callsites + twice. + (autofdo_source_profile::offline_external_functions): Use + raw_assembler_name. + (walk_block): Use raw_assembler_name. + +2025-07-10 Robin Dapp + + PR target/121014 + * cfgexpand.cc (expand_debug_expr): Assert FLOAT_MODE_P. + * optabs-tree.cc (optab_for_tree_code): Assert FLOAT_TYPE_P. + * tree-vect-loop.cc (vect_get_loop_len): Use EXACT_DIV_EXPR. + +2025-07-10 Robin Dapp + + PR target/118734 + * config/riscv/constraints.md (Wdm): Use tunable for Wdm + constraint. + * config/riscv/riscv-protos.h (emit_avltype_insn): Declare. + (can_be_broadcasted_p): Rename to... + (can_be_broadcast_p): ...this. + * config/riscv/predicates.md: Use renamed function. + (strided_load_broadcast_p): Declare. + * config/riscv/riscv-selftests.cc (run_broadcast_selftests): + Only run broadcast selftest if strided broadcasts are OK. + * config/riscv/riscv-v.cc (emit_avltype_insn): New function. + (sew64_scalar_helper): Only emit a pred_broadcast if the new + tunable says so. + (can_be_broadcasted_p): Rename to... + (can_be_broadcast_p): ...this and use new tunable. + * config/riscv/riscv.cc (struct riscv_tune_param): Add strided + broad tunable. + (strided_load_broadcast_p): Implement. + * config/riscv/vector.md: Use strided_load_broadcast_p () and + work around 64-bit broadcast on rv32 targets. + +2025-07-10 Co-authored-by: Jeff Law + + * config/riscv/riscv.cc (riscv_fusion_pairs): Add new cases. + (riscv_set_is_add): New function. + (riscv_set_is_addi, riscv_set_is_adduw, riscv_set_is_shNadd): Likewise. + (riscv_set_is_shNadduw): Likewise. + (riscv_macro_fusion_pair_p): Add new fusion cases. + +2025-07-10 Richard Biener + + * tree-vect-slp.cc (vect_analyze_slp): Fail for non-canonical + gconds. + +2025-07-10 Richard Biener + + * tree-vect-slp.cc (vect_build_slp_instance): Do not use + SLP_TREE_VECTYPE to determine the conversion back to the + reduction IV. + +2025-07-10 Richard Biener + + * tree-vect-loop.cc (vectorizable_reduction): Avoid + vect_is_simple_use and record a vector type if we come + up with one. + +2025-07-10 Richard Biener + + * tree-vect-stmts.cc (get_load_store_type): Do not use + vect_is_simple_use to fill gather/scatter offset operand + vectype and dt. + +2025-07-10 Richard Biener + + * tree-vect-loop.cc (vect_model_reduction_cost): Get SLP + node instead of stmt_info and use that when recording costs. + +2025-07-10 Kyrylo Tkachov + + PR target/120999 + * config/aarch64/aarch64-sve2.md (*aarch64_sve2_nor): + Adjust movprfx alternative. + +2025-07-10 Richard Sandiford + + * doc/sourcebuild.texi (aarch64_sve2_hw, aarch64_sve2p1_hw): Document. + * config/aarch64/aarch64.cc (aarch64_evpc_hvla): Extend to + BYTES_BIG_ENDIAN. + +2025-07-10 Richard Biener + + * tree-vectorizer.h (vect_analyze_stmt): Remove stmt-info + and need_to_vectorize arguments. + * tree-vect-slp.cc (vect_slp_analyze_node_operations_1): + Adjust. + * tree-vect-stmts.cc (can_vectorize_live_stmts): Remove + stmt_info argument and remove non-SLP path. + (vect_analyze_stmt): Remove stmt_info and need_to_vectorize + argument and prune paths no longer reachable. + (vect_transform_stmt): Adjust. + +2025-07-10 Jakub Jelinek + + * config/i386/x86-tune.def: Change "Tunning the" to "tuning" in + comment and use semicolon instead of dot in comment. + * loop-unroll.cc (decide_unroll_stupid): Comment spelling fix, + tunning -> tuning. + +2025-07-10 Jakub Jelinek + + * tree-vect-loop.cc (scale_profile_for_vect_loop): Comment + spelling fix: bellow -> below. + * ipa-polymorphic-call.cc (record_known_type): Likewise. + * config/i386/x86-tune.def: Likewise. + * config/riscv/vector.md (*vsetvldi_no_side_effects_si_extend): + Likewise. + * tree-scalar-evolution.cc (iv_can_overflow_p): Likewise. + * ipa-devirt.cc (add_type_duplicate): Likewise. + * tree-ssa-loop-niter.cc (maybe_lower_iteration_bound): Likewise. + * gimple-ssa-sccopy.cc: Likewise. + * cgraphunit.cc: Likewise. + * graphite.h (struct poly_dr): Likewise. + * ipa-reference.cc (ignore_edge_p): Likewise. + * tree-ssa-alias.cc (ao_compare::compare_ao_refs): Likewise. + * profile-count.h (profile_probability::probably_reliable_p): + Likewise. + * ipa-inline-transform.cc (inline_call): Likewise. + +2025-07-10 Richard Biener + + * tree-vect-loop.cc (vect_dissolve_slp_only_groups): Remove. + (vect_analyze_loop_2): Do not call it. + +2025-07-10 Richard Biener + + * tree-vect-loop.cc (vect_active_double_reduction_p): Remove. + (vect_analyze_loop_operations): Remove. + (vect_analyze_loop_2): Do not call it. + +2025-07-10 Richard Biener + + * tree-vect-loop.cc (vect_determine_vf_for_stmt_1): Rename + to ... + (vect_determine_vectype_for_stmt_1): ... this and only set + STMT_VINFO_VECTYPE. Fail for single-element vector types. + (vect_determine_vf_for_stmt): Rename to ... + (vect_determine_vectype_for_stmt): ... this and only set + STMT_VINFO_VECTYPE. Fail for single-element vector types. + (vect_determine_vectorization_factor): Rename to ... + (vect_set_stmts_vectype): ... this and only set STMT_VINFO_VECTYPE. + (vect_update_vf_for_slp): Remove. + (vect_analyze_loop_operations): Remove walk over stmts. + (vect_analyze_loop_2): Call vect_set_stmts_vectype instead of + vect_determine_vectorization_factor. Set vectorization factor + from LOOP_VINFO_SLP_UNROLLING_FACTOR. Fail if vect_detect_hybrid_slp + detects hybrid stmts or when vect_make_slp_decision finds + nothing to SLP. + * tree-vect-slp.cc (vect_detect_hybrid_slp): Move check + whether we have any hybrid stmts here from vect_update_vf_for_slp + * tree-vect-stmts.cc (vect_analyze_stmt): Remove loop over + stmts. + * tree-vectorizer.h (vect_detect_hybrid_slp): Update. + +2025-07-09 Richard Sandiford + + * config/aarch64/aarch64.cc (aarch64_simd_valid_imm): Account + for FLOAT_WORDS_BIG_ENDIAN when building a floating-point value. + +2025-07-09 Jan Hubicka + + * auto-profile.cc (afdo_adjust_guessed_profile): Add forgotten + if (dump_file) guard. + +2025-07-09 Richard Sandiford + + * config/aarch64/aarch64.cc (aarch64_sve_index_series_p): New + function, split out from... + (aarch64_simd_valid_imm): ...here. Account for the different + SVE and Advanced SIMD element orders on big-endian targets. + Check each vector in a structure mode. + +2025-07-09 Richard Sandiford + + * read-rtl-function.cc (function_reader::read_rtx_operand_r): Use + hard_regno_nregs to work out REG_NREGS for hard registers. + +2025-07-09 Pan Li + + * config/riscv/riscv-v.cc (expand_vx_binary_vec_vec_dup): Add + new case SS_MINUS. + * config/riscv/riscv.cc (riscv_rtx_costs): Ditto. + * config/riscv/vector-iterators.md: Add new op ss_minus. + +2025-07-09 Richard Sandiford + + * ext-dce.cc (ext_dce_process_uses): Apply is_constant directly + to the subreg_lsb. + +2025-07-09 Jan Dubiec + + PR target/109286 + * config.gcc: Include elfos.h before h8300/h8300.h. + * config/h8300/h8300.h (INIT_SECTION_ASM_OP): Override + default version from elfos.h. + (FINI_SECTION_ASM_OP): Ditto. + (ASM_DECLARE_FUNCTION_NAME): Ditto. + (ASM_GENERATE_INTERNAL_LABEL): Macro removed because it was + being overridden in elfos.h anyway. + (ASM_OUTPUT_SKIP): Ditto. + +2025-07-09 Icen Zeyada + + PR tree-optimization/119196 + * match.pd: Allow scalar optimizations with bitwise AND/OR/XOR to apply to vectors. + +2025-07-09 Icen Zeyada + + PR tree-optimization/119196 + * match.pd: Merge multiple vec_cond_expr in a single one for + bit_and, bit_ior and bit_xor. + +2025-07-09 Jeff Law + + PR target/120642 + * config/riscv/riscv-avlprop.cc (pass_avlprop::execute): Do not do + constant AVL propagation for xtheadvector. + +2025-07-09 Richard Biener + + * tree-vect-loop.cc (vectorizable_reduction): Get the + output vector type from slp_for_stmt_info. + * tree-vect-stmts.cc (vect_analyze_stmt): Bail out earlier + for PURE_SLP_STMT when doing loop stmt analysis. + +2025-07-09 Jan Hubicka + + * auto-profile.cc (struct scale): New structure. + (add_scale): Also record weights. + (afdo_adjust_guessed_profile): Compute robust average + of scales and cap by max count in function. + +2025-07-09 Jan Hubicka + + * tree-inline.cc (initialize_cfun): Use num and den for scaling. + +2025-07-09 Jan Hubicka + + * auto-profile.cc (get_original_name): Fix loop walking the + suffixes. + +2025-07-09 Christophe Lyon + + * config/arm/arm_neon.h: Remove useless push/pop pragmas. + +2025-07-09 Tamar Christina + + PR tree-optimization/120922 + * tree-vect-loop-manip.cc (vect_gen_vector_loop_niters): Support range + for partial vectors. + +2025-07-09 Tamar Christina + + PR tree-optimization/120922 + * tree-vect-loop-manip.cc (vect_gen_vector_loop_niters): Don't set range + for partial vectors. + +2025-07-08 Takayuki 'January June' Suwa + + * config/xtensa/xtensa.cc (xtensa_b4const_or_zero): + Remove. + (xtensa_b4const): Add a case where the value is 0, and rename + to xtensa_b4const_or_zero. + (xtensa_rtx_costs): Fix to also consider the result of + xtensa_b4constu(). + +2025-07-08 Stefan Schulze Frielinghaus + + * config/s390/s390.md (stack_protect_get_tpsi): New insn. + (stack_protect_get_tpdi): New insn. + (stack_protect_set): Use new insn. + (stack_protect_test): Use new insn. + +2025-07-08 Robin Dapp + + PR target/120461 + * config/riscv/riscv-v.cc (emit_vlmax_insn_lra): Do not emit + vsetivli for XTHeadVector. + +2025-07-08 Robin Dapp + + PR target/113829 + * config/riscv/riscv-vector-builtins.cc (registered_function::overloaded_hash): + Skip non-type arguments. + +2025-07-08 Andreas Schwab + + PR target/120995 + * config/riscv/sync.md (zacas_atomic_cas_value_strong): + Allow op3 to be zero. + +2025-07-08 Richard Biener + + * config/i386/x86-tune.def (X86_TUNE_AVX512_MASKED_EPILOGUES): + New tunable, default on for m_ZNVER4 and m_ZNVER5. + * config/i386/i386.cc (ix86_vector_costs::finish_cost): With + X86_TUNE_AVX512_MASKED_EPILOGUES and when the main loop + had a vectorization factor > 2 use a masked epilogue when + possible and when not obviously problematic. + +2025-07-08 Richard Biener + + * tree-vectorizer.h (vector_costs::suggested_epilogue_mode): + Add masked output parameter and return m_masked_epilogue. + (vector_costs::m_masked_epilogue): New tristate flag. + (vector_costs::vector_costs): Initialize m_masked_epilogue. + * tree-vect-loop.cc (vect_analyze_loop_1): Pass in masked + flag to optionally initialize can_use_partial_vectors_p. + (vect_analyze_loop): For epilogues also get whether to use + a masked epilogue for this loop from the target and use + that for the first epilogue mode we try. + +2025-07-08 Richard Biener + + PR tree-optimization/120358 + * tree-ssa-structalias.cc (get_constraint_for_1): Adjust + pruning of sub-variables according to the imprecise + known start offset. + +2025-07-08 Alexandre Oliva + + * config/vxworks-dummy.h (TARGET_VXWORKS_VAROFF): New. + (TARGET_VXWORKS_GOTTPIC): New. + * config/vxworks.h (TARGET_VXWORKS_VAROFF): Override. + (TARGET_VXWORKS_GOTTPIC): Likewise. + * config/i386/i386.cc (output_set_got): Disable VxWorks6 GOT + sequence on VxWorks7. + (legitimize_pic_address): Accept relative addressing of + labels on VxWorks7. + (ix86_delegitimize_address_1): Likewise. + (ix86_output_addr_diff_elt): Likewise. + * config/i386/i386.md (tablejump): Likewise. + (set_got, set_got_labelled): Set no-red-zone flag on VxWorks7. + * config/i386/predicates.md (gotoff_operand): Test + TARGET_VXWORKS_VAROFF. + +2025-07-08 Alexandre Oliva + + * config.gcc (vxworks-dummy.h): Add to aarch64-*-* as well. + +2025-07-07 Qing Zhao + + Revert: + 2025-07-07 Qing Zhao + + * doc/extend.texi: Extend counted_by attribute to pointer fields in + structures. Add one more requirement to pointers with counted_by + attribute. + +2025-07-07 Qing Zhao + + Revert: + 2025-07-01 Qing Zhao + + * tree-object-size.cc (access_with_size_object_size): Update comments + for pointers with .ACCESS_WITH_SIZE. + (collect_object_sizes_for): Propagate size info through GIMPLE_ASSIGN + for pointers with .ACCESS_WITH_SIZE. + +2025-07-07 Martin Jambor + + * value-range.h (class irange): Mark member function verify_range + with override. + (class prange): Mark member function verify_range with final override. + (class frange): Mark member function verify_range with override. + +2025-07-07 H.J. Lu + + PR target/120888 + * config/xtensa/xtensa.cc (xtensa_promote_function_mode): New. + (TARGET_PROMOTE_FUNCTION_MODE): Use. + (TARGET_PROMOTE_PROTOTYPES): Removed. + +2025-07-07 Juergen Christ + + * config/s390/s390.md: Update UNSPECs + * config/s390/vector.md (fmax3): New expander. + (fmin3): New expander. + * config/s390/vx-builtins.md (*fmin): New insn. + (vfmin): Redefined to use new insn. + (*fmax): New insn. + (vfmax): Redefined to use new insn. + +2025-07-07 Jason Merrill + + PR c++/120917 + * doc/invoke.texi: Add -Wno-abbreviated-auto-in-template-arg. + +2025-07-07 Kyrylo Tkachov + + * config/aarch64/aarch64.md (popcountti2): Add TARGET_SVE path. + +2025-07-07 Richard Biener + + PR tree-optimization/120817 + * tree-ssa-dse.cc (initialize_ao_ref_for_dse): Use + ao_ref_init_from_ptr_and_range with unknown size for + .MASK_STORE and .MASK_LEN_STORE. + +2025-07-07 Pan Li + + * config/riscv/riscv-protos.h (riscv_expand_usmul): Add new func + decl. + * config/riscv/riscv.cc (riscv_expand_xmode_usmul): Add new func + to expand Xmode SAT_MUL. + (riscv_expand_non_xmode_usmul): Ditto but for non-Xmode. + (riscv_expand_usmul): Add new func to implment SAT_MUL. + * config/riscv/riscv.md (usmul3): Add new pattern to match + standard name usmul. + +2025-07-07 Pan Li + + * match.pd: Add new match pattern for unsigned SAT_MUL. + * tree-ssa-math-opts.cc (gimple_unsigned_integer_sat_mul): + new decl for pattern match func. + (match_unsigned_saturation_mul): Add new func to match unsigned + SAT_MUL. + (math_opts_dom_walker::after_dom_children): Try to match + unsigned SAT_MUL on NOP. + +2025-07-07 Pan Li + + * internal-fn.cc (commutative_binary_fn_p): Add new case + for SAT_MUL. + * internal-fn.def (SAT_MUL): Add new IFN_SAT_MUL. + * optabs.def (OPTAB_NL): Remove fixed point limitation. + +2025-07-07 Juergen Christ + + * config/s390/s390.md: Removed unused unspecs. + * config/s390/vector.md (avg3_ceil): New expander. + (uavg3_ceil): New expander. + (smul3_highpart): New expander. + (umul3_highpart): New expander. + * config/s390/vx-builtins.md (vec_umulh): Remove unspec. + (vec_smulh): Remove unspec. + +2025-07-07 Spencer Abson + + * config/aarch64/aarch64-sve.md (vec_cmp): Extend + to handle partial FP modes. + (@aarch64_pred_fcm): Likewise. + (@aarch64_pred_fcmuo): Likewise. + (*one_cmpl3): Rename to... + (@aarch64_pred_one_cmpl_z): ... this. + * config/aarch64/aarch64.cc (aarch64_emit_sve_fp_cond): Allow the + target and governing predicates to have different modes. + (aarch64_emit_sve_or_fp_conds): Likewise. + (aarch64_emit_sve_invert_fp_cond): Likewise. + (aarch64_expand_sve_vec_cmp_float): Likewise. + +2025-07-07 Richard Sandiford + + PR tree-optimization/118891 + * tree-vect-stmts.cc (supportable_widening_operation): Swap the + hi and lo internal functions on big-endian targets. + +2025-07-07 Richard Sandiford + + * ext-dce.cc (ext_dce_process_uses): Apply is_constant directly + to the subreg_lsb. + +2025-07-07 Richard Sandiford + + * config/aarch64/aarch64-sve.md (@aarch64_sve_set_neonq_): + Use %Z instead of lowpart_subreg. Tweak formatting. + +2025-07-07 Richard Sandiford + + PR target/118891 + * config/aarch64/aarch64.cc (aarch64_expand_vector_init): Fix the + ZIP1 operand order for big-endian targets. + +2025-07-07 Jan Hubicka + + * tree-ssa-live.cc (dump_scope_block): Print discriminators + of inlined functions. + +2025-07-07 H.J. Lu + + PR target/120670 + PR target/120683 + * config/i386/i386-expand.cc (expand_set_or_cpymem_via_loop): + Don't generate the loop if the loop count is 1. + (expand_cpymem_epilogue): Use move_by_pieces. + (setmem_epilogue_gen_val): New. + (expand_setmem_epilogue): Use store_by_pieces. + (expand_small_cpymem_or_setmem): Choose cpymem mode from MOVE_MAX. + For memset with vector and the size is smaller than the vector + size, first try the narrower vector, otherwise, use the scalar + value. + (promote_duplicated_reg): Duplicate the scalar value for vector. + (ix86_expand_set_or_cpymem): Always expand vector-version of + memset for vector_loop. Use misaligned prologue if alignment + isn't needed and destination isn't aligned. Always initialize + vec_promoted_val from the promoted scalar value for vector_loop. + +2025-07-07 Andrew Pinski + + PR middle-end/120709 + * builtins.cc (expand_builtin_crc_table_based): Error out + instead of asserting the 3rd argument is an integer constant. + * internal-fn.cc (expand_crc_optab_fn): Likewise. + * doc/extend.texi (crc): Document requirement of the poly argument + being a constant. + +2025-07-06 Georg-Johann Lay + + * config/avr/avr-mcus.def: -mmcu= takes lower case MCU names. + * doc/avr-mmcu.texi: Rebuild. + +2025-07-06 Georg-Johann Lay + + * config/avr/avr-mcus.def (avr32da28S, avr32da32S, avr32da48S) + (avr64da28S, avr64da32S, avr64da48S avr64da64S) + (avr128da28S, avr128da32S, avr128da48S, avr128da64S): Add devices. + * doc/avr-mmcu.texi: Rebuild. + +2025-07-06 Andrew Pinski + + PR tree-optimization/120951 + * tree-call-cdce.cc (use_internal_fn): For non-call exceptions + with EQ_EXPR can throw for floating point types, then create + the EQ_EXPR seperately. + +2025-07-06 Andrew Pinski + + PR middle-end/120921 + * tree-cfg.cc (verify_gimple_assign_single): Reject constant and address expression LHS. + For non-empty vector constructors, make sure the LHS is an is_gimple_reg. + +2025-07-06 Jan Hubicka + + * auto-profile.cc + (autofdo_source_profile::read): Scale cutoff. + (read_autofdo_file): Initialize cutoff + * coverage.cc (read_counts_file): Initialize cutoff to 1. + * gcov-io.h (struct gcov_summary): Add cutoff field. + * ipa-inline.cc (inline_small_functions): mac_count can be non-zero + also with auto_profile. + * lto-cgraph.cc (output_profile_summary): Write cutoff + and sum_max. + (input_profile_summary): Read cutoff and sum max. + (merge_profile_summaries): Initialize and scale global cutoffs + and sum max. + * profile-count.cc: Include profile.h + (profile_count::force_nonzero): move here from ...; use cutoff. + * profile-count.h: (profile_count::force_nonzero): ... here. + +2025-07-06 Jan Hubicka + + * profile-count.cc (profile_count::operator*): fix overflow check. + +2025-07-05 Alexandre Oliva + + * config/rs6000/vxworks.h (SUBTARGET_DRIVER_SELF_SPECS): + Redefine to select word size matching TARGET_VXWORKS64. + (TARGET_VXWORKS64): Redefine in terms of TARGET_64BIT. + +2025-07-04 Vineet Gupta + + PR target/118241 + * config/riscv/riscv.md (prefetch): Add alternative "r". + +2025-07-04 Vineet Gupta + + * config/riscv/predicates.md (prefetch_operand): mack 5 bits. + +2025-07-04 Raphael Moreira Zinsly + + * config/sh/predicates.md + (treg_set_expr_not_const01): call sh_recog_treg_set_expr_not_01 + * config/sh/sh-protos.h + (sh_recog_treg_set_expr_not_01): New function + * config/sh/sh.cc (sh_recog_treg_set_expr_not_01): Likewise + +2025-07-04 Andrew Pinski + + PR c/118948 + * fold-const.cc (tree_expr_nonnegative_warnv_p): Use + error_operand_p instead of checking for error_mark_node directly. + +2025-07-04 Pan Li + + * config/riscv/riscv-v.cc (expand_vx_binary_vec_dup_vec): Add + new case SS_PLUS. + (expand_vx_binary_vec_vec_dup): Ditto. + * config/riscv/riscv.cc (riscv_rtx_costs): Ditto. + * config/riscv/vector-iterators.md: Add new op ss_plus. + +2025-07-04 Richard Biener + + PR tree-optimization/120944 + * tree-ssa-sccvn.cc (vn_reference_lookup_3): Gate optimizations + invalid when volatile is involved. + +2025-07-04 Jan Hubicka + + * common.opt: Add period. + * common.opt.urls: Regenerate. + +2025-07-04 Richard Biener + + PR tree-optimization/120927 + * tree-vect-data-refs.cc (vect_compute_data_ref_alignment): + Do not force a DRs base alignment when analyzing an + epilog loop. Check whether the step preserves alignment + for all VFs possibly involved sofar. + +2025-07-04 Xi Ruoyao + + * config/loongarch/loongarch.md (crc_combine): Avoid nested + subreg. + +2025-07-04 Shreya Munnangi + + * config/riscv/riscv.cc (riscv_macro_fusion_pair_p): Add basic + instrumentation to all cases where fusion is detected. Fix + minor formatting goofs found in the process. + +2025-07-04 panciyan + + * match.pd: Add signed scalar SAT_ADD IMM form2 matching. + +2025-07-03 Juergen Christ + + * config/s390/s390.cc (expand_perm_with_merge): Add size change cases. + (expand_perm_with_pack): New function. + (vectorize_vec_perm_const_1): Wire up new function. + +2025-07-03 Co-authored-by: Daniel Barboza + Co-authored-by: Shreya Munnangi + + PR target/118886 + * config/riscv/riscv.cc (riscv_macro_fusion_pair_p): Check + for fusion being disabled earlier. If PREV is already fused, + then it can't be fused again. Be more selective about fusing + when the destination registers do not match. Don't fuse into + loads that aren't scalar integer modes. Revamp store pair + commit support. + +2025-07-03 Karl Meakin + + * config/aarch64/aarch64.md (aarch64_cbz1): Move + above rules for CBB/CBH/CB. + (*aarch64_tbz1): Likewise. + +2025-07-03 Karl Meakin + + * config/aarch64/aarch64-protos.h (aarch64_cb_rhs): New function. + * config/aarch64/aarch64.cc (aarch64_cb_rhs): Likewise. + * config/aarch64/aarch64.md (cbranch4): Rename to ... + (cbranch4): ...here, and emit CMPBR if possible. + (cbranch4): New expand rule. + (aarch64_cb): New insn rule. + (aarch64_cb): Likewise. + * config/aarch64/constraints.md (Uc0): New constraint. + (Uc1): Likewise. + (Uc2): Likewise. + * config/aarch64/iterators.md (cmpbr_suffix): New mode attr. + (INT_CMP): New code iterator. + (cmpbr_imm_constraint): New code attr. + +2025-07-03 Karl Meakin + + * config/aarch64/aarch64-option-extensions.def (cmpbr): New + option. + * config/aarch64/aarch64.h (TARGET_CMPBR): New macro. + * doc/invoke.texi (cmpbr): New option. + +2025-07-03 Karl Meakin + + * config/aarch64/aarch64.md (far_branch): Replace 0/1 with + no/yes. + (aarch64_bcond): Handle rename. + (aarch64_cbz1): Likewise. + (*aarch64_tbz1): Likewise. + (@aarch64_tbz): Likewise. + +2025-07-03 Karl Meakin + + * config/aarch64/aarch64.md (BRANCH_LEN_P_1MiB): New constant. + (BRANCH_LEN_N_1MiB): Likewise. + (BRANCH_LEN_P_32KiB): Likewise. + (BRANCH_LEN_N_32KiB): Likewise. + +2025-07-03 Karl Meakin + + * config/aarch64/aarch64.md (condjump): Rename to ... + (aarch64_bcond): ...here. + (*compare_condjump): Rename to ... + (*aarch64_bcond_wide_imm): ...here. + (aarch64_cb): Rename to ... + (aarch64_cbz1): ...here. + (*cb1): Rename to ... + (*aarch64_tbz1): ...here. + (@aarch64_tb): Rename to ... + (@aarch64_tbz): ...here. + (restore_stack_nonlocal): Handle rename. + (stack_protect_combined_test): Likewise. + * config/aarch64/aarch64-simd.md (cbranch4): Likewise. + * config/aarch64/aarch64-sme.md (aarch64_restore_za): Likewise. + * config/aarch64/aarch64.cc (aarch64_gen_test_and_branch): Likewise. + +2025-07-03 Karl Meakin + + * config/aarch64/aarch64.md (cbranch4): Reformat. + (cbranchcc4): Likewise. + (condjump): Likewise. + (*compare_condjump): Likewise. + (aarch64_cb1): Likewise. + (*cb1): Likewise. + (tbranch_3): Likewise. + (@aarch64_tb): Likewise. + +2025-07-03 Karl Meakin + + * config/aarch64/aarch64.md (condjump): Move. + (*compare_condjump): Likewise. + (aarch64_cb1): Likewise. + (*cb1): Likewise. + (tbranch_3): Likewise. + (@aarch64_tb): Likewise. + +2025-07-03 Siddhesh Poyarekar + + PR tree-optimization/120780 + * tree-object-size.cc (inner_at_offset, + get_wholesize_for_memref): New functions. + (addr_object_size): Call get_wholesize_for_memref. + +2025-07-03 H.J. Lu + + PR target/120936 + * config/i386/i386.cc (x86_print_call_or_nop): Add a label + argument and use it to print label. + (x86_function_profiler): Emit label only when __mcount_loc + section is used. + +2025-07-03 Jan Hubicka + + * auto-profile.cc (get_combined_location): Handle negative + offsets; output better diagnostics. + (get_relative_location_for_locus): Reutrn -1 for unknown location. + (function_instance::get_cgraph_node): New member function. + (match_with_target): New function. + (dump_stmt): New function. + (function_instance::lookup_count): New function. + (mark_expr_locations): New function. + (function_instance::match): New function. + (autofdo_source_profile::offline_external_functions): Do + not repeat renaming; manage two worklists and do matching. + (autofdo_source_profile::offline_unrealized_inlines): Simplify. + (afdo_set_bb_count): do not look for lost discriminators. + (auto_profile): Do not ICE when profile reading failed. + * common.opt (Wauto-profile): New warning flag + * doc/invoke.texi (-Wauto-profile): Document. + +2025-07-03 Jan Hubicka + + * ipa-fnsummary.cc (analyze_function_body): For loop + heuristics use header count instead of preheader count. + +2025-07-03 Jan Hubicka + + * ipa-cp.cc (update_profiling_info): Watch for division by zero. + +2025-07-03 Alex Coplan + + * config/aarch64/aarch64-sve.md + (vec_load_lanes): Expand else operand in + subvector mode, as per optab documentation. + (vec_mask_load_lanes): Add missing mode for + operand 3. + * config/aarch64/predicates.md (aarch64_maskload_else_operand): + Remove const_int. + +2025-07-03 Alex Coplan + + * doc/md.texi (Standard Names): Clarify mode of else operand for + vec_mask_load_lanesmn optab. + +2025-07-03 Jan Hubicka + + * ipa-cp.cc (cs_interesting_for_ipcp_p): Handle + correctly GLOBAL0 afdo counts. + (ipcp_cloning_candidate_p): Do not rule out nodes + !node->optimize_for_size_p (). + (good_cloning_opportunity_p): Handle afdo counts + as non-zero. + +2025-07-03 Jan Hubicka + + * ipa-cp.cc (hint_time_bonus): Return sreal and avoid + conversions to integer. + (good_cloning_opportunity_p): Avoid sreal to integer + conversions + (perform_estimation_of_a_value): Update. + +2025-07-03 Jan Hubicka + + * auto-profile.cc (afdo_hot_bb_threshod): New global + variable. + (maybe_hot_afdo_count_p): New function. + (autofdo_source_profile::read): Do not set up dump file; + set afdo_hot_bb_threshod. + (afdo_annotate_cfg): Handle partial training. + (afdo_callsite_hot_enough_for_early_inline): + Use maybe_hot_afdo_count_p. + (auto_profile_offline::execute): Read autofdo file. + * auto-profile.h (maybe_hot_afdo_count_p): Declare. + (afdo_hot_bb_threshold): Declare. + * coverage.cc (read_counts_file): Also set gcov_profile_info. + (coverage_init): Do not read autofdo file. + * opts.cc (enable_fdo_optimizations): Add autofdo parameter; + do not set flag_branch_probabilities and flag_profile_values + with it. + (common_handle_option): Update. + * passes.cc (finish_optimization_passes): Do not end branch + prob here. + (pass_manager::dump_profile_report): Also mark change after + autofdo pass. + * profile.cc: Include auto-profile.h + (gcov_profile_info): New global variable. + (struct afdo_fdo_record): New struture. + (compute_branch_probabilities): Record afdo profile. + (end_branch_prob): Dump afdo/fdo profile comparsion. + * profile.h (gcov_profile_info): Declarre. + * tree-profile.cc (tree_profiling): Call end_branch_prob + (pass_ipa_tree_profile::gate): Also enable with autoFDO + +2025-07-03 Richard Biener + + PR tree-optimization/118669 + * tree-vect-stmts.cc (vectorizable_load): Emit loads + with proper (element) alignment. + (vectorizable_store): Likewise. + +2025-07-03 H.J. Lu + + PR target/120908 + * config/i386/i386.cc (legitimize_tls_address): Pass RDI to + gen_tls_local_dynamic_64. + * config/i386/i386.md (*tls_global_dynamic_64_largepic): Add + RDI clobber and use it to generate LEA. + (*tls_local_dynamic_64_): Likewise. + (*tls_local_dynamic_base_64_largepic): Likewise. + (@tls_local_dynamic_64_): Add a clobber. + +2025-07-02 H.J. Lu + + PR target/120908 + * config/i386/i386.cc (legitimize_tls_address): Pass RDI to + gen_tls_global_dynamic_64. + * config/i386/i386.md (*tls_global_dynamic_64_): Add RDI + clobber and use it to generate LEA. + (@tls_global_dynamic_64_): Add a clobber. + +2025-07-02 Alexey Merzlyakov + + PR target/120356 + * config/riscv/riscv-v.cc + (expand_const_vector_interleaved_stepped_npatterns): + Fix ASHIFT to LSHIFTRT insn. + +2025-07-02 Richard Biener + + PR tree-optimization/120927 + * tree-vect-loop.cc (vect_analyze_loop): Stop querying + further epilogues after one with partial vectors. + +2025-07-02 Haochen Jiang + + * config/i386/driver-i386.cc (host_detect_local_cpu): Change + to AMX-FP8 for Diamond Rapids. + +2025-07-01 Qing Zhao + + * tree-object-size.cc (access_with_size_object_size): Update comments + for pointers with .ACCESS_WITH_SIZE. + (collect_object_sizes_for): Propagate size info through GIMPLE_ASSIGN + for pointers with .ACCESS_WITH_SIZE. + +2025-07-01 Qing Zhao + + * doc/extend.texi: Extend counted_by attribute to pointer fields in + structures. Add one more requirement to pointers with counted_by + attribute. + +2025-07-01 Jakub Jelinek + + PR c++/120471 + * tree.h (address_invariant_p): New function. + * tree.cc (address_invariant_p): New function. + (tree_invariant_p_1): Use it for ADDR_EXPR handling. Formatting + tweak. + +2025-07-01 Remi Machet + + * config/aarch64/aarch64-simd.md (*shrn_to_subhn_): Add pattern + converting mvn+shrn into mvni+subhn. + +2025-07-01 Jakub Jelinek + + PR middle-end/120608 + * passes.def (pass_musttail): Move before pass_sanopt. + * tree-tailcall.cc (empty_eh_cleanup): Handle GIMPLE_RESX + which doesn't throw externally through recursion on single + eh edge (if any and cnt still allows that). + (find_tail_calls): Add ESUCC, IGNORED_EDGES and MUST_SEE_BBS + arguments. Handle GIMPLE_CONDs for non-simplified cleanups with + finally_tmp temporaries both on backward and forward walks, adjust + recursive call. + (tree_optimize_tail_calls_1): Adjust find_tail_calls callers. + +2025-07-01 Ezra Sitorus + + * config/aarch64/aarch64-sys-regs.def: Copy from Binutils. + +2025-07-01 H.J. Lu + + PR debug/120902 + * print-tree.cc (debug with const tree_node *): Call debug_tree + instead of debug. + +2025-07-01 Yuao Ma + + * fold-const-call.cc (fold_const_call_ss): Constant fold for + single arg pi-based trigonometric builtins. + (fold_const_call_sss): Constant fold for double arg pi-based + trigonometric builtins. + * fold-const.cc (negate_mathfn_p): asinpi/atanpi is odd func. + (tree_call_nonnegative_warnv_p): acospi always non-neg, + asinpi/atanpi non-neg iff arg non-neg. + * tree-call-cdce.cc (can_test_argument_range): Add acospi/asinpi. + (edom_only_function): Add acospi/asinpi/cospi/sinpi. + (get_no_error_domain): Add acospi/asinpi. + +2025-06-30 Jeff Law + + PR rtl-optimization/120242 + PR rtl-optimization/120627 + PR rtl-optimization/120736 + PR rtl-optimization/120813 + * ext-dce.cc (ext_dce_process_uses): Remove some cases where we + unnecessarily expanded live sets for promoted subregs. + (expand_changed_pseudos): New function. + (reset_subreg_promoted_p): Use it. + +2025-06-30 Alexey Merzlyakov + + PR target/120714 + * config/riscv/riscv.cc (riscv_allocate_and_probe_stack_space): + Fix SP-addresses in REG_CFA_DEF_CFA notes for stack-clash case. + +2025-06-30 David Malcolm + + * diagnostic-color.cc: Use nullptr rather than NULL. + * diagnostic-format-sarif.cc: Likewise. + * diagnostic-format-text.cc: Likewise. + * diagnostic-macro-unwinding.cc: Likewise. + * diagnostic-path-output.cc: Likewise. + * diagnostic-path.cc: Likewise. + * diagnostic-show-locus.cc: Likewise. + * diagnostic-spec.cc: Likewise. + * diagnostic.cc: Likewise. + * lazy-diagnostic-path.cc: Likewise. + * simple-diagnostic-path.cc: Likewise. + * tree-diagnostic-client-data-hooks.cc: Likewise. + +2025-06-30 David Malcolm + + * diagnostic-format-sarif.cc + (sarif_builder::maybe_make_kinds_array): Convert + diagnostic_event::meaning enums to enum class. + * diagnostic-path-output.cc (path_label::get_text): Likewise. + * diagnostic-path.cc + (diagnostic_event::meaning::maybe_get_verb_str): Likewise. + (diagnostic_event::meaning::maybe_get_noun_str): Likewise. + (diagnostic_event::meaning::maybe_get_property_str): Likewise. + * diagnostic-path.h (diagnostic_event::verb): Likewise. + (diagnostic_event::noun): Likewise. + (diagnostic_event::property): Likewise. + (diagnostic_event::meaning): Likewise. + +2025-06-30 David Malcolm + + * Makefile.in (OBJS-libcommon): Drop diagnostic-format-json.o. + * common.opt (fdiagnostics-format=): Drop + "json|json-stderr|json-file". + (diagnostics_output_format): Drop values "json", "json-stderr", + and "json-file". + * diagnostic-format-json.cc: Delete file. + * diagnostic-format.h + (diagnostic_output_format_init_json_stderr): Delete. + (diagnostic_output_format_init_json_file): Delete. + * diagnostic.cc (diagnostic_output_format_init): Delete cases for + DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR and + DIAGNOSTICS_OUTPUT_FORMAT_JSON_FILE. + * diagnostic.h (DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR): Delete. + (DIAGNOSTICS_OUTPUT_FORMAT_JSON_FILE): Delete. + * doc/invoke.texi: Remove references to json output format. + * doc/ux.texi: Likewise. + * selftest-run-tests.cc (selftest::run_tests): Drop call to + deleted selftest::diagnostic_format_json_cc_tests. + * selftest.h (selftest::diagnostic_format_json_cc_tests): Delete. + +2025-06-30 Mark Wielaard + + * common.opt.urls: Regenerate. + +2025-06-30 Pan Li + + * config/riscv/riscv-v.cc (expand_vx_binary_vec_vec_dup): Add + new case US_MINUS. + * config/riscv/riscv.cc (riscv_rtx_costs): Ditto. + * config/riscv/vector-iterators.md: Add new op us_minus. + +2025-06-30 Peter Bergner + + PR target/109116 + * config/rs6000/mma.md (unspec): Delete UNSPEC_MMA_EXTRACT. + (vsx_disassemble_pair): Expand into a vector register sized subreg. + (mma_disassemble_acc): Likewise. + (*vsx_disassemble_pair): Delete. + (*mma_disassemble_acc): Likewise. + +2025-06-30 Kito Cheng + + * config/riscv/sifive-7.md: Add primary vector pipeline model + for SiFive 7 series. + +2025-06-30 Kito Cheng + + PR target/120659 + * config/riscv/sifive-7.md: Add B extension, fp16 and missing + scalar instruction type for sifive-7 pipeline model. + +2025-06-30 Richard Biener + + * tree-vect-slp.cc (vect_build_slp_2): Handle ternary + and call operators when swapping operands. + +2025-06-30 Paul-Antoine Arras + + PR target/119100 + * config/riscv/autovec-opt.md (*vfnmsub_,*vfnmadd_): Handle + both add and acc variants. + * config/riscv/vector.md (*pred_mul_neg__scalar_undef): New + pattern. + +2025-06-30 Kyrylo Tkachov + + * config/aarch64/aarch64-cores.def (gb10): New entry. + * config/aarch64/aarch64-tune.md: Regenerate. + * doc/invoke.texi (AArch64 Options): Document the above. + +2025-06-30 Jakub Jelinek + + PR c/120520 + PR c/117023 + * builtin-attrs.def (DEF_LIST_INT_INT_INT): Define it and + use for 1,2,3. + (ATTR_NONNULL_IF123_LIST): New DEF_ATTR_TREE_LIST. + (ATTR_NONNULL_4_IF123_LIST): Likewise. + * builtins.def (BUILT_IN_FWRITE): Use ATTR_NONNULL_4_IF123_LIST + instead of ATTR_NONNULL_LIST. + (BUILT_IN_FWRITE_UNLOCKED): Likewise. + * gimple.h (infer_nonnull_range_by_attribute): Add another optional + tree * argument defaulted to NULL. + * gimple.cc (infer_nonnull_range_by_attribute): Add OP3 argument, + handle 3 argument nonnull_if_nonzero attribute. + * builtins.cc (validate_arglist): Handle 3 argument nonnull_if_nonzero + attribute. + * tree-ssa-ccp.cc (pass_post_ipa_warn::execute): Likewise. + * ubsan.cc (instrument_nonnull_arg): Adjust + infer_nonnull_range_by_attribute caller, handle 3 argument + nonnull_if_nonzero attribute. + * gimple-range-infer.cc (gimple_infer_range::gimple_infer_range): + Handle 3 argument nonnull_if_nonzero attribute. + * doc/extend.texi (nonnull_if_nonzero): Document 3 argument version + of the attribute. + +2025-06-30 Richard Sandiford + + PR rtl-optimization/120733 + * lra-eliminations.cc (move_plus_up): Check whether lowpart_subreg + returns null. + +2025-06-30 Jan Hubicka + + * auto-profile.cc (autofdo_source_profile::offline_external_functions): + Add missing newline in dump. + (afdo_propagate_edge): If annotated BB or edge has too small count + bump it up to mitigate profile imprecisions caused by vectorizer. + (afdo_propagate): Increase number of iteraitons and fix dump + +2025-06-30 Jan Hubicka + + * auto-profile.cc (struct decl_lineno): Turn to structure; add + location. + (dump_inline_stack): Update. + (get_inline_stack): Update. + (get_relative_location_for_locus): Fixup formating. + (function_instance::get_function_instance_by_decl): Add + LOCATION parameter; improve dumping. + (autofdo_source_profile::get_callsite_total_count): Improve dumping; + update. + (walk_block): Update. + (autofdo_source_profile::offline_unrealized_inlines): Update. + (autofdo_source_profile::get_count_info): Update. + +2025-06-30 H.J. Lu + + PR target/120840 + * config/i386/i386-expand.cc (ix86_expand_call): Don't mark + hard frame pointer as clobber. + * config/i386/i386-options.cc (ix86_set_func_type): Use + TYPE_NO_CALLEE_SAVED_REGISTERS instead of + TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP. + * config/i386/i386.cc (ix86_function_ok_for_sibcall): Remove the + TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP check. + (ix86_save_reg): Merge TYPE_NO_CALLEE_SAVED_REGISTERS and + TYPE_PRESERVE_NONE with TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP. + * config/i386/i386.h (call_saved_registers_type): Remove + TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP. + * doc/extend.texi: Update no_callee_saved_registers documentation. + +2025-06-30 Jin Ma + + * config/riscv/riscv-vsetvl.cc (bitmap_union_of_preds_with_entry): + Refactor. + +2025-06-30 Kito Cheng + + * config/riscv/pipeline-checker: New file. + +2025-06-28 H.J. Lu + + PR debug/120849 + * print-tree.cc (debug): New. + * print-tree.h (debug): Likewise. + +2025-06-28 Georg-Johann Lay + + PR target/120856 + * config/avr/avr.cc (avr_hard_regno_mode_ok) [-mno-lra]: Deny + hard regs >= 4 bytes that overlap Y. + +2025-06-28 Jan Hubicka + Kugan Vivekanandarajah + + * auto-profile.cc (get_original_name): Only strip suffixes introduced + after auto-fdo annotation. + (string_table::get_index_by_decl): Simplify. + (string_table::add_name): New member function. + (string_table::read): Micro-optimize allocation. + (function_instance::get_function_instance_by_decl): Dump reasons + for failure; try to compensate lost discriminators. + (function_instance::merge): Simplify sanity check; do not check + for realized flag; fix merging of targets. + (function_instance::offline_if_in_set): Simplify. + (function_instance::dump): Sanity check that names are consistent. + (autofdo_source_profile::offline_external_functions): Also handle + stripping suffixes. + (walk_block): Move up in source. + (autofdo_source_profile::offline_unrealized_inlines): Also compute + realized functions. + (autofdo_source_profile::get_function_instance_by_name_index): Simplify. + (autofdo_source_profile::add_function_instance): Simplify. + (autofdo_source_profile::read): Do not strip suffxies; error on duplicates. + (mark_realized_functions): Remove. + (auto_profile): Do not call mark_realized_functions. + * passes.def: Move auto_profile_offline before free_lang_data. + +2025-06-27 Eric Botcazou + + * gimple-fold.cc (fold_const_aggregate_ref_1) : + Bail out immediately if the reference has reverse storage order. + * tree-ssa-sccvn.cc (fully_constant_vn_reference_p): Likewise. + +2025-06-27 Jakub Jelinek + + PR c++/120777 + * gimple-fold.cc (gimple_get_virt_method_for_vtable): Revert + 2018-09-18 changes. + +2025-06-27 Nathaniel Shead + + PR c++/98735 + PR c++/118904 + * tree.cc (struct identifier_hash): New type. + (struct identifier_count_traits): New traits. + (internal_label_nums): New hash map. + (generate_internal_label): New function. + (prefix_for_internal_label): New function. + * tree.h (IDENTIFIER_INTERNAL_P): New macro. + (generate_internal_label): Declare. + (prefix_for_internal_label): Declare. + * ubsan.cc (ubsan_ids): Remove. + (ubsan_type_descriptor): Use generate_internal_label. + (ubsan_create_data): Likewise. + +2025-06-27 Jan Hubicka + + * auto-profile.cc (function_instance::set_name, + function_instance::set_realized, function_instnace::realized_p, + function_instance::set_in_worklist, + function_instance::clear_in_worklist, + function_instance::in_worklist_p): New member functions. + (function_instance::in_worklist, function_instance::realized_): + new. + (get_relative_location_for_locus): Break out from .... + (get_relative_location_for_stmt): ... here. + (function_instance::~function_instance): Sanity check that + removed function is not in worklist. + (function_instance::merge): Do not offline realized instances. + (function_instance::offline): Make private; add duplicate functions + to worklist rather then merging immediately. + (function_instance::offline_if_in_set): Cleanup. + (function_instance::remove_external_functions): Likewise. + (function_instance::offline_if_not_realized): New member function. + (autofdo_source_profile::offline_external_functions): Handle delayed + functions. + (autofdo_source_profile::offline_unrealized_inlines): New member function. + (walk_block): New function. + (mark_realized_functions): New function. + (afdo_annotate_cfg): Fix dump. + (auto_profile): Mark realized functions and offline rest; do not compute + fn summary. + +2025-06-27 Georg-Johann Lay + + PR target/113934 + * config/avr/avr.opt (-mlra): Turn on per default. + +2025-06-27 Richard Biener + + PR tree-optimization/120808 + * tree-vect-slp-patterns.cc (vect_match_expression_p): + Take a code_helper and also match calls. + (addsub_pattern::recognize): Handle .FMA/.FMS pairs + in addition to PLUS/MINUS. + (addsub_pattern::build): Adjust. + +2025-06-27 Richard Biener + + * tree-vectorizer.h (vect_chooses_same_modes_p): New + overload. + * tree-vect-stmts.cc (vect_chooses_same_modes_p): Likewise. + * tree-vect-loop.cc (vect_analyze_loop): Prune epilogue + analysis further when not using partial vectors. + +2025-06-27 Richard Biener + + * tree-vect-loop.cc (vect_analyze_loop): Consider AVX512 + style masking when computing supports_partial_vectors. + +2025-06-27 Tamar Christina + + * doc/extend.texi: Fix typo in unsed attribute docs. + +2025-06-27 H.J. Lu + + PR target/120830 + * config/i386/i386-features.cc (ix86_get_vector_cse_mode): Handle + vector broadcast source. + +2025-06-27 Alexandre Oliva + + PR rtl-optimization/120424 + * lra-eliminations.cc (elimination_2sp_occurred_p): Rename + from... + (elimination_fp2sp_occured_p): ... this. Adjust all uses. + (lra_eliminate_regs_1): Don't require a from-frame-pointer + elimination to set it. + (update_reg_eliminate): Likewise to test it. + +2025-06-27 Alexandre Oliva + + PR rtl-optimization/120424 + * lra-eliminations.cc (lra_eliminate_regs_1): Adjust autoinc + addresses that are MEMs. + +2025-06-27 Alexandre Oliva + + PR rtl-optimization/120424 + * lra-eliminations.cc (lra_update_fp2sp_elimination): Reorder + and regroup related statements. + +2025-06-27 Alexandre Oliva + + PR rtl-optimization/120424 + * lra-eliminations.cc (lra_update_fp2sp_elimination): + Avoid sp offsets in further fp2sp eliminations... + (update_reg_eliminate): ... and restore to_rtx before assert + checking. + +2025-06-27 Alexandre Oliva + + PR rtl-optimization/120424 + * lra-eliminations.cc (lra_update_fp2sp_elimination): + Compute complete live ranges and recompute slots' live ranges + if needed. + * lra-lives.cc (lra_reset_live_range_list): New. + (lra_complete_live_ranges): New. + * lra-spills.cc (assign_spill_hard_regs): Reject empty live + ranges. + (add_pseudo_to_slot): Likewise. + (lra_recompute_slots_live_ranges): New. + * lra-int.h (lra_reset_live_range_list): Declare. + (lra_complete_live_ranges): Declare. + (lra_recompute_slots_live_ranges): Declare. + +2025-06-27 Alexandre Oliva + + PR rtl-optimization/120424 + * genoutput.cc (scan_operands): Make MATCH_SCRATCHes eliminable. + +2025-06-27 Alexandre Oliva + + PR rtl-optimization/120424 + * lra-eliminations.cc (lra_update_fp2sp_elimination): + Inactivate the unused fp2sp elimination right away. + +2025-06-26 Dimitar Dimitrov + + * config/pru/pru.md (reg move splitter): New splitter for 64-bit + register moves into two 32-bit moves. + (const_int move splitter): New splitter for 64-bit constant + integer moves into two 32-bit moves. + +2025-06-26 David Malcolm + + * diagnostic.h (diagnostic_context::set_permissive_option): New. + (diagnostic_context::set_fatal_errors): New. + (diagnostic_context::set_internal_error_callback): New. + (diagnostic_context::set_adjust_diagnostic_info_callback): New. + (diagnostic_context::inhibit_notes): New. + (diagnostic_context::m_opt_permissive): Make private. + (diagnostic_context::m_fatal_errors): Likewise. + (diagnostic_context::m_internal_error): Likewise. + (diagnostic_context::m_adjust_diagnostic_info): Likewise. + (diagnostic_context::m_inhibit_notes_p): Likewise. + (diagnostic_inhibit_notes): Delete. + * opts.cc (common_handle_option): Use + diagnostic_context::set_fatal_errors. + * toplev.cc (internal_error_function): Use + diagnostic_context::set_internal_error_callback. + (general_init): Likewise. + (process_options): Use diagnostic_context::inhibit_notes. + +2025-06-26 David Malcolm + + PR analyzer/120809 + * diagnostic-format-html.cc + (html_builder::maybe_make_state_diagram): Bulletproof against the + SVG generation failing. + * xml.cc (xml::printer::push_element): Assert that the ptr is + nonnull. + (xml::printer::append): Likewise. + +2025-06-26 David Malcolm + + * diagnostic-output-spec.cc (sarif_scheme_handler::make_sink): + Split out creation of sarif_generation_options and + sarif_serialization_format into... + (sarif_scheme_handler::make_sarif_gen_opts): ...this... + (sarif_scheme_handler::make_sarif_serialization_object): ...and + this. + +2025-06-26 Paul-Antoine Arras + + PR target/120828 + * config/riscv/riscv-v.cc (prepare_ternary_operands): Handle the + vector-scalar case. + +2025-06-26 Uros Bizjak + + PR target/120719 + * config/i386/i386.md (crc_revsi4): New expander. + +2025-06-26 Kito Cheng + + * config/riscv/riscv.md: Fix build issue. + +2025-06-26 Martin Jambor + + * lto-ltrans-cache.h (class ltrans_file_cache): Remove member prefix. + * lto-ltrans-cache.cc (ltrans_file_cache::ltrans_file_cache): Do + not initialize member prefix. + +2025-06-26 Kito Cheng + + * config/riscv/riscv.md: Add comment and reorder include + files. + +2025-06-26 Martin Jambor + + * tree-vect-stmts.cc (supportable_indirect_convert_operation): + Remove an unused shadowed variable. + +2025-06-26 Martin Jambor + + * tree-vect-slp.cc (cond_expr_maps): Remove. + +2025-06-26 Jan Hubicka + + * auto-profile.cc (function_instance::merge): Add TODO. + (autofdo_source_profile::offline_external_functions): + Do not use range for on the worklist. + * timevar.def (TV_IPA_AUTOFDO_OFFLINE): New timevar. + +2025-06-26 Jan Hubicka + + * auto-profile.cc (name_index_set, name_index_map): New types. + (dump_afdo_loc): New function. + (dump_inline_stack): Simplify. + (function_instance::merge): Merge recursively inlined functions; + offline if necessary; collect new fnctions. + (function_instance::offline): New member function. + (function_instance::offline_if_in_set): New member function. + (function_instance::remove_external_functions): New member function. + (function_instance::dump): New member function. + (function_instance::debug): New member function. + (function_instance::dump_inline_stack): New member function. + (function_instance::find_icall_target_map): Use removed_icall_target. + (function_instance::remove_icall_target): Only mark icall target removed. + (autofdo_source_profile::offline_external_functions): New function. + (function_instance::read_function_instance): Record inlined_to pointers; + use -1 for unknown head counts. + (autofdo_source_profile::get_function_instance_by_name_index): New + function. + (autofdo_source_profile::add_function_instance): New member function. + (autofdo_source_profile::read): Do not leak memory; fix formatting. + (read_profile): Fix formatting. + (afdo_annotate_cfg): LIkewise. + (class pass_ipa_auto_profile_offline): New pass. + (make_pass_ipa_auto_profile_offline): New function. + * passes.def (pass_ipa_auto_profile_offline): Add + * tree-pass.h (make_pass_ipa_auto_profile): Declare + +2025-06-26 H.J. Lu + + PR target/120819 + * config/i386/i386-features.cc (ix86_broadcast_inner): Also handle + all 1s float vector constant. + +2025-06-26 H.J. Lu + + PR target/120816 + * config/i386/i386-features.cc (remove_redundant_vector_load): + Handle REG_EH_REGION note in DEF_INSN. + +2025-06-26 H.J. Lu + + PR target/119628 + * config/i386/i386-expand.cc (ix86_expand_call): Call + ix86_type_no_callee_saved_registers_p instead of looking up + no_callee_saved_registers attribute. + * config/i386/i386-options.cc (ix86_set_func_type): Look up + preserve_none attribute. Check preserve_none attribute for + interrupt attribute. Don't check no_caller_saved_registers nor + no_callee_saved_registers conflicts here. + (ix86_set_func_type): Check no_callee_saved_registers before + checking no_caller_saved_registers attribute. + (ix86_set_current_function): Allow SSE with + no_caller_saved_registers attribute. + (ix86_handle_call_saved_registers_attribute): Check preserve_none, + no_callee_saved_registers and no_caller_saved_registers conflicts. + (ix86_gnu_attributes): Add preserve_none attribute. + * config/i386/i386-protos.h (ix86_type_no_callee_saved_registers_p): + New. + * config/i386/i386.cc + (x86_64_preserve_none_int_parameter_registers): New. + (ix86_using_red_zone): Don't use red-zone when there are no + caller-saved registers with SSE. + (ix86_type_no_callee_saved_registers_p): New. + (ix86_function_ok_for_sibcall): Also check TYPE_PRESERVE_NONE + and call ix86_type_no_callee_saved_registers_p instead of looking + up no_callee_saved_registers attribute. + (ix86_comp_type_attributes): Call + ix86_type_no_callee_saved_registers_p instead of looking up + no_callee_saved_registers attribute. Return 0 if preserve_none + attribute doesn't match in 64-bit mode. + (ix86_function_arg_regno_p): For cfun with TYPE_PRESERVE_NONE, + use x86_64_preserve_none_int_parameter_registers. + (init_cumulative_args): Set preserve_none_abi. + (function_arg_64): Use x86_64_preserve_none_int_parameter_registers + with preserve_none attribute. + (setup_incoming_varargs_64): Use + x86_64_preserve_none_int_parameter_registers with preserve_none + attribute. + (ix86_save_reg): Treat TYPE_PRESERVE_NONE like + TYPE_NO_CALLEE_SAVED_REGISTERS. + (ix86_nsaved_sseregs): Allow saving XMM registers for + no_caller_saved_registers attribute. + (ix86_compute_frame_layout): Likewise. + (x86_this_parameter): Use + x86_64_preserve_none_int_parameter_registers with preserve_none + attribute. + * config/i386/i386.h (ix86_args): Add preserve_none_abi. + (call_saved_registers_type): Add TYPE_PRESERVE_NONE. + (machine_function): Change call_saved_registers to 3 bits. + * doc/extend.texi: Add preserve_none attribute. Update + no_caller_saved_registers attribute to remove -mgeneral-regs-only + restriction. + +2025-06-25 H.J. Lu + + * config/i386/i386-features.cc (ix86_place_single_vector_set): + Add debug dump. + (replace_vector_const): Likewise. + (remove_redundant_vector_load): Likewise. + +2025-06-25 Luis Silva + + * config/arc/arc.md (mulvsi4): New define_expand. + (mulsi3_Vcmp): New define_insn. + +2025-06-25 Luis Silva + + * config/arc/arc.cc (arc_select_cc_mode): Handle multiplication + results compared against zero, selecting CC_Zmode. + * config/arc/arc.md (*mulsi3_cmp0): New define_insn. + (*mulsi3_cmp0_noout): New define_insn. + +2025-06-25 Shahab Vahedi + + * config/arc/arc.md (subsi3_v, subvsi4, subsi3_c): New patterns. + +2025-06-25 Shahab Vahedi + + * config/arc/arc-modes.def (CC_V): New mode. + * config/arc/arc-protos.h (arc_gen_unlikely_cbranch): New + function declaration. + * config/arc/arc.cc (arc_gen_unlikely_cbranch): New + function. + (get_arc_condition_code): Handle new mode. + * config/arc/arc.md (addvsi3_v, addvsi4, addsi3_c, uaddvsi4): New + patterns. + * config/arc/predicates.md (proper_comparison_operator): Handel + the new V_mode. + (equality_comparison_operator): Likewise. + +2025-06-25 Martin Jambor + + * diagnostic-path-output.cc (path_label::get_effects): Mark as + final override. + * diagnostic-format-html.cc + (html_output_format::after_diagnostic): Likewise. + +2025-06-25 Martin Jambor + + * gimple-range-op.cc + (gimple_range_op_handler::maybe_builtin_call): Use + CFN_BUILT_IN_ISINF instead of BUILT_IN_ISINF. + +2025-06-25 Martin Jambor + + * value-relation.h (class dom_oracle): Mark member function + next_relation as override. + +2025-06-25 Martin Jambor + + * tree-ssa-propagate.h (class substitute_and_fold_engine): Mark + member functions value_of_expr and range_of_expr as override. + +2025-06-25 Martin Jambor + + * range-op-mixed.h (class operator_plus): Mark member function + overflow_free_p as final override. + (class operator_minus): Likewise. + (class operator_mult): Likewise. + * range-op-ptr.cc (class pointer_plus_operator): Mark member + function lhs_op1_relation as final override. + * range-op.cc (class operator_div::): Mark member functions + op2_range and update_bitmask as final override. + (class operator_logical_and): Mark member functions fold_range, + op1_range and op2_range as final override. Remove unnecessary + virtual. + (class operator_logical_or): Likewise. + (class operator_logical_not): Mark member functions fold_range and + op1_range as final override. Remove unnecessary virtual. + formatting easier. + (class operator_absu): Mark member functions wi_fold as final + override. + +2025-06-25 Martin Jambor + + * gimple-ssa-sccopy.cc (class pass_sccopy): Mark member functions + gate and execute as final override. + +2025-06-25 Martin Jambor + + * avoid-store-forwarding.cc (class + pass_rtl_avoid_store_forwarding): Mark member function gate as + final override. + +2025-06-25 Andrew MacLeod + + * value-relation.cc (relation_to_code): Remove. + +2025-06-25 Andrew MacLeod + + * value-range.cc (frange::verify_range): Constify. + (irange::verify_range): Constify. + * value-range.h (vrange::verify_range): New. + (irange::verify_range): Make public. + (prange::verify_range): Make public. + (prange::verify_range): Make public. + (value_range::verify_range): New. + +2025-06-25 Andrew MacLeod + + * value-range.cc (irange::get_bitmask): Return original mask if + result is unknown. + (assert_snap_result): New. + (test_irange_snap_bounds): New. + (range_tests_misc): Call test_irange_snap_bounds. + +2025-06-25 Richard Biener + + PR tree-optimization/109892 + * tree-vect-loop.cc (check_reduction_path): Handle fma. + (vectorizable_reduction): Apply FOLD_LEFT_REDUCTION code + generation constraints. + +2025-06-25 Richard Biener + + PR tree-optimization/120808 + * tree-vectorizer.h (compatible_calls_p): Add flag to + indicate a FMA/FMS pair is allowed. + * tree-vect-slp.cc (compatible_calls_p): Likewise. + (vect_build_slp_tree_1): Allow mixed .FMA/.FMS as two-operator. + (vect_build_slp_tree_2): Handle calls in two-operator SLP build. + * tree-vect-slp-patterns.cc (compatible_complex_nodes_p): + Adjust. + +2025-06-25 Alfie Richards + + * tree-ssa-loop-ivopts.cc (constant_multiple_of): Change + tree_to_aff_combination to tree_to_aff_combination_expand and add + parameter to take ivopts_data. + (get_computation_aff_1): Change parameters and calls to include + ivopts_data. + (get_computation_aff): Ditto. + (get_computation_at) Ditto.: + (get_debug_computation_at) Ditto.: + (get_computation_cost) Ditto.: + (rewrite_use_nonlinear_expr) Ditto.: + (rewrite_use_address) Ditto.: + (rewrite_use_compare) Ditto.: + (remove_unused_ivs) Ditto.: + +2025-06-25 Richard Sandiford + + PR rtl-optimization/120745 + * rtl-ssa/changes.cc (process_uses_of_deleted_def): Rewrite to + handle deletions of non-degenerate phis. + +2025-06-25 H.J. Lu + + PR target/120815 + * common/config/i386/i386-common.cc (processor_alias_table): + Replace CPU_SLM/PTA_NEHALEM with CPU_HASWELL/PTA_HASWELL for + PROCESSOR_INTEL. + * config/i386/i386-options.cc (processor_cost_table): Replace + intel_cost with alderlake_cost. + * config/i386/x86-tune-costs.h (intel_cost): Removed. + * config/i386/x86-tune-sched.cc (ix86_issue_rate): Treat + PROCESSOR_INTEL like PROCESSOR_ALDERLAKE. + (ix86_adjust_cost): Likewise. + * doc/invoke.texi: Update -mtune=intel for Diamond Rapids and + Clearwater Forest. + +2025-06-25 Haochen Jiang + + * config/i386/i386.h (PTA_ALDERLAKE): Use PTA_GOLDMONT_PLUS + as base to remove PTA_CLDEMOTE. + (PTA_SIERRAFOREST): Add PTA_CLDEMOTE since PTA_ALDERLAKE + does not include that anymore. + * doc/invoke.texi: Update texi file. + +2025-06-25 Jiawei + + * common/config/riscv/riscv-common.cc: New Profiles. + +2025-06-25 Jan Hubicka + + * common.opt: (fauto-profile-inlining): New + * doc/invoke.texi (-fauto-profile-inlining): Document. + * ipa-inline.cc (inline_functions_by_afdo): Check + flag_auto_profile. + (early_inliner): Also do inline_functions_by_afdo with + !flag_early_inlining. + +2025-06-25 Jan Hubicka + + * auto-profile.cc: Update toplevel comment. + (early_inline): Remove. + (auto_profile): Don't do early inlining. + +2025-06-24 Tobias Burnus + + * config/gcn/gcn-opts.h (TARGET_GLC_NAME): Fix and extend the + description in the comment. + * config/gcn/gcn.cc (print_operand): Extend the comment about + 'G' and 'g'. + * config/gcn/gcn.md: Use 'glc' instead of %G where appropriate. + +2025-06-24 Paul-Antoine Arras + + PR target/119100 + * config/riscv/autovec-opt.md (*_vf_): Handle both add and + acc FMA variants. + * config/riscv/vector.md (*pred_mul__scalar_undef): New. + +2025-06-24 Uros Bizjak + + * config/i386/i386.md + (@pro_epilogue_adjust_stack_add_nocc): Add type attribute. + (pro_epilogue_adjust_stack_add_nocc peephole2 pattern): + Convert pro_epilogue_adjust_stack_add_nocc variant to + pro_epilogue_adjust_stack_add when FLAGS_REG is dead. + +2025-06-24 Richard Biener + + * tree-vect-stmts.cc (vectorizable_load): Remove non-SLP + paths and propagate out ncopies == 1. + +2025-06-24 Marc Poulhiès + + * diagnostic-state-to-dot.cc (get_color_for_dynalloc_state): + Rename argument dynalloc_state to dynalloc_st. + (add_title_tr): Rename argument style to styl. + (on_xml_node): Rename local variable dynalloc_state to dynalloc_st. + +2025-06-24 Yuao Ma + + * tree-call-cdce.cc (edom_only_function): Remove atan. + +2025-06-24 Juergen Christ + + * config/s390/vector.md (VF): Don't restrict modes. + (VEC_SET_SINGLEFLOAT): Ditto. + +2025-06-24 Tamar Christina + + * config/aarch64/aarch64.cc (aarch64_override_options_internal): Set + value of parameter based on option. + * config/aarch64/aarch64.opt (autovec-preference): New. + * doc/invoke.texi (autovec-preference): Document it. + +2025-06-24 Tamar Christina + + * config/aarch64/aarch64.opt (max-vectorization): New. + * config/aarch64/aarch64.cc (aarch64_override_options_internal): Save + and restore option. + Implement it through vect-scalar-cost-multiplier. + (aarch64_attributes): Default to off. + * common/config/aarch64/aarch64-common.cc (aarch64_handle_option): + Initialize option. + * doc/extend.texi (max-vectorization): Document attribute. + * doc/invoke.texi (max-vectorization): Document flag. + +2025-06-24 hongtao.liu + + PR target/115842 + * tree-ssa-loop-ivopts.cc (determine_group_iv_cost_address): + Don't recalculate inv_expr when group-candidate cost + calucalution. + +2025-06-24 Tamar Christina + + * doc/extend.texi: Document pragma unroll interaction with vectorizer. + * tree-vectorizer.h (LOOP_VINFO_USER_UNROLL): New. + (class _loop_vec_info): Add user_unroll. + * tree-vect-loop.cc (vect_analyze_loop_1): Set + suggested_unroll_factor and retry. + (_loop_vec_info::_loop_vec_info): Initialize user_unroll. + (vect_transform_loop): Clear the loop->unroll value if the pragma was + used. + +2025-06-24 Tamar Christina + + * tree-vect-loop-manip.cc (vect_gen_vector_loop_niters, + vect_gen_vector_loop_niters_mult_vf): Remove uses of log_vf. + +2025-06-24 H.J. Lu + + PR target/92080 + * config/i386/i386-expand.cc (ix86_expand_call): Set + recursive_function to true for recursive call. + * config/i386/i386-features.cc (ix86_place_single_vector_set): + Add an argument for inner scalar, default to nullptr. Set the + source from inner scalar if not nullptr. + (ix86_get_vector_load_mode): Renamed to ... + (ix86_get_vector_cse_mode): This. Add an argument for scalar mode + and handle integer and float scalar modes. + (replace_vector_const): Add an argument for scalar mode and pass + it to ix86_get_vector_load_mode. + (x86_cse_kind): New. + (redundant_load): Likewise. + (ix86_broadcast_inner): Likewise. + (remove_redundant_vector_load): Also support const0_rtx and + constm1_rtx broadcasts. Handle vector broadcasts from constant + and variable scalars. + * config/i386/i386.h (machine_function): Add recursive_function. + +2025-06-24 H.J. Lu + + PR target/70308 + PR target/101366 + PR target/102294 + PR target/108585 + PR target/118276 + PR target/119596 + PR target/119703 + PR target/119704 + * config/i386/x86-tune-costs.h (generic_memcpy): Updated. + (generic_memset): Likewise. + (generic_cost): Change CLEAR_RATIO to 10. + +2025-06-24 Jan Hubicka + + * tree-inline.cc (expand_call_inline): Preserve discriminator. + +2025-06-24 Jan Hubicka + + * auto-profile.cc (afdo_set_bb_count): Dump also 0 count stmts. + (afdo_annotate_cfg): Fix conditional for block having non-zero static + profile. + +2025-06-24 Lili Cui + + PR target/120741 + * config/i386/i386.cc (ix86_expand_prologue): + Remove 1 assertion. + +2025-06-24 Jeff Law + + PR target/118241 + * config/riscv/predicates.md: Fix comment typo in recent change. + +2025-06-23 Sam James + Jeff Law + + PR rtl-optimization/120795 + * ext-dce.cc (ext_dce_try_optimize_insn): Enable rescan in + remove_reg_equal_equiv_notes call. + +2025-06-23 David Malcolm + + PR other/116792 + PR testsuite/116163 + PR sarif-replay/120792 + * Makefile.in (OBJS-libcommon): Add diagnostic-output-spec.o. + * diagnostic-format-html.cc (html_builder::html_builder): Ensure + title is non-empty. + * diagnostic-output-spec.cc: New file, taken from material in + opts-diagnostic.cc. + * diagnostic-output-spec.h: New file. + * diagnostic.cc (diagnostic_context::set_main_input_filename): + New. + * diagnostic.h (diagnostic_context::set_main_input_filename): New + decl. + * doc/libgdiagnostics/topics/compatibility.rst + (LIBGDIAGNOSTICS_ABI_2): New. + * doc/libgdiagnostics/topics/diagnostic-manager.rst + (diagnostic_manager_add_sink_from_spec): New. + (diagnostic_manager_set_analysis_target): New. + * libgdiagnostics++.h (manager::add_sink_from_spec): New. + (manager::set_analysis_target): New. + * libgdiagnostics.cc: Include "diagnostic-output-spec.h". + (struct spec_context): New. + (diagnostic_manager_add_sink_from_spec): New. + (diagnostic_manager_set_analysis_target): New. + * libgdiagnostics.h + (LIBDIAGNOSTICS_HAVE_diagnostic_manager_add_sink_from_spec): New + define. + (diagnostic_manager_add_sink_from_spec): New decl. + (LIBDIAGNOSTICS_HAVE_diagnostic_manager_set_analysis_target): New + define. + (diagnostic_manager_set_analysis_target): New decl. + * libgdiagnostics.map (LIBGDIAGNOSTICS_ABI_2): New. + * libsarifreplay.cc (sarif_replayer::handle_artifact_obj): Looks + for "analysisTarget" in roles and call set_analysis_target using + the artifact if found. + * opts-diagnostic.cc: Refactor, moving material to + diagnostic-output-spec.cc. + (struct opt_spec_context): New. + (handle_OPT_fdiagnostics_add_output_): Use opt_spec_context. + (handle_OPT_fdiagnostics_set_output_): Likewise. + * sarif-replay.cc: Define INCLUDE_STRING. + (struct options): Add m_extra_output_specs. + (usage_msg): Add -fdiagnostics-add-output=SCHEME. + (str_starts_with): New. + (parse_options): Add -fdiagnostics-add-output=SCHEME. + (main): Likewise. + * selftest-run-tests.cc (selftest::run_tests): Call + diagnostic_output_spec_cc_tests rather than + opts_diagnostic_cc_tests. + * selftest.h (selftest::diagnostic_output_spec_cc_tests): + Replace... + (selftest::opts_diagnostic_cc_tests): ...this. + +2025-06-23 David Malcolm + + PR other/116792 + * Makefile.in (ANALYZER_OBJS): Add + analyzer/ana-state-to-diagnostic-state.o. + (OBJS): Move graphviz.o to... + (OBJS-libcommon): ...here. Add diagnostic-state-to-dot.o and pex.o. + * diagnostic-format-html.cc: Include "diagnostic-state.h" and + "graphviz.h". + (html_generation_options::html_generation_options): Initialize the + new flags. + (HTML_SCRIPT): Add function "get_any_state_diagram". Use it + when changing current focus id to update the visibility of the + pertinent diagram, if any. + (print_pre_source): New. + (html_builder::maybe_make_state_diagram): New. + (html_path_label_writer::html_path_label_writer): Add "path" param. + Initialize m_path and m_curr_event_id. + (html_path_label_writer::begin_label): Store current event id. + (html_path_label_writer::end_label): Attempt to make a state + diagram and add it if successful. + (html_path_label_writer::get_element_id): New. + (html_path_label_writer::m_path): New field. + (html_path_label_writer::m_curr_event_id): New field. + (html_builder::make_element_for_diagnostic): Pass path to label + writer. + * diagnostic-format-html.h + (html_generation_options::m_show_state_diagrams): New field. + (html_generation_options::m_show_state_diagram_xml): New field. + (html_generation_options::m_show_state_diagram_dot_src): New field. + * diagnostic-format-sarif.cc: Include "xml.h". + (populate_thread_flow_location_object): If requested, attempt to + generate xml state and add it to the proeprty bag as + "gcc/diagnostic_event/xml_state" in xml source form. + (sarif_generation_options::sarif_generation_options): Initialize + m_xml_state. + * diagnostic-format-sarif.h + (sarif_generation_options::m_xml_state): New field. + * diagnostic-path.cc: Define INCLUDE_MAP. Include "xml.h". + (diagnostic_event::maybe_make_xml_state): New. + * diagnostic-path.h (class xml::document): New forward decl. + (diagnostic_event::maybe_make_xml_state): New vfunc decl. + * diagnostic-state-to-dot.cc: New file. + * diagnostic-state.h: New file. + * digraph.cc: Define INCLUDE_STRING and INCLUDE_VECTOR. + * doc/analyzer.texi: Document state diagrams in html output. + (__analyzer_dump_dot): New. + (__analyzer_dump_xml): New. + * doc/invoke.texi (sarif): Add "xml-state" key. + (experimental-html): Add keys "show-state-diagrams", + "show-state-diagrams-dot-src" and "show-state-diagrams-xml". + * graphviz.cc: Define INCLUDE_MAP, INCLUDE_STRING, and + INCLUDE_VECTOR. Include "xml.h", "xml-printer.h", "pex.h" and + "selftest.h". + (graphviz_out::graphviz_out): Extract... + (dot::writer::writer): ...this. + (graphviz_out::write_indent): Convert to... + (dot::writer::write_indent): ...this. + (graphviz_out::print): Use get_pp. + (graphviz_out::println): Likewise. + (graphviz_out::begin_tr): Likewise. + (graphviz_out::end_tr): Likewise. + (graphviz_out::begin_td): Likewise. + (graphviz_out::end_td): Likewise. + (graphviz_out::begin_trtd): Likewise. + (graphviz_out::end_tdtr): Likewise. + (dot::ast_node::dump): New. + (dot::id::id): New. + (dot::id::print): New. + (dot::id::is_identifier_p): New. + (dot::kv_pair::print): New. + (dot::attr_list::print): New. + (dot::stmt_list::print): New. + (dot::stmt_list::add_edge): New. + (dot::stmt_list::add_attr): New. + (dot::graph::print): New. + (dot::stmt_with_attr_list::set_label): New. + (dot::node_stmt::print): New. + (dot::attr_stmt::print): New. + (dot::kv_stmt::print): New. + (dot::node_id::print): New. + (dot::port::print): New. + (dot::edge_stmt::print): New. + (dot::subgraph::print): New. + (dot::make_svg_document_buffer_from_graph): New. + (dot::make_svg_from_graph): New. + (selftest:test_ids): New. + (selftest:test_trivial_graph): New. + (selftest:test_layout_example): New. + (selftest:graphviz_cc_tests): New. + * graphviz.h (xml::node): New forward decl. + (class graphviz_out): Split out into... + (class dot::writer): ...this new class + (struct dot::ast_node): New. + (struct dot::id): New. + (struct dot::kv_pair): New. + (struct dot::attr_list): New. + (struct dot::stmt_list): New. + (struct dot::graph): New. + (struct dot::stmt): New. + (struct dot::stmt_with_attr_list): New. + (struct dot::node_stmt): New. + (struct dot::attr_stmt): New. + (struct dot::kv_stmt): New. + (enum class dot::compass_pt): New. + (struct dot::port): New. + (struct dot::node_id): New. + (struct dot::edge_stmt): New. + (struct dot::subgraph): New. + (dot::make_svg_from_graph): New. + * opts-diagnostic.cc (sarif_scheme_handler::make_sink): Add + "xml-state" flag. + (html_scheme_handler::make_sink): Add flags "show-state-diagrams", + "show-state-diagram-dot-src", and "show-state-diagram-xml". + * pex.cc: New file. + * pex.h: New file. + * selftest-run-tests.cc (selftest::run_tests): Call + graphviz_cc_tests. + * selftest.h (selftest::graphviz_cc_tests): New decl. + * xml.cc (xml::node_with_children::add_comment): New. + (xml::node_with_children::find_child_element): New. + (xml::element::get_attr): New. + (xml::comment::write_as_xml): New. + (selftest::test_printer): Add coverage of find_child_element and + get_attr. + (selftest::test_comment): New. + (selftest::xml_cc_tests): Call test_comment. + * xml.h: New forward decls. + (xml::node::dyn_cast_text): Use nullptr. + (xml::node::dyn_cast_element): New vfunc. + (xml::node_with_children::add_comment): New decl. + (xml::node_with_children::find_child_element): New decl. + (xml::element::dyn_cast_element): New vfunc impl. + (xml::element::get_attr): New decl. + (struct xml::comment): New xml::node subclass. + +2025-06-23 David Malcolm + + PR other/116792 + * diagnostic-format-html.cc (html_token_printer::print_tokens): + Handle pp_token::kind::event_id. + (selftest::test_token_printer): Add coverage of printing an event + id. + +2025-06-23 Pan Li + + * config/riscv/riscv-v.cc (expand_vx_binary_vec_dup_vec): Add + new case US_PLUS. + (expand_vx_binary_vec_vec_dup): Ditto. + * config/riscv/riscv.cc (riscv_rtx_costs): Ditto. + * config/riscv/vector-iterators.md: Add new op us_plus. + +2025-06-23 Jakub Jelinek + + PR middle-end/120608 + * tree-tailcall.cc (empty_eh_cleanup): Ignore .ASAN_MARK (POISON) + internal calls for the cfun->has_musttail case and diag_musttail. + (find_tail_calls): Likewise. + +2025-06-23 Jakub Jelinek + + PR middle-end/120608 + * cfgexpand.cc: Include rtl-iter.h. + (expand_gimple_tailcall): Add ASAN_EPILOG_SEQ argument, if non-NULL + and expand_gimple_stmt emitted a tail call, emit a copy of that + insn sequence before the call sequence. + (expand_gimple_basic_block): Remove DISABLE_TAIL_CALLS argument, add + ASAN_EPILOG_SEQ argument. Disable tail call flag only on non-musttail + calls if that flag is set, pass it to expand_gimple_tailcall. + (pass_expand::execute): Pass VAR_RET_SEQ directly as last + expand_gimple_basic_block argument rather than its comparison with + NULL. + +2025-06-23 Pengfei Li + + * tree-vect-data-refs.cc (vect_peeling_supportable): Return new + enum values to indicate if combined peeling and versioning can + potentially support vectorization. + (vect_enhance_data_refs_alignment): Support combined peeling and + versioning in vectorization analysis. + * tree-vect-loop-manip.cc (vect_create_cond_for_align_checks): + Add a new type of runtime check for mutually aligned DRs. + * tree-vect-loop.cc (_loop_vec_info::_loop_vec_info): Set + default value of allow_mutual_alignment in the initializer list. + * tree-vectorizer.h (enum peeling_support): Define type of + peeling support for function vect_peeling_supportable. + (LOOP_VINFO_ALLOW_MUTUAL_ALIGNMENT): New access macro. + +2025-06-23 Mikael Morin + + * match.pd (`-(-X)`, `~(~X)`, `conj(conj(X))`): Add a + NON_LVALUE_EXPR wrapper to the simplification of doubled unary + operators NEGATE_EXPR, BIT_NOT_EXPR and CONJ_EXPR. + +2025-06-23 Richard Biener + + PR tree-optimization/120729 + * gimple-predicate-analysis.h (uninit_analysis::prune_phi_opnds): + Add argument of work budget remaining. + * gimple-predicate-analysis.cc (uninit_analysis::prune_phi_opnds): + Likewise. Maintain and honor it throughout the recursion. + * params.opt (uninit-max-prune-work): New. + * doc/invoke.texi (uninit-max-prune-work): Document. + +2025-06-23 Richard Sandiford + + PR rtl-optimization/120721 + * function.cc (instantiate_virtual_regs_in_insn): Use force_subreg + instead of simplify_gen_subreg when instantiating an rvalue SUBREG. + +2025-06-23 H.J. Lu + + PR target/120728 + * config/i386/i386.cc (ix86_get_ssemov): Use vmovdqu16/vmovdqu8 + only with EVEX register operands. + +2025-06-23 H.J. Lu + + * config/i386/i386-options.cc (processor_cost_table): Add a + PROCESSOR_XXX comment to each entry. + +2025-06-22 Andrew Pinski + + PR target/119830 + * config/riscv/riscv.cc (riscv_build_integer_1): Make arithmetic in bclr case + clean for 32 bit hosts. + +2025-06-22 Jeff Law + + PR rtl-optimization/120550 + * ext-dce.cc (ext_dce_try_optimize_insn): Drop REG_EQUAL/REG_EQUIV + notes on modified insns. + +2025-06-22 Takayuki 'January June' Suwa + + * config/xtensa/xtensa.h (TARGET_DEPBITS): New macro. + * config/xtensa/xtensa.md (insvsi): New insn pattern. + +2025-06-22 Takayuki 'January June' Suwa + + * config/xtensa/xtensa.cc (xtensa_zero_call_used_regs): + New prototype and function. + (TARGET_ZERO_CALL_USED_REGS): Define macro. + +2025-06-22 Jan Hubicka + + * auto-profile.cc (update_count_by_afdo_count): Make static; + add variant accepting profile_count. + (afdo_find_equiv_class): Use update_count_by_afdo_count. + (afdo_propagate_edge): Likewise. + (afdo_propagate): Likewise. + (afdo_calculate_branch_prob): Fix handling of all_known. + (afdo_annotate_cfg): Annotate by 0 where both afdo and static + profile agrees. + +2025-06-22 Jan Hubicka + + * auto-profile.cc (afdo_set_bb_count): Dump inline stacks + and reasons when lookup failed. + (afdo_set_bb_count): Record info about BBs with zero AFDO count. + (afdo_annotate_cfg): Set profile to global0_afdo if there are + no samples in profile. + +2025-06-22 Jan Hubicka + + * ipa-profile.cc (ipa_profile): Use widest_int to avoid + possible overflows. + +2025-06-22 Jan Hubicka + + * auto-profile.cc (autofdo::afdo_count_scale): New. + (autofdo_source_profile::update_inlined_ind_target): Scale + counts. + (autofdo_source_profile::read): Set scale and dump + statistics. + (afdo_indirect_call): Scale. + (afdo_set_bb_count): Scale. + (afdo_find_equiv_class): Fix dumps. + (afdo_annotate_cfg): Scale. + +2025-06-22 Jan Hubicka + + * cgraph.cc (cgraph_node::make_profile_global0): Support + GUESSED_GLOBAL0_AFDO + * ipa-cp.cc (update_profiling_info): Use + GUESSED_GLOBAL0_AFDO. + * profile-count.cc (profile_probability::dump): Use + quality (). + (profile_probability::stream_in): Use m_adjusted_quality. + (profile_probability::stream_out): Use m_adjusted_quality. + (profile_count::combine_with_ipa_count): Use quality (). + (profile_probability::sqrt): Likewise. + * profile-count.h (enum profile_quality): Add + GUESSED_GLOBAL0_AFDO; reoder GUESSED_GLOBAL0_ADJUSTED and + GUESSED_GLOBAL0. + (profile_probability): Add min_quality; replase m_quality + by m_adjused_quality; add set_quality; update all users + of quality. + (profile_count): Set n_bits to 60; make m_quality 4 bits; + update uses of quality. + (profile_count::afdo_zero, profile_count::globa0afdo): New. + +2025-06-21 Jan Hubicka + + * tree-inline.cc (copy_cfg_body): Fix profile of split functions. + +2025-06-21 Jeff Law + + PR target/118241 + * config/riscv/predicates.md (prefetch_operand): New predicate. + * config/riscv/constraints.md (Q): New constraint. + * config/riscv/riscv.md (prefetch): Use new predicate and constraint. + (riscv_prefetchi_): Similarly. + +2025-06-21 Jakub Jelinek + + PR middle-end/120746 + * value-range.cc (irange::snap): Use int type instead of uint. + +2025-06-21 Jan Hubicka + + * auto-profile.cc (dump_inline_stack): New function. + (get_inline_stack_in_node): New function. + (get_relative_location_for_stmt): Add FN parameter. + (has_indirect_call): Remove. + (function_instance::find_icall_target_map): Add FN parameter. + (function_instance::remove_icall_target): New function. + (function_instance::read_function_instance): Set sum_max. + (autofdo_source_profile::get_count_info): Add NODE parameter. + (autofdo_source_profile::update_inlined_ind_target): Add NODE parameter. + (autofdo_source_profile::remove_icall_target): New function. + (afdo_indirect_call): Add INDIRECT_EDGE parameter; dump reason + for failure; do not check for recursion; do not inline call. + (afdo_vpt): Add INDIRECT_EDGE parameter. + (afdo_set_bb_count): Do not take PROMOTED set. + (afdo_vpt_for_early_inline): Remove. + (afdo_annotate_cfg): Do not take PROMOTED set. + (auto_profile): Do not call afdo_vpt_for_early_inline. + (afdo_callsite_hot_enough_for_early_inline): Dump count. + (remove_afdo_speculative_target): New function. + * auto-profile.h (afdo_vpt_for_early_inline): Declare. + (remove_afdo_speculative_target): Declare. + * ipa-inline.cc (inline_functions_by_afdo): Do VPT. + (early_inliner): Redirecct edges if inlining happened. + * tree-inline.cc (expand_call_inline): Add sanity check. + +2025-06-21 Jan Hubicka + + * auto-profile.cc (get_inline_stack): Add fn parameter. + * ipa-inline.cc (want_early_inline_function_p): Do not care + about AFDO. + (inline_functions_by_afdo): New function. + (early_inliner): Use it. + +2025-06-21 Pan Li + + PR target/120652 + * config/riscv/autovec.md: Add immediate_operand for + select_vl operand 2. + +2025-06-20 Andrew MacLeod + + PR tree-optimization/120701 + * value-range.cc (irange::verify_range): Verify range pairs are + sorted properly. + (irange::snap): Check for over/underflow properly. + +2025-06-20 Andrew Stubbs + + PR target/120722 + * config/gcn/gcn.cc (gcn_hard_regno_mode_ok): Allow SImode in VCC_HI. + +2025-06-20 Jørgen Kvalsvik + + PR gcov-profile/120634 + * prime-paths.cc (struct auto_vec_vec): Add constructor from + vec. + (test_split_components): Use auto_vec_vec. + (test_scc_internal_prime_paths): Ditto. + (test_scc_entry_exit_paths): Ditto. + (test_complete_prime_paths): Ditto. + (test_entry_prime_paths): Ditto. + (test_singleton_path): Ditto. + +2025-06-20 Jørgen Kvalsvik + + PR gcov-profile/120634 + * prime-paths.cc (trie::paths): Use auto_vec. + +2025-06-20 Richard Biener + + PR tree-optimization/120654 + * vr-values.cc (range_fits_type_p): Check for undefined_p () + before accessing type (). + +2025-06-20 H.J. Lu + + PR target/120708 + * config/i386/i386-expand.cc (ix86_expand_set_or_cpymem): Use + MOVE_MAX to get the widest vector mode in vector loop. + +2025-06-20 Stafford Horne + + * config/or1k/or1k.cc (or1k_noce_conversion_profitable_p): New + function. + (or1k_is_cmov_insn): New function. + (TARGET_NOCE_CONVERSION_PROFITABLE_P): Define macro. + * config/or1k/or1k.md (cbranchsi4): Convert to insn_and_split. + (cbranch4): Convert to insn_and_split. + +2025-06-20 Stafford Horne + + PR target/120587 + * config/or1k/or1k.md (zero_extendbisi2_sr_f): New expand. + (extendbisi2_sr_f): New expand. + * config/or1k/predicates.md (sr_f_reg_operand): New predicate. + +2025-06-20 Pan Li + + * config/riscv/riscv-v.cc (expand_vx_binary_vec_dup_vec): Add + new case UMIN. + (expand_vx_binary_vec_vec_dup): Ditto. + * config/riscv/riscv.cc (riscv_rtx_costs): Ditto. + * config/riscv/vector-iterators.md: Add new op umin. + +2025-06-19 Jakub Jelinek + + PR target/120689 + * function.cc (assign_parm_setup_block): Align parm to at least + word alignment even on !STRICT_ALIGNMENT targets, as long as + BITS_PER_WORD is not larger than MAX_SUPPORTED_STACK_ALIGNMENT. + +2025-06-19 H.J. Lu + + PR target/120427 + * config/i386/i386.md (*mov_and): Changed to + define_insn_and_split. Split it to "mov $0,mem" if not -Oz. + (*mov_or): Changed to define_insn_and_split. Split it + to "mov $-1,mem" if not -Oz. + (peephole2): Don't transform "mov $-1,reg" to "push $-1; pop reg" + for -Oz since it will be transformed to "or $-1,reg". + +2025-06-19 Georg-Johann Lay + + PR other/115893 + * doc/install.texi (Prerequisites): Note that Texinfo older + than v7.1 may throw incorrect build warnings, cf. + https://lists.nongnu.org/archive/html/help-texinfo/2023-11/msg00004.html + +2025-06-19 Dongyan Chen + + * config/riscv/riscv-cores.def (RISCV_TUNE): Add "generic" tune. + * config/riscv/riscv.cc: Add generic_tune_info. + * config/riscv/riscv.h (RISCV_TUNE_STRING_DEFAULT): Change default tune. + +2025-06-19 Jakub Jelinek + + PR middle-end/120631 + * dfp.cc (decimal_real_to_integer): Use result multiplication not just + when precision > 128 and dn.exponent > 19, but when precision > 64 + and dn.exponent > 0. + +2025-06-19 Kito Cheng + + * config/riscv/riscv.cc (riscv_legitimize_move): Use + riscv_2x_xlen_mode_p. + (riscv_binary_cost): Ditto. + (riscv_hard_regno_mode_ok): Ditto. + +2025-06-19 Kito Cheng + + * config/riscv/riscv.cc (riscv_cost_model): Add cost model for + zilsd. + +2025-06-19 Lili Cui + + PR target/120697 + * config/i386/i386.cc (ix86_expand_prologue): + Remove 3 assertions and associated code. + +2025-06-18 Dimitar Dimitrov + Richard Sandiford + Andrew Pinski + + PR target/119966 + * emit-rtl.cc (validate_subreg): Call simplify_subreg_regno + instead of checking info.representable_p.. + * rtl.h (simplify_subreg_regno): Add new argument + allow_stack_regs. + * rtlanal.cc (simplify_subreg_regno): Do not reject + stack-related registers if allow_stack_regs is true. + +2025-06-18 Andrew MacLeod + + * value-range.cc (irange::intersect_bitmask): Always update the + stored mask to reflect the current calculated mask. + +2025-06-18 Andrew MacLeod + + PR tree-optimization/119039 + * value-range.cc (irange::contains_p): Call wide_int version of + contains_p for singleton ranges. + (irange::intersect): If either range is a singleton, use + contains_p. + +2025-06-18 Andrew MacLeod + + PR tree-optimization/119039 + * vr-values.cc (simplify_using_ranges::legacy_fold_cond): Remove. + (simplify_using_ranges::simplify_switch_using_ranges): Adjust. + +2025-06-18 Richard Biener + + * tree-cfg.cc (dump_function_to_file): Use flags, not dump_flags. + +2025-06-18 Jan Beulich + + * doc/gcov.texi: Drop blank after @anchor. + +2025-06-18 Jan Beulich + + * doc/extend.texi: Fill first argument of @xref{}. + +2025-06-18 Jakub Jelinek + + PR middle-end/120631 + * real.cc (decimal_from_integer): Add digits argument, if larger than + 256, use XALLOCAVEC allocated buffer. + (real_from_integer): Pass val_in's precision divided by 3 to + decimal_from_integer. + * dfp.cc (decimal_real_to_integer): For precision > 128 if finite + and exponent is large, decrease exponent and multiply resulting + wide_int by powers of 10^19. + +2025-06-18 Pan Li + + * config/riscv/riscv-v.cc (expand_vx_binary_vec_dup_vec): Add + new case SMIN. + (expand_vx_binary_vec_vec_dup): Ditto. + * config/riscv/riscv.cc (riscv_rtx_costs): Ditto. + * config/riscv/vector-iterators.md: Add new op smin. + +2025-06-18 Lili Cui + Michael Matz + + * config/i386/i386-protos.h (ix86_get_separate_components): + New function. + (ix86_components_for_bb): Likewise. + (ix86_disqualify_components): Likewise. + (ix86_emit_prologue_components): Likewise. + (ix86_emit_epilogue_components): Likewise. + (ix86_set_handled_components): Likewise. + * config/i386/i386.cc (save_regs_using_push_pop): + Split from ix86_compute_frame_layout. + (ix86_compute_frame_layout): + Use save_regs_using_push_pop. + (pro_epilogue_adjust_stack): + Use gen_pro_epilogue_adjust_stack_add_nocc. + (ix86_expand_prologue): Add some assertions and adjust + the stack frame at the beginning of the prolog for shrink + wrapping separate. + (ix86_emit_save_regs_using_mov): + Skip registers that are wrapped separately. + (ix86_emit_restore_regs_using_mov): Likewise. + (ix86_expand_epilogue): Add some assertions and set + restore_regs_via_mov to true for shrink wrapping separate. + (ix86_get_separate_components): New function. + (ix86_components_for_bb): Likewise. + (ix86_disqualify_components): Likewise. + (ix86_emit_prologue_components): Likewise. + (ix86_emit_epilogue_components): Likewise. + (ix86_set_handled_components): Likewise. + (TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS): Define. + (TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB): Likewise. + (TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS): Likewise. + (TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS): Likewise. + (TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS): Likewise. + (TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS): Likewise. + * config/i386/i386.h (struct machine_function):Add + reg_is_wrapped_separately array for register wrapping + information. + * config/i386/i386.md + (@pro_epilogue_adjust_stack_add_nocc): New. + +2025-06-18 Andrew MacLeod + + PR tree-optimization/120661 + * value-range.cc (irange::snap): New. + (irange::snap_subranges): New. + (irange::set_range_from_bitmask): Call snap_subranges. + * value-range.h (snap, snap_subranges): New prototypes. + +2025-06-17 Jan Hubicka + + * auto-profile.cc (afdo_indirect_call): Compute speculative edge + probability. + (add_scale): Break out from ... + (scale_bbs): Break out from ... + (afdo_adjust_guessed_profile): ... here; use componet array instead of + current_component hash_map; handle components with only 0 profile; + be more agressive on finding scales along the boundary. + +2025-06-17 Jan Hubicka + + * cgraph.cc (cgraph_node::apply_scale): Special case scaling + to profile_count::zero (). + (cgraph_node::verify_node): Add extra compatibility check. + +2025-06-17 Umesh Kalappa + + * config/riscv/sync.md (lrsc_atomic_exchange): Use scratch + register for loop control rather than lr output. + +2025-06-17 Jason Merrill + + * diagnostic.h (diagnostic_option_classifier): Friend + diagnostic_context. + (diagnostic_context::get_classification_history): New. + +2025-06-17 Jakub Jelinek + + PR tree-optimization/120677 + * gimple-crc-optimization.cc (crc_optimization::optimize_crc_loop): + Insert before gsi_after_labels instead of gsi_start_bb. Use + gimple_bb (output_crc) instead of output_crc->bb. Formatting fix. + +2025-06-17 Richard Sandiford + + PR target/113027 + * config/aarch64/aarch64-protos.h (aarch64_decompose_vec_struct_index): + Declare. + * config/aarch64/aarch64.cc (aarch64_decompose_vec_struct_index): New + function. + * config/aarch64/iterators.md (VEL, Vel): Add Advanced SIMD + structure modes. + * config/aarch64/aarch64-simd.md (vec_set) + (vec_extract): New patterns. + +2025-06-17 Tobias Burnus + + * omp-offload.cc (omp_discover_declare_target_tgt_fn_r): Also + walk external functions that are declare inline (and have a + DECL_SAVED_TREE). + +2025-06-16 Spencer Abson + + * config/aarch64/aarch64-protos.h (aarch64_sve_valid_pred_p): + Declare helper for aarch64_predicate_operand. + (aarch64_sve_packed_pred): Declare helper for new expanders. + (aarch64_sve_fp_pred): Likewise. + * config/aarch64/aarch64-sve.md (2): + Extend into... + (2): New expander for converting + vectors of HF,SF to vectors of HI,SI,DI. + (2): New expander for converting + vectors of SI,DI to vectors of DF. + (*aarch64_sve__nontrunc): + New pattern to match those we've added here. + (@aarch64_sve__trunc): Extend + into... + (@aarch64_sve__trunc): Match both + VNx2SI<-VNx2DF and VNx4SI<-VNx4DF. + (2): Extend into... + (2): New expander for converting vectors + of HI,SI,DI to vectors of HF,SF,DF. + (*aarch64_sve__nonextend): New + pattern to match those we've added here. + (trunc2): New expander to handle + narrowing ('truncating') FP<-FP conversions. + (*aarch64_sve__trunc): New + pattern to handle those we've added here. + (extend2): New expander to handle + widening ('extending') FP<-FP conversions. + (*aarch64_sve__nontrunc): New + pattern to handle those we've added here. + * config/aarch64/aarch64.cc (aarch64_sve_packed_pred): New function. + (aarch64_sve_fp_pred): Likewise. + (aarch64_sve_valid_pred_p): Likewise. + * config/aarch64/iterators.md (SVE_PARTIAL_HSF): New mode iterator. + (SVE_HSF): Likewise. + (SVE_SDF): Likewise. + (SVE_SI): Likewise. + (SVE_2SDI) Likewise. + (self_mask): Extend to all integer/FP vector modes. + (narrower_mask): Likewise (excluding QI). + * config/aarch64/predicates.md (aarch64_predicate_operand): New special + predicate to handle narrower predicate modes. + +2025-06-16 Spencer Abson + + * config/aarch64/aarch64-sve.md: Replace uses of SVE_FULL_F_BF + with SVE_FULL_F_B16B16. + Replace use of SVE_F with SVE_F_BF. + * config/aarch64/iterators.md (SVE_PARTIAL_F): New iterator for + partial SVE FP modes. + (SVE_FULL_F_BF): Rename to SVE_FULL_F_B16B16. + (SVE_PARTIAL_F_B16B16): New iterator (BF16 included) for partial + SVE FP modes. + (SVE_F_B16B16): New iterator for all SVE FP modes. + (SVE_BF): New iterator for all SVE BF16 modes. + (SVE_F): Redefine to exclude BF16 modes. + (SVE_F_BF): New iterator to replace the previous SVE_F. + (VPRED): Describe the VPRED mapping for partial vector modes. + (b): Cover partial FP modes. + (is_bf16): Likewise. + +2025-06-16 Jason Merrill + + * doc/invoke.texi: Document -Wsfinae-incomplete. + +2025-06-16 Matthieu Longo + Srinath Parvathaneni + + * config.in: Regenerate. + * config/aarch64/aarch64-elf-metadata.h + (class aeabi_subsection): New class for BAs. + * config/aarch64/aarch64-protos.h + (aarch64_pacret_enabled): New function. + * config/aarch64/aarch64.cc + (HAVE_AS_AEABI_BUILD_ATTRIBUTES): New definition. + (aarch64_file_end_indicate_exec_stack): Emit BAss. + (aarch64_pacret_enabled): New function. + (aarch64_start_file): Indent. + * configure: Regenerate. + * configure.ac: New configure check for BAs support in binutils. + +2025-06-16 Matthieu Longo + + * Makefile.in: Add missing declaration of BACKEND_H. + * config.gcc: Add aarch64-elf-metadata.o to extra_objs. + * config/aarch64/aarch64-elf-metadata.h: New file + * config/aarch64/aarch64-elf-metadata.cc: New file. + * config/aarch64/aarch64.cc + (GNU_PROPERTY_AARCH64_FEATURE_1_AND): Removed. + (GNU_PROPERTY_AARCH64_FEATURE_1_BTI): Likewise. + (GNU_PROPERTY_AARCH64_FEATURE_1_PAC): Likewise. + (GNU_PROPERTY_AARCH64_FEATURE_1_GCS): Likewise. + (aarch64_file_end_indicate_exec_stack): Move GNU properties code to + aarch64-elf-metadata.cc + * config/aarch64/t-aarch64: Declare target aarch64-elf-metadata.o + +2025-06-16 Matthieu Longo + + * config/aarch64/aarch64.cc + (aarch64_file_end_indicate_exec_stack): Emit assembly comments. + +2025-06-16 Jan Hubicka + + * auto-profile.cc (edge_set): Remove unused typedef. + (is_bb_annotated): Sanity check that annotated BBs has + quality AFDO and non-anntoated non-AFDO. Exceptions are + zeros. + (set_bb_annotated): Verify that BB set annotated has + AFDO profile. + (afdo_set_bb_count): Do not return true for 0 counts. + (afdo_find_equiv_class): Fix formating; + do not combine profile of annoated and non-annotated BBs. + (afdo_propagate_edge): Fix variable names; dump info + about changes; do not change non-annoated BB profiles; + if all flow out of BB was decided on, annotate remaining + edges with 0. + (afdo_propagate): Dump info about copied BB counts + and number of iteraitons used. + (cmp): New function. + (afdo_adjust_guessed_profile): New function. + (afdo_calculate_branch_prob): Do not initialize loop + optimizer here; call afdo_adjust_guessed_profile. + (afdo_annotate_cfg): Initialize profile here; + anotate entry/exit blocks only of profile is non-0. + * profile-count.h: (profile_count::force_guessed): New. + * tree-cfg.cc (gimple_verify_flow_info): Fix typo. + +2025-06-16 Jiawei + + * common/config/riscv/riscv-common.cc: Add b-ext and supm. + +2025-06-16 Takayuki 'January June' Suwa + + * config/xtensa/predicates.md (reload_operand): + Remove. + * config/xtensa/xtensa.md: + Remove the peephole2 pattern that was previously added. + +2025-06-16 Takayuki 'January June' Suwa + + * config/xtensa/xtensa.md: + Remove the peephole2 pattern that was previously added. + +2025-06-16 Jiawei + + * simplify-rtx.cc (simplify_context::simplify_binary_operation_1): Handle + more logical simplifications. + +2025-06-15 Pan Li + + * config/riscv/riscv-v.cc (expand_vx_binary_vec_dup_vec): Add new + case UMAX. + (expand_vx_binary_vec_vec_dup): Ditto. + * config/riscv/riscv.cc (riscv_rtx_costs): Ditto. + * config/riscv/vector-iterators.md: Add new op umax. + +2025-06-14 Georg-Johann Lay + + Backported from master: + 2025-06-14 Georg-Johann Lay + + PR rtl-optimization/120423 + PR rtl-optimization/116389 + * config/avr/avr.md [-mno-lra]: Add pre-reload split to transform + (left shift of) a paradoxical subreg to a (left shift of) zero-extend. + +2025-06-13 Jakub Jelinek + + PR middle-end/120629 + * cfgexpand.cc (expand_split_edge): New function. + (expand_gimple_cond, construct_init_block): Use it. + +2025-06-13 Spencer Abson + + PR target/118150 + * config/aarch64/aarch64-sve.md (*one_cmpl3_cc): New + combiner pattern. + (*one_cmpl3_ptest): Likewise. + +2025-06-13 Jakub Jelinek + + PR middle-end/120629 + * cfgexpand.cc (construct_init_block): If first_block isn't BB_RTL, + has any PHI nodes and false_edge->dest_idx before redirection is + different from make_single_succ_edge result's dest_idx, swap the + latter with the former last pred edge and their dest_idx members. + +2025-06-13 Kito Cheng + + * gcc.cc (driver::set_up_specs): Use gcc_exec_prefix to + read the spec file rather than standard_exec_prefix. + +2025-06-13 H.J. Lu + + PR target/120589 + * config/mcore/mcore.cc (mcore_mark_dllimport): Don't use + gen_rtx_MEM. + +2025-06-12 Jakub Jelinek + + PR tree-optimization/120638 + * tree-ssa-math-opts.cc (pass_cse_reciprocals::execute): Call + reset_flow_sensitive_info on arg1. + +2025-06-12 Stafford Horne + + PR target/120587 + * config/or1k/or1k.cc (or1k_can_change_mode_class): Allow + changing flags mode from BI to SI to allow for paradoxical + subregs. + +2025-06-12 Uros Bizjak + + PR target/120604 + * config/i386/i386-expand.cc (ix86_expand_int_movcc): Make sure + we can represent the difference between two 64-bit DImode + immediate values in 64-bit HOST_WIDE_INT. + +2025-06-12 Jakub Jelinek + + PR middle-end/120629 + * cfgexpand.cc (expand_gimple_cond): If dest bb isn't BB_RTL, + has any PHI nodes and false_edge->dest_idx before redirection is + different from make_single_succ_edge result's dest_idx, swap the + latter with the former last pred edge and their dest_idx members. + +2025-06-12 Pan Li + + * config/riscv/riscv-v.cc (expand_vx_binary_vec_dup_vec): Add new + case SMAX. + (expand_vx_binary_vec_vec_dup): Ditto. + * config/riscv/riscv.cc (riscv_rtx_costs): Ditto. + * config/riscv/vector-iterators.md: Add new op smax. + +2025-06-12 Richard Sandiford + + PR target/120624 + * config/aarch64/aarch64.md (SME_STATE_REGNUM): Expand on comments. + * config/aarch64/aarch64-sme.md (aarch64_restore_za): Also set + SME_STATE_REGNUM + +2025-06-12 Alfie Richards + + * cgraph.cc (cgraph_node::record_function_versions): Refactor and + rename to... + (cgraph_node::add_function_version): new function. + * cgraph.h (cgraph_node::record_function_versions): Refactor and + rename to... + (cgraph_node::add_function_version): new function. + * config/aarch64/aarch64.cc (aarch64_get_function_versions_dispatcher): + Remove reordering. + * config/i386/i386-features.cc (ix86_get_function_versions_dispatcher): + Remove reordering. + * config/riscv/riscv.cc (riscv_get_function_versions_dispatcher): + Remove reordering. + * config/rs6000/rs6000.cc (rs6000_get_function_versions_dispatcher): + Remove reordering. + +2025-06-12 Alfie Richards + + * attribs.cc (is_function_default_version): Add target_version logic. + +2025-06-12 Hu, Lin1 + + * config/i386/x86-tune-sched.cc (ix86_issue_rate): Set 4 for SRF, + 6 for GRR, GNR, CWF, DMR, ARL, PTL. + +2025-06-11 David Malcolm + + PR other/116792 + * diagnostic-format-html.cc: Include "selftest-xml.h". + (html_builder::make_element_for_diagnostic): Move... + (class html_token_printer): ...from local to the function + to the global namespace. + (struct selftest::token_printer_test): New. + (selftest::test_token_printer): New. + (selftest::test_simple_log): Simplify using ASSERT_XML_PRINT_EQ. + (selftest::test_metadata): Likewise. + (selftest::diagnostic_format_html_cc_tests): Run the new test. + * selftest-xml.h: New file. + * xml.cc: Include "selftest-xml.h". + (selftest::assert_xml_print_eq): New. + (selftest::test_no_dtd): Simplify using ASSERT_XML_PRINT_EQ. + (selftest::test_printer): Likewise. + (selftest::test_attribute_ordering): Likewise. + +2025-06-11 Edwin Lu + + * config/riscv/riscv.cc (struct riscv_tune_param): Add tune + param. + (riscv_sched_can_speculate_insn): Implement. + (TARGET_SCHED_CAN_SPECULATE_INSN): Ditto. + +2025-06-11 Uros Bizjak + + PR target/120604 + * config/i386/i386-expand.cc (ix86_expand_int_movcc): Cast operands of + signed 64-bit HOST_WIDE_INT subtractions to (unsigned HOST_WIDE_INT). + +2025-06-11 Paul-Antoine Arras + + PR target/119100 + * config/riscv/autovec-opt.md (*_vf_): Only handle vfmadd + and vfmsub. + (*vfnmsub_): New pattern. + (*vfnmadd_): New pattern. + * config/riscv/riscv.cc (get_vector_binary_rtx_cost): Add cost model for + NEG and VEC_DUPLICATE. + +2025-06-11 Jakub Jelinek + + PR middle-end/120434 + * gimple-range-fold.cc: Include rtl.h. + (fold_using_range::range_of_range_op): Handle bb ending with + GIMPLE_COND during RTL expansion where there is only one succ + edge instead of two. + +2025-06-11 Jakub Jelinek + + * internal-fn.cc (expand_POPCOUNT): Use + expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE) instead of + expand_normal (lhs). + +2025-06-11 David Malcolm + + PR other/116792 + * diagnostic-format-html.cc: Include "diagnostic-path.h" and + "diagnostic-client-data-hooks.h". + (html_builder::m_logical_loc_mgr): New field. + (html_builder::m_cur_nesting_levels): New field. + (html_builder::m_last_logical_location): New field. + (html_builder::m_last_location): New field. + (html_builder::m_last_expanded_location): New field. + (HTML_STYLE): Add "white-space: pre;" to .source and .annotation. + Add "gcc-quoted-text" CSS class. + (html_builder::html_builder): Initialize the new fields. If CSS + is enabled, add CDN links to PatternFly 3 stylesheets. + (html_builder::add_stylesheet): New. + (html_builder::on_report_diagnostic): Add "alert" param to + make_element_for_diagnostic, setting it by default, but unsetting + it for nested diagnostics below the top level. Use + add_at_nesting_level for nested diagnostics. + (add_nesting_level_attr): New. + (html_builder::add_at_nesting_level): New. + (get_pf_class_for_alert_div): New. + (get_pf_class_for_alert_icon): New. + (get_label_for_logical_location_kind): New. + (add_labelled_value): New. + (html_builder::make_element_for_diagnostic): Add leading comment. + Add "alert" param. Drop class="gcc-diagnostic" from
tag, + instead adding the class for a PatternFly 3 alert if "alert" is + true, and adding a with an alert icon, both according to + the diagnostic severity. Add a severity prefix to the message for + alerts. Add any metadata/option text as suffixes to the message. + Show any logical location. Show any physical location. Don't + show the locus if the last location is unchanged within the + diagnostic_group. Wrap any execution path element in a +
and add a label to it. Wrap any + generated patch in a
and add a label + to it. + (selftest::test_simple_log): Update expected HTML. + +2025-06-11 David Malcolm + + * diagnostic-path-output.cc: Use xml::printer::add_text_from_pp. + * diagnostic-show-locus.cc: Likewise. + * xml-printer.h (xml::printer::add_text_from_pp): New decl. + * xml.cc (xml::node_with_children::add_text_from_pp): New. + (xml::printer::add_text_from_pp): New. + * xml.h (xml::node_with_children::add_text_from_pp): New decl. + +2025-06-11 David Malcolm + + PR other/120610 + * diagnostic-format-html.cc (html_builder::html_builder): Update + for new param of xml::printer::pop_tag. + (html_path_label_writer::end_label): Likewise. + (html_builder::make_element_for_diagnostic::html_token_printer): + Give the instance its own xml::printer. Update for new param of + xml::printer::pop_tag. + (html_builder::make_element_for_diagnostic): Give the instance its + own xml::printer. + (html_builder::make_metadata_element): Update for new param of + xml::printer::pop_tag. + (html_builder::flush_to_file): Likewise. + * diagnostic-path-output.cc (begin_html_stack_frame): Likewise. + (begin_html_stack_frame): Likewise. + (end_html_stack_frame): Likewise. + (print_path_summary_as_html): Likewise. + * diagnostic-show-locus.cc + (struct to_text::auto_check_tag_nesting): New. + (struct to_html:: auto_check_tag_nesting): New. + (to_text::pop_html_tag): Change param to const char *. + (to_html::pop_html_tag): Likewise; rename param to + "expected_name". + (default_diagnostic_start_span_fn): Update for new param + of xml::printer::pop_tag. + (layout_printer::end_label): Likewise. + (layout_printer::print_trailing_fixits): Add RAII sentinel + to check tag nesting for the HTML case. Delete stray popping + of "td" in the presence of fix-it hints. + (layout_printer::print_line): Add RAII sentinel + to check tag nesting for the HTML case. + (diagnostic_source_print_policy::print_as_html): Likewise. + (layout_printer::print): Likewise. + * xml-printer.h (xml::printer::printer): Add optional + "check_popped_tags" param. + (xml::printer::pop_tag): Add "expected_name" param. + (xml::printer::get_num_open_tags): New accessor. + (xml::printer::dump): New decl. + (xml::printer::m_check_popped_tags): New field. + (class xml::auto_check_tag_nesting): New. + (class xml::auto_print_element): Update for new param of pop_tag. + * xml.cc: Move pragma pop so that the pragma also covers + xml::printer's member functions, "dump" in particular. + (xml::printer::printer): Add param "check_popped_tags". + (xml::printer::pop_tag): Add param "expected_name" and use it to assert + that the popped tag is as expected. Assert that we have a tag to + pop. + (xml::printer::dump): New. + (selftest::test_printer): Update for new param of pop_tag. + (selftest::test_attribute_ordering): Likewise. + +2025-06-11 David Malcolm + + * gimple-ssa-warn-access.cc + (pass_waccess::maybe_check_dealloc_call): Add missing + auto_diagnostic_group to nest the "returned from %qD" + note within the warning. + +2025-06-10 Jan Hubicka + + * cgraph.cc (cgraph_node::make_profile_local): New member function. + (cgraph_node::make_profile_global0): New member function. + (cgraph_node::apply_scale): Do not call adjust_for_ipa_scalling. + (cgraph_node::scale_profile_to): New member function. + * cgraph.h (cgraph_node::make_profile_local, + cgraph_node::make_profile_global0, cgraph_node::scale_profile_to): + Declare. + * ipa-cp.cc (lenient_count_portion_handling): Fix logic dropping count + to local. + (update_counts_for_self_gen_clones): Use scale_profile_to. + (update_profiling_info): Use make_profile_local, make_profile_global0 + and scale_profile_to. + (update_specialized_profile): Likewise. + * ipa-inline-transform.cc (clone_inlined_nodes): Call + adjust_for_ipa_scalling. + +2025-06-10 Jakub Jelinek + + PR middle-end/120434 + * expr.cc (expand_expr_real_2) : If get_range_pos_neg + at -O2 for scalar integer extension suggests the most significant + bit of op0 is not set, try both unsigned and signed conversion and + choose the cheaper one. If both are the same cost, choose one + based on TYPE_UNSIGNED (TREE_TYPE (treeop0)). + +2025-06-10 Jakub Jelinek + + PR middle-end/120434 + * config/i386/i386.md (*bsr_rex64_2): Rename to ... + (*bsr_rex64_2): ... this. Use any_extend instead of sign_extend. + (*bsr_2): Rename to ... + (*bsr_2): ... this. Use any_extend instead of sign_extend. + (bsr splitters after those): Use any_extend instead of sign_extend. + +2025-06-10 Jakub Jelinek + + PR middle-end/120434 + * cfgrtl.h (update_bb_for_insn_chain): Declare. + * cfgrtl.cc (update_bb_for_insn_chain): No longer static. + * cfgexpand.h (expand_remove_edge): Declare. + * cfgexpand.cc: Include "gimple-range.h". + (head_end_for_bb): New variable. + (label_rtx_for_bb): Drop ATTRIBUTE_UNUSED from bb argument. + Use head_end_for_bb if possible for non-BB_RTL bbs. + (expand_remove_edge): New function. + (maybe_cleanup_end_of_block): Use it instead of remove_edge. + (expand_gimple_cond): Don't clear EDGE_TRUE_VALUE and + EDGE_FALSE_VALUE just yet. Use head_end_for_bb elts instead + of BB_END and update_bb_for_insn_chain instead of update_bb_for_insn. + (expand_gimple_tailcall): Use expand_remove_edge instead of + remove_edge. Use head_end_for_bb elts instead of BB_END and + update_bb_for_insn_chain instead of update_bb_for_insn. + (expand_gimple_basic_block): Don't change bb to BB_RTL here, instead + use head_end_for_bb elts instead of BB_HEAD and BB_END. Use + update_bb_for_insn_chain instead of update_bb_for_insn. + (pass_expand::execute): Enable ranger before expand_gimple_basic_block + calls and create head_end_for_bb vector. Disable ranger after + those calls, turn still non-BB_RTL blocks into BB_RTL and set their + BB_HEAD and BB_END from head_end_for_bb elts, and clear EDGE_TRUE_VALUE + and EDGE_FALSE_VALUE flags on edges. Release head_end_for_bb + vector. + * tree-outof-ssa.cc (expand_phi_nodes): Don't clear phi nodes here. + * tree.h (get_range_pos_neg): Add gimple * argument defaulted to NULL. + * tree.cc (get_range_pos_neg): Add stmt argument. Use + get_range_query (cfun) instead of get_global_range_query () and pass + stmt as third argument to range_of_expr. + * expr.cc (expand_expr_divmod): Pass currently_expanding_gimple_stmt + to get_range_pos_neg. + (expand_expr_real_1) : Change internal fn handling + to avoid temporarily overwriting gimple_call_lhs of ifn, instead + temporarily overwrite SSA_NAME_VAR of its lhs. + (maybe_optimize_pow2p_mod_cmp): Pass currently_expanding_gimple_stmt + to get_range_pos_neg. + (maybe_optimize_mod_cmp): Likewise. + * internal-fn.cc (get_min_precision): Likewise. Use + get_range_query (cfun) instead of get_global_range_query () and pass + currently_expanding_gimple_stmt as third argument to range_of_expr. + Pass g to get_range_pos_neg. + (expand_addsub_overflow): Pass currently_expanding_gimple_stmt + to get_range_pos_neg. + (expand_mul_overflow): Likewise. + (expand_arith_overflow): Pass stmt to get_range_pos_neg. + * gimple-range-edge.cc: Include rtl.h. + (gimple_outgoing_range_stmt_p): Return NULL for BB_RTL bbs. + (gimple_outgoing_range::calc_switch_range): If default_edge is NULL, + assert currently_expanding_to_rtl and return before trying to + set range on that edge. + * builtins.cc (expand_builtin_strnlen): Use get_range_query (cfun) + instead of get_global_range_query () and pass + currently_expanding_gimple_stmt as third argument to range_of_expr. + (determine_block_size): Likewise. + * gimple-range.cc (gimple_ranger::range_on_exit): Set s to NULL + instead of last_nondebug_stmt for BB_RTL bbs. + * stmt.cc: Include cfgexpand.h. + (expand_case): Use expand_remove_edge instead of remove_edge. + +2025-06-10 Andrew MacLeod + + * value-range.cc (irange::set_range_from_bitmask): When the bitmask + result is a singleton, check if it is contained in the range. + +2025-06-10 Tobias Burnus + + * config/gcn/gcn-devices.def: Add gfx942, gfx950 and gfx9-4-generic. + * config/gcn/gcn-opts.h (TARGET_CDNA3, TARGET_CDNA3_PLUS, + TARGET_GLC_NAME, TARGET_TARGET_SC_CACHE): Define. + (TARGET_ARCHITECTED_FLAT_SCRATCH): Use also for CDNA3. + * config/gcn/gcn.h (gcn_isa): Add ISA_CDNA3 to the enum. + * config/gcn/gcn.cc (print_operand): Update 'g' to use + TARGET_GLC_NAME; add 'G' to print TARGET_GLC_NAME unconditionally. + * config/gcn/gcn-valu.md (scatter, gather): Use TARGET_GLC_NAME. + * config/gcn/gcn.md: Use %G instead of glc; use 'buffer_inv sc1' + for TARGET_TARGET_SC_CACHE. + * doc/invoke.texi (march): Add gfx942, gfx950 and gfx9-4-generic. + * doc/install.texi (amdgcn*-*-*): Add gfx942, gfx950 and gfx9-4-generic. + * config/gcn/gcn-tables.opt: Regenerate. + +2025-06-10 Jeff Law + + * config/riscv/riscv.md (lui-constraintand_to_or): Do not use + the RTL template for split code. Emit it directly taking care to avoid + emitting a constant load that needed synthesis. Fix formatting. + +2025-06-10 Kito Cheng + + * doc/riscv-ext.texi: Regen. + +2025-06-10 Pan Li + + * config/riscv/riscv-v.cc (expand_vx_binary_vec_vec_dup): Add new + case UMOD. + * config/riscv/riscv.cc (riscv_rtx_costs): Ditto. + * config/riscv/vector-iterators.md: Add new op umod. + +2025-06-09 David Malcolm + + * diagnostic-format-sarif.cc (maybe_get_sarif_kind): Update for + conversion of enum logical_location_kind to enum class. + * diagnostic.cc (logical_location_manager::function_p): Likewise. + * libgdiagnostics.cc (html-output/missing-semicolon.py::get_kind): + Likewise. + * logical-location.h (enum logical_location_kind): Convert to... + (enum class logical_location_kind): ...this. + * selftest-logical-location.cc + (test_logical_location_manager::item_from_funcname): Update for + conversion of enum logical_location_kind to enum class. + * tree-logical-location.cc + (tree_logical_location_manager::get_kind): Likewise. + +2025-06-09 Jan Hubicka + + * cgraph.cc (cgraph_node::apply_scale): New member function. + * cgraph.h (struct cgraph_node): declare. + * ipa-cp.cc (update_counts_for_self_gen_clones): + Use cgraph_node::apply_scale. + (update_profiling_info): Do not overwrite local + profile when dropping to 0 global profile. + (update_specialized_profile): Likewise. + * ipa-inline-transform.cc (update_noncloned_counts): Remove. + (can_remove_node_now_p_1): Fix formating. + (clone_inlined_nodes): Use cgraph_node::apply_scale. + * profile-count.cc (profile_count::dump): Do not ICE + when count is not compatible with entry block count. + * tree-cfg.cc (gimple_verify_flow_info): Check + compatibility of count and entry block count. + +2025-06-09 David Malcolm + + PR other/116792 + * diagnostic-format-html.cc (html_builder::m_title_element): New + field. + (html_builder::html_builder): Initialize it. Don't add + placeholder text. + (html_builder::set_main_input_filename): New. + (html_output_format::set_main_input_filename): New. + (test_html_diagnostic_context::test_html_diagnostic_context): Call + set_main_input_filename on the new sink. + (seldtest::test_simple_log): Update expected text. + * diagnostic-format-json.cc (diagnostic_output_format_init_json): + Return a reference to the new sink. + (diagnostic_output_format_init_json_stderr): Likewise. + (diagnostic_output_format_init_json_file): Likewise. + * diagnostic-format-sarif.cc (sarif_builder::sarif_builder): Drop + "main_input_filename_" param, and move adding an artifact for it + with diagnostic_artifact_role::analysis_target to... + (sarif_builder::set_main_input_filename): ...this new function. + (sarif_output_format::set_main_input_filename): New. + (sarif_output_format::sarif_output_format): Drop + "main_input_filename_" param. + (sarif_stream_output_format::sarif_stream_output_format): + Likewise. + (sarif_file_output_format::sarif_file_output_format): Likewise. + (diagnostic_output_format_init_sarif): Return a reference to *FMT. + (diagnostic_output_format_init_sarif_stderr): Return a refererence + to the new sink. Drop "main_input_filename_" param. + (diagnostic_output_format_init_sarif_file): Likewise. + (diagnostic_output_format_init_sarif_stream): Likewise. + (make_sarif_sink): Drop "main_input_filename_" param. + (selftest::test_sarif_diagnostic_context::test_sarif_diagnostic_context): + Likewise. Call set_main_input_filename on the new format. + (selftest::test_sarif_diagnostic_context::buffered_output_format::buffered_output_format): + Drop "main_input_filename_" param. + (selftest::test_make_location_object): Likewise. + * diagnostic-format-sarif.h + (diagnostic_output_format_init_sarif_stderr): Return a refererence + to the new sink. Drop "main_input_filename_" param. + (diagnostic_output_format_init_sarif_file): Likewise. + (diagnostic_output_format_init_sarif_stream): Likewise. + (make_sarif_sink): Drop "main_input_filename_" param. + * diagnostic-format.h + (diagnostic_output_format::set_main_input_filename): New vfunc. + (diagnostic_output_format_init_json_stderr): Return a refererence + to the new sink. + (diagnostic_output_format_init_json_file): Likewise. + * diagnostic.cc (diagnostic_output_format_init): Likewise. Call + set_main_input_filename on the new sink. + * libgdiagnostics.cc (sarif_sink::sarif_sink): Update for above + changes. + * opts-diagnostic.cc (sarif_scheme_handler::make_sink): Likewise. + (handle_OPT_fdiagnostics_add_output_): Likewise. + (handle_OPT_fdiagnostics_set_output_): Likewise. + +2025-06-09 Jeff Law <jlaw@ventanamicro.com> + + * config/riscv/riscv.cc (riscv_noce_conversion_profitable_p): Relax + condition for adjustments due to copies from promoted SUBREGs. + +2025-06-09 Tamar Christina <tamar.christina@arm.com> + + * doc/extend.texi (outline-atomics): Document the inverse -mno flag. + +2025-06-09 Tamar Christina <tamar.christina@arm.com> + + * params.opt (vect-scalar-cost-multiplier): New. + * tree-vect-loop.cc (vect_estimate_min_profitable_iters): Use it. + * doc/invoke.texi (vect-scalar-cost-multiplier): Document it. + +2025-06-09 liuhongt <hongtao.liu@intel.com> + + PR target/103750 + * config/i386/i386.cc (ix86_rtx_costs): Adjust rtx_cost for + maskload. + * config/i386/sse.md (*<avx512>_load<mode>mask_and15): New + define_insn_and_split. + (*<avx512>_load<mode>mask_and3): Ditto. + +2025-06-09 Pan Li <pan2.li@intel.com> + + * config/riscv/riscv-v.cc (expand_vx_binary_vec_vec_dup): Add new + case MOD. + * config/riscv/riscv.cc (riscv_rtx_costs): Ditto. + * config/riscv/vector-iterators.md: Add new op mod. + +2025-06-08 Kugan Vivekanandarajah <kvivekananda@nvidia.com> + + * auto-profile.cc (function_instance::merge): Fix typo. + +2025-06-08 Vineet Gupta <vineetg@rivosinc.com> + + PR target/120203 + * config/riscv/riscv.cc (CFUN_IN_CALL): New macro. + (struct mode_switching_info): Add new field. + (riscv_frm_adjust_mode_after_call): Remove. + (riscv_frm_mode_needed): Track call_insn. + +2025-06-08 Vineet Gupta <vineetg@rivosinc.com> + + PR target/119164 + * config/riscv/riscv.cc (riscv_emit_frm_mode_set): check + STATIC_FRM_P for transition to DYN. + +2025-06-08 Vineet Gupta <vineetg@rivosinc.com> + + * config/riscv/riscv.cc (riscv_frm_emit_after_bb_end): Delete. + (riscv_frm_mode_needed): Remove call riscv_frm_emit_after_bb_end. + +2025-06-08 Vineet Gupta <vineetg@rivosinc.com> + + * config/riscv/riscv.cc (riscv_dynamic_frm_mode_p): Remove. + (riscv_mode_confluence): Ditto. + (TARGET_MODE_CONFLUENCE): Ditto. + +2025-06-08 Vineet Gupta <vineetg@rivosinc.com> + + * emit-rtl.cc (next_nonnote_nondebug_insn): Update comments. + +2025-06-08 Andrew Pinski <quic_apinski@quicinc.com> + + * tree-ssa-phiopt.cc (cond_if_else_store_replacement): Move + definitin of else_vdef to right before the usage. Reformat + slightly. + +2025-06-08 Andrew Pinski <quic_apinski@quicinc.com> + + PR tree-optimization/120533 + * tree-ssa-phiopt.cc (cond_if_else_store_replacement_limited): New function. + (pass_phiopt::execute): Call cond_if_else_store_replacement_limited + for diamand case. + +2025-06-08 Andrew Pinski <quic_apinski@quicinc.com> + + * tree-ssa-phiopt.cc (single_trailing_store_in_bb): Add vphi argument. + Check for single use of the vdef of the store instead of a loop + and check vdef's single use statement is the same as vphi. + (cond_if_else_store_replacement): Update call to single_trailing_store_in_bb. + +2025-06-08 Andrew Pinski <quic_apinski@quicinc.com> + + * tree-ssa-phiopt.cc (cond_if_else_store_replacement): Use get_virtual_phi + instead of inlining it. + +2025-06-08 Co-authored-by: Jeff Law <jlaw@ventanamicro.com> + + * config/riscv/riscv.cc (riscv_expand_conditional_move): Use + riscv_extend_comparands to extend sub-word comparison arguments. + +2025-06-08 Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp> + + * config/xtensa/xtensa.cc (printx, print_operand): + Add two instruction operand format codes 'U' and 'V', + whose represent scale factors of 0 to 15th positive/negative + power of two. + * config/xtensa/xtensa.md (c_enum "unspec"): + Add UNSPEC_CEIL and UNSPEC_FLOOR. + (int_iterator ANY_ROUND, int_attr m_round): + New integer iterator and its attribute. + (fix<s_fix>_truncsfsi2, *fix<s_fix>_truncsfsi2_2x, + *fix<s_fix>_truncsfsi2_scaled, float<s_float>sisf2, + *float<s_float>sisf2_scaled): + Use output templates with the operand formats added above, + instead of individual output statements. + (l<m_round>sfsi2, *l<m_round>sfsi2_2x, *l<m_round>sfsi2_scaled): + New insn patterns. + +2025-06-07 Jeff Law <jlaw@ventanamicro.com> + + * config/riscv/riscv.cc (riscv_expand_conditional_move): Use + riscv_extend_comparands to extend sub-word comparison arguments. + +2025-06-07 Andrew Pinski <quic_apinski@quicinc.com> + + PR tree-optimization/120572 + * doc/invoke.texi (Wmusttail-local-addr, + Wno-maybe-musttail-local-addr): Fix opindex. + * common.opt.urls: Regenerate. + +2025-06-06 David Malcolm <dmalcolm@redhat.com> + + * diagnostic-format-html.cc (struct html_doctypedecl): New. + (html_builder::html_builder): Use it to populate the document's + m_doctypedecl. + * xml.cc (xml::document::write_as_xml): Replace hardcoded HTML DTD + with use of m_doctypedecl field. + (selftest::test_no_dtd): New. + (selftest::xml_cc_tests): New. + * xml.h (struct doctypedecl): New decl. + +2025-06-06 David Malcolm <dmalcolm@redhat.com> + + * Makefile.in (OBJS-libcommon): Add xml.o. + * diagnostic-format-html.cc (namespace xml): Move implementation + to xml.cc + (selftest::test_printer): Likewise. + (selftest::test_attribute_ordering): Likewise. + (selftest::diagnostic_format_html_cc_tests): Don't call the moved + tests here; they will be called from xml_cc_tests in xml.cc. + * selftest-run-tests.cc (selftest::run_tests): Call xml_cc_tests. + * selftest.h (selftest::xml_cc_tests): New decl. + * xml.cc: New file, based on material from + diagnostic-format-html.cc. + +2025-06-06 David Malcolm <dmalcolm@redhat.com> + + * selftest.h: Fix the sorting of the various *_cc_tests decls. + +2025-06-06 David Malcolm <dmalcolm@redhat.com> + + * text-art/widget.cc (selftest::test_empty_wrapper_widget): New. + (selftest::text_art_widget_cc_tests): Call it. + * text-art/widget.h (text_art::wrapper_widget::calc_req_size): + Gracefully handle m_child being null. + (text_art::wrapper_widget::update_child_alloc_rects): Likewise. + (text_art::wrapper_widget::paint_to_canvas): Likewise. + +2025-06-06 Andrew Pinski <quic_apinski@quicinc.com> + + * tree-ssa-phiopt.cc (cond_if_else_store_replacement_1): Add vphi argument. + Manually update the vphi and new_stmt vdef/lhs. + (cond_if_else_store_replacement): Update call to cond_if_else_store_replacement_1. + +2025-06-06 Tobias Burnus <tburnus@baylibre.com> + Sandra Loosemore <sloosemore@baylibre.com> + + * gimple-fold.cc (gimple_fold_builtin_omp_get_initial_device, + gimple_fold_builtin_omp_get_num_devices): New. + (gimple_fold_builtin): Call them. + * omp-builtins.def (BUILT_IN_OMP_GET_INITIAL_DEVICE): Add + (BUILT_IN_OMP_GET_NUM_DEVICES): Make uservisible + pure. + +2025-06-06 Tobias Burnus <tburnus@baylibre.com> + + * builtins.def (DEF_GOACC_BUILTIN_COMPILER, DEF_GOMP_BUILTIN_COMPILER): + Set NONANSI_P = false to enable those also with -fno-nonansi-builtins. + +2025-06-06 Richard Biener <rguenther@suse.de> + + * tree-vect-stmts.cc (get_group_load_store_type): Remove + non-SLP path. + (get_load_store_type): Likewise. + +2025-06-06 Pan Li <pan2.li@intel.com> + + * config/riscv/riscv-v.cc (expand_vx_binary_vec_vec_dup): Add new + case UDIV. + * config/riscv/riscv.cc (riscv_rtx_costs): Ditto. + * config/riscv/vector-iterators.md: Add new op divu. + +2025-06-06 Richard Biener <rguenther@suse.de> + + * tree-vect-stmts.cc (vectorizable_store): Remove non-SLP + paths. + +2025-06-06 Richard Biener <rguenther@suse.de> + + * gimple-fold.h (create_tmp_reg_or_ssa_name): Remove. + * gimple-fold.cc (create_tmp_reg_or_ssa_name): Likewise. + (gimple_fold_builtin_memory_op): Use make_ssa_name. + (gimple_fold_builtin_strchr): Likewise. + (gimple_fold_builtin_strcat): Likewise. + (gimple_load_first_char): Likewise. + (gimple_fold_builtin_string_compare): Likewise. + (gimple_build): Likewise. + * tree-inline.cc (copy_bb): Likewise. + * config/rs6000/rs6000-builtin.cc (fold_build_vec_cmp): Likewise. + (rs6000_gimple_fold_mma_builtin): Likewise. + (rs6000_gimple_fold_builtin): Likewise. + +2025-06-06 Eric Botcazou <ebotcazou@adacore.com> + + * expr.cc (store_constructor) <ARRAY_TYPE>: Perform the arithmetics + on offsets in (unsigned) sizetype. + +2025-06-06 Jan Hubicka <hubicka@ucw.cz> + + * coverage.cc (coverage_init): Return early when in LTO + +2025-06-06 Jan Hubicka <hubicka@ucw.cz> + + * profile-count.cc (profile_count::to_sreal_scale): Special case 0 of autofdo. + (profile_count::combine_with_ipa_count): If outer function has GLOBAL0 profile + but innter counter has non-zero profile, force it to be 0. + +2025-06-06 Jiawei <jiawei@iscas.ac.cn> + Jiawei Chen <jiawei@iscas.ac.cn> + Yangyu Chen <cyy@cyyself.name> + Tang Haojin <tanghaojin@outlook.com> + + * config/riscv/riscv-cores.def (RISCV_TUNE): New cpu tune. + (RISCV_CORE): New cpu. + * doc/invoke.texi: Ditto. + +2025-06-06 Richard Biener <rguenther@suse.de> + + PR tree-optimization/120032 + * tree-ssa-forwprop.cc (simplify_count_zeroes): When we cannot use + the IFN to determine the result at zero use a conditional move + to reproduce the correct result from the table-based + algorithm. + +2025-06-06 Richard Biener <rguenther@suse.de> + + PR tree-optimization/120032 + * match.pd (clz_table_index): New match. + * tree-ssa-forwprop.cc (check_table_array): Rename from + check_ctz_array. Split out actual verification to a functor. + (check_table_string): Rename from check_ctz_string and likewise. + (check_table): Rename from check_ctz_table and adjust. + (gimple_clz_table_index): Declare. + (simplify_count_zeroes): Rename from simplify_count_trailing_zeroes. + Extend to cover CLZ. + (pass_forwprop::execute): Adjust. + +2025-06-06 Richard Biener <rguenther@suse.de> + + * tree-ssa-forwprop.cc (simplify_count_trailing_zeroes): + Use ranger instead of tree_expr_nonzero_p. + +2025-06-06 Richard Biener <rguenther@suse.de> + + * tree-ssa-forwprop.cc (optimize_count_trailing_zeroes): + Inline into ... + (simplify_count_trailing_zeroes): ... this function. + Split out ... + (check_ctz_table): ... a wrapper for CONSTRUCTOR vs. STRING_CST + handling. + +2025-06-05 Jeff Law <jlaw@ventanamicro.com> + + * config/riscv/riscv.cc (riscv_expand_conditional_move): Avoid + zicond in some cases involving sign bit tests. + * config/riscv/riscv.md: Split a splat of the sign bit feeding a + masking off high bits into a pair of right shifts. + +2025-06-05 Uros Bizjak <ubizjak@gmail.com> + + PR target/120553 + * config/i386/i386.md (mov<mode>cc): Use "general_operand" + predicate for operands 2 and 3 for all modes. + +2025-06-05 Marek Polacek <polacek@redhat.com> + + * doc/invoke.texi: Update a link to c99status.html. + * doc/standards.texi: Likewise. + +2025-06-05 Andrew Pinski <quic_apinski@quicinc.com> + + * tree-ssa-ccp.cc (insert_clobber_before_stack_restore): Update the virtual + op on the inserted clobber and the stack restore function. + (do_ssa_ccp): Don't add TODO_update_ssa to the todo. + +2025-06-05 Andrew Pinski <quic_apinski@quicinc.com> + + * config/aarch64/aarch64-sve-builtins.cc: Include value-range.h and tree-ssanames.h + (gimple_folder::convert_and_fold): Use make_ssa_name + instead of create_tmp_var for the temporary. Add comment about callback argument. + +2025-06-05 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/120231 + * range-op.cc (range_op_table::range_op_table): Register op_cast + also for FLOAT_EXPR and FIX_TRUNC_EXPR. + (RO_III): Adjust comment. + (range_op_handler::op1_range): Handle RO_IFI rather than RO_IFF. + Don't handle RO_FII. + (range_operator::op1_range): Remove overload with + irange &, tree, const frange &, const frange &, relation_trio + and frange &, tree, const irange &, const irange &, relation_trio + arguments. Add overload with + irange &, tree, const frange &, const irange &, relation_trio + arguments. + * range-op-mixed.h (operator_cast::op1_range): Remove overload with + irange &, tree, const frange &, const frange &, relation_trio + and frange &, tree, const irange &, const irange &, relation_trio + arguments. Add overload with + irange &, tree, const frange &, const irange &, relation_trio and + frange &, tree, const irange &, const frange &, relation_trio + arguments. + * range-op.h (range_operator::op1_cast): Remove overload with + irange &, tree, const frange &, const frange &, relation_trio + and frange &, tree, const irange &, const irange &, relation_trio + arguments. Add overload with + irange &, tree, const frange &, const irange &, relation_trio + arguments. + * range-op-float.cc (operator_cast::fold_range): Implement + float to int and int to float casts. + (operator_cast::op1_range): Remove overload with + irange &, tree, const frange &, const frange &, relation_trio + and frange &, tree, const irange &, const irange &, relation_trio + arguments. Add overload with + irange &, tree, const frange &, const irange &, relation_trio and + frange &, tree, const irange &, const frange &, relation_trio + arguments and implement reverse op of float to int and int to float + cast there. + +2025-06-05 Jan Hubicka <hubicka@ucw.cz> + + * auto-profile.cc (afdo_calculate_branch_prob): Fix typo + in previous patch. + +2025-06-05 Kito Cheng <kito.cheng@sifive.com> + + * common/config/riscv/riscv-common.cc: Remove structured binding + from the code. + +2025-06-05 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/120547 + * real.cc (real_from_integer): Remove maxbitlen variable, use + len instead of that. When shifting right, or in 1 if any of the + shifted away bits are non-zero. Formatting fix. + +2025-06-05 Jan Hubicka <hubicka@ucw.cz> + + * auto-profile.cc (update_count_by_afdo_count): Fix handling + of GUESSED_LOCAL. + (afdo_calculate_branch_prob): Preserve static profile for + probabilities 0 and 1. + +2025-06-05 Pan Li <pan2.li@intel.com> + + * config/riscv/autovec-opt.md: Leverage vdup_v and v_vdup + binary op for different patterns. + * config/riscv/vector-iterators.md: Add vdup_v and v_vdup + binary op iterators. + +2025-06-05 Jeff Law <jlaw@ventanamicro.com> + + * config/riscv/zicond.md: Add new splitters to select + 1, -1 or -1, 1 based on a sign bit test. + +2025-06-05 Jiawei <jiawei@iscas.ac.cn> + + * config/riscv/riscv-ext.def: New extension definition. + * config/riscv/riscv-ext.opt: New extension mask. + * doc/riscv-ext.texi: Document the new extension. + +2025-06-05 Jiawei <jiawei@iscas.ac.cn> + + * config/riscv/riscv-ext.def: New extension definition. + * config/riscv/riscv-ext.opt: New extension mask. + * doc/riscv-ext.texi: Document the new extension. + +2025-06-05 Jiawei <jiawei@iscas.ac.cn> + + * config/riscv/riscv-ext.def: New extension definition. + * config/riscv/riscv-ext.opt: New extension mask. + * doc/riscv-ext.texi: Document the new extension. + +2025-06-05 Jiawei <jiawei@iscas.ac.cn> + + * config/riscv/riscv-ext.def: New extension definition. + * config/riscv/riscv-ext.opt: New extension mask. + * doc/riscv-ext.texi: Document the new extension. + +2025-06-05 Jiawei <jiawei@iscas.ac.cn> + + * config/riscv/riscv-ext.def: New extension definition. + * config/riscv/riscv-ext.opt: New extension mask. + * doc/riscv-ext.texi: Document the new extension. + +2025-06-05 Jiawei <jiawei@iscas.ac.cn> + + * config/riscv/riscv-ext.def: New extension definition. + * config/riscv/riscv-ext.opt: New extension mask. + * doc/riscv-ext.texi: Document the new extension. + +2025-06-05 Jiawei <jiawei@iscas.ac.cn> + + * config/riscv/riscv-ext.def: New extension definition. + * config/riscv/riscv-ext.opt: New extension mask. + * doc/riscv-ext.texi: Document the new extension. + +2025-06-05 Eric Botcazou <ebotcazou@adacore.com> + + * tree-vect-data-refs.cc (vect_can_force_dr_alignment_p): Return + false if the variable has no symtab node. + +2025-06-05 Spencer Abson <spencer.abson@arm.com> + + * tree-eh.cc (operation_could_trap_helper_p): Cover FIX_TRUNC + expressions explicitly. + +2025-06-05 Tobias Burnus <tburnus@baylibre.com> + + * config.gcc (--with-{arch,tune}): Use .def file to validate gcn + processor names. + * doc/install.texi (amdgcn*-*-*): Update list of devices supported + by --with-arch/--with-tune. + +2025-06-05 Hongyu Wang <hongyu.wang@intel.com> + + PR middle-end/112824 + * tree-sra.cc (sra_get_max_scalarization_size): Use MOVE_MAX + instead of UNITS_PER_WORD to define max_scalarization_size. + +2025-06-05 Hu, Lin1 <lin1.hu@intel.com> + + * config/i386/sse.md + (avx512f_movddup512<mask_name>): Change sselog1 to ssemov. + (avx_movddup256<mask_name>): Ditto. + (*vec_dupv2di): Change alternative 4's type attribute from sselog1 + to ssemov. + +2025-06-05 Jiawei <jiawei@iscas.ac.cn> + + * config/riscv/riscv-ext.def: Update declaration. + +2025-06-04 Kugan Vivekanandarajah <kvivekananda@nvidia.com> + + * auto-profile.cc (autofdo_source_profile::read): Dump message + while merging profile. + * pass_manager.h (get_pass_auto_profile): New. + +2025-06-04 Sandra Loosemore <sloosemore@baylibre.com> + + PR c++/120518 + * omp-general.cc (omp_device_num_check): Look inside a + CLEANUP_POINT_EXPR when trying to optimize special cases. + +2025-06-04 Thomas Schwinge <tschwinge@baylibre.com> + + * config/nvptx/mkoffload.cc (process): Use an 'auto_vec' for + 'file_idx'. + +2025-06-04 Andrew Pinski <quic_apinski@quicinc.com> + + PR tree-optimization/14295 + PR tree-optimization/108358 + PR tree-optimization/114169 + * tree-ssa-forwprop.cc (optimize_agr_copyprop): New function. + (pass_forwprop::execute): Call optimize_agr_copyprop for load/store statements. + +2025-06-04 Pengfei Li <Pengfei.Li2@arm.com> + + * match.pd: Add folding rule for vector average. + * tree-ssa-ccp.cc (get_default_value): Reject vector types. + (evaluate_stmt): Reject vector types. + * tree-ssanames.cc (get_nonzero_bits_1): Extend to handle + uniform vectors. + +2025-06-04 Xi Ruoyao <xry111@xry111.site> + + PR rtl-optimization/120050 + * ext-dce.cc (ext_dce_process_uses): Break early if a SUBREG in + rhs is promoted and the truncation from the inner mode to the + outer mode is not a noop when handling SETs. + +2025-06-04 Jakub Jelinek <jakub@redhat.com> + + * range-op-float.cc (range_operator::fold_range, + range_operator::op1_range, range_operator::op2_range, + range_operator::lhs_op1_relation, range_operator::lhs_op2_relation, + operator_equal::op1_range, foperator_unordered_gt::op1_range): Fix + up parameter indentation. + * range-op.cc (range_operator::fold_range, range_operator::op1_range, + range_operator::op1_op2_relation_effect, + range_operator::update_bitmask, plus_minus_ranges, + operator_bitwise_and::lhs_op1_relation): Likewise. + +2025-06-04 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/120231 + * range-op-mixed.h (operator_cast::fold_range): Add overload + with 3 {,const} frange & operands. Change parameter names and + add final override keywords for float <-> integer cast overloads. + (operator_cast::op1_range): Likewise. + * range-op-float.cc (operator_cast::fold_range): New overload + with 3 {,const} frange & operands. + (operator_cast::op1_range): Likewise. + +2025-06-04 Dongyan Chen <chendongyan@isrc.iscas.ac.cn> + + * config/riscv/riscv-ext.def: Imply zicsr. + +2025-06-04 Dongyan Chen <chendongyan@isrc.iscas.ac.cn> + + * config/riscv/riscv-ext.def: New extension defs. + * config/riscv/riscv-ext.opt: Ditto. + * doc/riscv-ext.texi: Ditto. + +2025-06-04 Richard Sandiford <richard.sandiford@arm.com> + + PR rtl-optimization/120447 + * emit-rtl.cc (validate_subreg): Restrict ordered_p test + between osize and regsize to cases where the inner value + occupies multiple blocks. + +2025-06-04 Pan Li <pan2.li@intel.com> + + * config/riscv/riscv.cc (get_vector_binary_rtx_cost): Rename + the args to scalar2vr. + (riscv_rtx_costs): Leverage above func to avoid code dup. + +2025-06-04 H.J. Lu <hjl.tools@gmail.com> + + PR debug/120525 + * var-tracking.cc (prepare_call_arguments): Use MEM_EXPR only + if MEM_P is true. + +2025-06-04 Jiawei <jiawei@iscas.ac.cn> + + * config/riscv/riscv-ext.def: New extension defs. + * config/riscv/riscv-ext.opt: Ditto. + * doc/riscv-ext.texi: Ditto. + +2025-06-04 Hu, Lin1 <lin1.hu@intel.com> + + * config/i386/i386.md (define_peephole2): Define some new peephole2 for + APX NDD. + +2025-06-04 Hu, Lin1 <lin1.hu@intel.com> + + * config/i386/i386.md: Add 4 new peephole2 by swap the original + peephole2's operands' order to support new pattern. + +2025-06-04 H.J. Lu <hjl.tools@gmail.com> + + PR other/120494 + * calls.cc (expand_call): Always add REG_CALL_DECL note. + (emit_library_call_value_1): Likewise. + 2025-06-03 Richard Biener <rguenther@suse.de> * gimple-fold.cc (create_tmp_reg_or_ssa_name): Always diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 932c2dd9fa20..7578d8939d61 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20250604 +20250722 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 49869531bc8a..05dfa0871be2 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -972,6 +972,7 @@ endif DUMPFILE_H = $(srcdir)/../libcpp/include/line-map.h dumpfile.h VEC_H = vec.h statistics.h $(GGC_H) HASH_TABLE_H = $(HASHTAB_H) hash-table.h $(GGC_H) +BITMAP_H = bitmap.h $(HASHTAB_H) statistics.h EXCEPT_H = except.h $(HASHTAB_H) TARGET_DEF = target.def target-hooks-macros.h target-insns.def C_TARGET_DEF = c-family/c-target.def target-hooks-macros.h @@ -1023,6 +1024,8 @@ FLAGS_H = flags.h flag-types.h $(OPTIONS_H) OPTIONS_H = options.h flag-types.h $(OPTIONS_H_EXTRA) FUNCTION_H = function.h $(HASHTAB_H) $(TM_H) hard-reg-set.h \ $(VEC_H) $(INPUT_H) +BACKEND_H = backend.h $(TM_H) $(FUNCTION_H) $(BITMAP_H) sbitmap.h \ + $(BASIC_BLOCK_H) cfg.h EXPR_H = expr.h insn-config.h $(FUNCTION_H) $(RTL_H) $(FLAGS_H) $(TREE_H) \ $(EMIT_RTL_H) OPTABS_H = optabs.h insn-codes.h insn-opinit.h @@ -1076,7 +1079,6 @@ LTO_STREAMER_H = lto-streamer.h $(LINKER_PLUGIN_API_H) $(TARGET_H) \ $(CGRAPH_H) $(VEC_H) $(HASH_TABLE_H) $(TREE_H) $(GIMPLE_H) \ $(GCOV_IO_H) $(DIAGNOSTIC_H) alloc-pool.h IPA_PROP_H = ipa-prop.h $(TREE_H) $(VEC_H) $(CGRAPH_H) $(GIMPLE_H) alloc-pool.h -BITMAP_H = bitmap.h $(HASHTAB_H) statistics.h GCC_PLUGIN_H = gcc-plugin.h highlev-plugin-common.h plugin.def \ $(CONFIG_H) $(SYSTEM_H) $(HASHTAB_H) PLUGIN_H = plugin.h $(GCC_PLUGIN_H) @@ -1323,6 +1325,7 @@ C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \ # Analyzer object files ANALYZER_OBJS = \ analyzer/access-diagram.o \ + analyzer/ana-state-to-diagnostic-state.o \ analyzer/analysis-plan.o \ analyzer/analyzer.o \ analyzer/analyzer-language.o \ @@ -1535,7 +1538,6 @@ OBJS = \ godump.o \ graph.o \ graphds.o \ - graphviz.o \ graphite.o \ graphite-isl-ast-to-gimple.o \ graphite-dependences.o \ @@ -1794,6 +1796,7 @@ OBJS = \ tree-ssa-sink.o \ tree-ssa-strlen.o \ tree-ssa-structalias.o \ + pta-andersen.o \ tree-ssa-tail-merge.o \ tree-ssa-ter.o \ tree-ssa-threadbackward.o \ @@ -1851,17 +1854,22 @@ OBJS = \ # no target dependencies. OBJS-libcommon = diagnostic-spec.o diagnostic.o diagnostic-color.o \ diagnostic-format-html.o \ - diagnostic-format-json.o \ diagnostic-format-sarif.o \ diagnostic-format-text.o \ diagnostic-global-context.o \ + diagnostic-digraphs.o \ diagnostic-macro-unwinding.o \ + diagnostic-output-spec.o \ diagnostic-path.o \ diagnostic-path-output.o \ diagnostic-show-locus.o \ + diagnostic-state-graphs.o \ + diagnostic-state-to-dot.o \ edit-context.o \ + graphviz.o pex.o \ pretty-print.o intl.o \ json.o json-parsing.o \ + xml.o \ sbitmap.o \ vec.o input.o hash-table.o ggc-none.o memory-block.o \ selftest.o selftest-diagnostic.o sort.o \ diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 55c8f7411c0d..d1b78d403a1f 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,2659 @@ +2025-07-21 Eric Botcazou <ebotcazou@gcc.gnu.org> + + PR ada/121184 + * styleg.adb (Check_Comment): Use consistent warning message. + +2025-07-21 Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org> + + * gcc-interface/trans.cc (gnat_to_gnu): Pass null pointer to + parse_{input,output}_constraint(). + +2025-07-18 Steve Baird <baird@adacore.com> + + * sem_ch12.adb (Validate_Derived_Type_Instance): Cope with the case + where the ancestor type for a formal derived type is declared in + an earlier formal package but Get_Instance_Of does not return the + corresponding type from the corresponding actual package. + +2025-07-18 Bob Duff <duff@adacore.com> + + * tbuild.adb (Unchecked_Convert_To): Back out + change. + +2025-07-18 Marc Poulhiès <poulhies@adacore.com> + Eric Botcazou <botcazou@adacore.com> + + * exp_ch6.adb (Convert): Do not call Expand_Inlined_Call for + unsupported cases. + * inline.adb (Expand_Inlined_Call): Add assert to catch unsupported + case. + +2025-07-18 Gary Dismukes <dismukes@adacore.com> + + * einfo.ads: Document new field Overridden_Inherited_Operation and + list it as a field for the entity kinds that it applies to. + * gen_il-fields.ads (type Opt_Field_Enum): Add new literal + Overridden_Inherited_Operation to the type. + * gen_il-gen-gen_entities.adb: Add Overridden_Inherited_Operation as + a field of entities of kinds E_Enumeration_Literal and Subprogram_Kind. + * sem_ch4.adb (Is_Callable_Private_Overriding): Change name (was + Is_Private_Overriding). Replace Is_Hidden test on Overridden_Operation + with test of Is_Hidden on the new field Overridden_Inherited_Operation. + * sem_ch6.adb (New_Overloaded_Entity): Set the new field + Overridden_Inherited_Operation on an operation derived from + an interface to refer to the inherited operation of a private + extension that's overridden by the derived operation. Also set + that field in the more common cases of an explicit subprogram + that overrides, to refer to the inherited subprogram that is + overridden. (Contrary to its name, the Overridden_Operation + field of the overriding subprogram, which is also set in these + places, refers to the *parent* subprogram from which the inherited + subprogram is derived.) Also, remove a redundant Present (Alias (S)) + test in an if_statement and the dead "else" part of that statement. + +2025-07-18 Piotr Trojanek <trojanek@adacore.com> + + * sem_util.adb (Build_Elaboration_Entity): Set ghost mode to none + before creating the elaboration entity; restore the ghost mode + afterwards. + +2025-07-18 Javier Miranda <miranda@adacore.com> + + * exp_aggr.adb (Gen_Assign): Code cleanup. + (Initialize_Component): Do not adjust the tag when the type of + the aggregate components is a mutably tagged type. + +2025-07-14 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/121056 + * sem_ch4.adb (Try_Object_Operation.Try_Primitive_Operation): Add + test on Is_Record_Type before accessing Underlying_Record_View. + +2025-07-10 Jakub Jelinek <jakub@redhat.com> + + * par-load.adb: Comment spelling fix: bellow -> below. + * libgnarl/s-taskin.ads: Likewise. + +2025-07-04 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/Make-lang.in (ACATSDIR): Change to acats-4. + +2025-07-04 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/utils.cc (make_packable_type): Clear the TYPE_PACKED + flag in the case where the alignment is bumped. + +2025-07-04 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/trans.cc (Subprogram_Body_to_gnu): Do not generate + a block-copy out for a null initialization procedure when the _Init + parameter is not passed in. + +2025-07-04 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.cc (gnat_to_gnu_subprog_type): Only apply the + transformation to integer types. + +2025-07-04 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.cc (gnat_to_gnu_subprog_type): Add guards. + +2025-07-04 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.cc (gnat_to_gnu_subprog_type): In the case of a + subprogram using the Copy-In/Copy-Out mechanism, deal specially with + the case of 2 parameters of differing sizes. + * gcc-interface/trans.cc (Subprogram_Body_to_gnu): In the case of a + subprogram using the Copy-In/Copy-Out mechanism, make sure the types + are consistent on the two sides for all the parameters. + +2025-07-04 Steve Baird <baird@adacore.com> + + * sem_res.adb (Resolve_Type_Conversion): Replace code for + detecting a similar case with a more comprehensive test. + +2025-07-04 Bob Duff <duff@adacore.com> + + * doc/gnat_rm/implementation_defined_pragmas.rst + (Short_Circuit_And_Or): Add more documentation. + * sem_ch8.adb (Analyze_Subprogram_Renaming): + Disallow renamings. + * gnat_rm.texi: Regenerate. + +2025-07-04 Ronan Desplanques <desplanques@adacore.com> + + * exp_ch7.adb (Make_Final_Call): Tweak search of Finalize primitive. + * exp_util.adb (Finalize_Address): Likewise. + +2025-07-04 Eric Botcazou <ebotcazou@adacore.com> + + * freeze.adb (Check_Compile_Time_Size): Try harder to see whether + the bounds of array types are known at compile time. + +2025-07-04 Piotr Trojanek <trojanek@adacore.com> + + * sem_aux.ads (First_Discriminant): Remove space before period. + +2025-07-04 Steve Baird <baird@adacore.com> + + * sem_ch13.adb (Analyze_Record_Representation_Clause): In deciding + whether to generate a warning about a missing component clause, in + addition to calling Is_Unchecked_Union also call a new local + function, Unchecked_Union_Pragma_Pending, which checks for the + case of a not-yet-analyzed Unchecked_Union pragma occurring later + in the declaration list. + +2025-07-04 Steve Baird <baird@adacore.com> + + * mutably_tagged.adb (Make_CW_Size_Compile_Check): Include the + value of the Size'Class limit in the message generated via a + Compile_Time_Error pragma. + +2025-07-04 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch13.adb (Check_Aspect_At_Freeze_Point): Remove obsolete bits. + +2025-07-04 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch13.adb (Analyze_Aspect_Specifications): Fix error emission. + +2025-07-03 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/Makefile.in (gnatlib-sjlj): Delete. + (gnatlib-zcx): Do not modify Frontend_Exceptions constant. + * libgnat/system-linux-loongarch.ads (Frontend_Exceptions): Delete. + +2025-07-03 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.cc (type_contains_only_integral_data): Do not + return false only because the type contains pointer data. + +2025-07-03 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.cc (gnat_to_gnu_entity): Use default messages + for errors reported for Object_Size clauses. + (validate_size): Give an error for stand-alone objects of composite + types if the specified size is not a multiple of the alignment. + +2025-07-03 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/trans.cc (addressable_p): Add COMPG third parameter. + <COMPONENT_REF>: Do not return true out of alignment considerations + for non-strict-alignment targets if COMPG is set. + (Call_to_gnu): Pass true as COMPG in the call to the addressable_p + predicate if the called subprogram is an initialization procedure. + +2025-07-03 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/trans.cc (gnat_to_gnu) <N_Allocator>: Allocate the + bounds alongside the data if the Is_Constr_Array_Subt_With_Bounds + flag is set on the designated type. + <N_Free_Statement>: Take into account the allocated bounds if the + Is_Constr_Array_Subt_With_Bounds flag is set on the designated type. + +2025-07-03 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.cc (gnat_to_gnu_component_type): Validate the + Component_Size like the size of a type only if the component type + is actually packed. + +2025-07-03 Piotr Trojanek <trojanek@adacore.com> + + * sem_elab.adb (Check_Overriding_Primitive): Find early call region + of the subprogram body declaration, not of the subprogram body stub. + +2025-07-03 Bob Duff <duff@adacore.com> + + * gen_il-gen-gen_nodes.adb (N_Unchecked_Type_Conversion): + Remove useless Nmake_Assert. + * tbuild.adb (Unchecked_Convert_To): + Narrow the bitfield-related conditions. + +2025-07-03 Ronan Desplanques <desplanques@adacore.com> + + * exp_util.adb (Insert_Actions): Fix check. + +2025-07-03 Ronan Desplanques <desplanques@adacore.com> + + * exp_ch6.adb (Expand_Ctrl_Function_Call): Precisify comment. + +2025-07-03 Eric Botcazou <ebotcazou@adacore.com> + + * exp_ch6.adb (Expand_Ctrl_Function_Call): Do not bail out for the + declarations of return objects. + +2025-07-03 Daniel King <dmking@adacore.com> + + * Makefile.rtl (LIBGNAT_TARGET_PAIRS): New unit s-tsgsba__cheri.adb for morello-freebsd. + * libgnarl/s-tassta.adb (Get_Stack_Base): New function. + * libgnarl/s-tsgsba__cheri.adb: New file for CHERI targets. + * libgnarl/s-tsgsba.adb: New default file for non-CHERI targets. + * libgnat/s-stausa.adb (Fill_Stack, Compute_Result): Port to CHERI. + * libgnat/s-stausa.ads (Initialize_Analyzer, Stack_Analyzer): Port to CHERI. + +2025-07-03 Piotr Trojanek <trojanek@adacore.com> + + * sem_ch3.adb (Check_Return_Subtype_Indication): Use Original_Node. + +2025-07-03 Piotr Trojanek <trojanek@adacore.com> + + * sem_ch3.adb (Check_Return_Subtype_Indication): Use type from + explicit subtype indication, when possible. + +2025-07-03 Piotr Trojanek <trojanek@adacore.com> + + * sem_ch3.adb (Check_Return_Subtype_Indication): Adjust error message + to match the RM wording. + +2025-07-03 Piotr Trojanek <trojanek@adacore.com> + + * sem_ch3.adb (Check_Return_Subtype_Indication): Use the nominal + subtype of a return object; literally implement the RM rule about + elementary types; check for static subtype compatibility both when + the subtype is given as a subtype mark and a subtype indication. + +2025-07-03 Eric Botcazou <ebotcazou@adacore.com> + + * repinfo.adb (First_Comp_Or_Discr.Is_Placed_Before): Return True + only if the components are in the same component list. + +2025-07-03 Denis Mazzucato <mazzucato@adacore.com> + + * sem_disp.adb (Check_Dispatching_call): Fix uninitialized Subp_Entity. + * sem_util.adb (Update_Controlling_Argument): No need to replace controlling argument + in case of functions. + +2025-07-03 Eric Botcazou <ebotcazou@adacore.com> + + * errid.ads: Adjust header to renaming and fix copyright line. + * errid.adb: Adjust header to renaming and add blank line. + * erroutc-pretty_emitter.ads: Adjust header to renaming. + * erroutc-pretty_emitter.adb: Likewise. + * erroutc-sarif_emitter.ads: Likewise. + * erroutc-sarif_emitter.adb: Likewise. + * errsw.ads: Adjust header to renaming and add blank line. + * errsw.adb: Likewise. + * json_utils.ads: Likewise. + * json_utils.adb: Adjust header to renaming. + +2025-07-03 Piotr Trojanek <trojanek@adacore.com> + + * errid.ads (Diagnostic_Entries): Now a constant. + +2025-07-03 Piotr Trojanek <trojanek@adacore.com> + + * errid.ads (Diagnostic_Entries): Remove nested aggregate. + * errsw.adb (Switches): Likewise. + +2025-07-03 Ronan Desplanques <desplanques@adacore.com> + + * exp_ch7.adb (Make_Deep_Record_Body): Fix case of absent Initialize + primitive. + +2025-07-03 Piotr Trojanek <trojanek@adacore.com> + + * exp_ch3.adb (Count_Default_Sized_Task_Stacks): Refine subtypes of + parameters; same for callsites. + +2025-07-03 Eric Botcazou <ebotcazou@adacore.com> + + * exp_imgv.adb (Expand_Value_Attribute): Do not call Set_Etype on N + after rewriting it by means of OK_Convert_To. + +2025-07-03 Ronan Desplanques <desplanques@adacore.com> + + * exp_aggr.adb (Generate_Finalization_Actions): Stop assuming that + initialize primitive exists. + +2025-07-03 Ronan Desplanques <desplanques@adacore.com> + + * exp_ch7.adb (Build_Record_Deep_Procs): Fix typo in comment. + +2025-07-03 Gary Dismukes <dismukes@adacore.com> + + * sem_ch12.adb (Install_Spec): Remove "not Is_Generic_Instance (Par)" + in test for setting Instance_Parent_Unit. Revise comment to no longer + say "noninstance", plus remove "???". + (Remove_Parent): Restructure if_statement to allow for both "elsif" + parts to be executed (by changing them to be separate if_statements + within an "else" part). + +2025-07-03 Ronan Desplanques <desplanques@adacore.com> + + * exp_ch3.adb (Predefined_Primitive_Bodies): Fix comment. + +2025-07-03 Piotr Trojanek <trojanek@adacore.com> + + * exp_tss.adb (TSS): Refactor IF condition to make code smaller. + * lib.adb (Increment_Serial_Number, Synchronize_Serial_Number): + Use type of renamed object when creating renaming. + * lib.ads (Unit_Record): Refine subtype of dependency number. + +2025-07-03 Eric Botcazou <ebotcazou@adacore.com> + + * libgnat/s-valuef.adb: Document the prerequisites more precisely. + * libgnat/a-tifiio.adb (OK_Get_32): Adjust to the prerequisites. + (OK_Get_64): Likewise. + * libgnat/a-tifiio__128.adb (OK_Get_32): Likewise. + (OK_Get_64): Likewise. + (OK_Get_128): Likewise. + * libgnat/a-wtfiio.adb (OK_Get_32): Likewise. + (OK_Get_64): Likewise. + * libgnat/a-wtfiio__128.adb (OK_Get_32): Likewise. + (OK_Get_64): Likewise. + (OK_Get_128): Likewise. + * libgnat/a-ztfiio.adb (OK_Get_32): Likewise. + (OK_Get_64): Likewise. + * libgnat/a-ztfiio__128.adb (OK_Get_32): Likewise. + (OK_Get_64): Likewise. + (OK_Get_128): Likewise. + * exp_imgv.adb (Expand_Value_Attribute): Adjust the conditions under + which the RE_Value_Fixed{32,64,128} routines are called for ordinary + fixed-point types. + +2025-07-03 Ronan Desplanques <desplanques@adacore.com> + + * exp_ch3.adb (Make_Predefined_Primitive_Specs): Fix comment. + +2025-07-03 Ronan Desplanques <desplanques@adacore.com> + + * exp_ch7.adb (Insert_Actions_In_Scope_Around): Fix condition. + +2025-07-03 Bob Duff <duff@adacore.com> + + * checks.adb: Remove unnecessary "return;" statements. + * eval_fat.adb: Likewise. + * exp_aggr.adb: Likewise. + * exp_attr.adb: Likewise. + * exp_ch3.adb: Likewise. + * exp_ch4.adb: Likewise. + * exp_ch5.adb: Likewise. + * exp_ch6.adb: Likewise. + * exp_unst.adb: Likewise. + * krunch.adb: Likewise. + * layout.adb: Likewise. + * libgnat/s-excdeb.adb: Likewise. + * libgnat/s-trasym__dwarf.adb: Likewise. + * par-endh.adb: Likewise. + * par-tchk.adb: Likewise. + * sem.adb: Likewise. + * sem_attr.adb: Likewise. + * sem_ch6.adb: Likewise. + * sem_elim.adb: Likewise. + * sem_eval.adb: Likewise. + * sfn_scan.adb: Likewise. + +2025-07-03 Bob Duff <duff@adacore.com> + + * doc/gnat_rm/implementation_defined_characteristics.rst: + Change Ignore to Disable. + * sem_ch13.ads (Analyze_Aspect_Specifications): + Minor: Remove incorrect comment; there is no need to check + Has_Aspects (N) at the call site. + * gnat_rm.texi: Regenerate. + * gnat_ugn.texi: Regenerate. + +2025-07-03 Bob Duff <duff@adacore.com> + + * types.ads (Empty_Or_Error): Remove. + * atree.adb: Remove reference to Empty_Or_Error. + * par-endh.adb: Likewise. + * sem_ch12.adb: Likewise. + * sem_ch3.adb: Likewise. + * sem_util.adb: Likewise. + * treepr.adb: Likewise. + +2025-07-03 Viljar Indus <indus@adacore.com> + + * sem_ch10.adb(Analyze_With_Clause): Call Semantics instead + of Analyze to bring Current_Sem_Unit up to date. + +2025-07-03 Piotr Trojanek <trojanek@adacore.com> + + * lib-xref-spark_specific.adb + (Enclosing_Subprogram_Or_Library_Package): Traverse subunits and body + stubs. + +2025-07-03 Tonu Naks <naks@adacore.com> + + * libgnat/i-cstrin.ads (Value): add documentation + +2025-07-03 Aleksandra Pasek <pasek@adacore.com> + + * libgnat/a-strsup.adb (Super_Delete): Fix index check. + * libgnat/a-stwisu.adb (Super_Delete): Likewise. + * libgnat/a-stzsup.adb (Super_Delete): Likewise. + +2025-07-03 Eric Botcazou <ebotcazou@adacore.com> + + * exp_ch4.adb (Handle_Changed_Representation): Alphabetize local + variables. Set the No_Finalize_Actions flag on the assignment. + +2025-07-03 Joffrey Huguet <huguet@adacore.com> + + * aspects.ads: Define an identifier for Potentially_Invalid. + * doc/gnat_rm/implementation_defined_aspects.rst: Add section for Potentially_Invalid. + * sem_attr.adb (Analyze_Attribute_Old_Result): Attribute Old is allowed to occur in a + Potentially_Invalid aspect. + * sem_ch13.adb (Analyze_Aspect_Specifications): Handle Potentially_Invalid. + * sem_util.adb (Has_Potentially_Invalid): Returns True iff an entity is subject to the + Potentially_Invalid aspect. + * sem_util.ads (Has_Potentially_Invalid): Idem. + * snames.ads-tmpl: New name for Potentially_Invalid. + * gnat_rm.texi: Regenerate. + +2025-07-03 Piotr Trojanek <trojanek@adacore.com> + + * sem_ch10.adb (Analyze_Compilation_Unit): Ignored ghost unit need no + elaboration checks. + +2025-07-03 Eric Botcazou <ebotcazou@adacore.com> + + * libgnat/s-valued.adb (Integer_to_Decimal): Use truncation for the + scaled divide operation performed for bases other than 10. + +2025-07-01 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/120705 + * exp_ch6.adb (Needs_BIP_Collection): Always return False if the + type has relaxed finalization. + +2025-07-01 Eric Botcazou <ebotcazou@adacore.com> + + * libgnat/s-valuef.adb (Integer_to_Fixed): Restore rounding of the + first scaled divide operation. + +2025-07-01 Piotr Trojanek <trojanek@adacore.com> + + * gnat1drv.adb (Gnat1drv): Do minimal decoration of the spec and body + of an ignored ghost compilation unit. + +2025-07-01 Piotr Trojanek <trojanek@adacore.com> + + * ali.ads (Unit_Record): Fix grammar in comment. + * bindgen.adb (Num_Elab_Calls, Num_Primary_Stacks): Remove counters + that were only incremented and never actually used. + +2025-07-01 Tonu Naks <naks@adacore.com> + + * libgnat/s-valuer.adb (Scan_Decimal_Digits, + Scan_Integral_Digits): fix condition for rejecting + underscore. + +2025-07-01 Eric Botcazou <ebotcazou@adacore.com> + + * libgnat/s-valued.adb (Integer_To_Decimal): Deal specifically with + Val = 2**(Int'Size - 1) if Minus is not set. Exit the loops when V + saturates to 0 in the case of (huge) negative exponents. Use Base + instead of B consistently in unsigned computations. + * libgnat/s-valuef.adb (Integer_To_Fixed): Use Base instead of B + consistently in unsigned computations. + +2025-07-01 Piotr Trojanek <trojanek@adacore.com> + + * exp_ch4.adb (Fixup_Universal_Fixed_Operation): Move to spec. + * exp_ch4.ads (Fixup_Universal_Fixed_Operation): Move from body. + * exp_spark.adb (Expand_SPARK): Call a fixup expansion routine. + +2025-07-01 Gary Dismukes <dismukes@adacore.com> + + * exp_ch3.adb (Build_Heap_Or_Pool_Allocator): Test not Has_Relaxed_Finalization + as a guard against retrieving BIP_Collection formal (and related code). + +2025-07-01 Javier Miranda <miranda@adacore.com> + + * exp_ch3.adb (Build_Untagged_Record_Equality): Report the + warning when no component of an untagged record type U is a + record type, and the type C of some of its components has + defined its user-defined equality operator "=". + * exp_ch4.adb (Expand_Composite_Equality): Report the warning + calling Warn_On_Ignored_Equality_Operator. + * sem_warn.ads (Warn_On_Ignored_Equality_Operator): New subprogram. + * sem_warn.adb (Warn_On_Ignored_Equality_Operator): Factorize code + reporting the warning. + +2025-07-01 Tonu Naks <naks@adacore.com> + + * libgnat/a-ngelfu.adb: conditional computation of X^2 + +2025-07-01 Steve Baird <baird@adacore.com> + + * Makefile.rtl: Add entry for new unit's object file. + * libgnat/s-casuti.adb: Remove bodies of subprograms that were moved + to the new unit. + * libgnat/s-casuti.ads: Replace (with renamings) declarations for + subprograms that moved to the new unit. + * libgnat/s-cautns.adb: Body for new unit (a new source file). + * libgnat/s-cautns.ads: Spec for new unit (a new source file). + * libgnat/s-valuti.adb: Use the new unit instead of the old one. + * gcc-interface/Make-lang.in: Add entries for new unit's object file. + * gcc-interface/Makefile.in: Likewise. + +2025-07-01 Gary Dismukes <dismukes@adacore.com> + + * sem_ch3.adb (Constrain_Corresponding_Record): Inherit Class_Wide_Type on the + created constrained subtype. + +2025-07-01 Artur Pietrek <pietrek@adacore.com> + + * doc/gnat_ugn/building_executable_programs_with_gnat.rst: add + GNAT LLVM explicit selection in GPR file + * gnat_ugn.texi: Regenerate. + +2025-07-01 Eric Botcazou <ebotcazou@adacore.com> + + * exp_ch7.adb (Shift_Address_For_Descriptor): Add dummy variable + to make sure that System_Storage_Elements is loaded. + +2025-07-01 Ronan Desplanques <desplanques@adacore.com> + + * doc/gnat_rm/gnat_language_extensions.rst: Document new extension. + * gen_il-fields.ads (Opt_Field_Enum): Add new fields. + * gen_il-types.ads (N_Loop_Flow_Statement, N_Continue_Statement): New + node kinds. + * gen_il-gen-gen_nodes.adb (N_Loop_Flow_Statement): New abstract node + kind. + (N_Continue_Statement): New node kind. + (N_Exit_Statement): Reparent below N_Loop_Flow_Statement. + * sinfo.ads (N_Continue_Statement): Add description. + * sinfo-utils.ads (Loop_Flow_Keyword): New function. + * sinfo-utils.adb (Loop_Flow_Keyword): New function. + * gen_il-gen-gen_entities.adb (E_Loop): Add new field. + * einfo.ads (Continue_Mark): Document new field. + * sprint.adb (Sprint_Node_Actual): Update for new node kind. + * snames.ads-tmpl: Add new keyword. + * par-ch5.adb (P_Continue_Statement, Parse_Loop_Flow_Statement): New + functions. + (P_Sequence_Of_Statements): Handle continue statements. + (P_Exit_Statement): Use Parse_Loop_Flow_Statement. + * sem.adb (Analyze): Handle new node kind. + * sem_ch5.adb (Analyze_Loop_Flow_Statement): New function. + (Analyze_Continue_Statement): New procedure. + (Analyze_Exit_Statement): Use new Analyze_Loop_Flow_Statement function. + * sem_ch5.ads (Analyze_Continue_Statement): New procedure. + * expander.adb (Expand): Handle new node kind. + * exp_ch5.ads (Expand_N_Continue_Statement): New procedure. + * exp_ch5.adb (Expand_Loop_Flow_Statement): New procedure. + (Expand_N_Continue_Statement): New procedure. + (Expand_N_Exit_Statement): Use new Expand_Loop_Flow_Statement + procedure. + (Build_Formal_Container_Iteration): Always reuse original loop entity. + * gnat_rm.texi: Regenerate. + +2025-07-01 Bob Duff <duff@adacore.com> + + * repinfo.adb (List_Entities): + Disable output in case of object renamings. + +2025-07-01 Aleksandra Pasek <pasek@adacore.com> + + * libgnat/s-valuen.ads: Correct comment. + +2025-07-01 Alexandre Oliva <oliva@adacore.com> + + * init.c: Include string.h. + +2025-07-01 Tonu Naks <naks@adacore.com> + + * doc/gnat_rm.rst: remove ref to 2012 chapter + * doc/gnat_rm/about_this_guide.rst: remove ref to 2012 chapter + * doc/gnat_rm/compatibility_and_porting_guide.rst: update list of + supported versions + * doc/gnat_rm/implementation_of_ada_2012_features.rst: delete + * doc/gnat_rm/specialized_needs_annexes.rst: update list of + supported versions + * gnat_rm.texi: Regenerate. + +2025-07-01 Tonu Naks <naks@adacore.com> + + * doc/gnat_rm/implementation_advice.rst: remove GLADE + * doc/gnat_rm/implementation_defined_characteristics.rst: remove GLADE + * doc/gnat_rm/specialized_needs_annexes.rst: remove GLADE + * doc/gnat_rm/the_gnat_library.rst: remove GLADE + * gnat_rm.texi: Regenerate. + +2025-07-01 Alexandre Oliva <oliva@adacore.com> + + * adaint.c [__vxworks] (alloca): Redirect to builtin. + +2025-07-01 Ghjuvan Lacambre <lacambre@adacore.com> + + * freeze.adb (Freeze_Record_Type): Check for CodePeer_Mode. + +2025-07-01 Piotr Trojanek <trojanek@adacore.com> + + * sem_ch12.adb (Analyze_Subprogram_Instantiation): Move aspects when + instantiating subprogram as a library unit. + +2025-07-01 Ronan Desplanques <desplanques@adacore.com> + + * exp_ch5.adb (Expand_N_Loop_Statement): Remove useless subexpressions. + +2025-07-01 Jose Ruiz <ruiz@adacore.com> + + * doc/gnat_ugn/gnat_and_program_execution.rst: Add the + documentation about benefits of using sanitizers in + mixed-language applications. + * gnat_ugn.texi: Regenerate. + +2025-07-01 Viljar Indus <indus@adacore.com> + + * atree.ads (Compile_Time_Pragma_Warnings): Removed. + * errout.adb (Initialize): Remove initialization for + Compile_Time_Pragma_Warnings. + (Error_Msg_Internal): Use Warning_As_Error_Kind in the + Error_Msg_Object. Set its value based on the reason the + warning was changed to an error. + (Write_JSON_Span): Adjust the code for Warn_Err. + (Output_Messages): Update the calculation for actual warnings + and errors by just using Warnings_Treated_As_Errors. + (Set_Msg_Text): Simply mark that we are dealing with a + run time message here. Move the code for the Warning_Mode to + Error_Msg_Internal. + * erroutc-pretty_emitter.adb (Write_Error_Msg_Line): Adjust the code + for Warn_Err. Use the Warn_As_Err_Tag token. + * erroutc.adb (Compilation_Errors): Simplify the implementation so + that it only checks for errors and warnings treated as errors. + (Decrease_Error_Msg_Count): Remove the count for + Compile_Time_Pragma_Warnings. + (dmsg): Adjust the code for changes to Warn_Err. + (Increase_Error_Msg_Count): Likewise and remove the count for + Compile_Time_Pragma_Warnings. + (Output_Msg_Text): Warnings converted to error by the + Warning_As_Error pragma and -gnatwE now use the error prefix + in their messages but only warnings changed by the pragma get + the [warning-as-error] tag. + (Output_Text_Within): Adjust the variable name for + Is_Runtime_Raise_Msg. + (Write_Error_Summary): Adjust printing of warnings so that it + just uses the counts for Warnings_Detected and + Warnings_Treated_As_Errors. + * erroutc.ads (Is_Runtime_Raise): renamed to Is_Runtime_Raise_Msg. + (Warning_As_Error_Kind): New type for marking the warning message + is treated as an error which also captures the reason for the + change. Historically each of the reasons will have a different way + of displaying the warning message. + (Error_Msg_Object.Warn_Err): Change type to Warning_As_Error_Kind. + (Kind_To_String): Warnings treated as errors originating from + the pragma or -gnatwE will return error where as warnings + originating from -gnatwe will return warning. + (Compilation_Errors): Update the documentation. + (Warn_As_Err_Tag): Constant string to be used when printing warnings + as errors. + * errutil.adb (Error_Msg): Adjust the code for Warn_Err. + +2025-07-01 Eric Botcazou <ebotcazou@adacore.com> + + * exp_ch7.adb (Shift_Address_For_Descriptor): New function. + (Make_Address_For_Finalize): Call above function. + (Make_Finalize_Address_Stmts): Likewise. + * exp_util.ads (Is_Constr_Array_Subt_Of_Unc_With_Controlled): New + predicate. + * exp_util.adb (Is_Constr_Array_Subt_Of_Unc_With_Controlled): Ditto. + (Remove_Side_Effects): Call above predicate. + * sem_ch3.adb (Analyze_Object_Declaration): Likewise. + * sem_ch4.adb (Analyze_Allocator): Allocate the bounds by setting + Is_Constr_Array_Subt_With_Bounds when appropriate. + +2025-07-01 Javier Miranda <miranda@adacore.com> + + * sem_ch4.adb (Try_Object_Operation): Handle mutably tagged + class-wide type prefix. + +2025-07-01 Viljar Indus <indus@adacore.com> + + * errout.adb (Error_Msg_Internal): Use the new + Warning_Treated_As_Error function. + * erroutc.adb (Get_Warning_Option): Add new version of this + function that operates on the Error_Msg_Object directly instead + of the Error_Id. Update the existing function to call the new + version interanlly. + (Get_Warning_Tag): Likewise. + (Warning_Treated_As_Error): Add a new method that combines the + checks for the error message itself and its tag. + * erroutc.ads (Get_Warning_Option): Add new spec. + (Get_Warning_Option): Likewise. + (Get_Warning_Option): Likewise. + +2025-07-01 Viljar Indus <indus@adacore.com> + + * atree.ads: Add Compile_Time_Pragma_Warnings for counting + compile time warnings. + * errout.adb (Initialize): Initialize Compile_Time_Pragma_Warnings. + (Output_Messages): Use Compile_Time_Pragma_Warnings instead of + Count_Compile_Time_Pragma_Warnings. + * erroutc.adb (Compilation_Errors): Likewise. + (Count_Compile_Time_Pragma_Warnings): Removed. + (Decrease_Error_Msg_Count): Update Compile_Time_Pragma_Warnings. + (Increase_Error_Msg_Count): Likewise. + (Write_Error_Summary): Use Compile_Time_Pragma_Warnings instead of + Count_Compile_Time_Pragma_Warnings. + * erroutc.ads (Count_Compile_Time_Pragma_Warnings): Removed. + +2025-07-01 Viljar Indus <indus@adacore.com> + + * errout.adb (Delete_Warning_And_Continuations): Use + Decrease_Error_Msg_Count to update the message counts. + (Delete_Warning): Likewise. + (To_Be_Removed): Likewise. + +2025-07-01 Viljar Indus <indus@adacore.com> + + * errout.adb (Remove_Warning_Messages): Mark removed messages as + deleted. + * erroutc.adb (Purge_Messages): Likewise. + +2025-07-01 Martin Clochard <clochard@adacore.com> + + * frontend.adb (Frontend): do not override GNATprove's setting for + Warn_On_Non_Local_Exception + +2025-07-01 Eric Botcazou <ebotcazou@adacore.com> + + * sem_ch4.adb (Analyze_Allocator): Do not set Etype to itself. + +2025-07-01 Eric Botcazou <ebotcazou@adacore.com> + + * exp_util.adb (Finalize_Address): Do not go to the root type for + array types. + +2025-07-01 Eric Botcazou <ebotcazou@adacore.com> + + * libgnat/s-valuer.ads (System.Value_R): Remove Round parameter. + (Scan_Raw_Real): Replace Extra with Extra2 and adjust the comment. + (Value_Raw_Real): Likewise. + * libgnat/s-valuer.adb (Round_Extra): Delete. + (Scan_Decimal_Digits): Replace Extra with Extra2 and adjust the + implementation. + (Scan_Integral_Digits): Replace Extra with Extra2 and Extra_Rounded + with Extra2_Filled and adjust the implementation. + (Scan_Raw_Real): Replace Extra with Extra2 and adjust the + implementation. + (Value_Raw_Real): Likewise. + * libgnat/s-valrea.adb (Impl): Remove actual for Round formal. + * libgnat/s-valued.adb (Impl): Likewise. + (Integer_to_Decimal): Replace Extra with Extra2 and adjust the + implementation. Rename Unsigned_To_Signed to To_Signed. + (Scan_Decimal): Replace Extra with Extra2 and adjust the + implementation. + (Value_Decimal): Likewise. + * libgnat/s-valuef.adb (Impl): Remove actual for Round formal. + (Integer_to_Fixed): Replace Extra with Extra2 and adjust the + implementation. Rename Unsigned_To_Signed to To_Signed. Only + round the last scaled divide operation. + (Scan_Fixed): Replace Extra with Extra2 and adjust the + implementation. + (Value_Fixed): Likewise. + +2025-07-01 Ronan Desplanques <desplanques@adacore.com> + + * libgnat/s-valuer.adb (Scan_Decimal_Digits, Scan_Integral_Digits): + Minor rephrasing. + +2025-07-01 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch5.adb (Analyze_Loop_Parameter_Specification): Set ekind + earlier. + +2025-07-01 Eric Botcazou <ebotcazou@adacore.com> + + * exp_util.ads (Is_Finalizable_Access): New predicate. + (Is_Non_BIP_Func_Call): Delete. + (Is_Secondary_Stack_BIP_Func_Call): Likewise. + * exp_util.adb (Is_Finalizable_Access): New predicate. + (Initialized_By_Aliased_BIP_Func_Call): Delete. + (Initialized_By_Reference): Likewise. + (Is_Aliased): Only consider the nontransient object serviced by + the transient scope. + (Is_Part_Of_BIP_Return_Statement): Minor tweak. + (Is_Finalizable_Transient): Remove calls to Initialized_By_Reference + and Initialized_By_Aliased_BIP_Func_Call. + Call Is_Finalizable_Access for access objects. + (Is_Non_BIP_Func_Call): Delete. + (Is_Secondary_Stack_BIP_Func_Call): Likewise. + (Requires_Cleanup_Actions): Call Is_Finalizable_Access for access + objects. + (Side_Effect_Free): Return True for N_Reference. + * exp_ch7.adb (Build_Finalizer.Process_Declarations): Call + Is_Finalizable_Access for access objects. + +2025-07-01 Eric Botcazou <ebotcazou@adacore.com> + + * exp_util.adb (Is_Expression_Of_Func_Return): New predicate. + (Is_Related_To_Func_Return): Call Is_Expression_Of_Func_Return. + (Remove_Side_Effects): Generate a temporary for a function call + that returns a constrained array type with controlled component + and an unconstrained first subtype. + +2025-07-01 Piotr Trojanek <trojanek@adacore.com> + + * inline.adb (Rewrite_Procedure_Call): Replace with a simple rewriting + of procedure call into a single block node, i.e. remove broken + optimization. + * sem_util.adb (Next_Actual): Adapt GNATprove-specific code that peeks + into inlined calls. + +2025-07-01 Martin Clochard <clochard@adacore.com> + + * exp_util.adb (Is_Controlling_Formal_Ref): test scope against + derived subprogram as well. + +2025-07-01 Viljar Indus <indus@adacore.com> + + * errout.adb (Error_Msg_Internal): Relocate Warn_As_Err propagation + to Increase_Error_Msg_Counti. + (Delete_Warning_And_Continuations): Update + Warnings_Treated_As_Errors count. + (Delete_Warning): Likewise. + (To_Be_Removed): Likewise. + * erroutc.adb (Increase_Error_Msg_Count): Count warnings treated + as errors here and perform the propagation of this property to + the parent message. + (Output_Msg_Text): Remove counting of warnings as errors from + here. + (Decrease_Error_Msg_Count): Update Warnings_Treated_As_Errors + count. + +2025-06-30 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/120106 + * Make-generated.in (GNATMAKE_FOR_BUILD): Define. + +2025-06-30 Viljar Indus <indus@adacore.com> + + * comperr.adb (Compiler_Abort): Pass the exit code in calls to + Output_Messages. + * errout.adb (Output_Messages): Add new parameter for the + Exit_Code and store its value. + * errout.ads (Output_Messages): Likewise. + * erroutc-sarif_emitter.adb (Print_Invocations): Set + Execution_Successful based on the exit code. + * erroutc.ads (Exit_Code): Store the exit code value. + * gnat1drv.adb (Gnat1drv): Pass the exit code in calls to + Output_Messages. + * prepcomp.adb (Parse_Preprocessing_Data_File, Prpare_To_Preprocess): + Likewise. + +2025-06-30 Ronan Desplanques <desplanques@adacore.com> + + * gen_il-gen-gen_entities.adb (Gen_Entities): Tweak Has_Exit. + +2025-06-30 Bob Duff <duff@adacore.com> + + * exp_attr.adb (Attribute_Max_Size_In_Storage_Elements): + Return Storage_Count'Last converted to universal_integer. + +2025-06-30 Tonu Naks <naks@adacore.com> + + * doc/gnat_rm.rst: add entry point for the new chapter + * doc/gnat_rm/about_this_guide.rst: add reference to the new + chapter + * doc/gnat_rm/implementation_of_ada_2022_features.rst: new file + * doc/gnat_rm/implementation_of_ada_2012_features.rst: update + explanation about RM references + * gnat_rm.texi: Regenerate. + * gnat_ugn.texi: Regenerate. + +2025-06-30 Ronan Desplanques <desplanques@adacore.com> + + * par-util.adb (Check_Future_Keyword): Use Snames subtypes. Extend + comment. + +2025-06-30 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch5.adb (Analyze_Loop_Statement): Remove obsolete comment. + +2025-06-30 Bob Duff <duff@adacore.com> + + * sem_warn.adb (Warn_On_Useless_Assignments): + Enable Warn_On_Useless_Assignment in the case of + Warn_On_All_Unread_Out_Parameters. + +2025-06-30 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Analyze_Subtype_Declaration): Remove uses of E_Void. + (Copy_Parent_Attributes): New procedure. + +2025-06-30 Ronan Desplanques <desplanques@adacore.com> + + * cstand.adb (Make_Aliased_Component, Make_Formal, New_Operator, + Create_Standard): Remove useless calls. + +2025-06-30 Eric Botcazou <ebotcazou@adacore.com> + + * libgnat/s-valuer.adb (Scan_Decimal_Digits): Also pretend that the + precision limit was just reached if it was already reached. + (Scan_Integral_Digits): Add Extra_Rounded out parameter, set it to + False on entry and to True when Extra is rounded. + (Scan_Raw_Real): New Extra_Rounded local variable. Pass it in the + calls to Scan_Integral_Digits. If it is True, pass a dummy extra + digit to Scan_Decimal_Digits. + +2025-06-30 Claire Dross <dross@adacore.com> + + * libgnat/a-strsup.ads: Ignore Ghost_Predicate in the assertion policy. + +2025-06-30 Javier Miranda <miranda@adacore.com> + + * sem_aggr.adb (Resolve_Record_Aggregate): Adjust the code to + handle mutably tagged class-wide types since they don't have + discriminants, but all class-wide types are considered to have + unknown discriminants. Initialize mutably tagged class-wide + type components calling their IP subprogram. + * exp_aggr.adb (Gen_Assign): Handle mutably tagged class-wide type + components that have an initializing qualified expression, and + mutably tagged class-wide components default initialization. + (Gen_Loop): Handle mutably tagged class-wide types. + (Gen_Assign): ditto. + (Build_Record_Aggr_Code): Default initialization of mutably tagged + class-wide types is performed by their IP subprogram. + * exp_ch3.adb (Init_Component): Generate code to raise Program_Error + in the IP subprogram of arrays when the type of their components is + a mutably tagged abstract class-wide type. + (Build_Init_Procedure): ditto for the init procedure of record types. + (Build_Init_Statements): Ensure that the type of the expression + initializing a mutably class-wide tagged type component is frozen. + (Requires_Init_Proc): Mutably tagged class-wide types require the + init-proc since it takes care of their default initialization. + * sem_util.adb (Needs_Simple_Initialization): Mutably tagged class-wide + types don't require simple initialization. + * types.ads (PE_Abstract_Type_Component): New reason for Program_Error. + * types.h (PE_Abstract_Type_Component): ditto. + * exp_ch11.adb (Get_RT_Exception_Name): Handle new reason for + Program_Error. + * libgnat/a-except.adb (Rcheck_PE_Abstract_Type_Component): New + subprogram. + +2025-06-30 Piotr Trojanek <trojanek@adacore.com> + + * sem_util.ads (Get_Enclosing_Object, Get_Enum_Lit_From_Pos, + Is_Universal_Numeric_Type): Reorder declarations. + +2025-06-30 Piotr Trojanek <trojanek@adacore.com> + + * sem_util.adb (Get_Enclosing_Object): Traverse unchecked type + conversions since they from the compiler and should be transparent for + semantic reasoning. + +2025-06-30 Steve Baird <baird@adacore.com> + + * einfo-utils.adb (Predicate_Function): Look through an Itype if + that takes us to another subtype of the same type. + +2025-06-30 Gary Dismukes <dismukes@adacore.com> + + * exp_util.adb (Must_Map_Call_To_Parent_Primitive): Change function + name (was Call_To_Parent_Dispatching_Op_Must_Be_Mapped). Move logic + for attributes and dereferences, plus testing for controlled formals, + into new function Expr_Has_Ctrl_Formal_Ref. Add handling for + access attributes, multiple levels of attributes/dereferences, + conditional_expressions, and declare_expressions. Properly account + for function calls with multiple operands and enclosing calls. + (Expr_Has_Ctrl_Formal_Ref): New function to determine whether + an expression is a reference to a controlling formal or has + a prefix that is such a reference. + (Is_Controlling_Formal_Ref): New function in Expr_Has_Ctrl_Formal_Ref + to determine if a node is a direct reference to a controlling formal. + * freeze.adb (Build_DTW_Body): Create an unchecked conversion instead + of a regular type conversion for converting actuals in calls to parent + inherited primitives that are wrapped for inherited pre/postconditions. + Avoids generating unnecessary checks (such as accessibility checks on + conversions for anonymous access formals). + +2025-06-30 Piotr Trojanek <trojanek@adacore.com> + + * sem_util.ads (Get_Enclosing_Ghost_Entity): Rename spec. + * sem_util.adb (Get_Enclosing_Ghost_Object): Rename body; reorder + alphabetically; adapt recursive call. + * ghost.adb: Adapt calls to Get_Enclosing_Ghost_Object. + +2025-06-30 Piotr Trojanek <trojanek@adacore.com> + + * ghost.adb (Ghost_Entity): Remove; use Get_Enclosing_Ghost_Object + instead; adapt callers. + +2025-06-30 Eric Botcazou <ebotcazou@adacore.com> + + * sem_prag.adb (Analyze_Pragma) <Pragma_No_Component_Reordering>: + Call Find_Type on the first argument of the pragma. + +2025-06-30 Tonu Naks <naks@adacore.com> + + * gnatls.adb: remove -l switch + +2025-06-30 Steve Baird <baird@adacore.com> + + * doc/gnat_rm/gnat_language_extensions.rst: Update documentation for + mutably tagged types and the Size'Class aspect. + * gnat_rm.texi: Regenerate. + +2025-06-30 Piotr Trojanek <trojanek@adacore.com> + + * ghost.adb + (Whole_Object_Ref): Remove; use Get_Enclosing_Ghost_Object instead. + (Is_Ghost_Assignment): Handle more than object identifiers. + (Mark_And_Set_Ghost_Assignment): Likewise. + * sem_util.adb (Get_Enclosing_Ghost_Object): Detect more expressions + as ghost references; rename to better match the intended meaning. + * sem_util.ads (Get_Enclosing_Ghost_Object): Rename; adjust comment. + +2025-06-30 Eric Botcazou <ebotcazou@adacore.com> + + * exp_aggr.adb (Backend_Processing_Possible.Component_Check): Return + False for delayed conditional expressions. + +2025-06-30 Eric Botcazou <ebotcazou@adacore.com> + + * exp_aggr.ads (Parent_Is_Regular_Aggregate): New predicate. + * exp_aggr.adb (In_Place_Assign_OK.Safe_Component): Implement more + accurate criterion for function calls. + (Convert_To_Assignments): Use Parent_Is_Regular_Aggregate predicate. + (Expand_Array_Aggregate): Likewise. Remove obsolete comment. + (Initialize_Component): Do not adjust when the expression is a naked + function call and Back_End_Return_Slot is True. + (Parent_Is_Regular_Aggregate): New predicate. + * exp_ch3.adb (Build_Record_Init_Proc.Build_Assignment): Add test of + Back_End_Return_Slot in conjunction with a function call. + * exp_ch4.adb (Expand_Allocator_Expression): Likewise. Use the + Is_Container_Aggregate predicate to detect container aggregates. + (Expand_N_Case_Expression): Delay the expansion if the parent is a + regular aggregate and the type should not be copied. + (Expand_N_If_Expression): Likewise. + (New_Assign_Copy): New function. + * exp_ch6.adb (Expand_Ctrl_Function_Call): Bail out when the parent + is a regular aggregate. + * sem_util.adb (Check_Function_Writable_Actuals): Do not take into + account attribute references created by the compiler. + +2025-06-30 Alexandre Oliva <oliva@adacore.com> + + * socket.c [__vxworks] + (__gnat_gethostbyname): Drop excess '&'. + (__gnat_gethostbyaddr): Likewise. + +2025-06-30 Alexandre Oliva <oliva@adacore.com> + + * adaint.c [__vxworks]: Include ctype.h. + +2025-06-30 Steve Baird <baird@adacore.com> + + * exp_put_image.adb (Build_Record_Put_Image_Procedure): If + Discriminant_Specifications takes us from the full view of a type + to an (intentionally) unanalyzed subtree, then instead find + discriminant entities by calling Discriminant_Specifications on + the partial view of the type. + +2025-06-30 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch6.adb (Check_Delayed_Subprogram, Possible_Freeze): Restrict + cases where freezing is delayed. + * sem_ch6.ads (Check_Delayed_Subprogram): Improve documentation + comment. + * sprint.adb (Write_Itype): Improve output. + +2025-06-30 Eric Botcazou <ebotcazou@adacore.com> + + * libgnat/s-valrea.adb (Integer_to_Real): Rename to... + (Integer_To_Real): ...this. Remove the second condition of the + conjunction in the test for the zero value. + (Scan_Real): Adjust to above renaming. + (Value_Real): Likewise. + * libgnat/s-valuer.ads (Scan_Raw_Real): Add note about Val. + +2025-06-30 Jose Ruiz <ruiz@adacore.com> + + * doc/gnat_ugn/gnat_and_program_execution.rst: Fix a + couple of minor formatting issues. + * gnat_ugn.texi: Regenerate. + +2025-06-30 Ronan Desplanques <desplanques@adacore.com> + + * treepr.ads (Print_Entity_Chain, pec, rpec): New subprograms. + * treepr.adb (Print_Entity_Chain, pec, rpec): Likewise. + +2025-06-30 Ronan Desplanques <desplanques@adacore.com> + + * atree.ads (Parent_Or_List_Containing): Fix typo. + +2025-06-30 Ronan Desplanques <desplanques@adacore.com> + + * treepr.adb (Print_Node): Tweak Parent field printing. + +2025-06-30 Jose Ruiz <ruiz@adacore.com> + + * doc/gnat_ugn/gnat_and_program_execution.rst: Add the + documentation about using sanitizers with Ada code. + * gnat_ugn.texi: Regenerate. + +2025-06-30 Jose Ruiz <ruiz@adacore.com> + + * doc/gnat_ugn/gnat_and_program_execution.rst: Add the + documentation about using sanitizers with Ada code. + * gnat_ugn.texi: Regenerate. + +2025-06-30 Piotr Trojanek <trojanek@adacore.com> + + * sem_util.adb (Get_Enclosing_Object): Remove dead code. + +2025-06-30 Steve Baird <baird@adacore.com> + + * einfo-utils.adb (Predicate_Function): Improve handling of a case + where a predicate specified for a subtype of a partial view of a + type was incorrectly ignored. + (Set_Predicate_Function): If the attribute has already been set to + the same value, then do nothing (instead of raising P_E). + * sem_ch13.adb (Build_Predicate_Function): Add new function + Has_Source_Predicate. If a subtype inherits a predicate but also + has its own explicitly specified predicate, then avoid + misinterpreting the presence of the function built for the + inherited predicate to mean that no additional predicate function + is needed. + * sem_util.adb (Build_Subtype): In the case where we are given a + constrained record or array subtype and we need to construct a + different subtype, subject to a different constraint, the + subtype_mark of the constructed subtype needs to reference an + unconstrained subtype (because a new constraint is going to be + imposed). If the Predicated_Parent attribute of the given subtype + is present and refers to a suitable unconstrained subtype, then + use that subtype instead of setting the Predicated_Parent + attribute on a new node (and performing the associated attribute + copying). + +2025-06-30 Eric Botcazou <ebotcazou@adacore.com> + + * exp_ch7.adb (Process_Transient_In_Scope): Bail out if the object + is an ignored ghost entity. + +2025-06-30 Eric Botcazou <ebotcazou@adacore.com> + + * exp_util.adb (Insert_Actions): Extend special treatment applied + to freeze nodes to the case of blocks generated for aggregates. + +2025-06-30 Johannes Kliemann <kliemann@adacore.com> + + * libgnat/s-valuer.adb: Switch missing if-statements to + short-circuit form. + * libgnat/i-cpoint.adb: Ditto. + +2025-06-28 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/120854 + * sem_eval.adb (Get_String_Val): Be prepared for an integer literal + after a serious error is detected, and raise PE on other nodes. + +2025-06-26 David Malcolm <dmalcolm@redhat.com> + + * gcc-interface/misc.cc (gnat_init): Use + diagnostic_context::set_internal_error_callback. + +2025-06-22 Nicolas Boulenguez <nicolas@debian.org> + + PR ada/120106 + * gcc-interface/Make-lang.in: Set GNAT{MAKE,BIND,LINK_LS}_FOR_HOST + from GNAT{MAKE,BIND} instead of using hardcoded commands. + +2025-06-22 Eric Botcazou <ebotcazou@adacore.com> + + * Make-generated.in: Remove obsolete stuff. + +2025-06-22 Nicolas Boulenguez <nicolas@debian.org> + + PR ada/120106 + PR ada/120106 + * Make-generated.in: Use GNATMAKE_FOR_BUILD instead of gnatmake. + * gcc-interface/Makefile.in: Likewise. + +2025-06-17 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/120665 + * sem_aggr.adb (Resolve_Container_Aggregate): Use robust guards. + +2025-06-12 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Variable>: Generate + a zero-initialization for the anonymous object of a small aggregate + allocated on the stack. + (inline_status_for_subprog): Minor tweak. + +2025-06-12 Tonu Naks <naks@adacore.com> + + * comperr.adb: update support instructions + * switch.adb: update support instructions + +2025-06-12 Ronan Desplanques <desplanques@adacore.com> + + * sinfo.ads: Fix RM reference. + +2025-06-12 Piotr Trojanek <trojanek@adacore.com> + + * sem_ch3.adb (Apply_External_Initialization): Reuse local constant. + +2025-06-12 Eric Botcazou <ebotcazou@adacore.com> + + * doc/gnat_rm/gnat_language_extensions.rst + (Generalized Finalization): Document the actual implementation. + (No_Raise): Move to separate section. + * gnat_rm.texi: Regenerate. + +2025-06-12 Ronan Desplanques <desplanques@adacore.com> + + * libgnat/s-valuer.adb (Scan_Raw_Real): Apply tweak. + +2025-06-12 Tonu Naks <naks@adacore.com> + + * comperr.adb: replace report@ with support@ + * gnatcmd.adb: replace report@ with support@ + +2025-06-12 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Build_Derived_Private_Type): Fix test. + (Build_Derived_Record_Type): Adjust error recovery paths. + +2025-06-12 Eric Botcazou <ebotcazou@adacore.com> + + * einfo.ads (Has_Homonym): Fix inaccuracy in description. + * sem_ch8.ads (Find_Direct_Name): Remove obsolete description. + * sem_ch12.adb (Analyze_Associations): Rename I_Node parameter + into N and adjust description. + (Analyze_Subprogram_Instantiation): Add missing description. + (Contains_Instance_Of): Fix description. + (Associations): Rename Generic_Actual_Rec into Actual_Rec and + Gen_Assocs_Rec into Match_Rec. + (Analyze_One_Association): Rename I_Node parameter into N. + (Check_Fixed_Point_Warning): Rename Gen_Assocs parameter into + Match. + (Body of Associations): Minor cleanups and tweaks. + (Analyze_Associations): Rename I_Node parameter into N and + adjust implementation. + (Analyze_One_Association): Likewise. + (Analyze_Package_Instantiation): Remove obsolete code and clean up. + (Check_Fixed_Point_Warning): Rename Gen_Assocs parameter into + Match and adjust implementation. + (Freeze_Package_Instance): Simplify condition. + (Get_Unit_Instantiation_Node): Add support for instantiations of + subprograms and stop the loop properly in case of errors. + * sem_util.ads (Add_Global_Declaration): Rename N parameter into + Decl and fix description. + * sem_util.adb (Add_Global_Declaration): Rename N parameter into + Decl and adjust implementation. + +2025-06-12 Ronan Desplanques <desplanques@adacore.com> + + * libgnat/s-valuer.adb (Scan_Raw_Real): Add RM reference. + +2025-06-12 Ronan Desplanques <desplanques@adacore.com> + + * libgnat/s-valuer.adb (Scan_Raw_Real): Remove subexpression. Improve + surrounding comments. + +2025-06-12 Bob Duff <duff@adacore.com> + + * vast.adb: Check basic tree properties. + * atree.adb (Traverse_Field): Minor. + * treepr.adb (Destroy): Minor comment. + +2025-06-12 Eric Botcazou <ebotcazou@adacore.com> + + * libgnat/s-valuer.adb (Round_Extra): Use multiplicative test. + +2025-06-12 Ronan Desplanques <desplanques@adacore.com> + + * einfo-utils.adb (Set_Convention): Remove obsolete test. + +2025-06-12 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Process_Discriminants): Set Ekind earlier. + * sem_util.adb (Enter_Name): Adjust error processing. + +2025-06-12 Eric Botcazou <ebotcazou@adacore.com> + + * libgnat/s-valuef.adb (Integer_To_Fixed): Enable overflow checks. + Deal specifically with Val = 2**(Int'Size - 1) if Minus is not set. + Exit the loop when V saturates to 0 in the case of (huge) negative + exponents. + +2025-06-12 Ronan Desplanques <desplanques@adacore.com> + + * exp_util.adb (Insert_Actions): Refine test. + +2025-06-12 Eric Botcazou <ebotcazou@adacore.com> + + * doc/gnat_ugn/building_executable_programs_with_gnat.rst (Compiler + switches) <-O>: Fix long line. + * gnat_ugn.texi: Regenerate. + +2025-06-12 Eric Botcazou <ebotcazou@adacore.com> + + * doc/gnat_ugn/building_executable_programs_with_gnat.rst (List of + all switches): Add -gnatRh subswitch. + (Debugging Control): Document -gnatRh subswitch. + * opt.ads (List_Representation_Info_Holes): New boolean variable. + * repinfo.adb: Add with clause for GNAT.Heap_Sort_G. + (List_Common_Type_Info): Relax assertion. + (List_Object_Info): Replace assertion with additional test. + (List_Record_Layout): If -gnatRh is specified, make sure that the + components are ordered by increasing offsets. Output a comment + line giving the number of unused bits if there is a hole between + consecutive components. Streamline the control flow of the loop. + (List_Record_Info): Use the original record type giving the layout + of components, if any, to display the layout of the record. + * switch-c.adb (Scan_Front_End_Switches) <-gnatR>: Add support for + -gnatRh subswitch. + * usage.adb (Usage): Document -gnatRh subswitch. + * gnat_ugn.texi: Regenerate. + +2025-06-12 Johannes Kliemann <kliemann@adacore.com> + + * libgnat/s-secsta.adb (SS_Allocate): Add comment about + conservative alignment padding calculation. + * libgnat/s-secsta__cheri.adb (SS_Allocate): Add comment about + conservative alignment padding calculation. + +2025-06-12 Ronan Desplanques <desplanques@adacore.com> + + * sem_warn.adb (Check_References): Rewrite expression + +2025-06-12 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Constrain_Index, Make_Index, Array_Type_Declaration, + Analyze_Number_Declaration): Remove uses of E_Void. + +2025-06-12 Eric Botcazou <ebotcazou@adacore.com> + + * usage.adb (Usage): Justify the documentation of common switches + like that of other switches. Rework that of the -O switch. + * doc/gnat_ugn/building_executable_programs_with_gnat.rst (Compiler + switches) <-O>: Rework and document 'z' and 'g' operands. + * doc/gnat_ugn/gnat_and_program_execution.rst (Optimization Levels): + Rework and document -Oz and -Og switches. + * gnat_ugn.texi: Regenerate. + +2025-06-12 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Constrain_Index): Avoid unused itypes. + +2025-06-12 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Constrain_Index): Factorize return statement. + +2025-06-12 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Build_Derived_Numeric_Type): Remove duplicate call. + +2025-06-10 Piotr Trojanek <trojanek@adacore.com> + + * gen_il-gen-gen_entities.adb (Formal_Object_Kind): Remove + Entry_Component field. + +2025-06-10 Piotr Trojanek <trojanek@adacore.com> + + * sem_attr.adb (Resolve_Attribute): Remove redundant guard. + +2025-06-10 Eric Botcazou <ebotcazou@adacore.com> + + * inline.adb (Analyze_Inlined_Bodies): Minor comment tweak. + +2025-06-10 Eric Botcazou <ebotcazou@adacore.com> + + * inline.adb (Instantiate_Body): Do not call Add_Scope_To_Clean if + the main unit is generic. + (Instantiate_Bodies): Do not deal with generic main units here. + * sem_ch12.adb (Need_Subprogram_Instance_Body): Return false if the + main unit is generic. + +2025-06-10 Eric Botcazou <ebotcazou@adacore.com> + + * Makefile.rtl (ADA_EXCLUDE_SRCS): Add the 128-bit support files. + +2025-06-10 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Process_Subtype): Factorize code. + +2025-06-10 Bob Duff <duff@adacore.com> + + * einfo.ads (Associated_Node_For_Itype): Document that + Parent field may be empty. + * vast.adb: Allow empty Parent in Itypes. + +2025-06-10 Gary Dismukes <dismukes@adacore.com> + + * einfo.ads: Revise comment about Dynamic_Predicate flag to make it + more accurate. + * sem_case.adb (Check_Choices): Test "not Has_Static_Predicate_Aspect" + as additional guard for error about use of subtype with nonstatic + predicate as a case choice. Improve related error message. + +2025-06-10 Tonu Naks <naks@adacore.com> + + * libgnat/s-valueu.adb: add explict raise + * libgnat/s-valueu.ads: update annotation + +2025-06-10 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch6.adb, sem_ch6.ads (Check_Discriminant_Conformance): Move to … + * sem_ch3.adb (Check_Discriminant_Conformance): … here. + +2025-06-10 Eric Botcazou <ebotcazou@adacore.com> + + * freeze.adb (Freeze_Static_Object): Do not issue any error message + for compiler-generated entities. + +2025-06-10 Bob Duff <duff@adacore.com> + + * vast.adb: Implement two checks. Improve debugging + outputs. + +2025-06-10 Eric Botcazou <ebotcazou@adacore.com> + + * exp_ch4.adb (Insert_Conditional_Object_Declaration): Deal with a + transient scope being created around the declaration. + * freeze.adb (Freeze_Entity): Do not call Freeze_Static_Object for + a renaming declaration. + +2025-06-10 Eric Botcazou <ebotcazou@adacore.com> + + * libgnat/s-vafi32.ads: Fix head description. + * libgnat/s-vafi64.ads: Likewise. + * libgnat/s-vafi128.ads: Likewise. + +2025-06-10 Bob Duff <duff@adacore.com> + + * vast.adb: Initial implementation. + * vast.ads: Rename procedure. Remove parameter; body should decide + what to do. + * lib.ads (ipu): Minor: Rewrite comment for brevity, and because + of an inconvenient misspelling. + (Num_Units): Not used; remove. + (Remove_Unit): Minor: Remove "Currently" (which was current a decade + ago from) comment. + * lib.adb (Num_Units): Not used; remove. + * debug_a.adb (Debug_A_Entry): Fix bug: Use Write_Name_For_Debug, + so this won't crash on the Error node. + * debug.adb: Document -gnatd_V and -gnatd_W compiler switches. + * exp_ch6.adb (Validate_Subprogram_Calls): Remove redundant check for + Serious_Errors_Detected. (We turn off code gen when errors are + detected.) + * frontend.adb: Move decisions into VAST body. + * namet.ads (Present): Remove unnecessary overriding; these are + inherited by the derived types. + * namet.adb (Present): Likewise. + +2025-06-10 Gary Dismukes <dismukes@adacore.com> + + * exp_aggr.adb (Build_Container_Aggr_Code.To_Int): Apply Enumeration_Pos + to Entity (Expr) rather than Expr. + +2025-06-10 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Find_Type_Of_Object): Fix comment. + +2025-06-10 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Analyze_Component_Declaration): Rename constant. + +2025-06-10 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Constrain_Array): Simplify. + (Process_Subtype): Adjust. + +2025-06-10 Eric Botcazou <ebotcazou@adacore.com> + + * sem_ch12.adb (Copy_Generic_Node): Do not call Root_Type to find + the root type of an aggregate of a derived tagged type. + +2025-06-10 Ronan Desplanques <desplanques@adacore.com> + + * libgnarl/s-stusta.adb (Compute_All_Tasks): Skip terminated tasks. + +2025-06-10 Viljar Indus <indus@adacore.com> + + * sem_prag.adb (Is_Configuration_Pragma): Check that nodes + preceding the pragma are pragma nodes or originally were + pragma nodes. + +2025-06-10 Eric Botcazou <ebotcazou@adacore.com> + + * libgnat/s-valued.adb (Integer_to_Decimal): Add Extra parameter and + use its value to call Bad_Value on boundary values. + (Scan_Decimal): Adjust call to Integer_to_Decimal. + (Value_Decimal): Likewise. + +2025-06-10 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.ads (Process_Subtype): New formal. + * sem_ch3.adb (Process_Subtype): Likewise. + (Analyze_Subtype_Declaration, Access_Type_Declaration): Use new + formal. + +2025-06-10 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Process_Subtype): Fix recursive call. + +2025-06-10 Eric Botcazou <ebotcazou@adacore.com> + + * par-ch5.adb (P_Declare_Statement): Rename local variable. + (P_Begin_Statement): Likewise. + +2025-06-10 Piotr Trojanek <trojanek@adacore.com> + + * einfo.ads (Overridden_Operation, Static_Initialization): Remove + comments about a reused entity field. + +2025-06-10 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Process_Subtype): Tweak formatting. + +2025-06-10 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Process_Subtype): Add assertion. + +2025-06-10 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Process_Subtype): Factorize initialization of variable. + +2025-06-09 Gary Dismukes <dismukes@adacore.com> + + * sem_ch3.adb (Constrain_Index): In the case of a fixed-lower-bound index, + set Etype of the newly created itype's Scalar_Range from the index's Etype. + * sem_ch12.adb (Validate_Array_Type_Instance): If the actual subtype is + a fixed-lower-bound type, then check again the Etype of its Scalar_Range. + +2025-06-09 Piotr Trojanek <trojanek@adacore.com> + + * sem_prag.adb (Analyze_Pragma): Fix conditions for legality checks on + formal type declarations. + +2025-06-09 Piotr Trojanek <trojanek@adacore.com> + + * sem_prag.adb (Analyze_Pragma): If pragmas apply to a formal array + type, then set the flags on the base type. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Process_Subtype): Clarify code. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.ads (Process_Subtype): Add formal. + * sem_ch3.adb (Process_Subtype): Use new formal. + (Analyze_Subtype_Declaration, Array_Type_Declaration, + Build_Derived_Access_Type): Pass new actual. + * sem_ch4.adb (Find_Type_Of_Object): Likewise. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch6.adb (Set_Formal_Mode): Extend profile. Move parts of the + body… + (Process_Formals): … here. Move call to Set_Formal_Mode earlier. Call + Set_Is_Not_Self_Hidden in second traversal. + +2025-06-09 Gary Dismukes <dismukes@adacore.com> + + * exp_aggr.adb (Expand_Container_Aggregate): Use the Base_Type of the + subtype provided by the context as the subtype of the temporary object + initialized by the aggregate. + +2025-06-09 Eric Botcazou <ebotcazou@adacore.com> + + * par-ch4.adb (P_Function_Name): Delete body. + (P_Qualified_Simple_Name_Resync): Do not raise Error_Resync on an + operator symbol followed by something else than a dot. + * par-ch6.adb (P_Subprogram): Do not call P_Function_Name. + * par.adb (P_Function_Name): Delete declaration. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem.adb (Analyze): Adapt to new Ekinds. + * sem_ch3.adb (Analyze_Component_Declaration): Set Ekind early. + (Is_Visible_Component, Record_Type_Definition): Adjust. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem.adb (Analyze): Fix comment. + +2025-06-09 Eric Botcazou <ebotcazou@adacore.com> + + * par-ch4.adb (P_Name): Remove obsolete references in comments. + (P_Qualified_Simple_Name): Call P_Qualified_Simple_Name_Resync. + (P_Qualified_Simple_Name_Resync): Adjust a couple of comments. + +2025-06-09 Gary Dismukes <dismukes@adacore.com> + + * exp_util.adb (Call_To_Parent_Dispatching_Op_Must_Be_Mapped): Replace + test of Covers with test of Is_Controlling_Formal. Add handling for + 'Result actuals. Remove Actual_Type and its uses. + +2025-06-09 Piotr Trojanek <trojanek@adacore.com> + + * sem_util.adb (Is_Name_Reference): Remove check for selector_name of a + selected_component; reuse existing code for indexed components and + slices. + (Statically_Names_Object): Remove dead code. + +2025-06-09 Eric Botcazou <ebotcazou@adacore.com> + + * einfo.ads (Overlays_Constant): Define in constants and variables. + * gen_il-gen-gen_entities.adb (Entity_Kind): Move Overlays_Constant + semantic flag to... + (Constant_Or_Variable_Kind): ...here. + * sem_util.adb (Note_Possible_Modification): Add guard. + +2025-06-09 Bob Duff <duff@adacore.com> + + * exp_ch6.adb: (Make_Build_In_Place_Call_In_Object_Declaration): + Deal with renamings transformed into object declarations. + * sem_ch8.adb (Analyze_Object_Renaming): + Reinstate transformation of a renaming into + an object declaration. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Analyze_Object_Declaration): Call Mutate_Ekind earlier. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Analyze_Object_Declaration): Tweak error handling. + +2025-06-09 Piotr Trojanek <trojanek@adacore.com> + + * par-ch13.adb (Get_Aspect_Specifications): Save and restore flag while + parsing aspect Abstract_State. + * par-ch2.adb (P_Pragma): Same while parsing pragma Abstract_State. + * par-ch4.adb (P_Aggregate_Or_Paren_Expr): Specialize error message + for contract Abstract_State and extended aggregate. + * par.adb (Inside_Abstract_State): Add new context flag. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch10.adb (Analyze_Compilation_Unit): Check for generic bodies. + * exp_disp.adb (Build_Dispatch_Tables): Likewise. + +2025-06-09 Piotr Trojanek <trojanek@adacore.com> + + * sem_util.adb (Find_Overlaid_Entity): Don't call Etype on empty Ent; + tune style; move computation of Overl_Typ out of the loop. + +2025-06-09 Javier Miranda <miranda@adacore.com> + + * doc/gnat_rm/implementation_defined_pragmas.rst: Adding + documentation. + * doc/gnat_ugn/the_gnat_compilation_model.rst: ditto. + * gnat_rm.texi: Regenerate. + * gnat_ugn.texi: Regenerate. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem_attr.adb (Analyze_Attribute): Remove test. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem_util.adb (Enter_Name): Remove special handling. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem_util.adb (Enter_Name): Remove comment. + +2025-06-09 Bob Duff <duff@adacore.com> + + * exp_ch6.adb: Remove a couple of "???" suggesting something that + we will likely never do. + (Make_Build_In_Place_Call_In_Object_Declaration): + When a constraint check is needed, do the check. + Do it at the call site for now. + The check is still missing in the untagged case, + because the caller allocates in that case. + * sem_ch8.adb (Analyze_Object_Renaming): + Remove obsolete transformation of a renaming into + an object declaration. Given that we also (sometimes) tranform + object declarations into renamings, this transformation was + adding complexity; the new code in + Make_Build_In_Place_Call_In_Object_Declaration above + would need to explicitly avoid the run-time check in the case of + renamings, because renamings are supposed to ignore the nominal + subtype. Anyway, it is no longer needed. + * exp_ch3.adb (Expand_N_Object_Declaration): Rewrite comment; + it IS clear how to do it, but we haven't done it right yet. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * atree.ads (Copy_Node): Fix comment. + +2025-06-09 Piotr Trojanek <trojanek@adacore.com> + + * exp_attr.adb (Expand_N_Attribute_Reference): When expanding attribute + Valid, use signedness from the validated view, not from its base type. + +2025-06-09 Marc Poulhiès <poulhies@adacore.com> + + * sem_util.adb (Find_Overlaid_Entity): Add extra parameter to + extract the type being overlaid. + (Note_Possible_Modification): Adjust call to Find_Overlaid_Entity. + (Ultimate_Overlaid_Entity): Likewise. + * sem_ch13.adb (Analyze_Attribute_Definition_Clause): Likewise. + * sem_util.ads (Find_Overlaid_Entity): Add extra parameter to + extract the type being overlaid. + * freeze.adb (Check_Address_Clause): Likewise. + +2025-06-09 Gary Dismukes <dismukes@adacore.com> + + * contracts.adb (Inherit_Condition): Remove Assoc_List and its uses + along with function Check_Condition, since mapping of formals will + effectively be done in Build_Class_Wide_Expression (by Replace_Entity). + * exp_util.adb (Replace_Entity): Only rewrite entity references in + function calls that qualify according to the result of calling the + new function Call_To_Parent_Dispatching_Op_Must_Be_Mapped. + (Call_To_Parent_Dispatching_Op_Must_Be_Mapped): New function that + determines whether a function call to a primitive of Par_Subp + associated tagged type needs to be mapped (according to whether + it has any actuals that reference controlling formals of the + primitive). + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch3.adb (Analyze_Object_Declaration): Remove comment. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem_util.ads (Current_Entity_In_Scope): Add example in comment. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * atree.ads (Rewrite, Replace): Clarify comments. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * atree.ads (Rewrite): Remove comment. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * atree.adb (Rewrite): Improve readability. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem_util.adb (Kill_Current_Values): Tweak condition. + +2025-06-09 Eric Botcazou <ebotcazou@adacore.com> + + * exp_ch4.adb (Insert_Conditional_Object_Declaration): Remove Decl + formal parameter, add Typ and Const formal parameters. + (Expand_N_Case_Expression): Fix pasto in comment. Adjust call to + Insert_Conditional_Object_Declaration and tidy up surrounding code. + (Expand_N_If_Expression): Adjust couple of calls to + Insert_Conditional_Object_Declaration. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch8.adb (Find_Selected_Component): Fix error path. + +2025-06-09 Eric Botcazou <ebotcazou@adacore.com> + + * libgnat/s-dourea.adb (Is_Infinity): Rename to... + (Is_Infinity_Or_NaN): ...this. + ("*"): Adjust accordingly. + ("/"): Likewise. + (Sqr): Likewise. + * libgnat/s-dorepr.adb (Two_Prod): Likewise. + (Two_Sqr): Likewise. + * libgnat/s-dorepr__fma.adb (Two_Prod): Likewise. + +2025-06-09 Daniel King <dmking@adacore.com> + + * libgnat/i-cheri.ads + (Set_Bounds, Set_Exact_Bounds): Remove wrong intrinsic binding. + * libgnat/i-cheri.adb + (Set_Bounds, Set_Exact_Bounds): New subprogram bodies. + +2025-06-09 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch8.adb (Find_Selected_Component): Add mention. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * urealp.adb (UR_Negate): Capture array element in a local constant. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * urealp.adb (UR_Exponentiate): Use local variable. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * sem_ch13.adb (Analyze_Attribute_Definition_Clause): Tune code for + attribute Small. + * sem_prag.adb (Analyze_Attribute): Tune code for pragma Time_Slice. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * ada_get_targ.adb, cstand.ads, cstand.adb, sem_eval.adb, sem_eval.ads, + urealp.adb, urealp.ads: Tune style. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * get_targ.ads (Register_Proc_Type): Add null exclusion. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * cstand.adb (Build_Float_Type, Register_Float_Type): Refine + parameter subtypes. + * set_targ.ads (FPT_Mode_Entry): Refine component subtype. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * sem_prag.adb (Analyze_Pragma): Add dependency of Program_Exit on + Global and Depends contracts. + (Analyze_Program_Exit_In_Decl_Part): Check references to subprogram + outputs. + +2025-06-06 Claire Dross <dross@adacore.com> + + * doc/gnat_rm/implementation_defined_pragmas.rst + (Pragma Exit_Cases): Update the documentation for Exit_Cases. + * sem_prag.adb + (Anlayze_Pragma): Accept Program_Exit as an exit kind. + * gnat_rm.texi: Regenerate. + * gnat_ugn.texi: Regenerate. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * aspects.ads (Aspect_Argument): Argument for Program_Exit is now + optional. + * doc/gnat_rm/implementation_defined_pragmas.rst + (Pragma Program_Exit): Change documentation for pragma syntax. + * sem_prag.adb (Analyze_Pragma): Argument for Program_Exit is now + optional. + (Analyze_Program_Exit_In_Decl_Part): Likewise. + * gnat_rm.texi: Regenerate. + * gnat_ugn.texi: Regenerate. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * aspects.ads (Aspect_Id): Add new aspect identifier. + (Aspect_Argument): Specify argument for the new aspect. + (Is_Representation_Aspect): New aspect is not a representation aspect. + (Aspect_Names): Map new aspect to name. + (Aspect_Delay): New aspect is always delayed. + * contracts.adb (Expand_Subprogram_Contract) + (Add_Pre_Post_Condition, Add_Contract_Item) + (Analyze_Entry_Or_Subprogram_Contract) + (Analyze_Entry_Or_Subprogram_Body_Contract) + (Analyze_Subprogram_Body_Stub_Contract): Support new aspect. + * contracts.ads (Add_Contract_Item, + Analyze_Entry_Or_Subprogram_Contract, + Analyze_Entry_Or_Subprogram_Body_Contract, + Analyze_Subprogram_Body_Stub_Contract): Mention new contract in + comment. + * doc/gnat_rm/implementation_defined_aspects.rst + (Aspect Program_Exit): Document new aspect. + * doc/gnat_rm/implementation_defined_pragmas.rst + (Pragma Program_Exit): Document new pragma. + * einfo-utils.adb (Get_Pragma): Support new pragma. + * einfo-utils.ads (Get_Pragma): Mention new pragma in comment. + * exp_prag.adb (Expand_Pragma_Program_Exit): Expand new pragma; + body. + * exp_prag.ads (Expand_Pragma_Program_Exit): Expand new pragma; + spec. + * inline.adb (Remove_Aspects_And_Pragmas): Support new pragma. + * par-prag.adb (Prag): Support new pragma. + * sem_attr.adb (Analyze_Attribute_Old_Result): Accept attribute + Old in new pragma. + * sem_ch12.adb (Implementation of Generic Contracts): Mention new + aspect in comment. + * sem_ch13.adb (Insert_Pragma, Analyze_Aspect_Specifications): + Convert new new aspect to pragma. + * sem_ch6.adb (Analyze_Subprogram_Body_Helper): Renumber + subsequent rule in comment. + * sem_prag.adb (Check_Postcondition_Use_In_Inlined_Subprogram) + (Contract_Freeze_Error): Mention new pragma in comment. + (Analyze_Pragma): Support new pragma; renumber subsequent rule in + comment. + (Analyze_Program_Exit_In_Decl_Part): Analyze new pragma; body. + (Sig_Flags): References in new pragma are significant when + detecting unreferenced objects. + * sem_prag.ads (Aspect_Specifying_Pragma) + (Assertion_Expression_Pragma, Pragma_Significant_To_Subprograms): + Support new aspect and pragma. + (Analyze_Program_Exit_In_Decl_Part): Analyze new pragma; spec. + (Find_Related_Package_Or_Body): Mention new pragma in comment. + * sem_util.adb (Is_Subprogram_Contract_Annotation): Support new + pragma. + * sem_util.ads (Is_Subprogram_Contract_Annotation): Mention new + pragma in comment. + * sinfo.ads (Is_Generic_Contract_Pragma): Mention new pragma in + comment. + * snames.ads-tmpl (Preset Names, Pragma_Id): Add name and pragma + identifiers. + * gnat_rm.texi: Regenerate. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * libgnat/g-dyntab.ads (Instance): Update and extend comment. + * scos.ads: Remove comment about the corresponding C header. + * scos.h: Remove. + +2025-06-06 Steve Baird <baird@adacore.com> + + * sem_util.adb (Collect_Primitive_Operations): When collecting + primitive operations, do not include child unit subprograms. + +2025-06-06 Javier Miranda <miranda@adacore.com> + + * sem_ch4.adb (Constant_Indexing_OK): Add missing support for + RM 4.1.6(13/3), and improve performance to avoid climbing more + than needed. Add documentation. + (Try_Indexing_Function): New subprogram. + (Expr_Matches_In_Formal): Added new formals. + (Handle_Selected_Component): New subprogram. + (Has_IN_Mode): New subprogram. + (Try_Container_Indexing): Add documentation, code reorganization + and extend its functionality to improve its support for prefixed + notation calls. + +2025-06-06 Viljar Indus <indus@adacore.com> + + * debug.adb: Mark -gnatd_D as unused. + * diagnostics-repository.adb: Move to... + * errid.adb: ...here. + * diagnostics-repository.ads: Move to... + * errid.ads: ...here. + * errout.adb (Error_Msg_Internal): Add new arguments for the new + attributes of Error_Msg_Objects. + (Error_Msg): Likewise. + (Error_Msg_N): Likewise. + (Labeled_Span): New method for creating Labeled_Span-s + (Primary_Label_Span): New method for creating primary Labeled_Spans. + (Secondary_Labeled_Span): New method for creating secondary + Labeled_Spans. + (Edit): New method for creating Edit elements. + (Fix): New method for creating Fix elements. + (Error_Msg_F): Simplify code for evaluating the span. + (Error_Msg_FE): Likewise. + (Error_Msg_NE): Likewise. + (Error_Msg_NEL): Likewise. + (Error_Msg_N_Gigi): New method that is used as a wrapper for the + Error_Msg_xxx methods that have the new arguments. This function + is later mapped to the Error_Msg method used inside gigi. + (Error_Msg_NE_Gigi): Likewise. + (Write_JSON_Span): Ensure that the Style prefix is included that is + removed when parsing the message is reinserted to the JSON report. + (Output_Messages): Use the new Pretty_Printer and Sarif_Printer + packages to print the messages and remove the old implementation + for the pretty printer. + (Set_Msg_Text): Remove message kind insertion characters from the + final message text to avoid some message kinds being duplicated. + (To_Full_Span_First): New method for creating a span for a node. + (To_Full_Span): Likewise. + * errout.ads: Add the specs for all of the newly added functions. + * diagnostics-pretty_emitter.adb: Move to... + * erroutc-pretty_emitter.adb: ...here. + * diagnostics-pretty_emitter.ads: Move to... + * erroutc-pretty_emitter.ads: ...here. + * diagnostics-sarif_emitter.adb: Move to... + * erroutc-sarif_emitter.adb: ...here. + * diagnostics-sarif_emitter.ads: Move to... + * erroutc-sarif_emitter.ads: ...here. + * erroutc.adb (Next_Error_Msg): New method for iterating to the + next error message. + (Next_Continuation_Msg): New method for iterating to the next + continuation message. + (Primary_Location): New method for returning the first primary + location for the error message. + (Get_Human_Id): New method for returning the human readable + name for the switch associated with this error message. + (Get_Doc_Switch): New method for creating the tag for the switch + used in the error message. + (Output_Text_Within): Change the method to operating on Strings + instead of String pointers. + (Output_Msg_Text): Simplify implementation for generating the + error message. + (Prescan_Message): Make the String handling more error proof. + * erroutc.ads (Error_Msg_Object): Add new attributes that were + added to Diagnostic objects to Error_Msg_Objects. + Add new methods for handling the new error objects. + * diagnostics-switch_repository.adb: Move to... + * errsw.adb: ...here. + * errutil.adb (Error_Msg): Initialize all of the new attributes + added to Error_Msg_Object-s. + * fe.h (Error_Msg_N): Update the binding. + (Error_Msg_NE): Update the binding. + For now the error_msg methods in gigi will use the old + simplified interface for those methods. + * diagnostics-json_utils.adb: Move to... + * json_utils.adb: ...here. + * diagnostics-json_utils.ads: Move to... + * json_utils.ads: ...here. + * par-endh.adb: Replace the old error_msg + calls with the updated interface. + * sem_aggr.adb: Likewise. + * sem_ch13.adb: Likewise. + * sem_ch4.adb: Likewise. + * sem_ch9.adb: Likewise. + * diagnostics-brief_emitter.adb: Removed. + * diagnostics-brief_emitter.ads: Removed. + * diagnostics-constructors.adb: Removed. + * diagnostics-constructors.ads: Removed. + * diagnostics-converter.adb: Removed. + * diagnostics-converter.ads: Removed. + * diagnostics-switch_repository.ads: Removed. + * diagnostics-utils.adb: Removed. + * diagnostics-utils.ads: Removed. + * diagnostics.adb: Removed. + * diagnostics.ads: Removed. + * errsw.ads: New file. Based on diagnostics-switch_repository.ads. + It additionally contains all the switch enumerations. + * gcc-interface/Make-lang.in: Update compilation dependencies. + * gcc-interface/Makefile.in: Likewise. + +2025-06-06 Ronan Desplanques <desplanques@adacore.com> + + * contracts.adb (Add_Invariant_And_Predicate_Checks): Assign Ekind. + * inline.adb (Expand_Inlined_Call): Likewise. + * exp_ch9.adb (Build_Simple_Entry_Call): Likewise. + * exp_dist.adb (Append_Array_Traversal): Likewise. + * exp_fixd.adb (Build_Double_Divide_Code, Build_Scaled_Divide_Code): + Likewise. + +2025-06-06 Olivier Hainque <hainque@adacore.com> + + * libgnarl/s-linux__android-aarch64.ads: Provide an + Android_Sigaction generic package to expose an aarch64 + version of struct_sigation, using a provided sigset_t + for sa_flags. + * libgnarl/s-linux__android-arm.ads: Likewise, for ARM + rather than aarch64. + * libgnarl/s-osinte__android.ads: Move sigset_t definition + to the visible part and use it to instantiate the Android_Sigation + generic provided by System.Linux, which is specialized for ARM vs + aarch64. Define struct_sigaction out of the Android_Sigaction + instance, remove the local representation clauses. + +2025-06-06 Olivier Hainque <hainque@adacore.com> + + * Makefile.rtl: Rework the Android pairs to match those of a + regular Linux port rather than a generic posix one. + * libgnarl/s-osinte__android.ads: Import pcrtl and add bindings + for the pthread_rwlock entry points, used by the Linux units now + in the libgnat target pairs. + * sysdep.c (__gnat_has_cap_sys_nice): Define for Android, + conservative return 0. + * adaint.c (__gnat_cpu_alloc): Define for Android as for Linux. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * namet.ads (Name_Entry): Update comments to explain the current needs. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * lib.ads (Unit_Record): Remove representation clauses and filler + components + * lib-load.adb, lib-writ.adb: Remove initialization of data fillers. + * nlists.adb (Allocate_List_Tables): Remove explicit initialization. + * repinfo.adb (Exp_Node): Remove representation clauses. + * sinput.ads (Source_File_Record): Likewise. + * urealp.adb (Ureal_Entry): Likewise. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * doc/gnat_rm/representation_clauses_and_pragmas.rst + (Effect of Convention on Representation): Fix number of list items. + * gnat_rm.texi: Regenerate. + * gnat_ugn.texi: Regenerate. + +2025-06-06 Eric Botcazou <ebotcazou@adacore.com> + + * sem_ch10.adb (Install_Siblings.In_Context): Add missing guard. + +2025-06-06 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch4.adb (Analyze_Selected_Component): Tweak condition. + +2025-06-06 Eric Botcazou <ebotcazou@adacore.com> + + * exp_ch4.adb (Insert_Conditional_Object_Declaration): Make sure the + object is allocated properly by the code generator at library level. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * sem_eval.adb (Check_Non_Static_Context): Remove special handling of + floating-point zero. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * einfo.ads (Incomplete_View): Move from Sinfo; adapt wording. + * exp_ch3.adb (Build_Record_Init_Proc): Adapt retrieval of + Incomplete_View. + * gen_il-fields.ads (Opt_Field_Enum): Move Incomplete_View from node + to entity field. + * gen_il-gen-gen_entities.adb (Gen_Entities): Add field. + * gen_il-gen-gen_nodes.adb (Gen_Nodes): Remove field. + * sem_ch3.adb (Analyze_Full_Type_Declaration, + Check_Anonymous_Access_Component): Adapt setting of Incomplete_View. + * sem_ch6.adb (Analyze_Subprogram_Body_Helper): Adapt retrieval of + Incomplete_View for class-wide types; no longer rely on class-wide + type being attached to non-classwide type declaration. + * sem_util.adb (Collect_Primitive_Operations): Adapt retrieval of + Incomplete_View. + * sinfo.ads (Incomplete_View): Move to Einfo. + +2025-06-06 squirek <squirek@adacore.com> + + * aspects.ads: Add support for constructors. + * exp_aggr.adb: Likewise. + * exp_attr.adb: Likewise. + * exp_ch3.adb: Likewise. + * exp_ch4.adb: Likewise. + * exp_util.adb: Likewise. + * gen_il-fields.ads: Likewise. + * gen_il-gen-gen_entities.adb: Likewise. + * gen_il-gen-gen_nodes.adb: Likewise. + * par-ch4.adb: Likewise. + * sem_aggr.adb: Likewise. + * sem_attr.adb, sem_attr.ads: Likewise. + * sem_ch13.adb: Likewise. + * sem_ch3.adb: Likewise. + * sem_ch5.adb: Likewise. + * sem_ch6.adb: Likewise. + * sem_res.adb: Likewise. + * sem_util.adb, sem_util.ads: Likewise. + * snames.ads-tmpl: Likewise. + +2025-06-06 squirek <squirek@adacore.com> + + * doc/gnat_rm/gnat_language_extensions.rst: Add documentation. + * gnat_rm.texi: Regenerate. + +2025-06-06 Eric Botcazou <ebotcazou@adacore.com> + + * einfo.ads (Modulus): Change to implementation base type only. + * gen_il-gen-gen_entities.adb (Modular_Integer_Kind): Change type + of Modulus field to Impl_Base_Type_Only. + +2025-06-06 Eric Botcazou <ebotcazou@adacore.com> + + * einfo.ads (Original_Access_Type): Restore. + * gen_il-fields.ads (Opt_Field_Enum): Restore Original_Access_Type. + * gen_il-gen-gen_entities.adb: Adjust accordingly. + * exp_ch9.adb (Expand_Access_Protected_Subprogram_Type): Restore the + call to Set_Original_Access_Type. + +2025-06-06 Eric Botcazou <ebotcazou@adacore.com> + + * einfo.ads (Default_Expr_Function): Delete. + (Dependent_Instances): Likewise. + (Handler_Records): Likewise. + (Needs_Activation_Record): Likewise. + (Original_Access_Type): Likewise. + (Register_Exception_Call): Likewise. + * sinfo.ads (Accept_Handler_Records): Likewise. + * gen_il-fields.ads (Opt_Field_Enum): Remove Accept_Handler_Records, + Default_Expr_Function, Dependent_Instances, Handler_Records, + Needs_Activation_Record, Original_Access_Type and + Register_Exception_Call. + * gen_il-gen-gen_entities.adb: Adjust accordingly. + * gen_il-gen-gen_nodes.adb: Likewise. + * exp_ch9.adb (Expand_Access_Protected_Subprogram_Type): Remove call + to Set_Original_Access_Type. + (Expand_N_Selective_Accept): Remove call to Set_Handler_Records. + * exp_ch11.adb (Expand_N_Exception_Declaration): Remove call to + Set_Register_Exception_Call. + * sem_ch3.adb (Access_Subprogram_Declaration): Remove call to + Set_Needs_Activation_Record. + * sem_ch12.adb (Instantiate_Package_Body): Remove call to + Set_Handler_Records. + +2025-06-06 Steve Baird <baird@adacore.com> + + * sem_ch4.adb + (Find_Unary_Types): Because we reanalyze names in an instance, + we sometimes have to take steps to filter out extraneous name + resolution candidates that happen to be visible at the point of the + instance declaration. Remove some code that appears to have been + written with this in mind. This is done for two reasons. First, the + code sometimes doesn't work (possibly because the In_Instance test + is not specific enough - it probably should be testing to see whether + we are in an instance of the particular generic in which the result + of calling Corresponding_Generic_Type was declared) and causes correct + code to be rejected. Second, the code seems to no longer be necessary + (possibly because of subsequent fixes in this area which are not + specific to unary operators). + +2025-06-06 Ronan Desplanques <desplanques@adacore.com> + + * sem_ch8.adb (Premature_Usage): Remove dead code. + +2025-06-06 Eric Botcazou <ebotcazou@adacore.com> + + * einfo.ads (Size_Check_Code): Delete. + * gen_il-fields.ads (Opt_Field_Enum): Remove Size_Check_Code. + * gen_il-gen-gen_entities.adb (Constant_Or_Variable_Kind): Likewise. + * sem_ch13.adb (Analyze_Attribute_Definition_Clause): Remove call + to Kill_Size_Check_Code. + * sem_prag.adb (Analyze_Pragma): Likewise. + * sem_util.ads (Kill_Size_Check_Code): Delete. + * sem_util.adb (Kill_Size_Check_Code): Likewise. + +2025-06-06 Claire Dross <dross@adacore.com> + + * sem_ch6.adb (Analyze_SPARK_Subprogram_Specification): + Allow the first parameter of functions whose return type is + an anonymous access-to-variable type to have mode IN OUT. + +2025-06-06 Ronan Desplanques <desplanques@adacore.com> + + * gen_il-fields.ads: New field. + * gen_il-gen-gen_entities.adb: New field. + * einfo.ads: Document new field. + * sem_res.adb (Check_Discriminant_Use): Record relevant uses in new + field. Move warning emission to... + * sem_ch3.adb (Analyze_Full_Type_Declaration): ... Here. + +2025-06-06 Steve Baird <baird@adacore.com> + + * sem_disp.adb + (Check_Dispatching_Operation): Delete code to generate + "missing overriding indicator" warning. Update comments. + +2025-06-06 Ronan Desplanques <desplanques@adacore.com> + + * cstand.adb (Create_Standard): Delay declaration generation for + Natural and Positive. + +2025-06-06 Ronan Desplanques <desplanques@adacore.com> + + * cstand.adb (Create_Standard): Remove useless calls. + +2025-06-06 Eric Botcazou <ebotcazou@adacore.com> + + * exp_aggr.adb (Expand_Record_Aggregate): Use the named form for the + second actual parameter in the call to Duplicate_Subexpr. + * exp_attr.adb (Expand_Size_Attribute): Likewise. + * exp_ch5.adb (Expand_Assign_Array): Likewise. + (Expand_Assign_Array_Bitfield): Likewise. + (Expand_Assign_Array_Bitfield_Fast): Likewise. + * exp_util.ads (Duplicate_Subexpr): Add New_Scope formal parameter. + (Duplicate_Subexpr_No_Checks): Likewise. + (Duplicate_Subexpr_Move_Checks): Likewise. + * exp_util.adb (Build_Allocate_Deallocate_Proc): Pass Proc_Id as the + actual for New_Scope in the calls to Duplicate_Subexpr_No_Checks. + (Duplicate_Subexpr): Add New_Scope formal parameter and forward it + in the call to New_Copy_Tree. + (Duplicate_Subexpr_No_Checks): Likewise. + (Duplicate_Subexpr_Move_Checks): Likewise. + +2025-06-06 Piotr Trojanek <trojanek@adacore.com> + + * checks.adb (Insert_Valid_Check): Set flag Assignment_OK in the object + declaration inserted for the validity checks. + +2025-06-05 squirek <squirek@adacore.com> + + * sem_warn.adb + (Warn_On_Useless_Assignment): Disable out value "overwritten" warning + when we are not warning on unread out parameters (e.g. "-gnatw.o"). + +2025-06-05 Tonu Naks <naks@adacore.com> + + * libgnat/i-cstrin.adb: null pointer check in Update + +2025-06-05 Arnaud Charlet <charlet@adacore.com> + + * exp_util.adb, rtsfind.adb, rtsfind.ads, sem_prag.adb: Remove + references to RO_GH_Big_Integer and + Ada_Numerics_Big_Numbers_Big_Integers_Ghost. + * libgnat/a-strfix.adb, libgnat/a-strmap.adb, + libgnat/a-strsea.adb, libgnat/a-strsup.adb, + libgnat/i-c.ads, libgnat/i-c.adb, libgnat/s-aridou.adb, + libgnat/s-aridou.ads, libgnat/s-arit128.adb, + libgnat/s-arit128.ads, libgnat/s-arit32.adb, + libgnat/s-arit32.ads, libgnat/s-arit64.adb, + libgnat/s-arit64.ads, libgnat/s-casuti.adb, + libgnat/s-exnint.ads, libgnat/s-exnlli.ads, + libgnat/s-exnllli.ads, libgnat/s-expint.ads, + libgnat/s-explli.ads, libgnat/s-expllli.ads, + libgnat/s-explllu.ads, libgnat/s-expllu.ads, + libgnat/s-expmod.adb, libgnat/s-expmod.ads, + libgnat/s-exponn.adb, libgnat/s-exponn.ads, + libgnat/s-expont.adb, libgnat/s-expont.ads, + libgnat/s-exponu.adb, libgnat/s-exponu.ads, + libgnat/s-imaged.ads, libgnat/s-imaged.adb, + libgnat/s-expuns.ads, libgnat/s-imagef.ads, + libgnat/s-imagef.adb, libgnat/s-imagei.adb, + libgnat/s-imagei.ads, libgnat/s-imageu.adb, + libgnat/s-imageu.ads, libgnat/s-imgboo.adb, + libgnat/s-imde128.ads, libgnat/s-imde32.ads, + libgnat/s-imde64.ads, libgnat/s-imfi128.ads, + libgnat/s-imfi32.ads, libgnat/s-imfi64.ads, + libgnat/s-imgboo.ads, libgnat/s-imgint.ads, + libgnat/s-imglli.ads, libgnat/s-imgllli.ads, + libgnat/s-imglllu.ads, libgnat/s-imgllu.ads, + libgnat/s-imguns.ads, libgnat/s-valboo.adb, + libgnat/s-valboo.ads, libgnat/s-valint.ads, + libgnat/s-vallli.ads, libgnat/s-valllli.ads, + libgnat/s-vallllu.ads, libgnat/s-valllu.ads, + libgnat/s-valuns.ads, libgnat/s-valuti.adb, + libgnat/s-valuti.ads, libgnat/s-valuei.adb, + libgnat/s-valuei.ads, libgnat/s-valueu.ads, + libgnat/s-valueu.adb, libgnat/s-veboop.adb, + libgnat/s-veboop.ads, libgnat/s-widint.ads, + libgnat/s-widlli.ads, libgnat/s-widllli.ads, + libgnat/s-widlllu.ads, libgnat/s-widllu.ads, + libgnat/s-widthi.adb, libgnat/s-widthu.adb, + libgnat/s-widthu.ads, libgnat/s-widuns.ads: Remove ghost code + and SPARK annotations. + * libgnat/a-nbnbig.ads, libgnat/a-nbnbig.adb, + libgnat/s-spark.ads, libgnat/s-spcuop.adb, + libgnat/s-spcuop.ads, libgnat/s-vaispe.adb, + libgnat/s-vaispe.ads, libgnat/s-vauspe.adb, + libgnat/s-vauspe.ads, libgnat/s-vs_int.ads, + libgnat/s-vs_lli.ads, libgnat/s-vs_llu.ads, + libgnat/s-vs_uns.ads, libgnat/s-valspe.adb, + libgnat/s-valspe.ads, libgnat/s-vsllli.ads, + libgnat/s-vslllu.ads: Removed. + * Makefile.rtl: Update list of runtime units. + * gcc-interface/Make-lang.in: Remove object files. + +2025-06-05 Ronan Desplanques <desplanques@adacore.com> + + * fname-uf.adb: Fix documentation comment. + (Get_Default_File_Name): Fix indices of default patterns. + +2025-06-05 Ronan Desplanques <desplanques@adacore.com> + + * atree.ads (New_Copy, Relocate_Node): Tweak documentation comments. + +2025-06-05 Andres Toom <toom@adacore.com> + + * libgnat/a-nudira.ads: Activate SPARK mode and add missing + basic contracts. Mark the unit as always terminating. + * libgnat/a-nuflra.ads: Idem. + +2025-06-05 Javier Miranda <miranda@adacore.com> + + * exp_ch7.adb (Process_Object_Declaration): Avoid generating + duplicate names for master nodes. + +2025-06-05 Ronan Desplanques <desplanques@adacore.com> + + * opt.ads: Remove useless variable. + * sem_ch9.adb (Analyze_Abort_Statement, Analyze_Accept_Alternative, + Analyze_Accept_Statement, Analyze_Asynchronous_Select, + Analyze_Conditional_Entry_Call, Analyze_Delay_Alternative, + Analyze_Delay_Relative, Analyze_Delay_Until, Analyze_Entry_Body, + Analyze_Entry_Body_Formal_Part, Analyze_Entry_Call_Alternative, + Analyze_Entry_Declaration, Analyze_Entry_Index_Specification, + Analyze_Protected_Body, Analyze_Protected_Definition, + Analyze_Protected_Type_Declaration, Analyze_Requeue, + Analyze_Selective_Accept, Analyze_Single_Protected_Declaration, + Analyze_Single_Task_Declaration, Analyze_Task_Body, + Analyze_Task_Definition, Analyze_Task_Type_Declaration, + Analyze_Terminate_Alternative, Analyze_Timed_Entry_Call, + Analyze_Triggering_Alternative): Remove useless assignments. + +2025-06-05 Steve Baird <baird@adacore.com> + + * sem_util.adb + (Side_Effect_Free_Statements): Return False if the statement list + includes an explicit (i.e. Comes_From_Source) raise statement. + +2025-06-05 Javier Miranda <miranda@adacore.com> + + * sem_ch6.adb (Analyze_Expression_Function): Add missing check + on premature use of incomplete type. + +2025-06-05 Aleksandra Pasek <pasek@adacore.com> + + * libgnat/s-arit32.adb: Add Ghost aspect to Lo. + +2025-06-05 Ronan Desplanques <desplanques@adacore.com> + + * exp_ch4.adb (Tagged_Membership): Fix for protected types. + +2025-06-05 Bob Duff <duff@adacore.com> + + * sem_eval.adb (Fold_Shift): If the Amount parameter is greater + than the size in bits, use the size. For example, if we are + shifting an Unsigned_8 value, then Amount => 1_000_001 gives the + same result as Amount => 8. This change avoids computing the value + of 2**1_000_000, which takes too long and uses too much memory. + Note that the computation we're talking about is a compile-time + computation. Minor cleanup. DRY. + * sem_eval.ads (Fold_Str, Fold_Uint, Fold_Ureal): Fold the + comments into one comment, because DRY. Remove useless + verbiage. + +2025-06-05 Ronan Desplanques <desplanques@adacore.com> + + * exp_attr.adb (Interunit_Ref_OK): Tweak categorization of compilation + units. + +2025-06-05 Aleksandra Pasek <pasek@adacore.com> + + * libgnat/s-aridou.adb: Add missing Ghost aspect to + Lemma_Not_In_Range_Big2xx64. + +2025-06-05 Ronan Desplanques <desplanques@adacore.com> + + * libgnat/s-trasym__dwarf.adb (Init_Module): Add mitigation. + +2025-06-05 Eric Botcazou <ebotcazou@adacore.com> + + * exp_aggr.adb (Build_Two_Pass_Aggr_Code): New function containing + most of the code initially present in Two_Pass_Aggregate_Expansion. + (Two_Pass_Aggregate_Expansion): Remove redundant N parameter. + Implement built-in-place expansion for (static) object declarations + and allocators, using Build_Two_Pass_Aggr_Code for the main work. + (Expand_Array_Aggregate): Adjust Two_Pass_Aggregate_Expansion call. + Replace Etype (N) by Typ in a couple of places. + * exp_ch3.adb (Expand_Freeze_Array_Type): Remove special case for + two-pass array aggregates. + (Expand_N_Object_Declaration): Do not adjust the object when it is + initialized by a two-pass array aggregate. + * exp_ch4.adb (Expand_Allocator_Expression): Apply the processing + used for container aggregates to two-pass array aggregates. + * exp_ch6.adb (Validate_Subprogram_Calls): Skip calls present in + initialization expressions of N_Object_Declaration nodes that have + No_Initialization set. + * sem_ch3.adb (Analyze_Object_Declaration): Detect the cases of an + array originally initialized by an aggregate consistently. + +2025-06-05 Johannes Kliemann <kliemann@adacore.com> + + * libgnat/s-arit32.adb (Lemma_Not_In_Range_Big2xx32): Add missing + Ghost aspect. + +2025-06-05 Ronan Desplanques <desplanques@adacore.com> + + * generate_minimal_reproducer.adb (Generate_Minimal_Reproducer): Fix + handling of preprocessing dependencies. + +2025-06-05 Viljar Indus <indus@adacore.com> + + * doc/gnat_rm/implementation_defined_attributes.rst: Update the + documentation for Valid_Value. + * sem_attr.adb (Analyze_Attribute): Reject types where + the root type originates from Standard. + * gnat_rm.texi: Regenerate. + * gnat_ugn.texi: Regenerate. + +2025-06-05 Gary Dismukes <dismukes@adacore.com> + + * exp_aggr.adb (Two_Pass_Aggregate_Expansion): Change call to Make_Assignment + for the indexed aggregate object to call Change_Make_OK_Assignment instead. + +2025-06-05 Steve Baird <baird@adacore.com> + + * sem_prag.adb + (Analyze_Constituent): In the specific case case of a defined-too-late + abstract state constituent, generate an additional error message. + +2025-06-05 Viljar Indus <indus@adacore.com> + + * diagnostics-sarif_emitter.adb (Print_Invocations): fix + commandLine and executionSuccessful nodes. + Fix typo in the name for startLine. + * osint.adb (Modified Get_Current_Dir) Fix generation of + the current directory. + (Relative_Path): Avoid relative paths starting with a + path separator. + * osint.ads: Update the documentation for Relative_Path. + +2025-06-05 Ronan Desplanques <desplanques@adacore.com> + + * libgnat/i-cstrin.adb (New_String): Fix size of allocation. + +2025-06-05 squirek <squirek@adacore.com> + + * sem_ch8.adb (Analyze_Package_Name): Add code to expand use + clauses such that they have an implicit with associated with them + when extensions are enabled. + * sem_ch10.ads (Analyze_With_Clause): New. + * sem_ch10.adb (Analyze_With_Clause): Add comes from source check + for warning. + (Expand_With_Clause): Moved to the spec. + * sem_util.adb, sem_util.ads + (Is_In_Context_Clause): Moved from sem_prag. + * sem_prag.adb (Analyze_Pragma): Update calls to + Is_In_Context_Clause. + (Is_In_Context_Clause): Moved to sem_util. + +2025-06-05 Piotr Trojanek <trojanek@adacore.com> + + * doc/gnat_ugn/platform_specific_information.rst + (Setting Stack Size from gnatlink): Improve documentation. + * gnat-style.texi: Regenerate. + * gnat_rm.texi: Regenerate. + * gnat_ugn.texi: Regenerate. + +2025-06-05 squirek <squirek@adacore.com> + + * accessibility.adb (Check_Return_Construct_Accessibility): + Disable check generation when we are only checking semantics. + * opt.ads: Add new flag for -gnatc mode + * switch-c.adb (Scan_Front_End_Switches): Set flag for -gnatc mode + +2025-06-05 Viljar Indus <indus@adacore.com> + + * sem_ch8.adb (Mark_Use_Type): Additionally mark the types + of the parameters and return values as used when analyzing an + operator. + +2025-06-05 Eric Botcazou <ebotcazou@adacore.com> + + * exp_ch9.adb (Build_Dispatching_Requeue): Take 'Tag of the + concurrent object instead of doing an unchecked conversion. + * exp_pakd.adb (Expand_Packed_Address_Reference): Perform address + arithmetic using an operator of System.Storage_Elements. + +2025-06-05 Eric Botcazou <ebotcazou@adacore.com> + + * exp_ch6.adb (Expand_Actuals): Remove obsolete comment. + (Make_Build_In_Place_Call_In_Anonymous_Context): Always use a proper + object declaration initialized with the function call in the cases + where a temporary is needed, with Assignment_OK set on it. + * sem_util.adb (Entity_Of): Deal with rewritten function call first. + +2025-06-05 Ronan Desplanques <desplanques@adacore.com> + + * libgnat/i-cstrin.adb (Position_Of_Nul): Change specification and + adjust body accordingly. + (New_Char_Array): Fix size of allocation. + (To_Chars_Ptr): Adapt to Position_Of_Nul change. + +2025-06-05 Ronan Desplanques <desplanques@adacore.com> + + * generate_minimal_reproducer.adb (Generate_Minimal_Reproducer): Fix + oracle generation. + +2025-06-05 Ronan Desplanques <desplanques@adacore.com> + + * generate_minimal_reproducer.adb (Generate_Minimal_Reproducer): + Fix when main library item is an instantiation. + +2025-06-05 Steve Baird <baird@adacore.com> + + * exp_attr.adb (Expand_N_Attribute_Reference): When accessing the + maps declared in package Cached_Attribute_Ops, the key value + passed to Get or to Set should never be the entity node for a + subtype. Use the entity of the corresponding type declaration + instead. + +2025-06-05 Viljar Indus <indus@adacore.com> + + * sem_res.adb (Resolve_Declare_Expression): Mark used + local variables inside a declare expression as referenced. + +2025-06-05 Javier Miranda <miranda@adacore.com> + + * sem.ads: Update reference to renamed subprogram in documentation. + * sem_ch3.ads (Preanalyze_Assert_Expression): Renamed. + (Preanalyze_Spec_Expression): Renamed. + * sem_ch3.adb (Preanalyze_Assert_Expression): Renamed and code cleanup. + (Preanalyze_Spec_Expression): Renamed. + (Preanalyze_Default_Expression): Renamed. + * contracts.adb: Update calls to renamed subprograms. + * exp_pakd.adb: Ditto. + * exp_util.adb: Ditto. + * freeze.adb: Ditto. + * sem_ch12.adb: Ditto. + * sem_ch13.adb: Ditto. + * sem_ch6.adb: Ditto. + * sem_prag.adb: Ditto. + * sem_res.adb (Preanalyze_And_Resolve): Add to the version without + context type the special handling for GNATprove mode provided by + the version with context type; required to cleanup the body of + Preanalyze_Assert_Expression. + +2025-06-05 squirek <squirek@adacore.com> + + * accessibility.adb + (Check_Return_Construct_Accessibility): Disable check generation + when we are only checking semantics. + +2025-06-05 Viljar Indus <indus@adacore.com> + + * diagnostics-json_utils.adb: Add new method To_File_Uri to + convert any path to the URI standard. + * diagnostics-json_utils.ads: Likewise. + * diagnostics-sarif_emitter.adb: Converted Artifact_Change + types to use the Source_File_Index instead of the file name + to store the source file. + Removed the body from Destroy (Elem : in out Artifact_Change) + since it no longer contained elements with dynamic memory. + Updated the implementation of Equals (L, R : Artifact_Change) + to take into account the changes for Artifact_Change. + Print_Artifact_Location: Use the Source_File_Index as an + input argument. Now prints the uriBaseId attribute and a + relative path from the uriBaseId to the file in question as + the value of the uri attribute. + New method Print_Original_Uri_Base_Ids to print the + originalUriBaseIds node. + Print_Run no prints the originalUriBaseIds node. + Use constants instead of strings for all the SARIF attributes. + * osint.adb: Add new method Relative_Path to calculate the + relative path from a base directory. + Add new method Root to calculate the root of each directory. + Add new method Get_Current_Dir to get the current working + directory for the execution environment. + * osint.ads: Likewise. + * clean.adb: Use full names for calls to Get_Current_Dir. + * gnatls.adb: Likewise. + +2025-06-05 Steve Baird <baird@adacore.com> + + * sem_res.adb + (Set_Mixed_Mode_Operand): If we are about to call Resolve + passing in Any_Fixed as the expected type, then instead pass in + the fixed point type of the other operand (i.e., B_Typ). + +2025-06-05 Gary Dismukes <dismukes@adacore.com> + + * sem_util.adb (Check_Function_Writable_Actuals): Add handling for + N_Iterated_Component_Association and N_Iterated_Element_Association. + Fix a typo in an RM reference (6.4.1(20/3) => 6.4.1(6.20/3)). + (Collect_Expression_Ids): New procedure factoring code for collecting + identifiers from expressions of aggregate associations. + (Handle_Association_Choices): New procedure factoring code for handling + id collection for expressions of aggregate associations with multiple + choices. Removed redundant test of Box_Present from original code. + 2025-05-24 Eric Botcazou <ebotcazou@adacore.com> * gcc-interface/Make-lang.in (ACATSDIR): Use acats-2 directory. diff --git a/gcc/ada/Make-generated.in b/gcc/ada/Make-generated.in index 5cb1b32009d1..4d42eef3a300 100644 --- a/gcc/ada/Make-generated.in +++ b/gcc/ada/Make-generated.in @@ -1,14 +1,6 @@ -# Dependencies for compiler sources that are generated at build time - -# Note: can't use ?= here, not supported by older versions of GNU Make +GNATMAKE_FOR_BUILD = gnatmake -ifeq ($(origin CP), undefined) -CP=cp -endif - -ifeq ($(origin MKDIR), undefined) -MKDIR=mkdir -p -endif +# Dependencies for compiler sources that are generated at build time fsrcdir := $(shell cd $(srcdir);${PWD_COMMAND}) @@ -18,7 +10,7 @@ GEN_IL_FLAGS = -gnata -gnat2012 -gnatw.g -gnatyg -gnatU $(GEN_IL_INCLUDES) ada/seinfo_tables.ads ada/seinfo_tables.adb ada/sinfo.h ada/einfo.h ada/nmake.ads ada/nmake.adb ada/seinfo.ads ada/sinfo-nodes.ads ada/sinfo-nodes.adb ada/einfo-entities.ads ada/einfo-entities.adb: ada/stamp-gen_il ; @true ada/stamp-gen_il: $(fsrcdir)/ada/gen_il* $(MKDIR) ada/gen_il - cd ada/gen_il; gnatmake -g $(GEN_IL_FLAGS) gen_il-main + cd ada/gen_il; $(GNATMAKE_FOR_BUILD) $(GEN_IL_FLAGS) gen_il-main # Ignore errors to work around finalization issues in older compilers - cd ada/gen_il; ./gen_il-main $(fsrcdir)/../move-if-change ada/gen_il/seinfo_tables.ads ada/seinfo_tables.ads @@ -39,14 +31,14 @@ ada/stamp-gen_il: $(fsrcdir)/ada/gen_il* # would cause bootstrapping with older compilers to fail. You can call it by # hand, as a sanity check that these files are legal. ada/seinfo_tables.o: ada/seinfo_tables.ads ada/seinfo_tables.adb - cd ada ; gnatmake $(GEN_IL_INCLUDES) seinfo_tables.adb -gnatU -gnatX + cd ada ; $(GNATMAKE_FOR_BUILD) $(GEN_IL_INCLUDES) seinfo_tables.adb -gnatX ada/snames.h ada/snames.ads ada/snames.adb : ada/stamp-snames ; @true ada/stamp-snames : ada/snames.ads-tmpl ada/snames.adb-tmpl ada/snames.h-tmpl ada/xsnamest.adb ada/xutil.ads ada/xutil.adb -$(MKDIR) ada/bldtools/snamest $(RM) $(addprefix ada/bldtools/snamest/,$(notdir $^)) $(CP) $^ ada/bldtools/snamest - cd ada/bldtools/snamest && gnatmake xsnamest && ./xsnamest + cd ada/bldtools/snamest && $(GNATMAKE_FOR_BUILD) xsnamest && ./xsnamest $(fsrcdir)/../move-if-change ada/bldtools/snamest/snames.ns ada/snames.ads $(fsrcdir)/../move-if-change ada/bldtools/snamest/snames.nb ada/snames.adb $(fsrcdir)/../move-if-change ada/bldtools/snamest/snames.nh ada/snames.h diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl index cb41e6887cdf..50e683aa80a7 100644 --- a/gcc/ada/Makefile.rtl +++ b/gcc/ada/Makefile.rtl @@ -211,7 +211,6 @@ GNATRTL_NONTASKING_OBJS= \ a-nallfl$(objext) \ a-nalofl$(objext) \ a-nashfl$(objext) \ - a-nbnbig$(objext) \ a-nbnbin$(objext) \ a-nbnbre$(objext) \ a-ncelfu$(objext) \ @@ -545,6 +544,7 @@ GNATRTL_NONTASKING_OBJS= \ s-caun16$(objext) \ s-caun32$(objext) \ s-caun64$(objext) \ + s-cautns$(objext) \ s-chepoo$(objext) \ s-commun$(objext) \ s-conca2$(objext) \ @@ -745,8 +745,6 @@ GNATRTL_NONTASKING_OBJS= \ s-shasto$(objext) \ s-soflin$(objext) \ s-soliin$(objext) \ - s-spark$(objext) \ - s-spcuop$(objext) \ s-spsufi$(objext) \ s-stache$(objext) \ s-stalib$(objext) \ @@ -772,7 +770,6 @@ GNATRTL_NONTASKING_OBJS= \ s-vaenu8$(objext) \ s-vafi32$(objext) \ s-vafi64$(objext) \ - s-vaispe$(objext) \ s-valboo$(objext) \ s-valcha$(objext) \ s-valflt$(objext) \ @@ -782,7 +779,6 @@ GNATRTL_NONTASKING_OBJS= \ s-vallli$(objext) \ s-valllu$(objext) \ s-valrea$(objext) \ - s-valspe$(objext) \ s-valued$(objext) \ s-valuef$(objext) \ s-valuei$(objext) \ @@ -792,14 +788,9 @@ GNATRTL_NONTASKING_OBJS= \ s-valuns$(objext) \ s-valuti$(objext) \ s-valwch$(objext) \ - s-vauspe$(objext) \ s-veboop$(objext) \ s-vector$(objext) \ s-vercon$(objext) \ - s-vs_int$(objext) \ - s-vs_lli$(objext) \ - s-vs_llu$(objext) \ - s-vs_uns$(objext) \ s-wchcnv$(objext) \ s-wchcon$(objext) \ s-wchjis$(objext) \ @@ -1046,8 +1037,6 @@ GNATRTL_128BIT_OBJS = \ s-vafi128$(objext) \ s-valllli$(objext) \ s-vallllu$(objext) \ - s-vsllli$(objext) \ - s-vslllu$(objext) \ s-widllli$(objext) \ s-widlllu$(objext) @@ -1419,24 +1408,32 @@ ifeq ($(SELECTED_PAIRS),PAIRS_NONE) ifeq ($(strip $(filter-out arm% aarch64 linux-android%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ + a-exetim.adb<libgnarl/a-exetim__posix.adb \ + a-exetim.ads<libgnarl/a-exetim__default.ads \ a-intnam.ads<libgnarl/a-intnam__linux.ads \ + a-nallfl.ads<libgnat/a-nallfl__wraplf.ads \ + a-synbar.adb<libgnarl/a-synbar__posix.adb \ + a-synbar.ads<libgnarl/a-synbar__posix.ads \ + s-dorepr.adb<libgnat/s-dorepr__fma.adb \ s-inmaop.adb<libgnarl/s-inmaop__posix.adb \ s-intman.adb<libgnarl/s-intman__android.adb \ - s-osinte.adb<libgnarl/s-osinte__android.adb \ s-osinte.ads<libgnarl/s-osinte__android.ads \ + s-osinte.adb<libgnarl/s-osinte__android.adb \ s-oslock.ads<libgnat/s-oslock__posix.ads \ s-osprim.adb<libgnat/s-osprim__posix.adb \ - s-taprop.adb<libgnarl/s-taprop__posix.adb \ + s-parame.adb<libgnat/s-parame__aarch64-linux.adb \ + s-taprop.adb<libgnarl/s-taprop__linux.adb \ + s-tasinf.ads<libgnarl/s-tasinf__linux.ads \ + s-tasinf.adb<libgnarl/s-tasinf__linux.adb \ + s-tpopsp.adb<libgnarl/s-tpopsp__tls.adb \ s-taspri.ads<libgnarl/s-taspri__posix.ads \ - s-tpopsp.adb<libgnarl/s-tpopsp__posix-foreign.adb \ - a-nallfl.ads<libgnat/a-nallfl__wraplf.ads \ $(ATOMICS_TARGET_PAIRS) \ $(ATOMICS_BUILTINS_TARGET_PAIRS) \ system.ads<libgnat/system-linux-arm.ads TOOLS_TARGET_PAIRS = indepsw.adb<indepsw-gnu.adb - EXTRA_GNATRTL_TASKING_OBJS=s-linux.o + EXTRA_GNATRTL_TASKING_OBJS=s-linux.o a-exetim.o # ARM and aarch64 rely on different unwinding mechanisms, and as # a 64bit target, aarch64 can also incorporate support for 128bit @@ -1857,6 +1854,7 @@ ifeq ($(strip $(filter-out %aarch64 freebsd%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS += \ s-intman.adb<libgnarl/s-intman__cheribsd.adb \ s-osinte.ads<libgnarl/s-osinte__cheribsd.ads \ + s-tsgsba.adb<libgnarl/s-tsgsba__cheri.adb \ s-secsta.adb<libgnat/s-secsta__cheri.adb EXTRA_GNATRTL_NONTASKING_OBJS += i-cheri.o i-cheri-exceptions.o @@ -3246,8 +3244,92 @@ ADA_EXCLUDE_SRCS =\ i-vxwoio.adb i-vxwoio.ads i-vxwork.ads \ s-linux.ads s-vxwext.adb s-vxwext.ads s-win32.ads s-winext.ads \ s-stchop.ads s-stchop.adb \ - s-strcom.adb s-strcom.ads s-thread.ads \ + s-strcom.ads s-strcom.adb \ + s-thread.ads \ s-qnx.ads \ + s-arit128.ads s-arit128.adb \ + s-casi128.ads s-casi128.adb \ + s-caun128.ads s-caun128.adb \ + s-exnllli.ads \ + s-expllli.ads \ + s-explllu.ads \ + s-fode128.ads \ + s-fofi128.ads \ + s-imde128.ads \ + s-imfi128.ads \ + s-imglllb.ads \ + s-imgllli.ads \ + s-imglllu.ads \ + s-imglllw.ads \ + s-pack65.ads s-pack65.adb \ + s-pack66.ads s-pack66.adb \ + s-pack67.ads s-pack67.adb \ + s-pack68.ads s-pack68.adb \ + s-pack69.ads s-pack69.adb \ + s-pack70.ads s-pack70.adb \ + s-pack71.ads s-pack71.adb \ + s-pack72.ads s-pack72.adb \ + s-pack73.ads s-pack73.adb \ + s-pack74.ads s-pack74.adb \ + s-pack75.ads s-pack75.adb \ + s-pack76.ads s-pack76.adb \ + s-pack77.ads s-pack77.adb \ + s-pack78.ads s-pack78.adb \ + s-pack79.ads s-pack79.adb \ + s-pack80.ads s-pack80.adb \ + s-pack81.ads s-pack81.adb \ + s-pack82.ads s-pack82.adb \ + s-pack83.ads s-pack83.adb \ + s-pack84.ads s-pack84.adb \ + s-pack85.ads s-pack85.adb \ + s-pack86.ads s-pack86.adb \ + s-pack87.ads s-pack87.adb \ + s-pack88.ads s-pack88.adb \ + s-pack89.ads s-pack89.adb \ + s-pack90.ads s-pack90.adb \ + s-pack91.ads s-pack91.adb \ + s-pack92.ads s-pack92.adb \ + s-pack93.ads s-pack93.adb \ + s-pack94.ads s-pack94.adb \ + s-pack95.ads s-pack95.adb \ + s-pack96.ads s-pack96.adb \ + s-pack97.ads s-pack97.adb \ + s-pack98.ads s-pack98.adb \ + s-pack99.ads s-pack99.adb \ + s-pack100.ads s-pack100.adb \ + s-pack101.ads s-pack101.adb \ + s-pack102.ads s-pack102.adb \ + s-pack103.ads s-pack103.adb \ + s-pack104.ads s-pack104.adb \ + s-pack105.ads s-pack105.adb \ + s-pack106.ads s-pack106.adb \ + s-pack107.ads s-pack107.adb \ + s-pack108.ads s-pack108.adb \ + s-pack109.ads s-pack109.adb \ + s-pack110.ads s-pack110.adb \ + s-pack111.ads s-pack111.adb \ + s-pack112.ads s-pack112.adb \ + s-pack113.ads s-pack113.adb \ + s-pack114.ads s-pack114.adb \ + s-pack115.ads s-pack115.adb \ + s-pack116.ads s-pack116.adb \ + s-pack117.ads s-pack117.adb \ + s-pack118.ads s-pack118.adb \ + s-pack119.ads s-pack119.adb \ + s-pack120.ads s-pack120.adb \ + s-pack121.ads s-pack121.adb \ + s-pack122.ads s-pack122.adb \ + s-pack123.ads s-pack123.adb \ + s-pack124.ads s-pack124.adb \ + s-pack125.ads s-pack125.adb \ + s-pack126.ads s-pack126.adb \ + s-pack127.ads s-pack127.adb \ + s-vade128.ads \ + s-vafi128.ads \ + s-valllli.ads \ + s-vallllu.ads \ + s-widllli.ads \ + s-widlllu.ads # ADA_EXCLUDE_SRCS without the sources used by the target ADA_EXCLUDE_FILES=$(filter-out \ diff --git a/gcc/ada/accessibility.adb b/gcc/ada/accessibility.adb index 8c85173aa34c..0b8d3f7746d7 100644 --- a/gcc/ada/accessibility.adb +++ b/gcc/ada/accessibility.adb @@ -1642,6 +1642,13 @@ package body Accessibility is (No (Extra_Accessibility_Of_Result (Scope_Id)) and then Is_Formal_Of_Current_Function (Assoc_Expr) and then Is_Tagged_Type (Etype (Scope_Id))) + + -- Disable the check generation when we are only checking semantics + -- since required locals do not get generated (e.g. extra + -- accessibility of result), and constant folding can occur and + -- lead to spurious errors. + + and then not Check_Semantics_Only_Mode then -- Generate a dynamic check based on the extra accessibility of -- the result or the scope of the current function. @@ -1684,8 +1691,8 @@ package body Accessibility is and then Entity (Check_Cond) = Standard_True then Error_Msg_N - ("access discriminant in return object would be a dangling" - & " reference", Return_Stmt); + ("access discriminant in return object could be a dangling" + & " reference??", Return_Stmt); end if; end if; diff --git a/gcc/ada/ada_get_targ.adb b/gcc/ada/ada_get_targ.adb index 72e54520b28b..853197ad0024 100644 --- a/gcc/ada/ada_get_targ.adb +++ b/gcc/ada/ada_get_targ.adb @@ -219,9 +219,14 @@ package body Get_Targ is begin Float_Str (Float_Str'First .. Float_Str'First + 4) := "float"; Call_Back - (C_Name => Float_Str, Digs => 6, Complex => False, Count => 0, + (C_Name => Float_Str, + Digs => 6, + Complex => False, + Count => 0, Float_Rep => IEEE_Binary, - Precision => 32, Size => 32, Alignment => 32); + Precision => 32, + Size => 32, + Alignment => 32); Double_Str (Double_Str'First .. Double_Str'First + 5) := "double"; Call_Back diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c index 1fcfae165a7e..adc39517280a 100644 --- a/gcc/ada/adaint.c +++ b/gcc/ada/adaint.c @@ -61,6 +61,11 @@ #define POSIX #include "vxWorks.h" #include <sys/time.h> +#include <ctype.h> /* for isalpha */ + +#ifndef alloca +#define alloca(n) __builtin_alloca(n) +#endif #if defined (__mips_vxworks) #include "cacheLib.h" @@ -3475,7 +3480,7 @@ __gnat_lwp_self (void) } #endif -#if defined (__linux__) +#if defined (__linux__) || defined (__ANDROID__) #include <sched.h> /* glibc versions earlier than 2.7 do not define the routines to handle diff --git a/gcc/ada/ali.ads b/gcc/ada/ali.ads index 2f90b88a7c67..da71c51e4ab9 100644 --- a/gcc/ada/ali.ads +++ b/gcc/ada/ali.ads @@ -358,8 +358,8 @@ package ALI is -- Indicates presence of PR parameter for a preelaborated package No_Elab : Boolean; - -- Indicates presence of NE parameter for a unit that has does not - -- have an elaboration routine (since it has no elaboration code). + -- Indicates presence of NE parameter for a unit that does not have an + -- elaboration routine (since it has no elaboration code). Pure : Boolean; -- Indicates presence of PU parameter for a package having pragma Pure diff --git a/gcc/ada/aspects.ads b/gcc/ada/aspects.ads index 70ea12023abb..737f15136062 100644 --- a/gcc/ada/aspects.ads +++ b/gcc/ada/aspects.ads @@ -81,6 +81,7 @@ package Aspects is Aspect_Bit_Order, Aspect_Component_Size, Aspect_Constant_Indexing, + Aspect_Constructor, -- GNAT Aspect_Contract_Cases, -- GNAT Aspect_Convention, Aspect_CPU, @@ -91,6 +92,7 @@ package Aspects is Aspect_Default_Value, Aspect_Depends, -- GNAT Aspect_Designated_Storage_Model, -- GNAT + Aspect_Destructor, -- GNAT Aspect_Dimension, -- GNAT Aspect_Dimension_System, -- GNAT Aspect_Dispatching_Domain, @@ -106,6 +108,7 @@ package Aspects is Aspect_GNAT_Annotate, -- GNAT Aspect_Implicit_Dereference, Aspect_Initial_Condition, -- GNAT + Aspect_Initialize, -- GNAT Aspect_Initializes, -- GNAT Aspect_Input, Aspect_Integer_Literal, @@ -125,11 +128,13 @@ package Aspects is Aspect_Part_Of, -- GNAT Aspect_Post, Aspect_Postcondition, + Aspect_Potentially_Invalid, -- GNAT Aspect_Pre, Aspect_Precondition, Aspect_Predicate, -- GNAT Aspect_Predicate_Failure, Aspect_Priority, + Aspect_Program_Exit, Aspect_Put_Image, Aspect_Read, Aspect_Real_Literal, @@ -255,6 +260,7 @@ package Aspects is | Aspect_Iterator_Element | Aspect_Max_Entry_Queue_Length | Aspect_No_Controlled_Parts + | Aspect_No_Task_Parts | Aspect_Real_Literal | Aspect_String_Literal | Aspect_Variable_Indexing; @@ -289,6 +295,7 @@ package Aspects is Aspect_CUDA_Global => True, Aspect_Depends => True, Aspect_Designated_Storage_Model => True, + Aspect_Destructor => True, Aspect_Dimension => True, Aspect_Dimension_System => True, Aspect_Disable_Controlled => True, @@ -324,6 +331,7 @@ package Aspects is Aspect_Obsolescent => True, Aspect_Part_Of => True, Aspect_Persistent_BSS => True, + Aspect_Potentially_Invalid => True, Aspect_Predicate => True, Aspect_Pure_Function => True, Aspect_Refined_Depends => True, @@ -404,8 +412,11 @@ package Aspects is subtype Boolean_Aspects is Aspect_Id range Aspect_Always_Terminates .. Aspect_Id'Last; - subtype Pre_Post_Aspects is - Aspect_Id range Aspect_Post .. Aspect_Precondition; + subtype Pre_Post_Aspects is Aspect_Id + with Static_Predicate => Pre_Post_Aspects in Aspect_Post + | Aspect_Postcondition + | Aspect_Pre + | Aspect_Precondition; -- The following type is used for indicating allowed expression forms @@ -428,6 +439,7 @@ package Aspects is Aspect_Bit_Order => Expression, Aspect_Component_Size => Expression, Aspect_Constant_Indexing => Name, + Aspect_Constructor => Name, Aspect_Contract_Cases => Expression, Aspect_Convention => Name, Aspect_CPU => Expression, @@ -438,6 +450,7 @@ package Aspects is Aspect_Default_Value => Expression, Aspect_Depends => Expression, Aspect_Designated_Storage_Model => Name, + Aspect_Destructor => Name, Aspect_Dimension => Expression, Aspect_Dimension_System => Expression, Aspect_Dispatching_Domain => Expression, @@ -453,6 +466,7 @@ package Aspects is Aspect_GNAT_Annotate => Expression, Aspect_Implicit_Dereference => Name, Aspect_Initial_Condition => Expression, + Aspect_Initialize => Expression, Aspect_Initializes => Expression, Aspect_Input => Name, Aspect_Integer_Literal => Name, @@ -472,11 +486,13 @@ package Aspects is Aspect_Part_Of => Expression, Aspect_Post => Expression, Aspect_Postcondition => Expression, + Aspect_Potentially_Invalid => Optional_Expression, Aspect_Pre => Expression, Aspect_Precondition => Expression, Aspect_Predicate => Expression, Aspect_Predicate_Failure => Expression, Aspect_Priority => Expression, + Aspect_Program_Exit => Optional_Expression, Aspect_Put_Image => Name, Aspect_Read => Name, Aspect_Real_Literal => Name, @@ -529,6 +545,7 @@ package Aspects is Aspect_Component_Size => True, Aspect_Constant_Indexing => False, Aspect_Contract_Cases => False, + Aspect_Constructor => False, Aspect_Convention => True, Aspect_CPU => False, Aspect_Default_Component_Value => True, @@ -538,6 +555,7 @@ package Aspects is Aspect_Default_Value => True, Aspect_Depends => False, Aspect_Designated_Storage_Model => True, + Aspect_Destructor => False, Aspect_Dimension => False, Aspect_Dimension_System => False, Aspect_Dispatching_Domain => False, @@ -556,6 +574,7 @@ package Aspects is Aspect_GNAT_Annotate => False, Aspect_Implicit_Dereference => False, Aspect_Initial_Condition => False, + Aspect_Initialize => False, Aspect_Initializes => False, Aspect_Input => False, Aspect_Integer_Literal => False, @@ -575,11 +594,13 @@ package Aspects is Aspect_Part_Of => False, Aspect_Post => False, Aspect_Postcondition => False, + Aspect_Potentially_Invalid => False, Aspect_Pre => False, Aspect_Precondition => False, Aspect_Predicate => False, Aspect_Predicate_Failure => False, Aspect_Priority => False, + Aspect_Program_Exit => False, Aspect_Put_Image => False, Aspect_Read => False, Aspect_Real_Literal => False, @@ -698,6 +719,7 @@ package Aspects is Aspect_Constant_After_Elaboration => Name_Constant_After_Elaboration, Aspect_Constant_Indexing => Name_Constant_Indexing, Aspect_Contract_Cases => Name_Contract_Cases, + Aspect_Constructor => Name_Constructor, Aspect_Convention => Name_Convention, Aspect_CPU => Name_CPU, Aspect_CUDA_Device => Name_CUDA_Device, @@ -709,6 +731,7 @@ package Aspects is Aspect_Default_Value => Name_Default_Value, Aspect_Depends => Name_Depends, Aspect_Designated_Storage_Model => Name_Designated_Storage_Model, + Aspect_Destructor => Name_Destructor, Aspect_Dimension => Name_Dimension, Aspect_Dimension_System => Name_Dimension_System, Aspect_Disable_Controlled => Name_Disable_Controlled, @@ -742,6 +765,7 @@ package Aspects is Aspect_Inline => Name_Inline, Aspect_Inline_Always => Name_Inline_Always, Aspect_Initial_Condition => Name_Initial_Condition, + Aspect_Initialize => Name_Initialize, Aspect_Initializes => Name_Initializes, Aspect_Input => Name_Input, Aspect_Integer_Literal => Name_Integer_Literal, @@ -773,6 +797,7 @@ package Aspects is Aspect_Persistent_BSS => Name_Persistent_BSS, Aspect_Post => Name_Post, Aspect_Postcondition => Name_Postcondition, + Aspect_Potentially_Invalid => Name_Potentially_Invalid, Aspect_Pre => Name_Pre, Aspect_Precondition => Name_Precondition, Aspect_Predicate => Name_Predicate, @@ -780,6 +805,7 @@ package Aspects is Aspect_Preelaborable_Initialization => Name_Preelaborable_Initialization, Aspect_Preelaborate => Name_Preelaborate, Aspect_Priority => Name_Priority, + Aspect_Program_Exit => Name_Program_Exit, Aspect_Pure => Name_Pure, Aspect_Pure_Function => Name_Pure_Function, Aspect_Put_Image => Name_Put_Image, @@ -965,6 +991,7 @@ package Aspects is Aspect_Asynchronous => Always_Delay, Aspect_Attach_Handler => Always_Delay, Aspect_Constant_Indexing => Always_Delay, + Aspect_Constructor => Always_Delay, Aspect_CPU => Always_Delay, Aspect_CUDA_Device => Always_Delay, Aspect_CUDA_Global => Always_Delay, @@ -973,6 +1000,7 @@ package Aspects is Aspect_Default_Value => Always_Delay, Aspect_Default_Component_Value => Always_Delay, Aspect_Designated_Storage_Model => Always_Delay, + Aspect_Destructor => Always_Delay, Aspect_Discard_Names => Always_Delay, Aspect_Dispatching_Domain => Always_Delay, Aspect_Dynamic_Predicate => Always_Delay, @@ -1009,6 +1037,7 @@ package Aspects is Aspect_Preelaborable_Initialization => Always_Delay, Aspect_Preelaborate => Always_Delay, Aspect_Priority => Always_Delay, + Aspect_Program_Exit => Always_Delay, Aspect_Pure => Always_Delay, Aspect_Pure_Function => Always_Delay, Aspect_Put_Image => Always_Delay, @@ -1070,6 +1099,7 @@ package Aspects is Aspect_Import => Never_Delay, Aspect_Initial_Condition => Never_Delay, Aspect_Local_Restrictions => Never_Delay, + Aspect_Initialize => Never_Delay, Aspect_Initializes => Never_Delay, Aspect_Max_Entry_Queue_Length => Never_Delay, Aspect_Max_Queue_Length => Never_Delay, @@ -1080,6 +1110,7 @@ package Aspects is Aspect_No_Tagged_Streams => Never_Delay, Aspect_Obsolescent => Never_Delay, Aspect_Part_Of => Never_Delay, + Aspect_Potentially_Invalid => Never_Delay, Aspect_Refined_Depends => Never_Delay, Aspect_Refined_Global => Never_Delay, Aspect_Refined_Post => Never_Delay, diff --git a/gcc/ada/atree.adb b/gcc/ada/atree.adb index 8a69a0c224de..20ca189ad8c3 100644 --- a/gcc/ada/atree.adb +++ b/gcc/ada/atree.adb @@ -1296,8 +1296,7 @@ package body Atree is Node_Offsets.Table (Node_Offsets.First .. Node_Offsets.Last); begin - -- Empty_Or_Error use as described in types.ads - if Destination <= Empty_Or_Error or No (Source) then + if Destination in Empty | Error or else No (Source) then pragma Assert (Serious_Errors_Detected > 0); return; end if; @@ -1458,7 +1457,7 @@ package body Atree is -- Start of processing for Copy_Separate_Tree begin - if Source <= Empty_Or_Error then + if Source in Empty | Error then return Source; elsif Is_Entity (Source) then @@ -1841,7 +1840,7 @@ package body Atree is pragma Debug (Validate_Node (Source)); S_Size : constant Slot_Count := Size_In_Slots_To_Alloc (Source); begin - if Source <= Empty_Or_Error then + if Source in Empty | Error then return Source; end if; @@ -2271,10 +2270,10 @@ package body Atree is -- Copy substitute node into place, preserving old fields as required Copy_Node (Source => New_Node, Destination => Old_Node); - Set_Error_Posted (Old_Node, Old_Error_Posted); Set_Check_Actuals (Old_Node, Old_CA); Set_Is_Ignored_Ghost_Node (Old_Node, Old_Is_IGN); + Set_Error_Posted (Old_Node, Old_Error_Posted); if Nkind (New_Node) in N_Subexpr then Set_Paren_Count (Old_Node, Old_Paren_Count); @@ -2702,9 +2701,9 @@ package body Atree is -- tail recursive step won't go past the end. declare - Cur_Field : Offset_Array_Index := Traversed_Offset_Array'First; Offsets : Traversed_Offset_Array renames Traversed_Fields (Nkind (Cur_Node)); + Cur_Field : Offset_Array_Index := Traversed_Offset_Array'First; begin if Offsets (Traversed_Offset_Array'First) /= No_Field_Offset then diff --git a/gcc/ada/atree.ads b/gcc/ada/atree.ads index dc5fe0d8ad61..802db8709338 100644 --- a/gcc/ada/atree.ads +++ b/gcc/ada/atree.ads @@ -285,34 +285,29 @@ package Atree is procedure Copy_Node (Source, Destination : Node_Or_Entity_Id); -- Copy the entire contents of the source node to the destination node. - -- The contents of the source node is not affected. If the source node - -- has an extension, then the destination must have an extension also. - -- The parent pointer of the destination and its list link, if any, are - -- not affected by the copy. Note that parent pointers of descendants - -- are not adjusted, so the descendants of the destination node after - -- the Copy_Node is completed have dubious parent pointers. Note that - -- this routine does NOT copy aspect specifications, the Has_Aspects - -- flag in the returned node will always be False. The caller must deal - -- with copying aspect specifications where this is required. + -- The contents of the source node is not affected. The parent pointer of + -- the destination and its list link, if any, are not affected by the copy. + -- Note that parent pointers of descendants are not adjusted, so the + -- descendants of the destination node after the Copy_Node is completed + -- have dubious parent pointers. function New_Copy (Source : Node_Id) return Node_Id; -- This function allocates a new node, and then initializes it by copying -- the contents of the source node into it. The contents of the source node -- is not affected. The target node is always marked as not being in a list - -- (even if the source is a list member), and not overloaded. The new node - -- will have an extension if the source has an extension. New_Copy (Empty) - -- returns Empty, and New_Copy (Error) returns Error. Note that, unlike - -- Copy_Separate_Tree, New_Copy does not recursively copy any descendants, - -- so in general parent pointers are not set correctly for the descendants - -- of the copied node. + -- (even if the source is a list member), and not overloaded. + -- New_Copy (Empty) returns Empty, and New_Copy (Error) returns Error. Note + -- that, unlike Copy_Separate_Tree, New_Copy does not recursively copy any + -- descendants, so in general parent pointers are not set correctly for the + -- descendants of the copied node. function Relocate_Node (Source : Node_Id) return Node_Id; -- Source is a non-entity node that is to be relocated. A new node is -- allocated, and the contents of Source are copied to this node, using -- New_Copy. The parent pointers of descendants of the node are then -- adjusted to point to the relocated copy. The original node is not - -- modified, but the parent pointers of its descendants are no longer - -- valid. The new copy is always marked as not overloaded. This routine is + -- modified, but the parent pointers of its children no longer point back + -- at it. The new copy is always marked as not overloaded. This routine is -- used in conjunction with the tree rewrite routines (see descriptions of -- Replace/Rewrite). -- @@ -458,7 +453,7 @@ package Atree is function Parent_Or_List_Containing (X : Union_Id) return Union_Id; -- X must be in Node_Range or in List_Range. If X is in Node_Range and is - -- contained in a list, returns that list, otherwise return the parent of + -- contained in a list, returns that list, otherwise returns the parent of -- the list or node represented by X. function Paren_Count (N : Node_Id) return Nat; @@ -537,16 +532,13 @@ package Atree is procedure Rewrite (Old_Node, New_Node : Node_Id); -- This is used when a complete subtree is to be replaced. Old_Node is the -- root of the old subtree to be replaced, and New_Node is the root of the - -- newly constructed replacement subtree. The actual mechanism is to swap - -- the contents of these two nodes fixing up the parent pointers of the - -- replaced node (we do not attempt to preserve parent pointers for the - -- original node). - -- ??? The above explanation is incorrect, instead Copy_Node is called. + -- newly constructed replacement subtree. -- -- Note: New_Node may not contain references to Old_Node, for example as - -- descendants, since the rewrite would make such references invalid. If - -- New_Node does need to reference Old_Node, then these references should - -- be to a relocated copy of Old_Node (see Relocate_Node procedure). + -- descendants, since the rewrite would turn them into cyclic + -- self-references. If New_Node does need to reference Old_Node, then these + -- references should be to a relocated copy of Old_Node (see Relocate_Node + -- procedure). -- -- Note: The Original_Node function applied to Old_Node (which has now -- been replaced by the contents of New_Node), can be used to obtain the @@ -560,10 +552,8 @@ package Atree is -- original contents of the Old_Node, but rather the New_Node value. -- Replace also preserves the setting of Comes_From_Source. -- - -- Note that New_Node must not contain references to Old_Node, for example - -- as descendants, since the rewrite would make such references invalid. If - -- New_Node does need to reference Old_Node, then these references should - -- be to a relocated copy of Old_Node (see Relocate_Node procedure). + -- The note in the documentation of Rewrite about the risk of creating + -- cyclic references also applies here. -- -- Replace is used in certain circumstances where it is desirable to -- suppress any history of the rewriting operation. Notably, it is used diff --git a/gcc/ada/bindgen.adb b/gcc/ada/bindgen.adb index bc47ec12ab3a..cb39af67f9a5 100644 --- a/gcc/ada/bindgen.adb +++ b/gcc/ada/bindgen.adb @@ -53,13 +53,6 @@ package body Bindgen is -- Flag which indicates whether the program uses the GNARL library -- (presence of the unit System.OS_Interface) - Num_Elab_Calls : Nat := 0; - -- Number of generated calls to elaboration routines - - Num_Primary_Stacks : Nat := 0; - -- Number of default-sized primary stacks the binder needs to allocate for - -- task objects declared in the program. - Num_Sec_Stacks : Nat := 0; -- Number of default-sized primary stacks the binder needs to allocate for -- task objects declared in the program. @@ -2483,16 +2476,6 @@ package body Bindgen is ALIs.Table (ALIs.First).Time_Slice_Value := Opt.Time_Slice_Value; end if; - -- Count number of elaboration calls - - for E in Elab_Order'Range loop - if Units.Table (Elab_Order (E)).No_Elab then - null; - else - Num_Elab_Calls := Num_Elab_Calls + 1; - end if; - end loop; - -- Count the number of statically allocated stacks to be generated by -- the binder. If the user has specified the number of default-sized -- secondary stacks, use that number. Otherwise start the count at one @@ -2506,9 +2489,6 @@ package body Bindgen is end if; for J in Units.First .. Units.Last loop - Num_Primary_Stacks := - Num_Primary_Stacks + Units.Table (J).Primary_Stack_Count; - Num_Sec_Stacks := Num_Sec_Stacks + Units.Table (J).Sec_Stack_Count; end loop; diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb index dcfcaa33bcc4..0b3ae02259e3 100644 --- a/gcc/ada/checks.adb +++ b/gcc/ada/checks.adb @@ -750,7 +750,7 @@ package body Checks is -- mode then just skip the check (it is not required in any case). when RE_Not_Available => - return; + null; end Apply_Address_Clause_Check; ------------------------------------- @@ -1078,7 +1078,7 @@ package body Checks is exception when RE_Not_Available => - return; + null; end; end Apply_Arithmetic_Overflow_Strict; @@ -6437,8 +6437,6 @@ package body Checks is if Debug_Flag_CC then w (" exception occurred, overflow flag set"); end if; - - return; end Enable_Overflow_Check; ------------------------ @@ -6686,8 +6684,6 @@ package body Checks is if Debug_Flag_CC then w (" exception occurred, range flag set"); end if; - - return; end Enable_Range_Check; ------------------ @@ -7091,8 +7087,6 @@ package body Checks is end loop; -- If we fall through entry was not found - - return; end Find_Check; --------------------------------- @@ -8163,6 +8157,7 @@ package body Checks is end if; declare + Decl : Node_Id; CE : Node_Id; PV : Node_Id; Var_Id : Entity_Id; @@ -8215,12 +8210,20 @@ package body Checks is Mutate_Ekind (Var_Id, E_Variable); Set_Etype (Var_Id, Typ); - Insert_Action (Exp, + Decl := Make_Object_Declaration (Loc, Defining_Identifier => Var_Id, Object_Definition => New_Occurrence_Of (Typ, Loc), - Expression => New_Copy_Tree (Exp)), - Suppress => Validity_Check); + Expression => New_Copy_Tree (Exp)); + + -- We might be validity-checking object whose type is declared as + -- limited but completion is a scalar type. We need to explicitly + -- flag its assignment as OK, as otherwise it would be rejected by + -- the language rules. + + Set_Assignment_OK (Decl); + + Insert_Action (Exp, Decl, Suppress => Validity_Check); Set_Validated_Object (Var_Id, New_Copy_Tree (Exp)); diff --git a/gcc/ada/clean.adb b/gcc/ada/clean.adb index f28cf691cf9d..dcbeffe1b8e9 100644 --- a/gcc/ada/clean.adb +++ b/gcc/ada/clean.adb @@ -319,7 +319,9 @@ package body Clean is Delete ("", Executable); end if; - Delete_Binder_Generated_Files (Get_Current_Dir, Source); + Delete_Binder_Generated_Files + (GNAT.Directory_Operations.Get_Current_Dir, + Source); end; end if; end loop; @@ -405,7 +407,8 @@ package body Clean is Source : File_Name_Type) is Source_Name : constant String := Get_Name_String (Source); - Current : constant String := Get_Current_Dir; + Current : constant String := + GNAT.Directory_Operations.Get_Current_Dir; Last : constant Positive := B_Start'Length + Source_Name'Length; File_Name : String (1 .. Last + 4); diff --git a/gcc/ada/comperr.adb b/gcc/ada/comperr.adb index 180ea94353e4..c6285e986208 100644 --- a/gcc/ada/comperr.adb +++ b/gcc/ada/comperr.adb @@ -146,7 +146,7 @@ package body Comperr is if Serious_Errors_Detected /= 0 and then not Debug_Flag_K then Errout.Finalize (Last_Call => True); - Errout.Output_Messages; + Errout.Output_Messages (E_Errors); Set_Standard_Error; Write_Str ("compilation abandoned due to previous error"); @@ -307,16 +307,16 @@ package body Comperr is Write_Str ("| Please submit a bug report by email " & - "to report@adacore.com."); + "to support@adacore.com."); End_Line; Write_Str - ("| GAP members can alternatively use GNAT Tracker:"); + ("| GAP members can alternatively use GNATtracker:"); End_Line; Write_Str - ("| https://www.adacore.com/login?mode=gap " & - "section 'Create New Ticket'."); + ("| https://support.adacore.com/csm " & + "by using the button 'Create A New Case'."); End_Line; Write_Str @@ -326,17 +326,17 @@ package body Comperr is else Write_Str - ("| Please submit a bug report using GNAT Tracker:"); + ("| Please submit a bug report using GNATtracker at"); End_Line; Write_Str - ("| https://www.adacore.com/login " & - "section 'Create New Ticket'."); + ("| https://support.adacore.com/csm " & + "by using the button 'Create New Case'."); End_Line; Write_Str ("| Or submit a bug report by email " & - "to report@adacore.com"); + "to support@adacore.com"); End_Line; Write_Str diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb index 8b94a67639f2..70e94874a23f 100644 --- a/gcc/ada/contracts.adb +++ b/gcc/ada/contracts.adb @@ -110,8 +110,8 @@ package body Contracts is -- Expand the contracts of a subprogram body and its correspoding spec (if -- any). This routine processes all [refined] pre- and postconditions as -- well as Always_Terminates, Contract_Cases, Exceptional_Cases, - -- Subprogram_Variant, invariants and predicates. Body_Id denotes the - -- entity of the subprogram body. + -- Program_Exit, Subprogram_Variant, invariants and predicates. Body_Id + -- denotes the entity of the subprogram body. procedure Preanalyze_Condition (Subp : Entity_Id; @@ -235,6 +235,7 @@ package body Contracts is -- Interrupt_Handler -- Postcondition -- Precondition + -- Program_Exit -- Side_Effects -- Subprogram_Variant -- Test_Case @@ -267,6 +268,7 @@ package body Contracts is | Name_Contract_Cases | Name_Exceptional_Cases | Name_Exit_Cases + | Name_Program_Exit | Name_Subprogram_Variant | Name_Test_Case then @@ -647,9 +649,9 @@ package body Contracts is end if; -- Deal with preconditions, [refined] postconditions, Always_Terminates, - -- Contract_Cases, Exceptional_Cases, Subprogram_Variant, invariants and - -- predicates associated with body and its spec. Do not expand the - -- contract of subprogram body stubs. + -- Contract_Cases, Exceptional_Cases, Program_Exit, Subprogram_Variant, + -- invariants and predicates associated with body and its spec. Do not + -- expand the contract of subprogram body stubs. if Nkind (Body_Decl) = N_Subprogram_Body then Expand_Subprogram_Contract (Body_Id); @@ -797,6 +799,9 @@ package body Contracts is elsif Prag_Nam = Name_Exceptional_Cases then Analyze_Exceptional_Cases_In_Decl_Part (Prag); + elsif Prag_Nam = Name_Program_Exit then + Analyze_Program_Exit_In_Decl_Part (Prag); + elsif Prag_Nam = Name_Subprogram_Variant then Analyze_Subprogram_Variant_In_Decl_Part (Prag); @@ -1413,6 +1418,7 @@ package body Contracts is -- Global -- Postcondition -- Precondition + -- Program_Exit -- Subprogram_Variant -- Test_Case @@ -2422,6 +2428,7 @@ package body Contracts is -- verify the return value. Result := Make_Defining_Identifier (Loc, Name_uResult); + Mutate_Ekind (Result, E_Constant); Set_Etype (Result, Typ); -- Add an invariant check when the return type has invariants and @@ -2761,6 +2768,9 @@ package body Contracts is elsif Pragma_Name (Prag) = Name_Exit_Cases then Expand_Pragma_Exit_Cases (Prag); + elsif Pragma_Name (Prag) = Name_Program_Exit then + Expand_Pragma_Program_Exit (Prag); + elsif Pragma_Name (Prag) = Name_Subprogram_Variant then Expand_Pragma_Subprogram_Variant (Prag => Prag, @@ -4389,10 +4399,10 @@ package body Contracts is Seen : Subprogram_List (Subps'Range) := (others => Empty); function Inherit_Condition - (Par_Subp : Entity_Id; - Subp : Entity_Id) return Node_Id; - -- Inherit the class-wide condition from Par_Subp to Subp and adjust - -- all the references to formals in the inherited condition. + (Par_Subp : Entity_Id) return Node_Id; + -- Inherit the class-wide condition from Par_Subp. Simply makes + -- a copy of the condition in preparation for later mapping of + -- referenced formals and functions by Build_Class_Wide_Expression. procedure Merge_Conditions (From : Node_Id; Into : Node_Id); -- Merge two class-wide preconditions or postconditions (the former @@ -4407,92 +4417,11 @@ package body Contracts is ----------------------- function Inherit_Condition - (Par_Subp : Entity_Id; - Subp : Entity_Id) return Node_Id - is - function Check_Condition (Expr : Node_Id) return Boolean; - -- Used in assertion to check that Expr has no reference to the - -- formals of Par_Subp. - - --------------------- - -- Check_Condition -- - --------------------- - - function Check_Condition (Expr : Node_Id) return Boolean is - Par_Formal_Id : Entity_Id; - - function Check_Entity (N : Node_Id) return Traverse_Result; - -- Check occurrence of Par_Formal_Id - - ------------------ - -- Check_Entity -- - ------------------ - - function Check_Entity (N : Node_Id) return Traverse_Result is - begin - if Nkind (N) = N_Identifier - and then Present (Entity (N)) - and then Entity (N) = Par_Formal_Id - then - return Abandon; - end if; - - return OK; - end Check_Entity; - - function Check_Expression is new Traverse_Func (Check_Entity); - - -- Start of processing for Check_Condition - - begin - Par_Formal_Id := First_Formal (Par_Subp); - - while Present (Par_Formal_Id) loop - if Check_Expression (Expr) = Abandon then - return False; - end if; - - Next_Formal (Par_Formal_Id); - end loop; - - return True; - end Check_Condition; - - -- Local variables - - Assoc_List : constant Elist_Id := New_Elmt_List; - Par_Formal_Id : Entity_Id := First_Formal (Par_Subp); - Subp_Formal_Id : Entity_Id := First_Formal (Subp); - New_Condition : Node_Id; - + (Par_Subp : Entity_Id) return Node_Id is begin - while Present (Par_Formal_Id) loop - Append_Elmt (Par_Formal_Id, Assoc_List); - Append_Elmt (Subp_Formal_Id, Assoc_List); - - Next_Formal (Par_Formal_Id); - Next_Formal (Subp_Formal_Id); - end loop; - - -- Check that Parent field of all the nodes have their correct - -- decoration; required because otherwise mapped nodes with - -- wrong Parent field are left unmodified in the copied tree - -- and cause reporting wrong errors at later stages. - - pragma Assert - (Check_Parents (Class_Condition (Kind, Par_Subp), Assoc_List)); - - New_Condition := + return New_Copy_Tree - (Source => Class_Condition (Kind, Par_Subp), - Map => Assoc_List); - - -- Ensure that the inherited condition has no reference to the - -- formals of the parent subprogram. - - pragma Assert (Check_Condition (New_Condition)); - - return New_Condition; + (Source => Class_Condition (Kind, Par_Subp)); end Inherit_Condition; ---------------------- @@ -4606,9 +4535,7 @@ package body Contracts is Par_Prim := Subp_Id; Par_Iface_Prims := Covered_Interface_Primitives (Par_Prim); - Cond := Inherit_Condition - (Subp => Spec_Id, - Par_Subp => Subp_Id); + Cond := Inherit_Condition (Par_Subp => Subp_Id); if Present (Class_Cond) then Merge_Conditions (Cond, Class_Cond); @@ -4652,9 +4579,7 @@ package body Contracts is then Seen (Index) := Subp_Id; - Cond := Inherit_Condition - (Subp => Spec_Id, - Par_Subp => Subp_Id); + Cond := Inherit_Condition (Par_Subp => Subp_Id); Check_Class_Condition (Cond => Cond, @@ -4909,7 +4834,7 @@ package body Contracts is Install_Formals (Subp); Inside_Class_Condition_Preanalysis := True; - Preanalyze_Spec_Expression (Expr, Standard_Boolean); + Preanalyze_And_Resolve_Spec_Expression (Expr, Standard_Boolean); Inside_Class_Condition_Preanalysis := False; End_Scope; diff --git a/gcc/ada/contracts.ads b/gcc/ada/contracts.ads index ca9f84f9351d..8b82037ea576 100644 --- a/gcc/ada/contracts.ads +++ b/gcc/ada/contracts.ads @@ -56,6 +56,7 @@ package Contracts is -- Part_Of -- Postcondition -- Precondition + -- Program_Exit -- Refined_Depends -- Refined_Global -- Refined_Post @@ -90,6 +91,7 @@ package Contracts is -- Global (stand alone subprogram body) -- Postcondition (stand alone subprogram body) -- Precondition (stand alone subprogram body) + -- Program_Exit (stand alone subprogram body) -- Refined_Depends -- Refined_Global -- Refined_Post @@ -110,6 +112,7 @@ package Contracts is -- Global -- Postcondition -- Precondition + -- Program_Exit -- Subprogram_Variant -- Test_Case -- @@ -186,6 +189,7 @@ package Contracts is -- Global -- Postcondition -- Precondition + -- Program_Exit -- Refined_Depends -- Refined_Global -- Refined_Post diff --git a/gcc/ada/cstand.adb b/gcc/ada/cstand.adb index 5ba88b9ae1c9..79e7083f62bf 100644 --- a/gcc/ada/cstand.adb +++ b/gcc/ada/cstand.adb @@ -67,10 +67,10 @@ package body CStand is procedure Build_Float_Type (E : Entity_Id; - Digs : Int; + Digs : Pos; Rep : Float_Rep_Kind; Siz : Int; - Align : Int); + Align : Nat); -- Procedure to build standard predefined float base type. The first -- parameter is the entity for the type. The second parameter is the -- digits value. The third parameter indicates the representation to @@ -192,10 +192,10 @@ package body CStand is procedure Build_Float_Type (E : Entity_Id; - Digs : Int; + Digs : Pos; Rep : Float_Rep_Kind; Siz : Int; - Align : Int) + Align : Nat) is begin Set_Type_Definition (Parent (E), @@ -612,27 +612,14 @@ package body CStand is Set_Is_Pure (Standard_Standard); Set_Is_Compilation_Unit (Standard_Standard); - -- Create type/subtype declaration nodes for standard types + -- Create type declaration nodes for standard types for S in S_Types loop - - -- Subtype declaration case - - if S = S_Natural or else S = S_Positive then - Decl := New_Node (N_Subtype_Declaration, Stloc); - Set_Subtype_Indication (Decl, - New_Occurrence_Of (Standard_Integer, Stloc)); - - -- Full type declaration case - - else + if S not in S_Natural | S_Positive then Decl := New_Node (N_Full_Type_Declaration, Stloc); + Set_Defining_Identifier (Decl, Standard_Entity (S)); + Append (Decl, Decl_S); end if; - - Set_Is_Frozen (Standard_Entity (S)); - Set_Is_Public (Standard_Entity (S)); - Set_Defining_Identifier (Decl, Standard_Entity (S)); - Append (Decl, Decl_S); end loop; Create_Back_End_Float_Types; @@ -1023,6 +1010,14 @@ package body CStand is Hb => Intval (High_Bound (Scalar_Range (Standard_Integer)))); Set_Is_Constrained (Standard_Natural); + Append_To + (Decl_S, + Make_Subtype_Declaration + (Stloc, + Standard_Natural, + Subtype_Indication => + New_Occurrence_Of (Standard_Integer, Stloc))); + -- Setup entity for Positive Mutate_Ekind (Standard_Positive, E_Signed_Integer_Subtype); @@ -1040,6 +1035,14 @@ package body CStand is Hb => Intval (High_Bound (Scalar_Range (Standard_Integer)))); Set_Is_Constrained (Standard_Positive); + Append_To + (Decl_S, + Make_Subtype_Declaration + (Stloc, + Standard_Positive, + Subtype_Indication => + New_Occurrence_Of (Standard_Integer, Stloc))); + -- Create declaration for package ASCII Decl := New_Node (N_Package_Declaration, Stloc); @@ -1073,7 +1076,6 @@ package body CStand is Set_Never_Set_In_Source (A_Char, True); Set_Is_True_Constant (A_Char, True); Set_Etype (A_Char, Standard_Character); - Set_Scope (A_Char, Standard_Entity (S_ASCII)); Set_Is_Immediately_Visible (A_Char, False); Set_Is_Public (A_Char, True); Set_Is_Known_Valid (A_Char, True); @@ -1729,7 +1731,6 @@ package body CStand is begin Mutate_Ekind (Id, E_Component); Set_Etype (Id, Typ); - Set_Scope (Id, Rec); Reinit_Component_Location (Id); Set_Original_Record_Component (Id, Id); Set_Is_Aliased (Id); @@ -1747,7 +1748,6 @@ package body CStand is begin Mutate_Ekind (Formal, E_In_Parameter); Set_Mechanism (Formal, Default_Mechanism); - Set_Scope (Formal, Standard_Standard); Set_Etype (Formal, Typ); return Formal; @@ -1777,7 +1777,6 @@ package body CStand is Set_Is_Pure (Ident_Node, True); Mutate_Ekind (Ident_Node, E_Operator); Set_Etype (Ident_Node, Typ); - Set_Scope (Ident_Node, Standard_Standard); Set_Homonym (Ident_Node, Get_Name_Entity_Id (Op)); Set_Convention (Ident_Node, Convention_Intrinsic); @@ -2083,7 +2082,7 @@ package body CStand is Set_Defining_Identifier (New_Node (N_Full_Type_Declaration, Stloc), Ent); Set_Scope (Ent, Standard_Standard); Build_Float_Type - (Ent, Pos (Digs), Float_Rep, Int (Size), Int (Alignment / 8)); + (Ent, Pos (Digs), Float_Rep, Int (Size), Nat (Alignment / 8)); Append_New_Elmt (Ent, Back_End_Float_Types); end Register_Float_Type; @@ -2092,7 +2091,7 @@ package body CStand is -- Set_Float_Bounds -- ---------------------- - procedure Set_Float_Bounds (Id : Entity_Id) is + procedure Set_Float_Bounds (Id : Entity_Id) is L : Node_Id; H : Node_Id; -- Low and high bounds of literal value diff --git a/gcc/ada/cstand.ads b/gcc/ada/cstand.ads index 62644fe546c0..bfd30526e114 100644 --- a/gcc/ada/cstand.ads +++ b/gcc/ada/cstand.ads @@ -42,7 +42,7 @@ package CStand is -- The semantics info is in the format given by Entity_Info. The global -- variables Last_Standard_Node_Id and Last_Standard_List_Id are also set. - procedure Set_Float_Bounds (Id : Entity_Id); + procedure Set_Float_Bounds (Id : Entity_Id); -- Procedure to set bounds for float type or subtype. Id is the entity -- whose bounds and type are to be set (a floating-point type). diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb index ac3ce41dcc51..f250d7429a96 100644 --- a/gcc/ada/debug.adb +++ b/gcc/ada/debug.adb @@ -168,7 +168,7 @@ package body Debug is -- d_A Stop generation of ALI file -- d_B Warn on build-in-place function calls -- d_C - -- d_D Use improved diagnostics + -- d_D -- d_E Print diagnostics and switch repository -- d_F Encode full invocation paths in ALI files -- d_G @@ -186,8 +186,8 @@ package body Debug is -- d_S -- d_T Output trace information on invocation path recording -- d_U Disable prepending messages with "error:". - -- d_V Enable verifications on the expanded tree - -- d_W + -- d_V Enable VAST (verifications on the expanded tree) + -- d_W Enable VAST in verbose mode -- d_X Disable assertions to check matching of extra formals -- d_Y -- d_Z @@ -1065,8 +1065,11 @@ package body Debug is -- d_U Disable prepending 'error:' to error messages. This used to be the -- default and can be seen as the opposite of -gnatU. - -- d_V Enable verification of the expanded code before calling the backend - -- and generate error messages on each inconsistency found. + -- d_V Enable VAST (Verifier for the Ada Semantic Tree). This does + -- verification of the expanded code before calling the backend. + + -- d_W Same as d_V, but also prints lots of tracing/debugging output + -- as it walks the tree. -- d_X Disable assertions to check matching of extra formals; switch added -- temporarily to disable these checks until this work is complete if diff --git a/gcc/ada/debug_a.adb b/gcc/ada/debug_a.adb index d36ae696af64..8d68fc8eff7d 100644 --- a/gcc/ada/debug_a.adb +++ b/gcc/ada/debug_a.adb @@ -83,11 +83,8 @@ package body Debug_A is case Nkind (N) is when N_Has_Chars => - Write_Str (" """); - if Present (Chars (N)) then - Write_Str (Get_Name_String (Chars (N))); - end if; - Write_Str (""""); + Write_Str (" "); + Write_Name_For_Debug (Chars (N)); when others => null; end case; diff --git a/gcc/ada/diagnostics-brief_emitter.adb b/gcc/ada/diagnostics-brief_emitter.adb deleted file mode 100644 index 0315b53c402e..000000000000 --- a/gcc/ada/diagnostics-brief_emitter.adb +++ /dev/null @@ -1,137 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- D I A G N O S T I C S . B R I E F _ E M I T T E R -- --- -- --- B o d y -- --- -- --- Copyright (C) 1992-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- --- for more details. You should have received a copy of the GNU General -- --- Public License distributed with GNAT; see file COPYING3. If not, go to -- --- http://www.gnu.org/licenses for a complete copy of the license. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - -with Diagnostics.Utils; use Diagnostics.Utils; -with Erroutc; use Erroutc; -with Opt; use Opt; -with Output; use Output; - -package body Diagnostics.Brief_Emitter is - - procedure Print_Sub_Diagnostic - (Sub_Diag : Sub_Diagnostic_Type; - Diag : Diagnostic_Type); - - -------------------------- - -- Print_Sub_Diagnostic -- - -------------------------- - - procedure Print_Sub_Diagnostic - (Sub_Diag : Sub_Diagnostic_Type; - Diag : Diagnostic_Type) - is - -- In GNAT sub messages were grouped by the main messages by also having - -- the same location. In the brief printer we use the primary location - -- of the main diagnostic for all of the subdiagnostics. - Prim_Loc : constant Labeled_Span_Type := Primary_Location (Diag); - - Sptr : constant Source_Ptr := Prim_Loc.Span.Ptr; - - Text : String_Ptr; - - Line_Length : constant Nat := (if Error_Msg_Line_Length = 0 then Nat'Last - else Error_Msg_Line_Length); - - Switch_Str : constant String := Get_Doc_Switch (Diag); - begin - Text := new String'(To_String (Sptr) & ": " - & Kind_To_String (Sub_Diag, Diag) & ": " - & Sub_Diag.Message.all); - - if Switch_Str /= "" then - Text := new String'(Text.all & " " & Switch_Str); - end if; - - if Diag.Warn_Err then - Text := new String'(Text.all & " [warning-as-error]"); - end if; - - Output_Text_Within (Text, Line_Length); - Write_Eol; - end Print_Sub_Diagnostic; - - ---------------------- - -- Print_Diagnostic -- - ---------------------- - - procedure Print_Diagnostic (Diag : Diagnostic_Type) is - use Sub_Diagnostic_Lists; - - Prim_Loc : constant Labeled_Span_Type := Primary_Location (Diag); - - Sptr : constant Source_Ptr := Prim_Loc.Span.Ptr; - - Text : String_Ptr; - - Line_Length : constant Nat := (if Error_Msg_Line_Length = 0 then Nat'Last - else Error_Msg_Line_Length); - - Switch_Str : constant String := Get_Doc_Switch (Diag); - begin - Write_Str (To_String (Sptr) & ": "); - - -- Ignore the message prefix on Style messages. They will use - -- the (style) prefix within the message. - -- - -- Also disable the "error:" prefix if Unique_Error_Tag is unset. - - if (Diag.Kind = Style and then not Diag.Warn_Err) - or else (Diag.Kind = Error and then not Unique_Error_Tag) - then - Text := new String'(""); - else - Text := new String'(Kind_To_String (Diag) & ": "); - end if; - - Text := new String'(Text.all & Diag.Message.all); - - if Switch_Str /= "" then - Text := new String'(Text.all & " " & Switch_Str); - end if; - - if Diag.Warn_Err then - Text := new String'(Text.all & " [warning-as-error]"); - end if; - - Output_Text_Within (Text, Line_Length); - Write_Eol; - - if Present (Diag.Sub_Diagnostics) then - declare - - Sub_Diag : Sub_Diagnostic_Type; - - It : Iterator := Iterate (Diag.Sub_Diagnostics); - begin - while Has_Next (It) loop - Next (It, Sub_Diag); - - Print_Sub_Diagnostic (Sub_Diag, Diag); - end loop; - end; - end if; - - end Print_Diagnostic; -end Diagnostics.Brief_Emitter; diff --git a/gcc/ada/diagnostics-constructors.adb b/gcc/ada/diagnostics-constructors.adb deleted file mode 100644 index 0bc8750496d5..000000000000 --- a/gcc/ada/diagnostics-constructors.adb +++ /dev/null @@ -1,514 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- D I A G N O S T I C S . C O N S T R U C T O R S -- --- -- --- B o d y -- --- -- --- Copyright (C) 1992-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- --- for more details. You should have received a copy of the GNU General -- --- Public License distributed with GNAT; see file COPYING3. If not, go to -- --- http://www.gnu.org/licenses for a complete copy of the license. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - -with Sinfo.Nodes; use Sinfo.Nodes; -with Diagnostics.Utils; use Diagnostics.Utils; - -package body Diagnostics.Constructors is - - ----------------------------------------------- - -- Make_Default_Iterator_Not_Primitive_Error -- - ----------------------------------------------- - - function Make_Default_Iterator_Not_Primitive_Error - (Expr : Node_Id; - Subp : Entity_Id) return Diagnostic_Type - is - begin - return - Make_Diagnostic - (Msg => "improper function for default iterator", - Location => Primary_Labeled_Span (Expr), - Id => GNAT0001, - Kind => Diagnostics.Error, - Sub_Diags => - (1 => - Continuation - (Msg => - "default iterator defined " & - Sloc_To_String (Subp, Sloc (Expr)) & - " must be a local primitive or class-wide function", - Locations => - (1 => Primary_Labeled_Span (Subp))))); - end Make_Default_Iterator_Not_Primitive_Error; - - ------------------------------------------------- - -- Record_Default_Iterator_Not_Primitive_Error -- - ------------------------------------------------- - - procedure Record_Default_Iterator_Not_Primitive_Error - (Expr : Node_Id; - Subp : Entity_Id) - is - begin - Record_Diagnostic - (Make_Default_Iterator_Not_Primitive_Error (Expr, Subp)); - end Record_Default_Iterator_Not_Primitive_Error; - - --------------------------------------------------- - -- Make_Invalid_Operand_Types_For_Operator_Error -- - --------------------------------------------------- - - function Make_Invalid_Operand_Types_For_Operator_Error - (Op : Node_Id; - L : Node_Id; - L_Type : Node_Id; - R : Node_Id; - R_Type : Node_Id) return Diagnostic_Type - is - begin - return - Make_Diagnostic - (Msg => "invalid operand types for operator " & To_Name (Op), - Location => Primary_Labeled_Span (Op), - Id => GNAT0002, - Kind => Diagnostics.Error, - Spans => - (1 => - (Secondary_Labeled_Span - (N => L, - Label => To_Type_Name (L_Type))), - 2 => - Secondary_Labeled_Span - (N => R, - Label => To_Type_Name (R_Type)))); - end Make_Invalid_Operand_Types_For_Operator_Error; - - ----------------------------------------------------- - -- Record_Invalid_Operand_Types_For_Operator_Error -- - ----------------------------------------------------- - - procedure Record_Invalid_Operand_Types_For_Operator_Error - (Op : Node_Id; - L : Node_Id; - L_Type : Node_Id; - R : Node_Id; - R_Type : Node_Id) - is - - begin - Record_Diagnostic - (Make_Invalid_Operand_Types_For_Operator_Error - (Op, L, L_Type, R, R_Type)); - end Record_Invalid_Operand_Types_For_Operator_Error; - - --------------------------------------------------------- - -- Make_Invalid_Operand_Types_For_Operator_L_Int_Error -- - --------------------------------------------------------- - - function Make_Invalid_Operand_Types_For_Operator_L_Int_Error - (Op : Node_Id; - L : Node_Id; - L_Type : Node_Id; - R : Node_Id; - R_Type : Node_Id) return Diagnostic_Type - is - begin - return - Make_Diagnostic - (Msg => "invalid operand types for operator " & To_Name (Op), - Location => Primary_Labeled_Span (Op), - Id => GNAT0003, - Kind => Diagnostics.Error, - Spans => - (1 => - (Secondary_Labeled_Span - (N => L, - Label => - "left operand has type " & - To_Name (L_Type))), - 2 => - Secondary_Labeled_Span - (N => R, - Label => - "right operand has type " & - To_Name (R_Type))), - Sub_Diags => - (1 => Suggestion (Msg => "Convert left operand to ""Integer""") - ) - ); - end Make_Invalid_Operand_Types_For_Operator_L_Int_Error; - - ----------------------------------------------------------- - -- Record_Invalid_Operand_Types_For_Operator_L_Int_Error -- - ----------------------------------------------------------- - - procedure Record_Invalid_Operand_Types_For_Operator_L_Int_Error - (Op : Node_Id; - L : Node_Id; - L_Type : Node_Id; - R : Node_Id; - R_Type : Node_Id) - is - - begin - Record_Diagnostic - (Make_Invalid_Operand_Types_For_Operator_L_Int_Error - (Op, L, L_Type, R, R_Type)); - end Record_Invalid_Operand_Types_For_Operator_L_Int_Error; - - --------------------------------------------------------- - -- Make_Invalid_Operand_Types_For_Operator_R_Int_Error -- - --------------------------------------------------------- - - function Make_Invalid_Operand_Types_For_Operator_R_Int_Error - (Op : Node_Id; - L : Node_Id; - L_Type : Node_Id; - R : Node_Id; - R_Type : Node_Id) return Diagnostic_Type - is - begin - return - Make_Diagnostic - (Msg => "invalid operand types for operator " & To_Name (Op), - Location => Primary_Labeled_Span (Op), - Id => GNAT0004, - Kind => Diagnostics.Error, - Spans => - (1 => - Secondary_Labeled_Span - (N => L, - Label => - "left operand has type " & - To_Name (L_Type)), - 2 => - Secondary_Labeled_Span - (N => R, - Label => - "right operand has type " & - To_Name (R_Type))), - Sub_Diags => - (1 => Suggestion (Msg => "Convert right operand to ""Integer""") - ) - ); - end Make_Invalid_Operand_Types_For_Operator_R_Int_Error; - - ----------------------------------------------------------- - -- Record_Invalid_Operand_Types_For_Operator_R_Int_Error -- - ----------------------------------------------------------- - - procedure Record_Invalid_Operand_Types_For_Operator_R_Int_Error - (Op : Node_Id; - L : Node_Id; - L_Type : Node_Id; - R : Node_Id; - R_Type : Node_Id) - is - - begin - Record_Diagnostic - (Make_Invalid_Operand_Types_For_Operator_R_Int_Error - (Op, L, L_Type, R, R_Type)); - end Record_Invalid_Operand_Types_For_Operator_R_Int_Error; - - --------------------------------------------------------- - -- Make_Invalid_Operand_Types_For_Operator_L_Acc_Error -- - --------------------------------------------------------- - - function Make_Invalid_Operand_Types_For_Operator_L_Acc_Error - (Op : Node_Id; - L : Node_Id) return Diagnostic_Type - is - - begin - return - Make_Diagnostic - (Msg => "invalid operand types for operator " & To_Name (Op), - Location => Primary_Labeled_Span (Op), - Id => GNAT0005, - Kind => Diagnostics.Error, - Spans => - (1 => - Secondary_Labeled_Span - (N => L, - Label => - "left operand is access type ") - ) - ); - end Make_Invalid_Operand_Types_For_Operator_L_Acc_Error; - - ----------------------------------------------------------- - -- Record_Invalid_Operand_Types_For_Operator_L_Acc_Error -- - ----------------------------------------------------------- - - procedure Record_Invalid_Operand_Types_For_Operator_L_Acc_Error - (Op : Node_Id; - L : Node_Id) - is - begin - Record_Diagnostic - (Make_Invalid_Operand_Types_For_Operator_R_Acc_Error - (Op, L)); - end Record_Invalid_Operand_Types_For_Operator_L_Acc_Error; - - --------------------------------------------------------- - -- Make_Invalid_Operand_Types_For_Operator_L_Acc_Error -- - --------------------------------------------------------- - - function Make_Invalid_Operand_Types_For_Operator_R_Acc_Error - (Op : Node_Id; - R : Node_Id) return Diagnostic_Type - is - - begin - return - Make_Diagnostic - (Msg => "invalid operand types for operator " & To_Name (Op), - Location => Primary_Labeled_Span (Op), - Id => GNAT0006, - Kind => Diagnostics.Error, - Spans => - (1 => - Secondary_Labeled_Span - (N => R, - Label => - "right operand is access type ") - ) - ); - end Make_Invalid_Operand_Types_For_Operator_R_Acc_Error; - - ----------------------------------------------------------- - -- Record_Invalid_Operand_Types_For_Operator_R_Acc_Error -- - ----------------------------------------------------------- - - procedure Record_Invalid_Operand_Types_For_Operator_R_Acc_Error - (Op : Node_Id; - R : Node_Id) - is - begin - Record_Diagnostic - (Make_Invalid_Operand_Types_For_Operator_R_Acc_Error - (Op, R)); - end Record_Invalid_Operand_Types_For_Operator_R_Acc_Error; - - ----------------------------------------------------------- - -- Make_Invalid_Operand_Types_For_Operator_General_Error -- - ----------------------------------------------------------- - - function Make_Invalid_Operand_Types_For_Operator_General_Error - (Op : Node_Id) return Diagnostic_Type - is - - begin - return - Make_Diagnostic - (Msg => "invalid operand types for operator " & To_Name (Op), - Location => Primary_Labeled_Span (Op), - Id => GNAT0007, - Kind => Diagnostics.Error - ); - end Make_Invalid_Operand_Types_For_Operator_General_Error; - - ------------------------------------------------------------- - -- Record_Invalid_Operand_Types_For_Operator_General_Error -- - ------------------------------------------------------------- - - procedure Record_Invalid_Operand_Types_For_Operator_General_Error - (Op : Node_Id) - is - begin - Record_Diagnostic - (Make_Invalid_Operand_Types_For_Operator_General_Error (Op)); - end Record_Invalid_Operand_Types_For_Operator_General_Error; - - -------------------------------------------------- - -- Make_Pragma_No_Effect_With_Lock_Free_Warning -- - -------------------------------------------------- - - function Make_Pragma_No_Effect_With_Lock_Free_Warning - (Pragma_Node : Node_Id; Pragma_Name : Name_Id; - Lock_Free_Node : Node_Id; Lock_Free_Range : Node_Id) - return Diagnostic_Type - is - begin - return - Make_Diagnostic - (Msg => - "pragma " & '"' & Get_Name_String (Pragma_Name) & '"' & - " for " & To_Name (Lock_Free_Node) & - " has no effect when Lock_Free given", - Location => Primary_Labeled_Span (Pragma_Node, "No effect"), - Id => GNAT0008, - Kind => Diagnostics.Warning, - Spans => - (1 => - Labeled_Span - (Span => To_Full_Span (Lock_Free_Range), - Label => "Lock_Free in effect here", - Is_Primary => False, - Is_Region => True))); - end Make_Pragma_No_Effect_With_Lock_Free_Warning; - - -------------------------------------------- - -- Record_Pragma_No_Effect_With_Lock_Free -- - -------------------------------------------- - - procedure Record_Pragma_No_Effect_With_Lock_Free_Warning - (Pragma_Node : Node_Id; - Pragma_Name : Name_Id; - Lock_Free_Node : Node_Id; - Lock_Free_Range : Node_Id) - is - begin - Record_Diagnostic - (Make_Pragma_No_Effect_With_Lock_Free_Warning - (Pragma_Node, Pragma_Name, Lock_Free_Node, Lock_Free_Range)); - end Record_Pragma_No_Effect_With_Lock_Free_Warning; - - ---------------------------------- - -- Make_End_Loop_Expected_Error -- - ---------------------------------- - - function Make_End_Loop_Expected_Error - (End_Loc : Source_Span; - Start_Loc : Source_Ptr) return Diagnostic_Type - is - begin - return - Make_Diagnostic - (Msg => - """end loop;"" expected for ""loop"" " & - Sloc_To_String (Start_Loc, End_Loc.Ptr), - Location => Primary_Labeled_Span (End_Loc), - Id => GNAT0009, - Kind => Diagnostics.Error, - Spans => (1 => Secondary_Labeled_Span (To_Span (Start_Loc))), - Fixes => - (1 => - Fix - (Description => "Replace with 'end loop;'", - Edits => - (1 => Edit (Text => "end loop;", Span => End_Loc)), - Applicability => Legal))); - end Make_End_Loop_Expected_Error; - - ------------------------------------ - -- Record_End_Loop_Expected_Error -- - ------------------------------------ - - procedure Record_End_Loop_Expected_Error - (End_Loc : Source_Span; Start_Loc : Source_Ptr) - is - begin - Record_Diagnostic (Make_End_Loop_Expected_Error (End_Loc, Start_Loc)); - end Record_End_Loop_Expected_Error; - - ---------------------------------------- - -- Make_Representation_Too_Late_Error -- - ---------------------------------------- - - function Make_Representation_Too_Late_Error - (Rep : Node_Id; - Freeze : Node_Id; - Def : Node_Id) - return Diagnostic_Type - is - begin - return - Make_Diagnostic - (Msg => - "record representation cannot be specified" & - " after the type is frozen", - Location => - Primary_Labeled_Span - (N => Rep, - Label => "record representation clause specified here"), - Id => GNAT0010, - Kind => Error, - Spans => - (1 => - Secondary_Labeled_Span - (N => Freeze, - Label => - "Type " & To_Name (Def) & " is frozen here"), - 2 => - Secondary_Labeled_Span - (N => Def, - Label => - "Type " & To_Name (Def) & " is declared here")), - Sub_Diags => - (1 => - Suggestion - (Msg => - "move the record representation clause" & - " before the freeze point " & - Sloc_To_String (Sloc (Freeze), Sloc (Rep))))); - end Make_Representation_Too_Late_Error; - - ------------------------------------------ - -- Record_Representation_Too_Late_Error -- - ------------------------------------------ - - procedure Record_Representation_Too_Late_Error - (Rep : Node_Id; - Freeze : Node_Id; - Def : Node_Id) - is - begin - Record_Diagnostic - (Make_Representation_Too_Late_Error (Rep, Freeze, Def)); - end Record_Representation_Too_Late_Error; - - ------------------------------------------ - -- Make_Mixed_Container_Aggregate_Error -- - ------------------------------------------ - - function Make_Mixed_Container_Aggregate_Error - (Aggr : Node_Id; - Pos_Elem : Node_Id; - Named_Elem : Node_Id) return Diagnostic_Type - is - - begin - return - Make_Diagnostic - (Msg => - "container aggregate cannot be both positional and named", - Location => Primary_Labeled_Span (Aggr), - Id => GNAT0011, - Kind => Diagnostics.Error, - Spans => - (1 => Secondary_Labeled_Span - (Pos_Elem, "positional element "), - 2 => Secondary_Labeled_Span - (Named_Elem, "named element"))); - end Make_Mixed_Container_Aggregate_Error; - - -------------------------------------------- - -- Record_Mixed_Container_Aggregate_Error -- - -------------------------------------------- - - procedure Record_Mixed_Container_Aggregate_Error - (Aggr : Node_Id; - Pos_Elem : Node_Id; - Named_Elem : Node_Id) - is - begin - Record_Diagnostic - (Make_Mixed_Container_Aggregate_Error (Aggr, Pos_Elem, Named_Elem)); - end Record_Mixed_Container_Aggregate_Error; - -end Diagnostics.Constructors; diff --git a/gcc/ada/diagnostics-constructors.ads b/gcc/ada/diagnostics-constructors.ads deleted file mode 100644 index a568f0f879f8..000000000000 --- a/gcc/ada/diagnostics-constructors.ads +++ /dev/null @@ -1,143 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- D I A G N O S T I C S . C O N S T R U C T O R S -- --- -- --- S p e c -- --- -- --- Copyright (C) 1992-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- --- for more details. You should have received a copy of the GNU General -- --- Public License distributed with GNAT; see file COPYING3. If not, go to -- --- http://www.gnu.org/licenses for a complete copy of the license. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- -with Namet; use Namet; - -package Diagnostics.Constructors is - - function Make_Default_Iterator_Not_Primitive_Error - (Expr : Node_Id; - Subp : Entity_Id) return Diagnostic_Type; - - procedure Record_Default_Iterator_Not_Primitive_Error - (Expr : Node_Id; - Subp : Entity_Id); - - function Make_Invalid_Operand_Types_For_Operator_Error - (Op : Node_Id; - L : Node_Id; - L_Type : Node_Id; - R : Node_Id; - R_Type : Node_Id) return Diagnostic_Type; - - procedure Record_Invalid_Operand_Types_For_Operator_Error - (Op : Node_Id; - L : Node_Id; - L_Type : Node_Id; - R : Node_Id; - R_Type : Node_Id); - - function Make_Invalid_Operand_Types_For_Operator_L_Int_Error - (Op : Node_Id; - L : Node_Id; - L_Type : Node_Id; - R : Node_Id; - R_Type : Node_Id) return Diagnostic_Type; - - procedure Record_Invalid_Operand_Types_For_Operator_L_Int_Error - (Op : Node_Id; - L : Node_Id; - L_Type : Node_Id; - R : Node_Id; - R_Type : Node_Id); - - function Make_Invalid_Operand_Types_For_Operator_R_Int_Error - (Op : Node_Id; - L : Node_Id; - L_Type : Node_Id; - R : Node_Id; - R_Type : Node_Id) return Diagnostic_Type; - - procedure Record_Invalid_Operand_Types_For_Operator_R_Int_Error - (Op : Node_Id; - L : Node_Id; - L_Type : Node_Id; - R : Node_Id; - R_Type : Node_Id); - - function Make_Invalid_Operand_Types_For_Operator_L_Acc_Error - (Op : Node_Id; - L : Node_Id) return Diagnostic_Type; - - procedure Record_Invalid_Operand_Types_For_Operator_L_Acc_Error - (Op : Node_Id; - L : Node_Id); - - function Make_Invalid_Operand_Types_For_Operator_R_Acc_Error - (Op : Node_Id; - R : Node_Id) return Diagnostic_Type; - - procedure Record_Invalid_Operand_Types_For_Operator_R_Acc_Error - (Op : Node_Id; - R : Node_Id); - - function Make_Invalid_Operand_Types_For_Operator_General_Error - (Op : Node_Id) return Diagnostic_Type; - - procedure Record_Invalid_Operand_Types_For_Operator_General_Error - (Op : Node_Id); - - function Make_Pragma_No_Effect_With_Lock_Free_Warning - (Pragma_Node : Node_Id; - Pragma_Name : Name_Id; - Lock_Free_Node : Node_Id; - Lock_Free_Range : Node_Id) - return Diagnostic_Type; - - procedure Record_Pragma_No_Effect_With_Lock_Free_Warning - (Pragma_Node : Node_Id; - Pragma_Name : Name_Id; - Lock_Free_Node : Node_Id; - Lock_Free_Range : Node_Id); - - function Make_End_Loop_Expected_Error - (End_Loc : Source_Span; - Start_Loc : Source_Ptr) return Diagnostic_Type; - - procedure Record_End_Loop_Expected_Error - (End_Loc : Source_Span; - Start_Loc : Source_Ptr); - - function Make_Representation_Too_Late_Error - (Rep : Node_Id; - Freeze : Node_Id; - Def : Node_Id) - return Diagnostic_Type; - - procedure Record_Representation_Too_Late_Error - (Rep : Node_Id; - Freeze : Node_Id; - Def : Node_Id); - - function Make_Mixed_Container_Aggregate_Error - (Aggr : Node_Id; - Pos_Elem : Node_Id; - Named_Elem : Node_Id) return Diagnostic_Type; - - procedure Record_Mixed_Container_Aggregate_Error - (Aggr : Node_Id; - Pos_Elem : Node_Id; - Named_Elem : Node_Id); - -end Diagnostics.Constructors; diff --git a/gcc/ada/diagnostics-converter.adb b/gcc/ada/diagnostics-converter.adb deleted file mode 100644 index b3d9edfffec6..000000000000 --- a/gcc/ada/diagnostics-converter.adb +++ /dev/null @@ -1,254 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- D I A G N O S T I C S . C O N V E R T E R -- --- -- --- B o d y -- --- -- --- Copyright (C) 1992-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- --- for more details. You should have received a copy of the GNU General -- --- Public License distributed with GNAT; see file COPYING3. If not, go to -- --- http://www.gnu.org/licenses for a complete copy of the license. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- -with Erroutc; use Erroutc; -with Debug; use Debug; -with Diagnostics.Repository; use Diagnostics.Repository; -with Diagnostics.SARIF_Emitter; use Diagnostics.SARIF_Emitter; -with Diagnostics.Switch_Repository; use Diagnostics.Switch_Repository; -with Opt; use Opt; -with Osint; use Osint; -with Output; use Output; -use Diagnostics.Diagnostics_Lists; -with System.OS_Lib; use System.OS_Lib; - -package body Diagnostics.Converter is - - function Convert (E_Id : Error_Msg_Id) return Diagnostic_Type; - - function Convert_Sub_Diagnostic - (E_Id : Error_Msg_Id) return Sub_Diagnostic_Type; - - function Get_Warning_Kind (E_Msg : Error_Msg_Object) return Diagnostic_Kind - is (if E_Msg.Warn_Chr = "* " then Restriction_Warning - elsif E_Msg.Warn_Chr = "? " then Default_Warning - elsif E_Msg.Warn_Chr = " " then Tagless_Warning - else Warning); - -- NOTE: Some messages have both info and warning set to true. The old - -- printer added the warning switch label but treated the message as - -- an info message. - - function Get_Diagnostics_Kind (E_Msg : Error_Msg_Object) - return Diagnostic_Kind - is (if E_Msg.Kind = Erroutc.Warning then Get_Warning_Kind (E_Msg) - elsif E_Msg.Kind = Erroutc.Style then Style - elsif E_Msg.Kind = Erroutc.Info then Info - elsif E_Msg.Kind = Erroutc.Non_Serious_Error then Non_Serious_Error - else Error); - - ----------------------------------- - -- Convert_Errors_To_Diagnostics -- - ----------------------------------- - - procedure Convert_Errors_To_Diagnostics - is - E : Error_Msg_Id; - begin - E := First_Error_Msg; - while E /= No_Error_Msg loop - - if not Errors.Table (E).Deleted - and then not Errors.Table (E).Msg_Cont - then - - -- We do not need to update the count of converted error messages - -- since they are accounted for in their creation. - - Record_Diagnostic (Convert (E), Update_Count => False); - end if; - - E := Errors.Table (E).Next; - end loop; - - end Convert_Errors_To_Diagnostics; - - ---------------------------- - -- Convert_Sub_Diagnostic -- - ---------------------------- - - function Convert_Sub_Diagnostic - (E_Id : Error_Msg_Id) return Sub_Diagnostic_Type - is - E_Msg : constant Error_Msg_Object := Errors.Table (E_Id); - D : Sub_Diagnostic_Type; - begin - D.Message := E_Msg.Text; - - -- All converted sub-diagnostics are continuations. When emitted they - -- shall be printed with the same kind token as the main diagnostic. - D.Kind := Continuation; - - Add_Location (D, - Primary_Labeled_Span - (if E_Msg.Insertion_Sloc /= No_Location - then To_Span (E_Msg.Insertion_Sloc) - else E_Msg.Sptr)); - - if E_Msg.Optr.Ptr /= E_Msg.Sptr.Ptr then - Add_Location (D, Secondary_Labeled_Span (E_Msg.Optr)); - end if; - - return D; - end Convert_Sub_Diagnostic; - - ------------- - -- Convert -- - ------------- - - function Convert (E_Id : Error_Msg_Id) return Diagnostic_Type is - - E_Next_Id : Error_Msg_Id; - - E_Msg : constant Error_Msg_Object := Errors.Table (E_Id); - D : Diagnostic_Type; - begin - D.Message := E_Msg.Text; - - D.Kind := Get_Diagnostics_Kind (E_Msg); - - if E_Msg.Kind in Erroutc.Warning | Erroutc.Style | Erroutc.Info then - D.Switch := Get_Switch_Id (E_Msg); - end if; - - D.Warn_Err := E_Msg.Warn_Err; - - -- Convert the primary location - - Add_Location (D, Primary_Labeled_Span (E_Msg.Sptr)); - - -- Convert the secondary location if it is different from the primary - - if E_Msg.Optr.Ptr /= E_Msg.Sptr.Ptr then - Add_Location (D, Secondary_Labeled_Span (E_Msg.Optr)); - end if; - - E_Next_Id := Errors.Table (E_Id).Next; - while E_Next_Id /= No_Error_Msg - and then Errors.Table (E_Next_Id).Msg_Cont - loop - Add_Sub_Diagnostic (D, Convert_Sub_Diagnostic (E_Next_Id)); - E_Next_Id := Errors.Table (E_Next_Id).Next; - end loop; - - return D; - end Convert; - - ---------------------- - -- Emit_Diagnostics -- - ---------------------- - - procedure Emit_Diagnostics is - D : Diagnostic_Type; - - It : Iterator := Iterate (All_Diagnostics); - - Sarif_File_Name : constant String := - Get_First_Main_File_Name & ".gnat.sarif"; - - Switches_File_Name : constant String := "gnat_switches.json"; - - Diagnostics_File_Name : constant String := "gnat_diagnostics.json"; - - Dummy : Boolean; - begin - if Opt.SARIF_Output then - Set_Standard_Error; - - Print_SARIF_Report (All_Diagnostics); - - Set_Standard_Output; - elsif Opt.SARIF_File then - Delete_File (Sarif_File_Name, Dummy); - declare - Output_FD : constant File_Descriptor := - Create_New_File - (Sarif_File_Name, - Fmode => Text); - - begin - Set_Output (Output_FD); - - Print_SARIF_Report (All_Diagnostics); - - Set_Standard_Output; - - Close (Output_FD); - end; - else - Set_Standard_Error; - - while Has_Next (It) loop - Next (It, D); - - Print_Diagnostic (D); - end loop; - - Set_Standard_Output; - end if; - - if Debug_Flag_Underscore_EE then - - -- Print the switch repository to a file - - Delete_File (Switches_File_Name, Dummy); - declare - Output_FD : constant File_Descriptor := - Create_New_File - (Switches_File_Name, - Fmode => Text); - - begin - Set_Output (Output_FD); - - Print_Switch_Repository; - - Set_Standard_Output; - - Close (Output_FD); - end; - - -- Print the diagnostics repository to a file - - Delete_File (Diagnostics_File_Name, Dummy); - declare - Output_FD : constant File_Descriptor := - Create_New_File - (Diagnostics_File_Name, - Fmode => Text); - - begin - Set_Output (Output_FD); - - Print_Diagnostic_Repository; - - Set_Standard_Output; - - Close (Output_FD); - end; - end if; - - Destroy (All_Diagnostics); - end Emit_Diagnostics; - -end Diagnostics.Converter; diff --git a/gcc/ada/diagnostics-pretty_emitter.ads b/gcc/ada/diagnostics-pretty_emitter.ads deleted file mode 100644 index 2f5ba042aaa6..000000000000 --- a/gcc/ada/diagnostics-pretty_emitter.ads +++ /dev/null @@ -1,28 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- D I A G N O S T I C S . P R E T T Y _ E M I T T E R -- --- -- --- S p e c -- --- -- --- Copyright (C) 1992-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- --- for more details. You should have received a copy of the GNU General -- --- Public License distributed with GNAT; see file COPYING3. If not, go to -- --- http://www.gnu.org/licenses for a complete copy of the license. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - -package Diagnostics.Pretty_Emitter is - procedure Print_Diagnostic (Diag : Diagnostic_Type); -end Diagnostics.Pretty_Emitter; diff --git a/gcc/ada/diagnostics-sarif_emitter.ads b/gcc/ada/diagnostics-sarif_emitter.ads deleted file mode 100644 index 4c8ec785b4e6..000000000000 --- a/gcc/ada/diagnostics-sarif_emitter.ads +++ /dev/null @@ -1,29 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- D I A G N O S T I C S . S A R I F _ E M I T T E R -- --- -- --- S p e c -- --- -- --- Copyright (C) 1992-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- --- for more details. You should have received a copy of the GNU General -- --- Public License distributed with GNAT; see file COPYING3. If not, go to -- --- http://www.gnu.org/licenses for a complete copy of the license. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - -package Diagnostics.SARIF_Emitter is - - procedure Print_SARIF_Report (Diags : Diagnostic_List); -end Diagnostics.SARIF_Emitter; diff --git a/gcc/ada/diagnostics-switch_repository.ads b/gcc/ada/diagnostics-switch_repository.ads deleted file mode 100644 index afc4d1f879d6..000000000000 --- a/gcc/ada/diagnostics-switch_repository.ads +++ /dev/null @@ -1,39 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- D I A G N O S T I C S . D I A G N O S T I C S _ R E P O S I T O R Y -- --- -- --- S p e c -- --- -- --- Copyright (C) 1992-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- --- for more details. You should have received a copy of the GNU General -- --- Public License distributed with GNAT; see file COPYING3. If not, go to -- --- http://www.gnu.org/licenses for a complete copy of the license. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- -with Erroutc; use Erroutc; - -package Diagnostics.Switch_Repository is - - function Get_Switch (Id : Switch_Id) return Switch_Type; - - function Get_Switch (Diag : Diagnostic_Type) return Switch_Type; - - function Get_Switch_Id (E : Error_Msg_Object) return Switch_Id; - - function Get_Switch_Id (Name : String) return Switch_Id; - - procedure Print_Switch_Repository; - -end Diagnostics.Switch_Repository; diff --git a/gcc/ada/diagnostics-utils.adb b/gcc/ada/diagnostics-utils.adb deleted file mode 100644 index abde955f8e8e..000000000000 --- a/gcc/ada/diagnostics-utils.adb +++ /dev/null @@ -1,357 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- D I A G N O S T I C S . U T I L S -- --- -- --- B o d y -- --- -- --- Copyright (C) 1992-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- --- for more details. You should have received a copy of the GNU General -- --- Public License distributed with GNAT; see file COPYING3. If not, go to -- --- http://www.gnu.org/licenses for a complete copy of the license. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - -with Diagnostics.Repository; use Diagnostics.Repository; -with Diagnostics.Switch_Repository; use Diagnostics.Switch_Repository; -with Errout; use Errout; -with Erroutc; use Erroutc; -with Namet; use Namet; -with Opt; use Opt; -with Sinput; use Sinput; -with Sinfo.Nodes; use Sinfo.Nodes; -with Warnsw; use Warnsw; - -package body Diagnostics.Utils is - - ------------------ - -- Get_Human_Id -- - ------------------ - - function Get_Human_Id (D : Diagnostic_Type) return String_Ptr is - begin - if D.Switch = No_Switch_Id then - return Diagnostic_Entries (D.Id).Human_Id; - else - return Get_Switch (D).Human_Id; - end if; - end Get_Human_Id; - - ------------------ - -- To_File_Name -- - ------------------ - - function To_File_Name (Sptr : Source_Ptr) return String is - Sfile : constant Source_File_Index := Get_Source_File_Index (Sptr); - Ref_Name : constant File_Name_Type := - (if Full_Path_Name_For_Brief_Errors then Full_Ref_Name (Sfile) - else Reference_Name (Sfile)); - - begin - return Get_Name_String (Ref_Name); - end To_File_Name; - - -------------------- - -- Line_To_String -- - -------------------- - - function Line_To_String (Sptr : Source_Ptr) return String is - Line : constant Logical_Line_Number := Get_Logical_Line_Number (Sptr); - Img_Raw : constant String := Int'Image (Int (Line)); - - begin - return Img_Raw (Img_Raw'First + 1 .. Img_Raw'Last); - end Line_To_String; - - ---------------------- - -- Column_To_String -- - ---------------------- - - function Column_To_String (Sptr : Source_Ptr) return String is - Col : constant Column_Number := Get_Column_Number (Sptr); - Img_Raw : constant String := Int'Image (Int (Col)); - - begin - return - (if Col < 10 then "0" else "") - & Img_Raw (Img_Raw'First + 1 .. Img_Raw'Last); - end Column_To_String; - - --------------- - -- To_String -- - --------------- - - function To_String (Sptr : Source_Ptr) return String is - begin - return - To_File_Name (Sptr) & ":" & Line_To_String (Sptr) & ":" - & Column_To_String (Sptr); - end To_String; - - -------------------- - -- Sloc_To_String -- - -------------------- - - function Sloc_To_String - (N : Node_Or_Entity_Id; Ref : Source_Ptr) return String - is - - begin - return Sloc_To_String (Sloc (N), Ref); - end Sloc_To_String; - - -------------------- - -- Sloc_To_String -- - -------------------- - - function Sloc_To_String (Sptr : Source_Ptr; Ref : Source_Ptr) return String - is - - begin - if Sptr = No_Location then - return "at unknown location"; - - elsif Sptr = System_Location then - return "in package System"; - - elsif Sptr = Standard_Location then - return "in package Standard"; - - elsif Sptr = Standard_ASCII_Location then - return "in package Standard.ASCII"; - - else - if Full_File_Name (Get_Source_File_Index (Sptr)) - /= Full_File_Name (Get_Source_File_Index (Ref)) - then - return "at " & To_String (Sptr); - else - return "at line " & Line_To_String (Sptr); - end if; - end if; - end Sloc_To_String; - - ------------------ - -- To_Full_Span -- - ------------------ - - function To_Full_Span (N : Node_Id) return Source_Span - is - Fst, Lst : Node_Id; - begin - First_And_Last_Nodes (N, Fst, Lst); - return To_Span (Ptr => Sloc (N), - First => First_Sloc (Fst), - Last => Last_Sloc (Lst)); - end To_Full_Span; - - --------------- - -- To_String -- - --------------- - - function To_String (Id : Diagnostic_Id) return String is - begin - if Id = No_Diagnostic_Id then - return "GNAT0000"; - else - return Id'Img; - end if; - end To_String; - - ------------- - -- To_Name -- - ------------- - - function To_Name (E : Entity_Id) return String is - begin - -- The name of the node operator "&" has many special cases. Reuse the - -- node to name conversion implementation from the errout package for - -- now. - - Error_Msg_Node_1 := E; - Set_Msg_Text ("&", Sloc (E)); - - return Msg_Buffer (1 .. Msglen); - end To_Name; - - ------------------ - -- To_Type_Name -- - ------------------ - - function To_Type_Name (E : Entity_Id) return String is - begin - Error_Msg_Node_1 := E; - Set_Msg_Text ("}", Sloc (E)); - - return Msg_Buffer (1 .. Msglen); - end To_Type_Name; - - -------------------- - -- Kind_To_String -- - -------------------- - - function Kind_To_String - (D : Sub_Diagnostic_Type; - Parent : Diagnostic_Type) return String - is - (case D.Kind is - when Continuation => Kind_To_String (Parent), - when Help => "help", - when Note => "note", - when Suggestion => "suggestion"); - - -------------------- - -- Kind_To_String -- - -------------------- - - function Kind_To_String (D : Diagnostic_Type) return String is - (if D.Warn_Err then "error" - else - (case D.Kind is - when Diagnostics.Error | Non_Serious_Error => "error", - when Warning | Restriction_Warning | Default_Warning | - Tagless_Warning => "warning", - when Style => "style", - when Info => "info")); - - ------------------------------ - -- Get_Primary_Labeled_Span -- - ------------------------------ - - function Get_Primary_Labeled_Span (Spans : Labeled_Span_List) - return Labeled_Span_Type - is - use Labeled_Span_Lists; - - S : Labeled_Span_Type; - It : Iterator; - begin - if Present (Spans) then - It := Iterate (Spans); - while Has_Next (It) loop - Next (It, S); - if S.Is_Primary then - return S; - end if; - end loop; - end if; - - return No_Labeled_Span; - end Get_Primary_Labeled_Span; - - -------------------- - -- Get_Doc_Switch -- - -------------------- - - function Get_Doc_Switch (Diag : Diagnostic_Type) return String is - begin - if Warning_Doc_Switch - and then Diag.Kind in Default_Warning - | Info - | Restriction_Warning - | Style - | Warning - then - if Diag.Switch = No_Switch_Id then - if Diag.Kind = Restriction_Warning then - return "[restriction warning]"; - - -- Info messages can have a switch tag but they should not have - -- a default switch tag. - - elsif Diag.Kind /= Info then - - -- For Default_Warning - - return "[enabled by default]"; - end if; - else - declare - S : constant Switch_Type := Get_Switch (Diag); - begin - return "[-" & S.Short_Name.all & "]"; - end; - end if; - end if; - - return ""; - end Get_Doc_Switch; - - -------------------- - -- Appears_Before -- - -------------------- - - function Appears_Before (D1, D2 : Diagnostic_Type) return Boolean is - - begin - return Appears_Before (Primary_Location (D1).Span.Ptr, - Primary_Location (D2).Span.Ptr); - end Appears_Before; - - -------------------- - -- Appears_Before -- - -------------------- - - function Appears_Before (P1, P2 : Source_Ptr) return Boolean is - - begin - if Get_Source_File_Index (P1) = Get_Source_File_Index (P2) then - if Get_Logical_Line_Number (P1) = Get_Logical_Line_Number (P2) then - return Get_Column_Number (P1) < Get_Column_Number (P2); - else - return Get_Logical_Line_Number (P1) < Get_Logical_Line_Number (P2); - end if; - else - return Get_Source_File_Index (P1) < Get_Source_File_Index (P2); - end if; - end Appears_Before; - - ------------------------------ - -- Insert_Based_On_Location -- - ------------------------------ - - procedure Insert_Based_On_Location - (List : Diagnostic_List; - Diagnostic : Diagnostic_Type) - is - use Diagnostics_Lists; - - It : Iterator := Iterate (List); - D : Diagnostic_Type; - begin - -- This is the common scenario where the error is reported at the - -- natural order the tree is processed. This saves a lot of time when - -- looking for the correct position in the list when there are a lot of - -- diagnostics. - - if Present (List) and then - not Is_Empty (List) and then - Appears_Before (Last (List), Diagnostic) - then - Append (List, Diagnostic); - else - while Has_Next (It) loop - Next (It, D); - - if Appears_Before (Diagnostic, D) then - Insert_Before (List, D, Diagnostic); - return; - end if; - end loop; - - Append (List, Diagnostic); - end if; - end Insert_Based_On_Location; - -end Diagnostics.Utils; diff --git a/gcc/ada/diagnostics-utils.ads b/gcc/ada/diagnostics-utils.ads deleted file mode 100644 index 33cd67fc5385..000000000000 --- a/gcc/ada/diagnostics-utils.ads +++ /dev/null @@ -1,91 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- D I A G N O S T I C S . U T I L S -- --- -- --- S p e c -- --- -- --- Copyright (C) 1992-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- --- for more details. You should have received a copy of the GNU General -- --- Public License distributed with GNAT; see file COPYING3. If not, go to -- --- http://www.gnu.org/licenses for a complete copy of the license. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - -package Diagnostics.Utils is - - function Get_Human_Id (D : Diagnostic_Type) return String_Ptr; - - function Sloc_To_String (Sptr : Source_Ptr; Ref : Source_Ptr) return String; - -- Convert the source pointer to a string and prefix it with the correct - -- preposition. - -- - -- * If the location is in one of the standard locations, - -- then it yields "in package <LOCATION>". The explicit standard - -- locations are: - -- * System - -- * Standard - -- * Standard.ASCII - -- * if the location is missing the the sloc yields "at unknown location" - -- * if the location is in the same file as the current file, - -- then it yields "at line <line>". - -- * Otherwise sloc yields "at <file>:<line>:<column>" - - function Sloc_To_String (N : Node_Or_Entity_Id; - Ref : Source_Ptr) - return String; - -- Converts the Sloc of the node or entity to a Sloc string. - - function To_String (Sptr : Source_Ptr) return String; - -- Convert the source pointer to a string of the form: "file:line:column" - - function To_File_Name (Sptr : Source_Ptr) return String; - -- Converts the file name of the Sptr to a string. - - function Line_To_String (Sptr : Source_Ptr) return String; - -- Converts the logical line number of the Sptr to a string. - - function Column_To_String (Sptr : Source_Ptr) return String; - -- Converts the column number of the Sptr to a string. Column values less - -- than 10 are prefixed with a 0. - - function To_Full_Span (N : Node_Id) return Source_Span; - - function To_String (Id : Diagnostic_Id) return String; - -- Convert the diagnostic ID to a 4 character string padded with 0-s. - - function To_Name (E : Entity_Id) return String; - - function To_Type_Name (E : Entity_Id) return String; - - function Kind_To_String (D : Diagnostic_Type) return String; - - function Kind_To_String - (D : Sub_Diagnostic_Type; - Parent : Diagnostic_Type) return String; - - function Get_Primary_Labeled_Span (Spans : Labeled_Span_List) - return Labeled_Span_Type; - - function Get_Doc_Switch (Diag : Diagnostic_Type) return String; - - function Appears_Before (D1, D2 : Diagnostic_Type) return Boolean; - - function Appears_Before (P1, P2 : Source_Ptr) return Boolean; - - procedure Insert_Based_On_Location - (List : Diagnostic_List; - Diagnostic : Diagnostic_Type); - -end Diagnostics.Utils; diff --git a/gcc/ada/diagnostics.adb b/gcc/ada/diagnostics.adb deleted file mode 100644 index c98eda2264a9..000000000000 --- a/gcc/ada/diagnostics.adb +++ /dev/null @@ -1,539 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- D I A G N O S T I C S -- --- -- --- B o d y -- --- -- --- Copyright (C) 1992-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- --- for more details. You should have received a copy of the GNU General -- --- Public License distributed with GNAT; see file COPYING3. If not, go to -- --- http://www.gnu.org/licenses for a complete copy of the license. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - -with Atree; use Atree; -with Debug; use Debug; -with Diagnostics.Brief_Emitter; -with Diagnostics.Pretty_Emitter; -with Diagnostics.Repository; use Diagnostics.Repository; -with Diagnostics.Utils; use Diagnostics.Utils; -with Lib; use Lib; -with Opt; use Opt; -with Sinput; use Sinput; -with Warnsw; - -package body Diagnostics is - - ------------- - -- Destroy -- - ------------- - - procedure Destroy (Elem : in out Labeled_Span_Type) is - begin - Free (Elem.Label); - end Destroy; - - ------------- - -- Destroy -- - ------------- - - procedure Destroy (Elem : in out Sub_Diagnostic_Type) is - begin - Free (Elem.Message); - if Labeled_Span_Lists.Present (Elem.Locations) then - Labeled_Span_Lists.Destroy (Elem.Locations); - end if; - end Destroy; - - ------------- - -- Destroy -- - ------------- - - procedure Destroy (Elem : in out Edit_Type) is - begin - Free (Elem.Text); - end Destroy; - - ------------- - -- Destroy -- - ------------- - - procedure Destroy (Elem : in out Fix_Type) is - begin - Free (Elem.Description); - if Edit_Lists.Present (Elem.Edits) then - Edit_Lists.Destroy (Elem.Edits); - end if; - end Destroy; - - ------------- - -- Destroy -- - ------------- - - procedure Destroy (Elem : in out Diagnostic_Type) is - begin - Free (Elem.Message); - if Labeled_Span_Lists.Present (Elem.Locations) then - Labeled_Span_Lists.Destroy (Elem.Locations); - end if; - if Sub_Diagnostic_Lists.Present (Elem.Sub_Diagnostics) then - Sub_Diagnostic_Lists.Destroy (Elem.Sub_Diagnostics); - end if; - if Fix_Lists.Present (Elem.Fixes) then - Fix_Lists.Destroy (Elem.Fixes); - end if; - end Destroy; - - ------------------ - -- Add_Location -- - ------------------ - - procedure Add_Location - (Diagnostic : in out Sub_Diagnostic_Type; Location : Labeled_Span_Type) - is - use Labeled_Span_Lists; - begin - if not Present (Diagnostic.Locations) then - Diagnostic.Locations := Create; - end if; - - Append (Diagnostic.Locations, Location); - end Add_Location; - - ---------------------- - -- Primary_Location -- - ---------------------- - - function Primary_Location - (Diagnostic : Sub_Diagnostic_Type) return Labeled_Span_Type - is - begin - return Get_Primary_Labeled_Span (Diagnostic.Locations); - end Primary_Location; - - ------------------ - -- Add_Location -- - ------------------ - - procedure Add_Location - (Diagnostic : in out Diagnostic_Type; Location : Labeled_Span_Type) - is - use Labeled_Span_Lists; - begin - if not Present (Diagnostic.Locations) then - Diagnostic.Locations := Create; - end if; - - Append (Diagnostic.Locations, Location); - end Add_Location; - - ------------------------ - -- Add_Sub_Diagnostic -- - ------------------------ - - procedure Add_Sub_Diagnostic - (Diagnostic : in out Diagnostic_Type; - Sub_Diagnostic : Sub_Diagnostic_Type) - is - use Sub_Diagnostic_Lists; - begin - if not Present (Diagnostic.Sub_Diagnostics) then - Diagnostic.Sub_Diagnostics := Create; - end if; - - Append (Diagnostic.Sub_Diagnostics, Sub_Diagnostic); - end Add_Sub_Diagnostic; - - procedure Add_Edit (Fix : in out Fix_Type; Edit : Edit_Type) is - use Edit_Lists; - begin - if not Present (Fix.Edits) then - Fix.Edits := Create; - end if; - - Append (Fix.Edits, Edit); - end Add_Edit; - - ------------- - -- Add_Fix -- - ------------- - - procedure Add_Fix (Diagnostic : in out Diagnostic_Type; Fix : Fix_Type) is - use Fix_Lists; - begin - if not Present (Diagnostic.Fixes) then - Diagnostic.Fixes := Create; - end if; - - Append (Diagnostic.Fixes, Fix); - end Add_Fix; - - ----------------------- - -- Record_Diagnostic -- - ----------------------- - - procedure Record_Diagnostic (Diagnostic : Diagnostic_Type; - Update_Count : Boolean := True) - is - - procedure Update_Diagnostic_Count (Diagnostic : Diagnostic_Type); - - ----------------------------- - -- Update_Diagnostic_Count -- - ----------------------------- - - procedure Update_Diagnostic_Count (Diagnostic : Diagnostic_Type) is - - begin - case Diagnostic.Kind is - when Error => - Total_Errors_Detected := Total_Errors_Detected + 1; - Serious_Errors_Detected := Serious_Errors_Detected + 1; - - when Non_Serious_Error => - Total_Errors_Detected := Total_Errors_Detected + 1; - - when Warning - | Default_Warning - | Tagless_Warning - | Restriction_Warning - | Style - => - Warnings_Detected := Warnings_Detected + 1; - - if Diagnostic.Warn_Err then - Warnings_Treated_As_Errors := Warnings_Treated_As_Errors + 1; - end if; - - when Info => - Info_Messages := Info_Messages + 1; - end case; - end Update_Diagnostic_Count; - - procedure Handle_Serious_Error; - -- Internal procedure to do all error message handling for a serious - -- error message, other than bumping the error counts and arranging - -- for the message to be output. - - procedure Handle_Serious_Error is - begin - -- Turn off code generation if not done already - - if Operating_Mode = Generate_Code then - Operating_Mode := Check_Semantics; - Expander_Active := False; - end if; - - -- Set the fatal error flag in the unit table unless we are in - -- Try_Semantics mode (in which case we set ignored mode if not - -- currently set. This stops the semantics from being performed - -- if we find a serious error. This is skipped if we are currently - -- dealing with the configuration pragma file. - - if Current_Source_Unit /= No_Unit then - declare - U : constant Unit_Number_Type := - Get_Source_Unit - (Primary_Location (Diagnostic).Span.Ptr); - begin - if Try_Semantics then - if Fatal_Error (U) = None then - Set_Fatal_Error (U, Error_Ignored); - end if; - else - Set_Fatal_Error (U, Error_Detected); - end if; - end; - end if; - - -- Disable warnings on unused use clauses and the like. Otherwise, an - -- error might hide a reference to an entity in a used package, so - -- after fixing the error, the use clause no longer looks like it was - -- unused. - - Warnsw.Check_Unreferenced := False; - Warnsw.Check_Unreferenced_Formals := False; - end Handle_Serious_Error; - begin - Insert_Based_On_Location (All_Diagnostics, Diagnostic); - - if Update_Count then - Update_Diagnostic_Count (Diagnostic); - end if; - - if Diagnostic.Kind = Error then - Handle_Serious_Error; - end if; - end Record_Diagnostic; - - ---------------------- - -- Print_Diagnostic -- - ---------------------- - - procedure Print_Diagnostic (Diagnostic : Diagnostic_Type) is - - begin - if Debug_Flag_FF then - Diagnostics.Pretty_Emitter.Print_Diagnostic (Diagnostic); - else - Diagnostics.Brief_Emitter.Print_Diagnostic (Diagnostic); - end if; - end Print_Diagnostic; - - ---------------------- - -- Primary_Location -- - ---------------------- - - function Primary_Location - (Diagnostic : Diagnostic_Type) return Labeled_Span_Type - is - begin - return Get_Primary_Labeled_Span (Diagnostic.Locations); - end Primary_Location; - - --------------------- - -- Make_Diagnostic -- - --------------------- - - function Make_Diagnostic - (Msg : String; - Location : Labeled_Span_Type; - Id : Diagnostic_Id := No_Diagnostic_Id; - Kind : Diagnostic_Kind := Diagnostics.Error; - Switch : Switch_Id := No_Switch_Id; - Spans : Labeled_Span_Array := No_Locations; - Sub_Diags : Sub_Diagnostic_Array := No_Sub_Diags; - Fixes : Fix_Array := No_Fixes) - return Diagnostic_Type - is - D : Diagnostic_Type; - begin - D.Message := new String'(Msg); - D.Id := Id; - D.Kind := Kind; - - if Id /= No_Diagnostic_Id then - pragma Assert (Switch = Diagnostic_Entries (Id).Switch, - "Provided switch must be the same as in the registry"); - end if; - D.Switch := Switch; - - pragma Assert (Location.Is_Primary, "Main location must be primary"); - Add_Location (D, Location); - - for I in Spans'Range loop - Add_Location (D, Spans (I)); - end loop; - - for I in Sub_Diags'Range loop - Add_Sub_Diagnostic (D, Sub_Diags (I)); - end loop; - - for I in Fixes'Range loop - Add_Fix (D, Fixes (I)); - end loop; - - return D; - end Make_Diagnostic; - - ----------------------- - -- Record_Diagnostic -- - ----------------------- - - procedure Record_Diagnostic - (Msg : String; - Location : Labeled_Span_Type; - Id : Diagnostic_Id := No_Diagnostic_Id; - Kind : Diagnostic_Kind := Diagnostics.Error; - Switch : Switch_Id := No_Switch_Id; - Spans : Labeled_Span_Array := No_Locations; - Sub_Diags : Sub_Diagnostic_Array := No_Sub_Diags; - Fixes : Fix_Array := No_Fixes) - is - - begin - Record_Diagnostic - (Make_Diagnostic - (Msg => Msg, - Location => Location, - Id => Id, - Kind => Kind, - Switch => Switch, - Spans => Spans, - Sub_Diags => Sub_Diags, - Fixes => Fixes)); - end Record_Diagnostic; - - ------------------ - -- Labeled_Span -- - ------------------ - - function Labeled_Span (Span : Source_Span; - Label : String := ""; - Is_Primary : Boolean := True; - Is_Region : Boolean := False) - return Labeled_Span_Type - is - L : Labeled_Span_Type; - begin - L.Span := Span; - if Label /= "" then - L.Label := new String'(Label); - end if; - L.Is_Primary := Is_Primary; - L.Is_Region := Is_Region; - - return L; - end Labeled_Span; - - -------------------------- - -- Primary_Labeled_Span -- - -------------------------- - - function Primary_Labeled_Span (Span : Source_Span; - Label : String := "") - return Labeled_Span_Type - is begin - return Labeled_Span (Span => Span, Label => Label, Is_Primary => True); - end Primary_Labeled_Span; - - -------------------------- - -- Primary_Labeled_Span -- - -------------------------- - - function Primary_Labeled_Span (N : Node_Or_Entity_Id; - Label : String := "") - return Labeled_Span_Type - is - begin - return Primary_Labeled_Span (To_Full_Span (N), Label); - end Primary_Labeled_Span; - - ---------------------------- - -- Secondary_Labeled_Span -- - ---------------------------- - - function Secondary_Labeled_Span - (Span : Source_Span; - Label : String := "") - return Labeled_Span_Type - is - begin - return Labeled_Span (Span => Span, Label => Label, Is_Primary => False); - end Secondary_Labeled_Span; - - ---------------------------- - -- Secondary_Labeled_Span -- - ---------------------------- - - function Secondary_Labeled_Span (N : Node_Or_Entity_Id; - Label : String := "") - return Labeled_Span_Type - is - begin - return Secondary_Labeled_Span (To_Full_Span (N), Label); - end Secondary_Labeled_Span; - - -------------- - -- Sub_Diag -- - -------------- - - function Sub_Diag (Msg : String; - Kind : Sub_Diagnostic_Kind := - Diagnostics.Continuation; - Locations : Labeled_Span_Array := No_Locations) - return Sub_Diagnostic_Type - is - S : Sub_Diagnostic_Type; - begin - S.Message := new String'(Msg); - S.Kind := Kind; - - for I in Locations'Range loop - Add_Location (S, Locations (I)); - end loop; - - return S; - end Sub_Diag; - - ------------------ - -- Continuation -- - ------------------ - - function Continuation (Msg : String; - Locations : Labeled_Span_Array := No_Locations) - return Sub_Diagnostic_Type - is - begin - return Sub_Diag (Msg, Diagnostics.Continuation, Locations); - end Continuation; - - ---------- - -- Help -- - ---------- - - function Help (Msg : String; - Locations : Labeled_Span_Array := No_Locations) - return Sub_Diagnostic_Type - is - begin - return Sub_Diag (Msg, Diagnostics.Help, Locations); - end Help; - - ---------------- - -- Suggestion -- - ---------------- - - function Suggestion (Msg : String; - Locations : Labeled_Span_Array := No_Locations) - return Sub_Diagnostic_Type - is - begin - return Sub_Diag (Msg, Diagnostics.Suggestion, Locations); - end Suggestion; - - --------- - -- Fix -- - --------- - - function Fix - (Description : String; - Edits : Edit_Array; - Applicability : Applicability_Type := Unspecified) return Fix_Type - is - F : Fix_Type; - begin - F.Description := new String'(Description); - - for I in Edits'Range loop - Add_Edit (F, Edits (I)); - end loop; - - F.Applicability := Applicability; - - return F; - end Fix; - - ---------- - -- Edit -- - ---------- - - function Edit (Text : String; Span : Source_Span) return Edit_Type is - - begin - return (Text => new String'(Text), Span => Span); - end Edit; - -end Diagnostics; diff --git a/gcc/ada/diagnostics.ads b/gcc/ada/diagnostics.ads deleted file mode 100644 index 67a8c20bd676..000000000000 --- a/gcc/ada/diagnostics.ads +++ /dev/null @@ -1,477 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- D I A G N O S T I C S -- --- -- --- S p e c -- --- -- --- Copyright (C) 1992-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- --- for more details. You should have received a copy of the GNU General -- --- Public License distributed with GNAT; see file COPYING3. If not, go to -- --- http://www.gnu.org/licenses for a complete copy of the license. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - -with Types; use Types; -with GNAT.Lists; use GNAT.Lists; - -package Diagnostics is - - type Diagnostic_Id is - (No_Diagnostic_Id, - GNAT0001, - GNAT0002, - GNAT0003, - GNAT0004, - GNAT0005, - GNAT0006, - GNAT0007, - GNAT0008, - GNAT0009, - GNAT0010, - GNAT0011); - - -- Labeled_Span_Type represents a span of source code that is associated - -- with a textual label. Primary spans indicate the primary location of the - -- diagnostic. Non-primary spans are used to indicate secondary locations. - -- - -- Spans can contain labels that are used to annotate the highlighted span. - -- Usually, the label is a short and concise message that provide - -- additional allthough non-critical information about the span. This is - -- an important since labels are not printed in the brief output and are - -- only present in the pretty and structural outputs. That is an important - -- distintion when choosing between a label and a sub-diagnostic. - type Labeled_Span_Type is record - Label : String_Ptr := null; - -- Text associated with the span - - Span : Source_Span := (others => No_Location); - -- Textual region in the source code - - Is_Primary : Boolean := True; - -- Primary spans are used to indicate the primary location of the - -- diagnostic. Typically there should just be one primary span per - -- diagnostic. - -- Non-primary spans are used to indicate secondary locations and - -- typically are formatted in a different way or omitted in some - -- contexts. - - Is_Region : Boolean := False; - -- Regional spans are multiline spans that have a unique way of being - -- displayed in the pretty output. - end record; - - No_Labeled_Span : constant Labeled_Span_Type := (others => <>); - - procedure Destroy (Elem : in out Labeled_Span_Type); - pragma Inline (Destroy); - - package Labeled_Span_Lists is new Doubly_Linked_Lists - (Element_Type => Labeled_Span_Type, - "=" => "=", - Destroy_Element => Destroy, - Check_Tampering => False); - subtype Labeled_Span_List is Labeled_Span_Lists.Doubly_Linked_List; - - type Sub_Diagnostic_Kind is - (Continuation, - Help, - Note, - Suggestion); - - -- Sub_Diagnostic_Type represents a sub-diagnostic message that is meant - -- to provide additional information about the primary diagnostic message. - -- - -- Sub-diagnostics are usually constructed with a full sentence as the - -- message and provide important context to the main diagnostic message or - -- some concrete action to the user. - -- - -- This is different from the labels of labeled spans which are meant to be - -- short and concise and are mostly there to annotate the higlighted span. - - type Sub_Diagnostic_Type is record - Kind : Sub_Diagnostic_Kind; - - Message : String_Ptr; - - Locations : Labeled_Span_List; - end record; - - procedure Add_Location - (Diagnostic : in out Sub_Diagnostic_Type; Location : Labeled_Span_Type); - - function Primary_Location - (Diagnostic : Sub_Diagnostic_Type) return Labeled_Span_Type; - - procedure Destroy (Elem : in out Sub_Diagnostic_Type); - pragma Inline (Destroy); - - package Sub_Diagnostic_Lists is new Doubly_Linked_Lists - (Element_Type => Sub_Diagnostic_Type, - "=" => "=", - Destroy_Element => Destroy, - Check_Tampering => False); - - subtype Sub_Diagnostic_List is Sub_Diagnostic_Lists.Doubly_Linked_List; - - -- An Edit_Type represents a textual edit that is associated with a Fix. - type Edit_Type is record - Span : Source_Span; - -- Region of the file to be removed - - Text : String_Ptr; - -- Text to be inserted at the start location of the span - end record; - - procedure Destroy (Elem : in out Edit_Type); - pragma Inline (Destroy); - - package Edit_Lists is new Doubly_Linked_Lists - (Element_Type => Edit_Type, - "=" => "=", - Destroy_Element => Destroy, - Check_Tampering => False); - - subtype Edit_List is Edit_Lists.Doubly_Linked_List; - - -- Type Applicability_Type will indicate the state of the resulting code - -- after applying a fix. - -- * Option Has_Placeholders indicates that the fix contains placeholders - -- that the user would need to fill. - -- * Option Legal indicates that applying the fix will result in legal Ada - -- code. - -- * Option Possibly_Illegal indicates that applying the fix will result in - -- possibly legal, but also possibly illegal Ada code. - type Applicability_Type is - (Has_Placeholders, - Legal, - Possibly_Illegal, - Unspecified); - - type Fix_Type is record - Description : String_Ptr := null; - -- Message describing the fix that will be displayed to the user. - - Applicability : Applicability_Type := Unspecified; - - Edits : Edit_List; - -- File changes for the fix. - end record; - - procedure Destroy (Elem : in out Fix_Type); - pragma Inline (Destroy); - - package Fix_Lists is new Doubly_Linked_Lists - (Element_Type => Fix_Type, - "=" => "=", - Destroy_Element => Destroy, - Check_Tampering => False); - - subtype Fix_List is Fix_Lists.Doubly_Linked_List; - - procedure Add_Edit (Fix : in out Fix_Type; Edit : Edit_Type); - - type Status_Type is - (Active, - Deprecated); - - type Switch_Id is ( - No_Switch_Id, - gnatwb, - gnatwc, - gnatwd, - gnatwf, - gnatwg, - gnatwh, - gnatwi, - gnatwj, - gnatwk, - gnatwl, - gnatwm, - gnatwo, - gnatwp, - gnatwq, - gnatwr, - gnatwt, - gnatwu, - gnatwv, - gnatww, - gnatwx, - gnatwy, - gnatwz, - gnatw_dot_a, - gnatw_dot_b, - gnatw_dot_c, - gnatw_dot_f, - gnatw_dot_h, - gnatw_dot_i, - gnatw_dot_j, - gnatw_dot_k, - gnatw_dot_l, - gnatw_dot_m, - gnatw_dot_n, - gnatw_dot_o, - gnatw_dot_p, - gnatw_dot_q, - gnatw_dot_r, - gnatw_dot_s, - gnatw_dot_t, - gnatw_dot_u, - gnatw_dot_v, - gnatw_dot_w, - gnatw_dot_x, - gnatw_dot_y, - gnatw_dot_z, - gnatw_underscore_a, - gnatw_underscore_c, - gnatw_underscore_j, - gnatw_underscore_l, - gnatw_underscore_p, - gnatw_underscore_q, - gnatw_underscore_r, - gnatw_underscore_s, - gnaty, - gnatya, - gnatyb, - gnatyc, - gnatyd, - gnatye, - gnatyf, - gnatyh, - gnatyi, - gnatyk, - gnatyl, - gnatym, - gnatyn, - gnatyo, - gnatyp, - gnatyr, - gnatys, - gnatyu, - gnatyx, - gnatyz, - gnatyaa, - gnatybb, - gnatycc, - gnatydd, - gnatyii, - gnatyll, - gnatymm, - gnatyoo, - gnatyss, - gnatytt, - gnatel - ); - - subtype Active_Switch_Id is Switch_Id range gnatwb .. gnatel; - -- The range of switch ids that represent switches that trigger a specific - -- diagnostic check. - - type Switch_Type is record - - Status : Status_Type := Active; - -- The status will indicate whether the switch is currently active, - -- or has been deprecated. A deprecated switch will not control - -- diagnostics, and will not be emitted by the GNAT usage. - - Human_Id : String_Ptr := null; - -- The Human_Id will be a unique and stable string-based ID which - -- identifies the content of the switch within the switch registry. - -- This ID will appear in SARIF readers. - - Short_Name : String_Ptr := null; - -- The Short_Name will denote the -gnatXX name of the switch. - - Description : String_Ptr := null; - -- The description will contain the description of the switch, as it is - -- currently emitted by the GNAT usage. - - Documentation_Url : String_Ptr := null; - -- The documentation_url will point to the AdaCore documentation site - -- for the switch. - - end record; - - type Diagnostic_Kind is - (Error, - Non_Serious_Error, - -- Typically all errors are considered serious and the compiler should - -- stop its processing since the tree is essentially invalid. However, - -- some errors are not serious and the compiler can continue its - -- processing to discover more critical errors. - Warning, - Default_Warning, - -- Warning representing the old warnings created with the '??' insertion - -- character. These warning have the [enabled by default] tag. - Restriction_Warning, - -- Warning representing the old warnings created with the '?*?' - -- insertion character. These warning have the [restriction warning] - -- tag. - Style, - Tagless_Warning, - -- Warning representing the old warnings created with the '?' insertion - -- character. - Info - ); - - type Diagnostic_Entry_Type is record - Status : Status_Type := Active; - - Human_Id : String_Ptr := null; - -- A human readable code for the diagnostic. If the diagnostic has a - -- switch with a human id then the human_id of the switch shall be used - -- in SARIF reports. - - Documentation : String_Ptr := null; - - Switch : Switch_Id := No_Switch_Id; - -- The switch that controls the diagnostic message. - end record; - - type Diagnostic_Type is record - - Id : Diagnostic_Id := No_Diagnostic_Id; - - Kind : Diagnostic_Kind := Error; - - Switch : Switch_Id := No_Switch_Id; - - Message : String_Ptr := null; - - Warn_Err : Boolean := False; - -- Signal whether the diagnostic was converted from a warning to an - -- error. This needs to be set during the message emission as this - -- behavior depends on the context of the code. - - Locations : Labeled_Span_List := Labeled_Span_Lists.Nil; - - Sub_Diagnostics : Sub_Diagnostic_List := Sub_Diagnostic_Lists.Nil; - - Fixes : Fix_List := Fix_Lists.Nil; - end record; - - procedure Destroy (Elem : in out Diagnostic_Type); - pragma Inline (Destroy); - - package Diagnostics_Lists is new Doubly_Linked_Lists - (Element_Type => Diagnostic_Type, - "=" => "=", - Destroy_Element => Destroy, - Check_Tampering => False); - - subtype Diagnostic_List is Diagnostics_Lists.Doubly_Linked_List; - - All_Diagnostics : Diagnostic_List := Diagnostics_Lists.Create; - - procedure Add_Location - (Diagnostic : in out Diagnostic_Type; Location : Labeled_Span_Type); - - procedure Add_Sub_Diagnostic - (Diagnostic : in out Diagnostic_Type; - Sub_Diagnostic : Sub_Diagnostic_Type); - - procedure Add_Fix (Diagnostic : in out Diagnostic_Type; Fix : Fix_Type); - - procedure Record_Diagnostic (Diagnostic : Diagnostic_Type; - Update_Count : Boolean := True); - - procedure Print_Diagnostic (Diagnostic : Diagnostic_Type); - - function Primary_Location - (Diagnostic : Diagnostic_Type) return Labeled_Span_Type; - - type Labeled_Span_Array is - array (Positive range <>) of Labeled_Span_Type; - type Sub_Diagnostic_Array is - array (Positive range <>) of Sub_Diagnostic_Type; - type Fix_Array is - array (Positive range <>) of Fix_Type; - type Edit_Array is - array (Positive range <>) of Edit_Type; - - No_Locations : constant Labeled_Span_Array (1 .. 0) := (others => <>); - No_Sub_Diags : constant Sub_Diagnostic_Array (1 .. 0) := (others => <>); - No_Fixes : constant Fix_Array (1 .. 0) := (others => <>); - No_Edits : constant Edit_Array (1 .. 0) := (others => <>); - - function Make_Diagnostic - (Msg : String; - Location : Labeled_Span_Type; - Id : Diagnostic_Id := No_Diagnostic_Id; - Kind : Diagnostic_Kind := Diagnostics.Error; - Switch : Switch_Id := No_Switch_Id; - Spans : Labeled_Span_Array := No_Locations; - Sub_Diags : Sub_Diagnostic_Array := No_Sub_Diags; - Fixes : Fix_Array := No_Fixes) - return Diagnostic_Type; - - procedure Record_Diagnostic - (Msg : String; - Location : Labeled_Span_Type; - Id : Diagnostic_Id := No_Diagnostic_Id; - Kind : Diagnostic_Kind := Diagnostics.Error; - Switch : Switch_Id := No_Switch_Id; - Spans : Labeled_Span_Array := No_Locations; - Sub_Diags : Sub_Diagnostic_Array := No_Sub_Diags; - Fixes : Fix_Array := No_Fixes); - - function Labeled_Span (Span : Source_Span; - Label : String := ""; - Is_Primary : Boolean := True; - Is_Region : Boolean := False) - return Labeled_Span_Type; - - function Primary_Labeled_Span (Span : Source_Span; - Label : String := "") - return Labeled_Span_Type; - - function Primary_Labeled_Span (N : Node_Or_Entity_Id; - Label : String := "") - return Labeled_Span_Type; - - function Secondary_Labeled_Span (Span : Source_Span; - Label : String := "") - return Labeled_Span_Type; - - function Secondary_Labeled_Span (N : Node_Or_Entity_Id; - Label : String := "") - return Labeled_Span_Type; - - function Sub_Diag (Msg : String; - Kind : Sub_Diagnostic_Kind := - Diagnostics.Continuation; - Locations : Labeled_Span_Array := No_Locations) - return Sub_Diagnostic_Type; - - function Continuation (Msg : String; - Locations : Labeled_Span_Array := No_Locations) - return Sub_Diagnostic_Type; - - function Help (Msg : String; - Locations : Labeled_Span_Array := No_Locations) - return Sub_Diagnostic_Type; - - function Suggestion (Msg : String; - Locations : Labeled_Span_Array := No_Locations) - return Sub_Diagnostic_Type; - - function Fix (Description : String; - Edits : Edit_Array; - Applicability : Applicability_Type := Unspecified) - return Fix_Type; - - function Edit (Text : String; - Span : Source_Span) - return Edit_Type; -end Diagnostics; diff --git a/gcc/ada/doc/gnat_rm.rst b/gcc/ada/doc/gnat_rm.rst index e52f2a636d98..27551caf36a4 100644 --- a/gcc/ada/doc/gnat_rm.rst +++ b/gcc/ada/doc/gnat_rm.rst @@ -54,7 +54,7 @@ GNAT Reference Manual gnat_rm/interfacing_to_other_languages gnat_rm/specialized_needs_annexes gnat_rm/implementation_of_specific_ada_features - gnat_rm/implementation_of_ada_2012_features + gnat_rm/implementation_of_ada_2022_features gnat_rm/gnat_language_extensions gnat_rm/security_hardening_features gnat_rm/obsolescent_features diff --git a/gcc/ada/doc/gnat_rm/about_this_guide.rst b/gcc/ada/doc/gnat_rm/about_this_guide.rst index 9defee818aca..ff72194383ac 100644 --- a/gcc/ada/doc/gnat_rm/about_this_guide.rst +++ b/gcc/ada/doc/gnat_rm/about_this_guide.rst @@ -14,7 +14,7 @@ GNAT compiler. It includes information on implementation dependent characteristics of GNAT, including all the information required by Annex M of the Ada language standard. -GNAT implements Ada 95, Ada 2005 and Ada 2012, and it may also be +GNAT implements Ada 95, Ada 2005, Ada 2012 and Ada 2022, and it may also be invoked in Ada 83 compatibility mode. By default, GNAT assumes Ada 2012, but you can override with a compiler switch @@ -93,8 +93,8 @@ This reference manual contains the following chapters: to GNAT's implementation of machine code insertions, tasking, and several other features. -* :ref:`Implementation_of_Ada_2012_Features`, describes the status of the - GNAT implementation of the Ada 2012 language standard. +* :ref:`Implementation_of_Ada_2022_Features`, describes the status of the + GNAT implementation of the Ada 2022 language standard. * :ref:`Security_Hardening_Features` documents GNAT extensions aimed at security hardening. diff --git a/gcc/ada/doc/gnat_rm/compatibility_and_porting_guide.rst b/gcc/ada/doc/gnat_rm/compatibility_and_porting_guide.rst index 5a20995ca084..3da2b325410c 100644 --- a/gcc/ada/doc/gnat_rm/compatibility_and_porting_guide.rst +++ b/gcc/ada/doc/gnat_rm/compatibility_and_porting_guide.rst @@ -134,9 +134,9 @@ types will be portable. Compatibility with Ada 83 ========================= -.. index:: Compatibility (between Ada 83 and Ada 95 / Ada 2005 / Ada 2012) +.. index:: Compatibility (between Ada 83 and Ada 95 / Ada 2005 / Ada 2012 / Ada 2022) -Ada 95 and the subsequent revisions Ada 2005 and Ada 2012 +Ada 95 and the subsequent revisions Ada 2005, Ada 2012, Ada 2022 are highly upwards compatible with Ada 83. In particular, the design intention was that the difficulties associated with moving from Ada 83 to later versions of the standard should be no greater @@ -505,7 +505,7 @@ such an Ada 83 application is being ported to different target hardware (for example where the byte endianness has changed) then you will need to carefully examine the program logic; the porting effort will heavily depend on the robustness of the original design. Moreover, Ada 95 (and thus -Ada 2005 and Ada 2012) are sometimes +Ada 2005, Ada 2012, and Ada 2022) are sometimes incompatible with typical Ada 83 compiler practices regarding implicit packing, the meaning of the Size attribute, and the size of access values. GNAT's approach to these issues is described in :ref:`Representation_Clauses`. diff --git a/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst b/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst index ee2df668eb1d..ff111ddd3a12 100644 --- a/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst +++ b/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst @@ -657,6 +657,22 @@ An exception message can also be added: when Imported_C_Func /= 0; end; +Implicit With +------------- + +This feature allows a standalone ``use`` clause in the context clause of a +compilation unit to imply an implicit ``with`` of the same library unit where +an equivalent ``with`` clause would be allowed. + +.. code-block:: ada + + use Ada.Text_IO; + procedure Main is + begin + Put_Line ("Hello"); + end; + + Storage Model ------------- @@ -1334,113 +1350,150 @@ case statement with composite selector type". Mutably Tagged Types with Size'Class Aspect ------------------------------------------- -The ``Size'Class`` aspect can be applied to a tagged type to specify a size -constraint for the type and its descendants. When this aspect is specified -on a tagged type, the class-wide type of that type is considered to be a -"mutably tagged" type - meaning that objects of the class-wide type can have -their tag changed by assignment from objects with a different tag. +For a specific tagged nonformal type T that satisfies some conditions +described later in this section, the universal-integer-valued type-related +representation aspect ``Size'Class`` may be specified; any such specified +aspect value shall be static. -Example: +Specifying this aspect imposes an upper bound on the sizes of all specific +descendants of T (including T itself). T'Class (but not T) is then said to be +a "mutably tagged" type - meaning that T'Class is a definite subtype and that +the tag of a variable of type T'Class may be modified by assignment in some +cases described later in this section. An inherited ``Size'Class`` aspect +value may be overridden, but not with a larger value. -.. code-block:: ada +If the ``Size'Class`` aspect is specified for a type T, then every specific +descendant of T (including T itself) - type Base is tagged null record - with Size'Class => 16 * 8; -- Size in bits (128 bits, or 16 bytes) +* shall have a Size that does not exceed the specified value; and - type Derived_Type is new Base with record - Data_Field : Integer; - end record; -- ERROR if Derived_Type exceeds 16 bytes +* shall have a (possibly inherited) ``Size'Class`` aspect that does not exceed + the specifed value; and + +* shall be undiscriminated; and + +* shall have no composite subcomponent whose subtype is subject to a nonstatic + constraint; and + +* shall not have a tagged partial view other than a private extension; and + +* shall not be a descendant of an interface type; and + +* shall not have a statically deeper accessibility level than that of T. -Class-wide types with a specified ``Size'Class`` can be used as the type of -array components, record components, and stand-alone objects. +If the ``Size'Class`` aspect is not specified for a type T (either explicitly +or by inheritance), then it shall not be specified for any descendant of T. + +Example: .. code-block:: ada - Inst : Base'Class; - type Array_of_Base is array (Positive range <>) of Base'Class; + type Root_Type is tagged null record with Size'Class => 16 * 8; -If the ``Size'Class`` aspect is specified for a type ``T``, then every -specific descendant of ``T`` [redundant: (including ``T``)] + type Derived_Type is new Root_Type with record + Stuff : Some_Type; + end record; -- ERROR if Derived_Type exceeds 16 bytes -- shall have a Size that does not exceed the specified value; and +Because any subtype of a mutably tagged type is definite, it can be used as a +component subtype for enclosing array or record types, as the subtype of a +default-initialized stand-alone object, or as the subtype of an uninitialized +allocator, as in this example: + +.. code-block:: ada -- shall be undiscriminated; and + Obj : Root_Type'Class; + type Array_of_Roots is array (Positive range <>) of Root_Type'Class; -- shall have no composite subcomponent whose subtype is subject to a - dynamic constraint; and +Default initialization of an object of such a definite subtype proceeds as +for the corresponding specific type, except that Program_Error is raised if +the specific type is abstract. In particular, the initial tag of the object +is that of the corresponding specific type. -- shall have no interface progenitors; and +There is a general design principle that if a type has a tagged partial view, +then the type's ``Size'Class`` aspect (or lack thereof) should be determinable +by looking only at the partial view. That provides the motivation for the +rules of the next two paragraphs. -- shall not have a tagged partial view other than a private extension; and +If a type has a tagged partial view, then a ``Size'Class`` aspect specification +may be provided only at the point of the partial view declaration (in other +words, no such aspect specification may be provided when the full view of +the type is declared). All of the above rules (in particular, the rule that +an overriding ``Size'Class`` aspect value shall not be larger than the +overridden inherited value) are also enforced when the full view (which may +have a different ancestor type than that of the partial view) is declared. +If a partial view for a type inherits a ``Size'Class`` aspect value and does +not override that value with an explicit aspect specification, then the +(static) aspect values inherited by the partial view and by the full view +shall be equal. -- shall not have a statically deeper accessibility level than that of ``T``. +An actual parameter of an instantiation whose corresponding formal parameter +is a formal tagged private type shall not be either mutably tagged or the +corresponding specific type of a mutably tagged type. -In addition to the places where Legality Rules normally apply (see 12.3), -these legality rules apply also in the private part and in the body of an -instance of a generic unit. +For the legality rules in this section, the RM 12.3(11) rule about legality +checking in the visible part and formal part of an instance is extended (in +the same way that it is extended in many other places in the RM) to include +the private part of an instance. -For any subtype ``S`` that is a subtype of a descendant of ``T``, ``S'Class'Size`` is -defined to yield the specified value [redundant:, although ``S'Class'Size`` is -not a static expression]. +An object (or a view thereof) of a tagged type is defined to be +"tag-constrained" if it is -A class-wide descendant of a type with a specified ``Size'Class`` aspect is -defined to be a "mutably tagged" type. Any subtype of a mutably tagged type is, -by definition, a definite subtype (RM 3.3 notwithstanding). Default -initialization of an object of such a definite subtype proceeds as for the -corresponding specific type, except that ``Program_Error`` is raised if the -specific type is abstract. [In particular, the initial tag of the object is -that of the corresponding specific type.] +* an object whose type is not mutably tagged; or -An object of a tagged type is defined to be "tag-constrained" if it is +* a constant object; or -- an object whose type is not mutably tagged; or +* a view conversion of a tag-constrained object; or -- a constant object; or +* a view conversion to a type that is not a descendant of the operand's + type; or -- a view conversion of a tag-constrained object; or +* a formal in out or out parameter whose corresponding actual parameter is + tag-constrained; or -- a formal ``in out`` or ``out`` parameter whose corresponding - actual parameter is tag-constrained. +* a dereference of an access value. -In the case of an assignment to a tagged variable that -is not tag-constrained, no check is performed that the tag of the value of -the expression is the same as that of the target (RM 5.2 notwithstanding). +In the case of an assignment to a tagged variable that is not +tag-constrained, no check is performed that the tag of the value +of the expression is the same as that of the target (RM 5.2 notwithstanding). Instead, the tag of the target object becomes that of the source object of -the assignment. +the assignment. Note that the tag of an object of a mutably tagged type MT +will always be the tag of some specific type that is a descendant of MT. An assignment to a composite object similarly copies the tags of any -subcomponents of the source object that have a mutably-tagged type. - -The ``Constrained`` attribute is defined for any name denoting an object of a -mutably tagged type (RM 3.7.2 notwithstanding). In this case, the Constrained -attribute yields the value True if the object is tag-constrained and False -otherwise. - -Renaming is not allowed (see 8.5.1) for a type conversion having an operand of -a mutably tagged type ``MT`` and a target type ``TT`` such that ``TT'Class`` -does not cover ``MT``, nor for any part of such an object, nor for any slice -of such an object. This rule also applies in any context where a name is -required to be one for which "renaming is allowed" (for example, see RM 12.4). - -A name denoting a view of a variable of a mutably tagged type shall not -occur as an operative constituent of the prefix of a name denoting a -prefixed view of a callable entity, except as the callee name in a call to -the callable entity. - -For a type conversion between two general access types, either both or neither -of the designated types shall be mutably tagged. For an ``Access`` (or -``Unchecked_Access``) attribute reference, the designated type of the type of the -attribute reference and the type of the prefix of the attribute shall either -both or neither be mutably tagged. +subcomponents of the source object that have a mutably tagged type. + +The Constrained attribute is defined for any name denoting an object of a +mutably tagged type (RM 3.7.2 notwithstanding). In this case, the +Constrained attribute yields the value True if the object is +tag-constrained and False otherwise. + +Renaming is not allowed (see RM 8.5.1) for a type conversion having an operand +of a mutably tagged type MT and a target type TT such that TT (or its +corresponding specific type if TT is class-wide) is not an ancestor of MT +(this is sometimes called a "downward" conversion), nor for any part of +such an object, nor for any slice of any part of such an object. This +rule also applies in any context where a name is required to be one for +which "renaming is allowed" (for example, see RM 12.4). +[This is analogous to the way that renaming is not allowed for a +discriminant-dependent component of an unconstrained variable.] + +A name denoting a view of a variable of a mutably tagged type shall not occur +as an operative constituent of the prefix of a name denoting a prefixed +view of a callable entity, except as the callee name in a call to the +callable entity. This disallows, for example, renaming such a prefixed view, +passing the prefixed view name as a generic actual parameter, or using the +prefixed view name as the prefix of an attribute. The execution of a construct is erroneous if the construct has a constituent that is a name denoting a subcomponent of a tagged object and the object's -tag is changed by this execution between evaluating the name and the last use -(within this execution) of the subcomponent denoted by the name. +tag is changed by this execution between evaluating the name and the last +use (within this execution) of the subcomponent denoted by the name. +This is analogous to the RM 3.7.2(4) rule about discriminant-dependent +subcomponents. -If the type of a formal parameter is a specific tagged type then the execution +If the type of a formal parameter is a specific tagged type, then the execution of the call is erroneous if the tag of the actual is changed while the formal -parameter exists (that is, before leaving the corresponding callable -construct). +parameter exists (that is, before leaving the corresponding callable construct). +This is analogous to the RM 6.4.1(18) rule about discriminated parameters. Generalized Finalization ------------------------ @@ -1453,97 +1506,60 @@ that the record type must be a root type, in other words not a derived type. The aspect additionally makes it possible to specify relaxed semantics for the finalization operations by means of the ``Relaxed_Finalization`` setting. - -Example: +Here is the archetypal example: .. code-block:: ada - type Ctrl is record - Id : Natural := 0; + type T is record + ... end record with Finalizable => (Initialize => Initialize, Adjust => Adjust, Finalize => Finalize, Relaxed_Finalization => True); - procedure Adjust (Obj : in out Ctrl); - procedure Finalize (Obj : in out Ctrl); - procedure Initialize (Obj : in out Ctrl); + procedure Adjust (Obj : in out T); + procedure Finalize (Obj : in out T); + procedure Initialize (Obj : in out T); -The three procedures have the same profile, taking a single ``in out T`` -parameter. - -We follow the same dynamic semantics as controlled objects: +The three procedures have the same profile, with a single ``in out`` parameter, +and also have the same dynamic semantics as for controlled types: - ``Initialize`` is called when an object of type ``T`` is declared without - default expression. + initialization expression. - ``Adjust`` is called after an object of type ``T`` is assigned a new value. - ``Finalize`` is called when an object of type ``T`` goes out of scope (for - stack-allocated objects) or is explicitly deallocated (for heap-allocated - objects). It is also called when on the value being replaced in an - assignment. - -However the following differences are enforced by default when compared to the -current Ada controlled-objects finalization model: - -* No automatic finalization of heap allocated objects: ``Finalize`` is only - called when an object is implicitly deallocated. As a consequence, no-runtime - support is needed for the implicit case, and no header will be maintained for - this in heap-allocated controlled objects. + stack-allocated objects) or is deallocated (for heap-allocated objects). + It is also called when the value is replaced by an assignment. - Heap-allocated objects allocated through a nested access type definition will - hence **not** be deallocated either. The result is simply that memory will be - leaked in those cases. +However, when ``Relaxed_Finalization`` is either ``True`` or not explicitly +specified, the following differences are implemented relative to the semantics +of controlled types: -* The ``Finalize`` procedure should have have the :ref:`No_Raise_Aspect` specified. - If that's not the case, a compilation error will be raised. +* The compiler has permission to perform no automatic finalization of + heap-allocated objects: ``Finalize`` is only called when such an object + is explicitly deallocated, or when the designated object is assigned a new + value. As a consequence, no runtime support is needed for performing + implicit deallocation. In particular, no per-object header data is needed + for heap-allocated objects. -Additionally, two other configuration aspects are added, -``Legacy_Heap_Finalization`` and ``Exceptions_In_Finalize``: + Heap-allocated objects allocated through a nested access type will therefore + **not** be deallocated either. The result is simply that memory will be leaked + in this case. -* ``Legacy_Heap_Finalization``: Uses the legacy automatic finalization of - heap-allocated objects - -* ``Exceptions_In_Finalize``: Allow users to have a finalizer that raises exceptions - **NB!** note that using this aspect introduces execution time penalities. - -.. _No_Raise_Aspect: - -No_Raise aspect ----------------- +* The ``Adjust`` and ``Finalize`` procedures are automatically considered as + having the :ref:`No_Raise_Aspect` specified for them. In particular, the + compiler has permission to enforce none of the guarantees specified by the + RM 7.6.1 (14/1) and subsequent subclauses. -The ``No_Raise`` aspect can be applied to a subprogram to declare that this subprogram is not -expected to raise any exceptions. Should an exception still occur during the execution of -this subprogram, ``Program_Error`` is raised. - -New specification for ``Ada.Finalization.Controlled`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -``Ada.Finalization.Controlled`` is now specified as: - -.. code-block:: ada - - type Controlled is abstract tagged null record - with Initialize => Initialize, - Adjust => Adjust, - Finalize => Finalize, - Legacy_Heap_Finalization, Exceptions_In_Finalize; - - procedure Initialize (Self : in out Controlled) is abstract; - procedure Adjust (Self : in out Controlled) is abstract; - procedure Finalize (Self : in out Controlled) is abstract; - - -### Examples - -A simple example of a ref-counted type: +Simple example of ref-counted type: .. code-block:: ada type T is record - Value : Integer; + Value : Integer; Ref_Count : Natural := 0; end record; @@ -1555,8 +1571,8 @@ A simple example of a ref-counted type: type T_Ref is record Value : T_Access; end record - with Adjust => Adjust, - Finalize => Finalize; + with Finalizable => (Adjust => Adjust, + Finalize => Finalize); procedure Adjust (Ref : in out T_Ref) is begin @@ -1568,8 +1584,7 @@ A simple example of a ref-counted type: Def_Ref (Ref.Value); end Finalize; - -A simple file handle that ensures resources are properly released: +Simple file handle that ensures resources are properly released: .. code-block:: ada @@ -1579,51 +1594,47 @@ A simple file handle that ensures resources are properly released: function Open (Path : String) return File; procedure Close (F : in out File); + private type File is limited record Handle : ...; end record - with Finalize => Close; - - -Finalized tagged types -^^^^^^^^^^^^^^^^^^^^^^^ + with Finalizable (Finalize => Close); + end P; -Aspects are inherited by derived types and optionally overriden by those. The -compiler-generated calls to the user-defined operations are then -dispatching whenever it makes sense, i.e. the object in question is of -class-wide type and the class includes at least one finalized tagged type. +Finalizable tagged types +^^^^^^^^^^^^^^^^^^^^^^^^ -However note that for simplicity, it is forbidden to change the value of any of -those new aspects in derived types. +The aspect is inherited by derived types and the primitives may be overridden +by the derivation. The compiler-generated calls to these operations are then +dispatching whenever it makes sense, i.e. when the object in question is of a +class-wide type and the class includes at least one finalizable tagged type. Composite types ^^^^^^^^^^^^^^^ -When a finalized type is used as a component of a composite type, the latter -becomes finalized as well. The three primitives are derived automatically -in order to call the primitives of their components. - -If that composite type was already user-finalized, then the compiler -calls the primitives of the components so as to stay consistent with today's -controlled types's behavior. - -So, ``Initialize`` and ``Adjust`` are called on components before they -are called on the composite object, but ``Finalize`` is called on the composite -object first. +When a finalizable type is used as a component of a composite type, the latter +becomes finalizable as well. The three primitives are derived automatically +in order to call the primitives of their components. The dynamic semantics is +the same as for controlled components of composite types. Interoperability with controlled types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -As a consequence of the redefinition of the ``Controlled`` type as a base type -with the new aspects defined, interoperability with controlled type naturally -follows the definition of the above rules. In particular: +Finalizable types are fully interoperable with controlled types, in particular +it is possible for a finalizable type to have a controlled component and vice +versa, but the stricter dynamic semantics, in other words that of controlled +types, is applied in this case. + +.. _No_Raise_Aspect: -* It is possible to have a new finalized type have a controlled type - component -* It is possible to have a controlled type have a finalized type - component +No_Raise aspect +---------------- +The ``No_Raise`` aspect can be applied to a subprogram to declare that this +subprogram is not expected to raise an exception. Should an exception still +be raised during the execution of the subprogram, it is caught at the end of +this execution and ``Program_Error`` is propagated to the caller. Inference of Dependent Types in Generic Instantiations ------------------------------------------------------ @@ -1766,3 +1777,87 @@ If an exception is raised in the finally part, it cannot be caught by the ``exce Abort/ATC (asynchronous transfer of control) cannot interrupt a finally block, nor prevent its execution, that is the finally block must be executed in full even if the containing task is aborted, or if the control is transferred out of the block. + +Continue statement +------------------ + +The ``continue`` keyword makes it possible to stop execution of a loop iteration +and continue with the next one. A continue statement has the same syntax +(except "exit" is replaced with "continue"), static semantics, and legality +rules as an exit statement. The difference is in the dynamic semantics: where an +exit statement would cause a transfer of control that completes the (implicitly +or explicitly) specified loop_statement, a continue statement would instead +cause a transfer of control that completes only the current iteration of that +loop_statement, like a goto statement targeting a label following the last +statement in the sequence of statements of the specified loop_statement. + +Note that ``continue`` is a keyword but it is not a reserved word. This is a +configuration that does not exist in standard Ada. + +Destructors +----------- + +The ``Destructor`` aspect can be applied to any record type, tagged or not. +It must denote a primitive of the type that is a procedure with one parameter +of the type and of mode ``in out``: + +.. code-block:: ada + + type T is record + ... + end record with Destructor => Foo; + + procedure Foo (X : in out T); + +This is equivalent to the following code that uses ``Finalizable``: + +.. code-block:: ada + + type T is record + ... + end record with Finalizable => (Finalize => Foo); + + procedure Foo (X : in out T); + +Unlike ``Finalizable``, however, ``Destructor`` can be specified on a derived +type. And when it is, the effect of the aspect combines with the destructors of +the parent type. Take, for example: + +.. code-block:: ada + + type T1 is record + ... + end record with Destructor => Foo; + + procedure Foo (X : in out T1); + + type T2 is new T1 with Destructor => Bar; + + procedure Bar (X : in out T2); + +Here, when an object of type ``T2`` is finalized, a call to ``Bar`` +will be performed and it will be followed by a call to ``Foo``. + +The ``Destructor`` aspect comes with a legality rule: if a primitive procedure +of a type is denoted by a ``Destructor`` aspect specification, it is illegal to +override this procedure in a derived type. For example, the following is illegal: + +.. code-block:: ada + + type T1 is record + ... + end record with Destructor => Foo; + + procedure Foo (X : in out T1); + + type T2 is new T1; + + overriding + procedure Foo (X : in out T2); -- Error here + +It is possible to specify ``Destructor`` on the completion of a private type, +but there is one more restriction in that case: the denoted primitive must +be private to the enclosing package. This is necessary due to the previously +mentioned legality rule, to prevent breaking the privacy of the type when +imposing that rule on outside types that derive from the private view of the +type. diff --git a/gcc/ada/doc/gnat_rm/implementation_advice.rst b/gcc/ada/doc/gnat_rm/implementation_advice.rst index 435cfa412ce9..d4fdd09fccde 100644 --- a/gcc/ada/doc/gnat_rm/implementation_advice.rst +++ b/gcc/ada/doc/gnat_rm/implementation_advice.rst @@ -1218,16 +1218,12 @@ RM E.5(28-29): Partition Communication Subsystem should allow them to block until the corresponding subprogram body returns." -Followed by GLADE, a separately supplied PCS that can be used with -GNAT. +A separately supplied PCS that can be used with GNAT when combined with the PolyORB product. "The ``Write`` operation on a stream of type ``Params_Stream_Type`` should raise ``Storage_Error`` if it runs out of space trying to write the ``Item`` into the stream." -Followed by GLADE, a separately supplied PCS that can be used with -GNAT. - .. index:: COBOL support RM F(7): COBOL Support diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst b/gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst index 61ea10c01cc0..a36956805125 100644 --- a/gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst +++ b/gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst @@ -538,6 +538,14 @@ Aspect Persistent_BSS This boolean aspect is equivalent to :ref:`pragma Persistent_BSS<Pragma-Persistent_BSS>`. +Aspect Potentially_Invalid +========================== +.. index:: Potentially_Invalid + +For the syntax and semantics of this aspect, see the SPARK 2014 Reference +Manual, section 13.9.1. + + Aspect Predicate ================ .. index:: Predicate @@ -549,6 +557,12 @@ predicate is static or dynamic is controlled by the form of the expression. It is also separately controllable using pragma ``Assertion_Policy``. +Aspect Program_Exit +=================== +.. index:: Program_Exit + +This boolean aspect is equivalent to :ref:`pragma Program_Exit<Pragma-Program_Exit>`. + Aspect Pure_Function ==================== .. index:: Pure_Function diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst index f0518106853f..86d2a815e1e0 100644 --- a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst +++ b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst @@ -1629,9 +1629,9 @@ Attribute Valid_Value .. index:: Valid_Value The ``'Valid_Value`` attribute is defined for enumeration types other than -those in package Standard. This attribute is a function that takes -a String, and returns Boolean. ``T'Valid_Value (S)`` returns True -if and only if ``T'Value (S)`` would not raise Constraint_Error. +those in package Standard or types derived from those types. This attribute is +a function that takes a String, and returns Boolean. ``T'Valid_Value (S)`` +returns True if and only if ``T'Value (S)`` would not raise Constraint_Error. Attribute Valid_Scalars ======================= diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst b/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst index 3e41899f95ef..f7746c8e72fe 100644 --- a/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst +++ b/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst @@ -377,11 +377,7 @@ may have been set by a call to ``Ada.Command_Line.Set_Exit_Status``). * "The mechanisms for building and running partitions. See 10.2(24)." -GNAT itself supports programs with only a single partition. The GNATDIST -tool provided with the GLADE package (which also includes an implementation -of the PCS) provides a completely flexible method for building and running -programs consisting of multiple partitions. See the separate GLADE manual -for details. +GNAT itself supports programs with only a single partition. The PolyORB product (which also includes an implementation of the PCS) provides a completely flexible method for building and running programs consisting of multiple partitions. See the separate PolyORB user guide for details. * "The details of program execution, including program @@ -394,7 +390,7 @@ See separate section on compilation model. implementation. See 10.2(28)." Passive partitions are supported on targets where shared memory is -provided by the operating system. See the GLADE reference manual for +provided by the operating system. See the PolyORB user guide for further details. * @@ -467,7 +463,7 @@ Implementation-defined assertion_aspect_marks include Assert_And_Cut, Assume, Contract_Cases, Debug, Ghost, Initial_Condition, Loop_Invariant, Loop_Variant, Postcondition, Precondition, Predicate, Refined_Post, Statement_Assertions, and Subprogram_Variant. Implementation-defined -policy_identifiers include Ignore and Suppressible. +policy_identifiers include Disable and Suppressible. * "The default assertion policy. See 11.4.2(10)." @@ -1188,27 +1184,27 @@ Unknown. "The means for creating and executing distributed programs. See E(5)." -The GLADE package provides a utility GNATDIST for creating and executing -distributed programs. See the GLADE reference manual for further details. +The PolyORB product provides means creating and executing +distributed programs. See the PolyORB user guide for further details. * "Any events that can result in a partition becoming inaccessible. See E.1(7)." -See the GLADE reference manual for full details on such events. +See the PolyORB user guide for full details on such events. * "The scheduling policies, treatment of priorities, and management of shared resources between partitions in certain cases. See E.1(11)." -See the GLADE reference manual for full details on these aspects of +See the PolyORB user guide for full details on these aspects of multi-partition execution. * "Whether the execution of the remote subprogram is immediately aborted as a result of cancellation. See E.4(13)." -See the GLADE reference manual for details on the effect of abort in +See the PolyORB user guide for details on the effect of abort in a distributed application. * @@ -1219,7 +1215,7 @@ System.RPC.Partition_ID'Last is Integer'Last. See source file :file:`s-rpc.ads`. * "Implementation-defined interfaces in the PCS. See E.5(26)." -See the GLADE reference manual for a full description of all +See the PolyORB user guide for a full description of all implementation defined interfaces. * diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst index d18ce36b84d6..3986298d11e9 100644 --- a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst +++ b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst @@ -123,6 +123,11 @@ and generics may name types with unknown discriminants without using the ``(<>)`` notation. In addition, some but not all of the additional restrictions of Ada 83 are enforced. +Like all configuration pragmas, if the pragma is placed before a library +level package specification it is not propagated to the corresponding +package body (see RM 10.1.5(8)); it must be added explicitly to the +package body. + Ada 83 mode is intended for two purposes. Firstly, it allows existing Ada 83 code to be compiled and adapted to GNAT with less effort. Secondly, it aids in keeping code backwards compatible with Ada 83. @@ -149,6 +154,11 @@ contexts. This pragma is useful when writing a reusable component that itself uses Ada 95 features, but which is intended to be usable from either Ada 83 or Ada 95 programs. +Like all configuration pragmas, if the pragma is placed before a library +level package specification it is not propagated to the corresponding +package body (see RM 10.1.5(8)); it must be added explicitly to the +package body. + Pragma Ada_05 ============= @@ -166,6 +176,11 @@ This pragma is useful when writing a reusable component that itself uses Ada 2005 features, but which is intended to be usable from either Ada 83 or Ada 95 programs. +Like all configuration pragmas, if the pragma is placed before a library +level package specification it is not propagated to the corresponding +package body (see RM 10.1.5(8)); it must be added explicitly to the +package body. + The one argument form (which is not a configuration pragma) is used for managing the transition from Ada 95 to Ada 2005 in the run-time library. If an entity is marked @@ -209,6 +224,11 @@ contexts. This pragma is useful when writing a reusable component that itself uses Ada 2012 features, but which is intended to be usable from Ada 83, Ada 95, or Ada 2005 programs. +Like all configuration pragmas, if the pragma is placed before a library +level package specification it is not propagated to the corresponding +package body (see RM 10.1.5(8)); it must be added explicitly to the +package body. + The one argument form, which is not a configuration pragma, is used for managing the transition from Ada 2005 to Ada 2012 in the run-time library. If an entity is marked @@ -252,6 +272,11 @@ contexts. This pragma is useful when writing a reusable component that itself uses Ada 2022 features, but which is intended to be usable from Ada 83, Ada 95, Ada 2005 or Ada 2012 programs. +Like all configuration pragmas, if the pragma is placed before a library +level package specification it is not propagated to the corresponding +package body (see RM 10.1.5(8)); it must be added explicitly to the +package body. + The one argument form, which is not a configuration pragma, is used for managing the transition from Ada 2012 to Ada 2022 in the run-time library. If an entity is marked @@ -1940,7 +1965,8 @@ Syntax: EXIT_CASE ::= GUARD => EXIT_KIND EXIT_KIND ::= Normal_Return | Exception_Raised - | (Exception_Raised => exception_name) + | (Exception_Raised => exception_name) + | Program_Exit GUARD ::= Boolean_expression For the semantics of this aspect, see the SPARK 2014 Reference Manual, section @@ -5285,6 +5311,20 @@ generating ``Restrictions`` pragmas, it generates violations of the profile generate warning messages instead of error messages. +.. _Pragma-Program_Exit: + +Pragma Program_Exit +=================== + +Syntax: + +.. code-block:: ada + + pragma Program_Exit [ (boolean_EXPRESSION) ]; + +For the semantics of this pragma, see the entry for aspect ``Program_Exit`` +in the SPARK 2014 Reference Manual, section 6.1.10. + Pragma Propagate_Exceptions =========================== .. index:: Interfacing to C++ @@ -5874,13 +5914,33 @@ Syntax: pragma Short_Circuit_And_Or; -This configuration pragma causes any occurrence of the AND operator applied to -operands of type Standard.Boolean to be short-circuited (i.e. the AND operator -is treated as if it were AND THEN). Or is similarly treated as OR ELSE. This -may be useful in the context of certification protocols requiring the use of -short-circuited logical operators. If this configuration pragma occurs locally -within the file being compiled, it applies only to the file being compiled. +This configuration pragma causes the predefined AND and OR operators of +type Standard.Boolean to have short-circuit semantics. That is, they +behave like AND THEN and OR ELSE; the right-hand side is not evaluated +if the left-hand side determines the result. This may be useful in the +context of certification protocols requiring the use of short-circuited +logical operators. + There is no requirement that all units in a partition use this option. +However, mixing of short-circuit and non-short-circuit semantics can be +confusing. Therefore, the recommended use is to put the pragma in a +configuration file that applies to the whole program. Alternatively, if +you have a legacy library that should not use this pragma, you can put +it in a separate library project that does not use the pragma. +In any case, fine-grained mixing of the different semantics is not +recommended. If pragma ``Short_Circuit_And_Or`` is specified, then it +is illegal to rename the predefined Boolean AND and OR, or to pass +them to generic formal functions; this corresponds to the fact that +AND THEN and OR ELSE cannot be renamed nor passed as generic formal +functions. + +Note that this pragma has no effect on other logical operators -- +predefined operators of modular types, array-of-boolean types and types +derived from Standard.Boolean, nor user-defined operators. + +See also the pragma ``Unevaluated_Use_Of_Old`` and the restriction +``No_Direct_Boolean_Operators``, which may be useful in conjunction +with ``Short_Circuit_And_Or``. Pragma Short_Descriptors ======================== diff --git a/gcc/ada/doc/gnat_rm/implementation_of_ada_2012_features.rst b/gcc/ada/doc/gnat_rm/implementation_of_ada_2012_features.rst deleted file mode 100644 index 9708e15de8d6..000000000000 --- a/gcc/ada/doc/gnat_rm/implementation_of_ada_2012_features.rst +++ /dev/null @@ -1,1330 +0,0 @@ -.. _Implementation_of_Ada_2012_Features: - -*********************************** -Implementation of Ada 2012 Features -*********************************** - -.. index:: Ada 2012 implementation status - -.. index:: -gnat12 option (gcc) - -.. index:: pragma Ada_2012 - -.. index:: configuration pragma Ada_2012 - -.. index:: Ada_2012 configuration pragma - -This chapter contains a complete list of Ada 2012 features that have been -implemented. -Generally, these features are only -available if the *-gnat12* (Ada 2012 features enabled) option is set, -which is the default behavior, -or if the configuration pragma ``Ada_2012`` is used. - -However, new pragmas, attributes, and restrictions are -unconditionally available, since the Ada 95 standard allows the addition of -new pragmas, attributes, and restrictions (there are exceptions, which are -documented in the individual descriptions), and also certain packages -were made available in earlier versions of Ada. - -An ISO date (YYYY-MM-DD) appears in parentheses on the description line. -This date shows the implementation date of the feature. Any wavefront -subsequent to this date will contain the indicated feature, as will any -subsequent releases. A date of 0000-00-00 means that GNAT has always -implemented the feature, or implemented it as soon as it appeared as a -binding interpretation. - -Each feature corresponds to an Ada Issue ('AI') approved by the Ada -standardization group (ISO/IEC JTC1/SC22/WG9) for inclusion in Ada 2012. -The features are ordered based on the relevant sections of the Ada -Reference Manual ("RM"). When a given AI relates to multiple points -in the RM, the earliest is used. - -A complete description of the AIs may be found in -http://www.ada-auth.org/ai05-summary.html. - -.. index:: AI-0002 (Ada 2012 feature) - -* *AI-0002 Export C with unconstrained arrays (0000-00-00)* - - The compiler is not required to support exporting an Ada subprogram with - convention C if there are parameters or a return type of an unconstrained - array type (such as ``String``). GNAT allows such declarations but - generates warnings. It is possible, but complicated, to write the - corresponding C code and certainly such code would be specific to GNAT and - non-portable. - - RM References: B.01 (17) B.03 (62) B.03 (71.1/2) - -.. index:: AI-0003 (Ada 2012 feature) - -* *AI-0003 Qualified expressions as names (2010-07-11)* - - In Ada 2012, a qualified expression is considered to be syntactically a name, - meaning that constructs such as ``A'(F(X)).B`` are now legal. This is - useful in disambiguating some cases of overloading. - - RM References: 3.03 (11) 3.03 (21) 4.01 (2) 4.04 (7) 4.07 (3) - 5.04 (7) - -.. index:: AI-0007 (Ada 2012 feature) - -* *AI-0007 Stream read and private scalar types (0000-00-00)* - - The RM as written appeared to limit the possibilities of declaring read - attribute procedures for private scalar types. This limitation was not - intended, and has never been enforced by GNAT. - - RM References: 13.13.02 (50/2) 13.13.02 (51/2) - -.. index:: AI-0008 (Ada 2012 feature) - -* *AI-0008 General access to constrained objects (0000-00-00)* - - The wording in the RM implied that if you have a general access to a - constrained object, it could be used to modify the discriminants. This was - obviously not intended. ``Constraint_Error`` should be raised, and GNAT - has always done so in this situation. - - RM References: 3.03 (23) 3.10.02 (26/2) 4.01 (9) 6.04.01 (17) 8.05.01 (5/2) - -.. index:: AI-0009 (Ada 2012 feature) - -* *AI-0009 Pragma Independent[_Components] (2010-07-23)* - - This AI introduces the new pragmas ``Independent`` and - ``Independent_Components``, - which control guaranteeing independence of access to objects and components. - The AI also requires independence not unaffected by confirming rep clauses. - - RM References: 9.10 (1) 13.01 (15/1) 13.02 (9) 13.03 (13) C.06 (2) - C.06 (4) C.06 (6) C.06 (9) C.06 (13) C.06 (14) - -.. index:: AI-0012 (Ada 2012 feature) - -* *AI-0012 Pack/Component_Size for aliased/atomic (2010-07-15)* - - It is now illegal to give an inappropriate component size or a pragma - ``Pack`` that attempts to change the component size in the case of atomic - or aliased components. Previously GNAT ignored such an attempt with a - warning. - - RM References: 13.02 (6.1/2) 13.02 (7) C.06 (10) C.06 (11) C.06 (21) - -.. index:: AI-0015 (Ada 2012 feature) - -* *AI-0015 Constant return objects (0000-00-00)* - - The return object declared in an *extended_return_statement* may be - declared constant. This was always intended, and GNAT has always allowed it. - - RM References: 6.05 (2.1/2) 3.03 (10/2) 3.03 (21) 6.05 (5/2) - 6.05 (5.7/2) - -.. index:: AI-0017 (Ada 2012 feature) - -* *AI-0017 Freezing and incomplete types (0000-00-00)* - - So-called 'Taft-amendment types' (i.e., types that are completed in package - bodies) are not frozen by the occurrence of bodies in the - enclosing declarative part. GNAT always implemented this properly. - - RM References: 13.14 (3/1) - -.. index:: AI-0019 (Ada 2012 feature) - -* *AI-0019 Freezing of primitives for tagged types (0000-00-00)* - - The RM suggests that primitive subprograms of a specific tagged type are - frozen when the tagged type is frozen. This would be an incompatible change - and is not intended. GNAT has never attempted this kind of freezing and its - behavior is consistent with the recommendation of this AI. - - RM References: 13.14 (2) 13.14 (3/1) 13.14 (8.1/1) 13.14 (10) 13.14 (14) 13.14 (15.1/2) - -.. index:: AI-0026 (Ada 2012 feature) - -* *AI-0026 Missing rules for Unchecked_Union (2010-07-07)* - - Record representation clauses concerning Unchecked_Union types cannot mention - the discriminant of the type. The type of a component declared in the variant - part of an Unchecked_Union cannot be controlled, have controlled components, - nor have protected or task parts. If an Unchecked_Union type is declared - within the body of a generic unit or its descendants, then the type of a - component declared in the variant part cannot be a formal private type or a - formal private extension declared within the same generic unit. - - RM References: 7.06 (9.4/2) B.03.03 (9/2) B.03.03 (10/2) - -.. index:: AI-0030 (Ada 2012 feature) - -* *AI-0030 Requeue on synchronized interfaces (2010-07-19)* - - Requeue is permitted to a protected, synchronized or task interface primitive - providing it is known that the overriding operation is an entry. Otherwise - the requeue statement has the same effect as a procedure call. Use of pragma - ``Implemented`` provides a way to impose a static requirement on the - overriding operation by adhering to one of the implementation kinds: entry, - protected procedure or any of the above. - - RM References: 9.05 (9) 9.05.04 (2) 9.05.04 (3) 9.05.04 (5) - 9.05.04 (6) 9.05.04 (7) 9.05.04 (12) - -.. index:: AI-0031 (Ada 2012 feature) - -* *AI-0031 Add From parameter to Find_Token (2010-07-25)* - - A new version of ``Find_Token`` is added to all relevant string packages, - with an extra parameter ``From``. Instead of starting at the first - character of the string, the search for a matching Token starts at the - character indexed by the value of ``From``. - These procedures are available in all versions of Ada - but if used in versions earlier than Ada 2012 they will generate a warning - that an Ada 2012 subprogram is being used. - - RM References: A.04.03 (16) A.04.03 (67) A.04.03 (68/1) A.04.04 (51) - A.04.05 (46) - -.. index:: AI-0032 (Ada 2012 feature) - -* *AI-0032 Extended return for class-wide functions (0000-00-00)* - - If a function returns a class-wide type, the object of an extended return - statement can be declared with a specific type that is covered by the class- - wide type. This has been implemented in GNAT since the introduction of - extended returns. Note AI-0103 complements this AI by imposing matching - rules for constrained return types. - - RM References: 6.05 (5.2/2) 6.05 (5.3/2) 6.05 (5.6/2) 6.05 (5.8/2) - 6.05 (8/2) - -.. index:: AI-0033 (Ada 2012 feature) - -* *AI-0033 Attach/Interrupt_Handler in generic (2010-07-24)* - - Neither of these two pragmas may appear within a generic template, because - the generic might be instantiated at other than the library level. - - RM References: 13.11.02 (16) C.03.01 (7/2) C.03.01 (8/2) - -.. index:: AI-0034 (Ada 2012 feature) - -* *AI-0034 Categorization of limited views (0000-00-00)* - - The RM makes certain limited with clauses illegal because of categorization - considerations, when the corresponding normal with would be legal. This is - not intended, and GNAT has always implemented the recommended behavior. - - RM References: 10.02.01 (11/1) 10.02.01 (17/2) - -.. index:: AI-0035 (Ada 2012 feature) - -* *AI-0035 Inconsistencies with Pure units (0000-00-00)* - - This AI remedies some inconsistencies in the legality rules for Pure units. - Derived access types are legal in a pure unit (on the assumption that the - rule for a zero storage pool size has been enforced on the ancestor type). - The rules are enforced in generic instances and in subunits. GNAT has always - implemented the recommended behavior. - - RM References: 10.02.01 (15.1/2) 10.02.01 (15.4/2) 10.02.01 (15.5/2) 10.02.01 (17/2) - -.. index:: AI-0037 (Ada 2012 feature) - -* *AI-0037 Out-of-range box associations in aggregate (0000-00-00)* - - This AI confirms that an association of the form ``Indx => <>`` in an - array aggregate must raise ``Constraint_Error`` if ``Indx`` - is out of range. The RM specified a range check on other associations, but - not when the value of the association was defaulted. GNAT has always inserted - a constraint check on the index value. - - RM References: 4.03.03 (29) - -.. index:: AI-0038 (Ada 2012 feature) - -* *AI-0038 Minor errors in Text_IO (0000-00-00)* - - These are minor errors in the description on three points. The intent on - all these points has always been clear, and GNAT has always implemented the - correct intended semantics. - - RM References: A.10.05 (37) A.10.07 (8/1) A.10.07 (10) A.10.07 (12) A.10.08 (10) A.10.08 (24) - -.. index:: AI-0039 (Ada 2012 feature) - -* *AI-0039 Stream attributes cannot be dynamic (0000-00-00)* - - The RM permitted the use of dynamic expressions (such as ``ptr.all``) - for stream attributes, but these were never useful and are now illegal. GNAT - has always regarded such expressions as illegal. - - RM References: 13.03 (4) 13.03 (6) 13.13.02 (38/2) - -.. index:: AI-0040 (Ada 2012 feature) - -* *AI-0040 Limited with clauses on descendant (0000-00-00)* - - This AI confirms that a limited with clause in a child unit cannot name - an ancestor of the unit. This has always been checked in GNAT. - - RM References: 10.01.02 (20/2) - -.. index:: AI-0042 (Ada 2012 feature) - -* *AI-0042 Overriding versus implemented-by (0000-00-00)* - - This AI fixes a wording gap in the RM. An operation of a synchronized - interface can be implemented by a protected or task entry, but the abstract - operation is not being overridden in the usual sense, and it must be stated - separately that this implementation is legal. This has always been the case - in GNAT. - - RM References: 9.01 (9.2/2) 9.04 (11.1/2) - -.. index:: AI-0043 (Ada 2012 feature) - -* *AI-0043 Rules about raising exceptions (0000-00-00)* - - This AI covers various omissions in the RM regarding the raising of - exceptions. GNAT has always implemented the intended semantics. - - RM References: 11.04.01 (10.1/2) 11 (2) - -.. index:: AI-0044 (Ada 2012 feature) - -* *AI-0044 Restrictions on container instantiations (0000-00-00)* - - This AI places restrictions on allowed instantiations of generic containers. - These restrictions are not checked by the compiler, so there is nothing to - change in the implementation. This affects only the RM documentation. - - RM References: A.18 (4/2) A.18.02 (231/2) A.18.03 (145/2) A.18.06 (56/2) A.18.08 (66/2) A.18.09 (79/2) A.18.26 (5/2) A.18.26 (9/2) - -.. index:: AI-0046 (Ada 2012 feature) - -* *AI-0046 Null exclusion match for full conformance (2010-07-17)* - - For full conformance, in the case of access parameters, the null exclusion - must match (either both or neither must have ``not null``). - - RM References: 6.03.02 (18) - -.. index:: AI-0050 (Ada 2012 feature) - -* *AI-0050 Raising Constraint_Error early for function call (0000-00-00)* - - The implementation permissions for raising ``Constraint_Error`` early on a function call - when it was clear an exception would be raised were over-permissive and allowed - mishandling of discriminants in some cases. GNAT did - not take advantage of these incorrect permissions in any case. - - RM References: 6.05 (24/2) - -.. index:: AI-0056 (Ada 2012 feature) - -* *AI-0056 Index on null string returns zero (0000-00-00)* - - The wording in the Ada 2005 RM implied an incompatible handling of the - ``Index`` functions, resulting in raising an exception instead of - returning zero in some situations. - This was not intended and has been corrected. - GNAT always returned zero, and is thus consistent with this AI. - - RM References: A.04.03 (56.2/2) A.04.03 (58.5/2) - -.. index:: AI-0058 (Ada 2012 feature) - -* *AI-0058 Abnormal completion of an extended return (0000-00-00)* - - The RM had some incorrect wording implying wrong treatment of abnormal - completion in an extended return. GNAT has always implemented the intended - correct semantics as described by this AI. - - RM References: 6.05 (22/2) - -.. index:: AI-0060 (Ada 2012 feature) - -* *AI-0060 Extended definition of remote access types (0000-00-00)* - - This AI extends the definition of remote access types to include access - to limited, synchronized, protected or task class-wide interface types. - GNAT already implemented this extension. - - RM References: A (4) E.02.02 (9/1) E.02.02 (9.2/1) E.02.02 (14/2) E.02.02 (18) - -.. index:: AI-0062 (Ada 2012 feature) - -* *AI-0062 Null exclusions and deferred constants (0000-00-00)* - - A full constant may have a null exclusion even if its associated deferred - constant does not. GNAT has always allowed this. - - RM References: 7.04 (6/2) 7.04 (7.1/2) - -.. index:: AI-0064 (Ada 2012 feature) - -* *AI-0064 Redundant finalization rule (0000-00-00)* - - This is an editorial change only. The intended behavior is already checked - by an existing ACATS test, which GNAT has always executed correctly. - - RM References: 7.06.01 (17.1/1) - -.. index:: AI-0065 (Ada 2012 feature) - -* *AI-0065 Remote access types and external streaming (0000-00-00)* - - This AI clarifies the fact that all remote access types support external - streaming. This fixes an obvious oversight in the definition of the - language, and GNAT always implemented the intended correct rules. - - RM References: 13.13.02 (52/2) - -.. index:: AI-0070 (Ada 2012 feature) - -* *AI-0070 Elaboration of interface types (0000-00-00)* - - This is an editorial change only, there are no testable consequences short of - checking for the absence of generated code for an interface declaration. - - RM References: 3.09.04 (18/2) - -.. index:: AI-0072 (Ada 2012 feature) - -* *AI-0072 Task signalling using 'Terminated (0000-00-00)* - - This AI clarifies that task signalling for reading ``'Terminated`` only - occurs if the result is True. GNAT semantics has always been consistent with - this notion of task signalling. - - RM References: 9.10 (6.1/1) - -.. index:: AI-0073 (Ada 2012 feature) - -* *AI-0073 Functions returning abstract types (2010-07-10)* - - This AI covers a number of issues regarding returning abstract types. In - particular generic functions cannot have abstract result types or access - result types designated an abstract type. There are some other cases which - are detailed in the AI. Note that this binding interpretation has not been - retrofitted to operate before Ada 2012 mode, since it caused a significant - number of regressions. - - RM References: 3.09.03 (8) 3.09.03 (10) 6.05 (8/2) - -.. index:: AI-0076 (Ada 2012 feature) - -* *AI-0076 function with controlling result (0000-00-00)* - - This is an editorial change only. The RM defines calls with controlling - results, but uses the term 'function with controlling result' without an - explicit definition. - - RM References: 3.09.02 (2/2) - -.. index:: AI-0077 (Ada 2012 feature) - -* *AI-0077 Limited withs and scope of declarations (0000-00-00)* - - This AI clarifies that a declaration does not include a context clause, - and confirms that it is illegal to have a context in which both a limited - and a nonlimited view of a package are accessible. Such double visibility - was always rejected by GNAT. - - RM References: 10.01.02 (12/2) 10.01.02 (21/2) 10.01.02 (22/2) - -.. index:: AI-0078 (Ada 2012 feature) - -* *AI-0078 Relax Unchecked_Conversion alignment rules (0000-00-00)* - - In Ada 2012, compilers are required to support unchecked conversion where the - target alignment is a multiple of the source alignment. GNAT always supported - this case (and indeed all cases of differing alignments, doing copies where - required if the alignment was reduced). - - RM References: 13.09 (7) - -.. index:: AI-0079 (Ada 2012 feature) - -* *AI-0079 Allow other_format characters in source (2010-07-10)* - - Wide characters in the unicode category *other_format* are now allowed in - source programs between tokens, but not within a token such as an identifier. - - RM References: 2.01 (4/2) 2.02 (7) - -.. index:: AI-0080 (Ada 2012 feature) - -* *AI-0080 'View of' not needed if clear from context (0000-00-00)* - - This is an editorial change only, described as non-testable in the AI. - - RM References: 3.01 (7) - -.. index:: AI-0087 (Ada 2012 feature) - -* *AI-0087 Actual for formal nonlimited derived type (2010-07-15)* - - The actual for a formal nonlimited derived type cannot be limited. In - particular, a formal derived type that extends a limited interface but which - is not explicitly limited cannot be instantiated with a limited type. - - RM References: 7.05 (5/2) 12.05.01 (5.1/2) - -.. index:: AI-0088 (Ada 2012 feature) - -* *AI-0088 The value of exponentiation (0000-00-00)* - - This AI clarifies the equivalence rule given for the dynamic semantics of - exponentiation: the value of the operation can be obtained by repeated - multiplication, but the operation can be implemented otherwise (for example - using the familiar divide-by-two-and-square algorithm, even if this is less - accurate), and does not imply repeated reads of a volatile base. - - RM References: 4.05.06 (11) - -.. index:: AI-0091 (Ada 2012 feature) - -* *AI-0091 Do not allow other_format in identifiers (0000-00-00)* - - Wide characters in the unicode category *other_format* are not permitted - within an identifier, since this can be a security problem. The error - message for this case has been improved to be more specific, but GNAT has - never allowed such characters to appear in identifiers. - - RM References: 2.03 (3.1/2) 2.03 (4/2) 2.03 (5/2) 2.03 (5.1/2) 2.03 (5.2/2) 2.03 (5.3/2) 2.09 (2/2) - -.. index:: AI-0093 (Ada 2012 feature) - -* *AI-0093 Additional rules use immutably limited (0000-00-00)* - - This is an editorial change only, to make more widespread use of the Ada 2012 - 'immutably limited'. - - RM References: 3.03 (23.4/3) - -.. index:: AI-0095 (Ada 2012 feature) - -* *AI-0095 Address of intrinsic subprograms (0000-00-00)* - - The prefix of ``'Address`` cannot statically denote a subprogram with - convention ``Intrinsic``. The use of the ``Address`` attribute raises - ``Program_Error`` if the prefix denotes a subprogram with convention - ``Intrinsic``. - - RM References: 13.03 (11/1) - -.. index:: AI-0096 (Ada 2012 feature) - -* *AI-0096 Deriving from formal private types (2010-07-20)* - - In general it is illegal for a type derived from a formal limited type to be - nonlimited. This AI makes an exception to this rule: derivation is legal - if it appears in the private part of the generic, and the formal type is not - tagged. If the type is tagged, the legality check must be applied to the - private part of the package. - - RM References: 3.04 (5.1/2) 6.02 (7) - -.. index:: AI-0097 (Ada 2012 feature) - -* *AI-0097 Treatment of abstract null extension (2010-07-19)* - - The RM as written implied that in some cases it was possible to create an - object of an abstract type, by having an abstract extension inherit a non- - abstract constructor from its parent type. This mistake has been corrected - in GNAT and in the RM, and this construct is now illegal. - - RM References: 3.09.03 (4/2) - -.. index:: AI-0098 (Ada 2012 feature) - -* *AI-0098 Anonymous subprogram access restrictions (0000-00-00)* - - An unintentional omission in the RM implied some inconsistent restrictions on - the use of anonymous access to subprogram values. These restrictions were not - intentional, and have never been enforced by GNAT. - - RM References: 3.10.01 (6) 3.10.01 (9.2/2) - -.. index:: AI-0099 (Ada 2012 feature) - -* *AI-0099 Tag determines whether finalization needed (0000-00-00)* - - This AI clarifies that 'needs finalization' is part of dynamic semantics, - and therefore depends on the run-time characteristics of an object (i.e. its - tag) and not on its nominal type. As the AI indicates: "we do not expect - this to affect any implementation". - - RM References: 7.06.01 (6) 7.06.01 (7) 7.06.01 (8) 7.06.01 (9/2) - -.. index:: AI-0100 (Ada 2012 feature) - -* *AI-0100 Placement of pragmas (2010-07-01)* - - This AI is an earlier version of AI-163. It simplifies the rules - for legal placement of pragmas. In the case of lists that allow pragmas, if - the list may have no elements, then the list may consist solely of pragmas. - - RM References: 2.08 (7) - -.. index:: AI-0102 (Ada 2012 feature) - -* *AI-0102 Some implicit conversions are illegal (0000-00-00)* - - It is illegal to assign an anonymous access constant to an anonymous access - variable. The RM did not have a clear rule to prevent this, but GNAT has - always generated an error for this usage. - - RM References: 3.07 (16) 3.07.01 (9) 6.04.01 (6) 8.06 (27/2) - -.. index:: AI-0103 (Ada 2012 feature) - -* *AI-0103 Static matching for extended return (2010-07-23)* - - If the return subtype of a function is an elementary type or a constrained - type, the subtype indication in an extended return statement must match - statically this return subtype. - - RM References: 6.05 (5.2/2) - -.. index:: AI-0104 (Ada 2012 feature) - -* *AI-0104 Null exclusion and uninitialized allocator (2010-07-15)* - - The assignment ``Ptr := new not null Some_Ptr;`` will raise - ``Constraint_Error`` because the default value of the allocated object is - **null**. This useless construct is illegal in Ada 2012. - - RM References: 4.08 (2) - -.. index:: AI-0106 (Ada 2012 feature) - -* *AI-0106 No representation pragmas on generic formals (0000-00-00)* - - The RM appeared to allow representation pragmas on generic formal parameters, - but this was not intended, and GNAT has never permitted this usage. - - RM References: 13.01 (9.1/1) - -.. index:: AI-0108 (Ada 2012 feature) - -* *AI-0108 Limited incomplete view and discriminants (0000-00-00)* - - This AI confirms that an incomplete type from a limited view does not have - discriminants. This has always been the case in GNAT. - - RM References: 10.01.01 (12.3/2) - -.. index:: AI-0109 (Ada 2012 feature) - -* *AI-0109 Redundant check in S'Class'Input (0000-00-00)* - - This AI is an editorial change only. It removes the need for a tag check - that can never fail. - - RM References: 13.13.02 (34/2) - -.. index:: AI-0112 (Ada 2012 feature) - -* *AI-0112 Detection of duplicate pragmas (2010-07-24)* - - This AI concerns giving names to various representation aspects, but the - practical effect is simply to make the use of duplicate - ``Atomic[_Components]``, - ``Volatile[_Components]``, and - ``Independent[_Components]`` pragmas illegal, and GNAT - now performs this required check. - - RM References: 13.01 (8) - -.. index:: AI-0114 (Ada 2012 feature) - -* *AI-0114 Classification of letters (0000-00-00)* - - The code points 170 (``FEMININE ORDINAL INDICATOR``), - 181 (``MICRO SIGN``), and - 186 (``MASCULINE ORDINAL INDICATOR``) are technically considered - lower case letters by Unicode. - However, they are not allowed in identifiers, and they - return ``False`` to ``Ada.Characters.Handling.Is_Letter/Is_Lower``. - This behavior is consistent with that defined in Ada 95. - - RM References: A.03.02 (59) A.04.06 (7) - -.. index:: AI-0116 (Ada 2012 feature) - -* *AI-0116 Alignment of class-wide objects (0000-00-00)* - - This AI requires that the alignment of a class-wide object be no greater - than the alignment of any type in the class. GNAT has always followed this - recommendation. - - RM References: 13.03 (29) 13.11 (16) - -.. index:: AI-0118 (Ada 2012 feature) - -* *AI-0118 The association of parameter associations (0000-00-00)* - - This AI clarifies the rules for named associations in subprogram calls and - generic instantiations. The rules have been in place since Ada 83. - - RM References: 6.04.01 (2) 12.03 (9) - -.. index:: AI-0120 (Ada 2012 feature) - -* *AI-0120 Constant instance of protected object (0000-00-00)* - - This is an RM editorial change only. The section that lists objects that are - constant failed to include the current instance of a protected object - within a protected function. This has always been treated as a constant - in GNAT. - - RM References: 3.03 (21) - -.. index:: AI-0122 (Ada 2012 feature) - -* *AI-0122 Private with and children of generics (0000-00-00)* - - This AI clarifies the visibility of private children of generic units within - instantiations of a parent. GNAT has always handled this correctly. - - RM References: 10.01.02 (12/2) - -.. index:: AI-0123 (Ada 2012 feature) - -* *AI-0123 Composability of equality (2010-04-13)* - - Equality of untagged record composes, so that the predefined equality for a - composite type that includes a component of some untagged record type - ``R`` uses the equality operation of ``R`` (which may be user-defined - or predefined). This makes the behavior of untagged records identical to that - of tagged types in this respect. - - This change is an incompatibility with previous versions of Ada, but it - corrects a non-uniformity that was often a source of confusion. Analysis of - a large number of industrial programs indicates that in those rare cases - where a composite type had an untagged record component with a user-defined - equality, either there was no use of the composite equality, or else the code - expected the same composability as for tagged types, and thus had a bug that - would be fixed by this change. - - RM References: 4.05.02 (9.7/2) 4.05.02 (14) 4.05.02 (15) 4.05.02 (24) - 8.05.04 (8) - -.. index:: AI-0125 (Ada 2012 feature) - -* *AI-0125 Nonoverridable operations of an ancestor (2010-09-28)* - - In Ada 2012, the declaration of a primitive operation of a type extension - or private extension can also override an inherited primitive that is not - visible at the point of this declaration. - - RM References: 7.03.01 (6) 8.03 (23) 8.03.01 (5/2) 8.03.01 (6/2) - -.. index:: AI-0126 (Ada 2012 feature) - -* *AI-0126 Dispatching with no declared operation (0000-00-00)* - - This AI clarifies dispatching rules, and simply confirms that dispatching - executes the operation of the parent type when there is no explicitly or - implicitly declared operation for the descendant type. This has always been - the case in all versions of GNAT. - - RM References: 3.09.02 (20/2) 3.09.02 (20.1/2) 3.09.02 (20.2/2) - -.. index:: AI-0127 (Ada 2012 feature) - -* *AI-0127 Adding Locale Capabilities (2010-09-29)* - - This package provides an interface for identifying the current locale. - - RM References: A.19 A.19.01 A.19.02 A.19.03 A.19.05 A.19.06 - A.19.07 A.19.08 A.19.09 A.19.10 A.19.11 A.19.12 A.19.13 - -.. index:: AI-0128 (Ada 2012 feature) - -* *AI-0128 Inequality is a primitive operation (0000-00-00)* - - If an equality operator ("=") is declared for a type, then the implicitly - declared inequality operator ("/=") is a primitive operation of the type. - This is the only reasonable interpretation, and is the one always implemented - by GNAT, but the RM was not entirely clear in making this point. - - RM References: 3.02.03 (6) 6.06 (6) - -.. index:: AI-0129 (Ada 2012 feature) - -* *AI-0129 Limited views and incomplete types (0000-00-00)* - - This AI clarifies the description of limited views: a limited view of a - package includes only one view of a type that has an incomplete declaration - and a full declaration (there is no possible ambiguity in a client package). - This AI also fixes an omission: a nested package in the private part has no - limited view. GNAT always implemented this correctly. - - RM References: 10.01.01 (12.2/2) 10.01.01 (12.3/2) - -.. index:: AI-0132 (Ada 2012 feature) - -* *AI-0132 Placement of library unit pragmas (0000-00-00)* - - This AI fills a gap in the description of library unit pragmas. The pragma - clearly must apply to a library unit, even if it does not carry the name - of the enclosing unit. GNAT has always enforced the required check. - - RM References: 10.01.05 (7) - -.. index:: AI-0134 (Ada 2012 feature) - -* *AI-0134 Profiles must match for full conformance (0000-00-00)* - - For full conformance, the profiles of anonymous-access-to-subprogram - parameters must match. GNAT has always enforced this rule. - - RM References: 6.03.01 (18) - -.. index:: AI-0137 (Ada 2012 feature) - -* *AI-0137 String encoding package (2010-03-25)* - - The packages ``Ada.Strings.UTF_Encoding``, together with its child - packages, ``Conversions``, ``Strings``, ``Wide_Strings``, - and ``Wide_Wide_Strings`` have been - implemented. These packages (whose documentation can be found in the spec - files :file:`a-stuten.ads`, :file:`a-suenco.ads`, :file:`a-suenst.ads`, - :file:`a-suewst.ads`, :file:`a-suezst.ads`) allow encoding and decoding of - ``String``, ``Wide_String``, and ``Wide_Wide_String`` - values using UTF coding schemes (including UTF-8, UTF-16LE, UTF-16BE, and - UTF-16), as well as conversions between the different UTF encodings. With - the exception of ``Wide_Wide_Strings``, these packages are available in - Ada 95 and Ada 2005 mode as well as Ada 2012 mode. - The ``Wide_Wide_Strings`` package - is available in Ada 2005 mode as well as Ada 2012 mode (but not in Ada 95 - mode since it uses ``Wide_Wide_Character``). - - RM References: A.04.11 - -.. index:: AI-0139-2 (Ada 2012 feature) - -* *AI-0139-2 Syntactic sugar for iterators (2010-09-29)* - - The new syntax for iterating over arrays and containers is now implemented. - Iteration over containers is for now limited to read-only iterators. Only - default iterators are supported, with the syntax: ``for Elem of C``. - - RM References: 5.05 - -.. index:: AI-0146 (Ada 2012 feature) - -* *AI-0146 Type invariants (2009-09-21)* - - Type invariants may be specified for private types using the aspect notation. - Aspect ``Type_Invariant`` may be specified for any private type, - ``Type_Invariant'Class`` can - only be specified for tagged types, and is inherited by any descendent of the - tagged types. The invariant is a boolean expression that is tested for being - true in the following situations: conversions to the private type, object - declarations for the private type that are default initialized, and - [**in**] **out** - parameters and returned result on return from any primitive operation for - the type that is visible to a client. - GNAT defines the synonyms ``Invariant`` for ``Type_Invariant`` and - ``Invariant'Class`` for ``Type_Invariant'Class``. - - RM References: 13.03.03 (00) - -.. index:: AI-0147 (Ada 2012 feature) - -* *AI-0147 Conditional expressions (2009-03-29)* - - Conditional expressions are permitted. The form of such an expression is: - - :: - - (if expr then expr {elsif expr then expr} [else expr]) - - The parentheses can be omitted in contexts where parentheses are present - anyway, such as subprogram arguments and pragma arguments. If the **else** - clause is omitted, **else** *True* is assumed; - thus ``(if A then B)`` is a way to conveniently represent - *(A implies B)* in standard logic. - - RM References: 4.03.03 (15) 4.04 (1) 4.04 (7) 4.05.07 (0) 4.07 (2) - 4.07 (3) 4.09 (12) 4.09 (33) 5.03 (3) 5.03 (4) 7.05 (2.1/2) - -.. index:: AI-0152 (Ada 2012 feature) - -* *AI-0152 Restriction No_Anonymous_Allocators (2010-09-08)* - - Restriction ``No_Anonymous_Allocators`` prevents the use of allocators - where the type of the returned value is an anonymous access type. - - RM References: H.04 (8/1) - -.. index:: AI-0157 (Ada 2012 feature) - -* *AI-0157 Allocation/Deallocation from empty pool (2010-07-11)* - - Allocation and Deallocation from an empty storage pool (i.e. allocation or - deallocation of a pointer for which a static storage size clause of zero - has been given) is now illegal and is detected as such. GNAT - previously gave a warning but not an error. - - RM References: 4.08 (5.3/2) 13.11.02 (4) 13.11.02 (17) - -.. index:: AI-0158 (Ada 2012 feature) - -* *AI-0158 Generalizing membership tests (2010-09-16)* - - This AI extends the syntax of membership tests to simplify complex conditions - that can be expressed as membership in a subset of values of any type. It - introduces syntax for a list of expressions that may be used in loop contexts - as well. - - RM References: 3.08.01 (5) 4.04 (3) 4.05.02 (3) 4.05.02 (5) 4.05.02 (27) - -.. index:: AI-0161 (Ada 2012 feature) - -* *AI-0161 Restriction No_Default_Stream_Attributes (2010-09-11)* - - A new restriction ``No_Default_Stream_Attributes`` prevents the use of any - of the default stream attributes for elementary types. If this restriction is - in force, then it is necessary to provide explicit subprograms for any - stream attributes used. - - RM References: 13.12.01 (4/2) 13.13.02 (40/2) 13.13.02 (52/2) - -.. index:: AI-0162 (Ada 2012 feature) - -* *AI-0162 Incomplete type completed by partial view (2010-09-15)* - - Incomplete types are made more useful by allowing them to be completed by - private types and private extensions. - - RM References: 3.10.01 (2.5/2) 3.10.01 (2.6/2) 3.10.01 (3) 3.10.01 (4/2) - -.. index:: AI-0163 (Ada 2012 feature) - -* *AI-0163 Pragmas in place of null (2010-07-01)* - - A statement sequence may be composed entirely of pragmas. It is no longer - necessary to add a dummy ``null`` statement to make the sequence legal. - - RM References: 2.08 (7) 2.08 (16) - -.. index:: AI-0171 (Ada 2012 feature) - -* *AI-0171 Pragma CPU and Ravenscar Profile (2010-09-24)* - - A new package ``System.Multiprocessors`` is added, together with the - definition of pragma ``CPU`` for controlling task affinity. A new no - dependence restriction, on ``System.Multiprocessors.Dispatching_Domains``, - is added to the Ravenscar profile. - - RM References: D.13.01 (4/2) D.16 - -.. index:: AI-0173 (Ada 2012 feature) - -* *AI-0173 Testing if tags represent abstract types (2010-07-03)* - - The function ``Ada.Tags.Type_Is_Abstract`` returns ``True`` if invoked - with the tag of an abstract type, and ``False`` otherwise. - - RM References: 3.09 (7.4/2) 3.09 (12.4/2) - -.. index:: AI-0176 (Ada 2012 feature) - -* *AI-0176 Quantified expressions (2010-09-29)* - - Both universally and existentially quantified expressions are implemented. - They use the new syntax for iterators proposed in AI05-139-2, as well as - the standard Ada loop syntax. - - RM References: 1.01.04 (12) 2.09 (2/2) 4.04 (7) 4.05.09 (0) - -.. index:: AI-0177 (Ada 2012 feature) - -* *AI-0177 Parameterized expressions (2010-07-10)* - - The new Ada 2012 notion of parameterized expressions is implemented. The form - is: - - .. code-block:: ada - - function-specification is (expression) - - This is exactly equivalent to the - corresponding function body that returns the expression, but it can appear - in a package spec. Note that the expression must be parenthesized. - - RM References: 13.11.01 (3/2) - -.. index:: AI-0178 (Ada 2012 feature) - -* *AI-0178 Incomplete views are limited (0000-00-00)* - - This AI clarifies the role of incomplete views and plugs an omission in the - RM. GNAT always correctly restricted the use of incomplete views and types. - - RM References: 7.05 (3/2) 7.05 (6/2) - -.. index:: AI-0179 (Ada 2012 feature) - -* *AI-0179 Statement not required after label (2010-04-10)* - - It is not necessary to have a statement following a label, so a label - can appear at the end of a statement sequence without the need for putting a - null statement afterwards, but it is not allowable to have only labels and - no real statements in a statement sequence. - - RM References: 5.01 (2) - -.. index:: AI-0181 (Ada 2012 feature) - -* *AI-0181 Soft hyphen is a non-graphic character (2010-07-23)* - - From Ada 2005 on, soft hyphen is considered a non-graphic character, which - means that it has a special name (``SOFT_HYPHEN``) in conjunction with the - ``Image`` and ``Value`` attributes for the character types. Strictly - speaking this is an inconsistency with Ada 95, but in practice the use of - these attributes is so obscure that it will not cause problems. - - RM References: 3.05.02 (2/2) A.01 (35/2) A.03.03 (21) - -.. index:: AI-0182 (Ada 2012 feature) - -* *AI-0182 Additional forms for* ``Character'Value`` *(0000-00-00)* - - This AI allows ``Character'Value`` to accept the string ``'?'`` where - ``?`` is any character including non-graphic control characters. GNAT has - always accepted such strings. It also allows strings such as - ``HEX_00000041`` to be accepted, but GNAT does not take advantage of this - permission and raises ``Constraint_Error``, as is certainly still - permitted. - - RM References: 3.05 (56/2) - -.. index:: AI-0183 (Ada 2012 feature) - -* *AI-0183 Aspect specifications (2010-08-16)* - - Aspect specifications have been fully implemented except for pre and post- - conditions, and type invariants, which have their own separate AI's. All - forms of declarations listed in the AI are supported. The following is a - list of the aspects supported (with GNAT implementation aspects marked) - -==================================== =========== -Supported Aspect Source -==================================== =========== - ``Ada_2005`` -- GNAT - ``Ada_2012`` -- GNAT - ``Address`` - ``Alignment`` - ``Atomic`` - ``Atomic_Components`` - ``Bit_Order`` - ``Component_Size`` - ``Contract_Cases`` -- GNAT - ``Discard_Names`` - ``External_Tag`` - ``Favor_Top_Level`` -- GNAT - ``Inline`` - ``Inline_Always`` -- GNAT - ``Invariant`` -- GNAT - ``Machine_Radix`` - ``No_Return`` - ``Object_Size`` -- GNAT - ``Pack`` - ``Persistent_BSS`` -- GNAT - ``Post`` - ``Pre`` - ``Predicate`` - ``Preelaborable_Initialization`` - ``Pure_Function`` -- GNAT - ``Remote_Access_Type`` -- GNAT - ``Shared`` -- GNAT - ``Size`` - ``Storage_Pool`` - ``Storage_Size`` - ``Stream_Size`` - ``Suppress`` - ``Suppress_Debug_Info`` -- GNAT - ``Test_Case`` -- GNAT - ``Thread_Local_Storage`` -- GNAT - ``Type_Invariant`` - ``Unchecked_Union`` - ``Universal_Aliasing`` -- GNAT - ``Unmodified`` -- GNAT - ``Unreferenced`` -- GNAT - ``Unreferenced_Objects`` -- GNAT - ``Unsuppress`` - ``Value_Size`` -- GNAT - ``Volatile`` - ``Volatile_Components`` - ``Warnings`` -- GNAT -==================================== =========== - - Note that for aspects with an expression, e.g. ``Size``, the expression is - treated like a default expression (visibility is analyzed at the point of - occurrence of the aspect, but evaluation of the expression occurs at the - freeze point of the entity involved). - - RM References: 3.02.01 (3) 3.02.02 (2) 3.03.01 (2/2) 3.08 (6) - 3.09.03 (1.1/2) 6.01 (2/2) 6.07 (2/2) 9.05.02 (2/2) 7.01 (3) 7.03 - (2) 7.03 (3) 9.01 (2/2) 9.01 (3/2) 9.04 (2/2) 9.04 (3/2) - 9.05.02 (2/2) 11.01 (2) 12.01 (3) 12.03 (2/2) 12.04 (2/2) 12.05 (2) - 12.06 (2.1/2) 12.06 (2.2/2) 12.07 (2) 13.01 (0.1/2) 13.03 (5/1) - 13.03.01 (0) - -.. index:: AI-0185 (Ada 2012 feature) - -* *AI-0185 Ada.Wide_[Wide_]Characters.Handling (2010-07-06)* - - Two new packages ``Ada.Wide_[Wide_]Characters.Handling`` provide - classification functions for ``Wide_Character`` and - ``Wide_Wide_Character``, as well as providing - case folding routines for ``Wide_[Wide_]Character`` and - ``Wide_[Wide_]String``. - - RM References: A.03.05 (0) A.03.06 (0) - -.. index:: AI-0188 (Ada 2012 feature) - -* *AI-0188 Case expressions (2010-01-09)* - - Case expressions are permitted. This allows use of constructs such as: - - .. code-block:: ada - - X := (case Y is when 1 => 2, when 2 => 3, when others => 31) - - RM References: 4.05.07 (0) 4.05.08 (0) 4.09 (12) 4.09 (33) - -.. index:: AI-0189 (Ada 2012 feature) - -* *AI-0189 No_Allocators_After_Elaboration (2010-01-23)* - - This AI introduces a new restriction ``No_Allocators_After_Elaboration``, - which says that no dynamic allocation will occur once elaboration is - completed. - In general this requires a run-time check, which is not required, and which - GNAT does not attempt. But the static cases of allocators in a task body or - in the body of the main program are detected and flagged at compile or bind - time. - - RM References: D.07 (19.1/2) H.04 (23.3/2) - -.. index:: AI-0190 (Ada 2012 feature) - -* *AI-0190 pragma Default_Storage_Pool (2010-09-15)* - - This AI introduces a new pragma ``Default_Storage_Pool``, which can be - used to control storage pools globally. - In particular, you can force every access - type that is used for allocation (**new**) to have an explicit storage pool, - or you can declare a pool globally to be used for all access types that lack - an explicit one. - - RM References: D.07 (8) - -.. index:: AI-0193 (Ada 2012 feature) - -* *AI-0193 Alignment of allocators (2010-09-16)* - - This AI introduces a new attribute ``Max_Alignment_For_Allocation``, - analogous to ``Max_Size_In_Storage_Elements``, but for alignment instead - of size. - - RM References: 13.11 (16) 13.11 (21) 13.11.01 (0) 13.11.01 (1) - 13.11.01 (2) 13.11.01 (3) - -.. index:: AI-0194 (Ada 2012 feature) - -* *AI-0194 Value of Stream_Size attribute (0000-00-00)* - - The ``Stream_Size`` attribute returns the default number of bits in the - stream representation of the given type. - This value is not affected by the presence - of stream subprogram attributes for the type. GNAT has always implemented - this interpretation. - - RM References: 13.13.02 (1.2/2) - -.. index:: AI-0195 (Ada 2012 feature) - -* *AI-0195 Invalid value handling is implementation defined (2010-07-03)* - - The handling of invalid values is now designated to be implementation - defined. This is a documentation change only, requiring Annex M in the GNAT - Reference Manual to document this handling. - In GNAT, checks for invalid values are made - only when necessary to avoid erroneous behavior. Operations like assignments - which cannot cause erroneous behavior ignore the possibility of invalid - values and do not do a check. The date given above applies only to the - documentation change, this behavior has always been implemented by GNAT. - - RM References: 13.09.01 (10) - -.. index:: AI-0196 (Ada 2012 feature) - -* *AI-0196 Null exclusion tests for out parameters (0000-00-00)* - - Null exclusion checks are not made for ``out`` parameters when - evaluating the actual parameters. GNAT has never generated these checks. - - RM References: 6.04.01 (13) - -.. index:: AI-0198 (Ada 2012 feature) - -* *AI-0198 Inheriting abstract operators (0000-00-00)* - - This AI resolves a conflict between two rules involving inherited abstract - operations and predefined operators. If a derived numeric type inherits - an abstract operator, it overrides the predefined one. This interpretation - was always the one implemented in GNAT. - - RM References: 3.09.03 (4/3) - -.. index:: AI-0199 (Ada 2012 feature) - -* *AI-0199 Aggregate with anonymous access components (2010-07-14)* - - A choice list in a record aggregate can include several components of - (distinct) anonymous access types as long as they have matching designated - subtypes. - - RM References: 4.03.01 (16) - -.. index:: AI-0200 (Ada 2012 feature) - -* *AI-0200 Mismatches in formal package declarations (0000-00-00)* - - This AI plugs a gap in the RM which appeared to allow some obviously intended - illegal instantiations. GNAT has never allowed these instantiations. - - RM References: 12.07 (16) - -.. index:: AI-0201 (Ada 2012 feature) - -* *AI-0201 Independence of atomic object components (2010-07-22)* - - If an Atomic object has a pragma ``Pack`` or a ``Component_Size`` - attribute, then individual components may not be addressable by independent - tasks. However, if the representation clause has no effect (is confirming), - then independence is not compromised. Furthermore, in GNAT, specification of - other appropriately addressable component sizes (e.g. 16 for 8-bit - characters) also preserves independence. GNAT now gives very clear warnings - both for the declaration of such a type, and for any assignment to its components. - - RM References: 9.10 (1/3) C.06 (22/2) C.06 (23/2) - -.. index:: AI-0203 (Ada 2012 feature) - -* *AI-0203 Extended return cannot be abstract (0000-00-00)* - - A return_subtype_indication cannot denote an abstract subtype. GNAT has never - permitted such usage. - - RM References: 3.09.03 (8/3) - -.. index:: AI-0205 (Ada 2012 feature) - -* *AI-0205 Extended return declares visible name (0000-00-00)* - - This AI corrects a simple omission in the RM. Return objects have always - been visible within an extended return statement. - - RM References: 8.03 (17) - -.. index:: AI-0206 (Ada 2012 feature) - -* *AI-0206 Remote types packages and preelaborate (2010-07-24)* - - Remote types packages are now allowed to depend on preelaborated packages. - This was formerly considered illegal. - - RM References: E.02.02 (6) - -.. index:: AI-0207 (Ada 2012 feature) - -* *AI-0207 Mode conformance and access constant (0000-00-00)* - - This AI confirms that access_to_constant indication must match for mode - conformance. This was implemented in GNAT when the qualifier was originally - introduced in Ada 2005. - - RM References: 6.03.01 (16/2) - -.. index:: AI-0208 (Ada 2012 feature) - -* *AI-0208 Characteristics of incomplete views (0000-00-00)* - - The wording in the Ada 2005 RM concerning characteristics of incomplete views - was incorrect and implied that some programs intended to be legal were now - illegal. GNAT had never considered such programs illegal, so it has always - implemented the intent of this AI. - - RM References: 3.10.01 (2.4/2) 3.10.01 (2.6/2) - -.. index:: AI-0210 (Ada 2012 feature) - -* *AI-0210 Correct Timing_Events metric (0000-00-00)* - - This is a documentation only issue regarding wording of metric requirements, - that does not affect the implementation of the compiler. - - RM References: D.15 (24/2) - -.. index:: AI-0211 (Ada 2012 feature) - -* *AI-0211 No_Relative_Delays forbids Set_Handler use (2010-07-09)* - - The restriction ``No_Relative_Delays`` forbids any calls to the subprogram - ``Ada.Real_Time.Timing_Events.Set_Handler``. - - RM References: D.07 (5) D.07 (10/2) D.07 (10.4/2) D.07 (10.7/2) - -.. index:: AI-0214 (Ada 2012 feature) - -* *AI-0214 Defaulted discriminants for limited tagged (2010-10-01)* - - Ada 2012 relaxes the restriction that forbids discriminants of tagged types - to have default expressions by allowing them when the type is limited. It - is often useful to define a default value for a discriminant even though - it can't be changed by assignment. - - RM References: 3.07 (9.1/2) 3.07.02 (3) - -.. index:: AI-0216 (Ada 2012 feature) - -* *AI-0216 No_Task_Hierarchy forbids local tasks (0000-00-00)* - - It is clearly the intention that ``No_Task_Hierarchy`` is intended to - forbid tasks declared locally within subprograms, or functions returning task - objects, and that is the implementation that GNAT has always provided. - However the language in the RM was not sufficiently clear on this point. - Thus this is a documentation change in the RM only. - - RM References: D.07 (3/3) - -.. index:: AI-0219 (Ada 2012 feature) - -* *AI-0219 Pure permissions and limited parameters (2010-05-25)* - - This AI refines the rules for the cases with limited parameters which do not - allow the implementations to omit 'redundant'. GNAT now properly conforms - to the requirements of this binding interpretation. - - RM References: 10.02.01 (18/2) - -.. index:: AI-0220 (Ada 2012 feature) - -* *AI-0220 Needed components for aggregates (0000-00-00)* - - This AI addresses a wording problem in the RM that appears to permit some - complex cases of aggregates with nonstatic discriminants. GNAT has always - implemented the intended semantics. - - RM References: 4.03.01 (17) diff --git a/gcc/ada/doc/gnat_rm/implementation_of_ada_2022_features.rst b/gcc/ada/doc/gnat_rm/implementation_of_ada_2022_features.rst new file mode 100644 index 000000000000..f9ff06849ad6 --- /dev/null +++ b/gcc/ada/doc/gnat_rm/implementation_of_ada_2022_features.rst @@ -0,0 +1,2249 @@ +.. _Implementation_of_Ada_2022_Features: + +*********************************** +Implementation of Ada 2022 Features +*********************************** + +.. index:: Ada 2022 implementation status + +.. index:: -gnat22 option (gcc) + +.. index:: pragma Ada_2022 + +.. index:: configuration pragma Ada_2022 + +.. index:: Ada_2022 configuration pragma + +This chapter contains a complete list of Ada 2022 features that have been +implemented. Generally, these features are only available if the *-gnat22* (Ada 2022 features enabled) option is set, or if the configuration pragma ``Ada_2022`` is used. + +However, new pragmas, attributes, and restrictions are unconditionally available, since the Ada standard allows the addition of new pragmas, attributes, and restrictions (there are exceptions, which are +documented in the individual descriptions), and also certain packages +were made available in earlier versions of Ada. + +An ISO date (YYYY-MM-DD) appears in parentheses on the description line. +This date shows the implementation date of the feature. Any wavefront +subsequent to this date will contain the indicated feature, as will any +subsequent releases. A date of 0000-00-00 means that GNAT has always +implemented the feature, or implemented it as soon as it appeared as a +binding interpretation. + +Each feature corresponds to an Ada Issue ('AI') approved by the Ada +standardization group (ISO/IEC JTC1/SC22/WG9) for inclusion in Ada 2022. + +The section "RM references" lists all modified paragraphs in the Ada 2012 reference manual. The details of each modification as well as a complete description of the AIs may be found in +http://www.ada-auth.org/AI12-SUMMARY.HTML. + +.. index:: AI12-0001 (Ada 2022 feature) + +* *AI12-0001 Independence and Representation clauses for atomic objects (2019-11-27)* + + The compiler accepts packing clauses in all cases, even if they have effectively no influence on the layout. Types, where packing is essentially infeasible are, for instance atomic, aliased and by-reference types. + + RM references: 13.02 (6.1/2) 13.02 (7) 13.02 (8) 13.02 (9/3) C.06 (8.1/3) + C.06 (10) C.06 (11) C.06 (21) C.06 (24) + +.. index:: AI12-0003 (Ada 2022 feature) + +* *AI12-0003 Specifying the standard storage pool (2020-06-25)* + + Allows the standard storage pool being specified with a ``Default_Storage_Pool`` pragma or aspect. + + RM references: 8.02 (11) 13.11.03 (1/3) 13.11.03 (3.1/3) 13.11.03 (4/3) + 13.11.03 (4.1/3) 13.11.03 (5/3) 13.11.03 (6.2/3) 13.11.03 + (6.3/3) + +.. index:: AI12-0004 (Ada 2022 feature) + +* *AI12-0004 Normalization and allowed characters for identifiers (2020-06-11)* + + This AI clarifies that Ada identifiers containing characters which are not + allowed in Normalization Form KC are illegal. + + RM references: 2.01 (4.1/3) 2.03 (4/3) A.03.02 (4/3) A.03.02 (32.5/3) + A.03.05 (18/3) A.03.05 (51/3) + +.. index:: AI12-0020 (Ada 2022 feature) + +* *AI12-0020 'Image for all types (2020-03-30)* + + Put_Image prints out a human-readable representation of an object. The + functionality in Ada2022 RM is fully implemented except the support for + types in the ``Remote_Types`` packages. + + RM references: 4.10 (0) 3.05 (27.1/2) 3.05 (27.2/2) 3.05 (27.3/2) 3.05 + (27.4/2) 3.05 (27.5/2) 3.05 (27.6/2) 3.05 (27.7/2) 3.05 (28) 3.05 + (29) 3.05 (30/3) 3.05 (31) 3.05 (32) 3.05 (33/3) 3.05 (37.1/2) + 3.05 (38) 3.05 (39) 3.05 (43/3) 3.05 (55/3) 3.05 (55.1/5) 3.05 + (55.2/4) 3.05 (55.3/4) 3.05 (55.4/4) 3.05 (59) H.04 (23) H.04 (23.8/2) + +.. index:: AI12-0022 (Ada 2022 feature) + +* *AI12-0022 Raise_Expressions (2013-01-27)* + + This feature allows you to write "raise NAME [with STRING]" in an + expression to rise given exception. It is particularly useful in the case of + assertions such as preconditions allowing to specify which exception a + precondition raises if it fails. + + RM references: 4.04 (3/3) 11.02 (6) 11.03 (2/2) 11.03 (3) 11.03 (3.1/2) + 11.03 (4/2) 11.04.01 (10.1/3) + +.. index:: AI12-0027 (Ada 2022 feature) + +* *AI12-0027 Access values should never designate unaliased components (2020-06-15)* + + AI12-0027 adds a requirement for a value conversion that converts from an array of unaliased components to an array of aliased components to make a copy. It defines such conversions to have a local accessibility, effectively preventing the possibility of unsafe accesses to unaliased components. + + RM references: 4.06 (24.17/3) 4.06 (24.21/2) 4.06 (58) 6.02 (10/3) 3.10.02 (10/3) + +.. index:: AI12-0028 (Ada 2022 feature) + +* *AI12-0028 Import of variadic C functions (2020-03-03)* + + Ada programs can now properly call variadic C functions by means of the + conventions C_Variadic_<n>, for small integer values <n>. + + RM references: B.03 (1/3) B.03 (60.15/3) B.03 (75) + +.. index:: AI12-0030 (Ada 2022 feature) + +* *AI12-0030 Formal derived types and stream attribute availability (2020-08-21)* + + Corner cases involving streaming operations for formal derived limited types + that are now defined to raise Program_Error. Before, behavior in these cases + was undefined. Stream attribute availability is more precisely computed in cases where a derived type declaration occurs ahead of a streaming attribute specification for the parent type. + + RM references: 12.05.01 (21/3) 13.13.02 (49/2) + +.. index:: AI12-0031 (Ada 2022 feature) + +* *AI12-0031 All_Calls_Remote and indirect calls (0000-00-00)* + + Remote indirect calls (i.e., calls through a remote access-to-subprogram type) + behave the same as remote direct calls. + + RM references: E.02.03 (19/3) + +.. index:: AI12-0032 (Ada 2022 feature) + +* *AI12-0032 Questions on 'Old (2020-04-24)* + + AI12-0032 resolves several issues related to the 'Old attribute. The GNAT + compiler already implemented what the AI requires in most of those cases, but two having to do with static and dynamic checking of the accessibility level of the constant object implicitly declared for an 'Old attribute reference were not yet implemented. Accessibility checking for these constants is now implemented as defined in the AI. + + RM references: 4.01.03 (9/3) 6.01.01 (22/3) 6.01.01 (26/3) 6.01.01 (35/3) + +.. index:: AI12-0033 (Ada 2022 feature) + +* *AI12-0033 Sets of CPUs when defining dispatching domains (0000-00-00)* + + The set of CPUs associated with a dispatching domain is no longer required + to be a contiguous range of CPU values. + + RM references: D.16.01 (7/3) D.16.01 (9/3) D.16.01 (20/3) D.16.01 (23/3) + D.16.01 (24/3) D.16.01 (26/3) + +.. index:: AI12-0035 (Ada 2022 feature) + +* *AI12-0035 Accessibility checks for indefinite elements of containers (0000-00-00)* + + If the element type for an instance of one of the indefinite container generics has an access discriminant, then accessibility checks (at run-time) prevent inserting a value into a container object if the value's discriminant designates an object that is too short-lived (that is, if the designated object has an accessibility level that is deeper than that of the instance). Without this check, dangling references would be possible. GNAT handled this correctly already before this AI was issued. + + RM references: A.18 (5/3) A.18.11 (8/2) A.18.12 (7/2) A.18.13 (8/2) + A.18.14 (8/2) A.18.15 (4/2) A.18.16 (4/2) A.18.17 (7/3) A.18.18 + (39/3) A.18.18 (47/3) + +.. index:: AI12-0036 (Ada 2022 feature) + +* *AI12-0036 The actual for an untagged formal derived type cannot be tagged (2019-10-21)* + + AI12-0036 is a binding interpretation that adds the following legality rule: + The actual type for a formal derived type shall be tagged if and only if the + formal derived type is a private extension. The check is implemented for all Ada dialects, not just Ada 2022. + + RM references: 12.05.01 (5.1/3) + +.. index:: AI12-0037 (Ada 2022 feature) + +* *AI12-0037 New types in Ada.Locales can't be converted to/from strings (2016-09-10)* + + The type definitions for Language_Code and Country_Code are now using dynamic + predicates. + + RM references: A.19 (4/3) + +.. index:: AI12-0039 (Ada 2022 feature) + +* *AI12-0039 Ambiguity in syntax for membership expression removed (0000-00-00)* + + An ambiguity in the syntax for membership expressions was resolved. For example, "A in B and C" can be parsed in only one way because of this AI. + + RM references: 4.04 (3/3) 4.04 (3.2/3) 4.05.02 (3.1/3) 4.05.02 (4) 4.05.02 + (4.1/3) 4.05.02 (27/3) 4.05.02 (27.1/3) 4.05.02 (28.1/3) 4.05.02 + (28.2/3) 4.05.02 (29/3) 4.05.02 (30/3) 4.05.02 (30.1/3) 4.05.02 + (30.2/3) 4.05.02 (30.3/3) 4.09 (11/3) 4.09 (32.6/3) 8.06 (27.1/3) + 3.02.04 (17/3) + +.. index:: AI12-0040 (Ada 2022 feature) + +* *AI12-0040 Resolving the selecting_expression of a case_expression (0000-00-00)* + + The definition of "complete context" is corrected so that selectors of case expressions + and of case statements are treated uniformly. + + RM references: 8.06 (9) + +.. index:: AI12-0041 (Ada 2022 feature) + +* *AI12-0041 Type_Invariant'Class for interface types (2016-12-12)* + + Subprogram calls within class-wide type invariant expressions get resolved + as primitive operations instead of being dynamically dispatched. + + RM references: 7.03.02 (1/3) 7.03.02 (3/3) + +.. index:: AI12-0042 (Ada 2022 feature) + +* *AI12-0042 Type invariant checking rules (2020-06-05)* + + AI12-0042 adds rules for type invariants. + Specifically, when inheriting a private dispatching operation when the ancestor operation is visible at the point of the type extension, the operation must be abstract or else overridden. In addition, for a class-wide view conversion from an object of a specific type T to which a type invariant applies, an invariant check is performed when the conversion is within the immediate scope of T. + + RM references: 7.03.02 (6/3) 7.03.02 (17/3) 7.03.02 (18/3) 7.03.02 (19/3) + 7.03.02 (20/3) + +.. index:: AI12-0043 (Ada 2022 feature) + +* *AI12-0043 Details of the storage pool used when Storage_Size is specified (0000-00-00)* + + Clarify that a Storage_Size specification for an access type specifies both an upper bound and a lower bound (not just a lower bound) of the amount of storage allowed for allocated objects. + + RM references: 13.11 (18) + +.. index:: AI12-0044 (Ada 2022 feature) + +* *AI12-0044 Calling visible functions from type invariant expressions (2020-05-11)* + + AI05-0289-1 extends invariant checking to `in` parameters. However, this makes + it impossible to call a public function of the type from an invariant + expression, as that public function will attempt to check the invariant, + resulting in an infinite recursion. + + This AI specifies, that type-invariant checking is performed on parameters + of mode `in` upon return from procedure calls, but not of `in`-mode + parameters in functions. + + RM references: 7.03.02 (19/3) + +.. index:: AI12-0045 (Ada 2022 feature) + +* *AI12-0045 Pre- and Postconditions are allowed on generic subprograms (2015-03-17)* + + The SPARK toolset now supports contracts on generic subprograms, packages and + their respective bodies. + + RM references: 6.01.01 (1/3) + +.. index:: AI12-0046 (Ada 2022 feature) + +* *AI12-0046 Enforcing legality for anonymous access components in record aggregates (0000-00-00)* + + For a record aggregate of the form (X | Y => ....), any relevant legality rules are checked for both for X and Y. + + For example, + + .. code:: + + X : aliased constant String := ... ; + type R is record + F1 : access constant String; + F2 : access String; + end record; + Obj : R := (F1 | F2 => X'Access); -- ok for F1, but illegal for F2 + + RM references: 4.03.01 (16/3) + +.. index:: AI12-0047 (Ada 2022 feature) + +* *AI12-0047 Generalized iterators and discriminant-dependent components (0000-00-00)* + + Iterating over the elements of an array is subject to the same legality checks as renaming the array. For example, if an assignment to an enclosing discriminated object could cause an array object to cease to exist then we don't allow renaming the array. So it is similarly not allowed to iterate over the elements of such an array. + + RM references: 5.05.02 (6/3) + +.. index:: AI12-0048 (Ada 2022 feature) + +* *AI12-0048 Default behavior of tasks on a multiprocessor with a specified dispatching policy (0000-00-00)* + + Clarify that if the user does not impose requirements about what CPUs a given task might execute on, then the implementation does not get to impose such requirements. This avoids potential problems with priority inversion. + + RM references: D.16.01 (30/3) + +.. index:: AI12-0049 (Ada 2022 feature) + +* *AI12-0049 Invariants need to be checked on the initialization of deferred constants (0000-00-00)* + + Invariant checking for deferred constants (and subcomponents thereof) is performed. Corrects a clear oversight in the previous RM wording. + + RM references: 7.03.02 (10/3) + +.. index:: AI12-0050 (Ada 2022 feature) + +* *AI12-0050 Conformance of quantified expressions (2016-07-22)* + + Compiler rejects a subprogram body when an expression for a boolean formal + parameter includes a quantified expression, and the subprogram declaration + contains a textual copy of the same. + + RM references: 6.03.01 (20) 6.03.01 (21) + +.. index:: AI12-0051 (Ada 2022 feature) + +* *AI12-0051 The Priority aspect can be specified when Attach_Handler is specified (0000-00-00)* + + Previous RM wording had two contradictory rules for determining (in some cases) the priority of a protected subprogram that is attached to an interrupt. The AI clarifies which one of the rules takes precedence. + + RM references: D.03 (10/3) + +.. index:: AI12-0052 (Ada 2022 feature) + +* *AI12-0052 Implicit objects are considered overlapping (0000-00-00)* + + Clarify that the rules about unsynchronized concurrent access apply as one would expect in the case of predefined routines that access Text_IO's default input and default output files. There was no compiler changes needed to implement this. + + RM references: A (3/2) A.10.03 (21) + +.. index:: AI12-0054-2 (Ada 2022 feature) + +* *AI12-0054-2 Aspect Predicate_Failure (0000-00-00)* + + New aspect Predicate_Failure is defined. A solution for the problem that a predicate like + + .. code:: + + subtype Open_File is File with Dynamic_Predicate =\> Is_Open (Open_File) or else (raise File_Not_Open); + + does the wrong thing in the case of a membership test. + + RM references: 3.02.04 (14/3) 3.02.04 (31/3) 3.02.04 (35/3) + +.. index:: AI12-0055 (Ada 2022 feature) + +* *AI12-0055 All properties of a usage profile are defined by pragmas (2020-06-09)* + + AI12-0055 allows the use of the No_Dynamic_CPU_Assignment restriction in pragmas Restrictions and Restrictions_Warnings. + + RM references: D.07 (10/3) D.13 (6/3) D.13 (8/3) D.13 (10/3) + +.. index:: AI12-0059 (Ada 2022 feature) + +* *AI12-0059 Object_Size attribute (2019-12-02)* + + AI12-0059 brings GNAT-defined attribute Object_Size to Ada standard + and clarifies its semantics. Given that the attribute already existed in + GNAT compiler, the feature is supported for all language versions. + + RM references: 4.09.01 (2/3) 13.01 (14) 13.01 (23) 13.03 (9/3) 13.03 + (50/2) 13.03 (51) 13.03 (52) 13.03 (58) + +.. index:: AI12-0061 (Ada 2022 feature) + +* *AI12-0061 Iterated component associations in array aggregates (2016-09-01)* + + Ada issue AI12-061 introduces a new construct in array aggregates allowing + component associations to be parameterized by a loop variable, for example: + + .. code:: + + Array (1 .. 10) of Integer := + (for I in 1 .. 10 => I ** 2); + type Matrix is + array + (Positive range <>, Positive range <>) of Float; + G : constant Matrix + := + (for I in 1 .. 4 => + (for J in 1 .. 4 => + (if I=J then + 1.0 else 0.0))); -- Identity matrix + + The expression in such an association can also be a function that returns a + limited type, and the range can be specified by the 'others' choice. + + RM references: 4.03.03 (5/2) 4.03.03 (6) 4.03.03 (17/3) 4.03.03 (20) + 4.03.03 (23.1/4) 4.03.03 (32/3) 4.03.03 (43) 3.01 (6/3) 3.03 (6) + 3.03 (18.1/3) 3.03.01 (23/3) 5.05 (6) 8.01 (2.1/4) + +.. index:: AI12-0062 (Ada 2022 feature) + +* *AI12-0062 Raise exception with failing string function (0000-00-00)* + + Clarify that if raising exception E1 is accompanied with a String-valued + expression whose evaluation raises exception E2, then E2 is what gets propagated. + + RM references: 11.03 (4/2) + +.. index:: AI12-0065 (Ada 2022 feature) + +* *AI12-0065 Descendants of incomplete views (0000-00-00)* + + This AI is a clarification of potentially confusing wording. GNAT correctly handles the example given in AARM 7.3.1(5.b-5.d), which illustrates the topic of this AI. + + RM references: 7.03.01 (5.2/3) + +.. index:: AI12-0067 (Ada 2022 feature) + +* *AI12-0067 Accessibility level of explicitly aliased parameters of procedures and entries (0000-00-00)* + + The AI fixes a case where the intent was fairly obvious but the RM wording failed to mention a case (with the result that the accessibility level of an explicitly aliased parameter of a procedure or entry was undefined even though the intent was clear). + + RM references: 3.10.02 (7/3) + +.. index:: AI12-0068 (Ada 2022 feature) + +* *AI12-0068 Predicates and the current instance of a subtype (2020-05-06)* + + AI12-0068 is a binding interpretation that defines the current instance name in a type or subtype aspect to be a value rather than an object. This affects + attributes whose prefix is a current instance in predicates, type invariants, and ``Default_Initial_Condition`` aspects. In particular, in the case of the ``Constrained`` attribute the value will always be True, and formerly legal attributes that require an object as their prefix (such as ``Size``, ``Access``, ``Address``, etc.) are illegal when applied to a current instance in type and subtype aspects. + + RM references: 8.06 (17/3) + +.. index:: AI12-0069 (Ada 2022 feature) + +* *AI12-0069 Inconsistency in Tree container definition (0000-00-00)* + + The description of how iteration over a Tree container's elements was contradictory in some cases regarding whether a cursor designating the Root node is included in the iteration. This contradiction was resolved. In the "!ACATS Test" section of the AI, it says that if an implementation were to get this wrong then almost any attempt to iterate over any tree would fail at runtime. + + RM references: A.18.10 (153/3) A.18.10 (155/3) A.18.10 (157/3) A.18.10 (159/3) + +.. index:: AI12-0070 (Ada 2022 feature) + +* *AI12-0070 9.3(2) does not work for anonymous access types (0000-00-00)* + + The RM contained some old wording about the master of an allocated object that only made sense for named access types. The AI clarifies the wording to clearly state the scope of validity and ensures that the paragraph does not contradict 3.10.2's rules for anonymous access types. + + RM references: 3.10.02 (13.1/3) 9.03 (2) + +.. index:: AI12-0071 (Ada 2022 feature) + +* *AI12-0071 Order of evaluation when multiple predicates apply (2015-08-10)* + + AI12-0071 specifies the semantics of multiple/inherited predicates on a + single subtype. + + RM references: 3.02.04 (4/3) 3.02.04 (6/3) 3.02.04 (30/3) 3.02.04 (31/3) + 3.02.04 (32/3) 3.02.04 (33/3) 3.02.04 (35/3) 3.05.05 (7.1/3) + 3.05.05 (7.2/3) 3.05.05 (7.3/3) 3.08.01 (10.1/3) 3.08.01 (15/3) + 4.05.02 (29/3) 4.05.02 (30/3) 4.06 (51/3) 4.09.01 (10/3) 5.04 + (7/3) 5.05 (9/3) 13.09.02 (3/3) 13.09.02 (12) + +.. index:: AI12-0072 (Ada 2022 feature) + +* *AI12-0072 Missing rules for Discard_Names aspect (0000-00-00)* + + Clarify that Discard_Names is an aspect, not just a pragma. + + RM references: C.05 (1) C.05 (5) C.05 (7/2) C.05 (8) + +.. index:: AI12-0073 (Ada 2022 feature) + +* *AI12-0073 Synchronous Barriers are not allowed with Ravenscar (2020-02-24)* + + Ada 2022 adds (as a binding interpretation) a ``No_Dependence => + Ada.Synchronous_Barriers`` restriction to the Ravenscar profile. + + RM references: D.13 (6/3) + +.. index:: AI12-0074 (Ada 2022 feature) + +* *AI12-0074 View conversions and out parameters passed by copy (2020-03-26)* + + This Ada 2022 AI makes illegal some cases of out parameters whose type has a + ``Default_Value`` aspect. + + RM references: 4.06 (56) 6.04.01 (6.25/3) 6.04.01 (13.1/3) + +.. index:: AI12-0075 (Ada 2022 feature) + +* *AI12-0075 Static expression functions (2020-04-13)* + + Ada 2022 defines a new aspect ``Static`` that can be specified on expression + functions. Such an expression function can be called in contexts requiring static expressions when the actual parameters are all static, allowing for greater abstraction in complex static expressions. + + RM references: 4.09 (21) 6.08 (3/4) 6.08 (5/4) 6.08 (6/4) 7.03.02 (8.2/5) + 7.03.02 (15/4) 7.03.02 (16/4) 7.03.02 (17/4) 7.03.02 (19/4) + 7.03.02 (20/5) + +.. index:: AI12-0076 (Ada 2022 feature) + +* *AI12-0076 Variable state in pure packages (0000-00-00)* + + Defines an obscure constant-modifying construct to be erroneous. The issue is that the current instance of a type is a variable object, so the following is legal: + + .. code:: + + type T; + type T_Ref (Access_To_Variable : access T) is null record; + type T is limited record + Self : T_Ref (T'Access); + Int : Integer; + end record; + + Obj : constant T := (Self => <>, Int => 123); + begin + Obj.Self.Access_To_Variable.Int := 456; -- modifying a component of a constant + + In cases where constancy is really needed (e.g., for an object declared in a Pure context), such a case needs to be erroneous. + + RM references: 10.02.01 (17/3) E.02.02 (17/2) + +.. index:: AI12-0077 (Ada 2022 feature) + +* *AI12-0077 Has_Same_Storage on objects of size zero (2020-03-30)* + + This binding interpretation requires the Has_Same_Storage attribute + to return always `false` for objects that have a size of zero. + + RM references: 13.03 (73.4/3) + +.. index:: AI12-0078 (Ada 2022 feature) + +* *AI12-0078 Definition of node for tree container is confusing (0000-00-00)* + + Clarifies the expected behavior in processing tree containers. + + RM references: A.18.10 (2/3) A.18.10 (3/3) + +.. index:: AI12-0081 (Ada 2022 feature) + +* *AI12-0081 Real-time aspects need to specify when they are evaluated (0000-00-00)* + + Clarify the point at which Priority and Interrupt_Priority aspect expressions are evaluated. + + RM references: D.01 (17/3) D.16 (9/3) + +.. index:: AI12-0084 (Ada 2022 feature) + +* *AI12-0084 Box expressions in array aggregates (2014-12-15)* + + This AI addresses an issue where compiler used to fail to initialize + components of a multidimensional aggregates with box initialization when + scalar components have a specified default value. The AI clarifies that + in an array aggregate with box (i.e., ``<>``) component values, the + ``Default_Component_Value`` of the array type (if any) should not be ignored. + + RM references: 4.03.03 (23.1/2) + +.. index:: AI12-0085 (Ada 2022 feature) + +* *AI12-0085 Missing aspect cases for Remote_Types (0000-00-00)* + + A distributed systems annex (Annex E) clarification. Aspect specifications + that are forbidden using attribute definition clause syntax are also forbidden + using aspect_specification syntax. + + RM references: E.02.02 (17/2) + +.. index:: AI12-0086 (Ada 2022 feature) + +* *AI12-0086 Aggregates and variant parts (2019-08-14)* + + In Ada 2012, a discriminant value that governs an active variant part in an + aggregate had to be static. AI12-0086 relaxes this restriction: If the subtype of the discriminant value is a static subtype all of whose values select the same variant, then the expression for the discriminant is allowed to be nonstatic. + + RM references: 4.03.01 (17/3) 4.03.01 (19/3) + +.. index:: AI12-0088 (Ada 2022 feature) + +* *AI12-0088 UTF_Encoding.Conversions and overlong characters on input (0000-00-00)* + + Clarify that overlong characters are acceptable on input even if we never generate them as output. + + RM references: A.04.11 (54/3) A.04.11 (55/3) + +.. index:: AI12-0089 (Ada 2022 feature) + +* *AI12-0089 Accessibility rules need to take into account that a generic function is not a (0000-00-00)* + + Fix cases in RM wording where the accessibility rules for a function failed to take into account the fact that a generic function is not a function. For example, a generic function with an explicitly aliased parameter should be able to return references to that parameter in the same ways that a (non-generic) function can. The previous wording did not allow that. + + RM references: 3.10.02 (7/3) 3.10.02 (19.2/3) 3.10.02 (19.3/3) 6.05 (4/3) + +.. index:: AI12-0093 (Ada 2022 feature) + +* *AI12-0093 Iterator with indefinite cursor (0000-00-00)* + + A clarification that confirms what GNAT is already doing. + + RM references: 5.05.02 (8/3) 5.05.02 (10/3) + +.. index:: AI12-0094 (Ada 2022 feature) + +* *AI12-0094 An access_definition should be a declarative region (0000-00-00)* + + Fixes wording omission in the RM, confirming that the behaviour of GNAT is + correct. + + RM references: 8.03 (2) 8.03 (26/3) + +.. index:: AI12-0095 (Ada 2022 feature) + +* *AI12-0095 Generic formal types and constrained partial views (0000-00-00)* + + Deciding whether an actual parameter corresponding to an explicitly aliased formal parameter is legal depends on (among other things) whether the parameter type has a constrained partial view. The AI clarifies how this compile-time checking works in the case of a generic formal type (assume the best in the spec and recheck each instance, assume the worst in a generic body). + + RM references: 3.10.02 (27.2/3) 4.06 (24.16/2) 6.04.01 (6.2/3) 12.05.01 (15) + +.. index:: AI12-0096 (Ada 2022 feature) + +* *AI12-0096 The exception raised when a subtype conversion fails a predicate check (0000-00-00)* + + Clarify that the Predicate_Failure aspect works the same in a subtype conversion as in any other context. + + RM references: 4.06 (57/3) + +.. index:: AI12-0097 (Ada 2022 feature) + +* *AI12-0097 Tag of the return object of a simple return expression (0000-00-00)* + + Clarify wording about the tag of a function result in the case of a simple (i.e. not extended) return statement in a function with a class-wide result type. + + RM references: 6.05 (8/3) + +.. index:: AI12-0098 (Ada 2022 feature) + +* *AI12-0098 Problematic examples for ATC (0000-00-00)* + + The AI clarifies reference manual examples, there is no compiler impact. + + RM references: 9.07.04 (13) + +.. index:: AI12-0099 (Ada 2022 feature) + +* *AI12-0099 Wording problems with predicates (2020-05-04)* + + When extending a task or protected type from an ancestor interface subtype with a predicate, a link error can occur due to the compiler failing to generate the predicate-checking function. This AI clarifies the requirement for such predicate inheritance for concurrent types. + + RM references: 3.02.04 (4/4) 3.02.04 (12/3) 3.02.04 (20/3) + +.. index:: AI12-0100 (Ada 2022 feature) + +* *AI12-0100 A qualified expression makes a predicate check (2020-02-17)* + + The compiler now enforces predicate checks on qualified expressions when the + qualifying subtype imposes a predicate. + + RM references: 4.07 (4) + +.. index:: AI12-0101 (Ada 2022 feature) + +* *AI12-0101 Incompatibility of hidden untagged record equality (2019-10-31)* + + AI12-0101 is a binding interpretation that removes a legality rule that + prohibited the declaration of a primitive equality function for a private type in the private part of its enclosing package (either before or after the completion of the type) when the type is completed as an untagged record type. Such declarations are now accepted in Ada 2012 and later Ada versions. + + As a consequence of this work, some cases where the implementation of AI05-0123 was incomplete were corrected. + More specifically, if a user-defined equality operator is present for an untagged record type in an Ada 2012 program, that user-defined equality operator will be (correctly) executed in some difficult-to-characterize cases where the predefined component-by-component comparison was previously being (incorrectly) executed. This can arise, for example, in the case of the predefined equality operation for an enclosing composite type that has a component of the user-defined primitive equality op's operand type. + This correction means that the impact of this change is not limited solely to code that was previously rejected at compile time. + + RM references: 4.05.02 (9.8/3) + +.. index:: AI12-0102 (Ada 2022 feature) + +* *AI12-0102 Stream_IO.File_Type has Preelaborable_Initialization (0000-00-00)* + + Modifies the declaration of one type in a predefined package. GNAT's version of ``Ada.Streams.Stream_IO`` already had this modification (the ``Preelaborable__Initialization`` pragma). + + RM references: A.12.01 (5) + +.. index:: AI12-0103 (Ada 2022 feature) + +* *AI12-0103 Expression functions that are completions in package specifications (0000-00-00)* + + Clarifies that expression functions that are completions do not cause "general" freeze-everybody-in-sight freezing like a subprogram body. + + RM references: 13.14 (3/3) 13.14 (5/3) + +.. index:: AI12-0104 (Ada 2022 feature) + +* *AI12-0104 Overriding an aspect is undefined (0000-00-00)* + + A clarification of the wording in RM, no compiler impact. + + RM references: 4.01.06 (4/3) 4.01.06 (17/3) + +.. index:: AI12-0105 (Ada 2022 feature) + +* *AI12-0105 Pre and Post are not allowed on any subprogram completion (0000-00-00)* + + Language-defined aspects (e.g., ``Post``) cannot be specified as part of the completion of a subprogram declaration. Fix a hole in the RM wording to clarify that this general rule applies even in the special cases where the completion is either an expression function or a null procedure. + + RM references: 13.01.01 (18/3) + +.. index:: AI12-0106 (Ada 2022 feature) + +* *AI12-0106 Write'Class aspect (0000-00-00)* + + Clarify that the syntax used in an ACATS test BDD2005 for specifying a class-wide streaming aspect is correct. + + RM references: 13.01.01 (28/3) 13.13.02 (38/3) + +.. index:: AI12-0107 (Ada 2022 feature) + +* *AI12-0107 A prefixed view of a By_Protected_Procedure interface has convention protected (2020-06-05)* + + A prefixed view of a subprogram with aspect Synchronization set to + By_Protected_Procedure has convention protected. + + RM references: 6.03.01 (10.1/2) 6.03.01 (12) 6.03.01 (13) + +.. index:: AI12-0109 (Ada 2022 feature) + +* *AI12-0109 Representation of untagged derived types (2019-11-12)* + + Ada disallows a nonconforming specification of a type-related representation + aspect of an untagged by-reference type. The motivation for this rule is to ensure that a parent type and a later type derived from the parent agree with respect to such aspects. AI12-0109 disallows a construct that otherwise could be used to get around this rule: an aspect specification for the parent type that occurs after the declaration of the derived type. + + RM references: 13.01 (10/3) + +.. index:: AI12-0110 (Ada 2022 feature) + +* *AI12-0110 Tampering checks are performed first (2020-04-14)* + + AI12-0110 requires tampering checks in the containers library to be + performed first, before any other checks. + + RM references: A.18.02 (97.1/3) A.18.03 (69.1/3) A.18.04 (15.1/3) A.18.07 + (14.1/3) A.18.10 (90/3) A.18.18 (35/3) + +.. index:: AI12-0112 (Ada 2022 feature) + +* *AI12-0112 Contracts for container operations (0000-00-00)* + + A representation change replacing english descriptions of contracts for + operations on predefined container types with pre/post-conditions. No compiler + impact. + + RM references: A.18.02 (99/3) 11.04.02 (23.1/3) 11.05 (23) 11.05 (26) A + (4) A.18 (10) + +.. index:: AI12-0114 (Ada 2022 feature) + +* *AI12-0114 Overlapping objects designated by access parameters are not thread-safe (0000-00-00)* + + There are rules saying that concurrent calls to predefined subprograms don't interfere with each other unless actual parameters overlap. The AI clarifies that such an interference is also possible if overlapping objects are reachable via access dereferencing from actual parameters of the two calls. + + RM references: A (3/2) + +.. index:: AI12-0116 (Ada 2022 feature) + +* *AI12-0116 Private types and predicates (0000-00-00)* + + Clarify that the same aspect cannot be specified twice for the same type. ``Dynamic_Predicate``, for example, can be specified on either the partial view of a type or on the completion in the private part, but not on both. + + RM references: 13.01 (9/3) 13.01 (9.1/3) + +.. index:: AI12-0117 (Ada 2022 feature) + +* *AI12-0117 Restriction No_Tasks_Unassigned_To_CPU (2020-06-12)* + + This AI adds a restriction No_Tasks_Unassigned_To_CPU to provide safe + use of Ravenscar. + + The CPU aspect is specified for the environment task. No CPU aspect is + specified to be statically equal to ``Not_A_Specific_CPU``. If aspect CPU + is specified (dynamically) to the value ``Not_A_Specific_CPU``, then + Program_Error is raised. If Set_CPU or ``Delay_Until_And_Set_CPU`` are called + with the CPU parameter equal to ``Not_A_Specific_CPU``, then ``Program_Error`` is raised. + + RM references: D.07 (10.8/3) + +.. index:: AI12-0120 (Ada 2022 feature) + +* *AI12-0120 Legality and exceptions of generalized loop iteration (0000-00-00)* + + Clarify that the expansion-based definition of generalized loop iteration + includes legality checking. If the expansion would be illegal (for example, + because of passing a constant actual parameter in a call when the mode of + the corresponding formal parameter is in-out), then the loop is illegal too. + + RM references: 5.05.02 (6.1/4) 5.05.02 (10/3) 5.05.02 (13/3) + +.. index:: AI12-0121 (Ada 2022 feature) + +* *AI12-0121 Stream-oriented aspects (0000-00-00)* + + Clarify that streaming-oriented aspects (e.g., Read) can be specified using + aspect_specification syntax, not just via an attribute definition clause. + + RM references: 13.13.02 (38/3) + +.. index:: AI12-0124 (Ada 2022 feature) + +* *AI12-0124 Add Object'Image (2017-03-24)* + + The corrigendum of Ada 2012 extends attribute ``'Image following`` the syntax for the GNAT ``'Img`` attribute. This AI fixes a gap in the earlier implementation, which did not recognize function calls and attributes that are functions as valid object prefixes. + + RM references: 3.05 (55/3) + +.. index:: AI12-0125-3 (Ada 2022 feature) + +* *AI12-0125-3 Add @ as an abbreviation for the LHS of an assignment (2016-11-11)* + + This AI introduces the use of the character '@' as an abbreviation for the left-hand side of an assignment statement, usable anywhere within the expression on the right-hand side. To use this feature the compilation flag -gnat2022 must be specified. + + RM references: 5.02.01 (0) 2.02 (9) 3.03 (21.1/3) 4.01 (2/3) 8.06 (9/4) + +.. index:: AI12-0127 (Ada 2022 feature) + +* *AI12-0127 Partial aggregate notation (2016-10-12)* + + This AI describes a new constructor for aggregates, in terms of an existing record or array object, and a series of component-wise modifications of its value, given by named associations for the modified components. To use this feature the compilation flag ``-gnat2022`` must be specified. + + RM references: 4.03 (2) 4.03 (3/2) 4.03 (4) 4.03.01 (9) 4.03.01 (15/3) + 4.03.01 (16/4) 4.03.01 (17/5) 4.03.01 (17.1/2) 4.03.03 (4) 4.03.03 + (14) 4.03.03 (17/5) 4.03.04 (0) 7.05 (2.6/2) + +.. index:: AI12-0128 (Ada 2022 feature) + +* *AI12-0128 Exact size access to parts of composite atomic objects (2019-11-24)* + + According to this AI, the compiler generates full access to atomic composite objects even if the access is only partial in the source code. To use this feature the compilation flag ``-gnat2022`` must be specified. + + RM references: C.06 (13.2/3) C.06 (19) C.06 (20) C.06 (22/2) C.06 (25/4) + +.. index:: AI12-0129 (Ada 2022 feature) + +* *AI12-0129 Make protected objects more protecting (2020-07-01)* + + A new aspect Exclusive_Functions has been added to the language to force the + use of read/write locks on protected functions when needed. + + RM references: 9.05.01 (2) 9.05.01 (4) 9.05.01 (5) 9.05.01 (7) 9.05.03 + (15) 9.05.03 (23) + +.. index:: AI12-0130 (Ada 2022 feature) + +* *AI12-0130 All I/O packages should have Flush (2016-07-03)* + + The Flush routine has been added for the ``Sequential_IO`` and ``Direct_IO`` standard packages in the Ada 2012 COR.1:2016. The Flush routine here is equivalent to the one found in ``Text_IO``. The ``Flush`` procedure synchronizes the external file with the internal file (by flushing any internal buffers) without closing the file. + + RM references: A.08.01 (10) A.08.02 (28/3) A.08.04 (10) A.10.03 (21) + A.12.01 (28/2) A.12.01 (28.6/1) + +.. index:: AI12-0131 (Ada 2022 feature) + +* *AI12-0131 Inherited Pre'Class when unspecified on initial subprogram (0000-00-00)* + + If T1 is a tagged type with a primitive P that has no class-wide precondition, + and if T2 is an extension of T1 which overrides the inherited primitive P, then that overriding P is not allowed to have a class-wide precondition. Allowing it would be ineffective except in corner cases where it would be confusing. + + RM references: 6.01.01 (17/3) 6.01.01 (18/3) + +.. index:: AI12-0132 (Ada 2022 feature) + +* *AI12-0132 Freezing of renames-as-body (2020-06-13)* + + This AI clarifies that a renames-as-body freezes the expression of any + expression function that it renames. + + RM references: 13.14 (5/3) + +.. index:: AI12-0133 (Ada 2022 feature) + +* *AI12-0133 Type invariants and default initialized objects (0000-00-00)* + + Clarify that invariant checking for a default-initialized object is performed regardless of where the object is declared (in particular, even when the full view of the type is visible). + + RM references: 7.03.02 (10.3/3) + +.. index:: AI12-0135 (Ada 2022 feature) + +* *AI12-0135 Enumeration types should be eligible for convention C (0000-00-00)* + + Ada previously allowed but did not require supporting specifying convention C for an enumeration type. Now it is required that an implementation shall support it. + + RM references: B.01 (14/3) B.01 (41/3) B.03 (65) + +.. index:: AI12-0136 (Ada 2022 feature) + +* *AI12-0136 Language-defined packages and aspect Default_Storage_Pool (0000-00-00)* + + Clarify that the effect of specifying Default_Storage_Pool for an instance of a predefined generic is implementation-defined. No compiler impact. + + RM references: 13.11.03 (5/3) + +.. index:: AI12-0137 (Ada 2022 feature) + +* *AI12-0137 Incomplete views and access to class-wide types (0000-00-00)* + + If the designated type of an access type is incomplete when the access type is declared, then we have rules about whether we get a complete view when a value of the access type is dereferenced. Clarify that analogous rules apply if the designated type is class-wide. + + RM references: 3.10.01 (2.1/2) + +.. index:: AI12-0138 (Ada 2022 feature) + +* *AI12-0138 Iterators of formal derived types (2021-02-11)* + + AI12-0138 specifies the legality rules for confirming specifications of + nonoverridable aspects. This completes the legality checks for aspect ``Implicit_Dereference`` and simplifies the checks for those aspects that are inherited operations. + + RM references: 13.01.01 (18/4) 13.01.01 (34/3) 4.01.05 (6/3) 4.01.06 (5/3) + 4.01.06 (6/3) 4.01.06 (7/3) 4.01.06 (8/3) 4.01.06 (9/3) 5.05.01 (11/3) + +.. index:: AI12-0140 (Ada 2022 feature) + +* *AI12-0140 Access to unconstrained partial view when full view is constrained (0000-00-00)* + + Clarify some confusion about about whether what matters when checking whether designated subtypes statically match is the view of the designated type that is currently available v.s. the view that was available when the access type was declared. + + RM references: 3.02 (7/2) 7.03.01 (5/1) + +.. index:: AI12-0143 (Ada 2022 feature) + +* *AI12-0143 Using an entry index of a family in a precondition (2022-04-05)* + + Ada 2022 adds the ``Index`` attribute, which allows the use of the entry family index of an entry call within preconditions and post-conditions. + + RM references: 6.01.01 (30/3) 9.05.04 (5/3) + +.. index:: AI12-0144 (Ada 2022 feature) + +* *AI12-0144 Make Discrete_Random more flexible (2020-01-31)* + + A new function Random with First/Last parameters is provided in the + ``Ada.Numerics.Discrete_Random`` package. + + RM references: A.05.02 (20) A.05.02 (32) A.05.02 (41) A.05.02 (42) + +.. index:: AI12-0145 (Ada 2022 feature) + +* *AI12-0145 Pool_of_Subpool returns null when called too early (0000-00-00)* + + Clarify that if you ask for the pool of a subpool (by calling ``Pool_Of_Subpool``) before ``Set_Pool_of_Subpool`` is called, then the result is null. + + RM references: 13.11.04 (20/3) + +.. index:: AI12-0147 (Ada 2022 feature) + +* *AI12-0147 Expression functions and null procedures can be declared in a protected_body (2015-03-05)* + + AI12-0147 specifies that null procedures and expression functions are now + allowed in protected bodies. + + RM references: 9.04 (8/1) + +.. index:: AI12-0149 (Ada 2022 feature) + +* *AI12-0149 Type invariants are checked for functions returning access-to-type (0000-00-00)* + + Extend the rule saying that ``Type_Invariant`` checks are performed for access-to-T parameters (where T has a specified ``Type_Invariant``) so that the rule also applies to function results. + + RM references: 7.03.02 (19.3/4) + +.. index:: AI12-0150 (Ada 2022 feature) + +* *AI12-0150 Class-wide type invariants and statically bound calls (0000-00-00)* + + The same approach used in AI12-0113 to ensure that contract-related calls associated with a call to a subprogram "match" with respect to dispatching also applies to ``Type_Invariant`` checking. + + RM references: 7.03.02 (3/3) 7.03.02 (5/3) 7.03.02 (9/3) 7.03.02 (22/3) + +.. index:: AI12-0154 (Ada 2022 feature) + +* *AI12-0154 Aspects of library units (0000-00-00)* + + Clarify that an aspect_specification for a library unit is equivalent to a corresponding aspect-specifying pragma. + + RM references: 13.01.01 (32/3) + +.. index:: AI12-0156 (Ada 2022 feature) + +* *AI12-0156 Use subtype_indication in generalized iterators (0000-00-00)* + + For iterating over an array, we already allow (but do not require) explicitly providing a subtype indication in an iterator_specification. Tee AI generalizes this to handle the case where the element type of the array is of an anonymous access type. This also allows (but does not require) explicitly naming the cursor subtype in a generalized iterator. + The main motivation for allowing these new cases is improving readability by making it easy to infer the (sub)type of the iteration object just by looking at the loop. + + RM references: 5.05.02 (2/3) 5.05.02 (5/4) 5.05.02 (7/3) 3.10.02 (11.1/2) + +.. index:: AI12-0157 (Ada 2022 feature) + +* *AI12-0157 Missing rules for expression functions (0000-00-00)* + + Clarify that an expression function behaves like a single-return-statement + function in more cases: it can return an aggregate without extra parens, the expression has an applicable index constraint, and the same accessibility rules apply in both cases. + + For instance, the code below is legal: + + .. code:: + + subtype S is String (1 .. 10); + function f return S is (others => '?'); + + RM references: 3.10.02 (19.2/4) 3.10.02 (19.3/4) 4.03.03 (11/2) 6.08 (2/3) + 6.08 (3/3) 6.08 (5/3) 6.08 (6/3) 6.08 (7/3) 7.05 (2.9/3) 13.14 + (5.1/4) 13.14 (5.2/4) 13.14 (8/3) 13.14 (10.1/3) 13.14 (10.2/3) + 13.14 (10.3/3) + +.. index:: AI12-0160 (Ada 2022 feature) + +* *AI12-0160 Adding an indexing aspect to an indexable container type (0000-00-00)* + + If the parent type of a derived type has exactly one of the two indexing aspects (that is, constant_indexing and variable_indexing) specified, then the derived type cannot have a specification for the other one. + + RM references: 4.01.06 (6/4) 4.01.06 (9/4) 3.06 (22.2/3) + +.. index:: AI12-0162 (Ada 2022 feature) + +* *AI12-0162 Memberships and Unchecked_Unions (0000-00-00)* + + Clarify that membership tests for unchecked_union types work consistently when + testing membership in more than one subtype (X in AA | BB | CC) as when + testing for one. + + RM references: B.03.03 (25/2) + +.. index:: AI12-0164 (Ada 2022 feature) + +* *AI12-0164 Max_Entry_Queue_Length aspect for entries (2019-06-11)* + + AI12-0164 defines pragma and aspect ``Max_Entry_Queue_Length`` in addition + to the GNAT-specific equivalents ``Max_Queue_Length`` and ``Max_Entry_Queue_Depth``. + + RM references: D.04 (16) + +.. index:: AI12-0165 (Ada 2022 feature) + +* *AI12-0165 Operations of class-wide types and formal abstract subprograms (2021-10-19)* + + Ada 2022 specifies that when the controlling type of a formal abstract + subprogram declaration is a formal type, and the actual type is a class-wide type T'Class, the actual subprogram can be an implicitly declared subprogram corresponding to a primitive operation of type T. + + RM references: 12.06 (8.5/2) + +.. index:: AI12-0166 (Ada 2022 feature) + +* *AI12-0166 External calls to protected functions that appear to be internal calls (2016-11-15)* + + According to this AI, the compiler rejects a call to a protected operation when the call appears within a precondition for another protected operation. + + RM references: 6.01.01 (34/3) 9.05 (3/3) 9.05 (7.1/3) + +.. index:: AI12-0167 (Ada 2022 feature) + +* *AI12-0167 Type_Invariants and tagged-type View Conversions (0000-00-00)* + + This AI clarifies that no invariant check is performed in a case where an invariant-violating value is assigned to a component. This confirms the current compiler behavior. + + RM references: 7.03.02 (9/4) + +.. index:: AI12-0168 (Ada 2022 feature) + +* *AI12-0168 Freezing of generic instantiations of generics with bodies (0000-00-00)* + + Adjust freezing rules to be compatible with AI12-0103-1. The change confirms the current compiler behavior. + + RM references: 13.14 (3/4) + +.. index:: AI12-0169 (Ada 2022 feature) + +* *AI12-0169 Aspect specifications for entry bodies (0000-00-00)* + + Change syntax to allow aspect specifications for implementation-defined aspects on entry bodies. The change doesn't influence any of the language-defined aspects and is solely required for SPARK. + + RM references: 9.05.02 (5) + +.. index:: AI12-0170 (Ada 2022 feature) + +* *AI12-0170 Abstract subprogram calls in class-wide precondition expressions (2020-07-06)* + + This AI specifies rules for calls to abstract functions within class-wide preconditions and postconditions. + + RM references: 3.09.03 (7) 6.01.01 (7/4) 6.01.01 (18/4) 6.01.01 (18.2/4) + +.. index:: AI12-0172 (Ada 2022 feature) + +* *AI12-0172 Raise expressions in limited contexts (2019-07-29)* + + The compiler has been enhanced to support the use of raise expressions in + limited contexts. + + RM references: 7.05 (2.1/3) + +.. index:: AI12-0173 (Ada 2022 feature) + +* *AI12-0173 Expression of an extended return statement (0000-00-00)* + + Fix the wording related to expression of an extended return statement that was made ambiguous by changes of syntax in other AI's. No compiler changes involved. + + RM references: 6.05 (3/2) 6.05 (5/3) + +.. index:: AI12-0174 (Ada 2022 feature) + +* *AI12-0174 Aggregates of Unchecked_Unions using named notation (0000-00-00)* + + In many cases, it is illegal to name a discriminant of an unchecked_union type. Relax this rule to allow the use of named notation in an aggregate of an unchecked_union type. + + RM references: B.03.03 (9/3) + +.. index:: AI12-0175 (Ada 2022 feature) + +* *AI12-0175 Preelaborable packages with address clauses (2020-03-20)* + + The compiler nows accepts calls to certain functions that are essentially unchecked conversions in preelaborated library units. To use this feature the compilation flag ``-gnat2022`` must be specified. + + RM references: 10.02.01 (7) + +.. index:: AI12-0179 (Ada 2022 feature) + +* *AI12-0179 Failure of postconditions of language-defined units (0000-00-00)* + + A clarification that expressing postconditions for predefined units via RM wording or via ``Post`` aspect specifications are equivalent. In particular, the expression in such a ``Post`` aspect specification should not yield False. No implementation changes needed. + + RM references: 1.01.03 (17/3) 11.04.02 (23.1/3) + +.. index:: AI12-0180 (Ada 2022 feature) + +* *AI12-0180 Using protected subprograms and entries within an invariant (2020-06-22)* + + AI12-0180 makes entries and protected subprograms directly visible within Invariant aspects of a task or protected type. + + RM references: 13.01.01 (12/3) + +.. index:: AI12-0181 (Ada 2022 feature) + +* *AI12-0181 Self-referencing representation aspects (0000-00-00)* + + Clarify that a name or expression which freezes an entity cannot occur in an aspect specification for that entity. + + RM references: 13.01 (9/4) 13.01 (9.1/4) 13.14 (19) + +.. index:: AI12-0182 (Ada 2022 feature) + +* *AI12-0182 Pre'Class and protected operations (0000-00-00)* + + Confirm that Pre'Class and Post'Class cannot be specified for a protected operation. No language change. + + RM references: 13.01.01 (16/3) + +.. index:: AI12-0184 (Ada 2022 feature) + +* *AI12-0184 Long Long C Data Types (2020-01-30)* + + Two new types ``long_long`` and ``unsigned_long_long`` are introduced in the package ``Interfaces.C``. + + RM references: B.03 (71.3/3) + +.. index:: AI12-0185 (Ada 2022 feature) + +* *AI12-0185 Resolution of postcondition-specific attributes (0000-00-00)* + + Clarify resolution rules for ``'Old`` and ``'Result`` attribute references to match original intent. + + RM references: 6.01.01 (7/4) 6.01.01 (8/3) 6.01.01 (26.10/4) 6.01.01 (29/3) + +.. index:: AI12-0186 (Ada 2022 feature) + +* *AI12-0186 Profile freezing for the Access attribute (0000-00-00)* + + Clarify that the use of Some_Subprogram'Access does not freeze the profile of Some_Subprogram. + + RM references: 13.14 (15) + +.. index:: AI12-0187 (Ada 2022 feature) + +* *AI12-0187 Stable properties of abstract data types (2020-11-04)* + + Ada 2022 defines a new aspect, ``Stable_Properties``, for use in + generating additional postcondition checks for subprograms. + + RM references: 7.03.04 (0) 13.01.01 (4/3) + +.. index:: AI12-0191 (Ada 2022 feature) + +* *AI12-0191 Clarify "part" for type invariants (0000-00-00)* + + Clarify that for purposes of determining whether an invariant check is required for a "part" of an object, we do not look at "parts" which do not correspond to "parts" of the nominal type of the object. For example, if we have a parameter Param of a tagged type T1 (or equivalently of type T1'Class), and type T2 is an extension of T1 which declares a component Foo, and T1'Class (Param)'Tag = T2'Tag, then no invariant check is performed for Param's Foo component (or any subcomponent thereof). + + RM references: 3.03 (23/5) 3.09.01 (4.1/2) 6.08 (5.8/5) 7.03.02 (8.3/5) + 7.03.02 (8.4/5) 7.03.02 (8.5/5) 7.03.02 (8.6/5) 7.03.02 (8.7/5) + 7.03.02 (8.8/5) 7.03.02 (8.9/5) 7.03.02 (8.10/5) 7.03.02 (8.11/5) + 7.03.02 (8.12/5) 7.03.02 (10.1/4) 7.03.02 (15/5) 7.03.02 (17/4) + 7.03.02 (18/4) 7.03.02 (19/4) 13.13.02 (9/3) + +.. index:: AI12-0192 (Ada 2022 feature) + +* *AI12-0192 "requires late initialization" and protected types (2020-03-11)* + + This AI clarifies that components of a protected type require late initialization when their initialization references (implicitly) the current instance of the type. + + RM references: 3.03.01 (8.1/2) + +.. index:: AI12-0194 (Ada 2022 feature) + +* *AI12-0194 Language-defined aspects and entry bodies (0000-00-00)* + + The AI Includes entry bodies on the list of bodies for which no language-defined aspects can be specified (although specifying an implementation-defined aspect may be allowed). + + A wording change, no implementation impact. + + RM references: 13.01.01 (17/3) + +.. index:: AI12-0195 (Ada 2022 feature) + +* *AI12-0195 Inheriting body but overriding precondition or postcondition (2021-08-11)* + + Ada 2022 specifies that if a primitive with a class-wide precondition or + postcondition is inherited, and some primitive function called in the class-wide precondition or postcondition is overridden, then a dispatching call to the first primitive with a controlling operand that has the tag of the overriding type is required to check both the interpretation using the overriding function and the interpretation using the original overridden function. + + RM references: 6.01.01 (38/4) + +.. index:: AI12-0196 (Ada 2022 feature) + +* *AI12-0196 Concurrent access to Ada container libraries (0000-00-00)* + + Clarify that parallel execution of operations which use cursors to refer to different elements of the same container does not violate the rules about erroneous concurrent access in some cases. That is, if C1 and C2 are cursors that refer to different elements of some container, then it is ok to concurrently execute an operation that is passed C1 and which accesses one element of the container, with another operation (perhaps the same operation, perhaps not) that is passed C2 and which accesses another element of the container. + + RM references: A.18 (2/2) A.18.02 (125/2) A.18.02 (133/3) A.18.02 (135/3) + A.18.03 (81/3) A.18.04 (36/3) A.18.07 (34/2) A.18.10 (116/3) + +.. index:: AI12-0198 (Ada 2022 feature) + +* *AI12-0198 Potentially unevaluated components of array aggregates (2020-05-13)* + + Ada 2022 enforces the detection of components that belong to a nonstatic or + null range of index values of an array aggregate. + + RM references: 6.01.01 (22.1/4) + +.. index:: AI12-0199 (Ada 2022 feature) + +* *AI12-0199 Abstract subprogram calls in class-wide invariant expressions (0000-00-00)* + + Class-wide type invariants do not apply to abstract types, to avoid various + problems. Define the notion of a "corresponding expression" for a class-wide + type invariant, replacing references to components as appropriate, taking into + account rules for corresponding and specified discriminants when applying them + to a nonabstract descendant. + + RM references: 7.03.02 (5/4) 7.03.02 (8/3) + +.. index:: AI12-0201 (Ada 2022 feature) + +* *AI12-0201 Missing operations of static string types (2020-02-25)* + + Relational operators and type conversions of static string types are now static in Ada 2022. + + RM references: 4.09 (9) 4.09 (19) 4.09 (20) 4.09 (24) + +.. index:: AI12-0203 (Ada 2022 feature) + +* *AI12-0203 Overriding a nonoverridable aspect (0000-00-00)* + + A corner case wording clarification that has no impact on compilers. + + RM references: 4.01.05 (5.1/4) 4.01.05 (7/3) + +.. index:: AI12-0204 (Ada 2022 feature) + +* *AI12-0204 Renaming of a prefixed view (2020-02-24)* + + AI12-0204 clarifies that the prefix of a prefixed view that is renamed or + passed as a formal subprogram must be renameable as an object. + + RM references: 8.05.04 (5.2/2) 12.06 (8.3/2) 4.01.03 (13.1/2) 4.01.06 (9/5) + +.. index:: AI12-0205 (Ada 2022 feature) + +* *AI12-0205 Defaults for generic formal types (2021-04-01)* + + AI12-0205 specifies syntax and semantics that provide defaults for formal types of generic units. The legality rules guarantee that the default subtype_mark that is specified for a formal type would be a legal actual in any instantiation of the generic unit. + + RM references: 12.03 (7/3) 12.03 (10) 12.05 (2.1/3) 12.05 (2.2/3) 12.05 (7/2) + +.. index:: AI12-0206 (Ada 2022 feature) + +* *AI12-0206 Nonoverridable should allow arbitrary kinds of aspects (0000-00-00)* + + A non-overridable aspect can have a value other than a name; for example, ``Max_Entry_Queue_Length`` is non-overridable and it has a scalar value. + Part of adding support for ``Max_Entry_Queue_Length`` (which is already supported by GNAT). + + RM references: 13.01.01 (18.2/4) 13.01.01 (18.3/4) 13.01.01 (18.6/4) + +.. index:: AI12-0207 (Ada 2022 feature) + +* *AI12-0207 Convention of anonymous access types (2020-02-01)* + + The convention of anonymous access elements of arrays now have the same convention as the array instead of convention Ada. + + RM references: 6.03.01 (13.1/3) B.01 (19) B.01 (21/3) + +.. index:: AI12-0208 (Ada 2022 feature) + +* *AI12-0208 Predefined Big numbers support (0000-00-00)* + + Add predefined package ``Ada.Numerics.Big_Numbers``. + + RM references: A.05.05 (0) A.05.06 (0) A.05.07 (0) + +.. index:: AI12-0211 (Ada 2022 feature) + +* *AI12-0211 Interface types and inherited nonoverridable aspects (2020-08-24)* + + AI12-0211 introduces two new legality rules for Ada 2022. The first says that + if a nonoverridable aspect is explicitly specified for a type that also inherits that aspect from another type (an ancestor or a progenitor), then the explicit aspect specification shall be confirming. The second says that if a type inherits a nonoverridable aspect from two different sources (this can only occur if at least one of the two is an interface type), then the two sources shall agree with respect to the given aspect. This AI is a binding interpretation, so these checks are performed even for earlier Ada versions. Because of compatibility concerns, an escape mechanism for suppressing these legality checks is provided: these new checks always pass if the ``-gnatd.M`` switch (relaxed RM semantics) is specified. + + RM references: 13.01.01 (18.3/5) 13.01.01 (18.4/4) + +.. index:: AI12-0212 (Ada 2022 feature) + +* *AI12-0212 Container aggregates; generalized array aggregates (0000-00-00)* + + The AI defines a new feature: generalized array aggregates that already exists in GNAT. + + RM references: 4.03.05 (0) 1.01.04 (12) 1.01.04 (13) 2.01 (15) 2.02 (9/5) + 3.07.01 (3) 3.08.01 (4) 4.03 (2/5) 4.03 (3/5) 4.03.01 (5) 4.03.03 + (3/2) 4.03.03 (4/5) 4.03.03 (5.1/5) 4.03.03 (9) 4.03.03 (17/5) + 4.03.03 (21) 4.03.03 (23.2/5) 4.03.03 (26) 4.03.03 (27) 4.03.03 + (31) 4.03.04 (4/5) 4.04 (3.1/3) 11.02 (3) 13.01.01 (5/3) + 13.01.01 (7/3) A.18.02 (8/3) A.18.02 (14/2) A.18.02 (47/2) A.18.02 + (175/2) A.18.03 (6/3) A.18.05 (3/3) A.18.06 (4/3) A.18.08 (3/3) + A.18.09 (4/3) + +.. index:: AI12-0216 (Ada 2022 feature) + +* *AI12-0216 6.4.1(6.16-17/3) should never apply to composite objects (0000-00-00)* + + Fix wording so that parameter passing cases where there isn't really any aliasing problems or evaluation order dependency are classified as acceptable. + + No compiler impact. + + RM references: 6.04.01 (6.17/3) + +.. index:: AI12-0217 (Ada 2022 feature) + +* *AI12-0217 Rules regarding restrictions on the use of the Old attribute are too strict (2020-03-25)* + + AI12-0217 loosens the rules regarding what is allowed as the prefix of a 'Old + attribute reference. In particular, a prefix is now only required to "statically name" (as opposed to the previous "statically denote") an object. This means that components of composite objects that previously would have been illegal are now legal prefixes. + + RM references: 6.01.01 (24/3) 6.01.01 (27/3) + +.. index:: AI12-0220 (Ada 2022 feature) + +* *AI12-0220 Pre/Post for access-to-subprogram types (2020-04-14)* + + Contract aspects can now be specified for access-to-subprogram types, as + defined for Ada 2022 in this AI. + + RM references: 6.01.01 (1/4) 6.01.01 (2/3) 6.01.01 (4/3) 6.01.01 (19/3) + 6.01.01 (28/3) 6.01.01 (29/3) 6.01.01 (39/3) 13.01.01 (12/5) + +.. index:: AI12-0222 (Ada 2022 feature) + +* *AI12-0222 Representation aspects and private types (0000-00-00)* + + Clarify that the rule against specifying a representation aspect for a type before the type is completely defined also applies in the case where aspect_specification syntax is used (not just in the case where a pragma or some other kind of representation item is used). + + GNAT already implements this. + + RM references: 13.01 (9/5) 13.01 (9.1/4) 13.01 (9.2/5) + +.. index:: AI12-0225 (Ada 2022 feature) + +* *AI12-0225 Prefix of Obj'Image (0000-00-00)* + + Clarify some Object vs. Value corner cases to allow names that do not denote objects in more contexts, such as a qualified expression as a prefix of an Image attribute. + + RM references: 3.05 (55.1/4) + +.. index:: AI12-0226 (Ada 2022 feature) + +* *AI12-0226 Make objects more consistent (0000-00-00)* + + Allow value conversions as objects. For instance this example becomes legal: ``Long_Integer (Duration'Last)'Image``. + + RM references: 3.03 (11.1/3) 3.03 (21.1/3) 3.03 (23.8/5) 4.06 (58.1/4) + 4.06 (58.3/4) + +.. index:: AI12-0227 (Ada 2022 feature) + +* *AI12-0227 Evaluation of nonstatic universal expressions when no operators are involved (0000-00-00)* + + Nonstatic universal integer expressions are always evaluated at runtime as values of type root_integer; similarly, nonstatic universal real expressions are always evaluated at runtime as values of type root_real. + This AI corrects a wording oversight. Previously, the above was only true if a call to operator was involved. With this change it is true in all cases. + + No compiler impact. + + RM references: 4.04 (10) 8.06 (29) + +.. index:: AI12-0228 (Ada 2022 feature) + +* *AI12-0228 Properties of qualified expressions used as names (2020-02-19)* + + This AI clarifies that properties of a qualified object pass through a + qualified expression used as a name. Specifically, "aliased" and "known to be + constrained" are not changed by a qualified expression. + + RM references: 3.03 (23.7/3) 3.10 (9/3) + +.. index:: AI12-0231 (Ada 2022 feature) + +* *AI12-0231 Null_Task_Id and Activation_Is_Complete (0000-00-00)* + + Add ``Activation_Is_Complete`` to the list of functions that raise P_E if passed ``Null_Task_Id``, correcting an oversight. + + RM references: C.07.01 (15) + +.. index:: AI12-0232 (Ada 2022 feature) + +* *AI12-0232 Rules for pure generic bodies (0000-00-00)* + + Clarify the rules for a generic body nested in a pure library unit. + + RM references: 10.02.01 (9/3) 10.02.01 (15.1/3) 10.02.01 (15.5/3) + +.. index:: AI12-0233 (Ada 2022 feature) + +* *AI12-0233 Pre'Class for hidden operations of private types (0000-00-00)* + + Clarify how ``Pre'Class`` checking interacts with private-part overriding of inherited subprograms. A class-wide precondition can be checked at runtime even if it is specified in a private part that the caller cannot see into. + + RM references: 6.01.01 (38/4) + +.. index:: AI12-0234 (Ada 2022 feature) + +* *AI12-0234 Compare-and-swap for atomic objects (0000-00-00)* + + New predefined units for atomic operations (``System.Atomic_Operations`` and child units thereof). + + RM references: C.06.01 (0) C.06.02 (0) + +.. index:: AI12-0235 (Ada 2022 feature) + +* *AI12-0235 System.Storage_Pools should be pure (0000-00-00)* + + Change the predefined package System.Storage_Pools from preelaborated to pure. + + RM references: 13.11 (5) + +.. index:: AI12-0236 (Ada 2022 feature) + +* *AI12-0236 declare expressions (2020-04-08)* + + A ``declare expression`` allows constant objects and renamings to be + declared within an expression. + + RM references: 2.08 (6) 3.09.02 (3) 3.10.02 (9.1/3) 3.10.02 (16.1/3) + 3.10.02 (32.2/3) 4.03.02 (5.4/3) 4.03.03 (15.1/3) 4.04 (7/3) + 4.05.09 (0) 6.02 (10/4) 7.05 (2.1/5) 8.01 (2.1/4) + +.. index:: AI12-0237 (Ada 2022 feature) + +* *AI12-0237 Getting the representation of an enumeration value (2020-01-31)* + + The GNAT-specific attributes ``Enum_Rep`` and ``Enum_Val`` have been standardized and are now also supported as Ada 2022 attributes. + + RM references: 13.04 (10) 13.04 (11/3) + +.. index:: AI12-0242 (Ada 2022 feature) + +* *AI12-0242 Shorthand Reduction Expressions for Objects (0000-00-00)* + + Allow reduction expressions to iterate over an an array or an iterable object without having to explicitly create a value sequence. + + This allows, for instance, writing ``A'Reduce("+", 0)`` instead of the equivalent (but more verbose) ``[for Value of A => Value]'Reduce("+", 0);``. + + RM references: 4.05.10 (0) 4.01.04 (6) + +.. index:: AI12-0247 (Ada 2022 feature) + +* *AI12-0247 Potentially Blocking goes too far for Detect_Blocking (0000-00-00)* + + During a protected action, a call on a subprogram that contains a potentially blocking operation is considered a bounded error (so raising P_E is optional). + This rule imposed an unreasonable implementation burden. + The new rule introduced by this AI allows ignoring (i.e., not detecting) the problem until execution of a potentially blocking operation is actually attempted. + + RM references: 9.05 (55/5) 9.05 (56/5) 9.05.01 (18/5) H.05 (5/2) + +.. index:: AI12-0249 (Ada 2022 feature) + +* *AI12-0249 User-defined numeric literals (2020-04-07)* + + Compiler support is added for three new aspects (``Integer_Literal``, ``Real_Literal``, and ``String_Literal``) as described in AI12-0249 (for ``Integer_Literal`` and ``Real_Literal``), AI12-0295 (for ``String_Literal``), and in two follow-up AIs (AI12-0325 and AI12-0342). For pre-Ada 2022 versions of Ada, these are treated as implementation-defined + aspects. Some implementation work remains, particularly in the interactions between these aspects and tagged types. + + RM references: 4.02 (9) 4.02.01 (0) 4.09 (3) + +.. index:: AI12-0250 (Ada 2022 feature) + +* *AI12-0250 Iterator Filters (2020-05-19)* + + This AI defines Ada 2022 feature of iterator filters, which can be + applied to loop parameter specifications and iterator specifications. + + RM references: 4.03.03 (21) 4.03.03 (26) 4.03.03 (31) 4.03.05 (0) 4.05.10 + (0) 5.05 (4) 5.05 (7) 5.05 (9/4) 5.05 (9.1/4) 5.05 (10) + 5.05.02 (2/3) 5.05.02 (10/3) 5.05.02 (11/3) + +.. index:: AI12-0252 (Ada 2022 feature) + +* *AI12-0252 Duplicate interrupt handlers under Ravenscar (2018-07-05)* + + Ada Issue AI12-0252 requires that the runtime shall terminate with a + Program_Error when more than one interrupt handler is attached to the same interrupt and the restriction No_Dynamic_Attachment is in effect. + + RM references: C.03.01 (13) + +.. index:: AI12-0256 (Ada 2022 feature) + +* *AI12-0256 Aspect No_Controlled_Parts (2021-01-26)* + + The compiler now supports the Ada 2022 aspect No_Controlled_Parts (see + AI12-0256). When specified for a type, this aspect requires that the type and any of its ancestors must not have any controlled parts. + + RM references: H.04.01 (0) 13.01.01 (18.7/5) + +.. index:: AI12-0258 (Ada 2022 feature) + +* *AI12-0258 Containers and controlled element types (0000-00-00)* + + Most predefined containers are allowed to defer finalization of container elements until the finalization of the container. This allows implementation flexibility but causes problems in some cases. AI12-0258 tightens up the rules for the indefinite containers to say that finalization happens earlier - if a client needs the tighter finalization guarantees, then it can use the indefinite containers (even if the element subtype in question is definite). Other solutions involving the holder generic are also possible. + + GNAT implements these tighter element finalization requirements for instances of the indefinite container generics. + + RM references: A.18 (10/4) + +.. index:: AI12-0259 (Ada 2022 feature) + +* *AI12-0259 Lower bound of strings returned from Ada.Command_Line (0000-00-00)* + + Specify that the low-bound of a couple of predefined String-valued functions will always be one. + + RM references: A.15 (14) A.15 (16/3) + +.. index:: AI12-0260 (Ada 2022 feature) + +* *AI12-0260 Functions Is_Basic and To_Basic in Wide_Characters.Handling (2020-04-01)* + + AI12-0260 is implemented for Ada 2022, providing the new functions ``Is_Basic`` and ``To_Basic`` in package ``Ada.Wide_Characters.Handling``. + + RM references: 1.02 (8/3) A.03.05 (8/3) A.03.05 (20/3) A.03.05 (21/3) + A.03.05 (33/3) A.03.05 (61/3) + +.. index:: AI12-0261 (Ada 2022 feature) + +* *AI12-0261 Conflict in "private with" rules (0000-00-00)* + + If a library unit is only visible at some point because of a "private with", there are legality rules about a name denoting that entity. The AI cleans up the wording so that it captures the intent in a corner case involving a private-child library-unit subprogram. The previous wording incorrectly caused this case to be illegal. + + RM references: 10.01.02 (12/3) 10.01.02 (13/2) 10.01.02 (14/2) 10.01.02 + (15/2) 10.01.02 (16/2) + +.. index:: AI12-0262 (Ada 2022 feature) + +* *AI12-0262 Map-Reduce attribute (0000-00-00)* + + The AI defines Reduction Expressions to allow the programmer to apply the + Map-Reduce paradigm to map/transform a set of values to a new set of values, + and then summarize/reduce the transformed values into a single result value. + + RM references: 4.01.04 (1) 4.01.04 (6) 4.01.04 (11) 4.05.10 (0) + +.. index:: AI12-0263 (Ada 2022 feature) + +* *AI12-0263 Update references to ISO/IEC 10646 (0000-00-00)* + + Change RM references to ISO/IEC 10646:2011 to instead refer to ISO/IEC 10646:2017. No compiler impact. + + RM references: 1.01.04 (14.2/3) 2.01 (1/3) 2.01 (3.1/3) 2.01 (4/3) 2.01 + (4.1/5) 2.01 (5/3) 2.01 (15/3) 2.01 (4.1/5) 2.01 (5/3) 2.03 + (4.1/5) 2.03 (5/3) 3.05.02 (2/3) 3.05.02 (3/3) 3.05.02 (4/3) A.01 + (36.1/3) A.01 (36.2/3) A.03.02 (32.6/5) A.03.05 (51.2/5) A.03.05 + (55/3) A.03.05 (59/3) A.04.10 (3/3) B.05 (21/5) + +.. index:: AI12-0264 (Ada 2022 feature) + +* *AI12-0264 Overshifting and overrotating (0000-00-00)* + + Clarify Shift and Rotate op behavior with large shift/rotate amounts. + + RM references: B.02 (9) + +.. index:: AI12-0265 (Ada 2022 feature) + +* *AI12-0265 Default_Initial_Condition for types (2020-11-13)* + + The aspect ``Default_Initial_Condition``, originally proposed by SPARK and + supported in GNAT, is now also included in Ada 2022. One change from the + original implementation is that when the aspect is specified on ancestor types of a derived type, the ancestors' check expressions also apply to the derived type. + ``Default_Initial_Condition`` checks are also now applied in cases of default + initialization of components, allocators, ancestor parts of extension aggregates, and box associations of aggregates. + + RM references: 7.03.03 (0) 1.01.03 (17.1/5) 11.04.02 (23.2/5) 11.04.02 (23.3/5) + +.. index:: AI12-0269 (Ada 2022 feature) + +* *AI12-0269 Aspect No_Return for functions reprise (2020-03-19)* + + This amendment has been implemented under the ``-gnat2022`` switch, and the + compiler now accepts the aspect/pragma No_Return for functions and generic + functions. + + RM references: 6.05.01 (0) 6.05.01 (1/3) 6.05.01 (3.1/3) 6.05.01 (3.4/3) + 6.05.01 (5/2) 6.05.01 (6/2) 6.05.01 (7/2) J.15.02 (2/3) J.15.02 + (3/3) J.15.02 (4/3) + +.. index:: AI12-0272 (Ada 2022 feature) + +* *AI12-0272 (part 1) Pre/Postconditions for formal subprograms (0000-00-00)* + + Pre and Post aspects can be specified for a generic formal subprogram. ``Default_Initial_Condition`` can be specified for a generic formal private type. + + GNAT implements this with an exception of the part related to ``Default_Initial_Condition``. + + RM references: 6.01.01 (1/5) 6.01.01 (39/5) 7.03.03 (1/5) 7.03.03 (2/5) + 7.03.03 (8/5) 7.03.04 (5/5) F.01 (1) + +.. index:: AI12-0275 (Ada 2022 feature) + +* *AI12-0275 Make subtype_mark optional in object renames (2020-01-28)* + + AI12-0275 allows object renamings to be declared without an explicit + subtype_mark or access_definition. This feature can be used by compiling + with the switch ``-gnat2022``. + + RM references: 8.05.01 (2/3) 8.05.01 (3/2) + +.. index:: AI12-0277 (Ada 2022 feature) + +* *AI12-0277 The meaning of "accessibility level of the body of F" (0000-00-00)* + + Clarify that the only time that an explicitly aliased formal parameter has different accessibility properties than an aliased part of a "normal" parameter is for the accessibility checking associated with a return statement. + + RM references: 3.10.02 (19.2/4) + +.. index:: AI12-0278 (Ada 2022 feature) + +* *AI12-0278 Implicit conversions of anonymous return types (0000-00-00)* + + If a call to a function with an anonymous-access-type result is converted to a named access type, it doesn't matter whether the conversion is implicit or explicit. the AI fixes hole where the previous rules didn't cover the implicit conversion case. + + RM references: 3.10.02 (10.3/3) + +.. index:: AI12-0279 (Ada 2022 feature) + +* *AI12-0279 Nonpreemptive dispatching needs more dispatching points (2020-04-17)* + + Ada 2022 defines a new aspect `Yield` that can be specified in the declaration of a noninstance subprogram (including a generic formal subprogram), a generic subprogram, or an entry, to ensure that the associated subprogram has at least one task dispatching point during each invocation. + + RM references: D.02.01 (1.5/2) D.02.01 (7/5) + +.. index:: AI12-0280-2 (Ada 2022 feature) + +* *AI12-0280-2 Making 'Old more flexible (2020-07-24)* + + For Ada 2022, AI12-0280-2 relaxes Ada's restrictions on 'Old attribute + references whose attribute prefix does not statically name an entity. Previously, it was required that such an attribute reference must be unconditionally evaluated when the postcondition is evaluated; with the new rule, conditional evaluation is permitted if the relevant conditions can be evaluated upon entry to the subprogram with the same results as evaluation at the time of the postcondition's evaluation. In this case, the 'Old attribute prefix is evaluated conditionally (more specifically, the prefix is evaluated only if the result of that evaluation is going to be referenced later when the + postcondition is evaluated). + + RM references: 6.01.01 (20/3) 6.01.01 (21/3) 6.01.01 (22/3) 6.01.01 + (22.1/4) 6.01.01 (22.2/5) 6.01.01 (23/3) 6.01.01 (24/3) 6.01.01 + (26/4) 6.01.01 (27/5) 6.01.01 (39/5) + +.. index:: AI12-0282 (Ada 2022 feature) + +* *AI12-0282 Atomic, Volatile, and Independent generic formal types (0000-00-00)* + + The AI specifies that the aspects ``Atomic``, ``Volatile``, ``Independent``, ``Atomic_Components``, ``Volatile_Components``, and ``Independent_Components`` are specifiable for generic formal types. The actual type must have a matching specification. + + RM references: C.06 (6.1/3) C.06 (6.3/3) C.06 (6.5/3) C.06 (6.8/3) C.06 + (12/3) C.06 (12.1/3) C.06 (21/4) + +.. index:: AI12-0285 (Ada 2022 feature) + +* *AI12-0285 Syntax for Stable_Properties aspects (0000-00-00)* + + The AI establishes the required named notation for a Stable_Properties aspect specification in order to avoid syntactic ambiguities. + + With the old syntax, an example like + + .. code:: + + type Ugh is ... + with Stable_Properties =\> Foo, Bar, Nonblocking, Pack; + + was problematic; ``Nonblocking`` and ``Pack`` are other aspects, while ``Foo`` and ``Bar`` are ``Stable_Properties`` functions. With the clarified syntax, the example above shall be written as: + + .. code:: + + type Ugh is ... + with Stable_Properties => (Foo, Bar), Nonblocking, Pack; + + RM references: 7.03.04 (2/5) 7.03.04 (3/5) 7.03.04 (4/5) 7.03.04 (6/5) + 7.03.04 (7/5) 7.03.04 (9/5) 7.03.04 (10/5) 7.03.04 (14/5) 13.01.01 (4/5) + +.. index:: AI12-0287 (Ada 2022 feature) + +* *AI12-0287 Legality Rules for null exclusions in renaming are too fierce (2020-02-17)* + + The null exclusion legality rules for generic formal object matching and object renaming now only apply to generic formal objects with mode in out. + + RM references: 8.05.01 (4.4/2) 8.05.01 (4.5/2) 8.05.01 (4.6/2) 8.05.04 + (4.2/2) 12.04 (8.3/2) 12.04 (8.4/2) 12.04 (8.5/2) 12.04 (8.2/5) + 12.06 (8.2/5) + +.. index:: AI12-0289 (Ada 2022 feature) + +* *AI12-0289 Implicitly null excluding anonymous access types and conformance (2020-06-09)* + + AI12-0289 is implemented for Ada 2022, allowing safer use of access parameters + when the partial view of the designated type is untagged, but the full view is + tagged. + + RM references: 3.10 (26) + +.. index:: AI12-0290 (Ada 2022 feature) + +* *AI12-0290 Restriction Pure_Barriers (2020-02-18)* + + The GNAT implementation of the Pure_Barriers restriction has + been updated to match the Ada RM's definition as specified + in this AI. Some constructs that were accepted by the previous + implementation are now rejected, and vice versa. In + particular, the use of a component of a component of a + protected record in a barrier expression, as in "when + Some_Component.Another_Component =>", formerly was (at least + in some cases) not considered to be a violation of the + Pure_Barriers restriction; that is no longer the case. + + RM references: D.07 (2) D.07 (10.10/4) + +.. index:: AI12-0291 (Ada 2022 feature) + +* *AI12-0291 Jorvik Profile (2020-02-19)* + + The Jorvik profile is now implemented, as defined in this AI. + For Ada 2012 and earlier versions of Ada, Jorvik is an implementation-defined + profile whose definition matches its Ada 2022 definition. + + RM references: D.13 (0) D.13 (1/3) D.13 (4/3) D.13 (6/4) D.13 (9/3) D.13 + (10/3) D.13 (11/4) D.13 (12/4) + +.. index:: AI12-0293 (Ada 2022 feature) + +* *AI12-0293 Add predefined FIFO_Streams packages (0000-00-00)* + + The AI adds ``Ada.Streams.Storage`` and its two subunits ``Bounded`` and ``Unbounded``. + + RM references: 13.13.01 (1) 13.13.01 (9) 13.13.01 (9.1/1) + +.. index:: AI12-0295 (Ada 2022 feature) + +* *AI12-0295 User-defined string (2020-04-07)* + + Compiler support is added for three new aspects (``Integer_Literal``, ``Real_Literal``, and ``String_Literal``) as described in AI12-0249 (for ``Integer_Literal`` and ``Real_Literal``), AI12-0295 (for ``String_Literal``), and in two follow-up AIs (AI12-0325 and AI12-0342). For pre-Ada 2022 versions of Ada, these are treated as implementation-defined aspects. Some implementation work remains, particularly in the interactions between these aspects and tagged types. + + RM references: 4.02 (6) 4.02 (10) 4.02 (11) 3.06.03 (1) 4.02.01 (0) 4.09 (26/3) + +.. index:: AI12-0301 (Ada 2022 feature) + +* *AI12-0301 Predicates should be checked like constraints for types with Default_Value (2020-02-25)* + + This AI clarifies that predicate checks apply for objects that are initialized + by default and that are of a type that has any components whose subtypes specify ``Default_Value`` or ``Default_Component_Value``. + + RM references: 3.02.04 (31/4) + +.. index:: AI12-0304 (Ada 2022 feature) + +* *AI12-0304 Image attributes of language-defined types (2020-07-07)* + + According to this AI, ``Put_Image`` (and therefore ``'Image``) is provided for + the containers and for unbounded strings. + + RM references: 4.10 (0) + +.. index:: AI12-0306 (Ada 2022 feature) + +* *AI12-0306 Split null array aggregates from positional array aggregates (0000-00-00)* + + The AI clarifies the wording of the references RM paragraphs without introducing any language changes. + + RM references: 4.03.03 (2) 4.03.03 (3/2) 4.03.03 (9/5) 4.03.03 (26/5) + 4.03.03 (26.1/5) 4.03.03 (33/3) 4.03.03 (38) 4.03.03 (39) 4.03.03 (42) + +.. index:: AI12-0307 (Ada 2022 feature) + +* *AI12-0307 Resolution of aggregates (2020-08-13)* + + The proposed new syntax for aggregates in Ada 2022 uses square brackets as + delimiters, and in particular allows ``[]`` as a notation for empty array and container aggregates. This syntax is currently available as an experimental feature under the ``-gnatX`` flag. + + RM references: 4.03 (3/5) + +.. index:: AI12-0309 (Ada 2022 feature) + +* *AI12-0309 Missing checks for pragma Suppress (0000-00-00)* + + The AI includes some previously overlooked run-time checks in the list of checks that are potentially suppressed via a pragma ``Suppress``. For example, AI12-0251-1 adds a check that the number of chunks in a chunk_specification is not zero or negative. Clarify that suppressing ``Program_Error_Check`` suppresses that check too. + + RM references: 11.05 (10) 11.05 (19) 11.05 (20) 11.05 (22) 11.05 (24) + +.. index:: AI12-0311 (Ada 2022 feature) + +* *AI12-0311 Suppressing client-side assertions for language-defined units (0000-00-00)* + + The AI defines some new assertion policies that can be given as arguments in a Suppress pragma (e.g., Calendar_Assertion_Check). GNAT recognizes and ignores those new policies, the checks are not implemented. + + RM references: 11.04.02 (23.5/5) 11.05 (23) 11.05 (26) + +.. index:: AI12-0315 (Ada 2022 feature) + +* *AI12-0315 Image Attributes subclause improvements (0000-00-00)* + + Clarify that a named number or similar can be the prefix of an Image attribute reference. + + RM references: 4.10 (0) + +.. index:: AI12-0318 (Ada 2022 feature) + +* *AI12-0318 No_IO should apply to Ada.Directories (2020-01-31)* + + The restriction No_IO now applies to and prevents the use of the + ``Ada.Directories package``. + + RM references: H.04 (20/2) H.04 (24/3) + +.. index:: AI12-0321 (Ada 2022 feature) + +* *AI12-0321 Support for Arithmetic Atomic Operations and Test and Set (0000-00-00)* + + The AI adds some predefined atomic operations, e.g. package System.``Atomic_Operations.Test_And_Set``. + + RM references: C.06.03 (0) C.06.04 (0) + +.. index:: AI12-0325 (Ada 2022 feature) + +* *AI12-0325 Various issues with user-defined literals (2020-04-07)* + + Compiler support is added for three new aspects (``Integer_Literal``, ``Real_Literal``, and ``String_Literal``) as described in AI12-0249 (for ``Integer_Literal`` and ``Real_Literal``), AI12-0295 (for ``String_Literal``), and in two follow-up AIs (AI12-0325 and AI12-0342). For pre-Ada 2022 versions of Ada, these are treated as implementation-defined aspects. Some implementation work remains, particularly in the interactions between these aspects and tagged types. + + RM references: 4.02 (6) 4.02 (10) 4.02 (11) 4.02.01 (0) + +.. index:: AI12-0329 (Ada 2022 feature) + +* *AI12-0329 Naming of FIFO_Streams packages (0000-00-00)* + + The AI changes the name of predefined package ``Ada.Streams.FIFO_Streams`` to ``Ada.Streams.Storage``. + + RM references: 13.13.01 (9/5) 13.13.01 (9.1/5) + +.. index:: AI12-0331 (Ada 2022 feature) + +* *AI12-0331 Order of finalization of a subpool (0000-00-00)* + + Clarify that when a subpool is being finalized, objects allocated from that subpool are finalized before (not after) they cease to exist (i.e. object's storage has been reclaimed). + + RM references: 13.11.05 (5/3) 13.11.05 (6/3) 13.11.05 (7/3) 13.11.05 + (7.1/4) 13.11.05 (8/3) 13.11.05 (9/3) + +.. index:: AI12-0333 (Ada 2022 feature) + +* *AI12-0333 Predicate checks on out parameters (0000-00-00)* + + If a view conversion is passed as an actual parameter corresponding to an out-mode formal parameter, and if the subtype of the formal parameter has a predicate, then no predicate check associated with the conversion is performed. + + RM references: 3.02.04 (31/5) 4.06 (51/4) 6.04.01 (14) + +.. index:: AI12-0335 (Ada 2022 feature) + +* *AI12-0335 Dynamic accessibility check needed for some requeue targets (0000-00-00)* + + Define a new runtime accessibility check for a corner case involving requeue statements. + + RM references: 9.05.04 (7/4) + +.. index:: AI12-0336 (Ada 2022 feature) + +* *AI12-0336 Meaning of Time_Offset (0000-00-00)* + + The AI introduces changes to the predefined package ``Ada.Calendar.Time_Zones``. + + RM references: 9.06.01 (6/2) 9.06.01 (35/2) 9.06.01 (40/2) 9.06.01 (41/2) + 9.06.01 (42/3) 9.06.01 (90/2) 9.06.01 (91/2) + +.. index:: AI12-0337 (Ada 2022 feature) + +* *AI12-0337 Simple_Name("/") in Ada.Directories (0000-00-00)* + + Clarify behavior of subprograms in the predefined package ``Ada.Directories``. In particular, Simple_Name ("/") should return "/" on Unix-like systems. + + RM references: A.16 (47/2) A.16 (74/2) A.16 (82/3) + +.. index:: AI12-0338 (Ada 2022 feature) + +* *AI12-0338 Type invariant checking and incomplete types (0000-00-00)* + + Clarify that type invariants for type T are not checked for incomplete types whose completion is not available, even if that completion has components of type T. + + RM references: 7.03.02 (20/5) + +.. index:: AI12-0339 (Ada 2022 feature) + +* *AI12-0339 Empty function for Container aggregates (2020-08-06)* + + To provide uniform support for container aggregates, all standard container + libraries have been enhanced with a function Empty, to be used when initializing an aggregate prior to inserting the specified elements in the object being constructed. All products have been updated to remove the ambiguities that may have arisen from previous uses of entities named Empty in our sources, and the expansion of container aggregates uses Empty wherever needed. + + RM references: A.18.02 (8/5) A.18.02 (12.3/5) A.18.02 (78.2/5) A.18.02 + (98.6/5) A.18.03 (6/5) A.18.03 (10.2/5) A.18.03 (50.2/5) A.18.05 + (3/5) A.18.05 (7.2/5) A.18.05 (37.3/5) A.18.05 (46/2) A.18.06 + (4/5) A.18.06 (8.2/5) A.18.06 (51.4/5) A.18.08 (3/5) A.18.08 + (8.1/5) A.18.08 (59.2/5) A.18.08 (68/2) A.18.09 (4/5) A.18.09 + (9.1/5) A.18.09 (74.2/5) A.18.10 (15.2/5) A.18.18 (8.1/5) A.18.19 + (6.1/5) A.18.20 (6/3) A.18.21 (6/3) A.18.22 (6/3) A.18.23 (6/3) + A.18.24 (6/3) A.18.25 (8/3) + +.. index:: AI12-0340 (Ada 2022 feature) + +* *AI12-0340 Put_Image should use a Text_Buffer (0000-00-00)* + + Add a new predefined package Ada.Strings.Text_Buffers (along with child units) and change the definition of Put_Image attribute to refer to it. + + RM references: A.04.12 (0) 4.10 (3.1/5) 4.10 (3.2/5) 4.10 (6/5) 4.10 + (25.2/5) 4.10 (28/5) 4.10 (31/5) 4.10 (41/5) H.04 (23.2/5) H.04 (23.11/5) + +.. index:: AI12-0342 (Ada 2022 feature) + +* *AI12-0342 Various issues with user-defined literals (part 2) (2020-04-07)* + + Compiler support is added for three new aspects (``Integer_Literal``, ``Real_Literal``, and ``String_Literal``) as described in AI12-0249 (for ``Integer_Literal`` and ``Real_Literal``), AI12-0295 (for ``String_Literal``), and in two follow-up AIs (AI12-0325 and AI12-0342). For pre-Ada 2022 versions of Ada, these are treated as implementation-defined aspects. Some implementation work remains, particularly in the interactions between these aspects and tagged types. + + RM references: 4.02.01 (0) 3.09.02 (1/2) 6.03.01 (22) + +.. index:: AI12-0343 (Ada 2022 feature) + +* *AI12-0343 Return Statement Checks (2020-04-02)* + + This binding interpretation has been implemented and the accessibility, + predicate, and tag checks prescribed by RM 6.5 are now performed at the appropriate points, as required by this AI. + + RM references: 6.05 (5.12/5) 6.05 (8/4) 6.05 (8.1/3) 6.05 (21/3) + +.. index:: AI12-0345 (Ada 2022 feature) + +* *AI12-0345 Dynamic accessibility of explicitly aliased parameters (0000-00-00)* + + Further clarify (after AI12-0277) accessibility rules for explicitly aliased parameters. + + RM references: 3.10.02 (5) 3.10.02 (7/4) 3.10.02 (10.5/3) 3.10.02 (13.4/4) + 3.10.02 (19.2/5) 3.10.02 (21) + +.. index:: AI12-0350 (Ada 2022 feature) + +* *AI12-0350 Swap for Indefinite_Holders (0000-00-00)* + + Add a ``Swap`` procedure to the predefined package + ``Ada.Containers.Indefinite_Holders``. The AI also contains implementation advice for ``Ada.Containers.Bounded_Indefinite_Holders``, a package that is not implemented by GNAT. + + RM references: A.18.18 (22/5) A.18.18 (67/5) A.18.18 (73/3) A.18.32 (13/5) + +.. index:: AI12-0351 (Ada 2022 feature) + +* *AI12-0351 Matching for actuals for formal derived types (2020-04-03)* + + This binding interpretation requires the compiler to checks + that an actual subtype in a generic parameter association of an instantiation is statically compatible (even when the actual is unconstrained) with the ancestor of an associated nondiscriminated generic formal derived type. + + RM references: 12.05.01 (7) 12.05.01 (8) + +.. index:: AI12-0352 (Ada 2022 feature) + +* *AI12-0352 Early derivation and equality of untagged types (2020-07-09)* + + AI12-0352 clarifies that declaring a user-defined primitive equality operation for a record type T is illegal if it occurs after a type has been derived from T. + + RM references: 4.05.02 (9.8/4) + +.. index:: AI12-0356 (Ada 2022 feature) + +* *AI12-0356 Root_Storage_Pool_With_Subpools should have Preelaborable_Initialization (0000-00-00)* + + Add Preelaborable_Initialization pragmas for predefined types ``Root_Storage_Pool_With_Subpools`` and ``Root_Subpool``. + + RM references: 13.11.04 (4/3) 13.11.04 (5/3) + +.. index:: AI12-0363 (Ada 2022 feature) + +* *AI12-0363 Fixes for Atomic and Volatile (2020-09-08)* + + This amendment has been implemented under the ``-gnat2022`` switch and the compiler now supports the ``Full_Access_Only`` aspect, which is mostly equivalent to GNAT's ``Volatile_Full_Access``. + + RM references: 3.10.02 (26/3) 9.10 (1/5) C.06 (6.4/3) C.06 (6.10/3) C.06 + (8.1/4) C.06 (12/5) C.06 (12.1/5) C.06 (13.3/5) C.06 (19.1/5) + +.. index:: AI12-0364 (Ada 2022 feature) + +* *AI12-0364 Add a modular atomic arithmetic package (0000-00-00)* + + Generalize support for atomic integer operations to extend to modular types. Add new predefined generic package, + ``System.Atomic_Operations.Modular_Arithmetic``. + + RM references: C.06.05 (0) C.06.04 (1/5) C.06.04 (2/5) C.06.04 (3/5) + C.06.04 (9/5) + +.. index:: AI12-0366 (Ada 2022 feature) + +* *AI12-0366 Changes to Big_Integer and Big_Real (0000-00-00)* + + Simplify ``Big_Integer ``and ``Big_Real`` specs by eliminating explicit support for creating "invalid" values. No more + ``Optional_Big_[Integer,Real]`` types. + + RM references: A.05.06 (0) A.05.07 (0) + +.. index:: AI12-0367 (Ada 2022 feature) + +* *AI12-0367 Glitches in aspect specifications (0000-00-00)* + + The AI clarifies a few wording omissions. For example, a specified Small value for a fixed point type has to be positive. + + RM references: 3.05.09 (8/2) 3.05.10 (2/1) 13.01 (9.1/5) 13.14 (10) + +.. index:: AI12-0368 (Ada 2022 feature) + +* *AI12-0368 Declare expressions can be static (2020-05-30)* + + AI12-0368 allows declare expressions to be static in Ada 2022. + + RM references: 4.09 (8) 4.09 (12.1/3) 4.09 (17) 6.01.01 (24.2/5) 6.01.01 + (24.3/5) 6.01.01 (24.4/5) 6.01.01 (24.5/5) C.04 (9) + +.. index:: AI12-0369 (Ada 2022 feature) + +* *AI12-0369 Relaxing barrier restrictions (2020-03-25)* + + The definitions of the ``Simple_Barriers`` and ``Pure_Barriers`` restrictions were modified by this AI, replacing uses of "statically denotes" with "statically names". This means that in many cases (but not all) a barrier expression that references a subcomponent of a component of the protected type while subject to either of the two restrictions is now allowed; with the previous restriction definitions, such a barrier expression would not have been legal. + + RM references: D.07 (1.3/5) D.07 (10.12/5) + +.. index:: AI12-0372 (Ada 2022 feature) + +* *AI12-0372 Static accessibility of "master of the call" (0000-00-00)* + + Add an extra compile-time accessibility check for explicitly aliased parameters needed to prevent dangling references. + + RM references: 3.10.02 (10.5/5) 3.10.02 (19.3/4) 6.04.01 (6.4/3) + +.. index:: AI12-0373 (Ada 2022 feature) + +* *AI12-0373 Bunch of fixes (0000-00-00)* + + Small clarifications to various RM entries with minor impact on compiler implementation. + + RM references: 3.01 (1) 4.02 (4) 4.02 (8/2) 4.02.01 (3/5) 4.02.01 (4/5) + 4.02.01 (5/5) 4.09 (17.3/5) 6.01.01 (41/5) 8.05.04 (4/3) 13.01.01 + (4/3) 13.01.01 (11/3) 13.14 (3/5) + +.. index:: AI12-0376 (Ada 2022 feature) + +* *AI12-0376 Representation changes finally allowed for untagged derived types (0000-00-00)* + + A change of representation for a derived type is allowed in some previously-illegal cases where a change of representation is required to implement a call to a derived subprogram. + + RM references: 13.01 (10/4) + +.. index:: AI12-0377 (Ada 2022 feature) + +* *AI12-0377 View conversions and out parameters of types with Default_Value revisited (2020-06-17)* + + This AI clarifies that an actual of an out parameter that is a view conversion + is illegal if either the target or operand type has Default_Value specified while the other does not. + + RM references: 6.04.01 (5.1/4) 6.04.01 (5.2/4) 6.04.01 (5.3/4) 6.04.01 + (13.1/4) 6.04.01 (13.2/4) 6.04.01 (13.3/4) 6.04.01 (13.4/4) 6.04.01 (15/3) + +.. index:: AI12-0381 (Ada 2022 feature) + +* *AI12-0381 Tag of a delta aggregate (0000-00-00)* + + In the case of a delta aggregate of a specific tagged type, the tag of the aggregate comes from the specific type (as opposed to somehow from the base object). + + RM references: 4.03.04 (14/5) + +.. index:: AI12-0382 (Ada 2022 feature) + +* *AI12-0382 Loosen type-invariant overriding requirement of AI12-0042-1 (0000-00-00)* + + The AI relaxes some corner-case legality rules about type invariants that were added by AI12-0042-1. + + RM references: 7.3.2(6.1/4) + +.. index:: AI12-0383 (Ada 2022 feature) + +* *AI12-0383 Renaming values (2020-06-17)* + + This AI allow names that denote values rather than objects to nevertheless be + renamed using an object renaming. + + RM references: 8.05.01 (1) 8.05.01 (4) 8.05.01 (4.1/2) 8.05.01 (6/2) 8.05.01 (8) + +.. index:: AI12-0384-2 (Ada 2022 feature) + +* *AI12-0384-2 Fixups for Put_Image and Text_Buffers (2021-04-29)* + + In GNAT's initial implementation of the Ada 2022 ``Put_Image`` aspect and + attribute, buffering was performed using a GNAT-defined package, + ``Ada.Strings.Text_Output``. Ada 2022 requires a different package, Ada.``Strings.Text_Buffers``, for this role, and that package is now provided, and the older package is eliminated. + + RM references: 4.10 (0) A.04.12 (0) + +.. index:: AI12-0385 (Ada 2022 feature) + +* *AI12-0385 Predefined shifts and rotates should be static (0000-00-00)* + + This AI allows Shift and Rotate operations in static expressions. GNAT implements this AI partially. + + RM references: 4.09 (20) + +.. index:: AI12-0389 (Ada 2022 feature) + +* *AI12-0389 Ignoring unrecognized aspects (2020-10-08)* + + Two new restrictions, ``No_Unrecognized_Aspects`` and ``No_Unrecognized_Pragmas``, are available to make the compiler emit error messages on unrecognized pragmas and aspects. + + RM references: 13.01.01 (38/3) 13.12.01 (6.3/3) + +.. index:: AI12-0394 (Ada 2022 feature) + +* *AI12-0394 Named Numbers and User-Defined Numeric Literals (2020-10-05)* + + Ada 2022 allows using integer named numbers with types that have an + ``Integer_Literal`` aspect. Similarly, real named numbers may now be used with types that have a ``Real_Literal`` aspect with an overloading that takes two strings, to be used in particular with + ``Ada.Numerics.Big_Numbers.Big_Reals``. + + RM references: 3.03.02 (3) 4.02.01 (4/5) 4.02.01 (8/5) 4.02.01 (12/5) + 4.02.01 (13/5) 4.09 (5) + +.. index:: AI12-0395 (Ada 2022 feature) + +* *AI12-0395 Allow aspect_specifications on formal parameters (0000-00-00)* + + Change syntax rules to allow aspect_specifications on formal parameters, if an implementation if an implementation wants to define one. Currently, GNAT doesn't define any such aspect_specifications. + + RM references: 6.01 (15/3) + +.. index:: AI12-0397 (Ada 2022 feature) + +* *AI12-0397 Default_Initial_Condition applied to derived type (2020-12-09)* + + The compiler now implements the rules for resolving ``Default_Initial_Condition`` + expressions that involve references to the current instance of types with the aspect, as specified by this AI. The type of the current instance is defined to be like a formal derived type, so for a derived type that inherits the aspect, a call passing the current instance to a primitive means that the call will resolve to invoke the corresponding primitive of the descendant type. This also now permits calls to abstract primitives to occur within the aspect expression of an abstract type. + + RM references: 7.03.03 (3/5) 7.03.03 (6/5) 7.03.03 (8/5) + +.. index:: AI12-0398 (Ada 2022 feature) + +* *AI12-0398 Most declarations should have aspect specifications (2020-11-19)* + + It is now possible to specify aspects for discriminant specifications, extended return object declarations, and entry index specifications. This is an extension added for Ada 2022 by this AI. + + RM references: 3.07 (5/2) 6.03.01 (25) 6.05 (2.1/3) 9.05.02 (8) + +.. index:: AI12-0399 (Ada 2022 feature) + +* *AI12-0399 Aspect specification for Preelaborable_Initialization (0000-00-00)* + + Semantics-preserving presentation change. Replace ``Preelaborable_Initialization`` pragmas with equivalent aspect specs in the listed predefined packages. GNAT follows the guidance of this AI partially. + + RM references: 9.05 (53/5) 3.09 (6/5) 7.06 (5/2) 7.06 (7/2) 11.04.01 (2/5) + 11.04.01 (3/2) 13.11 (6/2) 13.11.04 (4/5) 13.11.04 (5/5) 13.13.01 + (3/2) A.04.02 (4/2) A.04.02 (20/2) A.04.05 (4/2) A.04.07 (4/2) + A.04.07 (20/2) A.04.08 (4/2) A.04.08 (20/2) A.12.01 (5/4) A.18.02 + (8/5) A.18.02 (9/2) A.18.02 (79.2/5) A.18.02 (79.3/5) A.18.03 + (6/5) A.18.03 (7/2) A.18.03 (50.2/5) A.18.03 (50.3/5) A.18.05 + (3/5) A.18.05 (4/2) A.18.05 (37.3/5) A.18.05 (37.4/5) A.18.06 + (4/5) A.18.06 (5/2) A.18.06 (51.4/5) A.18.06 (51.5/5) A.18.08 + (3/5) A.18.08 (4/2) A.18.08 (58.2/5) A.18.08 (58.3/5) A.18.09 + (4/5) A.18.09 (5/2) A.18.09 (74.2/5) A.18.09 (74.3/5) A.18.10 + (8/5) A.18.10 (9/3) A.18.10 (70.2/5) A.18.10 (70.3/5) A.18.18 + (6/5) B.03.01 (5/2) C.07.01 (2/5) G.01.01 (4/2) + +.. index:: AI12-0400 (Ada 2022 feature) + +* *AI12-0400 Ambiguities associated with Vector Append and container aggregates (0000-00-00)* + + Change the names of subprograms in the predefined Vector containers from ``Append`` to ``Append_Vector`` and from ``Prepend`` to ``Prepend_Vector`` in order to resolve some ambiguity problems. GNAT adds the subprograms with new names but also keeps the old ones for backward compatibility. + + RM references: A.18.02 (8/5) A.18.02 (36/5) A.18.02 (37/5) A.18.02 (38/5) + A.18.02 (44/5) A.18.02 (46/5) A.18.02 (47/5) A.18.02 (58/5) + A.18.02 (79.2/5) A.18.02 (150/5) A.18.02 (151/5) A.18.02 (152/5) + A.18.02 (153/5) A.18.02 (154/5) A.18.02 (155/5) A.18.02 (156/5) + A.18.02 (168/5) A.18.02 (169/5) A.18.02 (172/5) A.18.02 (173/5) + A.18.02 (174/5) A.18.02 (175.1/5) A.18.03 (23/5) A.18.03 (23.1/5) + A.18.03 (58.2/5) A.18.03 (96/5) A.18.03 (97.1/5) + +.. index:: AI12-0401 (Ada 2022 feature) + +* *AI12-0401 Renaming of qualified expression of variable (2020-10-31)* + + Ada 2022 AI12-0401 restricts renaming of a qualified expression to cases where + the operand is a constant, or the target subtype statically matches the nominal subtype of the operand, or is unconstrained with no predicates, to prevent setting variables to values outside their range or constraints. + + RM references: 3.03 (23.2/3) 8.05.01 (4.7/5) 8.05.01 (5/3) + +.. index:: AI12-0409 (Ada 2022 feature) + +* *AI12-0409 Preelaborable_Initialization and bounded containers (2021-06-23)* + + As defined by this AI, the ``Preelaborable_Initializatio`` aspect now has a + corresponding attribute of the same name. Types declared within a generic package specification are permitted to specify the expression of a ``Prelaborable_Initialization`` aspect by including one or more references to the attribute applied to a formal private or formal derived type conjoined by ``and`` operators. This permits the full type of a private type with such an aspect expression to have components of the named formal types, and such a type will have preelaborable initialization in an instance when the + actual types for all referenced formal types have preelaborable initialization. + + RM references: 10.02.01 (4.1/2) 10.02.01 (4.2/2) 10.02.01 (11.1/2) + 10.02.01 (11.2/2) 10.02.01 (11.6/2) 10.02.01 (11.7/2) 10.02.01 + (11.8/2) 13.01 (11/3) A.18.19 (5/5) A.18.20 (5/5) A.18.21 (5/5) + A.18.22 (5/5) A.18.23 (5/5) A.18.24 (5/5) A.18.25 (5/5) A.18.32 + (6/5) J.15.14 (0) + +.. index:: AI12-0411 (Ada 2022 feature) + +* *AI12-0411 Add "bool" to Interfaces.C (0000-00-00)* + + RM references: B.03 (13) B.03 (43/2) B.03 (65.1/4) + +.. index:: AI12-0412 (Ada 2022 feature) + +* *AI12-0412 Abstract Pre/Post'Class on primitive of abstract type (2021-05-19)* + + In Ada 2022, by AI12-0412, it's legal to specify Pre'Class and Post'Class + aspects on nonabstract primitive subprograms of an abstract type, but if the + expression of such an aspect is nonstatic, then it's illegal to make a nondispatching call to such a primitive, to apply ``'Access`` to it, or to pass such a primitive as an actual subprogram for a concrete formal subprogram in a generic instantiation. + + RM references: 6.01.01 (18.2/4) + +.. index:: AI12-0413 (Ada 2022 feature) + +* *AI12-0413 Reemergence of "=" when defined to be abstract (0000-00-00)* + + The AI clarifies rules about operator reemergence in instances, and nondispatching calls to abstract subprograms. + + RM references: 3.09.03 (7) 4.05.02 (14.1/3) 4.05.02 (24.1/3) 12.05 (8/3) + +.. index:: AI12-0423 (Ada 2022 feature) + +* *AI12-0423 Aspect inheritance fixups (0000-00-00)* + + Clarify that the No_Return aspect behaves as one would expect for an inherited subprogram and that inheritance works as one would expect for a multi-part aspect whose value is specified via an aggregate (e.g., the Aggregate aspect). + + RM references: 6.05.01 (3.3/3) 13.01 (15.7/5) 13.01 (15.8/5) + +.. index:: AI12-0432 (Ada 2022 feature) + +* *AI12-0432 View conversions of assignments and predicate checks (2021-05-05)* + + When a predicate applies to a tagged type, a view conversion to that type + normally requires a predicate check. However, as specified by AI12-0432, when the view conversion appears as the target of an assignment, a predicate check is not applied to the object in the conversion. + + RM references: 3.02.04 (31/5) 4.06 (51.1/5) diff --git a/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst b/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst index b0e131fe4abb..7250f6586ee1 100644 --- a/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst +++ b/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst @@ -1872,7 +1872,7 @@ conventions, and for example records are laid out in a manner that is consistent with C. This means that specifying convention C (for example) has no effect. -There are four exceptions to this general rule: +There are three exceptions to this general rule: * *Convention Fortran and array subtypes*. diff --git a/gcc/ada/doc/gnat_rm/specialized_needs_annexes.rst b/gcc/ada/doc/gnat_rm/specialized_needs_annexes.rst index 15b4a9483d0e..f34368c8c94d 100644 --- a/gcc/ada/doc/gnat_rm/specialized_needs_annexes.rst +++ b/gcc/ada/doc/gnat_rm/specialized_needs_annexes.rst @@ -4,9 +4,7 @@ Specialized Needs Annexes ************************* -Ada 95, Ada 2005, and Ada 2012 define a number of Specialized Needs Annexes, which are not -required in all implementations. However, as described in this chapter, -GNAT implements all of these annexes: +Ada 95, Ada 2005, Ada 2012, and Ada 2022 define a number of Specialized Needs Annexes, which are not required in all implementations. However, as described in this chapter, GNAT implements all of these annexes: *Systems Programming (Annex C)* The Systems Programming Annex is fully implemented. @@ -18,9 +16,8 @@ GNAT implements all of these annexes: *Distributed Systems (Annex E)* Stub generation is fully implemented in the GNAT compiler. In addition, - a complete compatible PCS is available as part of the GLADE system, - a separate product. When the two - products are used in conjunction, this annex is fully implemented. + a complete compatible PCS is available as part of ``PolyORB``, + a separate product. Note, that PolyORB is a deprecated product and will be eventually replaced with other technologies such as ``RTI``. *Information Systems (Annex F)* @@ -34,4 +31,3 @@ GNAT implements all of these annexes: *Safety and Security / High-Integrity Systems (Annex H)* The Safety and Security Annex (termed the High-Integrity Systems Annex in Ada 2005) is fully implemented. - diff --git a/gcc/ada/doc/gnat_rm/the_gnat_library.rst b/gcc/ada/doc/gnat_rm/the_gnat_library.rst index ac45b5eb7af8..d041090eab06 100644 --- a/gcc/ada/doc/gnat_rm/the_gnat_library.rst +++ b/gcc/ada/doc/gnat_rm/the_gnat_library.rst @@ -2037,7 +2037,7 @@ technically an implementation-defined addition). This package provides facilities for partition interfacing. It is used primarily in a distribution context when using Annex E -with ``GLADE``. +with ``PolyORB``. .. _`System.Pool_Global_(s-pooglo.ads)`: diff --git a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst index 4f46fba93aef..fdf19481a6fc 100644 --- a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst +++ b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst @@ -2112,7 +2112,7 @@ Alphabetical List of All Switches .. index:: -gnatR (gcc) -:switch:`-gnatR[0|1|2|3|4][e][j][m][s]` +:switch:`-gnatR[0|1|2|3|4][e][h][m][j][s]` Output representation information for declared types, objects and subprograms. Note that this switch is not allowed if a previous :switch:`-gnatD` switch has been given, since these two switches @@ -2259,15 +2259,16 @@ Alphabetical List of All Switches ======= ================================================================== *n* Effect ------- ------------------------------------------------------------------ - *0* No optimization, the default setting if no :switch:`-O` appears - *1* Normal optimization, the default if you specify :switch:`-O` without an - operand. A good compromise between code quality and compilation - time. - *2* Extensive optimization, may improve execution time, possibly at + *0* No optimization, the default setting if no :switch:`-O` appears. + *1* Moderate optimization, same as :switch:`-O` without an operand. + A good compromise between code quality and compilation time. + *2* Extensive optimization, should improve execution time, possibly at the cost of substantially increased compilation time. - *3* Same as :switch:`-O2`, and also includes inline expansion for small - subprograms in the same unit. - *s* Optimize space usage + *3* Full optimization, may further improve execution time, possibly at + the cost of substantially larger generated code. + *s* Optimize for size (code and data) rather than speed. + *z* Optimize aggressively for size (code and data) rather than speed. + *g* Optimize for debugging experience rather than speed. ======= ================================================================== See also :ref:`Optimization_Levels`. @@ -6088,7 +6089,7 @@ Debugging Control .. index:: -gnatR (gcc) -:switch:`-gnatR[0|1|2|3|4][e][j][m][s]` +:switch:`-gnatR[0|1|2|3|4][e][h][m][j][s]` This switch controls output from the compiler of a listing showing representation information for declared types, objects and subprograms. For :switch:`-gnatR0`, no information is output (equivalent to omitting @@ -6116,17 +6117,21 @@ Debugging Control extended representation information for record sub-components of records is included. + If the switch is followed by a ``h`` (e.g. :switch:`-gnatR3h`), then + the components of records are sorted by increasing offsets and holes + between consecutive components are flagged. + If the switch is followed by an ``m`` (e.g. :switch:`-gnatRm`), then subprogram conventions and parameter passing mechanisms for all the subprograms are included. - If the switch is followed by a ``j`` (e.g., :switch:`-gnatRj`), then + If the switch is followed by a ``j`` (e.g. :switch:`-gnatRj`), then the output is in the JSON data interchange format specified by the ECMA-404 standard. The semantic description of this JSON output is available in the specification of the Repinfo unit present in the compiler sources. - If the switch is followed by an ``s`` (e.g., :switch:`-gnatR3s`), then + If the switch is followed by an ``s`` (e.g. :switch:`-gnatR3s`), then the output is to a file with the name :file:`file.rep` where ``file`` is the name of the corresponding source file, except if ``j`` is also specified, in which case the file name is :file:`file.json`. @@ -8123,6 +8128,9 @@ We provide two options that you can use to build code with GNAT LLVM: which version of GNAT built that file because it contains either :code:`GNAT` or :code:`GNAT-LLVM`. + You can also explicitly select GNAT LLVM in your existing GPR project + file by adding :code:`for Toolchain_Name("Ada") use "GNAT_LLVM";` + .. only:: PRO If your project uses one of the libraries packaged with the GCC diff --git a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst index 756bc74d3a3f..031fafcfa5a5 100644 --- a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst +++ b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst @@ -23,6 +23,7 @@ This chapter covers several topics: * `Performing Dimensionality Analysis in GNAT`_ * `Stack Related Facilities`_ * `Memory Management Issues`_ +* `Sanitizers for Ada`_ .. _Running_and_Debugging_Ada_Programs: @@ -1584,18 +1585,16 @@ Turning on optimization makes the compiler attempt to improve the performance and/or code size at the expense of compilation time and possibly the ability to debug the program. -If you use multiple :switch:`-O` switches, with or without level -numbers, the last such switch is the one that's used. - -You can use the -:switch:`-O` switch (the permitted forms are :switch:`-O0`, :switch:`-O1` -:switch:`-O2`, :switch:`-O3`, and :switch:`-Os`) -to ``gcc`` to control the optimization level: +You can pass the :switch:`-O` switch, with or without an operand +(the permitted forms with an operand are :switch:`-O0`, :switch:`-O1`, +:switch:`-O2`, :switch:`-O3`, :switch:`-Os`, :switch:`-Oz`, and +:switch:`-Og`) to ``gcc`` to control the optimization level. If you +pass multiple :switch:`-O` switches, with or without an operand, +the last such switch is the one that's used: * :switch:`-O0` - No optimization (the default); - generates unoptimized code but has + No optimization (the default); generates unoptimized code but has the fastest compilation time. Debugging is easiest with this switch. Note that many other compilers do substantial optimization even if @@ -1606,32 +1605,45 @@ to ``gcc`` to control the optimization level: mind when doing performance comparisons. * :switch:`-O1` - Moderate optimization; optimizes reasonably well but does not - degrade compilation time significantly. You may not be able to see - some variables in the debugger and changing the value of some - variables in the debugger may not have the effect you desire. + Moderate optimization (same as :switch:`-O` without an operand); + optimizes reasonably well but does not degrade compilation time + significantly. You may not be able to see some variables in the + debugger, and changing the value of some variables in the debugger + may not have the effect you desire. * :switch:`-O2` - Full optimization; - generates highly optimized code and has - the slowest compilation time. You may see significant impacts on + Extensive optimization; generates highly optimized code but has + an increased compilation time. You may see significant impacts on your ability to display and modify variables in the debugger. * :switch:`-O3` - Full optimization as in :switch:`-O2`; - also uses more aggressive automatic inlining of subprograms within a unit - (:ref:`Inlining_of_Subprograms`) and attempts to vectorize loops. - + Full optimization; attempts more sophisticated transformations, in + particular on loops, possibly at the cost of larger generated code. + You may be hardly able to use the debugger at this optimization level. * :switch:`-Os` - Optimize space usage (code and data) of resulting program. + Optimize for size (code and data) of resulting binary rather than + speed; based on the :switch:`-O2` optimization level, but disables + some of its transformations that often increase code size, as well + as performs further optimizations designed to reduce code size. + +* :switch:`-Oz` + Optimize aggressively for size (code and data) of resulting binary + rather than speed; may increase the number of instructions executed + if these instructions require fewer bytes to be encoded. + +* :switch:`-Og` + Optimize for debugging experience rather than speed; based on the + :switch:`-O1` optimization level, but attempts to eliminate all the + negative effects of optimization on debugging. + Higher optimization levels perform more global transformations on the program and apply more expensive analysis algorithms in order to generate faster and more compact code. The price in compilation time, and the -resulting improvement in execution time, -both depend on the particular application and the hardware environment. -You should experiment to find the best level for your application. +resulting improvement in execution time, both depend on the particular +application and the hardware environment. You should experiment to find +the best level for your application. Since the precise set of optimizations done at each level will vary from release to release (and sometime from target to target), it is best to think @@ -4122,3 +4134,325 @@ execution of this erroneous program: The allocation root #1 of the first example has been split in 2 roots #1 and #3, thanks to the more precise associated backtrace. + +.. _Sanitizers_for_Ada: + +Sanitizers for Ada +================== + +.. index:: Sanitizers + +This section explains how to use sanitizers with Ada code. Sanitizers offer code +instrumentation and run-time libraries that detect certain memory issues and +undefined behaviors during execution. They provide dynamic analysis capabilities +useful for debugging and testing. + +While many sanitizer capabilities overlap with Ada's built-in runtime checks, +they are particularly valuable for identifying issues that arise from unchecked +features or low-level operations. + +.. _AddressSanitizer: + +AddressSanitizer +---------------- + +.. index:: AddressSanitizer +.. index:: ASan +.. index:: -fsanitize=address + +AddressSanitizer (aka ASan) is a memory error detector activated with the +:switch:`-fsanitize=address` switch. Note that many of the typical memory errors, +such as use after free or buffer overflow, are detected by Ada’s ``Access_Check`` +and ``Index_Check``. + +It can detect the following types of problems: + +* Wrong memory overlay + + A memory overlay is a situation in which an object of one type is placed at the + same memory location as a distinct object of a different type, thus overlaying + one object over the other in memory. When there is an overflow because the + objects do not overlap (like in the following example), the sanitizer can signal + it. + + .. code-block:: ada + + procedure Wrong_Size_Overlay is + type Block is array (Natural range <>) of Integer; + + Block4 : aliased Block := (1 .. 4 => 4); + Block5 : Block (1 .. 5) with Address => Block4'Address; + begin + Block5 (Block5'Last) := 5; -- Outside the object + end Wrong_Size_Overlay; + + If the code is built with the :switch:`-fsanitize=address` and :switch:`-g` options, + the following error is shown at execution time: + + :: + + ... + SUMMARY: AddressSanitizer: stack-buffer-overflow wrong_size_overlay.adb:7 in _ada_wrong_size_overlay + ... + +* Buffer overflow + + Ada’s ``Index_Check`` detects buffer overflows caused by out-of-bounds array + access. If run-time checks are disabled, the sanitizer can still detect such + overflows at execution time the same way as it signalled the previous wrong + memory overlay. Note that if both the Ada run-time checks and the sanitizer + are enabled, the Ada run-time exception takes precedence. + + .. code-block:: ada + + procedure Buffer_Overrun is + Size : constant := 100; + Buffer : array (1 .. Size) of Integer := (others => 0); + Wrong_Index : Integer := Size + 1 with Export; + begin + -- Access outside the boundaries + Put_Line ("Value: " & Integer'Image (Buffer (Wrong_Index))); + end Buffer_Overrun; + +* Use after lifetime + + Ada’s ``Accessibility_Check`` helps prevent use-after-return and + use-after-scope errors by enforcing lifetime rules. When these checks are + bypassed using ``Unchecked_Access``, sanitizers can still detect such + violations during execution. + + .. code-block:: ada + + with Ada.Text_IO; use Ada.Text_IO; + + procedure Use_After_Return is + type Integer_Access is access all Integer; + Ptr : Integer_Access; + + procedure Inner; + + procedure Inner is + Local : aliased Integer := 42; + begin + Ptr := Local'Unchecked_Access; + end Inner; + + begin + Inner; + -- Accessing Local after it has gone out of scope + Put_Line ("Value: " & Integer'Image (Ptr.all)); + end Use_After_Return; + + If the code is built with the :switch:`-fsanitize=address` and :switch:`-g` + options, the following error is shown at execution time: + + :: + + ... + ==1793927==ERROR: AddressSanitizer: stack-use-after-return on address 0xf6fa1a409060 at pc 0xb20b6cb6cac0 bp 0xffffcc89c8b0 sp 0xffffcc89c8c8 + READ of size 4 at 0xf6fa1a409060 thread T0 + #0 0xb20b6cb6cabc in _ada_use_after_return use_after_return.adb:18 + ... + + Address 0xf6fa1a409060 is located in stack of thread T0 at offset 32 in frame + #0 0xb20b6cb6c794 in use_after_return__inner use_after_return.adb:9 + + This frame has 1 object(s): + [32, 36) 'local' (line 10) <== Memory access at offset 32 is inside this variable + SUMMARY: AddressSanitizer: stack-use-after-return use_after_return.adb:18 in _ada_use_after_return + ... + +* Memory leak + + A memory leak happens when a program allocates memory from the heap but fails + to release it after it is no longer needed and loses all references to it like + in the following example. + + .. code-block:: ada + + procedure Memory_Leak is + type Integer_Access is access Integer; + + procedure Allocate is + Ptr : Integer_Access := new Integer'(42); + begin + null; + end Allocate; + begin + -- Memory leak occurs in the following procedure + Allocate; + end Memory_Leak; + + If the code is built with the :switch:`-fsanitize=address` and :switch:`-g` + options, the following error is emitted at execution time showing the + location of the offending allocation. + + :: + + ==1810634==ERROR: LeakSanitizer: detected memory leaks + + Direct leak of 4 byte(s) in 1 object(s) allocated from: + #0 0xe3cbee4bb4a8 in __interceptor_malloc asan_malloc_linux.cpp:69 + #1 0xc15bb25d0af8 in __gnat_malloc (memory_leak+0x10af8) (BuildId: f5914a6eac10824f81d512de50b514e7d5f733be) + #2 0xc15bb25c9060 in memory_leak__allocate memory_leak.adb:5 + ... + + SUMMARY: AddressSanitizer: 4 byte(s) leaked in 1 allocation(s). + +.. _UndefinedBehaviorSanitizer: + +UndefinedBehaviorSanitizer +-------------------------- + +.. index:: UndefinedBehaviorSanitizer +.. index:: UBSan +.. index:: -fsanitize=undefined + +UndefinedBehaviorSanitizer (aka UBSan) modifies the program at compile-time to +catch various kinds of undefined behavior during program execution. + +Different sanitize options (:switch:`-fsanitize=alignment,float-cast-overflow,signed-integer-overflow`) +detect the following types of problems: + +* Wrong alignment + + The :switch:`-fsanitize=alignment` flag (included also in + :switch:`-fsanitize=undefined`) enables run-time checks for misaligned memory + accesses, ensuring that objects are accessed at addresses that conform to the + alignment constraints of their declared types. Violations may lead to crashes + or performance penalties on certain architectures. + + In the following example: + + .. code-block:: ada + + with Ada.Text_IO; use Ada.Text_IO; + with System.Storage_Elements; use System.Storage_Elements; + + procedure Misaligned_Address is + type Aligned_Integer is new Integer with + Alignment => 4; -- Ensure 4-byte alignment + + Reference : Aligned_Integer := 42; -- Properly aligned object + + -- Create a misaligned object by modifying the address manually + Misaligned : Aligned_Integer with Address => Reference'Address + 1; + + begin + -- This causes undefined behavior or an alignment exception on strict architectures + Put_Line ("Misaligned Value: " & Aligned_Integer'Image (Misaligned)); + end Misaligned_Address; + + If the code is built with the :switch:`-fsanitize=alignment` and :switch:`-g` + options, the following error is shown at execution time. + + :: + + misaligned_address.adb:15:51: runtime error: load of misaligned address 0xffffd836dd45 for type 'volatile misaligned_address__aligned_integer', which requires 4 byte alignment + +* Signed integer overflow + + Ada performs range checks at runtime in arithmetic operation on signed integers + to ensure the value is within the target type's bounds. If this check is removed, + the :switch:`-fsanitize=signed-integer-overflow` flag (included also in + :switch:`-fsanitize=undefined`) enables run-time checks for signed integer + overflows. + + In the following example: + + .. code-block:: ada + + procedure Signed_Integer_Overflow is + type Small_Int is range -128 .. 127; + X, Y, Z : Small_Int with Export; + begin + X := 100; + Y := 50; + -- This addition will exceed 127, causing an overflow + Z := X + Y; + end Signed_Integer_Overflow; + + If the code is built with the :switch:`-fsanitize=signed-integer-overflow` and + :switch:`-g` options, the following error is shown at execution time. + + :: + + signed_integer_overflow.adb:8:11: runtime error: signed integer overflow: 100 + 50 cannot be represented in type 'signed_integer_overflow__small_int' + +* Float to integer overflow + + When converting a floating-point value to an integer type, Ada performs a range + check at runtime to ensure the value is within the target type's bounds. If this + check is removed, the sanitizer can detect overflows in conversions from + floating point to integer types. + + In the following code: + + .. code-block:: ada + + procedure Float_Cast_Overflow is + Flt : Float := Float'Last with Export; + Int : Integer; + begin + Int := Integer (Flt); -- Overflow + end Float_Cast_Overflow; + + If the code is built with the :switch:`-fsanitize=float-cast-overflow` and + :switch:`-g` options, the following error is shown at execution time. + + :: + + float_cast_overflow.adb:5:20: runtime error: 3.40282e+38 is outside the range of representable values of type 'integer' + +Sanitizers in mixed-language applications +----------------------------------------- + +Most of the checks performed by sanitizers operate at a global level, which +means they can detect issues even when they span across language boundaries. +This applies notably to: + +* All checks performed by the AddressSanitizer: wrong memory overlays, buffer + overflows, uses after lifetime, memory leaks. These checks apply globally, + regardless of where the objects are allocated or defined, or where they are + destroyed + +* Wrong alignment checks performed by the UndefinedBehaviorSanitizer. It will + check whether an object created in a given language is accessed in another + with an incompatible alignment + +An interesting case that highlights the benefit of global sanitization is a +buffer overflow caused by a mismatch in language bindings. Consider the +following C function, which allocates an array of 4 characters: + + .. code-block:: c + + char *get_str (void) { + char *str = malloc (4 * sizeof (char)); + } + +This function is then bound to Ada code, which incorrectly assumes the buffer +is of size 5: + + .. code-block:: ada + + type Buffer is array (1 .. 5) of Character; + + function Get_Str return access Buffer + with Import => True, Convention => C, External_Name => "get_str"; + + Str : access Buffer := Get_Str; + Ch : Character := S (S'Last); -- Detected by AddressSanitizer as erroneous + +On the Ada side, accessing ``Str (5)`` appears valid because the array type +declares five elements. However, the actual memory allocated in C only holds +four. This mismatch is not detectable by Ada run-time checks, because Ada has +no visibility into how the memory was allocated. + +However, the AddressSanitizer will detect the heap buffer overflow at runtime, +halting execution and providing a clear diagnostic: + + :: + + ... + SUMMARY: AddressSanitizer: heap-buffer-overflow buffer_overflow.adb:20 in _ada_buffer_overflow + ... diff --git a/gcc/ada/doc/gnat_ugn/platform_specific_information.rst b/gcc/ada/doc/gnat_ugn/platform_specific_information.rst index f2fc737f90d2..6493a065960d 100644 --- a/gcc/ada/doc/gnat_ugn/platform_specific_information.rst +++ b/gcc/ada/doc/gnat_ugn/platform_specific_information.rst @@ -2212,11 +2212,12 @@ Setting Stack Size from ``gnatlink`` You can specify the program stack size at link time. On most versions of Windows, starting with XP, this is mostly useful to set the size of the main stack (environment task). The other task stacks are set with -pragma Storage_Size or with the *gnatbind -d* command. +pragma Storage_Size or with the *gnatbind -d* command. The specified size will +become the reserved memory size of the underlying thread. Since very old versions of Windows (2000, NT4, etc.) don't allow setting the -reserve size of individual tasks, the link-time stack size applies to all -tasks, and pragma Storage_Size has no effect. +reserve size of individual tasks, for those versions the link-time stack size +applies to all tasks, and pragma Storage_Size has no effect. In particular, Stack Overflow checks are made against this link-time specified size. diff --git a/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst b/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst index 64a363132c71..891886b53601 100644 --- a/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst +++ b/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst @@ -1477,6 +1477,10 @@ You can place configuration pragmas either appear at the start of a compilation unit or in a configuration pragma file that applies to all compilations performed in a given compilation environment. +Configuration pragmas placed before a library level package specification +are not propagated to the corresponding package body (see RM 10.1.5(8)); +they must be added explicitly to the package body. + GNAT includes the ``gnatchop`` utility to provide an automatic way to handle configuration pragmas that follows the semantics for compilations (that is, files with multiple units) described in the RM. diff --git a/gcc/ada/einfo-utils.adb b/gcc/ada/einfo-utils.adb index ec1087ded1f5..417da6e828bc 100644 --- a/gcc/ada/einfo-utils.adb +++ b/gcc/ada/einfo-utils.adb @@ -1037,6 +1037,7 @@ package body Einfo.Utils is Id = Pragma_Contract_Cases or else Id = Pragma_Exceptional_Cases or else Id = Pragma_Exit_Cases or else + Id = Pragma_Program_Exit or else Id = Pragma_Subprogram_Variant or else Id = Pragma_Test_Case; @@ -2344,6 +2345,25 @@ package body Einfo.Utils is begin pragma Assert (Is_Type (Id)); + if Nkind (Associated_Node_For_Itype (Id)) = N_Subtype_Declaration then + declare + Associated_Id : constant Entity_Id := + Defining_Identifier (Associated_Node_For_Itype (Id)); + begin + -- Avoid Itype/predicate problems by looking through Itypes. + -- We never introduce new predicates for Itypes, so doing this + -- will never cause us to incorrectly overlook a predicate. + -- It is not clear whether the FE needs this fix, but + -- GNATProve does (note that GNATProve calls Predicate_Function). + + if Id /= Associated_Id + and then Base_Type (Id) = Base_Type (Associated_Id) + then + return Predicate_Function (Associated_Id); + end if; + end; + end if; + -- If type is private and has a completion, predicate may be defined on -- the full view. @@ -2375,6 +2395,37 @@ package body Einfo.Utils is if Ekind (Subp_Id) = E_Function and then Is_Predicate_Function (Subp_Id) then + -- We may have incorrectly looked through predicate-bearing + -- subtypes when going from a private subtype to its full + -- view, so compensate for that case. Unfortunately, + -- Subp_Id might not be analyzed at this point, so we + -- use a crude works-most-of-the-time text-based + -- test to detect the case where Id is a subtype (declared by + -- a subtype declaration) and no predicate was explicitly + -- specified for Id. Ugh. ??? + + if Nkind (Parent (Id)) = N_Subtype_Declaration + -- 1st choice ... + -- and then Etype (First_Entity (Subp_Id)) /= Id + -- but that doesn't work if Subp_Id is not analyzed. + + -- so we settle for 2nd choice, ignoring cases like + -- "subtype Foo is Pkg.Foo;" where distinct subtypes + -- have the same identifier: + -- + and then Get_Name_String (Chars (Subp_Id)) /= + Get_Name_String (Chars (Id)) & "Predicate" + then + declare + Mark : Node_Id := Subtype_Indication (Parent (Id)); + begin + if Nkind (Mark) = N_Subtype_Indication then + Mark := Subtype_Mark (Mark); + end if; + return Predicate_Function (Entity (Mark)); + end; + end if; + return Subp_Id; end if; @@ -2638,14 +2689,7 @@ package body Einfo.Utils is -- anonymous protected types, since protected types always have the -- default convention. - if Present (Etype (E)) - and then (Is_Object (E) - - -- Allow E_Void (happens for pragma Convention appearing - -- in the middle of a record applying to a component) - - or else Ekind (E) = E_Void) - then + if Present (Etype (E)) and then Is_Object (E) then declare Typ : constant Entity_Id := Etype (E); @@ -2809,7 +2853,6 @@ package body Einfo.Utils is end if; Subp_Elmt := First_Elmt (Subps); - Prepend_Elmt (V, Subps); -- Check for a duplicate predication function @@ -2819,11 +2862,17 @@ package body Einfo.Utils is if Ekind (Subp_Id) = E_Function and then Is_Predicate_Function (Subp_Id) then - raise Program_Error; + if V = Subp_Id then + return; + else + raise Program_Error; + end if; end if; Next_Elmt (Subp_Elmt); end loop; + + Prepend_Elmt (V, Subps); end Set_Predicate_Function; ----------------- diff --git a/gcc/ada/einfo-utils.ads b/gcc/ada/einfo-utils.ads index ed1f1537e9ee..78b49891f609 100644 --- a/gcc/ada/einfo-utils.ads +++ b/gcc/ada/einfo-utils.ads @@ -456,6 +456,7 @@ package Einfo.Utils is -- No_Caching -- Part_Of -- Precondition + -- Program_Exit -- Postcondition -- Refined_Depends -- Refined_Global diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads index f154e7f0d763..916d9c6f47c9 100644 --- a/gcc/ada/einfo.ads +++ b/gcc/ada/einfo.ads @@ -463,11 +463,13 @@ package Einfo is -- For an access_to_protected_subprogram parameter it is the declaration -- of the corresponding formal parameter. --- --- Itypes have no explicit declaration, and therefore are not attached to --- the tree: their Parent field is always empty. The Associated_Node_For_ --- Itype is the only way to determine the construct that leads to the --- creation of a given itype entity. + +-- Itypes need not have an explicit declaration, in which case they are +-- not attached to the tree through the Parent field, which is empty. In +-- other cases, they have one and are attached to the tree through the +-- Parent field as usual. Associated_Node_For_Itype should be used to +-- determine the construct that leads to the creation of a given itype +-- entity. -- Associated_Storage_Pool [root type only] -- Defined in simple and general access type entities. References the @@ -714,6 +716,14 @@ package Einfo is -- bodies. Set if the entity contains any ignored Ghost code in the form -- of declaration, procedure call, assignment statement or pragma. +-- Continue_Mark +-- Defined in loop entities. It points to the loop's statement after +-- which the label for continue statements must be inserted if one is +-- needed. This is not always the last statement in the loop's list; it +-- can notably be followed by assignment statements generated by +-- expansion of iterator specifications, which continue statements must +-- not jump past. + -- Contract -- Defined in constant, entry, entry family, operator, [generic] package, -- package body, protected unit, [generic] subprogram, subprogram body, @@ -832,12 +842,6 @@ package Einfo is -- Default_Value aspect specification for the type, or inherited -- on derivation. --- Default_Expr_Function --- Defined in parameters. It holds the entity of the parameterless --- function that is built to evaluate the default expression if it is --- more complex than a simple identifier or literal. For the latter --- simple cases or if there is no default value, this field is Empty. - -- Default_Expressions_Processed -- A flag in subprograms (functions, operators, procedures) and in -- entries and entry families used to indicate that default expressions @@ -864,12 +868,6 @@ package Einfo is -- that holds value of delta for the type, as given in the declaration -- or as inherited by a subtype or derived type. --- Dependent_Instances --- Defined in packages that are instances. Holds list of instances --- of inner generics. Used to place freeze nodes for those instances --- after that of the current one, i.e. after the corresponding generic --- bodies. - -- Depends_On_Private -- Defined in all type entities. Set if the type is private or if it -- depends on a private type. @@ -1281,9 +1279,10 @@ package Einfo is -- that represents an activation record pointer is an extra formal. -- Extra_Formals --- Applies to subprograms, subprogram types, entries, and entry --- families. Returns first extra formal of the subprogram or entry. --- Returns Empty if there are no extra formals. +-- Applies to subprograms, subprogram types, entries, and entry families. +-- Returns the first extra formal of the subprogram or entry. An entity +-- has no extra formals when this attribute is Empty, and its attribute +-- Extra_Formals_Known is True. -- Finalization_Collection [root type only] -- Defined in access-to-controlled or access-to-class-wide types. The @@ -1462,11 +1461,6 @@ package Einfo is -- associates generic parameters with the corresponding instances, in -- those cases where the instance is an entity. --- Handler_Records --- Defined in subprogram and package entities. Points to a list of --- identifiers referencing the handler record entities for the --- corresponding unit. - -- Has_Aliased_Components [implementation base type only] -- Defined in array type entities. Indicates that the component type -- of the array is aliased. Should this also be set for records to @@ -1601,6 +1595,11 @@ package Einfo is -- set, signalling that Freeze.Inherit_Delayed_Rep_Aspects must be called -- at the freeze point of the derived type. +-- Has_Destructor +-- Defined in all type and subtype entities. Set only for record type +-- entities for which at least one ancestor has the Destructor aspect +-- specified. + -- Has_DIC (synthesized) -- Defined in all type entities. Set for a private type and its full view -- when the type is subject to pragma Default_Initial_Condition (DIC), or @@ -1623,7 +1622,7 @@ package Einfo is -- Has_Dynamic_Predicate_Aspect -- Defined in all types and subtypes. Set if a Dynamic_Predicate aspect --- was explicitly applied to the type. Generally we treat predicates as +-- was applied to the type or subtype. Generally we treat predicates as -- static if possible, regardless of whether they are specified using -- Predicate, Static_Predicate, or Dynamic_Predicate. And if a predicate -- can be treated as static (i.e. its expression is predicate-static), @@ -1647,11 +1646,6 @@ package Einfo is -- that this does not imply a representation with holes, since the rep -- clause may merely confirm the default 0..N representation. --- Has_First_Controlling_Parameter_Aspect --- Defined in tagged types, concurrent types and concurrent record types. --- Set to indicate that the type has a First_Controlling_Parameter of --- True (whether by an aspect_specification, a pragma, or inheritance). - -- Has_Exit -- Defined in loop entities. Set if the loop contains an exit statement. @@ -1661,6 +1655,12 @@ package Einfo is -- flag prevents double expansion of a contract when a construct is -- rewritten into something else and subsequently reanalyzed/expanded. +-- Has_First_Controlling_Parameter_Aspect +-- Defined in tagged types, concurrent types, and concurrent record +-- types. Set to indicate that the type has a First_Controlling_Parameter +-- of True (whether by an aspect_specification, a pragma, or +-- inheritance). + -- Has_Foreign_Convention (synthesized) -- Applies to all entities. Determines if the Convention for the entity -- is a foreign convention, i.e. non-native: other than Convention_Ada, @@ -1675,6 +1675,12 @@ package Einfo is -- the instance will conflict with the linear elaboration of front-end -- inlining. +-- Extra_Formals_Known +-- Defined in subprograms, subprogram types, entries, and entry families. +-- Set when the extra formals have been determined. An entity has no +-- extra formals when this attribute is True, and its attribute +-- Extra_Formals is Empty. + -- Has_Fully_Qualified_Name -- Defined in all entities. Set if the name in the Chars field has been -- replaced by the fully qualified name, as used for debug output. See @@ -1704,7 +1710,7 @@ package Einfo is -- -- Has_Homonym -- Defined in all entities. Set if an entity has a homonym in the same --- scope. Used by the backend to generate unique names for all entities. +-- scope. Used by Exp_Dbug to generate unique names for all entities. -- Has_Implicit_Dereference -- Defined in types and discriminants. Set if the type has an aspect @@ -2262,6 +2268,11 @@ package Einfo is -- is relocated to the corresponding package body, which must have a -- corresponding nonlimited with_clause. +-- Incomplete_View +-- Defined in all entities. Present in those that are completions of +-- incomplete types. Denotes the corresponding incomplete view declared +-- by the incomplete declaration. + -- Indirect_Call_Wrapper -- Defined on subprogram entities. Set if the subprogram has class-wide -- preconditions. Denotes the internal wrapper that checks preconditions @@ -2517,11 +2528,12 @@ package Einfo is -- Is_Controlled_Active [base type only] -- Defined in all type entities. Indicates that the type is controlled, --- i.e. has been declared with the Finalizable aspect or has inherited --- the Finalizable aspect from an ancestor. Can only be set for record --- types, tagged or untagged. System.Finalization_Root.Root_Controlled --- is an example of the former case while Ada.Finalization.Controlled --- and Ada.Finalization.Limited_Controlled are examples of the latter. +-- i.e. has been declared with the Finalizable or the Destructor aspect +-- or has inherited the aspect from an ancestor. Can only be set for +-- record types, tagged or untagged. +-- System.Finalization_Root.Root_Controlled is an example of the former +-- case while Ada.Finalization.Controlled and +-- Ada.Finalization.Limited_Controlled are examples of the latter. -- Is_Controlled (synth) [base type only] -- Defined in all type entities. Set if Is_Controlled_Active is set for @@ -2547,6 +2559,10 @@ package Einfo is -- Defined in all entities. True if the entity is type System.Address, -- or (recursively) a subtype or derived type of System.Address. +-- Is_Destructor +-- Defined in procedure entities. True if the procedure is denoted by the +-- Destructor aspect on some type. + -- Is_DIC_Procedure -- Defined in functions and procedures. Set for a generated procedure -- which verifies the assumption of pragma Default_Initial_Condition at @@ -2781,6 +2797,10 @@ package Einfo is -- identifiers in standard library packages, and to implement the -- restriction No_Implementation_Identifiers. +-- Is_Implicit_Full_View +-- Defined in types. Set on types that the compiler generates to act as +-- full views of types that are derivations of private types. + -- Is_Imported -- Defined in all entities. Set if the entity is imported. For now we -- only allow the import of exceptions, functions, procedures, packages, @@ -2967,6 +2987,11 @@ package Einfo is -- fully constructed, since it simply indicates the last state. -- Thus this flag has no meaning to the backend. +-- Is_Large_Unconstrained_Definite +-- Defined in record types. Used to detect types with default +-- discriminant values that have exaggerated sizes and emit warnings +-- about them. + -- Is_Limited_Composite -- Defined in all entities. Set for composite types that have a limited -- component. Used to enforce the rule that operations on the composite @@ -3638,7 +3663,7 @@ package Einfo is -- subprogram or the formal's Extra_Accessibility - whichever one is -- lesser. The Minimum_Accessibility field then points to this object. --- Modulus [base type only] +-- Modulus [implementation base type only] -- Defined in modular types. Contains the modulus. For the binary case, -- this will be a power of 2, but if Non_Binary_Modulus is set, then it -- will not be a power of 2. @@ -3658,11 +3683,6 @@ package Einfo is -- preelaborable initialization at freeze time (this has to be deferred -- to the freeze point because of the rule about overriding Initialize). --- Needs_Activation_Record --- Defined on generated subprogram types. Indicates that a call through --- a named or anonymous access to subprogram requires an activation --- record when compiling with unnesting for C or LLVM. - -- Needs_Debug_Info -- Defined in all entities. Set if the entity requires normal debugging -- information to be generated. This is true of all entities that have @@ -3904,7 +3924,7 @@ package Einfo is -- Defined in E_Access_Subprogram_Type entities. Set only if the access -- type was generated by the expander as part of processing an access- -- to-protected-subprogram type. Points to the access-to-protected- --- subprogram type. +-- subprogram type. Read by CodePeer. -- Original_Array_Type -- Defined in modular types and array types and subtypes. Set only if @@ -3939,17 +3959,24 @@ package Einfo is -- Points to the component in the base type. -- Overlays_Constant --- Defined in all entities. Set only for E_Constant or E_Variable for --- which there is an address clause that causes the entity to overlay --- a constant object. +-- Defined in constants and variables. Set if there is an address clause +-- that causes the entity to overlay a constant object. + +-- Overridden_Inherited_Operation +-- Defined in subprograms and enumeration literals. When set on a +-- subprogram S, indicates an inherited subprogram that S overrides. +-- In the case of a privately declared explicit subprogram E that +-- overrides a private inherited subprogram, and the inherited +-- subprogram itself overrides another inherited subprogram declared +-- for a private extension, the field on E will reference the subprogram +-- inherited by the private extension. This field is used for properly +-- handling visibility for such privately declared subprograms. This +-- field is always Empty for enumeration literal entities. -- Overridden_Operation -- Defined in subprograms. For overriding operations, points to the --- user-defined parent subprogram that is being overridden. Note: this --- attribute uses the same field as Static_Initialization. The latter --- is only defined for internal initialization procedures, for which --- Overridden_Operation is irrelevant. Thus this attribute must not be --- set for init_procs. +-- user-defined parent subprogram from which the inherited subprogram +-- that is being overridden is derived. -- Package_Instantiation -- Defined in packages and generic packages. When defined, this field @@ -4176,14 +4203,6 @@ package Einfo is -- refine the state, in other words, all the hidden states that appear in -- the constituent_list of aspect/pragma Refined_State. --- Register_Exception_Call --- Defined in exception entities. When an exception is declared, --- a call is expanded to Register_Exception. This field points to --- the expanded N_Procedure_Call_Statement node for this call. It --- is used for Import/Export_Exception processing to modify the --- register call to make appropriate entries in the special tables --- used for handling these pragmas at run time. - -- Related_Array_Object -- Defined in array types and subtypes. Used only for the base type -- and subtype created for an anonymous array object. Set to point @@ -4383,11 +4402,6 @@ package Einfo is -- set, in which case this is the entity for the associated instance of -- System.Shared_Storage.Shared_Var_Procs. See Exp_Smem for full details. --- Size_Check_Code --- Defined in constants and variables. Normally Empty. Set if code is --- generated to check the size of the object. This field is used to --- suppress this code if a subsequent address clause is encountered. - -- Size_Clause (synthesized) -- Applies to all entities. If a size or value size clause is present in -- the rep item chain for an entity then that attribute definition clause @@ -4516,9 +4530,7 @@ package Einfo is -- initialized statically. The value of this attribute is a positional -- aggregate whose components are compile-time static values. Used -- when available in object declarations to eliminate the call to the --- initialization procedure, and to minimize elaboration code. Note: --- This attribute uses the same field as Overridden_Operation, which is --- irrelevant in init_procs. +-- initialization procedure, and to minimize elaboration code. -- Static_Real_Or_String_Predicate -- Defined in real types/subtypes with static predicates (with the two @@ -4986,7 +4998,6 @@ package Einfo is -- Materialize_Entity -- Needs_Debug_Info -- Never_Set_In_Source - -- Overlays_Constant -- Referenced -- Referenced_As_LHS -- Referenced_As_Out_Parameter @@ -5158,10 +5169,9 @@ package Einfo is -- E_Access_Subprogram_Type -- Equivalent_Type (remote types only) -- Directly_Designated_Type - -- Needs_No_Actuals -- Original_Access_Type + -- Needs_No_Actuals -- Can_Use_Internal_Rep - -- Needs_Activation_Record -- Associated_Storage_Pool $$$ -- Interface_Name $$$ -- (plus type attributes) @@ -5200,7 +5210,6 @@ package Einfo is -- Directly_Designated_Type -- Storage_Size_Variable is this needed ??? -- Can_Use_Internal_Rep - -- Needs_Activation_Record -- (plus type attributes) -- E_Anonymous_Access_Type @@ -5311,12 +5320,11 @@ package Einfo is -- Actual_Subtype -- Renamed_Object -- Renamed_Entity $$$ - -- Size_Check_Code (constants only) -- Prival_Link (privals only) -- Interface_Name (constants only) -- Related_Type (constants only) -- Initialization_Statements - -- BIP_Initialization_Call + -- BIP_Initialization_Call (constants only) -- Finalization_Master_Node -- Last_Aggregate_Assignment -- Activation_Record_Component @@ -5346,6 +5354,7 @@ package Einfo is -- Is_Volatile_Full_Access -- Optimize_Alignment_Space (constants only) -- Optimize_Alignment_Time (constants only) + -- Overlays_Constant (constants only) -- SPARK_Pragma_Inherited (constants only) -- Stores_Attribute_Old_Prefix (constants only) -- Treat_As_Volatile @@ -5406,11 +5415,12 @@ package Einfo is -- Scope_Depth_Value -- Protection_Object (protected kind) -- Contract_Wrapper - -- Extra_Formals -- Contract -- SPARK_Pragma (protected kind) -- Default_Expressions_Processed -- Entry_Accepted + -- Extra_Formals + -- Extra_Formals_Known -- Has_Yield_Aspect -- Has_Expanded_Contract -- Ignore_SPARK_Mode_Pragmas @@ -5438,6 +5448,7 @@ package Einfo is -- Enumeration_Pos -- Enumeration_Rep -- Alias + -- Overridden_Inherited_Operation -- Enumeration_Rep_Expr -- Interface_Name $$$ -- Renamed_Object $$$ @@ -5472,7 +5483,6 @@ package Einfo is -- Esize -- Alignment -- Renamed_Entity - -- Register_Exception_Call -- Interface_Name -- Activation_Record_Component -- Discard_Names @@ -5508,7 +5518,6 @@ package Einfo is -- E_Function -- E_Generic_Function -- Mechanism (Mechanism_Type) - -- Handler_Records (non-generic case only) -- Protected_Body_Subprogram -- Next_Inlined_Subprogram -- Elaboration_Entity (not implicit /=) @@ -5529,9 +5538,11 @@ package Einfo is -- Subps_Index (non-generic case only) -- Interface_Alias -- LSP_Subprogram (non-generic case only) + -- Overridden_Inherited_Operation -- Overridden_Operation -- Wrapped_Entity (non-generic case only) -- Extra_Formals + -- Extra_Formals_Known (non-generic case only) -- Anonymous_Collections (non-generic case only) -- Corresponding_Equality (implicit /= only) -- Thunk_Entity (thunk case only) @@ -5662,7 +5673,6 @@ package Einfo is -- Renamed_Object -- Spec_Entity -- Default_Value - -- Default_Expr_Function -- Protected_Formal -- Extra_Constrained -- Minimum_Accessibility @@ -5733,9 +5743,12 @@ package Einfo is -- Extra_Accessibility_Of_Result -- Last_Entity -- Subps_Index + -- Overridden_Inherited_Operation -- Overridden_Operation -- Linker_Section_Pragma -- Contract + -- Extra_Formals + -- Extra_Formals_Known -- Import_Pragma -- LSP_Subprogram -- SPARK_Pragma @@ -5773,8 +5786,6 @@ package Einfo is -- E_Package -- E_Generic_Package - -- Dependent_Instances (for an instance) - -- Handler_Records (non-generic case only) -- Generic_Homonym (generic case only) -- Associated_Formal_Package -- Elaboration_Entity @@ -5834,7 +5845,6 @@ package Einfo is -- Scope_Depth (synth) -- E_Package_Body - -- Handler_Records (non-generic case only) -- Related_Instance (non-generic case only) -- First_Entity -- Spec_Entity @@ -5869,7 +5879,6 @@ package Einfo is -- E_Procedure -- E_Generic_Procedure -- Associated_Node_For_Itype $$$ E_Procedure - -- Handler_Records (non-generic case only) -- Protected_Body_Subprogram -- Next_Inlined_Subprogram -- Elaboration_Entity @@ -5890,9 +5899,11 @@ package Einfo is -- Subps_Index (non-generic case only) -- Interface_Alias -- LSP_Subprogram (non-generic case only) + -- Overridden_Inherited_Operation -- Overridden_Operation (never for init proc) -- Wrapped_Entity (non-generic case only) -- Extra_Formals + -- Extra_Formals_Known (non-generic case only) -- Anonymous_Collections (non-generic case only) -- Static_Initialization (init_proc only) -- Thunk_Entity (thunk case only) @@ -5931,6 +5942,7 @@ package Einfo is -- Is_Class_Wide_Wrapper -- Is_Constructor -- Is_CUDA_Kernel + -- Is_Destructor (non-generic case only) -- Is_DIC_Procedure (non-generic case only) -- Is_Elaboration_Checks_OK_Id -- Is_Elaboration_Warnings_OK_Id @@ -6120,6 +6132,7 @@ package Einfo is -- Last_Entity -- Scope_Depth_Value -- Extra_Formals + -- Extra_Formals_Known -- Anonymous_Collections -- Contract -- SPARK_Pragma @@ -6133,6 +6146,7 @@ package Einfo is -- Extra_Accessibility_Of_Result -- Directly_Designated_Type -- Extra_Formals + -- Extra_Formals_Known -- Access_Subprogram_Wrapper -- First_Formal (synth) -- First_Formal_With_Extras (synth) @@ -6197,7 +6211,6 @@ package Einfo is -- Renamed_Object -- Renamed_Entity $$$ -- Discriminal_Link $$$ - -- Size_Check_Code -- Prival_Link -- Interface_Name -- Shared_Var_Procs_Instance @@ -6241,6 +6254,7 @@ package Einfo is -- OK_To_Rename -- Optimize_Alignment_Space -- Optimize_Alignment_Time + -- Overlays_Constant -- SPARK_Pragma_Inherited -- Suppress_Initialization -- Treat_As_Volatile @@ -6269,7 +6283,6 @@ package Einfo is -- Entry_Formal $$$ -- Esize $$$ -- First_Entity $$$ - -- Handler_Records $$$ -- Interface_Name $$$ -- Last_Entity $$$ -- Renamed_Entity $$$ diff --git a/gcc/ada/diagnostics-repository.adb b/gcc/ada/errid.adb similarity index 90% rename from gcc/ada/diagnostics-repository.adb rename to gcc/ada/errid.adb index f01a2df6f9b5..46d319e2d540 100644 --- a/gcc/ada/diagnostics-repository.adb +++ b/gcc/ada/errid.adb @@ -2,7 +2,7 @@ -- -- -- GNAT COMPILER COMPONENTS -- -- -- --- D I A G N O S T I C S . R E P O S I T O R Y -- +-- E R R I D -- -- -- -- B o d y -- -- -- @@ -22,12 +22,24 @@ -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -with Diagnostics.JSON_Utils; use Diagnostics.JSON_Utils; -with Diagnostics.Utils; use Diagnostics.Utils; -with Diagnostics.Switch_Repository; use Diagnostics.Switch_Repository; -with Output; use Output; -package body Diagnostics.Repository is +with JSON_Utils; use JSON_Utils; +with Output; use Output; + +package body Errid is + + --------------- + -- To_String -- + --------------- + + function To_String (Id : Diagnostic_Id) return String is + begin + if Id = No_Diagnostic_Id then + return "GNAT0000"; + else + return Id'Img; + end if; + end To_String; --------------------------------- -- Print_Diagnostic_Repository -- @@ -119,4 +131,4 @@ package body Diagnostics.Repository is Write_Eol; end Print_Diagnostic_Repository; -end Diagnostics.Repository; +end Errid; diff --git a/gcc/ada/diagnostics-repository.ads b/gcc/ada/errid.ads similarity index 73% rename from gcc/ada/diagnostics-repository.ads rename to gcc/ada/errid.ads index 778c99126be6..4d56d73cdf57 100644 --- a/gcc/ada/diagnostics-repository.ads +++ b/gcc/ada/errid.ads @@ -2,7 +2,7 @@ -- -- -- GNAT COMPILER COMPONENTS -- -- -- --- D I A G N O S T I C S . R E P O S I T O R Y -- +-- E R R I D -- -- -- -- S p e c -- -- -- @@ -22,7 +22,41 @@ -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -package Diagnostics.Repository is + +with Types; use Types; +with Errsw; use Errsw; + +package Errid is + + type Status_Type is + (Active, + Deprecated); + + type Diagnostic_Id is + (No_Diagnostic_Id, + GNAT0001, + GNAT0002, + GNAT0003, + GNAT0004, + GNAT0005, + GNAT0006); + + function To_String (Id : Diagnostic_Id) return String; + -- Convert the diagnostic ID to a 4 character string padded with 0-s. + + type Diagnostic_Entry_Type is record + Status : Status_Type := Active; + + Human_Id : String_Ptr := null; + -- A human readable code for the diagnostic. If the diagnostic has a + -- switch with a human id then the human_id of the switch shall be used + -- in SARIF reports. + + Documentation : String_Ptr := null; + + Switch : Switch_Id := No_Switch_Id; + -- The switch that controls the diagnostic message. + end record; type Diagnostics_Registry_Type is array (Diagnostic_Id) of Diagnostic_Entry_Type; @@ -43,66 +77,36 @@ package Diagnostics.Repository is -- - Optionally additional information -- TODO: the mandatory fields for the documentation file could be changed - Diagnostic_Entries : Diagnostics_Registry_Type := - (No_Diagnostic_Id => (others => <>), + Diagnostic_Entries : constant Diagnostics_Registry_Type := + (No_Diagnostic_Id => <>, GNAT0001 => (Status => Active, Human_Id => new String'("Default_Iterator_Not_Primitive_Error"), Documentation => new String'("./error_codes/GNAT0001.md"), Switch => No_Switch_Id), GNAT0002 => - (Status => Active, - Human_Id => - new String'("Invalid_Operand_Types_For_Operator_Error"), - Documentation => new String'("./error_codes/GNAT0002.md"), - Switch => No_Switch_Id), - GNAT0003 => - (Status => Active, - Human_Id => - new String'("Invalid_Operand_Types_Left_To_Int_Error"), - Documentation => new String'("./error_codes/GNAT0003.md"), - Switch => No_Switch_Id), - GNAT0004 => - (Status => Active, - Human_Id => - new String'("Invalid_Operand_Types_Right_To_Int_Error"), - Documentation => new String'("./error_codes/GNAT0004.md"), - Switch => No_Switch_Id), - GNAT0005 => - (Status => Active, - Human_Id => - new String'("Invalid_Operand_Types_Left_Acc_Error"), - Documentation => new String'("./error_codes/GNAT0005.md"), - Switch => No_Switch_Id), - GNAT0006 => - (Status => Active, - Human_Id => - new String'("Invalid_Operand_Types_Right_Acc_Error"), - Documentation => new String'("./error_codes/GNAT0006.md"), - Switch => No_Switch_Id), - GNAT0007 => (Status => Active, Human_Id => new String'("Invalid_Operand_Types_General_Error"), Documentation => new String'("./error_codes/GNAT0007.md"), Switch => No_Switch_Id), - GNAT0008 => + GNAT0003 => (Status => Active, Human_Id => new String'("Pragma_No_Effect_With_Lock_Free_Warning"), Documentation => new String'("./error_codes/GNAT0008.md"), Switch => No_Switch_Id), - GNAT0009 => + GNAT0004 => (Status => Active, Human_Id => new String'("End_Loop_Expected_Error"), Documentation => new String'("./error_codes/GNAT0009.md"), Switch => No_Switch_Id), - GNAT0010 => + GNAT0005 => (Status => Active, Human_Id => new String'("Representation_Too_Late_Error"), Documentation => new String'("./error_codes/GNAT0010.md"), Switch => No_Switch_Id), - GNAT0011 => + GNAT0006 => (Status => Active, Human_Id => new String'("Mixed_Container_Aggregate_Error"), Documentation => new String'("./error_codes/GNAT0011.md"), @@ -110,4 +114,4 @@ package Diagnostics.Repository is procedure Print_Diagnostic_Repository; -end Diagnostics.Repository; +end Errid; diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb index 23c6b8855fd4..472fbbe6cb27 100644 --- a/gcc/ada/errout.adb +++ b/gcc/ada/errout.adb @@ -33,11 +33,13 @@ with Atree; use Atree; with Casing; use Casing; with Csets; use Csets; with Debug; use Debug; -with Diagnostics.Converter; use Diagnostics.Converter; with Einfo; use Einfo; with Einfo.Entities; use Einfo.Entities; with Einfo.Utils; use Einfo.Utils; with Erroutc; use Erroutc; +with Erroutc.Pretty_Emitter; +with Erroutc.SARIF_Emitter; +with Errsw; use Errsw; with Gnatvsn; use Gnatvsn; with Lib; use Lib; with Opt; use Opt; @@ -97,10 +99,14 @@ package body Errout is ----------------------- procedure Error_Msg_Internal - (Msg : String; - Span : Source_Span; - Opan : Source_Span; - Msg_Cont : Boolean); + (Msg : String; + Span : Source_Span; + Opan : Source_Span; + Msg_Cont : Boolean; + Error_Code : Diagnostic_Id := No_Diagnostic_Id; + Label : String := ""; + Spans : Labeled_Span_Array := No_Locations; + Fixes : Fix_Array := No_Fixes); -- This is the low-level routine used to post messages after dealing with -- the issue of messages placed on instantiations (which get broken up -- into separate calls in Error_Msg). Span is the location on which the @@ -271,11 +277,7 @@ package body Errout is begin if not M.Deleted then M.Deleted := True; - Warnings_Detected := Warnings_Detected - 1; - - if M.Warn_Err then - Warnings_Treated_As_Errors := Warnings_Treated_As_Errors - 1; - end if; + Decrease_Error_Msg_Count (M); end if; Id := M.Next; @@ -285,6 +287,115 @@ package body Errout is end loop; end Delete_Warning_And_Continuations; + ------------------ + -- Labeled_Span -- + ------------------ + + function Labeled_Span + (Span : Source_Span; + Label : String := ""; + Is_Primary : Boolean := True; + Is_Region : Boolean := False) + return Labeled_Span_Type + is + L : Labeled_Span_Type; + begin + L.Span := Span; + if Label /= "" then + L.Label := new String'(Label); + end if; + L.Is_Primary := Is_Primary; + L.Is_Region := Is_Region; + L.Next := No_Labeled_Span; + + return L; + end Labeled_Span; + + -------------------------- + -- Primary_Labeled_Span -- + -------------------------- + + function Primary_Labeled_Span + (Span : Source_Span; + Label : String := "") return Labeled_Span_Type + is + begin + return Labeled_Span (Span => Span, Label => Label, Is_Primary => True); + end Primary_Labeled_Span; + + -------------------------- + -- Primary_Labeled_Span -- + -------------------------- + + function Primary_Labeled_Span + (N : Node_Or_Entity_Id; + Label : String := "") return Labeled_Span_Type + is + begin + return Primary_Labeled_Span (To_Full_Span (N), Label); + end Primary_Labeled_Span; + + ---------------------------- + -- Secondary_Labeled_Span -- + ---------------------------- + + function Secondary_Labeled_Span + (Span : Source_Span; + Label : String := "") return Labeled_Span_Type + is + begin + return Labeled_Span (Span => Span, Label => Label, Is_Primary => False); + end Secondary_Labeled_Span; + + ---------------------------- + -- Secondary_Labeled_Span -- + ---------------------------- + + function Secondary_Labeled_Span + (N : Node_Or_Entity_Id; + Label : String := "") return Labeled_Span_Type + is + begin + return Secondary_Labeled_Span (To_Full_Span (N), Label); + end Secondary_Labeled_Span; + + ---------- + -- Edit -- + ---------- + + function Edit (Text : String; Span : Source_Span) return Edit_Type is + begin + return (Text => new String'(Text), Span => Span, Next => No_Edit); + end Edit; + + --------- + -- Fix -- + --------- + + function Fix (Description : String; Edits : Edit_Array) return Fix_Type is + First_Edit : Edit_Id := No_Edit; + Last_Edit : Edit_Id := No_Edit; + begin + for I in Edits'Range loop + Erroutc.Edits.Append (Edits (I)); + + if Last_Edit /= No_Edit then + Erroutc.Edits.Table (Last_Edit).Next := Erroutc.Edits.Last; + end if; + Last_Edit := Erroutc.Edits.Last; + + -- Store the first element in the edit chain + + if First_Edit = No_Edit then + First_Edit := Last_Edit; + end if; + end loop; + + return (Description => new String'(Description), + Edits => First_Edit, + Next => No_Fix); + end Fix; + --------------- -- Error_Msg -- --------------- @@ -328,9 +439,13 @@ package body Errout is end Error_Msg; procedure Error_Msg - (Msg : String; - Flag_Span : Source_Span; - N : Node_Id) + (Msg : String; + Flag_Span : Source_Span; + N : Node_Id; + Error_Code : Diagnostic_Id := No_Diagnostic_Id; + Label : String := ""; + Spans : Labeled_Span_Array := No_Locations; + Fixes : Fix_Array := No_Fixes) is Flag_Location : constant Source_Ptr := Flag_Span.Ptr; @@ -459,7 +574,15 @@ package body Errout is -- Error_Msg_Internal to place the message in the requested location. if Instantiation (Sindex) = No_Location then - Error_Msg_Internal (Msg, Flag_Span, Flag_Span, False); + Error_Msg_Internal + (Msg => Msg, + Span => Flag_Span, + Opan => Flag_Span, + Msg_Cont => False, + Error_Code => Error_Code, + Label => Label, + Spans => Spans, + Fixes => Fixes); return; end if; @@ -626,10 +749,14 @@ package body Errout is -- Here we output the original message on the outer instantiation Error_Msg_Internal - (Msg => Msg, - Span => To_Span (Actual_Error_Loc), - Opan => Flag_Span, - Msg_Cont => Msg_Cont_Status); + (Msg => Msg, + Span => To_Span (Actual_Error_Loc), + Opan => Flag_Span, + Msg_Cont => Msg_Cont_Status, + Error_Code => Error_Code, + Label => Label, + Spans => Spans, + Fixes => Fixes); end; end Error_Msg; @@ -715,7 +842,7 @@ package body Errout is -- error flag in this situation. S1 := Prev_Token_Ptr; - C := Source (S1); + C := Sinput.Source (S1); -- If the previous token is a string literal, we need a special approach -- since there may be white space inside the literal and we don't want @@ -728,10 +855,10 @@ package body Errout is loop S1 := S1 + 1; - if Source (S1) = C then + if Sinput.Source (S1) = C then S1 := S1 + 1; - exit when Source (S1) /= C; - elsif Source (S1) in Line_Terminator then + exit when Sinput.Source (S1) /= C; + elsif Sinput.Source (S1) in Line_Terminator then exit; end if; end loop; @@ -749,10 +876,11 @@ package body Errout is -- characters in this context, since this is only for error recovery. else - while Source (S1) not in Line_Terminator - and then Source (S1) /= ' ' - and then Source (S1) /= ASCII.HT - and then (Source (S1) /= '-' or else Source (S1 + 1) /= '-') + while Sinput.Source (S1) not in Line_Terminator + and then Sinput.Source (S1) /= ' ' + and then Sinput.Source (S1) /= ASCII.HT + and then (Sinput.Source (S1) /= '-' + or else Sinput.Source (S1 + 1) /= '-') and then S1 /= Token_Ptr loop S1 := S1 + 1; @@ -785,8 +913,8 @@ package body Errout is -- we would really like to place it in the "last" character of the tab -- space, but that it too much trouble to worry about). - elsif Source (Token_Ptr - 1) = ' ' - or else Source (Token_Ptr - 1) = ASCII.HT + elsif Sinput.Source (Token_Ptr - 1) = ' ' + or else Sinput.Source (Token_Ptr - 1) = ASCII.HT then Error_Msg (Msg, Token_Ptr - 1); @@ -842,13 +970,8 @@ package body Errout is ----------------- procedure Error_Msg_F (Msg : String; N : Node_Id) is - Fst, Lst : Node_Id; begin - First_And_Last_Nodes (N, Fst, Lst); - Error_Msg_NEL (Msg, N, N, - To_Span (Ptr => Sloc (Fst), - First => First_Sloc (Fst), - Last => Last_Sloc (Lst))); + Error_Msg_NEL (Msg, N, N, To_Full_Span_First (N)); end Error_Msg_F; ------------------ @@ -860,13 +983,8 @@ package body Errout is N : Node_Id; E : Node_Or_Entity_Id) is - Fst, Lst : Node_Id; begin - First_And_Last_Nodes (N, Fst, Lst); - Error_Msg_NEL (Msg, N, E, - To_Span (Ptr => Sloc (Fst), - First => First_Sloc (Fst), - Last => Last_Sloc (Lst))); + Error_Msg_NEL (Msg, N, E, To_Full_Span_First (N)); end Error_Msg_FE; ------------------------------ @@ -918,10 +1036,14 @@ package body Errout is ------------------------ procedure Error_Msg_Internal - (Msg : String; - Span : Source_Span; - Opan : Source_Span; - Msg_Cont : Boolean) + (Msg : String; + Span : Source_Span; + Opan : Source_Span; + Msg_Cont : Boolean; + Error_Code : Diagnostic_Id := No_Diagnostic_Id; + Label : String := ""; + Spans : Labeled_Span_Array := No_Locations; + Fixes : Fix_Array := No_Fixes) is Sptr : constant Source_Ptr := Span.Ptr; Optr : constant Source_Ptr := Opan.Ptr; @@ -934,8 +1056,11 @@ package body Errout is Temp_Msg : Error_Msg_Id; - Warn_Err : Boolean; - -- Set if warning to be treated as error + First_Fix : Fix_Id := No_Fix; + Last_Fix : Fix_Id := No_Fix; + + Primary_Loc : Labeled_Span_Id := No_Labeled_Span; + Last_Loc : Labeled_Span_Id := No_Labeled_Span; procedure Handle_Serious_Error; -- Internal procedure to do all error message handling for a serious @@ -1156,11 +1281,15 @@ package body Errout is -- Remove (style) or info: at start of message - if Msglen > 8 and then Msg_Buffer (1 .. 8) = "(style) " then - M := 9; + if Msglen > Style_Prefix'Length + and then Msg_Buffer (1 .. Style_Prefix'Length) = Style_Prefix + then + M := Style_Prefix'Length + 1; - elsif Msglen > 6 and then Msg_Buffer (1 .. 6) = "info: " then - M := 7; + elsif Msglen > Info_Prefix'Length + and then Msg_Buffer (1 .. Info_Prefix'Length) = Info_Prefix + then + M := Info_Prefix'Length + 1; else M := 1; @@ -1226,6 +1355,37 @@ package body Errout is return; end if; + if Continuation and then Has_Insertion_Line then + Erroutc.Locations.Append + (Primary_Labeled_Span (To_Span (Error_Msg_Sloc), Label)); + else + Erroutc.Locations.Append (Primary_Labeled_Span (Span, Label)); + end if; + + Primary_Loc := Erroutc.Locations.Last; + + Last_Loc := Primary_Loc; + + for Span of Spans loop + Erroutc.Locations.Append (Span); + Erroutc.Locations.Table (Last_Loc).Next := Erroutc.Locations.Last; + Last_Loc := Erroutc.Locations.Last; + end loop; + + for Fix of Fixes loop + Erroutc.Fixes.Append (Fix); + if Last_Fix /= No_Fix then + Erroutc.Fixes.Table (Last_Fix).Next := Erroutc.Fixes.Last; + end if; + Last_Fix := Erroutc.Fixes.Last; + + -- Store the first element in the fix chain + + if First_Fix = No_Fix then + First_Fix := Last_Fix; + end if; + end loop; + -- Here we build a new error object Errors.Append @@ -1240,29 +1400,38 @@ package body Errout is Line => Get_Physical_Line_Number (Sptr), Col => Get_Column_Number (Sptr), Compile_Time_Pragma => Is_Compile_Time_Msg, - Warn_Err => False, -- reset below + Warn_Err => None, -- reset below Warn_Chr => Warning_Msg_Char, Uncond => Is_Unconditional_Msg, Msg_Cont => Continuation, Deleted => False, - Kind => Error_Msg_Kind)); + Kind => Error_Msg_Kind, + Locations => Primary_Loc, + Id => Error_Code, + Switch => + Get_Switch_Id (Error_Msg_Kind, Warning_Msg_Char), + Fixes => First_Fix)); Cur_Msg := Errors.Last; - -- Test if warning to be treated as error - - Warn_Err := - Error_Msg_Kind in Warning | Style - and then (Warning_Treated_As_Error (Msg_Buffer (1 .. Msglen)) - or else Warning_Treated_As_Error (Get_Warning_Tag (Cur_Msg)) - or else Is_Runtime_Raise); - - -- Propagate Warn_Err to this message and preceding continuations. - - for J in reverse 1 .. Errors.Last loop - Errors.Table (J).Warn_Err := Warn_Err; - - exit when not Errors.Table (J).Msg_Cont; - end loop; + -- Test if a warning is to be treated as error: + -- * It is marked by a pragma Warning_As_Error + -- * Warning_Mode is Treat_Run_Time_Warnings_As_Errors and we are + -- dealing with a runtime warning. + -- * Warning_Mode is Warnings_As_Errors and it is not a compile time + -- message. + + if Error_Msg_Kind in Warning | Style then + if Warning_Treated_As_Error (Errors.Table (Cur_Msg)) then + Errors.Table (Cur_Msg).Warn_Err := From_Pragma; + elsif Warning_Mode = Treat_Run_Time_Warnings_As_Errors + and then Is_Runtime_Raise_Msg + then + Errors.Table (Cur_Msg).Warn_Err := From_Run_Time_As_Err; + elsif Warning_Mode = Treat_As_Error and then not Is_Compile_Time_Msg + then + Errors.Table (Cur_Msg).Warn_Err := From_Warn_As_Err; + end if; + end if; -- If immediate errors mode set, output error message now. Also output -- now if the -d1 debug flag is set (so node number message comes out @@ -1416,33 +1585,72 @@ package body Errout is -- Error_Msg_N -- ----------------- - procedure Error_Msg_N (Msg : String; N : Node_Or_Entity_Id) is - Fst, Lst : Node_Id; + procedure Error_Msg_N + (Msg : String; + N : Node_Or_Entity_Id; + Error_Code : Diagnostic_Id := No_Diagnostic_Id; + Label : String := ""; + Spans : Labeled_Span_Array := No_Locations; + Fixes : Fix_Array := No_Fixes) + is begin - First_And_Last_Nodes (N, Fst, Lst); - Error_Msg_NEL (Msg, N, N, - To_Span (Ptr => Sloc (N), - First => First_Sloc (Fst), - Last => Last_Sloc (Lst))); + Error_Msg_NEL + (Msg => Msg, + N => N, + E => N, + Flag_Span => To_Full_Span (N), + Error_Code => Error_Code, + Label => Label, + Spans => Spans, + Fixes => Fixes); end Error_Msg_N; + ---------------------- + -- Error_Msg_N_Gigi -- + ---------------------- + + procedure Error_Msg_N_Gigi (Msg : String; N : Node_Or_Entity_Id) is + begin + Error_Msg_N (Msg, N); + end Error_Msg_N_Gigi; + ------------------ -- Error_Msg_NE -- ------------------ procedure Error_Msg_NE + (Msg : String; + N : Node_Or_Entity_Id; + E : Node_Or_Entity_Id; + Error_Code : Diagnostic_Id := No_Diagnostic_Id; + Label : String := ""; + Spans : Labeled_Span_Array := No_Locations; + Fixes : Fix_Array := No_Fixes) + is + begin + Error_Msg_NEL + (Msg => Msg, + N => N, + E => E, + Flag_Span => To_Full_Span (N), + Error_Code => Error_Code, + Label => Label, + Spans => Spans, + Fixes => Fixes); + end Error_Msg_NE; + + ----------------------- + -- Error_Msg_NE_Gigi -- + ----------------------- + + procedure Error_Msg_NE_Gigi (Msg : String; N : Node_Or_Entity_Id; E : Node_Or_Entity_Id) is - Fst, Lst : Node_Id; begin - First_And_Last_Nodes (N, Fst, Lst); - Error_Msg_NEL (Msg, N, E, - To_Span (Ptr => Sloc (N), - First => First_Sloc (Fst), - Last => Last_Sloc (Lst))); - end Error_Msg_NE; + Error_Msg_NE (Msg, N, E); + end Error_Msg_NE_Gigi; ------------------- -- Error_Msg_NEL -- @@ -1465,10 +1673,14 @@ package body Errout is end Error_Msg_NEL; procedure Error_Msg_NEL - (Msg : String; - N : Node_Or_Entity_Id; - E : Node_Or_Entity_Id; - Flag_Span : Source_Span) + (Msg : String; + N : Node_Or_Entity_Id; + E : Node_Or_Entity_Id; + Flag_Span : Source_Span; + Error_Code : Diagnostic_Id := No_Diagnostic_Id; + Label : String := ""; + Spans : Labeled_Span_Array := No_Locations; + Fixes : Fix_Array := No_Fixes) is begin if Special_Msg_Delete (Msg, N, E) then @@ -1502,7 +1714,14 @@ package body Errout is then Debug_Output (N); Error_Msg_Node_1 := E; - Error_Msg (Msg, Flag_Span, N); + Error_Msg + (Msg => Msg, + Flag_Span => Flag_Span, + N => N, + Error_Code => Error_Code, + Label => Label, + Spans => Spans, + Fixes => Fixes); else Last_Killed := True; @@ -1522,17 +1741,12 @@ package body Errout is Msg : String; N : Node_Or_Entity_Id) is - Fst, Lst : Node_Id; begin if Eflag and then In_Extended_Main_Source_Unit (N) and then Comes_From_Source (N) then - First_And_Last_Nodes (N, Fst, Lst); - Error_Msg_NEL (Msg, N, N, - To_Span (Ptr => Sloc (N), - First => First_Sloc (Fst), - Last => Last_Sloc (Lst))); + Error_Msg_NEL (Msg, N, N, To_Full_Span (N)); end if; end Error_Msg_NW; @@ -1597,7 +1811,7 @@ package body Errout is begin if not Errors.Table (E).Deleted then Errors.Table (E).Deleted := True; - Warnings_Detected := Warnings_Detected - 1; + Decrease_Error_Msg_Count (Errors.Table (E)); end if; end Delete_Warning; @@ -2425,7 +2639,8 @@ package body Errout is Write_Str ("{""kind"":"); - if Errors.Table (E).Kind = Warning and then not Errors.Table (E).Warn_Err + if Errors.Table (E).Kind = Warning + and then Errors.Table (E).Warn_Err = None then Write_Str ("""warning"""); elsif Errors.Table (E).Kind in @@ -2457,9 +2672,13 @@ package body Errout is Write_Str (",""option"":""" & Option & """"); end if; - -- Print message content + -- Print message content and ensure that the removed style prefix is + -- still in the message. Write_Str (",""message"":"""); + if Errors.Table (E).Kind = Style then + Write_JSON_Escaped_String (Style_Prefix); + end if; Write_JSON_Escaped_String (Errors.Table (E).Text); Write_Str (""""); @@ -2488,7 +2707,7 @@ package body Errout is -- Output_Messages -- --------------------- - procedure Output_Messages is + procedure Output_Messages (Exit_Code : Exit_Code_Type) is -- Local subprograms @@ -2502,109 +2721,21 @@ package body Errout is procedure Write_Max_Errors; -- Write message if max errors reached - procedure Write_Source_Code_Lines - (Span : Source_Span; - SGR_Span : String); - -- Write the source code line corresponding to Span, as follows when - -- Span in on one line: - -- - -- line | actual code line here with Span somewhere - -- | ~~~~~^~~~ - -- - -- where the caret on the line points to location Span.Ptr, and the - -- range Span.First..Span.Last is underlined. - -- - -- or when the span is over multiple lines: - -- - -- line | beginning of the Span on this line - -- ... | ... - -- line>| actual code line here with Span.Ptr somewhere - -- ... | ... - -- line | end of the Span on this line - -- - -- or when the span is a simple location, as follows: - -- - -- line | actual code line here with Span somewhere - -- | ^ here - -- - -- where the caret on the line points to location Span.Ptr - -- - -- SGR_Span is the SGR string to start the section of code in the span, - -- that should be closed with SGR_Reset. - -------------------- -- Emit_Error_Msgs -- --------------------- procedure Emit_Error_Msgs is - Use_Prefix : Boolean; - E : Error_Msg_Id; + E : Error_Msg_Id; begin Set_Standard_Error; E := First_Error_Msg; while E /= No_Error_Msg loop - - -- If -gnatdF is used, separate main messages from previous - -- messages with a newline (unless it is an info message) and - -- make continuation messages follow the main message with only - -- an indentation of two space characters, without repeating - -- file:line:col: prefix. - - Use_Prefix := - not (Debug_Flag_FF and then Errors.Table (E).Msg_Cont); - if not Errors.Table (E).Deleted then - - if Debug_Flag_FF then - if Errors.Table (E).Msg_Cont then - Write_Str (" "); - elsif Errors.Table (E).Kind /= Info then - Write_Eol; - end if; - end if; - - if Use_Prefix then - Output_Msg_Location (E); - end if; - + Output_Msg_Location (E); Output_Msg_Text (E); Write_Eol; - - -- If -gnatdF is used, write the source code line - -- corresponding to the location of the main message (unless - -- it is an info message). Also write the source code line - -- corresponding to an insertion location inside - -- continuation messages. - - if Debug_Flag_FF - and then Errors.Table (E).Kind /= Info - then - if Errors.Table (E).Msg_Cont then - declare - Loc : constant Source_Ptr := - Errors.Table (E).Insertion_Sloc; - begin - if Loc /= No_Location then - Write_Source_Code_Lines - (To_Span (Loc), SGR_Span => SGR_Note); - end if; - end; - - else - declare - SGR_Span : constant String := - (if Errors.Table (E).Kind = Info then SGR_Note - elsif Errors.Table (E).Kind = Warning - and then not Errors.Table (E).Warn_Err - then SGR_Warning - else SGR_Error); - begin - Write_Source_Code_Lines - (Errors.Table (E).Optr, SGR_Span); - end; - end if; - end if; end if; E := Errors.Table (E).Next; @@ -2664,310 +2795,18 @@ package body Errout is end if; end Write_Max_Errors; - ----------------------------- - -- Write_Source_Code_Lines -- - ----------------------------- - - procedure Write_Source_Code_Lines - (Span : Source_Span; - SGR_Span : String) - is - function Get_Line_End - (Buf : Source_Buffer_Ptr; - Loc : Source_Ptr) return Source_Ptr; - -- Get the source location for the end of the line in Buf for Loc. If - -- Loc is past the end of Buf already, return Buf'Last. - - function Get_Line_Start - (Buf : Source_Buffer_Ptr; - Loc : Source_Ptr) return Source_Ptr; - -- Get the source location for the start of the line in Buf for Loc - - function Image (X : Positive; Width : Positive) return String; - -- Output number X over Width characters, with whitespace padding. - -- Only output the low-order Width digits of X, if X is larger than - -- Width digits. - - procedure Write_Buffer - (Buf : Source_Buffer_Ptr; - First : Source_Ptr; - Last : Source_Ptr); - -- Output the characters from First to Last position in Buf, using - -- Write_Buffer_Char. - - procedure Write_Buffer_Char - (Buf : Source_Buffer_Ptr; - Loc : Source_Ptr); - -- Output the characters at position Loc in Buf, translating ASCII.HT - -- in a suitable number of spaces so that the output is not modified - -- by starting in a different column that 1. - - procedure Write_Line_Marker - (Num : Pos; - Mark : Boolean; - Width : Positive); - -- Output the line number Num over Width characters, with possibly - -- a Mark to denote the line with the main location when reporting - -- a span over multiple lines. - - ------------------ - -- Get_Line_End -- - ------------------ - - function Get_Line_End - (Buf : Source_Buffer_Ptr; - Loc : Source_Ptr) return Source_Ptr - is - Cur_Loc : Source_Ptr := Source_Ptr'Min (Loc, Buf'Last); - begin - while Cur_Loc < Buf'Last - and then Buf (Cur_Loc) /= ASCII.LF - loop - Cur_Loc := Cur_Loc + 1; - end loop; - - return Cur_Loc; - end Get_Line_End; - - -------------------- - -- Get_Line_Start -- - -------------------- - - function Get_Line_Start - (Buf : Source_Buffer_Ptr; - Loc : Source_Ptr) return Source_Ptr - is - Cur_Loc : Source_Ptr := Loc; - begin - while Cur_Loc > Buf'First - and then Buf (Cur_Loc - 1) /= ASCII.LF - loop - Cur_Loc := Cur_Loc - 1; - end loop; - - return Cur_Loc; - end Get_Line_Start; - - ----------- - -- Image -- - ----------- - - function Image (X : Positive; Width : Positive) return String is - Str : String (1 .. Width); - Curr : Natural := X; - begin - for J in reverse 1 .. Width loop - if Curr > 0 then - Str (J) := Character'Val (Character'Pos ('0') + Curr mod 10); - Curr := Curr / 10; - else - Str (J) := ' '; - end if; - end loop; - - return Str; - end Image; - - ------------------ - -- Write_Buffer -- - ------------------ - - procedure Write_Buffer - (Buf : Source_Buffer_Ptr; - First : Source_Ptr; - Last : Source_Ptr) - is - begin - for Loc in First .. Last loop - Write_Buffer_Char (Buf, Loc); - end loop; - end Write_Buffer; - - ----------------------- - -- Write_Buffer_Char -- - ----------------------- - - procedure Write_Buffer_Char - (Buf : Source_Buffer_Ptr; - Loc : Source_Ptr) - is - begin - -- If the character ASCII.HT is not the last one in the file, - -- output as many spaces as the character represents in the - -- original source file. - - if Buf (Loc) = ASCII.HT - and then Loc < Buf'Last - then - for X in Get_Column_Number (Loc) .. - Get_Column_Number (Loc + 1) - 1 - loop - Write_Char (' '); - end loop; - - -- Otherwise output the character itself - - else - Write_Char (Buf (Loc)); - end if; - end Write_Buffer_Char; - - ----------------------- - -- Write_Line_Marker -- - ----------------------- - - procedure Write_Line_Marker - (Num : Pos; - Mark : Boolean; - Width : Positive) - is - begin - Write_Str (Image (Positive (Num), Width => Width)); - Write_Str ((if Mark then ">" else " ") & "|"); - end Write_Line_Marker; - - -- Local variables - - Loc : constant Source_Ptr := Span.Ptr; - Line : constant Pos := Pos (Get_Physical_Line_Number (Loc)); - - Col : constant Natural := Natural (Get_Column_Number (Loc)); - - Fst : constant Source_Ptr := Span.First; - Line_Fst : constant Pos := - Pos (Get_Physical_Line_Number (Fst)); - Col_Fst : constant Natural := - Natural (Get_Column_Number (Fst)); - Lst : constant Source_Ptr := Span.Last; - Line_Lst : constant Pos := - Pos (Get_Physical_Line_Number (Lst)); - Col_Lst : constant Natural := - Natural (Get_Column_Number (Lst)); - - Width : constant := 5; - Buf : Source_Buffer_Ptr; - Cur_Loc : Source_Ptr := Fst; - Cur_Line : Pos := Line_Fst; - - -- Start of processing for Write_Source_Code_Lines - - begin - if Loc >= First_Source_Ptr then - Buf := Source_Text (Get_Source_File_Index (Loc)); - - -- First line of the span with actual source code. We retrieve - -- the beginning of the line instead of relying on Col_Fst, as - -- ASCII.HT characters change column numbers by possibly more - -- than one. - - Write_Line_Marker - (Cur_Line, - Line_Fst /= Line_Lst and then Cur_Line = Line, - Width); - Write_Buffer (Buf, Get_Line_Start (Buf, Cur_Loc), Cur_Loc - 1); - - -- Output the first/caret/last lines of the span, as well as - -- lines that are directly above/below the caret if they complete - -- the gap with first/last lines, otherwise use ... to denote - -- intermediate lines. - - -- If the span is on one line and not a simple source location, - -- color it appropriately. - - if Line_Fst = Line_Lst - and then Col_Fst /= Col_Lst - then - Write_Str (SGR_Span); - end if; - - declare - function Do_Write_Line (Cur_Line : Pos) return Boolean is - (Cur_Line in Line_Fst | Line | Line_Lst - or else - (Cur_Line = Line_Fst + 1 and then Cur_Line = Line - 1) - or else - (Cur_Line = Line + 1 and then Cur_Line = Line_Lst - 1)); - begin - while Cur_Loc <= Buf'Last - and then Cur_Loc <= Lst - loop - if Do_Write_Line (Cur_Line) then - Write_Buffer_Char (Buf, Cur_Loc); - end if; - - if Buf (Cur_Loc) = ASCII.LF then - Cur_Line := Cur_Line + 1; - - -- Output ... for skipped lines - - if (Cur_Line = Line - and then not Do_Write_Line (Cur_Line - 1)) - or else - (Cur_Line = Line + 1 - and then not Do_Write_Line (Cur_Line)) - then - Write_Str ((1 .. Width - 3 => ' ') & "... | ..."); - Write_Eol; - end if; - - -- Display the line marker if the line should be - -- displayed. - - if Do_Write_Line (Cur_Line) then - Write_Line_Marker - (Cur_Line, - Line_Fst /= Line_Lst and then Cur_Line = Line, - Width); - end if; - end if; - - Cur_Loc := Cur_Loc + 1; - end loop; - end; - - if Line_Fst = Line_Lst - and then Col_Fst /= Col_Lst - then - Write_Str (SGR_Reset); - end if; - - -- Output the rest of the last line of the span - - Write_Buffer (Buf, Cur_Loc, Get_Line_End (Buf, Cur_Loc)); - - -- If the span is on one line, output a second line with caret - -- sign pointing to location Loc - - if Line_Fst = Line_Lst then - Write_Str (String'(1 .. Width => ' ')); - Write_Str (" |"); - Write_Str (String'(1 .. Col_Fst - 1 => ' ')); - - Write_Str (SGR_Span); - - Write_Str (String'(Col_Fst .. Col - 1 => '~')); - Write_Str ("^"); - Write_Str (String'(Col + 1 .. Col_Lst => '~')); - - -- If the span is really just a location, add the word "here" - -- to clarify this is the location for the message. - - if Col_Fst = Col_Lst then - Write_Str (" here"); - end if; - - Write_Str (SGR_Reset); - - Write_Eol; - end if; - end if; - end Write_Source_Code_Lines; - -- Local variables E : Error_Msg_Id; Err_Flag : Boolean; + Sarif_File_Name : constant String := + Get_First_Main_File_Name & ".gnat.sarif"; + Switches_File_Name : constant String := "gnat_switches.json"; + Diagnostics_File_Name : constant String := "gnat_diagnostics.json"; + + Dummy : Boolean; + -- Start of processing for Output_Messages begin @@ -2977,6 +2816,8 @@ package body Errout is raise Program_Error; end if; + Erroutc.Exit_Code := Exit_Code; + -- Reset current error source file if the main unit has a pragma -- Source_Reference. This ensures outputting the proper name of -- the source file in this situation. @@ -3039,15 +2880,72 @@ package body Errout is -- Use updated diagnostic mechanism - if Debug_Flag_Underscore_DD then - Convert_Errors_To_Diagnostics; + if Opt.SARIF_Output then + Set_Standard_Error; + Erroutc.SARIF_Emitter.Print_SARIF_Report; + Set_Standard_Output; - Emit_Diagnostics; + elsif Opt.SARIF_File then + System.OS_Lib.Delete_File (Sarif_File_Name, Dummy); + declare + Output_FD : + constant System.OS_Lib.File_Descriptor := + System.OS_Lib.Create_New_File + (Sarif_File_Name, Fmode => System.OS_Lib.Text); + + begin + Set_Output (Output_FD); + Erroutc.SARIF_Emitter.Print_SARIF_Report; + Set_Standard_Output; + System.OS_Lib.Close (Output_FD); + end; + elsif Debug_Flag_FF then + Erroutc.Pretty_Emitter.Print_Error_Messages; else Emit_Error_Msgs; end if; end if; + if Debug_Flag_Underscore_EE then + -- Print the switch repository to a file + + System.OS_Lib.Delete_File (Switches_File_Name, Dummy); + declare + Output_FD : constant System.OS_Lib.File_Descriptor := + System.OS_Lib.Create_New_File + (Switches_File_Name, + Fmode => System.OS_Lib.Text); + + begin + Set_Output (Output_FD); + + Print_Switch_Repository; + + Set_Standard_Output; + + System.OS_Lib.Close (Output_FD); + end; + + -- Print the diagnostics repository to a file + + System.OS_Lib.Delete_File (Diagnostics_File_Name, Dummy); + declare + Output_FD : constant System.OS_Lib.File_Descriptor := + System.OS_Lib.Create_New_File + (Diagnostics_File_Name, + Fmode => System.OS_Lib.Text); + + begin + Set_Output (Output_FD); + + Print_Diagnostic_Repository; + + Set_Standard_Output; + + System.OS_Lib.Close (Output_FD); + end; + end if; + -- Full source listing case if Full_List then @@ -3241,19 +3139,10 @@ package body Errout is end if; if Warning_Mode = Treat_As_Error then - declare - Compile_Time_Pragma_Warnings : constant Nat := - Count_Compile_Time_Pragma_Warnings; - Total : constant Int := Total_Errors_Detected + Warnings_Detected - - Compile_Time_Pragma_Warnings; - -- We need to protect against a negative Total here, because - -- if a pragma Compile_Time_Warning occurs in dead code, it - -- gets counted in Compile_Time_Pragma_Warnings but not in - -- Warnings_Detected. - begin - Total_Errors_Detected := Int'Max (Total, 0); - Warnings_Detected := Compile_Time_Pragma_Warnings; - end; + pragma Assert (Warnings_Detected >= Warnings_Treated_As_Errors); + Total_Errors_Detected := + Total_Errors_Detected + Warnings_Treated_As_Errors; + Warnings_Detected := Warnings_Detected - Warnings_Treated_As_Errors; end if; end Output_Messages; @@ -3442,7 +3331,7 @@ package body Errout is and then not Errors.Table (E).Uncond then - Warnings_Detected := Warnings_Detected - 1; + Decrease_Error_Msg_Count (Errors.Table (E)); return True; @@ -3467,6 +3356,8 @@ package body Errout is E := First_Error_Msg; while E /= No_Error_Msg loop while To_Be_Removed (Errors.Table (E).Next) loop + Errors.Table (Errors.Table (E).Next).Deleted := True; + Errors.Table (E).Next := Errors.Table (Errors.Table (E).Next).Next; @@ -4056,17 +3947,45 @@ package body Errout is Msglen := 0; Flag_Source := Get_Source_File_Index (Flag); - -- Skip info: at start, we have recorded this in Error_Msg_Kind, and - -- this will be used (Info field in error message object) to put back - -- the string when it is printed. We need to do this, or we get confused + P := Text'First; + + -- Skip the continuation symbols at the start + + if P <= Text'Last and then Text (P) = '\' then + Continuation := True; + P := P + 1; + + if P <= Text'Last and then Text (P) = '\' then + Continuation_New_Line := True; + P := P + 1; + end if; + end if; + + -- Skip the message kind tokens at start since it is recorded + -- in Error_Msg_Kind, and this will be used to put back the string when + -- it is printed. We need to do this, or we get confused -- with instantiation continuations. - if Text'Length > 6 - and then Text (Text'First .. Text'First + 5) = "info: " + if Text'Length > P + Info_Prefix'Length - 1 + and then Text (P .. P + Info_Prefix'Length - 1) = Info_Prefix then - P := Text'First + 6; - else - P := Text'First; + P := P + Info_Prefix'Length; + elsif Text'Length > P + Style_Prefix'Length - 1 + and then Text (P .. P + Style_Prefix'Length - 1) = Style_Prefix + then + P := P + Style_Prefix'Length; + elsif Text'Length > P + High_Prefix'Length - 1 + and then Text (P .. P + High_Prefix'Length - 1) = High_Prefix + then + P := P + High_Prefix'Length; + elsif Text'Length > P + Medium_Prefix'Length - 1 + and then Text (P .. P + Medium_Prefix'Length - 1) = Medium_Prefix + then + P := P + Medium_Prefix'Length; + elsif Text'Length > P + Low_Prefix'Length - 1 + and then Text (P .. P + Low_Prefix'Length - 1) = Low_Prefix + then + P := P + Low_Prefix'Length; end if; -- Loop through characters of message @@ -4109,14 +4028,6 @@ package body Errout is when '#' => Set_Msg_Insertion_Line_Number (Error_Msg_Sloc, Flag); - when '\' => - Continuation := True; - - if P <= Text'Last and then Text (P) = '\' then - Continuation_New_Line := True; - P := P + 1; - end if; - when '@' => Set_Msg_Insertion_Column; @@ -4176,15 +4087,7 @@ package body Errout is Set_Msg_Insertion_Code; else - -- Switch the message from a warning to an error if the flag - -- -gnatwE is specified to treat run-time exception warnings - -- as non-serious errors. - - if Error_Msg_Kind = Warning - and then Warning_Mode = Treat_Run_Time_Warnings_As_Errors - then - Is_Runtime_Raise := True; - end if; + Is_Runtime_Raise_Msg := True; if Error_Msg_Kind = Warning then Set_Msg_Str ("will be raised at run time"); @@ -4372,6 +4275,48 @@ package body Errout is end if; end SPARK_Msg_NE; + ------------------ + -- To_Full_Span -- + ------------------ + + function To_Full_Span (N : Node_Id) return Source_Span is + Fst, Lst : Node_Id; + begin + First_And_Last_Nodes (N, Fst, Lst); + return To_Span (Ptr => Sloc (N), + First => First_Sloc (Fst), + Last => Last_Sloc (Lst)); + end To_Full_Span; + + ------------------------ + -- To_Full_Span_First -- + ------------------------ + + function To_Full_Span_First (N : Node_Id) return Source_Span is + Fst, Lst : Node_Id; + begin + First_And_Last_Nodes (N, Fst, Lst); + return To_Span (Ptr => Sloc (Fst), + First => First_Sloc (Fst), + Last => Last_Sloc (Lst)); + end To_Full_Span_First; + + ------------- + -- To_Name -- + ------------- + + function To_Name (E : Entity_Id) return String is + begin + -- The name of the node operator "&" has many special cases. Reuse the + -- node to name conversion implementation from the errout package for + -- now. + + Error_Msg_Node_1 := E; + Set_Msg_Text ("&", Sloc (E)); + + return Msg_Buffer (1 .. Msglen); + end To_Name; + -------------------------- -- Unwind_Internal_Type -- -------------------------- diff --git a/gcc/ada/errout.ads b/gcc/ada/errout.ads index 24cc1c233a92..40b5155f3f7f 100644 --- a/gcc/ada/errout.ads +++ b/gcc/ada/errout.ads @@ -30,7 +30,9 @@ with Err_Vars; with Erroutc; +with Errid; use Errid; with Namet; use Namet; +with Osint; use Osint; with Table; with Types; use Types; with Uintp; use Uintp; @@ -580,6 +582,19 @@ package Errout is -- client to set this to No_Error_Msg and then test it to see if a warning -- message has been issued. + subtype Labeled_Span_Type is Erroutc.Labeled_Span_Type; + subtype Fix_Type is Erroutc.Fix_Type; + subtype Edit_Type is Erroutc.Edit_Type; + + type Labeled_Span_Array is + array (Positive range <>) of Labeled_Span_Type; + type Fix_Array is array (Positive range <>) of Fix_Type; + type Edit_Array is array (Positive range <>) of Edit_Type; + + No_Locations : constant Labeled_Span_Array (1 .. 0) := (others => <>); + No_Fixes : constant Fix_Array (1 .. 0) := (others => <>); + No_Edits : constant Edit_Array (1 .. 0) := (others => <>); + procedure Delete_Warning_And_Continuations (Msg : Error_Msg_Id); -- Deletes the given warning message and all its continuations. This is -- typically used in conjunction with reading the value of Warning_Msg. @@ -702,9 +717,9 @@ package Errout is -- and must be set True on the last call (a value of True activates some -- processing that must only be done after all messages are posted). - procedure Output_Messages; + procedure Output_Messages (Exit_Code : Exit_Code_Type); -- Output list of messages, including messages giving number of detected - -- errors and warnings. + -- errors and warnings and store the exit code used. procedure Error_Msg (Msg : String; Flag_Location : Source_Ptr); @@ -713,11 +728,24 @@ package Errout is procedure Error_Msg (Msg : String; Flag_Location : Source_Ptr; N : Node_Id); procedure Error_Msg - (Msg : String; Flag_Span : Source_Span; N : Node_Id); + (Msg : String; + Flag_Span : Source_Span; + N : Node_Id; + Error_Code : Diagnostic_Id := No_Diagnostic_Id; + Label : String := ""; + Spans : Labeled_Span_Array := No_Locations; + Fixes : Fix_Array := No_Fixes); -- Output a message at specified location. Can be called from the parser -- or the semantic analyzer. If N is set, points to the relevant node for -- this message. The version with a span is preferred whenever possible, -- in other cases the version with a location can still be used. + -- + -- @param Error_Code is the unique identifier for that kind of message. + -- @param Label specifies an optional short label that will be displayed + -- under the Flag_Span. + -- @param Spans specifies other spans with labels that will be highlighted + -- in the error message. + -- @param Fixes contains a list of possible fixes for the error message. procedure Error_Msg (Msg : String; @@ -753,7 +781,13 @@ package Errout is -- Output a message at the start of the previous token. This routine can -- be called only from the parser, since it references Prev_Token_Ptr. - procedure Error_Msg_N (Msg : String; N : Node_Or_Entity_Id); + procedure Error_Msg_N + (Msg : String; + N : Node_Or_Entity_Id; + Error_Code : Diagnostic_Id := No_Diagnostic_Id; + Label : String := ""; + Spans : Labeled_Span_Array := No_Locations; + Fixes : Fix_Array := No_Fixes); -- Output a message at the Sloc of the given node. This routine can be -- called from the parser or the semantic analyzer, although the call from -- the latter is much more common (and is the most usual way of generating @@ -762,6 +796,9 @@ package Errout is -- suppressed if the node N already has a message posted, or if it is a -- warning and N is an entity node for which warnings are suppressed. + procedure Error_Msg_N_Gigi (Msg : String; N : Node_Or_Entity_Id); + -- This is a wrapper for the Error_Msg_N method that gets linked to gigi. + -- -- WARNING: There is a matching C declaration of this subprogram in fe.h procedure Error_Msg_F (Msg : String; N : Node_Id); @@ -771,15 +808,23 @@ package Errout is -- want for placing an error message flag in the right place. procedure Error_Msg_NE - (Msg : String; - N : Node_Or_Entity_Id; - E : Node_Or_Entity_Id); + (Msg : String; + N : Node_Or_Entity_Id; + E : Node_Or_Entity_Id; + Error_Code : Diagnostic_Id := No_Diagnostic_Id; + Label : String := ""; + Spans : Labeled_Span_Array := No_Locations; + Fixes : Fix_Array := No_Fixes); -- Output a message at the Sloc of the given node N, with an insertion of -- the name from the given entity node E. This is used by the semantic -- routines, where this is a common error message situation. The Msg text -- will contain a & or } as usual to mark the insertion point. This -- routine can be called from the parser or the analyzer. + procedure Error_Msg_NE_Gigi + (Msg : String; N : Node_Or_Entity_Id; E : Node_Or_Entity_Id); + -- This is a wrapper for the Error_Msg_NE method that gets linked to gigi. + -- -- WARNING: There is a matching C declaration of this subprogram in fe.h procedure Error_Msg_FE @@ -795,10 +840,14 @@ package Errout is E : Node_Or_Entity_Id; Flag_Location : Source_Ptr); procedure Error_Msg_NEL - (Msg : String; - N : Node_Or_Entity_Id; - E : Node_Or_Entity_Id; - Flag_Span : Source_Span); + (Msg : String; + N : Node_Or_Entity_Id; + E : Node_Or_Entity_Id; + Flag_Span : Source_Span; + Error_Code : Diagnostic_Id := No_Diagnostic_Id; + Label : String := ""; + Spans : Labeled_Span_Array := No_Locations; + Fixes : Fix_Array := No_Fixes); -- Exactly the same as Error_Msg_NE, except that the flag is placed at -- the specified Flag_Location/Flag_Span instead of at Sloc (N). @@ -827,6 +876,16 @@ package Errout is -- at the original source tree, since that's what we want for placing an -- error message flag in the right place. + function To_Full_Span (N : Node_Id) return Source_Span; + -- Creates a Source_Span by calculating the positions of its first and last + -- node contained by N in the source code and sets the span to point at the + -- location of N. + + function To_Full_Span_First (N : Node_Id) return Source_Span; + -- Creates a Source_Span by calculating the positions of its first and last + -- node contained by N in the source code and sets the span to point to the + -- starting position of the span. + function First_Node (C : Node_Id) return Node_Id; -- Return the first output of First_And_Last_Nodes @@ -966,6 +1025,32 @@ package Errout is procedure dmsg (Id : Error_Msg_Id) renames Erroutc.dmsg; -- Debugging routine to dump an error message + function Labeled_Span + (Span : Source_Span; + Label : String := ""; + Is_Primary : Boolean := True; + Is_Region : Boolean := False) + return Labeled_Span_Type; + -- Constructs a Labeled_Span structure with all of its attributes. + + function Primary_Labeled_Span + (Span : Source_Span; Label : String := "") return Labeled_Span_Type; + function Primary_Labeled_Span + (N : Node_Or_Entity_Id; Label : String := "") return Labeled_Span_Type; + -- Shorthand function for creating Primary Labeled_Spans + + function Secondary_Labeled_Span + (Span : Source_Span; Label : String := "") return Labeled_Span_Type; + function Secondary_Labeled_Span + (N : Node_Or_Entity_Id; Label : String := "") return Labeled_Span_Type; + -- Shorthand function for creating Secondary Labeled_Spans + + function Edit (Text : String; Span : Source_Span) return Edit_Type; + -- Constructs a Edit structure with all of its attributes. + + function Fix (Description : String; Edits : Edit_Array) return Fix_Type; + -- Constructs a Fix structure with all of its attributes. + ------------------------------------ -- SPARK Error Output Subprograms -- ------------------------------------ @@ -1028,4 +1113,8 @@ package Errout is -- Function Is_Size_Too_Small_Message tests for it by testing a prefix. -- The function and constant should be kept in synch. + function To_Name (E : Entity_Id) return String; + -- Converts an entities name into a String as if the '&' insertion + -- character was used. + end Errout; diff --git a/gcc/ada/diagnostics-pretty_emitter.adb b/gcc/ada/erroutc-pretty_emitter.adb similarity index 58% rename from gcc/ada/diagnostics-pretty_emitter.adb rename to gcc/ada/erroutc-pretty_emitter.adb index 6d3b90827301..72cc03fadb5a 100644 --- a/gcc/ada/diagnostics-pretty_emitter.adb +++ b/gcc/ada/erroutc-pretty_emitter.adb @@ -2,7 +2,7 @@ -- -- -- GNAT COMPILER COMPONENTS -- -- -- --- D I A G N O S T I C S . P R E T T Y _ E M I T T E R -- +-- E R R O U T C . P R E T T Y _ E M I T T E R -- -- -- -- B o d y -- -- -- @@ -23,12 +23,13 @@ -- -- ------------------------------------------------------------------------------ -with Diagnostics.Utils; use Diagnostics.Utils; -with Output; use Output; -with Sinput; use Sinput; -with Erroutc; use Erroutc; +with Namet; use Namet; +with Opt; use Opt; +with Output; use Output; +with Sinput; use Sinput; +with GNAT.Lists; use GNAT.Lists; -package body Diagnostics.Pretty_Emitter is +package body Erroutc.Pretty_Emitter is REGION_OFFSET : constant := 1; -- Number of characters between the line bar and the region span @@ -46,17 +47,35 @@ package body Diagnostics.Pretty_Emitter is MAX_BAR_POS : constant := 7; -- The maximum position of the line bar from the start of the line + + procedure Destroy (Elem : in out Labeled_Span_Type); + pragma Inline (Destroy); + + procedure Destroy (Elem : in out Labeled_Span_Type) is + begin + -- Diagnostic elements will be freed when all the diagnostics have been + -- emitted. + null; + end Destroy; + + package Labeled_Span_Lists is new Doubly_Linked_Lists + (Element_Type => Labeled_Span_Type, + "=" => "=", + Destroy_Element => Destroy, + Check_Tampering => False); + subtype Labeled_Span_List is Labeled_Span_Lists.Doubly_Linked_List; + type Printable_Line is record - First : Source_Ptr; + First : Source_Ptr; -- The first character of the line - Last : Source_Ptr; + Last : Source_Ptr; -- The last character of the line Line_Nr : Pos; -- The line number - Spans : Labeled_Span_List; + Spans : Labeled_Span_List; -- The spans applied on the line end record; @@ -75,9 +94,14 @@ package body Diagnostics.Pretty_Emitter is subtype Lines_List is Lines_Lists.Doubly_Linked_List; type File_Sections is record - File : String_Ptr; + File : String_Ptr; -- Name of the file + Ptr : Source_Ptr; + -- Pointer to the Primary location in the file section that is printed + -- at the start of the file section. If there are none then the first + -- location in the section. + Lines : Lines_List; -- Lines to be printed for the file end record; @@ -86,9 +110,7 @@ package body Diagnostics.Pretty_Emitter is pragma Inline (Destroy); function Equals (L, R : File_Sections) return Boolean is - (L.File /= null - and then R.File /= null - and then L.File.all = R.File.all); + (L.File /= null and then R.File /= null and then L.File.all = R.File.all); package File_Section_Lists is new Doubly_Linked_Lists (Element_Type => File_Sections, @@ -98,8 +120,8 @@ package body Diagnostics.Pretty_Emitter is subtype File_Section_List is File_Section_Lists.Doubly_Linked_List; - function Create_File_Sections (Spans : Labeled_Span_List) - return File_Section_List; + function Create_File_Sections + (Locations : Labeled_Span_Id) return File_Section_List; -- Create a list of file sections from the labeled spans that are to be -- printed. -- @@ -107,36 +129,31 @@ package body Diagnostics.Pretty_Emitter is -- the file and the spans that are applied to each of those lines. procedure Create_File_Section - (Sections : in out File_Section_List; - Loc : Labeled_Span_Type); + (Sections : in out File_Section_List; Loc : Labeled_Span_Type); -- Create a new file section for the given labeled span. procedure Add_Printable_Line - (Lines : Lines_List; - Loc : Labeled_Span_Type; - S_Ptr : Source_Ptr); + (Lines : Lines_List; Loc : Labeled_Span_Type; S_Ptr : Source_Ptr); procedure Create_Printable_Line - (Lines : Lines_List; - Loc : Labeled_Span_Type; - S_Ptr : Source_Ptr); + (Lines : Lines_List; Loc : Labeled_Span_Type; S_Ptr : Source_Ptr); -- Create a new printable line for the given labeled span and add it in the -- correct position to the Lines list based on the line number. - function Has_Region_Span_Start (L : Printable_Line) return Boolean; - function Has_Region_Span_End (L : Printable_Line) return Boolean; + function Get_Region_Span + (Spans : Labeled_Span_List) return Labeled_Span_Type; function Has_Multiple_Labeled_Spans (L : Printable_Line) return Boolean; - procedure Write_Region_Delimiter; + procedure Write_Region_Delimiter (SGR_Code : String); -- Write the arms signifying the start and end of a region span -- e.g. +-- - procedure Write_Region_Bar; + procedure Write_Region_Bar (SGR_Code : String); -- Write the bar signifying the continuation of a region span -- e.g. | - procedure Write_Region_Continuation; + procedure Write_Region_Continuation (SGR_Code : String); -- Write the continuation signifying the continuation of a region span -- e.g. : @@ -144,33 +161,62 @@ package body Diagnostics.Pretty_Emitter is -- Write a number of whitespaces equal to the size of the region span function Trimmed_Image (I : Natural) return String; - - procedure Write_Span_Labels (Loc : Labeled_Span_Type; - L : Printable_Line; - Line_Size : Integer; - Idx : String; - Within_Region_Span : Boolean); - - procedure Write_File_Section (Sec : File_Sections; - Write_File_Name : Boolean; - File_Name_Offset : Integer); - - procedure Write_Labeled_Spans (Spans : Labeled_Span_List; - Write_File_Name : Boolean; - File_Name_Offset : Integer); + -- Removes the leading whitespace from the 'Image of a Natural number. + + procedure Write_Span_Labels + (Loc : Labeled_Span_Type; + L : Printable_Line; + Line_Size : Integer; + Idx : String; + Within_Region_Span : Boolean; + SGR_Code : String; + Region_Span_SGR_Code : String); + + procedure Write_File_Section + (Sec : File_Sections; + Write_File_Name : Boolean; + File_Name_Offset : Integer; + Include_Spans : Boolean; + SGR_Code : String := SGR_Note); + -- Prints the labled spans for a given File_Section. + -- + -- --> <File_Section.File_Name> + -- <Labeled_Spans inside the file> + + procedure Write_Labeled_Spans + (Locations : Labeled_Span_Id; + Write_File_Name : Boolean; + File_Name_Offset : Integer; + Include_Spans : Boolean := True; + SGR_Code : String := SGR_Note); + -- Pretty-prints all of the code regions indicated by the Locations. The + -- labeled spans in the Locations are grouped by file into File_Sections + -- and sorted by the file name of the Primary location followed by all + -- other locations sorted alphabetically. procedure Write_Intersecting_Labels - (Intersecting_Labels : Labeled_Span_List); + (Intersecting_Labels : Labeled_Span_List; SGR_Code : String); + -- Prints the indices and their associated labels of intersecting labels. + -- + -- Labeled spans that are insercting on the same line are printed without + -- labels. Instead the span pointer is replaced by an index number and in + -- the end all of the indices are printed with their associated labels. + -- + -- + -- 42 | [for I in V1.First_Index .. V1.Last_Index => V1(I), -6]; + -- | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + -- | 1- + -- | 2------------------------------------------- + -- | 1: positional element + -- | 2: named element function Get_Line_End - (Buf : Source_Buffer_Ptr; - Loc : Source_Ptr) return Source_Ptr; + (Buf : Source_Buffer_Ptr; Loc : Source_Ptr) return Source_Ptr; -- Get the source location for the end of the line (LF) in Buf for Loc. If -- Loc is past the end of Buf already, return Buf'Last. function Get_Line_Start - (Buf : Source_Buffer_Ptr; - Loc : Source_Ptr) return Source_Ptr; + (Buf : Source_Buffer_Ptr; Loc : Source_Ptr) return Source_Ptr; -- Get the source location for the start of the line in Buf for Loc function Get_First_Line_Char @@ -187,40 +233,50 @@ package body Diagnostics.Pretty_Emitter is -- Width digits. procedure Write_Buffer - (Buf : Source_Buffer_Ptr; - First : Source_Ptr; - Last : Source_Ptr); + (Buf : Source_Buffer_Ptr; First : Source_Ptr; Last : Source_Ptr); -- Output the characters from First to Last position in Buf, using -- Write_Buffer_Char. - procedure Write_Buffer_Char - (Buf : Source_Buffer_Ptr; - Loc : Source_Ptr); + procedure Write_Buffer_Char (Buf : Source_Buffer_Ptr; Loc : Source_Ptr); -- Output the characters at position Loc in Buf, translating ASCII.HT -- in a suitable number of spaces so that the output is not modified -- by starting in a different column that 1. - procedure Write_Line_Marker - (Num : Pos; - Width : Positive); + procedure Write_Line_Marker (Num : Pos; Width : Positive); + -- Attempts to write the line number within Width number of whitespaces + -- followed by a bar ':' symbol. + -- + -- e.g ' 12 |' + -- + -- This is usually used on source code lines that are marked by a span. procedure Write_Empty_Bar_Line (Width : Integer); + -- Writes Width number of whitespaces and a bar '|' symbol. + -- + -- e.g ' |' + -- + -- This is usually used on lines where the label is going to printed. procedure Write_Empty_Skip_Line (Width : Integer); + -- Writes Width number of whitespaces and a bar ':' symbol. + -- + -- e.g ' :' + -- + -- This is usually used between non-continous source lines that neec to be + -- printed. - procedure Write_Error_Msg_Line (Diag : Diagnostic_Type); + procedure Write_Error_Msg_Line (E_Msg : Error_Msg_Object); -- Write the error message line for the given diagnostic: -- -- '['<Diag.Id>']' <Diag.Kind>: <Diag.Message> ['['<Diag.Switch>']'] - function Should_Write_File_Name (Sub_Diag : Sub_Diagnostic_Type; - Diag : Diagnostic_Type) return Boolean; + function Should_Write_File_Name + (Sub_Diag : Error_Msg_Object; Diag : Error_Msg_Object) return Boolean; -- If the sub-diagnostic and the main diagnostic only point to the same -- file then there is no reason to add the file name to the sub-diagnostic. - function Should_Write_Spans (Sub_Diag : Sub_Diagnostic_Type; - Diag : Diagnostic_Type) - return Boolean; + function Should_Write_Spans + (Sub_Diag : Error_Msg_Object; Diag : Error_Msg_Object) return Boolean; -- Old sub-diagnostics used to have the same location as the main -- diagnostic in order to group them correctly. However in most cases -- it was not meant to point to a location but rather add an additional @@ -229,39 +285,55 @@ package body Diagnostics.Pretty_Emitter is -- If the sub-diagnostic and the main diagnostic have the same location -- then we should avoid printing the spans. - procedure Print_Edit - (Edit : Edit_Type; - Offset : Integer); + procedure Print_Diagnostic (E : Error_Msg_Id); + -- Entry point for printing a primary diagnostic message. - procedure Print_Fix - (Fix : Fix_Type; - Offset : Integer); + procedure Print_Edit (Edit : Edit_Type; Offset : Integer); + -- Prints an edit object as follows: + -- + -- --> <File_Name> + -- -<Line_Nr> <Old_Line> + -- +<Line_Nr> <New_Line> + + procedure Print_Fix (Fix : Fix_Type; Offset : Integer); + -- Prints a fix object as follows + -- + -- + Fix: <Fix.Description> + -- <Fix.Edits> procedure Print_Sub_Diagnostic - (Sub_Diag : Sub_Diagnostic_Type; - Diag : Diagnostic_Type; - Offset : Integer); + (Sub_Diag : Error_Msg_Object; Diag : Error_Msg_Object; Offset : Integer); + + function To_String (Sptr : Source_Ptr) return String; + -- Convert the source pointer to a string of the form: "file:line:column" + + function To_File_Name (Sptr : Source_Ptr) return String; + -- Converts the file name of the Sptr to a string. + + function Line_To_String (Sptr : Source_Ptr) return String; + -- Converts the logical line number of the Sptr to a string. + + function Column_To_String (Sptr : Source_Ptr) return String; + -- Converts the column number of the Sptr to a string. Column values less + -- than 10 are prefixed with a 0. ------------- -- Destroy -- ------------- - procedure Destroy (Elem : in out Printable_Line) - is + procedure Destroy (Elem : in out Printable_Line) is begin - -- Diagnostic elements will be freed when all the diagnostics have been - -- emitted. - null; + Labeled_Span_Lists.Destroy (Elem.Spans); end Destroy; ------------- -- Destroy -- ------------- - procedure Destroy (Elem : in out File_Sections) - is + procedure Destroy (Elem : in out File_Sections) is begin Free (Elem.File); + Lines_Lists.Destroy (Elem.Lines); end Destroy; ------------------ @@ -273,9 +345,7 @@ package body Diagnostics.Pretty_Emitter is is Cur_Loc : Source_Ptr := Source_Ptr'Min (Loc, Buf'Last); begin - while Cur_Loc < Buf'Last - and then Buf (Cur_Loc) /= ASCII.LF - loop + while Cur_Loc < Buf'Last and then Buf (Cur_Loc) /= ASCII.LF loop Cur_Loc := Cur_Loc + 1; end loop; @@ -291,9 +361,7 @@ package body Diagnostics.Pretty_Emitter is is Cur_Loc : Source_Ptr := Loc; begin - while Cur_Loc > Buf'First - and then Buf (Cur_Loc - 1) /= ASCII.LF - loop + while Cur_Loc > Buf'First and then Buf (Cur_Loc - 1) /= ASCII.LF loop Cur_Loc := Cur_Loc - 1; end loop; @@ -309,9 +377,7 @@ package body Diagnostics.Pretty_Emitter is is Cur_Loc : Source_Ptr := Get_Line_Start (Buf, Loc); begin - while Cur_Loc < Buf'Last - and then Buf (Cur_Loc) = ' ' - loop + while Cur_Loc < Buf'Last and then Buf (Cur_Loc) = ' ' loop Cur_Loc := Cur_Loc + 1; end loop; @@ -347,7 +413,7 @@ package body Diagnostics.Pretty_Emitter is for J in reverse 1 .. Width loop if Curr > 0 then Str (J) := Character'Val (Character'Pos ('0') + Curr mod 10); - Curr := Curr / 10; + Curr := Curr / 10; else Str (J) := ' '; end if; @@ -360,11 +426,10 @@ package body Diagnostics.Pretty_Emitter is -- Has_Multiple_Labeled_Spans -- -------------------------------- - function Has_Multiple_Labeled_Spans (L : Printable_Line) return Boolean - is + function Has_Multiple_Labeled_Spans (L : Printable_Line) return Boolean is Count : Natural := 0; - Loc : Labeled_Span_Type; + Loc : Labeled_Span_Type; Loc_It : Labeled_Span_Lists.Iterator := Labeled_Span_Lists.Iterate (L.Spans); begin @@ -378,64 +443,34 @@ package body Diagnostics.Pretty_Emitter is return Count > 1; end Has_Multiple_Labeled_Spans; - --------------------------- - -- Has_Region_Span_Start -- - --------------------------- + --------------------- + -- Get_Region_Span -- + --------------------- - function Has_Region_Span_Start (L : Printable_Line) return Boolean is + function Get_Region_Span + (Spans : Labeled_Span_List) return Labeled_Span_Type + is Loc : Labeled_Span_Type; Loc_It : Labeled_Span_Lists.Iterator := - Labeled_Span_Lists.Iterate (L.Spans); - - Has_Region_Start : Boolean := False; + Labeled_Span_Lists.Iterate (Spans); begin while Labeled_Span_Lists.Has_Next (Loc_It) loop Labeled_Span_Lists.Next (Loc_It, Loc); - if not Has_Region_Start - and then Loc.Is_Region - and then L.Line_Nr = - Pos (Get_Physical_Line_Number (Loc.Span.First)) - then - Has_Region_Start := True; + if Loc.Is_Region then + return Loc; end if; end loop; - return Has_Region_Start; - end Has_Region_Span_Start; - - ------------------------- - -- Has_Region_Span_End -- - ------------------------- - - function Has_Region_Span_End (L : Printable_Line) return Boolean is - Loc : Labeled_Span_Type; - Loc_It : Labeled_Span_Lists.Iterator := - Labeled_Span_Lists.Iterate (L.Spans); - - Has_Region_End : Boolean := False; - begin - while Labeled_Span_Lists.Has_Next (Loc_It) loop - Labeled_Span_Lists.Next (Loc_It, Loc); - if not Has_Region_End - and then Loc.Is_Region - and then L.Line_Nr = - Pos (Get_Physical_Line_Number (Loc.Span.Last)) - then - Has_Region_End := True; - end if; - end loop; - return Has_Region_End; - end Has_Region_Span_End; + return No_Labeled_Span_Object; + end Get_Region_Span; ------------------ -- Write_Buffer -- ------------------ procedure Write_Buffer - (Buf : Source_Buffer_Ptr; - First : Source_Ptr; - Last : Source_Ptr) + (Buf : Source_Buffer_Ptr; First : Source_Ptr; Last : Source_Ptr) is begin for Loc in First .. Last loop @@ -447,20 +482,14 @@ package body Diagnostics.Pretty_Emitter is -- Write_Buffer_Char -- ----------------------- - procedure Write_Buffer_Char - (Buf : Source_Buffer_Ptr; - Loc : Source_Ptr) - is + procedure Write_Buffer_Char (Buf : Source_Buffer_Ptr; Loc : Source_Ptr) is begin -- If the character ASCII.HT is not the last one in the file, -- output as many spaces as the character represents in the -- original source file. - if Buf (Loc) = ASCII.HT - and then Loc < Buf'Last - then - for X in Get_Column_Number (Loc) .. - Get_Column_Number (Loc + 1) - 1 + if Buf (Loc) = ASCII.HT and then Loc < Buf'Last then + for X in Get_Column_Number (Loc) .. Get_Column_Number (Loc + 1) - 1 loop Write_Char (' '); end loop; @@ -476,10 +505,7 @@ package body Diagnostics.Pretty_Emitter is -- Write_Line_Marker -- ----------------------- - procedure Write_Line_Marker - (Num : Pos; - Width : Positive) - is + procedure Write_Line_Marker (Num : Pos; Width : Positive) is begin Write_Str (Image (Positive (Num), Width => Width - 2)); Write_Str (" |"); @@ -511,23 +537,27 @@ package body Diagnostics.Pretty_Emitter is -- Write_Region_Delimiter -- ---------------------------- - procedure Write_Region_Delimiter is + procedure Write_Region_Delimiter (SGR_Code : String) is begin Write_Str (String'(1 .. REGION_OFFSET => ' ')); + Write_Str (SGR_Code); Write_Str ("+"); Write_Str (String'(1 .. REGION_ARM_SIZE => '-')); + Write_Str (SGR_Reset); end Write_Region_Delimiter; ---------------------- -- Write_Region_Bar -- ---------------------- - procedure Write_Region_Bar is + procedure Write_Region_Bar (SGR_Code : String) is begin Write_Str (String'(1 .. REGION_OFFSET => ' ')); + Write_Str (SGR_Code); Write_Str ("|"); + Write_Str (SGR_Reset); Write_Str (String'(1 .. REGION_ARM_SIZE => ' ')); end Write_Region_Bar; @@ -535,11 +565,13 @@ package body Diagnostics.Pretty_Emitter is -- Write_Region_Continuation -- ------------------------------- - procedure Write_Region_Continuation is + procedure Write_Region_Continuation (SGR_Code : String) is begin Write_Str (String'(1 .. REGION_OFFSET => ' ')); + Write_Str (SGR_Code); Write_Str (":"); + Write_Str (SGR_Reset); Write_Str (String'(1 .. REGION_ARM_SIZE => ' ')); end Write_Region_Continuation; @@ -562,8 +594,8 @@ package body Diagnostics.Pretty_Emitter is Loc : Labeled_Span_Type; S_Ptr : Source_Ptr) is - L : Printable_Line; - L_It : Lines_Lists.Iterator; + L : Printable_Line; + L_It : Lines_Lists.Iterator; Line_Ptr : constant Pos := Pos (Get_Physical_Line_Number (S_Ptr)); Line_Found : Boolean := False; @@ -590,16 +622,14 @@ package body Diagnostics.Pretty_Emitter is --------------------------- procedure Create_Printable_Line - (Lines : Lines_List; - Loc : Labeled_Span_Type; - S_Ptr : Source_Ptr) + (Lines : Lines_List; Loc : Labeled_Span_Type; S_Ptr : Source_Ptr) is Spans : constant Labeled_Span_List := Labeled_Span_Lists.Create; Buf : constant Source_Buffer_Ptr := Source_Text (Get_Source_File_Index (S_Ptr)); - Line_Nr : constant Pos := Pos (Get_Physical_Line_Number (S_Ptr)); + Line_Nr : constant Pos := Pos (Get_Physical_Line_Number (S_Ptr)); New_Line : constant Printable_Line := (First => Get_Line_Start (Buf, S_Ptr), @@ -620,9 +650,7 @@ package body Diagnostics.Pretty_Emitter is while Lines_Lists.Has_Next (L_It) loop Lines_Lists.Next (L_It, L); - if not Found_Greater_Line - and then L.Line_Nr > New_Line.Line_Nr - then + if not Found_Greater_Line and then L.Line_Nr > New_Line.Line_Nr then Found_Greater_Line := True; Insert_Before_Line := L; @@ -630,13 +658,10 @@ package body Diagnostics.Pretty_Emitter is end if; end loop; - if Found_Greater_Line then - - -- Insert after all the lines have been iterated over to avoid the - -- mutation lock in GNAT.Lists + -- Insert after all the lines have been iterated over to avoid the + -- mutation lock in GNAT.Lists. - null; - else + if not Found_Greater_Line then Lines_Lists.Append (Lines, New_Line); end if; end Create_Printable_Line; @@ -652,15 +677,15 @@ package body Diagnostics.Pretty_Emitter is -- Carret positions Ptr : constant Source_Ptr := Loc.Span.Ptr; - Line_Ptr : constant Pos := Pos (Get_Physical_Line_Number (Ptr)); + Line_Ptr : constant Pos := Pos (Get_Physical_Line_Number (Ptr)); -- Span start positions Fst : constant Source_Ptr := Loc.Span.First; - Line_Fst : constant Pos := Pos (Get_Physical_Line_Number (Fst)); + Line_Fst : constant Pos := Pos (Get_Physical_Line_Number (Fst)); -- Span end positions Lst : constant Source_Ptr := Loc.Span.Last; - Line_Lst : constant Pos := Pos (Get_Physical_Line_Number (Lst)); + Line_Lst : constant Pos := Pos (Get_Physical_Line_Number (Lst)); begin Create_Printable_Line (Lines, Loc, Fst); @@ -675,6 +700,7 @@ package body Diagnostics.Pretty_Emitter is File_Section_Lists.Append (Sections, (File => new String'(To_File_Name (Loc.Span.Ptr)), + Ptr => Loc.Span.Ptr, Lines => Lines)); end Create_File_Section; @@ -683,11 +709,10 @@ package body Diagnostics.Pretty_Emitter is -------------------------- function Create_File_Sections - (Spans : Labeled_Span_List) return File_Section_List + (Locations : Labeled_Span_Id) return File_Section_List is Loc : Labeled_Span_Type; - Loc_It : Labeled_Span_Lists.Iterator := - Labeled_Span_Lists.Iterate (Spans); + Loc_It : Labeled_Span_Id := Locations; Sections : File_Section_List := File_Section_Lists.Create; @@ -696,8 +721,8 @@ package body Diagnostics.Pretty_Emitter is File_Found : Boolean; begin - while Labeled_Span_Lists.Has_Next (Loc_It) loop - Labeled_Span_Lists.Next (Loc_It, Loc); + while Loc_It /= No_Labeled_Span loop + Loc := Erroutc.Locations.Table (Loc_It); File_Found := False; F_It := File_Section_Lists.Iterate (Sections); @@ -711,16 +736,20 @@ package body Diagnostics.Pretty_Emitter is File_Found := True; Add_Printable_Line (Sec.Lines, Loc, Loc.Span.First); - Add_Printable_Line (Sec.Lines, Loc, Loc.Span.Ptr); - Add_Printable_Line (Sec.Lines, Loc, Loc.Span.Last); + + if Loc.Is_Primary then + Sec.Ptr := Loc.Span.Ptr; + end if; end if; end loop; if not File_Found then Create_File_Section (Sections, Loc); end if; + + Loc_It := Loc.Next; end loop; return Sections; @@ -730,21 +759,24 @@ package body Diagnostics.Pretty_Emitter is -- Write_Span_Labels -- ----------------------- - procedure Write_Span_Labels (Loc : Labeled_Span_Type; - L : Printable_Line; - Line_Size : Integer; - Idx : String; - Within_Region_Span : Boolean) + procedure Write_Span_Labels + (Loc : Labeled_Span_Type; + L : Printable_Line; + Line_Size : Integer; + Idx : String; + Within_Region_Span : Boolean; + SGR_Code : String; + Region_Span_SGR_Code : String) is Span_Char : constant Character := (if Loc.Is_Primary then '~' else '-'); Buf : constant Source_Buffer_Ptr := Source_Text (Get_Source_File_Index (L.First)); - Col_L_Fst : constant Natural := Natural - (Get_Column_Number (Get_First_Line_Char (Buf, L.First))); - Col_L_Lst : constant Natural := Natural - (Get_Column_Number (Get_Last_Line_Char (Buf, L.Last))); + Col_L_Fst : constant Natural := + Natural (Get_Column_Number (Get_First_Line_Char (Buf, L.First))); + Col_L_Lst : constant Natural := + Natural (Get_Column_Number (Get_Last_Line_Char (Buf, L.Last))); -- Carret positions Ptr : constant Source_Ptr := Loc.Span.Ptr; @@ -775,8 +807,7 @@ package body Diagnostics.Pretty_Emitter is (if Line_Ptr = L.Line_Nr then Col_Ptr else Col_L_Fst); Span_Ptr_Lst : constant Natural := - (if Line_Ptr = L.Line_Nr - then Span_Ptr_Fst + Span_Sym'Length + (if Line_Ptr = L.Line_Nr then Span_Ptr_Fst + Span_Sym'Length else Span_Fst); begin @@ -784,13 +815,15 @@ package body Diagnostics.Pretty_Emitter is Write_Empty_Bar_Line (Line_Size); if Within_Region_Span then - Write_Region_Bar; + Write_Region_Bar (Region_Span_SGR_Code); else Write_Region_Offset; end if; Write_Str (String'(1 .. Span_Fst - 1 => ' ')); + Write_Str (SGR_Code); + if Line_Ptr = L.Line_Nr then Write_Str (String'(Span_Fst .. Col_Ptr - 1 => Span_Char)); Write_Str (Span_Sym); @@ -798,6 +831,8 @@ package body Diagnostics.Pretty_Emitter is Write_Str (String'(Span_Ptr_Lst .. Span_Lst => Span_Char)); + Write_Str (SGR_Reset); + Write_Eol; -- Write the label under the line unless it is an intersecting span. @@ -808,24 +843,27 @@ package body Diagnostics.Pretty_Emitter is Write_Empty_Bar_Line (Line_Size); if Within_Region_Span then - Write_Region_Bar; + Write_Region_Bar (Region_Span_SGR_Code); else Write_Region_Offset; end if; Write_Str (String'(1 .. Span_Fst - 1 => ' ')); + Write_Str (SGR_Code); Write_Str (Loc.Label.all); + Write_Str (SGR_Reset); Write_Eol; end if; else if Line_Lst = L.Line_Nr then Write_Empty_Bar_Line (Line_Size); Write_Str (String'(1 .. REGION_OFFSET => ' ')); + Write_Str (SGR_Code); Write_Str (Loc.Label.all); + Write_Str (SGR_Reset); Write_Eol; end if; end if; - end Write_Span_Labels; ------------------- @@ -833,7 +871,7 @@ package body Diagnostics.Pretty_Emitter is ------------------- function Trimmed_Image (I : Natural) return String is - Img_Raw : constant String := Natural'Image (I); + Img_Raw : constant String := Natural'Image (I); begin return Img_Raw (Img_Raw'First + 1 .. Img_Raw'Last); end Trimmed_Image; @@ -843,22 +881,24 @@ package body Diagnostics.Pretty_Emitter is ------------------------------- procedure Write_Intersecting_Labels - (Intersecting_Labels : Labeled_Span_List) + (Intersecting_Labels : Labeled_Span_List; SGR_Code : String) is - Ls : Labeled_Span_Type; - Ls_It : Labeled_Span_Lists.Iterator := + L : Labeled_Span_Type; + L_It : Labeled_Span_Lists.Iterator := Labeled_Span_Lists.Iterate (Intersecting_Labels); - Idx : Integer := 0; + Idx : Integer := 0; begin - while Labeled_Span_Lists.Has_Next (Ls_It) loop - Labeled_Span_Lists.Next (Ls_It, Ls); + while Labeled_Span_Lists.Has_Next (L_It) loop + Labeled_Span_Lists.Next (L_It, L); Idx := Idx + 1; Write_Empty_Bar_Line (MAX_BAR_POS); Write_Str (" "); + Write_Str ((if L.Is_Primary then SGR_Code else SGR_Note)); Write_Int (Int (Idx)); Write_Str (": "); - Write_Str (Ls.Label.all); + Write_Str (L.Label.all); + Write_Str (SGR_Reset); Write_Eol; end loop; end Write_Intersecting_Labels; @@ -867,18 +907,18 @@ package body Diagnostics.Pretty_Emitter is -- Write_File_Section -- ------------------------ - procedure Write_File_Section (Sec : File_Sections; - Write_File_Name : Boolean; - File_Name_Offset : Integer) + procedure Write_File_Section + (Sec : File_Sections; Write_File_Name : Boolean; + File_Name_Offset : Integer; Include_Spans : Boolean; + SGR_Code : String := SGR_Note) is use Lines_Lists; - L : Printable_Line; - L_It : Iterator := Iterate (Sec.Lines); + function Get_SGR_Code (L : Labeled_Span_Type) return String is + (if L.Is_Primary then SGR_Code else SGR_Note); - -- The error should be included in the first (primary) span of the file. - Loc : constant Labeled_Span_Type := - Labeled_Span_Lists.First (Lines_Lists.First (Sec.Lines).Spans); + L : Printable_Line; + L_It : Iterator := Iterate (Sec.Lines); Multiple_Labeled_Spans : Boolean := False; @@ -896,45 +936,62 @@ package body Diagnostics.Pretty_Emitter is -- offset the file start location for sub-diagnostics Write_Str (String'(1 .. File_Name_Offset => ' ')); - Write_Str ("--> " & To_String (Loc.Span.Ptr)); + Write_Str ("--> " & To_String (Sec.Ptr)); Write_Eol; end if; + -- Historically SPARK does not include spans in their info messages. + + if not Include_Spans then + return; + end if; + while Has_Next (L_It) loop Next (L_It, L); declare - Line_Nr : constant Pos := L.Line_Nr; + Line_Nr : constant Pos := L.Line_Nr; Line_Str : constant String := Trimmed_Image (Natural (Line_Nr)); Line_Size : constant Integer := Integer'Max (Line_Str'Length, MAX_BAR_POS); - Loc : Labeled_Span_Type; + Loc : Labeled_Span_Type; Loc_It : Labeled_Span_Lists.Iterator := Labeled_Span_Lists.Iterate (L.Spans); Buf : constant Source_Buffer_Ptr := Source_Text (Get_Source_File_Index (L.First)); + Region_Span : constant Labeled_Span_Type := + Get_Region_Span (L.Spans); + Contains_Region_Span_Start : constant Boolean := - Has_Region_Span_Start (L); + Region_Span /= No_Labeled_Span_Object + and then Line_Nr = + Pos (Get_Physical_Line_Number (Region_Span.Span.First)); Contains_Region_Span_End : constant Boolean := - Has_Region_Span_End (L); + Region_Span /= No_Labeled_Span_Object + and then Line_Nr = + Pos (Get_Physical_Line_Number (Region_Span.Span.Last)); + + Region_Span_Color : constant String := + (if Region_Span /= No_Labeled_Span_Object then + Get_SGR_Code (Region_Span) + else SGR_Note); begin if not Multiple_Labeled_Spans then - Multiple_Labeled_Spans := Has_Multiple_Labeled_Spans (L); + Multiple_Labeled_Spans := Has_Multiple_Labeled_Spans (L); end if; -- Write an empty line with the continuation symbol if the line -- numbers are not contiguous - if Prev_Line_Nr /= 0 - and then Pos (Prev_Line_Nr + 1) /= Line_Nr + if Prev_Line_Nr /= 0 and then Pos (Prev_Line_Nr + 1) /= Line_Nr then Write_Empty_Skip_Line (Line_Size); if Within_Region_Span then - Write_Region_Continuation; + Write_Region_Continuation (Region_Span_Color); end if; Write_Eol; @@ -950,28 +1007,23 @@ package body Diagnostics.Pretty_Emitter is -- whitespaces. if Contains_Region_Span_Start or Contains_Region_Span_End then - Write_Region_Delimiter; + Write_Region_Delimiter (Region_Span_Color); elsif Within_Region_Span then - Write_Region_Bar; + Write_Region_Bar (Region_Span_Color); else Write_Region_Offset; end if; -- Write the line itself - Write_Buffer - (Buf => Buf, - First => L.First, - Last => L.Last); + Write_Buffer (Buf => Buf, First => L.First, Last => L.Last); -- Write all the spans for the line while Labeled_Span_Lists.Has_Next (Loc_It) loop Labeled_Span_Lists.Next (Loc_It, Loc); - if Multiple_Labeled_Spans - and then Loc.Label /= null - then + if Multiple_Labeled_Spans and then Loc.Label /= null then -- Collect all the spans with labels to print them at the -- end. @@ -980,17 +1032,23 @@ package body Diagnostics.Pretty_Emitter is Idx := Idx + 1; - Write_Span_Labels (Loc, - L, - Line_Size, - Trimmed_Image (Idx), - Within_Region_Span); + Write_Span_Labels + (Loc => Loc, + L => L, + Line_Size => Line_Size, + Idx => Trimmed_Image (Idx), + Within_Region_Span => Within_Region_Span, + SGR_Code => Get_SGR_Code (Loc), + Region_Span_SGR_Code => Region_Span_Color); else - Write_Span_Labels (Loc, - L, - Line_Size, - "", - Within_Region_Span); + Write_Span_Labels + (Loc => Loc, + L => L, + Line_Size => Line_Size, + Idx => "", + Within_Region_Span => Within_Region_Span, + SGR_Code => Get_SGR_Code (Loc), + Region_Span_SGR_Code => Region_Span_Color); end if; end loop; @@ -1003,18 +1061,21 @@ package body Diagnostics.Pretty_Emitter is end; end loop; - Write_Intersecting_Labels (Intersecting_Labels); + Write_Intersecting_Labels (Intersecting_Labels, SGR_Code); end Write_File_Section; ------------------------- -- Write_Labeled_Spans -- ------------------------- - procedure Write_Labeled_Spans (Spans : Labeled_Span_List; - Write_File_Name : Boolean; - File_Name_Offset : Integer) + procedure Write_Labeled_Spans + (Locations : Labeled_Span_Id; + Write_File_Name : Boolean; + File_Name_Offset : Integer; + Include_Spans : Boolean := True; + SGR_Code : String := SGR_Note) is - Sections : File_Section_List := Create_File_Sections (Spans); + Sections : File_Section_List := Create_File_Sections (Locations); Sec : File_Sections; F_It : File_Section_Lists.Iterator := @@ -1024,7 +1085,11 @@ package body Diagnostics.Pretty_Emitter is File_Section_Lists.Next (F_It, Sec); Write_File_Section - (Sec, Write_File_Name, File_Name_Offset); + (Sec => Sec, + Write_File_Name => Write_File_Name, + File_Name_Offset => File_Name_Offset, + Include_Spans => Include_Spans, + SGR_Code => SGR_Code); end loop; File_Section_Lists.Destroy (Sections); @@ -1034,33 +1099,29 @@ package body Diagnostics.Pretty_Emitter is -- Write_Error_Msg_Line -- -------------------------- - procedure Write_Error_Msg_Line (Diag : Diagnostic_Type) is - Switch_Str : constant String := Get_Doc_Switch (Diag); - - Kind_Str : constant String := Kind_To_String (Diag); + procedure Write_Error_Msg_Line (E_Msg : Error_Msg_Object) is + Switch_Str : constant String := Get_Doc_Switch (E_Msg); - SGR_Code : constant String := - (if Kind_Str = "error" then SGR_Error - elsif Kind_Str = "warning" then SGR_Warning - elsif Kind_Str = "info" then SGR_Note - else SGR_Reset); + SGR_Code : constant String := Get_SGR_Code (E_Msg); begin Write_Str (SGR_Code); - Write_Str ("[" & To_String (Diag.Id) & "]"); + if not GNATprove_Mode or else E_Msg.Id /= No_Diagnostic_Id then + Write_Str ("[" & To_String (E_Msg.Id) & "]"); + end if; - Write_Str (" " & Kind_To_String (Diag) & ": "); + Write_Str (" " & Kind_To_String (E_Msg) & ": "); Write_Str (SGR_Reset); - Write_Str (Diag.Message.all); + Write_Str (E_Msg.Text.all); if Switch_Str /= "" then Write_Str (" " & Switch_Str); end if; - if Diag.Warn_Err then - Write_Str (" [warning-as-error]"); + if E_Msg.Warn_Err = From_Pragma then + Write_Str (" " & Warn_As_Err_Tag); end if; Write_Eol; @@ -1070,44 +1131,49 @@ package body Diagnostics.Pretty_Emitter is -- Should_Write_File_Name -- ---------------------------- - function Should_Write_File_Name (Sub_Diag : Sub_Diagnostic_Type; - Diag : Diagnostic_Type) - return Boolean + function Should_Write_File_Name + (Sub_Diag : Error_Msg_Object; Diag : Error_Msg_Object) return Boolean is - Sub_Loc : constant Labeled_Span_Type := Primary_Location (Sub_Diag); - Diag_Loc : constant Labeled_Span_Type := Primary_Location (Diag); + Sub_Loc : constant Labeled_Span_Type := + Locations.Table (Primary_Location (Sub_Diag)); + + Diag_Loc : constant Labeled_Span_Type := + Locations.Table (Primary_Location (Diag)); - function Has_Multiple_Files (Spans : Labeled_Span_List) return Boolean; + function Has_Multiple_Files (Diag : Error_Msg_Object) return Boolean; ------------------------ -- Has_Multiple_Files -- ------------------------ - function Has_Multiple_Files - (Spans : Labeled_Span_List) return Boolean - is + function Has_Multiple_Files (Diag : Error_Msg_Object) return Boolean is First : constant Labeled_Span_Type := - Labeled_Span_Lists.First (Spans); + Locations.Table (Diag.Locations); File : constant String := To_File_Name (First.Span.Ptr); - Loc : Labeled_Span_Type; - It : Labeled_Span_Lists.Iterator := - Labeled_Span_Lists.Iterate (Spans); - + Loc_Id : Labeled_Span_Id := Diag.Locations; + Loc : Labeled_Span_Type; begin - while Labeled_Span_Lists.Has_Next (It) loop - Labeled_Span_Lists.Next (It, Loc); + Loc_Id := Diag.Locations; + while Loc_Id /= No_Labeled_Span loop + Loc := Locations.Table (Loc_Id); if To_File_Name (Loc.Span.Ptr) /= File then return True; end if; + + Loc_Id := Loc.Next; end loop; + return False; end Has_Multiple_Files; + + -- Start of processing for Should_Write_File_Name + begin return - Has_Multiple_Files (Diag.Locations) + Has_Multiple_Files (Diag) or else To_File_Name (Sub_Loc.Span.Ptr) /= To_File_Name (Diag_Loc.Span.Ptr); end Should_Write_File_Name; @@ -1116,16 +1182,16 @@ package body Diagnostics.Pretty_Emitter is -- Should_Write_Spans -- ------------------------ - function Should_Write_Spans (Sub_Diag : Sub_Diagnostic_Type; - Diag : Diagnostic_Type) - return Boolean + function Should_Write_Spans + (Sub_Diag : Error_Msg_Object; Diag : Error_Msg_Object) return Boolean is - Sub_Loc : constant Labeled_Span_Type := Primary_Location (Sub_Diag); - Diag_Loc : constant Labeled_Span_Type := Primary_Location (Diag); + Sub_Loc : constant Labeled_Span_Id := Primary_Location (Sub_Diag); + Diag_Loc : constant Labeled_Span_Id := Primary_Location (Diag); begin - return Sub_Loc /= No_Labeled_Span - and then Diag_Loc /= No_Labeled_Span - and then Sub_Loc.Span.Ptr /= Diag_Loc.Span.Ptr; + return + Sub_Loc /= No_Labeled_Span and then Diag_Loc /= No_Labeled_Span + and then Locations.Table (Sub_Loc).Span.Ptr /= + Locations.Table (Diag_Loc).Span.Ptr; end Should_Write_Spans; ---------------- @@ -1134,7 +1200,7 @@ package body Diagnostics.Pretty_Emitter is procedure Print_Edit (Edit : Edit_Type; Offset : Integer) is Buf : constant Source_Buffer_Ptr := - Source_Text (Get_Source_File_Index (Edit.Span.Ptr)); + Source_Text (Get_Source_File_Index (Edit.Span.Ptr)); Line_Nr : constant Pos := Pos (Get_Physical_Line_Number (Edit.Span.Ptr)); @@ -1150,10 +1216,7 @@ package body Diagnostics.Pretty_Emitter is Write_Char ('-'); Write_Line_Marker (Line_Nr, MAX_BAR_POS - 1); - Write_Buffer - (Buf => Buf, - First => Line_Fst, - Last => Line_Lst); + Write_Buffer (Buf => Buf, First => Line_Fst, Last => Line_Lst); -- write the edited line @@ -1161,19 +1224,13 @@ package body Diagnostics.Pretty_Emitter is Write_Line_Marker (Line_Nr, MAX_BAR_POS - 1); Write_Buffer - (Buf => Buf, - First => Line_Fst, - Last => Edit.Span.First - 1); + (Buf => Buf, First => Line_Fst, Last => Edit.Span.First - 1); if Edit.Text /= null then Write_Str (Edit.Text.all); end if; - Write_Buffer - (Buf => Buf, - First => Edit.Span.Last + 1, - Last => Line_Lst); - + Write_Buffer (Buf => Buf, First => Edit.Span.Last + 1, Last => Line_Lst); end Print_Edit; --------------- @@ -1181,7 +1238,7 @@ package body Diagnostics.Pretty_Emitter is --------------- procedure Print_Fix (Fix : Fix_Type; Offset : Integer) is - use Edit_Lists; + E : Edit_Id; begin Write_Str (String'(1 .. Offset => ' ')); Write_Str ("+ Fix: "); @@ -1191,19 +1248,12 @@ package body Diagnostics.Pretty_Emitter is end if; Write_Eol; - if Present (Fix.Edits) then - declare - Edit : Edit_Type; - - It : Iterator := Iterate (Fix.Edits); - begin - while Has_Next (It) loop - Next (It, Edit); + E := Fix.Edits; + while E /= No_Edit loop + Print_Edit (Edits.Table (E), MAX_BAR_POS - 1); - Print_Edit (Edit, MAX_BAR_POS - 1); - end loop; - end; - end if; + E := Edits.Table (E).Next; + end loop; end Print_Fix; -------------------------- @@ -1211,26 +1261,23 @@ package body Diagnostics.Pretty_Emitter is -------------------------- procedure Print_Sub_Diagnostic - (Sub_Diag : Sub_Diagnostic_Type; - Diag : Diagnostic_Type; - Offset : Integer) + (Sub_Diag : Error_Msg_Object; Diag : Error_Msg_Object; Offset : Integer) is begin Write_Str (String'(1 .. Offset => ' ')); - if Sub_Diag.Kind = Suggestion then - Write_Str ("+ Suggestion: "); - else - Write_Str ("+ "); - end if; + Write_Str ("+ "); - Write_Str (Sub_Diag.Message.all); + Write_Str (Sub_Diag.Text.all); Write_Eol; if Should_Write_Spans (Sub_Diag, Diag) then - Write_Labeled_Spans (Sub_Diag.Locations, - Should_Write_File_Name (Sub_Diag, Diag), - Offset); + Write_Labeled_Spans + (Locations => Sub_Diag.Locations, + Write_File_Name => Should_Write_File_Name (Sub_Diag, Diag), + File_Name_Offset => Offset, + Include_Spans => not GNATprove_Mode or else Sub_Diag.Kind /= Info, + SGR_Code => SGR_Note); end if; end Print_Sub_Diagnostic; @@ -1238,57 +1285,126 @@ package body Diagnostics.Pretty_Emitter is -- Print_Diagnostic -- ---------------------- - procedure Print_Diagnostic (Diag : Diagnostic_Type) is + procedure Print_Diagnostic (E : Error_Msg_Id) is + E_Msg : constant Error_Msg_Object := Errors.Table (E); + + E_Next_Id : Error_Msg_Id; + F : Fix_Id; begin -- Print the main diagnostic - Write_Error_Msg_Line (Diag); + Write_Error_Msg_Line (E_Msg); -- Print diagnostic locations along with spans - Write_Labeled_Spans (Diag.Locations, True, 0); + Write_Labeled_Spans + (Locations => E_Msg.Locations, + Write_File_Name => True, + File_Name_Offset => 0, + Include_Spans => not GNATprove_Mode or else E_Msg.Kind /= Info, + SGR_Code => Get_SGR_Code (E_Msg)); -- Print subdiagnostics - if Sub_Diagnostic_Lists.Present (Diag.Sub_Diagnostics) then - declare - use Sub_Diagnostic_Lists; - Sub_Diag : Sub_Diagnostic_Type; - - It : Iterator := Iterate (Diag.Sub_Diagnostics); - begin - while Has_Next (It) loop - Next (It, Sub_Diag); - - -- Print the subdiagnostic and offset the location of the file - -- name + E_Next_Id := E_Msg.Next; + while E_Next_Id /= No_Error_Msg + and then Errors.Table (E_Next_Id).Msg_Cont + loop + -- Print the subdiagnostic and offset the location of the file + -- name + Print_Sub_Diagnostic + (Errors.Table (E_Next_Id), E_Msg, MAX_BAR_POS - 1); - Print_Sub_Diagnostic (Sub_Diag, Diag, MAX_BAR_POS - 1); - end loop; - end; - end if; + E_Next_Id := Errors.Table (E_Next_Id).Next; + end loop; -- Print fixes - if Fix_Lists.Present (Diag.Fixes) then - declare - use Fix_Lists; - Fix : Fix_Type; - - It : Iterator := Iterate (Diag.Fixes); - begin - while Has_Next (It) loop - Next (It, Fix); + F := E_Msg.Fixes; + while F /= No_Fix loop + Print_Fix (Fixes.Table (F), MAX_BAR_POS - 1); - Print_Fix (Fix, MAX_BAR_POS - 1); - end loop; - end; - end if; + F := Fixes.Table (F).Next; + end loop; -- Separate main diagnostics with a blank line Write_Eol; - end Print_Diagnostic; -end Diagnostics.Pretty_Emitter; + + -------------------------- + -- Print_Error_Messages -- + -------------------------- + + procedure Print_Error_Messages is + E : Error_Msg_Id; + begin + Set_Standard_Error; + + E := First_Error_Msg; + while E /= No_Error_Msg loop + + if not Errors.Table (E).Deleted and then not Errors.Table (E).Msg_Cont + then + Print_Diagnostic (E); + end if; + + E := Errors.Table (E).Next; + end loop; + + Set_Standard_Output; + end Print_Error_Messages; + + ------------------ + -- To_File_Name -- + ------------------ + + function To_File_Name (Sptr : Source_Ptr) return String is + Sfile : constant Source_File_Index := Get_Source_File_Index (Sptr); + Ref_Name : constant File_Name_Type := + (if Full_Path_Name_For_Brief_Errors then Full_Ref_Name (Sfile) + else Reference_Name (Sfile)); + + begin + return Get_Name_String (Ref_Name); + end To_File_Name; + + -------------------- + -- Line_To_String -- + -------------------- + + function Line_To_String (Sptr : Source_Ptr) return String is + Line : constant Logical_Line_Number := Get_Logical_Line_Number (Sptr); + Img_Raw : constant String := Int'Image (Int (Line)); + + begin + return Img_Raw (Img_Raw'First + 1 .. Img_Raw'Last); + end Line_To_String; + + ---------------------- + -- Column_To_String -- + ---------------------- + + function Column_To_String (Sptr : Source_Ptr) return String is + Col : constant Column_Number := Get_Column_Number (Sptr); + Img_Raw : constant String := Int'Image (Int (Col)); + + begin + return + (if Col < 10 then "0" else "") & + Img_Raw (Img_Raw'First + 1 .. Img_Raw'Last); + end Column_To_String; + + --------------- + -- To_String -- + --------------- + + function To_String (Sptr : Source_Ptr) return String is + begin + return + To_File_Name (Sptr) & ":" & Line_To_String (Sptr) & ":" & + Column_To_String (Sptr); + end To_String; + +end Erroutc.Pretty_Emitter; diff --git a/gcc/ada/diagnostics-brief_emitter.ads b/gcc/ada/erroutc-pretty_emitter.ads similarity index 90% rename from gcc/ada/diagnostics-brief_emitter.ads rename to gcc/ada/erroutc-pretty_emitter.ads index 706293e48ddb..a4521a26d170 100644 --- a/gcc/ada/diagnostics-brief_emitter.ads +++ b/gcc/ada/erroutc-pretty_emitter.ads @@ -2,7 +2,7 @@ -- -- -- GNAT COMPILER COMPONENTS -- -- -- --- D I A G N O S T I C S . B R I E F _ E M I T T E R -- +-- E R R O U T C . P R E T T Y _ E M I T T E R -- -- -- -- S p e c -- -- -- @@ -23,6 +23,6 @@ -- -- ------------------------------------------------------------------------------ -package Diagnostics.Brief_Emitter is - procedure Print_Diagnostic (Diag : Diagnostic_Type); -end Diagnostics.Brief_Emitter; +package Erroutc.Pretty_Emitter is + procedure Print_Error_Messages; +end Erroutc.Pretty_Emitter; diff --git a/gcc/ada/diagnostics-sarif_emitter.adb b/gcc/ada/erroutc-sarif_emitter.adb similarity index 58% rename from gcc/ada/diagnostics-sarif_emitter.adb rename to gcc/ada/erroutc-sarif_emitter.adb index 31b3154d5a34..1d4df0c6f691 100644 --- a/gcc/ada/diagnostics-sarif_emitter.adb +++ b/gcc/ada/erroutc-sarif_emitter.adb @@ -2,7 +2,7 @@ -- -- -- GNAT COMPILER COMPONENTS -- -- -- --- D I A G N O S T I C S . S A R I F _ E M I T T E R -- +-- E R R O U T C . S A R I F _ E M I T T E R -- -- -- -- B o d y -- -- -- @@ -23,29 +23,103 @@ -- -- ------------------------------------------------------------------------------ -with Diagnostics.Utils; use Diagnostics.Utils; -with Diagnostics.JSON_Utils; use Diagnostics.JSON_Utils; -with Gnatvsn; use Gnatvsn; -with Output; use Output; -with Sinput; use Sinput; -with Lib; use Lib; -with Namet; use Namet; -with Osint; use Osint; -with Errout; use Errout; - -package body Diagnostics.SARIF_Emitter is +with JSON_Utils; use JSON_Utils; +with GNAT.Lists; use GNAT.Lists; +with Gnatvsn; use Gnatvsn; +with Lib; use Lib; +with Namet; use Namet; +with Output; use Output; +with Sinput; use Sinput; +with System.OS_Lib; + +package body Erroutc.SARIF_Emitter is + + -- SARIF attribute names + + N_ARTIFACT_CHANGES : constant String := "artifactChanges"; + N_ARTIFACT_LOCATION : constant String := "artifactLocation"; + N_COMMAND_LINE : constant String := "commandLine"; + N_DELETED_REGION : constant String := "deletedRegion"; + N_DESCRIPTION : constant String := "description"; + N_DRIVER : constant String := "driver"; + N_END_COLUMN : constant String := "endColumn"; + N_END_LINE : constant String := "endLine"; + N_EXECUTION_SUCCESSFUL : constant String := "executionSuccessful"; + N_FIXES : constant String := "fixes"; + N_ID : constant String := "id"; + N_INSERTED_CONTENT : constant String := "insertedContent"; + N_INVOCATIONS : constant String := "invocations"; + N_LOCATIONS : constant String := "locations"; + N_LEVEL : constant String := "level"; + N_MESSAGE : constant String := "message"; + N_NAME : constant String := "name"; + N_ORIGINAL_URI_BASE_IDS : constant String := "originalUriBaseIds"; + N_PHYSICAL_LOCATION : constant String := "physicalLocation"; + N_REGION : constant String := "region"; + N_RELATED_LOCATIONS : constant String := "relatedLocations"; + N_REPLACEMENTS : constant String := "replacements"; + N_RESULTS : constant String := "results"; + N_RULES : constant String := "rules"; + N_RULE_ID : constant String := "ruleId"; + N_RUNS : constant String := "runs"; + N_SCHEMA : constant String := "$schema"; + N_START_COLUMN : constant String := "startColumn"; + N_START_LINE : constant String := "startLine"; + N_TEXT : constant String := "text"; + N_TOOL : constant String := "tool"; + N_URI : constant String := "uri"; + N_URI_BASE_ID : constant String := "uriBaseId"; + N_VERSION : constant String := "version"; -- We are currently using SARIF 2.1.0 SARIF_Version : constant String := "2.1.0"; pragma Style_Checks ("M100"); - SARIF_Schema : constant String := + SARIF_Schema : constant String := "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json"; pragma Style_Checks ("M79"); + URI_Base_Id_Name : constant String := "PWD"; + -- We use the pwd as the originalUriBaseIds when providing absolute paths + -- in locations. + + Current_Dir : constant String := Get_Current_Dir; + -- Cached value of the current directory that is used in the URI_Base_Id + -- and it is also the path that all other Uri attributes will be created + -- relative to. + + procedure Destroy (Elem : in out Error_Msg_Object) is null; + pragma Inline (Destroy); + package Error_Msg_Lists is new Doubly_Linked_Lists + (Element_Type => Error_Msg_Object, + "=" => "=", + Destroy_Element => Destroy, + Check_Tampering => False); + + subtype Error_Msg_List is Error_Msg_Lists.Doubly_Linked_List; + + procedure Destroy (Elem : in out Edit_Type); + + procedure Destroy (Elem : in out Edit_Type) is + begin + -- Diagnostic elements will be freed when all the diagnostics have been + -- emitted. + null; + end Destroy; + + pragma Inline (Destroy); + + package Edit_Lists is new Doubly_Linked_Lists + (Element_Type => Edit_Type, + "=" => "=", + Destroy_Element => Destroy, + Check_Tampering => False); + + subtype Edit_List is Edit_Lists.Doubly_Linked_List; + type Artifact_Change is record - File : String_Ptr; - -- Name of the file + File_Index : Source_File_Index; + -- Index for the source file Replacements : Edit_List; -- Regions of texts to be edited @@ -55,9 +129,7 @@ package body Diagnostics.SARIF_Emitter is pragma Inline (Destroy); function Equals (L, R : Artifact_Change) return Boolean is - (L.File /= null - and then R.File /= null - and then L.File.all = R.File.all); + (L.File_Index = R.File_Index); package Artifact_Change_Lists is new Doubly_Linked_Lists (Element_Type => Artifact_Change, @@ -71,7 +143,7 @@ package body Diagnostics.SARIF_Emitter is -- Group edits of a Fix into Artifact_Changes that organize the edits by -- file name. - function Get_Unique_Rules (Diags : Diagnostic_List) return Diagnostic_List; + function Get_Unique_Rules return Error_Msg_List; -- Get a list of diagnostics that have unique Diagnostic Id-s. procedure Print_Replacement (Replacement : Edit_Type); @@ -90,7 +162,7 @@ package body Diagnostics.SARIF_Emitter is -- artifactChanges: [<ArtifactChange>] -- } - procedure Print_Fixes (Diag : Diagnostic_Type); + procedure Print_Fixes (E_Msg : Error_Msg_Object); -- Print the fixes node -- -- "fixes": [ @@ -119,15 +191,15 @@ package body Diagnostics.SARIF_Emitter is -- replacements: [<Replacements>] -- } - procedure Print_Artifact_Location (File_Name : String); + procedure Print_Artifact_Location (Sfile : Source_File_Index); -- Print an artifactLocation node -- -- "artifactLocation": { - -- "URI": <File_Name> + -- "uri": <File_Name>, + -- "uriBaseId": "PWD" -- } - procedure Print_Location (Loc : Labeled_Span_Type; - Msg : String_Ptr); + procedure Print_Location (Loc : Labeled_Span_Type; Msg : String_Ptr); -- Print a location node that consists of -- * an optional message node -- * a physicalLocation node @@ -140,7 +212,7 @@ package body Diagnostics.SARIF_Emitter is -- }, -- "physicalLocation": { -- "artifactLocation": { - -- "URI": <File_Name (Loc)> + -- "uri": <File_Name (Loc)> -- }, -- "region": { -- "startLine": <Line(Loc.Fst)>, @@ -151,7 +223,7 @@ package body Diagnostics.SARIF_Emitter is -- } -- } - procedure Print_Locations (Diag : Diagnostic_Type); + procedure Print_Locations (E_Msg : Error_Msg_Object); -- Print a locations node that consists of multiple location nodes. However -- typically just one location for the primary span of the diagnostic. -- @@ -159,14 +231,26 @@ package body Diagnostics.SARIF_Emitter is -- <Location (Primary_Span (Diag))> -- ], - procedure Print_Message (Text : String; Name : String := "message"); - -- Print a SARIF message node + procedure Print_Message (Text : String; Name : String := N_MESSAGE); + -- Print a SARIF message node. + -- + -- There are many message type nodes in the SARIF report however they can + -- have a different node <Name>. -- - -- "message": { + -- <Name>: { -- "text": <text> -- }, - procedure Print_Related_Locations (Diag : Diagnostic_Type); + procedure Print_Original_Uri_Base_Ids; + -- Print the originalUriBaseIds that holds the PWD value + -- + -- "originalUriBaseIds": { + -- "PWD": { + -- "uri": "<current_working_directory>" + -- } + -- }, + + procedure Print_Related_Locations (E_Msg : Error_Msg_Object); -- Print a relatedLocations node that consists of multiple location nodes. -- Related locations are the non-primary spans of the diagnostic and the -- primary locations of sub-diagnostics. @@ -175,11 +259,12 @@ package body Diagnostics.SARIF_Emitter is -- <Location (Diag.Loc)> -- ], - procedure Print_Region (Start_Line : Int; - Start_Col : Int; - End_Line : Int; - End_Col : Int; - Name : String := "region"); + procedure Print_Region + (Start_Line : Int; + Start_Col : Int; + End_Line : Int; + End_Col : Int; + Name : String := N_REGION); -- Print a region node. -- -- More specifically a text region node that specifies the textual @@ -207,7 +292,7 @@ package body Diagnostics.SARIF_Emitter is -- the GNAT span definition and we amend the endColumn value so that it -- matches the SARIF definition. - procedure Print_Result (Diag : Diagnostic_Type); + procedure Print_Result (E_Msg : Error_Msg_Object); -- { -- "ruleId": <Diag.Id>, -- "level": <Diag.Kind>, @@ -218,7 +303,7 @@ package body Diagnostics.SARIF_Emitter is -- "relatedLocations": [<Secondary_Locations>] -- }, - procedure Print_Results (Diags : Diagnostic_List); + procedure Print_Results; -- Print a results node that consists of multiple result nodes for each -- diagnostic instance. -- @@ -226,7 +311,7 @@ package body Diagnostics.SARIF_Emitter is -- <Result (Diag)> -- ] - procedure Print_Rule (Diag : Diagnostic_Type); + procedure Print_Rule (E : Error_Msg_Object); -- Print a rule node that consists of the following attributes: -- * ruleId -- * name @@ -236,7 +321,7 @@ package body Diagnostics.SARIF_Emitter is -- "name": <Human_Id(Diag)> -- }, - procedure Print_Rules (Diags : Diagnostic_List); + procedure Print_Rules; -- Print a rules node that consists of multiple rule nodes. -- Rules are considered to be a set of unique diagnostics with the unique -- id-s. @@ -245,7 +330,7 @@ package body Diagnostics.SARIF_Emitter is -- <Rule (Diag)> -- ] - procedure Print_Runs (Diags : Diagnostic_List); + procedure Print_Runs; -- Print a runs node that can consist of multiple run nodes. -- However for our report it consists of a single run that consists of -- * a tool node @@ -256,7 +341,7 @@ package body Diagnostics.SARIF_Emitter is -- "results": [<Results (Diags)>] -- } - procedure Print_Tool (Diags : Diagnostic_List); + procedure Print_Tool; -- Print a tool node that consists of -- * a driver node that consists of: -- * name @@ -275,11 +360,9 @@ package body Diagnostics.SARIF_Emitter is -- Destroy -- ------------- - procedure Destroy (Elem : in out Artifact_Change) - is - + procedure Destroy (Elem : in out Artifact_Change) is begin - Free (Elem.File); + Edit_Lists.Destroy (Elem.Replacements); end Destroy; -------------------------- @@ -294,8 +377,7 @@ package body Diagnostics.SARIF_Emitter is -- Insert -- ------------ - procedure Insert (Changes : Artifact_Change_List; E : Edit_Type) - is + procedure Insert (Changes : Artifact_Change_List; E : Edit_Type) is A : Artifact_Change; It : Artifact_Change_Lists.Iterator := @@ -304,7 +386,7 @@ package body Diagnostics.SARIF_Emitter is while Artifact_Change_Lists.Has_Next (It) loop Artifact_Change_Lists.Next (It, A); - if A.File.all = To_File_Name (E.Span.Ptr) then + if A.File_Index = Get_Source_File_Index (E.Span.Ptr) then Edit_Lists.Append (A.Replacements, E); return; end if; @@ -316,7 +398,7 @@ package body Diagnostics.SARIF_Emitter is Edit_Lists.Append (Replacements, E); Artifact_Change_Lists.Append (Changes, - (File => new String'(To_File_Name (E.Span.Ptr)), + (File_Index => Get_Source_File_Index (E.Span.Ptr), Replacements => Replacements)); end; end Insert; @@ -325,12 +407,19 @@ package body Diagnostics.SARIF_Emitter is E : Edit_Type; - It : Edit_Lists.Iterator := Edit_Lists.Iterate (Fix.Edits); + It : Edit_Id; + + -- Start of processing for Get_Artifact_Changes + begin - while Edit_Lists.Has_Next (It) loop - Edit_Lists.Next (It, E); + It := Fix.Edits; + + while It /= No_Edit loop + E := Edits.Table (It); Insert (Changes, E); + + It := E.Next; end loop; return Changes; @@ -340,46 +429,46 @@ package body Diagnostics.SARIF_Emitter is -- Get_Unique_Rules -- ---------------------- - function Get_Unique_Rules (Diags : Diagnostic_List) - return Diagnostic_List - is - use Diagnostics.Diagnostics_Lists; + function Get_Unique_Rules return Error_Msg_List is + use Error_Msg_Lists; - procedure Insert (Rules : Diagnostic_List; D : Diagnostic_Type); + procedure Insert (Rules : Error_Msg_List; E : Error_Msg_Object); ------------ -- Insert -- ------------ - procedure Insert (Rules : Diagnostic_List; D : Diagnostic_Type) is + procedure Insert (Rules : Error_Msg_List; E : Error_Msg_Object) is It : Iterator := Iterate (Rules); - R : Diagnostic_Type; + R : Error_Msg_Object; begin while Has_Next (It) loop Next (It, R); - if R.Id = D.Id then + if R.Id = E.Id then return; - elsif R.Id > D.Id then - Insert_Before (Rules, R, D); + elsif R.Id > E.Id then + Insert_Before (Rules, R, E); return; end if; end loop; - Append (Rules, D); + Append (Rules, E); end Insert; - D : Diagnostic_Type; - Unique_Rules : constant Diagnostic_List := Create; + Unique_Rules : constant Error_Msg_List := Create; + + E : Error_Msg_Id; + + -- Start of processing for Get_Unique_Rules - It : Iterator := Iterate (Diags); begin - if Present (Diags) then - while Has_Next (It) loop - Next (It, D); - Insert (Unique_Rules, D); - end loop; - end if; + E := First_Error_Msg; + while E /= No_Error_Msg loop + Insert (Unique_Rules, Errors.Table (E)); + + Next_Error_Msg (E); + end loop; return Unique_Rules; end Get_Unique_Rules; @@ -388,10 +477,9 @@ package body Diagnostics.SARIF_Emitter is -- Print_Artifact_Change -- --------------------------- - procedure Print_Artifact_Change (A : Artifact_Change) - is - use Diagnostics.Edit_Lists; - E : Edit_Type; + procedure Print_Artifact_Change (A : Artifact_Change) is + use Edit_Lists; + E : Edit_Type; E_It : Iterator; First : Boolean := True; @@ -402,12 +490,12 @@ package body Diagnostics.SARIF_Emitter is -- Print artifactLocation - Print_Artifact_Location (A.File.all); + Print_Artifact_Location (A.File_Index); Write_Char (','); NL_And_Indent; - Write_Str ("""" & "replacements" & """" & ": " & "["); + Write_Str ("""" & N_REPLACEMENTS & """" & ": " & "["); Begin_Block; NL_And_Indent; @@ -443,14 +531,49 @@ package body Diagnostics.SARIF_Emitter is -- Print_Artifact_Location -- ----------------------------- - procedure Print_Artifact_Location (File_Name : String) is - + procedure Print_Artifact_Location (Sfile : Source_File_Index) is + Full_Name : constant String := Get_Name_String (Full_Ref_Name (Sfile)); begin - Write_Str ("""" & "artifactLocation" & """" & ": " & "{"); + Write_Str ("""" & N_ARTIFACT_LOCATION & """" & ": " & "{"); Begin_Block; NL_And_Indent; - Write_String_Attribute ("uri", File_Name); + if System.OS_Lib.Is_Absolute_Path (Full_Name) then + declare + Abs_Name : constant String := + System.OS_Lib.Normalize_Pathname + (Name => Full_Name, Resolve_Links => False); + begin + -- We cannot create relative paths between different drives on + -- Windows. If the path is on a different drive than the PWD print + -- the absolute path in the URI and omit the baseUriId attribute. + + if Osint.On_Windows + and then Abs_Name (Abs_Name'First) = + Current_Dir (Current_Dir'First) + then + Write_String_Attribute (N_URI, To_File_Uri (Abs_Name)); + else + Write_String_Attribute + (N_URI, To_File_Uri (Relative_Path (Abs_Name, Current_Dir))); + + Write_Char (','); + NL_And_Indent; + + Write_String_Attribute (N_URI_BASE_ID, URI_Base_Id_Name); + end if; + end; + else + -- If the path was not absolute it was given relative to the + -- uriBaseId. + + Write_String_Attribute (N_URI, To_File_Uri (Full_Name)); + + Write_Char (','); + NL_And_Indent; + + Write_String_Attribute (N_URI_BASE_ID, URI_Base_Id_Name); + end if; End_Block; NL_And_Indent; @@ -478,17 +601,18 @@ package body Diagnostics.SARIF_Emitter is -- Print deletedRegion - Print_Region (Start_Line => Line_Fst, - Start_Col => Col_Fst, - End_Line => Line_Lst, - End_Col => Col_Lst, - Name => "deletedRegion"); + Print_Region + (Start_Line => Line_Fst, + Start_Col => Col_Fst, + End_Line => Line_Lst, + End_Col => Col_Lst, + Name => N_DELETED_REGION); if Replacement.Text /= null then Write_Char (','); NL_And_Indent; - Print_Message (Replacement.Text.all, "insertedContent"); + Print_Message (Replacement.Text.all, N_INSERTED_CONTENT); end if; -- End replacement @@ -512,7 +636,7 @@ package body Diagnostics.SARIF_Emitter is -- Print the message if the location has one if Fix.Description /= null then - Print_Message (Fix.Description.all, "description"); + Print_Message (Fix.Description.all, N_DESCRIPTION); Write_Char (','); NL_And_Indent; @@ -522,9 +646,9 @@ package body Diagnostics.SARIF_Emitter is use Artifact_Change_Lists; Changes : Artifact_Change_List := Get_Artifact_Changes (Fix); A : Artifact_Change; - A_It : Iterator := Iterate (Changes); + A_It : Iterator := Iterate (Changes); begin - Write_Str ("""" & "artifactChanges" & """" & ": " & "["); + Write_Str ("""" & N_ARTIFACT_CHANGES & """" & ": " & "["); Begin_Block; while Has_Next (A_It) loop @@ -557,31 +681,30 @@ package body Diagnostics.SARIF_Emitter is -- Print_Fixes -- ----------------- - procedure Print_Fixes (Diag : Diagnostic_Type) is - use Diagnostics.Fix_Lists; - F : Fix_Type; - F_It : Iterator; + procedure Print_Fixes (E_Msg : Error_Msg_Object) is + F : Fix_Type; + F_It : Fix_Id; First : Boolean := True; begin - Write_Str ("""" & "fixes" & """" & ": " & "["); + Write_Str ("""" & N_FIXES & """" & ": " & "["); Begin_Block; - if Present (Diag.Fixes) then - F_It := Iterate (Diag.Fixes); - while Has_Next (F_It) loop - Next (F_It, F); + F_It := E_Msg.Fixes; + while F_It /= No_Fix loop + F := Fixes.Table (F_It); - if First then - First := False; - else - Write_Char (','); - end if; + if First then + First := False; + else + Write_Char (','); + end if; - NL_And_Indent; - Print_Fix (F); - end loop; - end if; + NL_And_Indent; + Print_Fix (F); + + F_It := F.Next; + end loop; End_Block; NL_And_Indent; @@ -601,6 +724,9 @@ package body Diagnostics.SARIF_Emitter is function Compose_Command_Line return String is Buffer : Bounded_String; begin + Find_Program_Name; + Append (Buffer, Name_Buffer (1 .. Name_Len)); + Append (Buffer, ' '); Append (Buffer, Get_First_Main_File_Name); for I in 1 .. Compilation_Switches_Last loop declare @@ -616,7 +742,7 @@ package body Diagnostics.SARIF_Emitter is end Compose_Command_Line; begin - Write_Str ("""" & "invocations" & """" & ": " & "["); + Write_Str ("""" & N_INVOCATIONS & """" & ": " & "["); Begin_Block; NL_And_Indent; @@ -626,13 +752,13 @@ package body Diagnostics.SARIF_Emitter is -- Print commandLine - Write_String_Attribute ("commandLine", Compose_Command_Line); + Write_String_Attribute (N_COMMAND_LINE, Compose_Command_Line); Write_Char (','); NL_And_Indent; -- Print executionSuccessful - Write_Boolean_Attribute ("executionSuccessful", Compilation_Errors); + Write_Boolean_Attribute (N_EXECUTION_SUCCESSFUL, Exit_Code = E_Success); End_Block; NL_And_Indent; @@ -647,11 +773,12 @@ package body Diagnostics.SARIF_Emitter is -- Print_Region -- ------------------ - procedure Print_Region (Start_Line : Int; - Start_Col : Int; - End_Line : Int; - End_Col : Int; - Name : String := "region") + procedure Print_Region + (Start_Line : Int; + Start_Col : Int; + End_Line : Int; + End_Col : Int; + Name : String := N_REGION) is begin @@ -659,22 +786,22 @@ package body Diagnostics.SARIF_Emitter is Begin_Block; NL_And_Indent; - Write_Int_Attribute ("startLine", Start_Line); + Write_Int_Attribute (N_START_LINE, Start_Line); Write_Char (','); NL_And_Indent; - Write_Int_Attribute ("startColumn", Start_Col); + Write_Int_Attribute (N_START_COLUMN, Start_Col); Write_Char (','); NL_And_Indent; - Write_Int_Attribute ("endLine", End_Line); + Write_Int_Attribute (N_END_LINE, End_Line); Write_Char (','); NL_And_Indent; -- Convert the end of the span to the definition of the endColumn -- for a SARIF region. - Write_Int_Attribute ("endColumn", End_Col + 1); + Write_Int_Attribute (N_END_COLUMN, End_Col + 1); End_Block; NL_And_Indent; @@ -685,9 +812,7 @@ package body Diagnostics.SARIF_Emitter is -- Print_Location -- -------------------- - procedure Print_Location (Loc : Labeled_Span_Type; - Msg : String_Ptr) - is + procedure Print_Location (Loc : Labeled_Span_Type; Msg : String_Ptr) is -- Span start positions Fst : constant Source_Ptr := Loc.Span.First; @@ -713,23 +838,24 @@ package body Diagnostics.SARIF_Emitter is NL_And_Indent; end if; - Write_Str ("""" & "physicalLocation" & """" & ": " & "{"); + Write_Str ("""" & N_PHYSICAL_LOCATION & """" & ": " & "{"); Begin_Block; NL_And_Indent; -- Print artifactLocation - Print_Artifact_Location (To_File_Name (Loc.Span.Ptr)); + Print_Artifact_Location (Get_Source_File_Index (Loc.Span.Ptr)); Write_Char (','); NL_And_Indent; -- Print region - Print_Region (Start_Line => Line_Fst, - Start_Col => Col_Fst, - End_Line => Line_Lst, - End_Col => Col_Lst); + Print_Region + (Start_Line => Line_Fst, + Start_Col => Col_Fst, + End_Line => Line_Lst, + End_Col => Col_Lst); End_Block; NL_And_Indent; @@ -744,18 +870,18 @@ package body Diagnostics.SARIF_Emitter is -- Print_Locations -- --------------------- - procedure Print_Locations (Diag : Diagnostic_Type) is - use Diagnostics.Labeled_Span_Lists; + procedure Print_Locations (E_Msg : Error_Msg_Object) is Loc : Labeled_Span_Type; - It : Iterator := Iterate (Diag.Locations); + It : Labeled_Span_Id; First : Boolean := True; begin - Write_Str ("""" & "locations" & """" & ": " & "["); + Write_Str ("""" & N_LOCATIONS & """" & ": " & "["); Begin_Block; - while Has_Next (It) loop - Next (It, Loc); + It := E_Msg.Locations; + while It /= No_Labeled_Span loop + Loc := Locations.Table (It); -- Only the primary span is considered as the main location other -- spans are considered related locations @@ -770,51 +896,77 @@ package body Diagnostics.SARIF_Emitter is NL_And_Indent; Print_Location (Loc, Loc.Label); end if; + + It := Loc.Next; end loop; End_Block; NL_And_Indent; Write_Char (']'); - end Print_Locations; ------------------- -- Print_Message -- ------------------- - procedure Print_Message (Text : String; Name : String := "message") is + procedure Print_Message (Text : String; Name : String := N_MESSAGE) is begin Write_Str ("""" & Name & """" & ": " & "{"); Begin_Block; NL_And_Indent; - Write_String_Attribute ("text", Text); + Write_String_Attribute (N_TEXT, Text); End_Block; NL_And_Indent; Write_Char ('}'); end Print_Message; + --------------------------------- + -- Print_Original_Uri_Base_Ids -- + --------------------------------- + + procedure Print_Original_Uri_Base_Ids is + begin + Write_Str ("""" & N_ORIGINAL_URI_BASE_IDS & """" & ": " & "{"); + Begin_Block; + NL_And_Indent; + + Write_Str ("""" & URI_Base_Id_Name & """" & ": " & "{"); + Begin_Block; + NL_And_Indent; + + Write_String_Attribute (N_URI, To_File_Uri (Current_Dir)); + + End_Block; + NL_And_Indent; + Write_Char ('}'); + + End_Block; + NL_And_Indent; + Write_Char ('}'); + end Print_Original_Uri_Base_Ids; + ----------------------------- -- Print_Related_Locations -- ----------------------------- - procedure Print_Related_Locations (Diag : Diagnostic_Type) is - Loc : Labeled_Span_Type; - Loc_It : Labeled_Span_Lists.Iterator := - Labeled_Span_Lists.Iterate (Diag.Locations); + procedure Print_Related_Locations (E_Msg : Error_Msg_Object) is + Loc : Labeled_Span_Type; + Loc_It : Labeled_Span_Id; - Sub : Sub_Diagnostic_Type; - Sub_It : Sub_Diagnostic_Lists.Iterator; + Sub : Error_Msg_Object; + Sub_It : Error_Msg_Id; First : Boolean := True; begin - Write_Str ("""" & "relatedLocations" & """" & ": " & "["); + Write_Str ("""" & N_RELATED_LOCATIONS & """" & ": " & "["); Begin_Block; -- Related locations are the non-primary spans of the diagnostic - while Labeled_Span_Lists.Has_Next (Loc_It) loop - Labeled_Span_Lists.Next (Loc_It, Loc); + Loc_It := E_Msg.Locations; + while Loc_It /= No_Labeled_Span loop + Loc := Locations.Table (Loc_It); -- Non-primary spans are considered related locations @@ -828,78 +980,64 @@ package body Diagnostics.SARIF_Emitter is NL_And_Indent; Print_Location (Loc, Loc.Label); end if; + Loc_It := Loc.Next; end loop; -- And the sub-diagnostic locations - if Sub_Diagnostic_Lists.Present (Diag.Sub_Diagnostics) then - Sub_It := Sub_Diagnostic_Lists.Iterate (Diag.Sub_Diagnostics); + Sub_It := E_Msg.Next; + while Sub_It /= No_Error_Msg and then Errors.Table (Sub_It).Msg_Cont loop + Sub := Errors.Table (Sub_It); - while Sub_Diagnostic_Lists.Has_Next (Sub_It) loop - Sub_Diagnostic_Lists.Next (Sub_It, Sub); - - declare - Found : Boolean := False; + declare + Found : Boolean := False; - Prim_Loc : Labeled_Span_Type; - begin - if Labeled_Span_Lists.Present (Sub.Locations) then - Loc_It := Labeled_Span_Lists.Iterate (Sub.Locations); - while Labeled_Span_Lists.Has_Next (Loc_It) loop - Labeled_Span_Lists.Next (Loc_It, Loc); - - -- For sub-diagnostic locations, only the primary span is - -- considered. - - if not Found and then Loc.Is_Primary then - Found := True; - Prim_Loc := Loc; - end if; - end loop; - else + Prim_Loc_Id : Labeled_Span_Id; + begin + Prim_Loc_Id := Primary_Location (Sub); - -- If there are no locations for the sub-diagnostic then use - -- the primary location of the main diagnostic. + if Prim_Loc_Id /= No_Labeled_Span then + Found := True; + else + Prim_Loc_Id := Primary_Location (E_Msg); + Found := True; + end if; - Found := True; - Prim_Loc := Primary_Location (Diag); + -- For mapping sub-diagnostics to related locations we have to + -- make some compromises in details. + -- + -- Firstly we only make one entry that is for the primary span + -- of the sub-diagnostic. + -- + -- Secondly this span can also have a label. However this + -- pattern is not advised and by default we include the message + -- of the sub-diagnostic as the message in location node since + -- it should have more information. + + if Found then + if First then + First := False; + else + Write_Char (','); end if; + NL_And_Indent; + Print_Location (Locations.Table (Prim_Loc_Id), Sub.Text); + end if; + end; - -- For mapping sub-diagnostics to related locations we have to - -- make some compromises in details. - -- - -- Firstly we only make one entry that is for the primary span - -- of the sub-diagnostic. - -- - -- Secondly this span can also have a label. However this - -- pattern is not advised and by default we include the message - -- of the sub-diagnostic as the message in location node since - -- it should have more information. - - if Found then - if First then - First := False; - else - Write_Char (','); - end if; - NL_And_Indent; - Print_Location (Prim_Loc, Sub.Message); - end if; - end; - end loop; - end if; + Next_Continuation_Msg (Sub_It); + end loop; End_Block; NL_And_Indent; Write_Char (']'); - end Print_Related_Locations; ------------------ -- Print_Result -- ------------------ - procedure Print_Result (Diag : Diagnostic_Type) is + procedure Print_Result (E_Msg : Error_Msg_Object) is begin Write_Char ('{'); @@ -908,42 +1046,42 @@ package body Diagnostics.SARIF_Emitter is -- Print ruleId - Write_String_Attribute ("ruleId", "[" & To_String (Diag.Id) & "]"); + Write_String_Attribute (N_RULE_ID, "[" & To_String (E_Msg.Id) & "]"); Write_Char (','); NL_And_Indent; -- Print level - Write_String_Attribute ("level", Kind_To_String (Diag)); + Write_String_Attribute (N_LEVEL, Kind_To_String (E_Msg)); Write_Char (','); NL_And_Indent; -- Print message - Print_Message (Diag.Message.all); + Print_Message (E_Msg.Text.all); Write_Char (','); NL_And_Indent; -- Print locations - Print_Locations (Diag); + Print_Locations (E_Msg); Write_Char (','); NL_And_Indent; -- Print related locations - Print_Related_Locations (Diag); + Print_Related_Locations (E_Msg); Write_Char (','); NL_And_Indent; -- Print fixes - Print_Fixes (Diag); + Print_Fixes (E_Msg); End_Block; NL_And_Indent; @@ -955,32 +1093,28 @@ package body Diagnostics.SARIF_Emitter is -- Print_Results -- ------------------- - procedure Print_Results (Diags : Diagnostic_List) is - use Diagnostics.Diagnostics_Lists; - - D : Diagnostic_Type; - - It : Iterator := Iterate (All_Diagnostics); + procedure Print_Results is + E : Error_Msg_Id; First : Boolean := True; begin - Write_Str ("""" & "results" & """" & ": " & "["); + Write_Str ("""" & N_RESULTS & """" & ": " & "["); Begin_Block; - if Present (Diags) then - while Has_Next (It) loop - Next (It, D); + E := First_Error_Msg; + while E /= No_Error_Msg loop + if First then + First := False; + else + Write_Char (','); + end if; - if First then - First := False; - else - Write_Char (','); - end if; + NL_And_Indent; - NL_And_Indent; - Print_Result (D); - end loop; - end if; + Print_Result (Errors.Table (E)); + + Next_Error_Msg (E); + end loop; End_Block; NL_And_Indent; @@ -991,21 +1125,21 @@ package body Diagnostics.SARIF_Emitter is -- Print_Rule -- ---------------- - procedure Print_Rule (Diag : Diagnostic_Type) is - Human_Id : constant String_Ptr := Get_Human_Id (Diag); + procedure Print_Rule (E : Error_Msg_Object) is + Human_Id : constant String_Ptr := Get_Human_Id (E); begin Write_Char ('{'); Begin_Block; NL_And_Indent; - Write_String_Attribute ("id", "[" & To_String (Diag.Id) & "]"); + Write_String_Attribute (N_ID, "[" & To_String (E.Id) & "]"); Write_Char (','); NL_And_Indent; if Human_Id = null then - Write_String_Attribute ("name", "Uncategorized_Diagnostic"); + Write_String_Attribute (N_NAME, "Uncategorized_Diagnostic"); else - Write_String_Attribute ("name", Human_Id.all); + Write_String_Attribute (N_NAME, Human_Id.all); end if; End_Block; @@ -1017,17 +1151,15 @@ package body Diagnostics.SARIF_Emitter is -- Print_Rules -- ----------------- - procedure Print_Rules (Diags : Diagnostic_List) is - use Diagnostics.Diagnostics_Lists; - - R : Diagnostic_Type; - Rules : constant Diagnostic_List := Get_Unique_Rules (Diags); - - It : Iterator := Iterate (Rules); + procedure Print_Rules is + use Error_Msg_Lists; + R : Error_Msg_Object; + Rules : Error_Msg_List := Get_Unique_Rules; + It : Iterator := Iterate (Rules); First : Boolean := True; begin - Write_Str ("""" & "rules" & """" & ": " & "["); + Write_Str ("""" & N_RULES & """" & ": " & "["); Begin_Block; while Has_Next (It) loop @@ -1047,36 +1179,37 @@ package body Diagnostics.SARIF_Emitter is NL_And_Indent; Write_Char (']'); + Error_Msg_Lists.Destroy (Rules); end Print_Rules; ---------------- -- Print_Tool -- ---------------- - procedure Print_Tool (Diags : Diagnostic_List) is + procedure Print_Tool is begin - Write_Str ("""" & "tool" & """" & ": " & "{"); + Write_Str ("""" & N_TOOL & """" & ": " & "{"); Begin_Block; NL_And_Indent; -- -- Attributes of tool - Write_Str ("""" & "driver" & """" & ": " & "{"); + Write_Str ("""" & N_DRIVER & """" & ": " & "{"); Begin_Block; NL_And_Indent; -- Attributes of tool.driver - Write_String_Attribute ("name", "GNAT"); + Write_String_Attribute (N_NAME, "GNAT"); Write_Char (','); NL_And_Indent; - Write_String_Attribute ("version", Gnat_Version_String); + Write_String_Attribute (N_VERSION, Gnat_Version_String); Write_Char (','); NL_And_Indent; - Print_Rules (Diags); + Print_Rules; -- End of tool.driver @@ -1097,10 +1230,10 @@ package body Diagnostics.SARIF_Emitter is -- Print_Runs -- ---------------- - procedure Print_Runs (Diags : Diagnostic_List) is + procedure Print_Runs is begin - Write_Str ("""" & "runs" & """" & ": " & "["); + Write_Str ("""" & N_RUNS & """" & ": " & "["); Begin_Block; NL_And_Indent; @@ -1113,7 +1246,7 @@ package body Diagnostics.SARIF_Emitter is -- A run consists of a tool - Print_Tool (Diags); + Print_Tool; Write_Char (','); NL_And_Indent; @@ -1124,9 +1257,13 @@ package body Diagnostics.SARIF_Emitter is Write_Char (','); NL_And_Indent; + Print_Original_Uri_Base_Ids; + Write_Char (','); + NL_And_Indent; + -- A run consists of results - Print_Results (Diags); + Print_Results; -- End of run @@ -1147,21 +1284,21 @@ package body Diagnostics.SARIF_Emitter is -- Print_SARIF_Report -- ------------------------ - procedure Print_SARIF_Report (Diags : Diagnostic_List) is + procedure Print_SARIF_Report is begin Write_Char ('{'); Begin_Block; NL_And_Indent; - Write_String_Attribute ("$schema", SARIF_Schema); + Write_String_Attribute (N_SCHEMA, SARIF_Schema); Write_Char (','); NL_And_Indent; - Write_String_Attribute ("version", SARIF_Version); + Write_String_Attribute (N_VERSION, SARIF_Version); Write_Char (','); NL_And_Indent; - Print_Runs (Diags); + Print_Runs; End_Block; NL_And_Indent; @@ -1170,4 +1307,4 @@ package body Diagnostics.SARIF_Emitter is Write_Eol; end Print_SARIF_Report; -end Diagnostics.SARIF_Emitter; +end Erroutc.SARIF_Emitter; diff --git a/gcc/ada/diagnostics-converter.ads b/gcc/ada/erroutc-sarif_emitter.ads similarity index 90% rename from gcc/ada/diagnostics-converter.ads rename to gcc/ada/erroutc-sarif_emitter.ads index a3b15797a94b..e3953712f85b 100644 --- a/gcc/ada/diagnostics-converter.ads +++ b/gcc/ada/erroutc-sarif_emitter.ads @@ -2,7 +2,7 @@ -- -- -- GNAT COMPILER COMPONENTS -- -- -- --- D I A G N O S T I C S . C O N V E R T E R -- +-- E R R O U T C . S A R I F _ E M I T T E R -- -- -- -- S p e c -- -- -- @@ -23,9 +23,6 @@ -- -- ------------------------------------------------------------------------------ -package Diagnostics.Converter is - - procedure Convert_Errors_To_Diagnostics; - - procedure Emit_Diagnostics; -end Diagnostics.Converter; +package Erroutc.SARIF_Emitter is + procedure Print_SARIF_Report; +end Erroutc.SARIF_Emitter; diff --git a/gcc/ada/erroutc.adb b/gcc/ada/erroutc.adb index c8de60d2a5d8..14a11ff925c0 100644 --- a/gcc/ada/erroutc.adb +++ b/gcc/ada/erroutc.adb @@ -225,49 +225,11 @@ package body Erroutc is ------------------------ function Compilation_Errors return Boolean is - Warnings_Count : constant Int := Warnings_Detected; begin - if Total_Errors_Detected /= 0 then - return True; - - elsif Warnings_Treated_As_Errors /= 0 then - return True; - - -- We should never treat warnings that originate from a - -- Compile_Time_Warning pragma as an error. Warnings_Count is the sum - -- of both "normal" and Compile_Time_Warning warnings. This means that - -- there are only one or more non-Compile_Time_Warning warnings when - -- Warnings_Count is greater than Count_Compile_Time_Pragma_Warnings. - - elsif Warning_Mode = Treat_As_Error - and then Warnings_Count > Count_Compile_Time_Pragma_Warnings - then - return True; - end if; - - return False; + return Total_Errors_Detected /= 0 + or else Warnings_Treated_As_Errors /= 0; end Compilation_Errors; - ---------------------------------------- - -- Count_Compile_Time_Pragma_Warnings -- - ---------------------------------------- - - function Count_Compile_Time_Pragma_Warnings return Int is - Result : Int := 0; - begin - for J in 1 .. Errors.Last loop - begin - if Errors.Table (J).Kind = Warning - and then Errors.Table (J).Compile_Time_Pragma - and then not Errors.Table (J).Deleted - then - Result := Result + 1; - end if; - end; - end loop; - return Result; - end Count_Compile_Time_Pragma_Warnings; - ------------------------------ -- Decrease_Error_Msg_Count -- ------------------------------ @@ -282,6 +244,10 @@ package body Erroutc is when Warning | Style => Warnings_Detected := Warnings_Detected - 1; + if E.Warn_Err /= None then + Warnings_Treated_As_Errors := Warnings_Treated_As_Errors - 1; + end if; + when High_Check | Medium_Check | Low_Check => Check_Messages := Check_Messages - 1; @@ -340,7 +306,7 @@ package body Erroutc is w (" Line = ", Int (E.Line)); w (" Col = ", Int (E.Col)); w (" Kind = ", E.Kind'Img); - w (" Warn_Err = ", E.Warn_Err); + w (" Warn_Err = ", E.Warn_Err'Img); w (" Warn_Chr = '" & E.Warn_Chr & '''); w (" Uncond = ", E.Uncond); w (" Msg_Cont = ", E.Msg_Cont); @@ -372,11 +338,16 @@ package body Erroutc is ------------------------ function Get_Warning_Option (Id : Error_Msg_Id) return String is - Is_Style : constant Boolean := Errors.Table (Id).Kind in Style; - Warn_Chr : constant String (1 .. 2) := Errors.Table (Id).Warn_Chr; + begin + return Get_Warning_Option (Errors.Table (Id)); + end Get_Warning_Option; + + function Get_Warning_Option (E : Error_Msg_Object) return String is + Is_Style : constant Boolean := E.Kind in Style; + Warn_Chr : constant String (1 .. 2) := E.Warn_Chr; begin - if Has_Switch_Tag (Errors.Table (Id)) + if Has_Switch_Tag (E) and then Warn_Chr (1) /= '?' then if Warn_Chr = "$ " then @@ -398,11 +369,16 @@ package body Erroutc is --------------------- function Get_Warning_Tag (Id : Error_Msg_Id) return String is - Warn_Chr : constant String (1 .. 2) := Errors.Table (Id).Warn_Chr; - Option : constant String := Get_Warning_Option (Id); + begin + return Get_Warning_Tag (Errors.Table (Id)); + end Get_Warning_Tag; + + function Get_Warning_Tag (E : Error_Msg_Object) return String is + Warn_Chr : constant String (1 .. 2) := E.Warn_Chr; + Option : constant String := Get_Warning_Option (E); begin - if Has_Switch_Tag (Id) then + if Has_Switch_Tag (E) then if Warn_Chr = "? " then return "[enabled by default]"; elsif Warn_Chr = "* " then @@ -429,6 +405,24 @@ package body Erroutc is when Warning | Style => Warnings_Detected := Warnings_Detected + 1; + if E.Warn_Err /= None then + Warnings_Treated_As_Errors := Warnings_Treated_As_Errors + 1; + + -- Propagate Warn_Err to all of the preceeding continuation + -- messages and the main message. + + for J in reverse 1 .. Errors.Last loop + if Errors.Table (J).Warn_Err = None then + Errors.Table (J).Warn_Err := E.Warn_Err; + + Warnings_Treated_As_Errors := + Warnings_Treated_As_Errors + 1; + end if; + + exit when not Errors.Table (J).Msg_Cont; + end loop; + end if; + when High_Check | Medium_Check | Low_Check => Check_Messages := Check_Messages + 1; @@ -491,6 +485,134 @@ package body Erroutc is E_Msg.Kind in Warning | Info | Style and then E_Msg.Warn_Chr /= " "; end Has_Switch_Tag; + -------------------- + -- Next_Error_Msg -- + -------------------- + + procedure Next_Error_Msg (E : in out Error_Msg_Id) is + begin + loop + E := Errors.Table (E).Next; + exit when E = No_Error_Msg; + exit when not Errors.Table (E).Deleted + and then not Errors.Table (E).Msg_Cont; + end loop; + end Next_Error_Msg; + + --------------------------- + -- Next_Continuation_Msg -- + --------------------------- + + procedure Next_Continuation_Msg (E : in out Error_Msg_Id) is + begin + E := Errors.Table (E).Next; + + if E = No_Error_Msg or else not Errors.Table (E).Msg_Cont then + E := No_Error_Msg; + end if; + end Next_Continuation_Msg; + + ---------------------- + -- Primary_Location -- + ---------------------- + + function Primary_Location (E : Error_Msg_Object) return Labeled_Span_Id is + L : Labeled_Span_Id; + begin + L := E.Locations; + while L /= No_Labeled_Span loop + if Locations.Table (L).Is_Primary then + return L; + end if; + + L := Locations.Table (L).Next; + end loop; + + return No_Labeled_Span; + end Primary_Location; + + ------------------ + -- Get_Human_Id -- + ------------------ + + function Get_Human_Id (E : Error_Msg_Object) return String_Ptr is + begin + if E.Switch = No_Switch_Id then + return Diagnostic_Entries (E.Id).Human_Id; + else + return Get_Switch (E).Human_Id; + end if; + end Get_Human_Id; + + -------------------- + -- Get_Doc_Switch -- + -------------------- + + function Get_Doc_Switch (E : Error_Msg_Object) return String is + begin + if Warning_Doc_Switch + and then E.Warn_Chr /= " " + and then E.Kind in Info + | Style + | Warning + then + if E.Switch = No_Switch_Id then + if E.Warn_Chr = "* " then + return "[restriction warning]"; + + -- Info messages can have a switch tag but they should not have + -- a default switch tag. + + elsif E.Kind /= Info then + + -- For Default_Warning + + return "[enabled by default]"; + end if; + else + declare + S : constant Switch_Type := Get_Switch (E); + begin + return "[-" & S.Short_Name.all & "]"; + end; + end if; + end if; + + return ""; + end Get_Doc_Switch; + + ---------------- + -- Get_Switch -- + ---------------- + + function Get_Switch (E : Error_Msg_Object) return Switch_Type is + begin + return Get_Switch (E.Switch); + end Get_Switch; + + ------------------- + -- Get_Switch_Id -- + ------------------- + + function Get_Switch_Id (E : Error_Msg_Object) return Switch_Id is + begin + return Get_Switch_Id (E.Kind, E.Warn_Chr); + end Get_Switch_Id; + + function Get_Switch_Id + (Kind : Error_Msg_Type; Warn_Chr : String) return Switch_Id is + begin + if Warn_Chr = "$ " then + return Get_Switch_Id ("gnatel"); + elsif Kind in Warning | Info then + return Get_Switch_Id ("gnatw" & Warn_Chr); + elsif Kind = Style then + return Get_Switch_Id ("gnaty" & Warn_Chr); + else + return No_Switch_Id; + end if; + end Get_Switch_Id; + ------------- -- Matches -- ------------- @@ -752,7 +874,7 @@ package body Erroutc is -- Output_Text_Within -- ------------------------ - procedure Output_Text_Within (Txt : String_Ptr; Line_Length : Nat) is + procedure Output_Text_Within (Txt : String; Line_Length : Nat) is Offs : constant Nat := Column - 1; -- Offset to start of message, used for continuations @@ -869,98 +991,59 @@ package body Erroutc is procedure Output_Msg_Text (E : Error_Msg_Id) is - E_Msg : Error_Msg_Object renames Errors.Table (E); - Text : constant String_Ptr := E_Msg.Text; - Tag : constant String := Get_Warning_Tag (E); - Txt : String_Ptr; - - Line_Length : constant Nat := + E_Msg : Error_Msg_Object renames Errors.Table (E); + Text : constant String_Ptr := E_Msg.Text; + Tag : constant String := Get_Warning_Tag (E); + SGR_Code : constant String := Get_SGR_Code (E_Msg); + Kind_Prefix : constant String := + (if E_Msg.Kind = Style then Style_Prefix + else Kind_To_String (E_Msg) & ": "); + Buf : Bounded_String (Max_Msg_Length); + Line_Length : constant Nat := (if Error_Msg_Line_Length = 0 then Nat'Last else Error_Msg_Line_Length); begin - -- Postfix warning tag to message if needed - - if Tag /= "" and then Warning_Doc_Switch then - Txt := new String'(Text.all & ' ' & Tag); - else - Txt := Text; + -- Prefix with "error:" rather than warning. + -- Additionally include the style suffix when needed. + + if E_Msg.Warn_Err in From_Pragma | From_Run_Time_As_Err then + Append + (Buf, + SGR_Error & "error: " & SGR_Reset & + (if E_Msg.Kind = Style then Style_Prefix else "")); + + -- Print the message kind prefix + -- * Info/Style/Warning messages + -- * Check messages that are not continuations in the pretty printer + -- * Error messages when error tags are allowed + + elsif E_Msg.Kind in Info | Style | Warning + or else + (E_Msg.Kind in High_Check | Medium_Check | Low_Check + and then not (E_Msg.Msg_Cont and then Debug_Flag_FF)) + or else + (E_Msg.Kind in Error | Non_Serious_Error + and then Opt.Unique_Error_Tag) + then + Append (Buf, SGR_Code & Kind_Prefix & SGR_Reset); end if; - -- If -gnatdF is used, continuation messages follow the main message - -- with only an indentation of two space characters, without repeating - -- any prefix. - - if Debug_Flag_FF and then E_Msg.Msg_Cont then - null; - - -- For info messages, prefix message with "info: " - - elsif E_Msg.Kind = Info then - Txt := new String'(SGR_Note & "info: " & SGR_Reset & Txt.all); - - -- Warning treated as error - - elsif E_Msg.Warn_Err then - - -- We prefix with "error:" rather than warning: and postfix - -- [warning-as-error] at the end. - - Warnings_Treated_As_Errors := Warnings_Treated_As_Errors + 1; - Txt := new String'(SGR_Error & "error: " & SGR_Reset - & Txt.all & " [warning-as-error]"); - - -- Normal warning, prefix with "warning: " - - elsif E_Msg.Kind = Warning then - Txt := new String'(SGR_Warning & "warning: " & SGR_Reset & Txt.all); - - -- No prefix needed for style message, "(style)" is there already - - elsif E_Msg.Kind = Style then - if Txt (Txt'First .. Txt'First + 6) = "(style)" then - Txt := new String'(SGR_Warning & "(style)" & SGR_Reset - & Txt (Txt'First + 7 .. Txt'Last)); - end if; - - -- No prefix needed for check message, severity is there already - - elsif E_Msg.Kind in High_Check | Medium_Check | Low_Check then - - -- The message format is "severity: ..." - -- - -- Enclose the severity with an SGR control string if requested + Append (Buf, Text.all); - if Use_SGR_Control then - declare - Msg : String renames Text.all; - Colon : Natural := 0; - begin - -- Find first colon - - for J in Msg'Range loop - if Msg (J) = ':' then - Colon := J; - exit; - end if; - end loop; - - pragma Assert (Colon > 0); + -- Postfix warning tag to message if needed - Txt := new String'(SGR_Error - & Msg (Msg'First .. Colon) - & SGR_Reset - & Msg (Colon + 1 .. Msg'Last)); - end; - end if; + if Tag /= "" and then Warning_Doc_Switch then + Append (Buf, ' ' & Tag); + end if; - -- All other cases, add "error: " if unique error tag set + -- Postfix [warning-as-error] at the end - elsif Opt.Unique_Error_Tag then - Txt := new String'(SGR_Error & "error: " & SGR_Reset & Txt.all); + if E_Msg.Warn_Err = From_Pragma then + Append (Buf, " " & Warn_As_Err_Tag); end if; - Output_Text_Within (Txt, Line_Length); + Output_Text_Within (To_String (Buf), Line_Length); end Output_Msg_Text; --------------------- @@ -1051,41 +1134,51 @@ package body Erroutc is Error_Msg_Kind := Error; Is_Unconditional_Msg := False; - Is_Runtime_Raise := False; + Is_Runtime_Raise_Msg := False; Warning_Msg_Char := " "; -- Check style message - if Msg'Length > 7 - and then Msg (Msg'First .. Msg'First + 6) = "(style)" + if Msg'Length > Style_Prefix'Length + and then + Msg (Msg'First .. Msg'First + Style_Prefix'Length - 1) = + Style_Prefix then Error_Msg_Kind := Style; -- Check info message - elsif Msg'Length > 6 - and then Msg (Msg'First .. Msg'First + 5) = "info: " + elsif Msg'Length > Info_Prefix'Length + and then + Msg (Msg'First .. Msg'First + Info_Prefix'Length - 1) = + Info_Prefix then Error_Msg_Kind := Info; -- Check high check message - elsif Msg'Length > 6 - and then Msg (Msg'First .. Msg'First + 5) = "high: " + elsif Msg'Length > High_Prefix'Length + and then + Msg (Msg'First .. Msg'First + High_Prefix'Length - 1) = + High_Prefix then Error_Msg_Kind := High_Check; -- Check medium check message - elsif Msg'Length > 8 - and then Msg (Msg'First .. Msg'First + 7) = "medium: " + elsif Msg'Length > Medium_Prefix'Length + and then + Msg (Msg'First .. Msg'First + Medium_Prefix'Length - 1) = + Medium_Prefix then Error_Msg_Kind := Medium_Check; -- Check low check message - elsif Msg'Length > 5 - and then Msg (Msg'First .. Msg'First + 4) = "low: " + elsif Msg'Length > Low_Prefix'Length + and then + Msg (Msg'First .. Msg'First + Low_Prefix'Length - 1) = + Low_Prefix then Error_Msg_Kind := Low_Check; end if; @@ -1211,6 +1304,8 @@ package body Erroutc is E := First_Error_Msg; while E /= No_Error_Msg loop while To_Be_Purged (Errors.Table (E).Next) loop + Errors.Table (Errors.Table (E).Next).Deleted := True; + Errors.Table (E).Next := Errors.Table (Errors.Table (E).Next).Next; end loop; @@ -2004,6 +2099,14 @@ package body Erroutc is return False; end Warning_Treated_As_Error; + function Warning_Treated_As_Error (E : Error_Msg_Object) return Boolean is + + begin + return + Warning_Treated_As_Error (E.Text.all) + or else Warning_Treated_As_Error (Get_Warning_Tag (E)); + end Warning_Treated_As_Error; + ------------------------- -- Warnings_Suppressed -- ------------------------- @@ -2080,76 +2183,32 @@ package body Erroutc is Write_Str (" errors"); end if; - -- We now need to output warnings. When using -gnatwe, all warnings - -- should be treated as errors, except for warnings originating from - -- the use of the Compile_Time_Warning pragma. Another situation - -- where a warning might be treated as an error is when the source - -- code contains a Warning_As_Error pragma. - -- When warnings are treated as errors, we still log them as - -- warnings, but we add a message denoting how many of these warnings - -- are also errors. - - declare - Warnings_Count : constant Int := Warnings_Detected; - - Compile_Time_Warnings : Int; - -- Number of warnings that come from a Compile_Time_Warning - -- pragma. + if Warnings_Detected > 0 then + Write_Str (", "); + Write_Int (Warnings_Detected); + Write_Str (" warning"); - Non_Compile_Time_Warnings : Int; - -- Number of warnings that do not come from a Compile_Time_Warning - -- pragmas. + if Warnings_Detected > 1 then + Write_Char ('s'); + end if; - begin - if Warnings_Count > 0 then - Write_Str (", "); - Write_Int (Warnings_Count); - Write_Str (" warning"); + if Warnings_Treated_As_Errors > 0 then + Write_Str (" ("); - if Warnings_Count > 1 then - Write_Char ('s'); + if Warnings_Treated_As_Errors /= Warnings_Detected then + Write_Int (Warnings_Treated_As_Errors); + Write_Str (" "); end if; - Compile_Time_Warnings := Count_Compile_Time_Pragma_Warnings; - Non_Compile_Time_Warnings := - Warnings_Count - Compile_Time_Warnings; - - if Warning_Mode = Treat_As_Error - and then Non_Compile_Time_Warnings > 0 - then - Write_Str (" ("); - - if Compile_Time_Warnings > 0 then - Write_Int (Non_Compile_Time_Warnings); - Write_Str (" "); - end if; - - Write_Str ("treated as error"); - - if Non_Compile_Time_Warnings > 1 then - Write_Char ('s'); - end if; + Write_Str ("treated as error"); - Write_Char (')'); - - elsif Warnings_Treated_As_Errors > 0 then - Write_Str (" ("); - - if Warnings_Treated_As_Errors /= Warnings_Count then - Write_Int (Warnings_Treated_As_Errors); - Write_Str (" "); - end if; - - Write_Str ("treated as error"); - - if Warnings_Treated_As_Errors > 1 then - Write_Str ("s"); - end if; - - Write_Str (")"); + if Warnings_Treated_As_Errors > 1 then + Write_Str ("s"); end if; + + Write_Str (")"); end if; - end; + end if; if Info_Messages /= 0 then Write_Str (", "); diff --git a/gcc/ada/erroutc.ads b/gcc/ada/erroutc.ads index 3f080a557ec9..2d8499a5bffd 100644 --- a/gcc/ada/erroutc.ads +++ b/gcc/ada/erroutc.ads @@ -27,10 +27,16 @@ -- reporting packages, including Errout and Prj.Err. with Table; +with Errsw; use Errsw; +with Errid; use Errid; +with Osint; use Osint; with Types; use Types; package Erroutc is + Exit_Code : Exit_Code_Type := E_Success; + -- Exit_Code used at the end of the compilation + type Error_Msg_Type is (Error, -- Default value Non_Serious_Error, @@ -76,15 +82,14 @@ package Erroutc is -- Set true to indicate that the current message originates from a -- Compile_Time_Warning or Compile_Time_Error pragma. + Is_Runtime_Raise_Msg : Boolean := False; + -- Set to True to indicate that the current message is a constraint error + -- that will be raised at runtime (contains [). + Is_Unconditional_Msg : Boolean := False; -- Set True to indicate that the current message contains the insertion -- character ! and is thus to be treated as an unconditional message. - Is_Runtime_Raise : Boolean := False; - -- Set to True to indicate that the current message is a warning about a - -- constraint error that will be raised at runtime (contains [ and switch - -- -gnatwE was given).. - Error_Msg_Kind : Error_Msg_Type := Error; Warning_Msg_Char : String (1 .. 2); @@ -177,6 +182,95 @@ package Erroutc is -- The following record type and table are used to represent error -- messages, with one entry in the table being allocated for each message. + type Labeled_Span_Id is new Int; + No_Labeled_Span : constant Labeled_Span_Id := 0; + + type Labeled_Span_Type is record + Label : String_Ptr := null; + -- Text associated with the span + + Span : Source_Span := (others => No_Location); + -- Textual region in the source code + + Is_Primary : Boolean := True; + -- Primary spans are used to indicate the primary location of the + -- diagnostic. Typically there should just be one primary span per + -- diagnostic. + -- Non-primary spans are used to indicate secondary locations and + -- typically are formatted in a different way or omitted in some + -- contexts. + + Is_Region : Boolean := False; + -- Regional spans are multiline spans that have a unique way of being + -- displayed in the pretty output. + + Next : Labeled_Span_Id := No_Labeled_Span; + + end record; + + No_Labeled_Span_Object : Labeled_Span_Type := (others => <>); + + package Locations is new Table.Table ( + Table_Component_Type => Labeled_Span_Type, + Table_Index_Type => Labeled_Span_Id, + Table_Low_Bound => 1, + Table_Initial => 200, + Table_Increment => 200, + Table_Name => "Location"); + + type Edit_Id is new Int; + No_Edit : constant Edit_Id := 0; + + type Edit_Type is record + Span : Source_Span; + -- Region of the file to be removed + + Text : String_Ptr; + -- Text to be inserted at the start location of the span + + Next : Edit_Id := No_Edit; + end record; + + package Edits is new Table.Table ( + Table_Component_Type => Edit_Type, + Table_Index_Type => Edit_Id, + Table_Low_Bound => 1, + Table_Initial => 200, + Table_Increment => 200, + Table_Name => "Edit"); + + type Fix_Id is new Int; + No_Fix : constant Fix_Id := 0; + + type Fix_Type is record + Description : String_Ptr := null; + -- Message describing the fix that will be displayed to the user. + + Edits : Edit_Id := No_Edit; + -- File changes for the fix. + + Next : Fix_Id := No_Fix; + end record; + + package Fixes is new Table.Table ( + Table_Component_Type => Fix_Type, + Table_Index_Type => Fix_Id, + Table_Low_Bound => 1, + Table_Initial => 200, + Table_Increment => 200, + Table_Name => "Fix"); + + type Warning_As_Error_Kind is + (None, From_Pragma, From_Warn_As_Err, From_Run_Time_As_Err); + -- The reason for a warning to be converted as an error: + -- * None - Regular warning. Default value for non-warning messages. + -- * From_Pragma - Warning converted to an error due to a pragma + -- Warning_As_Error. + -- * From_Warn_As_Err - Warning converted to an error because the + -- Warning_Mode was set to Treat_As_Errors by -gnatwe. + -- * From_Run_Time_As_Err - Warning converted to an error because the + -- Warning_Mode was set to Treat_Run_Time_Warnings_As_Errors by -gnatwE. + type Error_Msg_Object is record Text : String_Ptr; -- Text of error message, fully expanded with all insertions @@ -224,9 +318,11 @@ package Erroutc is -- True if the message originates from a Compile_Time_Warning or -- Compile_Time_Error pragma - Warn_Err : Boolean; - -- True if this is a warning message which is to be treated as an error - -- as a result of a match with a Warning_As_Error pragma. + Warn_Err : Warning_As_Error_Kind; + -- By default this is None. If the warning was converted by some reason + -- to an error then it has a different value. Depending on the value + -- the warning will be printed in a different way due to historical + -- reasons. Warn_Chr : String (1 .. 2); -- See Warning_Msg_Char @@ -248,6 +344,27 @@ package Erroutc is -- in the circuit for deleting duplicate/redundant error messages. Kind : Error_Msg_Type; + -- The kind of the error message. This determines how the message + -- should be handled and what kind of prefix should be added before the + -- message text. + + Switch : Switch_Id := No_Switch_Id; + -- Identifier for a given switch that enabled the diagnostic + + Id : Diagnostic_Id := No_Diagnostic_Id; + -- Unique error code for the given message + + Locations : Labeled_Span_Id := No_Labeled_Span; + -- Identifier to the first location identified by the error message. + -- These locations are marked with an underlying span line and + -- optionally given a short label. + + Fixes : Fix_Id := No_Fix; + -- Identifier to the first fix object for the error message. The fix + -- contains a suggestion to prevent the error from being triggered. + -- This includes edits that can be made to the source code. An edit + -- contians a region of the code that needs to be changed and the new + -- text that should be inserted to that region. end record; package Errors is new Table.Table ( @@ -268,6 +385,56 @@ package Erroutc is -- as the physically last entry in the error message table, since messages -- are not always inserted in sequence. + procedure Next_Error_Msg (E : in out Error_Msg_Id); + -- Update E to point to the next error message in the list of error + -- messages. Skip deleted and continuation messages. + + procedure Next_Continuation_Msg (E : in out Error_Msg_Id); + -- Update E to point to the next continuation message + + function Kind_To_String (E : Error_Msg_Object) return String is + (if E.Warn_Err in From_Pragma | From_Run_Time_As_Err then "error" + else + (case E.Kind is + when Error | Non_Serious_Error => "error", + when Warning => "warning", + when Style => "style", + when Info => "info", + when Low_Check => "low", + when Medium_Check => "medium", + when High_Check => "high")); + -- Returns the name of the error message kind. If it is a warning that has + -- been turned to an error then it returns "error". + + function Get_Doc_Switch (E : Error_Msg_Object) return String; + -- Returns the documentation switch for a given Error_Msg_Object. + -- + -- This either the name of the switch encased in brackets. E.g [-gnatwx]. + -- + -- If the Warn_Char is "* " is then it will return [restriction warning]. + -- + -- Otherwise for messages without a switch it will return + -- [enabled by default] . + + function Primary_Location (E : Error_Msg_Object) return Labeled_Span_Id; + -- Returns the first Primary Labeled_Span associated with the error + -- message. Otherwise it returns No_Labeled_Span. + + function Get_Human_Id (E : Error_Msg_Object) return String_Ptr; + -- Returns a longer human readable name for the switch associated with the + -- error message. + + function Get_Switch (E : Error_Msg_Object) return Switch_Type; + -- Returns the Switch information for the given error message + + function Get_Switch_Id (E : Error_Msg_Object) return Switch_Id; + -- Returns the Switch information identifier for the given error message + + function Get_Switch_Id + (Kind : Error_Msg_Type; Warn_Chr : String) return Switch_Id; + -- Returns the Switch information identifier based on the error kind and + -- the warning character. + -------------------------- -- Warning Mode Control -- -------------------------- @@ -422,6 +589,14 @@ package Erroutc is function SGR_Locus return String is (SGR_Seq (Color_Bold)); + function Get_SGR_Code (E_Msg : Error_Msg_Object) return String is + (if E_Msg.Warn_Err /= None then SGR_Error + else + (case E_Msg.Kind is + when Warning | Style => SGR_Warning, + when Info => SGR_Note, + when others => SGR_Error)); + ----------------- -- Subprograms -- ----------------- @@ -443,8 +618,8 @@ package Erroutc is -- buffer, and preceded by a space. function Compilation_Errors return Boolean; - -- Returns true if errors have been detected, or warnings in -gnatwe - -- (treat warnings as errors) mode. + -- Returns true if errors have been detected, or warnings that are treated + -- as errors. procedure dmsg (Id : Error_Msg_Id); -- Debugging routine to dump an error message @@ -462,16 +637,14 @@ package Erroutc is -- redundant. If so, the message to be deleted and all its continuations -- are marked with the Deleted flag set to True. - function Count_Compile_Time_Pragma_Warnings return Int; - -- Returns the number of warnings in the Errors table that were triggered - -- by a Compile_Time_Warning pragma. - function Get_Warning_Option (Id : Error_Msg_Id) return String; + function Get_Warning_Option (E : Error_Msg_Object) return String; -- Returns the warning switch causing this warning message or an empty -- string is there is none.. function Get_Warning_Tag (Id : Error_Msg_Id) return String; - -- Given an error message ID, return tag showing warning message class, or + function Get_Warning_Tag (E : Error_Msg_Object) return String; + -- Given an error message, return tag showing warning message class, or -- the null string if this option is not enabled or this is not a warning. procedure Increase_Error_Msg_Count (E : Error_Msg_Object); @@ -513,7 +686,7 @@ package Erroutc is -- splits the line generating multiple lines of output, and in this case -- the last line has no terminating end of line character. - procedure Output_Text_Within (Txt : String_Ptr; Line_Length : Nat); + procedure Output_Text_Within (Txt : String; Line_Length : Nat); -- Output the text in Txt, splitting it into lines of at most the size of -- Line_Length. @@ -549,6 +722,18 @@ package Erroutc is -- Note that the call has no effect for continuation messages (those whose -- first character is '\') except for the Has_Insertion_Line setting. + -- Definitions for valid message kind prefixes within error messages. + + Info_Prefix : constant String := "info: "; + Low_Prefix : constant String := "low: "; + Medium_Prefix : constant String := "medium: "; + High_Prefix : constant String := "high: "; + Style_Prefix : constant String := "(style) "; + + Warn_As_Err_Tag : constant String := "[warning-as-error]"; + -- Tag used at the end of warning messages that were converted by + -- pragma Warning_As_Error. + procedure Purge_Messages (From : Source_Ptr; To : Source_Ptr); -- All error messages whose location is in the range From .. To (not -- including the end points) will be deleted from the error listing. @@ -705,6 +890,10 @@ package Erroutc is -- given by Warning_As_Error pragmas, as stored in the Warnings_As_Errors -- table. + function Warning_Treated_As_Error (E : Error_Msg_Object) return Boolean; + -- Returns true if a Warning_As_Error pragma matches either the error text + -- or the warning tag of the message. + procedure Write_Error_Summary; -- Write error summary diff --git a/gcc/ada/diagnostics-switch_repository.adb b/gcc/ada/errsw.adb similarity index 96% rename from gcc/ada/diagnostics-switch_repository.adb rename to gcc/ada/errsw.adb index 1627de36097d..1edc8cd615b2 100644 --- a/gcc/ada/diagnostics-switch_repository.adb +++ b/gcc/ada/errsw.adb @@ -2,7 +2,7 @@ -- -- -- GNAT COMPILER COMPONENTS -- -- -- --- D I A G N O S T I C S . D I A G N O S T I C S _ R E P O S I T O R Y -- +-- E R R S W -- -- -- -- B o d y -- -- -- @@ -22,14 +22,16 @@ -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -with Diagnostics.JSON_Utils; use Diagnostics.JSON_Utils; -with Output; use Output; -package body Diagnostics.Switch_Repository is + +with JSON_Utils; use JSON_Utils; +with Output; use Output; + +package body Errsw is Switches : constant array (Switch_Id) of Switch_Type := (No_Switch_Id => - (others => <>), + <>, gnatwb => (Human_Id => new String'("Warn_On_Bad_Fixed_Value"), Status => Active, @@ -553,12 +555,6 @@ package body Diagnostics.Switch_Repository is return Switches (Id); end Get_Switch; - function Get_Switch (Diag : Diagnostic_Type) return Switch_Type is - - begin - return Get_Switch (Diag.Switch); - end Get_Switch; - ------------------- -- Get_Switch_Id -- ------------------- @@ -577,26 +573,6 @@ package body Diagnostics.Switch_Repository is return No_Switch_Id; end Get_Switch_Id; - ------------------- - -- Get_Switch_Id -- - ------------------- - - function Get_Switch_Id (E : Error_Msg_Object) return Switch_Id is - Switch_Name : constant String := - (if E.Warn_Chr = "$ " then "gnatel" - elsif E.Warn_Chr in "? " | " " then "" - elsif E.Kind in Erroutc.Warning | Erroutc.Info - then "gnatw" & E.Warn_Chr - elsif E.Kind in Erroutc.Style then "gnatw" & E.Warn_Chr - else ""); - begin - if Switch_Name /= "" then - return Get_Switch_Id (Switch_Name); - else - return No_Switch_Id; - end if; - end Get_Switch_Id; - ----------------------------- -- Print_Switch_Repository -- ----------------------------- @@ -687,4 +663,4 @@ package body Diagnostics.Switch_Repository is Write_Eol; end Print_Switch_Repository; -end Diagnostics.Switch_Repository; +end Errsw; diff --git a/gcc/ada/errsw.ads b/gcc/ada/errsw.ads new file mode 100644 index 000000000000..93af18296bb3 --- /dev/null +++ b/gcc/ada/errsw.ads @@ -0,0 +1,155 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- E R R S W -- +-- -- +-- S p e c -- +-- -- +-- Copyright (C) 1992-2025, Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- +-- for more details. You should have received a copy of the GNU General -- +-- Public License distributed with GNAT; see file COPYING3. If not, go to -- +-- http://www.gnu.org/licenses for a complete copy of the license. -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +with Types; use Types; + +package Errsw is + + type Status_Type is + (Active, + Deprecated); + + type Switch_Id is ( + No_Switch_Id, + gnatwb, + gnatwc, + gnatwd, + gnatwf, + gnatwg, + gnatwh, + gnatwi, + gnatwj, + gnatwk, + gnatwl, + gnatwm, + gnatwo, + gnatwp, + gnatwq, + gnatwr, + gnatwt, + gnatwu, + gnatwv, + gnatww, + gnatwx, + gnatwy, + gnatwz, + gnatw_dot_a, + gnatw_dot_b, + gnatw_dot_c, + gnatw_dot_f, + gnatw_dot_h, + gnatw_dot_i, + gnatw_dot_j, + gnatw_dot_k, + gnatw_dot_l, + gnatw_dot_m, + gnatw_dot_n, + gnatw_dot_o, + gnatw_dot_p, + gnatw_dot_q, + gnatw_dot_r, + gnatw_dot_s, + gnatw_dot_t, + gnatw_dot_u, + gnatw_dot_v, + gnatw_dot_w, + gnatw_dot_x, + gnatw_dot_y, + gnatw_dot_z, + gnatw_underscore_a, + gnatw_underscore_c, + gnatw_underscore_j, + gnatw_underscore_l, + gnatw_underscore_p, + gnatw_underscore_q, + gnatw_underscore_r, + gnatw_underscore_s, + gnaty, + gnatya, + gnatyb, + gnatyc, + gnatyd, + gnatye, + gnatyf, + gnatyh, + gnatyi, + gnatyk, + gnatyl, + gnatym, + gnatyn, + gnatyo, + gnatyp, + gnatyr, + gnatys, + gnatyu, + gnatyx, + gnatyz, + gnatyaa, + gnatybb, + gnatycc, + gnatydd, + gnatyii, + gnatyll, + gnatymm, + gnatyoo, + gnatyss, + gnatytt, + gnatel + ); + + subtype Active_Switch_Id is Switch_Id range gnatwb .. gnatel; + + type Switch_Type is record + + Status : Status_Type := Active; + -- The status will indicate whether the switch is currently active, + -- or has been deprecated. A deprecated switch will not control + -- diagnostics, and will not be emitted by the GNAT usage. + + Human_Id : String_Ptr := null; + -- The Human_Id will be a unique and stable string-based ID which + -- identifies the content of the switch within the switch registry. + -- This ID will appear in SARIF readers. + + Short_Name : String_Ptr := null; + -- The Short_Name will denote the -gnatXX name of the switch. + + Description : String_Ptr := null; + -- The description will contain the description of the switch, as it is + -- currently emitted by the GNAT usage. + + Documentation_Url : String_Ptr := null; + -- The documentation_url will point to the AdaCore documentation site + -- for the switch. + + end record; + + function Get_Switch (Id : Switch_Id) return Switch_Type; + + function Get_Switch_Id (Name : String) return Switch_Id; + + procedure Print_Switch_Repository; + +end Errsw; diff --git a/gcc/ada/errutil.adb b/gcc/ada/errutil.adb index 5548d533e79e..b3674a1bcb50 100644 --- a/gcc/ada/errutil.adb +++ b/gcc/ada/errutil.adb @@ -25,7 +25,9 @@ with Atree; use Atree; with Err_Vars; use Err_Vars; +with Errid; use Errid; with Erroutc; use Erroutc; +with Errsw; use Errsw; with Namet; use Namet; with Opt; use Opt; with Output; use Output; @@ -206,12 +208,18 @@ package body Errutil is Line => Get_Physical_Line_Number (Sptr), Col => Get_Column_Number (Sptr), Compile_Time_Pragma => Is_Compile_Time_Msg, - Warn_Err => Warning_Mode = Treat_As_Error, + Warn_Err => (if Warning_Mode = Treat_As_Error + then From_Warn_As_Err + else None), Warn_Chr => Warning_Msg_Char, Uncond => Is_Unconditional_Msg, Msg_Cont => Continuation, Deleted => False, - Kind => Error_Msg_Kind)); + Kind => Error_Msg_Kind, + Id => No_Diagnostic_Id, + Switch => No_Switch_Id, + Locations => No_Labeled_Span, + Fixes => No_Fix)); Cur_Msg := Errors.Last; Prev_Msg := No_Error_Msg; diff --git a/gcc/ada/eval_fat.adb b/gcc/ada/eval_fat.adb index 09a5b3fa1b7a..5a2e43ef5978 100644 --- a/gcc/ada/eval_fat.adb +++ b/gcc/ada/eval_fat.adb @@ -146,8 +146,6 @@ package body Eval_Fat is if UR_Is_Negative (X) then Fraction := -Fraction; end if; - - return; end Decompose; ------------------- diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb index 7cb26ce1af51..9458bdea6633 100644 --- a/gcc/ada/exp_aggr.adb +++ b/gcc/ada/exp_aggr.adb @@ -865,7 +865,9 @@ package body Exp_Aggr is -- Checks 8: (no delayed components) - if Is_Delayed_Aggregate (Expr) then + if Is_Delayed_Aggregate (Expr) + or else Is_Delayed_Conditional_Expression (Expr) + then return False; end if; @@ -1405,6 +1407,26 @@ package body Exp_Aggr is N_Iterated_Component_Association then null; + + -- For mutably tagged class-wide type components that have an + -- initializing qualified expression, the expression must be + -- analyzed and resolved using the type of the qualified + -- expression; otherwise spurious errors would be reported + -- because components defined in derivations of the root type + -- of the mutably tagged class-wide type would not be visible. + + -- Resolve_Aggr_Expr has previously checked that the type of + -- the qualified expression is a descendant of the root type + -- of the mutably class-wide tagged type. + + elsif Is_Mutably_Tagged_Type (Comp_Typ) + and then Nkind (Expr) = N_Qualified_Expression + then + -- Avoid class-wide expected type for aggregate + -- (which would be rejected as illegal) + -- if the aggregate is explicitly qualified. + + Analyze_And_Resolve (Expr_Q, Etype (Expr)); else Analyze_And_Resolve (Expr_Q, Comp_Typ); end if; @@ -1457,14 +1479,21 @@ package body Exp_Aggr is -- object creation that will invoke it otherwise. else - if Present (Base_Init_Proc (Ctype)) then + -- For mutably tagged class-wide types, default initialization is + -- performed by the init procedure of their specific type. + + if Is_Mutably_Tagged_Type (Comp_Typ) then + Comp_Typ := Find_Specific_Type (Comp_Typ); + end if; + + if Present (Base_Init_Proc (Comp_Typ)) then Check_Restriction (No_Default_Initialization, N); if not Restriction_Active (No_Default_Initialization) then Append_List_To (Stmts, Build_Initialization_Call (N, Id_Ref => Indexed_Comp, - Typ => Ctype, + Typ => Comp_Typ, With_Default_Init => True)); end if; @@ -1473,17 +1502,17 @@ package body Exp_Aggr is -- be analyzed and resolved before the code for initialization -- of other components. - if Has_Invariants (Ctype) then - Set_Etype (Indexed_Comp, Ctype); + if Has_Invariants (Comp_Typ) then + Set_Etype (Indexed_Comp, Comp_Typ); Append_To (Stmts, Make_Invariant_Call (Indexed_Comp)); end if; end if; - if Needs_Finalization (Ctype) then + if Needs_Finalization (Comp_Typ) then Init_Call := Make_Init_Call (Obj_Ref => New_Copy_Tree (Indexed_Comp), - Typ => Ctype); + Typ => Comp_Typ); -- Guard against a missing [Deep_]Initialize when the component -- type was not properly frozen. @@ -1504,9 +1533,13 @@ package body Exp_Aggr is -- is not empty, but a default init still applies, such as for -- Default_Value cases, in which case we won't get here. ??? - if Has_DIC (Ctype) and then Present (DIC_Procedure (Ctype)) then + if Has_DIC (Comp_Typ) + and then Present (DIC_Procedure (Comp_Typ)) + then Append_To (Stmts, - Build_DIC_Call (Loc, New_Copy_Tree (Indexed_Comp), Ctype)); + Build_DIC_Call (Loc, + Obj_Name => New_Copy_Tree (Indexed_Comp), + Typ => Comp_Typ)); end if; end if; @@ -1518,6 +1551,8 @@ package body Exp_Aggr is -------------- function Gen_Loop (L, H : Node_Id; Expr : Node_Id) return List_Id is + Comp_Typ : Entity_Id; + Is_Iterated_Component : constant Boolean := Parent_Kind (Expr) = N_Iterated_Component_Association; @@ -1573,6 +1608,12 @@ package body Exp_Aggr is Tcopy := New_Copy_Tree (Expr); Set_Parent (Tcopy, N); + Comp_Typ := Component_Type (Etype (N)); + + if Is_Class_Wide_Equivalent_Type (Comp_Typ) then + Comp_Typ := Corresponding_Mutably_Tagged_Type (Comp_Typ); + end if; + -- For iterated_component_association analyze and resolve -- the expression with name of the index parameter visible. -- To manipulate scopes, we use entity of the implicit loop. @@ -1584,8 +1625,7 @@ package body Exp_Aggr is begin Push_Scope (Scope (Index_Parameter)); Enter_Name (Index_Parameter); - Analyze_And_Resolve - (Tcopy, Component_Type (Etype (N))); + Analyze_And_Resolve (Tcopy, Comp_Typ); End_Scope; end; @@ -1593,7 +1633,7 @@ package body Exp_Aggr is -- resolve the expression. else - Analyze_And_Resolve (Tcopy, Component_Type (Etype (N))); + Analyze_And_Resolve (Tcopy, Comp_Typ); end if; Expander_Mode_Restore; @@ -2130,6 +2170,7 @@ package body Exp_Aggr is Set_Loop_Actions (Others_Assoc, New_List); First := False; end if; + Expr := Get_Assoc_Expr (Others_Assoc); Append_List (Gen_Loop (Low, High, Expr), To => New_Code); end if; @@ -2490,12 +2531,21 @@ package body Exp_Aggr is Ref := Convert_To (Init_Typ, New_Copy_Tree (Target)); Set_Assignment_OK (Ref); - Append_To (L, - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of - (Find_Controlled_Prim_Op (Init_Typ, Name_Initialize), Loc), - Parameter_Associations => New_List (New_Copy_Tree (Ref)))); + declare + Intlz : constant Entity_Id := + Find_Controlled_Prim_Op (Init_Typ, Name_Initialize); + begin + if Present (Intlz) then + Append_To + (L, + Make_Procedure_Call_Statement + (Loc, + Name => + New_Occurrence_Of (Intlz, Loc), + Parameter_Associations => + New_List (New_Copy_Tree (Ref)))); + end if; + end; end if; end Generate_Finalization_Actions; @@ -3267,54 +3317,85 @@ package body Exp_Aggr is -- a call to the corresponding IP subprogram if available. elsif Box_Present (Comp) - and then Has_Non_Null_Base_Init_Proc (Etype (Selector)) - then - Check_Restriction (No_Default_Initialization, N); - - if Ekind (Selector) /= E_Discriminant then - Generate_Finalization_Actions; - end if; + and then + (Has_Non_Null_Base_Init_Proc (Etype (Selector)) - -- Ada 2005 (AI-287): If the component type has tasks then - -- generate the activation chain and master entities (except - -- in case of an allocator because in that case these entities - -- are generated by Build_Task_Allocate_Block). + -- Default initialization of mutably tagged class-wide type + -- components is performed by the IP subprogram. + or else Is_Class_Wide_Equivalent_Type (Etype (Selector))) + then declare - Ctype : constant Entity_Id := Etype (Selector); - Inside_Allocator : Boolean := False; - P : Node_Id := Parent (N); + Ctype : Entity_Id := Etype (Selector); begin - if Is_Task_Type (Ctype) or else Has_Task (Ctype) then - while Present (P) loop - if Nkind (P) = N_Allocator then - Inside_Allocator := True; - exit; + if Is_Class_Wide_Equivalent_Type (Ctype) then + Ctype := + Root_Type (Corresponding_Mutably_Tagged_Type (Ctype)); + end if; + + Check_Restriction (No_Default_Initialization, N); + + if Ekind (Selector) /= E_Discriminant then + Generate_Finalization_Actions; + end if; + + -- Ada 2005 (AI-287): If the component type has tasks then + -- generate the activation chain and master entities (except + -- in case of an allocator because in that case these entities + -- are generated by Build_Task_Allocate_Block). + + declare + Inside_Allocator : Boolean := False; + P : Node_Id := Parent (N); + + begin + if Is_Task_Type (Ctype) or else Has_Task (Ctype) then + while Present (P) loop + if Nkind (P) = N_Allocator then + Inside_Allocator := True; + exit; + end if; + + P := Parent (P); + end loop; + + if not Inside_Init_Proc and not Inside_Allocator then + Build_Activation_Chain_Entity (N); end if; + end if; + end; - P := Parent (P); - end loop; + if not Restriction_Active (No_Default_Initialization) then + Append_List_To (L, + Build_Initialization_Call (N, + Id_Ref => Make_Selected_Component (Loc, + Prefix => + New_Copy_Tree (Target), + Selector_Name => + New_Occurrence_Of + (Selector, Loc)), + Typ => Ctype, + Enclos_Type => Typ, + With_Default_Init => True)); - if not Inside_Init_Proc and not Inside_Allocator then - Build_Activation_Chain_Entity (N); + if Is_Class_Wide_Equivalent_Type (Etype (Selector)) + and then Is_Abstract_Type (Ctype) + then + Error_Msg_Name_1 := Chars (Selector); + Error_Msg_N + ("default initialization of abstract type " + & "component % not allowed??", Comp); + Error_Msg_N + ("\Program_Error will be raised at run time??", Comp); + + Append_To (L, + Make_Raise_Program_Error (Loc, + Reason => PE_Abstract_Type_Component)); end if; end if; end; - if not Restriction_Active (No_Default_Initialization) then - Append_List_To (L, - Build_Initialization_Call (N, - Id_Ref => Make_Selected_Component (Loc, - Prefix => - New_Copy_Tree (Target), - Selector_Name => - New_Occurrence_Of (Selector, Loc)), - Typ => Etype (Selector), - Enclos_Type => Typ, - With_Default_Init => True)); - end if; - -- Prepare for component assignment elsif Ekind (Selector) /= E_Discriminant @@ -3471,12 +3552,27 @@ package body Exp_Aggr is end if; end if; - Initialize_Component - (N => N, - Comp => Comp_Expr, - Comp_Typ => Etype (Selector), - Init_Expr => Expr_Q, - Stmts => L); + -- For mutably tagged class-wide components with a qualified + -- initializing expressions use the qualified expression as + -- its Init_Expr; required to avoid reporting spurious errors. + + if Is_Class_Wide_Equivalent_Type (Comp_Type) + and then Nkind (Expression (Comp)) = N_Qualified_Expression + then + Initialize_Component + (N => N, + Comp => Comp_Expr, + Comp_Typ => Etype (Selector), + Init_Expr => Expression (Comp), + Stmts => L); + else + Initialize_Component + (N => N, + Comp => Comp_Expr, + Comp_Typ => Etype (Selector), + Init_Expr => Expr_Q, + Stmts => L); + end if; end if; -- comment would be good here ??? @@ -3865,8 +3961,8 @@ package body Exp_Aggr is function Safe_Component (Expr : Node_Id) return Boolean; -- Verify that an expression cannot depend on the target being assigned - -- to. Return true for compile-time known values, stand-alone objects, - -- parameters passed by copy, calls to functions that return by copy, + -- (which is Target_Object if it is set), return true for compile-time + -- known values, stand-alone objects, formal parameters passed by copy, -- selected components thereof only if the aggregate's type is an array, -- indexed components and slices thereof only if the aggregate's type is -- a record, and simple expressions involving only these as operands. @@ -3877,7 +3973,8 @@ package body Exp_Aggr is -- which is excluded by the above condition. Additionally, if the target -- is statically known, return true for arbitrarily nested selections, -- indexations or slicings, provided that their ultimate prefix is not - -- the target itself. + -- the target itself, and calls to functions that take only these as + -- actual parameters provided that the target is not aliased. -------------------- -- Safe_Aggregate -- @@ -3982,12 +4079,26 @@ package body Exp_Aggr is return Check_Component (Prefix (C), T_OK); when N_Function_Call => - if Nkind (Name (C)) = N_Explicit_Dereference then - return not Returns_By_Ref (Etype (Name (C))); - else - return not Returns_By_Ref (Entity (Name (C))); + if No (Target_Object) or else Is_Aliased (Target_Object) then + return False; + end if; + + if Present (Parameter_Associations (C)) then + declare + Actual : Node_Id; + begin + Actual := First_Actual (C); + while Present (Actual) loop + if not Check_Component (Actual, T_OK) then + return False; + end if; + Next_Actual (Actual); + end loop; + end; end if; + return True; + when N_Indexed_Component | N_Slice => -- In a target record, these operations cannot determine -- alone a component so we can recurse whatever the target. @@ -4179,11 +4290,7 @@ package body Exp_Aggr is -- excluding container aggregates as these are transformed into -- subprogram calls later. - (Nkind (Parent_Node) = N_Component_Association - and then not Is_Container_Aggregate (Parent (Parent_Node))) - - or else (Nkind (Parent_Node) in N_Aggregate | N_Extension_Aggregate - and then not Is_Container_Aggregate (Parent_Node)) + Parent_Is_Regular_Aggregate (Parent_Node) -- Allocator (see Convert_Aggr_In_Allocator) @@ -4327,6 +4434,7 @@ package body Exp_Aggr is Typ : constant Entity_Id := Etype (N); Dims : constant Nat := Number_Dimensions (Typ); Max_Others_Replicate : constant Nat := Max_Aggregate_Size (N); + Ctyp : constant Entity_Id := Component_Type (Typ); Static_Components : Boolean := True; @@ -4803,7 +4911,13 @@ package body Exp_Aggr is -- components because in this case will need to call the corresponding -- IP procedure. - if Has_Default_Init_Comps (N) then + if Has_Default_Init_Comps (N) + or else Present (Constructor_Name (Ctyp)) + or else (Is_Access_Type (Ctyp) + and then Present + (Constructor_Name + (Directly_Designated_Type (Ctyp)))) + then return; end if; @@ -4956,6 +5070,14 @@ package body Exp_Aggr is -- type using the computable sizes of the aggregate and its sub- -- aggregates. + function Build_Two_Pass_Aggr_Code + (Lhs : Node_Id; + Aggr_Typ : out Entity_Id) return List_Id; + -- The aggregate consists only of iterated associations and Lhs is an + -- expression containing the location of the anonymous object, which + -- may be built in place. Returns the dynamic subtype of the aggregate + -- in Aggr_Typ and the list of statements needed to build it. + procedure Check_Bounds (Aggr_Bounds_Node, Index_Bounds_Node : Node_Id); -- Checks that the bounds of Aggr_Bounds are within the bounds defined -- by Index_Bounds. For null array aggregate (Ada 2022) check that the @@ -4983,7 +5105,7 @@ package body Exp_Aggr is -- built directly into the target of an assignment, the target must -- be free of side effects. N is the target of the assignment. - procedure Two_Pass_Aggregate_Expansion (N : Node_Id); + procedure Two_Pass_Aggregate_Expansion; -- If the aggregate consists only of iterated associations then the -- aggregate is constructed in two steps: -- a) Build an expression to compute the number of elements @@ -5053,6 +5175,221 @@ package body Exp_Aggr is Freeze_Itype (Agg_Type, N); end Build_Constrained_Type; + ------------------------------ + -- Build_Two_Pass_Aggr_Code -- + ------------------------------ + + function Build_Two_Pass_Aggr_Code + (Lhs : Node_Id; + Aggr_Typ : out Entity_Id) return List_Id + is + Index_Id : constant Entity_Id := Make_Temporary (Loc, 'I', N); + Index_Type : constant Entity_Id := Etype (First_Index (Typ)); + Index_Base : constant Entity_Id := Base_Type (Index_Type); + Size_Id : constant Entity_Id := Make_Temporary (Loc, 'I', N); + Size_Type : constant Entity_Id := + Integer_Type_For + (Esize (Index_Base), Is_Unsigned_Type (Index_Base)); + + Assoc : Node_Id; + Incr : Node_Id; + Iter : Node_Id; + New_Comp : Node_Id; + One_Loop : Node_Id; + Iter_Id : Entity_Id; + + Aggr_Code : List_Id; + Size_Expr_Code : List_Id; + + begin + Size_Expr_Code := New_List ( + Make_Object_Declaration (Loc, + Defining_Identifier => Size_Id, + Object_Definition => New_Occurrence_Of (Size_Type, Loc), + Expression => Make_Integer_Literal (Loc, 0))); + + -- First pass: execute the iterators to count the number of elements + -- that will be generated. + + Assoc := First (Component_Associations (N)); + while Present (Assoc) loop + Iter := Iterator_Specification (Assoc); + Iter_Id := Defining_Identifier (Iter); + Incr := + Make_Assignment_Statement (Loc, + Name => New_Occurrence_Of (Size_Id, Loc), + Expression => + Make_Op_Add (Loc, + Left_Opnd => New_Occurrence_Of (Size_Id, Loc), + Right_Opnd => Make_Integer_Literal (Loc, 1))); + + -- Avoid using the same iterator definition in both loops by + -- creating a new iterator for each loop and mapping it over the + -- original iterator references. + + One_Loop := + Make_Implicit_Loop_Statement (N, + Iteration_Scheme => + Make_Iteration_Scheme (Loc, + Iterator_Specification => + New_Copy_Tree (Iter, + Map => New_Elmt_List (Iter_Id, New_Copy (Iter_Id)))), + Statements => New_List (Incr)); + + Append (One_Loop, Size_Expr_Code); + Next (Assoc); + end loop; + + Insert_Actions (N, Size_Expr_Code); + + -- Build a constrained subtype with the bounds deduced from + -- the size computed above and declare the aggregate object. + -- The index type is some discrete type, so the bounds of the + -- constrained subtype are computed as T'Val (integer bounds). + + declare + -- Pos_Lo := Index_Type'Pos (Index_Type'First) + + Pos_Lo : constant Node_Id := + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Index_Type, Loc), + Attribute_Name => Name_Pos, + Expressions => New_List ( + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Index_Type, Loc), + Attribute_Name => Name_First))); + + -- Corresponding index value, i.e. Index_Type'First + + Aggr_Lo : constant Node_Id := + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Index_Type, Loc), + Attribute_Name => Name_First); + + -- Pos_Hi := Pos_Lo + Size - 1 + + Pos_Hi : constant Node_Id := + Make_Op_Add (Loc, + Left_Opnd => Pos_Lo, + Right_Opnd => + Make_Op_Subtract (Loc, + Left_Opnd => New_Occurrence_Of (Size_Id, Loc), + Right_Opnd => Make_Integer_Literal (Loc, 1))); + + -- Corresponding index value + + Aggr_Hi : constant Node_Id := + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Index_Type, Loc), + Attribute_Name => Name_Val, + Expressions => New_List (Pos_Hi)); + + begin + Aggr_Typ := Make_Temporary (Loc, 'T'); + + Insert_Action (N, + Make_Subtype_Declaration (Loc, + Defining_Identifier => Aggr_Typ, + Subtype_Indication => + Make_Subtype_Indication (Loc, + Subtype_Mark => + New_Occurrence_Of (Base_Type (Typ), Loc), + Constraint => + Make_Index_Or_Discriminant_Constraint + (Loc, + Constraints => + New_List (Make_Range (Loc, Aggr_Lo, Aggr_Hi)))))); + end; + + -- Second pass: use the iterators to generate the elements of the + -- aggregate. We assume that the second evaluation of each iterator + -- generates the same number of elements as the first pass, and thus + -- consider that the execution is erroneous (even if the RM does not + -- state this explicitly) if the number of elements generated differs + -- between first and second pass. + + Assoc := First (Component_Associations (N)); + + -- Initialize insertion position to first array component + + Aggr_Code := New_List ( + Make_Object_Declaration (Loc, + Defining_Identifier => Index_Id, + Object_Definition => + New_Occurrence_Of (Index_Type, Loc), + Expression => + Make_Attribute_Reference (Loc, + Prefix => New_Copy_Tree (Lhs), + Attribute_Name => Name_First))); + + while Present (Assoc) loop + Iter := Iterator_Specification (Assoc); + Iter_Id := Defining_Identifier (Iter); + New_Comp := + Make_OK_Assignment_Statement (Loc, + Name => + Make_Indexed_Component (Loc, + Prefix => New_Copy_Tree (Lhs), + Expressions => + New_List (New_Occurrence_Of (Index_Id, Loc))), + Expression => Copy_Separate_Tree (Expression (Assoc))); + + -- Arrange for the component to be adjusted if need be (the call + -- will be generated by Make_Tag_Ctrl_Assignment). + + if Needs_Finalization (Ctyp) + and then not Is_Inherently_Limited_Type (Ctyp) + then + Set_No_Finalize_Actions (New_Comp); + else + Set_No_Ctrl_Actions (New_Comp); + end if; + + -- Advance index position for insertion + + Incr := + Make_Assignment_Statement (Loc, + Name => New_Occurrence_Of (Index_Id, Loc), + Expression => + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Index_Type, Loc), + Attribute_Name => Name_Succ, + Expressions => + New_List (New_Occurrence_Of (Index_Id, Loc)))); + + -- Add guard to skip last increment when upper bound is reached + + Incr := + Make_If_Statement (Loc, + Condition => + Make_Op_Ne (Loc, + Left_Opnd => New_Occurrence_Of (Index_Id, Loc), + Right_Opnd => + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Index_Type, Loc), + Attribute_Name => Name_Last)), + Then_Statements => New_List (Incr)); + + -- Avoid using the same iterator definition in both loops by + -- creating a new iterator for each loop and mapping it over + -- the original iterator references. + + One_Loop := + Make_Implicit_Loop_Statement (N, + Iteration_Scheme => + Make_Iteration_Scheme (Loc, + Iterator_Specification => + New_Copy_Tree (Iter, + Map => New_Elmt_List (Iter_Id, New_Copy (Iter_Id)))), + Statements => New_List (New_Comp, Incr)); + + Append (One_Loop, Aggr_Code); + Next (Assoc); + end loop; + + return Aggr_Code; + end Build_Two_Pass_Aggr_Code; + ------------------ -- Check_Bounds -- ------------------ @@ -5596,214 +5933,98 @@ package body Exp_Aggr is -- Two_Pass_Aggregate_Expansion -- ---------------------------------- - procedure Two_Pass_Aggregate_Expansion (N : Node_Id) is - Loc : constant Source_Ptr := Sloc (N); - Comp_Type : constant Entity_Id := Etype (N); - Index_Id : constant Entity_Id := Make_Temporary (Loc, 'I', N); - Index_Type : constant Entity_Id := Etype (First_Index (Etype (N))); - Index_Base : constant Entity_Id := Base_Type (Index_Type); - Size_Id : constant Entity_Id := Make_Temporary (Loc, 'I', N); - Size_Type : constant Entity_Id := - Integer_Type_For - (Esize (Index_Base), Is_Unsigned_Type (Index_Base)); - TmpE : constant Entity_Id := Make_Temporary (Loc, 'A', N); - - Assoc : Node_Id := First (Component_Associations (N)); - Incr : Node_Id; - Iter : Node_Id; - New_Comp : Node_Id; - One_Loop : Node_Id; - Iter_Id : Entity_Id; - - Size_Expr_Code : List_Id; - Insertion_Code : List_Id := New_List; + procedure Two_Pass_Aggregate_Expansion is + Aggr_Code : List_Id; + Aggr_Typ : Entity_Id; + Lhs : Node_Id; + Obj_Id : Entity_Id; + Par : Node_Id; begin - Size_Expr_Code := New_List ( - Make_Object_Declaration (Loc, - Defining_Identifier => Size_Id, - Object_Definition => New_Occurrence_Of (Size_Type, Loc), - Expression => Make_Integer_Literal (Loc, 0))); - - -- First pass: execute the iterators to count the number of elements - -- that will be generated. - - while Present (Assoc) loop - Iter := Iterator_Specification (Assoc); - Iter_Id := Defining_Identifier (Iter); - Incr := Make_Assignment_Statement (Loc, - Name => New_Occurrence_Of (Size_Id, Loc), - Expression => - Make_Op_Add (Loc, - Left_Opnd => New_Occurrence_Of (Size_Id, Loc), - Right_Opnd => Make_Integer_Literal (Loc, 1))); - - -- Avoid using the same iterator definition in both loops by - -- creating a new iterator for each loop and mapping it over the - -- original iterator references. - - One_Loop := Make_Implicit_Loop_Statement (N, - Iteration_Scheme => - Make_Iteration_Scheme (Loc, - Iterator_Specification => - New_Copy_Tree (Iter, - Map => New_Elmt_List (Iter_Id, New_Copy (Iter_Id)))), - Statements => New_List (Incr)); - - Append (One_Loop, Size_Expr_Code); - Next (Assoc); + Par := Parent (N); + while Nkind (Par) = N_Qualified_Expression loop + Par := Parent (Par); end loop; - Insert_Actions (N, Size_Expr_Code); - - -- Build a constrained subtype with the bounds deduced from - -- the size computed above and declare the aggregate object. - -- The index type is some discrete type, so the bounds of the - -- constrained subtype are computed as T'Val (integer bounds). - - declare - -- Pos_Lo := Index_Type'Pos (Index_Type'First) - - Pos_Lo : constant Node_Id := - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Index_Type, Loc), - Attribute_Name => Name_Pos, - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Index_Type, Loc), - Attribute_Name => Name_First))); - - -- Corresponding index value, i.e. Index_Type'First - - Aggr_Lo : constant Node_Id := - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Index_Type, Loc), - Attribute_Name => Name_First); - - -- Pos_Hi := Pos_Lo + Size - 1 - - Pos_Hi : constant Node_Id := - Make_Op_Add (Loc, - Left_Opnd => Pos_Lo, - Right_Opnd => - Make_Op_Subtract (Loc, - Left_Opnd => New_Occurrence_Of (Size_Id, Loc), - Right_Opnd => Make_Integer_Literal (Loc, 1))); - - -- Corresponding index value + -- If the aggregate is the initialization expression of an object + -- declaration, we always build the aggregate in place, although + -- this is required only for immutably limited types and types + -- that need finalization, see RM 7.6(17.2/3-17.3/3). - Aggr_Hi : constant Node_Id := - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Index_Type, Loc), - Attribute_Name => Name_Val, - Expressions => New_List (Pos_Hi)); - - SubE : constant Entity_Id := Make_Temporary (Loc, 'T'); - SubD : constant Node_Id := - Make_Subtype_Declaration (Loc, - Defining_Identifier => SubE, - Subtype_Indication => - Make_Subtype_Indication (Loc, - Subtype_Mark => - New_Occurrence_Of (Etype (Comp_Type), Loc), - Constraint => - Make_Index_Or_Discriminant_Constraint - (Loc, - Constraints => - New_List (Make_Range (Loc, Aggr_Lo, Aggr_Hi))))); - - -- Create a temporary array of the above subtype which - -- will be used to capture the aggregate assignments. - - TmpD : constant Node_Id := - Make_Object_Declaration (Loc, - Defining_Identifier => TmpE, - Object_Definition => New_Occurrence_Of (SubE, Loc)); - - begin - Insert_Actions (N, New_List (SubD, TmpD)); - end; - - -- Second pass: use the iterators to generate the elements of the - -- aggregate. Insertion index starts at Index_Type'First. We - -- assume that the second evaluation of each iterator generates - -- the same number of elements as the first pass, and consider - -- that the execution is erroneous (even if the RM does not state - -- this explicitly) if the number of elements generated differs - -- between first and second pass. - - Assoc := First (Component_Associations (N)); + if Nkind (Par) = N_Object_Declaration then + Obj_Id := Defining_Identifier (Par); + Lhs := New_Occurrence_Of (Obj_Id, Loc); + Set_Assignment_OK (Lhs); + Aggr_Code := Build_Two_Pass_Aggr_Code (Lhs, Aggr_Typ); - -- Initialize insertion position to first array component. + -- Save the last assignment statement associated with the + -- aggregate when building a controlled object. This last + -- assignment is used by the finalization machinery when + -- marking an object as successfully initialized. - Insertion_Code := New_List ( - Make_Object_Declaration (Loc, - Defining_Identifier => Index_Id, - Object_Definition => - New_Occurrence_Of (Index_Type, Loc), - Expression => - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Index_Type, Loc), - Attribute_Name => Name_First))); + if Needs_Finalization (Typ) then + Mutate_Ekind (Obj_Id, E_Variable); + Set_Last_Aggregate_Assignment (Obj_Id, Last (Aggr_Code)); + end if; - while Present (Assoc) loop - Iter := Iterator_Specification (Assoc); - Iter_Id := Defining_Identifier (Iter); - New_Comp := Make_Assignment_Statement (Loc, - Name => - Make_Indexed_Component (Loc, - Prefix => New_Occurrence_Of (TmpE, Loc), - Expressions => - New_List (New_Occurrence_Of (Index_Id, Loc))), - Expression => Copy_Separate_Tree (Expression (Assoc))); + -- If a transient scope has been created around the declaration, + -- we need to attach the code to it so that finalization actions + -- of the declaration will be inserted after it; otherwise, we + -- directly insert it after the declaration. In both cases, the + -- code will be analyzed after the declaration is processed, i.e. + -- once the actual subtype of the object is established. - -- Advance index position for insertion. + if Scope_Is_Transient and then Par = Node_To_Be_Wrapped then + Store_After_Actions_In_Scope_Without_Analysis (Aggr_Code); + else + Insert_List_After (Par, Aggr_Code); + end if; - Incr := Make_Assignment_Statement (Loc, - Name => New_Occurrence_Of (Index_Id, Loc), - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Index_Type, Loc), - Attribute_Name => Name_Succ, - Expressions => - New_List (New_Occurrence_Of (Index_Id, Loc)))); + Set_Etype (N, Aggr_Typ); + Set_No_Initialization (Par); - -- Add guard to skip last increment when upper bound is reached. + -- Likewise if it is the qualified expression of an allocator but, + -- in this case, we wait until after Expand_Allocator_Expression + -- rewrites the allocator as the initialization expression of an + -- object declaration, so that we have the left-hand side. - Incr := Make_If_Statement (Loc, - Condition => - Make_Op_Ne (Loc, - Left_Opnd => New_Occurrence_Of (Index_Id, Loc), - Right_Opnd => - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Index_Type, Loc), - Attribute_Name => Name_Last)), - Then_Statements => New_List (Incr)); + elsif Nkind (Par) = N_Allocator then + if Nkind (Parent (Par)) = N_Object_Declaration + and then + not Comes_From_Source (Defining_Identifier (Parent (Par))) + then + Obj_Id := Defining_Identifier (Parent (Par)); + Lhs := + Make_Explicit_Dereference (Loc, + Prefix => New_Occurrence_Of (Obj_Id, Loc)); + Set_Assignment_OK (Lhs); + Aggr_Code := Build_Two_Pass_Aggr_Code (Lhs, Aggr_Typ); - -- Avoid using the same iterator definition in both loops by - -- creating a new iterator for each loop and mapping it over the - -- original iterator references. + Insert_Actions_After (Parent (Par), Aggr_Code); - One_Loop := Make_Implicit_Loop_Statement (N, - Iteration_Scheme => - Make_Iteration_Scheme (Loc, - Iterator_Specification => - New_Copy_Tree (Iter, - Map => New_Elmt_List (Iter_Id, New_Copy (Iter_Id)))), - Statements => New_List (New_Comp, Incr)); + Set_Expression (Par, New_Occurrence_Of (Aggr_Typ, Loc)); + Set_No_Initialization (Par); + end if; - Append (One_Loop, Insertion_Code); - Next (Assoc); - end loop; + -- Otherwise we create a temporary for the anonymous object and + -- replace the aggregate with the temporary. - Insert_Actions (N, Insertion_Code); + else + Obj_Id := Make_Temporary (Loc, 'A', N); + Lhs := New_Occurrence_Of (Obj_Id, Loc); + Set_Assignment_OK (Lhs); - -- Depending on context this may not work for build-in-place - -- arrays ??? + Aggr_Code := Build_Two_Pass_Aggr_Code (Lhs, Aggr_Typ); + Prepend_To (Aggr_Code, + Make_Object_Declaration (Loc, + Defining_Identifier => Obj_Id, + Object_Definition => New_Occurrence_Of (Aggr_Typ, Loc))); - Rewrite (N, New_Occurrence_Of (TmpE, Loc)); + Insert_Actions (N, Aggr_Code); + Rewrite (N, Lhs); + Analyze_And_Resolve (N, Aggr_Typ); + end if; end Two_Pass_Aggregate_Expansion; -- Local variables @@ -5829,7 +6050,7 @@ package body Exp_Aggr is -- Aggregates that require a two-pass expansion are handled separately elsif Is_Two_Pass_Aggregate (N) then - Two_Pass_Aggregate_Expansion (N); + Two_Pass_Aggregate_Expansion; return; -- Do not attempt expansion if error already detected. We may reach this @@ -6002,12 +6223,11 @@ package body Exp_Aggr is -- static type imposed by the context. declare - Itype : constant Entity_Id := Etype (N); Index : Node_Id; Needs_Type : Boolean := False; begin - Index := First_Index (Itype); + Index := First_Index (Typ); while Present (Index) loop if not Is_OK_Static_Subtype (Etype (Index)) then Needs_Type := True; @@ -6019,7 +6239,7 @@ package body Exp_Aggr is if Needs_Type then Build_Constrained_Type (Positional => True); - Rewrite (N, Unchecked_Convert_To (Itype, N)); + Rewrite (N, Unchecked_Convert_To (Typ, N)); Analyze (N); end if; end; @@ -6037,14 +6257,9 @@ package body Exp_Aggr is if -- Internal aggregates (transformed when expanding the parent), -- excluding container aggregates as these are transformed into - -- subprogram calls later. So far aggregates with self-references - -- are not supported if they appear in a conditional expression. - - (Nkind (Parent_Node) = N_Component_Association - and then not Is_Container_Aggregate (Parent (Parent_Node))) + -- subprogram calls later. - or else (Nkind (Parent_Node) in N_Aggregate | N_Extension_Aggregate - and then not Is_Container_Aggregate (Parent_Node)) + Parent_Is_Regular_Aggregate (Parent_Node) -- Allocator (see Convert_Aggr_In_Allocator). Sliding cannot be done -- in place for the time being. @@ -6147,7 +6362,7 @@ package body Exp_Aggr is then Tmp := Name (Parent_Node); - if Etype (Tmp) /= Etype (N) then + if Etype (Tmp) /= Typ then Apply_Length_Check (N, Etype (Tmp)); if Nkind (N) = N_Raise_Constraint_Error then @@ -6388,7 +6603,7 @@ package body Exp_Aggr is exception when RE_Not_Available => - return; + null; end Expand_N_Aggregate; ------------------------------- @@ -6517,6 +6732,7 @@ package body Exp_Aggr is function Build_Size_Expr (Comp : Node_Id) return Node_Id is Lo, Hi : Node_Id; It : Node_Id; + It_Subt : Entity_Id; Siz_Exp : Node_Id := Empty; Choice : Node_Id; Temp_Siz_Exp : Node_Id; @@ -6591,20 +6807,22 @@ package body Exp_Aggr is elsif Nkind (Comp) = N_Iterated_Component_Association then if Present (Iterator_Specification (Comp)) then - -- If the static size of the iterable object is known, + -- If the size of the iterable object can be determined, -- attempt to return it. It := Name (Iterator_Specification (Comp)); Preanalyze (It); - -- Handle the simplest cases for now where It denotes an array - -- object. + It_Subt := Etype (It); + + -- Handle the simplest cases for now, where It denotes an array + -- object or a container object. if Nkind (It) in N_Identifier - and then Ekind (Etype (It)) = E_Array_Subtype + and then Ekind (It_Subt) = E_Array_Subtype then declare - Idx_N : Node_Id := First_Index (Etype (It)); + Idx_N : Node_Id := First_Index (It_Subt); Siz_Exp : Node_Id := Empty; begin while Present (Idx_N) loop @@ -6638,6 +6856,96 @@ package body Exp_Aggr is return Siz_Exp; end; + + -- Case of iterating over a container object. Note that this + -- must be a simple object, and not something like a function + -- call (which might have side effects, and we wouldn't want + -- it to be evaluated more than once). We take advantage of + -- RM22 4.3.5(40/5), which allows implementation-defined + -- behavior for the parameter passed to the Empty function, + -- and here use the container Length function when available. + -- Class-wide objects are also excluded, since those would + -- lead to dispatching, which could call a user-defined + -- overriding of Length that might have arbitrary effects. + + elsif Is_Entity_Name (It) + and then Is_Object (Entity (It)) + and then Ekind (It_Subt) in Record_Kind + and then not Is_Class_Wide_Type (It_Subt) + then + declare + Aggr_Base : constant Entity_Id := Base_Type (Typ); + It_Base : constant Entity_Id := Base_Type (It_Subt); + Empty_Formal : constant Entity_Id := + First_Formal (Entity (Empty_Subp)); + Length_Subp : Entity_Id; + Param_List : List_Id; + + begin + -- We only determine a nondefault capacity in the case + -- of containers of predefined container types, which + -- generally have a Length function. User-defined + -- containers don't necessarily have such a function, + -- or it may be named differently, or it may have + -- the wrong semantics. The base subtypes are tested, + -- since their Sloc will refer to the original container + -- generics in the predefined library, even though the + -- types are declared in a package instantiation in some + -- other unit. Also, this is only done when Empty_Subp + -- has a formal parameter (generally named Capacity), + -- and not in the case of a parameterless Empty function. + -- Finally, we test for the container aggregate's type + -- having a first discriminant with the name Capacity, + -- since determining capacity via Length is only sensible + -- for container types with that discriminant (bounded + -- containers). + + if Present (Empty_Formal) + and then In_Predefined_Unit (It_Base) + and then In_Predefined_Unit (Aggr_Base) + and then Has_Discriminants (Aggr_Base) + and then + Get_Name_String + (Chars (First_Discriminant (Aggr_Base))) + = "capacity" + then + -- Look for the container type's Length function in + -- the package where it's defined. + + Push_Scope (Scope (It_Base)); + + Length_Subp := Current_Entity_In_Scope (Name_Length); + + Pop_Scope; + + -- If we found a Length function that has a single + -- parameter of the iterator object's container type, + -- then expand a call to that, passing the object, + -- and return that call, which will be used as the + -- "size" of the current element association of the + -- bounded container aggregate. + + if Present (Length_Subp) + and then Ekind (Length_Subp) = E_Function + and then + Present (First_Entity (Length_Subp)) + and then + No (Next_Entity (First_Entity (Length_Subp))) + and then + Base_Type + (Etype (First_Entity (Length_Subp))) = It_Base + then + Param_List := + New_List (New_Occurrence_Of (Entity (It), Loc)); + + return + Make_Function_Call (Loc, + Name => + New_Occurrence_Of (Length_Subp, Loc), + Parameter_Associations => Param_List); + end if; + end if; + end; end if; return Empty; @@ -6904,7 +7212,7 @@ package body Exp_Aggr is begin return UI_To_Int ((if Nkind (Expr) = N_Integer_Literal then Intval (Expr) - else Enumeration_Pos (Expr))); + else Enumeration_Pos (Entity (Expr)))); end To_Int; -- Local variables @@ -7362,7 +7670,7 @@ package body Exp_Aggr is -- Likewise if the aggregate is the qualified expression of an allocator -- but, in this case, we wait until after Expand_Allocator_Expression -- rewrites the allocator as the initialization expression of an object - -- declaration to have the left hand side. + -- declaration, so that we have the left-hand side. elsif Nkind (Par) = N_Allocator then if Nkind (Parent (Par)) = N_Object_Declaration @@ -7390,10 +7698,19 @@ package body Exp_Aggr is Set_Assignment_OK (Lhs); Aggr_Code := Build_Container_Aggr_Code (N, Typ, Lhs, Init); + + -- Use the unconstrained base subtype of the subtype provided by + -- the context for declaring the temporary object (which may come + -- from a constrained assignment target), to ensure that the + -- aggregate can be successfully expanded and assigned to the + -- temporary without exceeding its capacity. (Later assignment + -- of the temporary to a target object may result in failing + -- a discriminant check.) + Prepend_To (Aggr_Code, Make_Object_Declaration (Loc, Defining_Identifier => Obj_Id, - Object_Definition => New_Occurrence_Of (Typ, Loc), + Object_Definition => New_Occurrence_Of (Base_Type (Typ), Loc), Expression => Init)); Insert_Actions (N, Aggr_Code); @@ -7703,7 +8020,7 @@ package body Exp_Aggr is exception when RE_Not_Available => - return; + null; end Expand_N_Extension_Aggregate; ----------------------------- @@ -7971,7 +8288,8 @@ package body Exp_Aggr is Make_Selected_Component (Loc, Prefix => Unchecked_Convert_To (Typ, - Duplicate_Subexpr (Parent_Expr, True)), + Duplicate_Subexpr + (Parent_Expr, Name_Req => True)), Selector_Name => New_Occurrence_Of (Comp, Loc)); Append_To (Comps, @@ -8580,6 +8898,8 @@ package body Exp_Aggr is -- generated by Make_Tag_Ctrl_Assignment). But, in the case of an array -- aggregate, controlled subaggregates are not considered because each -- of their individual elements will receive an adjustment of its own. + -- Moreover, the result of a function call need not be adjusted if it + -- has already been adjusted in the called function. if Finalization_OK and then not Is_Inherently_Limited_Type (Comp_Typ) @@ -8588,6 +8908,8 @@ package body Exp_Aggr is and then Is_Array_Type (Comp_Typ) and then Needs_Finalization (Component_Type (Comp_Typ)) and then Nkind (Unqualify (Init_Expr)) = N_Aggregate) + and then not (Back_End_Return_Slot + and then Nkind (Init_Expr) = N_Function_Call) then Set_No_Finalize_Actions (Init_Stmt); @@ -8596,7 +8918,15 @@ package body Exp_Aggr is else Set_No_Ctrl_Actions (Init_Stmt); - if Tagged_Type_Expansion and then Is_Tagged_Type (Comp_Typ) then + if Tagged_Type_Expansion + and then Is_Tagged_Type (Comp_Typ) + + -- Cannot adjust the tag when the expected type of the component is + -- a mutably tagged (and therefore class-wide) type; each component + -- of the aggregate has the tag of its initializing expression. + + and then not Is_Mutably_Tagged_Type (Comp_Typ) + then declare Typ : Entity_Id := Underlying_Type (Comp_Typ); @@ -9314,6 +9644,24 @@ package body Exp_Aggr is return False; end Must_Slide; + --------------------------------- + -- Parent_Is_Regular_Aggregate -- + --------------------------------- + + function Parent_Is_Regular_Aggregate (Par : Node_Id) return Boolean is + begin + case Nkind (Par) is + when N_Component_Association => + return Parent_Is_Regular_Aggregate (Parent (Par)); + + when N_Extension_Aggregate | N_Aggregate => + return not Is_Container_Aggregate (Par); + + when others => + return False; + end case; + end Parent_Is_Regular_Aggregate; + --------------------- -- Sort_Case_Table -- --------------------- diff --git a/gcc/ada/exp_aggr.ads b/gcc/ada/exp_aggr.ads index c071e7604ad9..0da0d8fe8a8a 100644 --- a/gcc/ada/exp_aggr.ads +++ b/gcc/ada/exp_aggr.ads @@ -59,6 +59,10 @@ package Exp_Aggr is -- This is the case if it consists only of iterated component associations -- with iterator specifications, see RM 4.3.3(20.2/5). + function Parent_Is_Regular_Aggregate (Par : Node_Id) return Boolean; + -- Return True if Par is an aggregate that is not a container aggregate, or + -- a component association of such an aggregate. + function Static_Array_Aggregate (N : Node_Id) return Boolean; -- N is an array aggregate that may have a component association with -- an others clause and a range. If bounds are static and the expressions diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb index b896228a70e3..810248de1acd 100644 --- a/gcc/ada/exp_attr.adb +++ b/gcc/ada/exp_attr.adb @@ -24,6 +24,7 @@ ------------------------------------------------------------------------------ with Accessibility; use Accessibility; +with Aspects; use Aspects; with Atree; use Atree; with Checks; use Checks; with Debug; use Debug; @@ -88,8 +89,10 @@ package body Exp_Attr is function Attribute_Op_Hash (Id : Entity_Id) return Header_Num is (Header_Num (Id mod Map_Size)); - -- Cache used to avoid building duplicate subprograms for a single - -- type/streaming-attribute pair. + -- Caches used to avoid building duplicate subprograms for a single + -- type/attribute pair (where the attribute is either Put_Image or + -- one of the four streaming attributes). The type used as a key in + -- in accessing these maps should not be the entity of a subtype. package Read_Map is new GNAT.HTable.Simple_HTable (Header_Num => Header_Num, @@ -282,8 +285,8 @@ package body Exp_Attr is (In_Same_Extended_Unit (Subp_Unit, Attr_Ref_Unit) -- If subp declared in unit body, then we don't want to refer -- to it from within unit spec so return False in that case. - and then not (Body_Required (Attr_Ref_Unit) - and not Body_Required (Subp_Unit))); + and then not (not Is_Body (Unit (Attr_Ref_Unit)) + and Is_Body (Unit (Subp_Unit)))); -- Returns True if it is ok to refer to a cached subprogram declared in -- Subp_Unit from the point of an attribute reference occurring in -- Attr_Ref_Unit. Both arguments are usually N_Compilation_Nodes, @@ -1912,6 +1915,15 @@ package body Exp_Attr is -- call to the appropriate TSS procedure. Pname is the entity for the -- procedure to call. + procedure Read_Controlling_Tag + (P_Type : Entity_Id; Cntrl : out Node_Id); + -- Read the external tag from the stream and use it to construct the + -- controlling operand for a dispatching call. + + procedure Write_Controlling_Tag (P_Type : Entity_Id); + -- Write the external tag of the given attribute prefix type to + -- the stream. Also perform the accompanying accessibility check. + ------------------------------------- -- Build_And_Insert_Type_Attr_Subp -- ------------------------------------- @@ -2172,6 +2184,153 @@ package body Exp_Attr is Analyze (N); end Rewrite_Attribute_Proc_Call; + -------------------------- + -- Read_Controlling_Tag -- + -------------------------- + + procedure Read_Controlling_Tag + (P_Type : Entity_Id; Cntrl : out Node_Id) + is + Strm : constant Node_Id := First (Exprs); + Expr : Node_Id; -- call to Descendant_Tag + Get_Tag : Node_Id; -- expression to read the 'Tag + + begin + -- Read the internal tag (RM 13.13.2(34)) and use it to + -- initialize a dummy tag value. We used to unconditionally + -- generate: + -- + -- Descendant_Tag (String'Input (Strm), P_Type); + -- + -- which turns into a call to String_Input_Blk_IO. However, + -- if the input is malformed, that could try to read an + -- enormous String, causing chaos. So instead we call + -- String_Input_Tag, which does the same thing as + -- String_Input_Blk_IO, except that if the String is + -- absurdly long, it raises an exception. + -- + -- However, if the No_Stream_Optimizations restriction + -- is active, we disable this unnecessary attempt at + -- robustness; we really need to read the string + -- character-by-character. + -- + -- This value is used only to provide a controlling + -- argument for the eventual _Input call. Descendant_Tag is + -- called rather than Internal_Tag to ensure that we have a + -- tag for a type that is descended from the prefix type and + -- declared at the same accessibility level (the exception + -- Tag_Error will be raised otherwise). The level check is + -- required for Ada 2005 because tagged types can be + -- extended in nested scopes (AI-344). + + -- Note: we used to generate an explicit declaration of a + -- constant Ada.Tags.Tag object, and use an occurrence of + -- this constant in Cntrl, but this caused a secondary stack + -- leak. + + if Restriction_Active (No_Stream_Optimizations) then + Get_Tag := + Make_Attribute_Reference (Loc, + Prefix => + New_Occurrence_Of (Standard_String, Loc), + Attribute_Name => Name_Input, + Expressions => New_List ( + Relocate_Node (Duplicate_Subexpr (Strm)))); + else + Get_Tag := + Make_Function_Call (Loc, + Name => + New_Occurrence_Of + (RTE (RE_String_Input_Tag), Loc), + Parameter_Associations => New_List ( + Relocate_Node (Duplicate_Subexpr (Strm)))); + end if; + + Expr := + Make_Function_Call (Loc, + Name => + New_Occurrence_Of (RTE (RE_Descendant_Tag), Loc), + Parameter_Associations => New_List ( + Get_Tag, + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (P_Type, Loc), + Attribute_Name => Name_Tag))); + + Set_Etype (Expr, RTE (RE_Tag)); + + -- Construct a controlling operand for a dispatching call. + + Cntrl := Unchecked_Convert_To (P_Type, Expr); + Set_Etype (Cntrl, P_Type); + Set_Parent (Cntrl, N); + end Read_Controlling_Tag; + + ---------------------------- + -- Write_Controlling_Tag -- + ---------------------------- + + procedure Write_Controlling_Tag (P_Type : Entity_Id) is + Strm : constant Node_Id := First (Exprs); + Item : constant Node_Id := Next (Strm); + begin + -- Ada 2005 (AI-344): Check that the accessibility level + -- of the type of the output object is not deeper than + -- that of the attribute's prefix type. + + -- if Get_Access_Level (Item'Tag) + -- /= Get_Access_Level (P_Type'Tag) + -- then + -- raise Tag_Error; + -- end if; + + -- String'Output (Strm, External_Tag (Item'Tag)); + + -- We cannot figure out a practical way to implement this + -- accessibility check on virtual machines, so we omit it. + + if Ada_Version >= Ada_2005 + and then Tagged_Type_Expansion + then + Insert_Action (N, + Make_Implicit_If_Statement (N, + Condition => + Make_Op_Ne (Loc, + Left_Opnd => + Build_Get_Access_Level (Loc, + Make_Attribute_Reference (Loc, + Prefix => + Relocate_Node ( + Duplicate_Subexpr (Item, + Name_Req => True)), + Attribute_Name => Name_Tag)), + + Right_Opnd => + Make_Integer_Literal (Loc, + Type_Access_Level (P_Type))), + + Then_Statements => + New_List (Make_Raise_Statement (Loc, + New_Occurrence_Of ( + RTE (RE_Tag_Error), Loc))))); + end if; + + Insert_Action (N, + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Standard_String, Loc), + Attribute_Name => Name_Output, + Expressions => New_List ( + Relocate_Node (Duplicate_Subexpr (Strm)), + Make_Function_Call (Loc, + Name => + New_Occurrence_Of (RTE (RE_External_Tag), Loc), + Parameter_Associations => New_List ( + Make_Attribute_Reference (Loc, + Prefix => + Relocate_Node + (Duplicate_Subexpr (Item, Name_Req => True)), + Attribute_Name => Name_Tag)))))); + end Write_Controlling_Tag; + Typ : constant Entity_Id := Etype (N); Btyp : constant Entity_Id := Base_Type (Typ); Ptyp : constant Entity_Id := Etype (Pref); @@ -4484,94 +4643,57 @@ package body Exp_Attr is elsif Is_Class_Wide_Type (P_Type) then - -- No need to do anything else compiling under restriction - -- No_Dispatching_Calls. During the semantic analysis we - -- already notified such violation. + if Is_Mutably_Tagged_Type (P_Type) then - if Restriction_Active (No_Dispatching_Calls) then - return; - end if; + -- In mutably tagged case, rewrite + -- T'Class'Input (Strm) + -- as (roughly) + -- declare + -- Result : T'Class; + -- T'Class'Read (Strm, Result); + -- begin + -- Result; + -- end; - declare - Rtyp : constant Entity_Id := Root_Type (P_Type); + declare + Result_Temp : constant Entity_Id := + Make_Temporary (Loc, 'I'); - Expr : Node_Id; -- call to Descendant_Tag - Get_Tag : Node_Id; -- expression to read the 'Tag + -- Gets default initialization + Result_Temp_Decl : constant Node_Id := + Make_Object_Declaration (Loc, + Defining_Identifier => Result_Temp, + Object_Definition => + New_Occurrence_Of (P_Type, Loc)); - begin - -- Read the internal tag (RM 13.13.2(34)) and use it to - -- initialize a dummy tag value. We used to unconditionally - -- generate: - -- - -- Descendant_Tag (String'Input (Strm), P_Type); - -- - -- which turns into a call to String_Input_Blk_IO. However, - -- if the input is malformed, that could try to read an - -- enormous String, causing chaos. So instead we call - -- String_Input_Tag, which does the same thing as - -- String_Input_Blk_IO, except that if the String is - -- absurdly long, it raises an exception. - -- - -- However, if the No_Stream_Optimizations restriction - -- is active, we disable this unnecessary attempt at - -- robustness; we really need to read the string - -- character-by-character. - -- - -- This value is used only to provide a controlling - -- argument for the eventual _Input call. Descendant_Tag is - -- called rather than Internal_Tag to ensure that we have a - -- tag for a type that is descended from the prefix type and - -- declared at the same accessibility level (the exception - -- Tag_Error will be raised otherwise). The level check is - -- required for Ada 2005 because tagged types can be - -- extended in nested scopes (AI-344). - - -- Note: we used to generate an explicit declaration of a - -- constant Ada.Tags.Tag object, and use an occurrence of - -- this constant in Cntrl, but this caused a secondary stack - -- leak. - - if Restriction_Active (No_Stream_Optimizations) then - Get_Tag := - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Standard_String, Loc), - Attribute_Name => Name_Input, - Expressions => New_List ( - Relocate_Node (Duplicate_Subexpr (Strm)))); - else - Get_Tag := - Make_Function_Call (Loc, - Name => - New_Occurrence_Of - (RTE (RE_String_Input_Tag), Loc), - Parameter_Associations => New_List ( - Relocate_Node (Duplicate_Subexpr (Strm)))); - end if; + function Result_Temp_Name return Node_Id is + (New_Occurrence_Of (Result_Temp, Loc)); - Expr := - Make_Function_Call (Loc, - Name => - New_Occurrence_Of (RTE (RE_Descendant_Tag), Loc), - Parameter_Associations => New_List ( - Get_Tag, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (P_Type, Loc), - Attribute_Name => Name_Tag))); + Actions : constant List_Id := New_List ( + Result_Temp_Decl, + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (P_Type, Loc), + Attribute_Name => Name_Read, + Expressions => New_List ( + Relocate_Node (Strm), Result_Temp_Name))); + begin + Rewrite (N, Make_Expression_With_Actions (Loc, + Actions, Result_Temp_Name)); + Analyze_And_Resolve (N, P_Type); + return; + end; + end if; - Set_Etype (Expr, RTE (RE_Tag)); + -- No need to do anything else compiling under restriction + -- No_Dispatching_Calls. During the semantic analysis we + -- already notified such violation. - -- Now we need to get the entity for the call, and construct - -- a function call node, where we preset a reference to Dnn - -- as the controlling argument (doing an unchecked convert - -- to the class-wide tagged type to make it look like a real - -- tagged object). + if Restriction_Active (No_Dispatching_Calls) then + return; + end if; - Fname := Find_Prim_Op (Rtyp, TSS_Stream_Input); - Cntrl := Unchecked_Convert_To (P_Type, Expr); - Set_Etype (Cntrl, P_Type); - Set_Parent (Cntrl, N); - end; + Read_Controlling_Tag (P_Type, Cntrl); + Fname := Find_Prim_Op (Root_Type (P_Type), TSS_Stream_Input); -- For tagged types, use the primitive Input function @@ -4669,7 +4791,7 @@ package body Exp_Attr is end if; if not Is_Tagged_Type (P_Type) then - Cached_Attribute_Ops.Input_Map.Set (P_Type, Fname); + Cached_Attribute_Ops.Input_Map.Set (U_Type, Fname); end if; end Input; @@ -4983,6 +5105,316 @@ package body Exp_Attr is Analyze_And_Resolve (N, Typ); + ---------- + -- Make -- + ---------- + + when Attribute_Make => + declare + Params : List_Id; + Param : Node_Id; + Par : Node_Id; + Construct : Entity_Id; + Obj : Node_Id := Empty; + Make_Expr : Node_Id := N; + + Formal : Entity_Id; + Replace_Expr : Node_Id; + Init_Param : Node_Id; + Construct_Call : Node_Id; + Curr_Nam : Node_Id := Empty; + + function Replace_Formal_Ref + (N : Node_Id) return Traverse_Result; + + function Replace_Formal_Ref + (N : Node_Id) return Traverse_Result is + begin + if Is_Entity_Name (N) + and then Chars (Formal) = Chars (N) + then + Rewrite (N, + New_Copy_Tree (Replace_Expr)); + end if; + + return OK; + end Replace_Formal_Ref; + + procedure Search_And_Replace_Formal is new + Traverse_Proc (Replace_Formal_Ref); + + begin + -- Remove side effects for constructor call + + Param := First (Expressions (N)); + while Present (Param) loop + if Nkind (Param) = N_Parameter_Association then + Remove_Side_Effects (Explicit_Actual_Parameter (Param), + Check_Side_Effects => False); + else + Remove_Side_Effects (Param, Check_Side_Effects => False); + end if; + + Next (Param); + end loop; + + -- Construct the parameters list + + Params := New_Copy_List (Expressions (N)); + if Is_Empty_List (Params) then + Params := New_List; + end if; + + -- Identify the enclosing parent for the non-copy cases + + Par := Parent (N); + if Nkind (Par) = N_Qualified_Expression then + Par := Parent (Par); + Make_Expr := Par; + end if; + if Nkind (Par) = N_Allocator then + Par := Parent (Par); + Curr_Nam := Make_Explicit_Dereference + (Loc, Prefix => Empty); + Obj := Curr_Nam; + end if; + + declare + Base_Obj : Node_Id := Empty; + Typ_Comp : Entity_Id; + Agg_Comp : Entity_Id; + Comp_Nam : Node_Id := Empty; + begin + while Nkind (Par) not in N_Object_Declaration + | N_Assignment_Statement + loop + if Nkind (Par) = N_Aggregate then + Typ_Comp := First_Entity (Etype (Par)); + Agg_Comp := First (Expressions (Par)); + loop + if No (Agg_Comp) then + return; + end if; + + if Agg_Comp = Make_Expr then + Comp_Nam := + Make_Selected_Component (Loc, + Prefix => Empty, + Selector_Name => + New_Occurrence_Of (Typ_Comp, Loc)); + + Make_Expr := Parent (Make_Expr); + Par := Parent (Par); + exit; + end if; + + Next_Entity (Typ_Comp); + Next (Agg_Comp); + end loop; + elsif Nkind (Par) = N_Component_Association then + Comp_Nam := + Make_Selected_Component (Loc, + Prefix => Empty, + Selector_Name => + Make_Identifier (Loc, + (Chars (First (Choices (Par)))))); + + Make_Expr := Parent (Parent (Make_Expr)); + Par := Parent (Parent (Par)); + else + declare + Temp : constant Entity_Id := + Make_Temporary (Loc, 'T', N); + begin + Rewrite (N, + Make_Expression_With_Actions (Loc, + Actions => New_List ( + Make_Object_Declaration (Loc, + Defining_Identifier => Temp, + Object_Definition => + New_Occurrence_Of (Typ, Loc), + Expression => + New_Copy_Tree (N))), + Expression => New_Occurrence_Of (Temp, Loc))); + Analyze_And_Resolve (N); + return; + end; + end if; + + if No (Curr_Nam) then + Curr_Nam := Comp_Nam; + Obj := Curr_Nam; + elsif Has_Prefix (Curr_Nam) then + Set_Prefix (Curr_Nam, Comp_Nam); + Curr_Nam := Comp_Nam; + end if; + end loop; + + Base_Obj := (case Nkind (Par) is + when N_Assignment_Statement => + New_Copy_Tree (Name (Par)), + when N_Object_Declaration => + New_Occurrence_Of + (Defining_Identifier (Par), Loc), + when others => (raise Program_Error)); + + if Present (Curr_Nam) then + Set_Prefix (Curr_Nam, Base_Obj); + else + Obj := Base_Obj; + end if; + end; + + Prepend_To (Params, Obj); + + -- Find the constructor we are interested in by doing a + -- pseudo-pass to resolve the constructor call. + + declare + Dummy_Params : List_Id := New_Copy_List (Expressions (N)); + Dummy_Self : Node_Id; + Dummy_Block : Node_Id; + Dummy_Call : Node_Id; + Dummy_Id : Entity_Id := Make_Temporary (Loc, 'D', N); + begin + if Is_Empty_List (Dummy_Params) then + Dummy_Params := New_List; + end if; + + Dummy_Self := Make_Object_Declaration (Loc, + Defining_Identifier => Dummy_Id, + Object_Definition => + New_Occurrence_Of (Typ, Loc)); + Prepend_To (Dummy_Params, New_Occurrence_Of (Dummy_Id, Loc)); + + Dummy_Call := Make_Procedure_Call_Statement (Loc, + Parameter_Associations => Dummy_Params, + Name => + (if not Has_Prefix (Pref) then + Make_Identifier (Loc, + Chars (Constructor_Name (Typ))) + else + Make_Expanded_Name (Loc, + Chars => + Chars (Constructor_Name (Typ)), + Prefix => + New_Copy_Tree (Prefix (Pref)), + Selector_Name => + Make_Identifier (Loc, + Chars (Constructor_Name (Typ)))))); + Set_Is_Expanded_Constructor_Call (Dummy_Call, True); + + Dummy_Block := Make_Block_Statement (Loc, + Declarations => New_List (Dummy_Self), + Handled_Statement_Sequence => + Make_Handled_Sequence_Of_Statements (Loc, + Statements => New_List (Dummy_Call))); + + Expander_Active := False; + + Insert_After_And_Analyze + (Enclosing_Declaration_Or_Statement (Par), Dummy_Block); + + Expander_Active := True; + + -- Finally, we can get the constructor based on our pseudo-pass + + Construct := Entity (Name (Dummy_Call)); + + -- Replace the Typ'Make attribute with an aggregate featuring + -- then relevant aggregate from the correct constructor's + -- Inializeaspect if it is present - otherwise, simply use a + -- box. + + if Has_Aspect (Construct, Aspect_Initialize) then + Rewrite (N, + New_Copy_Tree + (Find_Value_Of_Aspect (Construct, Aspect_Initialize))); + + Param := Next (First (Params)); + Formal := Next_Entity (First_Entity (Construct)); + while Present (Param) loop + if Nkind (Param) = N_Parameter_Association then + Formal := Selector_Name (Param); + Replace_Expr := Explicit_Actual_Parameter (Param); + else + Replace_Expr := Param; + end if; + + Init_Param := First (Component_Associations (N)); + while Present (Init_Param) loop + Search_And_Replace_Formal (Expression (Init_Param)); + + Next (Init_Param); + end loop; + + if Nkind (Param) /= N_Parameter_Association then + Next_Entity (Formal); + end if; + Next (Param); + end loop; + + Init_Param := First (Component_Associations (N)); + while Present (Init_Param) loop + if Nkind (Expression (Init_Param)) = N_Attribute_Reference + and then Attribute_Name + (Expression (Init_Param)) = Name_Make + then + Insert_After (Par, + Make_Assignment_Statement (Loc, + Name => + Make_Selected_Component (Loc, + Prefix => + New_Copy_Tree (First (Params)), + Selector_Name => + Make_Identifier (Loc, + Chars (First (Choices (Init_Param))))), + Expression => + New_Copy_Tree (Expression (Init_Param)))); + + Rewrite (Expression (Init_Param), + Make_Aggregate (Loc, + Expressions => New_List, + Component_Associations => New_List ( + Make_Component_Association (Loc, + Choices => + New_List (Make_Others_Choice (Loc)), + Expression => Empty, + Box_Present => True)))); + end if; + + Next (Init_Param); + end loop; + else + Rewrite (N, + Make_Aggregate (Loc, + Expressions => New_List, + Component_Associations => New_List ( + Make_Component_Association (Loc, + Choices => New_List (Make_Others_Choice (Loc)), + Expression => Empty, + Box_Present => True)))); + end if; + + -- Rewrite this block to be null and pretend it didn't happen + + Rewrite (Dummy_Block, Make_Null_Statement (Loc)); + end; + + Analyze_And_Resolve (N, Typ); + + -- Finally, insert the constructor call + + Construct_Call := + Make_Procedure_Call_Statement (Loc, + Name => + New_Occurrence_Of (Construct, Loc), + Parameter_Associations => Params); + + Set_Is_Expanded_Constructor_Call (Construct_Call); + Insert_After (Par, Construct_Call); + end; + -------------- -- Mantissa -- -------------- @@ -5040,22 +5472,42 @@ package body Exp_Attr is Typ : constant Entity_Id := Etype (N); begin - -- If the prefix is X'Class, we transform it into a direct reference - -- to the class-wide type, because the back end must not see a 'Class - -- reference. See also 'Size. + -- Tranform T'Class'Max_Size_In_Storage_Elements (for any T) into + -- Storage_Count'Pos (Storage_Count'Last), because it must include + -- all descendants, which can be arbitrarily large. Note that the + -- back end must not see any 'Class attribute references. + -- The 'Pos is to make it be of type universal_integer. + -- + -- ???If T'Class'Size is specified, it should probably affect + -- T'Class'Max_Size_In_Storage_Elements accordingly. if Is_Entity_Name (Pref) and then Is_Class_Wide_Type (Entity (Pref)) then - Rewrite (Prefix (N), New_Occurrence_Of (Entity (Pref), Loc)); - return; - end if; + declare + Storage_Count_Type : constant Entity_Id := + RTE (RE_Storage_Count); + Attr : constant Node_Id := + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Storage_Count_Type, Loc), + Attribute_Name => Name_Pos, + Expressions => New_List ( + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Storage_Count_Type, Loc), + Attribute_Name => Name_Last))); + begin + Rewrite (N, Attr); + Analyze_And_Resolve (N, Typ); + return; + end; -- Heap-allocated controlled objects contain two extra pointers which -- are not part of the actual type. Transform the attribute reference -- into a runtime expression to add the size of the hidden header. - if Needs_Finalization (Ptyp) and then not Header_Size_Added (N) then + elsif Needs_Finalization (Ptyp) + and then not Header_Size_Added (N) + then Set_Header_Size_Added (N); -- Generate: @@ -5624,6 +6076,14 @@ package body Exp_Attr is Attr_Ref => N); end; + -- In the mutably tagged case, T'Class'Output calls T'Class'Write; + -- T'Write will take care of writing out the external tag. + + elsif Is_Mutably_Tagged_Type (P_Type) then + Set_Attribute_Name (N, Name_Write); + Analyze (N); + return; + -- Class-wide case, first output external tag, then dispatch -- to the appropriate primitive Output function (RM 13.13.2(31)). @@ -5637,68 +6097,7 @@ package body Exp_Attr is return; end if; - Tag_Write : declare - Strm : constant Node_Id := First (Exprs); - Item : constant Node_Id := Next (Strm); - - begin - -- Ada 2005 (AI-344): Check that the accessibility level - -- of the type of the output object is not deeper than - -- that of the attribute's prefix type. - - -- if Get_Access_Level (Item'Tag) - -- /= Get_Access_Level (P_Type'Tag) - -- then - -- raise Tag_Error; - -- end if; - - -- String'Output (Strm, External_Tag (Item'Tag)); - - -- We cannot figure out a practical way to implement this - -- accessibility check on virtual machines, so we omit it. - - if Ada_Version >= Ada_2005 - and then Tagged_Type_Expansion - then - Insert_Action (N, - Make_Implicit_If_Statement (N, - Condition => - Make_Op_Ne (Loc, - Left_Opnd => - Build_Get_Access_Level (Loc, - Make_Attribute_Reference (Loc, - Prefix => - Relocate_Node ( - Duplicate_Subexpr (Item, - Name_Req => True)), - Attribute_Name => Name_Tag)), - - Right_Opnd => - Make_Integer_Literal (Loc, - Type_Access_Level (P_Type))), - - Then_Statements => - New_List (Make_Raise_Statement (Loc, - New_Occurrence_Of ( - RTE (RE_Tag_Error), Loc))))); - end if; - - Insert_Action (N, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Standard_String, Loc), - Attribute_Name => Name_Output, - Expressions => New_List ( - Relocate_Node (Duplicate_Subexpr (Strm)), - Make_Function_Call (Loc, - Name => - New_Occurrence_Of (RTE (RE_External_Tag), Loc), - Parameter_Associations => New_List ( - Make_Attribute_Reference (Loc, - Prefix => - Relocate_Node - (Duplicate_Subexpr (Item, Name_Req => True)), - Attribute_Name => Name_Tag)))))); - end Tag_Write; + Write_Controlling_Tag (P_Type); Pname := Find_Prim_Op (U_Type, TSS_Stream_Output); @@ -5750,7 +6149,7 @@ package body Exp_Attr is Rewrite_Attribute_Proc_Call (Pname); if not Is_Tagged_Type (P_Type) then - Cached_Attribute_Ops.Output_Map.Set (P_Type, Pname); + Cached_Attribute_Ops.Output_Map.Set (U_Type, Pname); end if; end Output; @@ -6460,6 +6859,7 @@ package body Exp_Attr is P_Type : constant Entity_Id := Entity (Pref); B_Type : constant Entity_Id := Base_Type (P_Type); U_Type : constant Entity_Id := Underlying_Type (P_Type); + Cntrl : Node_Id := Empty; -- nonempty only if P_Type mutably tagged Pname : Entity_Id; Decl : Node_Id; Prag : Node_Id; @@ -6608,6 +7008,11 @@ package body Exp_Attr is -- this will dispatch in the class-wide case which is what we want elsif Is_Tagged_Type (U_Type) then + + if Is_Mutably_Tagged_Type (U_Type) then + Read_Controlling_Tag (P_Type, Cntrl); + end if; + Pname := Find_Prim_Op (U_Type, TSS_Stream_Read); -- All other record type cases, including protected records. The @@ -6668,8 +7073,48 @@ package body Exp_Attr is Rewrite_Attribute_Proc_Call (Pname); + if Present (Cntrl) then + pragma Assert (Is_Mutably_Tagged_Type (U_Type)); + pragma Assert (Nkind (N) = N_Procedure_Call_Statement); + + -- Assign the Tag value that was read from the stream + -- to the tag of the out-mode actual parameter so that + -- we dispatch correctly. This isn't quite right. + -- We should assign a complete object (not just + -- the tag), but that would require a dispatching call to + -- perform default initialization of the source object and + -- dispatching default init calls are currently not supported. + + declare + function Select_Tag (Prefix : Node_Id) return Node_Id is + (Make_Selected_Component (Loc, + Prefix => Prefix, + Selector_Name => + New_Occurrence_Of (First_Tag_Component + (Etype (Prefix)), Loc))); + + Controlling_Actual : constant Node_Id := + Next (First (Parameter_Associations (N))); + + pragma Assert (Is_Controlling_Actual (Controlling_Actual)); + + Assign_Tag : Node_Id; + begin + Remove_Side_Effects (Controlling_Actual, Name_Req => True); + + Assign_Tag := + Make_Assignment_Statement (Loc, + Name => + Select_Tag (New_Copy_Tree (Controlling_Actual)), + Expression => Select_Tag (Cntrl)); + + Insert_Before (Before => N, Node => Assign_Tag); + Analyze (Assign_Tag); + end; + end if; + if not Is_Tagged_Type (P_Type) then - Cached_Attribute_Ops.Read_Map.Set (P_Type, Pname); + Cached_Attribute_Ops.Read_Map.Set (U_Type, Pname); end if; end Read; @@ -7870,9 +8315,8 @@ package body Exp_Attr is else declare Uns : constant Boolean := - Is_Unsigned_Type (Ptyp) - or else (Is_Private_Type (Ptyp) - and then Is_Unsigned_Type (PBtyp)); + Is_Unsigned_Type (Validated_View (Ptyp)); + Size : Uint; P : Node_Id := Pref; @@ -8279,6 +8723,14 @@ package body Exp_Attr is -- this will dispatch in the class-wide case which is what we want elsif Is_Tagged_Type (U_Type) then + + -- If T'Class is mutably tagged, then the external tag + -- is written out by T'Class'Write, not by T'Class'Output. + + if Is_Mutably_Tagged_Type (U_Type) then + Write_Controlling_Tag (P_Type); + end if; + Pname := Find_Prim_Op (U_Type, TSS_Stream_Write); -- All other record type cases, including protected records. @@ -8349,7 +8801,7 @@ package body Exp_Attr is Rewrite_Attribute_Proc_Call (Pname); if not Is_Tagged_Type (P_Type) then - Cached_Attribute_Ops.Write_Map.Set (P_Type, Pname); + Cached_Attribute_Ops.Write_Map.Set (U_Type, Pname); end if; end Write; @@ -8444,7 +8896,7 @@ package body Exp_Attr is exception when RE_Not_Available => - return; + null; end Expand_N_Attribute_Reference; -------------------------------- @@ -8600,10 +9052,10 @@ package body Exp_Attr is Rewrite (N, Make_Op_Multiply (Loc, Make_Attribute_Reference (Loc, - Prefix => Duplicate_Subexpr (Pref, True), + Prefix => Duplicate_Subexpr (Pref, Name_Req => True), Attribute_Name => Name_Length), Make_Attribute_Reference (Loc, - Prefix => Duplicate_Subexpr (Pref, True), + Prefix => Duplicate_Subexpr (Pref, Name_Req => True), Attribute_Name => Name_Component_Size))); Analyze_And_Resolve (N, Typ); end if; @@ -8951,15 +9403,22 @@ package body Exp_Attr is return Empty; end if; - if Nam = TSS_Stream_Read then - Ent := Cached_Attribute_Ops.Read_Map.Get (Typ); - elsif Nam = TSS_Stream_Write then - Ent := Cached_Attribute_Ops.Write_Map.Get (Typ); - elsif Nam = TSS_Stream_Input then - Ent := Cached_Attribute_Ops.Input_Map.Get (Typ); - elsif Nam = TSS_Stream_Output then - Ent := Cached_Attribute_Ops.Output_Map.Get (Typ); - end if; + declare + function U_Base return Entity_Id is + (Underlying_Type (Base_Type (Typ))); + -- Return the right type node for use in a C_A_O map lookup. + -- In particular, we do not want the entity for a subtype. + begin + if Nam = TSS_Stream_Read then + Ent := Cached_Attribute_Ops.Read_Map.Get (U_Base); + elsif Nam = TSS_Stream_Write then + Ent := Cached_Attribute_Ops.Write_Map.Get (U_Base); + elsif Nam = TSS_Stream_Input then + Ent := Cached_Attribute_Ops.Input_Map.Get (U_Base); + elsif Nam = TSS_Stream_Output then + Ent := Cached_Attribute_Ops.Output_Map.Get (U_Base); + end if; + end; Cached_Attribute_Ops.Validate_Cached_Candidate (Subp => Ent, Attr_Ref => Attr_Ref); diff --git a/gcc/ada/exp_ch11.adb b/gcc/ada/exp_ch11.adb index a0dbcad83306..ee6010a74445 100644 --- a/gcc/ada/exp_ch11.adb +++ b/gcc/ada/exp_ch11.adb @@ -1194,8 +1194,6 @@ package body Exp_Ch11 is Prefix => New_Occurrence_Of (Id, Loc), Attribute_Name => Name_Unrestricted_Access))))); - Set_Register_Exception_Call (Id, First (L)); - if not Is_Library_Level_Entity (Id) then Flag_Id := Make_Defining_Identifier (Loc, @@ -1972,6 +1970,8 @@ package body Exp_Ch11 is when CE_Tag_Check_Failed => Add_Str_To_Name_Buffer ("CE_Tag_Check"); + when PE_Abstract_Type_Component => + Add_Str_To_Name_Buffer ("PE_Abstract_Type_Component"); when PE_Access_Before_Elaboration => Add_Str_To_Name_Buffer ("PE_Access_Before_Elaboration"); when PE_Accessibility_Check_Failed => diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb index bc46fd37e0c6..5bb4a25a715a 100644 --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -69,6 +69,7 @@ with Sem_Res; use Sem_Res; with Sem_SCIL; use Sem_SCIL; with Sem_Type; use Sem_Type; with Sem_Util; use Sem_Util; +with Sem_Warn; use Sem_Warn; with Sinfo; use Sinfo; with Sinfo.Nodes; use Sinfo.Nodes; with Sinfo.Utils; use Sinfo.Utils; @@ -77,6 +78,7 @@ with Snames; use Snames; with Tbuild; use Tbuild; with Ttypes; use Ttypes; with Validsw; use Validsw; +with Warnsw; use Warnsw; package body Exp_Ch3 is @@ -340,9 +342,9 @@ package body Exp_Ch3 is -- typSO provides result of 'Output attribute -- typPI provides result of 'Put_Image attribute -- - -- The following entries are additionally present for non-limited tagged - -- types, and implement additional dispatching operations for predefined - -- operations: + -- The following entries implement additional dispatching operations for + -- predefined operations. Deep finalization is present on all tagged types; + -- the others only on nonlimited tagged types: -- -- _equality implements "=" operator -- _assign implements assignment operation @@ -399,7 +401,7 @@ package body Exp_Ch3 is (Tag_Typ : Entity_Id; Renamed_Eq : Entity_Id) return List_Id; -- Create the bodies of the predefined primitives that are described in - -- Predefined_Primitive_Specs. When not empty, Renamed_Eq must denote + -- Make_Predefined_Primitive_Specs. When not empty, Renamed_Eq must denote -- the defining unit name of the type's predefined equality as returned -- by Make_Predefined_Primitive_Specs. @@ -671,7 +673,8 @@ package body Exp_Ch3 is -------------------- function Init_Component return List_Id is - Comp : Node_Id; + Comp : Node_Id; + Result : List_Id; begin Comp := @@ -681,7 +684,7 @@ package body Exp_Ch3 is if Has_Default_Aspect (A_Type) then Set_Assignment_OK (Comp); - return New_List ( + Result := New_List ( Make_Assignment_Statement (Loc, Name => Comp, Expression => @@ -690,7 +693,7 @@ package body Exp_Ch3 is elsif Comp_Simple_Init then Set_Assignment_OK (Comp); - return New_List ( + Result := New_List ( Make_Assignment_Statement (Loc, Name => Comp, Expression => @@ -701,7 +704,7 @@ package body Exp_Ch3 is else Clean_Task_Names (Comp_Type, Proc_Id); - return + Result := Build_Initialization_Call (N => Nod, Id_Ref => Comp, @@ -709,6 +712,19 @@ package body Exp_Ch3 is In_Init_Proc => True, Enclos_Type => A_Type); end if; + + -- Raise Program_Error in the init procedure of arrays when the type + -- of their components is a mutably tagged abstract class-wide type. + + if Is_Class_Wide_Equivalent_Type (Component_Type (A_Type)) + and then Is_Abstract_Type (Comp_Type) + then + Append_To (Result, + Make_Raise_Program_Error (Loc, + Reason => PE_Abstract_Type_Component)); + end if; + + return Result; end Init_Component; ------------------------ @@ -926,10 +942,11 @@ package body Exp_Ch3 is Make_Handled_Sequence_Of_Statements (Loc, Statements => Body_Stmts))); - Mutate_Ekind (Proc_Id, E_Procedure); - Set_Is_Public (Proc_Id, Is_Public (A_Type)); - Set_Is_Internal (Proc_Id); - Set_Has_Completion (Proc_Id); + Mutate_Ekind (Proc_Id, E_Procedure); + Set_Is_Public (Proc_Id, Is_Public (A_Type)); + Set_Is_Internal (Proc_Id); + Set_Has_Completion (Proc_Id); + Freeze_Extra_Formals (Proc_Id); if not Debug_Generated_Code then Set_Debug_Info_Off (Proc_Id); @@ -2652,11 +2669,9 @@ package body Exp_Ch3 is -- may have an incomplete type. In that case, it must also be -- replaced by the formal of the Init_Proc. - if Nkind (Parent (Rec_Type)) = N_Full_Type_Declaration - and then Present (Incomplete_View (Parent (Rec_Type))) - then + if Present (Incomplete_View (Rec_Type)) then Append_Elmt ( - N => Incomplete_View (Parent (Rec_Type)), + N => Incomplete_View (Rec_Type), To => Map); Append_Elmt ( N => Defining_Identifier @@ -2677,9 +2692,10 @@ package body Exp_Ch3 is Exp_Q := Unqualify (Exp); - -- Adjust the component if controlled, except if it is an aggregate - -- that will be expanded inline (but note that the case of container - -- aggregates does require component adjustment), or a function call. + -- Adjust the component if controlled, except if the expression is an + -- aggregate that will be expanded inline (but note that the case of + -- container aggregates does require component adjustment), or else + -- a function call whose result is adjusted in the called function. -- Note that, when we don't inhibit component adjustment, the tag -- will be automatically inserted by Make_Tag_Ctrl_Assignment in the -- tagged case. Otherwise, we have to generate a tag assignment here. @@ -2688,7 +2704,8 @@ package body Exp_Ch3 is and then (Nkind (Exp_Q) not in N_Aggregate | N_Extension_Aggregate or else Is_Container_Aggregate (Exp_Q)) and then not Is_Build_In_Place_Function_Call (Exp) - and then Nkind (Exp) /= N_Function_Call + and then not (Back_End_Return_Slot + and then Nkind (Exp) = N_Function_Call) then Set_No_Finalize_Actions (First (Res)); @@ -3188,6 +3205,7 @@ package body Exp_Ch3 is end if; Set_Parameter_Specifications (Proc_Spec_Node, Parameters); + Freeze_Extra_Formals (Proc_Id); Set_Specification (Body_Node, Proc_Spec_Node); Set_Declarations (Body_Node, Decls); @@ -3325,6 +3343,17 @@ package body Exp_Ch3 is Make_Tag_Assignment_From_Type (Loc, Make_Identifier (Loc, Name_uInit), Rec_Type)); + -- Ensure that Program_Error is raised if a mutably class-wide + -- abstract tagged type is initialized by default. + + if Is_Abstract_Type (Rec_Type) + and then Is_Mutably_Tagged_Type (Class_Wide_Type (Rec_Type)) + then + Append_To (Init_Tags_List, + Make_Raise_Program_Error (Loc, + Reason => PE_Abstract_Type_Component)); + end if; + -- Ada 2005 (AI-251): Initialize the secondary tags components -- located at fixed positions (tags whose position depends on -- variable size components are initialized later ---see below) @@ -3746,6 +3775,16 @@ package body Exp_Ch3 is -- Explicit initialization if Present (Expression (Decl)) then + + -- Ensure that the type of the expression initializing a + -- mutably tagged class-wide type component is frozen. + + if Nkind (Expression (Decl)) = N_Qualified_Expression + and then Is_Class_Wide_Equivalent_Type (Etype (Id)) + then + Freeze_Before (N, Etype (Expression (Decl))); + end if; + if Is_CPP_Constructor_Call (Expression (Decl)) then Actions := Build_Initialization_Call @@ -3765,6 +3804,21 @@ package body Exp_Ch3 is Actions := Build_Assignment (Id, Expression (Decl)); end if; + -- Expand components with constructors to have the 'Make + -- attribute. + + elsif Present (Constructor_Name (Typ)) + and then Present (Default_Constructor (Typ)) + then + Set_Expression (Decl, + Make_Attribute_Reference (Loc, + Attribute_Name => Name_Make, + Prefix => + Subtype_Indication + (Component_Definition (Decl)))); + Analyze (Expression (Decl)); + Actions := Build_Assignment (Id, Expression (Decl)); + -- CPU, Dispatching_Domain, Priority, and Secondary_Stack_Size -- components are filled in with the corresponding rep-item -- expression of the concurrent type (if any). @@ -3902,6 +3956,15 @@ package body Exp_Ch3 is Discr_Map => Discr_Map, Init_Control_Actual => Init_Control_Actual); + if Is_Mutably_Tagged_CW_Equivalent_Type (Etype (Id)) + and then not Is_Parent + and then Is_Abstract_Type (Typ) + then + Append_To (Init_Call_Stmts, + Make_Raise_Program_Error (Comp_Loc, + Reason => PE_Abstract_Type_Component)); + end if; + if Is_Parent then -- This is tricky. At first it looks like -- we are going to end up with nested @@ -4522,6 +4585,11 @@ package body Exp_Ch3 is if Present (Expression (Comp_Decl)) or else Has_Non_Null_Base_Init_Proc (Typ) or else Component_Needs_Simple_Initialization (Typ) + + -- Mutably tagged class-wide types require the init-proc since + -- it takes care of their default initialization. + + or else Is_Mutably_Tagged_CW_Equivalent_Type (Typ) then return True; end if; @@ -5093,6 +5161,32 @@ package body Exp_Ch3 is if Is_Library_Level_Entity (Typ) then Set_Is_Public (Op); end if; + + -- Otherwise, the result is defined in terms of the primitive equals + -- operator (RM 4.5.2 (24/3)). Report a warning if some component of + -- the untagged record has defined a user-defined "=", because it can + -- be surprising that the predefined "=" takes precedence over it. + -- This warning is not reported when Build_Eq is True because the + -- expansion of the built body will call Expand_Composite_Equality + -- that will report it if necessary. + + elsif Warn_On_Ignored_Equality then + Comp := First_Component (Typ); + + while Present (Comp) loop + if Present (User_Defined_Eq (Etype (Comp))) + and then not Is_Record_Type (Etype (Comp)) + and then not Is_Intrinsic_Subprogram + (User_Defined_Eq (Etype (Comp))) + then + Warn_On_Ignored_Equality_Operator + (Typ => Typ, + Comp_Typ => Etype (Comp), + Loc => Sloc (User_Defined_Eq (Etype (Comp)))); + end if; + + Next_Component (Comp); + end loop; end if; end Build_Untagged_Record_Equality; @@ -5423,18 +5517,12 @@ package body Exp_Ch3 is -- with an initial value, its Init_Proc will never be called. The -- initial value itself may have been expanded into assignments, -- in which case the declaration has the No_Initialization flag. - -- The exception is when the initial value is a 2-pass aggregate, - -- because the special expansion used for it creates a temporary - -- that needs a fully-fledged initialization. if Is_Itype (Base) and then Nkind (Associated_Node_For_Itype (Base)) = N_Object_Declaration and then - ((Present (Expression (Associated_Node_For_Itype (Base))) - and then not - Is_Two_Pass_Aggregate - (Expression (Associated_Node_For_Itype (Base)))) + (Present (Expression (Associated_Node_For_Itype (Base))) or else No_Initialization (Associated_Node_For_Itype (Base))) then null; @@ -5870,7 +5958,7 @@ package body Exp_Ch3 is exception when RE_Not_Available => - return; + null; end Expand_Freeze_Enumeration_Type; ------------------------------- @@ -6410,7 +6498,7 @@ package body Exp_Ch3 is end; end if; - if Has_Controlled_Component (Typ) then + if Has_Controlled_Component (Typ) or else Has_Destructor (Typ) then Build_Controlling_Procs (Typ); end if; @@ -6484,17 +6572,16 @@ package body Exp_Ch3 is -- procedure, because a self-referential type might call one of these -- primitives in the body of the init_proc itself. -- - -- This is not needed: - -- 1) If expansion is disabled, because extra formals are only added - -- when we are generating code. + -- This is not needed when expansion is disabled, because extra formals + -- are only added when we are generating code. -- - -- 2) For types with foreign convention since primitives with foreign - -- convention don't have extra formals and AI95-117 requires that - -- all primitives of a tagged type inherit the convention. + -- Notice that for tagged types with foreign convention this is also + -- required because (although primitives with foreign convention don't + -- have extra formals), a tagged type with foreign convention may have + -- primitives with convention Ada. if Expander_Active and then Is_Tagged_Type (Typ) - and then not Has_Foreign_Convention (Typ) then declare Elmt : Elmt_Id; @@ -6760,12 +6847,13 @@ package body Exp_Ch3 is procedure Expand_N_Object_Declaration (N : Node_Id) is Loc : constant Source_Ptr := Sloc (N); Def_Id : constant Entity_Id := Defining_Identifier (N); - Expr : constant Node_Id := Expression (N); Obj_Def : constant Node_Id := Object_Definition (N); Typ : constant Entity_Id := Etype (Def_Id); Base_Typ : constant Entity_Id := Base_Type (Typ); Next_N : constant Node_Id := Next (N); + Expr : Node_Id := Expression (N); + Special_Ret_Obj : constant Boolean := Is_Special_Return_Object (Def_Id); -- If this is a special return object, it will be allocated differently -- and ultimately rewritten as a renaming, so initialization activities @@ -6821,8 +6909,8 @@ package body Exp_Ch3 is procedure Count_Default_Sized_Task_Stacks (Typ : Entity_Id; - Pri_Stacks : out Int; - Sec_Stacks : out Int); + Pri_Stacks : out Nat; + Sec_Stacks : out Nat); -- Count the number of default-sized primary and secondary task stacks -- required for task objects contained within type Typ. If the number of -- task objects contained within the type is not known at compile time @@ -6894,7 +6982,9 @@ package body Exp_Ch3 is -- Processing for objects that require finalization actions - if Needs_Finalization (Ret_Typ) then + if Needs_Finalization (Ret_Typ) + and then not Has_Relaxed_Finalization (Ret_Typ) + then declare Decls : constant List_Id := New_List; Fin_Coll_Id : constant Entity_Id := @@ -7097,8 +7187,8 @@ package body Exp_Ch3 is procedure Count_Default_Sized_Task_Stacks (Typ : Entity_Id; - Pri_Stacks : out Int; - Sec_Stacks : out Int) + Pri_Stacks : out Nat; + Sec_Stacks : out Nat) is Component : Entity_Id; @@ -7170,8 +7260,8 @@ package body Exp_Ch3 is while Present (Component) loop declare - P : Int; - S : Int; + P : Nat; + S : Nat; begin Count_Default_Sized_Task_Stacks (Etype (Component), P, S); @@ -7482,7 +7572,11 @@ package body Exp_Ch3 is -- Don't do anything for deferred constants. All proper actions will be -- expanded during the full declaration. - if No (Expr) and Constant_Present (N) then + if No (Expr) + and then Constant_Present (N) + and then (No (Constructor_Name (Typ)) + or else No (Default_Constructor (Typ))) + then return; end if; @@ -7507,6 +7601,21 @@ package body Exp_Ch3 is return; end if; + -- Expand objects with default constructors to have the 'Make + -- attribute. + + if Comes_From_Source (N) + and then No (Expr) + and then Present (Constructor_Name (Typ)) + and then Present (Default_Constructor (Typ)) + then + Expr := Make_Attribute_Reference (Loc, + Attribute_Name => Name_Make, + Prefix => Object_Definition (N)); + Set_Expression (N, Expr); + Analyze_And_Resolve (Expr); + end if; + -- Make shared memory routines for shared passive variable if Is_Shared_Passive (Def_Id) then @@ -7570,7 +7679,7 @@ package body Exp_Ch3 is and then not (Is_Array_Type (Typ) and then Has_Init_Expression (N)) then declare - PS_Count, SS_Count : Int; + PS_Count, SS_Count : Nat; begin Count_Default_Sized_Task_Stacks (Typ, PS_Count, SS_Count); Increment_Primary_Stack_Count (PS_Count); @@ -8293,12 +8402,15 @@ package body Exp_Ch3 is -- where the object has been initialized by a call to a function -- returning on the primary stack (see Expand_Ctrl_Function_Call) -- since no copy occurred, given that the type is by-reference. + -- Likewise if it is initialized by a 2-pass aggregate, since the + -- actual initialization will only occur during the second pass. -- Similarly, no adjustment is needed if we are going to rewrite -- the object declaration into a renaming declaration. if Needs_Finalization (Typ) and then not Is_Inherently_Limited_Type (Typ) and then Nkind (Expr_Q) /= N_Function_Call + and then not Is_Two_Pass_Aggregate (Expr_Q) and then not Rewrite_As_Renaming then Adj_Call := @@ -8711,8 +8823,9 @@ package body Exp_Ch3 is -- be illegal in some cases (such as converting access- -- to-unconstrained to access-to-constrained), but the -- the unchecked conversion will presumably fail to work - -- right in just such cases. It's not clear at all how to - -- handle this. + -- right in just such cases. In order to handle this + -- properly, in the Caller_Allocation case, the callee + -- needs to do the constraint check. Alloc_Stmt := Make_If_Statement (Loc, @@ -9127,7 +9240,7 @@ package body Exp_Ch3 is exception when RE_Not_Available => - return; + null; end Expand_N_Object_Declaration; --------------------------------- @@ -9389,7 +9502,7 @@ package body Exp_Ch3 is exception when RE_Not_Available => - return; + null; end Expand_Tagged_Root; ------------------------------ @@ -12733,25 +12846,27 @@ package body Exp_Ch3 is Append_To (Res, Decl); end if; - Fin_Call := Empty; - Decl := Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Finalize, True); + if not Has_Destructor (Tag_Typ) then + Fin_Call := Empty; + Decl := Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Finalize, True); - if Is_Controlled (Tag_Typ) then - Fin_Call := - Make_Final_Call - (Obj_Ref => Make_Identifier (Loc, Name_V), - Typ => Tag_Typ); - end if; + if Is_Controlled (Tag_Typ) then + Fin_Call := + Make_Final_Call + (Obj_Ref => Make_Identifier (Loc, Name_V), Typ => Tag_Typ); + end if; - if No (Fin_Call) then - Fin_Call := Make_Null_Statement (Loc); - end if; + if No (Fin_Call) then + Fin_Call := Make_Null_Statement (Loc); + end if; - Set_Handled_Statement_Sequence (Decl, - Make_Handled_Sequence_Of_Statements (Loc, - Statements => New_List (Fin_Call))); + Set_Handled_Statement_Sequence + (Decl, + Make_Handled_Sequence_Of_Statements + (Loc, Statements => New_List (Fin_Call))); - Append_To (Res, Decl); + Append_To (Res, Decl); + end if; end if; return Res; diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index 82978c775cf2..43c94f37ba1a 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -177,12 +177,6 @@ package body Exp_Ch4 is -- integer type. This is a case where top level processing is required to -- handle overflow checks in subtrees. - procedure Fixup_Universal_Fixed_Operation (N : Node_Id); - -- N is a N_Op_Divide or N_Op_Multiply node whose result is universal - -- fixed. We do not have such a type at runtime, so the purpose of this - -- routine is to find the real type by looking up the tree. We also - -- determine if the operation must be rounded. - procedure Get_First_Index_Bounds (T : Entity_Id; Lo, Hi : out Uint); -- T is an array whose index bounds are all known at compile time. Return -- the value of the low and high bounds of the first index of T. @@ -193,12 +187,12 @@ package body Exp_Ch4 is procedure Insert_Conditional_Object_Declaration (Obj_Id : Entity_Id; + Typ : Entity_Id; Expr : Node_Id; - Decl : Node_Id); - -- Expr is the dependent expression of a conditional expression and Decl - -- is the declaration of an object whose initialization expression is the - -- conditional expression. Insert in the actions of Expr the declaration - -- of Obj_Id modeled on Decl and with Expr as initialization expression. + Const : Boolean); + -- Expr is the dependent expression of a conditional expression. Insert in + -- the actions of Expr the declaration of Obj_Id with type Typ and Expr as + -- initialization expression. Const is True when Obj_Id is a constant. procedure Insert_Dereference_Action (N : Node_Id); -- N is an expression whose type is an access. When the type of the @@ -240,6 +234,10 @@ package body Exp_Ch4 is -- skipped if the operation is done in Bignum mode but that's fine, since -- the Bignum call takes care of everything. + function New_Assign_Copy (N : Node_Id; Expr : Node_Id) return Node_Id; + -- N is an assignment statement. Return a copy of N with the same name but + -- expression changed to Expr and perform a couple of adjustments. + procedure Narrow_Large_Operation (N : Node_Id); -- Try to compute the result of a large operation in a narrower type than -- its nominal type. This is mainly aimed at getting rid of operations done @@ -434,7 +432,7 @@ package body Exp_Ch4 is exception when RE_Not_Available => - return; + null; end Build_Boolean_Array_Proc_Call; --------------------------------- @@ -727,7 +725,7 @@ package body Exp_Ch4 is -- adjust after the assignment but, in either case, we do not -- finalize before since the target is newly allocated memory. - if Nkind (Exp) = N_Function_Call then + if Back_End_Return_Slot and then Nkind (Exp) = N_Function_Call then Set_No_Ctrl_Actions (Assign); else Set_No_Finalize_Actions (Assign); @@ -769,7 +767,6 @@ package body Exp_Ch4 is -- Local variables Aggr_In_Place : Boolean; - Container_Aggr : Boolean; Delayed_Cond_Expr : Boolean; TagT : Entity_Id := Empty; @@ -865,13 +862,12 @@ package body Exp_Ch4 is Aggr_In_Place := Is_Delayed_Aggregate (Exp); Delayed_Cond_Expr := Is_Delayed_Conditional_Expression (Exp); - Container_Aggr := Nkind (Exp) = N_Aggregate - and then Has_Aspect (T, Aspect_Aggregate); - -- An allocator with a container aggregate as qualified expression must - -- be rewritten into the form expected by Expand_Container_Aggregate. + -- An allocator with a container aggregate, resp. a 2-pass aggregate, + -- as qualified expression must be rewritten into the form expected by + -- Expand_Container_Aggregate, resp. Two_Pass_Aggregate_Expansion. - if Container_Aggr then + if Is_Container_Aggregate (Exp) or else Is_Two_Pass_Aggregate (Exp) then Temp := Make_Temporary (Loc, 'P', N); Set_Analyzed (Exp, False); Insert_Action (N, @@ -1240,7 +1236,7 @@ package body Exp_Ch4 is exception when RE_Not_Available => - return; + null; end Expand_Allocator_Expression; ----------------------------- @@ -2358,6 +2354,7 @@ package body Exp_Ch4 is Rhs : Node_Id) return Node_Id is Loc : constant Source_Ptr := Sloc (Nod); + CW_Comp : Boolean := False; Full_Type : Entity_Id; Eq_Op : Entity_Id; @@ -2387,10 +2384,17 @@ package body Exp_Ch4 is Full_Type := Underlying_Type (Full_Type); end if; + if Is_Class_Wide_Equivalent_Type (Full_Type) then + CW_Comp := True; + Full_Type := + Get_Corresponding_Mutably_Tagged_Type_If_Present (Full_Type); + pragma Assert (Is_Tagged_Type (Full_Type)); + end if; + -- Case of tagged record types if Is_Tagged_Type (Full_Type) then - Eq_Op := Find_Primitive_Eq (Comp_Type); + Eq_Op := Find_Primitive_Eq (if CW_Comp then Full_Type else Comp_Type); pragma Assert (Present (Eq_Op)); return @@ -2468,21 +2472,20 @@ package body Exp_Ch4 is declare Op : constant Entity_Id := Find_Primitive_Eq (Comp_Type); + begin - if Warn_On_Ignored_Equality - and then Present (Op) + if Present (Op) and then not In_Predefined_Unit (Base_Type (Comp_Type)) and then not Is_Intrinsic_Subprogram (Op) then pragma Assert (Is_First_Subtype (Outer_Type) or else Is_Generic_Actual_Type (Outer_Type)); - Error_Msg_Node_2 := Comp_Type; - Error_Msg_N - ("?_q?""="" for type & uses predefined ""="" for }", - Outer_Type); - Error_Msg_Sloc := Sloc (Op); - Error_Msg_N ("\?_q?""="" # is ignored here", Outer_Type); + + Warn_On_Ignored_Equality_Operator + (Typ => Outer_Type, + Comp_Typ => Comp_Type, + Loc => Sloc (Op)); end if; end; @@ -4490,6 +4493,15 @@ package body Exp_Ch4 is Error_Msg_N ("?_a?use of an anonymous access type allocator", N); end if; + -- Here we set no initialization on types with constructors since we + -- generate initialization for the separately. + + if Present (Constructor_Name (Directly_Designated_Type (PtrT))) + and then Nkind (Expression (N)) = N_Identifier + then + Set_No_Initialization (N, False); + end if; + -- RM E.2.2(17). We enforce that the expected type of an allocator -- shall not be a remote access-to-class-wide-limited-private type. -- We probably shouldn't be doing this legality check during expansion, @@ -5063,7 +5075,7 @@ package body Exp_Ch4 is exception when RE_Not_Available => - return; + null; end Expand_N_Allocator; ----------------------- @@ -5181,6 +5193,8 @@ package body Exp_Ch4 is -- expansion until the (immediate) parent is rewritten as a return -- statement (or is already the return statement). Likewise if it is -- in the context of an object declaration that can be optimized. + -- Likewise if it is in the context of a regular agggregate and the + -- type should not be copied. if not Expansion_Delayed (N) then declare @@ -5188,6 +5202,8 @@ package body Exp_Ch4 is begin if Nkind (Uncond_Par) = N_Simple_Return_Statement or else Is_Optimizable_Declaration (Uncond_Par) + or else (Parent_Is_Regular_Aggregate (Uncond_Par) + and then not Is_Copy_Type (Typ)) then Delay_Conditional_Expressions_Between (N, Uncond_Par); end if; @@ -5303,7 +5319,7 @@ package body Exp_Ch4 is -- 'Unrestricted_Access. -- Generate: - -- type Ptr_Typ is not null access all [constant] Typ; + -- type Target_Typ is not null access all [constant] Typ; else Target_Typ := Make_Temporary (Loc, 'P'); @@ -5367,17 +5383,7 @@ package body Exp_Ch4 is if Optimize_Assignment_Stmt then -- We directly copy the parent node to preserve its flags - Stmts := New_List (New_Copy (Par)); - Set_Sloc (First (Stmts), Alt_Loc); - Set_Name (First (Stmts), New_Copy_Tree (Name (Par))); - Set_Expression (First (Stmts), Alt_Expr); - - -- If the expression is itself a conditional expression whose - -- expansion has been delayed, analyze it again and expand it. - - if Is_Delayed_Conditional_Expression (Alt_Expr) then - Unanalyze_Delayed_Conditional_Expression (Alt_Expr); - end if; + Stmts := New_List (New_Assign_Copy (Par, Alt_Expr)); -- Generate: -- return AX; @@ -5401,20 +5407,16 @@ package body Exp_Ch4 is elsif Optimize_Object_Decl then Obj := Make_Temporary (Loc, 'C', Alt_Expr); - Insert_Conditional_Object_Declaration (Obj, Alt_Expr, Par); - - Alt_Expr := - Make_Attribute_Reference (Alt_Loc, - Prefix => New_Occurrence_Of (Obj, Alt_Loc), - Attribute_Name => Name_Unrestricted_Access); - - LHS := New_Occurrence_Of (Target, Loc); - Set_Assignment_OK (LHS); + Insert_Conditional_Object_Declaration + (Obj, Typ, Alt_Expr, Const => Constant_Present (Par)); Stmts := New_List ( Make_Assignment_Statement (Alt_Loc, - Name => LHS, - Expression => Alt_Expr)); + Name => New_Occurrence_Of (Target, Loc), + Expression => + Make_Attribute_Reference (Alt_Loc, + Prefix => New_Occurrence_Of (Obj, Alt_Loc), + Attribute_Name => Name_Unrestricted_Access))); -- Take the unrestricted access of the expression value for non- -- scalar types. This approach avoids big copies and covers the @@ -5799,8 +5801,9 @@ package body Exp_Ch4 is -- expansion until the (immediate) parent is rewritten as a return -- statement (or is already the return statement). Likewise if it is -- in the context of an object declaration that can be optimized. - -- Note that this deals with the case of the elsif part of the if - -- expression, if it exists. + -- Likewise if it is in the context of a regular agggregate and the + -- type should not be copied. Note that this deals with the case of + -- the elsif part of the if expression, if it exists. if not Expansion_Delayed (N) then declare @@ -5808,6 +5811,8 @@ package body Exp_Ch4 is begin if Nkind (Uncond_Par) = N_Simple_Return_Statement or else Is_Optimizable_Declaration (Uncond_Par) + or else (Parent_Is_Regular_Aggregate (Uncond_Par) + and then not Is_Copy_Type (Typ)) then Delay_Conditional_Expressions_Between (N, Uncond_Par); end if; @@ -5910,26 +5915,8 @@ package body Exp_Ch4 is -- We directly copy the parent node to preserve its flags - New_Then := New_Copy (Par); - Set_Sloc (New_Then, Sloc (Thenx)); - Set_Name (New_Then, New_Copy_Tree (Name (Par))); - Set_Expression (New_Then, Relocate_Node (Thenx)); - - -- If the expression is itself a conditional expression whose - -- expansion has been delayed, analyze it again and expand it. - - if Is_Delayed_Conditional_Expression (Expression (New_Then)) then - Unanalyze_Delayed_Conditional_Expression (Expression (New_Then)); - end if; - - New_Else := New_Copy (Par); - Set_Sloc (New_Else, Sloc (Elsex)); - Set_Name (New_Else, New_Copy_Tree (Name (Par))); - Set_Expression (New_Else, Relocate_Node (Elsex)); - - if Is_Delayed_Conditional_Expression (Expression (New_Else)) then - Unanalyze_Delayed_Conditional_Expression (Expression (New_Else)); - end if; + New_Then := New_Assign_Copy (Par, Relocate_Node (Thenx)); + New_Else := New_Assign_Copy (Par, Relocate_Node (Elsex)); If_Stmt := Make_Implicit_If_Statement (N, @@ -6012,8 +5999,10 @@ package body Exp_Ch4 is Target : constant Entity_Id := Make_Temporary (Loc, 'C', N); begin - Insert_Conditional_Object_Declaration (Then_Obj, Thenx, Par); - Insert_Conditional_Object_Declaration (Else_Obj, Elsex, Par); + Insert_Conditional_Object_Declaration + (Then_Obj, Typ, Thenx, Const => Constant_Present (Par)); + Insert_Conditional_Object_Declaration + (Else_Obj, Typ, Elsex, Const => Constant_Present (Par)); -- Generate: -- type Ptr_Typ is not null access all [constant] Typ; @@ -7777,7 +7766,7 @@ package body Exp_Ch4 is exception when RE_Not_Available => - return; + null; end Expand_N_Null; --------------------- @@ -9162,7 +9151,7 @@ package body Exp_Ch4 is exception when RE_Not_Available => - return; + null; end Expand_N_Op_Expon; -------------------- @@ -11304,11 +11293,12 @@ package body Exp_Ch4 is ----------------------------------- procedure Handle_Changed_Representation is - Temp : Entity_Id; + Cons : List_Id; Decl : Node_Id; - Odef : Node_Id; N_Ix : Node_Id; - Cons : List_Id; + Odef : Node_Id; + Stmt : Node_Id; + Temp : Entity_Id; begin -- Nothing else to do if no change of representation @@ -11451,19 +11441,24 @@ package body Exp_Ch4 is Defining_Identifier => Temp, Object_Definition => Odef); - Set_No_Initialization (Decl, True); + -- The temporary need not be initialized + + Set_No_Initialization (Decl); + + Stmt := + Make_Assignment_Statement (Loc, + Name => New_Occurrence_Of (Temp, Loc), + Expression => Relocate_Node (N)); + + -- And, therefore, cannot be finalized + + Set_No_Finalize_Actions (Stmt); -- Insert required actions. It is essential to suppress checks -- since we have suppressed default initialization, which means -- that the variable we create may have no discriminants. - Insert_Actions (N, - New_List ( - Decl, - Make_Assignment_Statement (Loc, - Name => New_Occurrence_Of (Temp, Loc), - Expression => Relocate_Node (N))), - Suppress => All_Checks); + Insert_Actions (N, New_List (Decl, Stmt), Suppress => All_Checks); Rewrite (N, New_Occurrence_Of (Temp, Loc)); return; @@ -13284,17 +13279,20 @@ package body Exp_Ch4 is procedure Insert_Conditional_Object_Declaration (Obj_Id : Entity_Id; + Typ : Entity_Id; Expr : Node_Id; - Decl : Node_Id) + Const : Boolean) is Loc : constant Source_Ptr := Sloc (Expr); Obj_Decl : constant Node_Id := Make_Object_Declaration (Loc, Defining_Identifier => Obj_Id, - Aliased_Present => Aliased_Present (Decl), - Constant_Present => Constant_Present (Decl), - Object_Definition => New_Copy_Tree (Object_Definition (Decl)), + Aliased_Present => True, + Constant_Present => Const, + Object_Definition => New_Occurrence_Of (Typ, Loc), Expression => Relocate_Node (Expr)); + -- We make the object unconditionally aliased to avoid dangling bound + -- issues when its nominal subtype is an unconstrained array type. Master_Node_Decl : Node_Id; Master_Node_Id : Entity_Id; @@ -13309,6 +13307,21 @@ package body Exp_Ch4 is Insert_Action (Expr, Obj_Decl); + -- The object can never be local to an elaboration routine at library + -- level since we will take 'Unrestricted_Access of it. Beware that + -- Is_Library_Level_Entity always returns False when called from within + -- a transient scope, but the associated block will not be materialized + -- when the transient scope is finally closed in the case of an object + -- declaration (see Exp.Ch7.Wrap_Transient_Declaration). + + if Scope (Obj_Id) = Current_Scope and then Scope_Is_Transient then + Set_Is_Statically_Allocated + (Obj_Id, Is_Library_Level_Entity (Scope (Obj_Id))); + else + Set_Is_Statically_Allocated + (Obj_Id, Is_Library_Level_Entity (Obj_Id)); + end if; + -- If the object needs finalization, we need to insert its Master_Node -- manually because 1) the machinery in Exp_Ch7 will not pick it since -- it will be declared in the arm of a conditional statement and 2) we @@ -13568,7 +13581,7 @@ package body Exp_Ch4 is exception when RE_Not_Available => - return; + null; end Insert_Dereference_Action; -------------------------------- @@ -14197,6 +14210,39 @@ package body Exp_Ch4 is end if; end Narrow_Large_Operation; + --------------------- + -- New_Assign_Copy -- + --------------------- + + function New_Assign_Copy (N : Node_Id; Expr : Node_Id) return Node_Id is + New_N : constant Node_Id := New_Copy (N); + + begin + Set_Sloc (New_N, Sloc (Expr)); + Set_Name (New_N, New_Copy_Tree (Name (N))); + Set_Expression (New_N, Expr); + + -- The result of a function call need not be adjusted if it has + -- already been adjusted in the called function. + + if No_Finalize_Actions (New_N) + and then Back_End_Return_Slot + and then Nkind (Expr) = N_Function_Call + then + Set_No_Finalize_Actions (New_N, False); + Set_No_Ctrl_Actions (New_N); + end if; + + -- If the expression is itself a conditional expression whose + -- expansion has been delayed, analyze it again and expand it. + + if Is_Delayed_Conditional_Expression (Expr) then + Unanalyze_Delayed_Conditional_Expression (Expr); + end if; + + return New_N; + end New_Assign_Copy; + -------------------------------- -- Optimize_Length_Comparison -- -------------------------------- @@ -15035,10 +15081,11 @@ package body Exp_Ch4 is -- Handle entities from the limited view - Orig_Right_Type : constant Entity_Id := Available_View (Etype (Right)); + Orig_Right_Type : constant Entity_Id := + Base_Type (Available_View (Etype (Right))); Full_R_Typ : Entity_Id; - Left_Type : Entity_Id := Available_View (Etype (Left)); + Left_Type : Entity_Id := Base_Type (Available_View (Etype (Left))); Right_Type : Entity_Id := Orig_Right_Type; Obj_Tag : Node_Id; diff --git a/gcc/ada/exp_ch4.ads b/gcc/ada/exp_ch4.ads index d954852b1659..42077158ca60 100644 --- a/gcc/ada/exp_ch4.ads +++ b/gcc/ada/exp_ch4.ads @@ -124,4 +124,10 @@ package Exp_Ch4 is -- have special circuitry in Expand_N_Type_Conversion to promote both of -- the operands to type Integer. + procedure Fixup_Universal_Fixed_Operation (N : Node_Id); + -- N is a N_Op_Divide or N_Op_Multiply node whose result is universal + -- fixed. We do not have such a type at runtime, so the purpose of this + -- routine is to find the real type by looking up the tree. We also + -- determine if the operation must be rounded. + end Exp_Ch4; diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb index 06616eaf87d3..66a4fc0512b0 100644 --- a/gcc/ada/exp_ch5.adb +++ b/gcc/ada/exp_ch5.adb @@ -190,6 +190,9 @@ package body Exp_Ch5 is -- specification and Container is either the Container (for OF) or the -- iterator (for IN). + procedure Expand_Loop_Flow_Statement (N : N_Loop_Flow_Statement_Id); + -- Common processing for expansion of "loop flow" statements + procedure Expand_Predicated_Loop (N : Node_Id); -- Expand for loop over predicated subtype @@ -280,14 +283,11 @@ package body Exp_Ch5 is Statements => Stats, End_Label => Empty); - -- If the contruct has a specified loop name, preserve it in the new - -- loop, for possible use in exit statements. + -- Preserve the construct's loop name in the new loop, for possible use + -- in exit statements. - if Present (Identifier (N)) - and then Comes_From_Source (Identifier (N)) - then - Set_Identifier (New_Loop, Identifier (N)); - end if; + pragma Assert (Present (Identifier (N))); + Set_Identifier (New_Loop, Identifier (N)); end Build_Formal_Container_Iteration; ------------------------------ @@ -1039,7 +1039,8 @@ package body Exp_Ch5 is Prefix => Make_Indexed_Component (Loc, Prefix => - Duplicate_Subexpr_Move_Checks (Larray, True), + Duplicate_Subexpr_Move_Checks + (Larray, Name_Req => True), Expressions => New_List ( Make_Attribute_Reference (Loc, Prefix => @@ -1054,7 +1055,8 @@ package body Exp_Ch5 is Prefix => Make_Indexed_Component (Loc, Prefix => - Duplicate_Subexpr_Move_Checks (Rarray, True), + Duplicate_Subexpr_Move_Checks + (Rarray, Name_Req => True), Expressions => New_List ( Make_Attribute_Reference (Loc, Prefix => @@ -1152,7 +1154,7 @@ package body Exp_Ch5 is exception when RE_Not_Available => - return; + null; end Expand_Assign_Array; ------------------------------ @@ -1396,7 +1398,7 @@ package body Exp_Ch5 is Prefix => Make_Indexed_Component (Loc, Prefix => - Duplicate_Subexpr (Larray, True), + Duplicate_Subexpr (Larray, Name_Req => True), Expressions => New_List (New_Copy_Tree (Left_Lo))), Attribute_Name => Name_Address); @@ -1405,7 +1407,7 @@ package body Exp_Ch5 is Prefix => Make_Indexed_Component (Loc, Prefix => - Duplicate_Subexpr (Larray, True), + Duplicate_Subexpr (Larray, Name_Req => True), Expressions => New_List (New_Copy_Tree (Left_Lo))), Attribute_Name => Name_Bit); @@ -1414,7 +1416,7 @@ package body Exp_Ch5 is Prefix => Make_Indexed_Component (Loc, Prefix => - Duplicate_Subexpr (Rarray, True), + Duplicate_Subexpr (Rarray, Name_Req => True), Expressions => New_List (New_Copy_Tree (Right_Lo))), Attribute_Name => Name_Address); @@ -1423,7 +1425,7 @@ package body Exp_Ch5 is Prefix => Make_Indexed_Component (Loc, Prefix => - Duplicate_Subexpr (Rarray, True), + Duplicate_Subexpr (Rarray, Name_Req => True), Expressions => New_List (New_Copy_Tree (Right_Lo))), Attribute_Name => Name_Bit); @@ -1439,11 +1441,11 @@ package body Exp_Ch5 is Make_Op_Multiply (Loc, Make_Attribute_Reference (Loc, Prefix => - Duplicate_Subexpr (Name (N), True), + Duplicate_Subexpr (Name (N), Name_Req => True), Attribute_Name => Name_Length), Make_Attribute_Reference (Loc, Prefix => - Duplicate_Subexpr (Name (N), True), + Duplicate_Subexpr (Name (N), Name_Req => True), Attribute_Name => Name_Component_Size)); begin @@ -1527,11 +1529,11 @@ package body Exp_Ch5 is Make_Op_Multiply (Loc, Make_Attribute_Reference (Loc, Prefix => - Duplicate_Subexpr (Name (N), True), + Duplicate_Subexpr (Name (N), Name_Req => True), Attribute_Name => Name_Length), Make_Attribute_Reference (Loc, Prefix => - Duplicate_Subexpr (Larray, True), + Duplicate_Subexpr (Larray, Name_Req => True), Attribute_Name => Name_Component_Size)); L_Arg, R_Arg, Call : Node_Id; @@ -1582,7 +1584,7 @@ package body Exp_Ch5 is end if; return Make_Assignment_Statement (Loc, - Name => Duplicate_Subexpr (Larray, True), + Name => Duplicate_Subexpr (Larray, Name_Req => True), Expression => Unchecked_Convert_To (L_Typ, Call)); end Expand_Assign_Array_Bitfield_Fast; @@ -3453,7 +3455,7 @@ package body Exp_Ch5 is exception when RE_Not_Available => - return; + null; end Expand_N_Assignment_Statement; ------------------------------ @@ -4423,16 +4425,98 @@ package body Exp_Ch5 is end; end Expand_N_Case_Statement; + --------------------------------- + -- Expand_N_Continue_Statement -- + --------------------------------- + + procedure Expand_N_Continue_Statement (N : Node_Id) is + X : constant Node_Id := Call_Or_Target_Loop (N); + + Loc : constant Source_Ptr := Sloc (N); + + Label : E_Label_Id; + begin + if No (X) then + return; + end if; + + if Nkind (X) = N_Procedure_Call_Statement then + Replace (N, X); + Analyze (N); + return; + end if; + + Expand_Loop_Flow_Statement (N); + + declare + L : constant E_Loop_Id := Call_Or_Target_Loop (N); + M : constant Node_Id := Continue_Mark (L); + A : constant Node_Id := Next (M); + begin + if not (Present (A) and then Nkind (A) = N_Label) then + -- This is the first continue statement that is expanded for this + -- loop; we set up the label that the goto statement will target. + declare + P : constant Node_Id := Atree.Node_Parent (L); + + Decl_List : constant List_Id := + (if Nkind (P) = N_Implicit_Label_Declaration + then List_Containing (P) + else Declarations (Parent (Parent (P)))); + + Label_Entity : constant Entity_Id := + Make_Defining_Identifier + (Loc, New_External_Name (Chars (L), 'C')); + Label_Id : constant N_Identifier_Id := + Make_Identifier (Loc, Chars (Label_Entity)); + Label_Node : constant N_Label_Id := + Make_Label (Loc, Label_Id); + Label_Decl : constant N_Implicit_Label_Declaration_Id := + Make_Implicit_Label_Declaration + (Loc, Label_Entity, Label_Node); + begin + Mutate_Ekind (Label_Entity, E_Label); + Set_Etype (Label_Entity, Standard_Void_Type); + + Set_Entity (Label_Id, Label_Entity); + Set_Etype (Label_Id, Standard_Void_Type); + + Insert_After (Node => Label_Node, After => M); + + Append (Node => Label_Decl, To => Decl_List); + + Label := Label_Entity; + end; + else + -- Some other continue statement for this loop was expanded + -- already, so we can reuse the label that is already set up. + Label := Entity (Identifier (A)); + end if; + end; + + declare + C : constant Opt_N_Subexpr_Id := Condition (N); + Goto_St : constant N_Goto_Statement_Id := + Make_Goto_Statement (Loc, New_Occurrence_Of (Label, Loc)); + + New_St : constant Node_Id := + (if Present (C) + then Make_If_Statement (Sloc (N), C, New_List (Goto_St)) + else Goto_St); + begin + Set_Parent (New_St, Parent (N)); + Replace (N, New_St); + end; + + end Expand_N_Continue_Statement; + ----------------------------- -- Expand_N_Exit_Statement -- ----------------------------- - -- The only processing required is to deal with a possible C/Fortran - -- boolean value used as the condition for the exit statement. - procedure Expand_N_Exit_Statement (N : Node_Id) is begin - Adjust_Condition (Condition (N)); + Expand_Loop_Flow_Statement (N); end Expand_N_Exit_Statement; ---------------------------------- @@ -5754,7 +5838,6 @@ package body Exp_Ch5 is Loc : constant Source_Ptr := Sloc (N); Scheme : constant Node_Id := Iteration_Scheme (N); Stmt : Node_Id; - begin -- Delete null loop @@ -5978,8 +6061,7 @@ package body Exp_Ch5 is -- ... -- end loop - elsif Present (Scheme) - and then Present (Condition_Actions (Scheme)) + elsif Present (Condition_Actions (Scheme)) and then Present (Condition (Scheme)) then declare @@ -6011,9 +6093,7 @@ package body Exp_Ch5 is -- Here to deal with iterator case - elsif Present (Scheme) - and then Present (Iterator_Specification (Scheme)) - then + elsif Present (Iterator_Specification (Scheme)) then Expand_Iterator_Loop (N); -- An iterator loop may generate renaming declarations for elements @@ -6044,6 +6124,18 @@ package body Exp_Ch5 is Process_Statements_For_Controlled_Objects (Stmt); end Expand_N_Loop_Statement; + -------------------------------- + -- Expand_Loop_Flow_Statement -- + -------------------------------- + + -- The only processing required is to deal with a possible C/Fortran + -- boolean value used as the condition for the statement. + + procedure Expand_Loop_Flow_Statement (N : N_Loop_Flow_Statement_Id) is + begin + Adjust_Condition (Condition (N)); + end Expand_Loop_Flow_Statement; + ---------------------------- -- Expand_Predicated_Loop -- ---------------------------- diff --git a/gcc/ada/exp_ch5.ads b/gcc/ada/exp_ch5.ads index efde755c08f9..e75c12822339 100644 --- a/gcc/ada/exp_ch5.ads +++ b/gcc/ada/exp_ch5.ads @@ -31,6 +31,7 @@ package Exp_Ch5 is procedure Expand_N_Assignment_Statement (N : Node_Id); procedure Expand_N_Block_Statement (N : Node_Id); procedure Expand_N_Case_Statement (N : Node_Id); + procedure Expand_N_Continue_Statement (N : Node_Id); procedure Expand_N_Exit_Statement (N : Node_Id); procedure Expand_N_Goto_When_Statement (N : Node_Id); procedure Expand_N_If_Statement (N : Node_Id); diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb index 7e464541be25..1195582aaeab 100644 --- a/gcc/ada/exp_ch6.adb +++ b/gcc/ada/exp_ch6.adb @@ -158,7 +158,7 @@ package body Exp_Ch6 is Alloc_Form_Exp : Node_Id := Empty; Pool_Exp : Node_Id := Empty); -- Ada 2005 (AI-318-02): If the result type of a build-in-place call needs - -- them, add the actuals parameters BIP_Alloc_Form and BIP_Storage_Pool. + -- them, add the actual parameters BIP_Alloc_Form and BIP_Storage_Pool. -- If Alloc_Form_Exp is present, then pass it for the first parameter, -- otherwise pass a literal corresponding to the Alloc_Form parameter -- (which must not be Unspecified in that case). If Pool_Exp is present, @@ -287,10 +287,11 @@ package body Exp_Ch6 is -- This expansion is necessary in all the cases where the constant object -- denoted by the call needs finalization in the current subprogram, which - -- excludes return statements, and is not identified with another object - -- that will be finalized, which excludes (statically) declared objects, - -- dynamically allocated objects, and targets of assignments that are done - -- directly (without intermediate temporaries). + -- excludes simple return statements, and is not identified with another + -- object that will be finalized, which excludes (statically) declared + -- objects, dynamically allocated objects, components of aggregates, and + -- targets of assignments that are done directly (without intermediate + -- temporaries). procedure Expand_Non_Function_Return (N : Node_Id); -- Expand a simple return statement found in a procedure body, entry body, @@ -442,9 +443,7 @@ package body Exp_Ch6 is return; end if; - -- Locate the implicit allocation form parameter in the called function. - -- Maybe it would be better for each implicit formal of a build-in-place - -- function to have a flag or a Uint attribute to identify it. ??? + -- Locate the implicit allocation form parameter in the called function Alloc_Form_Formal := Build_In_Place_Formal (Function_Id, BIP_Alloc_Form); @@ -928,9 +927,6 @@ package body Exp_Ch6 is Formal_Suffix : constant String := BIP_Formal_Suffix (Kind); begin - -- Maybe it would be better for each implicit formal of a build-in-place - -- function to have a flag or a Uint attribute to identify it. ??? - -- The return type in the function declaration may have been a limited -- view, and the extra formals for the function were not generated at -- that point. At the point of call the full view must be available and @@ -1159,13 +1155,18 @@ package body Exp_Ch6 is (Subp_Call : Node_Id; Subp_Id : Entity_Id) return Boolean is - Formal : Entity_Id; + use Deferred_Extra_Formals_Support; + Actual : Node_Id; + Formal : Entity_Id; begin pragma Assert (Nkind (Subp_Call) in N_Entry_Call_Statement | N_Function_Call | N_Procedure_Call_Statement); + pragma Assert (Extra_Formals_Known (Subp_Id) + or else not Expander_Active + or else Is_Unsupported_Extra_Actuals_Call (Subp_Call, Subp_Id)); -- In CodePeer_Mode, the tree for `'Elab_Spec` procedures will be -- malformed because GNAT does not perform the usual expansion that @@ -2470,11 +2471,6 @@ package body Exp_Ch6 is -- (and ensure that we have an activation chain defined for tasks -- and a Master variable). - -- Currently we limit such functions to those with inherently - -- limited result subtypes, but eventually we plan to expand the - -- functions that are treated as build-in-place to include other - -- composite result types. - -- But do not do it here for intrinsic subprograms since this will -- be done properly after the subprogram is expanded. @@ -2875,15 +2871,17 @@ package body Exp_Ch6 is ----------------- procedure Expand_Call (N : Node_Id) is - function Is_Unchecked_Union_Equality (N : Node_Id) return Boolean; + function Is_Unchecked_Union_Predefined_Equality_Call + (N : Node_Id) return Boolean; -- Return True if N is a call to the predefined equality operator of an -- unchecked union type, or a renaming thereof. - --------------------------------- - -- Is_Unchecked_Union_Equality -- - --------------------------------- + ------------------------------------------------- + -- Is_Unchecked_Union_Predefined_Equality_Call -- + ------------------------------------------------- - function Is_Unchecked_Union_Equality (N : Node_Id) return Boolean is + function Is_Unchecked_Union_Predefined_Equality_Call + (N : Node_Id) return Boolean is begin if Is_Entity_Name (Name (N)) and then Ekind (Entity (Name (N))) = E_Function @@ -2908,7 +2906,7 @@ package body Exp_Ch6 is else return False; end if; - end Is_Unchecked_Union_Equality; + end Is_Unchecked_Union_Predefined_Equality_Call; -- If this is an indirect call through an Access_To_Subprogram -- with contract specifications, it is rewritten as a call to @@ -3005,7 +3003,7 @@ package body Exp_Ch6 is -- Case of a call to the predefined equality operator of an unchecked -- union type, which requires specific processing. - elsif Is_Unchecked_Union_Equality (N) then + elsif Is_Unchecked_Union_Predefined_Equality_Call (N) then declare Eq : constant Entity_Id := Entity (Name (N)); @@ -3029,29 +3027,12 @@ package body Exp_Ch6 is end if; end Expand_Call; - ------------------------ - -- Expand_Call_Helper -- - ------------------------ - - -- This procedure handles expansion of function calls and procedure call - -- statements (i.e. it serves as the body for Expand_N_Function_Call and - -- Expand_N_Procedure_Call_Statement). Processing for calls includes: - - -- Replace call to Raise_Exception by Raise_Exception_Always if possible - -- Provide values of actuals for all formals in Extra_Formals list - -- Replace "call" to enumeration literal function by literal itself - -- Rewrite call to predefined operator as operator - -- Replace actuals to in-out parameters that are numeric conversions, - -- with explicit assignment to temporaries before and after the call. - - -- Note that the list of actuals has been filled with default expressions - -- during semantic analysis of the call. Only the extra actuals required - -- for the 'Constrained attribute and for accessibility checks are added - -- at this point. + -------------------------- + -- Create_Extra_Actuals -- + -------------------------- - procedure Expand_Call_Helper (N : Node_Id; Post_Call : out List_Id) is - Loc : constant Source_Ptr := Sloc (N); - Call_Node : Node_Id := N; + procedure Create_Extra_Actuals (Call_Node : Node_Id) is + Loc : constant Source_Ptr := Sloc (Call_Node); Extra_Actuals : List_Id := No_List; Prev : Node_Id := Empty; @@ -3081,88 +3062,6 @@ package body Exp_Ch6 is -- expression for the value of the actual, EF is the entity for the -- extra formal. - procedure Add_View_Conversion_Invariants - (Formal : Entity_Id; - Actual : Node_Id); - -- Adds invariant checks for every intermediate type between the range - -- of a view converted argument to its ancestor (from parent to child). - - function Can_Fold_Predicate_Call (P : Entity_Id) return Boolean; - -- Try to constant-fold a predicate check, which often enough is a - -- simple arithmetic expression that can be computed statically if - -- its argument is static. This cleans up the output of CCG, even - -- though useless predicate checks will be generally removed by - -- back-end optimizations. - - procedure Check_Subprogram_Variant; - -- Emit a call to the internally generated procedure with checks for - -- aspect Subprogram_Variant, if present and enabled. - - function Inherited_From_Formal (S : Entity_Id) return Entity_Id; - -- Within an instance, a type derived from an untagged formal derived - -- type inherits from the original parent, not from the actual. The - -- current derivation mechanism has the derived type inherit from the - -- actual, which is only correct outside of the instance. If the - -- subprogram is inherited, we test for this particular case through a - -- convoluted tree traversal before setting the proper subprogram to be - -- called. - - function In_Unfrozen_Instance (E : Entity_Id) return Boolean; - -- Return true if E comes from an instance that is not yet frozen - - function Is_Class_Wide_Interface_Type (E : Entity_Id) return Boolean; - -- Return True when E is a class-wide interface type or an access to - -- a class-wide interface type. - - function Is_Direct_Deep_Call (Subp : Entity_Id) return Boolean; - -- Determine if Subp denotes a non-dispatching call to a Deep routine - - function New_Value (From : Node_Id) return Node_Id; - -- From is the original Expression. New_Value is equivalent to a call - -- to Duplicate_Subexpr with an explicit dereference when From is an - -- access parameter. - - -------------------------- - -- Add_Actual_Parameter -- - -------------------------- - - procedure Add_Actual_Parameter (Insert_Param : Node_Id) is - Actual_Expr : constant Node_Id := - Explicit_Actual_Parameter (Insert_Param); - - begin - -- Case of insertion is first named actual - - if No (Prev) or else - Nkind (Parent (Prev)) /= N_Parameter_Association - then - Set_Next_Named_Actual - (Insert_Param, First_Named_Actual (Call_Node)); - Set_First_Named_Actual (Call_Node, Actual_Expr); - - if No (Prev) then - if No (Parameter_Associations (Call_Node)) then - Set_Parameter_Associations (Call_Node, New_List); - end if; - - Append (Insert_Param, Parameter_Associations (Call_Node)); - - else - Insert_After (Prev, Insert_Param); - end if; - - -- Case of insertion is not first named actual - - else - Set_Next_Named_Actual - (Insert_Param, Next_Named_Actual (Parent (Prev))); - Set_Next_Named_Actual (Parent (Prev), Actual_Expr); - Append (Insert_Param, Parameter_Associations (Call_Node)); - end if; - - Prev := Actual_Expr; - end Add_Actual_Parameter; - -------------------------------------- -- Add_Cond_Expression_Extra_Actual -- -------------------------------------- @@ -3377,14 +3276,14 @@ package body Exp_Ch6 is if Etype (Formal) = Standard_Natural then Actual := Make_Integer_Literal (Loc, Uint_0); Analyze_And_Resolve (Actual, Standard_Natural); - Add_Extra_Actual_To_Call (N, Formal, Actual); + Add_Extra_Actual_To_Call (Call_Node, Formal, Actual); -- BIPtaskmaster elsif Etype (Formal) = Standard_Integer then Actual := Make_Integer_Literal (Loc, Uint_0); Analyze_And_Resolve (Actual, Standard_Integer); - Add_Extra_Actual_To_Call (N, Formal, Actual); + Add_Extra_Actual_To_Call (Call_Node, Formal, Actual); -- BIPstoragepool, BIPcollection, BIPactivationchain, -- and BIPaccess. @@ -3392,7 +3291,7 @@ package body Exp_Ch6 is elsif Is_Access_Type (Etype (Formal)) then Actual := Make_Null (Loc); Analyze_And_Resolve (Actual, Etype (Formal)); - Add_Extra_Actual_To_Call (N, Formal, Actual); + Add_Extra_Actual_To_Call (Call_Node, Formal, Actual); else pragma Assert (False); @@ -3411,6 +3310,47 @@ package body Exp_Ch6 is pragma Assert (Check_BIP_Actuals (Call_Node, Function_Id)); end Add_Dummy_Build_In_Place_Actuals; + -------------------------- + -- Add_Actual_Parameter -- + -------------------------- + + procedure Add_Actual_Parameter (Insert_Param : Node_Id) is + Actual_Expr : constant Node_Id := + Explicit_Actual_Parameter (Insert_Param); + + begin + -- Case of insertion is first named actual + + if No (Prev) + or else Nkind (Parent (Prev)) /= N_Parameter_Association + then + Set_Next_Named_Actual + (Insert_Param, First_Named_Actual (Call_Node)); + Set_First_Named_Actual (Call_Node, Actual_Expr); + + if No (Prev) then + if No (Parameter_Associations (Call_Node)) then + Set_Parameter_Associations (Call_Node, New_List); + end if; + + Append (Insert_Param, Parameter_Associations (Call_Node)); + + else + Insert_After (Prev, Insert_Param); + end if; + + -- Case of insertion is not first named actual + + else + Set_Next_Named_Actual + (Insert_Param, Next_Named_Actual (Parent (Prev))); + Set_Next_Named_Actual (Parent (Prev), Actual_Expr); + Append (Insert_Param, Parameter_Associations (Call_Node)); + end if; + + Prev := Actual_Expr; + end Add_Actual_Parameter; + ---------------------- -- Add_Extra_Actual -- ---------------------- @@ -3436,89 +3376,504 @@ package body Exp_Ch6 is end if; end Add_Extra_Actual; - ------------------------------------ - -- Add_View_Conversion_Invariants -- - ------------------------------------ - - procedure Add_View_Conversion_Invariants - (Formal : Entity_Id; - Actual : Node_Id) - is - Arg : Entity_Id; - Curr_Typ : Entity_Id; - Inv_Checks : List_Id; - Par_Typ : Entity_Id; + -- Local variables - begin - Inv_Checks := No_List; + use Deferred_Extra_Formals_Support; - -- Extract the argument from a potentially nested set of view - -- conversions. + Actual : Node_Id; + Formal : Entity_Id; + Param_Count : Positive; + Subp : constant Entity_Id := Get_Called_Entity (Call_Node); - Arg := Actual; - while Nkind (Arg) = N_Type_Conversion loop - Arg := Expression (Arg); - end loop; + -- Start of processing for Create_Extra_Actuals - -- Move up the derivation chain starting with the type of the formal - -- parameter down to the type of the actual object. + begin + -- Special case: Thunks must not compute the extra actuals; they must + -- just propagate their extra actuals to the target primitive. - Curr_Typ := Empty; - Par_Typ := Etype (Arg); - while Par_Typ /= Etype (Formal) and Par_Typ /= Curr_Typ loop - Curr_Typ := Par_Typ; + if Is_Thunk (Current_Scope) + and then Thunk_Entity (Current_Scope) = Subp + then + declare + Target_Formal : Entity_Id; + Thunk_Formal : Entity_Id; - if Has_Invariants (Curr_Typ) - and then Present (Invariant_Procedure (Curr_Typ)) - then - -- Verify the invariant of the current type. Generate: + begin + pragma Assert (Extra_Formals_Known (Subp) + and then Extra_Formals_Match_OK (Current_Scope, Subp)); - -- <Curr_Typ>Invariant (Curr_Typ (Arg)); + Target_Formal := Extra_Formals (Subp); + Thunk_Formal := Extra_Formals (Current_Scope); + while Present (Target_Formal) loop + Add_Extra_Actual + (Expr => New_Occurrence_Of (Thunk_Formal, Loc), + EF => Thunk_Formal); - Prepend_New_To (Inv_Checks, - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of - (Invariant_Procedure (Curr_Typ), Loc), - Parameter_Associations => New_List ( - Make_Type_Conversion (Loc, - Subtype_Mark => New_Occurrence_Of (Curr_Typ, Loc), - Expression => New_Copy_Tree (Arg))))); - end if; + Target_Formal := Extra_Formal (Target_Formal); + Thunk_Formal := Extra_Formal (Thunk_Formal); + end loop; - Par_Typ := Base_Type (Etype (Curr_Typ)); - end loop; + while Is_Non_Empty_List (Extra_Actuals) loop + Add_Actual_Parameter (Remove_Head (Extra_Actuals)); + end loop; - -- If the node is a function call the generated tests have been - -- already handled in Insert_Post_Call_Actions. + return; + end; + end if; - if not Is_Empty_List (Inv_Checks) - and then Nkind (Call_Node) = N_Procedure_Call_Statement - then - Insert_Actions_After (Call_Node, Inv_Checks); - end if; - end Add_View_Conversion_Invariants; + pragma Assert (Extra_Formals_Known (Subp) + or else Is_Unsupported_Extra_Formals_Entity (Subp)); - ----------------------------- - -- Can_Fold_Predicate_Call -- - ----------------------------- + -- First step, compute extra actuals, corresponding to any Extra_Formals + -- present. Note that we do not access Extra_Formals directly; instead + -- we generate and collect the corresponding actuals in Extra_Actuals. - function Can_Fold_Predicate_Call (P : Entity_Id) return Boolean is - Actual : Node_Id; + Formal := First_Formal (Subp); + Actual := First_Actual (Call_Node); + Param_Count := 1; + while Present (Formal) loop + -- Prepare to examine current entry - function Augments_Other_Dynamic_Predicate (DP_Aspect_Spec : Node_Id) - return Boolean; - -- Given a Dynamic_Predicate aspect aspecification for a - -- discrete type, returns True iff another DP specification - -- applies (indirectly, via a subtype type or a derived type) - -- to the same entity that this aspect spec applies to. + Prev := Actual; - function May_Fold (N : Node_Id) return Traverse_Result; - -- The predicate expression is foldable if it only contains operators - -- and literals. During this check, we also replace occurrences of - -- the formal of the constructed predicate function with the static - -- value of the actual. This is done on a copy of the analyzed - -- expression for the predicate. + -- Create possible extra actual for constrained case. Usually, the + -- extra actual is of the form actual'constrained, but since this + -- attribute is only available for unconstrained records, TRUE is + -- expanded if the type of the formal happens to be constrained (for + -- instance when this procedure is inherited from an unconstrained + -- record to a constrained one) or if the actual has no discriminant + -- (its type is constrained). An exception to this is the case of a + -- private type without discriminants. In this case we pass FALSE + -- because the object has underlying discriminants with defaults. + + if Present (Extra_Constrained (Formal)) then + if Is_Mutably_Tagged_Type (Etype (Actual)) + or else (Is_Private_Type (Etype (Prev)) + and then not Has_Discriminants + (Base_Type (Etype (Prev)))) + then + Add_Extra_Actual + (Expr => New_Occurrence_Of (Standard_False, Loc), + EF => Extra_Constrained (Formal)); + + elsif Is_Constrained (Etype (Formal)) + or else not Has_Discriminants (Etype (Prev)) + then + Add_Extra_Actual + (Expr => New_Occurrence_Of (Standard_True, Loc), + EF => Extra_Constrained (Formal)); + + -- Do not produce extra actuals for Unchecked_Union parameters. + -- Jump directly to the end of the loop. + + elsif Is_Unchecked_Union (Base_Type (Etype (Actual))) then + goto Skip_Extra_Actual_Generation; + + else + -- If the actual is a type conversion, then the constrained + -- test applies to the actual, not the target type. + + declare + Act_Prev : Node_Id; + + begin + -- Test for unchecked conversions as well, which can occur + -- as out parameter actuals on calls to stream procedures. + + Act_Prev := Prev; + while Nkind (Act_Prev) in N_Type_Conversion + | N_Unchecked_Type_Conversion + loop + Act_Prev := Expression (Act_Prev); + end loop; + + -- If the expression is a conversion of a dereference, this + -- is internally generated code that manipulates addresses, + -- e.g. when building interface tables. No check should + -- occur in this case, and the discriminated object is not + -- directly at hand. + + if not Comes_From_Source (Actual) + and then Nkind (Actual) = N_Unchecked_Type_Conversion + and then Nkind (Act_Prev) = N_Explicit_Dereference + then + Add_Extra_Actual + (Expr => New_Occurrence_Of (Standard_False, Loc), + EF => Extra_Constrained (Formal)); + + else + Add_Extra_Actual + (Expr => + Make_Attribute_Reference (Sloc (Prev), + Prefix => + Duplicate_Subexpr_No_Checks + (Act_Prev, Name_Req => True), + Attribute_Name => Name_Constrained), + EF => Extra_Constrained (Formal)); + end if; + end; + end if; + end if; + + -- Create possible extra actual for accessibility level + + if Present (Extra_Accessibility (Formal)) then + + -- Ada 2005 (AI-251): Thunks must propagate the extra actuals of + -- accessibility levels. + + if Is_Thunk (Current_Scope) then + declare + Parm_Ent : Entity_Id; + + begin + if Is_Controlling_Actual (Actual) then + + -- Find the corresponding actual of the thunk + + Parm_Ent := First_Entity (Current_Scope); + for J in 2 .. Param_Count loop + Next_Entity (Parm_Ent); + end loop; + + -- Handle unchecked conversion of access types generated + -- in thunks (cf. Expand_Interface_Thunk). + + elsif Is_Access_Type (Etype (Actual)) + and then Nkind (Actual) = N_Unchecked_Type_Conversion + then + Parm_Ent := Entity (Expression (Actual)); + + else pragma Assert (Is_Entity_Name (Actual)); + Parm_Ent := Entity (Actual); + end if; + + Add_Extra_Actual + (Expr => Accessibility_Level + (Expr => Parm_Ent, + Level => Dynamic_Level, + Allow_Alt_Model => False), + EF => Extra_Accessibility (Formal)); + end; + + -- Conditional expressions + + elsif Nkind (Prev) = N_Expression_With_Actions + and then Nkind (Original_Node (Prev)) in + N_If_Expression | N_Case_Expression + then + Add_Cond_Expression_Extra_Actual (Formal); + + -- Internal constant generated to remove side effects (normally + -- from the expansion of dispatching calls). + + -- First verify the actual is internal + + elsif not Comes_From_Source (Prev) + and then not Is_Rewrite_Substitution (Prev) + + -- Next check that the actual is a constant + + and then Nkind (Prev) = N_Identifier + and then Ekind (Entity (Prev)) = E_Constant + and then Nkind (Parent (Entity (Prev))) = N_Object_Declaration + then + -- Generate the accessibility level based on the expression in + -- the constant's declaration. + + declare + Ent : Entity_Id := Entity (Prev); + + begin + -- Handle deferred constants + + if Present (Full_View (Ent)) then + Ent := Full_View (Ent); + end if; + + Add_Extra_Actual + (Expr => Accessibility_Level + (Expr => Expression (Parent (Ent)), + Level => Dynamic_Level, + Allow_Alt_Model => False), + EF => Extra_Accessibility (Formal)); + end; + + -- Normal case + + else + Add_Extra_Actual + (Expr => Accessibility_Level + (Expr => Prev, + Level => Dynamic_Level, + Allow_Alt_Model => False), + EF => Extra_Accessibility (Formal)); + end if; + end if; + + -- This label is required when skipping extra actual generation for + -- Unchecked_Union parameters. + + <<Skip_Extra_Actual_Generation>> + + Param_Count := Param_Count + 1; + Next_Actual (Actual); + Next_Formal (Formal); + end loop; + + -- If we are calling an Ada 2012 function which needs to have the + -- "accessibility level determined by the point of call" (AI05-0234) + -- passed in to it, then pass it in. + + if Ekind (Subp) in E_Function | E_Operator | E_Subprogram_Type + and then + Present (Extra_Accessibility_Of_Result (Ultimate_Alias (Subp))) + then + declare + Extra_Form : Node_Id := Empty; + Level : Node_Id := Empty; + + begin + -- Detect cases where the function call has been internally + -- generated by examining the original node and return library + -- level - taking care to avoid ignoring function calls expanded + -- in prefix notation. + + if Nkind (Original_Node (Call_Node)) not in N_Function_Call + | N_Selected_Component + | N_Indexed_Component + then + Level := Make_Integer_Literal + (Loc, Scope_Depth (Standard_Standard)); + + -- Otherwise get the level normally based on the call node + + else + Level := Accessibility_Level + (Expr => Call_Node, + Level => Dynamic_Level, + Allow_Alt_Model => False); + end if; + + -- It may be possible that we are re-expanding an already + -- expanded call when are are dealing with dispatching ??? + + if No (Parameter_Associations (Call_Node)) + or else Nkind (Last (Parameter_Associations (Call_Node))) + /= N_Parameter_Association + or else not Is_Accessibility_Actual + (Last (Parameter_Associations (Call_Node))) + then + Extra_Form := Extra_Accessibility_Of_Result + (Ultimate_Alias (Subp)); + + Add_Extra_Actual + (Expr => Level, + EF => Extra_Form); + end if; + end; + end if; + + -- Second step: In the previous loop we gathered the extra actuals (the + -- ones that correspond to Extra_Formals), so now they can be appended. + + if Is_Non_Empty_List (Extra_Actuals) then + declare + Num_Extra_Actuals : constant Nat := List_Length (Extra_Actuals); + + begin + while Is_Non_Empty_List (Extra_Actuals) loop + Add_Actual_Parameter (Remove_Head (Extra_Actuals)); + end loop; + + -- Add dummy extra BIP actuals if we are calling a function that + -- inherited the BIP extra actuals but does not require them. + + if Nkind (Call_Node) = N_Function_Call + and then Is_Function_Call_With_BIP_Formals (Call_Node) + and then not Is_Build_In_Place_Function_Call (Call_Node) + then + Add_Dummy_Build_In_Place_Actuals (Subp, + Num_Added_Extra_Actuals => Num_Extra_Actuals); + end if; + end; + + -- Add dummy extra BIP actuals if we are calling a function that + -- inherited the BIP extra actuals but does not require them. + + elsif Nkind (Call_Node) = N_Function_Call + and then Is_Function_Call_With_BIP_Formals (Call_Node) + and then not Is_Build_In_Place_Function_Call (Call_Node) + then + Add_Dummy_Build_In_Place_Actuals (Subp); + end if; + + -- For non build-in-place calls formals and actuals must match; + -- for build-in-place function calls, the pending bip actuals are + -- added by the following subprograms as part of the bottom-up + -- expansion of the call (and this check will be performed there): + -- Make_Build_In_Place_Call_In_Allocator + -- Make_Build_In_Place_Call_In_Anonymous_Context + -- Make_Build_In_Place_Call_In_Assignment + -- Make_Build_In_Place_Call_In_Object_Declaration + -- Make_Build_In_Place_Iface_Call_In_Allocator + -- Make_Build_In_Place_Iface_Call_In_Anonymous_Context + -- Make_Build_In_Place_Iface_Call_In_Object_Declaration + + pragma Assert (Is_Build_In_Place_Function_Call (Call_Node) + or else (Check_Number_Of_Actuals (Call_Node, Subp) + and then Check_BIP_Actuals (Call_Node, Subp))); + end Create_Extra_Actuals; + + ------------------------ + -- Expand_Call_Helper -- + ------------------------ + + -- This procedure handles expansion of function calls and procedure call + -- statements (i.e. it serves as the body for Expand_N_Function_Call and + -- Expand_N_Procedure_Call_Statement). Processing for calls includes: + + -- Replace call to Raise_Exception by Raise_Exception_Always if possible + -- Provide values of actuals for all formals in Extra_Formals list + -- Replace "call" to enumeration literal function by literal itself + -- Rewrite call to predefined operator as operator + -- Replace actuals to in-out parameters that are numeric conversions, + -- with explicit assignment to temporaries before and after the call. + + -- Note that the list of actuals has been filled with default expressions + -- during semantic analysis of the call. Only the extra actuals required + -- for the 'Constrained attribute and for accessibility checks are added + -- at this point. + + procedure Expand_Call_Helper (N : Node_Id; Post_Call : out List_Id) is + Loc : constant Source_Ptr := Sloc (N); + Call_Node : Node_Id := N; + Prev : Node_Id := Empty; + + procedure Add_View_Conversion_Invariants + (Formal : Entity_Id; + Actual : Node_Id); + -- Adds invariant checks for every intermediate type between the range + -- of a view converted argument to its ancestor (from parent to child). + + function Can_Fold_Predicate_Call (P : Entity_Id) return Boolean; + -- Try to constant-fold a predicate check, which often enough is a + -- simple arithmetic expression that can be computed statically if + -- its argument is static. This cleans up the output of CCG, even + -- though useless predicate checks will be generally removed by + -- back-end optimizations. + + procedure Check_Subprogram_Variant; + -- Emit a call to the internally generated procedure with checks for + -- aspect Subprogram_Variant, if present and enabled. + + function Inherited_From_Formal (S : Entity_Id) return Entity_Id; + -- Within an instance, a type derived from an untagged formal derived + -- type inherits from the original parent, not from the actual. The + -- current derivation mechanism has the derived type inherit from the + -- actual, which is only correct outside of the instance. If the + -- subprogram is inherited, we test for this particular case through a + -- convoluted tree traversal before setting the proper subprogram to be + -- called. + + function In_Unfrozen_Instance (E : Entity_Id) return Boolean; + -- Return true if E comes from an instance that is not yet frozen + + function Is_Class_Wide_Interface_Type (E : Entity_Id) return Boolean; + -- Return True when E is a class-wide interface type or an access to + -- a class-wide interface type. + + function Is_Direct_Deep_Call (Subp : Entity_Id) return Boolean; + -- Determine if Subp denotes a non-dispatching call to a Deep routine + + function New_Value (From : Node_Id) return Node_Id; + -- From is the original Expression. New_Value is equivalent to a call + -- to Duplicate_Subexpr with an explicit dereference when From is an + -- access parameter. + + ------------------------------------ + -- Add_View_Conversion_Invariants -- + ------------------------------------ + + procedure Add_View_Conversion_Invariants + (Formal : Entity_Id; + Actual : Node_Id) + is + Arg : Entity_Id; + Curr_Typ : Entity_Id; + Inv_Checks : List_Id; + Par_Typ : Entity_Id; + + begin + Inv_Checks := No_List; + + -- Extract the argument from a potentially nested set of view + -- conversions. + + Arg := Actual; + while Nkind (Arg) = N_Type_Conversion loop + Arg := Expression (Arg); + end loop; + + -- Move up the derivation chain starting with the type of the formal + -- parameter down to the type of the actual object. + + Curr_Typ := Empty; + Par_Typ := Etype (Arg); + while Par_Typ /= Etype (Formal) and Par_Typ /= Curr_Typ loop + Curr_Typ := Par_Typ; + + if Has_Invariants (Curr_Typ) + and then Present (Invariant_Procedure (Curr_Typ)) + then + -- Verify the invariant of the current type. Generate: + + -- <Curr_Typ>Invariant (Curr_Typ (Arg)); + + Prepend_New_To (Inv_Checks, + Make_Procedure_Call_Statement (Loc, + Name => + New_Occurrence_Of + (Invariant_Procedure (Curr_Typ), Loc), + Parameter_Associations => New_List ( + Make_Type_Conversion (Loc, + Subtype_Mark => New_Occurrence_Of (Curr_Typ, Loc), + Expression => New_Copy_Tree (Arg))))); + end if; + + Par_Typ := Base_Type (Etype (Curr_Typ)); + end loop; + + -- If the node is a function call the generated tests have been + -- already handled in Insert_Post_Call_Actions. + + if not Is_Empty_List (Inv_Checks) + and then Nkind (Call_Node) = N_Procedure_Call_Statement + then + Insert_Actions_After (Call_Node, Inv_Checks); + end if; + end Add_View_Conversion_Invariants; + + ----------------------------- + -- Can_Fold_Predicate_Call -- + ----------------------------- + + function Can_Fold_Predicate_Call (P : Entity_Id) return Boolean is + Actual : Node_Id; + + function Augments_Other_Dynamic_Predicate (DP_Aspect_Spec : Node_Id) + return Boolean; + -- Given a Dynamic_Predicate aspect aspecification for a + -- discrete type, returns True iff another DP specification + -- applies (indirectly, via a subtype type or a derived type) + -- to the same entity that this aspect spec applies to. + + function May_Fold (N : Node_Id) return Traverse_Result; + -- The predicate expression is foldable if it only contains operators + -- and literals. During this check, we also replace occurrences of + -- the formal of the constructed predicate function with the static + -- value of the actual. This is done on a copy of the analyzed + -- expression for the predicate. -------------------------------------- -- Augments_Other_Dynamic_Predicate -- @@ -3952,6 +4307,9 @@ package body Exp_Ch6 is Subp : Entity_Id; CW_Interface_Formals_Present : Boolean := False; + Defer_Extra_Actuals : Boolean := False; + + use Deferred_Extra_Formals_Support; -- Start of processing for Expand_Call_Helper @@ -4038,12 +4396,6 @@ package body Exp_Ch6 is end if; end if; - -- Ensure that the called subprogram has all its formals - - if not Is_Frozen (Subp) then - Create_Extra_Formals (Subp); - end if; - -- Ada 2005 (AI-345): We have a procedure call as a triggering -- alternative in an asynchronous select or as an entry call in -- a conditional or timed select. Check whether the procedure call @@ -4089,257 +4441,110 @@ package body Exp_Ch6 is end; end if; - -- If this is a call to a predicate function, try to constant fold it - - if Nkind (Call_Node) = N_Function_Call - and then Is_Entity_Name (Name (Call_Node)) - and then Is_Predicate_Function (Subp) - and then Can_Fold_Predicate_Call (Subp) - then - return; - end if; - - -- First step, compute extra actuals, corresponding to any Extra_Formals - -- present. Note that we do not access Extra_Formals directly, instead - -- we simply note the presence of the extra formals as we process the - -- regular formals collecting corresponding actuals in Extra_Actuals. - - -- We also generate any required range checks for actuals for in formals - -- as we go through the loop, since this is a convenient place to do it. - -- (Though it seems that this would be better done in Expand_Actuals???) - - -- Special case: Thunks must not compute the extra actuals; they must - -- just propagate to the target primitive their extra actuals. - - if Is_Thunk (Current_Scope) - and then Thunk_Entity (Current_Scope) = Subp - and then Present (Extra_Formals (Subp)) - then - pragma Assert (Extra_Formals_Match_OK (Current_Scope, Subp)); - - declare - Target_Formal : Entity_Id; - Thunk_Formal : Entity_Id; - - begin - Target_Formal := Extra_Formals (Subp); - Thunk_Formal := Extra_Formals (Current_Scope); - while Present (Target_Formal) loop - Add_Extra_Actual - (Expr => New_Occurrence_Of (Thunk_Formal, Loc), - EF => Thunk_Formal); - - Target_Formal := Extra_Formal (Target_Formal); - Thunk_Formal := Extra_Formal (Thunk_Formal); - end loop; - - while Is_Non_Empty_List (Extra_Actuals) loop - Add_Actual_Parameter (Remove_Head (Extra_Actuals)); - end loop; - - -- Mark the call as processed build-in-place call; required - -- to avoid adding the extra formals twice. - - if Nkind (Call_Node) = N_Function_Call then - Set_Is_Expanded_Build_In_Place_Call (Call_Node); - end if; - - Expand_Actuals (Call_Node, Subp, Post_Call); - pragma Assert (Is_Empty_List (Post_Call)); - pragma Assert (Check_Number_Of_Actuals (Call_Node, Subp)); - pragma Assert (Check_BIP_Actuals (Call_Node, Subp)); - return; - end; - end if; - - Formal := First_Formal (Subp); - Actual := First_Actual (Call_Node); - Param_Count := 1; - while Present (Formal) loop - -- Prepare to examine current entry - - Prev := Actual; - - -- Ada 2005 (AI-251): Check if any formal is a class-wide interface - -- to expand it in a further round. - - CW_Interface_Formals_Present := - CW_Interface_Formals_Present - or else Is_Class_Wide_Interface_Type (Etype (Formal)); - - -- Create possible extra actual for constrained case. Usually, the - -- extra actual is of the form actual'constrained, but since this - -- attribute is only available for unconstrained records, TRUE is - -- expanded if the type of the formal happens to be constrained (for - -- instance when this procedure is inherited from an unconstrained - -- record to a constrained one) or if the actual has no discriminant - -- (its type is constrained). An exception to this is the case of a - -- private type without discriminants. In this case we pass FALSE - -- because the object has underlying discriminants with defaults. - - if Present (Extra_Constrained (Formal)) then - if Is_Mutably_Tagged_Type (Etype (Actual)) - or else (Is_Private_Type (Etype (Prev)) - and then not Has_Discriminants - (Base_Type (Etype (Prev)))) - then - Add_Extra_Actual - (Expr => New_Occurrence_Of (Standard_False, Loc), - EF => Extra_Constrained (Formal)); - - elsif Is_Constrained (Etype (Formal)) - or else not Has_Discriminants (Etype (Prev)) - then - Add_Extra_Actual - (Expr => New_Occurrence_Of (Standard_True, Loc), - EF => Extra_Constrained (Formal)); - - -- Do not produce extra actuals for Unchecked_Union parameters. - -- Jump directly to the end of the loop. - - elsif Is_Unchecked_Union (Base_Type (Etype (Actual))) then - goto Skip_Extra_Actual_Generation; + -- Ensure that the called subprogram has all its formals; extra formals + -- of init procs were added when they were built. - else - -- If the actual is a type conversion, then the constrained - -- test applies to the actual, not the target type. + if not Extra_Formals_Known (Subp) then + Create_Extra_Formals (Subp); - declare - Act_Prev : Node_Id; + -- If the previous call to Create_Extra_Formals could not add the + -- extra formals, then we must defer adding the extra actuals of + -- this call until we know the underlying type of all the formals + -- and return type of the called subprogram or entry. Deferral of + -- extra actuals occurs in two cases: + -- 1) In the body of internally built dynamic call helpers of + -- class-wide preconditions. + -- 2) In the body of expanded expression functions. - begin - -- Test for unchecked conversions as well, which can occur - -- as out parameter actuals on calls to stream procedures. + if not Extra_Formals_Known (Subp) then + declare + Scop_Id : Entity_Id := Current_Scope; - Act_Prev := Prev; - while Nkind (Act_Prev) in N_Type_Conversion - | N_Unchecked_Type_Conversion - loop - Act_Prev := Expression (Act_Prev); - end loop; + begin + -- Locate the enclosing subprogram or entry since it is + -- required to register this deferred call. - -- If the expression is a conversion of a dereference, this - -- is internally generated code that manipulates addresses, - -- e.g. when building interface tables. No check should - -- occur in this case, and the discriminated object is not - -- directly at hand. + Scop_Id := Current_Scope; + while Present (Scop_Id) + and then Scop_Id /= Standard_Standard + and then not Is_Subprogram_Or_Entry (Scop_Id) + loop + Scop_Id := Scope (Scop_Id); + end loop; - if not Comes_From_Source (Actual) - and then Nkind (Actual) = N_Unchecked_Type_Conversion - and then Nkind (Act_Prev) = N_Explicit_Dereference - then - Add_Extra_Actual - (Expr => New_Occurrence_Of (Standard_False, Loc), - EF => Extra_Constrained (Formal)); + pragma Assert (Is_Subprogram_Or_Entry (Scop_Id)); + pragma Assert (Is_Deferred_Extra_Formals_Entity (Subp)); + Register_Deferred_Extra_Formals_Call (Call_Node, Scop_Id); - else - Add_Extra_Actual - (Expr => - Make_Attribute_Reference (Sloc (Prev), - Prefix => - Duplicate_Subexpr_No_Checks - (Act_Prev, Name_Req => True), - Attribute_Name => Name_Constrained), - EF => Extra_Constrained (Formal)); - end if; - end; - end if; + Defer_Extra_Actuals := True; + end; end if; + end if; - -- Create possible extra actual for accessibility level - - if Present (Extra_Accessibility (Formal)) then - -- Ada 2005 (AI-251): Thunks must propagate the extra actuals of - -- accessibility levels. - - if Is_Thunk (Current_Scope) then - declare - Parm_Ent : Entity_Id; - - begin - if Is_Controlling_Actual (Actual) then - - -- Find the corresponding actual of the thunk - - Parm_Ent := First_Entity (Current_Scope); - for J in 2 .. Param_Count loop - Next_Entity (Parm_Ent); - end loop; - - -- Handle unchecked conversion of access types generated - -- in thunks (cf. Expand_Interface_Thunk). - - elsif Is_Access_Type (Etype (Actual)) - and then Nkind (Actual) = N_Unchecked_Type_Conversion - then - Parm_Ent := Entity (Expression (Actual)); - - else pragma Assert (Is_Entity_Name (Actual)); - Parm_Ent := Entity (Actual); - end if; - - Add_Extra_Actual - (Expr => Accessibility_Level - (Expr => Parm_Ent, - Level => Dynamic_Level, - Allow_Alt_Model => False), - EF => Extra_Accessibility (Formal)); - end; + pragma Assert (Extra_Formals_Known (Subp) + or else Is_Deferred_Extra_Formals_Entity (Subp) + or else Is_Unsupported_Extra_Formals_Entity (Subp)); - -- Conditional expressions + -- If this is a call to a predicate function, try to constant fold it - elsif Nkind (Prev) = N_Expression_With_Actions - and then Nkind (Original_Node (Prev)) in - N_If_Expression | N_Case_Expression - then - Add_Cond_Expression_Extra_Actual (Formal); + if Nkind (Call_Node) = N_Function_Call + and then Is_Entity_Name (Name (Call_Node)) + and then Is_Predicate_Function (Subp) + and then Can_Fold_Predicate_Call (Subp) + then + return; + end if; - -- Internal constant generated to remove side effects (normally - -- from the expansion of dispatching calls). + -- First step, compute extra actuals, corresponding to any Extra_Formals + -- present. Note that we do not access Extra_Formals directly; instead + -- we simply note the presence of the extra formals as we process the + -- regular formals collecting corresponding actuals in Extra_Actuals. - -- First verify the actual is internal + -- We also generate any required range checks for actuals for in-mode + -- formals as we go through the loop, since this is a convenient place + -- to do it. (Though it seems that this would be better done in + -- Expand_Actuals???) - elsif not Comes_From_Source (Prev) - and then not Is_Rewrite_Substitution (Prev) + -- Special case: Thunks must not compute the extra actuals; they must + -- just propagate their extra actuals to the target primitive (this + -- propagation is performed by Create_Extra_Actuals). - -- Next check that the actual is a constant + if Is_Thunk (Current_Scope) + and then Thunk_Entity (Current_Scope) = Subp + and then Extra_Formals_Known (Subp) + and then Present (Extra_Formals (Subp)) + then + Create_Extra_Actuals (N); - and then Nkind (Prev) = N_Identifier - and then Ekind (Entity (Prev)) = E_Constant - and then Nkind (Parent (Entity (Prev))) = N_Object_Declaration - then - -- Generate the accessibility level based on the expression in - -- the constant's declaration. + -- Mark the call as an expanded build-in-place call; required + -- to avoid adding the extra formals twice. - declare - Ent : Entity_Id := Entity (Prev); + if Nkind (Call_Node) = N_Function_Call then + Set_Is_Expanded_Build_In_Place_Call (Call_Node); + end if; - begin - -- Handle deferred constants + Expand_Actuals (Call_Node, Subp, Post_Call); - if Present (Full_View (Ent)) then - Ent := Full_View (Ent); - end if; + pragma Assert (Is_Empty_List (Post_Call)); + pragma Assert (Check_Number_Of_Actuals (Call_Node, Subp)); + pragma Assert (Check_BIP_Actuals (Call_Node, Subp)); + return; + end if; - Add_Extra_Actual - (Expr => Accessibility_Level - (Expr => Expression (Parent (Ent)), - Level => Dynamic_Level, - Allow_Alt_Model => False), - EF => Extra_Accessibility (Formal)); - end; + Formal := First_Formal (Subp); + Actual := First_Actual (Call_Node); + Param_Count := 1; + while Present (Formal) loop + -- Prepare to examine current entry - -- Normal case + Prev := Actual; - else - Add_Extra_Actual - (Expr => Accessibility_Level - (Expr => Prev, - Level => Dynamic_Level, - Allow_Alt_Model => False), - EF => Extra_Accessibility (Formal)); - end if; - end if; + -- Ada 2005 (AI-251): Check if any formal is a class-wide interface + -- to expand it in a further round. + + CW_Interface_Formals_Present := + CW_Interface_Formals_Present + or else Is_Class_Wide_Interface_Type (Etype (Formal)); -- Perform the check of 4.6(49) that prevents a null value from being -- passed as an actual to an access parameter. Note that the check @@ -4534,66 +4739,11 @@ package body Exp_Ch6 is -- This label is required when skipping extra actual generation for -- Unchecked_Union parameters. - <<Skip_Extra_Actual_Generation>> - Param_Count := Param_Count + 1; Next_Actual (Actual); Next_Formal (Formal); end loop; - -- If we are calling an Ada 2012 function which needs to have the - -- "accessibility level determined by the point of call" (AI05-0234) - -- passed in to it, then pass it in. - - if Ekind (Subp) in E_Function | E_Operator | E_Subprogram_Type - and then - Present (Extra_Accessibility_Of_Result (Ultimate_Alias (Subp))) - then - declare - Extra_Form : Node_Id := Empty; - Level : Node_Id := Empty; - - begin - -- Detect cases where the function call has been internally - -- generated by examining the original node and return library - -- level - taking care to avoid ignoring function calls expanded - -- in prefix notation. - - if Nkind (Original_Node (Call_Node)) not in N_Function_Call - | N_Selected_Component - | N_Indexed_Component - then - Level := Make_Integer_Literal - (Loc, Scope_Depth (Standard_Standard)); - - -- Otherwise get the level normally based on the call node - - else - Level := Accessibility_Level - (Expr => Call_Node, - Level => Dynamic_Level, - Allow_Alt_Model => False); - end if; - - -- It may be possible that we are re-expanding an already - -- expanded call when are are dealing with dispatching ??? - - if No (Parameter_Associations (Call_Node)) - or else Nkind (Last (Parameter_Associations (Call_Node))) - /= N_Parameter_Association - or else not Is_Accessibility_Actual - (Last (Parameter_Associations (Call_Node))) - then - Extra_Form := Extra_Accessibility_Of_Result - (Ultimate_Alias (Subp)); - - Add_Extra_Actual - (Expr => Level, - EF => Extra_Form); - end if; - end; - end if; - -- If we are expanding the RHS of an assignment we need to check if tag -- propagation is needed. You might expect this processing to be in -- Analyze_Assignment but has to be done earlier (bottom-up) because the @@ -4606,27 +4756,34 @@ package body Exp_Ch6 is then declare Ass : Node_Id := Empty; + Par : Node_Id := Parent (Call_Node); begin - if Nkind (Parent (Call_Node)) = N_Assignment_Statement then - Ass := Parent (Call_Node); + -- Search for the LHS of an enclosing assignment statement to a + -- classwide type object (if present) and propagate the tag to + -- this function call. + + while Nkind (Par) in N_Case_Expression + | N_Case_Expression_Alternative + | N_Explicit_Dereference + | N_If_Expression + | N_Qualified_Expression + | N_Unchecked_Type_Conversion + loop + if Nkind (Par) = N_Case_Expression_Alternative then + Par := Parent (Par); + end if; - elsif Nkind (Parent (Call_Node)) = N_Qualified_Expression - and then Nkind (Parent (Parent (Call_Node))) = - N_Assignment_Statement - then - Ass := Parent (Parent (Call_Node)); + exit when not Is_Tag_Indeterminate (Par); - elsif Nkind (Parent (Call_Node)) = N_Explicit_Dereference - and then Nkind (Parent (Parent (Call_Node))) = - N_Assignment_Statement - then - Ass := Parent (Parent (Call_Node)); - end if; + Par := Parent (Par); + end loop; - if Present (Ass) - and then Is_Class_Wide_Type (Etype (Name (Ass))) + if Nkind (Par) = N_Assignment_Statement + and then Is_Class_Wide_Type (Etype (Name (Par))) then + Ass := Par; + -- Move the error messages below to sem??? if Is_Access_Type (Etype (Call_Node)) then @@ -4639,6 +4796,12 @@ package body Exp_Ch6 is Call_Node, Root_Type (Etype (Name (Ass)))); else Propagate_Tag (Name (Ass), Call_Node); + + -- Remember that the tag has been propagated to avoid + -- propagating it again, as part of the (bottom-up) + -- analysis of the enclosing assignment. + + Set_Tag_Propagated (Name (Ass)); end if; elsif Etype (Call_Node) /= Root_Type (Etype (Name (Ass))) then @@ -4649,6 +4812,12 @@ package body Exp_Ch6 is else Propagate_Tag (Name (Ass), Call_Node); + + -- Remember that the tag has been propagated to avoid + -- propagating it again, as part of the (bottom-up) + -- analysis of the enclosing assignment. + + Set_Tag_Propagated (Name (Ass)); end if; -- The call will be rewritten as a dispatching call, and @@ -4787,38 +4956,12 @@ package body Exp_Ch6 is then null; - -- During that loop we gathered the extra actuals (the ones that - -- correspond to Extra_Formals), so now they can be appended. - - elsif Is_Non_Empty_List (Extra_Actuals) then - declare - Num_Extra_Actuals : constant Nat := List_Length (Extra_Actuals); - - begin - while Is_Non_Empty_List (Extra_Actuals) loop - Add_Actual_Parameter (Remove_Head (Extra_Actuals)); - end loop; - - -- Add dummy extra BIP actuals if we are calling a function that - -- inherited the BIP extra actuals but does not require them. - - if Nkind (Call_Node) = N_Function_Call - and then Is_Function_Call_With_BIP_Formals (Call_Node) - and then not Is_Build_In_Place_Function_Call (Call_Node) - then - Add_Dummy_Build_In_Place_Actuals (Subp, - Num_Added_Extra_Actuals => Num_Extra_Actuals); - end if; - end; - - -- Add dummy extra BIP actuals if we are calling a function that - -- inherited the BIP extra actuals but does not require them. + elsif not Defer_Extra_Actuals then + Create_Extra_Formals (Subp); - elsif Nkind (Call_Node) = N_Function_Call - and then Is_Function_Call_With_BIP_Formals (Call_Node) - and then not Is_Build_In_Place_Function_Call (Call_Node) - then - Add_Dummy_Build_In_Place_Actuals (Subp); + if Extra_Formals_Known (Subp) then + Create_Extra_Actuals (N); + end if; end if; -- At this point we have all the actuals, so this is the point at which @@ -5236,6 +5379,10 @@ package body Exp_Ch6 is -- also Build_Renamed_Body) cannot be expanded here because this may -- give rise to order-of-elaboration issues for the types of the -- parameters of the subprogram, if any. + -- + -- Expand_Inlined_Call procedure does not support the frontend + -- inlining of calls that return unconstrained types used as actuals + -- or in return statements. elsif Present (Unit_Declaration_Node (Subp)) and then Nkind (Unit_Declaration_Node (Subp)) = @@ -5244,6 +5391,8 @@ package body Exp_Ch6 is and then Nkind (Body_To_Inline (Unit_Declaration_Node (Subp))) not in N_Entity + and then Nkind (Parent (N)) /= N_Function_Call + and then Nkind (Parent (N)) /= N_Simple_Return_Statement then Expand_Inlined_Call (Call_Node, Subp, Orig_Subp); @@ -5375,7 +5524,7 @@ package body Exp_Ch6 is -- to copy/readjust/finalize, we can just pass the value through (see -- Expand_N_Simple_Return_Statement), and thus no attachment is needed. -- Note that simple return statements are distributed into conditional - -- expressions but we may be invoked before this distribution is done. + -- expressions, but we may be invoked before this distribution is done. if Nkind (Uncond_Par) = N_Simple_Return_Statement then return; @@ -5396,9 +5545,14 @@ package body Exp_Ch6 is end if; -- Note that object declarations are also distributed into conditional - -- expressions but we may be invoked before this distribution is done. + -- expressions, but we may be invoked before this distribution is done. + -- However that's not the case for the declarations of return objects, + -- see the twin Is_Optimizable_Declaration predicates that are present + -- in Expand_N_Case_Expression and Expand_N_If_Expression of Exp_Ch4. - elsif Nkind (Uncond_Par) = N_Object_Declaration then + elsif Nkind (Uncond_Par) = N_Object_Declaration + and then not Is_Return_Object (Defining_Identifier (Uncond_Par)) + then return; end if; @@ -5412,6 +5566,16 @@ package body Exp_Ch6 is return; end if; + -- Another optimization: if the returned value is used to initialize the + -- component of an aggregate, then no need to copy/readjust/finalize, we + -- can initialize it in place. Note that assignments for aggregates are + -- also distributed into conditional expressions, but we may be invoked + -- before this distribution is done. + + if Parent_Is_Regular_Aggregate (Uncond_Par) then + return; + end if; + -- Avoid expansion to catch the error when the function call is on the -- left-hand side of an assignment. Likewise if it is on the right-hand -- side and no controlling actions will be performed for the assignment, @@ -5764,7 +5928,7 @@ package body Exp_Ch6 is exception when RE_Not_Available => - return; + null; end Expand_N_Simple_Return_Statement; ------------------------------ @@ -8551,6 +8715,8 @@ package body Exp_Ch6 is Rewrite (Allocator, New_Occurrence_Of (Return_Obj_Access, Loc)); Analyze_And_Resolve (Allocator, Acc_Type); + + pragma Assert (Returns_By_Ref (Function_Id)); pragma Assert (Check_Number_Of_Actuals (Func_Call, Function_Id)); pragma Assert (Check_BIP_Actuals (Func_Call, Function_Id)); end Make_Build_In_Place_Call_In_Allocator; @@ -8562,12 +8728,10 @@ package body Exp_Ch6 is procedure Make_Build_In_Place_Call_In_Anonymous_Context (Function_Call : Node_Id) is - Loc : constant Source_Ptr := Sloc (Function_Call); - Func_Call : constant Node_Id := Unqual_Conv (Function_Call); - Function_Id : Entity_Id; - Result_Subt : Entity_Id; - Return_Obj_Id : Entity_Id; - Return_Obj_Decl : Entity_Id; + Loc : constant Source_Ptr := Sloc (Function_Call); + Func_Call : constant Node_Id := Unqual_Conv (Function_Call); + Function_Id : Entity_Id; + Result_Subt : Entity_Id; begin -- If the call has already been processed to add build-in-place actuals @@ -8580,10 +8744,6 @@ package body Exp_Ch6 is return; end if; - -- Mark the call as processed as a build-in-place call - - Set_Is_Expanded_Build_In_Place_Call (Func_Call); - if Is_Entity_Name (Name (Func_Call)) then Function_Id := Entity (Name (Func_Call)); @@ -8601,8 +8761,13 @@ package body Exp_Ch6 is -- If the build-in-place function returns a controlled object, then the -- object needs to be finalized immediately after the context. Since -- this case produces a transient scope, the servicing finalizer needs - -- to name the returned object. Create a temporary which is initialized - -- with the function call: + -- to name the returned object. + + -- If the build-in-place function returns a definite subtype, then an + -- object also needs to be created and an access value designating it + -- passed as an actual. + + -- Create a temporary which is initialized with the function call: -- -- Temp_Id : Func_Type := BIP_Func_Call; -- @@ -8610,75 +8775,25 @@ package body Exp_Ch6 is -- the expander using the appropriate mechanism in Make_Build_In_Place_ -- Call_In_Object_Declaration. - if Needs_Finalization (Result_Subt) then + if Needs_Finalization (Result_Subt) + or else Caller_Known_Size (Func_Call, Result_Subt) + then declare Temp_Id : constant Entity_Id := Make_Temporary (Loc, 'R'); - Temp_Decl : Node_Id; - - begin - -- Reset the guard on the function call since the following does - -- not perform actual call expansion. - - Set_Is_Expanded_Build_In_Place_Call (Func_Call, False); - - Temp_Decl := + Temp_Decl : constant Node_Id := Make_Object_Declaration (Loc, Defining_Identifier => Temp_Id, - Object_Definition => - New_Occurrence_Of (Result_Subt, Loc), - Expression => - New_Copy_Tree (Function_Call)); + Aliased_Present => True, + Object_Definition => New_Occurrence_Of (Result_Subt, Loc), + Expression => Relocate_Node (Function_Call)); + begin + Set_Assignment_OK (Temp_Decl); Insert_Action (Function_Call, Temp_Decl); - Rewrite (Function_Call, New_Occurrence_Of (Temp_Id, Loc)); Analyze (Function_Call); end; - -- When the result subtype is definite, an object of the subtype is - -- declared and an access value designating it is passed as an actual. - - elsif Caller_Known_Size (Func_Call, Result_Subt) then - - -- Create a temporary object to hold the function result - - Return_Obj_Id := Make_Temporary (Loc, 'R'); - Set_Etype (Return_Obj_Id, Result_Subt); - - Return_Obj_Decl := - Make_Object_Declaration (Loc, - Defining_Identifier => Return_Obj_Id, - Aliased_Present => True, - Object_Definition => New_Occurrence_Of (Result_Subt, Loc)); - - Set_No_Initialization (Return_Obj_Decl); - - Insert_Action (Func_Call, Return_Obj_Decl); - - -- When the function has a controlling result, an allocation-form - -- parameter must be passed indicating that the caller is allocating - -- the result object. This is needed because such a function can be - -- called as a dispatching operation and must be treated similarly - -- to functions with unconstrained result subtypes. - - Add_Unconstrained_Actuals_To_Build_In_Place_Call - (Func_Call, Function_Id, Alloc_Form => Caller_Allocation); - - Add_Collection_Actual_To_Build_In_Place_Call - (Func_Call, Function_Id); - - Add_Task_Actuals_To_Build_In_Place_Call - (Func_Call, Function_Id, Make_Identifier (Loc, Name_uMaster)); - - -- Add an implicit actual to the function call that provides access - -- to the caller's return object. - - Add_Access_Actual_To_Build_In_Place_Call - (Func_Call, Function_Id, New_Occurrence_Of (Return_Obj_Id, Loc)); - - pragma Assert (Check_Number_Of_Actuals (Func_Call, Function_Id)); - pragma Assert (Check_BIP_Actuals (Func_Call, Function_Id)); - -- When the result subtype is unconstrained, the function must allocate -- the return object in the secondary stack, so appropriate implicit -- parameters are added to the call to indicate that. A transient @@ -8703,6 +8818,11 @@ package body Exp_Ch6 is Add_Access_Actual_To_Build_In_Place_Call (Func_Call, Function_Id, Empty); + -- Mark the call as processed as a build-in-place call + + Set_Is_Expanded_Build_In_Place_Call (Func_Call); + + pragma Assert (Returns_By_Ref (Function_Id)); pragma Assert (Check_Number_Of_Actuals (Func_Call, Function_Id)); pragma Assert (Check_BIP_Actuals (Func_Call, Function_Id)); end if; @@ -8804,6 +8924,8 @@ package body Exp_Ch6 is Insert_After_And_Analyze (Ptr_Typ_Decl, Obj_Decl); Rewrite (Assign, Make_Null_Statement (Loc)); + + pragma Assert (Returns_By_Ref (Func_Id)); pragma Assert (Check_Number_Of_Actuals (Func_Call, Func_Id)); pragma Assert (Check_BIP_Actuals (Func_Call, Func_Id)); end Make_Build_In_Place_Call_In_Assignment; @@ -8873,6 +8995,25 @@ package body Exp_Ch6 is and then not Has_Foreign_Convention (Return_Applies_To (Scope (Obj_Def_Id))); + Constraint_Check_Needed : constant Boolean := + (Has_Discriminants (Obj_Typ) or else Is_Array_Type (Obj_Typ)) + and then Is_Tagged_Type (Obj_Typ) + and then Nkind (Original_Node (Obj_Decl)) /= + N_Object_Renaming_Declaration + and then Is_Constrained (Obj_Typ); + -- We are processing a call in the context of something like + -- "X : T := F (...);". This is True if we need to do a constraint + -- check, because T has constrained bounds or discriminants, + -- and F is returning an unconstrained subtype. + -- We are currently doing the check at the call site, + -- which is possible only in the callee-allocates case, + -- which is why we have Is_Tagged_Type above. + -- ???The check is missing in the untagged caller-allocates case. + -- ???The check for renaming declarations above is needed because + -- Sem_Ch8.Analyze_Object_Renaming sometimes changes a renaming + -- into an object declaration. We probably shouldn't do that, + -- but for now, we need this check. + -- Start of processing for Make_Build_In_Place_Call_In_Object_Declaration begin @@ -8915,15 +9056,16 @@ package body Exp_Ch6 is Subtype_Indication => New_Occurrence_Of (Designated_Type, Loc))); - -- The access type and its accompanying object must be inserted after - -- the object declaration in the constrained case, so that the function - -- call can be passed access to the object. In the indefinite case, or + -- The access type and its object must be inserted after the object + -- declaration in the caller-allocates case, so that the function call + -- can be passed access to the object. In the caller-allocates case, or -- if the object declaration is for a return object, the access type and -- object must be inserted before the object, since the object -- declaration is rewritten to be a renaming of a dereference of the -- access object. - if Definite and then not Is_OK_Return_Object then + if Definite and not Is_OK_Return_Object and not Constraint_Check_Needed + then Insert_Action_After (Obj_Decl, Ptr_Typ_Decl); else Insert_Action (Obj_Decl, Ptr_Typ_Decl); @@ -9004,7 +9146,7 @@ package body Exp_Ch6 is -- to the (specific) result type of the function is inserted to handle -- the case where the object is declared with a class-wide type. - elsif Definite then + elsif Definite and not Constraint_Check_Needed then Caller_Object := Unchecked_Convert_To (Result_Subt, New_Occurrence_Of (Obj_Def_Id, Loc)); @@ -9142,8 +9284,8 @@ package body Exp_Ch6 is -- itself the return expression of an enclosing BIP function, then mark -- the object as having no initialization. - if Definite and then not Is_OK_Return_Object then - + if Definite and not Is_OK_Return_Object and not Constraint_Check_Needed + then Set_Expression (Obj_Decl, Empty); Set_No_Initialization (Obj_Decl); @@ -9202,8 +9344,13 @@ package body Exp_Ch6 is Analyze (Obj_Decl); Replace_Renaming_Declaration_Id (Obj_Decl, Original_Node (Obj_Decl)); + + if Constraint_Check_Needed then + Apply_Constraint_Check (Call_Deref, Obj_Typ); + end if; end if; + pragma Assert (Returns_By_Ref (Function_Id)); pragma Assert (Check_Number_Of_Actuals (Func_Call, Function_Id)); pragma Assert (Check_BIP_Actuals (Func_Call, Function_Id)); end Make_Build_In_Place_Call_In_Object_Declaration; @@ -9598,9 +9745,8 @@ package body Exp_Ch6 is -- such build-in-place functions, primitive or not. return not Restriction_Active (No_Finalization) - and then ((Needs_Finalization (Typ) - and then not Has_Relaxed_Finalization (Typ)) - or else Is_Tagged_Type (Typ)) + and then (Needs_Finalization (Typ) or else Is_Tagged_Type (Typ)) + and then not Has_Relaxed_Finalization (Typ) and then not Has_Foreign_Convention (Typ); end Needs_BIP_Collection; @@ -9842,35 +9988,16 @@ package body Exp_Ch6 is => declare Call_Node : Node_Id renames Nod; - Subp : Entity_Id; + Subp : constant Entity_Id := Get_Called_Entity (Nod); begin - -- Call using access to subprogram with explicit dereference - - if Nkind (Name (Call_Node)) = N_Explicit_Dereference then - Subp := Etype (Name (Call_Node)); - - -- Prefix notation calls - - elsif Nkind (Name (Call_Node)) = N_Selected_Component then - Subp := Entity (Selector_Name (Name (Call_Node))); - - -- Call to member of entry family, where Name is an indexed - -- component, with the prefix being a selected component - -- giving the task and entry family name, and the index - -- being the entry index. - - elsif Nkind (Name (Call_Node)) = N_Indexed_Component then - Subp := - Entity (Selector_Name (Prefix (Name (Call_Node)))); - - -- Normal case + pragma Assert (Check_BIP_Actuals (Call_Node, Subp)); - else - Subp := Entity (Name (Call_Node)); - end if; + -- Build-in-place function calls return their result by + -- reference. - pragma Assert (Check_BIP_Actuals (Call_Node, Subp)); + pragma Assert (not Is_Build_In_Place_Function (Subp) + or else Returns_By_Ref (Subp)); end; -- Skip generic bodies @@ -9909,6 +10036,13 @@ package body Exp_Ch6 is return Skip; end if; + -- Skip calls placed in unexpanded initialization expressions + + when N_Object_Declaration => + if No_Initialization (Nod) then + return Skip; + end if; + -- Skip calls placed in subprogram specifications since function -- calls initializing default parameter values will be processed -- when the call to the subprogram is found (if the default actual @@ -9964,15 +10098,15 @@ package body Exp_Ch6 is -- Start of processing for Validate_Subprogram_Calls begin - -- No action required if we are not generating code or compiling sources - -- that have errors. + -- No action if we are not generating code (including if we have + -- errors). - if Serious_Errors_Detected > 0 - or else Operating_Mode /= Generate_Code - then + if Operating_Mode /= Generate_Code then return; end if; + pragma Assert (Serious_Errors_Detected = 0); + Check_Calls (N); end Validate_Subprogram_Calls; diff --git a/gcc/ada/exp_ch6.ads b/gcc/ada/exp_ch6.ads index 118d994e605c..483b78bd1781 100644 --- a/gcc/ada/exp_ch6.ads +++ b/gcc/ada/exp_ch6.ads @@ -101,6 +101,10 @@ package Exp_Ch6 is -- Adds Extra_Actual as a named parameter association for the formal -- Extra_Formal in Subprogram_Call. + procedure Create_Extra_Actuals (Call_Node : Node_Id); + -- Create the extra actuals of the given call and add them to its + -- actual parameters list. + procedure Apply_CW_Accessibility_Check (Exp : Node_Id; Func : Entity_Id); -- Ada 2005 (AI95-344): If the result type is class-wide, insert a check -- that the level of the return expression's underlying type is not deeper diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb index 67af1d772631..dd864b7ffd36 100644 --- a/gcc/ada/exp_ch7.adb +++ b/gcc/ada/exp_ch7.adb @@ -59,6 +59,7 @@ with Sinfo.Nodes; use Sinfo.Nodes; with Sinfo.Utils; use Sinfo.Utils; with Sem; use Sem; with Sem_Aux; use Sem_Aux; +with Sem_Ch6; use Sem_Ch6; with Sem_Ch7; use Sem_Ch7; with Sem_Ch8; use Sem_Ch8; with Sem_Res; use Sem_Res; @@ -436,7 +437,7 @@ package body Exp_Ch7 is procedure Build_Record_Deep_Procs (Typ : Entity_Id); -- Build the deep Initialize/Adjust/Finalize for a record Typ with - -- Has_Component_Component set and store them using the TSS mechanism. + -- Has_Controlled_Component set and store them using the TSS mechanism. -------------------------------- -- Transient Scope Management -- @@ -696,6 +697,15 @@ package body Exp_Ch7 is -- Set the Finalize_Address primitive for the object that has been -- attached to a finalization Master_Node. + function Shift_Address_For_Descriptor + (Addr : Node_Id; + Typ : Entity_Id; + Op_Nam : Name_Id) return Node_Id + with Pre => Is_Array_Type (Typ) + and then not Is_Constrained (Typ) + and then Op_Nam in Name_Op_Add | Name_Op_Subtract; + -- Add to Addr, or subtract from Addr, the size of the descriptor of Typ + ---------------------------------- -- Attach_Object_To_Master_Node -- ---------------------------------- @@ -2322,6 +2332,8 @@ package body Exp_Ch7 is Ensure_Freeze_Node (Fin_Id); Insert_After (Fin_Spec, Freeze_Node (Fin_Id)); + Mutate_Ekind (Fin_Id, E_Procedure); + Freeze_Extra_Formals (Fin_Id); Set_Is_Frozen (Fin_Id); Append_To (Stmts, Fin_Body); @@ -2466,7 +2478,6 @@ package body Exp_Ch7 is -- Local variables Decl : Node_Id; - Expr : Node_Id; Obj_Id : Entity_Id; Obj_Typ : Entity_Id; Pack_Id : Entity_Id; @@ -2516,7 +2527,6 @@ package body Exp_Ch7 is elsif Nkind (Decl) = N_Object_Declaration then Obj_Id := Defining_Identifier (Decl); Obj_Typ := Base_Type (Etype (Obj_Id)); - Expr := Expression (Decl); -- Bypass any form of processing for objects which have their -- finalization disabled. This applies only to objects at the @@ -2572,21 +2582,10 @@ package body Exp_Ch7 is Processing_Actions (Decl, Strict => not Has_Relaxed_Finalization (Obj_Typ)); - -- The object is of the form: - -- Obj : Access_Typ := Non_BIP_Function_Call'reference; - - -- Obj : Access_Typ := - -- BIP_Function_Call (BIPalloc => 2, ...)'reference; + -- The object is an access-to-controlled that must be finalized elsif Is_Access_Type (Obj_Typ) - and then Needs_Finalization - (Available_View (Designated_Type (Obj_Typ))) - and then Present (Expr) - and then - (Is_Secondary_Stack_BIP_Func_Call (Expr) - or else - (Is_Non_BIP_Func_Call (Expr) - and then not Is_Related_To_Func_Return (Obj_Id))) + and then Is_Finalizable_Access (Decl) then Processing_Actions (Decl, @@ -2783,16 +2782,31 @@ package body Exp_Ch7 is Master_Node_Id := Make_Defining_Identifier (Master_Node_Loc, Chars => New_External_Name (Chars (Obj_Id), Suffix => "MN")); + Master_Node_Decl := Make_Master_Node_Declaration (Master_Node_Loc, Master_Node_Id, Obj_Id); Push_Scope (Scope (Obj_Id)); + + -- Avoid generating duplicate names for master nodes + + if Ekind (Obj_Id) = E_Loop_Parameter + and then + Present (Current_Entity_In_Scope (Chars (Master_Node_Id))) + then + Set_Chars (Master_Node_Id, + New_External_Name (Chars (Obj_Id), + Suffix => "MN", + Suffix_Index => -1)); + end if; + if not Has_Strict_Ctrl_Objs or else Count = 1 then Prepend_To (Decls, Master_Node_Decl); else Insert_Before (Decl, Master_Node_Decl); end if; + Analyze (Master_Node_Decl); Pop_Scope; @@ -3575,18 +3589,22 @@ package body Exp_Ch7 is procedure Build_Record_Deep_Procs (Typ : Entity_Id) is begin - Set_TSS (Typ, - Make_Deep_Proc - (Prim => Initialize_Case, - Typ => Typ, - Stmts => Make_Deep_Record_Body (Initialize_Case, Typ))); - - if not Is_Inherently_Limited_Type (Typ) then - Set_TSS (Typ, - Make_Deep_Proc - (Prim => Adjust_Case, - Typ => Typ, - Stmts => Make_Deep_Record_Body (Adjust_Case, Typ))); + if Has_Controlled_Component (Typ) then + Set_TSS + (Typ, + Make_Deep_Proc + (Prim => Initialize_Case, + Typ => Typ, + Stmts => Make_Deep_Record_Body (Initialize_Case, Typ))); + + if not Is_Inherently_Limited_Type (Typ) then + Set_TSS + (Typ, + Make_Deep_Proc + (Prim => Adjust_Case, + Typ => Typ, + Stmts => Make_Deep_Record_Body (Adjust_Case, Typ))); + end if; end if; -- Do not generate Deep_Finalize and Finalize_Address if finalization is @@ -5260,6 +5278,13 @@ package body Exp_Ch7 is Obj_Typ : Entity_Id; begin + -- Ignored Ghost objects do not need any cleanup actions because + -- they will not appear in the final tree. + + if Is_Ignored_Ghost_Entity (Obj_Id) then + return; + end if; + -- If the object needs to be exported to the outer finalizer, -- create the declaration of the Master_Node for the object, -- which will later be picked up by Build_Finalizer. @@ -5442,7 +5467,7 @@ package body Exp_Ch7 is -- Finalization calls are inserted after the target - if Present (Act_After) then + if Is_Non_Empty_List (Act_After) then Last_Obj := Last (Act_After); Insert_List_After (Target, Act_After); else @@ -5537,35 +5562,14 @@ package body Exp_Ch7 is -- an object with a dope vector (see Make_Finalize_Address_Stmts). -- This is achieved by setting Is_Constr_Array_Subt_With_Bounds, -- but the address of the object is still that of its elements, - -- so we need to shift it. + -- so we need to shift it back to skip the dope vector. if Is_Array_Type (Utyp) and then not Is_Constrained (First_Subtype (Utyp)) then - -- Shift the address from the start of the elements to the - -- start of the dope vector: - - -- V - (Utyp'Descriptor_Size / Storage_Unit) - Obj_Addr := - Make_Function_Call (Loc, - Name => - Make_Expanded_Name (Loc, - Chars => Name_Op_Subtract, - Prefix => - New_Occurrence_Of - (RTU_Entity (System_Storage_Elements), Loc), - Selector_Name => - Make_Identifier (Loc, Name_Op_Subtract)), - Parameter_Associations => New_List ( - Obj_Addr, - Make_Op_Divide (Loc, - Left_Opnd => - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Utyp, Loc), - Attribute_Name => Name_Descriptor_Size), - Right_Opnd => - Make_Integer_Literal (Loc, System_Storage_Unit)))); + Shift_Address_For_Descriptor + (Obj_Addr, First_Subtype (Utyp), Name_Op_Subtract); end if; return Obj_Addr; @@ -5601,7 +5605,10 @@ package body Exp_Ch7 is -- Deal with untagged derivation of private views - if Present (Utyp) and then Is_Untagged_Derivation (Typ) then + if Present (Utyp) + and then Is_Untagged_Derivation (Typ) + and then Is_Implicit_Full_View (Utyp) + then Utyp := Underlying_Type (Root_Type (Base_Type (Typ))); Ref := Unchecked_Convert_To (Utyp, Ref); Set_Assignment_OK (Ref); @@ -6638,6 +6645,16 @@ package body Exp_Ch7 is -- Raised : Boolean := False; -- -- begin + -- begin + -- <Destructor_Proc> (V); -- If applicable + -- exception + -- when others => + -- if not Raised then + -- Raised := True; + -- Save_Occurrence (E, Get_Current_Excep.all.all); + -- end if; + -- end; + -- -- if F then -- begin -- Finalize (V); -- If applicable @@ -6693,6 +6710,8 @@ package body Exp_Ch7 is -- -- begin -- Deep_Finalize (V._parent, False); -- If applicable + -- or + -- Deep_Finalize (Parent_Type (V), False); -- Untagged case -- exception -- when Id : others => -- if not Raised then @@ -7097,7 +7116,7 @@ package body Exp_Ch7 is -- or the type is not controlled. if Is_Empty_List (Bod_Stmts) then - Append_To (Bod_Stmts, Make_Null_Statement (Loc)); + Append_New_To (Bod_Stmts, Make_Null_Statement (Loc)); return Bod_Stmts; @@ -7584,9 +7603,13 @@ package body Exp_Ch7 is -- Deep_Finalize (Obj._parent, False); - if Is_Tagged_Type (Typ) and then Is_Derived_Type (Typ) then + if Is_Derived_Type (Typ) then declare - Par_Typ : constant Entity_Id := Parent_Field_Type (Typ); + Tagd : constant Boolean := Is_Tagged_Type (Typ); + Par_Typ : constant Entity_Id := + (if Tagd + then Parent_Field_Type (Typ) + else Etype (Base_Type (Typ))); Call : Node_Id; Fin_Stmt : Node_Id; @@ -7595,10 +7618,16 @@ package body Exp_Ch7 is Call := Make_Final_Call (Obj_Ref => - Make_Selected_Component (Loc, - Prefix => Make_Identifier (Loc, Name_V), - Selector_Name => - Make_Identifier (Loc, Name_uParent)), + (if Tagd + then + Make_Selected_Component + (Loc, + Prefix => Make_Identifier (Loc, Name_V), + Selector_Name => + Make_Identifier (Loc, Name_uParent)) + else + Convert_To + (Par_Typ, Make_Identifier (Loc, Name_V))), Typ => Par_Typ, Skip_Self => True); @@ -7606,6 +7635,21 @@ package body Exp_Ch7 is -- begin -- Deep_Finalize (V._parent, False); + -- exception + -- when Id : others => + -- if not Raised then + -- Raised := True; + -- Save_Occurrence (E, + -- Get_Current_Excep.all.all); + -- end if; + -- end; + -- + -- in the tagged case. In the untagged case, which arises + -- with the Destructor aspect, generate: + -- + -- begin + -- Deep_Finalize (Parent_Type (V), False); + -- exception -- when Id : others => -- if not Raised then @@ -7659,7 +7703,7 @@ package body Exp_Ch7 is -- than before, the extension components. That might -- be more intuitive (as discussed in preceding -- comment), but it is not required. - Prepend_To (Bod_Stmts, Fin_Stmt); + Prepend_New_To (Bod_Stmts, Fin_Stmt); end if; end if; end if; @@ -7710,12 +7754,58 @@ package body Exp_Ch7 is (Finalizer_Data)))); end if; - Prepend_To (Bod_Stmts, + Prepend_New_To (Bod_Stmts, Make_If_Statement (Loc, Condition => Make_Identifier (Loc, Name_F), Then_Statements => New_List (Fin_Stmt))); end if; end; + + declare + ASN : constant Opt_N_Aspect_Specification_Id := + Get_Rep_Item (Typ, Name_Destructor, False); + + Stmt : Node_Id; + Proc : Entity_Id; + begin + if Present (ASN) then + -- Generate: + -- begin + -- <Destructor_Proc> (V); + + -- exception + -- when others => + -- if not Raised then + -- Raised := True; + -- Save_Occurrence (E, + -- Get_Current_Excep.all.all); + -- end if; + -- end; + + Proc := Entity (Expression (ASN)); + Stmt := + Make_Procedure_Call_Statement + (Loc, + Name => New_Occurrence_Of (Proc, Loc), + Parameter_Associations => + New_List (Make_Identifier (Loc, Name_V))); + if Exceptions_OK then + Stmt := + Make_Block_Statement + (Loc, + Handled_Statement_Sequence => + Make_Handled_Sequence_Of_Statements + (Loc, + Statements => New_List (Stmt), + Exception_Handlers => + New_List + (Build_Exception_Handler + (Finalizer_Data)))); + end if; + + Prepend_New_To (Bod_Stmts, Stmt); + end if; + end; end if; -- At this point either all finalization statements have been @@ -7833,13 +7923,23 @@ package body Exp_Ch7 is when Initialize_Case => if Is_Controlled (Typ) then - return New_List ( - Make_Procedure_Call_Statement (Loc, - Name => - New_Occurrence_Of - (Find_Controlled_Prim_Op (Typ, Name_Initialize), Loc), - Parameter_Associations => New_List ( - Make_Identifier (Loc, Name_V)))); + declare + Intlz : constant Entity_Id := + Find_Controlled_Prim_Op (Typ, Name_Initialize); + begin + if Present (Intlz) then + return + New_List + (Make_Procedure_Call_Statement + (Loc, + Name => + New_Occurrence_Of (Intlz, Loc), + Parameter_Associations => + New_List (Make_Identifier (Loc, Name_V)))); + else + return Empty_List; + end if; + end; else return Empty_List; end if; @@ -7899,7 +7999,7 @@ package body Exp_Ch7 is if Is_Untagged_Derivation (Typ) then if Is_Protected_Type (Typ) then Utyp := Corresponding_Record_Type (Root_Type (Base_Type (Typ))); - else + elsif Is_Implicit_Full_View (Utyp) then Utyp := Underlying_Type (Root_Type (Base_Type (Typ))); if Is_Protected_Type (Utyp) then @@ -7959,7 +8059,7 @@ package body Exp_Ch7 is return Empty; elsif Skip_Self then - if Has_Controlled_Component (Utyp) then + if Has_Controlled_Component (Utyp) or else Has_Destructor (Utyp) then if Is_Tagged_Type (Utyp) then Fin_Id := Find_Optional_Prim_Op (Utyp, TSS_Deep_Finalize); else @@ -7972,6 +8072,7 @@ package body Exp_Ch7 is elsif Is_Class_Wide_Type (Typ) or else Is_Interface (Typ) or else Has_Controlled_Component (Utyp) + or else Has_Destructor (Utyp) then if Is_Tagged_Type (Utyp) then Fin_Id := Find_Optional_Prim_Op (Utyp, TSS_Deep_Finalize); @@ -8174,6 +8275,10 @@ package body Exp_Ch7 is Ptr_Typ : Entity_Id; begin + -- Array types: picking the (unconstrained) base type as designated type + -- requires allocating the bounds alongside the data, so we only do this + -- when the first subtype itself was declared as unconstrained. + if Is_Array_Type (Typ) then if Is_Constrained (First_Subtype (Typ)) then Desig_Typ := First_Subtype (Typ); @@ -8269,63 +8374,18 @@ package body Exp_Ch7 is -- lays in front of the elements and then use a thin pointer to perform -- the address-to-access conversion. - if Is_Array_Type (Typ) - and then not Is_Constrained (First_Subtype (Typ)) - then - declare - Dope_Id : Entity_Id; - - begin - -- Ensure that Ptr_Typ is a thin pointer; generate: - -- for Ptr_Typ'Size use System.Address'Size; - - Append_To (Decls, - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (Ptr_Typ, Loc), - Chars => Name_Size, - Expression => - Make_Integer_Literal (Loc, System_Address_Size))); + if Is_Array_Type (Typ) and then not Is_Constrained (Desig_Typ) then + Obj_Expr := + Shift_Address_For_Descriptor (Obj_Expr, Desig_Typ, Name_Op_Add); - -- Generate: - -- Dnn : constant Storage_Offset := - -- Desig_Typ'Descriptor_Size / Storage_Unit; - - Dope_Id := Make_Temporary (Loc, 'D'); + -- Ensure that Ptr_Typ is a thin pointer; generate: + -- for Ptr_Typ'Size use System.Address'Size; - Append_To (Decls, - Make_Object_Declaration (Loc, - Defining_Identifier => Dope_Id, - Constant_Present => True, - Object_Definition => - New_Occurrence_Of (RTE (RE_Storage_Offset), Loc), - Expression => - Make_Op_Divide (Loc, - Left_Opnd => - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Desig_Typ, Loc), - Attribute_Name => Name_Descriptor_Size), - Right_Opnd => - Make_Integer_Literal (Loc, System_Storage_Unit)))); - - -- Shift the address from the start of the dope vector to the - -- start of the elements: - -- - -- V + Dnn - - Obj_Expr := - Make_Function_Call (Loc, - Name => - Make_Expanded_Name (Loc, - Chars => Name_Op_Add, - Prefix => - New_Occurrence_Of - (RTU_Entity (System_Storage_Elements), Loc), - Selector_Name => - Make_Identifier (Loc, Name_Op_Add)), - Parameter_Associations => New_List ( - Obj_Expr, - New_Occurrence_Of (Dope_Id, Loc))); - end; + Append_To (Decls, + Make_Attribute_Definition_Clause (Loc, + Name => New_Occurrence_Of (Ptr_Typ, Loc), + Chars => Name_Size, + Expression => Make_Integer_Literal (Loc, System_Address_Size))); end if; Fin_Call := @@ -8510,7 +8570,10 @@ package body Exp_Ch7 is -- Deal with untagged derivation of private views - if Is_Untagged_Derivation (Typ) and then not Is_Conc then + if Is_Untagged_Derivation (Typ) + and then not Is_Conc + and then Is_Implicit_Full_View (Utyp) + then Utyp := Underlying_Type (Root_Type (Base_Type (Typ))); Ref := Unchecked_Convert_To (Utyp, Ref); @@ -8903,6 +8966,43 @@ package body Exp_Ch7 is return Scope_Stack.Table (Scope_Stack.Last).Node_To_Be_Wrapped; end Node_To_Be_Wrapped; + ---------------------------------- + -- Shift_Address_For_Descriptor -- + ---------------------------------- + + function Shift_Address_For_Descriptor + (Addr : Node_Id; + Typ : Entity_Id; + Op_Nam : Name_Id) return Node_Id + is + Loc : constant Source_Ptr := Sloc (Addr); + Dummy : constant Entity_Id := RTE (RE_Storage_Offset); + -- Make sure System_Storage_Elements is loaded for RTU_Entity + + begin + -- Generate: + -- Addr +/- (Typ'Descriptor_Size / Storage_Unit) + + return + Make_Function_Call (Loc, + Name => + Make_Expanded_Name (Loc, + Chars => Op_Nam, + Prefix => + New_Occurrence_Of + (RTU_Entity (System_Storage_Elements), Loc), + Selector_Name => Make_Identifier (Loc, Op_Nam)), + Parameter_Associations => New_List ( + Addr, + Make_Op_Divide (Loc, + Left_Opnd => + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Typ, Loc), + Attribute_Name => Name_Descriptor_Size), + Right_Opnd => + Make_Integer_Literal (Loc, System_Storage_Unit)))); + end Shift_Address_For_Descriptor; + ---------------------------- -- Store_Actions_In_Scope -- ---------------------------- @@ -9441,9 +9541,16 @@ package body Exp_Ch7 is procedure Wrap_Transient_Expression (N : Node_Id) is Loc : constant Source_Ptr := Sloc (N); Expr : Node_Id := Relocate_Node (N); - Temp : constant Entity_Id := Make_Temporary (Loc, 'E', N); Typ : constant Entity_Id := Etype (N); + Temp : constant Entity_Id := Make_Temporary (Loc, 'E', + Related_Node => Expr); + -- We link the temporary with its relocated expression to facilitate + -- locating the expression in the expanded code; this simplifies the + -- implementation of the function that searchs in the expanded code + -- for a function call that has been wrapped in a transient block + -- (see Get_Relocated_Function_Call). + begin -- Generate: diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb index d75fd3a68256..c979cf6899b1 100644 --- a/gcc/ada/exp_ch9.adb +++ b/gcc/ada/exp_ch9.adb @@ -4273,6 +4273,7 @@ package body Exp_Ch9 is Defining_Identifier => Obj, Object_Definition => New_Occurrence_Of (Conctyp, Loc), Expression => ExpR); + Mutate_Ekind (Obj, E_Variable); Set_Etype (Obj, Conctyp); Decls := New_List (Decl); Rewrite (Concval, New_Occurrence_Of (Obj, Loc)); @@ -4690,11 +4691,11 @@ package body Exp_Ch9 is -- The availability of the activation chain entity does not ensure -- that we have tasks to activate because it may have been declared - -- by the frontend to pass a required extra formal to a build-in-place + -- by the front end to pass a required extra formal to a build-in-place -- subprogram call. If we are within the scope of a protected type and -- pragma Detect_Blocking is active we can assume that no tasks will be -- activated; if tasks are created in a protected object and this pragma - -- is active then the frontend emits a warning and Program_Error is + -- is active then the front end emits a warning and Program_Error is -- raised at runtime. elsif Detect_Blocking and then Within_Protected_Type (Current_Scope) then @@ -5747,7 +5748,7 @@ package body Exp_Ch9 is Insert_Before_And_Analyze (N, Decl1); -- Associate the access to subprogram with its original access to - -- protected subprogram type. Needed by the backend to know that this + -- protected subprogram type. Needed by CodePeer to know that this -- type corresponds with an access to protected subprogram type. Set_Original_Access_Type (D_T2, T); @@ -8093,12 +8094,18 @@ package body Exp_Ch9 is -- access type. Finally the Entry_Component of each formal is set to -- reference the corresponding record component. - procedure Expand_N_Entry_Declaration (N : Node_Id) is + procedure Expand_N_Entry_Declaration + (N : Node_Id; + Was_Deferred : Boolean := False) + is + use Deferred_Extra_Formals_Support; + Loc : constant Source_Ptr := Sloc (N); Entry_Ent : constant Entity_Id := Defining_Identifier (N); Components : List_Id; Formal : Node_Id; Ftype : Entity_Id; + First_Decl : Node_Id; Last_Decl : Node_Id; Component : Entity_Id; Ctype : Entity_Id; @@ -8107,7 +8114,21 @@ package body Exp_Ch9 is Acc_Ent : Entity_Id; begin + -- No action if the addition of the extra formals was deferred, + -- since it means that the underlying type of some formal is not + -- available, and hence we cannot build the record type that will + -- hold all the parameter values. + + if Present (First_Formal (Entry_Ent)) + and then not Extra_Formals_Known (Entry_Ent) + and then not Is_Unsupported_Extra_Formals_Entity (Entry_Ent) + then + pragma Assert (Is_Deferred_Extra_Formals_Entity (Entry_Ent)); + return; + end if; + Formal := First_Formal (Entry_Ent); + First_Decl := N; Last_Decl := N; -- Most processing is done only if parameters are present @@ -8183,6 +8204,24 @@ package body Exp_Ch9 is Subtype_Indication => New_Occurrence_Of (Rec_Ent, Loc))); Insert_After (Last_Decl, Decl); + Last_Decl := Decl; + + -- Analyze all the inserted declarations. This is required when + -- the entry has formals and the addition of its extra formals + -- was deferred; otherwise their analysis will be performed as + -- as part of the regular flow of the front end at the end of + -- analysis of the enclosing task/protected type declaration. + + if Was_Deferred then + Push_Scope (Scope (Entry_Ent)); + + while First_Decl /= Last_Decl loop + Next (First_Decl); + Analyze (First_Decl); + end loop; + + End_Scope; + end if; end if; end Expand_N_Entry_Declaration; @@ -9877,7 +9916,7 @@ package body Exp_Ch9 is -- (T => To_Tag_Ptr (Obj'Address).all, -- Position => -- Ada.Tags.Get_Offset_Index - -- (Ada.Tags.Tag (Concval), + -- (Concval._Tag, -- <interface dispatch table position of Ename>)); -- Note that Obj'Address is recursively expanded into a call to @@ -9898,7 +9937,9 @@ package body Exp_Ch9 is Make_Function_Call (Loc, Name => New_Occurrence_Of (RTE (RE_Get_Offset_Index), Loc), Parameter_Associations => New_List ( - Unchecked_Convert_To (RTE (RE_Tag), Concval), + Make_Attribute_Reference (Loc, + Prefix => Concval, + Attribute_Name => Name_Tag), Make_Integer_Literal (Loc, DT_Position (Entity (Ename)))))))); @@ -10593,14 +10634,6 @@ package body Exp_Ch9 is Build_Accept_Body (Accept_Statement (Alt))); Reset_Scopes_To (Proc_Body, PB_Ent); - - -- During the analysis of the body of the accept statement, any - -- zero cost exception handler records were collected in the - -- Accept_Handler_Records field of the N_Accept_Alternative node. - -- This is where we move them to where they belong, namely the - -- newly created procedure. - - Set_Handler_Records (PB_Ent, Accept_Handler_Records (Alt)); Append (Proc_Body, Body_List); else diff --git a/gcc/ada/exp_ch9.ads b/gcc/ada/exp_ch9.ads index cae6cb3a166e..681114133fe1 100644 --- a/gcc/ada/exp_ch9.ads +++ b/gcc/ada/exp_ch9.ads @@ -227,9 +227,16 @@ package Exp_Ch9 is procedure Expand_N_Delay_Until_Statement (N : Node_Id); procedure Expand_N_Entry_Body (N : Node_Id); procedure Expand_N_Entry_Call_Statement (N : Node_Id); - procedure Expand_N_Entry_Declaration (N : Node_Id); procedure Expand_N_Protected_Body (N : Node_Id); + procedure Expand_N_Entry_Declaration + (N : Node_Id; + Was_Deferred : Boolean := False); + -- Expands an entry declaration, building a record type to hold all the + -- parameter values. Was_Deferred is True when this expansion was deferred + -- because the underlying type of some formal was not available to build + -- the record. + procedure Expand_N_Protected_Type_Declaration (N : Node_Id); -- Expands protected type declarations. This results, among other things, -- in the declaration of a record type for the representation of protected diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb index 458b32c1730e..619ac407cb0a 100644 --- a/gcc/ada/exp_disp.adb +++ b/gcc/ada/exp_disp.adb @@ -413,7 +413,9 @@ package body Exp_Disp is if Nkind (D) = N_Package_Declaration then Build_Package_Dispatch_Tables (D); - elsif Nkind (D) = N_Package_Body then + elsif Nkind (D) = N_Package_Body + and then Ekind (Corresponding_Spec (D)) /= E_Generic_Package + then Build_Dispatch_Tables (Declarations (D)); elsif Nkind (D) = N_Package_Body_Stub @@ -799,7 +801,7 @@ package body Exp_Disp is -- No action needed if the dispatching call has been already expanded - or else Is_Expanded_Dispatching_Call (Name (Call_Node)) + or else Is_Expanded_Dispatching_Call (Call_Node) then return; end if; @@ -924,6 +926,8 @@ package body Exp_Disp is New_Formal : Entity_Id; Last_Formal : Entity_Id := Empty; + use Deferred_Extra_Formals_Support; + begin if Present (Old_Formal) then New_Formal := New_Copy (Old_Formal); @@ -960,51 +964,21 @@ package body Exp_Disp is end if; -- Now that the explicit formals have been duplicated, any extra - -- formals needed by the subprogram must be duplicated; we know - -- that extra formals are available because they were added when - -- the tagged type was frozen (see Expand_Freeze_Record_Type). + -- formals needed by the subprogram must be added; we know that + -- extra formals are available because they were added when the + -- tagged type was frozen (see Expand_Freeze_Record_Type). pragma Assert (Is_Frozen (Typ)); - -- Warning: The addition of the extra formals cannot be performed - -- here invoking Create_Extra_Formals since we must ensure that all - -- the extra formals of the pointer type and the target subprogram - -- match (and for functions that return a tagged type the profile of - -- the built subprogram type always returns a class-wide type, which - -- may affect the addition of some extra formals). - - if Present (Last_Formal) - and then Present (Extra_Formal (Last_Formal)) - then - Old_Formal := Extra_Formal (Last_Formal); - New_Formal := New_Copy (Old_Formal); - Set_Scope (New_Formal, Subp_Typ); + if Extra_Formals_Known (Subp) then + Create_Extra_Formals (Subp_Typ); - Set_Extra_Formal (Last_Formal, New_Formal); - Set_Extra_Formals (Subp_Typ, New_Formal); + -- Extra formals were previously deferred - if Ekind (Subp) = E_Function - and then Present (Extra_Accessibility_Of_Result (Subp)) - and then Extra_Accessibility_Of_Result (Subp) = Old_Formal - then - Set_Extra_Accessibility_Of_Result (Subp_Typ, New_Formal); - end if; - - Old_Formal := Extra_Formal (Old_Formal); - while Present (Old_Formal) loop - Set_Extra_Formal (New_Formal, New_Copy (Old_Formal)); - New_Formal := Extra_Formal (New_Formal); - Set_Scope (New_Formal, Subp_Typ); - - if Ekind (Subp) = E_Function - and then Present (Extra_Accessibility_Of_Result (Subp)) - and then Extra_Accessibility_Of_Result (Subp) = Old_Formal - then - Set_Extra_Accessibility_Of_Result (Subp_Typ, New_Formal); - end if; - - Old_Formal := Extra_Formal (Old_Formal); - end loop; + else + pragma Assert (Is_Deferred_Extra_Formals_Entity (Subp)); + Register_Deferred_Extra_Formals_Entity (Subp_Typ); + Register_Deferred_Extra_Formals_Call (Call_Node, Current_Scope); end if; end; @@ -1235,6 +1209,8 @@ package body Exp_Disp is -- the generation of spurious warnings under ZFP run-time. Analyze_And_Resolve (Call_Node, Call_Typ, Suppress => All_Checks); + + Set_Is_Expanded_Dispatching_Call (Call_Node); end Expand_Dispatching_Call; --------------------------------- @@ -2376,17 +2352,6 @@ package body Exp_Disp is and then not Restriction_Active (No_Dispatching_Calls); end Has_DT; - ---------------------------------- - -- Is_Expanded_Dispatching_Call -- - ---------------------------------- - - function Is_Expanded_Dispatching_Call (N : Node_Id) return Boolean is - begin - return Nkind (N) in N_Subprogram_Call - and then Nkind (Name (N)) = N_Explicit_Dereference - and then Is_Dispatch_Table_Entity (Etype (Name (N))); - end Is_Expanded_Dispatching_Call; - ------------------------------------- -- Is_Predefined_Dispatching_Alias -- ------------------------------------- @@ -8343,13 +8308,15 @@ package body Exp_Disp is Defining_Unit_Name => IP, Parameter_Specifications => Parms))); - Set_Init_Proc (Typ, IP); - Set_Is_Imported (IP); - Set_Is_Constructor (IP); - Set_Interface_Name (IP, Interface_Name (E)); - Set_Convention (IP, Convention_CPP); - Set_Is_Public (IP); - Set_Has_Completion (IP); + Set_Init_Proc (Typ, IP); + Set_Is_Imported (IP); + Set_Is_Constructor (IP); + Set_Interface_Name (IP, Interface_Name (E)); + Set_Convention (IP, Convention_CPP); + Set_Is_Public (IP); + Set_Has_Completion (IP); + Mutate_Ekind (IP, E_Procedure); + Freeze_Extra_Formals (IP); -- Case 2: Constructor of a tagged type @@ -8482,6 +8449,8 @@ package body Exp_Disp is Discard_Node (IP_Body); Set_Init_Proc (Typ, IP); + Mutate_Ekind (IP, E_Procedure); + Freeze_Extra_Formals (IP); end; end if; @@ -8547,6 +8516,8 @@ package body Exp_Disp is Discard_Node (IP_Body); Set_Init_Proc (Typ, IP); + Mutate_Ekind (IP, E_Procedure); + Freeze_Extra_Formals (IP); end; end if; diff --git a/gcc/ada/exp_disp.ads b/gcc/ada/exp_disp.ads index 3cba8ca447e3..76f592358005 100644 --- a/gcc/ada/exp_disp.ads +++ b/gcc/ada/exp_disp.ads @@ -236,9 +236,6 @@ package Exp_Disp is function Has_CPP_Constructors (Typ : Entity_Id) return Boolean; -- Returns true if the type has CPP constructors - function Is_Expanded_Dispatching_Call (N : Node_Id) return Boolean; - -- Returns true if N is the expanded code of a dispatching call - function Make_DT (Typ : Entity_Id) return List_Id; -- Expand the declarations for the Dispatch Table of Typ diff --git a/gcc/ada/exp_dist.adb b/gcc/ada/exp_dist.adb index 694fbe47daba..a351b9b8a8fb 100644 --- a/gcc/ada/exp_dist.adb +++ b/gcc/ada/exp_dist.adb @@ -10980,6 +10980,7 @@ package body Exp_Dist is if not Constrained or else Depth > 1 then Inner_Any := Make_Defining_Identifier (Loc, New_External_Name ('A', Depth)); + Mutate_Ekind (Inner_Any, E_Variable); Set_Etype (Inner_Any, RTE (RE_Any)); else Inner_Any := Empty; @@ -10988,6 +10989,7 @@ package body Exp_Dist is if Present (Counter) then Inner_Counter := Make_Defining_Identifier (Loc, New_External_Name ('J', Depth)); + Mutate_Ekind (Inner_Counter, E_Variable); else Inner_Counter := Empty; end if; diff --git a/gcc/ada/exp_fixd.adb b/gcc/ada/exp_fixd.adb index 03c7ca849158..8759099c193e 100644 --- a/gcc/ada/exp_fixd.adb +++ b/gcc/ada/exp_fixd.adb @@ -570,12 +570,16 @@ package body Exp_Fixd is -- Case where we can compute the denominator in Max_Integer_Size bits if QR_Id = RE_Null then + Mutate_Ekind (Qnn, E_Constant); + Mutate_Ekind (Rnn, E_Constant); -- Create temporaries for numerator and denominator and set Etypes, -- so that New_Occurrence_Of picks them up for Build_xxx calls. Nnn := Make_Temporary (Loc, 'N'); + Mutate_Ekind (Nnn, E_Constant); Dnn := Make_Temporary (Loc, 'D'); + Mutate_Ekind (Dnn, E_Constant); Set_Etype (Nnn, QR_Typ); Set_Etype (Dnn, QR_Typ); @@ -621,6 +625,8 @@ package body Exp_Fixd is -- to call the runtime routine to compute the quotient and remainder. else + Mutate_Ekind (Qnn, E_Variable); + Mutate_Ekind (Rnn, E_Variable); Rnd := Boolean_Literals (Rounded_Result_Set (N)); Code := New_List ( @@ -935,8 +941,13 @@ package body Exp_Fixd is -- Case where we can compute the numerator in Max_Integer_Size bits if QR_Id = RE_Null then + Mutate_Ekind (Qnn, E_Constant); + Mutate_Ekind (Rnn, E_Constant); + Nnn := Make_Temporary (Loc, 'N'); + Mutate_Ekind (Nnn, E_Constant); Dnn := Make_Temporary (Loc, 'D'); + Mutate_Ekind (Dnn, E_Constant); -- Set Etypes, so that they can be picked up by New_Occurrence_Of @@ -982,6 +993,9 @@ package body Exp_Fixd is -- to call the runtime routine to compute the quotient and remainder. else + Mutate_Ekind (Qnn, E_Variable); + Mutate_Ekind (Rnn, E_Variable); + Rnd := Boolean_Literals (Rounded_Result_Set (N)); Code := New_List ( diff --git a/gcc/ada/exp_imgv.adb b/gcc/ada/exp_imgv.adb index c7cf06ba444f..3fef6fabe64e 100644 --- a/gcc/ada/exp_imgv.adb +++ b/gcc/ada/exp_imgv.adb @@ -1631,7 +1631,6 @@ package body Exp_Imgv is Name => New_Occurrence_Of (RTE (Vid), Loc), Parameter_Associations => Args))); - Set_Etype (N, Btyp); Analyze_And_Resolve (N, Btyp); return; @@ -1640,23 +1639,22 @@ package body Exp_Imgv is Num : constant Uint := Norm_Num (Small_Value (Rtyp)); Den : constant Uint := Norm_Den (Small_Value (Rtyp)); Max : constant Uint := UI_Max (Num, Den); - Min : constant Uint := UI_Min (Num, Den); Siz : constant Uint := Esize (Rtyp); begin if Siz <= 32 and then Max <= Uint_2 ** 31 - and then (Min = Uint_1 or else Max <= Uint_2 ** 27) + and then (Num = Uint_1 or else Max <= Uint_2 ** 27) then Vid := RE_Value_Fixed32; elsif Siz <= 64 and then Max <= Uint_2 ** 63 - and then (Min = Uint_1 or else Max <= Uint_2 ** 59) + and then (Num = Uint_1 or else Max <= Uint_2 ** 59) then Vid := RE_Value_Fixed64; elsif System_Max_Integer_Size = 128 and then Max <= Uint_2 ** 127 - and then (Min = Uint_1 or else Max <= Uint_2 ** 123) + and then (Num = Uint_1 or else Max <= Uint_2 ** 123) then Vid := RE_Value_Fixed128; else @@ -1676,7 +1674,6 @@ package body Exp_Imgv is Name => New_Occurrence_Of (RTE (Vid), Loc), Parameter_Associations => Args))); - Set_Etype (N, Btyp); Analyze_And_Resolve (N, Btyp); return; end if; diff --git a/gcc/ada/exp_pakd.adb b/gcc/ada/exp_pakd.adb index 4eb93c3192a6..f04016fa8117 100644 --- a/gcc/ada/exp_pakd.adb +++ b/gcc/ada/exp_pakd.adb @@ -904,7 +904,8 @@ package body Exp_Pakd is -- discriminants, so we treat it as a default/per-object expression. Set_Parent (Len_Expr, Typ); - Preanalyze_Spec_Expression (Len_Expr, Standard_Long_Long_Integer); + Preanalyze_And_Resolve_Spec_Expression + (Len_Expr, Standard_Long_Long_Integer); -- Use a modular type if possible. We can do this if we have -- static bounds, and the length is small enough, and the length @@ -1525,21 +1526,24 @@ package body Exp_Pakd is Get_Base_And_Bit_Offset (Prefix (N), Base, Offset); + Offset := Unchecked_Convert_To (RTE (RE_Storage_Offset), Offset); + Rewrite (N, - Unchecked_Convert_To (RTE (RE_Address), - Make_Op_Add (Loc, - Left_Opnd => - Unchecked_Convert_To (RTE (RE_Integer_Address), - Make_Attribute_Reference (Loc, - Prefix => Base, - Attribute_Name => Name_Address)), - - Right_Opnd => - Unchecked_Convert_To (RTE (RE_Integer_Address), - Make_Op_Divide (Loc, - Left_Opnd => Offset, - Right_Opnd => - Make_Integer_Literal (Loc, System_Storage_Unit)))))); + Make_Function_Call (Loc, + Name => + Make_Expanded_Name (Loc, + Chars => Name_Op_Add, + Prefix => + New_Occurrence_Of (RTU_Entity (System_Storage_Elements), Loc), + Selector_Name => Make_Identifier (Loc, Name_Op_Add)), + Parameter_Associations => New_List ( + Make_Attribute_Reference (Loc, + Prefix => Base, + Attribute_Name => Name_Address), + Make_Op_Divide (Loc, + Left_Opnd => Offset, + Right_Opnd => + Make_Integer_Literal (Loc, System_Storage_Unit))))); Analyze_And_Resolve (N, RTE (RE_Address)); end Expand_Packed_Address_Reference; diff --git a/gcc/ada/exp_prag.adb b/gcc/ada/exp_prag.adb index cc5962098a03..340f2dc10028 100644 --- a/gcc/ada/exp_prag.adb +++ b/gcc/ada/exp_prag.adb @@ -3082,6 +3082,16 @@ package body Exp_Prag is In_Assertion_Expr := In_Assertion_Expr - 1; end Expand_Pragma_Loop_Variant; + -------------------------------- + -- Expand_Pragma_Program_Exit -- + -------------------------------- + + procedure Expand_Pragma_Program_Exit (Prag : Node_Id) is + pragma Unreferenced (Prag); + begin + null; + end Expand_Pragma_Program_Exit; + -------------------------------- -- Expand_Pragma_Psect_Object -- -------------------------------- diff --git a/gcc/ada/exp_prag.ads b/gcc/ada/exp_prag.ads index 036d7b11404b..cd78dd20651f 100644 --- a/gcc/ada/exp_prag.ads +++ b/gcc/ada/exp_prag.ads @@ -72,4 +72,8 @@ package Exp_Prag is -- of Prag is replaced with a reference to procedure with checks for the -- variant expressions. + procedure Expand_Pragma_Program_Exit (Prag : Node_Id); + -- This routine only exists for consistency with other pragmas, since + -- Program_Exit has no meaningful expansion. + end Exp_Prag; diff --git a/gcc/ada/exp_put_image.adb b/gcc/ada/exp_put_image.adb index ae5fa40fa380..ce3390b50384 100644 --- a/gcc/ada/exp_put_image.adb +++ b/gcc/ada/exp_put_image.adb @@ -77,8 +77,28 @@ package body Exp_Put_Image is -- reference). The Loc parameter is used as the Sloc of the created entity. function Put_Image_Base_Type (E : Entity_Id) return Entity_Id; - -- Returns the base type, except for an array type whose whose first - -- subtype is constrained, in which case it returns the first subtype. + -- For an array type whose whose first subtype is constrained, return + -- the first subtype. For the internal representation type corresponding + -- to a mutably tagged type, return the mutably tagged type. Otherwise, + -- return the base type. Similar to Exp_Strm.Stream_Base_Type. + + procedure Put_Specific_Type_Name_Qualifier + (Loc : Source_Ptr; + Stms : List_Id; + Tagged_Obj : Node_Id; + Buffer_Name : Node_Id; + Is_Interface_Type : Boolean); + -- Append to the given statement list calls to add into the + -- buffer the name of the given object's tag and then a "'". + + function Put_String_Exp_To_Buffer + (Loc : Source_Ptr; + String_Exp : Node_Id; + Buffer_Name : Node_Id; + Wide_Wide : Boolean := False) return Node_Id; + -- Generate a call to evaluate a String (or Wide_Wide_String, depending + -- on the Wide_Wide Boolean parameter) expression and output it into + -- the buffer. ------------------------------------- -- Build_Array_Put_Image_Procedure -- @@ -189,7 +209,7 @@ package body Exp_Put_Image is Ndim : constant Pos := Number_Dimensions (Typ); Ctyp : constant Entity_Id := Component_Type (Typ); - Stm : Node_Id; + Stms : List_Id := New_List; Exl : constant List_Id := New_List; PI_Entity : Entity_Id; @@ -220,15 +240,36 @@ package body Exp_Put_Image is Append_To (Exl, Make_Identifier (Loc, New_External_Name ('L', Dim))); end loop; - Stm := - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Put_Image_Base_Type (Ctyp), Loc), - Attribute_Name => Name_Put_Image, - Expressions => New_List ( - Make_Identifier (Loc, Name_S), - Make_Indexed_Component (Loc, - Prefix => Make_Identifier (Loc, Name_V), - Expressions => Exl))); + declare + Ctype_For_Call : constant Entity_Id := Put_Image_Base_Type (Ctyp); + Indexed_Comp : constant Node_Id := + Make_Indexed_Component (Loc, + Prefix => Make_Identifier (Loc, Name_V), + Expressions => Exl); + begin + if Is_Mutably_Tagged_Type (Ctype_For_Call) then + pragma Assert (not Is_Mutably_Tagged_Type (Component_Type (Typ))); + + Make_Mutably_Tagged_Conversion (Indexed_Comp, + Typ => Ctype_For_Call); + + pragma Assert (Is_Mutably_Tagged_Type (Etype (Indexed_Comp))); + + Put_Specific_Type_Name_Qualifier (Loc, + Stms => Stms, + Tagged_Obj => Indexed_Comp, + Buffer_Name => Make_Identifier (Loc, Name_S), + Is_Interface_Type => False); + end if; + + Append_To (Stms, + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Ctype_For_Call, Loc), + Attribute_Name => Name_Put_Image, + Expressions => New_List ( + Make_Identifier (Loc, Name_S), + Indexed_Comp))); + end; -- The corresponding attribute for the component type of the array might -- be user-defined, and frozen after the array type. In that case, @@ -245,46 +286,42 @@ package body Exp_Put_Image is -- Loop through the dimensions, innermost first, generating a loop for -- each dimension. - declare - Stms : List_Id := New_List (Stm); - begin - for Dim in reverse 1 .. Ndim loop - declare - New_Stms : constant List_Id := New_List; - Between_Proc : RE_Id; - begin - -- For a one-dimensional array of elementary type, use - -- RE_Simple_Array_Between. The same applies to the last - -- dimension of a multidimensional array. + for Dim in reverse 1 .. Ndim loop + declare + New_Stms : constant List_Id := New_List; + Between_Proc : RE_Id; + begin + -- For a one-dimensional array of elementary type, use + -- RE_Simple_Array_Between. The same applies to the last + -- dimension of a multidimensional array. - if Is_Elementary_Type (Ctyp) and then Dim = Ndim then - Between_Proc := RE_Simple_Array_Between; - else - Between_Proc := RE_Array_Between; - end if; + if Is_Elementary_Type (Ctyp) and then Dim = Ndim then + Between_Proc := RE_Simple_Array_Between; + else + Between_Proc := RE_Array_Between; + end if; - Append_To (New_Stms, - Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (RE_Array_Before), Loc), - Parameter_Associations => New_List - (Make_Identifier (Loc, Name_S)))); + Append_To (New_Stms, + Make_Procedure_Call_Statement (Loc, + Name => New_Occurrence_Of (RTE (RE_Array_Before), Loc), + Parameter_Associations => New_List + (Make_Identifier (Loc, Name_S)))); - Append_To - (New_Stms, - Wrap_In_Loop (Stms, Dim, Indices (Dim), Between_Proc)); + Append_To + (New_Stms, + Wrap_In_Loop (Stms, Dim, Indices (Dim), Between_Proc)); - Append_To (New_Stms, - Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (RE_Array_After), Loc), - Parameter_Associations => New_List - (Make_Identifier (Loc, Name_S)))); + Append_To (New_Stms, + Make_Procedure_Call_Statement (Loc, + Name => New_Occurrence_Of (RTE (RE_Array_After), Loc), + Parameter_Associations => New_List + (Make_Identifier (Loc, Name_S)))); - Stms := New_Stms; - end; - end loop; + Stms := New_Stms; + end; + end loop; - Build_Put_Image_Proc (Loc, Typ, Decl, Pnam, Stms); - end; + Build_Put_Image_Proc (Loc, Typ, Decl, Pnam, Stms); end Build_Array_Put_Image_Procedure; ------------------------------------- @@ -379,7 +416,8 @@ package body Exp_Put_Image is begin -- We have built a dispatching call to handle calls to -- descendants (since they are not available through rtsfind). - -- Further details available in the body of Put_String_Exp. + -- Further details available in the body of + -- Put_String_Exp_To_Buffer. return Put_Call; end; @@ -691,21 +729,33 @@ package body Exp_Put_Image is --------------------------- procedure Append_Component_Attr (Clist : List_Id; C : Entity_Id) is - Component_Typ : constant Entity_Id := - Put_Image_Base_Type - (Get_Corresponding_Mutably_Tagged_Type_If_Present (Etype (C))); + Component_Typ : constant Entity_Id := Put_Image_Base_Type (Etype (C)); + Selected_Comp : constant Node_Id := + Make_Selected_Component (Loc, + Prefix => Make_Identifier (Loc, Name_V), + Selector_Name => New_Occurrence_Of (C, Loc)); begin - if Ekind (C) /= E_Void then - Append_To (Clist, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Component_Typ, Loc), - Attribute_Name => Name_Put_Image, - Expressions => New_List ( - Make_Identifier (Loc, Name_S), - Make_Selected_Component (Loc, - Prefix => Make_Identifier (Loc, Name_V), - Selector_Name => New_Occurrence_Of (C, Loc))))); + if Is_Mutably_Tagged_Type (Component_Typ) then + pragma Assert (not Is_Mutably_Tagged_Type (Etype (C))); + + Make_Mutably_Tagged_Conversion (Selected_Comp, + Typ => Component_Typ); + + pragma Assert (Is_Mutably_Tagged_Type (Etype (Selected_Comp))); + + Put_Specific_Type_Name_Qualifier (Loc, + Stms => Clist, + Tagged_Obj => Selected_Comp, + Buffer_Name => Make_Identifier (Loc, Name_S), + Is_Interface_Type => False); end if; + + Append_To (Clist, + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Component_Typ, Loc), + Attribute_Name => Name_Put_Image, + Expressions => New_List (Make_Identifier (Loc, Name_S), + Selected_Comp))); end Append_Component_Attr; ------------------------------- @@ -944,9 +994,38 @@ package body Exp_Put_Image is -- Generate Put_Images for the discriminants of the type - Append_List_To (Stms, - Make_Component_Attributes - (Discriminant_Specifications (Type_Decl))); + declare + Discrim_Specs : List_Id := Discriminant_Specifications (Type_Decl); + Partial_View : Entity_Id; + begin + if Present (First (Discrim_Specs)) + and then Ekind (Defining_Identifier (First (Discrim_Specs))) = + E_Void + then + -- If the known discriminant part is repeated for the + -- completion of a private type declaration, then the + -- second copy is (by design) not analyzed. So we'd better + -- use the first copy instead. + + Partial_View := Incomplete_Or_Partial_View + (Defining_Identifier (Type_Decl)); + + pragma Assert (Ekind (Partial_View) in + E_Private_Type + | E_Limited_Private_Type + | E_Record_Type_With_Private); + + Discrim_Specs := + Discriminant_Specifications (Parent (Partial_View)); + + pragma Assert (Present (First (Discrim_Specs))); + pragma Assert + (Ekind (Defining_Identifier (First (Discrim_Specs))) /= + E_Void); + end if; + + Append_List_To (Stms, Make_Component_Attributes (Discrim_Specs)); + end; Rdef := Type_Definition (Type_Decl); @@ -1276,105 +1355,20 @@ package body Exp_Put_Image is New_Occurrence_Of (Sink_Entity, Loc)))); Actions : List_Id; - function Put_String_Exp (String_Exp : Node_Id; - Wide_Wide : Boolean := False) return Node_Id; - -- Generate a call to evaluate a String (or Wide_Wide_String, depending - -- on the Wide_Wide Boolean parameter) expression and output it into - -- the buffer. - - -------------------- - -- Put_String_Exp -- - -------------------- - - function Put_String_Exp (String_Exp : Node_Id; - Wide_Wide : Boolean := False) return Node_Id is - Put_Id : constant RE_Id := - (if Wide_Wide then RE_Wide_Wide_Put else RE_Put_UTF_8); - - -- We could build a nondispatching call here, but to make - -- that work we'd have to change Rtsfind spec to make available - -- corresponding callees out of Ada.Strings.Text_Buffers.Unbounded - -- (as opposed to from Ada.Strings.Text_Buffers). Seems simpler to - -- introduce a type conversion and leave it to the optimizer to - -- eliminate the dispatching. This does not *introduce* any problems - -- if a no-dispatching-allowed restriction is in effect, since we - -- are already in the middle of generating a call to T'Class'Image. - - Sink_Exp : constant Node_Id := - Make_Type_Conversion (Loc, - Subtype_Mark => - New_Occurrence_Of - (Class_Wide_Type (RTE (RE_Root_Buffer_Type)), Loc), - Expression => New_Occurrence_Of (Sink_Entity, Loc)); - begin - return - Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (Put_Id), Loc), - Parameter_Associations => New_List (Sink_Exp, String_Exp)); - end Put_String_Exp; - - -- Local variables - - Tag_Node : Node_Id; - -- Start of processing for Build_Image_Call begin if Is_Class_Wide_Type (U_Type) then + Actions := New_List (Sink_Decl); - -- For interface types we must generate code to displace the pointer - -- to the object to reference the base of the underlying object. - - -- Generate: - -- To_Tag_Ptr (Image_Prefix'Address).all - - -- Note that Image_Prefix'Address is recursively expanded into a - -- call to Ada.Tags.Base_Address (Image_Prefix'Address). - - if Is_Interface (U_Type) then - Tag_Node := - Make_Explicit_Dereference (Loc, - Unchecked_Convert_To (RTE (RE_Tag_Ptr), - Make_Attribute_Reference (Loc, - Prefix => Duplicate_Subexpr (Image_Prefix), - Attribute_Name => Name_Address))); + Put_Specific_Type_Name_Qualifier (Loc, + Stms => Actions, + Tagged_Obj => Image_Prefix, + Buffer_Name => New_Occurrence_Of (Sink_Entity, Loc), + Is_Interface_Type => Is_Interface (U_Type)); - -- Common case - - else - Tag_Node := - Make_Attribute_Reference (Loc, - Prefix => Duplicate_Subexpr (Image_Prefix), - Attribute_Name => Name_Tag); - end if; - - -- Generate qualified-expression syntax; qualification name comes - -- from calling Ada.Tags.Wide_Wide_Expanded_Name. - - declare - -- The copy of Image_Prefix will be evaluated before the - -- original, which is ok if no side effects are involved. - - pragma Assert (Side_Effect_Free (Image_Prefix)); - - Specific_Type_Name : constant Node_Id := - Put_String_Exp - (Make_Function_Call (Loc, - Name => New_Occurrence_Of - (RTE (RE_Wide_Wide_Expanded_Name), Loc), - Parameter_Associations => New_List (Tag_Node)), - Wide_Wide => True); - - Qualification : constant Node_Id := - Put_String_Exp (Make_String_Literal (Loc, "'")); - begin - Actions := New_List - (Sink_Decl, - Specific_Type_Name, - Qualification, - Put_Im, - Result_Decl); - end; + Append_To (Actions, Put_Im); + Append_To (Actions, Result_Decl); else Actions := New_List (Sink_Decl, Put_Im, Result_Decl); end if; @@ -1458,9 +1452,89 @@ package body Exp_Put_Image is return E; elsif Is_Private_Type (Base_Type (E)) and not Is_Private_Type (E) then return Implementation_Base_Type (E); + elsif Is_Mutably_Tagged_CW_Equivalent_Type (E) then + return Get_Corresponding_Mutably_Tagged_Type_If_Present (E); else return Base_Type (E); end if; end Put_Image_Base_Type; + -------------------------------------- + -- Put_Specific_Type_Name_Qualifier -- + -------------------------------------- + + procedure Put_Specific_Type_Name_Qualifier + (Loc : Source_Ptr; + Stms : List_Id; + Tagged_Obj : Node_Id; + Buffer_Name : Node_Id; + Is_Interface_Type : Boolean) + is + Tag_Node : Node_Id; + begin + if Is_Interface_Type then + Tag_Node := + Make_Explicit_Dereference (Loc, + Unchecked_Convert_To (RTE (RE_Tag_Ptr), + Make_Attribute_Reference (Loc, + Prefix => New_Copy_Tree (Tagged_Obj), + Attribute_Name => Name_Address))); + else + Tag_Node := + Make_Attribute_Reference (Loc, + Prefix => New_Copy_Tree (Tagged_Obj), + Attribute_Name => Name_Tag); + end if; + + Append_To (Stms, + Put_String_Exp_To_Buffer (Loc, + String_Exp => + Make_Function_Call (Loc, + Name => New_Occurrence_Of + (RTE (RE_Wide_Wide_Expanded_Name), Loc), + Parameter_Associations => New_List (Tag_Node)), + Buffer_Name => Buffer_Name, + Wide_Wide => True)); + + Append_To (Stms, + Put_String_Exp_To_Buffer (Loc, + String_Exp => Make_String_Literal (Loc, "'"), + Buffer_Name => New_Copy_Tree (Buffer_Name))); + end Put_Specific_Type_Name_Qualifier; + + ------------------------------ + -- Put_String_Exp_To_Buffer -- + ------------------------------ + + function Put_String_Exp_To_Buffer + (Loc : Source_Ptr; + String_Exp : Node_Id; + Buffer_Name : Node_Id; + Wide_Wide : Boolean := False) return Node_Id + is + Put_Id : constant RE_Id := + (if Wide_Wide then RE_Wide_Wide_Put else RE_Put_UTF_8); + + -- We could build a nondispatching call here, but to make + -- that work we'd have to change Rtsfind spec to make available + -- corresponding callees out of Ada.Strings.Text_Buffers.Unbounded + -- (as opposed to from Ada.Strings.Text_Buffers). Seems simpler to + -- introduce a type conversion and leave it to the optimizer to + -- eliminate the dispatching. This does not *introduce* any problems + -- if a no-dispatching-allowed restriction is in effect, since we + -- are already in the middle of generating a call to T'Class'Image. + + Sink_Exp : constant Node_Id := + Make_Type_Conversion (Loc, + Subtype_Mark => + New_Occurrence_Of + (Class_Wide_Type (RTE (RE_Root_Buffer_Type)), Loc), + Expression => Buffer_Name); + begin + return + Make_Procedure_Call_Statement (Loc, + Name => New_Occurrence_Of (RTE (Put_Id), Loc), + Parameter_Associations => New_List (Sink_Exp, String_Exp)); + end Put_String_Exp_To_Buffer; + end Exp_Put_Image; diff --git a/gcc/ada/exp_spark.adb b/gcc/ada/exp_spark.adb index b75b31b674db..a75a507388bc 100644 --- a/gcc/ada/exp_spark.adb +++ b/gcc/ada/exp_spark.adb @@ -73,6 +73,10 @@ package body Exp_SPARK is procedure Expand_SPARK_N_Attribute_Reference (N : Node_Id); -- Perform attribute-reference-specific expansion + procedure Expand_SPARK_N_Continue_Statement (N : Node_Id); + -- Expand continue statements which are resolved as procedure calls, into + -- said procedure calls. Real continue statements are left as-is. + procedure Expand_SPARK_N_Delta_Aggregate (N : Node_Id); -- Perform delta-aggregate-specific expansion @@ -172,6 +176,14 @@ package body Exp_SPARK is when N_Op_Ne => Expand_SPARK_N_Op_Ne (N); + -- Resolution of type conversion relies on minimal expansion of + -- fixedpoint operations to insert the range check on their result. + + when N_Op_Multiply | N_Op_Divide => + if Etype (N) = Universal_Fixed then + Exp_Ch4.Fixup_Universal_Fixed_Operation (N); + end if; + when N_Freeze_Entity => -- Currently we only expand type freeze entities, so ignore other -- freeze entites, because it is expensive to create a suitable @@ -183,6 +195,9 @@ package body Exp_SPARK is -- In SPARK mode, no other constructs require expansion + when N_Continue_Statement => + Expand_SPARK_N_Continue_Statement (N); + when others => null; end case; @@ -427,6 +442,23 @@ package body Exp_SPARK is end if; end Expand_SPARK_Delta_Or_Update; + --------------------------------------- + -- Expand_SPARK_N_Continue_Statement -- + --------------------------------------- + + procedure Expand_SPARK_N_Continue_Statement (N : Node_Id) is + X : constant Node_Id := Call_Or_Target_Loop (N); + begin + if No (X) then + return; + end if; + + if Nkind (X) = N_Procedure_Call_Statement then + Replace (N, X); + Analyze (N); + end if; + end Expand_SPARK_N_Continue_Statement; + ------------------------------ -- Expand_SPARK_N_Aggregate -- ------------------------------ diff --git a/gcc/ada/exp_strm.adb b/gcc/ada/exp_strm.adb index 250efd2dc904..5e1c9134fb57 100644 --- a/gcc/ada/exp_strm.adb +++ b/gcc/ada/exp_strm.adb @@ -29,6 +29,7 @@ with Einfo.Entities; use Einfo.Entities; with Einfo.Utils; use Einfo.Utils; with Elists; use Elists; with Exp_Util; use Exp_Util; +with Mutably_Tagged; use Mutably_Tagged; with Namet; use Namet; with Nlists; use Nlists; with Nmake; use Nmake; @@ -101,13 +102,10 @@ package body Exp_Strm is -- Loc parameter is used as the Sloc of the created entity. function Stream_Base_Type (E : Entity_Id) return Entity_Id; - -- Stream attributes work on the basis of the base type except for the - -- array case. For the array case, we do not go to the base type, but - -- to the first subtype if it is constrained. This avoids problems with - -- incorrect conversions in the packed array case. Stream_Base_Type is - -- exactly this function (returns the base type, unless we have an array - -- type whose first subtype is constrained, in which case it returns the - -- first subtype). + -- For an array type whose whose first subtype is constrained, return + -- the first subtype. For the internal representation type corresponding + -- to a mutably tagged type, return the mutably tagged type. Otherwise, + -- return the base type. Similar to Exp_Put_Image.Put_Image_Base_Type. -------------------------------- -- Build_Array_Input_Function -- @@ -1502,6 +1500,7 @@ package body Exp_Strm is function Make_Field_Attribute (C : Entity_Id) return Node_Id is Field_Typ : constant Entity_Id := Stream_Base_Type (Etype (C)); + Selected : Node_Id; TSS_Names : constant array (Name_Input .. Name_Write) of TSS_Name_Type := @@ -1524,15 +1523,23 @@ package body Exp_Strm is return Make_Null_Statement (Loc); end if; + Selected := Make_Selected_Component (Loc, + Prefix => Make_Identifier (Loc, Name_V), + Selector_Name => New_Occurrence_Of (C, Loc)); + + if Is_Mutably_Tagged_CW_Equivalent_Type (Etype (C)) then + Make_Mutably_Tagged_Conversion + (Selected, + Typ => Get_Corresponding_Mutably_Tagged_Type_If_Present + (Etype (C))); + end if; + return Make_Attribute_Reference (Loc, Prefix => New_Occurrence_Of (Field_Typ, Loc), Attribute_Name => Nam, - Expressions => New_List ( - Make_Identifier (Loc, Name_S), - Make_Selected_Component (Loc, - Prefix => Make_Identifier (Loc, Name_V), - Selector_Name => New_Occurrence_Of (C, Loc)))); + Expressions => New_List (Make_Identifier (Loc, Name_S), + Selected)); end Make_Field_Attribute; --------------------------- @@ -1808,6 +1815,10 @@ package body Exp_Strm is function Stream_Base_Type (E : Entity_Id) return Entity_Id is begin + if Is_Class_Wide_Equivalent_Type (E) then + return Corresponding_Mutably_Tagged_Type (E); + end if; + if Is_Array_Type (E) and then Is_First_Subtype (E) then diff --git a/gcc/ada/exp_tss.adb b/gcc/ada/exp_tss.adb index 89bcd29c5ad7..89af166a654c 100644 --- a/gcc/ada/exp_tss.adb +++ b/gcc/ada/exp_tss.adb @@ -504,13 +504,9 @@ package body Exp_Tss is Subp : Entity_Id; begin - if No (FN) then - return Empty; - - elsif No (TSS_Elist (FN)) then - return Empty; - - else + if Present (FN) + and then Present (TSS_Elist (FN)) + then Elmt := First_Elmt (TSS_Elist (FN)); while Present (Elmt) loop if Is_TSS (Node (Elmt), Nam) then diff --git a/gcc/ada/exp_unst.adb b/gcc/ada/exp_unst.adb index 4dc75693d8f8..58f668944a0a 100644 --- a/gcc/ada/exp_unst.adb +++ b/gcc/ada/exp_unst.adb @@ -2305,8 +2305,6 @@ package body Exp_Unst is end if; end Adjust_One_Call; end loop Adjust_Calls; - - return; end Unnest_Subprogram; ------------------------ diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb index b8c6a9f8848b..5a6fca081a69 100644 --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -167,6 +167,9 @@ package body Exp_Util is -- Force evaluation of bounds of a slice, which may be given by a range -- or by a subtype indication with or without a constraint. + function Is_Expression_Of_Func_Return (N : Node_Id) return Boolean; + -- Return True if N is the expression of a function return + function Is_Uninitialized_Aggregate (Exp : Node_Id; T : Entity_Id) return Boolean; @@ -1081,10 +1084,12 @@ package body Exp_Util is Make_Attribute_Reference (Loc, Prefix => (if Is_Allocate then - Duplicate_Subexpr_No_Checks (Expression (Alloc_Expr)) + Duplicate_Subexpr_No_Checks + (Expression (Alloc_Expr), New_Scope => Proc_Id) else Make_Explicit_Dereference (Loc, - Duplicate_Subexpr_No_Checks (Expr))), + Duplicate_Subexpr_No_Checks + (Expr, New_Scope => Proc_Id))), Attribute_Name => Name_Alignment))); end if; @@ -1137,7 +1142,9 @@ package body Exp_Util is if Is_RTE (Etype (Temp), RE_Tag_Ptr) then Param := Make_Explicit_Dereference (Loc, - Prefix => Duplicate_Subexpr_No_Checks (Temp)); + Prefix => + Duplicate_Subexpr_No_Checks + (Temp, New_Scope => Proc_Id)); -- In the default case, obtain the tag of the object about -- to be allocated / deallocated. Generate: @@ -1157,7 +1164,9 @@ package body Exp_Util is Param := Make_Attribute_Reference (Loc, - Prefix => Duplicate_Subexpr_No_Checks (Temp), + Prefix => + Duplicate_Subexpr_No_Checks + (Temp, New_Scope => Proc_Id), Attribute_Name => Name_Tag); end if; @@ -1517,7 +1526,228 @@ package body Exp_Util is New_E := Type_Map.Get (Entity (N)); if Present (New_E) then - Rewrite (N, New_Occurrence_Of (New_E, Sloc (N))); + declare + + Ctrl_Type : constant Entity_Id + := Find_Dispatching_Type (Par_Subp); + + function Must_Map_Call_To_Parent_Primitive + (Call_Node : Node_Id; + Check_Parents : Boolean := True) return Boolean; + -- If Call_Node is a call to a primitive function F of the + -- tagged type T associated with Par_Subp that either has + -- any actuals that involve controlling formals of Par_Subp, + -- or else the call to F is an actual parameter of an + -- enclosing call to a primitive of T that has any actuals + -- that involve controlling formals of Par_Subp (and + -- recursively up the tree of enclosing function calls), + -- returns True; otherwise returns False. Returning True + -- implies that the call to F must be mapped to a call + -- that instead targets the corresponding function F of + -- the tagged type for which Subp is a primitive function. + -- Checks_Parent specifies whether this function should + -- recursively check enclosing calls. + + --------------------------------------- + -- Must_Map_Call_To_Parent_Primitive -- + --------------------------------------- + + function Must_Map_Call_To_Parent_Primitive + (Call_Node : Node_Id; + Check_Parents : Boolean := True) return Boolean + is + pragma Assert (Nkind (Call_Node) = N_Function_Call); + + Actual : Node_Id := First_Actual (Call_Node); + + function Expr_Has_Ctrl_Formal_Ref + (Expr : Node_Id) return Boolean; + -- Determines whether Expr is or contains a reference + -- to a controlling formal and returns True if so. More + -- specifically, if Expr is not directly a reference + -- to a formal, it can be an access attribute or Old + -- attribute whose immediate object prefix is such + -- a reference (possibly through a chain of multiple + -- such attributes); or else it can be a dereference + -- of a controlling formal; or else it can be either + -- a dependent expression of a conditional expression, + -- or the expression of a declare expression that + -- qualifies as such. Returns True if the expression + -- satisifies one of those requirements; otherwise + -- returns False. + + ------------------------------ + -- Expr_Has_Ctrl_Formal_Ref -- + ------------------------------ + + function Expr_Has_Ctrl_Formal_Ref + (Expr : Node_Id) return Boolean + is + + function Is_Controlling_Formal_Ref + (N : Node_Id) return Boolean; + -- Returns True if and only if N denotes a reference + -- to a controlling formal declared for Par_Subp, or + -- Subp as formals may have been rewritten before the + -- test happens. + + ------------------------------- + -- Is_Controlling_Formal_Ref -- + ------------------------------- + + function Is_Controlling_Formal_Ref + (N : Node_Id) return Boolean + is + begin + return Nkind (N) in N_Identifier | N_Expanded_Name + and then Is_Formal (Entity (N)) + and then Is_Controlling_Formal (Entity (N)) + and then Scope (Entity (N)) in Par_Subp | Subp; + end Is_Controlling_Formal_Ref; + + -- Start of processing for Expr_Has_Ctrl_Formal_Ref + + begin + if (Nkind (Expr) = N_Attribute_Reference + and then Attribute_Name (Expr) + in Name_Old + | Name_Access + | Name_Unchecked_Access + | Name_Unrestricted_Access) + or else Nkind (Expr) = N_Explicit_Dereference + then + return Expr_Has_Ctrl_Formal_Ref (Prefix (Expr)); + + elsif Nkind (Expr) = N_If_Expression then + declare + Then_Expr : constant Node_Id := + Pick (Expressions (Expr), 2); + Else_Expr : constant Node_Id := + Pick (Expressions (Expr), 3); + begin + return Expr_Has_Ctrl_Formal_Ref (Then_Expr) + or else Expr_Has_Ctrl_Formal_Ref (Else_Expr); + end; + + elsif Nkind (Expr) = N_Case_Expression then + declare + Case_Expr_Alt : Node_Id := + First (Alternatives (Expr)); + begin + while Present (Case_Expr_Alt) loop + if Expr_Has_Ctrl_Formal_Ref + (Expression (Case_Expr_Alt)) + then + return True; + end if; + + Next (Case_Expr_Alt); + end loop; + end; + + return False; + + -- Case of a declare_expression + + elsif Nkind (Expr) = N_Expression_With_Actions + and then Comes_From_Source (Expr) + then + return Expr_Has_Ctrl_Formal_Ref (Expression (Expr)); + + -- All other cases must be references to a formal + + else + return Is_Controlling_Formal_Ref (Expr); + end if; + end Expr_Has_Ctrl_Formal_Ref; + + -- Start of processing for Must_Map_Call_To_Parent_Primitive + + begin + if Is_Entity_Name (Name (Call_Node)) + and then Is_Dispatching_Operation + (Entity (Name (Call_Node))) + and then + Is_Ancestor + (Ctrl_Type, + Find_Dispatching_Type + (Entity (Name (Call_Node)))) + then + while Present (Actual) loop + + -- If at least one actual references a controlling + -- formal parameter of a class-wide Pre/Post + -- aspect's associated subprogram (including + -- a direct prefix of an access attribute or + -- dereference), the rule in RM 6.1.1(7) applies, + -- and we want to map the call to target the + -- corresponding function of the derived type. + + if Expr_Has_Ctrl_Formal_Ref (Actual) then + return True; + + -- RM 6.1.1(7) also applies to Result attributes + -- of primitive functions with controlling results. + + elsif Is_Attribute_Result (Actual) + and then Has_Controlling_Result (Subp) + then + return True; + + -- Recursively check any actuals that are function + -- calls with controlling results. + + elsif Nkind (Actual) = N_Function_Call + and then + Has_Controlling_Result + (Entity (Name (Actual))) + and then + Must_Map_Call_To_Parent_Primitive + (Actual, Check_Parents => False) + then + return True; + end if; + + Next_Actual (Actual); + end loop; + + -- Recursively check parents that are function calls, + -- to handle cases like "F1 (F2, F3 (X))", where + -- Call_Node is the call to F2, and we need to map + -- F1, F2, and F3 due to the reference to formal X. + + if Check_Parents + and then Nkind (Parent (Call_Node)) = N_Function_Call + then + return Must_Map_Call_To_Parent_Primitive + (Parent (Call_Node)); + end if; + + return False; + + else + return False; + end if; + end Must_Map_Call_To_Parent_Primitive; + + begin + -- If N's entity is in the map, then the entity is either + -- a formal of the parent subprogram that should necessarily + -- be mapped, or it's a function call's target entity that + -- that should be mapped if the call involves any actuals + -- that reference formals of the parent subprogram (or the + -- function call is part of an enclosing call that similarly + -- qualifies for mapping). Rewrite a node that references + -- any such qualified entity to a new node referencing the + -- corresponding entity associated with the derived type. + + if not Is_Subprogram (Entity (N)) + or else Nkind (Parent (N)) /= N_Function_Call + or else Must_Map_Call_To_Parent_Primitive (Parent (N)) + then + Rewrite (N, New_Occurrence_Of (New_E, Sloc (N))); + end if; + end; end if; -- Update type of function call node, which should be the same as @@ -1956,7 +2186,7 @@ package body Exp_Util is -- time capture the visibility of the proper package part. Set_Parent (Expr, Typ_Decl); - Preanalyze_Assert_Expression (Expr, Any_Boolean); + Preanalyze_And_Resolve_Assert_Expression (Expr, Any_Boolean); -- Save a copy of the expression with all replacements and analysis -- already taken place in case a derived type inherits the pragma. @@ -1969,8 +2199,8 @@ package body Exp_Util is -- If the pragma comes from an aspect specification, replace the -- saved expression because all type references must be substituted - -- for the call to Preanalyze_Spec_Expression in Check_Aspect_At_xxx - -- routines. + -- for the call to Preanalyze_And_Resolve_Spec_Expression in + -- Check_Aspect_At_xxx routines. if Present (DIC_Asp) then Set_Expression_Copy (DIC_Asp, New_Copy_Tree (Expr)); @@ -3217,7 +3447,7 @@ package body Exp_Util is -- part. Set_Parent (Expr, Parent (Prag_Expr)); - Preanalyze_Assert_Expression (Expr, Any_Boolean); + Preanalyze_And_Resolve_Assert_Expression (Expr, Any_Boolean); -- Save a copy of the expression when T is tagged to detect -- errors and capture the visibility of the proper package part @@ -3229,8 +3459,8 @@ package body Exp_Util is -- If the pragma comes from an aspect specification, replace -- the saved expression because all type references must be - -- substituted for the call to Preanalyze_Spec_Expression in - -- Check_Aspect_At_xxx routines. + -- substituted for the call to Preanalyze_And_Resolve_Spec_ + -- Expression in Check_Aspect_At_xxx routines. if Present (Prag_Asp) then Set_Expression_Copy (Prag_Asp, New_Copy_Tree (Expr)); @@ -5062,12 +5292,13 @@ package body Exp_Util is function Duplicate_Subexpr (Exp : Node_Id; - Name_Req : Boolean := False; - Renaming_Req : Boolean := False) return Node_Id + New_Scope : Entity_Id := Empty; + Name_Req : Boolean := False; + Renaming_Req : Boolean := False) return Node_Id is begin Remove_Side_Effects (Exp, Name_Req, Renaming_Req); - return New_Copy_Tree (Exp); + return New_Copy_Tree (Exp, New_Scope => New_Scope); end Duplicate_Subexpr; --------------------------------- @@ -5076,8 +5307,9 @@ package body Exp_Util is function Duplicate_Subexpr_No_Checks (Exp : Node_Id; - Name_Req : Boolean := False; - Renaming_Req : Boolean := False) return Node_Id + New_Scope : Entity_Id := Empty; + Name_Req : Boolean := False; + Renaming_Req : Boolean := False) return Node_Id is New_Exp : Node_Id; @@ -5087,7 +5319,7 @@ package body Exp_Util is Name_Req => Name_Req, Renaming_Req => Renaming_Req); - New_Exp := New_Copy_Tree (Exp); + New_Exp := New_Copy_Tree (Exp, New_Scope => New_Scope); Remove_Checks (New_Exp); return New_Exp; end Duplicate_Subexpr_No_Checks; @@ -5098,14 +5330,15 @@ package body Exp_Util is function Duplicate_Subexpr_Move_Checks (Exp : Node_Id; - Name_Req : Boolean := False; - Renaming_Req : Boolean := False) return Node_Id + New_Scope : Entity_Id := Empty; + Name_Req : Boolean := False; + Renaming_Req : Boolean := False) return Node_Id is New_Exp : Node_Id; begin Remove_Side_Effects (Exp, Name_Req, Renaming_Req); - New_Exp := New_Copy_Tree (Exp); + New_Exp := New_Copy_Tree (Exp, New_Scope => New_Scope); Remove_Checks (Exp); return New_Exp; end Duplicate_Subexpr_Move_Checks; @@ -5949,13 +6182,14 @@ package body Exp_Util is -- now known to be protected, the finalization routine is the one -- defined on the corresponding record of the ancestor (corresponding -- records do not automatically inherit operations, but maybe they - -- should???) + -- should???). This does not apply to array types, where every base + -- type has a finalization routine that depends on the first subtype. - if Is_Untagged_Derivation (Btyp) then + if Is_Untagged_Derivation (Btyp) and then not Is_Array_Type (Btyp) then if Is_Protected_Type (Btyp) then Utyp := Corresponding_Record_Type (Root_Type (Btyp)); - else + elsif Is_Implicit_Full_View (Utyp) then Utyp := Underlying_Type (Root_Type (Btyp)); if Is_Protected_Type (Utyp) then @@ -7933,21 +8167,21 @@ package body Exp_Util is -- never climb up as far as the N_Expression_With_Actions itself. when N_Expression_With_Actions => - if N = Expression (P) then - if Is_Empty_List (Actions (P)) then - Append_List_To (Actions (P), Ins_Actions); - Analyze_List (Actions (P)); - else - Insert_List_After_And_Analyze - (Last (Actions (P)), Ins_Actions); - end if; - - return; + if Is_List_Member (N) and then List_Containing (N) = Actions (P) + then + raise Program_Error; + end if; + if Is_Empty_List (Actions (P)) then + Append_List_To (Actions (P), Ins_Actions); + Analyze_List (Actions (P)); else - raise Program_Error; + Insert_List_After_And_Analyze + (Last (Actions (P)), Ins_Actions); end if; + return; + -- Case of appearing in the condition of a while expression or -- elsif. We insert the actions into the Condition_Actions field. -- They will be moved further out when the while loop or elsif @@ -8075,20 +8309,24 @@ package body Exp_Util is elsif Nkind (Parent (P)) in N_Variant | N_Record_Definition then null; - -- Do not insert freeze nodes within the loop generated for - -- an aggregate, because they may be elaborated too late for - -- subsequent use in the back end: within a package spec the - -- loop is part of the elaboration procedure and is only - -- elaborated during the second pass. - - -- If the loop comes from source, or the entity is local to the - -- loop itself it must remain within. - - elsif Nkind (Parent (P)) = N_Loop_Statement - and then not Comes_From_Source (Parent (P)) + -- Do not insert freeze nodes within a block or loop generated + -- for an aggregate, because they may be elaborated too late + -- for subsequent use in the back end: within a package spec, + -- the block or loop is part of the elaboration procedure and + -- is only elaborated during the second pass. + + -- If the block or loop comes from source, or the entity is + -- local to the block or loop itself, it must remain within. + + elsif ((Nkind (Parent (P)) = N_Handled_Sequence_Of_Statements + and then + Nkind (Parent (Parent (P))) = N_Block_Statement + and then not Comes_From_Source (Parent (Parent (P)))) + or else (Nkind (Parent (P)) = N_Loop_Statement + and then not Comes_From_Source (Parent (P)))) and then Nkind (First (Ins_Actions)) = N_Freeze_Entity - and then - Scope (Entity (First (Ins_Actions))) /= Current_Scope + and then not + Within_Scope (Entity (First (Ins_Actions)), Current_Scope) then null; @@ -8103,19 +8341,31 @@ package body Exp_Util is return; end if; - -- the expansion of Task and protected type declarations can + -- The expansion of task and protected type declarations can -- create declarations for temporaries which, like other actions - -- are inserted and analyzed before the current declaraation. - -- However, the current scope is the synchronized type, and - -- for unnesting it is critical that the proper scope for these - -- generated entities be the enclosing one. + -- are inserted and analyzed before the current declaration. + -- However, in some cases, the current scope is the synchronized + -- type, and for unnesting it is critical that the proper scope + -- for these generated entities be the enclosing one. when N_Task_Type_Declaration | N_Protected_Type_Declaration => - Push_Scope (Scope (Current_Scope)); - Insert_List_Before_And_Analyze (P, Ins_Actions); - Pop_Scope; + declare + Skip_Scope : constant Boolean := + Ekind (Current_Scope) in Concurrent_Kind; + begin + if Skip_Scope then + Push_Scope (Scope (Current_Scope)); + end if; + + Insert_List_Before_And_Analyze (P, Ins_Actions); + + if Skip_Scope then + Pop_Scope; + end if; + end; + return; -- A special case, N_Raise_xxx_Error can act either as a statement @@ -8563,6 +8813,20 @@ package body Exp_Util is end if; end Is_Captured_Function_Call; + ------------------------------------------------- + -- Is_Constr_Array_Subt_Of_Unc_With_Controlled -- + ------------------------------------------------- + + function Is_Constr_Array_Subt_Of_Unc_With_Controlled (Typ : Entity_Id) + return Boolean + is + begin + return Is_Array_Type (Typ) + and then Is_Constrained (Typ) + and then Has_Controlled_Component (Typ) + and then not Is_Constrained (First_Subtype (Typ)); + end Is_Constr_Array_Subt_Of_Unc_With_Controlled; + ------------------------------------------ -- Is_Conversion_Or_Reference_To_Formal -- ------------------------------------------ @@ -8606,6 +8870,97 @@ package body Exp_Util is and then Nkind (Name (N)) = N_Explicit_Dereference; end Is_Expanded_Class_Wide_Interface_Object_Decl; + ---------------------------------- + -- Is_Expression_Of_Func_Return -- + ---------------------------------- + + function Is_Expression_Of_Func_Return (N : Node_Id) return Boolean is + Par : constant Node_Id := Parent (N); + + begin + return Nkind (Par) = N_Simple_Return_Statement + or else (Nkind (Par) in N_Object_Declaration + | N_Object_Renaming_Declaration + and then Is_Return_Object (Defining_Entity (Par))); + end Is_Expression_Of_Func_Return; + + --------------------------- + -- Is_Finalizable_Access -- + --------------------------- + + function Is_Finalizable_Access (Decl : Node_Id) return Boolean is + Obj : constant Entity_Id := Defining_Identifier (Decl); + Typ : constant Entity_Id := Base_Type (Etype (Obj)); + Desig : constant Entity_Id := Available_View (Designated_Type (Typ)); + Expr : constant Node_Id := Expression (Decl); + + Secondary_Stack_Val : constant Uint := + UI_From_Int (BIP_Allocation_Form'Pos (Secondary_Stack)); + + Actual : Node_Id; + Call : Node_Id; + Formal : Node_Id; + Param : Node_Id; + + begin + -- The prerequisite is a reference to a controlled object + + if No (Expr) + or else Nkind (Expr) /= N_Reference + or else not Needs_Finalization (Desig) + then + return False; + end if; + + Call := Unqual_Conv (Prefix (Expr)); + + -- For a BIP function call, the only case where the return object needs + -- to be finalized through Obj is when it is allocated on the secondary + -- stack; when it is allocated in the caller, it is finalized directly, + -- and when it is allocated on the global heap or in a storage pool, it + -- is finalized through another mechanism. + + -- Obj : Access_Typ := + -- BIP_Function_Call (BIPalloc => Secondary_Stack, ...)'reference; + + if Is_Build_In_Place_Function_Call (Call) then + + -- Examine all parameter associations of the function call + + Param := First (Parameter_Associations (Call)); + while Present (Param) loop + if Nkind (Param) = N_Parameter_Association then + Formal := Selector_Name (Param); + Actual := Explicit_Actual_Parameter (Param); + + -- A match for BIPalloc => Secondary_Stack has been found + + if Is_Build_In_Place_Entity (Formal) + and then BIP_Suffix_Kind (Formal) = BIP_Alloc_Form + and then Nkind (Actual) = N_Integer_Literal + and then Intval (Actual) = Secondary_Stack_Val + then + return True; + end if; + end if; + + Next (Param); + end loop; + + -- For a non-BIP function call, the only case where the return object + -- need not be finalized is when it itself is going to be returned. + + -- Obj : Typ := Non_BIP_Function_Call'reference; + + elsif Nkind (Call) = N_Function_Call + and then not Is_Related_To_Func_Return (Obj) + then + return True; + end if; + + return False; + end Is_Finalizable_Access; + ------------------------------ -- Is_Finalizable_Transient -- ------------------------------ @@ -8617,19 +8972,6 @@ package body Exp_Util is Obj_Id : constant Entity_Id := Defining_Identifier (Decl); Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id)); - function Initialized_By_Aliased_BIP_Func_Call - (Trans_Id : Entity_Id) return Boolean; - -- Determine whether transient object Trans_Id is initialized by a - -- build-in-place function call where the BIPalloc parameter either - -- does not exist or is Caller_Allocation, and BIPaccess is not null. - -- This case creates an aliasing between the returned value and the - -- value denoted by BIPaccess. - - function Initialized_By_Reference (Trans_Id : Entity_Id) return Boolean; - -- Determine whether transient object Trans_Id is initialized by a - -- reference to another object. This is the only case where we can - -- possibly finalize a transient object through an access value. - function Is_Aliased (Trans_Id : Entity_Id; First_Stmt : Node_Id) return Boolean; @@ -8655,115 +8997,6 @@ package body Exp_Util is -- Return True if N is directly part of a build-in-place return -- statement. - ------------------------------------------ - -- Initialized_By_Aliased_BIP_Func_Call -- - ------------------------------------------ - - function Initialized_By_Aliased_BIP_Func_Call - (Trans_Id : Entity_Id) return Boolean - is - Call : Node_Id := Expression (Parent (Trans_Id)); - - begin - -- Build-in-place calls usually appear in 'reference format - - if Nkind (Call) = N_Reference then - Call := Prefix (Call); - end if; - - Call := Unqual_Conv (Call); - - -- We search for a formal with a matching suffix. We can't search - -- for the full name, because of the code at the end of Sem_Ch6.- - -- Create_Extra_Formals, which copies the Extra_Formals over to - -- the Alias of an instance, which will cause the formals to have - -- "incorrect" names. See also Exp_Ch6.Build_In_Place_Formal. - - if Is_Build_In_Place_Function_Call (Call) then - declare - Caller_Allocation_Val : constant Uint := - UI_From_Int (BIP_Allocation_Form'Pos (Caller_Allocation)); - Access_Suffix : constant String := - BIP_Formal_Suffix (BIP_Object_Access); - Alloc_Suffix : constant String := - BIP_Formal_Suffix (BIP_Alloc_Form); - - function Has_Suffix (Name, Suffix : String) return Boolean; - -- Return True if Name has suffix Suffix - - ---------------- - -- Has_Suffix -- - ---------------- - - function Has_Suffix (Name, Suffix : String) return Boolean is - Len : constant Natural := Suffix'Length; - - begin - return Name'Length > Len - and then Name (Name'Last - Len + 1 .. Name'Last) = Suffix; - end Has_Suffix; - - Access_OK : Boolean := False; - Alloc_OK : Boolean := True; - Param : Node_Id; - - begin - -- Examine all parameter associations of the function call - - Param := First (Parameter_Associations (Call)); - - while Present (Param) loop - if Nkind (Param) = N_Parameter_Association - and then Nkind (Selector_Name (Param)) = N_Identifier - then - declare - Actual : constant Node_Id := - Explicit_Actual_Parameter (Param); - Formal : constant Node_Id := - Selector_Name (Param); - Name : constant String := - Get_Name_String (Chars (Formal)); - - begin - -- A nonnull BIPaccess has been found - - if Has_Suffix (Name, Access_Suffix) - and then Nkind (Actual) /= N_Null - then - Access_OK := True; - - -- A BIPalloc has been found - - elsif Has_Suffix (Name, Alloc_Suffix) - and then Nkind (Actual) = N_Integer_Literal - then - Alloc_OK := Intval (Actual) = Caller_Allocation_Val; - end if; - end; - end if; - - Next (Param); - end loop; - - return Access_OK and Alloc_OK; - end; - end if; - - return False; - end Initialized_By_Aliased_BIP_Func_Call; - - ------------------------------ - -- Initialized_By_Reference -- - ------------------------------ - - function Initialized_By_Reference (Trans_Id : Entity_Id) return Boolean - is - Expr : constant Node_Id := Expression (Parent (Trans_Id)); - - begin - return Present (Expr) and then Nkind (Expr) = N_Reference; - end Initialized_By_Reference; - ---------------- -- Is_Aliased -- ---------------- @@ -8869,13 +9102,16 @@ package body Exp_Util is Stmt := First_Stmt; while Present (Stmt) loop - -- Transient objects initialized by a reference are finalized - -- (see Initialized_By_Reference above), so we must make sure - -- not to finalize the referenced object twice. And we cannot - -- finalize it at all if it is referenced by the nontransient - -- object serviced by the transient scope. - - if Nkind (Stmt) = N_Object_Declaration then + -- (Transient) objects initialized by a reference to another named + -- object are never finalized (see Is_Finalizable_Access), so we + -- need not worry about finalizing (transient) referenced objects + -- twice. Therefore, we only need to look at the nontransient + -- object serviced by the transient scope, if it exists and is + -- declared as a reference to another named object. + + if Nkind (Stmt) = N_Object_Declaration + and then Stmt = N + then Expr := Expression (Stmt); -- Aliasing of the form: @@ -8889,8 +9125,8 @@ package body Exp_Util is return True; end if; - -- (Transient) renamings are never finalized so we need not bother - -- about finalizing transient renamed objects twice. Therefore, we + -- (Transient) renamings are never finalized so we need not worry + -- about finalizing (transient) renamed objects twice. Therefore, -- we only need to look at the nontransient object serviced by the -- transient scope, if it exists and is declared as a renaming. @@ -9090,12 +9326,11 @@ package body Exp_Util is function Is_Part_Of_BIP_Return_Statement (N : Node_Id) return Boolean is Subp : constant Entity_Id := Current_Subprogram; Context : Node_Id; + begin -- First check if N is part of a BIP function - if No (Subp) - or else not Is_Build_In_Place_Function (Subp) - then + if No (Subp) or else not Is_Build_In_Place_Function (Subp) then return False; end if; @@ -9119,6 +9354,15 @@ package body Exp_Util is -- Start of processing for Is_Finalizable_Transient begin + -- If the node serviced by the transient context is a return statement, + -- then the finalization needs to be deferred to the generic machinery. + + if Nkind (N) = N_Simple_Return_Statement + or else Is_Part_Of_BIP_Return_Statement (N) + then + return False; + end if; + -- Handle access types if Is_Access_Type (Desig) then @@ -9128,34 +9372,27 @@ package body Exp_Util is return Ekind (Obj_Id) in E_Constant | E_Variable and then Needs_Finalization (Desig) - and then Nkind (N) /= N_Simple_Return_Statement - and then not Is_Part_Of_BIP_Return_Statement (N) -- Do not consider a transient object that was already processed and then not Is_Finalized_Transient (Obj_Id) - -- Do not consider renamed or 'reference-d transient objects because - -- the act of renaming extends the object's lifetime. + -- Do not consider iterators because those are treated as normal + -- controlled objects and are processed by the usual finalization + -- machinery. This avoids the double finalization of an iterator. - and then not Is_Aliased (Obj_Id, Decl) + and then not Is_Iterator (Desig) - -- If the transient object is of an access type, check that it is - -- initialized by a reference to another object. + -- If the transient object is of an access type, check that it must + -- be finalized. and then (not Is_Access_Type (Obj_Typ) - or else Initialized_By_Reference (Obj_Id)) + or else Is_Finalizable_Access (Decl)) - -- Do not consider transient objects which act as indirect aliases - -- of build-in-place function results. + -- Do not consider renamed transient objects because the act of + -- renaming extends the object's lifetime. - and then not Initialized_By_Aliased_BIP_Func_Call (Obj_Id) - - -- Do not consider iterators because those are treated as normal - -- controlled objects and are processed by the usual finalization - -- machinery. This avoids the double finalization of an iterator. - - and then not Is_Iterator (Desig) + and then not Is_Aliased (Obj_Id, Decl) -- Do not consider containers in the context of iterator loops. Such -- transient objects must exist for as long as the loop is around, @@ -9224,22 +9461,6 @@ package body Exp_Util is and then Present (LSP_Subprogram (E)); end Is_LSP_Wrapper; - -------------------------- - -- Is_Non_BIP_Func_Call -- - -------------------------- - - function Is_Non_BIP_Func_Call (Expr : Node_Id) return Boolean is - begin - -- The expected call is of the format - -- - -- Func_Call'reference - - return - Nkind (Expr) = N_Reference - and then Nkind (Prefix (Expr)) = N_Function_Call - and then not Is_Build_In_Place_Function_Call (Prefix (Expr)); - end Is_Non_BIP_Func_Call; - ---------------------------------- -- Is_Possibly_Unaligned_Object -- ---------------------------------- @@ -9512,21 +9733,16 @@ package body Exp_Util is function Is_Related_To_Func_Return (Id : Entity_Id) return Boolean is Expr : constant Node_Id := Related_Expression (Id); + begin -- In the case of a function with a class-wide result that returns -- a call to a function with a specific result, we introduce a -- type conversion for the return expression. We do not want that -- type conversion to influence the result of this function. - return - Present (Expr) - and then Nkind (Unqual_Conv (Expr)) = N_Explicit_Dereference - and then (Nkind (Parent (Expr)) = N_Simple_Return_Statement - or else - (Nkind (Parent (Expr)) in N_Object_Declaration - | N_Object_Renaming_Declaration - and then - Is_Return_Object (Defining_Entity (Parent (Expr))))); + return Present (Expr) + and then Nkind (Unqual_Conv (Expr)) = N_Explicit_Dereference + and then Is_Expression_Of_Func_Return (Expr); end Is_Related_To_Func_Return; -------------------------------- @@ -9612,55 +9828,6 @@ package body Exp_Util is end if; end Is_Renamed_Object; - -------------------------------------- - -- Is_Secondary_Stack_BIP_Func_Call -- - -------------------------------------- - - function Is_Secondary_Stack_BIP_Func_Call (Expr : Node_Id) return Boolean is - Actual : Node_Id; - Call : Node_Id := Expr; - Formal : Node_Id; - Param : Node_Id; - - begin - -- Build-in-place calls usually appear in 'reference format. Note that - -- the accessibility check machinery may add an extra 'reference due to - -- side-effect removal. - - while Nkind (Call) = N_Reference loop - Call := Prefix (Call); - end loop; - - Call := Unqual_Conv (Call); - - if Is_Build_In_Place_Function_Call (Call) then - - -- Examine all parameter associations of the function call - - Param := First (Parameter_Associations (Call)); - while Present (Param) loop - if Nkind (Param) = N_Parameter_Association then - Formal := Selector_Name (Param); - Actual := Explicit_Actual_Parameter (Param); - - -- A match for BIPalloc => 2 has been found - - if Is_Build_In_Place_Entity (Formal) - and then BIP_Suffix_Kind (Formal) = BIP_Alloc_Form - and then Nkind (Actual) = N_Integer_Literal - and then Intval (Actual) = Uint_2 - then - return True; - end if; - end if; - - Next (Param); - end loop; - end if; - - return False; - end Is_Secondary_Stack_BIP_Func_Call; - ------------------------------ -- Is_Secondary_Stack_Thunk -- ------------------------------ @@ -10871,11 +11038,10 @@ package body Exp_Util is -- operator on private type might not be visible and won't be -- resolved. - else pragma Assert (Is_RTE (Base_Type (Typ), RE_Big_Integer) - or else - Is_RTE (Base_Type (Typ), RO_GH_Big_Integer) - or else - Is_RTE (Base_Type (Typ), RO_SP_Big_Integer)); + else + pragma Assert + (Is_RTE (Base_Type (Typ), RE_Big_Integer) + or else Is_RTE (Base_Type (Typ), RO_SP_Big_Integer)); return Make_Function_Call (Loc, Name => @@ -11564,34 +11730,6 @@ package body Exp_Util is end if; end Matching_Standard_Type; - ----------------------------- - -- May_Generate_Large_Temp -- - ----------------------------- - - -- At the current time, the only types that we return False for (i.e. where - -- we decide we know they cannot generate large temps) are ones where we - -- know the size is 256 bits or less at compile time, and we are still not - -- doing a thorough job on arrays and records. - - function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is - begin - if not Size_Known_At_Compile_Time (Typ) then - return False; - end if; - - if Known_Esize (Typ) and then Esize (Typ) <= 256 then - return False; - end if; - - if Is_Array_Type (Typ) - and then Present (Packed_Array_Impl_Type (Typ)) - then - return May_Generate_Large_Temp (Packed_Array_Impl_Type (Typ)); - end if; - - return True; - end May_Generate_Large_Temp; - --------------------------------------- -- Move_To_Initialization_Statements -- --------------------------------------- @@ -12704,18 +12842,22 @@ package body Exp_Util is -- Otherwise we generate a reference to the expression else - -- Special processing for function calls that return a limited type. - -- We need to build a declaration that will enable build-in-place - -- expansion of the call. This is not done if the context is already - -- an object declaration, to prevent infinite recursion. - - -- This is relevant only in Ada 2005 mode. In Ada 95 programs we have - -- to accommodate functions returning limited objects by reference. - - if Ada_Version >= Ada_2005 - and then Nkind (Exp) = N_Function_Call - and then Is_Inherently_Limited_Type (Etype (Exp)) + -- Special processing for function calls with a result type that is + -- either BIP or a constrained array with controlled component and + -- an unconstrained first subtype, when the context is neither an + -- object declaration (to prevent infinite recursion) nor a function + -- return (to propagate the anonymous return object). + + -- We need to build an object declaration to trigger build-in-place + -- expansion of the call in the former case, and addition of bounds + -- to the object in the latter case. + + if Nkind (Exp) = N_Function_Call + and then (Is_Build_In_Place_Result_Type (Exp_Type) + or else + Is_Constr_Array_Subt_Of_Unc_With_Controlled (Exp_Type)) and then Nkind (Parent (Exp)) /= N_Object_Declaration + and then not Is_Expression_Of_Func_Return (Exp) then declare Obj : constant Entity_Id := Make_Temporary (Loc, 'F', Exp); @@ -13324,7 +13466,6 @@ package body Exp_Util is Nested_Constructs : Boolean) return Boolean is Decl : Node_Id; - Expr : Node_Id; Obj_Id : Entity_Id; Obj_Typ : Entity_Id; Pack_Id : Entity_Id; @@ -13362,7 +13503,6 @@ package body Exp_Util is elsif Nkind (Decl) = N_Object_Declaration then Obj_Id := Defining_Identifier (Decl); Obj_Typ := Base_Type (Etype (Obj_Id)); - Expr := Expression (Decl); -- Bypass any form of processing for objects which have their -- finalization disabled. This applies only to objects at the @@ -13416,21 +13556,10 @@ package body Exp_Util is then return True; - -- The object is of the form: - -- Obj : Access_Typ := Non_BIP_Function_Call'reference; - -- - -- Obj : Access_Typ := - -- BIP_Function_Call (BIPalloc => 2, ...)'reference; + -- The object is an access-to-controlled that must be finalized elsif Is_Access_Type (Obj_Typ) - and then Needs_Finalization - (Available_View (Designated_Type (Obj_Typ))) - and then Present (Expr) - and then - (Is_Secondary_Stack_BIP_Func_Call (Expr) - or else - (Is_Non_BIP_Func_Call (Expr) - and then not Is_Related_To_Func_Return (Obj_Id))) + and then Is_Finalizable_Access (Decl) then return True; @@ -13603,11 +13732,12 @@ package body Exp_Util is -- The above requirements should be documented in Sinfo ??? function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is + Pexp : constant Node_Id := Parent (Exp); + Otyp : Entity_Id; Ityp : Entity_Id; Oalign : Uint; Ialign : Uint; - Pexp : constant Node_Id := Parent (Exp); begin -- If the expression is the RHS of an assignment or object declaration @@ -13625,18 +13755,12 @@ package body Exp_Util is return True; -- If the expression is the prefix of an N_Selected_Component we should - -- also be OK because GCC knows to look inside the conversion except if - -- the type is discriminated. We assume that we are OK anyway if the - -- type is not set yet or if it is controlled since we can't afford to - -- introduce a temporary in this case. + -- also be OK because GCC knows to look inside the conversion. elsif Nkind (Pexp) = N_Selected_Component and then Prefix (Pexp) = Exp then - return No (Etype (Pexp)) - or else not Is_Type (Etype (Pexp)) - or else not Has_Discriminants (Etype (Pexp)) - or else Is_Constrained (Etype (Pexp)); + return True; end if; -- Set the output type, this comes from Etype if it is set, otherwise we @@ -13709,14 +13833,7 @@ package body Exp_Util is -- known size, but we can't consider them that way here, because we are -- talking about the actual size of the object. - -- We also make sure that in addition to the size being known, we do not - -- have a case which might generate an embarrassingly large temp in - -- stack checking mode. - elsif Size_Known_At_Compile_Time (Otyp) - and then - (not Stack_Checking_Enabled - or else not May_Generate_Large_Temp (Otyp)) and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp)) then return True; @@ -14439,6 +14556,11 @@ package body Exp_Util is when N_Aggregate => return Compile_Time_Known_Aggregate (N); + -- A reference is side-effect-free + + when N_Reference => + return True; + -- We consider that anything else has side effects. This is a bit -- crude, but we are pretty close for most common cases, and we -- are certainly correct (i.e. we never return True when the @@ -14466,7 +14588,16 @@ package body Exp_Util is else N := First (L); while Present (N) loop - if not Side_Effect_Free (N, Name_Req, Variable_Ref) then + if Nkind (N) = N_Parameter_Association then + if not + Side_Effect_Free + (Explicit_Actual_Parameter (N), Name_Req, Variable_Ref) + then + return False; + end if; + + Next (N); + elsif not Side_Effect_Free (N, Name_Req, Variable_Ref) then return False; else Next (N); diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads index 6178767aab61..4226fcc93777 100644 --- a/gcc/ada/exp_util.ads +++ b/gcc/ada/exp_util.ads @@ -479,8 +479,9 @@ package Exp_Util is function Duplicate_Subexpr (Exp : Node_Id; - Name_Req : Boolean := False; - Renaming_Req : Boolean := False) return Node_Id; + New_Scope : Entity_Id := Empty; + Name_Req : Boolean := False; + Renaming_Req : Boolean := False) return Node_Id; -- Given the node for a subexpression, this function makes a logical copy -- of the subexpression, and returns it. This is intended for use when the -- expansion of an expression needs to repeat part of it. For example, @@ -494,6 +495,9 @@ package Exp_Util is -- the caller is responsible for analyzing the returned copy after it is -- attached to the tree. -- + -- The New_Scope entity may be used to specify a new scope for all copied + -- entities and itypes. + -- -- The Name_Req flag is set to ensure that the result is suitable for use -- in a context requiring a name (for example, the prefix of an attribute -- reference). @@ -509,8 +513,9 @@ package Exp_Util is function Duplicate_Subexpr_No_Checks (Exp : Node_Id; - Name_Req : Boolean := False; - Renaming_Req : Boolean := False) return Node_Id; + New_Scope : Entity_Id := Empty; + Name_Req : Boolean := False; + Renaming_Req : Boolean := False) return Node_Id; -- Identical in effect to Duplicate_Subexpr, except that Remove_Checks is -- called on the result, so that the duplicated expression does not include -- checks. This is appropriate for use when Exp, the original expression is @@ -519,8 +524,9 @@ package Exp_Util is function Duplicate_Subexpr_Move_Checks (Exp : Node_Id; - Name_Req : Boolean := False; - Renaming_Req : Boolean := False) return Node_Id; + New_Scope : Entity_Id := Empty; + Name_Req : Boolean := False; + Renaming_Req : Boolean := False) return Node_Id; -- Identical in effect to Duplicate_Subexpr, except that Remove_Checks is -- called on Exp after the duplication is complete, so that the original -- expression does not include checks. In this case the result returned @@ -810,6 +816,11 @@ package Exp_Util is -- Rnn : constant Ann := Func (...)'reference; -- Rnn.all + function Is_Constr_Array_Subt_Of_Unc_With_Controlled (Typ : Entity_Id) + return Boolean; + -- Return True if Typ is a constrained subtype of an array type with an + -- unconstrained first subtype and a controlled component type. + function Is_Conversion_Or_Reference_To_Formal (N : Node_Id) return Boolean; -- Return True if N is a type conversion, or a dereference thereof, or a -- reference to a formal parameter. @@ -819,6 +830,14 @@ package Exp_Util is -- Determine if N is the expanded code for a class-wide interface type -- object declaration. + function Is_Finalizable_Access (Decl : Node_Id) return Boolean; + -- Determine whether declaration Decl denotes an access-to-controlled + -- object that must be finalized, i.e. both that the designated object + -- is controlled and that it must be finalized through this access, in + -- particular that it will not be also finalized directly. That is the + -- case only for objects initialized by a reference to a function call + -- that meet specific conditions. + function Is_Finalizable_Transient (Decl : Node_Id; N : Node_Id) return Boolean; @@ -845,9 +864,6 @@ package Exp_Util is -- preconditions or postconditions affected by overriding (AI12-0195). -- LSP stands for Liskov Substitution Principle. - function Is_Non_BIP_Func_Call (Expr : Node_Id) return Boolean; - -- Determine whether node Expr denotes a non build-in-place function call - function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean; -- Node N is an object reference. This function returns True if it is -- possible that the object may not be aligned according to the normal @@ -892,10 +908,6 @@ package Exp_Util is -- We consider that a (1 .. 2) is a renamed object since it is the prefix -- of the name in the renaming declaration. - function Is_Secondary_Stack_BIP_Func_Call (Expr : Node_Id) return Boolean; - -- Determine whether Expr denotes a build-in-place function which returns - -- its result on the secondary stack. - function Is_Secondary_Stack_Thunk (Id : Entity_Id) return Boolean; -- Determine whether Id denotes a secondary stack thunk @@ -1052,16 +1064,6 @@ package Exp_Util is -- typically return Standard_Short_Integer. For fixed-point types, this -- will return integer types of the corresponding size. - function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean; - -- Determines if the given type, Typ, may require a large temporary of the - -- kind that causes back-end trouble if stack checking is enabled. The - -- result is True only the size of the type is known at compile time and - -- large, where large is defined heuristically by the body of this routine. - -- The purpose of this routine is to help avoid generating troublesome - -- temporaries that interfere with stack checking mechanism. Note that the - -- caller has to check whether stack checking is actually enabled in order - -- to guide the expansion (typically of a function call). - procedure Move_To_Initialization_Statements (Decl, Stop : Node_Id); -- Decl is an N_Object_Declaration node and Stop is a node past Decl in -- the same list. Move all the nodes on the list between Decl and Stop diff --git a/gcc/ada/expander.adb b/gcc/ada/expander.adb index 8cec8217214f..3d7b0d77f119 100644 --- a/gcc/ada/expander.adb +++ b/gcc/ada/expander.adb @@ -230,6 +230,9 @@ package body Expander is when N_Conditional_Entry_Call => Expand_N_Conditional_Entry_Call (N); + when N_Continue_Statement => + Expand_N_Continue_Statement (N); + when N_Delay_Relative_Statement => Expand_N_Delay_Relative_Statement (N); diff --git a/gcc/ada/fe.h b/gcc/ada/fe.h index bb8b96e9cb5a..0b80a56cf195 100644 --- a/gcc/ada/fe.h +++ b/gcc/ada/fe.h @@ -110,8 +110,8 @@ extern Node_Id Get_Attribute_Definition_Clause (Entity_Id, unsigned char); /* errout: */ -#define Error_Msg_N errout__error_msg_n -#define Error_Msg_NE errout__error_msg_ne +#define Error_Msg_N errout__error_msg_n_gigi +#define Error_Msg_NE errout__error_msg_ne_gigi #define Set_Identifier_Casing errout__set_identifier_casing extern void Error_Msg_N (String_Pointer, Node_Id); diff --git a/gcc/ada/fname-uf.adb b/gcc/ada/fname-uf.adb index 39a09c4ce133..ec22ad7a3d2a 100644 --- a/gcc/ada/fname-uf.adb +++ b/gcc/ada/fname-uf.adb @@ -90,8 +90,9 @@ package body Fname.UF is Table_Initial => 10, Table_Increment => 100, Table_Name => "SFN_Patterns"); - -- Table recording calls to Set_File_Name_Pattern. Note that the first two - -- entries are set to represent the standard GNAT rules for file naming. + -- Table recording calls to Set_File_Name_Pattern. Note that the last two + -- entries are set to represent the standard GNAT rules for file naming; + -- that invariant is maintained by Set_File_Name_Pattern. procedure Instantiate_SFN_Pattern (Pattern : SFN_Pattern_Entry; @@ -178,6 +179,8 @@ package body Fname.UF is --------------------------- function Get_Default_File_Name (Uname : Unit_Name_Type) return String is + L : constant Int := SFN_Patterns.Last; + Buf : Bounded_String; Pattern : SFN_Pattern_Entry; @@ -185,10 +188,10 @@ package body Fname.UF is Get_Unit_Name_String (Buf, Uname, False); if Is_Spec_Name (Uname) then - Pattern := SFN_Patterns.Table (1); + Pattern := SFN_Patterns.Table (L - 1); else pragma Assert (Is_Body_Name (Uname)); - Pattern := SFN_Patterns.Table (2); + Pattern := SFN_Patterns.Table (L); end if; Instantiate_SFN_Pattern (Pattern, Buf); diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb index 54b620214e80..dbd7cf425a29 100644 --- a/gcc/ada/freeze.adb +++ b/gcc/ada/freeze.adb @@ -715,10 +715,11 @@ package body Freeze is then declare O_Ent : Entity_Id; + O_Typ : Entity_Id; Off : Boolean; begin - Find_Overlaid_Entity (Addr, O_Ent, Off); + Find_Overlaid_Entity (Addr, O_Ent, O_Typ, Off); if Ekind (O_Ent) = E_Constant and then Etype (O_Ent) = Typ @@ -764,6 +765,9 @@ package body Freeze is -- in fact constrained by non-static discriminant values. Could be made -- more precise ??? + function Value_Known (Exp : Node_Id) return Boolean; + -- Return True if the value of expression Exp is known at compile time + -------------------- -- Set_Small_Size -- -------------------- @@ -879,13 +883,13 @@ package body Freeze is High := Type_High_Bound (Etype (Index)); end if; - if not Compile_Time_Known_Value (Low) - or else not Compile_Time_Known_Value (High) - or else Etype (Index) = Any_Type - then + if Etype (Index) = Any_Type then return False; - else + elsif Compile_Time_Known_Value (Low) + and then Compile_Time_Known_Value (High) + then + Dim := Expr_Value (High) - Expr_Value (Low) + 1; if Dim > Uint_0 then @@ -893,6 +897,12 @@ package body Freeze is else Size := Uint_0; end if; + + elsif Value_Known (Low) and then Value_Known (High) then + Size := Uint_0; + + else + return False; end if; Next_Index (Index); @@ -1159,6 +1169,70 @@ package body Freeze is return True; end Static_Discriminated_Components; + ----------------- + -- Value_Known -- + ----------------- + + function Value_Known (Exp : Node_Id) return Boolean is + begin + -- This is the immediate case + + if Compile_Time_Known_Value (Exp) then + return True; + end if; + + -- The value may be known only to the back end, the typical example + -- being the alignment or the various sizes of composite types; in + -- the latter case, we may mutually recurse with Size_Known. + + case Nkind (Exp) is + when N_Attribute_Reference => + declare + P : constant Node_Id := Prefix (Exp); + + begin + if not Is_Entity_Name (P) + or else not Is_Type (Entity (P)) + then + return False; + end if; + + case Get_Attribute_Id (Attribute_Name (Exp)) is + when Attribute_Alignment => + return True; + + when Attribute_Component_Size => + return Size_Known (Component_Type (Entity (P))); + + when Attribute_Object_Size + | Attribute_Size + | Attribute_Value_Size + => + return Size_Known (Entity (P)); + + when others => + return False; + end case; + end; + + when N_Binary_Op => + return Value_Known (Left_Opnd (Exp)) + and then Value_Known (Right_Opnd (Exp)); + + when N_Qualified_Expression + | N_Type_Conversion + | N_Unchecked_Type_Conversion + => + return Value_Known (Expression (Exp)); + + when N_Unary_Op => + return Value_Known (Right_Opnd (Exp)); + + when others => + return False; + end case; + end Value_Known; + -- Start of processing for Check_Compile_Time_Size begin @@ -1495,12 +1569,13 @@ package body Freeze is New_Formal := Defining_Identifier (New_F_Spec); -- If the controlling argument is inherited, add conversion to - -- parent type for the call. + -- parent type for the call. We make this an unchecked conversion + -- since the formal subtypes of the parent and derived subprograms + -- must conform, so checks should not be needed. if Is_Controlling_Formal (Formal) then Append_To (Actuals, - Make_Type_Conversion (Loc, - New_Occurrence_Of (Etype (Formal), Loc), + Unchecked_Convert_To (Etype (Formal), New_Occurrence_Of (New_Formal, Loc))); else Append_To (Actuals, New_Occurrence_Of (New_Formal, Loc)); @@ -5449,9 +5524,12 @@ package body Freeze is Set_Must_Be_On_Byte_Boundary (Rec); -- Check for component clause that is inconsistent with - -- the required byte boundary alignment. + -- the required byte boundary alignment. Do not do this + -- in CodePeer_Mode, as we do not have sufficient info + -- on size and representation clauses. - if Present (CC) + if not CodePeer_Mode + and then Present (CC) and then Normalized_First_Bit (Comp) mod System_Storage_Unit /= 0 then @@ -6869,9 +6947,10 @@ package body Freeze is end if; end if; - -- Static objects require special handling + -- Statically allocated objects require special handling if (Ekind (E) = E_Constant or else Ekind (E) = E_Variable) + and then No (Renamed_Object (E)) and then Is_Statically_Allocated (E) then Freeze_Static_Object (E); @@ -7152,6 +7231,35 @@ package body Freeze is end if; Inherit_Aspects_At_Freeze_Point (E); + + -- Destructor legality check + + if Present (Primitive_Operations (E)) then + declare + Subp : Entity_Id; + Parent_Operation : Entity_Id; + + Elmt : Elmt_Id := First_Elmt (Primitive_Operations (E)); + + begin + while Present (Elmt) loop + Subp := Node (Elmt); + + if Present (Overridden_Operation (Subp)) then + Parent_Operation := Overridden_Operation (Subp); + + if Ekind (Parent_Operation) = E_Procedure + and then Is_Destructor (Parent_Operation) + then + Error_Msg_N ("cannot override destructor", Subp); + end if; + end if; + + Next_Elmt (Elmt); + end loop; + end; + end if; + end if; -- Case of array type @@ -8051,6 +8159,7 @@ package body Freeze is if Ekind (E) = E_Anonymous_Access_Subprogram_Type and then Ekind (Designated_Type (E)) = E_Subprogram_Type then + Create_Extra_Formals (Designated_Type (E)); Layout_Type (Etype (Designated_Type (E))); end if; @@ -9389,16 +9498,17 @@ package body Freeze is -- pre/postconditions during expansion of the subprogram body, the -- subprogram is already installed. - -- Call Preanalyze_Spec_Expression instead of Preanalyze_And_Resolve - -- for the sake of consistency with Analyze_Expression_Function. + -- Call Preanalyze_And_Resolve_Spec_Expression instead of Preanalyze_ + -- And_Resolve for the sake of consistency with Analyze_Expression_ + -- Function. if Def_Id /= Current_Scope then Push_Scope (Def_Id); Install_Formals (Def_Id); - Preanalyze_Spec_Expression (Dup_Expr, Typ); + Preanalyze_And_Resolve_Spec_Expression (Dup_Expr, Typ); End_Scope; else - Preanalyze_Spec_Expression (Dup_Expr, Typ); + Preanalyze_And_Resolve_Spec_Expression (Dup_Expr, Typ); end if; -- Restore certain attributes of Def_Id since the preanalysis may @@ -10230,11 +10340,17 @@ package body Freeze is -- issue an error message saying that this object cannot be imported -- or exported. If it has an address clause it is an overlay in the -- current partition and the static requirement is not relevant. - -- Do not issue any error message when ignoring rep clauses. + -- Do not issue any error message when ignoring rep clauses or for + -- compiler-generated entities. if Ignore_Rep_Clauses then null; + elsif not Comes_From_Source (E) then + pragma + Assert (Nkind (Parent (Declaration_Node (E))) in N_Case_Statement + | N_If_Statement); + elsif Is_Imported (E) then if No (Address_Clause (E)) then Error_Msg_N @@ -10307,6 +10423,8 @@ package body Freeze is -- Local variables + use Deferred_Extra_Formals_Support; + F : Entity_Id; Retype : Entity_Id; @@ -10407,8 +10525,11 @@ package body Freeze is Create_Extra_Formals (E); pragma Assert - ((Ekind (E) = E_Subprogram_Type - and then Extra_Formals_OK (E)) + ((Extra_Formals_Known (E) + or else Is_Deferred_Extra_Formals_Entity (E)) + or else + (Ekind (E) = E_Subprogram_Type + and then Extra_Formals_OK (E)) or else (Is_Subprogram (E) and then Extra_Formals_OK (E) @@ -10437,6 +10558,10 @@ package body Freeze is else Set_Mechanisms (E); + if not Extra_Formals_Known (E) then + Freeze_Extra_Formals (E); + end if; + -- For foreign conventions, warn about return of unconstrained array if Ekind (E) = E_Function then @@ -10492,6 +10617,11 @@ package body Freeze is end if; end if; + -- Check formals matching in thunks + + pragma Assert (not Is_Thunk (E) + or else Extra_Formals_Match_OK (Thunk_Entity (E), E)); + -- Pragma Inline_Always is disallowed for dispatching subprograms -- because the address of such subprograms is saved in the dispatch -- table to support dispatching calls, and dispatching calls cannot diff --git a/gcc/ada/frontend.adb b/gcc/ada/frontend.adb index 12cea9c794a3..564f153c9826 100644 --- a/gcc/ada/frontend.adb +++ b/gcc/ada/frontend.adb @@ -368,11 +368,12 @@ begin -- If we have restriction No_Exception_Propagation, and we did not have -- an explicit switch turning off Warn_On_Non_Local_Exception, then turn -- on this warning by default if we have encountered an exception - -- handler. + -- handler. We do not override the setting of GNATprove. if Restriction_Check_Required (No_Exception_Propagation) and then not No_Warn_On_Non_Local_Exception and then Exception_Handler_Encountered + and then not GNATprove_Mode then Warn_On_Non_Local_Exception := True; end if; @@ -506,9 +507,7 @@ begin -- Verify the validity of the tree - if Debug_Flag_Underscore_VV then - VAST.Check_Tree (Cunit (Main_Unit)); - end if; + VAST.VAST; -- Validate all the subprogram calls; this work will be done by VAST; in -- the meantime it is done to check extra formals and it can be disabled diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in index 2158bb68ccec..bbbd697eb6f4 100644 --- a/gcc/ada/gcc-interface/Make-lang.in +++ b/gcc/ada/gcc-interface/Make-lang.in @@ -185,6 +185,11 @@ ada.serial = gnat1$(exeext) # variable conveys what we need for this, set to "g++" if not bootstrapping, # ".../xg++" otherwise. +GNATMAKE_FOR_HOST = $(GNATMAKE) +GNATBIND_FOR_HOST = $(GNATBIND) +GNATLINK_FOR_HOST = $(subst gnatmake,gnatlink,$(GNATMAKE)) +GNATLS_FOR_HOST = $(subst gnatmake,gnatls,$(GNATMAKE)) + # There are too many Ada sources to check against here. Let's # always force the recursive make. ifeq ($(build), $(host)) @@ -214,20 +219,16 @@ ifeq ($(build), $(host)) CXX="$(CXX)" \ $(COMMON_FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) \ ADA_INCLUDES="-I../generated -I$(RTS_DIR)/../adainclude -I$(RTS_DIR)" \ - GNATMAKE="gnatmake" \ - GNATBIND="gnatbind" \ - GNATLINK="gnatlink" \ + GNATMAKE="$(GNATMAKE_FOR_HOST)" \ + GNATBIND="$(GNATBIND_FOR_HOST)" \ + GNATLINK="$(GNATLINK_FOR_HOST)" \ LIBGNAT="" endif else # Build is different from host so we are either building a canadian cross # or a cross-native compiler. We provide defaults for tools targeting the - # host platform, but they can be overriden by just setting <tool>_FOR_HOST + # host platform, but they can be overridden by just setting <tool>_FOR_HOST # variables. - GNATMAKE_FOR_HOST=$(host_noncanonical)-gnatmake - GNATBIND_FOR_HOST=$(host_noncanonical)-gnatbind - GNATLINK_FOR_HOST=$(host_noncanonical)-gnatlink - GNATLS_FOR_HOST=$(host_noncanonical)-gnatls ifeq ($(host), $(target)) # This is a cross native. All the sources are taken from the currently @@ -315,23 +316,17 @@ GNAT_ADA_OBJS = \ ada/cstand.o \ ada/debug.o \ ada/debug_a.o \ - ada/diagnostics-brief_emitter.o \ - ada/diagnostics-constructors.o \ - ada/diagnostics-converter.o \ - ada/diagnostics-json_utils.o \ - ada/diagnostics-pretty_emitter.o \ - ada/diagnostics-repository.o \ - ada/diagnostics-sarif_emitter.o \ - ada/diagnostics-switch_repository.o \ - ada/diagnostics-utils.o \ - ada/diagnostics.o \ ada/einfo-entities.o \ ada/einfo-utils.o \ ada/einfo.o \ ada/elists.o \ ada/err_vars.o \ + ada/errid.o \ ada/errout.o \ ada/erroutc.o \ + ada/erroutc-pretty_emitter.o \ + ada/erroutc-sarif_emitter.o \ + ada/errsw.o \ ada/eval_fat.o \ ada/exp_aggr.o \ ada/exp_spark.o \ @@ -380,6 +375,7 @@ GNAT_ADA_OBJS = \ ada/impunit.o \ ada/inline.o \ ada/itypes.o \ + ada/json_utils.o \ ada/krunch.o \ ada/layout.o \ ada/lib-load.o \ @@ -535,6 +531,7 @@ GNAT_ADA_OBJS+= \ ada/libgnat/s-bitops.o \ ada/libgnat/s-carun8.o \ ada/libgnat/s-casuti.o \ + ada/libgnat/s-cautns.o \ ada/libgnat/s-crtl.o \ ada/libgnat/s-conca2.o \ ada/libgnat/s-conca3.o \ @@ -562,8 +559,6 @@ GNAT_ADA_OBJS+= \ ada/libgnat/s-secsta.o \ ada/libgnat/s-soflin.o \ ada/libgnat/s-soliin.o \ - ada/libgnat/s-spark.o \ - ada/libgnat/s-spcuop.o \ ada/libgnat/s-stache.o \ ada/libgnat/s-stalib.o \ ada/libgnat/s-stoele.o \ @@ -575,11 +570,8 @@ GNAT_ADA_OBJS+= \ ada/libgnat/s-trasym.o \ ada/libgnat/s-unstyp.o \ ada/libgnat/s-valint.o \ - ada/libgnat/s-valspe.o \ ada/libgnat/s-valuns.o \ ada/libgnat/s-valuti.o \ - ada/libgnat/s-vs_int.o \ - ada/libgnat/s-vs_uns.o \ ada/libgnat/s-wchcnv.o \ ada/libgnat/s-wchcon.o \ ada/libgnat/s-wchjis.o \ @@ -615,23 +607,17 @@ GNATBIND_OBJS = \ ada/casing.o \ ada/csets.o \ ada/debug.o \ - ada/diagnostics-brief_emitter.o \ - ada/diagnostics-constructors.o \ - ada/diagnostics-converter.o \ - ada/diagnostics-json_utils.o \ - ada/diagnostics-pretty_emitter.o \ - ada/diagnostics-repository.o \ - ada/diagnostics-sarif_emitter.o \ - ada/diagnostics-switch_repository.o \ - ada/diagnostics-utils.o \ - ada/diagnostics.o \ ada/einfo-entities.o \ ada/einfo-utils.o \ ada/einfo.o \ ada/elists.o \ ada/err_vars.o \ + ada/errid.o \ ada/errout.o \ ada/erroutc.o \ + ada/erroutc-sarif_emitter.o \ + ada/erroutc-pretty_emitter.o \ + ada/errsw.o \ ada/exit.o \ ada/final.o \ ada/fmap.o \ @@ -639,6 +625,7 @@ GNATBIND_OBJS = \ ada/gnatbind.o \ ada/gnatvsn.o \ ada/hostparm.o \ + ada/json_utils.o \ ada/lib.o \ ada/link.o \ ada/namet.o \ @@ -710,6 +697,7 @@ GNATBIND_OBJS += \ ada/libgnat/s-assert.o \ ada/libgnat/s-carun8.o \ ada/libgnat/s-casuti.o \ + ada/libgnat/s-cautns.o \ ada/libgnat/s-conca2.o \ ada/libgnat/s-conca3.o \ ada/libgnat/s-conca4.o \ @@ -1108,7 +1096,7 @@ check-ada-subtargets: check-acats-subtargets check-gnat-subtargets # No ada-specific selftests selftest-ada: -ACATSDIR = $(TESTSUITEDIR)/ada/acats-2 +ACATSDIR = $(TESTSUITEDIR)/ada/acats-4 ACATSCMD = run_acats.sh check_acats_numbers0:=1 2 3 4 5 6 7 8 9 diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in index 2c42cb1afb48..8615b598623f 100644 --- a/gcc/ada/gcc-interface/Makefile.in +++ b/gcc/ada/gcc-interface/Makefile.in @@ -104,6 +104,8 @@ INSTALL_DATA_DATE = cp -p MAKEINFO = makeinfo TEXI2DVI = texi2dvi TEXI2PDF = texi2pdf + +GNATMAKE_FOR_BUILD = gnatmake GNATBIND_FLAGS = -static -x ADA_CFLAGS = ADAFLAGS = -W -Wall -gnatpg -gnata -gnatU @@ -321,23 +323,18 @@ GNATMAKE_OBJS = a-except.o ali.o ali-util.o aspects.o s-casuti.o alloc.o \ erroutc.o errutil.o err_vars.o fmap.o fname.o fname-uf.o fname-sf.o \ gnatmake.o gnatvsn.o hostparm.o interfac.o i-c.o i-cstrin.o krunch.o lib.o \ make.o makeusg.o make_util.o namet.o nlists.o opt.o osint.o osint-m.o \ - output.o restrict.o rident.o s-exctab.o \ + output.o restrict.o rident.o s-exctab.o s-cautns.o \ s-secsta.o s-stalib.o s-stoele.o scans.o scng.o sdefault.o sfn_scan.o \ s-purexc.o s-htable.o scil_ll.o sem_aux.o sinfo.o sinput.o sinput-c.o \ snames.o stand.o stringt.o styleg.o stylesw.o system.o validsw.o \ switch.o switch-m.o table.o targparm.o tempdir.o types.o uintp.o \ uname.o urealp.o usage.o widechar.o warnsw.o \ seinfo.o einfo-entities.o einfo-utils.o sinfo-nodes.o sinfo-utils.o \ - diagnostics-brief_emitter.o \ - diagnostics-constructors.o \ - diagnostics-converter.o \ - diagnostics-json_utils.o \ - diagnostics-pretty_emitter.o \ - diagnostics-repository.o \ - diagnostics-sarif_emitter.o \ - diagnostics-switch_repository.o \ - diagnostics-utils.o \ - diagnostics.o \ + errid.o \ + errsw.o \ + erroutc-pretty_emitter.o \ + erroutc-sarif_emitter.o \ + json_utils.o $(EXTRA_GNATMAKE_OBJS) # Make arch match the current multilib so that the RTS selection code @@ -634,7 +631,7 @@ OSCONS_EXTRACT=$(GCC_FOR_ADA_RTS) $(GNATLIBCFLAGS_FOR_C) -S s-oscons-tmplt.i -$(MKDIR) ./bldtools/oscons $(RM) $(addprefix ./bldtools/oscons/,$(notdir $^)) $(CP) $^ ./bldtools/oscons - (cd ./bldtools/oscons ; gnatmake xoscons) + (cd ./bldtools/oscons ; $(GNATMAKE_FOR_BUILD) xoscons) $(RTSDIR)/s-oscons.ads: ../stamp-gnatlib1-$(RTSDIR) s-oscons-tmplt.c gsocket.h ./bldtools/oscons/xoscons $(RM) $(RTSDIR)/s-oscons-tmplt.i $(RTSDIR)/s-oscons-tmplt.s @@ -843,35 +840,6 @@ gnatlib-shared: PICFLAG_FOR_TARGET="$(PICFLAG_FOR_TARGET)" \ $(GNATLIB_SHARED) -# When building a SJLJ runtime for VxWorks, we need to ensure that the extra -# linker options needed for ZCX are not passed to prevent the inclusion of -# useless objects and potential troubles from the presence of extra symbols -# and references in some configurations. The inhibition is performed by -# commenting the pragma instead of deleting the line, as the latter might -# result in getting multiple blank lines, hence possible style check errors. -gnatlib-sjlj: - $(MAKE) $(FLAGS_TO_PASS) \ - EH_MECHANISM="" \ - MULTISUBDIR="$(MULTISUBDIR)" \ - THREAD_KIND="$(THREAD_KIND)" \ - LN_S="$(LN_S)" \ - ../stamp-gnatlib1-$(RTSDIR) - sed \ - -e 's/Frontend_Exceptions.*/Frontend_Exceptions : constant Boolean := True;/' \ - -e 's/ZCX_By_Default.*/ZCX_By_Default : constant Boolean := False;/' \ - $(RTSDIR)/system.ads > $(RTSDIR)/s.ads - $(MV) $(RTSDIR)/s.ads $(RTSDIR)/system.ads - $(MAKE) $(FLAGS_TO_PASS) \ - EH_MECHANISM="" \ - GNATLIBFLAGS="$(GNATLIBFLAGS)" \ - GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \ - GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \ - FORCE_DEBUG_ADAFLAGS="$(FORCE_DEBUG_ADAFLAGS)" \ - MULTISUBDIR="$(MULTISUBDIR)" \ - THREAD_KIND="$(THREAD_KIND)" \ - LN_S="$(LN_S)" \ - gnatlib - gnatlib-zcx: $(MAKE) $(FLAGS_TO_PASS) \ EH_MECHANISM="-gcc" \ @@ -880,7 +848,6 @@ gnatlib-zcx: LN_S="$(LN_S)" \ ../stamp-gnatlib1-$(RTSDIR) sed \ - -e 's/Frontend_Exceptions.*/Frontend_Exceptions : constant Boolean := False;/' \ -e 's/ZCX_By_Default.*/ZCX_By_Default : constant Boolean := True;/' \ $(RTSDIR)/system.ads > $(RTSDIR)/s.ads $(MV) $(RTSDIR)/s.ads $(RTSDIR)/system.ads diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc index 1694b4eb1065..86cbf5ba4fb5 100644 --- a/gcc/ada/gcc-interface/decl.cc +++ b/gcc/ada/gcc-interface/decl.cc @@ -1228,6 +1228,24 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) gnu_expr = gnat_build_constructor (gnu_type, v); } + /* If we are allocating the anonymous object of a small aggregate on + the stack, zero-initialize it so that the entire object is assigned + and the subsequent assignments need not preserve unknown bits, but + do it only when optimization is enabled for the sake of consistency + with the gimplifier which does the same for CONSTRUCTORs. */ + else if (definition + && !imported_p + && !static_flag + && !gnu_expr + && TREE_CODE (gnu_type) == RECORD_TYPE + && TREE_CODE (gnu_object_size) == INTEGER_CST + && compare_tree_int (gnu_object_size, MAX_FIXED_MODE_SIZE) <= 0 + && Present (Related_Expression (gnat_entity)) + && Nkind (Original_Node (Related_Expression (gnat_entity))) + == N_Aggregate + && optimize) + gnu_expr = build_constructor (gnu_type, NULL); + /* Convert the expression to the type of the object if need be. */ if (gnu_expr && initial_value_needs_conversion (gnu_type, gnu_expr)) gnu_expr = convert (gnu_type, gnu_expr); @@ -4484,7 +4502,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) if (Known_Esize (gnat_entity)) gnu_size = validate_size (Esize (gnat_entity), gnu_type, gnat_entity, - VAR_DECL, false, false, size_s, type_s); + VAR_DECL, false, false, NULL, NULL); /* ??? The test on Has_Size_Clause must be removed when "unknown" is no longer represented as Uint_0 (i.e. Use_New_Unknown_Rep). */ @@ -5251,7 +5269,7 @@ inline_status_for_subprog (Entity_Id subprog) && Is_Record_Type (Etype (First_Formal (subprog))) && (gnu_type = gnat_to_gnu_type (Etype (First_Formal (subprog)))) && !TYPE_IS_BY_REFERENCE_P (gnu_type) - && tree_fits_uhwi_p (TYPE_SIZE (gnu_type)) + && TREE_CODE (TYPE_SIZE (gnu_type)) == INTEGER_CST && compare_tree_int (TYPE_SIZE (gnu_type), MAX_FIXED_MODE_SIZE) <= 0) return is_prescribed; @@ -5426,7 +5444,7 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition, const bool is_bit_packed = Is_Bit_Packed_Array (gnat_array); tree gnu_type = gnat_to_gnu_type (gnat_type); tree gnu_comp_size; - bool has_packed_components; + bool has_packed_component; unsigned int max_align; /* If an alignment is specified, use it as a cap on the component type @@ -5447,16 +5465,22 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition, && !TYPE_FAT_POINTER_P (gnu_type) && tree_fits_uhwi_p (TYPE_SIZE (gnu_type))) { - gnu_type = make_packable_type (gnu_type, false, max_align); - has_packed_components = true; + tree gnu_packable_type = make_packable_type (gnu_type, false, max_align); + if (gnu_packable_type != gnu_type) + { + gnu_type = gnu_packable_type; + has_packed_component = true; + } + else + has_packed_component = false; } else - has_packed_components = is_bit_packed; + has_packed_component = is_bit_packed; /* Get and validate any specified Component_Size. */ gnu_comp_size = validate_size (Component_Size (gnat_array), gnu_type, gnat_array, - has_packed_components ? TYPE_DECL : VAR_DECL, true, + has_packed_component ? TYPE_DECL : VAR_DECL, true, Has_Component_Size_Clause (gnat_array), NULL, NULL); /* If the component type is a RECORD_TYPE that has a self-referential size, @@ -5998,7 +6022,8 @@ gnat_to_gnu_profile_type (Entity_Id gnat_type) return gnu_type; } -/* Return true if TYPE contains only integral data, recursively if need be. */ +/* Return true if TYPE contains only integral data, recursively if need be. + (integral data is to be understood as not floating-point data here). */ static bool type_contains_only_integral_data (tree type) @@ -6018,7 +6043,7 @@ type_contains_only_integral_data (tree type) return type_contains_only_integral_data (TREE_TYPE (type)); default: - return INTEGRAL_TYPE_P (type); + return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type); } gcc_unreachable (); @@ -6396,6 +6421,33 @@ gnat_to_gnu_subprog_type (Entity_Id gnat_subprog, bool definition, since structures are incomplete for the back-end. */ else if (Convention (gnat_subprog) != Convention_Stubbed) { + /* If we have two entries that may be returned in integer registers, + the larger has power-of-2 size and the smaller is integer, then + extend the smaller to this power-of-2 size to get a return type + with power-of-2 size and no holes, again to speed up accesses. */ + if (list_length (gnu_cico_field_list) == 2 + && gnu_cico_only_integral_type) + { + tree typ1 = TREE_TYPE (gnu_cico_field_list); + tree typ2 = TREE_TYPE (DECL_CHAIN (gnu_cico_field_list)); + if (TREE_CODE (typ1) == INTEGER_TYPE + && integer_pow2p (TYPE_SIZE (typ2)) + && compare_tree_int (TYPE_SIZE (typ2), + MAX_FIXED_MODE_SIZE) <= 0 + && tree_int_cst_lt (TYPE_SIZE (typ1), TYPE_SIZE (typ2))) + TREE_TYPE (gnu_cico_field_list) + = gnat_type_for_size (TREE_INT_CST_LOW (TYPE_SIZE (typ2)), + TYPE_UNSIGNED (typ1)); + else if (TREE_CODE (typ2) == INTEGER_TYPE + && integer_pow2p (TYPE_SIZE (typ1)) + && compare_tree_int (TYPE_SIZE (typ1), + MAX_FIXED_MODE_SIZE) <= 0 + && tree_int_cst_lt (TYPE_SIZE (typ2), TYPE_SIZE (typ1))) + TREE_TYPE (DECL_CHAIN (gnu_cico_field_list)) + = gnat_type_for_size (TREE_INT_CST_LOW (TYPE_SIZE (typ1)), + TYPE_UNSIGNED (typ2)); + } + finish_record_type (gnu_cico_return_type, nreverse (gnu_cico_field_list), 0, false); @@ -9672,6 +9724,20 @@ validate_size (Uint uint_size, tree gnu_type, Entity_Id gnat_object, return NULL_TREE; } + /* The size of stand-alone objects is always a multiple of the alignment, + but that's already enforced for elementary types by the front-end. */ + if (kind == VAR_DECL + && !component_p + && RECORD_OR_UNION_TYPE_P (gnu_type) + && !TYPE_FAT_POINTER_P (gnu_type) + && !integer_zerop (size_binop (TRUNC_MOD_EXPR, size, + bitsize_int (TYPE_ALIGN (gnu_type))))) + { + post_error_ne_num ("size for& must be multiple of alignment ^", + gnat_error_node, gnat_object, TYPE_ALIGN (gnu_type)); + return NULL_TREE; + } + return size; } diff --git a/gcc/ada/gcc-interface/misc.cc b/gcc/ada/gcc-interface/misc.cc index ca5c9a2163ee..128040e4d90d 100644 --- a/gcc/ada/gcc-interface/misc.cc +++ b/gcc/ada/gcc-interface/misc.cc @@ -377,7 +377,7 @@ gnat_init (void) line_table->default_range_bits = 0; /* Register our internal error function. */ - global_dc->m_internal_error = &internal_error_function; + global_dc->set_internal_error_callback (&internal_error_function); return true; } diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc index 23fc814f9dec..cd480efd6f23 100644 --- a/gcc/ada/gcc-interface/trans.cc +++ b/gcc/ada/gcc-interface/trans.cc @@ -257,7 +257,7 @@ static tree emit_check (tree, tree, int, Node_Id); static tree build_unary_op_trapv (enum tree_code, tree, tree, Node_Id); static tree build_binary_op_trapv (enum tree_code, tree, tree, tree, Node_Id); static tree convert_with_check (Entity_Id, tree, bool, bool, Node_Id); -static bool addressable_p (tree, tree); +static bool addressable_p (tree, tree, bool); static bool aliasable_p (tree, tree); static tree assoc_to_constructor (Entity_Id, Node_Id, tree); static tree pos_to_constructor (Node_Id, tree); @@ -4049,7 +4049,7 @@ Subprogram_Body_to_gnu (Node_Id gnat_node) tree gnu_decl; /* Skip any entries that have been already filled in; they must - correspond to In Out parameters. */ + correspond to In Out parameters or previous Out parameters. */ while (gnu_cico_entry && TREE_VALUE (gnu_cico_entry)) gnu_cico_entry = TREE_CHAIN (gnu_cico_entry); @@ -4059,11 +4059,22 @@ Subprogram_Body_to_gnu (Node_Id gnat_node) if (DECL_BY_REF_P (gnu_decl)) gnu_decl = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_decl); - /* Do any needed references for padded types. */ - TREE_VALUE (gnu_cico_entry) - = convert (TREE_TYPE (TREE_PURPOSE (gnu_cico_entry)), gnu_decl); + TREE_VALUE (gnu_cico_entry) = gnu_decl; } + + /* Finally, ensure type consistency between TREE_PURPOSE and TREE_VALUE + so that the assignment of the latter to the former can be done. */ + tree gnu_cico_entry = gnu_cico_list; + while (gnu_cico_entry) + { + if (!VOID_TYPE_P (TREE_VALUE (gnu_cico_entry))) + TREE_VALUE (gnu_cico_entry) + = convert (TREE_TYPE (TREE_PURPOSE (gnu_cico_entry)), + TREE_VALUE (gnu_cico_entry)); + gnu_cico_entry = TREE_CHAIN (gnu_cico_entry); + } } + else vec_safe_push (gnu_return_label_stack, NULL_TREE); @@ -4161,9 +4172,13 @@ Subprogram_Body_to_gnu (Node_Id gnat_node) } } - /* Otherwise, if this is a procedure or a function which does not return - by invisible reference, we can do a direct block-copy out. */ - else + /* Otherwise, if this is a procedure or a function that does not return + by invisible reference, we can do a direct block-copy out, but we do + not need to do it for a null initialization procedure when the _Init + parameter is not passed in since we would copy uninitialized bits. */ + else if (!(Is_Null_Init_Proc (gnat_subprog) + && list_length (gnu_cico_list) == 1 + && TREE_CODE (TREE_VALUE (gnu_cico_list)) == VAR_DECL)) { tree gnu_retval; @@ -4876,6 +4891,8 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, tree gnu_formal = present_gnu_tree (gnat_formal) ? get_gnu_tree (gnat_formal) : NULL_TREE; tree gnu_actual_type = gnat_to_gnu_type (Etype (gnat_actual)); + const bool is_init_proc + = Is_Entity_Name (gnat_subprog) && Is_Init_Proc (Entity (gnat_subprog)); const bool in_param = (Ekind (gnat_formal) == E_In_Parameter); const bool is_true_formal_parm = gnu_formal && TREE_CODE (gnu_formal) == PARM_DECL; @@ -4925,7 +4942,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, copy to avoid breaking strict aliasing rules. */ if (is_by_ref_formal_parm && (gnu_name_type = gnat_to_gnu_type (Etype (gnat_name))) - && (!addressable_p (gnu_name, gnu_name_type) + && (!addressable_p (gnu_name, gnu_name_type, is_init_proc) || (node_is_type_conversion (gnat_actual) && (aliasing = !aliasable_p (gnu_name, gnu_actual_type))))) { @@ -5051,9 +5068,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, /* Do not initialize it for the _Init parameter of an initialization procedure since no data is meant to be passed in. */ - if (Ekind (gnat_formal) == E_Out_Parameter - && Is_Entity_Name (gnat_subprog) - && Is_Init_Proc (Entity (gnat_subprog))) + if (Ekind (gnat_formal) == E_Out_Parameter && is_init_proc) gnu_name = gnu_temp = create_temporary ("A", TREE_TYPE (gnu_name)); /* Initialize it on the fly like for an implicit temporary in the @@ -7590,6 +7605,10 @@ gnat_to_gnu (Node_Id gnat_node) case N_Allocator: { + const Entity_Id gnat_desig_type + = Designated_Type (Underlying_Type (Etype (gnat_node))); + const Entity_Id gnat_pool = Storage_Pool (gnat_node); + tree gnu_type, gnu_init; bool ignore_init_type; @@ -7608,9 +7627,6 @@ gnat_to_gnu (Node_Id gnat_node) else if (Nkind (gnat_temp) == N_Qualified_Expression) { - const Entity_Id gnat_desig_type - = Designated_Type (Underlying_Type (Etype (gnat_node))); - ignore_init_type = Has_Constrained_Partial_View (gnat_desig_type); gnu_init = gnat_to_gnu (Expression (gnat_temp)); @@ -7637,11 +7653,24 @@ gnat_to_gnu (Node_Id gnat_node) else gcc_unreachable (); - gnu_result_type = get_unpadded_type (Etype (gnat_node)); + /* If this is an array allocated with its bounds, use the thin pointer + as the result type to trigger the machinery in build_allocator, but + make sure not to do it for allocations on the return and secondary + stacks (see build_call_alloc_dealloc_proc for more details). */ + if (Is_Constr_Array_Subt_With_Bounds (gnat_desig_type) + && Is_Record_Type (Underlying_Type (Etype (gnat_pool))) + && !type_annotate_only) + { + tree gnu_array = gnat_to_gnu_type (Base_Type (gnat_desig_type)); + gnu_result_type + = build_pointer_type (TYPE_OBJECT_RECORD_TYPE (gnu_array)); + } + else + gnu_result_type = get_unpadded_type (Etype (gnat_node)); + return build_allocator (gnu_type, gnu_init, gnu_result_type, Procedure_To_Call (gnat_node), - Storage_Pool (gnat_node), gnat_node, - ignore_init_type); + gnat_pool, gnat_node, ignore_init_type); } break; @@ -8447,7 +8476,8 @@ gnat_to_gnu (Node_Id gnat_node) oconstraints[i] = constraint; if (parse_output_constraint (&constraint, i, ninputs, noutputs, - &allows_mem, &allows_reg, &fake)) + &allows_mem, &allows_reg, &fake, + nullptr)) { /* If the operand is going to end up in memory, mark it addressable. Note that we don't test @@ -8475,9 +8505,9 @@ gnat_to_gnu (Node_Id gnat_node) constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail))); - if (parse_input_constraint (&constraint, i, ninputs, noutputs, - 0, oconstraints, - &allows_mem, &allows_reg)) + if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0, + oconstraints, &allows_mem, + &allows_reg, nullptr)) { /* If the operand is going to end up in memory, mark it addressable. */ @@ -8577,6 +8607,18 @@ gnat_to_gnu (Node_Id gnat_node) (void) gnat_to_gnu_entity (gnat_desig_type, NULL_TREE, false); gnu_ptr = gnat_to_gnu (gnat_temp); + + /* If this is an array allocated with its bounds, first convert to + the thin pointer to trigger the special machinery below. */ + if (Is_Constr_Array_Subt_With_Bounds (gnat_desig_type)) + { + tree gnu_array = gnat_to_gnu_type (Base_Type (gnat_desig_type)); + gnu_ptr + = convert (build_pointer_type + (TYPE_OBJECT_RECORD_TYPE (gnu_array)), + gnu_ptr); + } + gnu_ptr_type = TREE_TYPE (gnu_ptr); /* If this is a thin pointer, we must first dereference it to create @@ -10353,7 +10395,8 @@ convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflow_p, unless it is an expression involving computation or if it involves a reference to a bitfield or to an object not sufficiently aligned for its type. If GNU_TYPE is non-null, return true only if GNU_EXPR can - be directly addressed as an object of this type. + be directly addressed as an object of this type. COMPG is true when + the predicate is invoked for compiler-generated code. *** Notes on addressability issues in the Ada compiler *** @@ -10410,7 +10453,7 @@ convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflow_p, generated to connect everything together. */ static bool -addressable_p (tree gnu_expr, tree gnu_type) +addressable_p (tree gnu_expr, tree gnu_type, bool compg) { /* For an integral type, the size of the actual type of the object may not be greater than that of the expected type, otherwise an indirect access @@ -10471,13 +10514,13 @@ addressable_p (tree gnu_expr, tree gnu_type) case COMPOUND_EXPR: /* The address of a compound expression is that of its 2nd operand. */ - return addressable_p (TREE_OPERAND (gnu_expr, 1), gnu_type); + return addressable_p (TREE_OPERAND (gnu_expr, 1), gnu_type, compg); case COND_EXPR: /* We accept &COND_EXPR as soon as both operands are addressable and expect the outcome to be the address of the selected operand. */ - return (addressable_p (TREE_OPERAND (gnu_expr, 1), NULL_TREE) - && addressable_p (TREE_OPERAND (gnu_expr, 2), NULL_TREE)); + return (addressable_p (TREE_OPERAND (gnu_expr, 1), NULL_TREE, compg) + && addressable_p (TREE_OPERAND (gnu_expr, 2), NULL_TREE, compg)); case COMPONENT_REF: return (((!DECL_BIT_FIELD (TREE_OPERAND (gnu_expr, 1)) @@ -10491,23 +10534,26 @@ addressable_p (tree gnu_expr, tree gnu_type) && (DECL_ALIGN (TREE_OPERAND (gnu_expr, 1)) >= default_field_alignment (TREE_OPERAND (gnu_expr, 1), TREE_TYPE (gnu_expr)) - /* We do not enforce this on strict-alignment platforms for - internal fields in order to keep supporting misalignment - of tagged types in legacy code. */ + /* But this was historically not enforced for targets that + do not require strict alignment, so we keep not doing + it for 1) internal fields in order to keep supporting + misalignment of tagged types and 2) compiler-generated + code in order to avoid creating useless temporaries. */ || (!STRICT_ALIGNMENT - && DECL_INTERNAL_P (TREE_OPERAND (gnu_expr, 1))))) + && (DECL_INTERNAL_P (TREE_OPERAND (gnu_expr, 1)) + || compg)))) /* The field of a padding record is always addressable. */ || TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_expr, 0)))) - && addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE)); + && addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE, compg)); case ARRAY_REF: case ARRAY_RANGE_REF: case REALPART_EXPR: case IMAGPART_EXPR: case NOP_EXPR: - return addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE); + return addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE, compg); case CONVERT_EXPR: return (AGGREGATE_TYPE_P (TREE_TYPE (gnu_expr)) - && addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE)); + && addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE, compg)); case VIEW_CONVERT_EXPR: { @@ -10525,7 +10571,8 @@ addressable_p (tree gnu_expr, tree gnu_type) || TYPE_ALIGN (inner_type) >= BIGGEST_ALIGNMENT || TYPE_ALIGN_OK (type) || TYPE_ALIGN_OK (inner_type)))) - && addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE)); + && addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE, + compg)); } default: diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc index 23737c3296cc..7324beef58fa 100644 --- a/gcc/ada/gcc-interface/utils.cc +++ b/gcc/ada/gcc-interface/utils.cc @@ -1225,7 +1225,6 @@ make_packable_type (tree type, bool in_record, unsigned int max_align) Note that we rely on the pointer equality created here for TYPE_NAME to look through conversions in various places. */ TYPE_NAME (new_type) = TYPE_NAME (type); - TYPE_PACKED (new_type) = 1; TYPE_JUSTIFIED_MODULAR_P (new_type) = TYPE_JUSTIFIED_MODULAR_P (type); TYPE_CONTAINS_TEMPLATE_P (new_type) = TYPE_CONTAINS_TEMPLATE_P (type); TYPE_REVERSE_STORAGE_ORDER (new_type) = TYPE_REVERSE_STORAGE_ORDER (type); @@ -1240,6 +1239,8 @@ make_packable_type (tree type, bool in_record, unsigned int max_align) new_size = ceil_pow2 (size); new_align = MIN (new_size, BIGGEST_ALIGNMENT); SET_TYPE_ALIGN (new_type, new_align); + /* build_aligned_type needs to be able to adjust back the alignment. */ + TYPE_PACKED (new_type) = 0; } else { @@ -1261,6 +1262,7 @@ make_packable_type (tree type, bool in_record, unsigned int max_align) if (max_align > 0 && new_align > max_align) new_align = max_align; SET_TYPE_ALIGN (new_type, MIN (align, new_align)); + TYPE_PACKED (new_type) = 1; } TYPE_USER_ALIGN (new_type) = 1; diff --git a/gcc/ada/gen_il-fields.ads b/gcc/ada/gen_il-fields.ads index c293e0fa63fb..a1e284f14e46 100644 --- a/gcc/ada/gen_il-fields.ads +++ b/gcc/ada/gen_il-fields.ads @@ -56,7 +56,6 @@ package Gen_IL.Fields is Abort_Present, Abortable_Part, Abstract_Present, - Accept_Handler_Records, Accept_Statement, Access_Definition, Access_To_Subprogram_Definition, @@ -230,7 +229,6 @@ package Gen_IL.Fields is Import_Interface_Present, In_Present, Includes_Infinities, - Incomplete_View, Inherited_Discriminant, Instance_Spec, Intval, @@ -256,6 +254,8 @@ package Gen_IL.Fields is Is_Elsif, Is_Entry_Barrier_Function, Is_Expanded_Build_In_Place_Call, + Is_Expanded_Constructor_Call, + Is_Expanded_Dispatching_Call, Is_Expanded_Prefixed_Call, Is_Folded_In_Parser, Is_Generic_Contract_Pragma, @@ -401,7 +401,9 @@ package Gen_IL.Fields is Suppress_Loop_Warnings, Synchronized_Present, Tagged_Present, + Tag_Propagated, Target, + Call_Or_Target_Loop, Target_Type, Task_Definition, Task_Present, @@ -472,6 +474,9 @@ package Gen_IL.Fields is Component_Clause, Component_Size, Component_Type, + Constructor_List, + Constructor_Name, + Continue_Mark, Contract, Contract_Wrapper, Corresponding_Concurrent_Type, @@ -487,12 +492,10 @@ package Gen_IL.Fields is Debug_Renaming_Link, Default_Aspect_Component_Value, Default_Aspect_Value, - Default_Expr_Function, Default_Expressions_Processed, Default_Value, Delay_Cleanups, Delta_Value, - Dependent_Instances, Depends_On_Private, Derived_Type_Link, Digits_Value, @@ -538,6 +541,7 @@ package Gen_IL.Fields is Extra_Constrained, Extra_Formal, Extra_Formals, + Extra_Formals_Known, Finalization_Collection, Finalization_Master_Node, Finalize_Storage_Only, @@ -553,7 +557,6 @@ package Gen_IL.Fields is Full_View, Generic_Homonym, Generic_Renamings, - Handler_Records, Has_Aliased_Components, Has_Alignment_Clause, Has_All_Calls_Remote, @@ -572,6 +575,7 @@ package Gen_IL.Fields is Has_Delayed_Aspects, Has_Delayed_Freeze, Has_Delayed_Rep_Aspects, + Has_Destructor, Has_Discriminants, Has_Dispatch_Table, Has_Dynamic_Predicate_Aspect, @@ -659,6 +663,7 @@ package Gen_IL.Fields is Ignore_SPARK_Mode_Pragmas, Import_Pragma, Incomplete_Actuals, + Incomplete_View, Indirect_Call_Wrapper, In_Package_Body, In_Private_Part, @@ -698,6 +703,7 @@ package Gen_IL.Fields is Is_CPP_Class, Is_CUDA_Kernel, Is_Descendant_Of_Address, + Is_Destructor, Is_DIC_Procedure, Is_Discrim_SO_Function, Is_Discriminant_Check_Function, @@ -729,6 +735,7 @@ package Gen_IL.Fields is Is_Ignored_Ghost_Entity, Is_Immediately_Visible, Is_Implementation_Defined, + Is_Implicit_Full_View, Is_Imported, Is_Independent, Is_Initial_Condition_Procedure, @@ -744,6 +751,7 @@ package Gen_IL.Fields is Is_Known_Non_Null, Is_Known_Null, Is_Known_Valid, + Is_Large_Unconstrained_Definite, Is_Limited_Composite, Is_Limited_Interface, Is_Limited_Record, @@ -822,7 +830,7 @@ package Gen_IL.Fields is Modulus, Must_Be_On_Byte_Boundary, Must_Have_Preelab_Init, - Needs_Activation_Record, + Needs_Construction, Needs_Debug_Info, Needs_No_Actuals, Never_Set_In_Source, @@ -848,6 +856,7 @@ package Gen_IL.Fields is Original_Protected_Subprogram, Original_Record_Component, Overlays_Constant, + Overridden_Inherited_Operation, Overridden_Operation, Package_Instantiation, Packed_Array_Impl_Type, @@ -870,7 +879,6 @@ package Gen_IL.Fields is Referenced_As_LHS, Referenced_As_Out_Parameter, Refinement_Constituents, - Register_Exception_Call, Related_Array_Object, Related_Expression, Related_Instance, @@ -892,7 +900,6 @@ package Gen_IL.Fields is Scope_Depth_Value, Sec_Stack_Needed_For_Return, Shared_Var_Procs_Instance, - Size_Check_Code, Size_Depends_On_Discriminant, Size_Known_At_Compile_Time, Small_Value, diff --git a/gcc/ada/gen_il-gen-gen_entities.adb b/gcc/ada/gen_il-gen-gen_entities.adb index 37ddd851d7c3..0fedfbc60992 100644 --- a/gcc/ada/gen_il-gen-gen_entities.adb +++ b/gcc/ada/gen_il-gen-gen_entities.adb @@ -77,7 +77,6 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Has_Delayed_Aspects, Flag), Sm (Has_Delayed_Freeze, Flag), Sm (Has_Delayed_Rep_Aspects, Flag), - Sm (Has_Exit, Flag), Sm (Has_Forward_Instantiation, Flag), Sm (Has_Fully_Qualified_Name, Flag), Sm (Has_Gigi_Rep_Item, Flag), @@ -114,6 +113,7 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Has_Xref_Entry, Flag), Sm (Has_Yield_Aspect, Flag), Sm (Homonym, Node_Id), + Sm (Incomplete_View, Node_Id), Sm (In_Package_Body, Flag), Sm (In_Private_Part, Flag), Sm (In_Use, Flag), @@ -212,10 +212,8 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Low_Bound_Tested, Flag), Sm (Materialize_Entity, Flag), Sm (May_Inherit_Delayed_Rep_Aspects, Flag), - Sm (Needs_Activation_Record, Flag), Sm (Needs_Debug_Info, Flag), Sm (Never_Set_In_Source, Flag), - Sm (Overlays_Constant, Flag), Sm (Prev_Entity, Node_Id), Sm (Referenced, Flag), Sm (Referenced_As_LHS, Flag), @@ -288,7 +286,6 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Extra_Formal, Node_Id), Sm (Generic_Homonym, Node_Id), Sm (Generic_Renamings, Elist_Id), - Sm (Handler_Records, List_Id), Sm (Has_Static_Discriminants, Flag), Sm (Inner_Instances, Elist_Id), Sm (Interface_Name, Node_Id), @@ -354,10 +351,10 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Last_Aggregate_Assignment, Node_Id), Sm (Optimize_Alignment_Space, Flag), Sm (Optimize_Alignment_Time, Flag), + Sm (Overlays_Constant, Flag), Sm (Prival_Link, Node_Id), Sm (Related_Type, Node_Id), Sm (Return_Statement, Node_Id), - Sm (Size_Check_Code, Node_Id), Sm (SPARK_Pragma, Node_Id), Sm (SPARK_Pragma_Inherited, Flag))); @@ -399,7 +396,6 @@ begin -- Gen_IL.Gen.Gen_Entities (Sm (Activation_Record_Component, Node_Id), Sm (Actual_Subtype, Node_Id), Sm (Alignment, Unat), - Sm (Default_Expr_Function, Node_Id), Sm (Default_Value, Node_Id), Sm (Entry_Component, Node_Id), Sm (Extra_Accessibility, Node_Id), @@ -429,9 +425,8 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Discriminant_Default_Value, Node_Id), Sm (Is_Activation_Record, Flag))); - Ab (Formal_Object_Kind, Object_Kind, - -- Generic formal objects are also objects - (Sm (Entry_Component, Node_Id))); + Ab (Formal_Object_Kind, Object_Kind); + -- Generic formal objects are also objects Cc (E_Generic_In_Out_Parameter, Formal_Object_Kind, -- A generic in out parameter, created by the use of a generic in out @@ -458,6 +453,8 @@ begin -- Gen_IL.Gen.Gen_Entities Pre => "Ekind (Base_Type (N)) in Access_Subprogram_Kind"), Sm (Class_Wide_Equivalent_Type, Node_Id), Sm (Class_Wide_Type, Node_Id), + Sm (Constructor_List, Elist_Id), + Sm (Constructor_Name, Node_Id), Sm (Contract, Node_Id), Sm (Current_Use_Clause, Node_Id), Sm (Derived_Type_Link, Node_Id), @@ -470,6 +467,7 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Full_View, Node_Id), Sm (Has_Completion_In_Body, Flag), Sm (Has_Constrained_Partial_View, Flag, Base_Type_Only), + Sm (Has_Destructor, Flag, Base_Type_Only), Sm (Has_Discriminants, Flag), Sm (Has_Dispatch_Table, Flag, Pre => "Is_Tagged_Type (N)"), @@ -505,6 +503,7 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Is_Fixed_Lower_Bound_Array_Subtype, Flag), Sm (Is_Fixed_Lower_Bound_Index_Subtype, Flag), Sm (Is_Generic_Actual_Type, Flag), + Sm (Is_Implicit_Full_View, Flag), Sm (Is_Mutably_Tagged_Type, Flag), Sm (Is_Non_Static_Subtype, Flag), Sm (Is_Private_Composite, Flag), @@ -516,6 +515,7 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Linker_Section_Pragma, Node_Id), Sm (Must_Be_On_Byte_Boundary, Flag), Sm (Must_Have_Preelab_Init, Flag), + Sm (Needs_Construction, Flag), Sm (No_Tagged_Streams_Pragma, Node_Id, Pre => "Is_Tagged_Type (N)"), Sm (Non_Binary_Modulus, Flag, Base_Type_Only), @@ -576,7 +576,7 @@ begin -- Gen_IL.Gen.Gen_Entities -- created for the base type, and this is the first named subtype). Ab (Modular_Integer_Kind, Integer_Kind, - (Sm (Modulus, Uint, Base_Type_Only), + (Sm (Modulus, Uint, Impl_Base_Type_Only), Sm (Original_Array_Type, Node_Id))); Cc (E_Modular_Integer_Type, Modular_Integer_Kind); @@ -781,7 +781,8 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (No_Reordering, Flag, Impl_Base_Type_Only), Sm (Parent_Subtype, Node_Id, Base_Type_Only), Sm (Reverse_Bit_Order, Flag, Base_Type_Only), - Sm (Underlying_Record_View, Node_Id))); + Sm (Underlying_Record_View, Node_Id), + Sm (Is_Large_Unconstrained_Definite, Flag, Impl_Base_Type_Only))); Cc (E_Record_Subtype, Aggregate_Kind, -- A record subtype, created by a record subtype declaration @@ -936,11 +937,13 @@ begin -- Gen_IL.Gen.Gen_Entities (Sm (Access_Subprogram_Wrapper, Node_Id), Sm (Extra_Accessibility_Of_Result, Node_Id), Sm (Extra_Formals, Node_Id), + Sm (Extra_Formals_Known, Flag), Sm (Needs_No_Actuals, Flag))); Ab (Overloadable_Kind, Entity_Kind, (Sm (Renamed_Or_Alias, Node_Id), Sm (Extra_Formals, Node_Id), + Sm (Extra_Formals_Known, Flag), Sm (Is_Abstract_Subprogram, Flag), Sm (Is_Primitive, Flag), Sm (Needs_No_Actuals, Flag), @@ -954,6 +957,7 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Enumeration_Rep_Expr, Node_Id), Sm (Esize, Uint), Sm (Alignment, Unat), + Sm (Overridden_Inherited_Operation, Node_Id), Sm (Interface_Name, Node_Id))); Ab (Subprogram_Kind, Overloadable_Kind, @@ -982,6 +986,7 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Is_Machine_Code_Subprogram, Flag), Sm (Last_Entity, Node_Id), Sm (Linker_Section_Pragma, Node_Id), + Sm (Overridden_Inherited_Operation, Node_Id), Sm (Overridden_Operation, Node_Id), Sm (Protected_Body_Subprogram, Node_Id), Sm (No_Raise, Flag), @@ -1004,7 +1009,6 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (DTC_Entity, Node_Id), Sm (Extra_Accessibility_Of_Result, Node_Id), Sm (Generic_Renamings, Elist_Id), - Sm (Handler_Records, List_Id), Sm (Has_Missing_Return, Flag), Sm (Inner_Instances, Elist_Id), Sm (Is_Called, Flag), @@ -1048,11 +1052,11 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (DTC_Entity, Node_Id), Sm (Entry_Parameters_Type, Node_Id), Sm (Generic_Renamings, Elist_Id), - Sm (Handler_Records, List_Id), Sm (Inner_Instances, Elist_Id), Sm (Is_Asynchronous, Flag), Sm (Is_Called, Flag), Sm (Is_CUDA_Kernel, Flag), + Sm (Is_Destructor, Flag), Sm (Is_DIC_Procedure, Flag), Sm (Is_Generic_Actual_Subprogram, Flag), Sm (Is_Initial_Condition_Procedure, Flag), @@ -1128,6 +1132,7 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Entry_Accepted, Flag), Sm (Entry_Parameters_Type, Node_Id), Sm (Extra_Formals, Node_Id), + Sm (Extra_Formals_Known, Flag), Sm (First_Entity, Node_Id), Sm (Has_Out_Or_In_Out_Parameter, Flag), Sm (Ignore_SPARK_Mode_Pragmas, Flag), @@ -1167,7 +1172,6 @@ begin -- Gen_IL.Gen.Gen_Entities (Sm (Alignment, Unat), Sm (Interface_Name, Node_Id), Sm (Is_Raised, Flag), - Sm (Register_Exception_Call, Node_Id), Sm (Renamed_Or_Alias, Node_Id))); Ab (Generic_Unit_Kind, Entity_Kind, @@ -1227,8 +1231,10 @@ begin -- Gen_IL.Gen.Gen_Entities Cc (E_Loop, Entity_Kind, -- A loop identifier, created by an explicit or implicit label on a -- loop statement. - (Sm (First_Entity, Node_Id), + (Sm (Continue_Mark, Node_Id), + Sm (First_Entity, Node_Id), Sm (First_Exit_Statement, Node_Id), + Sm (Has_Exit, Flag), Sm (Has_Loop_Entry_Attributes, Flag), Sm (Last_Entity, Node_Id), Sm (Renamed_Or_Alias, Node_Id), @@ -1256,8 +1262,6 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Body_Needed_For_SAL, Flag), Sm (Contract, Node_Id), Sm (Current_Use_Clause, Node_Id), - Sm (Dependent_Instances, Elist_Id, - Pre => "Is_Generic_Instance (N)"), Sm (Elaborate_Body_Desirable, Flag), Sm (Elaboration_Entity, Node_Id), Sm (Elaboration_Entity_Required, Flag), @@ -1265,7 +1269,6 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (First_Entity, Node_Id), Sm (First_Private_Entity, Node_Id), Sm (Generic_Renamings, Elist_Id), - Sm (Handler_Records, List_Id), Sm (Has_RACW, Flag), Sm (Hidden_In_Formal_Instance, Elist_Id), Sm (Ignore_SPARK_Mode_Pragmas, Flag), @@ -1297,7 +1300,6 @@ begin -- Gen_IL.Gen.Gen_Entities (Sm (Contract, Node_Id), Sm (Finalizer, Node_Id), Sm (First_Entity, Node_Id), - Sm (Handler_Records, List_Id), Sm (Ignore_SPARK_Mode_Pragmas, Flag), Sm (Last_Entity, Node_Id), Sm (Related_Instance, Node_Id), @@ -1332,6 +1334,7 @@ begin -- Gen_IL.Gen.Gen_Entities (Sm (Anonymous_Collections, Elist_Id), Sm (Contract, Node_Id), Sm (Extra_Formals, Node_Id), + Sm (Extra_Formals_Known, Flag), Sm (First_Entity, Node_Id), Sm (Ignore_SPARK_Mode_Pragmas, Flag), Sm (Interface_Name, Node_Id), diff --git a/gcc/ada/gen_il-gen-gen_nodes.adb b/gcc/ada/gen_il-gen-gen_nodes.adb index eb035361b570..412565f42a8b 100644 --- a/gcc/ada/gen_il-gen-gen_nodes.adb +++ b/gcc/ada/gen_il-gen-gen_nodes.adb @@ -149,6 +149,7 @@ begin -- Gen_IL.Gen.Gen_Nodes Sm (Is_Controlling_Actual, Flag), Sm (Is_Overloaded, Flag), Sm (Is_Static_Expression, Flag), + Sm (Is_Expanded_Dispatching_Call, Flag), Sm (Must_Not_Freeze, Flag), Sm (Raises_Constraint_Error, Flag))); @@ -181,7 +182,8 @@ begin -- Gen_IL.Gen.Gen_Nodes Sm (Is_Elaboration_Warnings_OK_Node, Flag), Sm (Is_SPARK_Mode_On_Node, Flag), Sm (Original_Discriminant, Node_Id), - Sm (Redundant_Use, Flag))); + Sm (Redundant_Use, Flag), + Sm (Tag_Propagated, Flag))); Cc (N_Operator_Symbol, N_Direct_Name, (Sy (Strval, String_Id))); @@ -303,6 +305,7 @@ begin -- Gen_IL.Gen.Gen_Nodes Sm (Is_Known_Guaranteed_ABE, Flag), Sm (Is_SPARK_Mode_On_Node, Flag), Sm (No_Elaboration_Check, Flag), + Sm (Is_Expanded_Constructor_Call, Flag), Sm (Is_Expanded_Prefixed_Call, Flag))); Cc (N_Function_Call, N_Subprogram_Call, @@ -345,7 +348,8 @@ begin -- Gen_IL.Gen.Gen_Nodes (Sy (Prefix, Node_Id), Sm (Actual_Designated_Subtype, Node_Id), Sm (Atomic_Sync_Required, Flag), - Sm (Has_Dereference_Action, Flag))); + Sm (Has_Dereference_Action, Flag), + Sm (Tag_Propagated, Flag))); Cc (N_Expression_With_Actions, N_Subexpr, (Sy (Actions, List_Id, Default_No_List), @@ -462,18 +466,14 @@ begin -- Gen_IL.Gen.Gen_Nodes Sm (Do_Length_Check, Flag), Sm (Do_Overflow_Check, Flag), Sm (Float_Truncate, Flag), + Sm (Tag_Propagated, Flag), Sm (Rounded_Result, Flag))); Cc (N_Unchecked_Type_Conversion, N_Subexpr, (Sy (Subtype_Mark, Node_Id, Default_Empty), Sy (Expression, Node_Id, Default_Empty), Sm (Kill_Range_Check, Flag), - Sm (No_Truncation, Flag)), - Nmake_Assert => "True or else Nkind (Expression) /= N_Unchecked_Type_Conversion"); --- Nmake_Assert => "Nkind (Expression) /= N_Unchecked_Type_Conversion"); - -- Assert that we don't have unchecked conversions of unchecked - -- conversions; if Expression might be an unchecked conversion, - -- then Tbuild.Unchecked_Convert_To should be used. + Sm (No_Truncation, Flag))); Cc (N_Subtype_Indication, N_Has_Etype, (Sy (Subtype_Mark, Node_Id, Default_Empty), @@ -533,8 +533,7 @@ begin -- Gen_IL.Gen.Gen_Nodes Sy (Discriminant_Specifications, List_Id, Default_No_List), Sy (Type_Definition, Node_Id), Sy (Aspect_Specifications, List_Id, Default_No_List), - Sm (Discr_Check_Funcs_Built, Flag), - Sm (Incomplete_View, Node_Id))); + Sm (Discr_Check_Funcs_Built, Flag))); Cc (N_Incomplete_Type_Declaration, N_Declaration, (Sy (Defining_Identifier, Node_Id), @@ -910,6 +909,7 @@ begin -- Gen_IL.Gen.Gen_Nodes Sm (Cleanup_Actions, List_Id), Sm (Exception_Junk, Flag), Sm (Is_Abort_Block, Flag), + Sm (Is_Expanded_Dispatching_Call, Flag), Sm (Is_Initialization_Block, Flag), Sm (Is_Task_Master, Flag))); @@ -967,6 +967,16 @@ begin -- Gen_IL.Gen.Gen_Nodes Sy (Is_Null_Loop, Flag), Sy (Suppress_Loop_Warnings, Flag))); + Ab (N_Loop_Flow_Statement, N_Statement_Other_Than_Procedure_Call, + (Sy (Name, Node_Id, Default_Empty), + Sy (Condition, Node_Id, Default_Empty))); + + Cc (N_Continue_Statement, N_Loop_Flow_Statement, + (Sm (Call_Or_Target_Loop, Node_Id))); + + Cc (N_Exit_Statement, N_Loop_Flow_Statement, + (Sm (Next_Exit_Statement, Node_Id))); + Cc (N_Null_Statement, N_Statement_Other_Than_Procedure_Call, (Sm (Next_Rep_Item, Node_Id))); @@ -1012,11 +1022,6 @@ begin -- Gen_IL.Gen.Gen_Nodes (Sy (Entry_Call_Alternative, Node_Id), Sy (Delay_Alternative, Node_Id))); - Cc (N_Exit_Statement, N_Statement_Other_Than_Procedure_Call, - (Sy (Name, Node_Id, Default_Empty), - Sy (Condition, Node_Id, Default_Empty), - Sm (Next_Exit_Statement, Node_Id))); - Cc (N_If_Statement, N_Statement_Other_Than_Procedure_Call, (Sy (Condition, Node_Id, Default_Empty), Sy (Then_Statements, List_Id), @@ -1030,8 +1035,7 @@ begin -- Gen_IL.Gen.Gen_Nodes (Sy (Accept_Statement, Node_Id), Sy (Condition, Node_Id, Default_Empty), Sy (Statements, List_Id, Default_Empty_List), - Sy (Pragmas_Before, List_Id, Default_No_List), - Sm (Accept_Handler_Records, List_Id))); + Sy (Pragmas_Before, List_Id, Default_No_List))); Cc (N_Delay_Alternative, Node_Kind, (Sy (Delay_Statement, Node_Id), diff --git a/gcc/ada/gen_il-internals.adb b/gcc/ada/gen_il-internals.adb index 8d0dfc710a4f..3fa8b9405427 100644 --- a/gcc/ada/gen_il-internals.adb +++ b/gcc/ada/gen_il-internals.adb @@ -277,6 +277,8 @@ package body Gen_IL.Internals is return "DT_Offset_To_Top_Func"; when DT_Position => return "DT_Position"; + when Extra_Formals_Known => + return "Extra_Formals_Known"; when Forwards_OK => return "Forwards_OK"; when Has_First_Controlling_Parameter_Aspect => diff --git a/gcc/ada/gen_il-types.ads b/gcc/ada/gen_il-types.ads index 6e0ab5b5da29..c3a97558f702 100644 --- a/gcc/ada/gen_il-types.ads +++ b/gcc/ada/gen_il-types.ads @@ -103,6 +103,7 @@ package Gen_IL.Types is N_Is_Range, N_Multiplying_Operator, N_Later_Decl_Item, + N_Loop_Flow_Statement, N_Membership_Test, N_Numeric_Or_String_Literal, N_Op, @@ -328,6 +329,7 @@ package Gen_IL.Types is N_Code_Statement, N_Compound_Statement, N_Conditional_Entry_Call, + N_Continue_Statement, N_Delay_Relative_Statement, N_Delay_Until_Statement, N_Entry_Call_Statement, diff --git a/gcc/ada/generate_minimal_reproducer.adb b/gcc/ada/generate_minimal_reproducer.adb index 66d34fe1a4f3..5a5ae16193e5 100644 --- a/gcc/ada/generate_minimal_reproducer.adb +++ b/gcc/ada/generate_minimal_reproducer.adb @@ -23,16 +23,18 @@ -- -- ------------------------------------------------------------------------------ +with Atree; with Fmap; with Fname.UF; with Lib; -with Namet; use Namet; -with Osint; use Osint; -with Output; use Output; -with Sinfo.Nodes; +with Namet; use Namet; +with Osint; use Osint; +with Output; use Output; +with Sinfo.Nodes; use Sinfo.Nodes; with System.CRTL; with System.OS_Lib; use System.OS_Lib; -with Types; use Types; +with Types; use Types; +with Uname; procedure Generate_Minimal_Reproducer is Reproducer_Generation_Failed : exception; @@ -85,6 +87,26 @@ procedure Generate_Minimal_Reproducer is Oracle_Path : constant String := Dirname & Directory_Separator & Executable_Name ("oracle"); + Main_Library_Item : constant Node_Id := Unit (Lib.Cunit (Main_Unit)); + + -- There is a special case that we need to detect: when the main library + -- item is the instantiation of a generic that has a body, and the + -- instantiation of generic bodies has started. We start by binding whether + -- the main library item is an instantiation to the following constant. + Main_Is_Instantiation : constant Boolean := + Nkind (Atree.Original_Node (Main_Library_Item)) + in N_Generic_Instantiation; + + -- If the main library item is an instantiation and its unit name is a body + -- name, it means that Make_Instance_Unit has been called. We need to use + -- the corresponding spec name to reconstruct the on-disk form of the + -- semantic closure. + Main_Unit_Name : constant Unit_Name_Type := + (if Main_Is_Instantiation + and then Uname.Is_Body_Name (Lib.Unit_Name (Main_Unit)) + then Uname.Get_Spec_Name (Lib.Unit_Name (Main_Unit)) + else Lib.Unit_Name (Main_Unit)); + Result : Integer; begin Create_Semantic_Closure_Project : @@ -118,25 +140,30 @@ begin end if; for J in Main_Unit .. Lib.Last_Unit loop - declare - Path : File_Name_Type := - Fmap.Mapped_Path_Name (Lib.Unit_File_Name (J)); - - Default_File_Name : constant String := - Fname.UF.Get_Default_File_Name (Lib.Unit_Name (J)); - - File_Copy_Path : constant String := - Src_Dir_Path & Directory_Separator & Default_File_Name; - - -- We may have synthesized units for child subprograms without - -- spec files. We need to filter out those units because we would - -- create bogus spec files that break compilation if we didn't. - Is_Synthetic_Subprogram_Spec : constant Boolean := - not Sinfo.Nodes.Comes_From_Source (Lib.Cunit (J)); - begin - if not Lib.Is_Internal_Unit (J) - and then not Is_Synthetic_Subprogram_Spec - then + -- We skip library units that fall under one of the following cases: + -- - Internal library units. + -- - Units that were synthesized for child subprograms without spec + -- files. + -- - Dummy entries that Add_Preprocessing_Dependency puts in + -- Lib.Units. + -- Those cases correspond to the conjuncts in the condition below. + if not Lib.Is_Internal_Unit (J) + and then Comes_From_Source (Lib.Cunit (J)) + and then Lib.Unit_Name (J) /= No_Unit_Name + then + declare + Path : File_Name_Type := + Fmap.Mapped_Path_Name (Lib.Unit_File_Name (J)); + + Unit_Name : constant Unit_Name_Type := + (if J = Main_Unit then Main_Unit_Name else Lib.Unit_Name (J)); + + Default_File_Name : constant String := + Fname.UF.Get_Default_File_Name (Unit_Name); + + File_Copy_Path : constant String := + Src_Dir_Path & Directory_Separator & Default_File_Name; + begin -- Mapped_Path_Name might have returned No_File. This has been -- observed for files with a Source_File_Name pragma. if Path = No_File then @@ -153,8 +180,8 @@ begin pragma Assert (Success); end; - end if; - end; + end; + end if; end loop; end Create_Semantic_Closure_Project; @@ -197,7 +224,7 @@ begin (Fmap.Mapped_Path_Name (Lib.Unit_File_Name (Main_Unit))); Default_Main_Name : constant String := - Fname.UF.Get_Default_File_Name (Lib.Unit_Name (Main_Unit)); + Fname.UF.Get_Default_File_Name (Main_Unit_Name); New_Main_Path : constant String := Src_Dir_Path & Directory_Separator & Default_Main_Name; @@ -228,7 +255,8 @@ begin Write_Eol; Write_Line (" Args : constant GNAT.OS_Lib.Argument_List :="); - Write_Str (" (new String'(""-gnatd_M"")"); + Write_Str + (" (new String'(""-quiet""), new String'(""-gnatd_M"")"); -- The following way of iterating through the command line arguments -- was copied from Set_Targ. TODO factorize??? diff --git a/gcc/ada/get_targ.ads b/gcc/ada/get_targ.ads index 35cf00d73a1a..4b658f10884f 100644 --- a/gcc/ada/get_targ.ads +++ b/gcc/ada/get_targ.ads @@ -113,7 +113,7 @@ package Get_Targ is type C_String is array (0 .. 255) of aliased Character; pragma Convention (C, C_String); - type Register_Type_Proc is access procedure + type Register_Type_Proc is not null access procedure (C_Name : C_String; -- Nul-terminated string with name of type Digs : Natural; -- Digits for floating point, 0 otherwise Complex : Boolean; -- True iff type has real and imaginary parts diff --git a/gcc/ada/ghost.adb b/gcc/ada/ghost.adb index 314a13deba87..6f648f2af922 100644 --- a/gcc/ada/ghost.adb +++ b/gcc/ada/ghost.adb @@ -67,17 +67,6 @@ package body Ghost is -- Local subprograms -- ----------------------- - function Whole_Object_Ref (Ref : Node_Id) return Node_Id; - -- For a name that denotes an object, returns a name that denotes the whole - -- object, declared by an object declaration, formal parameter declaration, - -- etc. For example, for P.X.Comp (J), if P is a package X is a record - -- object, this returns P.X. - - function Ghost_Entity (Ref : Node_Id) return Entity_Id; - pragma Inline (Ghost_Entity); - -- Obtain the entity of a Ghost entity from reference Ref. Return Empty if - -- no such entity exists. - procedure Install_Ghost_Mode (Mode : Ghost_Mode_Type); pragma Inline (Install_Ghost_Mode); -- Install Ghost mode Mode as the Ghost mode in effect @@ -787,7 +776,7 @@ package body Ghost is Formal : Entity_Id; Is_Default : Boolean := False) is - Actual_Obj : constant Entity_Id := Get_Enclosing_Deep_Object (Actual); + Actual_Obj : constant Entity_Id := Get_Enclosing_Ghost_Entity (Actual); begin if not Is_Ghost_Entity (Formal) then return; @@ -1085,27 +1074,6 @@ package body Ghost is end if; end Check_Ghost_Type; - ------------------ - -- Ghost_Entity -- - ------------------ - - function Ghost_Entity (Ref : Node_Id) return Entity_Id is - Obj_Ref : constant Node_Id := Ultimate_Prefix (Ref); - - begin - -- When the reference denotes a subcomponent, recover the related whole - -- object (SPARK RM 6.9(1)). - - if Is_Entity_Name (Obj_Ref) then - return Entity (Obj_Ref); - - -- Otherwise the reference cannot possibly denote a Ghost entity - - else - return Empty; - end if; - end Ghost_Entity; - -------------------------------- -- Implements_Ghost_Interface -- -------------------------------- @@ -1197,7 +1165,7 @@ package body Ghost is -- entity. if Nkind (N) = N_Assignment_Statement then - Id := Ghost_Entity (Name (N)); + Id := Get_Enclosing_Ghost_Entity (Name (N)); return Present (Id) and then Is_Ghost_Entity (Id); end if; @@ -1255,7 +1223,7 @@ package body Ghost is -- A procedure call is Ghost when it invokes a Ghost procedure if Nkind (N) = N_Procedure_Call_Statement then - Id := Ghost_Entity (Name (N)); + Id := Get_Enclosing_Ghost_Entity (Name (N)); return Present (Id) and then Is_Ghost_Entity (Id); end if; @@ -1492,29 +1460,23 @@ package body Ghost is end if; declare - Whole : constant Node_Id := Whole_Object_Ref (Lhs); - Id : Entity_Id; + Id : constant Entity_Id := Get_Enclosing_Ghost_Entity (Lhs); begin - if Is_Entity_Name (Whole) then - Id := Entity (Whole); - - if Present (Id) then - -- Left-hand side denotes a Checked ghost entity, so - -- install the region. + if Present (Id) then + -- Left-hand side denotes a Checked ghost entity, so install + -- the region. - if Is_Checked_Ghost_Entity (Id) then - Install_Ghost_Region (Check, N); + if Is_Checked_Ghost_Entity (Id) then + Install_Ghost_Region (Check, N); - -- Left-hand side denotes an Ignored ghost entity, so - -- install the region, and mark the assignment statement - -- as an ignored ghost assignment, so it will be removed - -- later. + -- Left-hand side denotes an Ignored ghost entity, so + -- install the region, and mark the assignment statement as + -- an ignored ghost assignment, so it will be removed later. - elsif Is_Ignored_Ghost_Entity (Id) then - Install_Ghost_Region (Ignore, N); - Set_Is_Ignored_Ghost_Node (N); - Record_Ignored_Ghost_Node (N); - end if; + elsif Is_Ignored_Ghost_Entity (Id) then + Install_Ghost_Region (Ignore, N); + Set_Is_Ignored_Ghost_Node (N); + Record_Ignored_Ghost_Node (N); end if; end if; end; @@ -1782,7 +1744,7 @@ package body Ghost is -- A procedure call becomes Ghost when the procedure being invoked is -- Ghost. Install the Ghost mode of the procedure. - Id := Ghost_Entity (Name (N)); + Id := Get_Enclosing_Ghost_Entity (Name (N)); if Present (Id) then if Is_Checked_Ghost_Entity (Id) then @@ -2096,7 +2058,7 @@ package body Ghost is -- of the target. if Nkind (N) = N_Assignment_Statement then - Id := Ghost_Entity (Name (N)); + Id := Get_Enclosing_Ghost_Entity (Name (N)); if Present (Id) then Set_Ghost_Mode_From_Entity (Id); @@ -2135,7 +2097,7 @@ package body Ghost is -- procedure being invoked. elsif Nkind (N) = N_Procedure_Call_Statement then - Id := Ghost_Entity (Name (N)); + Id := Get_Enclosing_Ghost_Entity (Name (N)); if Present (Id) then Set_Ghost_Mode_From_Entity (Id); @@ -2157,24 +2119,4 @@ package body Ghost is end if; end Set_Is_Ghost_Entity; - ---------------------- - -- Whole_Object_Ref -- - ---------------------- - - function Whole_Object_Ref (Ref : Node_Id) return Node_Id is - begin - if Nkind (Ref) in N_Indexed_Component | N_Slice - or else (Nkind (Ref) = N_Selected_Component - and then Is_Object_Reference (Prefix (Ref))) - then - if Is_Access_Type (Etype (Prefix (Ref))) then - return Ref; - else - return Whole_Object_Ref (Prefix (Ref)); - end if; - else - return Ref; - end if; - end Whole_Object_Ref; - end Ghost; diff --git a/gcc/ada/gnat-style.texi b/gcc/ada/gnat-style.texi index dde6ec4a6e7d..0880400bd28a 100644 --- a/gcc/ada/gnat-style.texi +++ b/gcc/ada/gnat-style.texi @@ -3,7 +3,7 @@ @setfilename gnat-style.info @documentencoding UTF-8 @ifinfo -@*Generated by Sphinx 8.0.2.@* +@*Generated by Sphinx 8.2.3.@* @end ifinfo @settitle GNAT Coding Style A Guide for GNAT Developers @defindex ge @@ -19,7 +19,7 @@ @copying @quotation -GNAT Coding Style: A Guide for GNAT Developers , Jan 03, 2025 +GNAT Coding Style: A Guide for GNAT Developers , Jun 02, 2025 AdaCore diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb index 46f04e484b79..52063c8067f7 100644 --- a/gcc/ada/gnat1drv.adb +++ b/gcc/ada/gnat1drv.adb @@ -982,7 +982,7 @@ procedure Gnat1drv is -- Local variables Back_End_Mode : Back_End.Back_End_Mode_Type; - Ecode : Exit_Code_Type; + Ecode : Exit_Code_Type := E_Success; Main_Unit_Kind : Node_Kind; -- Kind of main compilation unit node @@ -1169,9 +1169,10 @@ begin -- Exit with errors if the main source could not be parsed if Sinput.Main_Source_File <= No_Source_File then + Ecode := E_Errors; Errout.Finalize (Last_Call => True); - Errout.Output_Messages; - Exit_Program (E_Errors); + Errout.Output_Messages (Ecode); + Exit_Program (Ecode); end if; Main_Unit_Node := Cunit (Main_Unit); @@ -1198,9 +1199,10 @@ begin Errout.Finalize (Last_Call => False); if Compilation_Errors then + Ecode := E_Errors; Treepr.Tree_Dump; Errout.Finalize (Last_Call => True); - Errout.Output_Messages; + Errout.Output_Messages (Ecode); Namet.Finalize; -- Generate ALI file if specially requested @@ -1209,7 +1211,7 @@ begin Write_ALI (Object => False); end if; - Exit_Program (E_Errors); + Exit_Program (Ecode); end if; -- Case of no code required to be generated, exit indicating no error @@ -1217,7 +1219,7 @@ begin if Original_Operating_Mode = Check_Syntax then Treepr.Tree_Dump; Errout.Finalize (Last_Call => True); - Errout.Output_Messages; + Errout.Output_Messages (Ecode); Namet.Finalize; Check_Rep_Info; @@ -1350,7 +1352,15 @@ begin -- Exit the gnat driver with success, otherwise external builders -- such as gnatmake and gprbuild will treat the compilation of an -- ignored Ghost unit as a failure. Be sure we produce an empty - -- object file for the unit. + -- object file for the unit, while indicating for the ALI file + -- generation that neither spec or body has elaboration code + -- (which in ordinary compilation is indicated in Gigi). + + Set_Has_No_Elaboration_Code (Main_Unit_Node); + + if Present (Library_Unit (Main_Unit_Node)) then + Set_Has_No_Elaboration_Code (Library_Unit (Main_Unit_Node)); + end if; Ecode := E_Success; Back_End.Gen_Or_Update_Object_File; @@ -1407,7 +1417,7 @@ begin Post_Compilation_Validation_Checks; Errout.Finalize (Last_Call => True); - Errout.Output_Messages; + Errout.Output_Messages (Ecode); Treepr.Tree_Dump; -- Generate ALI file if specially requested, or for missing subunits, @@ -1461,7 +1471,7 @@ begin then Post_Compilation_Validation_Checks; Errout.Finalize (Last_Call => True); - Errout.Output_Messages; + Errout.Output_Messages (Ecode); Write_ALI (Object => False); Tree_Dump; Namet.Finalize; @@ -1541,7 +1551,8 @@ begin -- representation information for List_Rep_Info). Errout.Finalize (Last_Call => True); - Errout.Output_Messages; + Errout.Output_Messages + ((if Compilation_Errors then E_Errors else E_Success)); -- Back annotation of representation info is not done in CodePeer and -- SPARK modes. @@ -1557,8 +1568,9 @@ begin -- there will be no attempt to generate an object file. if Compilation_Errors then + Ecode := E_Errors; Treepr.Tree_Dump; - Exit_Program (E_Errors); + Exit_Program (Ecode); end if; if not GNATprove_Mode then @@ -1632,7 +1644,7 @@ begin exception when Unrecoverable_Error => Errout.Finalize (Last_Call => True); - Errout.Output_Messages; + Errout.Output_Messages (E_Errors); Set_Standard_Error; Write_Str ("compilation abandoned"); diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index 97469d739520..1ca3ede355b4 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -3,7 +3,7 @@ @setfilename gnat_rm.info @documentencoding UTF-8 @ifinfo -@*Generated by Sphinx 8.0.2.@* +@*Generated by Sphinx 8.2.3.@* @end ifinfo @settitle GNAT Reference Manual @defindex ge @@ -19,7 +19,7 @@ @copying @quotation -GNAT Reference Manual , Jan 03, 2025 +GNAT Reference Manual , Jul 21, 2025 AdaCore @@ -76,7 +76,7 @@ included in the section entitled @ref{1,,GNU Free Documentation License}. * Interfacing to Other Languages:: * Specialized Needs Annexes:: * Implementation of Specific Ada Features:: -* Implementation of Ada 2012 Features:: +* Implementation of Ada 2022 Features:: * GNAT language extensions:: * Security Hardening Features:: * Obsolescent Features:: @@ -238,6 +238,7 @@ Implementation Defined Pragmas * Pragma Priority_Specific_Dispatching:: * Pragma Profile:: * Pragma Profile_Warnings:: +* Pragma Program_Exit:: * Pragma Propagate_Exceptions:: * Pragma Provide_Shift_Operators:: * Pragma Psect_Object:: @@ -347,7 +348,9 @@ Implementation Defined Aspects * Aspect Obsolescent:: * Aspect Part_Of:: * Aspect Persistent_BSS:: +* Aspect Potentially_Invalid:: * Aspect Predicate:: +* Aspect Program_Exit:: * Aspect Pure_Function:: * Aspect Refined_Depends:: * Aspect Refined_Global:: @@ -916,6 +919,7 @@ Deep delta Aggregates Experimental Language Extensions * Conditional when constructs:: +* Implicit With:: * Storage Model:: * Attribute Super:: * Simpler Accessibility Model:: @@ -926,6 +930,8 @@ Experimental Language Extensions * Inference of Dependent Types in Generic Instantiations:: * External_Initialization Aspect:: * Finally construct:: +* Continue statement:: +* Destructors:: Storage Model @@ -939,10 +945,9 @@ Simpler Accessibility Model * Subprogram parameters:: * Function results:: -No_Raise aspect +Generalized Finalization -* New specification for Ada.Finalization.Controlled: New specification for Ada Finalization Controlled. -* Finalized tagged types:: +* Finalizable tagged types:: * Composite types:: * Interoperability with controlled types:: @@ -1007,7 +1012,7 @@ GNAT compiler. It includes information on implementation dependent characteristics of GNAT, including all the information required by Annex M of the Ada language standard. -GNAT implements Ada 95, Ada 2005 and Ada 2012, and it may also be +GNAT implements Ada 95, Ada 2005, Ada 2012 and Ada 2022, and it may also be invoked in Ada 83 compatibility mode. By default, GNAT assumes Ada 2012, but you can override with a compiler switch @@ -1112,8 +1117,8 @@ to GNAT’s implementation of machine code insertions, tasking, and several other features. @item -@ref{14,,Implementation of Ada 2012 Features}, describes the status of the -GNAT implementation of the Ada 2012 language standard. +@ref{14,,Implementation of Ada 2022 Features}, describes the status of the +GNAT implementation of the Ada 2022 language standard. @item @ref{15,,Security Hardening Features} documents GNAT extensions aimed @@ -1405,6 +1410,7 @@ consideration, the use of these pragmas should be minimized. * Pragma Priority_Specific_Dispatching:: * Pragma Profile:: * Pragma Profile_Warnings:: +* Pragma Program_Exit:: * Pragma Propagate_Exceptions:: * Pragma Provide_Shift_Operators:: * Pragma Psect_Object:: @@ -1577,6 +1583,11 @@ and generics may name types with unknown discriminants without using the @code{(<>)} notation. In addition, some but not all of the additional restrictions of Ada 83 are enforced. +Like all configuration pragmas, if the pragma is placed before a library +level package specification it is not propagated to the corresponding +package body (see RM 10.1.5(8)); it must be added explicitly to the +package body. + Ada 83 mode is intended for two purposes. Firstly, it allows existing Ada 83 code to be compiled and adapted to GNAT with less effort. Secondly, it aids in keeping code backwards compatible with Ada 83. @@ -1604,6 +1615,11 @@ contexts. This pragma is useful when writing a reusable component that itself uses Ada 95 features, but which is intended to be usable from either Ada 83 or Ada 95 programs. +Like all configuration pragmas, if the pragma is placed before a library +level package specification it is not propagated to the corresponding +package body (see RM 10.1.5(8)); it must be added explicitly to the +package body. + @node Pragma Ada_05,Pragma Ada_2005,Pragma Ada_95,Implementation Defined Pragmas @anchor{gnat_rm/implementation_defined_pragmas pragma-ada-05}@anchor{21} @section Pragma Ada_05 @@ -1622,6 +1638,11 @@ This pragma is useful when writing a reusable component that itself uses Ada 2005 features, but which is intended to be usable from either Ada 83 or Ada 95 programs. +Like all configuration pragmas, if the pragma is placed before a library +level package specification it is not propagated to the corresponding +package body (see RM 10.1.5(8)); it must be added explicitly to the +package body. + The one argument form (which is not a configuration pragma) is used for managing the transition from Ada 95 to Ada 2005 in the run-time library. If an entity is marked @@ -1667,6 +1688,11 @@ contexts. This pragma is useful when writing a reusable component that itself uses Ada 2012 features, but which is intended to be usable from Ada 83, Ada 95, or Ada 2005 programs. +Like all configuration pragmas, if the pragma is placed before a library +level package specification it is not propagated to the corresponding +package body (see RM 10.1.5(8)); it must be added explicitly to the +package body. + The one argument form, which is not a configuration pragma, is used for managing the transition from Ada 2005 to Ada 2012 in the run-time library. If an entity is marked @@ -1712,6 +1738,11 @@ contexts. This pragma is useful when writing a reusable component that itself uses Ada 2022 features, but which is intended to be usable from Ada 83, Ada 95, Ada 2005 or Ada 2012 programs. +Like all configuration pragmas, if the pragma is placed before a library +level package specification it is not propagated to the corresponding +package body (see RM 10.1.5(8)); it must be added explicitly to the +package body. + The one argument form, which is not a configuration pragma, is used for managing the transition from Ada 2012 to Ada 2022 in the run-time library. If an entity is marked @@ -3470,6 +3501,7 @@ EXIT_CASE ::= GUARD => EXIT_KIND EXIT_KIND ::= Normal_Return | Exception_Raised | (Exception_Raised => exception_name) + | Program_Exit GUARD ::= Boolean_expression @end example @@ -4682,8 +4714,8 @@ pragma Interrupt_State Normally certain interrupts are reserved to the implementation. Any attempt to attach an interrupt causes Program_Error to be raised, as described in RM C.3.2(22). A typical example is the @code{SIGINT} interrupt used in -many systems for an @code{Ctrl-C} interrupt. Normally this interrupt is -reserved to the implementation, so that @code{Ctrl-C} can be used to +many systems for an @code{Ctrl}-@code{C} interrupt. Normally this interrupt is +reserved to the implementation, so that @code{Ctrl}-@code{C} can be used to interrupt execution. Additionally, signals such as @code{SIGSEGV}, @code{SIGABRT}, @code{SIGFPE} and @code{SIGILL} are often mapped to specific Ada exceptions, or used to implement run-time functions such as the @@ -6912,7 +6944,7 @@ conforming Ada constructs. The profile enables the following three pragmas: @end itemize @end itemize -@node Pragma Profile_Warnings,Pragma Propagate_Exceptions,Pragma Profile,Implementation Defined Pragmas +@node Pragma Profile_Warnings,Pragma Program_Exit,Pragma Profile,Implementation Defined Pragmas @anchor{gnat_rm/implementation_defined_pragmas pragma-profile-warnings}@anchor{ce} @section Pragma Profile_Warnings @@ -6930,8 +6962,22 @@ generating @code{Restrictions} pragmas, it generates violations of the profile generate warning messages instead of error messages. -@node Pragma Propagate_Exceptions,Pragma Provide_Shift_Operators,Pragma Profile_Warnings,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-propagate-exceptions}@anchor{cf} +@node Pragma Program_Exit,Pragma Propagate_Exceptions,Pragma Profile_Warnings,Implementation Defined Pragmas +@anchor{gnat_rm/implementation_defined_pragmas id34}@anchor{cf}@anchor{gnat_rm/implementation_defined_pragmas pragma-program-exit}@anchor{d0} +@section Pragma Program_Exit + + +Syntax: + +@example +pragma Program_Exit [ (boolean_EXPRESSION) ]; +@end example + +For the semantics of this pragma, see the entry for aspect @code{Program_Exit} +in the SPARK 2014 Reference Manual, section 6.1.10. + +@node Pragma Propagate_Exceptions,Pragma Provide_Shift_Operators,Pragma Program_Exit,Implementation Defined Pragmas +@anchor{gnat_rm/implementation_defined_pragmas pragma-propagate-exceptions}@anchor{d1} @section Pragma Propagate_Exceptions @@ -6950,7 +6996,7 @@ purposes. It used to be used in connection with optimization of a now-obsolete mechanism for implementation of exceptions. @node Pragma Provide_Shift_Operators,Pragma Psect_Object,Pragma Propagate_Exceptions,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-provide-shift-operators}@anchor{d0} +@anchor{gnat_rm/implementation_defined_pragmas pragma-provide-shift-operators}@anchor{d2} @section Pragma Provide_Shift_Operators @@ -6970,7 +7016,7 @@ including the function declarations for these five operators, together with the pragma Import (Intrinsic, …) statements. @node Pragma Psect_Object,Pragma Pure_Function,Pragma Provide_Shift_Operators,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-psect-object}@anchor{d1} +@anchor{gnat_rm/implementation_defined_pragmas pragma-psect-object}@anchor{d3} @section Pragma Psect_Object @@ -6990,7 +7036,7 @@ EXTERNAL_SYMBOL ::= This pragma is identical in effect to pragma @code{Common_Object}. @node Pragma Pure_Function,Pragma Rational,Pragma Psect_Object,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id34}@anchor{d2}@anchor{gnat_rm/implementation_defined_pragmas pragma-pure-function}@anchor{d3} +@anchor{gnat_rm/implementation_defined_pragmas id35}@anchor{d4}@anchor{gnat_rm/implementation_defined_pragmas pragma-pure-function}@anchor{d5} @section Pragma Pure_Function @@ -7052,7 +7098,7 @@ unit is not a Pure unit in the categorization sense. So for example, a function thus marked is free to @code{with} non-pure units. @node Pragma Rational,Pragma Ravenscar,Pragma Pure_Function,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-rational}@anchor{d4} +@anchor{gnat_rm/implementation_defined_pragmas pragma-rational}@anchor{d6} @section Pragma Rational @@ -7070,7 +7116,7 @@ pragma Profile (Rational); @end example @node Pragma Ravenscar,Pragma Refined_Depends,Pragma Rational,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-ravenscar}@anchor{d5} +@anchor{gnat_rm/implementation_defined_pragmas pragma-ravenscar}@anchor{d7} @section Pragma Ravenscar @@ -7090,7 +7136,7 @@ pragma Profile (Ravenscar); which is the preferred method of setting the @code{Ravenscar} profile. @node Pragma Refined_Depends,Pragma Refined_Global,Pragma Ravenscar,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id35}@anchor{d6}@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-depends}@anchor{d7} +@anchor{gnat_rm/implementation_defined_pragmas id36}@anchor{d8}@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-depends}@anchor{d9} @section Pragma Refined_Depends @@ -7123,7 +7169,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_Depends the SPARK 2014 Reference Manual, section 6.1.5. @node Pragma Refined_Global,Pragma Refined_Post,Pragma Refined_Depends,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id36}@anchor{d8}@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-global}@anchor{d9} +@anchor{gnat_rm/implementation_defined_pragmas id37}@anchor{da}@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-global}@anchor{db} @section Pragma Refined_Global @@ -7148,7 +7194,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_Global} the SPARK 2014 Reference Manual, section 6.1.4. @node Pragma Refined_Post,Pragma Refined_State,Pragma Refined_Global,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id37}@anchor{da}@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-post}@anchor{db} +@anchor{gnat_rm/implementation_defined_pragmas id38}@anchor{dc}@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-post}@anchor{dd} @section Pragma Refined_Post @@ -7162,7 +7208,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_Post} i the SPARK 2014 Reference Manual, section 7.2.7. @node Pragma Refined_State,Pragma Relative_Deadline,Pragma Refined_Post,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id38}@anchor{dc}@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-state}@anchor{dd} +@anchor{gnat_rm/implementation_defined_pragmas id39}@anchor{de}@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-state}@anchor{df} @section Pragma Refined_State @@ -7188,7 +7234,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_State} the SPARK 2014 Reference Manual, section 7.2.2. @node Pragma Relative_Deadline,Pragma Remote_Access_Type,Pragma Refined_State,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-relative-deadline}@anchor{de} +@anchor{gnat_rm/implementation_defined_pragmas pragma-relative-deadline}@anchor{e0} @section Pragma Relative_Deadline @@ -7203,7 +7249,7 @@ versions of Ada as an implementation-defined pragma. See Ada 2012 Reference Manual for details. @node Pragma Remote_Access_Type,Pragma Rename_Pragma,Pragma Relative_Deadline,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id39}@anchor{df}@anchor{gnat_rm/implementation_defined_pragmas pragma-remote-access-type}@anchor{e0} +@anchor{gnat_rm/implementation_defined_pragmas id40}@anchor{e1}@anchor{gnat_rm/implementation_defined_pragmas pragma-remote-access-type}@anchor{e2} @section Pragma Remote_Access_Type @@ -7229,7 +7275,7 @@ pertaining to remote access to class-wide types. At instantiation, the actual type must be a remote access to class-wide type. @node Pragma Rename_Pragma,Pragma Restricted_Run_Time,Pragma Remote_Access_Type,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-rename-pragma}@anchor{e1} +@anchor{gnat_rm/implementation_defined_pragmas pragma-rename-pragma}@anchor{e3} @section Pragma Rename_Pragma @@ -7268,7 +7314,7 @@ Pragma Inline_Only will not necessarily mean the same thing as the other Ada compiler; it’s up to you to make sure the semantics are close enough. @node Pragma Restricted_Run_Time,Pragma Restriction_Warnings,Pragma Rename_Pragma,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-restricted-run-time}@anchor{e2} +@anchor{gnat_rm/implementation_defined_pragmas pragma-restricted-run-time}@anchor{e4} @section Pragma Restricted_Run_Time @@ -7289,7 +7335,7 @@ which is the preferred method of setting the restricted run time profile. @node Pragma Restriction_Warnings,Pragma Reviewable,Pragma Restricted_Run_Time,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-restriction-warnings}@anchor{e3} +@anchor{gnat_rm/implementation_defined_pragmas pragma-restriction-warnings}@anchor{e5} @section Pragma Restriction_Warnings @@ -7327,7 +7373,7 @@ generating a warning, but any other use of implementation defined pragmas will cause a warning to be generated. @node Pragma Reviewable,Pragma Secondary_Stack_Size,Pragma Restriction_Warnings,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-reviewable}@anchor{e4} +@anchor{gnat_rm/implementation_defined_pragmas pragma-reviewable}@anchor{e6} @section Pragma Reviewable @@ -7431,7 +7477,7 @@ comprehensive messages identifying possible problems based on this information. @node Pragma Secondary_Stack_Size,Pragma Share_Generic,Pragma Reviewable,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id40}@anchor{e5}@anchor{gnat_rm/implementation_defined_pragmas pragma-secondary-stack-size}@anchor{e6} +@anchor{gnat_rm/implementation_defined_pragmas id41}@anchor{e7}@anchor{gnat_rm/implementation_defined_pragmas pragma-secondary-stack-size}@anchor{e8} @section Pragma Secondary_Stack_Size @@ -7467,7 +7513,7 @@ Note the pragma cannot appear when the restriction @code{No_Secondary_Stack} is in effect. @node Pragma Share_Generic,Pragma Shared,Pragma Secondary_Stack_Size,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-share-generic}@anchor{e7} +@anchor{gnat_rm/implementation_defined_pragmas pragma-share-generic}@anchor{e9} @section Pragma Share_Generic @@ -7485,7 +7531,7 @@ than to check that the given names are all names of generic units or generic instances. @node Pragma Shared,Pragma Short_Circuit_And_Or,Pragma Share_Generic,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id41}@anchor{e8}@anchor{gnat_rm/implementation_defined_pragmas pragma-shared}@anchor{e9} +@anchor{gnat_rm/implementation_defined_pragmas id42}@anchor{ea}@anchor{gnat_rm/implementation_defined_pragmas pragma-shared}@anchor{eb} @section Pragma Shared @@ -7493,7 +7539,7 @@ This pragma is provided for compatibility with Ada 83. The syntax and semantics are identical to pragma Atomic. @node Pragma Short_Circuit_And_Or,Pragma Short_Descriptors,Pragma Shared,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-short-circuit-and-or}@anchor{ea} +@anchor{gnat_rm/implementation_defined_pragmas pragma-short-circuit-and-or}@anchor{ec} @section Pragma Short_Circuit_And_Or @@ -7503,16 +7549,36 @@ Syntax: pragma Short_Circuit_And_Or; @end example -This configuration pragma causes any occurrence of the AND operator applied to -operands of type Standard.Boolean to be short-circuited (i.e. the AND operator -is treated as if it were AND THEN). Or is similarly treated as OR ELSE. This -may be useful in the context of certification protocols requiring the use of -short-circuited logical operators. If this configuration pragma occurs locally -within the file being compiled, it applies only to the file being compiled. +This configuration pragma causes the predefined AND and OR operators of +type Standard.Boolean to have short-circuit semantics. That is, they +behave like AND THEN and OR ELSE; the right-hand side is not evaluated +if the left-hand side determines the result. This may be useful in the +context of certification protocols requiring the use of short-circuited +logical operators. + There is no requirement that all units in a partition use this option. +However, mixing of short-circuit and non-short-circuit semantics can be +confusing. Therefore, the recommended use is to put the pragma in a +configuration file that applies to the whole program. Alternatively, if +you have a legacy library that should not use this pragma, you can put +it in a separate library project that does not use the pragma. +In any case, fine-grained mixing of the different semantics is not +recommended. If pragma @code{Short_Circuit_And_Or} is specified, then it +is illegal to rename the predefined Boolean AND and OR, or to pass +them to generic formal functions; this corresponds to the fact that +AND THEN and OR ELSE cannot be renamed nor passed as generic formal +functions. + +Note that this pragma has no effect on other logical operators – +predefined operators of modular types, array-of-boolean types and types +derived from Standard.Boolean, nor user-defined operators. + +See also the pragma @code{Unevaluated_Use_Of_Old} and the restriction +@code{No_Direct_Boolean_Operators}, which may be useful in conjunction +with @code{Short_Circuit_And_Or}. @node Pragma Short_Descriptors,Pragma Side_Effects,Pragma Short_Circuit_And_Or,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-short-descriptors}@anchor{eb} +@anchor{gnat_rm/implementation_defined_pragmas pragma-short-descriptors}@anchor{ed} @section Pragma Short_Descriptors @@ -7526,7 +7592,7 @@ This pragma is provided for compatibility with other Ada implementations. It is recognized but ignored by all current versions of GNAT. @node Pragma Side_Effects,Pragma Simple_Storage_Pool_Type,Pragma Short_Descriptors,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id42}@anchor{ec}@anchor{gnat_rm/implementation_defined_pragmas pragma-side-effects}@anchor{ed} +@anchor{gnat_rm/implementation_defined_pragmas id43}@anchor{ee}@anchor{gnat_rm/implementation_defined_pragmas pragma-side-effects}@anchor{ef} @section Pragma Side_Effects @@ -7540,7 +7606,7 @@ For the semantics of this pragma, see the entry for aspect @code{Side_Effects} in the SPARK Reference Manual, section 6.1.12. @node Pragma Simple_Storage_Pool_Type,Pragma Source_File_Name,Pragma Side_Effects,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id43}@anchor{ee}@anchor{gnat_rm/implementation_defined_pragmas pragma-simple-storage-pool-type}@anchor{ef} +@anchor{gnat_rm/implementation_defined_pragmas id44}@anchor{f0}@anchor{gnat_rm/implementation_defined_pragmas pragma-simple-storage-pool-type}@anchor{f1} @section Pragma Simple_Storage_Pool_Type @@ -7594,7 +7660,7 @@ storage-management discipline). An object of a simple storage pool type can be associated with an access type by specifying the attribute -@ref{f0,,Simple_Storage_Pool}. For example: +@ref{f2,,Simple_Storage_Pool}. For example: @example My_Pool : My_Simple_Storage_Pool_Type; @@ -7604,11 +7670,11 @@ type Acc is access My_Data_Type; for Acc'Simple_Storage_Pool use My_Pool; @end example -See attribute @ref{f0,,Simple_Storage_Pool} +See attribute @ref{f2,,Simple_Storage_Pool} for further details. @node Pragma Source_File_Name,Pragma Source_File_Name_Project,Pragma Simple_Storage_Pool_Type,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id44}@anchor{f1}@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name}@anchor{f2} +@anchor{gnat_rm/implementation_defined_pragmas id45}@anchor{f3}@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name}@anchor{f4} @section Pragma Source_File_Name @@ -7700,20 +7766,20 @@ aware of these pragmas, and so other tools that use the project file would not be aware of the intended naming conventions. If you are using project files, file naming is controlled by Source_File_Name_Project pragmas, which are usually supplied automatically by the project manager. A pragma -Source_File_Name cannot appear after a @ref{f3,,Pragma Source_File_Name_Project}. +Source_File_Name cannot appear after a @ref{f5,,Pragma Source_File_Name_Project}. For more details on the use of the @code{Source_File_Name} pragma, see the sections on @cite{Using Other File Names} and @cite{Alternative File Naming Schemes} in the @cite{GNAT User’s Guide}. @node Pragma Source_File_Name_Project,Pragma Source_Reference,Pragma Source_File_Name,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id45}@anchor{f4}@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name-project}@anchor{f3} +@anchor{gnat_rm/implementation_defined_pragmas id46}@anchor{f6}@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name-project}@anchor{f5} @section Pragma Source_File_Name_Project This pragma has the same syntax and semantics as pragma Source_File_Name. It is only allowed as a stand-alone configuration pragma. -It cannot appear after a @ref{f2,,Pragma Source_File_Name}, and +It cannot appear after a @ref{f4,,Pragma Source_File_Name}, and most importantly, once pragma Source_File_Name_Project appears, no further Source_File_Name pragmas are allowed. @@ -7725,7 +7791,7 @@ Source_File_Name or Source_File_Name_Project pragmas (which would not be known to the project manager). @node Pragma Source_Reference,Pragma SPARK_Mode,Pragma Source_File_Name_Project,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-source-reference}@anchor{f5} +@anchor{gnat_rm/implementation_defined_pragmas pragma-source-reference}@anchor{f7} @section Pragma Source_Reference @@ -7749,7 +7815,7 @@ string expression other than a string literal. This is because its value is needed for error messages issued by all phases of the compiler. @node Pragma SPARK_Mode,Pragma Static_Elaboration_Desired,Pragma Source_Reference,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id46}@anchor{f6}@anchor{gnat_rm/implementation_defined_pragmas pragma-spark-mode}@anchor{f7} +@anchor{gnat_rm/implementation_defined_pragmas id47}@anchor{f8}@anchor{gnat_rm/implementation_defined_pragmas pragma-spark-mode}@anchor{f9} @section Pragma SPARK_Mode @@ -7831,7 +7897,7 @@ SPARK_Mode (@code{Off}), then that pragma will need to be repeated in the package body. @node Pragma Static_Elaboration_Desired,Pragma Stream_Convert,Pragma SPARK_Mode,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-static-elaboration-desired}@anchor{f8} +@anchor{gnat_rm/implementation_defined_pragmas pragma-static-elaboration-desired}@anchor{fa} @section Pragma Static_Elaboration_Desired @@ -7855,7 +7921,7 @@ construction of larger aggregates with static components that include an others choice.) @node Pragma Stream_Convert,Pragma Style_Checks,Pragma Static_Elaboration_Desired,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-stream-convert}@anchor{f9} +@anchor{gnat_rm/implementation_defined_pragmas pragma-stream-convert}@anchor{fb} @section Pragma Stream_Convert @@ -7932,7 +7998,7 @@ the pragma is silently ignored, and the default implementation of the stream attributes is used instead. @node Pragma Style_Checks,Pragma Subprogram_Variant,Pragma Stream_Convert,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-style-checks}@anchor{fa} +@anchor{gnat_rm/implementation_defined_pragmas pragma-style-checks}@anchor{fc} @section Pragma Style_Checks @@ -8078,7 +8144,7 @@ Rf2 : Integer := ARG; -- OK, no error @end example @node Pragma Subprogram_Variant,Pragma Subtitle,Pragma Style_Checks,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-subprogram-variant}@anchor{fb} +@anchor{gnat_rm/implementation_defined_pragmas pragma-subprogram-variant}@anchor{fd} @section Pragma Subprogram_Variant @@ -8110,7 +8176,7 @@ the implementation-defined @code{Subprogram_Variant} aspect, and shares its restrictions and semantics. @node Pragma Subtitle,Pragma Suppress,Pragma Subprogram_Variant,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-subtitle}@anchor{fc} +@anchor{gnat_rm/implementation_defined_pragmas pragma-subtitle}@anchor{fe} @section Pragma Subtitle @@ -8124,7 +8190,7 @@ This pragma is recognized for compatibility with other Ada compilers but is ignored by GNAT. @node Pragma Suppress,Pragma Suppress_All,Pragma Subtitle,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress}@anchor{fd} +@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress}@anchor{ff} @section Pragma Suppress @@ -8197,7 +8263,7 @@ Of course, run-time checks are omitted whenever the compiler can prove that they will not fail, whether or not checks are suppressed. @node Pragma Suppress_All,Pragma Suppress_Debug_Info,Pragma Suppress,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-all}@anchor{fe} +@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-all}@anchor{100} @section Pragma Suppress_All @@ -8216,7 +8282,7 @@ The use of the standard Ada pragma @code{Suppress (All_Checks)} as a normal configuration pragma is the preferred usage in GNAT. @node Pragma Suppress_Debug_Info,Pragma Suppress_Exception_Locations,Pragma Suppress_All,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id47}@anchor{ff}@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-debug-info}@anchor{100} +@anchor{gnat_rm/implementation_defined_pragmas id48}@anchor{101}@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-debug-info}@anchor{102} @section Pragma Suppress_Debug_Info @@ -8231,7 +8297,7 @@ for the specified entity. It is intended primarily for use in debugging the debugger, and navigating around debugger problems. @node Pragma Suppress_Exception_Locations,Pragma Suppress_Initialization,Pragma Suppress_Debug_Info,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-exception-locations}@anchor{101} +@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-exception-locations}@anchor{103} @section Pragma Suppress_Exception_Locations @@ -8254,7 +8320,7 @@ a partition, so it is fine to have some units within a partition compiled with this pragma and others compiled in normal mode without it. @node Pragma Suppress_Initialization,Pragma Task_Name,Pragma Suppress_Exception_Locations,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id48}@anchor{102}@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-initialization}@anchor{103} +@anchor{gnat_rm/implementation_defined_pragmas id49}@anchor{104}@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-initialization}@anchor{105} @section Pragma Suppress_Initialization @@ -8299,7 +8365,7 @@ is suppressed, just as though its subtype had been given in a pragma Suppress_Initialization, as described above. @node Pragma Task_Name,Pragma Task_Storage,Pragma Suppress_Initialization,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-task-name}@anchor{104} +@anchor{gnat_rm/implementation_defined_pragmas pragma-task-name}@anchor{106} @section Pragma Task_Name @@ -8355,7 +8421,7 @@ end; @end example @node Pragma Task_Storage,Pragma Test_Case,Pragma Task_Name,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-task-storage}@anchor{105} +@anchor{gnat_rm/implementation_defined_pragmas pragma-task-storage}@anchor{107} @section Pragma Task_Storage @@ -8375,7 +8441,7 @@ created, depending on the target. This pragma can appear anywhere a type. @node Pragma Test_Case,Pragma Thread_Local_Storage,Pragma Task_Storage,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id49}@anchor{106}@anchor{gnat_rm/implementation_defined_pragmas pragma-test-case}@anchor{107} +@anchor{gnat_rm/implementation_defined_pragmas id50}@anchor{108}@anchor{gnat_rm/implementation_defined_pragmas pragma-test-case}@anchor{109} @section Pragma Test_Case @@ -8431,7 +8497,7 @@ postcondition. Mode @code{Robustness} indicates that the precondition and postcondition of the subprogram should be ignored for this test case. @node Pragma Thread_Local_Storage,Pragma Time_Slice,Pragma Test_Case,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id50}@anchor{108}@anchor{gnat_rm/implementation_defined_pragmas pragma-thread-local-storage}@anchor{109} +@anchor{gnat_rm/implementation_defined_pragmas id51}@anchor{10a}@anchor{gnat_rm/implementation_defined_pragmas pragma-thread-local-storage}@anchor{10b} @section Pragma Thread_Local_Storage @@ -8469,7 +8535,7 @@ If this pragma is used on a system where @code{TLS} is not supported, then an error message will be generated and the program will be rejected. @node Pragma Time_Slice,Pragma Title,Pragma Thread_Local_Storage,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-time-slice}@anchor{10a} +@anchor{gnat_rm/implementation_defined_pragmas pragma-time-slice}@anchor{10c} @section Pragma Time_Slice @@ -8485,7 +8551,7 @@ It is ignored if it is used in a system that does not allow this control, or if it appears in other than the main program unit. @node Pragma Title,Pragma Type_Invariant,Pragma Time_Slice,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-title}@anchor{10b} +@anchor{gnat_rm/implementation_defined_pragmas pragma-title}@anchor{10d} @section Pragma Title @@ -8510,7 +8576,7 @@ notation is used, and named and positional notation can be mixed following the normal rules for procedure calls in Ada. @node Pragma Type_Invariant,Pragma Type_Invariant_Class,Pragma Title,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-type-invariant}@anchor{10c} +@anchor{gnat_rm/implementation_defined_pragmas pragma-type-invariant}@anchor{10e} @section Pragma Type_Invariant @@ -8531,7 +8597,7 @@ controlled by the assertion identifier @code{Type_Invariant} rather than @code{Invariant}. @node Pragma Type_Invariant_Class,Pragma Unchecked_Union,Pragma Type_Invariant,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id51}@anchor{10d}@anchor{gnat_rm/implementation_defined_pragmas pragma-type-invariant-class}@anchor{10e} +@anchor{gnat_rm/implementation_defined_pragmas id52}@anchor{10f}@anchor{gnat_rm/implementation_defined_pragmas pragma-type-invariant-class}@anchor{110} @section Pragma Type_Invariant_Class @@ -8558,7 +8624,7 @@ policy that controls this pragma is @code{Type_Invariant'Class}, not @code{Type_Invariant_Class}. @node Pragma Unchecked_Union,Pragma Unevaluated_Use_Of_Old,Pragma Type_Invariant_Class,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-unchecked-union}@anchor{10f} +@anchor{gnat_rm/implementation_defined_pragmas pragma-unchecked-union}@anchor{111} @section Pragma Unchecked_Union @@ -8578,7 +8644,7 @@ version in all language modes (Ada 83, Ada 95, and Ada 2005). For full details, consult the Ada 2012 Reference Manual, section B.3.3. @node Pragma Unevaluated_Use_Of_Old,Pragma User_Aspect_Definition,Pragma Unchecked_Union,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-unevaluated-use-of-old}@anchor{110} +@anchor{gnat_rm/implementation_defined_pragmas pragma-unevaluated-use-of-old}@anchor{112} @section Pragma Unevaluated_Use_Of_Old @@ -8633,7 +8699,7 @@ uses up to the end of the corresponding statement sequence or sequence of package declarations. @node Pragma User_Aspect_Definition,Pragma Unimplemented_Unit,Pragma Unevaluated_Use_Of_Old,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-user-aspect-definition}@anchor{111} +@anchor{gnat_rm/implementation_defined_pragmas pragma-user-aspect-definition}@anchor{113} @section Pragma User_Aspect_Definition @@ -8665,7 +8731,7 @@ pragma. If multiple definitions are visible for some aspect at some point, then the definitions must agree. A predefined aspect cannot be redefined. @node Pragma Unimplemented_Unit,Pragma Universal_Aliasing,Pragma User_Aspect_Definition,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-unimplemented-unit}@anchor{112} +@anchor{gnat_rm/implementation_defined_pragmas pragma-unimplemented-unit}@anchor{114} @section Pragma Unimplemented_Unit @@ -8685,7 +8751,7 @@ The abort only happens if code is being generated. Thus you can use specs of unimplemented packages in syntax or semantic checking mode. @node Pragma Universal_Aliasing,Pragma Unmodified,Pragma Unimplemented_Unit,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id52}@anchor{113}@anchor{gnat_rm/implementation_defined_pragmas pragma-universal-aliasing}@anchor{114} +@anchor{gnat_rm/implementation_defined_pragmas id53}@anchor{115}@anchor{gnat_rm/implementation_defined_pragmas pragma-universal-aliasing}@anchor{116} @section Pragma Universal_Aliasing @@ -8703,7 +8769,7 @@ they need to be suppressed, see the section on @code{Optimization and Strict Aliasing} in the @cite{GNAT User’s Guide}. @node Pragma Unmodified,Pragma Unreferenced,Pragma Universal_Aliasing,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id53}@anchor{115}@anchor{gnat_rm/implementation_defined_pragmas pragma-unmodified}@anchor{116} +@anchor{gnat_rm/implementation_defined_pragmas id54}@anchor{117}@anchor{gnat_rm/implementation_defined_pragmas pragma-unmodified}@anchor{118} @section Pragma Unmodified @@ -8737,7 +8803,7 @@ Thus it is never necessary to use @code{pragma Unmodified} for such variables, though it is harmless to do so. @node Pragma Unreferenced,Pragma Unreferenced_Objects,Pragma Unmodified,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id54}@anchor{117}@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced}@anchor{118} +@anchor{gnat_rm/implementation_defined_pragmas id55}@anchor{119}@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced}@anchor{11a} @section Pragma Unreferenced @@ -8799,7 +8865,7 @@ Thus it is never necessary to use @code{pragma Unreferenced} for such variables, though it is harmless to do so. @node Pragma Unreferenced_Objects,Pragma Unreserve_All_Interrupts,Pragma Unreferenced,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id55}@anchor{119}@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced-objects}@anchor{11a} +@anchor{gnat_rm/implementation_defined_pragmas id56}@anchor{11b}@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced-objects}@anchor{11c} @section Pragma Unreferenced_Objects @@ -8824,7 +8890,7 @@ compiler will automatically suppress unwanted warnings about these variables not being referenced. @node Pragma Unreserve_All_Interrupts,Pragma Unsuppress,Pragma Unreferenced_Objects,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-unreserve-all-interrupts}@anchor{11b} +@anchor{gnat_rm/implementation_defined_pragmas pragma-unreserve-all-interrupts}@anchor{11d} @section Pragma Unreserve_All_Interrupts @@ -8837,15 +8903,15 @@ pragma Unreserve_All_Interrupts; Normally certain interrupts are reserved to the implementation. Any attempt to attach an interrupt causes Program_Error to be raised, as described in RM C.3.2(22). A typical example is the @code{SIGINT} interrupt used in -many systems for a @code{Ctrl-C} interrupt. Normally this interrupt is -reserved to the implementation, so that @code{Ctrl-C} can be used to +many systems for a @code{Ctrl}-@code{C} interrupt. Normally this interrupt is +reserved to the implementation, so that @code{Ctrl}-@code{C} can be used to interrupt execution. If the pragma @code{Unreserve_All_Interrupts} appears anywhere in any unit in a program, then all such interrupts are unreserved. This allows the program to handle these interrupts, but disables their standard functions. For example, if this pragma is used, then pressing -@code{Ctrl-C} will not automatically interrupt execution. However, +@code{Ctrl}-@code{C} will not automatically interrupt execution. However, a program can then handle the @code{SIGINT} interrupt as it chooses. For a full list of the interrupts handled in a specific implementation, @@ -8860,7 +8926,7 @@ handled, see pragma @code{Interrupt_State}, which subsumes the functionality of the @code{Unreserve_All_Interrupts} pragma. @node Pragma Unsuppress,Pragma Unused,Pragma Unreserve_All_Interrupts,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-unsuppress}@anchor{11c} +@anchor{gnat_rm/implementation_defined_pragmas pragma-unsuppress}@anchor{11e} @section Pragma Unsuppress @@ -8896,7 +8962,7 @@ number of implementation-defined check names. See the description of pragma @code{Suppress} for full details. @node Pragma Unused,Pragma Use_VADS_Size,Pragma Unsuppress,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id56}@anchor{11d}@anchor{gnat_rm/implementation_defined_pragmas pragma-unused}@anchor{11e} +@anchor{gnat_rm/implementation_defined_pragmas id57}@anchor{11f}@anchor{gnat_rm/implementation_defined_pragmas pragma-unused}@anchor{120} @section Pragma Unused @@ -8930,7 +8996,7 @@ Thus it is never necessary to use @code{pragma Unused} for such variables, though it is harmless to do so. @node Pragma Use_VADS_Size,Pragma Validity_Checks,Pragma Unused,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-use-vads-size}@anchor{11f} +@anchor{gnat_rm/implementation_defined_pragmas pragma-use-vads-size}@anchor{121} @section Pragma Use_VADS_Size @@ -8954,7 +9020,7 @@ as implemented in the VADS compiler. See description of the VADS_Size attribute for further details. @node Pragma Validity_Checks,Pragma Volatile,Pragma Use_VADS_Size,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-validity-checks}@anchor{120} +@anchor{gnat_rm/implementation_defined_pragmas pragma-validity-checks}@anchor{122} @section Pragma Validity_Checks @@ -9010,7 +9076,7 @@ A := C; -- C will be validity checked @end example @node Pragma Volatile,Pragma Volatile_Full_Access,Pragma Validity_Checks,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id57}@anchor{121}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile}@anchor{122} +@anchor{gnat_rm/implementation_defined_pragmas id58}@anchor{123}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile}@anchor{124} @section Pragma Volatile @@ -9028,7 +9094,7 @@ implementation of pragma Volatile is upwards compatible with the implementation in DEC Ada 83. @node Pragma Volatile_Full_Access,Pragma Volatile_Function,Pragma Volatile,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id58}@anchor{123}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile-full-access}@anchor{124} +@anchor{gnat_rm/implementation_defined_pragmas id59}@anchor{125}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile-full-access}@anchor{126} @section Pragma Volatile_Full_Access @@ -9054,7 +9120,7 @@ is not to the whole object; the compiler is allowed (and generally will) access only part of the object in this case. @node Pragma Volatile_Function,Pragma Warning_As_Error,Pragma Volatile_Full_Access,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id59}@anchor{125}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile-function}@anchor{126} +@anchor{gnat_rm/implementation_defined_pragmas id60}@anchor{127}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile-function}@anchor{128} @section Pragma Volatile_Function @@ -9068,7 +9134,7 @@ For the semantics of this pragma, see the entry for aspect @code{Volatile_Functi in the SPARK 2014 Reference Manual, section 7.1.2. @node Pragma Warning_As_Error,Pragma Warnings,Pragma Volatile_Function,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-warning-as-error}@anchor{127} +@anchor{gnat_rm/implementation_defined_pragmas pragma-warning-as-error}@anchor{129} @section Pragma Warning_As_Error @@ -9108,7 +9174,7 @@ you can use multiple pragma Warning_As_Error. The above use of patterns to match the message applies only to warning messages generated by the front end. This pragma can also be applied to -warnings provided by the back end and mentioned in @ref{128,,Pragma Warnings}. +warnings provided by the back end and mentioned in @ref{12a,,Pragma Warnings}. By using a single full `-Wxxx' switch in the pragma, such warnings can also be treated as errors. @@ -9158,7 +9224,7 @@ the tag is changed from “warning:” to “error:” and the string “[warning-as-error]” is appended to the end of the message. @node Pragma Warnings,Pragma Weak_External,Pragma Warning_As_Error,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id60}@anchor{129}@anchor{gnat_rm/implementation_defined_pragmas pragma-warnings}@anchor{128} +@anchor{gnat_rm/implementation_defined_pragmas id61}@anchor{12b}@anchor{gnat_rm/implementation_defined_pragmas pragma-warnings}@anchor{12a} @section Pragma Warnings @@ -9314,7 +9380,7 @@ selectively for each tool, and as a consequence to detect useless pragma Warnings with switch @code{-gnatw.w}. @node Pragma Weak_External,Pragma Wide_Character_Encoding,Pragma Warnings,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-weak-external}@anchor{12a} +@anchor{gnat_rm/implementation_defined_pragmas pragma-weak-external}@anchor{12c} @section Pragma Weak_External @@ -9365,7 +9431,7 @@ end External_Module; @end example @node Pragma Wide_Character_Encoding,,Pragma Weak_External,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-wide-character-encoding}@anchor{12b} +@anchor{gnat_rm/implementation_defined_pragmas pragma-wide-character-encoding}@anchor{12d} @section Pragma Wide_Character_Encoding @@ -9396,7 +9462,7 @@ encoding within that file, and does not affect withed units, specs, or subunits. @node Implementation Defined Aspects,Implementation Defined Attributes,Implementation Defined Pragmas,Top -@anchor{gnat_rm/implementation_defined_aspects doc}@anchor{12c}@anchor{gnat_rm/implementation_defined_aspects id1}@anchor{12d}@anchor{gnat_rm/implementation_defined_aspects implementation-defined-aspects}@anchor{12e} +@anchor{gnat_rm/implementation_defined_aspects doc}@anchor{12e}@anchor{gnat_rm/implementation_defined_aspects id1}@anchor{12f}@anchor{gnat_rm/implementation_defined_aspects implementation-defined-aspects}@anchor{130} @chapter Implementation Defined Aspects @@ -9492,7 +9558,9 @@ or attribute definition clause. * Aspect Obsolescent:: * Aspect Part_Of:: * Aspect Persistent_BSS:: +* Aspect Potentially_Invalid:: * Aspect Predicate:: +* Aspect Program_Exit:: * Aspect Pure_Function:: * Aspect Refined_Depends:: * Aspect Refined_Global:: @@ -9525,7 +9593,7 @@ or attribute definition clause. @end menu @node Aspect Abstract_State,Aspect Always_Terminates,,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-abstract-state}@anchor{12f} +@anchor{gnat_rm/implementation_defined_aspects aspect-abstract-state}@anchor{131} @section Aspect Abstract_State @@ -9534,7 +9602,7 @@ or attribute definition clause. This aspect is equivalent to @ref{1e,,pragma Abstract_State}. @node Aspect Always_Terminates,Aspect Annotate,Aspect Abstract_State,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-always-terminates}@anchor{130} +@anchor{gnat_rm/implementation_defined_aspects aspect-always-terminates}@anchor{132} @section Aspect Always_Terminates @@ -9543,7 +9611,7 @@ This aspect is equivalent to @ref{1e,,pragma Abstract_State}. This boolean aspect is equivalent to @ref{29,,pragma Always_Terminates}. @node Aspect Annotate,Aspect Async_Readers,Aspect Always_Terminates,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-annotate}@anchor{131} +@anchor{gnat_rm/implementation_defined_aspects aspect-annotate}@anchor{133} @section Aspect Annotate @@ -9570,7 +9638,7 @@ Equivalent to @code{pragma Annotate (ID, ID @{, ARG@}, Entity => Name);} @end table @node Aspect Async_Readers,Aspect Async_Writers,Aspect Annotate,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-async-readers}@anchor{132} +@anchor{gnat_rm/implementation_defined_aspects aspect-async-readers}@anchor{134} @section Aspect Async_Readers @@ -9579,7 +9647,7 @@ Equivalent to @code{pragma Annotate (ID, ID @{, ARG@}, Entity => Name);} This boolean aspect is equivalent to @ref{32,,pragma Async_Readers}. @node Aspect Async_Writers,Aspect Constant_After_Elaboration,Aspect Async_Readers,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-async-writers}@anchor{133} +@anchor{gnat_rm/implementation_defined_aspects aspect-async-writers}@anchor{135} @section Aspect Async_Writers @@ -9588,7 +9656,7 @@ This boolean aspect is equivalent to @ref{32,,pragma Async_Readers}. This boolean aspect is equivalent to @ref{34,,pragma Async_Writers}. @node Aspect Constant_After_Elaboration,Aspect Contract_Cases,Aspect Async_Writers,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-constant-after-elaboration}@anchor{134} +@anchor{gnat_rm/implementation_defined_aspects aspect-constant-after-elaboration}@anchor{136} @section Aspect Constant_After_Elaboration @@ -9597,7 +9665,7 @@ This boolean aspect is equivalent to @ref{34,,pragma Async_Writers}. This aspect is equivalent to @ref{44,,pragma Constant_After_Elaboration}. @node Aspect Contract_Cases,Aspect Depends,Aspect Constant_After_Elaboration,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-contract-cases}@anchor{135} +@anchor{gnat_rm/implementation_defined_aspects aspect-contract-cases}@anchor{137} @section Aspect Contract_Cases @@ -9608,7 +9676,7 @@ of clauses being enclosed in parentheses so that syntactically it is an aggregate. @node Aspect Depends,Aspect Default_Initial_Condition,Aspect Contract_Cases,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-depends}@anchor{136} +@anchor{gnat_rm/implementation_defined_aspects aspect-depends}@anchor{138} @section Aspect Depends @@ -9617,7 +9685,7 @@ aggregate. This aspect is equivalent to @ref{56,,pragma Depends}. @node Aspect Default_Initial_Condition,Aspect Dimension,Aspect Depends,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-default-initial-condition}@anchor{137} +@anchor{gnat_rm/implementation_defined_aspects aspect-default-initial-condition}@anchor{139} @section Aspect Default_Initial_Condition @@ -9626,7 +9694,7 @@ This aspect is equivalent to @ref{56,,pragma Depends}. This aspect is equivalent to @ref{52,,pragma Default_Initial_Condition}. @node Aspect Dimension,Aspect Dimension_System,Aspect Default_Initial_Condition,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-dimension}@anchor{138} +@anchor{gnat_rm/implementation_defined_aspects aspect-dimension}@anchor{13a} @section Aspect Dimension @@ -9662,7 +9730,7 @@ Note that when the dimensioned type is an integer type, then any dimension value must be an integer literal. @node Aspect Dimension_System,Aspect Disable_Controlled,Aspect Dimension,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-dimension-system}@anchor{139} +@anchor{gnat_rm/implementation_defined_aspects aspect-dimension-system}@anchor{13b} @section Aspect Dimension_System @@ -9722,7 +9790,7 @@ See section ‘Performing Dimensionality Analysis in GNAT’ in the GNAT Users Guide for detailed examples of use of the dimension system. @node Aspect Disable_Controlled,Aspect Effective_Reads,Aspect Dimension_System,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-disable-controlled}@anchor{13a} +@anchor{gnat_rm/implementation_defined_aspects aspect-disable-controlled}@anchor{13c} @section Aspect Disable_Controlled @@ -9735,7 +9803,7 @@ where for example you might want a record to be controlled or not depending on whether some run-time check is enabled or suppressed. @node Aspect Effective_Reads,Aspect Effective_Writes,Aspect Disable_Controlled,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-effective-reads}@anchor{13b} +@anchor{gnat_rm/implementation_defined_aspects aspect-effective-reads}@anchor{13d} @section Aspect Effective_Reads @@ -9744,7 +9812,7 @@ whether some run-time check is enabled or suppressed. This aspect is equivalent to @ref{5b,,pragma Effective_Reads}. @node Aspect Effective_Writes,Aspect Exceptional_Cases,Aspect Effective_Reads,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-effective-writes}@anchor{13c} +@anchor{gnat_rm/implementation_defined_aspects aspect-effective-writes}@anchor{13e} @section Aspect Effective_Writes @@ -9753,7 +9821,7 @@ This aspect is equivalent to @ref{5b,,pragma Effective_Reads}. This aspect is equivalent to @ref{5d,,pragma Effective_Writes}. @node Aspect Exceptional_Cases,Aspect Exit_Cases,Aspect Effective_Writes,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-exceptional-cases}@anchor{13d} +@anchor{gnat_rm/implementation_defined_aspects aspect-exceptional-cases}@anchor{13f} @section Aspect Exceptional_Cases @@ -9768,7 +9836,7 @@ For the syntax and semantics of this aspect, see the SPARK 2014 Reference Manual, section 6.1.9. @node Aspect Exit_Cases,Aspect Extensions_Visible,Aspect Exceptional_Cases,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-exit-cases}@anchor{13e} +@anchor{gnat_rm/implementation_defined_aspects aspect-exit-cases}@anchor{140} @section Aspect Exit_Cases @@ -9783,7 +9851,7 @@ For the syntax and semantics of this aspect, see the SPARK 2014 Reference Manual, section 6.1.10. @node Aspect Extensions_Visible,Aspect Favor_Top_Level,Aspect Exit_Cases,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-extensions-visible}@anchor{13f} +@anchor{gnat_rm/implementation_defined_aspects aspect-extensions-visible}@anchor{141} @section Aspect Extensions_Visible @@ -9792,7 +9860,7 @@ Manual, section 6.1.10. This aspect is equivalent to @ref{6d,,pragma Extensions_Visible}. @node Aspect Favor_Top_Level,Aspect Ghost,Aspect Extensions_Visible,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-favor-top-level}@anchor{140} +@anchor{gnat_rm/implementation_defined_aspects aspect-favor-top-level}@anchor{142} @section Aspect Favor_Top_Level @@ -9801,7 +9869,7 @@ This aspect is equivalent to @ref{6d,,pragma Extensions_Visible}. This boolean aspect is equivalent to @ref{72,,pragma Favor_Top_Level}. @node Aspect Ghost,Aspect Ghost_Predicate,Aspect Favor_Top_Level,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-ghost}@anchor{141} +@anchor{gnat_rm/implementation_defined_aspects aspect-ghost}@anchor{143} @section Aspect Ghost @@ -9810,7 +9878,7 @@ This boolean aspect is equivalent to @ref{72,,pragma Favor_Top_Level}. This aspect is equivalent to @ref{76,,pragma Ghost}. @node Aspect Ghost_Predicate,Aspect Global,Aspect Ghost,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-ghost-predicate}@anchor{142} +@anchor{gnat_rm/implementation_defined_aspects aspect-ghost-predicate}@anchor{144} @section Aspect Ghost_Predicate @@ -9823,7 +9891,7 @@ For the detailed semantics of this aspect, see the entry for subtype predicates in the SPARK Reference Manual, section 3.2.4. @node Aspect Global,Aspect Initial_Condition,Aspect Ghost_Predicate,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-global}@anchor{143} +@anchor{gnat_rm/implementation_defined_aspects aspect-global}@anchor{145} @section Aspect Global @@ -9832,7 +9900,7 @@ in the SPARK Reference Manual, section 3.2.4. This aspect is equivalent to @ref{78,,pragma Global}. @node Aspect Initial_Condition,Aspect Initializes,Aspect Global,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-initial-condition}@anchor{144} +@anchor{gnat_rm/implementation_defined_aspects aspect-initial-condition}@anchor{146} @section Aspect Initial_Condition @@ -9841,7 +9909,7 @@ This aspect is equivalent to @ref{78,,pragma Global}. This aspect is equivalent to @ref{85,,pragma Initial_Condition}. @node Aspect Initializes,Aspect Inline_Always,Aspect Initial_Condition,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-initializes}@anchor{145} +@anchor{gnat_rm/implementation_defined_aspects aspect-initializes}@anchor{147} @section Aspect Initializes @@ -9850,7 +9918,7 @@ This aspect is equivalent to @ref{85,,pragma Initial_Condition}. This aspect is equivalent to @ref{88,,pragma Initializes}. @node Aspect Inline_Always,Aspect Invariant,Aspect Initializes,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-inline-always}@anchor{146} +@anchor{gnat_rm/implementation_defined_aspects aspect-inline-always}@anchor{148} @section Aspect Inline_Always @@ -9859,7 +9927,7 @@ This aspect is equivalent to @ref{88,,pragma Initializes}. This boolean aspect is equivalent to @ref{8a,,pragma Inline_Always}. @node Aspect Invariant,Aspect Invariant’Class,Aspect Inline_Always,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-invariant}@anchor{147} +@anchor{gnat_rm/implementation_defined_aspects aspect-invariant}@anchor{149} @section Aspect Invariant @@ -9870,18 +9938,18 @@ synonym for the language defined aspect @code{Type_Invariant} except that it is separately controllable using pragma @code{Assertion_Policy}. @node Aspect Invariant’Class,Aspect Iterable,Aspect Invariant,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-invariant-class}@anchor{148} +@anchor{gnat_rm/implementation_defined_aspects aspect-invariant-class}@anchor{14a} @section Aspect Invariant’Class @geindex Invariant'Class -This aspect is equivalent to @ref{10e,,pragma Type_Invariant_Class}. It is a +This aspect is equivalent to @ref{110,,pragma Type_Invariant_Class}. It is a synonym for the language defined aspect @code{Type_Invariant'Class} except that it is separately controllable using pragma @code{Assertion_Policy}. @node Aspect Iterable,Aspect Linker_Section,Aspect Invariant’Class,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-iterable}@anchor{149} +@anchor{gnat_rm/implementation_defined_aspects aspect-iterable}@anchor{14b} @section Aspect Iterable @@ -9965,7 +10033,7 @@ function Get_Element (Cont : Container; Position : Cursor) return Element_Type; This aspect is used in the GNAT-defined formal container packages. @node Aspect Linker_Section,Aspect Local_Restrictions,Aspect Iterable,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-linker-section}@anchor{14a} +@anchor{gnat_rm/implementation_defined_aspects aspect-linker-section}@anchor{14c} @section Aspect Linker_Section @@ -9974,7 +10042,7 @@ This aspect is used in the GNAT-defined formal container packages. This aspect is equivalent to @ref{9a,,pragma Linker_Section}. @node Aspect Local_Restrictions,Aspect Lock_Free,Aspect Linker_Section,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-local-restrictions}@anchor{14b} +@anchor{gnat_rm/implementation_defined_aspects aspect-local-restrictions}@anchor{14d} @section Aspect Local_Restrictions @@ -10028,7 +10096,7 @@ case of a declaration that occurs within nested packages that each have a Local_Restrictions specification). @node Aspect Lock_Free,Aspect Max_Queue_Length,Aspect Local_Restrictions,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-lock-free}@anchor{14c} +@anchor{gnat_rm/implementation_defined_aspects aspect-lock-free}@anchor{14e} @section Aspect Lock_Free @@ -10037,7 +10105,7 @@ a Local_Restrictions specification). This boolean aspect is equivalent to @ref{9c,,pragma Lock_Free}. @node Aspect Max_Queue_Length,Aspect No_Caching,Aspect Lock_Free,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-max-queue-length}@anchor{14d} +@anchor{gnat_rm/implementation_defined_aspects aspect-max-queue-length}@anchor{14f} @section Aspect Max_Queue_Length @@ -10046,7 +10114,7 @@ This boolean aspect is equivalent to @ref{9c,,pragma Lock_Free}. This aspect is equivalent to @ref{a4,,pragma Max_Queue_Length}. @node Aspect No_Caching,Aspect No_Elaboration_Code_All,Aspect Max_Queue_Length,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-no-caching}@anchor{14e} +@anchor{gnat_rm/implementation_defined_aspects aspect-no-caching}@anchor{150} @section Aspect No_Caching @@ -10055,7 +10123,7 @@ This aspect is equivalent to @ref{a4,,pragma Max_Queue_Length}. This boolean aspect is equivalent to @ref{a7,,pragma No_Caching}. @node Aspect No_Elaboration_Code_All,Aspect No_Inline,Aspect No_Caching,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-no-elaboration-code-all}@anchor{14f} +@anchor{gnat_rm/implementation_defined_aspects aspect-no-elaboration-code-all}@anchor{151} @section Aspect No_Elaboration_Code_All @@ -10065,7 +10133,7 @@ This aspect is equivalent to @ref{aa,,pragma No_Elaboration_Code_All} for a program unit. @node Aspect No_Inline,Aspect No_Raise,Aspect No_Elaboration_Code_All,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-no-inline}@anchor{150} +@anchor{gnat_rm/implementation_defined_aspects aspect-no-inline}@anchor{152} @section Aspect No_Inline @@ -10074,7 +10142,7 @@ for a program unit. This boolean aspect is equivalent to @ref{ad,,pragma No_Inline}. @node Aspect No_Raise,Aspect No_Tagged_Streams,Aspect No_Inline,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-no-raise}@anchor{151} +@anchor{gnat_rm/implementation_defined_aspects aspect-no-raise}@anchor{153} @section Aspect No_Raise @@ -10083,7 +10151,7 @@ This boolean aspect is equivalent to @ref{ad,,pragma No_Inline}. This boolean aspect is equivalent to @ref{af,,pragma No_Raise}. @node Aspect No_Tagged_Streams,Aspect No_Task_Parts,Aspect No_Raise,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-no-tagged-streams}@anchor{152} +@anchor{gnat_rm/implementation_defined_aspects aspect-no-tagged-streams}@anchor{154} @section Aspect No_Tagged_Streams @@ -10094,7 +10162,7 @@ argument specifying a root tagged type (thus this aspect can only be applied to such a type). @node Aspect No_Task_Parts,Aspect Object_Size,Aspect No_Tagged_Streams,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-no-task-parts}@anchor{153} +@anchor{gnat_rm/implementation_defined_aspects aspect-no-task-parts}@anchor{155} @section Aspect No_Task_Parts @@ -10110,16 +10178,16 @@ away certain tasking-related code that would otherwise be needed for T’Class, because descendants of T might contain tasks. @node Aspect Object_Size,Aspect Obsolescent,Aspect No_Task_Parts,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-object-size}@anchor{154} +@anchor{gnat_rm/implementation_defined_aspects aspect-object-size}@anchor{156} @section Aspect Object_Size @geindex Object_Size -This aspect is equivalent to @ref{155,,attribute Object_Size}. +This aspect is equivalent to @ref{157,,attribute Object_Size}. @node Aspect Obsolescent,Aspect Part_Of,Aspect Object_Size,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-obsolescent}@anchor{156} +@anchor{gnat_rm/implementation_defined_aspects aspect-obsolescent}@anchor{158} @section Aspect Obsolescent @@ -10130,7 +10198,7 @@ evaluation of this aspect happens at the point of occurrence, it is not delayed until the freeze point. @node Aspect Part_Of,Aspect Persistent_BSS,Aspect Obsolescent,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-part-of}@anchor{157} +@anchor{gnat_rm/implementation_defined_aspects aspect-part-of}@anchor{159} @section Aspect Part_Of @@ -10138,8 +10206,8 @@ delayed until the freeze point. This aspect is equivalent to @ref{bc,,pragma Part_Of}. -@node Aspect Persistent_BSS,Aspect Predicate,Aspect Part_Of,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-persistent-bss}@anchor{158} +@node Aspect Persistent_BSS,Aspect Potentially_Invalid,Aspect Part_Of,Implementation Defined Aspects +@anchor{gnat_rm/implementation_defined_aspects aspect-persistent-bss}@anchor{15a} @section Aspect Persistent_BSS @@ -10147,8 +10215,18 @@ This aspect is equivalent to @ref{bc,,pragma Part_Of}. This boolean aspect is equivalent to @ref{c0,,pragma Persistent_BSS}. -@node Aspect Predicate,Aspect Pure_Function,Aspect Persistent_BSS,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-predicate}@anchor{159} +@node Aspect Potentially_Invalid,Aspect Predicate,Aspect Persistent_BSS,Implementation Defined Aspects +@anchor{gnat_rm/implementation_defined_aspects aspect-potentially-invalid}@anchor{15b} +@section Aspect Potentially_Invalid + + +@geindex Potentially_Invalid + +For the syntax and semantics of this aspect, see the SPARK 2014 Reference +Manual, section 13.9.1. + +@node Aspect Predicate,Aspect Program_Exit,Aspect Potentially_Invalid,Implementation Defined Aspects +@anchor{gnat_rm/implementation_defined_aspects aspect-predicate}@anchor{15c} @section Aspect Predicate @@ -10161,53 +10239,62 @@ predicate is static or dynamic is controlled by the form of the expression. It is also separately controllable using pragma @code{Assertion_Policy}. -@node Aspect Pure_Function,Aspect Refined_Depends,Aspect Predicate,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-pure-function}@anchor{15a} +@node Aspect Program_Exit,Aspect Pure_Function,Aspect Predicate,Implementation Defined Aspects +@anchor{gnat_rm/implementation_defined_aspects aspect-program-exit}@anchor{15d} +@section Aspect Program_Exit + + +@geindex Program_Exit + +This boolean aspect is equivalent to @ref{d0,,pragma Program_Exit}. + +@node Aspect Pure_Function,Aspect Refined_Depends,Aspect Program_Exit,Implementation Defined Aspects +@anchor{gnat_rm/implementation_defined_aspects aspect-pure-function}@anchor{15e} @section Aspect Pure_Function @geindex Pure_Function -This boolean aspect is equivalent to @ref{d3,,pragma Pure_Function}. +This boolean aspect is equivalent to @ref{d5,,pragma Pure_Function}. @node Aspect Refined_Depends,Aspect Refined_Global,Aspect Pure_Function,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-refined-depends}@anchor{15b} +@anchor{gnat_rm/implementation_defined_aspects aspect-refined-depends}@anchor{15f} @section Aspect Refined_Depends @geindex Refined_Depends -This aspect is equivalent to @ref{d7,,pragma Refined_Depends}. +This aspect is equivalent to @ref{d9,,pragma Refined_Depends}. @node Aspect Refined_Global,Aspect Refined_Post,Aspect Refined_Depends,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-refined-global}@anchor{15c} +@anchor{gnat_rm/implementation_defined_aspects aspect-refined-global}@anchor{160} @section Aspect Refined_Global @geindex Refined_Global -This aspect is equivalent to @ref{d9,,pragma Refined_Global}. +This aspect is equivalent to @ref{db,,pragma Refined_Global}. @node Aspect Refined_Post,Aspect Refined_State,Aspect Refined_Global,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-refined-post}@anchor{15d} +@anchor{gnat_rm/implementation_defined_aspects aspect-refined-post}@anchor{161} @section Aspect Refined_Post @geindex Refined_Post -This aspect is equivalent to @ref{db,,pragma Refined_Post}. +This aspect is equivalent to @ref{dd,,pragma Refined_Post}. @node Aspect Refined_State,Aspect Relaxed_Initialization,Aspect Refined_Post,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-refined-state}@anchor{15e} +@anchor{gnat_rm/implementation_defined_aspects aspect-refined-state}@anchor{162} @section Aspect Refined_State @geindex Refined_State -This aspect is equivalent to @ref{dd,,pragma Refined_State}. +This aspect is equivalent to @ref{df,,pragma Refined_State}. @node Aspect Relaxed_Initialization,Aspect Remote_Access_Type,Aspect Refined_State,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-relaxed-initialization}@anchor{15f} +@anchor{gnat_rm/implementation_defined_aspects aspect-relaxed-initialization}@anchor{163} @section Aspect Relaxed_Initialization @@ -10217,82 +10304,82 @@ For the syntax and semantics of this aspect, see the SPARK 2014 Reference Manual, section 6.10. @node Aspect Remote_Access_Type,Aspect Scalar_Storage_Order,Aspect Relaxed_Initialization,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-remote-access-type}@anchor{160} +@anchor{gnat_rm/implementation_defined_aspects aspect-remote-access-type}@anchor{164} @section Aspect Remote_Access_Type @geindex Remote_Access_Type -This aspect is equivalent to @ref{e0,,pragma Remote_Access_Type}. +This aspect is equivalent to @ref{e2,,pragma Remote_Access_Type}. @node Aspect Scalar_Storage_Order,Aspect Secondary_Stack_Size,Aspect Remote_Access_Type,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-scalar-storage-order}@anchor{161} +@anchor{gnat_rm/implementation_defined_aspects aspect-scalar-storage-order}@anchor{165} @section Aspect Scalar_Storage_Order @geindex Scalar_Storage_Order -This aspect is equivalent to a @ref{162,,attribute Scalar_Storage_Order}. +This aspect is equivalent to a @ref{166,,attribute Scalar_Storage_Order}. @node Aspect Secondary_Stack_Size,Aspect Shared,Aspect Scalar_Storage_Order,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-secondary-stack-size}@anchor{163} +@anchor{gnat_rm/implementation_defined_aspects aspect-secondary-stack-size}@anchor{167} @section Aspect Secondary_Stack_Size @geindex Secondary_Stack_Size -This aspect is equivalent to @ref{e6,,pragma Secondary_Stack_Size}. +This aspect is equivalent to @ref{e8,,pragma Secondary_Stack_Size}. @node Aspect Shared,Aspect Side_Effects,Aspect Secondary_Stack_Size,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-shared}@anchor{164} +@anchor{gnat_rm/implementation_defined_aspects aspect-shared}@anchor{168} @section Aspect Shared @geindex Shared -This boolean aspect is equivalent to @ref{e9,,pragma Shared} +This boolean aspect is equivalent to @ref{eb,,pragma Shared} and is thus a synonym for aspect @code{Atomic}. @node Aspect Side_Effects,Aspect Simple_Storage_Pool,Aspect Shared,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-side-effects}@anchor{165} +@anchor{gnat_rm/implementation_defined_aspects aspect-side-effects}@anchor{169} @section Aspect Side_Effects @geindex Side_Effects -This aspect is equivalent to @ref{ed,,pragma Side_Effects}. +This aspect is equivalent to @ref{ef,,pragma Side_Effects}. @node Aspect Simple_Storage_Pool,Aspect Simple_Storage_Pool_Type,Aspect Side_Effects,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-simple-storage-pool}@anchor{166} +@anchor{gnat_rm/implementation_defined_aspects aspect-simple-storage-pool}@anchor{16a} @section Aspect Simple_Storage_Pool @geindex Simple_Storage_Pool -This aspect is equivalent to @ref{f0,,attribute Simple_Storage_Pool}. +This aspect is equivalent to @ref{f2,,attribute Simple_Storage_Pool}. @node Aspect Simple_Storage_Pool_Type,Aspect SPARK_Mode,Aspect Simple_Storage_Pool,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-simple-storage-pool-type}@anchor{167} +@anchor{gnat_rm/implementation_defined_aspects aspect-simple-storage-pool-type}@anchor{16b} @section Aspect Simple_Storage_Pool_Type @geindex Simple_Storage_Pool_Type -This boolean aspect is equivalent to @ref{ef,,pragma Simple_Storage_Pool_Type}. +This boolean aspect is equivalent to @ref{f1,,pragma Simple_Storage_Pool_Type}. @node Aspect SPARK_Mode,Aspect Subprogram_Variant,Aspect Simple_Storage_Pool_Type,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-spark-mode}@anchor{168} +@anchor{gnat_rm/implementation_defined_aspects aspect-spark-mode}@anchor{16c} @section Aspect SPARK_Mode @geindex SPARK_Mode -This aspect is equivalent to @ref{f7,,pragma SPARK_Mode} and +This aspect is equivalent to @ref{f9,,pragma SPARK_Mode} and may be specified for either or both of the specification and body of a subprogram or package. @node Aspect Subprogram_Variant,Aspect Suppress_Debug_Info,Aspect SPARK_Mode,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-subprogram-variant}@anchor{169} +@anchor{gnat_rm/implementation_defined_aspects aspect-subprogram-variant}@anchor{16d} @section Aspect Subprogram_Variant @@ -10302,83 +10389,83 @@ For the syntax and semantics of this aspect, see the SPARK 2014 Reference Manual, section 6.1.8. @node Aspect Suppress_Debug_Info,Aspect Suppress_Initialization,Aspect Subprogram_Variant,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-suppress-debug-info}@anchor{16a} +@anchor{gnat_rm/implementation_defined_aspects aspect-suppress-debug-info}@anchor{16e} @section Aspect Suppress_Debug_Info @geindex Suppress_Debug_Info -This boolean aspect is equivalent to @ref{100,,pragma Suppress_Debug_Info}. +This boolean aspect is equivalent to @ref{102,,pragma Suppress_Debug_Info}. @node Aspect Suppress_Initialization,Aspect Test_Case,Aspect Suppress_Debug_Info,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-suppress-initialization}@anchor{16b} +@anchor{gnat_rm/implementation_defined_aspects aspect-suppress-initialization}@anchor{16f} @section Aspect Suppress_Initialization @geindex Suppress_Initialization -This boolean aspect is equivalent to @ref{103,,pragma Suppress_Initialization}. +This boolean aspect is equivalent to @ref{105,,pragma Suppress_Initialization}. @node Aspect Test_Case,Aspect Thread_Local_Storage,Aspect Suppress_Initialization,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-test-case}@anchor{16c} +@anchor{gnat_rm/implementation_defined_aspects aspect-test-case}@anchor{170} @section Aspect Test_Case @geindex Test_Case -This aspect is equivalent to @ref{107,,pragma Test_Case}. +This aspect is equivalent to @ref{109,,pragma Test_Case}. @node Aspect Thread_Local_Storage,Aspect Universal_Aliasing,Aspect Test_Case,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-thread-local-storage}@anchor{16d} +@anchor{gnat_rm/implementation_defined_aspects aspect-thread-local-storage}@anchor{171} @section Aspect Thread_Local_Storage @geindex Thread_Local_Storage -This boolean aspect is equivalent to @ref{109,,pragma Thread_Local_Storage}. +This boolean aspect is equivalent to @ref{10b,,pragma Thread_Local_Storage}. @node Aspect Universal_Aliasing,Aspect Unmodified,Aspect Thread_Local_Storage,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-universal-aliasing}@anchor{16e} +@anchor{gnat_rm/implementation_defined_aspects aspect-universal-aliasing}@anchor{172} @section Aspect Universal_Aliasing @geindex Universal_Aliasing -This boolean aspect is equivalent to @ref{114,,pragma Universal_Aliasing}. +This boolean aspect is equivalent to @ref{116,,pragma Universal_Aliasing}. @node Aspect Unmodified,Aspect Unreferenced,Aspect Universal_Aliasing,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-unmodified}@anchor{16f} +@anchor{gnat_rm/implementation_defined_aspects aspect-unmodified}@anchor{173} @section Aspect Unmodified @geindex Unmodified -This boolean aspect is equivalent to @ref{116,,pragma Unmodified}. +This boolean aspect is equivalent to @ref{118,,pragma Unmodified}. @node Aspect Unreferenced,Aspect Unreferenced_Objects,Aspect Unmodified,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-unreferenced}@anchor{170} +@anchor{gnat_rm/implementation_defined_aspects aspect-unreferenced}@anchor{174} @section Aspect Unreferenced @geindex Unreferenced -This boolean aspect is equivalent to @ref{118,,pragma Unreferenced}. +This boolean aspect is equivalent to @ref{11a,,pragma Unreferenced}. When using the @code{-gnat2022} switch, this aspect is also supported on formal parameters, which is in particular the only form possible for expression functions. @node Aspect Unreferenced_Objects,Aspect User_Aspect,Aspect Unreferenced,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-unreferenced-objects}@anchor{171} +@anchor{gnat_rm/implementation_defined_aspects aspect-unreferenced-objects}@anchor{175} @section Aspect Unreferenced_Objects @geindex Unreferenced_Objects -This boolean aspect is equivalent to @ref{11a,,pragma Unreferenced_Objects}. +This boolean aspect is equivalent to @ref{11c,,pragma Unreferenced_Objects}. @node Aspect User_Aspect,Aspect Value_Size,Aspect Unreferenced_Objects,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-user-aspect}@anchor{172} +@anchor{gnat_rm/implementation_defined_aspects aspect-user-aspect}@anchor{176} @section Aspect User_Aspect @@ -10391,45 +10478,45 @@ replicating the set of aspect specifications associated with the named pragma-defined aspect. @node Aspect Value_Size,Aspect Volatile_Full_Access,Aspect User_Aspect,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-value-size}@anchor{173} +@anchor{gnat_rm/implementation_defined_aspects aspect-value-size}@anchor{177} @section Aspect Value_Size @geindex Value_Size -This aspect is equivalent to @ref{174,,attribute Value_Size}. +This aspect is equivalent to @ref{178,,attribute Value_Size}. @node Aspect Volatile_Full_Access,Aspect Volatile_Function,Aspect Value_Size,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-volatile-full-access}@anchor{175} +@anchor{gnat_rm/implementation_defined_aspects aspect-volatile-full-access}@anchor{179} @section Aspect Volatile_Full_Access @geindex Volatile_Full_Access -This boolean aspect is equivalent to @ref{124,,pragma Volatile_Full_Access}. +This boolean aspect is equivalent to @ref{126,,pragma Volatile_Full_Access}. @node Aspect Volatile_Function,Aspect Warnings,Aspect Volatile_Full_Access,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-volatile-function}@anchor{176} +@anchor{gnat_rm/implementation_defined_aspects aspect-volatile-function}@anchor{17a} @section Aspect Volatile_Function @geindex Volatile_Function -This boolean aspect is equivalent to @ref{126,,pragma Volatile_Function}. +This boolean aspect is equivalent to @ref{128,,pragma Volatile_Function}. @node Aspect Warnings,,Aspect Volatile_Function,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-warnings}@anchor{177} +@anchor{gnat_rm/implementation_defined_aspects aspect-warnings}@anchor{17b} @section Aspect Warnings @geindex Warnings -This aspect is equivalent to the two argument form of @ref{128,,pragma Warnings}, +This aspect is equivalent to the two argument form of @ref{12a,,pragma Warnings}, where the first argument is @code{ON} or @code{OFF} and the second argument is the entity. @node Implementation Defined Attributes,Standard and Implementation Defined Restrictions,Implementation Defined Aspects,Top -@anchor{gnat_rm/implementation_defined_attributes doc}@anchor{178}@anchor{gnat_rm/implementation_defined_attributes id1}@anchor{179}@anchor{gnat_rm/implementation_defined_attributes implementation-defined-attributes}@anchor{8} +@anchor{gnat_rm/implementation_defined_attributes doc}@anchor{17c}@anchor{gnat_rm/implementation_defined_attributes id1}@anchor{17d}@anchor{gnat_rm/implementation_defined_attributes implementation-defined-attributes}@anchor{8} @chapter Implementation Defined Attributes @@ -10535,7 +10622,7 @@ consideration, you should minimize the use of these attributes. @end menu @node Attribute Abort_Signal,Attribute Address_Size,,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-abort-signal}@anchor{17a} +@anchor{gnat_rm/implementation_defined_attributes attribute-abort-signal}@anchor{17e} @section Attribute Abort_Signal @@ -10549,7 +10636,7 @@ completely outside the normal semantics of Ada, for a user program to intercept the abort exception). @node Attribute Address_Size,Attribute Asm_Input,Attribute Abort_Signal,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-address-size}@anchor{17b} +@anchor{gnat_rm/implementation_defined_attributes attribute-address-size}@anchor{17f} @section Attribute Address_Size @@ -10565,7 +10652,7 @@ reference to System.Address’Size is nonstatic because Address is a private type. @node Attribute Asm_Input,Attribute Asm_Output,Attribute Address_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-asm-input}@anchor{17c} +@anchor{gnat_rm/implementation_defined_attributes attribute-asm-input}@anchor{180} @section Attribute Asm_Input @@ -10579,10 +10666,10 @@ to be a static expression, and is the constraint for the parameter, value to be used as the input argument. The possible values for the constant are the same as those used in the RTL, and are dependent on the configuration file used to built the GCC back end. -@ref{17d,,Machine Code Insertions} +@ref{181,,Machine Code Insertions} @node Attribute Asm_Output,Attribute Atomic_Always_Lock_Free,Attribute Asm_Input,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-asm-output}@anchor{17e} +@anchor{gnat_rm/implementation_defined_attributes attribute-asm-output}@anchor{182} @section Attribute Asm_Output @@ -10598,10 +10685,10 @@ result. The possible values for constraint are the same as those used in the RTL, and are dependent on the configuration file used to build the GCC back end. If there are no output operands, then this argument may either be omitted, or explicitly given as @code{No_Output_Operands}. -@ref{17d,,Machine Code Insertions} +@ref{181,,Machine Code Insertions} @node Attribute Atomic_Always_Lock_Free,Attribute Bit,Attribute Asm_Output,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-atomic-always-lock-free}@anchor{17f} +@anchor{gnat_rm/implementation_defined_attributes attribute-atomic-always-lock-free}@anchor{183} @section Attribute Atomic_Always_Lock_Free @@ -10612,7 +10699,7 @@ result indicates whether atomic operations are supported by the target for the given type. @node Attribute Bit,Attribute Bit_Position,Attribute Atomic_Always_Lock_Free,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-bit}@anchor{180} +@anchor{gnat_rm/implementation_defined_attributes attribute-bit}@anchor{184} @section Attribute Bit @@ -10643,7 +10730,7 @@ This attribute is designed to be compatible with the DEC Ada 83 definition and implementation of the @code{Bit} attribute. @node Attribute Bit_Position,Attribute Code_Address,Attribute Bit,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-bit-position}@anchor{181} +@anchor{gnat_rm/implementation_defined_attributes attribute-bit-position}@anchor{185} @section Attribute Bit_Position @@ -10658,7 +10745,7 @@ type `universal_integer'. The value depends only on the field the containing record @code{R}. @node Attribute Code_Address,Attribute Compiler_Version,Attribute Bit_Position,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-code-address}@anchor{182} +@anchor{gnat_rm/implementation_defined_attributes attribute-code-address}@anchor{186} @section Attribute Code_Address @@ -10701,7 +10788,7 @@ the same value as is returned by the corresponding @code{'Address} attribute. @node Attribute Compiler_Version,Attribute Constrained,Attribute Code_Address,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-compiler-version}@anchor{183} +@anchor{gnat_rm/implementation_defined_attributes attribute-compiler-version}@anchor{187} @section Attribute Compiler_Version @@ -10712,7 +10799,7 @@ prefix) yields a static string identifying the version of the compiler being used to compile the unit containing the attribute reference. @node Attribute Constrained,Attribute Default_Bit_Order,Attribute Compiler_Version,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-constrained}@anchor{184} +@anchor{gnat_rm/implementation_defined_attributes attribute-constrained}@anchor{188} @section Attribute Constrained @@ -10727,7 +10814,7 @@ record type without discriminants is always @code{True}. This usage is compatible with older Ada compilers, including notably DEC Ada. @node Attribute Default_Bit_Order,Attribute Default_Scalar_Storage_Order,Attribute Constrained,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-default-bit-order}@anchor{185} +@anchor{gnat_rm/implementation_defined_attributes attribute-default-bit-order}@anchor{189} @section Attribute Default_Bit_Order @@ -10744,7 +10831,7 @@ as a @code{Pos} value (0 for @code{High_Order_First}, 1 for @code{Default_Bit_Order} in package @code{System}. @node Attribute Default_Scalar_Storage_Order,Attribute Deref,Attribute Default_Bit_Order,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-default-scalar-storage-order}@anchor{186} +@anchor{gnat_rm/implementation_defined_attributes attribute-default-scalar-storage-order}@anchor{18a} @section Attribute Default_Scalar_Storage_Order @@ -10761,7 +10848,7 @@ equal to @code{Default_Bit_Order} if unspecified) as a @code{System.Bit_Order} value. This is a static attribute. @node Attribute Deref,Attribute Descriptor_Size,Attribute Default_Scalar_Storage_Order,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-deref}@anchor{187} +@anchor{gnat_rm/implementation_defined_attributes attribute-deref}@anchor{18b} @section Attribute Deref @@ -10774,7 +10861,7 @@ a named access-to-@cite{typ} type, except that it yields a variable, so it can b used on the left side of an assignment. @node Attribute Descriptor_Size,Attribute Elaborated,Attribute Deref,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-descriptor-size}@anchor{188} +@anchor{gnat_rm/implementation_defined_attributes attribute-descriptor-size}@anchor{18c} @section Attribute Descriptor_Size @@ -10803,7 +10890,7 @@ since @code{Positive} has an alignment of 4, the size of the descriptor is which yields a size of 32 bits, i.e. including 16 bits of padding. @node Attribute Elaborated,Attribute Elab_Body,Attribute Descriptor_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-elaborated}@anchor{189} +@anchor{gnat_rm/implementation_defined_attributes attribute-elaborated}@anchor{18d} @section Attribute Elaborated @@ -10818,7 +10905,7 @@ units has been completed. An exception is for units which need no elaboration, the value is always False for such units. @node Attribute Elab_Body,Attribute Elab_Spec,Attribute Elaborated,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-elab-body}@anchor{18a} +@anchor{gnat_rm/implementation_defined_attributes attribute-elab-body}@anchor{18e} @section Attribute Elab_Body @@ -10834,7 +10921,7 @@ e.g., if it is necessary to do selective re-elaboration to fix some error. @node Attribute Elab_Spec,Attribute Elab_Subp_Body,Attribute Elab_Body,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-elab-spec}@anchor{18b} +@anchor{gnat_rm/implementation_defined_attributes attribute-elab-spec}@anchor{18f} @section Attribute Elab_Spec @@ -10850,7 +10937,7 @@ Ada code, e.g., if it is necessary to do selective re-elaboration to fix some error. @node Attribute Elab_Subp_Body,Attribute Emax,Attribute Elab_Spec,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-elab-subp-body}@anchor{18c} +@anchor{gnat_rm/implementation_defined_attributes attribute-elab-subp-body}@anchor{190} @section Attribute Elab_Subp_Body @@ -10864,7 +10951,7 @@ elaboration procedure by the binder in CodePeer mode only and is unrecognized otherwise. @node Attribute Emax,Attribute Enabled,Attribute Elab_Subp_Body,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-emax}@anchor{18d} +@anchor{gnat_rm/implementation_defined_attributes attribute-emax}@anchor{191} @section Attribute Emax @@ -10877,7 +10964,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute. @node Attribute Enabled,Attribute Enum_Rep,Attribute Emax,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-enabled}@anchor{18e} +@anchor{gnat_rm/implementation_defined_attributes attribute-enabled}@anchor{192} @section Attribute Enabled @@ -10901,7 +10988,7 @@ a @code{pragma Suppress} or @code{pragma Unsuppress} before instantiating the package or subprogram, controlling whether the check will be present. @node Attribute Enum_Rep,Attribute Enum_Val,Attribute Enabled,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-enum-rep}@anchor{18f} +@anchor{gnat_rm/implementation_defined_attributes attribute-enum-rep}@anchor{193} @section Attribute Enum_Rep @@ -10941,7 +11028,7 @@ integer calculation is done at run time, then the call to @code{Enum_Rep} may raise @code{Constraint_Error}. @node Attribute Enum_Val,Attribute Epsilon,Attribute Enum_Rep,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-enum-val}@anchor{190} +@anchor{gnat_rm/implementation_defined_attributes attribute-enum-val}@anchor{194} @section Attribute Enum_Val @@ -10967,7 +11054,7 @@ absence of an enumeration representation clause. This is a static attribute (i.e., the result is static if the argument is static). @node Attribute Epsilon,Attribute Fast_Math,Attribute Enum_Val,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-epsilon}@anchor{191} +@anchor{gnat_rm/implementation_defined_attributes attribute-epsilon}@anchor{195} @section Attribute Epsilon @@ -10980,7 +11067,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute. @node Attribute Fast_Math,Attribute Finalization_Size,Attribute Epsilon,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-fast-math}@anchor{192} +@anchor{gnat_rm/implementation_defined_attributes attribute-fast-math}@anchor{196} @section Attribute Fast_Math @@ -10991,7 +11078,7 @@ prefix) yields a static Boolean value that is True if pragma @code{Fast_Math} is active, and False otherwise. @node Attribute Finalization_Size,Attribute Fixed_Value,Attribute Fast_Math,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-finalization-size}@anchor{193} +@anchor{gnat_rm/implementation_defined_attributes attribute-finalization-size}@anchor{197} @section Attribute Finalization_Size @@ -11009,7 +11096,7 @@ class-wide type whose tag denotes a type with no controlled parts. Note that only heap-allocated objects contain finalization data. @node Attribute Fixed_Value,Attribute From_Any,Attribute Finalization_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-fixed-value}@anchor{194} +@anchor{gnat_rm/implementation_defined_attributes attribute-fixed-value}@anchor{198} @section Attribute Fixed_Value @@ -11036,7 +11123,7 @@ This attribute is primarily intended for use in implementation of the input-output functions for fixed-point values. @node Attribute From_Any,Attribute Has_Access_Values,Attribute Fixed_Value,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-from-any}@anchor{195} +@anchor{gnat_rm/implementation_defined_attributes attribute-from-any}@anchor{199} @section Attribute From_Any @@ -11046,7 +11133,7 @@ This internal attribute is used for the generation of remote subprogram stubs in the context of the Distributed Systems Annex. @node Attribute Has_Access_Values,Attribute Has_Discriminants,Attribute From_Any,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-has-access-values}@anchor{196} +@anchor{gnat_rm/implementation_defined_attributes attribute-has-access-values}@anchor{19a} @section Attribute Has_Access_Values @@ -11064,7 +11151,7 @@ definitions. If the attribute is applied to a generic private type, it indicates whether or not the corresponding actual type has access values. @node Attribute Has_Discriminants,Attribute Has_Tagged_Values,Attribute Has_Access_Values,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-has-discriminants}@anchor{197} +@anchor{gnat_rm/implementation_defined_attributes attribute-has-discriminants}@anchor{19b} @section Attribute Has_Discriminants @@ -11080,7 +11167,7 @@ definitions. If the attribute is applied to a generic private type, it indicates whether or not the corresponding actual type has discriminants. @node Attribute Has_Tagged_Values,Attribute Img,Attribute Has_Discriminants,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-has-tagged-values}@anchor{198} +@anchor{gnat_rm/implementation_defined_attributes attribute-has-tagged-values}@anchor{19c} @section Attribute Has_Tagged_Values @@ -11097,7 +11184,7 @@ definitions. If the attribute is applied to a generic private type, it indicates whether or not the corresponding actual type has access values. @node Attribute Img,Attribute Initialized,Attribute Has_Tagged_Values,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-img}@anchor{199} +@anchor{gnat_rm/implementation_defined_attributes attribute-img}@anchor{19d} @section Attribute Img @@ -11127,7 +11214,7 @@ that returns the appropriate string when called. This means that in an instantiation as a function parameter. @node Attribute Initialized,Attribute Integer_Value,Attribute Img,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-initialized}@anchor{19a} +@anchor{gnat_rm/implementation_defined_attributes attribute-initialized}@anchor{19e} @section Attribute Initialized @@ -11137,7 +11224,7 @@ For the syntax and semantics of this attribute, see the SPARK 2014 Reference Manual, section 6.10. @node Attribute Integer_Value,Attribute Invalid_Value,Attribute Initialized,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-integer-value}@anchor{19b} +@anchor{gnat_rm/implementation_defined_attributes attribute-integer-value}@anchor{19f} @section Attribute Integer_Value @@ -11165,7 +11252,7 @@ This attribute is primarily intended for use in implementation of the standard input-output functions for fixed-point values. @node Attribute Invalid_Value,Attribute Large,Attribute Integer_Value,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-invalid-value}@anchor{19c} +@anchor{gnat_rm/implementation_defined_attributes attribute-invalid-value}@anchor{1a0} @section Attribute Invalid_Value @@ -11179,7 +11266,7 @@ including the ability to modify the value with the binder -Sxx flag and relevant environment variables at run time. @node Attribute Large,Attribute Library_Level,Attribute Invalid_Value,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-large}@anchor{19d} +@anchor{gnat_rm/implementation_defined_attributes attribute-large}@anchor{1a1} @section Attribute Large @@ -11192,7 +11279,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute. @node Attribute Library_Level,Attribute Loop_Entry,Attribute Large,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-library-level}@anchor{19e} +@anchor{gnat_rm/implementation_defined_attributes attribute-library-level}@anchor{1a2} @section Attribute Library_Level @@ -11218,7 +11305,7 @@ end Gen; @end example @node Attribute Loop_Entry,Attribute Machine_Size,Attribute Library_Level,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-loop-entry}@anchor{19f} +@anchor{gnat_rm/implementation_defined_attributes attribute-loop-entry}@anchor{1a3} @section Attribute Loop_Entry @@ -11251,7 +11338,7 @@ entry. This copy is not performed if the loop is not entered, or if the corresponding pragmas are ignored or disabled. @node Attribute Machine_Size,Attribute Mantissa,Attribute Loop_Entry,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-machine-size}@anchor{1a0} +@anchor{gnat_rm/implementation_defined_attributes attribute-machine-size}@anchor{1a4} @section Attribute Machine_Size @@ -11261,7 +11348,7 @@ This attribute is identical to the @code{Object_Size} attribute. It is provided for compatibility with the DEC Ada 83 attribute of this name. @node Attribute Mantissa,Attribute Maximum_Alignment,Attribute Machine_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-mantissa}@anchor{1a1} +@anchor{gnat_rm/implementation_defined_attributes attribute-mantissa}@anchor{1a5} @section Attribute Mantissa @@ -11274,7 +11361,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute. @node Attribute Maximum_Alignment,Attribute Max_Integer_Size,Attribute Mantissa,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-maximum-alignment}@anchor{1a2}@anchor{gnat_rm/implementation_defined_attributes id2}@anchor{1a3} +@anchor{gnat_rm/implementation_defined_attributes attribute-maximum-alignment}@anchor{1a6}@anchor{gnat_rm/implementation_defined_attributes id2}@anchor{1a7} @section Attribute Maximum_Alignment @@ -11290,7 +11377,7 @@ for an object, guaranteeing that it is properly aligned in all cases. @node Attribute Max_Integer_Size,Attribute Mechanism_Code,Attribute Maximum_Alignment,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-max-integer-size}@anchor{1a4} +@anchor{gnat_rm/implementation_defined_attributes attribute-max-integer-size}@anchor{1a8} @section Attribute Max_Integer_Size @@ -11301,7 +11388,7 @@ prefix) provides the size of the largest supported integer type for the target. The result is a static constant. @node Attribute Mechanism_Code,Attribute Null_Parameter,Attribute Max_Integer_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-mechanism-code}@anchor{1a5} +@anchor{gnat_rm/implementation_defined_attributes attribute-mechanism-code}@anchor{1a9} @section Attribute Mechanism_Code @@ -11332,7 +11419,7 @@ by reference @end table @node Attribute Null_Parameter,Attribute Object_Size,Attribute Mechanism_Code,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-null-parameter}@anchor{1a6} +@anchor{gnat_rm/implementation_defined_attributes attribute-null-parameter}@anchor{1aa} @section Attribute Null_Parameter @@ -11357,7 +11444,7 @@ There is no way of indicating this without the @code{Null_Parameter} attribute. @node Attribute Object_Size,Attribute Old,Attribute Null_Parameter,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-object-size}@anchor{155}@anchor{gnat_rm/implementation_defined_attributes id3}@anchor{1a7} +@anchor{gnat_rm/implementation_defined_attributes attribute-object-size}@anchor{157}@anchor{gnat_rm/implementation_defined_attributes id3}@anchor{1ab} @section Attribute Object_Size @@ -11427,7 +11514,7 @@ Similar additional checks are performed in other contexts requiring statically matching subtypes. @node Attribute Old,Attribute Passed_By_Reference,Attribute Object_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-old}@anchor{1a8} +@anchor{gnat_rm/implementation_defined_attributes attribute-old}@anchor{1ac} @section Attribute Old @@ -11442,7 +11529,7 @@ definition are allowed under control of implementation defined pragma @code{Unevaluated_Use_Of_Old}. @node Attribute Passed_By_Reference,Attribute Pool_Address,Attribute Old,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-passed-by-reference}@anchor{1a9} +@anchor{gnat_rm/implementation_defined_attributes attribute-passed-by-reference}@anchor{1ad} @section Attribute Passed_By_Reference @@ -11458,7 +11545,7 @@ passed by copy in calls. For scalar types, the result is always @code{False} and is static. For non-scalar types, the result is nonstatic. @node Attribute Pool_Address,Attribute Range_Length,Attribute Passed_By_Reference,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-pool-address}@anchor{1aa} +@anchor{gnat_rm/implementation_defined_attributes attribute-pool-address}@anchor{1ae} @section Attribute Pool_Address @@ -11480,7 +11567,7 @@ For an object created by @code{new}, @code{Ptr.all'Pool_Address} is what is passed to @code{Allocate} and returned from @code{Deallocate}. @node Attribute Range_Length,Attribute Restriction_Set,Attribute Pool_Address,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-range-length}@anchor{1ab} +@anchor{gnat_rm/implementation_defined_attributes attribute-range-length}@anchor{1af} @section Attribute Range_Length @@ -11493,7 +11580,7 @@ applied to the index subtype of a one dimensional array always gives the same result as @code{Length} applied to the array itself. @node Attribute Restriction_Set,Attribute Result,Attribute Range_Length,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-restriction-set}@anchor{1ac} +@anchor{gnat_rm/implementation_defined_attributes attribute-restriction-set}@anchor{1b0} @section Attribute Restriction_Set @@ -11563,7 +11650,7 @@ Restrictions pragma, they are not analyzed semantically, so they do not have a type. @node Attribute Result,Attribute Round,Attribute Restriction_Set,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-result}@anchor{1ad} +@anchor{gnat_rm/implementation_defined_attributes attribute-result}@anchor{1b1} @section Attribute Result @@ -11576,7 +11663,7 @@ For a further discussion of the use of this attribute and examples of its use, see the description of pragma Postcondition. @node Attribute Round,Attribute Safe_Emax,Attribute Result,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-round}@anchor{1ae} +@anchor{gnat_rm/implementation_defined_attributes attribute-round}@anchor{1b2} @section Attribute Round @@ -11587,7 +11674,7 @@ also permits the use of the @code{'Round} attribute for ordinary fixed point types. @node Attribute Safe_Emax,Attribute Safe_Large,Attribute Round,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-safe-emax}@anchor{1af} +@anchor{gnat_rm/implementation_defined_attributes attribute-safe-emax}@anchor{1b3} @section Attribute Safe_Emax @@ -11600,7 +11687,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute. @node Attribute Safe_Large,Attribute Safe_Small,Attribute Safe_Emax,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-safe-large}@anchor{1b0} +@anchor{gnat_rm/implementation_defined_attributes attribute-safe-large}@anchor{1b4} @section Attribute Safe_Large @@ -11613,7 +11700,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute. @node Attribute Safe_Small,Attribute Scalar_Storage_Order,Attribute Safe_Large,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-safe-small}@anchor{1b1} +@anchor{gnat_rm/implementation_defined_attributes attribute-safe-small}@anchor{1b5} @section Attribute Safe_Small @@ -11626,7 +11713,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute. @node Attribute Scalar_Storage_Order,Attribute Simple_Storage_Pool,Attribute Safe_Small,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-scalar-storage-order}@anchor{162}@anchor{gnat_rm/implementation_defined_attributes id4}@anchor{1b2} +@anchor{gnat_rm/implementation_defined_attributes attribute-scalar-storage-order}@anchor{166}@anchor{gnat_rm/implementation_defined_attributes id4}@anchor{1b6} @section Attribute Scalar_Storage_Order @@ -11789,7 +11876,7 @@ Note that debuggers may be unable to display the correct value of scalar components of a type for which the opposite storage order is specified. @node Attribute Simple_Storage_Pool,Attribute Small,Attribute Scalar_Storage_Order,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-simple-storage-pool}@anchor{f0}@anchor{gnat_rm/implementation_defined_attributes id5}@anchor{1b3} +@anchor{gnat_rm/implementation_defined_attributes attribute-simple-storage-pool}@anchor{f2}@anchor{gnat_rm/implementation_defined_attributes id5}@anchor{1b7} @section Attribute Simple_Storage_Pool @@ -11852,7 +11939,7 @@ as defined in section 13.11.2 of the Ada Reference Manual, except that the term `simple storage pool' is substituted for `storage pool'. @node Attribute Small,Attribute Small_Denominator,Attribute Simple_Storage_Pool,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-small}@anchor{1b4} +@anchor{gnat_rm/implementation_defined_attributes attribute-small}@anchor{1b8} @section Attribute Small @@ -11868,7 +11955,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute when applied to floating-point types. @node Attribute Small_Denominator,Attribute Small_Numerator,Attribute Small,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-small-denominator}@anchor{1b5} +@anchor{gnat_rm/implementation_defined_attributes attribute-small-denominator}@anchor{1b9} @section Attribute Small_Denominator @@ -11881,7 +11968,7 @@ denominator in the representation of @code{typ'Small} as a rational number with coprime factors (i.e. as an irreducible fraction). @node Attribute Small_Numerator,Attribute Storage_Unit,Attribute Small_Denominator,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-small-numerator}@anchor{1b6} +@anchor{gnat_rm/implementation_defined_attributes attribute-small-numerator}@anchor{1ba} @section Attribute Small_Numerator @@ -11894,7 +11981,7 @@ numerator in the representation of @code{typ'Small} as a rational number with coprime factors (i.e. as an irreducible fraction). @node Attribute Storage_Unit,Attribute Stub_Type,Attribute Small_Numerator,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-storage-unit}@anchor{1b7} +@anchor{gnat_rm/implementation_defined_attributes attribute-storage-unit}@anchor{1bb} @section Attribute Storage_Unit @@ -11904,7 +11991,7 @@ with coprime factors (i.e. as an irreducible fraction). prefix) provides the same value as @code{System.Storage_Unit}. @node Attribute Stub_Type,Attribute System_Allocator_Alignment,Attribute Storage_Unit,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-stub-type}@anchor{1b8} +@anchor{gnat_rm/implementation_defined_attributes attribute-stub-type}@anchor{1bc} @section Attribute Stub_Type @@ -11928,7 +12015,7 @@ unit @code{System.Partition_Interface}. Use of this attribute will create an implicit dependency on this unit. @node Attribute System_Allocator_Alignment,Attribute Target_Name,Attribute Stub_Type,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-system-allocator-alignment}@anchor{1b9} +@anchor{gnat_rm/implementation_defined_attributes attribute-system-allocator-alignment}@anchor{1bd} @section Attribute System_Allocator_Alignment @@ -11945,7 +12032,7 @@ with alignment too large or to enable a realignment circuitry if the alignment request is larger than this value. @node Attribute Target_Name,Attribute To_Address,Attribute System_Allocator_Alignment,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-target-name}@anchor{1ba} +@anchor{gnat_rm/implementation_defined_attributes attribute-target-name}@anchor{1be} @section Attribute Target_Name @@ -11958,7 +12045,7 @@ standard gcc target name without the terminating slash (for example, GNAT 5.0 on windows yields “i586-pc-mingw32msv”). @node Attribute To_Address,Attribute To_Any,Attribute Target_Name,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-to-address}@anchor{1bb} +@anchor{gnat_rm/implementation_defined_attributes attribute-to-address}@anchor{1bf} @section Attribute To_Address @@ -11981,7 +12068,7 @@ modular manner (e.g., -1 means the same as 16#FFFF_FFFF# on a 32 bits machine). @node Attribute To_Any,Attribute Type_Class,Attribute To_Address,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-to-any}@anchor{1bc} +@anchor{gnat_rm/implementation_defined_attributes attribute-to-any}@anchor{1c0} @section Attribute To_Any @@ -11991,7 +12078,7 @@ This internal attribute is used for the generation of remote subprogram stubs in the context of the Distributed Systems Annex. @node Attribute Type_Class,Attribute Type_Key,Attribute To_Any,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-type-class}@anchor{1bd} +@anchor{gnat_rm/implementation_defined_attributes attribute-type-class}@anchor{1c1} @section Attribute Type_Class @@ -12021,7 +12108,7 @@ applies to all concurrent types. This attribute is designed to be compatible with the DEC Ada 83 attribute of the same name. @node Attribute Type_Key,Attribute TypeCode,Attribute Type_Class,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-type-key}@anchor{1be} +@anchor{gnat_rm/implementation_defined_attributes attribute-type-key}@anchor{1c2} @section Attribute Type_Key @@ -12033,7 +12120,7 @@ about the type or subtype. This provides improved compatibility with other implementations that support this attribute. @node Attribute TypeCode,Attribute Unconstrained_Array,Attribute Type_Key,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-typecode}@anchor{1bf} +@anchor{gnat_rm/implementation_defined_attributes attribute-typecode}@anchor{1c3} @section Attribute TypeCode @@ -12043,7 +12130,7 @@ This internal attribute is used for the generation of remote subprogram stubs in the context of the Distributed Systems Annex. @node Attribute Unconstrained_Array,Attribute Universal_Literal_String,Attribute TypeCode,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-unconstrained-array}@anchor{1c0} +@anchor{gnat_rm/implementation_defined_attributes attribute-unconstrained-array}@anchor{1c4} @section Attribute Unconstrained_Array @@ -12057,7 +12144,7 @@ still static, and yields the result of applying this test to the generic actual. @node Attribute Universal_Literal_String,Attribute Unrestricted_Access,Attribute Unconstrained_Array,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-universal-literal-string}@anchor{1c1} +@anchor{gnat_rm/implementation_defined_attributes attribute-universal-literal-string}@anchor{1c5} @section Attribute Universal_Literal_String @@ -12085,7 +12172,7 @@ end; @end example @node Attribute Unrestricted_Access,Attribute Update,Attribute Universal_Literal_String,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-unrestricted-access}@anchor{1c2} +@anchor{gnat_rm/implementation_defined_attributes attribute-unrestricted-access}@anchor{1c6} @section Attribute Unrestricted_Access @@ -12272,7 +12359,7 @@ In general this is a risky approach. It may appear to “work” but such uses o of GNAT to another, so are best avoided if possible. @node Attribute Update,Attribute Valid_Value,Attribute Unrestricted_Access,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-update}@anchor{1c3} +@anchor{gnat_rm/implementation_defined_attributes attribute-update}@anchor{1c7} @section Attribute Update @@ -12353,19 +12440,19 @@ A := A'Update ((1, 2) => 20, (3, 4) => 30); which changes element (1,2) to 20 and (3,4) to 30. @node Attribute Valid_Value,Attribute Valid_Scalars,Attribute Update,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-valid-value}@anchor{1c4} +@anchor{gnat_rm/implementation_defined_attributes attribute-valid-value}@anchor{1c8} @section Attribute Valid_Value @geindex Valid_Value The @code{'Valid_Value} attribute is defined for enumeration types other than -those in package Standard. This attribute is a function that takes -a String, and returns Boolean. @code{T'Valid_Value (S)} returns True -if and only if @code{T'Value (S)} would not raise Constraint_Error. +those in package Standard or types derived from those types. This attribute is +a function that takes a String, and returns Boolean. @code{T'Valid_Value (S)} +returns True if and only if @code{T'Value (S)} would not raise Constraint_Error. @node Attribute Valid_Scalars,Attribute VADS_Size,Attribute Valid_Value,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-valid-scalars}@anchor{1c5} +@anchor{gnat_rm/implementation_defined_attributes attribute-valid-scalars}@anchor{1c9} @section Attribute Valid_Scalars @@ -12399,7 +12486,7 @@ write a function with a single use of the attribute, and then call that function from multiple places. @node Attribute VADS_Size,Attribute Value_Size,Attribute Valid_Scalars,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-vads-size}@anchor{1c6} +@anchor{gnat_rm/implementation_defined_attributes attribute-vads-size}@anchor{1ca} @section Attribute VADS_Size @@ -12419,7 +12506,7 @@ gives the result that would be obtained by applying the attribute to the corresponding type. @node Attribute Value_Size,Attribute Wchar_T_Size,Attribute VADS_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-value-size}@anchor{174}@anchor{gnat_rm/implementation_defined_attributes id6}@anchor{1c7} +@anchor{gnat_rm/implementation_defined_attributes attribute-value-size}@anchor{178}@anchor{gnat_rm/implementation_defined_attributes id6}@anchor{1cb} @section Attribute Value_Size @@ -12433,7 +12520,7 @@ a value of the given subtype. It is the same as @code{type'Size}, but, unlike @code{Size}, may be set for non-first subtypes. @node Attribute Wchar_T_Size,Attribute Word_Size,Attribute Value_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-wchar-t-size}@anchor{1c8} +@anchor{gnat_rm/implementation_defined_attributes attribute-wchar-t-size}@anchor{1cc} @section Attribute Wchar_T_Size @@ -12445,7 +12532,7 @@ primarily for constructing the definition of this type in package @code{Interfaces.C}. The result is a static constant. @node Attribute Word_Size,,Attribute Wchar_T_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-word-size}@anchor{1c9} +@anchor{gnat_rm/implementation_defined_attributes attribute-word-size}@anchor{1cd} @section Attribute Word_Size @@ -12456,7 +12543,7 @@ prefix) provides the value @code{System.Word_Size}. The result is a static constant. @node Standard and Implementation Defined Restrictions,Implementation Advice,Implementation Defined Attributes,Top -@anchor{gnat_rm/standard_and_implementation_defined_restrictions doc}@anchor{1ca}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id1}@anchor{1cb}@anchor{gnat_rm/standard_and_implementation_defined_restrictions standard-and-implementation-defined-restrictions}@anchor{9} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions doc}@anchor{1ce}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id1}@anchor{1cf}@anchor{gnat_rm/standard_and_implementation_defined_restrictions standard-and-implementation-defined-restrictions}@anchor{9} @chapter Standard and Implementation Defined Restrictions @@ -12485,7 +12572,7 @@ language defined or GNAT-specific, are listed in the following. @end menu @node Partition-Wide Restrictions,Program Unit Level Restrictions,,Standard and Implementation Defined Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions id2}@anchor{1cc}@anchor{gnat_rm/standard_and_implementation_defined_restrictions partition-wide-restrictions}@anchor{1cd} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions id2}@anchor{1d0}@anchor{gnat_rm/standard_and_implementation_defined_restrictions partition-wide-restrictions}@anchor{1d1} @section Partition-Wide Restrictions @@ -12578,7 +12665,7 @@ then all compilation units in the partition must obey the restriction). @end menu @node Immediate_Reclamation,Max_Asynchronous_Select_Nesting,,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions immediate-reclamation}@anchor{1ce} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions immediate-reclamation}@anchor{1d2} @subsection Immediate_Reclamation @@ -12590,7 +12677,7 @@ deallocation, any storage reserved at run time for an object is immediately reclaimed when the object no longer exists. @node Max_Asynchronous_Select_Nesting,Max_Entry_Queue_Length,Immediate_Reclamation,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-asynchronous-select-nesting}@anchor{1cf} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-asynchronous-select-nesting}@anchor{1d3} @subsection Max_Asynchronous_Select_Nesting @@ -12602,7 +12689,7 @@ detected at compile time. Violations of this restriction with values other than zero cause Storage_Error to be raised. @node Max_Entry_Queue_Length,Max_Protected_Entries,Max_Asynchronous_Select_Nesting,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-entry-queue-length}@anchor{1d0} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-entry-queue-length}@anchor{1d4} @subsection Max_Entry_Queue_Length @@ -12623,7 +12710,7 @@ compatibility purposes (and a warning will be generated for its use if warnings on obsolescent features are activated). @node Max_Protected_Entries,Max_Select_Alternatives,Max_Entry_Queue_Length,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-protected-entries}@anchor{1d1} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-protected-entries}@anchor{1d5} @subsection Max_Protected_Entries @@ -12634,7 +12721,7 @@ bounds of every entry family of a protected unit shall be static, or shall be defined by a discriminant of a subtype whose corresponding bound is static. @node Max_Select_Alternatives,Max_Storage_At_Blocking,Max_Protected_Entries,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-select-alternatives}@anchor{1d2} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-select-alternatives}@anchor{1d6} @subsection Max_Select_Alternatives @@ -12643,7 +12730,7 @@ defined by a discriminant of a subtype whose corresponding bound is static. [RM D.7] Specifies the maximum number of alternatives in a selective accept. @node Max_Storage_At_Blocking,Max_Task_Entries,Max_Select_Alternatives,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-storage-at-blocking}@anchor{1d3} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-storage-at-blocking}@anchor{1d7} @subsection Max_Storage_At_Blocking @@ -12654,7 +12741,7 @@ Storage_Size that can be retained by a blocked task. A violation of this restriction causes Storage_Error to be raised. @node Max_Task_Entries,Max_Tasks,Max_Storage_At_Blocking,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-task-entries}@anchor{1d4} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-task-entries}@anchor{1d8} @subsection Max_Task_Entries @@ -12667,7 +12754,7 @@ defined by a discriminant of a subtype whose corresponding bound is static. @node Max_Tasks,No_Abort_Statements,Max_Task_Entries,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-tasks}@anchor{1d5} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-tasks}@anchor{1d9} @subsection Max_Tasks @@ -12680,7 +12767,7 @@ time. Violations of this restriction with values other than zero cause Storage_Error to be raised. @node No_Abort_Statements,No_Access_Parameter_Allocators,Max_Tasks,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-abort-statements}@anchor{1d6} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-abort-statements}@anchor{1da} @subsection No_Abort_Statements @@ -12690,7 +12777,7 @@ Storage_Error to be raised. no calls to Task_Identification.Abort_Task. @node No_Access_Parameter_Allocators,No_Access_Subprograms,No_Abort_Statements,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-access-parameter-allocators}@anchor{1d7} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-access-parameter-allocators}@anchor{1db} @subsection No_Access_Parameter_Allocators @@ -12701,7 +12788,7 @@ occurrences of an allocator as the actual parameter to an access parameter. @node No_Access_Subprograms,No_Allocators,No_Access_Parameter_Allocators,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-access-subprograms}@anchor{1d8} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-access-subprograms}@anchor{1dc} @subsection No_Access_Subprograms @@ -12711,7 +12798,7 @@ parameter. declarations of access-to-subprogram types. @node No_Allocators,No_Anonymous_Allocators,No_Access_Subprograms,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-allocators}@anchor{1d9} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-allocators}@anchor{1dd} @subsection No_Allocators @@ -12721,7 +12808,7 @@ declarations of access-to-subprogram types. occurrences of an allocator. @node No_Anonymous_Allocators,No_Asynchronous_Control,No_Allocators,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-anonymous-allocators}@anchor{1da} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-anonymous-allocators}@anchor{1de} @subsection No_Anonymous_Allocators @@ -12731,7 +12818,7 @@ occurrences of an allocator. occurrences of an allocator of anonymous access type. @node No_Asynchronous_Control,No_Calendar,No_Anonymous_Allocators,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-asynchronous-control}@anchor{1db} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-asynchronous-control}@anchor{1df} @subsection No_Asynchronous_Control @@ -12741,7 +12828,7 @@ occurrences of an allocator of anonymous access type. dependences on the predefined package Asynchronous_Task_Control. @node No_Calendar,No_Coextensions,No_Asynchronous_Control,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-calendar}@anchor{1dc} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-calendar}@anchor{1e0} @subsection No_Calendar @@ -12751,7 +12838,7 @@ dependences on the predefined package Asynchronous_Task_Control. dependences on package Calendar. @node No_Coextensions,No_Default_Initialization,No_Calendar,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-coextensions}@anchor{1dd} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-coextensions}@anchor{1e1} @subsection No_Coextensions @@ -12761,7 +12848,7 @@ dependences on package Calendar. coextensions. See 3.10.2. @node No_Default_Initialization,No_Delay,No_Coextensions,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-default-initialization}@anchor{1de} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-default-initialization}@anchor{1e2} @subsection No_Default_Initialization @@ -12778,7 +12865,7 @@ is to prohibit all cases of variables declared without a specific initializer (including the case of OUT scalar parameters). @node No_Delay,No_Dependence,No_Default_Initialization,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-delay}@anchor{1df} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-delay}@anchor{1e3} @subsection No_Delay @@ -12788,7 +12875,7 @@ initializer (including the case of OUT scalar parameters). delay statements and no semantic dependences on package Calendar. @node No_Dependence,No_Direct_Boolean_Operators,No_Delay,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dependence}@anchor{1e0} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dependence}@anchor{1e4} @subsection No_Dependence @@ -12831,7 +12918,7 @@ to support specific constructs of the language. Here are some examples: @end itemize @node No_Direct_Boolean_Operators,No_Dispatch,No_Dependence,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-direct-boolean-operators}@anchor{1e1} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-direct-boolean-operators}@anchor{1e5} @subsection No_Direct_Boolean_Operators @@ -12844,7 +12931,7 @@ protocol requires the use of short-circuit (and then, or else) forms for all composite boolean operations. @node No_Dispatch,No_Dispatching_Calls,No_Direct_Boolean_Operators,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dispatch}@anchor{1e2} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dispatch}@anchor{1e6} @subsection No_Dispatch @@ -12854,7 +12941,7 @@ composite boolean operations. occurrences of @code{T'Class}, for any (tagged) subtype @code{T}. @node No_Dispatching_Calls,No_Dynamic_Attachment,No_Dispatch,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dispatching-calls}@anchor{1e3} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dispatching-calls}@anchor{1e7} @subsection No_Dispatching_Calls @@ -12915,7 +13002,7 @@ end Example; @end example @node No_Dynamic_Attachment,No_Dynamic_Priorities,No_Dispatching_Calls,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-attachment}@anchor{1e4} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-attachment}@anchor{1e8} @subsection No_Dynamic_Attachment @@ -12934,7 +13021,7 @@ compatibility purposes (and a warning will be generated for its use if warnings on obsolescent features are activated). @node No_Dynamic_Priorities,No_Entry_Calls_In_Elaboration_Code,No_Dynamic_Attachment,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-priorities}@anchor{1e5} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-priorities}@anchor{1e9} @subsection No_Dynamic_Priorities @@ -12943,7 +13030,7 @@ warnings on obsolescent features are activated). [RM D.7] There are no semantic dependencies on the package Dynamic_Priorities. @node No_Entry_Calls_In_Elaboration_Code,No_Enumeration_Maps,No_Dynamic_Priorities,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-calls-in-elaboration-code}@anchor{1e6} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-calls-in-elaboration-code}@anchor{1ea} @subsection No_Entry_Calls_In_Elaboration_Code @@ -12955,7 +13042,7 @@ restriction, the compiler can assume that no code past an accept statement in a task can be executed at elaboration time. @node No_Enumeration_Maps,No_Exception_Handlers,No_Entry_Calls_In_Elaboration_Code,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-enumeration-maps}@anchor{1e7} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-enumeration-maps}@anchor{1eb} @subsection No_Enumeration_Maps @@ -12966,7 +13053,7 @@ enumeration maps are used (that is Image and Value attributes applied to enumeration types). @node No_Exception_Handlers,No_Exception_Propagation,No_Enumeration_Maps,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-handlers}@anchor{1e8} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-handlers}@anchor{1ec} @subsection No_Exception_Handlers @@ -12991,7 +13078,7 @@ statement generated by the compiler). The Line parameter when nonzero represents the line number in the source program where the raise occurs. @node No_Exception_Propagation,No_Exception_Registration,No_Exception_Handlers,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-propagation}@anchor{1e9} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-propagation}@anchor{1ed} @subsection No_Exception_Propagation @@ -13008,7 +13095,7 @@ the package GNAT.Current_Exception is not permitted, and reraise statements (raise with no operand) are not permitted. @node No_Exception_Registration,No_Exceptions,No_Exception_Propagation,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-registration}@anchor{1ea} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-registration}@anchor{1ee} @subsection No_Exception_Registration @@ -13022,7 +13109,7 @@ code is simplified by omitting the otherwise-required global registration of exceptions when they are declared. @node No_Exceptions,No_Finalization,No_Exception_Registration,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exceptions}@anchor{1eb} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exceptions}@anchor{1ef} @subsection No_Exceptions @@ -13033,7 +13120,7 @@ raise statements and no exception handlers and also suppresses the generation of language-defined run-time checks. @node No_Finalization,No_Fixed_Point,No_Exceptions,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-finalization}@anchor{1ec} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-finalization}@anchor{1f0} @subsection No_Finalization @@ -13074,7 +13161,7 @@ object or a nested component, either declared on the stack or on the heap. The deallocation of a controlled object no longer finalizes its contents. @node No_Fixed_Point,No_Floating_Point,No_Finalization,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-fixed-point}@anchor{1ed} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-fixed-point}@anchor{1f1} @subsection No_Fixed_Point @@ -13084,7 +13171,7 @@ deallocation of a controlled object no longer finalizes its contents. occurrences of fixed point types and operations. @node No_Floating_Point,No_Implicit_Conditionals,No_Fixed_Point,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-floating-point}@anchor{1ee} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-floating-point}@anchor{1f2} @subsection No_Floating_Point @@ -13094,7 +13181,7 @@ occurrences of fixed point types and operations. occurrences of floating point types and operations. @node No_Implicit_Conditionals,No_Implicit_Dynamic_Code,No_Floating_Point,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-conditionals}@anchor{1ef} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-conditionals}@anchor{1f3} @subsection No_Implicit_Conditionals @@ -13110,7 +13197,7 @@ normal manner. Constructs generating implicit conditionals include comparisons of composite objects and the Max/Min attributes. @node No_Implicit_Dynamic_Code,No_Implicit_Heap_Allocations,No_Implicit_Conditionals,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-dynamic-code}@anchor{1f0} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-dynamic-code}@anchor{1f4} @subsection No_Implicit_Dynamic_Code @@ -13140,7 +13227,7 @@ foreign-language convention; primitive operations of nested tagged types. @node No_Implicit_Heap_Allocations,No_Implicit_Protected_Object_Allocations,No_Implicit_Dynamic_Code,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-heap-allocations}@anchor{1f1} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-heap-allocations}@anchor{1f5} @subsection No_Implicit_Heap_Allocations @@ -13149,7 +13236,7 @@ types. [RM D.7] No constructs are allowed to cause implicit heap allocation. @node No_Implicit_Protected_Object_Allocations,No_Implicit_Task_Allocations,No_Implicit_Heap_Allocations,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-protected-object-allocations}@anchor{1f2} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-protected-object-allocations}@anchor{1f6} @subsection No_Implicit_Protected_Object_Allocations @@ -13159,7 +13246,7 @@ types. protected object. @node No_Implicit_Task_Allocations,No_Initialize_Scalars,No_Implicit_Protected_Object_Allocations,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-task-allocations}@anchor{1f3} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-task-allocations}@anchor{1f7} @subsection No_Implicit_Task_Allocations @@ -13168,7 +13255,7 @@ protected object. [GNAT] No constructs are allowed to cause implicit heap allocation of a task. @node No_Initialize_Scalars,No_IO,No_Implicit_Task_Allocations,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-initialize-scalars}@anchor{1f4} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-initialize-scalars}@anchor{1f8} @subsection No_Initialize_Scalars @@ -13180,7 +13267,7 @@ code, and in particular eliminates dummy null initialization routines that are otherwise generated for some record and array types. @node No_IO,No_Local_Allocators,No_Initialize_Scalars,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-io}@anchor{1f5} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-io}@anchor{1f9} @subsection No_IO @@ -13191,7 +13278,7 @@ dependences on any of the library units Sequential_IO, Direct_IO, Text_IO, Wide_Text_IO, Wide_Wide_Text_IO, or Stream_IO. @node No_Local_Allocators,No_Local_Protected_Objects,No_IO,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-allocators}@anchor{1f6} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-allocators}@anchor{1fa} @subsection No_Local_Allocators @@ -13202,7 +13289,7 @@ occurrences of an allocator in subprograms, generic subprograms, tasks, and entry bodies. @node No_Local_Protected_Objects,No_Local_Tagged_Types,No_Local_Allocators,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-protected-objects}@anchor{1f7} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-protected-objects}@anchor{1fb} @subsection No_Local_Protected_Objects @@ -13212,7 +13299,7 @@ and entry bodies. only declared at the library level. @node No_Local_Tagged_Types,No_Local_Timing_Events,No_Local_Protected_Objects,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-tagged-types}@anchor{1f8} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-tagged-types}@anchor{1fc} @subsection No_Local_Tagged_Types @@ -13222,7 +13309,7 @@ only declared at the library level. declared at the library level. @node No_Local_Timing_Events,No_Long_Long_Integers,No_Local_Tagged_Types,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-timing-events}@anchor{1f9} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-timing-events}@anchor{1fd} @subsection No_Local_Timing_Events @@ -13232,7 +13319,7 @@ declared at the library level. declared at the library level. @node No_Long_Long_Integers,No_Multiple_Elaboration,No_Local_Timing_Events,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-long-long-integers}@anchor{1fa} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-long-long-integers}@anchor{1fe} @subsection No_Long_Long_Integers @@ -13244,7 +13331,7 @@ implicit base type is Long_Long_Integer, and modular types whose size exceeds Long_Integer’Size. @node No_Multiple_Elaboration,No_Nested_Finalization,No_Long_Long_Integers,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-multiple-elaboration}@anchor{1fb} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-multiple-elaboration}@anchor{1ff} @subsection No_Multiple_Elaboration @@ -13260,7 +13347,7 @@ possible, including non-Ada main programs and Stand Alone libraries, are not permitted and will be diagnosed by the binder. @node No_Nested_Finalization,No_Protected_Type_Allocators,No_Multiple_Elaboration,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-nested-finalization}@anchor{1fc} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-nested-finalization}@anchor{200} @subsection No_Nested_Finalization @@ -13269,7 +13356,7 @@ permitted and will be diagnosed by the binder. [RM D.7] All objects requiring finalization are declared at the library level. @node No_Protected_Type_Allocators,No_Protected_Types,No_Nested_Finalization,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-protected-type-allocators}@anchor{1fd} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-protected-type-allocators}@anchor{201} @subsection No_Protected_Type_Allocators @@ -13279,7 +13366,7 @@ permitted and will be diagnosed by the binder. expressions that attempt to allocate protected objects. @node No_Protected_Types,No_Recursion,No_Protected_Type_Allocators,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-protected-types}@anchor{1fe} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-protected-types}@anchor{202} @subsection No_Protected_Types @@ -13289,7 +13376,7 @@ expressions that attempt to allocate protected objects. declarations of protected types or protected objects. @node No_Recursion,No_Reentrancy,No_Protected_Types,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-recursion}@anchor{1ff} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-recursion}@anchor{203} @subsection No_Recursion @@ -13299,7 +13386,7 @@ declarations of protected types or protected objects. part of its execution. @node No_Reentrancy,No_Relative_Delay,No_Recursion,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-reentrancy}@anchor{200} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-reentrancy}@anchor{204} @subsection No_Reentrancy @@ -13309,7 +13396,7 @@ part of its execution. two tasks at the same time. @node No_Relative_Delay,No_Requeue_Statements,No_Reentrancy,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-relative-delay}@anchor{201} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-relative-delay}@anchor{205} @subsection No_Relative_Delay @@ -13320,7 +13407,7 @@ relative statements and prevents expressions such as @code{delay 1.23;} from appearing in source code. @node No_Requeue_Statements,No_Secondary_Stack,No_Relative_Delay,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-requeue-statements}@anchor{202} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-requeue-statements}@anchor{206} @subsection No_Requeue_Statements @@ -13338,7 +13425,7 @@ compatibility purposes (and a warning will be generated for its use if warnings on oNobsolescent features are activated). @node No_Secondary_Stack,No_Select_Statements,No_Requeue_Statements,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-secondary-stack}@anchor{203} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-secondary-stack}@anchor{207} @subsection No_Secondary_Stack @@ -13351,7 +13438,7 @@ stack is used to implement functions returning unconstrained objects secondary stacks for tasks (excluding the environment task) at run time. @node No_Select_Statements,No_Specific_Termination_Handlers,No_Secondary_Stack,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-select-statements}@anchor{204} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-select-statements}@anchor{208} @subsection No_Select_Statements @@ -13361,7 +13448,7 @@ secondary stacks for tasks (excluding the environment task) at run time. kind are permitted, that is the keyword @code{select} may not appear. @node No_Specific_Termination_Handlers,No_Specification_of_Aspect,No_Select_Statements,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-specific-termination-handlers}@anchor{205} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-specific-termination-handlers}@anchor{209} @subsection No_Specific_Termination_Handlers @@ -13371,7 +13458,7 @@ kind are permitted, that is the keyword @code{select} may not appear. or to Ada.Task_Termination.Specific_Handler. @node No_Specification_of_Aspect,No_Standard_Allocators_After_Elaboration,No_Specific_Termination_Handlers,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-specification-of-aspect}@anchor{206} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-specification-of-aspect}@anchor{20a} @subsection No_Specification_of_Aspect @@ -13382,7 +13469,7 @@ specification, attribute definition clause, or pragma is given for a given aspect. @node No_Standard_Allocators_After_Elaboration,No_Standard_Storage_Pools,No_Specification_of_Aspect,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-standard-allocators-after-elaboration}@anchor{207} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-standard-allocators-after-elaboration}@anchor{20b} @subsection No_Standard_Allocators_After_Elaboration @@ -13394,7 +13481,7 @@ library items of the partition has completed. Otherwise, Storage_Error is raised. @node No_Standard_Storage_Pools,No_Stream_Optimizations,No_Standard_Allocators_After_Elaboration,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-standard-storage-pools}@anchor{208} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-standard-storage-pools}@anchor{20c} @subsection No_Standard_Storage_Pools @@ -13406,7 +13493,7 @@ have an explicit Storage_Pool attribute defined specifying a user-defined storage pool. @node No_Stream_Optimizations,No_Streams,No_Standard_Storage_Pools,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-stream-optimizations}@anchor{209} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-stream-optimizations}@anchor{20d} @subsection No_Stream_Optimizations @@ -13419,7 +13506,7 @@ due to their superior performance. When this restriction is in effect, the compiler performs all IO operations on a per-character basis. @node No_Streams,No_Tagged_Type_Registration,No_Stream_Optimizations,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-streams}@anchor{20a} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-streams}@anchor{20e} @subsection No_Streams @@ -13446,7 +13533,7 @@ configuration pragmas to avoid exposing entity names at binary level for the entire partition. @node No_Tagged_Type_Registration,No_Task_Allocators,No_Streams,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-tagged-type-registration}@anchor{20b} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-tagged-type-registration}@anchor{20f} @subsection No_Tagged_Type_Registration @@ -13461,7 +13548,7 @@ are declared. This restriction may be necessary in order to also apply the No_Elaboration_Code restriction. @node No_Task_Allocators,No_Task_At_Interrupt_Priority,No_Tagged_Type_Registration,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-allocators}@anchor{20c} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-allocators}@anchor{210} @subsection No_Task_Allocators @@ -13471,7 +13558,7 @@ the No_Elaboration_Code restriction. or types containing task subcomponents. @node No_Task_At_Interrupt_Priority,No_Task_Attributes_Package,No_Task_Allocators,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-at-interrupt-priority}@anchor{20d} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-at-interrupt-priority}@anchor{211} @subsection No_Task_At_Interrupt_Priority @@ -13483,7 +13570,7 @@ a consequence, the tasks are always created with a priority below that an interrupt priority. @node No_Task_Attributes_Package,No_Task_Hierarchy,No_Task_At_Interrupt_Priority,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-attributes-package}@anchor{20e} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-attributes-package}@anchor{212} @subsection No_Task_Attributes_Package @@ -13500,7 +13587,7 @@ compatibility purposes (and a warning will be generated for its use if warnings on obsolescent features are activated). @node No_Task_Hierarchy,No_Task_Termination,No_Task_Attributes_Package,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-hierarchy}@anchor{20f} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-hierarchy}@anchor{213} @subsection No_Task_Hierarchy @@ -13510,7 +13597,7 @@ warnings on obsolescent features are activated). directly on the environment task of the partition. @node No_Task_Termination,No_Tasking,No_Task_Hierarchy,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-termination}@anchor{210} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-termination}@anchor{214} @subsection No_Task_Termination @@ -13519,7 +13606,7 @@ directly on the environment task of the partition. [RM D.7] Tasks that terminate are erroneous. @node No_Tasking,No_Terminate_Alternatives,No_Task_Termination,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-tasking}@anchor{211} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-tasking}@anchor{215} @subsection No_Tasking @@ -13532,7 +13619,7 @@ and cause an error message to be output either by the compiler or binder. @node No_Terminate_Alternatives,No_Unchecked_Access,No_Tasking,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-terminate-alternatives}@anchor{212} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-terminate-alternatives}@anchor{216} @subsection No_Terminate_Alternatives @@ -13541,7 +13628,7 @@ binder. [RM D.7] There are no selective accepts with terminate alternatives. @node No_Unchecked_Access,No_Unchecked_Conversion,No_Terminate_Alternatives,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-access}@anchor{213} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-access}@anchor{217} @subsection No_Unchecked_Access @@ -13551,7 +13638,7 @@ binder. occurrences of the Unchecked_Access attribute. @node No_Unchecked_Conversion,No_Unchecked_Deallocation,No_Unchecked_Access,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-conversion}@anchor{214} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-conversion}@anchor{218} @subsection No_Unchecked_Conversion @@ -13561,7 +13648,7 @@ occurrences of the Unchecked_Access attribute. dependences on the predefined generic function Unchecked_Conversion. @node No_Unchecked_Deallocation,No_Use_Of_Attribute,No_Unchecked_Conversion,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-deallocation}@anchor{215} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-deallocation}@anchor{219} @subsection No_Unchecked_Deallocation @@ -13571,7 +13658,7 @@ dependences on the predefined generic function Unchecked_Conversion. dependences on the predefined generic procedure Unchecked_Deallocation. @node No_Use_Of_Attribute,No_Use_Of_Entity,No_Unchecked_Deallocation,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-attribute}@anchor{216} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-attribute}@anchor{21a} @subsection No_Use_Of_Attribute @@ -13581,7 +13668,7 @@ dependences on the predefined generic procedure Unchecked_Deallocation. earlier versions of Ada. @node No_Use_Of_Entity,No_Use_Of_Pragma,No_Use_Of_Attribute,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-entity}@anchor{217} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-entity}@anchor{21b} @subsection No_Use_Of_Entity @@ -13601,7 +13688,7 @@ No_Use_Of_Entity => Ada.Text_IO.Put_Line @end example @node No_Use_Of_Pragma,Pure_Barriers,No_Use_Of_Entity,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-pragma}@anchor{218} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-pragma}@anchor{21c} @subsection No_Use_Of_Pragma @@ -13611,7 +13698,7 @@ No_Use_Of_Entity => Ada.Text_IO.Put_Line earlier versions of Ada. @node Pure_Barriers,Simple_Barriers,No_Use_Of_Pragma,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions pure-barriers}@anchor{219} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions pure-barriers}@anchor{21d} @subsection Pure_Barriers @@ -13662,7 +13749,7 @@ but still ensures absence of side effects, exceptions, and recursion during the evaluation of the barriers. @node Simple_Barriers,Static_Priorities,Pure_Barriers,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions simple-barriers}@anchor{21a} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions simple-barriers}@anchor{21e} @subsection Simple_Barriers @@ -13681,7 +13768,7 @@ compatibility purposes (and a warning will be generated for its use if warnings on obsolescent features are activated). @node Static_Priorities,Static_Storage_Size,Simple_Barriers,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-priorities}@anchor{21b} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-priorities}@anchor{21f} @subsection Static_Priorities @@ -13692,7 +13779,7 @@ are static, and that there are no dependences on the package @code{Ada.Dynamic_Priorities}. @node Static_Storage_Size,,Static_Priorities,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-storage-size}@anchor{21c} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-storage-size}@anchor{220} @subsection Static_Storage_Size @@ -13702,7 +13789,7 @@ are static, and that there are no dependences on the package in a Storage_Size pragma or attribute definition clause is static. @node Program Unit Level Restrictions,,Partition-Wide Restrictions,Standard and Implementation Defined Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions id3}@anchor{21d}@anchor{gnat_rm/standard_and_implementation_defined_restrictions program-unit-level-restrictions}@anchor{21e} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions id3}@anchor{221}@anchor{gnat_rm/standard_and_implementation_defined_restrictions program-unit-level-restrictions}@anchor{222} @section Program Unit Level Restrictions @@ -13733,7 +13820,7 @@ other compilation units in the partition. @end menu @node No_Elaboration_Code,No_Dynamic_Accessibility_Checks,,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-elaboration-code}@anchor{21f} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-elaboration-code}@anchor{223} @subsection No_Elaboration_Code @@ -13789,7 +13876,7 @@ associated with the unit. This counter is typically used to check for access before elaboration and to control multiple elaboration attempts. @node No_Dynamic_Accessibility_Checks,No_Dynamic_Sized_Objects,No_Elaboration_Code,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-accessibility-checks}@anchor{220} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-accessibility-checks}@anchor{224} @subsection No_Dynamic_Accessibility_Checks @@ -13838,7 +13925,7 @@ In all other cases, the level of T is as defined by the existing rules of Ada. @end itemize @node No_Dynamic_Sized_Objects,No_Entry_Queue,No_Dynamic_Accessibility_Checks,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-sized-objects}@anchor{221} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-sized-objects}@anchor{225} @subsection No_Dynamic_Sized_Objects @@ -13856,7 +13943,7 @@ access discriminants. It is often a good idea to combine this restriction with No_Secondary_Stack. @node No_Entry_Queue,No_Implementation_Aspect_Specifications,No_Dynamic_Sized_Objects,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-queue}@anchor{222} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-queue}@anchor{226} @subsection No_Entry_Queue @@ -13869,7 +13956,7 @@ checked at compile time. A program execution is erroneous if an attempt is made to queue a second task on such an entry. @node No_Implementation_Aspect_Specifications,No_Implementation_Attributes,No_Entry_Queue,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-aspect-specifications}@anchor{223} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-aspect-specifications}@anchor{227} @subsection No_Implementation_Aspect_Specifications @@ -13880,7 +13967,7 @@ GNAT-defined aspects are present. With this restriction, the only aspects that can be used are those defined in the Ada Reference Manual. @node No_Implementation_Attributes,No_Implementation_Identifiers,No_Implementation_Aspect_Specifications,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-attributes}@anchor{224} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-attributes}@anchor{228} @subsection No_Implementation_Attributes @@ -13892,7 +13979,7 @@ attributes that can be used are those defined in the Ada Reference Manual. @node No_Implementation_Identifiers,No_Implementation_Pragmas,No_Implementation_Attributes,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-identifiers}@anchor{225} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-identifiers}@anchor{229} @subsection No_Implementation_Identifiers @@ -13903,7 +13990,7 @@ implementation-defined identifiers (marked with pragma Implementation_Defined) occur within language-defined packages. @node No_Implementation_Pragmas,No_Implementation_Restrictions,No_Implementation_Identifiers,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-pragmas}@anchor{226} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-pragmas}@anchor{22a} @subsection No_Implementation_Pragmas @@ -13914,7 +14001,7 @@ GNAT-defined pragmas are present. With this restriction, the only pragmas that can be used are those defined in the Ada Reference Manual. @node No_Implementation_Restrictions,No_Implementation_Units,No_Implementation_Pragmas,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-restrictions}@anchor{227} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-restrictions}@anchor{22b} @subsection No_Implementation_Restrictions @@ -13926,7 +14013,7 @@ are present. With this restriction, the only other restriction identifiers that can be used are those defined in the Ada Reference Manual. @node No_Implementation_Units,No_Implicit_Aliasing,No_Implementation_Restrictions,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-units}@anchor{228} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-units}@anchor{22c} @subsection No_Implementation_Units @@ -13937,7 +14024,7 @@ mention in the context clause of any implementation-defined descendants of packages Ada, Interfaces, or System. @node No_Implicit_Aliasing,No_Implicit_Loops,No_Implementation_Units,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-aliasing}@anchor{229} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-aliasing}@anchor{22d} @subsection No_Implicit_Aliasing @@ -13952,7 +14039,7 @@ to be aliased, and in such cases, it can always be replaced by the standard attribute Unchecked_Access which is preferable. @node No_Implicit_Loops,No_Obsolescent_Features,No_Implicit_Aliasing,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-loops}@anchor{22a} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-loops}@anchor{22e} @subsection No_Implicit_Loops @@ -13969,7 +14056,7 @@ arrays larger than about 5000 scalar components. Note that if this restriction is set in the spec of a package, it will not apply to its body. @node No_Obsolescent_Features,No_Wide_Characters,No_Implicit_Loops,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-obsolescent-features}@anchor{22b} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-obsolescent-features}@anchor{22f} @subsection No_Obsolescent_Features @@ -13979,7 +14066,7 @@ is set in the spec of a package, it will not apply to its body. features are used, as defined in Annex J of the Ada Reference Manual. @node No_Wide_Characters,Static_Dispatch_Tables,No_Obsolescent_Features,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-wide-characters}@anchor{22c} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-wide-characters}@anchor{230} @subsection No_Wide_Characters @@ -13993,7 +14080,7 @@ appear in the program (that is literals representing characters not in type @code{Character}). @node Static_Dispatch_Tables,SPARK_05,No_Wide_Characters,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-dispatch-tables}@anchor{22d} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-dispatch-tables}@anchor{231} @subsection Static_Dispatch_Tables @@ -14003,7 +14090,7 @@ type @code{Character}). associated with dispatch tables can be placed in read-only memory. @node SPARK_05,,Static_Dispatch_Tables,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions spark-05}@anchor{22e} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions spark-05}@anchor{232} @subsection SPARK_05 @@ -14026,7 +14113,7 @@ gnatprove -P project.gpr --mode=check_all @end example @node Implementation Advice,Implementation Defined Characteristics,Standard and Implementation Defined Restrictions,Top -@anchor{gnat_rm/implementation_advice doc}@anchor{22f}@anchor{gnat_rm/implementation_advice id1}@anchor{230}@anchor{gnat_rm/implementation_advice implementation-advice}@anchor{a} +@anchor{gnat_rm/implementation_advice doc}@anchor{233}@anchor{gnat_rm/implementation_advice id1}@anchor{234}@anchor{gnat_rm/implementation_advice implementation-advice}@anchor{a} @chapter Implementation Advice @@ -14124,7 +14211,7 @@ case the text describes what GNAT does and why. @end menu @node RM 1 1 3 20 Error Detection,RM 1 1 3 31 Child Units,,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-1-1-3-20-error-detection}@anchor{231} +@anchor{gnat_rm/implementation_advice rm-1-1-3-20-error-detection}@anchor{235} @section RM 1.1.3(20): Error Detection @@ -14141,7 +14228,7 @@ or diagnosed at compile time. @geindex Child Units @node RM 1 1 3 31 Child Units,RM 1 1 5 12 Bounded Errors,RM 1 1 3 20 Error Detection,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-1-1-3-31-child-units}@anchor{232} +@anchor{gnat_rm/implementation_advice rm-1-1-3-31-child-units}@anchor{236} @section RM 1.1.3(31): Child Units @@ -14157,7 +14244,7 @@ Followed. @geindex Bounded errors @node RM 1 1 5 12 Bounded Errors,RM 2 8 16 Pragmas,RM 1 1 3 31 Child Units,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-1-1-5-12-bounded-errors}@anchor{233} +@anchor{gnat_rm/implementation_advice rm-1-1-5-12-bounded-errors}@anchor{237} @section RM 1.1.5(12): Bounded Errors @@ -14174,7 +14261,7 @@ runtime. @geindex Pragmas @node RM 2 8 16 Pragmas,RM 2 8 17-19 Pragmas,RM 1 1 5 12 Bounded Errors,Implementation Advice -@anchor{gnat_rm/implementation_advice id2}@anchor{234}@anchor{gnat_rm/implementation_advice rm-2-8-16-pragmas}@anchor{235} +@anchor{gnat_rm/implementation_advice id2}@anchor{238}@anchor{gnat_rm/implementation_advice rm-2-8-16-pragmas}@anchor{239} @section RM 2.8(16): Pragmas @@ -14287,7 +14374,7 @@ that this advice not be followed. For details see @ref{7,,Implementation Defined Pragmas}. @node RM 2 8 17-19 Pragmas,RM 3 5 2 5 Alternative Character Sets,RM 2 8 16 Pragmas,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-2-8-17-19-pragmas}@anchor{236} +@anchor{gnat_rm/implementation_advice rm-2-8-17-19-pragmas}@anchor{23a} @section RM 2.8(17-19): Pragmas @@ -14308,14 +14395,14 @@ replacing @code{library_items}.” @end itemize @end quotation -See @ref{235,,RM 2.8(16); Pragmas}. +See @ref{239,,RM 2.8(16); Pragmas}. @geindex Character Sets @geindex Alternative Character Sets @node RM 3 5 2 5 Alternative Character Sets,RM 3 5 4 28 Integer Types,RM 2 8 17-19 Pragmas,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-3-5-2-5-alternative-character-sets}@anchor{237} +@anchor{gnat_rm/implementation_advice rm-3-5-2-5-alternative-character-sets}@anchor{23b} @section RM 3.5.2(5): Alternative Character Sets @@ -14343,7 +14430,7 @@ there is no such restriction. @geindex Integer types @node RM 3 5 4 28 Integer Types,RM 3 5 4 29 Integer Types,RM 3 5 2 5 Alternative Character Sets,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-3-5-4-28-integer-types}@anchor{238} +@anchor{gnat_rm/implementation_advice rm-3-5-4-28-integer-types}@anchor{23c} @section RM 3.5.4(28): Integer Types @@ -14362,7 +14449,7 @@ are supported for convenient interface to C, and so that all hardware types of the machine are easily available. @node RM 3 5 4 29 Integer Types,RM 3 5 5 8 Enumeration Values,RM 3 5 4 28 Integer Types,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-3-5-4-29-integer-types}@anchor{239} +@anchor{gnat_rm/implementation_advice rm-3-5-4-29-integer-types}@anchor{23d} @section RM 3.5.4(29): Integer Types @@ -14378,7 +14465,7 @@ Followed. @geindex Enumeration values @node RM 3 5 5 8 Enumeration Values,RM 3 5 7 17 Float Types,RM 3 5 4 29 Integer Types,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-3-5-5-8-enumeration-values}@anchor{23a} +@anchor{gnat_rm/implementation_advice rm-3-5-5-8-enumeration-values}@anchor{23e} @section RM 3.5.5(8): Enumeration Values @@ -14398,7 +14485,7 @@ Followed. @geindex Float types @node RM 3 5 7 17 Float Types,RM 3 6 2 11 Multidimensional Arrays,RM 3 5 5 8 Enumeration Values,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-3-5-7-17-float-types}@anchor{23b} +@anchor{gnat_rm/implementation_advice rm-3-5-7-17-float-types}@anchor{23f} @section RM 3.5.7(17): Float Types @@ -14428,7 +14515,7 @@ is a software rather than a hardware format. @geindex multidimensional @node RM 3 6 2 11 Multidimensional Arrays,RM 9 6 30-31 Duration’Small,RM 3 5 7 17 Float Types,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-3-6-2-11-multidimensional-arrays}@anchor{23c} +@anchor{gnat_rm/implementation_advice rm-3-6-2-11-multidimensional-arrays}@anchor{240} @section RM 3.6.2(11): Multidimensional Arrays @@ -14446,7 +14533,7 @@ Followed. @geindex Duration'Small @node RM 9 6 30-31 Duration’Small,RM 10 2 1 12 Consistent Representation,RM 3 6 2 11 Multidimensional Arrays,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-9-6-30-31-duration-small}@anchor{23d} +@anchor{gnat_rm/implementation_advice rm-9-6-30-31-duration-small}@anchor{241} @section RM 9.6(30-31): Duration’Small @@ -14467,7 +14554,7 @@ it need not be the same time base as used for @code{Calendar.Clock}.” Followed. @node RM 10 2 1 12 Consistent Representation,RM 11 4 1 19 Exception Information,RM 9 6 30-31 Duration’Small,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-10-2-1-12-consistent-representation}@anchor{23e} +@anchor{gnat_rm/implementation_advice rm-10-2-1-12-consistent-representation}@anchor{242} @section RM 10.2.1(12): Consistent Representation @@ -14489,7 +14576,7 @@ advice without severely impacting efficiency of execution. @geindex Exception information @node RM 11 4 1 19 Exception Information,RM 11 5 28 Suppression of Checks,RM 10 2 1 12 Consistent Representation,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-11-4-1-19-exception-information}@anchor{23f} +@anchor{gnat_rm/implementation_advice rm-11-4-1-19-exception-information}@anchor{243} @section RM 11.4.1(19): Exception Information @@ -14520,7 +14607,7 @@ Pragma @code{Discard_Names}. @geindex suppression of @node RM 11 5 28 Suppression of Checks,RM 13 1 21-24 Representation Clauses,RM 11 4 1 19 Exception Information,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-11-5-28-suppression-of-checks}@anchor{240} +@anchor{gnat_rm/implementation_advice rm-11-5-28-suppression-of-checks}@anchor{244} @section RM 11.5(28): Suppression of Checks @@ -14535,7 +14622,7 @@ Followed. @geindex Representation clauses @node RM 13 1 21-24 Representation Clauses,RM 13 2 6-8 Packed Types,RM 11 5 28 Suppression of Checks,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-1-21-24-representation-clauses}@anchor{241} +@anchor{gnat_rm/implementation_advice rm-13-1-21-24-representation-clauses}@anchor{245} @section RM 13.1 (21-24): Representation Clauses @@ -14587,7 +14674,7 @@ Followed. @geindex Packed types @node RM 13 2 6-8 Packed Types,RM 13 3 14-19 Address Clauses,RM 13 1 21-24 Representation Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-2-6-8-packed-types}@anchor{242} +@anchor{gnat_rm/implementation_advice rm-13-2-6-8-packed-types}@anchor{246} @section RM 13.2(6-8): Packed Types @@ -14618,7 +14705,7 @@ subcomponent of the packed type. @geindex Address clauses @node RM 13 3 14-19 Address Clauses,RM 13 3 29-35 Alignment Clauses,RM 13 2 6-8 Packed Types,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-3-14-19-address-clauses}@anchor{243} +@anchor{gnat_rm/implementation_advice rm-13-3-14-19-address-clauses}@anchor{247} @section RM 13.3(14-19): Address Clauses @@ -14671,7 +14758,7 @@ Followed. @geindex Alignment clauses @node RM 13 3 29-35 Alignment Clauses,RM 13 3 42-43 Size Clauses,RM 13 3 14-19 Address Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-3-29-35-alignment-clauses}@anchor{244} +@anchor{gnat_rm/implementation_advice rm-13-3-29-35-alignment-clauses}@anchor{248} @section RM 13.3(29-35): Alignment Clauses @@ -14728,7 +14815,7 @@ Followed. @geindex Size clauses @node RM 13 3 42-43 Size Clauses,RM 13 3 50-56 Size Clauses,RM 13 3 29-35 Alignment Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-3-42-43-size-clauses}@anchor{245} +@anchor{gnat_rm/implementation_advice rm-13-3-42-43-size-clauses}@anchor{249} @section RM 13.3(42-43): Size Clauses @@ -14746,7 +14833,7 @@ object’s @code{Alignment} (if the @code{Alignment} is nonzero).” Followed. @node RM 13 3 50-56 Size Clauses,RM 13 3 71-73 Component Size Clauses,RM 13 3 42-43 Size Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-3-50-56-size-clauses}@anchor{246} +@anchor{gnat_rm/implementation_advice rm-13-3-50-56-size-clauses}@anchor{24a} @section RM 13.3(50-56): Size Clauses @@ -14797,7 +14884,7 @@ Followed. @geindex Component_Size clauses @node RM 13 3 71-73 Component Size Clauses,RM 13 4 9-10 Enumeration Representation Clauses,RM 13 3 50-56 Size Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-3-71-73-component-size-clauses}@anchor{247} +@anchor{gnat_rm/implementation_advice rm-13-3-71-73-component-size-clauses}@anchor{24b} @section RM 13.3(71-73): Component Size Clauses @@ -14831,7 +14918,7 @@ Followed. @geindex enumeration @node RM 13 4 9-10 Enumeration Representation Clauses,RM 13 5 1 17-22 Record Representation Clauses,RM 13 3 71-73 Component Size Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-4-9-10-enumeration-representation-clauses}@anchor{248} +@anchor{gnat_rm/implementation_advice rm-13-4-9-10-enumeration-representation-clauses}@anchor{24c} @section RM 13.4(9-10): Enumeration Representation Clauses @@ -14853,7 +14940,7 @@ Followed. @geindex records @node RM 13 5 1 17-22 Record Representation Clauses,RM 13 5 2 5 Storage Place Attributes,RM 13 4 9-10 Enumeration Representation Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-5-1-17-22-record-representation-clauses}@anchor{249} +@anchor{gnat_rm/implementation_advice rm-13-5-1-17-22-record-representation-clauses}@anchor{24d} @section RM 13.5.1(17-22): Record Representation Clauses @@ -14913,7 +15000,7 @@ and all mentioned features are implemented. @geindex Storage place attributes @node RM 13 5 2 5 Storage Place Attributes,RM 13 5 3 7-8 Bit Ordering,RM 13 5 1 17-22 Record Representation Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-5-2-5-storage-place-attributes}@anchor{24a} +@anchor{gnat_rm/implementation_advice rm-13-5-2-5-storage-place-attributes}@anchor{24e} @section RM 13.5.2(5): Storage Place Attributes @@ -14933,7 +15020,7 @@ Followed. There are no such components in GNAT. @geindex Bit ordering @node RM 13 5 3 7-8 Bit Ordering,RM 13 7 37 Address as Private,RM 13 5 2 5 Storage Place Attributes,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-5-3-7-8-bit-ordering}@anchor{24b} +@anchor{gnat_rm/implementation_advice rm-13-5-3-7-8-bit-ordering}@anchor{24f} @section RM 13.5.3(7-8): Bit Ordering @@ -14951,7 +15038,7 @@ Followed. @geindex as private type @node RM 13 7 37 Address as Private,RM 13 7 1 16 Address Operations,RM 13 5 3 7-8 Bit Ordering,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-7-37-address-as-private}@anchor{24c} +@anchor{gnat_rm/implementation_advice rm-13-7-37-address-as-private}@anchor{250} @section RM 13.7(37): Address as Private @@ -14969,7 +15056,7 @@ Followed. @geindex operations of @node RM 13 7 1 16 Address Operations,RM 13 9 14-17 Unchecked Conversion,RM 13 7 37 Address as Private,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-7-1-16-address-operations}@anchor{24d} +@anchor{gnat_rm/implementation_advice rm-13-7-1-16-address-operations}@anchor{251} @section RM 13.7.1(16): Address Operations @@ -14987,7 +15074,7 @@ operation raises @code{Program_Error}, since all operations make sense. @geindex Unchecked conversion @node RM 13 9 14-17 Unchecked Conversion,RM 13 11 23-25 Implicit Heap Usage,RM 13 7 1 16 Address Operations,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-9-14-17-unchecked-conversion}@anchor{24e} +@anchor{gnat_rm/implementation_advice rm-13-9-14-17-unchecked-conversion}@anchor{252} @section RM 13.9(14-17): Unchecked Conversion @@ -15031,7 +15118,7 @@ Followed. @geindex implicit @node RM 13 11 23-25 Implicit Heap Usage,RM 13 11 2 17 Unchecked Deallocation,RM 13 9 14-17 Unchecked Conversion,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-11-23-25-implicit-heap-usage}@anchor{24f} +@anchor{gnat_rm/implementation_advice rm-13-11-23-25-implicit-heap-usage}@anchor{253} @section RM 13.11(23-25): Implicit Heap Usage @@ -15082,7 +15169,7 @@ Followed. @geindex Unchecked deallocation @node RM 13 11 2 17 Unchecked Deallocation,RM 13 13 2 1 6 Stream Oriented Attributes,RM 13 11 23-25 Implicit Heap Usage,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-11-2-17-unchecked-deallocation}@anchor{250} +@anchor{gnat_rm/implementation_advice rm-13-11-2-17-unchecked-deallocation}@anchor{254} @section RM 13.11.2(17): Unchecked Deallocation @@ -15097,7 +15184,7 @@ Followed. @geindex Stream oriented attributes @node RM 13 13 2 1 6 Stream Oriented Attributes,RM A 1 52 Names of Predefined Numeric Types,RM 13 11 2 17 Unchecked Deallocation,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-13-2-1-6-stream-oriented-attributes}@anchor{251} +@anchor{gnat_rm/implementation_advice rm-13-13-2-1-6-stream-oriented-attributes}@anchor{255} @section RM 13.13.2(1.6): Stream Oriented Attributes @@ -15128,7 +15215,7 @@ scalar types. This XDR alternative can be enabled via the binder switch -xdr. @geindex Stream oriented attributes @node RM A 1 52 Names of Predefined Numeric Types,RM A 3 2 49 Ada Characters Handling,RM 13 13 2 1 6 Stream Oriented Attributes,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-a-1-52-names-of-predefined-numeric-types}@anchor{252} +@anchor{gnat_rm/implementation_advice rm-a-1-52-names-of-predefined-numeric-types}@anchor{256} @section RM A.1(52): Names of Predefined Numeric Types @@ -15146,7 +15233,7 @@ Followed. @geindex Ada.Characters.Handling @node RM A 3 2 49 Ada Characters Handling,RM A 4 4 106 Bounded-Length String Handling,RM A 1 52 Names of Predefined Numeric Types,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-a-3-2-49-ada-characters-handling}@anchor{253} +@anchor{gnat_rm/implementation_advice rm-a-3-2-49-ada-characters-handling}@anchor{257} @section RM A.3.2(49): @code{Ada.Characters.Handling} @@ -15163,7 +15250,7 @@ Followed. GNAT provides no such localized definitions. @geindex Bounded-length strings @node RM A 4 4 106 Bounded-Length String Handling,RM A 5 2 46-47 Random Number Generation,RM A 3 2 49 Ada Characters Handling,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-a-4-4-106-bounded-length-string-handling}@anchor{254} +@anchor{gnat_rm/implementation_advice rm-a-4-4-106-bounded-length-string-handling}@anchor{258} @section RM A.4.4(106): Bounded-Length String Handling @@ -15178,7 +15265,7 @@ Followed. No implicit pointers or dynamic allocation are used. @geindex Random number generation @node RM A 5 2 46-47 Random Number Generation,RM A 10 7 23 Get_Immediate,RM A 4 4 106 Bounded-Length String Handling,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-a-5-2-46-47-random-number-generation}@anchor{255} +@anchor{gnat_rm/implementation_advice rm-a-5-2-46-47-random-number-generation}@anchor{259} @section RM A.5.2(46-47): Random Number Generation @@ -15207,7 +15294,7 @@ condition here to hold true. @geindex Get_Immediate @node RM A 10 7 23 Get_Immediate,RM A 18 Containers,RM A 5 2 46-47 Random Number Generation,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-a-10-7-23-get-immediate}@anchor{256} +@anchor{gnat_rm/implementation_advice rm-a-10-7-23-get-immediate}@anchor{25a} @section RM A.10.7(23): @code{Get_Immediate} @@ -15231,7 +15318,7 @@ this functionality. @geindex Containers @node RM A 18 Containers,RM B 1 39-41 Pragma Export,RM A 10 7 23 Get_Immediate,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-a-18-containers}@anchor{257} +@anchor{gnat_rm/implementation_advice rm-a-18-containers}@anchor{25b} @section RM A.18: @code{Containers} @@ -15252,7 +15339,7 @@ follow the implementation advice. @geindex Export @node RM B 1 39-41 Pragma Export,RM B 2 12-13 Package Interfaces,RM A 18 Containers,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-b-1-39-41-pragma-export}@anchor{258} +@anchor{gnat_rm/implementation_advice rm-b-1-39-41-pragma-export}@anchor{25c} @section RM B.1(39-41): Pragma @code{Export} @@ -15300,7 +15387,7 @@ Followed. @geindex Interfaces @node RM B 2 12-13 Package Interfaces,RM B 3 63-71 Interfacing with C,RM B 1 39-41 Pragma Export,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-b-2-12-13-package-interfaces}@anchor{259} +@anchor{gnat_rm/implementation_advice rm-b-2-12-13-package-interfaces}@anchor{25d} @section RM B.2(12-13): Package @code{Interfaces} @@ -15330,7 +15417,7 @@ Followed. GNAT provides all the packages described in this section. @geindex interfacing with @node RM B 3 63-71 Interfacing with C,RM B 4 95-98 Interfacing with COBOL,RM B 2 12-13 Package Interfaces,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-b-3-63-71-interfacing-with-c}@anchor{25a} +@anchor{gnat_rm/implementation_advice rm-b-3-63-71-interfacing-with-c}@anchor{25e} @section RM B.3(63-71): Interfacing with C @@ -15418,7 +15505,7 @@ Followed. @geindex interfacing with @node RM B 4 95-98 Interfacing with COBOL,RM B 5 22-26 Interfacing with Fortran,RM B 3 63-71 Interfacing with C,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-b-4-95-98-interfacing-with-cobol}@anchor{25b} +@anchor{gnat_rm/implementation_advice rm-b-4-95-98-interfacing-with-cobol}@anchor{25f} @section RM B.4(95-98): Interfacing with COBOL @@ -15459,7 +15546,7 @@ Followed. @geindex interfacing with @node RM B 5 22-26 Interfacing with Fortran,RM C 1 3-5 Access to Machine Operations,RM B 4 95-98 Interfacing with COBOL,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-b-5-22-26-interfacing-with-fortran}@anchor{25c} +@anchor{gnat_rm/implementation_advice rm-b-5-22-26-interfacing-with-fortran}@anchor{260} @section RM B.5(22-26): Interfacing with Fortran @@ -15510,7 +15597,7 @@ Followed. @geindex Machine operations @node RM C 1 3-5 Access to Machine Operations,RM C 1 10-16 Access to Machine Operations,RM B 5 22-26 Interfacing with Fortran,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-1-3-5-access-to-machine-operations}@anchor{25d} +@anchor{gnat_rm/implementation_advice rm-c-1-3-5-access-to-machine-operations}@anchor{261} @section RM C.1(3-5): Access to Machine Operations @@ -15545,7 +15632,7 @@ object that is specified as exported.” Followed. @node RM C 1 10-16 Access to Machine Operations,RM C 3 28 Interrupt Support,RM C 1 3-5 Access to Machine Operations,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-1-10-16-access-to-machine-operations}@anchor{25e} +@anchor{gnat_rm/implementation_advice rm-c-1-10-16-access-to-machine-operations}@anchor{262} @section RM C.1(10-16): Access to Machine Operations @@ -15606,7 +15693,7 @@ Followed on any target supporting such operations. @geindex Interrupt support @node RM C 3 28 Interrupt Support,RM C 3 1 20-21 Protected Procedure Handlers,RM C 1 10-16 Access to Machine Operations,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-3-28-interrupt-support}@anchor{25f} +@anchor{gnat_rm/implementation_advice rm-c-3-28-interrupt-support}@anchor{263} @section RM C.3(28): Interrupt Support @@ -15624,7 +15711,7 @@ of interrupt blocking. @geindex Protected procedure handlers @node RM C 3 1 20-21 Protected Procedure Handlers,RM C 3 2 25 Package Interrupts,RM C 3 28 Interrupt Support,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-3-1-20-21-protected-procedure-handlers}@anchor{260} +@anchor{gnat_rm/implementation_advice rm-c-3-1-20-21-protected-procedure-handlers}@anchor{264} @section RM C.3.1(20-21): Protected Procedure Handlers @@ -15650,7 +15737,7 @@ Followed. Compile time warnings are given when possible. @geindex Interrupts @node RM C 3 2 25 Package Interrupts,RM C 4 14 Pre-elaboration Requirements,RM C 3 1 20-21 Protected Procedure Handlers,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-3-2-25-package-interrupts}@anchor{261} +@anchor{gnat_rm/implementation_advice rm-c-3-2-25-package-interrupts}@anchor{265} @section RM C.3.2(25): Package @code{Interrupts} @@ -15668,7 +15755,7 @@ Followed. @geindex Pre-elaboration requirements @node RM C 4 14 Pre-elaboration Requirements,RM C 5 8 Pragma Discard_Names,RM C 3 2 25 Package Interrupts,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-4-14-pre-elaboration-requirements}@anchor{262} +@anchor{gnat_rm/implementation_advice rm-c-4-14-pre-elaboration-requirements}@anchor{266} @section RM C.4(14): Pre-elaboration Requirements @@ -15684,7 +15771,7 @@ Followed. Executable code is generated in some cases, e.g., loops to initialize large arrays. @node RM C 5 8 Pragma Discard_Names,RM C 7 2 30 The Package Task_Attributes,RM C 4 14 Pre-elaboration Requirements,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-5-8-pragma-discard-names}@anchor{263} +@anchor{gnat_rm/implementation_advice rm-c-5-8-pragma-discard-names}@anchor{267} @section RM C.5(8): Pragma @code{Discard_Names} @@ -15702,7 +15789,7 @@ Followed. @geindex Task_Attributes @node RM C 7 2 30 The Package Task_Attributes,RM D 3 17 Locking Policies,RM C 5 8 Pragma Discard_Names,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-7-2-30-the-package-task-attributes}@anchor{264} +@anchor{gnat_rm/implementation_advice rm-c-7-2-30-the-package-task-attributes}@anchor{268} @section RM C.7.2(30): The Package Task_Attributes @@ -15723,7 +15810,7 @@ Not followed. This implementation is not targeted to such a domain. @geindex Locking Policies @node RM D 3 17 Locking Policies,RM D 4 16 Entry Queuing Policies,RM C 7 2 30 The Package Task_Attributes,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-d-3-17-locking-policies}@anchor{265} +@anchor{gnat_rm/implementation_advice rm-d-3-17-locking-policies}@anchor{269} @section RM D.3(17): Locking Policies @@ -15740,7 +15827,7 @@ whose names (@code{Inheritance_Locking} and @geindex Entry queuing policies @node RM D 4 16 Entry Queuing Policies,RM D 6 9-10 Preemptive Abort,RM D 3 17 Locking Policies,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-d-4-16-entry-queuing-policies}@anchor{266} +@anchor{gnat_rm/implementation_advice rm-d-4-16-entry-queuing-policies}@anchor{26a} @section RM D.4(16): Entry Queuing Policies @@ -15755,7 +15842,7 @@ Followed. No such implementation-defined queuing policies exist. @geindex Preemptive abort @node RM D 6 9-10 Preemptive Abort,RM D 7 21 Tasking Restrictions,RM D 4 16 Entry Queuing Policies,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-d-6-9-10-preemptive-abort}@anchor{267} +@anchor{gnat_rm/implementation_advice rm-d-6-9-10-preemptive-abort}@anchor{26b} @section RM D.6(9-10): Preemptive Abort @@ -15781,7 +15868,7 @@ Followed. @geindex Tasking restrictions @node RM D 7 21 Tasking Restrictions,RM D 8 47-49 Monotonic Time,RM D 6 9-10 Preemptive Abort,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-d-7-21-tasking-restrictions}@anchor{268} +@anchor{gnat_rm/implementation_advice rm-d-7-21-tasking-restrictions}@anchor{26c} @section RM D.7(21): Tasking Restrictions @@ -15800,7 +15887,7 @@ pragma @code{Profile (Restricted)} for more details. @geindex monotonic @node RM D 8 47-49 Monotonic Time,RM E 5 28-29 Partition Communication Subsystem,RM D 7 21 Tasking Restrictions,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-d-8-47-49-monotonic-time}@anchor{269} +@anchor{gnat_rm/implementation_advice rm-d-8-47-49-monotonic-time}@anchor{26d} @section RM D.8(47-49): Monotonic Time @@ -15835,7 +15922,7 @@ Followed. @geindex PCS @node RM E 5 28-29 Partition Communication Subsystem,RM F 7 COBOL Support,RM D 8 47-49 Monotonic Time,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-e-5-28-29-partition-communication-subsystem}@anchor{26a} +@anchor{gnat_rm/implementation_advice rm-e-5-28-29-partition-communication-subsystem}@anchor{26e} @section RM E.5(28-29): Partition Communication Subsystem @@ -15847,8 +15934,7 @@ should allow them to block until the corresponding subprogram body returns.” @end quotation -Followed by GLADE, a separately supplied PCS that can be used with -GNAT. +A separately supplied PCS that can be used with GNAT when combined with the PolyORB product. @quotation @@ -15857,13 +15943,10 @@ should raise @code{Storage_Error} if it runs out of space trying to write the @code{Item} into the stream.” @end quotation -Followed by GLADE, a separately supplied PCS that can be used with -GNAT. - @geindex COBOL support @node RM F 7 COBOL Support,RM F 1 2 Decimal Radix Support,RM E 5 28-29 Partition Communication Subsystem,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-f-7-cobol-support}@anchor{26b} +@anchor{gnat_rm/implementation_advice rm-f-7-cobol-support}@anchor{26f} @section RM F(7): COBOL Support @@ -15883,7 +15966,7 @@ Followed. @geindex Decimal radix support @node RM F 1 2 Decimal Radix Support,RM G Numerics,RM F 7 COBOL Support,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-f-1-2-decimal-radix-support}@anchor{26c} +@anchor{gnat_rm/implementation_advice rm-f-1-2-decimal-radix-support}@anchor{270} @section RM F.1(2): Decimal Radix Support @@ -15899,7 +15982,7 @@ representations. @geindex Numerics @node RM G Numerics,RM G 1 1 56-58 Complex Types,RM F 1 2 Decimal Radix Support,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-g-numerics}@anchor{26d} +@anchor{gnat_rm/implementation_advice rm-g-numerics}@anchor{271} @section RM G: Numerics @@ -15919,7 +16002,7 @@ Followed. @geindex Complex types @node RM G 1 1 56-58 Complex Types,RM G 1 2 49 Complex Elementary Functions,RM G Numerics,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-g-1-1-56-58-complex-types}@anchor{26e} +@anchor{gnat_rm/implementation_advice rm-g-1-1-56-58-complex-types}@anchor{272} @section RM G.1.1(56-58): Complex Types @@ -15981,7 +16064,7 @@ Followed. @geindex Complex elementary functions @node RM G 1 2 49 Complex Elementary Functions,RM G 2 4 19 Accuracy Requirements,RM G 1 1 56-58 Complex Types,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-g-1-2-49-complex-elementary-functions}@anchor{26f} +@anchor{gnat_rm/implementation_advice rm-g-1-2-49-complex-elementary-functions}@anchor{273} @section RM G.1.2(49): Complex Elementary Functions @@ -16003,7 +16086,7 @@ Followed. @geindex Accuracy requirements @node RM G 2 4 19 Accuracy Requirements,RM G 2 6 15 Complex Arithmetic Accuracy,RM G 1 2 49 Complex Elementary Functions,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-g-2-4-19-accuracy-requirements}@anchor{270} +@anchor{gnat_rm/implementation_advice rm-g-2-4-19-accuracy-requirements}@anchor{274} @section RM G.2.4(19): Accuracy Requirements @@ -16027,7 +16110,7 @@ Followed. @geindex complex arithmetic @node RM G 2 6 15 Complex Arithmetic Accuracy,RM H 6 15/2 Pragma Partition_Elaboration_Policy,RM G 2 4 19 Accuracy Requirements,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-g-2-6-15-complex-arithmetic-accuracy}@anchor{271} +@anchor{gnat_rm/implementation_advice rm-g-2-6-15-complex-arithmetic-accuracy}@anchor{275} @section RM G.2.6(15): Complex Arithmetic Accuracy @@ -16045,7 +16128,7 @@ Followed. @geindex Sequential elaboration policy @node RM H 6 15/2 Pragma Partition_Elaboration_Policy,,RM G 2 6 15 Complex Arithmetic Accuracy,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-h-6-15-2-pragma-partition-elaboration-policy}@anchor{272} +@anchor{gnat_rm/implementation_advice rm-h-6-15-2-pragma-partition-elaboration-policy}@anchor{276} @section RM H.6(15/2): Pragma Partition_Elaboration_Policy @@ -16060,7 +16143,7 @@ immediately terminated.” Not followed. @node Implementation Defined Characteristics,Intrinsic Subprograms,Implementation Advice,Top -@anchor{gnat_rm/implementation_defined_characteristics doc}@anchor{273}@anchor{gnat_rm/implementation_defined_characteristics id1}@anchor{274}@anchor{gnat_rm/implementation_defined_characteristics implementation-defined-characteristics}@anchor{b} +@anchor{gnat_rm/implementation_defined_characteristics doc}@anchor{277}@anchor{gnat_rm/implementation_defined_characteristics id1}@anchor{278}@anchor{gnat_rm/implementation_defined_characteristics implementation-defined-characteristics}@anchor{b} @chapter Implementation Defined Characteristics @@ -16701,11 +16784,7 @@ may have been set by a call to @code{Ada.Command_Line.Set_Exit_Status}). “The mechanisms for building and running partitions. See 10.2(24).” @end itemize -GNAT itself supports programs with only a single partition. The GNATDIST -tool provided with the GLADE package (which also includes an implementation -of the PCS) provides a completely flexible method for building and running -programs consisting of multiple partitions. See the separate GLADE manual -for details. +GNAT itself supports programs with only a single partition. The PolyORB product (which also includes an implementation of the PCS) provides a completely flexible method for building and running programs consisting of multiple partitions. See the separate PolyORB user guide for details. @itemize * @@ -16726,7 +16805,7 @@ implementation. See 10.2(28).” @end itemize Passive partitions are supported on targets where shared memory is -provided by the operating system. See the GLADE reference manual for +provided by the operating system. See the PolyORB user guide for further details. @@ -16836,7 +16915,7 @@ Implementation-defined assertion_aspect_marks include Assert_And_Cut, Assume, Contract_Cases, Debug, Ghost, Initial_Condition, Loop_Invariant, Loop_Variant, Postcondition, Precondition, Predicate, Refined_Post, Statement_Assertions, and Subprogram_Variant. Implementation-defined -policy_identifiers include Ignore and Suppressible. +policy_identifiers include Disable and Suppressible. @itemize * @@ -16910,7 +16989,7 @@ See separate section on data representations. such aspects and the legality rules for such aspects. See 13.1.1(38).” @end itemize -See @ref{12e,,Implementation Defined Aspects}. +See @ref{130,,Implementation Defined Aspects}. @itemize * @@ -17354,7 +17433,7 @@ When the @code{Pattern} parameter is not the null string, it is interpreted according to the syntax of regular expressions as defined in the @code{GNAT.Regexp} package. -See @ref{275,,GNAT.Regexp (g-regexp.ads)}. +See @ref{279,,GNAT.Regexp (g-regexp.ads)}. @itemize * @@ -18112,8 +18191,8 @@ Unknown. programs. See E(5).” @end itemize -The GLADE package provides a utility GNATDIST for creating and executing -distributed programs. See the GLADE reference manual for further details. +The PolyORB product provides means creating and executing +distributed programs. See the PolyORB user guide for further details. @itemize * @@ -18123,7 +18202,7 @@ distributed programs. See the GLADE reference manual for further details. inaccessible. See E.1(7).” @end itemize -See the GLADE reference manual for full details on such events. +See the PolyORB user guide for full details on such events. @itemize * @@ -18133,7 +18212,7 @@ See the GLADE reference manual for full details on such events. shared resources between partitions in certain cases. See E.1(11).” @end itemize -See the GLADE reference manual for full details on these aspects of +See the PolyORB user guide for full details on these aspects of multi-partition execution. @@ -18144,7 +18223,7 @@ multi-partition execution. immediately aborted as a result of cancellation. See E.4(13).” @end itemize -See the GLADE reference manual for details on the effect of abort in +See the PolyORB user guide for details on the effect of abort in a distributed application. @@ -18163,7 +18242,7 @@ System.RPC.Partition_ID’Last is Integer’Last. See source file @code{s-rpc.ad “Implementation-defined interfaces in the PCS. See E.5(26).” @end itemize -See the GLADE reference manual for a full description of all +See the PolyORB user guide for a full description of all implementation defined interfaces. @@ -18452,7 +18531,7 @@ Information on those subjects is not yet available. Execution is erroneous in that case. @node Intrinsic Subprograms,Representation Clauses and Pragmas,Implementation Defined Characteristics,Top -@anchor{gnat_rm/intrinsic_subprograms doc}@anchor{276}@anchor{gnat_rm/intrinsic_subprograms id1}@anchor{277}@anchor{gnat_rm/intrinsic_subprograms intrinsic-subprograms}@anchor{c} +@anchor{gnat_rm/intrinsic_subprograms doc}@anchor{27a}@anchor{gnat_rm/intrinsic_subprograms id1}@anchor{27b}@anchor{gnat_rm/intrinsic_subprograms intrinsic-subprograms}@anchor{c} @chapter Intrinsic Subprograms @@ -18490,7 +18569,7 @@ Ada standard does not require Ada compilers to implement this feature. @end menu @node Intrinsic Operators,Compilation_ISO_Date,,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms id2}@anchor{278}@anchor{gnat_rm/intrinsic_subprograms intrinsic-operators}@anchor{279} +@anchor{gnat_rm/intrinsic_subprograms id2}@anchor{27c}@anchor{gnat_rm/intrinsic_subprograms intrinsic-operators}@anchor{27d} @section Intrinsic Operators @@ -18521,7 +18600,7 @@ It is also possible to specify such operators for private types, if the full views are appropriate arithmetic types. @node Compilation_ISO_Date,Compilation_Date,Intrinsic Operators,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms compilation-iso-date}@anchor{27a}@anchor{gnat_rm/intrinsic_subprograms id3}@anchor{27b} +@anchor{gnat_rm/intrinsic_subprograms compilation-iso-date}@anchor{27e}@anchor{gnat_rm/intrinsic_subprograms id3}@anchor{27f} @section Compilation_ISO_Date @@ -18535,7 +18614,7 @@ application program should simply call the function the current compilation (in local time format YYYY-MM-DD). @node Compilation_Date,Compilation_Time,Compilation_ISO_Date,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms compilation-date}@anchor{27c}@anchor{gnat_rm/intrinsic_subprograms id4}@anchor{27d} +@anchor{gnat_rm/intrinsic_subprograms compilation-date}@anchor{280}@anchor{gnat_rm/intrinsic_subprograms id4}@anchor{281} @section Compilation_Date @@ -18545,7 +18624,7 @@ Same as Compilation_ISO_Date, except the string is in the form MMM DD YYYY. @node Compilation_Time,Enclosing_Entity,Compilation_Date,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms compilation-time}@anchor{27e}@anchor{gnat_rm/intrinsic_subprograms id5}@anchor{27f} +@anchor{gnat_rm/intrinsic_subprograms compilation-time}@anchor{282}@anchor{gnat_rm/intrinsic_subprograms id5}@anchor{283} @section Compilation_Time @@ -18559,7 +18638,7 @@ application program should simply call the function the current compilation (in local time format HH:MM:SS). @node Enclosing_Entity,Exception_Information,Compilation_Time,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms enclosing-entity}@anchor{280}@anchor{gnat_rm/intrinsic_subprograms id6}@anchor{281} +@anchor{gnat_rm/intrinsic_subprograms enclosing-entity}@anchor{284}@anchor{gnat_rm/intrinsic_subprograms id6}@anchor{285} @section Enclosing_Entity @@ -18573,7 +18652,7 @@ application program should simply call the function the current subprogram, package, task, entry, or protected subprogram. @node Exception_Information,Exception_Message,Enclosing_Entity,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms exception-information}@anchor{282}@anchor{gnat_rm/intrinsic_subprograms id7}@anchor{283} +@anchor{gnat_rm/intrinsic_subprograms exception-information}@anchor{286}@anchor{gnat_rm/intrinsic_subprograms id7}@anchor{287} @section Exception_Information @@ -18587,7 +18666,7 @@ so an application program should simply call the function the exception information associated with the current exception. @node Exception_Message,Exception_Name,Exception_Information,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms exception-message}@anchor{284}@anchor{gnat_rm/intrinsic_subprograms id8}@anchor{285} +@anchor{gnat_rm/intrinsic_subprograms exception-message}@anchor{288}@anchor{gnat_rm/intrinsic_subprograms id8}@anchor{289} @section Exception_Message @@ -18601,7 +18680,7 @@ so an application program should simply call the function the message associated with the current exception. @node Exception_Name,File,Exception_Message,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms exception-name}@anchor{286}@anchor{gnat_rm/intrinsic_subprograms id9}@anchor{287} +@anchor{gnat_rm/intrinsic_subprograms exception-name}@anchor{28a}@anchor{gnat_rm/intrinsic_subprograms id9}@anchor{28b} @section Exception_Name @@ -18615,7 +18694,7 @@ so an application program should simply call the function the name of the current exception. @node File,Line,Exception_Name,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms file}@anchor{288}@anchor{gnat_rm/intrinsic_subprograms id10}@anchor{289} +@anchor{gnat_rm/intrinsic_subprograms file}@anchor{28c}@anchor{gnat_rm/intrinsic_subprograms id10}@anchor{28d} @section File @@ -18629,7 +18708,7 @@ application program should simply call the function file. @node Line,Shifts and Rotates,File,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms id11}@anchor{28a}@anchor{gnat_rm/intrinsic_subprograms line}@anchor{28b} +@anchor{gnat_rm/intrinsic_subprograms id11}@anchor{28e}@anchor{gnat_rm/intrinsic_subprograms line}@anchor{28f} @section Line @@ -18643,7 +18722,7 @@ application program should simply call the function source line. @node Shifts and Rotates,Source_Location,Line,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms id12}@anchor{28c}@anchor{gnat_rm/intrinsic_subprograms shifts-and-rotates}@anchor{28d} +@anchor{gnat_rm/intrinsic_subprograms id12}@anchor{290}@anchor{gnat_rm/intrinsic_subprograms shifts-and-rotates}@anchor{291} @section Shifts and Rotates @@ -18686,7 +18765,7 @@ corresponding operator for modular type. In particular, shifting a negative number may change its sign bit to positive. @node Source_Location,,Shifts and Rotates,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms id13}@anchor{28e}@anchor{gnat_rm/intrinsic_subprograms source-location}@anchor{28f} +@anchor{gnat_rm/intrinsic_subprograms id13}@anchor{292}@anchor{gnat_rm/intrinsic_subprograms source-location}@anchor{293} @section Source_Location @@ -18700,7 +18779,7 @@ application program should simply call the function source file location. @node Representation Clauses and Pragmas,Standard Library Routines,Intrinsic Subprograms,Top -@anchor{gnat_rm/representation_clauses_and_pragmas doc}@anchor{290}@anchor{gnat_rm/representation_clauses_and_pragmas id1}@anchor{291}@anchor{gnat_rm/representation_clauses_and_pragmas representation-clauses-and-pragmas}@anchor{d} +@anchor{gnat_rm/representation_clauses_and_pragmas doc}@anchor{294}@anchor{gnat_rm/representation_clauses_and_pragmas id1}@anchor{295}@anchor{gnat_rm/representation_clauses_and_pragmas representation-clauses-and-pragmas}@anchor{d} @chapter Representation Clauses and Pragmas @@ -18746,7 +18825,7 @@ and this section describes the additional capabilities provided. @end menu @node Alignment Clauses,Size Clauses,,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas alignment-clauses}@anchor{292}@anchor{gnat_rm/representation_clauses_and_pragmas id2}@anchor{293} +@anchor{gnat_rm/representation_clauses_and_pragmas alignment-clauses}@anchor{296}@anchor{gnat_rm/representation_clauses_and_pragmas id2}@anchor{297} @section Alignment Clauses @@ -18768,7 +18847,7 @@ For elementary types, the alignment is the minimum of the actual size of objects of the type divided by @code{Storage_Unit}, and the maximum alignment supported by the target. (This maximum alignment is given by the GNAT-specific attribute -@code{Standard'Maximum_Alignment}; see @ref{1a2,,Attribute Maximum_Alignment}.) +@code{Standard'Maximum_Alignment}; see @ref{1a6,,Attribute Maximum_Alignment}.) @geindex Maximum_Alignment attribute @@ -18877,7 +18956,7 @@ assumption is non-portable, and other compilers may choose different alignments for the subtype @code{RS}. @node Size Clauses,Storage_Size Clauses,Alignment Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id3}@anchor{294}@anchor{gnat_rm/representation_clauses_and_pragmas size-clauses}@anchor{295} +@anchor{gnat_rm/representation_clauses_and_pragmas id3}@anchor{298}@anchor{gnat_rm/representation_clauses_and_pragmas size-clauses}@anchor{299} @section Size Clauses @@ -18954,7 +19033,7 @@ if it is known that a Size value can be accommodated in an object of type Integer. @node Storage_Size Clauses,Size of Variant Record Objects,Size Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id4}@anchor{296}@anchor{gnat_rm/representation_clauses_and_pragmas storage-size-clauses}@anchor{297} +@anchor{gnat_rm/representation_clauses_and_pragmas id4}@anchor{29a}@anchor{gnat_rm/representation_clauses_and_pragmas storage-size-clauses}@anchor{29b} @section Storage_Size Clauses @@ -19027,7 +19106,7 @@ Of course in practice, there will not be any explicit allocators in the case of such an access declaration. @node Size of Variant Record Objects,Biased Representation,Storage_Size Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id5}@anchor{298}@anchor{gnat_rm/representation_clauses_and_pragmas size-of-variant-record-objects}@anchor{299} +@anchor{gnat_rm/representation_clauses_and_pragmas id5}@anchor{29c}@anchor{gnat_rm/representation_clauses_and_pragmas size-of-variant-record-objects}@anchor{29d} @section Size of Variant Record Objects @@ -19137,7 +19216,7 @@ the maximum size, regardless of the current variant value, the variant value. @node Biased Representation,Value_Size and Object_Size Clauses,Size of Variant Record Objects,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas biased-representation}@anchor{29a}@anchor{gnat_rm/representation_clauses_and_pragmas id6}@anchor{29b} +@anchor{gnat_rm/representation_clauses_and_pragmas biased-representation}@anchor{29e}@anchor{gnat_rm/representation_clauses_and_pragmas id6}@anchor{29f} @section Biased Representation @@ -19175,7 +19254,7 @@ biased representation can be used for all discrete types except for enumeration types for which a representation clause is given. @node Value_Size and Object_Size Clauses,Component_Size Clauses,Biased Representation,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id7}@anchor{29c}@anchor{gnat_rm/representation_clauses_and_pragmas value-size-and-object-size-clauses}@anchor{29d} +@anchor{gnat_rm/representation_clauses_and_pragmas id7}@anchor{2a0}@anchor{gnat_rm/representation_clauses_and_pragmas value-size-and-object-size-clauses}@anchor{2a1} @section Value_Size and Object_Size Clauses @@ -19491,7 +19570,7 @@ definition clause forces biased representation. This warning can be turned off using @code{-gnatw.B}. @node Component_Size Clauses,Bit_Order Clauses,Value_Size and Object_Size Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas component-size-clauses}@anchor{29e}@anchor{gnat_rm/representation_clauses_and_pragmas id8}@anchor{29f} +@anchor{gnat_rm/representation_clauses_and_pragmas component-size-clauses}@anchor{2a2}@anchor{gnat_rm/representation_clauses_and_pragmas id8}@anchor{2a3} @section Component_Size Clauses @@ -19539,7 +19618,7 @@ and a pragma Pack for the same array type. if such duplicate clauses are given, the pragma Pack will be ignored. @node Bit_Order Clauses,Effect of Bit_Order on Byte Ordering,Component_Size Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas bit-order-clauses}@anchor{2a0}@anchor{gnat_rm/representation_clauses_and_pragmas id9}@anchor{2a1} +@anchor{gnat_rm/representation_clauses_and_pragmas bit-order-clauses}@anchor{2a4}@anchor{gnat_rm/representation_clauses_and_pragmas id9}@anchor{2a5} @section Bit_Order Clauses @@ -19645,7 +19724,7 @@ if desired. The following section contains additional details regarding the issue of byte ordering. @node Effect of Bit_Order on Byte Ordering,Pragma Pack for Arrays,Bit_Order Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-bit-order-on-byte-ordering}@anchor{2a2}@anchor{gnat_rm/representation_clauses_and_pragmas id10}@anchor{2a3} +@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-bit-order-on-byte-ordering}@anchor{2a6}@anchor{gnat_rm/representation_clauses_and_pragmas id10}@anchor{2a7} @section Effect of Bit_Order on Byte Ordering @@ -19902,7 +19981,7 @@ to set the boolean constant @code{Master_Byte_First} in an appropriate manner. @node Pragma Pack for Arrays,Pragma Pack for Records,Effect of Bit_Order on Byte Ordering,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id11}@anchor{2a4}@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-arrays}@anchor{2a5} +@anchor{gnat_rm/representation_clauses_and_pragmas id11}@anchor{2a8}@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-arrays}@anchor{2a9} @section Pragma Pack for Arrays @@ -20022,7 +20101,7 @@ Here 31-bit packing is achieved as required, and no warning is generated, since in this case the programmer intention is clear. @node Pragma Pack for Records,Record Representation Clauses,Pragma Pack for Arrays,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id12}@anchor{2a6}@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-records}@anchor{2a7} +@anchor{gnat_rm/representation_clauses_and_pragmas id12}@anchor{2aa}@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-records}@anchor{2ab} @section Pragma Pack for Records @@ -20106,7 +20185,7 @@ array that is longer than 64 bits, so it is itself non-packable on boundary, and takes an integral number of bytes, i.e., 72 bits. @node Record Representation Clauses,Handling of Records with Holes,Pragma Pack for Records,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id13}@anchor{2a8}@anchor{gnat_rm/representation_clauses_and_pragmas record-representation-clauses}@anchor{2a9} +@anchor{gnat_rm/representation_clauses_and_pragmas id13}@anchor{2ac}@anchor{gnat_rm/representation_clauses_and_pragmas record-representation-clauses}@anchor{2ad} @section Record Representation Clauses @@ -20185,7 +20264,7 @@ end record; @end example @node Handling of Records with Holes,Enumeration Clauses,Record Representation Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas handling-of-records-with-holes}@anchor{2aa}@anchor{gnat_rm/representation_clauses_and_pragmas id14}@anchor{2ab} +@anchor{gnat_rm/representation_clauses_and_pragmas handling-of-records-with-holes}@anchor{2ae}@anchor{gnat_rm/representation_clauses_and_pragmas id14}@anchor{2af} @section Handling of Records with Holes @@ -20261,7 +20340,7 @@ for Hrec'Size use 64; @end example @node Enumeration Clauses,Address Clauses,Handling of Records with Holes,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas enumeration-clauses}@anchor{2ac}@anchor{gnat_rm/representation_clauses_and_pragmas id15}@anchor{2ad} +@anchor{gnat_rm/representation_clauses_and_pragmas enumeration-clauses}@anchor{2b0}@anchor{gnat_rm/representation_clauses_and_pragmas id15}@anchor{2b1} @section Enumeration Clauses @@ -20304,7 +20383,7 @@ the overhead of converting representation values to the corresponding positional values, (i.e., the value delivered by the @code{Pos} attribute). @node Address Clauses,Use of Address Clauses for Memory-Mapped I/O,Enumeration Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas address-clauses}@anchor{2ae}@anchor{gnat_rm/representation_clauses_and_pragmas id16}@anchor{2af} +@anchor{gnat_rm/representation_clauses_and_pragmas address-clauses}@anchor{2b2}@anchor{gnat_rm/representation_clauses_and_pragmas id16}@anchor{2b3} @section Address Clauses @@ -20644,7 +20723,7 @@ then the program compiles without the warning and when run will generate the output @code{X was not clobbered}. @node Use of Address Clauses for Memory-Mapped I/O,Effect of Convention on Representation,Address Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id17}@anchor{2b0}@anchor{gnat_rm/representation_clauses_and_pragmas use-of-address-clauses-for-memory-mapped-i-o}@anchor{2b1} +@anchor{gnat_rm/representation_clauses_and_pragmas id17}@anchor{2b4}@anchor{gnat_rm/representation_clauses_and_pragmas use-of-address-clauses-for-memory-mapped-i-o}@anchor{2b5} @section Use of Address Clauses for Memory-Mapped I/O @@ -20702,7 +20781,7 @@ provides the pragma @code{Volatile_Full_Access} which can be used in lieu of pragma @code{Atomic} and will give the additional guarantee. @node Effect of Convention on Representation,Conventions and Anonymous Access Types,Use of Address Clauses for Memory-Mapped I/O,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-convention-on-representation}@anchor{2b2}@anchor{gnat_rm/representation_clauses_and_pragmas id18}@anchor{2b3} +@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-convention-on-representation}@anchor{2b6}@anchor{gnat_rm/representation_clauses_and_pragmas id18}@anchor{2b7} @section Effect of Convention on Representation @@ -20716,7 +20795,7 @@ conventions, and for example records are laid out in a manner that is consistent with C. This means that specifying convention C (for example) has no effect. -There are four exceptions to this general rule: +There are three exceptions to this general rule: @itemize * @@ -20780,7 +20859,7 @@ when one of these values is read, any nonzero value is treated as True. @end itemize @node Conventions and Anonymous Access Types,Determining the Representations chosen by GNAT,Effect of Convention on Representation,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas conventions-and-anonymous-access-types}@anchor{2b4}@anchor{gnat_rm/representation_clauses_and_pragmas id19}@anchor{2b5} +@anchor{gnat_rm/representation_clauses_and_pragmas conventions-and-anonymous-access-types}@anchor{2b8}@anchor{gnat_rm/representation_clauses_and_pragmas id19}@anchor{2b9} @section Conventions and Anonymous Access Types @@ -20856,7 +20935,7 @@ package ConvComp is @end example @node Determining the Representations chosen by GNAT,,Conventions and Anonymous Access Types,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas determining-the-representations-chosen-by-gnat}@anchor{2b6}@anchor{gnat_rm/representation_clauses_and_pragmas id20}@anchor{2b7} +@anchor{gnat_rm/representation_clauses_and_pragmas determining-the-representations-chosen-by-gnat}@anchor{2ba}@anchor{gnat_rm/representation_clauses_and_pragmas id20}@anchor{2bb} @section Determining the Representations chosen by GNAT @@ -21008,7 +21087,7 @@ generated by the compiler into the original source to fix and guarantee the actual representation to be used. @node Standard Library Routines,The Implementation of Standard I/O,Representation Clauses and Pragmas,Top -@anchor{gnat_rm/standard_library_routines doc}@anchor{2b8}@anchor{gnat_rm/standard_library_routines id1}@anchor{2b9}@anchor{gnat_rm/standard_library_routines standard-library-routines}@anchor{e} +@anchor{gnat_rm/standard_library_routines doc}@anchor{2bc}@anchor{gnat_rm/standard_library_routines id1}@anchor{2bd}@anchor{gnat_rm/standard_library_routines standard-library-routines}@anchor{e} @chapter Standard Library Routines @@ -21835,7 +21914,7 @@ For packages in Interfaces and System, all the RM defined packages are available in GNAT, see the Ada 2012 RM for full details. @node The Implementation of Standard I/O,The GNAT Library,Standard Library Routines,Top -@anchor{gnat_rm/the_implementation_of_standard_i_o doc}@anchor{2ba}@anchor{gnat_rm/the_implementation_of_standard_i_o id1}@anchor{2bb}@anchor{gnat_rm/the_implementation_of_standard_i_o the-implementation-of-standard-i-o}@anchor{f} +@anchor{gnat_rm/the_implementation_of_standard_i_o doc}@anchor{2be}@anchor{gnat_rm/the_implementation_of_standard_i_o id1}@anchor{2bf}@anchor{gnat_rm/the_implementation_of_standard_i_o the-implementation-of-standard-i-o}@anchor{f} @chapter The Implementation of Standard I/O @@ -21887,7 +21966,7 @@ these additional facilities are also described in this chapter. @end menu @node Standard I/O Packages,FORM Strings,,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id2}@anchor{2bc}@anchor{gnat_rm/the_implementation_of_standard_i_o standard-i-o-packages}@anchor{2bd} +@anchor{gnat_rm/the_implementation_of_standard_i_o id2}@anchor{2c0}@anchor{gnat_rm/the_implementation_of_standard_i_o standard-i-o-packages}@anchor{2c1} @section Standard I/O Packages @@ -21958,7 +22037,7 @@ flush the common I/O streams and in particular Standard_Output before elaborating the Ada code. @node FORM Strings,Direct_IO,Standard I/O Packages,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o form-strings}@anchor{2be}@anchor{gnat_rm/the_implementation_of_standard_i_o id3}@anchor{2bf} +@anchor{gnat_rm/the_implementation_of_standard_i_o form-strings}@anchor{2c2}@anchor{gnat_rm/the_implementation_of_standard_i_o id3}@anchor{2c3} @section FORM Strings @@ -21984,7 +22063,7 @@ unrecognized keyword appears in a form string, it is silently ignored and not considered invalid. @node Direct_IO,Sequential_IO,FORM Strings,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o direct-io}@anchor{2c0}@anchor{gnat_rm/the_implementation_of_standard_i_o id4}@anchor{2c1} +@anchor{gnat_rm/the_implementation_of_standard_i_o direct-io}@anchor{2c4}@anchor{gnat_rm/the_implementation_of_standard_i_o id4}@anchor{2c5} @section Direct_IO @@ -22003,7 +22082,7 @@ There is no limit on the size of Direct_IO files, they are expanded as necessary to accommodate whatever records are written to the file. @node Sequential_IO,Text_IO,Direct_IO,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id5}@anchor{2c2}@anchor{gnat_rm/the_implementation_of_standard_i_o sequential-io}@anchor{2c3} +@anchor{gnat_rm/the_implementation_of_standard_i_o id5}@anchor{2c6}@anchor{gnat_rm/the_implementation_of_standard_i_o sequential-io}@anchor{2c7} @section Sequential_IO @@ -22050,7 +22129,7 @@ using Stream_IO, and this is the preferred mechanism. In particular, the above program fragment rewritten to use Stream_IO will work correctly. @node Text_IO,Wide_Text_IO,Sequential_IO,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id6}@anchor{2c4}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io}@anchor{2c5} +@anchor{gnat_rm/the_implementation_of_standard_i_o id6}@anchor{2c8}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io}@anchor{2c9} @section Text_IO @@ -22133,7 +22212,7 @@ the file. @end menu @node Stream Pointer Positioning,Reading and Writing Non-Regular Files,,Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o id7}@anchor{2c6}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning}@anchor{2c7} +@anchor{gnat_rm/the_implementation_of_standard_i_o id7}@anchor{2ca}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning}@anchor{2cb} @subsection Stream Pointer Positioning @@ -22169,7 +22248,7 @@ between two Ada files, then the difference may be observable in some situations. @node Reading and Writing Non-Regular Files,Get_Immediate,Stream Pointer Positioning,Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o id8}@anchor{2c8}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files}@anchor{2c9} +@anchor{gnat_rm/the_implementation_of_standard_i_o id8}@anchor{2cc}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files}@anchor{2cd} @subsection Reading and Writing Non-Regular Files @@ -22220,7 +22299,7 @@ to read data past that end of file indication, until another end of file indication is entered. @node Get_Immediate,Treating Text_IO Files as Streams,Reading and Writing Non-Regular Files,Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o get-immediate}@anchor{2ca}@anchor{gnat_rm/the_implementation_of_standard_i_o id9}@anchor{2cb} +@anchor{gnat_rm/the_implementation_of_standard_i_o get-immediate}@anchor{2ce}@anchor{gnat_rm/the_implementation_of_standard_i_o id9}@anchor{2cf} @subsection Get_Immediate @@ -22238,7 +22317,7 @@ possible), it is undefined whether the FF character will be treated as a page mark. @node Treating Text_IO Files as Streams,Text_IO Extensions,Get_Immediate,Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o id10}@anchor{2cc}@anchor{gnat_rm/the_implementation_of_standard_i_o treating-text-io-files-as-streams}@anchor{2cd} +@anchor{gnat_rm/the_implementation_of_standard_i_o id10}@anchor{2d0}@anchor{gnat_rm/the_implementation_of_standard_i_o treating-text-io-files-as-streams}@anchor{2d1} @subsection Treating Text_IO Files as Streams @@ -22254,7 +22333,7 @@ skipped and the effect is similar to that described above for @code{Get_Immediate}. @node Text_IO Extensions,Text_IO Facilities for Unbounded Strings,Treating Text_IO Files as Streams,Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o id11}@anchor{2ce}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-extensions}@anchor{2cf} +@anchor{gnat_rm/the_implementation_of_standard_i_o id11}@anchor{2d2}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-extensions}@anchor{2d3} @subsection Text_IO Extensions @@ -22282,7 +22361,7 @@ the string is to be read. @end itemize @node Text_IO Facilities for Unbounded Strings,,Text_IO Extensions,Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o id12}@anchor{2d0}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-facilities-for-unbounded-strings}@anchor{2d1} +@anchor{gnat_rm/the_implementation_of_standard_i_o id12}@anchor{2d4}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-facilities-for-unbounded-strings}@anchor{2d5} @subsection Text_IO Facilities for Unbounded Strings @@ -22330,7 +22409,7 @@ files @code{a-szuzti.ads} and @code{a-szuzti.adb} provides similar extended @code{Wide_Wide_Text_IO} functionality for unbounded wide wide strings. @node Wide_Text_IO,Wide_Wide_Text_IO,Text_IO,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id13}@anchor{2d2}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-text-io}@anchor{2d3} +@anchor{gnat_rm/the_implementation_of_standard_i_o id13}@anchor{2d6}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-text-io}@anchor{2d7} @section Wide_Text_IO @@ -22577,12 +22656,12 @@ input also causes Constraint_Error to be raised. @end menu @node Stream Pointer Positioning<2>,Reading and Writing Non-Regular Files<2>,,Wide_Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o id14}@anchor{2d4}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-1}@anchor{2d5} +@anchor{gnat_rm/the_implementation_of_standard_i_o id14}@anchor{2d8}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-1}@anchor{2d9} @subsection Stream Pointer Positioning @code{Ada.Wide_Text_IO} is similar to @code{Ada.Text_IO} in its handling -of stream pointer positioning (@ref{2c5,,Text_IO}). There is one additional +of stream pointer positioning (@ref{2c9,,Text_IO}). There is one additional case: If @code{Ada.Wide_Text_IO.Look_Ahead} reads a character outside the @@ -22601,7 +22680,7 @@ to a normal program using @code{Wide_Text_IO}. However, this discrepancy can be observed if the wide text file shares a stream with another file. @node Reading and Writing Non-Regular Files<2>,,Stream Pointer Positioning<2>,Wide_Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o id15}@anchor{2d6}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-1}@anchor{2d7} +@anchor{gnat_rm/the_implementation_of_standard_i_o id15}@anchor{2da}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-1}@anchor{2db} @subsection Reading and Writing Non-Regular Files @@ -22612,7 +22691,7 @@ treated as data characters), and @code{End_Of_Page} always returns it is possible to read beyond an end of file. @node Wide_Wide_Text_IO,Stream_IO,Wide_Text_IO,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id16}@anchor{2d8}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-wide-text-io}@anchor{2d9} +@anchor{gnat_rm/the_implementation_of_standard_i_o id16}@anchor{2dc}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-wide-text-io}@anchor{2dd} @section Wide_Wide_Text_IO @@ -22781,12 +22860,12 @@ input also causes Constraint_Error to be raised. @end menu @node Stream Pointer Positioning<3>,Reading and Writing Non-Regular Files<3>,,Wide_Wide_Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o id17}@anchor{2da}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-2}@anchor{2db} +@anchor{gnat_rm/the_implementation_of_standard_i_o id17}@anchor{2de}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-2}@anchor{2df} @subsection Stream Pointer Positioning @code{Ada.Wide_Wide_Text_IO} is similar to @code{Ada.Text_IO} in its handling -of stream pointer positioning (@ref{2c5,,Text_IO}). There is one additional +of stream pointer positioning (@ref{2c9,,Text_IO}). There is one additional case: If @code{Ada.Wide_Wide_Text_IO.Look_Ahead} reads a character outside the @@ -22805,7 +22884,7 @@ to a normal program using @code{Wide_Wide_Text_IO}. However, this discrepancy can be observed if the wide text file shares a stream with another file. @node Reading and Writing Non-Regular Files<3>,,Stream Pointer Positioning<3>,Wide_Wide_Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o id18}@anchor{2dc}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-2}@anchor{2dd} +@anchor{gnat_rm/the_implementation_of_standard_i_o id18}@anchor{2e0}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-2}@anchor{2e1} @subsection Reading and Writing Non-Regular Files @@ -22816,7 +22895,7 @@ treated as data characters), and @code{End_Of_Page} always returns it is possible to read beyond an end of file. @node Stream_IO,Text Translation,Wide_Wide_Text_IO,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id19}@anchor{2de}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-io}@anchor{2df} +@anchor{gnat_rm/the_implementation_of_standard_i_o id19}@anchor{2e2}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-io}@anchor{2e3} @section Stream_IO @@ -22838,7 +22917,7 @@ manner described for stream attributes. @end itemize @node Text Translation,Shared Files,Stream_IO,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id20}@anchor{2e0}@anchor{gnat_rm/the_implementation_of_standard_i_o text-translation}@anchor{2e1} +@anchor{gnat_rm/the_implementation_of_standard_i_o id20}@anchor{2e4}@anchor{gnat_rm/the_implementation_of_standard_i_o text-translation}@anchor{2e5} @section Text Translation @@ -22872,7 +22951,7 @@ mode. (corresponds to_O_U16TEXT). @end itemize @node Shared Files,Filenames encoding,Text Translation,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id21}@anchor{2e2}@anchor{gnat_rm/the_implementation_of_standard_i_o shared-files}@anchor{2e3} +@anchor{gnat_rm/the_implementation_of_standard_i_o id21}@anchor{2e6}@anchor{gnat_rm/the_implementation_of_standard_i_o shared-files}@anchor{2e7} @section Shared Files @@ -22935,7 +23014,7 @@ heterogeneous input-output. Although this approach will work in GNAT if for this purpose (using the stream attributes). @node Filenames encoding,File content encoding,Shared Files,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o filenames-encoding}@anchor{2e4}@anchor{gnat_rm/the_implementation_of_standard_i_o id22}@anchor{2e5} +@anchor{gnat_rm/the_implementation_of_standard_i_o filenames-encoding}@anchor{2e8}@anchor{gnat_rm/the_implementation_of_standard_i_o id22}@anchor{2e9} @section Filenames encoding @@ -22975,7 +23054,7 @@ platform. On the other Operating Systems the run-time is supporting UTF-8 natively. @node File content encoding,Open Modes,Filenames encoding,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o file-content-encoding}@anchor{2e6}@anchor{gnat_rm/the_implementation_of_standard_i_o id23}@anchor{2e7} +@anchor{gnat_rm/the_implementation_of_standard_i_o file-content-encoding}@anchor{2ea}@anchor{gnat_rm/the_implementation_of_standard_i_o id23}@anchor{2eb} @section File content encoding @@ -23008,7 +23087,7 @@ Unicode 8-bit encoding This encoding is only supported on the Windows platform. @node Open Modes,Operations on C Streams,File content encoding,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id24}@anchor{2e8}@anchor{gnat_rm/the_implementation_of_standard_i_o open-modes}@anchor{2e9} +@anchor{gnat_rm/the_implementation_of_standard_i_o id24}@anchor{2ec}@anchor{gnat_rm/the_implementation_of_standard_i_o open-modes}@anchor{2ed} @section Open Modes @@ -23111,7 +23190,7 @@ subsequently requires switching from reading to writing or vice-versa, then the file is reopened in @code{r+} mode to permit the required operation. @node Operations on C Streams,Interfacing to C Streams,Open Modes,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id25}@anchor{2ea}@anchor{gnat_rm/the_implementation_of_standard_i_o operations-on-c-streams}@anchor{2eb} +@anchor{gnat_rm/the_implementation_of_standard_i_o id25}@anchor{2ee}@anchor{gnat_rm/the_implementation_of_standard_i_o operations-on-c-streams}@anchor{2ef} @section Operations on C Streams @@ -23271,7 +23350,7 @@ end Interfaces.C_Streams; @end example @node Interfacing to C Streams,,Operations on C Streams,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id26}@anchor{2ec}@anchor{gnat_rm/the_implementation_of_standard_i_o interfacing-to-c-streams}@anchor{2ed} +@anchor{gnat_rm/the_implementation_of_standard_i_o id26}@anchor{2f0}@anchor{gnat_rm/the_implementation_of_standard_i_o interfacing-to-c-streams}@anchor{2f1} @section Interfacing to C Streams @@ -23364,7 +23443,7 @@ imported from a C program, allowing an Ada file to operate on an existing C file. @node The GNAT Library,Interfacing to Other Languages,The Implementation of Standard I/O,Top -@anchor{gnat_rm/the_gnat_library doc}@anchor{2ee}@anchor{gnat_rm/the_gnat_library id1}@anchor{2ef}@anchor{gnat_rm/the_gnat_library the-gnat-library}@anchor{10} +@anchor{gnat_rm/the_gnat_library doc}@anchor{2f2}@anchor{gnat_rm/the_gnat_library id1}@anchor{2f3}@anchor{gnat_rm/the_gnat_library the-gnat-library}@anchor{10} @chapter The GNAT Library @@ -23549,7 +23628,7 @@ of GNAT, and will generate a warning message. @end menu @node Ada Characters Latin_9 a-chlat9 ads,Ada Characters Wide_Latin_1 a-cwila1 ads,,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-characters-latin-9-a-chlat9-ads}@anchor{2f0}@anchor{gnat_rm/the_gnat_library id2}@anchor{2f1} +@anchor{gnat_rm/the_gnat_library ada-characters-latin-9-a-chlat9-ads}@anchor{2f4}@anchor{gnat_rm/the_gnat_library id2}@anchor{2f5} @section @code{Ada.Characters.Latin_9} (@code{a-chlat9.ads}) @@ -23566,7 +23645,7 @@ is specifically authorized by the Ada Reference Manual (RM A.3.3(27)). @node Ada Characters Wide_Latin_1 a-cwila1 ads,Ada Characters Wide_Latin_9 a-cwila9 ads,Ada Characters Latin_9 a-chlat9 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-1-a-cwila1-ads}@anchor{2f2}@anchor{gnat_rm/the_gnat_library id3}@anchor{2f3} +@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-1-a-cwila1-ads}@anchor{2f6}@anchor{gnat_rm/the_gnat_library id3}@anchor{2f7} @section @code{Ada.Characters.Wide_Latin_1} (@code{a-cwila1.ads}) @@ -23583,7 +23662,7 @@ is specifically authorized by the Ada Reference Manual (RM A.3.3(27)). @node Ada Characters Wide_Latin_9 a-cwila9 ads,Ada Characters Wide_Wide_Latin_1 a-chzla1 ads,Ada Characters Wide_Latin_1 a-cwila1 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-9-a-cwila9-ads}@anchor{2f4}@anchor{gnat_rm/the_gnat_library id4}@anchor{2f5} +@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-9-a-cwila9-ads}@anchor{2f8}@anchor{gnat_rm/the_gnat_library id4}@anchor{2f9} @section @code{Ada.Characters.Wide_Latin_9} (@code{a-cwila9.ads}) @@ -23600,7 +23679,7 @@ is specifically authorized by the Ada Reference Manual (RM A.3.3(27)). @node Ada Characters Wide_Wide_Latin_1 a-chzla1 ads,Ada Characters Wide_Wide_Latin_9 a-chzla9 ads,Ada Characters Wide_Latin_9 a-cwila9 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-1-a-chzla1-ads}@anchor{2f6}@anchor{gnat_rm/the_gnat_library id5}@anchor{2f7} +@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-1-a-chzla1-ads}@anchor{2fa}@anchor{gnat_rm/the_gnat_library id5}@anchor{2fb} @section @code{Ada.Characters.Wide_Wide_Latin_1} (@code{a-chzla1.ads}) @@ -23617,7 +23696,7 @@ is specifically authorized by the Ada Reference Manual (RM A.3.3(27)). @node Ada Characters Wide_Wide_Latin_9 a-chzla9 ads,Ada Containers Bounded_Holders a-coboho ads,Ada Characters Wide_Wide_Latin_1 a-chzla1 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-9-a-chzla9-ads}@anchor{2f8}@anchor{gnat_rm/the_gnat_library id6}@anchor{2f9} +@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-9-a-chzla9-ads}@anchor{2fc}@anchor{gnat_rm/the_gnat_library id6}@anchor{2fd} @section @code{Ada.Characters.Wide_Wide_Latin_9} (@code{a-chzla9.ads}) @@ -23634,7 +23713,7 @@ is specifically authorized by the Ada Reference Manual (RM A.3.3(27)). @node Ada Containers Bounded_Holders a-coboho ads,Ada Command_Line Environment a-colien ads,Ada Characters Wide_Wide_Latin_9 a-chzla9 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-containers-bounded-holders-a-coboho-ads}@anchor{2fa}@anchor{gnat_rm/the_gnat_library id7}@anchor{2fb} +@anchor{gnat_rm/the_gnat_library ada-containers-bounded-holders-a-coboho-ads}@anchor{2fe}@anchor{gnat_rm/the_gnat_library id7}@anchor{2ff} @section @code{Ada.Containers.Bounded_Holders} (@code{a-coboho.ads}) @@ -23646,7 +23725,7 @@ This child of @code{Ada.Containers} defines a modified version of Indefinite_Holders that avoids heap allocation. @node Ada Command_Line Environment a-colien ads,Ada Command_Line Remove a-colire ads,Ada Containers Bounded_Holders a-coboho ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-command-line-environment-a-colien-ads}@anchor{2fc}@anchor{gnat_rm/the_gnat_library id8}@anchor{2fd} +@anchor{gnat_rm/the_gnat_library ada-command-line-environment-a-colien-ads}@anchor{300}@anchor{gnat_rm/the_gnat_library id8}@anchor{301} @section @code{Ada.Command_Line.Environment} (@code{a-colien.ads}) @@ -23659,7 +23738,7 @@ provides a mechanism for obtaining environment values on systems where this concept makes sense. @node Ada Command_Line Remove a-colire ads,Ada Command_Line Response_File a-clrefi ads,Ada Command_Line Environment a-colien ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-command-line-remove-a-colire-ads}@anchor{2fe}@anchor{gnat_rm/the_gnat_library id9}@anchor{2ff} +@anchor{gnat_rm/the_gnat_library ada-command-line-remove-a-colire-ads}@anchor{302}@anchor{gnat_rm/the_gnat_library id9}@anchor{303} @section @code{Ada.Command_Line.Remove} (@code{a-colire.ads}) @@ -23677,7 +23756,7 @@ to further calls to the subprograms in @code{Ada.Command_Line}. These calls will not see the removed argument. @node Ada Command_Line Response_File a-clrefi ads,Ada Direct_IO C_Streams a-diocst ads,Ada Command_Line Remove a-colire ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-command-line-response-file-a-clrefi-ads}@anchor{300}@anchor{gnat_rm/the_gnat_library id10}@anchor{301} +@anchor{gnat_rm/the_gnat_library ada-command-line-response-file-a-clrefi-ads}@anchor{304}@anchor{gnat_rm/the_gnat_library id10}@anchor{305} @section @code{Ada.Command_Line.Response_File} (@code{a-clrefi.ads}) @@ -23697,7 +23776,7 @@ Using a response file allow passing a set of arguments to an executable longer than the maximum allowed by the system on the command line. @node Ada Direct_IO C_Streams a-diocst ads,Ada Exceptions Is_Null_Occurrence a-einuoc ads,Ada Command_Line Response_File a-clrefi ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-direct-io-c-streams-a-diocst-ads}@anchor{302}@anchor{gnat_rm/the_gnat_library id11}@anchor{303} +@anchor{gnat_rm/the_gnat_library ada-direct-io-c-streams-a-diocst-ads}@anchor{306}@anchor{gnat_rm/the_gnat_library id11}@anchor{307} @section @code{Ada.Direct_IO.C_Streams} (@code{a-diocst.ads}) @@ -23712,7 +23791,7 @@ extracted from a file opened on the Ada side, and an Ada file can be constructed from a stream opened on the C side. @node Ada Exceptions Is_Null_Occurrence a-einuoc ads,Ada Exceptions Last_Chance_Handler a-elchha ads,Ada Direct_IO C_Streams a-diocst ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-exceptions-is-null-occurrence-a-einuoc-ads}@anchor{304}@anchor{gnat_rm/the_gnat_library id12}@anchor{305} +@anchor{gnat_rm/the_gnat_library ada-exceptions-is-null-occurrence-a-einuoc-ads}@anchor{308}@anchor{gnat_rm/the_gnat_library id12}@anchor{309} @section @code{Ada.Exceptions.Is_Null_Occurrence} (@code{a-einuoc.ads}) @@ -23726,7 +23805,7 @@ exception occurrence (@code{Null_Occurrence}) without raising an exception. @node Ada Exceptions Last_Chance_Handler a-elchha ads,Ada Exceptions Traceback a-exctra ads,Ada Exceptions Is_Null_Occurrence a-einuoc ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-exceptions-last-chance-handler-a-elchha-ads}@anchor{306}@anchor{gnat_rm/the_gnat_library id13}@anchor{307} +@anchor{gnat_rm/the_gnat_library ada-exceptions-last-chance-handler-a-elchha-ads}@anchor{30a}@anchor{gnat_rm/the_gnat_library id13}@anchor{30b} @section @code{Ada.Exceptions.Last_Chance_Handler} (@code{a-elchha.ads}) @@ -23740,7 +23819,7 @@ exceptions (hence the name last chance), and perform clean ups before terminating the program. Note that this subprogram never returns. @node Ada Exceptions Traceback a-exctra ads,Ada Sequential_IO C_Streams a-siocst ads,Ada Exceptions Last_Chance_Handler a-elchha ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-exceptions-traceback-a-exctra-ads}@anchor{308}@anchor{gnat_rm/the_gnat_library id14}@anchor{309} +@anchor{gnat_rm/the_gnat_library ada-exceptions-traceback-a-exctra-ads}@anchor{30c}@anchor{gnat_rm/the_gnat_library id14}@anchor{30d} @section @code{Ada.Exceptions.Traceback} (@code{a-exctra.ads}) @@ -23753,7 +23832,7 @@ give a traceback array of addresses based on an exception occurrence. @node Ada Sequential_IO C_Streams a-siocst ads,Ada Streams Stream_IO C_Streams a-ssicst ads,Ada Exceptions Traceback a-exctra ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-sequential-io-c-streams-a-siocst-ads}@anchor{30a}@anchor{gnat_rm/the_gnat_library id15}@anchor{30b} +@anchor{gnat_rm/the_gnat_library ada-sequential-io-c-streams-a-siocst-ads}@anchor{30e}@anchor{gnat_rm/the_gnat_library id15}@anchor{30f} @section @code{Ada.Sequential_IO.C_Streams} (@code{a-siocst.ads}) @@ -23768,7 +23847,7 @@ extracted from a file opened on the Ada side, and an Ada file can be constructed from a stream opened on the C side. @node Ada Streams Stream_IO C_Streams a-ssicst ads,Ada Strings Unbounded Text_IO a-suteio ads,Ada Sequential_IO C_Streams a-siocst ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-streams-stream-io-c-streams-a-ssicst-ads}@anchor{30c}@anchor{gnat_rm/the_gnat_library id16}@anchor{30d} +@anchor{gnat_rm/the_gnat_library ada-streams-stream-io-c-streams-a-ssicst-ads}@anchor{310}@anchor{gnat_rm/the_gnat_library id16}@anchor{311} @section @code{Ada.Streams.Stream_IO.C_Streams} (@code{a-ssicst.ads}) @@ -23783,7 +23862,7 @@ extracted from a file opened on the Ada side, and an Ada file can be constructed from a stream opened on the C side. @node Ada Strings Unbounded Text_IO a-suteio ads,Ada Strings Wide_Unbounded Wide_Text_IO a-swuwti ads,Ada Streams Stream_IO C_Streams a-ssicst ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-strings-unbounded-text-io-a-suteio-ads}@anchor{30e}@anchor{gnat_rm/the_gnat_library id17}@anchor{30f} +@anchor{gnat_rm/the_gnat_library ada-strings-unbounded-text-io-a-suteio-ads}@anchor{312}@anchor{gnat_rm/the_gnat_library id17}@anchor{313} @section @code{Ada.Strings.Unbounded.Text_IO} (@code{a-suteio.ads}) @@ -23800,7 +23879,7 @@ strings, avoiding the necessity for an intermediate operation with ordinary strings. @node Ada Strings Wide_Unbounded Wide_Text_IO a-swuwti ads,Ada Strings Wide_Wide_Unbounded Wide_Wide_Text_IO a-szuzti ads,Ada Strings Unbounded Text_IO a-suteio ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-strings-wide-unbounded-wide-text-io-a-swuwti-ads}@anchor{310}@anchor{gnat_rm/the_gnat_library id18}@anchor{311} +@anchor{gnat_rm/the_gnat_library ada-strings-wide-unbounded-wide-text-io-a-swuwti-ads}@anchor{314}@anchor{gnat_rm/the_gnat_library id18}@anchor{315} @section @code{Ada.Strings.Wide_Unbounded.Wide_Text_IO} (@code{a-swuwti.ads}) @@ -23817,7 +23896,7 @@ wide strings, avoiding the necessity for an intermediate operation with ordinary wide strings. @node Ada Strings Wide_Wide_Unbounded Wide_Wide_Text_IO a-szuzti ads,Ada Task_Initialization a-tasini ads,Ada Strings Wide_Unbounded Wide_Text_IO a-swuwti ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-strings-wide-wide-unbounded-wide-wide-text-io-a-szuzti-ads}@anchor{312}@anchor{gnat_rm/the_gnat_library id19}@anchor{313} +@anchor{gnat_rm/the_gnat_library ada-strings-wide-wide-unbounded-wide-wide-text-io-a-szuzti-ads}@anchor{316}@anchor{gnat_rm/the_gnat_library id19}@anchor{317} @section @code{Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO} (@code{a-szuzti.ads}) @@ -23834,7 +23913,7 @@ wide wide strings, avoiding the necessity for an intermediate operation with ordinary wide wide strings. @node Ada Task_Initialization a-tasini ads,Ada Text_IO C_Streams a-tiocst ads,Ada Strings Wide_Wide_Unbounded Wide_Wide_Text_IO a-szuzti ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-task-initialization-a-tasini-ads}@anchor{314}@anchor{gnat_rm/the_gnat_library id20}@anchor{315} +@anchor{gnat_rm/the_gnat_library ada-task-initialization-a-tasini-ads}@anchor{318}@anchor{gnat_rm/the_gnat_library id20}@anchor{319} @section @code{Ada.Task_Initialization} (@code{a-tasini.ads}) @@ -23846,7 +23925,7 @@ parameterless procedures. Note that such a handler is only invoked for those tasks activated after the handler is set. @node Ada Text_IO C_Streams a-tiocst ads,Ada Text_IO Reset_Standard_Files a-tirsfi ads,Ada Task_Initialization a-tasini ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-text-io-c-streams-a-tiocst-ads}@anchor{316}@anchor{gnat_rm/the_gnat_library id21}@anchor{317} +@anchor{gnat_rm/the_gnat_library ada-text-io-c-streams-a-tiocst-ads}@anchor{31a}@anchor{gnat_rm/the_gnat_library id21}@anchor{31b} @section @code{Ada.Text_IO.C_Streams} (@code{a-tiocst.ads}) @@ -23861,7 +23940,7 @@ extracted from a file opened on the Ada side, and an Ada file can be constructed from a stream opened on the C side. @node Ada Text_IO Reset_Standard_Files a-tirsfi ads,Ada Wide_Characters Unicode a-wichun ads,Ada Text_IO C_Streams a-tiocst ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-text-io-reset-standard-files-a-tirsfi-ads}@anchor{318}@anchor{gnat_rm/the_gnat_library id22}@anchor{319} +@anchor{gnat_rm/the_gnat_library ada-text-io-reset-standard-files-a-tirsfi-ads}@anchor{31c}@anchor{gnat_rm/the_gnat_library id22}@anchor{31d} @section @code{Ada.Text_IO.Reset_Standard_Files} (@code{a-tirsfi.ads}) @@ -23876,7 +23955,7 @@ execution (for example a standard input file may be redefined to be interactive). @node Ada Wide_Characters Unicode a-wichun ads,Ada Wide_Text_IO C_Streams a-wtcstr ads,Ada Text_IO Reset_Standard_Files a-tirsfi ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-wide-characters-unicode-a-wichun-ads}@anchor{31a}@anchor{gnat_rm/the_gnat_library id23}@anchor{31b} +@anchor{gnat_rm/the_gnat_library ada-wide-characters-unicode-a-wichun-ads}@anchor{31e}@anchor{gnat_rm/the_gnat_library id23}@anchor{31f} @section @code{Ada.Wide_Characters.Unicode} (@code{a-wichun.ads}) @@ -23889,7 +23968,7 @@ This package provides subprograms that allow categorization of Wide_Character values according to Unicode categories. @node Ada Wide_Text_IO C_Streams a-wtcstr ads,Ada Wide_Text_IO Reset_Standard_Files a-wrstfi ads,Ada Wide_Characters Unicode a-wichun ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-wide-text-io-c-streams-a-wtcstr-ads}@anchor{31c}@anchor{gnat_rm/the_gnat_library id24}@anchor{31d} +@anchor{gnat_rm/the_gnat_library ada-wide-text-io-c-streams-a-wtcstr-ads}@anchor{320}@anchor{gnat_rm/the_gnat_library id24}@anchor{321} @section @code{Ada.Wide_Text_IO.C_Streams} (@code{a-wtcstr.ads}) @@ -23904,7 +23983,7 @@ extracted from a file opened on the Ada side, and an Ada file can be constructed from a stream opened on the C side. @node Ada Wide_Text_IO Reset_Standard_Files a-wrstfi ads,Ada Wide_Wide_Characters Unicode a-zchuni ads,Ada Wide_Text_IO C_Streams a-wtcstr ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-wide-text-io-reset-standard-files-a-wrstfi-ads}@anchor{31e}@anchor{gnat_rm/the_gnat_library id25}@anchor{31f} +@anchor{gnat_rm/the_gnat_library ada-wide-text-io-reset-standard-files-a-wrstfi-ads}@anchor{322}@anchor{gnat_rm/the_gnat_library id25}@anchor{323} @section @code{Ada.Wide_Text_IO.Reset_Standard_Files} (@code{a-wrstfi.ads}) @@ -23919,7 +23998,7 @@ execution (for example a standard input file may be redefined to be interactive). @node Ada Wide_Wide_Characters Unicode a-zchuni ads,Ada Wide_Wide_Text_IO C_Streams a-ztcstr ads,Ada Wide_Text_IO Reset_Standard_Files a-wrstfi ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-wide-wide-characters-unicode-a-zchuni-ads}@anchor{320}@anchor{gnat_rm/the_gnat_library id26}@anchor{321} +@anchor{gnat_rm/the_gnat_library ada-wide-wide-characters-unicode-a-zchuni-ads}@anchor{324}@anchor{gnat_rm/the_gnat_library id26}@anchor{325} @section @code{Ada.Wide_Wide_Characters.Unicode} (@code{a-zchuni.ads}) @@ -23932,7 +24011,7 @@ This package provides subprograms that allow categorization of Wide_Wide_Character values according to Unicode categories. @node Ada Wide_Wide_Text_IO C_Streams a-ztcstr ads,Ada Wide_Wide_Text_IO Reset_Standard_Files a-zrstfi ads,Ada Wide_Wide_Characters Unicode a-zchuni ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-c-streams-a-ztcstr-ads}@anchor{322}@anchor{gnat_rm/the_gnat_library id27}@anchor{323} +@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-c-streams-a-ztcstr-ads}@anchor{326}@anchor{gnat_rm/the_gnat_library id27}@anchor{327} @section @code{Ada.Wide_Wide_Text_IO.C_Streams} (@code{a-ztcstr.ads}) @@ -23947,7 +24026,7 @@ extracted from a file opened on the Ada side, and an Ada file can be constructed from a stream opened on the C side. @node Ada Wide_Wide_Text_IO Reset_Standard_Files a-zrstfi ads,GNAT Altivec g-altive ads,Ada Wide_Wide_Text_IO C_Streams a-ztcstr ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-reset-standard-files-a-zrstfi-ads}@anchor{324}@anchor{gnat_rm/the_gnat_library id28}@anchor{325} +@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-reset-standard-files-a-zrstfi-ads}@anchor{328}@anchor{gnat_rm/the_gnat_library id28}@anchor{329} @section @code{Ada.Wide_Wide_Text_IO.Reset_Standard_Files} (@code{a-zrstfi.ads}) @@ -23962,7 +24041,7 @@ change during execution (for example a standard input file may be redefined to be interactive). @node GNAT Altivec g-altive ads,GNAT Altivec Conversions g-altcon ads,Ada Wide_Wide_Text_IO Reset_Standard_Files a-zrstfi ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-altivec-g-altive-ads}@anchor{326}@anchor{gnat_rm/the_gnat_library id29}@anchor{327} +@anchor{gnat_rm/the_gnat_library gnat-altivec-g-altive-ads}@anchor{32a}@anchor{gnat_rm/the_gnat_library id29}@anchor{32b} @section @code{GNAT.Altivec} (@code{g-altive.ads}) @@ -23975,7 +24054,7 @@ definitions of constants and types common to all the versions of the binding. @node GNAT Altivec Conversions g-altcon ads,GNAT Altivec Vector_Operations g-alveop ads,GNAT Altivec g-altive ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-altivec-conversions-g-altcon-ads}@anchor{328}@anchor{gnat_rm/the_gnat_library id30}@anchor{329} +@anchor{gnat_rm/the_gnat_library gnat-altivec-conversions-g-altcon-ads}@anchor{32c}@anchor{gnat_rm/the_gnat_library id30}@anchor{32d} @section @code{GNAT.Altivec.Conversions} (@code{g-altcon.ads}) @@ -23986,7 +24065,7 @@ binding. This package provides the Vector/View conversion routines. @node GNAT Altivec Vector_Operations g-alveop ads,GNAT Altivec Vector_Types g-alvety ads,GNAT Altivec Conversions g-altcon ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-operations-g-alveop-ads}@anchor{32a}@anchor{gnat_rm/the_gnat_library id31}@anchor{32b} +@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-operations-g-alveop-ads}@anchor{32e}@anchor{gnat_rm/the_gnat_library id31}@anchor{32f} @section @code{GNAT.Altivec.Vector_Operations} (@code{g-alveop.ads}) @@ -24000,7 +24079,7 @@ library. The hard binding is provided as a separate package. This unit is common to both bindings. @node GNAT Altivec Vector_Types g-alvety ads,GNAT Altivec Vector_Views g-alvevi ads,GNAT Altivec Vector_Operations g-alveop ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-types-g-alvety-ads}@anchor{32c}@anchor{gnat_rm/the_gnat_library id32}@anchor{32d} +@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-types-g-alvety-ads}@anchor{330}@anchor{gnat_rm/the_gnat_library id32}@anchor{331} @section @code{GNAT.Altivec.Vector_Types} (@code{g-alvety.ads}) @@ -24012,7 +24091,7 @@ This package exposes the various vector types part of the Ada binding to AltiVec facilities. @node GNAT Altivec Vector_Views g-alvevi ads,GNAT Array_Split g-arrspl ads,GNAT Altivec Vector_Types g-alvety ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-views-g-alvevi-ads}@anchor{32e}@anchor{gnat_rm/the_gnat_library id33}@anchor{32f} +@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-views-g-alvevi-ads}@anchor{332}@anchor{gnat_rm/the_gnat_library id33}@anchor{333} @section @code{GNAT.Altivec.Vector_Views} (@code{g-alvevi.ads}) @@ -24027,7 +24106,7 @@ vector elements and provides a simple way to initialize vector objects. @node GNAT Array_Split g-arrspl ads,GNAT AWK g-awk ads,GNAT Altivec Vector_Views g-alvevi ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-array-split-g-arrspl-ads}@anchor{330}@anchor{gnat_rm/the_gnat_library id34}@anchor{331} +@anchor{gnat_rm/the_gnat_library gnat-array-split-g-arrspl-ads}@anchor{334}@anchor{gnat_rm/the_gnat_library id34}@anchor{335} @section @code{GNAT.Array_Split} (@code{g-arrspl.ads}) @@ -24040,7 +24119,7 @@ an array wherever the separators appear, and provide direct access to the resulting slices. @node GNAT AWK g-awk ads,GNAT Binary_Search g-binsea ads,GNAT Array_Split g-arrspl ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-awk-g-awk-ads}@anchor{332}@anchor{gnat_rm/the_gnat_library id35}@anchor{333} +@anchor{gnat_rm/the_gnat_library gnat-awk-g-awk-ads}@anchor{336}@anchor{gnat_rm/the_gnat_library id35}@anchor{337} @section @code{GNAT.AWK} (@code{g-awk.ads}) @@ -24055,7 +24134,7 @@ or more files containing formatted data. The file is viewed as a database where each record is a line and a field is a data element in this line. @node GNAT Binary_Search g-binsea ads,GNAT Bind_Environment g-binenv ads,GNAT AWK g-awk ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-binary-search-g-binsea-ads}@anchor{334}@anchor{gnat_rm/the_gnat_library id36}@anchor{335} +@anchor{gnat_rm/the_gnat_library gnat-binary-search-g-binsea-ads}@anchor{338}@anchor{gnat_rm/the_gnat_library id36}@anchor{339} @section @code{GNAT.Binary_Search} (@code{g-binsea.ads}) @@ -24067,7 +24146,7 @@ Allow binary search of a sorted array (or of an array-like container; the generic does not reference the array directly). @node GNAT Bind_Environment g-binenv ads,GNAT Branch_Prediction g-brapre ads,GNAT Binary_Search g-binsea ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-bind-environment-g-binenv-ads}@anchor{336}@anchor{gnat_rm/the_gnat_library id37}@anchor{337} +@anchor{gnat_rm/the_gnat_library gnat-bind-environment-g-binenv-ads}@anchor{33a}@anchor{gnat_rm/the_gnat_library id37}@anchor{33b} @section @code{GNAT.Bind_Environment} (@code{g-binenv.ads}) @@ -24080,7 +24159,7 @@ These associations can be specified using the @code{-V} binder command line switch. @node GNAT Branch_Prediction g-brapre ads,GNAT Bounded_Buffers g-boubuf ads,GNAT Bind_Environment g-binenv ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-branch-prediction-g-brapre-ads}@anchor{338}@anchor{gnat_rm/the_gnat_library id38}@anchor{339} +@anchor{gnat_rm/the_gnat_library gnat-branch-prediction-g-brapre-ads}@anchor{33c}@anchor{gnat_rm/the_gnat_library id38}@anchor{33d} @section @code{GNAT.Branch_Prediction} (@code{g-brapre.ads}) @@ -24091,7 +24170,7 @@ line switch. Provides routines giving hints to the branch predictor of the code generator. @node GNAT Bounded_Buffers g-boubuf ads,GNAT Bounded_Mailboxes g-boumai ads,GNAT Branch_Prediction g-brapre ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-bounded-buffers-g-boubuf-ads}@anchor{33a}@anchor{gnat_rm/the_gnat_library id39}@anchor{33b} +@anchor{gnat_rm/the_gnat_library gnat-bounded-buffers-g-boubuf-ads}@anchor{33e}@anchor{gnat_rm/the_gnat_library id39}@anchor{33f} @section @code{GNAT.Bounded_Buffers} (@code{g-boubuf.ads}) @@ -24106,7 +24185,7 @@ useful directly or as parts of the implementations of other abstractions, such as mailboxes. @node GNAT Bounded_Mailboxes g-boumai ads,GNAT Bubble_Sort g-bubsor ads,GNAT Bounded_Buffers g-boubuf ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-bounded-mailboxes-g-boumai-ads}@anchor{33c}@anchor{gnat_rm/the_gnat_library id40}@anchor{33d} +@anchor{gnat_rm/the_gnat_library gnat-bounded-mailboxes-g-boumai-ads}@anchor{340}@anchor{gnat_rm/the_gnat_library id40}@anchor{341} @section @code{GNAT.Bounded_Mailboxes} (@code{g-boumai.ads}) @@ -24119,7 +24198,7 @@ such as mailboxes. Provides a thread-safe asynchronous intertask mailbox communication facility. @node GNAT Bubble_Sort g-bubsor ads,GNAT Bubble_Sort_A g-busora ads,GNAT Bounded_Mailboxes g-boumai ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-bubsor-ads}@anchor{33e}@anchor{gnat_rm/the_gnat_library id41}@anchor{33f} +@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-bubsor-ads}@anchor{342}@anchor{gnat_rm/the_gnat_library id41}@anchor{343} @section @code{GNAT.Bubble_Sort} (@code{g-bubsor.ads}) @@ -24134,7 +24213,7 @@ data items. Exchange and comparison procedures are provided by passing access-to-procedure values. @node GNAT Bubble_Sort_A g-busora ads,GNAT Bubble_Sort_G g-busorg ads,GNAT Bubble_Sort g-bubsor ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-a-g-busora-ads}@anchor{340}@anchor{gnat_rm/the_gnat_library id42}@anchor{341} +@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-a-g-busora-ads}@anchor{344}@anchor{gnat_rm/the_gnat_library id42}@anchor{345} @section @code{GNAT.Bubble_Sort_A} (@code{g-busora.ads}) @@ -24150,7 +24229,7 @@ access-to-procedure values. This is an older version, retained for compatibility. Usually @code{GNAT.Bubble_Sort} will be preferable. @node GNAT Bubble_Sort_G g-busorg ads,GNAT Byte_Order_Mark g-byorma ads,GNAT Bubble_Sort_A g-busora ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-g-busorg-ads}@anchor{342}@anchor{gnat_rm/the_gnat_library id43}@anchor{343} +@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-g-busorg-ads}@anchor{346}@anchor{gnat_rm/the_gnat_library id43}@anchor{347} @section @code{GNAT.Bubble_Sort_G} (@code{g-busorg.ads}) @@ -24166,7 +24245,7 @@ if the procedures can be inlined, at the expense of duplicating code for multiple instantiations. @node GNAT Byte_Order_Mark g-byorma ads,GNAT Byte_Swapping g-bytswa ads,GNAT Bubble_Sort_G g-busorg ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-byte-order-mark-g-byorma-ads}@anchor{344}@anchor{gnat_rm/the_gnat_library id44}@anchor{345} +@anchor{gnat_rm/the_gnat_library gnat-byte-order-mark-g-byorma-ads}@anchor{348}@anchor{gnat_rm/the_gnat_library id44}@anchor{349} @section @code{GNAT.Byte_Order_Mark} (@code{g-byorma.ads}) @@ -24182,7 +24261,7 @@ the encoding of the string. The routine includes detection of special XML sequences for various UCS input formats. @node GNAT Byte_Swapping g-bytswa ads,GNAT Calendar g-calend ads,GNAT Byte_Order_Mark g-byorma ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-byte-swapping-g-bytswa-ads}@anchor{346}@anchor{gnat_rm/the_gnat_library id45}@anchor{347} +@anchor{gnat_rm/the_gnat_library gnat-byte-swapping-g-bytswa-ads}@anchor{34a}@anchor{gnat_rm/the_gnat_library id45}@anchor{34b} @section @code{GNAT.Byte_Swapping} (@code{g-bytswa.ads}) @@ -24196,7 +24275,7 @@ General routines for swapping the bytes in 2-, 4-, and 8-byte quantities. Machine-specific implementations are available in some cases. @node GNAT Calendar g-calend ads,GNAT Calendar Time_IO g-catiio ads,GNAT Byte_Swapping g-bytswa ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-calendar-g-calend-ads}@anchor{348}@anchor{gnat_rm/the_gnat_library id46}@anchor{349} +@anchor{gnat_rm/the_gnat_library gnat-calendar-g-calend-ads}@anchor{34c}@anchor{gnat_rm/the_gnat_library id46}@anchor{34d} @section @code{GNAT.Calendar} (@code{g-calend.ads}) @@ -24210,7 +24289,7 @@ Also provides conversion of @code{Ada.Calendar.Time} values to and from the C @code{timeval} format. @node GNAT Calendar Time_IO g-catiio ads,GNAT CRC32 g-crc32 ads,GNAT Calendar g-calend ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-calendar-time-io-g-catiio-ads}@anchor{34a}@anchor{gnat_rm/the_gnat_library id47}@anchor{34b} +@anchor{gnat_rm/the_gnat_library gnat-calendar-time-io-g-catiio-ads}@anchor{34e}@anchor{gnat_rm/the_gnat_library id47}@anchor{34f} @section @code{GNAT.Calendar.Time_IO} (@code{g-catiio.ads}) @@ -24221,7 +24300,7 @@ C @code{timeval} format. @geindex GNAT.Calendar.Time_IO (g-catiio.ads) @node GNAT CRC32 g-crc32 ads,GNAT Case_Util g-casuti ads,GNAT Calendar Time_IO g-catiio ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-crc32-g-crc32-ads}@anchor{34c}@anchor{gnat_rm/the_gnat_library id48}@anchor{34d} +@anchor{gnat_rm/the_gnat_library gnat-crc32-g-crc32-ads}@anchor{350}@anchor{gnat_rm/the_gnat_library id48}@anchor{351} @section @code{GNAT.CRC32} (@code{g-crc32.ads}) @@ -24238,7 +24317,7 @@ of this algorithm see Aug. 1988. Sarwate, D.V. @node GNAT Case_Util g-casuti ads,GNAT CGI g-cgi ads,GNAT CRC32 g-crc32 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-case-util-g-casuti-ads}@anchor{34e}@anchor{gnat_rm/the_gnat_library id49}@anchor{34f} +@anchor{gnat_rm/the_gnat_library gnat-case-util-g-casuti-ads}@anchor{352}@anchor{gnat_rm/the_gnat_library id49}@anchor{353} @section @code{GNAT.Case_Util} (@code{g-casuti.ads}) @@ -24253,7 +24332,7 @@ without the overhead of the full casing tables in @code{Ada.Characters.Handling}. @node GNAT CGI g-cgi ads,GNAT CGI Cookie g-cgicoo ads,GNAT Case_Util g-casuti ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-cgi-g-cgi-ads}@anchor{350}@anchor{gnat_rm/the_gnat_library id50}@anchor{351} +@anchor{gnat_rm/the_gnat_library gnat-cgi-g-cgi-ads}@anchor{354}@anchor{gnat_rm/the_gnat_library id50}@anchor{355} @section @code{GNAT.CGI} (@code{g-cgi.ads}) @@ -24268,7 +24347,7 @@ builds a table whose index is the key and provides some services to deal with this table. @node GNAT CGI Cookie g-cgicoo ads,GNAT CGI Debug g-cgideb ads,GNAT CGI g-cgi ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-cgi-cookie-g-cgicoo-ads}@anchor{352}@anchor{gnat_rm/the_gnat_library id51}@anchor{353} +@anchor{gnat_rm/the_gnat_library gnat-cgi-cookie-g-cgicoo-ads}@anchor{356}@anchor{gnat_rm/the_gnat_library id51}@anchor{357} @section @code{GNAT.CGI.Cookie} (@code{g-cgicoo.ads}) @@ -24283,7 +24362,7 @@ Common Gateway Interface (CGI). It exports services to deal with Web cookies (piece of information kept in the Web client software). @node GNAT CGI Debug g-cgideb ads,GNAT Command_Line g-comlin ads,GNAT CGI Cookie g-cgicoo ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-cgi-debug-g-cgideb-ads}@anchor{354}@anchor{gnat_rm/the_gnat_library id52}@anchor{355} +@anchor{gnat_rm/the_gnat_library gnat-cgi-debug-g-cgideb-ads}@anchor{358}@anchor{gnat_rm/the_gnat_library id52}@anchor{359} @section @code{GNAT.CGI.Debug} (@code{g-cgideb.ads}) @@ -24295,7 +24374,7 @@ This is a package to help debugging CGI (Common Gateway Interface) programs written in Ada. @node GNAT Command_Line g-comlin ads,GNAT Compiler_Version g-comver ads,GNAT CGI Debug g-cgideb ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-command-line-g-comlin-ads}@anchor{356}@anchor{gnat_rm/the_gnat_library id53}@anchor{357} +@anchor{gnat_rm/the_gnat_library gnat-command-line-g-comlin-ads}@anchor{35a}@anchor{gnat_rm/the_gnat_library id53}@anchor{35b} @section @code{GNAT.Command_Line} (@code{g-comlin.ads}) @@ -24308,7 +24387,7 @@ including the ability to scan for named switches with optional parameters and expand file names using wildcard notations. @node GNAT Compiler_Version g-comver ads,GNAT Ctrl_C g-ctrl_c ads,GNAT Command_Line g-comlin ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-compiler-version-g-comver-ads}@anchor{358}@anchor{gnat_rm/the_gnat_library id54}@anchor{359} +@anchor{gnat_rm/the_gnat_library gnat-compiler-version-g-comver-ads}@anchor{35c}@anchor{gnat_rm/the_gnat_library id54}@anchor{35d} @section @code{GNAT.Compiler_Version} (@code{g-comver.ads}) @@ -24326,7 +24405,7 @@ of the compiler if a consistent tool set is used to compile all units of a partition). @node GNAT Ctrl_C g-ctrl_c ads,GNAT Current_Exception g-curexc ads,GNAT Compiler_Version g-comver ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-ctrl-c-g-ctrl-c-ads}@anchor{35a}@anchor{gnat_rm/the_gnat_library id55}@anchor{35b} +@anchor{gnat_rm/the_gnat_library gnat-ctrl-c-g-ctrl-c-ads}@anchor{35e}@anchor{gnat_rm/the_gnat_library id55}@anchor{35f} @section @code{GNAT.Ctrl_C} (@code{g-ctrl_c.ads}) @@ -24337,7 +24416,7 @@ of a partition). Provides a simple interface to handle Ctrl-C keyboard events. @node GNAT Current_Exception g-curexc ads,GNAT Debug_Pools g-debpoo ads,GNAT Ctrl_C g-ctrl_c ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-current-exception-g-curexc-ads}@anchor{35c}@anchor{gnat_rm/the_gnat_library id56}@anchor{35d} +@anchor{gnat_rm/the_gnat_library gnat-current-exception-g-curexc-ads}@anchor{360}@anchor{gnat_rm/the_gnat_library id56}@anchor{361} @section @code{GNAT.Current_Exception} (@code{g-curexc.ads}) @@ -24354,7 +24433,7 @@ This is particularly useful in simulating typical facilities for obtaining information about exceptions provided by Ada 83 compilers. @node GNAT Debug_Pools g-debpoo ads,GNAT Debug_Utilities g-debuti ads,GNAT Current_Exception g-curexc ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-debug-pools-g-debpoo-ads}@anchor{35e}@anchor{gnat_rm/the_gnat_library id57}@anchor{35f} +@anchor{gnat_rm/the_gnat_library gnat-debug-pools-g-debpoo-ads}@anchor{362}@anchor{gnat_rm/the_gnat_library id57}@anchor{363} @section @code{GNAT.Debug_Pools} (@code{g-debpoo.ads}) @@ -24371,7 +24450,7 @@ problems. See @code{The GNAT Debug_Pool Facility} section in the @cite{GNAT User’s Guide}. @node GNAT Debug_Utilities g-debuti ads,GNAT Decode_String g-decstr ads,GNAT Debug_Pools g-debpoo ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-debug-utilities-g-debuti-ads}@anchor{360}@anchor{gnat_rm/the_gnat_library id58}@anchor{361} +@anchor{gnat_rm/the_gnat_library gnat-debug-utilities-g-debuti-ads}@anchor{364}@anchor{gnat_rm/the_gnat_library id58}@anchor{365} @section @code{GNAT.Debug_Utilities} (@code{g-debuti.ads}) @@ -24384,7 +24463,7 @@ to and from string images of address values. Supports both C and Ada formats for hexadecimal literals. @node GNAT Decode_String g-decstr ads,GNAT Decode_UTF8_String g-deutst ads,GNAT Debug_Utilities g-debuti ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-decode-string-g-decstr-ads}@anchor{362}@anchor{gnat_rm/the_gnat_library id59}@anchor{363} +@anchor{gnat_rm/the_gnat_library gnat-decode-string-g-decstr-ads}@anchor{366}@anchor{gnat_rm/the_gnat_library id59}@anchor{367} @section @code{GNAT.Decode_String} (@code{g-decstr.ads}) @@ -24408,7 +24487,7 @@ Useful in conjunction with Unicode character coding. Note there is a preinstantiation for UTF-8. See next entry. @node GNAT Decode_UTF8_String g-deutst ads,GNAT Directory_Operations g-dirope ads,GNAT Decode_String g-decstr ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-decode-utf8-string-g-deutst-ads}@anchor{364}@anchor{gnat_rm/the_gnat_library id60}@anchor{365} +@anchor{gnat_rm/the_gnat_library gnat-decode-utf8-string-g-deutst-ads}@anchor{368}@anchor{gnat_rm/the_gnat_library id60}@anchor{369} @section @code{GNAT.Decode_UTF8_String} (@code{g-deutst.ads}) @@ -24429,7 +24508,7 @@ preinstantiation for UTF-8. See next entry. A preinstantiation of GNAT.Decode_Strings for UTF-8 encoding. @node GNAT Directory_Operations g-dirope ads,GNAT Directory_Operations Iteration g-diopit ads,GNAT Decode_UTF8_String g-deutst ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-directory-operations-g-dirope-ads}@anchor{366}@anchor{gnat_rm/the_gnat_library id61}@anchor{367} +@anchor{gnat_rm/the_gnat_library gnat-directory-operations-g-dirope-ads}@anchor{36a}@anchor{gnat_rm/the_gnat_library id61}@anchor{36b} @section @code{GNAT.Directory_Operations} (@code{g-dirope.ads}) @@ -24442,7 +24521,7 @@ the current directory, making new directories, and scanning the files in a directory. @node GNAT Directory_Operations Iteration g-diopit ads,GNAT Dynamic_HTables g-dynhta ads,GNAT Directory_Operations g-dirope ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-directory-operations-iteration-g-diopit-ads}@anchor{368}@anchor{gnat_rm/the_gnat_library id62}@anchor{369} +@anchor{gnat_rm/the_gnat_library gnat-directory-operations-iteration-g-diopit-ads}@anchor{36c}@anchor{gnat_rm/the_gnat_library id62}@anchor{36d} @section @code{GNAT.Directory_Operations.Iteration} (@code{g-diopit.ads}) @@ -24454,7 +24533,7 @@ A child unit of GNAT.Directory_Operations providing additional operations for iterating through directories. @node GNAT Dynamic_HTables g-dynhta ads,GNAT Dynamic_Tables g-dyntab ads,GNAT Directory_Operations Iteration g-diopit ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-dynamic-htables-g-dynhta-ads}@anchor{36a}@anchor{gnat_rm/the_gnat_library id63}@anchor{36b} +@anchor{gnat_rm/the_gnat_library gnat-dynamic-htables-g-dynhta-ads}@anchor{36e}@anchor{gnat_rm/the_gnat_library id63}@anchor{36f} @section @code{GNAT.Dynamic_HTables} (@code{g-dynhta.ads}) @@ -24472,7 +24551,7 @@ dynamic instances of the hash table, while an instantiation of @code{GNAT.HTable} creates a single instance of the hash table. @node GNAT Dynamic_Tables g-dyntab ads,GNAT Encode_String g-encstr ads,GNAT Dynamic_HTables g-dynhta ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-dynamic-tables-g-dyntab-ads}@anchor{36c}@anchor{gnat_rm/the_gnat_library id64}@anchor{36d} +@anchor{gnat_rm/the_gnat_library gnat-dynamic-tables-g-dyntab-ads}@anchor{370}@anchor{gnat_rm/the_gnat_library id64}@anchor{371} @section @code{GNAT.Dynamic_Tables} (@code{g-dyntab.ads}) @@ -24492,7 +24571,7 @@ dynamic instances of the table, while an instantiation of @code{GNAT.Table} creates a single instance of the table type. @node GNAT Encode_String g-encstr ads,GNAT Encode_UTF8_String g-enutst ads,GNAT Dynamic_Tables g-dyntab ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-encode-string-g-encstr-ads}@anchor{36e}@anchor{gnat_rm/the_gnat_library id65}@anchor{36f} +@anchor{gnat_rm/the_gnat_library gnat-encode-string-g-encstr-ads}@anchor{372}@anchor{gnat_rm/the_gnat_library id65}@anchor{373} @section @code{GNAT.Encode_String} (@code{g-encstr.ads}) @@ -24514,7 +24593,7 @@ encoding method. Useful in conjunction with Unicode character coding. Note there is a preinstantiation for UTF-8. See next entry. @node GNAT Encode_UTF8_String g-enutst ads,GNAT Exception_Actions g-excact ads,GNAT Encode_String g-encstr ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-encode-utf8-string-g-enutst-ads}@anchor{370}@anchor{gnat_rm/the_gnat_library id66}@anchor{371} +@anchor{gnat_rm/the_gnat_library gnat-encode-utf8-string-g-enutst-ads}@anchor{374}@anchor{gnat_rm/the_gnat_library id66}@anchor{375} @section @code{GNAT.Encode_UTF8_String} (@code{g-enutst.ads}) @@ -24535,7 +24614,7 @@ Note there is a preinstantiation for UTF-8. See next entry. A preinstantiation of GNAT.Encode_Strings for UTF-8 encoding. @node GNAT Exception_Actions g-excact ads,GNAT Exception_Traces g-exctra ads,GNAT Encode_UTF8_String g-enutst ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-exception-actions-g-excact-ads}@anchor{372}@anchor{gnat_rm/the_gnat_library id67}@anchor{373} +@anchor{gnat_rm/the_gnat_library gnat-exception-actions-g-excact-ads}@anchor{376}@anchor{gnat_rm/the_gnat_library id67}@anchor{377} @section @code{GNAT.Exception_Actions} (@code{g-excact.ads}) @@ -24548,7 +24627,7 @@ for specific exceptions, or when any exception is raised. This can be used for instance to force a core dump to ease debugging. @node GNAT Exception_Traces g-exctra ads,GNAT Exceptions g-except ads,GNAT Exception_Actions g-excact ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-exception-traces-g-exctra-ads}@anchor{374}@anchor{gnat_rm/the_gnat_library id68}@anchor{375} +@anchor{gnat_rm/the_gnat_library gnat-exception-traces-g-exctra-ads}@anchor{378}@anchor{gnat_rm/the_gnat_library id68}@anchor{379} @section @code{GNAT.Exception_Traces} (@code{g-exctra.ads}) @@ -24562,7 +24641,7 @@ Provides an interface allowing to control automatic output upon exception occurrences. @node GNAT Exceptions g-except ads,GNAT Expect g-expect ads,GNAT Exception_Traces g-exctra ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-exceptions-g-except-ads}@anchor{376}@anchor{gnat_rm/the_gnat_library id69}@anchor{377} +@anchor{gnat_rm/the_gnat_library gnat-exceptions-g-except-ads}@anchor{37a}@anchor{gnat_rm/the_gnat_library id69}@anchor{37b} @section @code{GNAT.Exceptions} (@code{g-except.ads}) @@ -24583,7 +24662,7 @@ predefined exceptions, and for example allows raising @code{Constraint_Error} with a message from a pure subprogram. @node GNAT Expect g-expect ads,GNAT Expect TTY g-exptty ads,GNAT Exceptions g-except ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-expect-g-expect-ads}@anchor{378}@anchor{gnat_rm/the_gnat_library id70}@anchor{379} +@anchor{gnat_rm/the_gnat_library gnat-expect-g-expect-ads}@anchor{37c}@anchor{gnat_rm/the_gnat_library id70}@anchor{37d} @section @code{GNAT.Expect} (@code{g-expect.ads}) @@ -24599,7 +24678,7 @@ It is not implemented for cross ports, and in particular is not implemented for VxWorks or LynxOS. @node GNAT Expect TTY g-exptty ads,GNAT Float_Control g-flocon ads,GNAT Expect g-expect ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-expect-tty-g-exptty-ads}@anchor{37a}@anchor{gnat_rm/the_gnat_library id71}@anchor{37b} +@anchor{gnat_rm/the_gnat_library gnat-expect-tty-g-exptty-ads}@anchor{37e}@anchor{gnat_rm/the_gnat_library id71}@anchor{37f} @section @code{GNAT.Expect.TTY} (@code{g-exptty.ads}) @@ -24611,7 +24690,7 @@ ports. It is not implemented for cross ports, and in particular is not implemented for VxWorks or LynxOS. @node GNAT Float_Control g-flocon ads,GNAT Formatted_String g-forstr ads,GNAT Expect TTY g-exptty ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-float-control-g-flocon-ads}@anchor{37c}@anchor{gnat_rm/the_gnat_library id72}@anchor{37d} +@anchor{gnat_rm/the_gnat_library gnat-float-control-g-flocon-ads}@anchor{380}@anchor{gnat_rm/the_gnat_library id72}@anchor{381} @section @code{GNAT.Float_Control} (@code{g-flocon.ads}) @@ -24625,7 +24704,7 @@ library calls may cause this mode to be modified, and the Reset procedure in this package can be used to reestablish the required mode. @node GNAT Formatted_String g-forstr ads,GNAT Generic_Fast_Math_Functions g-gfmafu ads,GNAT Float_Control g-flocon ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-formatted-string-g-forstr-ads}@anchor{37e}@anchor{gnat_rm/the_gnat_library id73}@anchor{37f} +@anchor{gnat_rm/the_gnat_library gnat-formatted-string-g-forstr-ads}@anchor{382}@anchor{gnat_rm/the_gnat_library id73}@anchor{383} @section @code{GNAT.Formatted_String} (@code{g-forstr.ads}) @@ -24640,7 +24719,7 @@ derived from Integer, Float or enumerations as values for the formatted string. @node GNAT Generic_Fast_Math_Functions g-gfmafu ads,GNAT Heap_Sort g-heasor ads,GNAT Formatted_String g-forstr ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-generic-fast-math-functions-g-gfmafu-ads}@anchor{380}@anchor{gnat_rm/the_gnat_library id74}@anchor{381} +@anchor{gnat_rm/the_gnat_library gnat-generic-fast-math-functions-g-gfmafu-ads}@anchor{384}@anchor{gnat_rm/the_gnat_library id74}@anchor{385} @section @code{GNAT.Generic_Fast_Math_Functions} (@code{g-gfmafu.ads}) @@ -24658,7 +24737,7 @@ have a vector implementation that can be automatically used by the compiler when auto-vectorization is enabled. @node GNAT Heap_Sort g-heasor ads,GNAT Heap_Sort_A g-hesora ads,GNAT Generic_Fast_Math_Functions g-gfmafu ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-heasor-ads}@anchor{382}@anchor{gnat_rm/the_gnat_library id75}@anchor{383} +@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-heasor-ads}@anchor{386}@anchor{gnat_rm/the_gnat_library id75}@anchor{387} @section @code{GNAT.Heap_Sort} (@code{g-heasor.ads}) @@ -24672,7 +24751,7 @@ access-to-procedure values. The algorithm used is a modified heap sort that performs approximately N*log(N) comparisons in the worst case. @node GNAT Heap_Sort_A g-hesora ads,GNAT Heap_Sort_G g-hesorg ads,GNAT Heap_Sort g-heasor ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-heap-sort-a-g-hesora-ads}@anchor{384}@anchor{gnat_rm/the_gnat_library id76}@anchor{385} +@anchor{gnat_rm/the_gnat_library gnat-heap-sort-a-g-hesora-ads}@anchor{388}@anchor{gnat_rm/the_gnat_library id76}@anchor{389} @section @code{GNAT.Heap_Sort_A} (@code{g-hesora.ads}) @@ -24688,7 +24767,7 @@ This differs from @code{GNAT.Heap_Sort} in having a less convenient interface, but may be slightly more efficient. @node GNAT Heap_Sort_G g-hesorg ads,GNAT HTable g-htable ads,GNAT Heap_Sort_A g-hesora ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-g-hesorg-ads}@anchor{386}@anchor{gnat_rm/the_gnat_library id77}@anchor{387} +@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-g-hesorg-ads}@anchor{38a}@anchor{gnat_rm/the_gnat_library id77}@anchor{38b} @section @code{GNAT.Heap_Sort_G} (@code{g-hesorg.ads}) @@ -24702,7 +24781,7 @@ if the procedures can be inlined, at the expense of duplicating code for multiple instantiations. @node GNAT HTable g-htable ads,GNAT IO g-io ads,GNAT Heap_Sort_G g-hesorg ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-htable-g-htable-ads}@anchor{388}@anchor{gnat_rm/the_gnat_library id78}@anchor{389} +@anchor{gnat_rm/the_gnat_library gnat-htable-g-htable-ads}@anchor{38c}@anchor{gnat_rm/the_gnat_library id78}@anchor{38d} @section @code{GNAT.HTable} (@code{g-htable.ads}) @@ -24715,7 +24794,7 @@ data. Provides two approaches, one a simple static approach, and the other allowing arbitrary dynamic hash tables. @node GNAT IO g-io ads,GNAT IO_Aux g-io_aux ads,GNAT HTable g-htable ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-io-g-io-ads}@anchor{38a}@anchor{gnat_rm/the_gnat_library id79}@anchor{38b} +@anchor{gnat_rm/the_gnat_library gnat-io-g-io-ads}@anchor{38e}@anchor{gnat_rm/the_gnat_library id79}@anchor{38f} @section @code{GNAT.IO} (@code{g-io.ads}) @@ -24731,7 +24810,7 @@ Standard_Input, and writing characters, strings and integers to either Standard_Output or Standard_Error. @node GNAT IO_Aux g-io_aux ads,GNAT Lock_Files g-locfil ads,GNAT IO g-io ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-io-aux-g-io-aux-ads}@anchor{38c}@anchor{gnat_rm/the_gnat_library id80}@anchor{38d} +@anchor{gnat_rm/the_gnat_library gnat-io-aux-g-io-aux-ads}@anchor{390}@anchor{gnat_rm/the_gnat_library id80}@anchor{391} @section @code{GNAT.IO_Aux} (@code{g-io_aux.ads}) @@ -24745,7 +24824,7 @@ Provides some auxiliary functions for use with Text_IO, including a test for whether a file exists, and functions for reading a line of text. @node GNAT Lock_Files g-locfil ads,GNAT MBBS_Discrete_Random g-mbdira ads,GNAT IO_Aux g-io_aux ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-lock-files-g-locfil-ads}@anchor{38e}@anchor{gnat_rm/the_gnat_library id81}@anchor{38f} +@anchor{gnat_rm/the_gnat_library gnat-lock-files-g-locfil-ads}@anchor{392}@anchor{gnat_rm/the_gnat_library id81}@anchor{393} @section @code{GNAT.Lock_Files} (@code{g-locfil.ads}) @@ -24759,7 +24838,7 @@ Provides a general interface for using files as locks. Can be used for providing program level synchronization. @node GNAT MBBS_Discrete_Random g-mbdira ads,GNAT MBBS_Float_Random g-mbflra ads,GNAT Lock_Files g-locfil ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-mbbs-discrete-random-g-mbdira-ads}@anchor{390}@anchor{gnat_rm/the_gnat_library id82}@anchor{391} +@anchor{gnat_rm/the_gnat_library gnat-mbbs-discrete-random-g-mbdira-ads}@anchor{394}@anchor{gnat_rm/the_gnat_library id82}@anchor{395} @section @code{GNAT.MBBS_Discrete_Random} (@code{g-mbdira.ads}) @@ -24771,7 +24850,7 @@ The original implementation of @code{Ada.Numerics.Discrete_Random}. Uses a modified version of the Blum-Blum-Shub generator. @node GNAT MBBS_Float_Random g-mbflra ads,GNAT MD5 g-md5 ads,GNAT MBBS_Discrete_Random g-mbdira ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-mbbs-float-random-g-mbflra-ads}@anchor{392}@anchor{gnat_rm/the_gnat_library id83}@anchor{393} +@anchor{gnat_rm/the_gnat_library gnat-mbbs-float-random-g-mbflra-ads}@anchor{396}@anchor{gnat_rm/the_gnat_library id83}@anchor{397} @section @code{GNAT.MBBS_Float_Random} (@code{g-mbflra.ads}) @@ -24783,7 +24862,7 @@ The original implementation of @code{Ada.Numerics.Float_Random}. Uses a modified version of the Blum-Blum-Shub generator. @node GNAT MD5 g-md5 ads,GNAT Memory_Dump g-memdum ads,GNAT MBBS_Float_Random g-mbflra ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-md5-g-md5-ads}@anchor{394}@anchor{gnat_rm/the_gnat_library id84}@anchor{395} +@anchor{gnat_rm/the_gnat_library gnat-md5-g-md5-ads}@anchor{398}@anchor{gnat_rm/the_gnat_library id84}@anchor{399} @section @code{GNAT.MD5} (@code{g-md5.ads}) @@ -24796,7 +24875,7 @@ the HMAC-MD5 message authentication function as described in RFC 2104 and FIPS PUB 198. @node GNAT Memory_Dump g-memdum ads,GNAT Most_Recent_Exception g-moreex ads,GNAT MD5 g-md5 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-memory-dump-g-memdum-ads}@anchor{396}@anchor{gnat_rm/the_gnat_library id85}@anchor{397} +@anchor{gnat_rm/the_gnat_library gnat-memory-dump-g-memdum-ads}@anchor{39a}@anchor{gnat_rm/the_gnat_library id85}@anchor{39b} @section @code{GNAT.Memory_Dump} (@code{g-memdum.ads}) @@ -24809,7 +24888,7 @@ standard output or standard error files. Uses GNAT.IO for actual output. @node GNAT Most_Recent_Exception g-moreex ads,GNAT OS_Lib g-os_lib ads,GNAT Memory_Dump g-memdum ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-most-recent-exception-g-moreex-ads}@anchor{398}@anchor{gnat_rm/the_gnat_library id86}@anchor{399} +@anchor{gnat_rm/the_gnat_library gnat-most-recent-exception-g-moreex-ads}@anchor{39c}@anchor{gnat_rm/the_gnat_library id86}@anchor{39d} @section @code{GNAT.Most_Recent_Exception} (@code{g-moreex.ads}) @@ -24823,7 +24902,7 @@ various logging purposes, including duplicating functionality of some Ada 83 implementation dependent extensions. @node GNAT OS_Lib g-os_lib ads,GNAT Perfect_Hash_Generators g-pehage ads,GNAT Most_Recent_Exception g-moreex ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-os-lib-g-os-lib-ads}@anchor{39a}@anchor{gnat_rm/the_gnat_library id87}@anchor{39b} +@anchor{gnat_rm/the_gnat_library gnat-os-lib-g-os-lib-ads}@anchor{39e}@anchor{gnat_rm/the_gnat_library id87}@anchor{39f} @section @code{GNAT.OS_Lib} (@code{g-os_lib.ads}) @@ -24839,7 +24918,7 @@ including a portable spawn procedure, and access to environment variables and error return codes. @node GNAT Perfect_Hash_Generators g-pehage ads,GNAT Random_Numbers g-rannum ads,GNAT OS_Lib g-os_lib ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-perfect-hash-generators-g-pehage-ads}@anchor{39c}@anchor{gnat_rm/the_gnat_library id88}@anchor{39d} +@anchor{gnat_rm/the_gnat_library gnat-perfect-hash-generators-g-pehage-ads}@anchor{3a0}@anchor{gnat_rm/the_gnat_library id88}@anchor{3a1} @section @code{GNAT.Perfect_Hash_Generators} (@code{g-pehage.ads}) @@ -24857,7 +24936,7 @@ hashcode are in the same order. These hashing functions are very convenient for use with realtime applications. @node GNAT Random_Numbers g-rannum ads,GNAT Regexp g-regexp ads,GNAT Perfect_Hash_Generators g-pehage ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-random-numbers-g-rannum-ads}@anchor{39e}@anchor{gnat_rm/the_gnat_library id89}@anchor{39f} +@anchor{gnat_rm/the_gnat_library gnat-random-numbers-g-rannum-ads}@anchor{3a2}@anchor{gnat_rm/the_gnat_library id89}@anchor{3a3} @section @code{GNAT.Random_Numbers} (@code{g-rannum.ads}) @@ -24871,7 +24950,7 @@ however NOT suitable for situations requiring cryptographically secure randomness. @node GNAT Regexp g-regexp ads,GNAT Registry g-regist ads,GNAT Random_Numbers g-rannum ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-regexp-g-regexp-ads}@anchor{275}@anchor{gnat_rm/the_gnat_library id90}@anchor{3a0} +@anchor{gnat_rm/the_gnat_library gnat-regexp-g-regexp-ads}@anchor{279}@anchor{gnat_rm/the_gnat_library id90}@anchor{3a4} @section @code{GNAT.Regexp} (@code{g-regexp.ads}) @@ -24887,7 +24966,7 @@ simplest of the three pattern matching packages provided, and is particularly suitable for ‘file globbing’ applications. @node GNAT Registry g-regist ads,GNAT Regpat g-regpat ads,GNAT Regexp g-regexp ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-registry-g-regist-ads}@anchor{3a1}@anchor{gnat_rm/the_gnat_library id91}@anchor{3a2} +@anchor{gnat_rm/the_gnat_library gnat-registry-g-regist-ads}@anchor{3a5}@anchor{gnat_rm/the_gnat_library id91}@anchor{3a6} @section @code{GNAT.Registry} (@code{g-regist.ads}) @@ -24901,7 +24980,7 @@ registry API, but at a lower level of abstraction, refer to the Win32.Winreg package provided with the Win32Ada binding @node GNAT Regpat g-regpat ads,GNAT Rewrite_Data g-rewdat ads,GNAT Registry g-regist ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-regpat-g-regpat-ads}@anchor{3a3}@anchor{gnat_rm/the_gnat_library id92}@anchor{3a4} +@anchor{gnat_rm/the_gnat_library gnat-regpat-g-regpat-ads}@anchor{3a7}@anchor{gnat_rm/the_gnat_library id92}@anchor{3a8} @section @code{GNAT.Regpat} (@code{g-regpat.ads}) @@ -24916,7 +24995,7 @@ from the original V7 style regular expression library written in C by Henry Spencer (and binary compatible with this C library). @node GNAT Rewrite_Data g-rewdat ads,GNAT Secondary_Stack_Info g-sestin ads,GNAT Regpat g-regpat ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-rewrite-data-g-rewdat-ads}@anchor{3a5}@anchor{gnat_rm/the_gnat_library id93}@anchor{3a6} +@anchor{gnat_rm/the_gnat_library gnat-rewrite-data-g-rewdat-ads}@anchor{3a9}@anchor{gnat_rm/the_gnat_library id93}@anchor{3aa} @section @code{GNAT.Rewrite_Data} (@code{g-rewdat.ads}) @@ -24930,7 +25009,7 @@ full content to be processed is not loaded into memory all at once. This makes this interface usable for large files or socket streams. @node GNAT Secondary_Stack_Info g-sestin ads,GNAT Semaphores g-semaph ads,GNAT Rewrite_Data g-rewdat ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-secondary-stack-info-g-sestin-ads}@anchor{3a7}@anchor{gnat_rm/the_gnat_library id94}@anchor{3a8} +@anchor{gnat_rm/the_gnat_library gnat-secondary-stack-info-g-sestin-ads}@anchor{3ab}@anchor{gnat_rm/the_gnat_library id94}@anchor{3ac} @section @code{GNAT.Secondary_Stack_Info} (@code{g-sestin.ads}) @@ -24942,7 +25021,7 @@ Provides the capability to query the high water mark of the current task’s secondary stack. @node GNAT Semaphores g-semaph ads,GNAT Serial_Communications g-sercom ads,GNAT Secondary_Stack_Info g-sestin ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-semaphores-g-semaph-ads}@anchor{3a9}@anchor{gnat_rm/the_gnat_library id95}@anchor{3aa} +@anchor{gnat_rm/the_gnat_library gnat-semaphores-g-semaph-ads}@anchor{3ad}@anchor{gnat_rm/the_gnat_library id95}@anchor{3ae} @section @code{GNAT.Semaphores} (@code{g-semaph.ads}) @@ -24953,7 +25032,7 @@ secondary stack. Provides classic counting and binary semaphores using protected types. @node GNAT Serial_Communications g-sercom ads,GNAT SHA1 g-sha1 ads,GNAT Semaphores g-semaph ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-serial-communications-g-sercom-ads}@anchor{3ab}@anchor{gnat_rm/the_gnat_library id96}@anchor{3ac} +@anchor{gnat_rm/the_gnat_library gnat-serial-communications-g-sercom-ads}@anchor{3af}@anchor{gnat_rm/the_gnat_library id96}@anchor{3b0} @section @code{GNAT.Serial_Communications} (@code{g-sercom.ads}) @@ -24965,7 +25044,7 @@ Provides a simple interface to send and receive data over a serial port. This is only supported on GNU/Linux and Windows. @node GNAT SHA1 g-sha1 ads,GNAT SHA224 g-sha224 ads,GNAT Serial_Communications g-sercom ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-sha1-g-sha1-ads}@anchor{3ad}@anchor{gnat_rm/the_gnat_library id97}@anchor{3ae} +@anchor{gnat_rm/the_gnat_library gnat-sha1-g-sha1-ads}@anchor{3b1}@anchor{gnat_rm/the_gnat_library id97}@anchor{3b2} @section @code{GNAT.SHA1} (@code{g-sha1.ads}) @@ -24978,7 +25057,7 @@ and RFC 3174, and the HMAC-SHA1 message authentication function as described in RFC 2104 and FIPS PUB 198. @node GNAT SHA224 g-sha224 ads,GNAT SHA256 g-sha256 ads,GNAT SHA1 g-sha1 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-sha224-g-sha224-ads}@anchor{3af}@anchor{gnat_rm/the_gnat_library id98}@anchor{3b0} +@anchor{gnat_rm/the_gnat_library gnat-sha224-g-sha224-ads}@anchor{3b3}@anchor{gnat_rm/the_gnat_library id98}@anchor{3b4} @section @code{GNAT.SHA224} (@code{g-sha224.ads}) @@ -24991,7 +25070,7 @@ and the HMAC-SHA224 message authentication function as described in RFC 2104 and FIPS PUB 198. @node GNAT SHA256 g-sha256 ads,GNAT SHA384 g-sha384 ads,GNAT SHA224 g-sha224 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-sha256-g-sha256-ads}@anchor{3b1}@anchor{gnat_rm/the_gnat_library id99}@anchor{3b2} +@anchor{gnat_rm/the_gnat_library gnat-sha256-g-sha256-ads}@anchor{3b5}@anchor{gnat_rm/the_gnat_library id99}@anchor{3b6} @section @code{GNAT.SHA256} (@code{g-sha256.ads}) @@ -25004,7 +25083,7 @@ and the HMAC-SHA256 message authentication function as described in RFC 2104 and FIPS PUB 198. @node GNAT SHA384 g-sha384 ads,GNAT SHA512 g-sha512 ads,GNAT SHA256 g-sha256 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-sha384-g-sha384-ads}@anchor{3b3}@anchor{gnat_rm/the_gnat_library id100}@anchor{3b4} +@anchor{gnat_rm/the_gnat_library gnat-sha384-g-sha384-ads}@anchor{3b7}@anchor{gnat_rm/the_gnat_library id100}@anchor{3b8} @section @code{GNAT.SHA384} (@code{g-sha384.ads}) @@ -25017,7 +25096,7 @@ and the HMAC-SHA384 message authentication function as described in RFC 2104 and FIPS PUB 198. @node GNAT SHA512 g-sha512 ads,GNAT Signals g-signal ads,GNAT SHA384 g-sha384 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-sha512-g-sha512-ads}@anchor{3b5}@anchor{gnat_rm/the_gnat_library id101}@anchor{3b6} +@anchor{gnat_rm/the_gnat_library gnat-sha512-g-sha512-ads}@anchor{3b9}@anchor{gnat_rm/the_gnat_library id101}@anchor{3ba} @section @code{GNAT.SHA512} (@code{g-sha512.ads}) @@ -25030,7 +25109,7 @@ and the HMAC-SHA512 message authentication function as described in RFC 2104 and FIPS PUB 198. @node GNAT Signals g-signal ads,GNAT Sockets g-socket ads,GNAT SHA512 g-sha512 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-signals-g-signal-ads}@anchor{3b7}@anchor{gnat_rm/the_gnat_library id102}@anchor{3b8} +@anchor{gnat_rm/the_gnat_library gnat-signals-g-signal-ads}@anchor{3bb}@anchor{gnat_rm/the_gnat_library id102}@anchor{3bc} @section @code{GNAT.Signals} (@code{g-signal.ads}) @@ -25042,7 +25121,7 @@ Provides the ability to manipulate the blocked status of signals on supported targets. @node GNAT Sockets g-socket ads,GNAT Source_Info g-souinf ads,GNAT Signals g-signal ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-sockets-g-socket-ads}@anchor{3b9}@anchor{gnat_rm/the_gnat_library id103}@anchor{3ba} +@anchor{gnat_rm/the_gnat_library gnat-sockets-g-socket-ads}@anchor{3bd}@anchor{gnat_rm/the_gnat_library id103}@anchor{3be} @section @code{GNAT.Sockets} (@code{g-socket.ads}) @@ -25057,7 +25136,7 @@ on all native GNAT ports and on VxWorks cross ports. It is not implemented for the LynxOS cross port. @node GNAT Source_Info g-souinf ads,GNAT Spelling_Checker g-speche ads,GNAT Sockets g-socket ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-source-info-g-souinf-ads}@anchor{3bb}@anchor{gnat_rm/the_gnat_library id104}@anchor{3bc} +@anchor{gnat_rm/the_gnat_library gnat-source-info-g-souinf-ads}@anchor{3bf}@anchor{gnat_rm/the_gnat_library id104}@anchor{3c0} @section @code{GNAT.Source_Info} (@code{g-souinf.ads}) @@ -25071,7 +25150,7 @@ subprograms yielding the date and time of the current compilation (like the C macros @code{__DATE__} and @code{__TIME__}) @node GNAT Spelling_Checker g-speche ads,GNAT Spelling_Checker_Generic g-spchge ads,GNAT Source_Info g-souinf ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-g-speche-ads}@anchor{3bd}@anchor{gnat_rm/the_gnat_library id105}@anchor{3be} +@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-g-speche-ads}@anchor{3c1}@anchor{gnat_rm/the_gnat_library id105}@anchor{3c2} @section @code{GNAT.Spelling_Checker} (@code{g-speche.ads}) @@ -25083,7 +25162,7 @@ Provides a function for determining whether one string is a plausible near misspelling of another string. @node GNAT Spelling_Checker_Generic g-spchge ads,GNAT Spitbol Patterns g-spipat ads,GNAT Spelling_Checker g-speche ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-generic-g-spchge-ads}@anchor{3bf}@anchor{gnat_rm/the_gnat_library id106}@anchor{3c0} +@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-generic-g-spchge-ads}@anchor{3c3}@anchor{gnat_rm/the_gnat_library id106}@anchor{3c4} @section @code{GNAT.Spelling_Checker_Generic} (@code{g-spchge.ads}) @@ -25096,7 +25175,7 @@ determining whether one string is a plausible near misspelling of another string. @node GNAT Spitbol Patterns g-spipat ads,GNAT Spitbol g-spitbo ads,GNAT Spelling_Checker_Generic g-spchge ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-spitbol-patterns-g-spipat-ads}@anchor{3c1}@anchor{gnat_rm/the_gnat_library id107}@anchor{3c2} +@anchor{gnat_rm/the_gnat_library gnat-spitbol-patterns-g-spipat-ads}@anchor{3c5}@anchor{gnat_rm/the_gnat_library id107}@anchor{3c6} @section @code{GNAT.Spitbol.Patterns} (@code{g-spipat.ads}) @@ -25112,7 +25191,7 @@ the SNOBOL4 dynamic pattern construction and matching capabilities, using the efficient algorithm developed by Robert Dewar for the SPITBOL system. @node GNAT Spitbol g-spitbo ads,GNAT Spitbol Table_Boolean g-sptabo ads,GNAT Spitbol Patterns g-spipat ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-spitbol-g-spitbo-ads}@anchor{3c3}@anchor{gnat_rm/the_gnat_library id108}@anchor{3c4} +@anchor{gnat_rm/the_gnat_library gnat-spitbol-g-spitbo-ads}@anchor{3c7}@anchor{gnat_rm/the_gnat_library id108}@anchor{3c8} @section @code{GNAT.Spitbol} (@code{g-spitbo.ads}) @@ -25127,7 +25206,7 @@ useful for constructing arbitrary mappings from strings in the style of the SNOBOL4 TABLE function. @node GNAT Spitbol Table_Boolean g-sptabo ads,GNAT Spitbol Table_Integer g-sptain ads,GNAT Spitbol g-spitbo ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-boolean-g-sptabo-ads}@anchor{3c5}@anchor{gnat_rm/the_gnat_library id109}@anchor{3c6} +@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-boolean-g-sptabo-ads}@anchor{3c9}@anchor{gnat_rm/the_gnat_library id109}@anchor{3ca} @section @code{GNAT.Spitbol.Table_Boolean} (@code{g-sptabo.ads}) @@ -25142,7 +25221,7 @@ for type @code{Standard.Boolean}, giving an implementation of sets of string values. @node GNAT Spitbol Table_Integer g-sptain ads,GNAT Spitbol Table_VString g-sptavs ads,GNAT Spitbol Table_Boolean g-sptabo ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-integer-g-sptain-ads}@anchor{3c7}@anchor{gnat_rm/the_gnat_library id110}@anchor{3c8} +@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-integer-g-sptain-ads}@anchor{3cb}@anchor{gnat_rm/the_gnat_library id110}@anchor{3cc} @section @code{GNAT.Spitbol.Table_Integer} (@code{g-sptain.ads}) @@ -25159,7 +25238,7 @@ for type @code{Standard.Integer}, giving an implementation of maps from string to integer values. @node GNAT Spitbol Table_VString g-sptavs ads,GNAT SSE g-sse ads,GNAT Spitbol Table_Integer g-sptain ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-vstring-g-sptavs-ads}@anchor{3c9}@anchor{gnat_rm/the_gnat_library id111}@anchor{3ca} +@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-vstring-g-sptavs-ads}@anchor{3cd}@anchor{gnat_rm/the_gnat_library id111}@anchor{3ce} @section @code{GNAT.Spitbol.Table_VString} (@code{g-sptavs.ads}) @@ -25176,7 +25255,7 @@ a variable length string type, giving an implementation of general maps from strings to strings. @node GNAT SSE g-sse ads,GNAT SSE Vector_Types g-ssvety ads,GNAT Spitbol Table_VString g-sptavs ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-sse-g-sse-ads}@anchor{3cb}@anchor{gnat_rm/the_gnat_library id112}@anchor{3cc} +@anchor{gnat_rm/the_gnat_library gnat-sse-g-sse-ads}@anchor{3cf}@anchor{gnat_rm/the_gnat_library id112}@anchor{3d0} @section @code{GNAT.SSE} (@code{g-sse.ads}) @@ -25188,7 +25267,7 @@ targets. It exposes vector component types together with a general introduction to the binding contents and use. @node GNAT SSE Vector_Types g-ssvety ads,GNAT String_Hash g-strhas ads,GNAT SSE g-sse ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-sse-vector-types-g-ssvety-ads}@anchor{3cd}@anchor{gnat_rm/the_gnat_library id113}@anchor{3ce} +@anchor{gnat_rm/the_gnat_library gnat-sse-vector-types-g-ssvety-ads}@anchor{3d1}@anchor{gnat_rm/the_gnat_library id113}@anchor{3d2} @section @code{GNAT.SSE.Vector_Types} (@code{g-ssvety.ads}) @@ -25197,7 +25276,7 @@ introduction to the binding contents and use. SSE vector types for use with SSE related intrinsics. @node GNAT String_Hash g-strhas ads,GNAT Strings g-string ads,GNAT SSE Vector_Types g-ssvety ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-string-hash-g-strhas-ads}@anchor{3cf}@anchor{gnat_rm/the_gnat_library id114}@anchor{3d0} +@anchor{gnat_rm/the_gnat_library gnat-string-hash-g-strhas-ads}@anchor{3d3}@anchor{gnat_rm/the_gnat_library id114}@anchor{3d4} @section @code{GNAT.String_Hash} (@code{g-strhas.ads}) @@ -25209,7 +25288,7 @@ Provides a generic hash function working on arrays of scalars. Both the scalar type and the hash result type are parameters. @node GNAT Strings g-string ads,GNAT String_Split g-strspl ads,GNAT String_Hash g-strhas ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-strings-g-string-ads}@anchor{3d1}@anchor{gnat_rm/the_gnat_library id115}@anchor{3d2} +@anchor{gnat_rm/the_gnat_library gnat-strings-g-string-ads}@anchor{3d5}@anchor{gnat_rm/the_gnat_library id115}@anchor{3d6} @section @code{GNAT.Strings} (@code{g-string.ads}) @@ -25219,7 +25298,7 @@ Common String access types and related subprograms. Basically it defines a string access and an array of string access types. @node GNAT String_Split g-strspl ads,GNAT Table g-table ads,GNAT Strings g-string ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-string-split-g-strspl-ads}@anchor{3d3}@anchor{gnat_rm/the_gnat_library id116}@anchor{3d4} +@anchor{gnat_rm/the_gnat_library gnat-string-split-g-strspl-ads}@anchor{3d7}@anchor{gnat_rm/the_gnat_library id116}@anchor{3d8} @section @code{GNAT.String_Split} (@code{g-strspl.ads}) @@ -25233,7 +25312,7 @@ to the resulting slices. This package is instantiated from @code{GNAT.Array_Split}. @node GNAT Table g-table ads,GNAT Task_Lock g-tasloc ads,GNAT String_Split g-strspl ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-table-g-table-ads}@anchor{3d5}@anchor{gnat_rm/the_gnat_library id117}@anchor{3d6} +@anchor{gnat_rm/the_gnat_library gnat-table-g-table-ads}@anchor{3d9}@anchor{gnat_rm/the_gnat_library id117}@anchor{3da} @section @code{GNAT.Table} (@code{g-table.ads}) @@ -25253,7 +25332,7 @@ while an instantiation of @code{GNAT.Dynamic_Tables} creates a type that can be used to define dynamic instances of the table. @node GNAT Task_Lock g-tasloc ads,GNAT Time_Stamp g-timsta ads,GNAT Table g-table ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-task-lock-g-tasloc-ads}@anchor{3d7}@anchor{gnat_rm/the_gnat_library id118}@anchor{3d8} +@anchor{gnat_rm/the_gnat_library gnat-task-lock-g-tasloc-ads}@anchor{3db}@anchor{gnat_rm/the_gnat_library id118}@anchor{3dc} @section @code{GNAT.Task_Lock} (@code{g-tasloc.ads}) @@ -25270,7 +25349,7 @@ single global task lock. Appropriate for use in situations where contention between tasks is very rarely expected. @node GNAT Time_Stamp g-timsta ads,GNAT Threads g-thread ads,GNAT Task_Lock g-tasloc ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-time-stamp-g-timsta-ads}@anchor{3d9}@anchor{gnat_rm/the_gnat_library id119}@anchor{3da} +@anchor{gnat_rm/the_gnat_library gnat-time-stamp-g-timsta-ads}@anchor{3dd}@anchor{gnat_rm/the_gnat_library id119}@anchor{3de} @section @code{GNAT.Time_Stamp} (@code{g-timsta.ads}) @@ -25285,7 +25364,7 @@ represents the current date and time in ISO 8601 format. This is a very simple routine with minimal code and there are no dependencies on any other unit. @node GNAT Threads g-thread ads,GNAT Traceback g-traceb ads,GNAT Time_Stamp g-timsta ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-threads-g-thread-ads}@anchor{3db}@anchor{gnat_rm/the_gnat_library id120}@anchor{3dc} +@anchor{gnat_rm/the_gnat_library gnat-threads-g-thread-ads}@anchor{3df}@anchor{gnat_rm/the_gnat_library id120}@anchor{3e0} @section @code{GNAT.Threads} (@code{g-thread.ads}) @@ -25302,7 +25381,7 @@ further details if your program has threads that are created by a non-Ada environment which then accesses Ada code. @node GNAT Traceback g-traceb ads,GNAT Traceback Symbolic g-trasym ads,GNAT Threads g-thread ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-traceback-g-traceb-ads}@anchor{3dd}@anchor{gnat_rm/the_gnat_library id121}@anchor{3de} +@anchor{gnat_rm/the_gnat_library gnat-traceback-g-traceb-ads}@anchor{3e1}@anchor{gnat_rm/the_gnat_library id121}@anchor{3e2} @section @code{GNAT.Traceback} (@code{g-traceb.ads}) @@ -25314,7 +25393,7 @@ Provides a facility for obtaining non-symbolic traceback information, useful in various debugging situations. @node GNAT Traceback Symbolic g-trasym ads,GNAT UTF_32 g-utf_32 ads,GNAT Traceback g-traceb ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3df}@anchor{gnat_rm/the_gnat_library id122}@anchor{3e0} +@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3e3}@anchor{gnat_rm/the_gnat_library id122}@anchor{3e4} @section @code{GNAT.Traceback.Symbolic} (@code{g-trasym.ads}) @@ -25323,7 +25402,7 @@ in various debugging situations. @geindex Trace back facilities @node GNAT UTF_32 g-utf_32 ads,GNAT UTF_32_Spelling_Checker g-u3spch ads,GNAT Traceback Symbolic g-trasym ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-utf-32-ads}@anchor{3e1}@anchor{gnat_rm/the_gnat_library id123}@anchor{3e2} +@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-utf-32-ads}@anchor{3e5}@anchor{gnat_rm/the_gnat_library id123}@anchor{3e6} @section @code{GNAT.UTF_32} (@code{g-utf_32.ads}) @@ -25342,7 +25421,7 @@ lower case to upper case fold routine corresponding to the Ada 2005 rules for identifier equivalence. @node GNAT UTF_32_Spelling_Checker g-u3spch ads,GNAT Wide_Spelling_Checker g-wispch ads,GNAT UTF_32 g-utf_32 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-utf-32-spelling-checker-g-u3spch-ads}@anchor{3e3}@anchor{gnat_rm/the_gnat_library id124}@anchor{3e4} +@anchor{gnat_rm/the_gnat_library gnat-utf-32-spelling-checker-g-u3spch-ads}@anchor{3e7}@anchor{gnat_rm/the_gnat_library id124}@anchor{3e8} @section @code{GNAT.UTF_32_Spelling_Checker} (@code{g-u3spch.ads}) @@ -25355,7 +25434,7 @@ near misspelling of another wide wide string, where the strings are represented using the UTF_32_String type defined in System.Wch_Cnv. @node GNAT Wide_Spelling_Checker g-wispch ads,GNAT Wide_String_Split g-wistsp ads,GNAT UTF_32_Spelling_Checker g-u3spch ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-wispch-ads}@anchor{3e5}@anchor{gnat_rm/the_gnat_library id125}@anchor{3e6} +@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-wispch-ads}@anchor{3e9}@anchor{gnat_rm/the_gnat_library id125}@anchor{3ea} @section @code{GNAT.Wide_Spelling_Checker} (@code{g-wispch.ads}) @@ -25367,7 +25446,7 @@ Provides a function for determining whether one wide string is a plausible near misspelling of another wide string. @node GNAT Wide_String_Split g-wistsp ads,GNAT Wide_Wide_Spelling_Checker g-zspche ads,GNAT Wide_Spelling_Checker g-wispch ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-wide-string-split-g-wistsp-ads}@anchor{3e7}@anchor{gnat_rm/the_gnat_library id126}@anchor{3e8} +@anchor{gnat_rm/the_gnat_library gnat-wide-string-split-g-wistsp-ads}@anchor{3eb}@anchor{gnat_rm/the_gnat_library id126}@anchor{3ec} @section @code{GNAT.Wide_String_Split} (@code{g-wistsp.ads}) @@ -25381,7 +25460,7 @@ to the resulting slices. This package is instantiated from @code{GNAT.Array_Split}. @node GNAT Wide_Wide_Spelling_Checker g-zspche ads,GNAT Wide_Wide_String_Split g-zistsp ads,GNAT Wide_String_Split g-wistsp ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-wide-wide-spelling-checker-g-zspche-ads}@anchor{3e9}@anchor{gnat_rm/the_gnat_library id127}@anchor{3ea} +@anchor{gnat_rm/the_gnat_library gnat-wide-wide-spelling-checker-g-zspche-ads}@anchor{3ed}@anchor{gnat_rm/the_gnat_library id127}@anchor{3ee} @section @code{GNAT.Wide_Wide_Spelling_Checker} (@code{g-zspche.ads}) @@ -25393,7 +25472,7 @@ Provides a function for determining whether one wide wide string is a plausible near misspelling of another wide wide string. @node GNAT Wide_Wide_String_Split g-zistsp ads,Interfaces C Extensions i-cexten ads,GNAT Wide_Wide_Spelling_Checker g-zspche ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-wide-wide-string-split-g-zistsp-ads}@anchor{3eb}@anchor{gnat_rm/the_gnat_library id128}@anchor{3ec} +@anchor{gnat_rm/the_gnat_library gnat-wide-wide-string-split-g-zistsp-ads}@anchor{3ef}@anchor{gnat_rm/the_gnat_library id128}@anchor{3f0} @section @code{GNAT.Wide_Wide_String_Split} (@code{g-zistsp.ads}) @@ -25407,7 +25486,7 @@ to the resulting slices. This package is instantiated from @code{GNAT.Array_Split}. @node Interfaces C Extensions i-cexten ads,Interfaces C Streams i-cstrea ads,GNAT Wide_Wide_String_Split g-zistsp ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id129}@anchor{3ed}@anchor{gnat_rm/the_gnat_library interfaces-c-extensions-i-cexten-ads}@anchor{3ee} +@anchor{gnat_rm/the_gnat_library id129}@anchor{3f1}@anchor{gnat_rm/the_gnat_library interfaces-c-extensions-i-cexten-ads}@anchor{3f2} @section @code{Interfaces.C.Extensions} (@code{i-cexten.ads}) @@ -25418,7 +25497,7 @@ for use with either manually or automatically generated bindings to C libraries. @node Interfaces C Streams i-cstrea ads,Interfaces Packed_Decimal i-pacdec ads,Interfaces C Extensions i-cexten ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id130}@anchor{3ef}@anchor{gnat_rm/the_gnat_library interfaces-c-streams-i-cstrea-ads}@anchor{3f0} +@anchor{gnat_rm/the_gnat_library id130}@anchor{3f3}@anchor{gnat_rm/the_gnat_library interfaces-c-streams-i-cstrea-ads}@anchor{3f4} @section @code{Interfaces.C.Streams} (@code{i-cstrea.ads}) @@ -25431,7 +25510,7 @@ This package is a binding for the most commonly used operations on C streams. @node Interfaces Packed_Decimal i-pacdec ads,Interfaces VxWorks i-vxwork ads,Interfaces C Streams i-cstrea ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id131}@anchor{3f1}@anchor{gnat_rm/the_gnat_library interfaces-packed-decimal-i-pacdec-ads}@anchor{3f2} +@anchor{gnat_rm/the_gnat_library id131}@anchor{3f5}@anchor{gnat_rm/the_gnat_library interfaces-packed-decimal-i-pacdec-ads}@anchor{3f6} @section @code{Interfaces.Packed_Decimal} (@code{i-pacdec.ads}) @@ -25446,7 +25525,7 @@ from a packed decimal format compatible with that used on IBM mainframes. @node Interfaces VxWorks i-vxwork ads,Interfaces VxWorks IO i-vxwoio ads,Interfaces Packed_Decimal i-pacdec ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id132}@anchor{3f3}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-i-vxwork-ads}@anchor{3f4} +@anchor{gnat_rm/the_gnat_library id132}@anchor{3f7}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-i-vxwork-ads}@anchor{3f8} @section @code{Interfaces.VxWorks} (@code{i-vxwork.ads}) @@ -25460,7 +25539,7 @@ mainframes. This package provides a limited binding to the VxWorks API. @node Interfaces VxWorks IO i-vxwoio ads,System Address_Image s-addima ads,Interfaces VxWorks i-vxwork ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id133}@anchor{3f5}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-io-i-vxwoio-ads}@anchor{3f6} +@anchor{gnat_rm/the_gnat_library id133}@anchor{3f9}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-io-i-vxwoio-ads}@anchor{3fa} @section @code{Interfaces.VxWorks.IO} (@code{i-vxwoio.ads}) @@ -25483,7 +25562,7 @@ function codes. A particular use of this package is to enable the use of Get_Immediate under VxWorks. @node System Address_Image s-addima ads,System Assertions s-assert ads,Interfaces VxWorks IO i-vxwoio ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id134}@anchor{3f7}@anchor{gnat_rm/the_gnat_library system-address-image-s-addima-ads}@anchor{3f8} +@anchor{gnat_rm/the_gnat_library id134}@anchor{3fb}@anchor{gnat_rm/the_gnat_library system-address-image-s-addima-ads}@anchor{3fc} @section @code{System.Address_Image} (@code{s-addima.ads}) @@ -25499,7 +25578,7 @@ function that gives an (implementation dependent) string which identifies an address. @node System Assertions s-assert ads,System Atomic_Counters s-atocou ads,System Address_Image s-addima ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id135}@anchor{3f9}@anchor{gnat_rm/the_gnat_library system-assertions-s-assert-ads}@anchor{3fa} +@anchor{gnat_rm/the_gnat_library id135}@anchor{3fd}@anchor{gnat_rm/the_gnat_library system-assertions-s-assert-ads}@anchor{3fe} @section @code{System.Assertions} (@code{s-assert.ads}) @@ -25515,7 +25594,7 @@ by an run-time assertion failure, as well as the routine that is used internally to raise this assertion. @node System Atomic_Counters s-atocou ads,System Memory s-memory ads,System Assertions s-assert ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id136}@anchor{3fb}@anchor{gnat_rm/the_gnat_library system-atomic-counters-s-atocou-ads}@anchor{3fc} +@anchor{gnat_rm/the_gnat_library id136}@anchor{3ff}@anchor{gnat_rm/the_gnat_library system-atomic-counters-s-atocou-ads}@anchor{400} @section @code{System.Atomic_Counters} (@code{s-atocou.ads}) @@ -25529,7 +25608,7 @@ on most targets, including all Alpha, AARCH64, ARM, ia64, PowerPC, SPARC V9, x86, and x86_64 platforms. @node System Memory s-memory ads,System Multiprocessors s-multip ads,System Atomic_Counters s-atocou ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id137}@anchor{3fd}@anchor{gnat_rm/the_gnat_library system-memory-s-memory-ads}@anchor{3fe} +@anchor{gnat_rm/the_gnat_library id137}@anchor{401}@anchor{gnat_rm/the_gnat_library system-memory-s-memory-ads}@anchor{402} @section @code{System.Memory} (@code{s-memory.ads}) @@ -25547,7 +25626,7 @@ calls to this unit may be made for low level allocation uses (for example see the body of @code{GNAT.Tables}). @node System Multiprocessors s-multip ads,System Multiprocessors Dispatching_Domains s-mudido ads,System Memory s-memory ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id138}@anchor{3ff}@anchor{gnat_rm/the_gnat_library system-multiprocessors-s-multip-ads}@anchor{400} +@anchor{gnat_rm/the_gnat_library id138}@anchor{403}@anchor{gnat_rm/the_gnat_library system-multiprocessors-s-multip-ads}@anchor{404} @section @code{System.Multiprocessors} (@code{s-multip.ads}) @@ -25560,7 +25639,7 @@ in GNAT we also make it available in Ada 95 and Ada 2005 (where it is technically an implementation-defined addition). @node System Multiprocessors Dispatching_Domains s-mudido ads,System Partition_Interface s-parint ads,System Multiprocessors s-multip ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id139}@anchor{401}@anchor{gnat_rm/the_gnat_library system-multiprocessors-dispatching-domains-s-mudido-ads}@anchor{402} +@anchor{gnat_rm/the_gnat_library id139}@anchor{405}@anchor{gnat_rm/the_gnat_library system-multiprocessors-dispatching-domains-s-mudido-ads}@anchor{406} @section @code{System.Multiprocessors.Dispatching_Domains} (@code{s-mudido.ads}) @@ -25573,7 +25652,7 @@ in GNAT we also make it available in Ada 95 and Ada 2005 (where it is technically an implementation-defined addition). @node System Partition_Interface s-parint ads,System Pool_Global s-pooglo ads,System Multiprocessors Dispatching_Domains s-mudido ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id140}@anchor{403}@anchor{gnat_rm/the_gnat_library system-partition-interface-s-parint-ads}@anchor{404} +@anchor{gnat_rm/the_gnat_library id140}@anchor{407}@anchor{gnat_rm/the_gnat_library system-partition-interface-s-parint-ads}@anchor{408} @section @code{System.Partition_Interface} (@code{s-parint.ads}) @@ -25583,10 +25662,10 @@ technically an implementation-defined addition). This package provides facilities for partition interfacing. It is used primarily in a distribution context when using Annex E -with @code{GLADE}. +with @code{PolyORB}. @node System Pool_Global s-pooglo ads,System Pool_Local s-pooloc ads,System Partition_Interface s-parint ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id141}@anchor{405}@anchor{gnat_rm/the_gnat_library system-pool-global-s-pooglo-ads}@anchor{406} +@anchor{gnat_rm/the_gnat_library id141}@anchor{409}@anchor{gnat_rm/the_gnat_library system-pool-global-s-pooglo-ads}@anchor{40a} @section @code{System.Pool_Global} (@code{s-pooglo.ads}) @@ -25603,7 +25682,7 @@ declared. It uses malloc/free to allocate/free and does not attempt to do any automatic reclamation. @node System Pool_Local s-pooloc ads,System Restrictions s-restri ads,System Pool_Global s-pooglo ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id142}@anchor{407}@anchor{gnat_rm/the_gnat_library system-pool-local-s-pooloc-ads}@anchor{408} +@anchor{gnat_rm/the_gnat_library id142}@anchor{40b}@anchor{gnat_rm/the_gnat_library system-pool-local-s-pooloc-ads}@anchor{40c} @section @code{System.Pool_Local} (@code{s-pooloc.ads}) @@ -25620,7 +25699,7 @@ a list of allocated blocks, so that all storage allocated for the pool can be freed automatically when the pool is finalized. @node System Restrictions s-restri ads,System Rident s-rident ads,System Pool_Local s-pooloc ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id143}@anchor{409}@anchor{gnat_rm/the_gnat_library system-restrictions-s-restri-ads}@anchor{40a} +@anchor{gnat_rm/the_gnat_library id143}@anchor{40d}@anchor{gnat_rm/the_gnat_library system-restrictions-s-restri-ads}@anchor{40e} @section @code{System.Restrictions} (@code{s-restri.ads}) @@ -25636,7 +25715,7 @@ compiler determined information on which restrictions are violated by one or more packages in the partition. @node System Rident s-rident ads,System Strings Stream_Ops s-ststop ads,System Restrictions s-restri ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id144}@anchor{40b}@anchor{gnat_rm/the_gnat_library system-rident-s-rident-ads}@anchor{40c} +@anchor{gnat_rm/the_gnat_library id144}@anchor{40f}@anchor{gnat_rm/the_gnat_library system-rident-s-rident-ads}@anchor{410} @section @code{System.Rident} (@code{s-rident.ads}) @@ -25652,7 +25731,7 @@ since the necessary instantiation is included in package System.Restrictions. @node System Strings Stream_Ops s-ststop ads,System Unsigned_Types s-unstyp ads,System Rident s-rident ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id145}@anchor{40d}@anchor{gnat_rm/the_gnat_library system-strings-stream-ops-s-ststop-ads}@anchor{40e} +@anchor{gnat_rm/the_gnat_library id145}@anchor{411}@anchor{gnat_rm/the_gnat_library system-strings-stream-ops-s-ststop-ads}@anchor{412} @section @code{System.Strings.Stream_Ops} (@code{s-ststop.ads}) @@ -25668,7 +25747,7 @@ stream attributes are applied to string types, but the subprograms in this package can be used directly by application programs. @node System Unsigned_Types s-unstyp ads,System Wch_Cnv s-wchcnv ads,System Strings Stream_Ops s-ststop ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id146}@anchor{40f}@anchor{gnat_rm/the_gnat_library system-unsigned-types-s-unstyp-ads}@anchor{410} +@anchor{gnat_rm/the_gnat_library id146}@anchor{413}@anchor{gnat_rm/the_gnat_library system-unsigned-types-s-unstyp-ads}@anchor{414} @section @code{System.Unsigned_Types} (@code{s-unstyp.ads}) @@ -25681,7 +25760,7 @@ also contains some related definitions for other specialized types used by the compiler in connection with packed array types. @node System Wch_Cnv s-wchcnv ads,System Wch_Con s-wchcon ads,System Unsigned_Types s-unstyp ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id147}@anchor{411}@anchor{gnat_rm/the_gnat_library system-wch-cnv-s-wchcnv-ads}@anchor{412} +@anchor{gnat_rm/the_gnat_library id147}@anchor{415}@anchor{gnat_rm/the_gnat_library system-wch-cnv-s-wchcnv-ads}@anchor{416} @section @code{System.Wch_Cnv} (@code{s-wchcnv.ads}) @@ -25702,7 +25781,7 @@ encoding method. It uses definitions in package @code{System.Wch_Con}. @node System Wch_Con s-wchcon ads,,System Wch_Cnv s-wchcnv ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id148}@anchor{413}@anchor{gnat_rm/the_gnat_library system-wch-con-s-wchcon-ads}@anchor{414} +@anchor{gnat_rm/the_gnat_library id148}@anchor{417}@anchor{gnat_rm/the_gnat_library system-wch-con-s-wchcon-ads}@anchor{418} @section @code{System.Wch_Con} (@code{s-wchcon.ads}) @@ -25714,7 +25793,7 @@ in ordinary strings. These definitions are used by the package @code{System.Wch_Cnv}. @node Interfacing to Other Languages,Specialized Needs Annexes,The GNAT Library,Top -@anchor{gnat_rm/interfacing_to_other_languages doc}@anchor{415}@anchor{gnat_rm/interfacing_to_other_languages id1}@anchor{416}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-other-languages}@anchor{11} +@anchor{gnat_rm/interfacing_to_other_languages doc}@anchor{419}@anchor{gnat_rm/interfacing_to_other_languages id1}@anchor{41a}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-other-languages}@anchor{11} @chapter Interfacing to Other Languages @@ -25732,7 +25811,7 @@ provided. @end menu @node Interfacing to C,Interfacing to C++,,Interfacing to Other Languages -@anchor{gnat_rm/interfacing_to_other_languages id2}@anchor{417}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-c}@anchor{418} +@anchor{gnat_rm/interfacing_to_other_languages id2}@anchor{41b}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-c}@anchor{41c} @section Interfacing to C @@ -25872,7 +25951,7 @@ of the length corresponding to the @code{type'Size} value in Ada. @end itemize @node Interfacing to C++,Interfacing to COBOL,Interfacing to C,Interfacing to Other Languages -@anchor{gnat_rm/interfacing_to_other_languages id3}@anchor{49}@anchor{gnat_rm/interfacing_to_other_languages id4}@anchor{419} +@anchor{gnat_rm/interfacing_to_other_languages id3}@anchor{49}@anchor{gnat_rm/interfacing_to_other_languages id4}@anchor{41d} @section Interfacing to C++ @@ -26089,7 +26168,7 @@ builds an opaque @code{Type_Info_Ptr} to reference a @code{std::type_info} object at a given @code{System.Address}. @node Interfacing to COBOL,Interfacing to Fortran,Interfacing to C++,Interfacing to Other Languages -@anchor{gnat_rm/interfacing_to_other_languages id5}@anchor{41a}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-cobol}@anchor{41b} +@anchor{gnat_rm/interfacing_to_other_languages id5}@anchor{41e}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-cobol}@anchor{41f} @section Interfacing to COBOL @@ -26097,7 +26176,7 @@ Interfacing to COBOL is achieved as described in section B.4 of the Ada Reference Manual. @node Interfacing to Fortran,Interfacing to non-GNAT Ada code,Interfacing to COBOL,Interfacing to Other Languages -@anchor{gnat_rm/interfacing_to_other_languages id6}@anchor{41c}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-fortran}@anchor{41d} +@anchor{gnat_rm/interfacing_to_other_languages id6}@anchor{420}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-fortran}@anchor{421} @section Interfacing to Fortran @@ -26107,7 +26186,7 @@ multi-dimensional array causes the array to be stored in column-major order as required for convenient interface to Fortran. @node Interfacing to non-GNAT Ada code,,Interfacing to Fortran,Interfacing to Other Languages -@anchor{gnat_rm/interfacing_to_other_languages id7}@anchor{41e}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-non-gnat-ada-code}@anchor{41f} +@anchor{gnat_rm/interfacing_to_other_languages id7}@anchor{422}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-non-gnat-ada-code}@anchor{423} @section Interfacing to non-GNAT Ada code @@ -26131,13 +26210,11 @@ values or simple record types without variants, or simple array types with fixed bounds. @node Specialized Needs Annexes,Implementation of Specific Ada Features,Interfacing to Other Languages,Top -@anchor{gnat_rm/specialized_needs_annexes doc}@anchor{420}@anchor{gnat_rm/specialized_needs_annexes id1}@anchor{421}@anchor{gnat_rm/specialized_needs_annexes specialized-needs-annexes}@anchor{12} +@anchor{gnat_rm/specialized_needs_annexes doc}@anchor{424}@anchor{gnat_rm/specialized_needs_annexes id1}@anchor{425}@anchor{gnat_rm/specialized_needs_annexes specialized-needs-annexes}@anchor{12} @chapter Specialized Needs Annexes -Ada 95, Ada 2005, and Ada 2012 define a number of Specialized Needs Annexes, which are not -required in all implementations. However, as described in this chapter, -GNAT implements all of these annexes: +Ada 95, Ada 2005, Ada 2012, and Ada 2022 define a number of Specialized Needs Annexes, which are not required in all implementations. However, as described in this chapter, GNAT implements all of these annexes: @table @asis @@ -26153,9 +26230,8 @@ The Real-Time Systems Annex is fully implemented. @item `Distributed Systems (Annex E)' Stub generation is fully implemented in the GNAT compiler. In addition, -a complete compatible PCS is available as part of the GLADE system, -a separate product. When the two -products are used in conjunction, this annex is fully implemented. +a complete compatible PCS is available as part of @code{PolyORB}, +a separate product. Note, that PolyORB is a deprecated product and will be eventually replaced with other technologies such as @code{RTI}. @item `Information Systems (Annex F)' @@ -26171,8 +26247,8 @@ The Safety and Security Annex (termed the High-Integrity Systems Annex in Ada 2005) is fully implemented. @end table -@node Implementation of Specific Ada Features,Implementation of Ada 2012 Features,Specialized Needs Annexes,Top -@anchor{gnat_rm/implementation_of_specific_ada_features doc}@anchor{422}@anchor{gnat_rm/implementation_of_specific_ada_features id1}@anchor{423}@anchor{gnat_rm/implementation_of_specific_ada_features implementation-of-specific-ada-features}@anchor{13} +@node Implementation of Specific Ada Features,Implementation of Ada 2022 Features,Specialized Needs Annexes,Top +@anchor{gnat_rm/implementation_of_specific_ada_features doc}@anchor{426}@anchor{gnat_rm/implementation_of_specific_ada_features id1}@anchor{427}@anchor{gnat_rm/implementation_of_specific_ada_features implementation-of-specific-ada-features}@anchor{13} @chapter Implementation of Specific Ada Features @@ -26191,7 +26267,7 @@ facilities. @end menu @node Machine Code Insertions,GNAT Implementation of Tasking,,Implementation of Specific Ada Features -@anchor{gnat_rm/implementation_of_specific_ada_features id2}@anchor{424}@anchor{gnat_rm/implementation_of_specific_ada_features machine-code-insertions}@anchor{17d} +@anchor{gnat_rm/implementation_of_specific_ada_features id2}@anchor{428}@anchor{gnat_rm/implementation_of_specific_ada_features machine-code-insertions}@anchor{181} @section Machine Code Insertions @@ -26359,7 +26435,7 @@ according to normal visibility rules. In particular if there is no qualification is required. @node GNAT Implementation of Tasking,GNAT Implementation of Shared Passive Packages,Machine Code Insertions,Implementation of Specific Ada Features -@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-tasking}@anchor{425}@anchor{gnat_rm/implementation_of_specific_ada_features id3}@anchor{426} +@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-tasking}@anchor{429}@anchor{gnat_rm/implementation_of_specific_ada_features id3}@anchor{42a} @section GNAT Implementation of Tasking @@ -26375,7 +26451,7 @@ to compliance with the Real-Time Systems Annex. @end menu @node Mapping Ada Tasks onto the Underlying Kernel Threads,Ensuring Compliance with the Real-Time Annex,,GNAT Implementation of Tasking -@anchor{gnat_rm/implementation_of_specific_ada_features id4}@anchor{427}@anchor{gnat_rm/implementation_of_specific_ada_features mapping-ada-tasks-onto-the-underlying-kernel-threads}@anchor{428} +@anchor{gnat_rm/implementation_of_specific_ada_features id4}@anchor{42b}@anchor{gnat_rm/implementation_of_specific_ada_features mapping-ada-tasks-onto-the-underlying-kernel-threads}@anchor{42c} @subsection Mapping Ada Tasks onto the Underlying Kernel Threads @@ -26444,7 +26520,7 @@ support this functionality when the parent contains more than one task. @geindex Forking a new process @node Ensuring Compliance with the Real-Time Annex,Support for Locking Policies,Mapping Ada Tasks onto the Underlying Kernel Threads,GNAT Implementation of Tasking -@anchor{gnat_rm/implementation_of_specific_ada_features ensuring-compliance-with-the-real-time-annex}@anchor{429}@anchor{gnat_rm/implementation_of_specific_ada_features id5}@anchor{42a} +@anchor{gnat_rm/implementation_of_specific_ada_features ensuring-compliance-with-the-real-time-annex}@anchor{42d}@anchor{gnat_rm/implementation_of_specific_ada_features id5}@anchor{42e} @subsection Ensuring Compliance with the Real-Time Annex @@ -26495,7 +26571,7 @@ placed at the end. @c Support_for_Locking_Policies @node Support for Locking Policies,,Ensuring Compliance with the Real-Time Annex,GNAT Implementation of Tasking -@anchor{gnat_rm/implementation_of_specific_ada_features support-for-locking-policies}@anchor{42b} +@anchor{gnat_rm/implementation_of_specific_ada_features support-for-locking-policies}@anchor{42f} @subsection Support for Locking Policies @@ -26529,7 +26605,7 @@ then ceiling locking is used. Otherwise, the @code{Ceiling_Locking} policy is ignored. @node GNAT Implementation of Shared Passive Packages,Code Generation for Array Aggregates,GNAT Implementation of Tasking,Implementation of Specific Ada Features -@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-shared-passive-packages}@anchor{42c}@anchor{gnat_rm/implementation_of_specific_ada_features id6}@anchor{42d} +@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-shared-passive-packages}@anchor{430}@anchor{gnat_rm/implementation_of_specific_ada_features id6}@anchor{431} @section GNAT Implementation of Shared Passive Packages @@ -26627,7 +26703,7 @@ This is used to provide the required locking semantics for proper protected object synchronization. @node Code Generation for Array Aggregates,The Size of Discriminated Records with Default Discriminants,GNAT Implementation of Shared Passive Packages,Implementation of Specific Ada Features -@anchor{gnat_rm/implementation_of_specific_ada_features code-generation-for-array-aggregates}@anchor{42e}@anchor{gnat_rm/implementation_of_specific_ada_features id7}@anchor{42f} +@anchor{gnat_rm/implementation_of_specific_ada_features code-generation-for-array-aggregates}@anchor{432}@anchor{gnat_rm/implementation_of_specific_ada_features id7}@anchor{433} @section Code Generation for Array Aggregates @@ -26658,7 +26734,7 @@ component values and static subtypes also lead to simpler code. @end menu @node Static constant aggregates with static bounds,Constant aggregates with unconstrained nominal types,,Code Generation for Array Aggregates -@anchor{gnat_rm/implementation_of_specific_ada_features id8}@anchor{430}@anchor{gnat_rm/implementation_of_specific_ada_features static-constant-aggregates-with-static-bounds}@anchor{431} +@anchor{gnat_rm/implementation_of_specific_ada_features id8}@anchor{434}@anchor{gnat_rm/implementation_of_specific_ada_features static-constant-aggregates-with-static-bounds}@anchor{435} @subsection Static constant aggregates with static bounds @@ -26705,7 +26781,7 @@ Zero2: constant two_dim := (others => (others => 0)); @end example @node Constant aggregates with unconstrained nominal types,Aggregates with static bounds,Static constant aggregates with static bounds,Code Generation for Array Aggregates -@anchor{gnat_rm/implementation_of_specific_ada_features constant-aggregates-with-unconstrained-nominal-types}@anchor{432}@anchor{gnat_rm/implementation_of_specific_ada_features id9}@anchor{433} +@anchor{gnat_rm/implementation_of_specific_ada_features constant-aggregates-with-unconstrained-nominal-types}@anchor{436}@anchor{gnat_rm/implementation_of_specific_ada_features id9}@anchor{437} @subsection Constant aggregates with unconstrained nominal types @@ -26720,7 +26796,7 @@ Cr_Unc : constant One_Unc := (12,24,36); @end example @node Aggregates with static bounds,Aggregates with nonstatic bounds,Constant aggregates with unconstrained nominal types,Code Generation for Array Aggregates -@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-static-bounds}@anchor{434}@anchor{gnat_rm/implementation_of_specific_ada_features id10}@anchor{435} +@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-static-bounds}@anchor{438}@anchor{gnat_rm/implementation_of_specific_ada_features id10}@anchor{439} @subsection Aggregates with static bounds @@ -26748,7 +26824,7 @@ end loop; @end example @node Aggregates with nonstatic bounds,Aggregates in assignment statements,Aggregates with static bounds,Code Generation for Array Aggregates -@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-nonstatic-bounds}@anchor{436}@anchor{gnat_rm/implementation_of_specific_ada_features id11}@anchor{437} +@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-nonstatic-bounds}@anchor{43a}@anchor{gnat_rm/implementation_of_specific_ada_features id11}@anchor{43b} @subsection Aggregates with nonstatic bounds @@ -26759,7 +26835,7 @@ have to be applied to sub-arrays individually, if they do not have statically compatible subtypes. @node Aggregates in assignment statements,,Aggregates with nonstatic bounds,Code Generation for Array Aggregates -@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-in-assignment-statements}@anchor{438}@anchor{gnat_rm/implementation_of_specific_ada_features id12}@anchor{439} +@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-in-assignment-statements}@anchor{43c}@anchor{gnat_rm/implementation_of_specific_ada_features id12}@anchor{43d} @subsection Aggregates in assignment statements @@ -26801,7 +26877,7 @@ a temporary (created either by the front-end or the code generator) and then that temporary will be copied onto the target. @node The Size of Discriminated Records with Default Discriminants,Image Values For Nonscalar Types,Code Generation for Array Aggregates,Implementation of Specific Ada Features -@anchor{gnat_rm/implementation_of_specific_ada_features id13}@anchor{43a}@anchor{gnat_rm/implementation_of_specific_ada_features the-size-of-discriminated-records-with-default-discriminants}@anchor{43b} +@anchor{gnat_rm/implementation_of_specific_ada_features id13}@anchor{43e}@anchor{gnat_rm/implementation_of_specific_ada_features the-size-of-discriminated-records-with-default-discriminants}@anchor{43f} @section The Size of Discriminated Records with Default Discriminants @@ -26881,7 +26957,7 @@ say) must be consistent, so it is imperative that the object, once created, remain invariant. @node Image Values For Nonscalar Types,Strict Conformance to the Ada Reference Manual,The Size of Discriminated Records with Default Discriminants,Implementation of Specific Ada Features -@anchor{gnat_rm/implementation_of_specific_ada_features id14}@anchor{43c}@anchor{gnat_rm/implementation_of_specific_ada_features image-values-for-nonscalar-types}@anchor{43d} +@anchor{gnat_rm/implementation_of_specific_ada_features id14}@anchor{440}@anchor{gnat_rm/implementation_of_specific_ada_features image-values-for-nonscalar-types}@anchor{441} @section Image Values For Nonscalar Types @@ -26901,7 +26977,7 @@ control of image text is required for some type T, then T’Put_Image should be explicitly specified. @node Strict Conformance to the Ada Reference Manual,,Image Values For Nonscalar Types,Implementation of Specific Ada Features -@anchor{gnat_rm/implementation_of_specific_ada_features id15}@anchor{43e}@anchor{gnat_rm/implementation_of_specific_ada_features strict-conformance-to-the-ada-reference-manual}@anchor{43f} +@anchor{gnat_rm/implementation_of_specific_ada_features id15}@anchor{442}@anchor{gnat_rm/implementation_of_specific_ada_features strict-conformance-to-the-ada-reference-manual}@anchor{443} @section Strict Conformance to the Ada Reference Manual @@ -26927,31 +27003,25 @@ machines that are not fully compliant with this standard, such as Alpha, the behavior (although at the cost of a significant performance penalty), so infinite and NaN values are properly generated. -@node Implementation of Ada 2012 Features,GNAT language extensions,Implementation of Specific Ada Features,Top -@anchor{gnat_rm/implementation_of_ada_2012_features doc}@anchor{440}@anchor{gnat_rm/implementation_of_ada_2012_features id1}@anchor{441}@anchor{gnat_rm/implementation_of_ada_2012_features implementation-of-ada-2012-features}@anchor{14} -@chapter Implementation of Ada 2012 Features +@node Implementation of Ada 2022 Features,GNAT language extensions,Implementation of Specific Ada Features,Top +@anchor{gnat_rm/implementation_of_ada_2022_features doc}@anchor{444}@anchor{gnat_rm/implementation_of_ada_2022_features id1}@anchor{445}@anchor{gnat_rm/implementation_of_ada_2022_features implementation-of-ada-2022-features}@anchor{14} +@chapter Implementation of Ada 2022 Features -@geindex Ada 2012 implementation status +@geindex Ada 2022 implementation status -@geindex -gnat12 option (gcc) +@geindex -gnat22 option (gcc) -@geindex pragma Ada_2012 +@geindex pragma Ada_2022 -@geindex configuration pragma Ada_2012 +@geindex configuration pragma Ada_2022 -@geindex Ada_2012 configuration pragma +@geindex Ada_2022 configuration pragma -This chapter contains a complete list of Ada 2012 features that have been -implemented. -Generally, these features are only -available if the `-gnat12' (Ada 2012 features enabled) option is set, -which is the default behavior, -or if the configuration pragma @code{Ada_2012} is used. +This chapter contains a complete list of Ada 2022 features that have been +implemented. Generally, these features are only available if the `-gnat22' (Ada 2022 features enabled) option is set, or if the configuration pragma @code{Ada_2022} is used. -However, new pragmas, attributes, and restrictions are -unconditionally available, since the Ada 95 standard allows the addition of -new pragmas, attributes, and restrictions (there are exceptions, which are +However, new pragmas, attributes, and restrictions are unconditionally available, since the Ada standard allows the addition of new pragmas, attributes, and restrictions (there are exceptions, which are documented in the individual descriptions), and also certain packages were made available in earlier versions of Ada. @@ -26963,2143 +27033,3402 @@ implemented the feature, or implemented it as soon as it appeared as a binding interpretation. Each feature corresponds to an Ada Issue (‘AI’) approved by the Ada -standardization group (ISO/IEC JTC1/SC22/WG9) for inclusion in Ada 2012. -The features are ordered based on the relevant sections of the Ada -Reference Manual (“RM”). When a given AI relates to multiple points -in the RM, the earliest is used. +standardization group (ISO/IEC JTC1/SC22/WG9) for inclusion in Ada 2022. -A complete description of the AIs may be found in -@indicateurl{http://www.ada-auth.org/ai05-summary.html}. +The section “RM references” lists all modified paragraphs in the Ada 2012 reference manual. The details of each modification as well as a complete description of the AIs may be found in +@indicateurl{http://www.ada-auth.org/AI12-SUMMARY.HTML}. -@geindex AI-0002 (Ada 2012 feature) +@geindex AI12-0001 (Ada 2022 feature) @itemize * @item -`AI-0002 Export C with unconstrained arrays (0000-00-00)' +`AI12-0001 Independence and Representation clauses for atomic objects (2019-11-27)' -The compiler is not required to support exporting an Ada subprogram with -convention C if there are parameters or a return type of an unconstrained -array type (such as @code{String}). GNAT allows such declarations but -generates warnings. It is possible, but complicated, to write the -corresponding C code and certainly such code would be specific to GNAT and -non-portable. +The compiler accepts packing clauses in all cases, even if they have effectively no influence on the layout. Types, where packing is essentially infeasible are, for instance atomic, aliased and by-reference types. -RM References: B.01 (17) B.03 (62) B.03 (71.1/2) +RM references: 13.02 (6.1/2) 13.02 (7) 13.02 (8) 13.02 (9/3) C.06 (8.1/3) +C.06 (10) C.06 (11) C.06 (21) C.06 (24) @end itemize -@geindex AI-0003 (Ada 2012 feature) +@geindex AI12-0003 (Ada 2022 feature) @itemize * @item -`AI-0003 Qualified expressions as names (2010-07-11)' +`AI12-0003 Specifying the standard storage pool (2020-06-25)' -In Ada 2012, a qualified expression is considered to be syntactically a name, -meaning that constructs such as @code{A'(F(X)).B} are now legal. This is -useful in disambiguating some cases of overloading. +Allows the standard storage pool being specified with a @code{Default_Storage_Pool} pragma or aspect. -RM References: 3.03 (11) 3.03 (21) 4.01 (2) 4.04 (7) 4.07 (3) -5.04 (7) +RM references: 8.02 (11) 13.11.03 (1/3) 13.11.03 (3.1/3) 13.11.03 (4/3) +13.11.03 (4.1/3) 13.11.03 (5/3) 13.11.03 (6.2/3) 13.11.03 +(6.3/3) @end itemize -@geindex AI-0007 (Ada 2012 feature) +@geindex AI12-0004 (Ada 2022 feature) @itemize * @item -`AI-0007 Stream read and private scalar types (0000-00-00)' +`AI12-0004 Normalization and allowed characters for identifiers (2020-06-11)' -The RM as written appeared to limit the possibilities of declaring read -attribute procedures for private scalar types. This limitation was not -intended, and has never been enforced by GNAT. +This AI clarifies that Ada identifiers containing characters which are not +allowed in Normalization Form KC are illegal. -RM References: 13.13.02 (50/2) 13.13.02 (51/2) +RM references: 2.01 (4.1/3) 2.03 (4/3) A.03.02 (4/3) A.03.02 (32.5/3) +A.03.05 (18/3) A.03.05 (51/3) @end itemize -@geindex AI-0008 (Ada 2012 feature) +@geindex AI12-0020 (Ada 2022 feature) @itemize * @item -`AI-0008 General access to constrained objects (0000-00-00)' +`AI12-0020 ‘Image for all types (2020-03-30)' -The wording in the RM implied that if you have a general access to a -constrained object, it could be used to modify the discriminants. This was -obviously not intended. @code{Constraint_Error} should be raised, and GNAT -has always done so in this situation. +Put_Image prints out a human-readable representation of an object. The +functionality in Ada2022 RM is fully implemented except the support for +types in the @code{Remote_Types} packages. -RM References: 3.03 (23) 3.10.02 (26/2) 4.01 (9) 6.04.01 (17) 8.05.01 (5/2) +RM references: 4.10 (0) 3.05 (27.1/2) 3.05 (27.2/2) 3.05 (27.3/2) 3.05 +(27.4/2) 3.05 (27.5/2) 3.05 (27.6/2) 3.05 (27.7/2) 3.05 (28) 3.05 +(29) 3.05 (30/3) 3.05 (31) 3.05 (32) 3.05 (33/3) 3.05 (37.1/2) +3.05 (38) 3.05 (39) 3.05 (43/3) 3.05 (55/3) 3.05 (55.1/5) 3.05 +(55.2/4) 3.05 (55.3/4) 3.05 (55.4/4) 3.05 (59) H.04 (23) H.04 (23.8/2) @end itemize -@geindex AI-0009 (Ada 2012 feature) +@geindex AI12-0022 (Ada 2022 feature) @itemize * @item -`AI-0009 Pragma Independent[_Components] (2010-07-23)' +`AI12-0022 Raise_Expressions (2013-01-27)' -This AI introduces the new pragmas @code{Independent} and -@code{Independent_Components}, -which control guaranteeing independence of access to objects and components. -The AI also requires independence not unaffected by confirming rep clauses. +This feature allows you to write “raise NAME [with STRING]” in an +expression to rise given exception. It is particularly useful in the case of +assertions such as preconditions allowing to specify which exception a +precondition raises if it fails. -RM References: 9.10 (1) 13.01 (15/1) 13.02 (9) 13.03 (13) C.06 (2) -C.06 (4) C.06 (6) C.06 (9) C.06 (13) C.06 (14) +RM references: 4.04 (3/3) 11.02 (6) 11.03 (2/2) 11.03 (3) 11.03 (3.1/2) +11.03 (4/2) 11.04.01 (10.1/3) @end itemize -@geindex AI-0012 (Ada 2012 feature) +@geindex AI12-0027 (Ada 2022 feature) @itemize * @item -`AI-0012 Pack/Component_Size for aliased/atomic (2010-07-15)' +`AI12-0027 Access values should never designate unaliased components (2020-06-15)' -It is now illegal to give an inappropriate component size or a pragma -@code{Pack} that attempts to change the component size in the case of atomic -or aliased components. Previously GNAT ignored such an attempt with a -warning. +AI12-0027 adds a requirement for a value conversion that converts from an array of unaliased components to an array of aliased components to make a copy. It defines such conversions to have a local accessibility, effectively preventing the possibility of unsafe accesses to unaliased components. -RM References: 13.02 (6.1/2) 13.02 (7) C.06 (10) C.06 (11) C.06 (21) +RM references: 4.06 (24.17/3) 4.06 (24.21/2) 4.06 (58) 6.02 (10/3) 3.10.02 (10/3) @end itemize -@geindex AI-0015 (Ada 2012 feature) +@geindex AI12-0028 (Ada 2022 feature) @itemize * @item -`AI-0015 Constant return objects (0000-00-00)' +`AI12-0028 Import of variadic C functions (2020-03-03)' -The return object declared in an `extended_return_statement' may be -declared constant. This was always intended, and GNAT has always allowed it. +Ada programs can now properly call variadic C functions by means of the +conventions C_Variadic_<n>, for small integer values <n>. -RM References: 6.05 (2.1/2) 3.03 (10/2) 3.03 (21) 6.05 (5/2) -6.05 (5.7/2) +RM references: B.03 (1/3) B.03 (60.15/3) B.03 (75) @end itemize -@geindex AI-0017 (Ada 2012 feature) +@geindex AI12-0030 (Ada 2022 feature) @itemize * @item -`AI-0017 Freezing and incomplete types (0000-00-00)' +`AI12-0030 Formal derived types and stream attribute availability (2020-08-21)' -So-called ‘Taft-amendment types’ (i.e., types that are completed in package -bodies) are not frozen by the occurrence of bodies in the -enclosing declarative part. GNAT always implemented this properly. +Corner cases involving streaming operations for formal derived limited types +that are now defined to raise Program_Error. Before, behavior in these cases +was undefined. Stream attribute availability is more precisely computed in cases where a derived type declaration occurs ahead of a streaming attribute specification for the parent type. -RM References: 13.14 (3/1) +RM references: 12.05.01 (21/3) 13.13.02 (49/2) @end itemize -@geindex AI-0019 (Ada 2012 feature) +@geindex AI12-0031 (Ada 2022 feature) @itemize * @item -`AI-0019 Freezing of primitives for tagged types (0000-00-00)' +`AI12-0031 All_Calls_Remote and indirect calls (0000-00-00)' -The RM suggests that primitive subprograms of a specific tagged type are -frozen when the tagged type is frozen. This would be an incompatible change -and is not intended. GNAT has never attempted this kind of freezing and its -behavior is consistent with the recommendation of this AI. +Remote indirect calls (i.e., calls through a remote access-to-subprogram type) +behave the same as remote direct calls. -RM References: 13.14 (2) 13.14 (3/1) 13.14 (8.1/1) 13.14 (10) 13.14 (14) 13.14 (15.1/2) +RM references: E.02.03 (19/3) @end itemize -@geindex AI-0026 (Ada 2012 feature) +@geindex AI12-0032 (Ada 2022 feature) @itemize * @item -`AI-0026 Missing rules for Unchecked_Union (2010-07-07)' +`AI12-0032 Questions on ‘Old (2020-04-24)' -Record representation clauses concerning Unchecked_Union types cannot mention -the discriminant of the type. The type of a component declared in the variant -part of an Unchecked_Union cannot be controlled, have controlled components, -nor have protected or task parts. If an Unchecked_Union type is declared -within the body of a generic unit or its descendants, then the type of a -component declared in the variant part cannot be a formal private type or a -formal private extension declared within the same generic unit. +AI12-0032 resolves several issues related to the ‘Old attribute. The GNAT +compiler already implemented what the AI requires in most of those cases, but two having to do with static and dynamic checking of the accessibility level of the constant object implicitly declared for an ‘Old attribute reference were not yet implemented. Accessibility checking for these constants is now implemented as defined in the AI. -RM References: 7.06 (9.4/2) B.03.03 (9/2) B.03.03 (10/2) +RM references: 4.01.03 (9/3) 6.01.01 (22/3) 6.01.01 (26/3) 6.01.01 (35/3) @end itemize -@geindex AI-0030 (Ada 2012 feature) +@geindex AI12-0033 (Ada 2022 feature) @itemize * @item -`AI-0030 Requeue on synchronized interfaces (2010-07-19)' +`AI12-0033 Sets of CPUs when defining dispatching domains (0000-00-00)' -Requeue is permitted to a protected, synchronized or task interface primitive -providing it is known that the overriding operation is an entry. Otherwise -the requeue statement has the same effect as a procedure call. Use of pragma -@code{Implemented} provides a way to impose a static requirement on the -overriding operation by adhering to one of the implementation kinds: entry, -protected procedure or any of the above. +The set of CPUs associated with a dispatching domain is no longer required +to be a contiguous range of CPU values. -RM References: 9.05 (9) 9.05.04 (2) 9.05.04 (3) 9.05.04 (5) -9.05.04 (6) 9.05.04 (7) 9.05.04 (12) +RM references: D.16.01 (7/3) D.16.01 (9/3) D.16.01 (20/3) D.16.01 (23/3) +D.16.01 (24/3) D.16.01 (26/3) @end itemize -@geindex AI-0031 (Ada 2012 feature) +@geindex AI12-0035 (Ada 2022 feature) @itemize * @item -`AI-0031 Add From parameter to Find_Token (2010-07-25)' +`AI12-0035 Accessibility checks for indefinite elements of containers (0000-00-00)' -A new version of @code{Find_Token} is added to all relevant string packages, -with an extra parameter @code{From}. Instead of starting at the first -character of the string, the search for a matching Token starts at the -character indexed by the value of @code{From}. -These procedures are available in all versions of Ada -but if used in versions earlier than Ada 2012 they will generate a warning -that an Ada 2012 subprogram is being used. +If the element type for an instance of one of the indefinite container generics has an access discriminant, then accessibility checks (at run-time) prevent inserting a value into a container object if the value’s discriminant designates an object that is too short-lived (that is, if the designated object has an accessibility level that is deeper than that of the instance). Without this check, dangling references would be possible. GNAT handled this correctly already before this AI was issued. -RM References: A.04.03 (16) A.04.03 (67) A.04.03 (68/1) A.04.04 (51) -A.04.05 (46) +RM references: A.18 (5/3) A.18.11 (8/2) A.18.12 (7/2) A.18.13 (8/2) +A.18.14 (8/2) A.18.15 (4/2) A.18.16 (4/2) A.18.17 (7/3) A.18.18 +(39/3) A.18.18 (47/3) @end itemize -@geindex AI-0032 (Ada 2012 feature) +@geindex AI12-0036 (Ada 2022 feature) @itemize * @item -`AI-0032 Extended return for class-wide functions (0000-00-00)' +`AI12-0036 The actual for an untagged formal derived type cannot be tagged (2019-10-21)' -If a function returns a class-wide type, the object of an extended return -statement can be declared with a specific type that is covered by the class- -wide type. This has been implemented in GNAT since the introduction of -extended returns. Note AI-0103 complements this AI by imposing matching -rules for constrained return types. +AI12-0036 is a binding interpretation that adds the following legality rule: +The actual type for a formal derived type shall be tagged if and only if the +formal derived type is a private extension. The check is implemented for all Ada dialects, not just Ada 2022. -RM References: 6.05 (5.2/2) 6.05 (5.3/2) 6.05 (5.6/2) 6.05 (5.8/2) -6.05 (8/2) +RM references: 12.05.01 (5.1/3) @end itemize -@geindex AI-0033 (Ada 2012 feature) +@geindex AI12-0037 (Ada 2022 feature) @itemize * @item -`AI-0033 Attach/Interrupt_Handler in generic (2010-07-24)' +`AI12-0037 New types in Ada.Locales can’t be converted to/from strings (2016-09-10)' -Neither of these two pragmas may appear within a generic template, because -the generic might be instantiated at other than the library level. +The type definitions for Language_Code and Country_Code are now using dynamic +predicates. -RM References: 13.11.02 (16) C.03.01 (7/2) C.03.01 (8/2) +RM references: A.19 (4/3) @end itemize -@geindex AI-0034 (Ada 2012 feature) +@geindex AI12-0039 (Ada 2022 feature) @itemize * @item -`AI-0034 Categorization of limited views (0000-00-00)' +`AI12-0039 Ambiguity in syntax for membership expression removed (0000-00-00)' -The RM makes certain limited with clauses illegal because of categorization -considerations, when the corresponding normal with would be legal. This is -not intended, and GNAT has always implemented the recommended behavior. +An ambiguity in the syntax for membership expressions was resolved. For example, “A in B and C” can be parsed in only one way because of this AI. -RM References: 10.02.01 (11/1) 10.02.01 (17/2) +RM references: 4.04 (3/3) 4.04 (3.2/3) 4.05.02 (3.1/3) 4.05.02 (4) 4.05.02 +(4.1/3) 4.05.02 (27/3) 4.05.02 (27.1/3) 4.05.02 (28.1/3) 4.05.02 +(28.2/3) 4.05.02 (29/3) 4.05.02 (30/3) 4.05.02 (30.1/3) 4.05.02 +(30.2/3) 4.05.02 (30.3/3) 4.09 (11/3) 4.09 (32.6/3) 8.06 (27.1/3) +3.02.04 (17/3) @end itemize -@geindex AI-0035 (Ada 2012 feature) +@geindex AI12-0040 (Ada 2022 feature) @itemize * @item -`AI-0035 Inconsistencies with Pure units (0000-00-00)' +`AI12-0040 Resolving the selecting_expression of a case_expression (0000-00-00)' -This AI remedies some inconsistencies in the legality rules for Pure units. -Derived access types are legal in a pure unit (on the assumption that the -rule for a zero storage pool size has been enforced on the ancestor type). -The rules are enforced in generic instances and in subunits. GNAT has always -implemented the recommended behavior. +The definition of “complete context” is corrected so that selectors of case expressions +and of case statements are treated uniformly. -RM References: 10.02.01 (15.1/2) 10.02.01 (15.4/2) 10.02.01 (15.5/2) 10.02.01 (17/2) +RM references: 8.06 (9) @end itemize -@geindex AI-0037 (Ada 2012 feature) +@geindex AI12-0041 (Ada 2022 feature) @itemize * @item -`AI-0037 Out-of-range box associations in aggregate (0000-00-00)' +`AI12-0041 Type_Invariant’Class for interface types (2016-12-12)' -This AI confirms that an association of the form @code{Indx => <>} in an -array aggregate must raise @code{Constraint_Error} if @code{Indx} -is out of range. The RM specified a range check on other associations, but -not when the value of the association was defaulted. GNAT has always inserted -a constraint check on the index value. +Subprogram calls within class-wide type invariant expressions get resolved +as primitive operations instead of being dynamically dispatched. -RM References: 4.03.03 (29) +RM references: 7.03.02 (1/3) 7.03.02 (3/3) @end itemize -@geindex AI-0038 (Ada 2012 feature) +@geindex AI12-0042 (Ada 2022 feature) @itemize * @item -`AI-0038 Minor errors in Text_IO (0000-00-00)' +`AI12-0042 Type invariant checking rules (2020-06-05)' -These are minor errors in the description on three points. The intent on -all these points has always been clear, and GNAT has always implemented the -correct intended semantics. +AI12-0042 adds rules for type invariants. +Specifically, when inheriting a private dispatching operation when the ancestor operation is visible at the point of the type extension, the operation must be abstract or else overridden. In addition, for a class-wide view conversion from an object of a specific type T to which a type invariant applies, an invariant check is performed when the conversion is within the immediate scope of T. -RM References: A.10.05 (37) A.10.07 (8/1) A.10.07 (10) A.10.07 (12) A.10.08 (10) A.10.08 (24) +RM references: 7.03.02 (6/3) 7.03.02 (17/3) 7.03.02 (18/3) 7.03.02 (19/3) +7.03.02 (20/3) @end itemize -@geindex AI-0039 (Ada 2012 feature) +@geindex AI12-0043 (Ada 2022 feature) @itemize * @item -`AI-0039 Stream attributes cannot be dynamic (0000-00-00)' +`AI12-0043 Details of the storage pool used when Storage_Size is specified (0000-00-00)' -The RM permitted the use of dynamic expressions (such as @code{ptr.all}) -for stream attributes, but these were never useful and are now illegal. GNAT -has always regarded such expressions as illegal. +Clarify that a Storage_Size specification for an access type specifies both an upper bound and a lower bound (not just a lower bound) of the amount of storage allowed for allocated objects. -RM References: 13.03 (4) 13.03 (6) 13.13.02 (38/2) +RM references: 13.11 (18) @end itemize -@geindex AI-0040 (Ada 2012 feature) +@geindex AI12-0044 (Ada 2022 feature) @itemize * @item -`AI-0040 Limited with clauses on descendant (0000-00-00)' +`AI12-0044 Calling visible functions from type invariant expressions (2020-05-11)' -This AI confirms that a limited with clause in a child unit cannot name -an ancestor of the unit. This has always been checked in GNAT. +AI05-0289-1 extends invariant checking to @cite{in} parameters. However, this makes +it impossible to call a public function of the type from an invariant +expression, as that public function will attempt to check the invariant, +resulting in an infinite recursion. -RM References: 10.01.02 (20/2) +This AI specifies, that type-invariant checking is performed on parameters +of mode @cite{in} upon return from procedure calls, but not of @cite{in}-mode +parameters in functions. + +RM references: 7.03.02 (19/3) @end itemize -@geindex AI-0042 (Ada 2012 feature) +@geindex AI12-0045 (Ada 2022 feature) @itemize * @item -`AI-0042 Overriding versus implemented-by (0000-00-00)' +`AI12-0045 Pre- and Postconditions are allowed on generic subprograms (2015-03-17)' -This AI fixes a wording gap in the RM. An operation of a synchronized -interface can be implemented by a protected or task entry, but the abstract -operation is not being overridden in the usual sense, and it must be stated -separately that this implementation is legal. This has always been the case -in GNAT. +The SPARK toolset now supports contracts on generic subprograms, packages and +their respective bodies. -RM References: 9.01 (9.2/2) 9.04 (11.1/2) +RM references: 6.01.01 (1/3) @end itemize -@geindex AI-0043 (Ada 2012 feature) +@geindex AI12-0046 (Ada 2022 feature) @itemize * @item -`AI-0043 Rules about raising exceptions (0000-00-00)' +`AI12-0046 Enforcing legality for anonymous access components in record aggregates (0000-00-00)' + +For a record aggregate of the form (X | Y => ….), any relevant legality rules are checked for both for X and Y. -This AI covers various omissions in the RM regarding the raising of -exceptions. GNAT has always implemented the intended semantics. +For example, -RM References: 11.04.01 (10.1/2) 11 (2) +@example +X : aliased constant String := ... ; +type R is record + F1 : access constant String; + F2 : access String; +end record; +Obj : R := (F1 | F2 => X'Access); -- ok for F1, but illegal for F2 +@end example + +RM references: 4.03.01 (16/3) @end itemize -@geindex AI-0044 (Ada 2012 feature) +@geindex AI12-0047 (Ada 2022 feature) @itemize * @item -`AI-0044 Restrictions on container instantiations (0000-00-00)' +`AI12-0047 Generalized iterators and discriminant-dependent components (0000-00-00)' -This AI places restrictions on allowed instantiations of generic containers. -These restrictions are not checked by the compiler, so there is nothing to -change in the implementation. This affects only the RM documentation. +Iterating over the elements of an array is subject to the same legality checks as renaming the array. For example, if an assignment to an enclosing discriminated object could cause an array object to cease to exist then we don’t allow renaming the array. So it is similarly not allowed to iterate over the elements of such an array. -RM References: A.18 (4/2) A.18.02 (231/2) A.18.03 (145/2) A.18.06 (56/2) A.18.08 (66/2) A.18.09 (79/2) A.18.26 (5/2) A.18.26 (9/2) +RM references: 5.05.02 (6/3) @end itemize -@geindex AI-0046 (Ada 2012 feature) +@geindex AI12-0048 (Ada 2022 feature) @itemize * @item -`AI-0046 Null exclusion match for full conformance (2010-07-17)' +`AI12-0048 Default behavior of tasks on a multiprocessor with a specified dispatching policy (0000-00-00)' -For full conformance, in the case of access parameters, the null exclusion -must match (either both or neither must have @code{not null}). +Clarify that if the user does not impose requirements about what CPUs a given task might execute on, then the implementation does not get to impose such requirements. This avoids potential problems with priority inversion. -RM References: 6.03.02 (18) +RM references: D.16.01 (30/3) @end itemize -@geindex AI-0050 (Ada 2012 feature) +@geindex AI12-0049 (Ada 2022 feature) @itemize * @item -`AI-0050 Raising Constraint_Error early for function call (0000-00-00)' +`AI12-0049 Invariants need to be checked on the initialization of deferred constants (0000-00-00)' -The implementation permissions for raising @code{Constraint_Error} early on a function call -when it was clear an exception would be raised were over-permissive and allowed -mishandling of discriminants in some cases. GNAT did -not take advantage of these incorrect permissions in any case. +Invariant checking for deferred constants (and subcomponents thereof) is performed. Corrects a clear oversight in the previous RM wording. -RM References: 6.05 (24/2) +RM references: 7.03.02 (10/3) @end itemize -@geindex AI-0056 (Ada 2012 feature) +@geindex AI12-0050 (Ada 2022 feature) @itemize * @item -`AI-0056 Index on null string returns zero (0000-00-00)' +`AI12-0050 Conformance of quantified expressions (2016-07-22)' -The wording in the Ada 2005 RM implied an incompatible handling of the -@code{Index} functions, resulting in raising an exception instead of -returning zero in some situations. -This was not intended and has been corrected. -GNAT always returned zero, and is thus consistent with this AI. +Compiler rejects a subprogram body when an expression for a boolean formal +parameter includes a quantified expression, and the subprogram declaration +contains a textual copy of the same. -RM References: A.04.03 (56.2/2) A.04.03 (58.5/2) +RM references: 6.03.01 (20) 6.03.01 (21) @end itemize -@geindex AI-0058 (Ada 2012 feature) +@geindex AI12-0051 (Ada 2022 feature) @itemize * @item -`AI-0058 Abnormal completion of an extended return (0000-00-00)' +`AI12-0051 The Priority aspect can be specified when Attach_Handler is specified (0000-00-00)' -The RM had some incorrect wording implying wrong treatment of abnormal -completion in an extended return. GNAT has always implemented the intended -correct semantics as described by this AI. +Previous RM wording had two contradictory rules for determining (in some cases) the priority of a protected subprogram that is attached to an interrupt. The AI clarifies which one of the rules takes precedence. -RM References: 6.05 (22/2) +RM references: D.03 (10/3) @end itemize -@geindex AI-0060 (Ada 2012 feature) +@geindex AI12-0052 (Ada 2022 feature) @itemize * @item -`AI-0060 Extended definition of remote access types (0000-00-00)' +`AI12-0052 Implicit objects are considered overlapping (0000-00-00)' -This AI extends the definition of remote access types to include access -to limited, synchronized, protected or task class-wide interface types. -GNAT already implemented this extension. +Clarify that the rules about unsynchronized concurrent access apply as one would expect in the case of predefined routines that access Text_IO’s default input and default output files. There was no compiler changes needed to implement this. -RM References: A (4) E.02.02 (9/1) E.02.02 (9.2/1) E.02.02 (14/2) E.02.02 (18) +RM references: A (3/2) A.10.03 (21) @end itemize -@geindex AI-0062 (Ada 2012 feature) +@geindex AI12-0054-2 (Ada 2022 feature) @itemize * @item -`AI-0062 Null exclusions and deferred constants (0000-00-00)' +`AI12-0054-2 Aspect Predicate_Failure (0000-00-00)' + +New aspect Predicate_Failure is defined. A solution for the problem that a predicate like + +@example +subtype Open_File is File with Dynamic_Predicate =\> Is_Open (Open_File) or else (raise File_Not_Open); +@end example -A full constant may have a null exclusion even if its associated deferred -constant does not. GNAT has always allowed this. +does the wrong thing in the case of a membership test. -RM References: 7.04 (6/2) 7.04 (7.1/2) +RM references: 3.02.04 (14/3) 3.02.04 (31/3) 3.02.04 (35/3) @end itemize -@geindex AI-0064 (Ada 2012 feature) +@geindex AI12-0055 (Ada 2022 feature) @itemize * @item -`AI-0064 Redundant finalization rule (0000-00-00)' +`AI12-0055 All properties of a usage profile are defined by pragmas (2020-06-09)' -This is an editorial change only. The intended behavior is already checked -by an existing ACATS test, which GNAT has always executed correctly. +AI12-0055 allows the use of the No_Dynamic_CPU_Assignment restriction in pragmas Restrictions and Restrictions_Warnings. -RM References: 7.06.01 (17.1/1) +RM references: D.07 (10/3) D.13 (6/3) D.13 (8/3) D.13 (10/3) @end itemize -@geindex AI-0065 (Ada 2012 feature) +@geindex AI12-0059 (Ada 2022 feature) @itemize * @item -`AI-0065 Remote access types and external streaming (0000-00-00)' +`AI12-0059 Object_Size attribute (2019-12-02)' -This AI clarifies the fact that all remote access types support external -streaming. This fixes an obvious oversight in the definition of the -language, and GNAT always implemented the intended correct rules. +AI12-0059 brings GNAT-defined attribute Object_Size to Ada standard +and clarifies its semantics. Given that the attribute already existed in +GNAT compiler, the feature is supported for all language versions. -RM References: 13.13.02 (52/2) +RM references: 4.09.01 (2/3) 13.01 (14) 13.01 (23) 13.03 (9/3) 13.03 +(50/2) 13.03 (51) 13.03 (52) 13.03 (58) @end itemize -@geindex AI-0070 (Ada 2012 feature) +@geindex AI12-0061 (Ada 2022 feature) @itemize * @item -`AI-0070 Elaboration of interface types (0000-00-00)' +`AI12-0061 Iterated component associations in array aggregates (2016-09-01)' + +Ada issue AI12-061 introduces a new construct in array aggregates allowing +component associations to be parameterized by a loop variable, for example: + +@example +Array (1 .. 10) of Integer := + (for I in 1 .. 10 => I ** 2); +type Matrix is +array + (Positive range <>, Positive range <>) of Float; +G : constant Matrix +:= + (for I in 1 .. 4 => + (for J in 1 .. 4 => + (if I=J then +1.0 else 0.0))); -- Identity matrix +@end example -This is an editorial change only, there are no testable consequences short of -checking for the absence of generated code for an interface declaration. +The expression in such an association can also be a function that returns a +limited type, and the range can be specified by the ‘others’ choice. -RM References: 3.09.04 (18/2) +RM references: 4.03.03 (5/2) 4.03.03 (6) 4.03.03 (17/3) 4.03.03 (20) +4.03.03 (23.1/4) 4.03.03 (32/3) 4.03.03 (43) 3.01 (6/3) 3.03 (6) +3.03 (18.1/3) 3.03.01 (23/3) 5.05 (6) 8.01 (2.1/4) @end itemize -@geindex AI-0072 (Ada 2012 feature) +@geindex AI12-0062 (Ada 2022 feature) @itemize * @item -`AI-0072 Task signalling using ‘Terminated (0000-00-00)' +`AI12-0062 Raise exception with failing string function (0000-00-00)' -This AI clarifies that task signalling for reading @code{'Terminated} only -occurs if the result is True. GNAT semantics has always been consistent with -this notion of task signalling. +Clarify that if raising exception E1 is accompanied with a String-valued +expression whose evaluation raises exception E2, then E2 is what gets propagated. -RM References: 9.10 (6.1/1) +RM references: 11.03 (4/2) @end itemize -@geindex AI-0073 (Ada 2012 feature) +@geindex AI12-0065 (Ada 2022 feature) @itemize * @item -`AI-0073 Functions returning abstract types (2010-07-10)' +`AI12-0065 Descendants of incomplete views (0000-00-00)' -This AI covers a number of issues regarding returning abstract types. In -particular generic functions cannot have abstract result types or access -result types designated an abstract type. There are some other cases which -are detailed in the AI. Note that this binding interpretation has not been -retrofitted to operate before Ada 2012 mode, since it caused a significant -number of regressions. +This AI is a clarification of potentially confusing wording. GNAT correctly handles the example given in AARM 7.3.1(5.b-5.d), which illustrates the topic of this AI. -RM References: 3.09.03 (8) 3.09.03 (10) 6.05 (8/2) +RM references: 7.03.01 (5.2/3) @end itemize -@geindex AI-0076 (Ada 2012 feature) +@geindex AI12-0067 (Ada 2022 feature) @itemize * @item -`AI-0076 function with controlling result (0000-00-00)' +`AI12-0067 Accessibility level of explicitly aliased parameters of procedures and entries (0000-00-00)' -This is an editorial change only. The RM defines calls with controlling -results, but uses the term ‘function with controlling result’ without an -explicit definition. +The AI fixes a case where the intent was fairly obvious but the RM wording failed to mention a case (with the result that the accessibility level of an explicitly aliased parameter of a procedure or entry was undefined even though the intent was clear). -RM References: 3.09.02 (2/2) +RM references: 3.10.02 (7/3) @end itemize -@geindex AI-0077 (Ada 2012 feature) +@geindex AI12-0068 (Ada 2022 feature) @itemize * @item -`AI-0077 Limited withs and scope of declarations (0000-00-00)' +`AI12-0068 Predicates and the current instance of a subtype (2020-05-06)' -This AI clarifies that a declaration does not include a context clause, -and confirms that it is illegal to have a context in which both a limited -and a nonlimited view of a package are accessible. Such double visibility -was always rejected by GNAT. +AI12-0068 is a binding interpretation that defines the current instance name in a type or subtype aspect to be a value rather than an object. This affects +attributes whose prefix is a current instance in predicates, type invariants, and @code{Default_Initial_Condition} aspects. In particular, in the case of the @code{Constrained} attribute the value will always be True, and formerly legal attributes that require an object as their prefix (such as @code{Size}, @code{Access}, @code{Address}, etc.) are illegal when applied to a current instance in type and subtype aspects. -RM References: 10.01.02 (12/2) 10.01.02 (21/2) 10.01.02 (22/2) +RM references: 8.06 (17/3) @end itemize -@geindex AI-0078 (Ada 2012 feature) +@geindex AI12-0069 (Ada 2022 feature) @itemize * @item -`AI-0078 Relax Unchecked_Conversion alignment rules (0000-00-00)' +`AI12-0069 Inconsistency in Tree container definition (0000-00-00)' -In Ada 2012, compilers are required to support unchecked conversion where the -target alignment is a multiple of the source alignment. GNAT always supported -this case (and indeed all cases of differing alignments, doing copies where -required if the alignment was reduced). +The description of how iteration over a Tree container’s elements was contradictory in some cases regarding whether a cursor designating the Root node is included in the iteration. This contradiction was resolved. In the “!ACATS Test” section of the AI, it says that if an implementation were to get this wrong then almost any attempt to iterate over any tree would fail at runtime. -RM References: 13.09 (7) +RM references: A.18.10 (153/3) A.18.10 (155/3) A.18.10 (157/3) A.18.10 (159/3) @end itemize -@geindex AI-0079 (Ada 2012 feature) +@geindex AI12-0070 (Ada 2022 feature) @itemize * @item -`AI-0079 Allow other_format characters in source (2010-07-10)' +`AI12-0070 9.3(2) does not work for anonymous access types (0000-00-00)' -Wide characters in the unicode category `other_format' are now allowed in -source programs between tokens, but not within a token such as an identifier. +The RM contained some old wording about the master of an allocated object that only made sense for named access types. The AI clarifies the wording to clearly state the scope of validity and ensures that the paragraph does not contradict 3.10.2’s rules for anonymous access types. -RM References: 2.01 (4/2) 2.02 (7) +RM references: 3.10.02 (13.1/3) 9.03 (2) @end itemize -@geindex AI-0080 (Ada 2012 feature) +@geindex AI12-0071 (Ada 2022 feature) @itemize * @item -`AI-0080 ‘View of’ not needed if clear from context (0000-00-00)' +`AI12-0071 Order of evaluation when multiple predicates apply (2015-08-10)' -This is an editorial change only, described as non-testable in the AI. +AI12-0071 specifies the semantics of multiple/inherited predicates on a +single subtype. -RM References: 3.01 (7) +RM references: 3.02.04 (4/3) 3.02.04 (6/3) 3.02.04 (30/3) 3.02.04 (31/3) +3.02.04 (32/3) 3.02.04 (33/3) 3.02.04 (35/3) 3.05.05 (7.1/3) +3.05.05 (7.2/3) 3.05.05 (7.3/3) 3.08.01 (10.1/3) 3.08.01 (15/3) +4.05.02 (29/3) 4.05.02 (30/3) 4.06 (51/3) 4.09.01 (10/3) 5.04 +(7/3) 5.05 (9/3) 13.09.02 (3/3) 13.09.02 (12) @end itemize -@geindex AI-0087 (Ada 2012 feature) +@geindex AI12-0072 (Ada 2022 feature) @itemize * @item -`AI-0087 Actual for formal nonlimited derived type (2010-07-15)' +`AI12-0072 Missing rules for Discard_Names aspect (0000-00-00)' -The actual for a formal nonlimited derived type cannot be limited. In -particular, a formal derived type that extends a limited interface but which -is not explicitly limited cannot be instantiated with a limited type. +Clarify that Discard_Names is an aspect, not just a pragma. -RM References: 7.05 (5/2) 12.05.01 (5.1/2) +RM references: C.05 (1) C.05 (5) C.05 (7/2) C.05 (8) @end itemize -@geindex AI-0088 (Ada 2012 feature) +@geindex AI12-0073 (Ada 2022 feature) @itemize * @item -`AI-0088 The value of exponentiation (0000-00-00)' +`AI12-0073 Synchronous Barriers are not allowed with Ravenscar (2020-02-24)' -This AI clarifies the equivalence rule given for the dynamic semantics of -exponentiation: the value of the operation can be obtained by repeated -multiplication, but the operation can be implemented otherwise (for example -using the familiar divide-by-two-and-square algorithm, even if this is less -accurate), and does not imply repeated reads of a volatile base. +Ada 2022 adds (as a binding interpretation) a @code{No_Dependence => +Ada.Synchronous_Barriers} restriction to the Ravenscar profile. -RM References: 4.05.06 (11) +RM references: D.13 (6/3) @end itemize -@geindex AI-0091 (Ada 2012 feature) +@geindex AI12-0074 (Ada 2022 feature) @itemize * @item -`AI-0091 Do not allow other_format in identifiers (0000-00-00)' +`AI12-0074 View conversions and out parameters passed by copy (2020-03-26)' -Wide characters in the unicode category `other_format' are not permitted -within an identifier, since this can be a security problem. The error -message for this case has been improved to be more specific, but GNAT has -never allowed such characters to appear in identifiers. +This Ada 2022 AI makes illegal some cases of out parameters whose type has a +@code{Default_Value} aspect. -RM References: 2.03 (3.1/2) 2.03 (4/2) 2.03 (5/2) 2.03 (5.1/2) 2.03 (5.2/2) 2.03 (5.3/2) 2.09 (2/2) +RM references: 4.06 (56) 6.04.01 (6.25/3) 6.04.01 (13.1/3) @end itemize -@geindex AI-0093 (Ada 2012 feature) +@geindex AI12-0075 (Ada 2022 feature) @itemize * @item -`AI-0093 Additional rules use immutably limited (0000-00-00)' +`AI12-0075 Static expression functions (2020-04-13)' -This is an editorial change only, to make more widespread use of the Ada 2012 -‘immutably limited’. +Ada 2022 defines a new aspect @code{Static} that can be specified on expression +functions. Such an expression function can be called in contexts requiring static expressions when the actual parameters are all static, allowing for greater abstraction in complex static expressions. -RM References: 3.03 (23.4/3) +RM references: 4.09 (21) 6.08 (3/4) 6.08 (5/4) 6.08 (6/4) 7.03.02 (8.2/5) +7.03.02 (15/4) 7.03.02 (16/4) 7.03.02 (17/4) 7.03.02 (19/4) +7.03.02 (20/5) @end itemize -@geindex AI-0095 (Ada 2012 feature) +@geindex AI12-0076 (Ada 2022 feature) @itemize * @item -`AI-0095 Address of intrinsic subprograms (0000-00-00)' +`AI12-0076 Variable state in pure packages (0000-00-00)' + +Defines an obscure constant-modifying construct to be erroneous. The issue is that the current instance of a type is a variable object, so the following is legal: + +@example + type T; + type T_Ref (Access_To_Variable : access T) is null record; + type T is limited record + Self : T_Ref (T'Access); + Int : Integer; + end record; + + Obj : constant T := (Self => <>, Int => 123); +begin + Obj.Self.Access_To_Variable.Int := 456; -- modifying a component of a constant +@end example -The prefix of @code{'Address} cannot statically denote a subprogram with -convention @code{Intrinsic}. The use of the @code{Address} attribute raises -@code{Program_Error} if the prefix denotes a subprogram with convention -@code{Intrinsic}. +In cases where constancy is really needed (e.g., for an object declared in a Pure context), such a case needs to be erroneous. -RM References: 13.03 (11/1) +RM references: 10.02.01 (17/3) E.02.02 (17/2) @end itemize -@geindex AI-0096 (Ada 2012 feature) +@geindex AI12-0077 (Ada 2022 feature) @itemize * @item -`AI-0096 Deriving from formal private types (2010-07-20)' +`AI12-0077 Has_Same_Storage on objects of size zero (2020-03-30)' -In general it is illegal for a type derived from a formal limited type to be -nonlimited. This AI makes an exception to this rule: derivation is legal -if it appears in the private part of the generic, and the formal type is not -tagged. If the type is tagged, the legality check must be applied to the -private part of the package. +This binding interpretation requires the Has_Same_Storage attribute +to return always @cite{false} for objects that have a size of zero. -RM References: 3.04 (5.1/2) 6.02 (7) +RM references: 13.03 (73.4/3) @end itemize -@geindex AI-0097 (Ada 2012 feature) +@geindex AI12-0078 (Ada 2022 feature) @itemize * @item -`AI-0097 Treatment of abstract null extension (2010-07-19)' +`AI12-0078 Definition of node for tree container is confusing (0000-00-00)' -The RM as written implied that in some cases it was possible to create an -object of an abstract type, by having an abstract extension inherit a non- -abstract constructor from its parent type. This mistake has been corrected -in GNAT and in the RM, and this construct is now illegal. +Clarifies the expected behavior in processing tree containers. -RM References: 3.09.03 (4/2) +RM references: A.18.10 (2/3) A.18.10 (3/3) @end itemize -@geindex AI-0098 (Ada 2012 feature) +@geindex AI12-0081 (Ada 2022 feature) @itemize * @item -`AI-0098 Anonymous subprogram access restrictions (0000-00-00)' +`AI12-0081 Real-time aspects need to specify when they are evaluated (0000-00-00)' -An unintentional omission in the RM implied some inconsistent restrictions on -the use of anonymous access to subprogram values. These restrictions were not -intentional, and have never been enforced by GNAT. +Clarify the point at which Priority and Interrupt_Priority aspect expressions are evaluated. -RM References: 3.10.01 (6) 3.10.01 (9.2/2) +RM references: D.01 (17/3) D.16 (9/3) @end itemize -@geindex AI-0099 (Ada 2012 feature) +@geindex AI12-0084 (Ada 2022 feature) @itemize * @item -`AI-0099 Tag determines whether finalization needed (0000-00-00)' +`AI12-0084 Box expressions in array aggregates (2014-12-15)' -This AI clarifies that ‘needs finalization’ is part of dynamic semantics, -and therefore depends on the run-time characteristics of an object (i.e. its -tag) and not on its nominal type. As the AI indicates: “we do not expect -this to affect any implementation”. +This AI addresses an issue where compiler used to fail to initialize +components of a multidimensional aggregates with box initialization when +scalar components have a specified default value. The AI clarifies that +in an array aggregate with box (i.e., @code{<>}) component values, the +@code{Default_Component_Value} of the array type (if any) should not be ignored. -RM References: 7.06.01 (6) 7.06.01 (7) 7.06.01 (8) 7.06.01 (9/2) +RM references: 4.03.03 (23.1/2) @end itemize -@geindex AI-0100 (Ada 2012 feature) +@geindex AI12-0085 (Ada 2022 feature) @itemize * @item -`AI-0100 Placement of pragmas (2010-07-01)' +`AI12-0085 Missing aspect cases for Remote_Types (0000-00-00)' -This AI is an earlier version of AI-163. It simplifies the rules -for legal placement of pragmas. In the case of lists that allow pragmas, if -the list may have no elements, then the list may consist solely of pragmas. +A distributed systems annex (Annex E) clarification. Aspect specifications +that are forbidden using attribute definition clause syntax are also forbidden +using aspect_specification syntax. -RM References: 2.08 (7) +RM references: E.02.02 (17/2) @end itemize -@geindex AI-0102 (Ada 2012 feature) +@geindex AI12-0086 (Ada 2022 feature) @itemize * @item -`AI-0102 Some implicit conversions are illegal (0000-00-00)' +`AI12-0086 Aggregates and variant parts (2019-08-14)' -It is illegal to assign an anonymous access constant to an anonymous access -variable. The RM did not have a clear rule to prevent this, but GNAT has -always generated an error for this usage. +In Ada 2012, a discriminant value that governs an active variant part in an +aggregate had to be static. AI12-0086 relaxes this restriction: If the subtype of the discriminant value is a static subtype all of whose values select the same variant, then the expression for the discriminant is allowed to be nonstatic. -RM References: 3.07 (16) 3.07.01 (9) 6.04.01 (6) 8.06 (27/2) +RM references: 4.03.01 (17/3) 4.03.01 (19/3) @end itemize -@geindex AI-0103 (Ada 2012 feature) +@geindex AI12-0088 (Ada 2022 feature) @itemize * @item -`AI-0103 Static matching for extended return (2010-07-23)' +`AI12-0088 UTF_Encoding.Conversions and overlong characters on input (0000-00-00)' -If the return subtype of a function is an elementary type or a constrained -type, the subtype indication in an extended return statement must match -statically this return subtype. +Clarify that overlong characters are acceptable on input even if we never generate them as output. -RM References: 6.05 (5.2/2) +RM references: A.04.11 (54/3) A.04.11 (55/3) @end itemize -@geindex AI-0104 (Ada 2012 feature) +@geindex AI12-0089 (Ada 2022 feature) @itemize * @item -`AI-0104 Null exclusion and uninitialized allocator (2010-07-15)' +`AI12-0089 Accessibility rules need to take into account that a generic function is not a (0000-00-00)' -The assignment @code{Ptr := new not null Some_Ptr;} will raise -@code{Constraint_Error} because the default value of the allocated object is -`null'. This useless construct is illegal in Ada 2012. +Fix cases in RM wording where the accessibility rules for a function failed to take into account the fact that a generic function is not a function. For example, a generic function with an explicitly aliased parameter should be able to return references to that parameter in the same ways that a (non-generic) function can. The previous wording did not allow that. -RM References: 4.08 (2) +RM references: 3.10.02 (7/3) 3.10.02 (19.2/3) 3.10.02 (19.3/3) 6.05 (4/3) @end itemize -@geindex AI-0106 (Ada 2012 feature) +@geindex AI12-0093 (Ada 2022 feature) @itemize * @item -`AI-0106 No representation pragmas on generic formals (0000-00-00)' +`AI12-0093 Iterator with indefinite cursor (0000-00-00)' -The RM appeared to allow representation pragmas on generic formal parameters, -but this was not intended, and GNAT has never permitted this usage. +A clarification that confirms what GNAT is already doing. -RM References: 13.01 (9.1/1) +RM references: 5.05.02 (8/3) 5.05.02 (10/3) @end itemize -@geindex AI-0108 (Ada 2012 feature) +@geindex AI12-0094 (Ada 2022 feature) @itemize * @item -`AI-0108 Limited incomplete view and discriminants (0000-00-00)' +`AI12-0094 An access_definition should be a declarative region (0000-00-00)' -This AI confirms that an incomplete type from a limited view does not have -discriminants. This has always been the case in GNAT. +Fixes wording omission in the RM, confirming that the behaviour of GNAT is +correct. -RM References: 10.01.01 (12.3/2) +RM references: 8.03 (2) 8.03 (26/3) @end itemize -@geindex AI-0109 (Ada 2012 feature) +@geindex AI12-0095 (Ada 2022 feature) @itemize * @item -`AI-0109 Redundant check in S’Class’Input (0000-00-00)' +`AI12-0095 Generic formal types and constrained partial views (0000-00-00)' -This AI is an editorial change only. It removes the need for a tag check -that can never fail. +Deciding whether an actual parameter corresponding to an explicitly aliased formal parameter is legal depends on (among other things) whether the parameter type has a constrained partial view. The AI clarifies how this compile-time checking works in the case of a generic formal type (assume the best in the spec and recheck each instance, assume the worst in a generic body). -RM References: 13.13.02 (34/2) +RM references: 3.10.02 (27.2/3) 4.06 (24.16/2) 6.04.01 (6.2/3) 12.05.01 (15) @end itemize -@geindex AI-0112 (Ada 2012 feature) +@geindex AI12-0096 (Ada 2022 feature) @itemize * @item -`AI-0112 Detection of duplicate pragmas (2010-07-24)' +`AI12-0096 The exception raised when a subtype conversion fails a predicate check (0000-00-00)' -This AI concerns giving names to various representation aspects, but the -practical effect is simply to make the use of duplicate -@code{Atomic[_Components]}, -@code{Volatile[_Components]}, and -@code{Independent[_Components]} pragmas illegal, and GNAT -now performs this required check. +Clarify that the Predicate_Failure aspect works the same in a subtype conversion as in any other context. -RM References: 13.01 (8) +RM references: 4.06 (57/3) @end itemize -@geindex AI-0114 (Ada 2012 feature) +@geindex AI12-0097 (Ada 2022 feature) @itemize * @item -`AI-0114 Classification of letters (0000-00-00)' +`AI12-0097 Tag of the return object of a simple return expression (0000-00-00)' -The code points 170 (@code{FEMININE ORDINAL INDICATOR}), -181 (@code{MICRO SIGN}), and -186 (@code{MASCULINE ORDINAL INDICATOR}) are technically considered -lower case letters by Unicode. -However, they are not allowed in identifiers, and they -return @code{False} to @code{Ada.Characters.Handling.Is_Letter/Is_Lower}. -This behavior is consistent with that defined in Ada 95. +Clarify wording about the tag of a function result in the case of a simple (i.e. not extended) return statement in a function with a class-wide result type. -RM References: A.03.02 (59) A.04.06 (7) +RM references: 6.05 (8/3) @end itemize -@geindex AI-0116 (Ada 2012 feature) +@geindex AI12-0098 (Ada 2022 feature) @itemize * @item -`AI-0116 Alignment of class-wide objects (0000-00-00)' +`AI12-0098 Problematic examples for ATC (0000-00-00)' -This AI requires that the alignment of a class-wide object be no greater -than the alignment of any type in the class. GNAT has always followed this -recommendation. +The AI clarifies reference manual examples, there is no compiler impact. -RM References: 13.03 (29) 13.11 (16) +RM references: 9.07.04 (13) @end itemize -@geindex AI-0118 (Ada 2012 feature) +@geindex AI12-0099 (Ada 2022 feature) @itemize * @item -`AI-0118 The association of parameter associations (0000-00-00)' +`AI12-0099 Wording problems with predicates (2020-05-04)' -This AI clarifies the rules for named associations in subprogram calls and -generic instantiations. The rules have been in place since Ada 83. +When extending a task or protected type from an ancestor interface subtype with a predicate, a link error can occur due to the compiler failing to generate the predicate-checking function. This AI clarifies the requirement for such predicate inheritance for concurrent types. -RM References: 6.04.01 (2) 12.03 (9) +RM references: 3.02.04 (4/4) 3.02.04 (12/3) 3.02.04 (20/3) @end itemize -@geindex AI-0120 (Ada 2012 feature) +@geindex AI12-0100 (Ada 2022 feature) @itemize * @item -`AI-0120 Constant instance of protected object (0000-00-00)' +`AI12-0100 A qualified expression makes a predicate check (2020-02-17)' -This is an RM editorial change only. The section that lists objects that are -constant failed to include the current instance of a protected object -within a protected function. This has always been treated as a constant -in GNAT. +The compiler now enforces predicate checks on qualified expressions when the +qualifying subtype imposes a predicate. -RM References: 3.03 (21) +RM references: 4.07 (4) @end itemize -@geindex AI-0122 (Ada 2012 feature) +@geindex AI12-0101 (Ada 2022 feature) @itemize * @item -`AI-0122 Private with and children of generics (0000-00-00)' +`AI12-0101 Incompatibility of hidden untagged record equality (2019-10-31)' + +AI12-0101 is a binding interpretation that removes a legality rule that +prohibited the declaration of a primitive equality function for a private type in the private part of its enclosing package (either before or after the completion of the type) when the type is completed as an untagged record type. Such declarations are now accepted in Ada 2012 and later Ada versions. -This AI clarifies the visibility of private children of generic units within -instantiations of a parent. GNAT has always handled this correctly. +As a consequence of this work, some cases where the implementation of AI05-0123 was incomplete were corrected. +More specifically, if a user-defined equality operator is present for an untagged record type in an Ada 2012 program, that user-defined equality operator will be (correctly) executed in some difficult-to-characterize cases where the predefined component-by-component comparison was previously being (incorrectly) executed. This can arise, for example, in the case of the predefined equality operation for an enclosing composite type that has a component of the user-defined primitive equality op’s operand type. +This correction means that the impact of this change is not limited solely to code that was previously rejected at compile time. -RM References: 10.01.02 (12/2) +RM references: 4.05.02 (9.8/3) @end itemize -@geindex AI-0123 (Ada 2012 feature) +@geindex AI12-0102 (Ada 2022 feature) @itemize * @item -`AI-0123 Composability of equality (2010-04-13)' +`AI12-0102 Stream_IO.File_Type has Preelaborable_Initialization (0000-00-00)' -Equality of untagged record composes, so that the predefined equality for a -composite type that includes a component of some untagged record type -@code{R} uses the equality operation of @code{R} (which may be user-defined -or predefined). This makes the behavior of untagged records identical to that -of tagged types in this respect. +Modifies the declaration of one type in a predefined package. GNAT’s version of @code{Ada.Streams.Stream_IO} already had this modification (the @code{Preelaborable__Initialization} pragma). -This change is an incompatibility with previous versions of Ada, but it -corrects a non-uniformity that was often a source of confusion. Analysis of -a large number of industrial programs indicates that in those rare cases -where a composite type had an untagged record component with a user-defined -equality, either there was no use of the composite equality, or else the code -expected the same composability as for tagged types, and thus had a bug that -would be fixed by this change. - -RM References: 4.05.02 (9.7/2) 4.05.02 (14) 4.05.02 (15) 4.05.02 (24) -8.05.04 (8) +RM references: A.12.01 (5) @end itemize -@geindex AI-0125 (Ada 2012 feature) +@geindex AI12-0103 (Ada 2022 feature) @itemize * @item -`AI-0125 Nonoverridable operations of an ancestor (2010-09-28)' +`AI12-0103 Expression functions that are completions in package specifications (0000-00-00)' -In Ada 2012, the declaration of a primitive operation of a type extension -or private extension can also override an inherited primitive that is not -visible at the point of this declaration. +Clarifies that expression functions that are completions do not cause “general” freeze-everybody-in-sight freezing like a subprogram body. -RM References: 7.03.01 (6) 8.03 (23) 8.03.01 (5/2) 8.03.01 (6/2) +RM references: 13.14 (3/3) 13.14 (5/3) @end itemize -@geindex AI-0126 (Ada 2012 feature) +@geindex AI12-0104 (Ada 2022 feature) @itemize * @item -`AI-0126 Dispatching with no declared operation (0000-00-00)' +`AI12-0104 Overriding an aspect is undefined (0000-00-00)' -This AI clarifies dispatching rules, and simply confirms that dispatching -executes the operation of the parent type when there is no explicitly or -implicitly declared operation for the descendant type. This has always been -the case in all versions of GNAT. +A clarification of the wording in RM, no compiler impact. -RM References: 3.09.02 (20/2) 3.09.02 (20.1/2) 3.09.02 (20.2/2) +RM references: 4.01.06 (4/3) 4.01.06 (17/3) @end itemize -@geindex AI-0127 (Ada 2012 feature) +@geindex AI12-0105 (Ada 2022 feature) @itemize * @item -`AI-0127 Adding Locale Capabilities (2010-09-29)' +`AI12-0105 Pre and Post are not allowed on any subprogram completion (0000-00-00)' -This package provides an interface for identifying the current locale. +Language-defined aspects (e.g., @code{Post}) cannot be specified as part of the completion of a subprogram declaration. Fix a hole in the RM wording to clarify that this general rule applies even in the special cases where the completion is either an expression function or a null procedure. -RM References: A.19 A.19.01 A.19.02 A.19.03 A.19.05 A.19.06 -A.19.07 A.19.08 A.19.09 A.19.10 A.19.11 A.19.12 A.19.13 +RM references: 13.01.01 (18/3) @end itemize -@geindex AI-0128 (Ada 2012 feature) +@geindex AI12-0106 (Ada 2022 feature) @itemize * @item -`AI-0128 Inequality is a primitive operation (0000-00-00)' +`AI12-0106 Write’Class aspect (0000-00-00)' -If an equality operator (“=”) is declared for a type, then the implicitly -declared inequality operator (“/=”) is a primitive operation of the type. -This is the only reasonable interpretation, and is the one always implemented -by GNAT, but the RM was not entirely clear in making this point. +Clarify that the syntax used in an ACATS test BDD2005 for specifying a class-wide streaming aspect is correct. -RM References: 3.02.03 (6) 6.06 (6) +RM references: 13.01.01 (28/3) 13.13.02 (38/3) @end itemize -@geindex AI-0129 (Ada 2012 feature) +@geindex AI12-0107 (Ada 2022 feature) @itemize * @item -`AI-0129 Limited views and incomplete types (0000-00-00)' +`AI12-0107 A prefixed view of a By_Protected_Procedure interface has convention protected (2020-06-05)' -This AI clarifies the description of limited views: a limited view of a -package includes only one view of a type that has an incomplete declaration -and a full declaration (there is no possible ambiguity in a client package). -This AI also fixes an omission: a nested package in the private part has no -limited view. GNAT always implemented this correctly. +A prefixed view of a subprogram with aspect Synchronization set to +By_Protected_Procedure has convention protected. -RM References: 10.01.01 (12.2/2) 10.01.01 (12.3/2) +RM references: 6.03.01 (10.1/2) 6.03.01 (12) 6.03.01 (13) @end itemize -@geindex AI-0132 (Ada 2012 feature) +@geindex AI12-0109 (Ada 2022 feature) @itemize * @item -`AI-0132 Placement of library unit pragmas (0000-00-00)' +`AI12-0109 Representation of untagged derived types (2019-11-12)' -This AI fills a gap in the description of library unit pragmas. The pragma -clearly must apply to a library unit, even if it does not carry the name -of the enclosing unit. GNAT has always enforced the required check. +Ada disallows a nonconforming specification of a type-related representation +aspect of an untagged by-reference type. The motivation for this rule is to ensure that a parent type and a later type derived from the parent agree with respect to such aspects. AI12-0109 disallows a construct that otherwise could be used to get around this rule: an aspect specification for the parent type that occurs after the declaration of the derived type. -RM References: 10.01.05 (7) +RM references: 13.01 (10/3) @end itemize -@geindex AI-0134 (Ada 2012 feature) +@geindex AI12-0110 (Ada 2022 feature) @itemize * @item -`AI-0134 Profiles must match for full conformance (0000-00-00)' +`AI12-0110 Tampering checks are performed first (2020-04-14)' -For full conformance, the profiles of anonymous-access-to-subprogram -parameters must match. GNAT has always enforced this rule. +AI12-0110 requires tampering checks in the containers library to be +performed first, before any other checks. -RM References: 6.03.01 (18) +RM references: A.18.02 (97.1/3) A.18.03 (69.1/3) A.18.04 (15.1/3) A.18.07 +(14.1/3) A.18.10 (90/3) A.18.18 (35/3) @end itemize -@geindex AI-0137 (Ada 2012 feature) +@geindex AI12-0112 (Ada 2022 feature) @itemize * @item -`AI-0137 String encoding package (2010-03-25)' +`AI12-0112 Contracts for container operations (0000-00-00)' -The packages @code{Ada.Strings.UTF_Encoding}, together with its child -packages, @code{Conversions}, @code{Strings}, @code{Wide_Strings}, -and @code{Wide_Wide_Strings} have been -implemented. These packages (whose documentation can be found in the spec -files @code{a-stuten.ads}, @code{a-suenco.ads}, @code{a-suenst.ads}, -@code{a-suewst.ads}, @code{a-suezst.ads}) allow encoding and decoding of -@code{String}, @code{Wide_String}, and @code{Wide_Wide_String} -values using UTF coding schemes (including UTF-8, UTF-16LE, UTF-16BE, and -UTF-16), as well as conversions between the different UTF encodings. With -the exception of @code{Wide_Wide_Strings}, these packages are available in -Ada 95 and Ada 2005 mode as well as Ada 2012 mode. -The @code{Wide_Wide_Strings} package -is available in Ada 2005 mode as well as Ada 2012 mode (but not in Ada 95 -mode since it uses @code{Wide_Wide_Character}). +A representation change replacing english descriptions of contracts for +operations on predefined container types with pre/post-conditions. No compiler +impact. -RM References: A.04.11 +RM references: A.18.02 (99/3) 11.04.02 (23.1/3) 11.05 (23) 11.05 (26) A +(4) A.18 (10) @end itemize -@geindex AI-0139-2 (Ada 2012 feature) +@geindex AI12-0114 (Ada 2022 feature) @itemize * @item -`AI-0139-2 Syntactic sugar for iterators (2010-09-29)' +`AI12-0114 Overlapping objects designated by access parameters are not thread-safe (0000-00-00)' -The new syntax for iterating over arrays and containers is now implemented. -Iteration over containers is for now limited to read-only iterators. Only -default iterators are supported, with the syntax: @code{for Elem of C}. +There are rules saying that concurrent calls to predefined subprograms don’t interfere with each other unless actual parameters overlap. The AI clarifies that such an interference is also possible if overlapping objects are reachable via access dereferencing from actual parameters of the two calls. -RM References: 5.05 +RM references: A (3/2) @end itemize -@geindex AI-0146 (Ada 2012 feature) +@geindex AI12-0116 (Ada 2022 feature) @itemize * @item -`AI-0146 Type invariants (2009-09-21)' +`AI12-0116 Private types and predicates (0000-00-00)' -Type invariants may be specified for private types using the aspect notation. -Aspect @code{Type_Invariant} may be specified for any private type, -@code{Type_Invariant'Class} can -only be specified for tagged types, and is inherited by any descendent of the -tagged types. The invariant is a boolean expression that is tested for being -true in the following situations: conversions to the private type, object -declarations for the private type that are default initialized, and -[`in'] `out' -parameters and returned result on return from any primitive operation for -the type that is visible to a client. -GNAT defines the synonyms @code{Invariant} for @code{Type_Invariant} and -@code{Invariant'Class} for @code{Type_Invariant'Class}. +Clarify that the same aspect cannot be specified twice for the same type. @code{Dynamic_Predicate}, for example, can be specified on either the partial view of a type or on the completion in the private part, but not on both. -RM References: 13.03.03 (00) +RM references: 13.01 (9/3) 13.01 (9.1/3) @end itemize -@geindex AI-0147 (Ada 2012 feature) +@geindex AI12-0117 (Ada 2022 feature) @itemize * @item -`AI-0147 Conditional expressions (2009-03-29)' - -Conditional expressions are permitted. The form of such an expression is: +`AI12-0117 Restriction No_Tasks_Unassigned_To_CPU (2020-06-12)' -@example -(if expr then expr @{elsif expr then expr@} [else expr]) -@end example +This AI adds a restriction No_Tasks_Unassigned_To_CPU to provide safe +use of Ravenscar. -The parentheses can be omitted in contexts where parentheses are present -anyway, such as subprogram arguments and pragma arguments. If the `else' -clause is omitted, `else' `True' is assumed; -thus @code{(if A then B)} is a way to conveniently represent -`(A implies B)' in standard logic. +The CPU aspect is specified for the environment task. No CPU aspect is +specified to be statically equal to @code{Not_A_Specific_CPU}. If aspect CPU +is specified (dynamically) to the value @code{Not_A_Specific_CPU}, then +Program_Error is raised. If Set_CPU or @code{Delay_Until_And_Set_CPU} are called +with the CPU parameter equal to @code{Not_A_Specific_CPU}, then @code{Program_Error} is raised. -RM References: 4.03.03 (15) 4.04 (1) 4.04 (7) 4.05.07 (0) 4.07 (2) -4.07 (3) 4.09 (12) 4.09 (33) 5.03 (3) 5.03 (4) 7.05 (2.1/2) +RM references: D.07 (10.8/3) @end itemize -@geindex AI-0152 (Ada 2012 feature) +@geindex AI12-0120 (Ada 2022 feature) @itemize * @item -`AI-0152 Restriction No_Anonymous_Allocators (2010-09-08)' +`AI12-0120 Legality and exceptions of generalized loop iteration (0000-00-00)' -Restriction @code{No_Anonymous_Allocators} prevents the use of allocators -where the type of the returned value is an anonymous access type. +Clarify that the expansion-based definition of generalized loop iteration +includes legality checking. If the expansion would be illegal (for example, +because of passing a constant actual parameter in a call when the mode of +the corresponding formal parameter is in-out), then the loop is illegal too. -RM References: H.04 (8/1) +RM references: 5.05.02 (6.1/4) 5.05.02 (10/3) 5.05.02 (13/3) @end itemize -@geindex AI-0157 (Ada 2012 feature) +@geindex AI12-0121 (Ada 2022 feature) @itemize * @item -`AI-0157 Allocation/Deallocation from empty pool (2010-07-11)' +`AI12-0121 Stream-oriented aspects (0000-00-00)' -Allocation and Deallocation from an empty storage pool (i.e. allocation or -deallocation of a pointer for which a static storage size clause of zero -has been given) is now illegal and is detected as such. GNAT -previously gave a warning but not an error. +Clarify that streaming-oriented aspects (e.g., Read) can be specified using +aspect_specification syntax, not just via an attribute definition clause. -RM References: 4.08 (5.3/2) 13.11.02 (4) 13.11.02 (17) +RM references: 13.13.02 (38/3) @end itemize -@geindex AI-0158 (Ada 2012 feature) +@geindex AI12-0124 (Ada 2022 feature) @itemize * @item -`AI-0158 Generalizing membership tests (2010-09-16)' +`AI12-0124 Add Object’Image (2017-03-24)' -This AI extends the syntax of membership tests to simplify complex conditions -that can be expressed as membership in a subset of values of any type. It -introduces syntax for a list of expressions that may be used in loop contexts -as well. +The corrigendum of Ada 2012 extends attribute @code{'Image following} the syntax for the GNAT @code{'Img} attribute. This AI fixes a gap in the earlier implementation, which did not recognize function calls and attributes that are functions as valid object prefixes. -RM References: 3.08.01 (5) 4.04 (3) 4.05.02 (3) 4.05.02 (5) 4.05.02 (27) +RM references: 3.05 (55/3) @end itemize -@geindex AI-0161 (Ada 2012 feature) +@geindex AI12-0125-3 (Ada 2022 feature) @itemize * @item -`AI-0161 Restriction No_Default_Stream_Attributes (2010-09-11)' +`AI12-0125-3 Add @@ as an abbreviation for the LHS of an assignment (2016-11-11)' -A new restriction @code{No_Default_Stream_Attributes} prevents the use of any -of the default stream attributes for elementary types. If this restriction is -in force, then it is necessary to provide explicit subprograms for any -stream attributes used. +This AI introduces the use of the character ‘@@’ as an abbreviation for the left-hand side of an assignment statement, usable anywhere within the expression on the right-hand side. To use this feature the compilation flag -gnat2022 must be specified. -RM References: 13.12.01 (4/2) 13.13.02 (40/2) 13.13.02 (52/2) +RM references: 5.02.01 (0) 2.02 (9) 3.03 (21.1/3) 4.01 (2/3) 8.06 (9/4) @end itemize -@geindex AI-0162 (Ada 2012 feature) +@geindex AI12-0127 (Ada 2022 feature) @itemize * @item -`AI-0162 Incomplete type completed by partial view (2010-09-15)' +`AI12-0127 Partial aggregate notation (2016-10-12)' -Incomplete types are made more useful by allowing them to be completed by -private types and private extensions. +This AI describes a new constructor for aggregates, in terms of an existing record or array object, and a series of component-wise modifications of its value, given by named associations for the modified components. To use this feature the compilation flag @code{-gnat2022} must be specified. -RM References: 3.10.01 (2.5/2) 3.10.01 (2.6/2) 3.10.01 (3) 3.10.01 (4/2) +RM references: 4.03 (2) 4.03 (3/2) 4.03 (4) 4.03.01 (9) 4.03.01 (15/3) +4.03.01 (16/4) 4.03.01 (17/5) 4.03.01 (17.1/2) 4.03.03 (4) 4.03.03 +(14) 4.03.03 (17/5) 4.03.04 (0) 7.05 (2.6/2) @end itemize -@geindex AI-0163 (Ada 2012 feature) +@geindex AI12-0128 (Ada 2022 feature) @itemize * @item -`AI-0163 Pragmas in place of null (2010-07-01)' +`AI12-0128 Exact size access to parts of composite atomic objects (2019-11-24)' -A statement sequence may be composed entirely of pragmas. It is no longer -necessary to add a dummy @code{null} statement to make the sequence legal. +According to this AI, the compiler generates full access to atomic composite objects even if the access is only partial in the source code. To use this feature the compilation flag @code{-gnat2022} must be specified. -RM References: 2.08 (7) 2.08 (16) +RM references: C.06 (13.2/3) C.06 (19) C.06 (20) C.06 (22/2) C.06 (25/4) @end itemize -@geindex AI-0171 (Ada 2012 feature) +@geindex AI12-0129 (Ada 2022 feature) @itemize * @item -`AI-0171 Pragma CPU and Ravenscar Profile (2010-09-24)' +`AI12-0129 Make protected objects more protecting (2020-07-01)' -A new package @code{System.Multiprocessors} is added, together with the -definition of pragma @code{CPU} for controlling task affinity. A new no -dependence restriction, on @code{System.Multiprocessors.Dispatching_Domains}, -is added to the Ravenscar profile. +A new aspect Exclusive_Functions has been added to the language to force the +use of read/write locks on protected functions when needed. -RM References: D.13.01 (4/2) D.16 +RM references: 9.05.01 (2) 9.05.01 (4) 9.05.01 (5) 9.05.01 (7) 9.05.03 +(15) 9.05.03 (23) @end itemize -@geindex AI-0173 (Ada 2012 feature) +@geindex AI12-0130 (Ada 2022 feature) @itemize * @item -`AI-0173 Testing if tags represent abstract types (2010-07-03)' +`AI12-0130 All I/O packages should have Flush (2016-07-03)' -The function @code{Ada.Tags.Type_Is_Abstract} returns @code{True} if invoked -with the tag of an abstract type, and @code{False} otherwise. +The Flush routine has been added for the @code{Sequential_IO} and @code{Direct_IO} standard packages in the Ada 2012 COR.1:2016. The Flush routine here is equivalent to the one found in @code{Text_IO}. The @code{Flush} procedure synchronizes the external file with the internal file (by flushing any internal buffers) without closing the file. -RM References: 3.09 (7.4/2) 3.09 (12.4/2) +RM references: A.08.01 (10) A.08.02 (28/3) A.08.04 (10) A.10.03 (21) +A.12.01 (28/2) A.12.01 (28.6/1) @end itemize -@geindex AI-0176 (Ada 2012 feature) +@geindex AI12-0131 (Ada 2022 feature) @itemize * @item -`AI-0176 Quantified expressions (2010-09-29)' +`AI12-0131 Inherited Pre’Class when unspecified on initial subprogram (0000-00-00)' -Both universally and existentially quantified expressions are implemented. -They use the new syntax for iterators proposed in AI05-139-2, as well as -the standard Ada loop syntax. +If T1 is a tagged type with a primitive P that has no class-wide precondition, +and if T2 is an extension of T1 which overrides the inherited primitive P, then that overriding P is not allowed to have a class-wide precondition. Allowing it would be ineffective except in corner cases where it would be confusing. -RM References: 1.01.04 (12) 2.09 (2/2) 4.04 (7) 4.05.09 (0) +RM references: 6.01.01 (17/3) 6.01.01 (18/3) @end itemize -@geindex AI-0177 (Ada 2012 feature) +@geindex AI12-0132 (Ada 2022 feature) @itemize * @item -`AI-0177 Parameterized expressions (2010-07-10)' - -The new Ada 2012 notion of parameterized expressions is implemented. The form -is: +`AI12-0132 Freezing of renames-as-body (2020-06-13)' -@example -function-specification is (expression) -@end example +This AI clarifies that a renames-as-body freezes the expression of any +expression function that it renames. -This is exactly equivalent to the -corresponding function body that returns the expression, but it can appear -in a package spec. Note that the expression must be parenthesized. - -RM References: 13.11.01 (3/2) +RM references: 13.14 (5/3) @end itemize -@geindex AI-0178 (Ada 2012 feature) +@geindex AI12-0133 (Ada 2022 feature) @itemize * @item -`AI-0178 Incomplete views are limited (0000-00-00)' +`AI12-0133 Type invariants and default initialized objects (0000-00-00)' -This AI clarifies the role of incomplete views and plugs an omission in the -RM. GNAT always correctly restricted the use of incomplete views and types. +Clarify that invariant checking for a default-initialized object is performed regardless of where the object is declared (in particular, even when the full view of the type is visible). -RM References: 7.05 (3/2) 7.05 (6/2) +RM references: 7.03.02 (10.3/3) @end itemize -@geindex AI-0179 (Ada 2012 feature) +@geindex AI12-0135 (Ada 2022 feature) @itemize * @item -`AI-0179 Statement not required after label (2010-04-10)' +`AI12-0135 Enumeration types should be eligible for convention C (0000-00-00)' -It is not necessary to have a statement following a label, so a label -can appear at the end of a statement sequence without the need for putting a -null statement afterwards, but it is not allowable to have only labels and -no real statements in a statement sequence. +Ada previously allowed but did not require supporting specifying convention C for an enumeration type. Now it is required that an implementation shall support it. -RM References: 5.01 (2) +RM references: B.01 (14/3) B.01 (41/3) B.03 (65) @end itemize -@geindex AI-0181 (Ada 2012 feature) +@geindex AI12-0136 (Ada 2022 feature) @itemize * @item -`AI-0181 Soft hyphen is a non-graphic character (2010-07-23)' +`AI12-0136 Language-defined packages and aspect Default_Storage_Pool (0000-00-00)' -From Ada 2005 on, soft hyphen is considered a non-graphic character, which -means that it has a special name (@code{SOFT_HYPHEN}) in conjunction with the -@code{Image} and @code{Value} attributes for the character types. Strictly -speaking this is an inconsistency with Ada 95, but in practice the use of -these attributes is so obscure that it will not cause problems. +Clarify that the effect of specifying Default_Storage_Pool for an instance of a predefined generic is implementation-defined. No compiler impact. -RM References: 3.05.02 (2/2) A.01 (35/2) A.03.03 (21) +RM references: 13.11.03 (5/3) @end itemize -@geindex AI-0182 (Ada 2012 feature) +@geindex AI12-0137 (Ada 2022 feature) @itemize * @item -`AI-0182 Additional forms for' @code{Character'Value} `(0000-00-00)' +`AI12-0137 Incomplete views and access to class-wide types (0000-00-00)' -This AI allows @code{Character'Value} to accept the string @code{'?'} where -@code{?} is any character including non-graphic control characters. GNAT has -always accepted such strings. It also allows strings such as -@code{HEX_00000041} to be accepted, but GNAT does not take advantage of this -permission and raises @code{Constraint_Error}, as is certainly still -permitted. +If the designated type of an access type is incomplete when the access type is declared, then we have rules about whether we get a complete view when a value of the access type is dereferenced. Clarify that analogous rules apply if the designated type is class-wide. -RM References: 3.05 (56/2) +RM references: 3.10.01 (2.1/2) @end itemize -@geindex AI-0183 (Ada 2012 feature) +@geindex AI12-0138 (Ada 2022 feature) @itemize * @item -`AI-0183 Aspect specifications (2010-08-16)' - -Aspect specifications have been fully implemented except for pre and post- -conditions, and type invariants, which have their own separate AI’s. All -forms of declarations listed in the AI are supported. The following is a -list of the aspects supported (with GNAT implementation aspects marked) -@end itemize - +`AI12-0138 Iterators of formal derived types (2021-02-11)' -@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxx} -@headitem +AI12-0138 specifies the legality rules for confirming specifications of +nonoverridable aspects. This completes the legality checks for aspect @code{Implicit_Dereference} and simplifies the checks for those aspects that are inherited operations. -Supported Aspect +RM references: 13.01.01 (18/4) 13.01.01 (34/3) 4.01.05 (6/3) 4.01.06 (5/3) +4.01.06 (6/3) 4.01.06 (7/3) 4.01.06 (8/3) 4.01.06 (9/3) 5.05.01 (11/3) +@end itemize -@tab +@geindex AI12-0140 (Ada 2022 feature) -Source -@item +@itemize * -@code{Ada_2005} +@item +`AI12-0140 Access to unconstrained partial view when full view is constrained (0000-00-00)' -@tab +Clarify some confusion about about whether what matters when checking whether designated subtypes statically match is the view of the designated type that is currently available v.s. the view that was available when the access type was declared. -– GNAT +RM references: 3.02 (7/2) 7.03.01 (5/1) +@end itemize -@item +@geindex AI12-0143 (Ada 2022 feature) -@code{Ada_2012} -@tab +@itemize * -– GNAT +@item +`AI12-0143 Using an entry index of a family in a precondition (2022-04-05)' -@item +Ada 2022 adds the @code{Index} attribute, which allows the use of the entry family index of an entry call within preconditions and post-conditions. -@code{Address} +RM references: 6.01.01 (30/3) 9.05.04 (5/3) +@end itemize -@tab +@geindex AI12-0144 (Ada 2022 feature) -@item -@code{Alignment} +@itemize * -@tab +@item +`AI12-0144 Make Discrete_Random more flexible (2020-01-31)' -@item +A new function Random with First/Last parameters is provided in the +@code{Ada.Numerics.Discrete_Random} package. -@code{Atomic} +RM references: A.05.02 (20) A.05.02 (32) A.05.02 (41) A.05.02 (42) +@end itemize -@tab +@geindex AI12-0145 (Ada 2022 feature) -@item -@code{Atomic_Components} +@itemize * -@tab +@item +`AI12-0145 Pool_of_Subpool returns null when called too early (0000-00-00)' -@item +Clarify that if you ask for the pool of a subpool (by calling @code{Pool_Of_Subpool}) before @code{Set_Pool_of_Subpool} is called, then the result is null. -@code{Bit_Order} +RM references: 13.11.04 (20/3) +@end itemize -@tab +@geindex AI12-0147 (Ada 2022 feature) -@item -@code{Component_Size} +@itemize * -@tab +@item +`AI12-0147 Expression functions and null procedures can be declared in a protected_body (2015-03-05)' -@item +AI12-0147 specifies that null procedures and expression functions are now +allowed in protected bodies. -@code{Contract_Cases} +RM references: 9.04 (8/1) +@end itemize -@tab +@geindex AI12-0149 (Ada 2022 feature) -– GNAT -@item +@itemize * -@code{Discard_Names} +@item +`AI12-0149 Type invariants are checked for functions returning access-to-type (0000-00-00)' -@tab +Extend the rule saying that @code{Type_Invariant} checks are performed for access-to-T parameters (where T has a specified @code{Type_Invariant}) so that the rule also applies to function results. -@item +RM references: 7.03.02 (19.3/4) +@end itemize -@code{External_Tag} +@geindex AI12-0150 (Ada 2022 feature) -@tab -@item +@itemize * -@code{Favor_Top_Level} +@item +`AI12-0150 Class-wide type invariants and statically bound calls (0000-00-00)' -@tab +The same approach used in AI12-0113 to ensure that contract-related calls associated with a call to a subprogram “match” with respect to dispatching also applies to @code{Type_Invariant} checking. -– GNAT +RM references: 7.03.02 (3/3) 7.03.02 (5/3) 7.03.02 (9/3) 7.03.02 (22/3) +@end itemize -@item +@geindex AI12-0154 (Ada 2022 feature) -@code{Inline} -@tab +@itemize * -@item +@item +`AI12-0154 Aspects of library units (0000-00-00)' -@code{Inline_Always} +Clarify that an aspect_specification for a library unit is equivalent to a corresponding aspect-specifying pragma. -@tab +RM references: 13.01.01 (32/3) +@end itemize -– GNAT +@geindex AI12-0156 (Ada 2022 feature) -@item -@code{Invariant} +@itemize * -@tab +@item +`AI12-0156 Use subtype_indication in generalized iterators (0000-00-00)' -– GNAT +For iterating over an array, we already allow (but do not require) explicitly providing a subtype indication in an iterator_specification. Tee AI generalizes this to handle the case where the element type of the array is of an anonymous access type. This also allows (but does not require) explicitly naming the cursor subtype in a generalized iterator. +The main motivation for allowing these new cases is improving readability by making it easy to infer the (sub)type of the iteration object just by looking at the loop. -@item +RM references: 5.05.02 (2/3) 5.05.02 (5/4) 5.05.02 (7/3) 3.10.02 (11.1/2) +@end itemize -@code{Machine_Radix} +@geindex AI12-0157 (Ada 2022 feature) -@tab -@item +@itemize * -@code{No_Return} +@item +`AI12-0157 Missing rules for expression functions (0000-00-00)' -@tab +Clarify that an expression function behaves like a single-return-statement +function in more cases: it can return an aggregate without extra parens, the expression has an applicable index constraint, and the same accessibility rules apply in both cases. -@item +For instance, the code below is legal: -@code{Object_Size} +@example +subtype S is String (1 .. 10); +function f return S is (others => '?'); +@end example -@tab +RM references: 3.10.02 (19.2/4) 3.10.02 (19.3/4) 4.03.03 (11/2) 6.08 (2/3) +6.08 (3/3) 6.08 (5/3) 6.08 (6/3) 6.08 (7/3) 7.05 (2.9/3) 13.14 +(5.1/4) 13.14 (5.2/4) 13.14 (8/3) 13.14 (10.1/3) 13.14 (10.2/3) +13.14 (10.3/3) +@end itemize -– GNAT +@geindex AI12-0160 (Ada 2022 feature) -@item -@code{Pack} +@itemize * -@tab +@item +`AI12-0160 Adding an indexing aspect to an indexable container type (0000-00-00)' -@item +If the parent type of a derived type has exactly one of the two indexing aspects (that is, constant_indexing and variable_indexing) specified, then the derived type cannot have a specification for the other one. -@code{Persistent_BSS} +RM references: 4.01.06 (6/4) 4.01.06 (9/4) 3.06 (22.2/3) +@end itemize -@tab +@geindex AI12-0162 (Ada 2022 feature) -– GNAT -@item +@itemize * -@code{Post} +@item +`AI12-0162 Memberships and Unchecked_Unions (0000-00-00)' -@tab +Clarify that membership tests for unchecked_union types work consistently when +testing membership in more than one subtype (X in AA | BB | CC) as when +testing for one. -@item +RM references: B.03.03 (25/2) +@end itemize -@code{Pre} +@geindex AI12-0164 (Ada 2022 feature) -@tab -@item +@itemize * -@code{Predicate} +@item +`AI12-0164 Max_Entry_Queue_Length aspect for entries (2019-06-11)' -@tab +AI12-0164 defines pragma and aspect @code{Max_Entry_Queue_Length} in addition +to the GNAT-specific equivalents @code{Max_Queue_Length} and @code{Max_Entry_Queue_Depth}. -@item +RM references: D.04 (16) +@end itemize -@code{Preelaborable_Initialization} +@geindex AI12-0165 (Ada 2022 feature) -@tab -@item +@itemize * -@code{Pure_Function} +@item +`AI12-0165 Operations of class-wide types and formal abstract subprograms (2021-10-19)' -@tab +Ada 2022 specifies that when the controlling type of a formal abstract +subprogram declaration is a formal type, and the actual type is a class-wide type T’Class, the actual subprogram can be an implicitly declared subprogram corresponding to a primitive operation of type T. -– GNAT +RM references: 12.06 (8.5/2) +@end itemize -@item +@geindex AI12-0166 (Ada 2022 feature) -@code{Remote_Access_Type} -@tab +@itemize * -– GNAT +@item +`AI12-0166 External calls to protected functions that appear to be internal calls (2016-11-15)' -@item +According to this AI, the compiler rejects a call to a protected operation when the call appears within a precondition for another protected operation. -@code{Shared} +RM references: 6.01.01 (34/3) 9.05 (3/3) 9.05 (7.1/3) +@end itemize -@tab +@geindex AI12-0167 (Ada 2022 feature) -– GNAT -@item +@itemize * -@code{Size} +@item +`AI12-0167 Type_Invariants and tagged-type View Conversions (0000-00-00)' -@tab +This AI clarifies that no invariant check is performed in a case where an invariant-violating value is assigned to a component. This confirms the current compiler behavior. -@item +RM references: 7.03.02 (9/4) +@end itemize -@code{Storage_Pool} +@geindex AI12-0168 (Ada 2022 feature) -@tab -@item +@itemize * -@code{Storage_Size} +@item +`AI12-0168 Freezing of generic instantiations of generics with bodies (0000-00-00)' -@tab +Adjust freezing rules to be compatible with AI12-0103-1. The change confirms the current compiler behavior. -@item +RM references: 13.14 (3/4) +@end itemize -@code{Stream_Size} +@geindex AI12-0169 (Ada 2022 feature) -@tab -@item +@itemize * -@code{Suppress} +@item +`AI12-0169 Aspect specifications for entry bodies (0000-00-00)' -@tab +Change syntax to allow aspect specifications for implementation-defined aspects on entry bodies. The change doesn’t influence any of the language-defined aspects and is solely required for SPARK. -@item +RM references: 9.05.02 (5) +@end itemize -@code{Suppress_Debug_Info} +@geindex AI12-0170 (Ada 2022 feature) -@tab -– GNAT +@itemize * -@item +@item +`AI12-0170 Abstract subprogram calls in class-wide precondition expressions (2020-07-06)' -@code{Test_Case} +This AI specifies rules for calls to abstract functions within class-wide preconditions and postconditions. -@tab +RM references: 3.09.03 (7) 6.01.01 (7/4) 6.01.01 (18/4) 6.01.01 (18.2/4) +@end itemize -– GNAT +@geindex AI12-0172 (Ada 2022 feature) -@item -@code{Thread_Local_Storage} +@itemize * -@tab +@item +`AI12-0172 Raise expressions in limited contexts (2019-07-29)' -– GNAT +The compiler has been enhanced to support the use of raise expressions in +limited contexts. -@item +RM references: 7.05 (2.1/3) +@end itemize -@code{Type_Invariant} +@geindex AI12-0173 (Ada 2022 feature) -@tab -@item +@itemize * -@code{Unchecked_Union} +@item +`AI12-0173 Expression of an extended return statement (0000-00-00)' -@tab +Fix the wording related to expression of an extended return statement that was made ambiguous by changes of syntax in other AI’s. No compiler changes involved. -@item +RM references: 6.05 (3/2) 6.05 (5/3) +@end itemize -@code{Universal_Aliasing} +@geindex AI12-0174 (Ada 2022 feature) -@tab -– GNAT +@itemize * -@item +@item +`AI12-0174 Aggregates of Unchecked_Unions using named notation (0000-00-00)' -@code{Unmodified} +In many cases, it is illegal to name a discriminant of an unchecked_union type. Relax this rule to allow the use of named notation in an aggregate of an unchecked_union type. -@tab +RM references: B.03.03 (9/3) +@end itemize -– GNAT +@geindex AI12-0175 (Ada 2022 feature) -@item -@code{Unreferenced} +@itemize * -@tab +@item +`AI12-0175 Preelaborable packages with address clauses (2020-03-20)' -– GNAT +The compiler nows accepts calls to certain functions that are essentially unchecked conversions in preelaborated library units. To use this feature the compilation flag @code{-gnat2022} must be specified. -@item +RM references: 10.02.01 (7) +@end itemize -@code{Unreferenced_Objects} +@geindex AI12-0179 (Ada 2022 feature) -@tab -– GNAT +@itemize * -@item +@item +`AI12-0179 Failure of postconditions of language-defined units (0000-00-00)' -@code{Unsuppress} +A clarification that expressing postconditions for predefined units via RM wording or via @code{Post} aspect specifications are equivalent. In particular, the expression in such a @code{Post} aspect specification should not yield False. No implementation changes needed. -@tab +RM references: 1.01.03 (17/3) 11.04.02 (23.1/3) +@end itemize -@item +@geindex AI12-0180 (Ada 2022 feature) -@code{Value_Size} -@tab +@itemize * -– GNAT +@item +`AI12-0180 Using protected subprograms and entries within an invariant (2020-06-22)' -@item +AI12-0180 makes entries and protected subprograms directly visible within Invariant aspects of a task or protected type. -@code{Volatile} +RM references: 13.01.01 (12/3) +@end itemize -@tab +@geindex AI12-0181 (Ada 2022 feature) -@item -@code{Volatile_Components} +@itemize * -@tab +@item +`AI12-0181 Self-referencing representation aspects (0000-00-00)' -@item +Clarify that a name or expression which freezes an entity cannot occur in an aspect specification for that entity. -@code{Warnings} +RM references: 13.01 (9/4) 13.01 (9.1/4) 13.14 (19) +@end itemize -@tab +@geindex AI12-0182 (Ada 2022 feature) -– GNAT -@end multitable +@itemize * +@item +`AI12-0182 Pre’Class and protected operations (0000-00-00)' -@quotation +Confirm that Pre’Class and Post’Class cannot be specified for a protected operation. No language change. -Note that for aspects with an expression, e.g. @code{Size}, the expression is -treated like a default expression (visibility is analyzed at the point of -occurrence of the aspect, but evaluation of the expression occurs at the -freeze point of the entity involved). - -RM References: 3.02.01 (3) 3.02.02 (2) 3.03.01 (2/2) 3.08 (6) -3.09.03 (1.1/2) 6.01 (2/2) 6.07 (2/2) 9.05.02 (2/2) 7.01 (3) 7.03 -(2) 7.03 (3) 9.01 (2/2) 9.01 (3/2) 9.04 (2/2) 9.04 (3/2) -9.05.02 (2/2) 11.01 (2) 12.01 (3) 12.03 (2/2) 12.04 (2/2) 12.05 (2) -12.06 (2.1/2) 12.06 (2.2/2) 12.07 (2) 13.01 (0.1/2) 13.03 (5/1) -13.03.01 (0) -@end quotation +RM references: 13.01.01 (16/3) +@end itemize -@geindex AI-0185 (Ada 2012 feature) +@geindex AI12-0184 (Ada 2022 feature) @itemize * @item -`AI-0185 Ada.Wide_[Wide_]Characters.Handling (2010-07-06)' +`AI12-0184 Long Long C Data Types (2020-01-30)' -Two new packages @code{Ada.Wide_[Wide_]Characters.Handling} provide -classification functions for @code{Wide_Character} and -@code{Wide_Wide_Character}, as well as providing -case folding routines for @code{Wide_[Wide_]Character} and -@code{Wide_[Wide_]String}. +Two new types @code{long_long} and @code{unsigned_long_long} are introduced in the package @code{Interfaces.C}. -RM References: A.03.05 (0) A.03.06 (0) +RM references: B.03 (71.3/3) @end itemize -@geindex AI-0188 (Ada 2012 feature) +@geindex AI12-0185 (Ada 2022 feature) @itemize * @item -`AI-0188 Case expressions (2010-01-09)' - -Case expressions are permitted. This allows use of constructs such as: +`AI12-0185 Resolution of postcondition-specific attributes (0000-00-00)' -@example -X := (case Y is when 1 => 2, when 2 => 3, when others => 31) -@end example +Clarify resolution rules for @code{'Old} and @code{'Result} attribute references to match original intent. -RM References: 4.05.07 (0) 4.05.08 (0) 4.09 (12) 4.09 (33) +RM references: 6.01.01 (7/4) 6.01.01 (8/3) 6.01.01 (26.10/4) 6.01.01 (29/3) @end itemize -@geindex AI-0189 (Ada 2012 feature) +@geindex AI12-0186 (Ada 2022 feature) @itemize * @item -`AI-0189 No_Allocators_After_Elaboration (2010-01-23)' +`AI12-0186 Profile freezing for the Access attribute (0000-00-00)' -This AI introduces a new restriction @code{No_Allocators_After_Elaboration}, -which says that no dynamic allocation will occur once elaboration is -completed. -In general this requires a run-time check, which is not required, and which -GNAT does not attempt. But the static cases of allocators in a task body or -in the body of the main program are detected and flagged at compile or bind -time. +Clarify that the use of Some_Subprogram’Access does not freeze the profile of Some_Subprogram. -RM References: D.07 (19.1/2) H.04 (23.3/2) +RM references: 13.14 (15) @end itemize -@geindex AI-0190 (Ada 2012 feature) +@geindex AI12-0187 (Ada 2022 feature) @itemize * @item -`AI-0190 pragma Default_Storage_Pool (2010-09-15)' +`AI12-0187 Stable properties of abstract data types (2020-11-04)' -This AI introduces a new pragma @code{Default_Storage_Pool}, which can be -used to control storage pools globally. -In particular, you can force every access -type that is used for allocation (`new') to have an explicit storage pool, -or you can declare a pool globally to be used for all access types that lack -an explicit one. +Ada 2022 defines a new aspect, @code{Stable_Properties}, for use in +generating additional postcondition checks for subprograms. -RM References: D.07 (8) +RM references: 7.03.04 (0) 13.01.01 (4/3) @end itemize -@geindex AI-0193 (Ada 2012 feature) +@geindex AI12-0191 (Ada 2022 feature) @itemize * @item -`AI-0193 Alignment of allocators (2010-09-16)' +`AI12-0191 Clarify “part” for type invariants (0000-00-00)' -This AI introduces a new attribute @code{Max_Alignment_For_Allocation}, -analogous to @code{Max_Size_In_Storage_Elements}, but for alignment instead -of size. +Clarify that for purposes of determining whether an invariant check is required for a “part” of an object, we do not look at “parts” which do not correspond to “parts” of the nominal type of the object. For example, if we have a parameter Param of a tagged type T1 (or equivalently of type T1’Class), and type T2 is an extension of T1 which declares a component Foo, and T1’Class (Param)’Tag = T2’Tag, then no invariant check is performed for Param’s Foo component (or any subcomponent thereof). -RM References: 13.11 (16) 13.11 (21) 13.11.01 (0) 13.11.01 (1) -13.11.01 (2) 13.11.01 (3) +RM references: 3.03 (23/5) 3.09.01 (4.1/2) 6.08 (5.8/5) 7.03.02 (8.3/5) +7.03.02 (8.4/5) 7.03.02 (8.5/5) 7.03.02 (8.6/5) 7.03.02 (8.7/5) +7.03.02 (8.8/5) 7.03.02 (8.9/5) 7.03.02 (8.10/5) 7.03.02 (8.11/5) +7.03.02 (8.12/5) 7.03.02 (10.1/4) 7.03.02 (15/5) 7.03.02 (17/4) +7.03.02 (18/4) 7.03.02 (19/4) 13.13.02 (9/3) @end itemize -@geindex AI-0194 (Ada 2012 feature) +@geindex AI12-0192 (Ada 2022 feature) @itemize * @item -`AI-0194 Value of Stream_Size attribute (0000-00-00)' +`AI12-0192 “requires late initialization” and protected types (2020-03-11)' -The @code{Stream_Size} attribute returns the default number of bits in the -stream representation of the given type. -This value is not affected by the presence -of stream subprogram attributes for the type. GNAT has always implemented -this interpretation. +This AI clarifies that components of a protected type require late initialization when their initialization references (implicitly) the current instance of the type. -RM References: 13.13.02 (1.2/2) +RM references: 3.03.01 (8.1/2) @end itemize -@geindex AI-0195 (Ada 2012 feature) +@geindex AI12-0194 (Ada 2022 feature) @itemize * @item -`AI-0195 Invalid value handling is implementation defined (2010-07-03)' +`AI12-0194 Language-defined aspects and entry bodies (0000-00-00)' -The handling of invalid values is now designated to be implementation -defined. This is a documentation change only, requiring Annex M in the GNAT -Reference Manual to document this handling. -In GNAT, checks for invalid values are made -only when necessary to avoid erroneous behavior. Operations like assignments -which cannot cause erroneous behavior ignore the possibility of invalid -values and do not do a check. The date given above applies only to the -documentation change, this behavior has always been implemented by GNAT. +The AI Includes entry bodies on the list of bodies for which no language-defined aspects can be specified (although specifying an implementation-defined aspect may be allowed). -RM References: 13.09.01 (10) +A wording change, no implementation impact. + +RM references: 13.01.01 (17/3) @end itemize -@geindex AI-0196 (Ada 2012 feature) +@geindex AI12-0195 (Ada 2022 feature) @itemize * @item -`AI-0196 Null exclusion tests for out parameters (0000-00-00)' +`AI12-0195 Inheriting body but overriding precondition or postcondition (2021-08-11)' -Null exclusion checks are not made for @code{out} parameters when -evaluating the actual parameters. GNAT has never generated these checks. +Ada 2022 specifies that if a primitive with a class-wide precondition or +postcondition is inherited, and some primitive function called in the class-wide precondition or postcondition is overridden, then a dispatching call to the first primitive with a controlling operand that has the tag of the overriding type is required to check both the interpretation using the overriding function and the interpretation using the original overridden function. -RM References: 6.04.01 (13) +RM references: 6.01.01 (38/4) @end itemize -@geindex AI-0198 (Ada 2012 feature) +@geindex AI12-0196 (Ada 2022 feature) @itemize * @item -`AI-0198 Inheriting abstract operators (0000-00-00)' +`AI12-0196 Concurrent access to Ada container libraries (0000-00-00)' -This AI resolves a conflict between two rules involving inherited abstract -operations and predefined operators. If a derived numeric type inherits -an abstract operator, it overrides the predefined one. This interpretation -was always the one implemented in GNAT. +Clarify that parallel execution of operations which use cursors to refer to different elements of the same container does not violate the rules about erroneous concurrent access in some cases. That is, if C1 and C2 are cursors that refer to different elements of some container, then it is ok to concurrently execute an operation that is passed C1 and which accesses one element of the container, with another operation (perhaps the same operation, perhaps not) that is passed C2 and which accesses another element of the container. -RM References: 3.09.03 (4/3) +RM references: A.18 (2/2) A.18.02 (125/2) A.18.02 (133/3) A.18.02 (135/3) +A.18.03 (81/3) A.18.04 (36/3) A.18.07 (34/2) A.18.10 (116/3) @end itemize -@geindex AI-0199 (Ada 2012 feature) +@geindex AI12-0198 (Ada 2022 feature) @itemize * @item -`AI-0199 Aggregate with anonymous access components (2010-07-14)' +`AI12-0198 Potentially unevaluated components of array aggregates (2020-05-13)' -A choice list in a record aggregate can include several components of -(distinct) anonymous access types as long as they have matching designated -subtypes. +Ada 2022 enforces the detection of components that belong to a nonstatic or +null range of index values of an array aggregate. -RM References: 4.03.01 (16) +RM references: 6.01.01 (22.1/4) @end itemize -@geindex AI-0200 (Ada 2012 feature) +@geindex AI12-0199 (Ada 2022 feature) @itemize * @item -`AI-0200 Mismatches in formal package declarations (0000-00-00)' +`AI12-0199 Abstract subprogram calls in class-wide invariant expressions (0000-00-00)' -This AI plugs a gap in the RM which appeared to allow some obviously intended -illegal instantiations. GNAT has never allowed these instantiations. +Class-wide type invariants do not apply to abstract types, to avoid various +problems. Define the notion of a “corresponding expression” for a class-wide +type invariant, replacing references to components as appropriate, taking into +account rules for corresponding and specified discriminants when applying them +to a nonabstract descendant. -RM References: 12.07 (16) +RM references: 7.03.02 (5/4) 7.03.02 (8/3) @end itemize -@geindex AI-0201 (Ada 2012 feature) +@geindex AI12-0201 (Ada 2022 feature) @itemize * @item -`AI-0201 Independence of atomic object components (2010-07-22)' +`AI12-0201 Missing operations of static string types (2020-02-25)' -If an Atomic object has a pragma @code{Pack} or a @code{Component_Size} -attribute, then individual components may not be addressable by independent -tasks. However, if the representation clause has no effect (is confirming), -then independence is not compromised. Furthermore, in GNAT, specification of -other appropriately addressable component sizes (e.g. 16 for 8-bit -characters) also preserves independence. GNAT now gives very clear warnings -both for the declaration of such a type, and for any assignment to its components. +Relational operators and type conversions of static string types are now static in Ada 2022. -RM References: 9.10 (1/3) C.06 (22/2) C.06 (23/2) +RM references: 4.09 (9) 4.09 (19) 4.09 (20) 4.09 (24) @end itemize -@geindex AI-0203 (Ada 2012 feature) +@geindex AI12-0203 (Ada 2022 feature) @itemize * @item -`AI-0203 Extended return cannot be abstract (0000-00-00)' +`AI12-0203 Overriding a nonoverridable aspect (0000-00-00)' -A return_subtype_indication cannot denote an abstract subtype. GNAT has never -permitted such usage. +A corner case wording clarification that has no impact on compilers. -RM References: 3.09.03 (8/3) +RM references: 4.01.05 (5.1/4) 4.01.05 (7/3) @end itemize -@geindex AI-0205 (Ada 2012 feature) +@geindex AI12-0204 (Ada 2022 feature) @itemize * @item -`AI-0205 Extended return declares visible name (0000-00-00)' +`AI12-0204 Renaming of a prefixed view (2020-02-24)' -This AI corrects a simple omission in the RM. Return objects have always -been visible within an extended return statement. +AI12-0204 clarifies that the prefix of a prefixed view that is renamed or +passed as a formal subprogram must be renameable as an object. -RM References: 8.03 (17) +RM references: 8.05.04 (5.2/2) 12.06 (8.3/2) 4.01.03 (13.1/2) 4.01.06 (9/5) @end itemize -@geindex AI-0206 (Ada 2012 feature) +@geindex AI12-0205 (Ada 2022 feature) @itemize * @item -`AI-0206 Remote types packages and preelaborate (2010-07-24)' +`AI12-0205 Defaults for generic formal types (2021-04-01)' -Remote types packages are now allowed to depend on preelaborated packages. -This was formerly considered illegal. +AI12-0205 specifies syntax and semantics that provide defaults for formal types of generic units. The legality rules guarantee that the default subtype_mark that is specified for a formal type would be a legal actual in any instantiation of the generic unit. -RM References: E.02.02 (6) +RM references: 12.03 (7/3) 12.03 (10) 12.05 (2.1/3) 12.05 (2.2/3) 12.05 (7/2) @end itemize -@geindex AI-0207 (Ada 2012 feature) +@geindex AI12-0206 (Ada 2022 feature) @itemize * @item -`AI-0207 Mode conformance and access constant (0000-00-00)' +`AI12-0206 Nonoverridable should allow arbitrary kinds of aspects (0000-00-00)' -This AI confirms that access_to_constant indication must match for mode -conformance. This was implemented in GNAT when the qualifier was originally -introduced in Ada 2005. +A non-overridable aspect can have a value other than a name; for example, @code{Max_Entry_Queue_Length} is non-overridable and it has a scalar value. +Part of adding support for @code{Max_Entry_Queue_Length} (which is already supported by GNAT). -RM References: 6.03.01 (16/2) +RM references: 13.01.01 (18.2/4) 13.01.01 (18.3/4) 13.01.01 (18.6/4) @end itemize -@geindex AI-0208 (Ada 2012 feature) +@geindex AI12-0207 (Ada 2022 feature) @itemize * @item -`AI-0208 Characteristics of incomplete views (0000-00-00)' +`AI12-0207 Convention of anonymous access types (2020-02-01)' -The wording in the Ada 2005 RM concerning characteristics of incomplete views -was incorrect and implied that some programs intended to be legal were now -illegal. GNAT had never considered such programs illegal, so it has always -implemented the intent of this AI. +The convention of anonymous access elements of arrays now have the same convention as the array instead of convention Ada. -RM References: 3.10.01 (2.4/2) 3.10.01 (2.6/2) +RM references: 6.03.01 (13.1/3) B.01 (19) B.01 (21/3) @end itemize -@geindex AI-0210 (Ada 2012 feature) +@geindex AI12-0208 (Ada 2022 feature) @itemize * @item -`AI-0210 Correct Timing_Events metric (0000-00-00)' +`AI12-0208 Predefined Big numbers support (0000-00-00)' -This is a documentation only issue regarding wording of metric requirements, -that does not affect the implementation of the compiler. +Add predefined package @code{Ada.Numerics.Big_Numbers}. -RM References: D.15 (24/2) +RM references: A.05.05 (0) A.05.06 (0) A.05.07 (0) @end itemize -@geindex AI-0211 (Ada 2012 feature) +@geindex AI12-0211 (Ada 2022 feature) @itemize * @item -`AI-0211 No_Relative_Delays forbids Set_Handler use (2010-07-09)' +`AI12-0211 Interface types and inherited nonoverridable aspects (2020-08-24)' -The restriction @code{No_Relative_Delays} forbids any calls to the subprogram -@code{Ada.Real_Time.Timing_Events.Set_Handler}. +AI12-0211 introduces two new legality rules for Ada 2022. The first says that +if a nonoverridable aspect is explicitly specified for a type that also inherits that aspect from another type (an ancestor or a progenitor), then the explicit aspect specification shall be confirming. The second says that if a type inherits a nonoverridable aspect from two different sources (this can only occur if at least one of the two is an interface type), then the two sources shall agree with respect to the given aspect. This AI is a binding interpretation, so these checks are performed even for earlier Ada versions. Because of compatibility concerns, an escape mechanism for suppressing these legality checks is provided: these new checks always pass if the @code{-gnatd.M} switch (relaxed RM semantics) is specified. -RM References: D.07 (5) D.07 (10/2) D.07 (10.4/2) D.07 (10.7/2) +RM references: 13.01.01 (18.3/5) 13.01.01 (18.4/4) @end itemize -@geindex AI-0214 (Ada 2012 feature) +@geindex AI12-0212 (Ada 2022 feature) @itemize * @item -`AI-0214 Defaulted discriminants for limited tagged (2010-10-01)' +`AI12-0212 Container aggregates; generalized array aggregates (0000-00-00)' -Ada 2012 relaxes the restriction that forbids discriminants of tagged types -to have default expressions by allowing them when the type is limited. It -is often useful to define a default value for a discriminant even though -it can’t be changed by assignment. +The AI defines a new feature: generalized array aggregates that already exists in GNAT. -RM References: 3.07 (9.1/2) 3.07.02 (3) +RM references: 4.03.05 (0) 1.01.04 (12) 1.01.04 (13) 2.01 (15) 2.02 (9/5) +3.07.01 (3) 3.08.01 (4) 4.03 (2/5) 4.03 (3/5) 4.03.01 (5) 4.03.03 +(3/2) 4.03.03 (4/5) 4.03.03 (5.1/5) 4.03.03 (9) 4.03.03 (17/5) +4.03.03 (21) 4.03.03 (23.2/5) 4.03.03 (26) 4.03.03 (27) 4.03.03 +(31) 4.03.04 (4/5) 4.04 (3.1/3) 11.02 (3) 13.01.01 (5/3) +13.01.01 (7/3) A.18.02 (8/3) A.18.02 (14/2) A.18.02 (47/2) A.18.02 +(175/2) A.18.03 (6/3) A.18.05 (3/3) A.18.06 (4/3) A.18.08 (3/3) +A.18.09 (4/3) @end itemize -@geindex AI-0216 (Ada 2012 feature) +@geindex AI12-0216 (Ada 2022 feature) @itemize * @item -`AI-0216 No_Task_Hierarchy forbids local tasks (0000-00-00)' +`AI12-0216 6.4.1(6.16-17/3) should never apply to composite objects (0000-00-00)' + +Fix wording so that parameter passing cases where there isn’t really any aliasing problems or evaluation order dependency are classified as acceptable. -It is clearly the intention that @code{No_Task_Hierarchy} is intended to -forbid tasks declared locally within subprograms, or functions returning task -objects, and that is the implementation that GNAT has always provided. -However the language in the RM was not sufficiently clear on this point. -Thus this is a documentation change in the RM only. +No compiler impact. -RM References: D.07 (3/3) +RM references: 6.04.01 (6.17/3) @end itemize -@geindex AI-0219 (Ada 2012 feature) +@geindex AI12-0217 (Ada 2022 feature) @itemize * @item -`AI-0219 Pure permissions and limited parameters (2010-05-25)' +`AI12-0217 Rules regarding restrictions on the use of the Old attribute are too strict (2020-03-25)' -This AI refines the rules for the cases with limited parameters which do not -allow the implementations to omit ‘redundant’. GNAT now properly conforms -to the requirements of this binding interpretation. +AI12-0217 loosens the rules regarding what is allowed as the prefix of a ‘Old +attribute reference. In particular, a prefix is now only required to “statically name” (as opposed to the previous “statically denote”) an object. This means that components of composite objects that previously would have been illegal are now legal prefixes. -RM References: 10.02.01 (18/2) +RM references: 6.01.01 (24/3) 6.01.01 (27/3) @end itemize -@geindex AI-0220 (Ada 2012 feature) +@geindex AI12-0220 (Ada 2022 feature) @itemize * @item -`AI-0220 Needed components for aggregates (0000-00-00)' +`AI12-0220 Pre/Post for access-to-subprogram types (2020-04-14)' -This AI addresses a wording problem in the RM that appears to permit some -complex cases of aggregates with nonstatic discriminants. GNAT has always -implemented the intended semantics. +Contract aspects can now be specified for access-to-subprogram types, as +defined for Ada 2022 in this AI. -RM References: 4.03.01 (17) +RM references: 6.01.01 (1/4) 6.01.01 (2/3) 6.01.01 (4/3) 6.01.01 (19/3) +6.01.01 (28/3) 6.01.01 (29/3) 6.01.01 (39/3) 13.01.01 (12/5) @end itemize -@node GNAT language extensions,Security Hardening Features,Implementation of Ada 2012 Features,Top -@anchor{gnat_rm/gnat_language_extensions doc}@anchor{442}@anchor{gnat_rm/gnat_language_extensions gnat-language-extensions}@anchor{443}@anchor{gnat_rm/gnat_language_extensions id1}@anchor{444} -@chapter GNAT language extensions +@geindex AI12-0222 (Ada 2022 feature) -The GNAT compiler implements a certain number of language extensions on top of -the latest Ada standard, implementing its own extended superset of Ada. +@itemize * + +@item +`AI12-0222 Representation aspects and private types (0000-00-00)' + +Clarify that the rule against specifying a representation aspect for a type before the type is completely defined also applies in the case where aspect_specification syntax is used (not just in the case where a pragma or some other kind of representation item is used). + +GNAT already implements this. + +RM references: 13.01 (9/5) 13.01 (9.1/4) 13.01 (9.2/5) +@end itemize + +@geindex AI12-0225 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0225 Prefix of Obj’Image (0000-00-00)' + +Clarify some Object vs. Value corner cases to allow names that do not denote objects in more contexts, such as a qualified expression as a prefix of an Image attribute. + +RM references: 3.05 (55.1/4) +@end itemize + +@geindex AI12-0226 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0226 Make objects more consistent (0000-00-00)' + +Allow value conversions as objects. For instance this example becomes legal: @code{Long_Integer (Duration'Last)'Image}. + +RM references: 3.03 (11.1/3) 3.03 (21.1/3) 3.03 (23.8/5) 4.06 (58.1/4) +4.06 (58.3/4) +@end itemize + +@geindex AI12-0227 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0227 Evaluation of nonstatic universal expressions when no operators are involved (0000-00-00)' + +Nonstatic universal integer expressions are always evaluated at runtime as values of type root_integer; similarly, nonstatic universal real expressions are always evaluated at runtime as values of type root_real. +This AI corrects a wording oversight. Previously, the above was only true if a call to operator was involved. With this change it is true in all cases. + +No compiler impact. + +RM references: 4.04 (10) 8.06 (29) +@end itemize + +@geindex AI12-0228 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0228 Properties of qualified expressions used as names (2020-02-19)' + +This AI clarifies that properties of a qualified object pass through a +qualified expression used as a name. Specifically, “aliased” and “known to be +constrained” are not changed by a qualified expression. + +RM references: 3.03 (23.7/3) 3.10 (9/3) +@end itemize + +@geindex AI12-0231 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0231 Null_Task_Id and Activation_Is_Complete (0000-00-00)' + +Add @code{Activation_Is_Complete} to the list of functions that raise P_E if passed @code{Null_Task_Id}, correcting an oversight. + +RM references: C.07.01 (15) +@end itemize + +@geindex AI12-0232 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0232 Rules for pure generic bodies (0000-00-00)' + +Clarify the rules for a generic body nested in a pure library unit. + +RM references: 10.02.01 (9/3) 10.02.01 (15.1/3) 10.02.01 (15.5/3) +@end itemize + +@geindex AI12-0233 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0233 Pre’Class for hidden operations of private types (0000-00-00)' + +Clarify how @code{Pre'Class} checking interacts with private-part overriding of inherited subprograms. A class-wide precondition can be checked at runtime even if it is specified in a private part that the caller cannot see into. + +RM references: 6.01.01 (38/4) +@end itemize + +@geindex AI12-0234 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0234 Compare-and-swap for atomic objects (0000-00-00)' + +New predefined units for atomic operations (@code{System.Atomic_Operations} and child units thereof). + +RM references: C.06.01 (0) C.06.02 (0) +@end itemize + +@geindex AI12-0235 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0235 System.Storage_Pools should be pure (0000-00-00)' + +Change the predefined package System.Storage_Pools from preelaborated to pure. + +RM references: 13.11 (5) +@end itemize + +@geindex AI12-0236 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0236 declare expressions (2020-04-08)' + +A @code{declare expression} allows constant objects and renamings to be +declared within an expression. + +RM references: 2.08 (6) 3.09.02 (3) 3.10.02 (9.1/3) 3.10.02 (16.1/3) +3.10.02 (32.2/3) 4.03.02 (5.4/3) 4.03.03 (15.1/3) 4.04 (7/3) +4.05.09 (0) 6.02 (10/4) 7.05 (2.1/5) 8.01 (2.1/4) +@end itemize + +@geindex AI12-0237 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0237 Getting the representation of an enumeration value (2020-01-31)' + +The GNAT-specific attributes @code{Enum_Rep} and @code{Enum_Val} have been standardized and are now also supported as Ada 2022 attributes. + +RM references: 13.04 (10) 13.04 (11/3) +@end itemize + +@geindex AI12-0242 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0242 Shorthand Reduction Expressions for Objects (0000-00-00)' + +Allow reduction expressions to iterate over an an array or an iterable object without having to explicitly create a value sequence. + +This allows, for instance, writing @code{A'Reduce("+", 0)} instead of the equivalent (but more verbose) @code{[for Value of A => Value]'Reduce("+", 0);}. + +RM references: 4.05.10 (0) 4.01.04 (6) +@end itemize + +@geindex AI12-0247 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0247 Potentially Blocking goes too far for Detect_Blocking (0000-00-00)' + +During a protected action, a call on a subprogram that contains a potentially blocking operation is considered a bounded error (so raising P_E is optional). +This rule imposed an unreasonable implementation burden. +The new rule introduced by this AI allows ignoring (i.e., not detecting) the problem until execution of a potentially blocking operation is actually attempted. + +RM references: 9.05 (55/5) 9.05 (56/5) 9.05.01 (18/5) H.05 (5/2) +@end itemize + +@geindex AI12-0249 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0249 User-defined numeric literals (2020-04-07)' + +Compiler support is added for three new aspects (@code{Integer_Literal}, @code{Real_Literal}, and @code{String_Literal}) as described in AI12-0249 (for @code{Integer_Literal} and @code{Real_Literal}), AI12-0295 (for @code{String_Literal}), and in two follow-up AIs (AI12-0325 and AI12-0342). For pre-Ada 2022 versions of Ada, these are treated as implementation-defined +aspects. Some implementation work remains, particularly in the interactions between these aspects and tagged types. + +RM references: 4.02 (9) 4.02.01 (0) 4.09 (3) +@end itemize + +@geindex AI12-0250 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0250 Iterator Filters (2020-05-19)' + +This AI defines Ada 2022 feature of iterator filters, which can be +applied to loop parameter specifications and iterator specifications. + +RM references: 4.03.03 (21) 4.03.03 (26) 4.03.03 (31) 4.03.05 (0) 4.05.10 +(0) 5.05 (4) 5.05 (7) 5.05 (9/4) 5.05 (9.1/4) 5.05 (10) +5.05.02 (2/3) 5.05.02 (10/3) 5.05.02 (11/3) +@end itemize + +@geindex AI12-0252 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0252 Duplicate interrupt handlers under Ravenscar (2018-07-05)' + +Ada Issue AI12-0252 requires that the runtime shall terminate with a +Program_Error when more than one interrupt handler is attached to the same interrupt and the restriction No_Dynamic_Attachment is in effect. + +RM references: C.03.01 (13) +@end itemize + +@geindex AI12-0256 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0256 Aspect No_Controlled_Parts (2021-01-26)' + +The compiler now supports the Ada 2022 aspect No_Controlled_Parts (see +AI12-0256). When specified for a type, this aspect requires that the type and any of its ancestors must not have any controlled parts. + +RM references: H.04.01 (0) 13.01.01 (18.7/5) +@end itemize + +@geindex AI12-0258 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0258 Containers and controlled element types (0000-00-00)' + +Most predefined containers are allowed to defer finalization of container elements until the finalization of the container. This allows implementation flexibility but causes problems in some cases. AI12-0258 tightens up the rules for the indefinite containers to say that finalization happens earlier - if a client needs the tighter finalization guarantees, then it can use the indefinite containers (even if the element subtype in question is definite). Other solutions involving the holder generic are also possible. + +GNAT implements these tighter element finalization requirements for instances of the indefinite container generics. + +RM references: A.18 (10/4) +@end itemize + +@geindex AI12-0259 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0259 Lower bound of strings returned from Ada.Command_Line (0000-00-00)' + +Specify that the low-bound of a couple of predefined String-valued functions will always be one. + +RM references: A.15 (14) A.15 (16/3) +@end itemize + +@geindex AI12-0260 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0260 Functions Is_Basic and To_Basic in Wide_Characters.Handling (2020-04-01)' + +AI12-0260 is implemented for Ada 2022, providing the new functions @code{Is_Basic} and @code{To_Basic} in package @code{Ada.Wide_Characters.Handling}. + +RM references: 1.02 (8/3) A.03.05 (8/3) A.03.05 (20/3) A.03.05 (21/3) +A.03.05 (33/3) A.03.05 (61/3) +@end itemize + +@geindex AI12-0261 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0261 Conflict in “private with” rules (0000-00-00)' + +If a library unit is only visible at some point because of a “private with”, there are legality rules about a name denoting that entity. The AI cleans up the wording so that it captures the intent in a corner case involving a private-child library-unit subprogram. The previous wording incorrectly caused this case to be illegal. + +RM references: 10.01.02 (12/3) 10.01.02 (13/2) 10.01.02 (14/2) 10.01.02 +(15/2) 10.01.02 (16/2) +@end itemize + +@geindex AI12-0262 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0262 Map-Reduce attribute (0000-00-00)' + +The AI defines Reduction Expressions to allow the programmer to apply the +Map-Reduce paradigm to map/transform a set of values to a new set of values, +and then summarize/reduce the transformed values into a single result value. + +RM references: 4.01.04 (1) 4.01.04 (6) 4.01.04 (11) 4.05.10 (0) +@end itemize + +@geindex AI12-0263 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0263 Update references to ISO/IEC 10646 (0000-00-00)' + +Change RM references to ISO/IEC 10646:2011 to instead refer to ISO/IEC 10646:2017. No compiler impact. + +RM references: 1.01.04 (14.2/3) 2.01 (1/3) 2.01 (3.1/3) 2.01 (4/3) 2.01 +(4.1/5) 2.01 (5/3) 2.01 (15/3) 2.01 (4.1/5) 2.01 (5/3) 2.03 +(4.1/5) 2.03 (5/3) 3.05.02 (2/3) 3.05.02 (3/3) 3.05.02 (4/3) A.01 +(36.1/3) A.01 (36.2/3) A.03.02 (32.6/5) A.03.05 (51.2/5) A.03.05 +(55/3) A.03.05 (59/3) A.04.10 (3/3) B.05 (21/5) +@end itemize + +@geindex AI12-0264 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0264 Overshifting and overrotating (0000-00-00)' + +Clarify Shift and Rotate op behavior with large shift/rotate amounts. + +RM references: B.02 (9) +@end itemize + +@geindex AI12-0265 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0265 Default_Initial_Condition for types (2020-11-13)' + +The aspect @code{Default_Initial_Condition}, originally proposed by SPARK and +supported in GNAT, is now also included in Ada 2022. One change from the +original implementation is that when the aspect is specified on ancestor types of a derived type, the ancestors’ check expressions also apply to the derived type. +@code{Default_Initial_Condition} checks are also now applied in cases of default +initialization of components, allocators, ancestor parts of extension aggregates, and box associations of aggregates. + +RM references: 7.03.03 (0) 1.01.03 (17.1/5) 11.04.02 (23.2/5) 11.04.02 (23.3/5) +@end itemize + +@geindex AI12-0269 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0269 Aspect No_Return for functions reprise (2020-03-19)' + +This amendment has been implemented under the @code{-gnat2022} switch, and the +compiler now accepts the aspect/pragma No_Return for functions and generic +functions. + +RM references: 6.05.01 (0) 6.05.01 (1/3) 6.05.01 (3.1/3) 6.05.01 (3.4/3) +6.05.01 (5/2) 6.05.01 (6/2) 6.05.01 (7/2) J.15.02 (2/3) J.15.02 +(3/3) J.15.02 (4/3) +@end itemize + +@geindex AI12-0272 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0272 (part 1) Pre/Postconditions for formal subprograms (0000-00-00)' + +Pre and Post aspects can be specified for a generic formal subprogram. @code{Default_Initial_Condition} can be specified for a generic formal private type. + +GNAT implements this with an exception of the part related to @code{Default_Initial_Condition}. + +RM references: 6.01.01 (1/5) 6.01.01 (39/5) 7.03.03 (1/5) 7.03.03 (2/5) +7.03.03 (8/5) 7.03.04 (5/5) F.01 (1) +@end itemize + +@geindex AI12-0275 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0275 Make subtype_mark optional in object renames (2020-01-28)' + +AI12-0275 allows object renamings to be declared without an explicit +subtype_mark or access_definition. This feature can be used by compiling +with the switch @code{-gnat2022}. + +RM references: 8.05.01 (2/3) 8.05.01 (3/2) +@end itemize + +@geindex AI12-0277 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0277 The meaning of “accessibility level of the body of F” (0000-00-00)' + +Clarify that the only time that an explicitly aliased formal parameter has different accessibility properties than an aliased part of a “normal” parameter is for the accessibility checking associated with a return statement. + +RM references: 3.10.02 (19.2/4) +@end itemize + +@geindex AI12-0278 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0278 Implicit conversions of anonymous return types (0000-00-00)' + +If a call to a function with an anonymous-access-type result is converted to a named access type, it doesn’t matter whether the conversion is implicit or explicit. the AI fixes hole where the previous rules didn’t cover the implicit conversion case. + +RM references: 3.10.02 (10.3/3) +@end itemize + +@geindex AI12-0279 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0279 Nonpreemptive dispatching needs more dispatching points (2020-04-17)' + +Ada 2022 defines a new aspect @cite{Yield} that can be specified in the declaration of a noninstance subprogram (including a generic formal subprogram), a generic subprogram, or an entry, to ensure that the associated subprogram has at least one task dispatching point during each invocation. + +RM references: D.02.01 (1.5/2) D.02.01 (7/5) +@end itemize + +@geindex AI12-0280-2 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0280-2 Making ‘Old more flexible (2020-07-24)' + +For Ada 2022, AI12-0280-2 relaxes Ada’s restrictions on ‘Old attribute +references whose attribute prefix does not statically name an entity. Previously, it was required that such an attribute reference must be unconditionally evaluated when the postcondition is evaluated; with the new rule, conditional evaluation is permitted if the relevant conditions can be evaluated upon entry to the subprogram with the same results as evaluation at the time of the postcondition’s evaluation. In this case, the ‘Old attribute prefix is evaluated conditionally (more specifically, the prefix is evaluated only if the result of that evaluation is going to be referenced later when the +postcondition is evaluated). + +RM references: 6.01.01 (20/3) 6.01.01 (21/3) 6.01.01 (22/3) 6.01.01 +(22.1/4) 6.01.01 (22.2/5) 6.01.01 (23/3) 6.01.01 (24/3) 6.01.01 +(26/4) 6.01.01 (27/5) 6.01.01 (39/5) +@end itemize + +@geindex AI12-0282 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0282 Atomic, Volatile, and Independent generic formal types (0000-00-00)' + +The AI specifies that the aspects @code{Atomic}, @code{Volatile}, @code{Independent}, @code{Atomic_Components}, @code{Volatile_Components}, and @code{Independent_Components} are specifiable for generic formal types. The actual type must have a matching specification. + +RM references: C.06 (6.1/3) C.06 (6.3/3) C.06 (6.5/3) C.06 (6.8/3) C.06 +(12/3) C.06 (12.1/3) C.06 (21/4) +@end itemize + +@geindex AI12-0285 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0285 Syntax for Stable_Properties aspects (0000-00-00)' + +The AI establishes the required named notation for a Stable_Properties aspect specification in order to avoid syntactic ambiguities. + +With the old syntax, an example like + +@example +type Ugh is ... + with Stable_Properties =\> Foo, Bar, Nonblocking, Pack; +@end example + +was problematic; @code{Nonblocking} and @code{Pack} are other aspects, while @code{Foo} and @code{Bar} are @code{Stable_Properties} functions. With the clarified syntax, the example above shall be written as: + +@example +type Ugh is ... + with Stable_Properties => (Foo, Bar), Nonblocking, Pack; +@end example + +RM references: 7.03.04 (2/5) 7.03.04 (3/5) 7.03.04 (4/5) 7.03.04 (6/5) +7.03.04 (7/5) 7.03.04 (9/5) 7.03.04 (10/5) 7.03.04 (14/5) 13.01.01 (4/5) +@end itemize + +@geindex AI12-0287 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0287 Legality Rules for null exclusions in renaming are too fierce (2020-02-17)' + +The null exclusion legality rules for generic formal object matching and object renaming now only apply to generic formal objects with mode in out. + +RM references: 8.05.01 (4.4/2) 8.05.01 (4.5/2) 8.05.01 (4.6/2) 8.05.04 +(4.2/2) 12.04 (8.3/2) 12.04 (8.4/2) 12.04 (8.5/2) 12.04 (8.2/5) +12.06 (8.2/5) +@end itemize + +@geindex AI12-0289 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0289 Implicitly null excluding anonymous access types and conformance (2020-06-09)' + +AI12-0289 is implemented for Ada 2022, allowing safer use of access parameters +when the partial view of the designated type is untagged, but the full view is +tagged. + +RM references: 3.10 (26) +@end itemize + +@geindex AI12-0290 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0290 Restriction Pure_Barriers (2020-02-18)' + +The GNAT implementation of the Pure_Barriers restriction has +been updated to match the Ada RM’s definition as specified +in this AI. Some constructs that were accepted by the previous +implementation are now rejected, and vice versa. In +particular, the use of a component of a component of a +protected record in a barrier expression, as in “when +Some_Component.Another_Component =>”, formerly was (at least +in some cases) not considered to be a violation of the +Pure_Barriers restriction; that is no longer the case. + +RM references: D.07 (2) D.07 (10.10/4) +@end itemize + +@geindex AI12-0291 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0291 Jorvik Profile (2020-02-19)' + +The Jorvik profile is now implemented, as defined in this AI. +For Ada 2012 and earlier versions of Ada, Jorvik is an implementation-defined +profile whose definition matches its Ada 2022 definition. + +RM references: D.13 (0) D.13 (1/3) D.13 (4/3) D.13 (6/4) D.13 (9/3) D.13 +(10/3) D.13 (11/4) D.13 (12/4) +@end itemize + +@geindex AI12-0293 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0293 Add predefined FIFO_Streams packages (0000-00-00)' + +The AI adds @code{Ada.Streams.Storage} and its two subunits @code{Bounded} and @code{Unbounded}. + +RM references: 13.13.01 (1) 13.13.01 (9) 13.13.01 (9.1/1) +@end itemize + +@geindex AI12-0295 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0295 User-defined string (2020-04-07)' + +Compiler support is added for three new aspects (@code{Integer_Literal}, @code{Real_Literal}, and @code{String_Literal}) as described in AI12-0249 (for @code{Integer_Literal} and @code{Real_Literal}), AI12-0295 (for @code{String_Literal}), and in two follow-up AIs (AI12-0325 and AI12-0342). For pre-Ada 2022 versions of Ada, these are treated as implementation-defined aspects. Some implementation work remains, particularly in the interactions between these aspects and tagged types. + +RM references: 4.02 (6) 4.02 (10) 4.02 (11) 3.06.03 (1) 4.02.01 (0) 4.09 (26/3) +@end itemize + +@geindex AI12-0301 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0301 Predicates should be checked like constraints for types with Default_Value (2020-02-25)' + +This AI clarifies that predicate checks apply for objects that are initialized +by default and that are of a type that has any components whose subtypes specify @code{Default_Value} or @code{Default_Component_Value}. + +RM references: 3.02.04 (31/4) +@end itemize + +@geindex AI12-0304 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0304 Image attributes of language-defined types (2020-07-07)' + +According to this AI, @code{Put_Image} (and therefore @code{'Image}) is provided for +the containers and for unbounded strings. + +RM references: 4.10 (0) +@end itemize + +@geindex AI12-0306 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0306 Split null array aggregates from positional array aggregates (0000-00-00)' + +The AI clarifies the wording of the references RM paragraphs without introducing any language changes. + +RM references: 4.03.03 (2) 4.03.03 (3/2) 4.03.03 (9/5) 4.03.03 (26/5) +4.03.03 (26.1/5) 4.03.03 (33/3) 4.03.03 (38) 4.03.03 (39) 4.03.03 (42) +@end itemize + +@geindex AI12-0307 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0307 Resolution of aggregates (2020-08-13)' + +The proposed new syntax for aggregates in Ada 2022 uses square brackets as +delimiters, and in particular allows @code{[]} as a notation for empty array and container aggregates. This syntax is currently available as an experimental feature under the @code{-gnatX} flag. + +RM references: 4.03 (3/5) +@end itemize + +@geindex AI12-0309 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0309 Missing checks for pragma Suppress (0000-00-00)' + +The AI includes some previously overlooked run-time checks in the list of checks that are potentially suppressed via a pragma @code{Suppress}. For example, AI12-0251-1 adds a check that the number of chunks in a chunk_specification is not zero or negative. Clarify that suppressing @code{Program_Error_Check} suppresses that check too. + +RM references: 11.05 (10) 11.05 (19) 11.05 (20) 11.05 (22) 11.05 (24) +@end itemize + +@geindex AI12-0311 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0311 Suppressing client-side assertions for language-defined units (0000-00-00)' + +The AI defines some new assertion policies that can be given as arguments in a Suppress pragma (e.g., Calendar_Assertion_Check). GNAT recognizes and ignores those new policies, the checks are not implemented. + +RM references: 11.04.02 (23.5/5) 11.05 (23) 11.05 (26) +@end itemize + +@geindex AI12-0315 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0315 Image Attributes subclause improvements (0000-00-00)' + +Clarify that a named number or similar can be the prefix of an Image attribute reference. + +RM references: 4.10 (0) +@end itemize + +@geindex AI12-0318 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0318 No_IO should apply to Ada.Directories (2020-01-31)' + +The restriction No_IO now applies to and prevents the use of the +@code{Ada.Directories package}. + +RM references: H.04 (20/2) H.04 (24/3) +@end itemize + +@geindex AI12-0321 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0321 Support for Arithmetic Atomic Operations and Test and Set (0000-00-00)' + +The AI adds some predefined atomic operations, e.g. package System.`@w{`}Atomic_Operations.Test_And_Set`@w{`}. + +RM references: C.06.03 (0) C.06.04 (0) +@end itemize + +@geindex AI12-0325 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0325 Various issues with user-defined literals (2020-04-07)' + +Compiler support is added for three new aspects (@code{Integer_Literal}, @code{Real_Literal}, and @code{String_Literal}) as described in AI12-0249 (for @code{Integer_Literal} and @code{Real_Literal}), AI12-0295 (for @code{String_Literal}), and in two follow-up AIs (AI12-0325 and AI12-0342). For pre-Ada 2022 versions of Ada, these are treated as implementation-defined aspects. Some implementation work remains, particularly in the interactions between these aspects and tagged types. + +RM references: 4.02 (6) 4.02 (10) 4.02 (11) 4.02.01 (0) +@end itemize + +@geindex AI12-0329 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0329 Naming of FIFO_Streams packages (0000-00-00)' + +The AI changes the name of predefined package @code{Ada.Streams.FIFO_Streams} to @code{Ada.Streams.Storage}. + +RM references: 13.13.01 (9/5) 13.13.01 (9.1/5) +@end itemize + +@geindex AI12-0331 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0331 Order of finalization of a subpool (0000-00-00)' + +Clarify that when a subpool is being finalized, objects allocated from that subpool are finalized before (not after) they cease to exist (i.e. object’s storage has been reclaimed). + +RM references: 13.11.05 (5/3) 13.11.05 (6/3) 13.11.05 (7/3) 13.11.05 +(7.1/4) 13.11.05 (8/3) 13.11.05 (9/3) +@end itemize + +@geindex AI12-0333 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0333 Predicate checks on out parameters (0000-00-00)' + +If a view conversion is passed as an actual parameter corresponding to an out-mode formal parameter, and if the subtype of the formal parameter has a predicate, then no predicate check associated with the conversion is performed. + +RM references: 3.02.04 (31/5) 4.06 (51/4) 6.04.01 (14) +@end itemize + +@geindex AI12-0335 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0335 Dynamic accessibility check needed for some requeue targets (0000-00-00)' + +Define a new runtime accessibility check for a corner case involving requeue statements. + +RM references: 9.05.04 (7/4) +@end itemize + +@geindex AI12-0336 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0336 Meaning of Time_Offset (0000-00-00)' + +The AI introduces changes to the predefined package @code{Ada.Calendar.Time_Zones}. + +RM references: 9.06.01 (6/2) 9.06.01 (35/2) 9.06.01 (40/2) 9.06.01 (41/2) +9.06.01 (42/3) 9.06.01 (90/2) 9.06.01 (91/2) +@end itemize + +@geindex AI12-0337 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0337 Simple_Name(“/”) in Ada.Directories (0000-00-00)' + +Clarify behavior of subprograms in the predefined package @code{Ada.Directories}. In particular, Simple_Name (“/”) should return “/” on Unix-like systems. + +RM references: A.16 (47/2) A.16 (74/2) A.16 (82/3) +@end itemize + +@geindex AI12-0338 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0338 Type invariant checking and incomplete types (0000-00-00)' + +Clarify that type invariants for type T are not checked for incomplete types whose completion is not available, even if that completion has components of type T. + +RM references: 7.03.02 (20/5) +@end itemize + +@geindex AI12-0339 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0339 Empty function for Container aggregates (2020-08-06)' + +To provide uniform support for container aggregates, all standard container +libraries have been enhanced with a function Empty, to be used when initializing an aggregate prior to inserting the specified elements in the object being constructed. All products have been updated to remove the ambiguities that may have arisen from previous uses of entities named Empty in our sources, and the expansion of container aggregates uses Empty wherever needed. + +RM references: A.18.02 (8/5) A.18.02 (12.3/5) A.18.02 (78.2/5) A.18.02 +(98.6/5) A.18.03 (6/5) A.18.03 (10.2/5) A.18.03 (50.2/5) A.18.05 +(3/5) A.18.05 (7.2/5) A.18.05 (37.3/5) A.18.05 (46/2) A.18.06 +(4/5) A.18.06 (8.2/5) A.18.06 (51.4/5) A.18.08 (3/5) A.18.08 +(8.1/5) A.18.08 (59.2/5) A.18.08 (68/2) A.18.09 (4/5) A.18.09 +(9.1/5) A.18.09 (74.2/5) A.18.10 (15.2/5) A.18.18 (8.1/5) A.18.19 +(6.1/5) A.18.20 (6/3) A.18.21 (6/3) A.18.22 (6/3) A.18.23 (6/3) +A.18.24 (6/3) A.18.25 (8/3) +@end itemize + +@geindex AI12-0340 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0340 Put_Image should use a Text_Buffer (0000-00-00)' + +Add a new predefined package Ada.Strings.Text_Buffers (along with child units) and change the definition of Put_Image attribute to refer to it. + +RM references: A.04.12 (0) 4.10 (3.1/5) 4.10 (3.2/5) 4.10 (6/5) 4.10 +(25.2/5) 4.10 (28/5) 4.10 (31/5) 4.10 (41/5) H.04 (23.2/5) H.04 (23.11/5) +@end itemize + +@geindex AI12-0342 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0342 Various issues with user-defined literals (part 2) (2020-04-07)' + +Compiler support is added for three new aspects (@code{Integer_Literal}, @code{Real_Literal}, and @code{String_Literal}) as described in AI12-0249 (for @code{Integer_Literal} and @code{Real_Literal}), AI12-0295 (for @code{String_Literal}), and in two follow-up AIs (AI12-0325 and AI12-0342). For pre-Ada 2022 versions of Ada, these are treated as implementation-defined aspects. Some implementation work remains, particularly in the interactions between these aspects and tagged types. + +RM references: 4.02.01 (0) 3.09.02 (1/2) 6.03.01 (22) +@end itemize + +@geindex AI12-0343 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0343 Return Statement Checks (2020-04-02)' + +This binding interpretation has been implemented and the accessibility, +predicate, and tag checks prescribed by RM 6.5 are now performed at the appropriate points, as required by this AI. + +RM references: 6.05 (5.12/5) 6.05 (8/4) 6.05 (8.1/3) 6.05 (21/3) +@end itemize + +@geindex AI12-0345 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0345 Dynamic accessibility of explicitly aliased parameters (0000-00-00)' + +Further clarify (after AI12-0277) accessibility rules for explicitly aliased parameters. + +RM references: 3.10.02 (5) 3.10.02 (7/4) 3.10.02 (10.5/3) 3.10.02 (13.4/4) +3.10.02 (19.2/5) 3.10.02 (21) +@end itemize + +@geindex AI12-0350 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0350 Swap for Indefinite_Holders (0000-00-00)' + +Add a @code{Swap} procedure to the predefined package +@code{Ada.Containers.Indefinite_Holders}. The AI also contains implementation advice for @code{Ada.Containers.Bounded_Indefinite_Holders}, a package that is not implemented by GNAT. + +RM references: A.18.18 (22/5) A.18.18 (67/5) A.18.18 (73/3) A.18.32 (13/5) +@end itemize + +@geindex AI12-0351 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0351 Matching for actuals for formal derived types (2020-04-03)' + +This binding interpretation requires the compiler to checks +that an actual subtype in a generic parameter association of an instantiation is statically compatible (even when the actual is unconstrained) with the ancestor of an associated nondiscriminated generic formal derived type. + +RM references: 12.05.01 (7) 12.05.01 (8) +@end itemize + +@geindex AI12-0352 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0352 Early derivation and equality of untagged types (2020-07-09)' + +AI12-0352 clarifies that declaring a user-defined primitive equality operation for a record type T is illegal if it occurs after a type has been derived from T. + +RM references: 4.05.02 (9.8/4) +@end itemize + +@geindex AI12-0356 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0356 Root_Storage_Pool_With_Subpools should have Preelaborable_Initialization (0000-00-00)' + +Add Preelaborable_Initialization pragmas for predefined types @code{Root_Storage_Pool_With_Subpools} and @code{Root_Subpool}. + +RM references: 13.11.04 (4/3) 13.11.04 (5/3) +@end itemize + +@geindex AI12-0363 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0363 Fixes for Atomic and Volatile (2020-09-08)' + +This amendment has been implemented under the @code{-gnat2022} switch and the compiler now supports the @code{Full_Access_Only} aspect, which is mostly equivalent to GNAT’s @code{Volatile_Full_Access}. + +RM references: 3.10.02 (26/3) 9.10 (1/5) C.06 (6.4/3) C.06 (6.10/3) C.06 +(8.1/4) C.06 (12/5) C.06 (12.1/5) C.06 (13.3/5) C.06 (19.1/5) +@end itemize + +@geindex AI12-0364 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0364 Add a modular atomic arithmetic package (0000-00-00)' + +Generalize support for atomic integer operations to extend to modular types. Add new predefined generic package, +@code{System.Atomic_Operations.Modular_Arithmetic}. + +RM references: C.06.05 (0) C.06.04 (1/5) C.06.04 (2/5) C.06.04 (3/5) +C.06.04 (9/5) +@end itemize + +@geindex AI12-0366 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0366 Changes to Big_Integer and Big_Real (0000-00-00)' + +Simplify @code{Big_Integer `@w{`}and `@w{`}Big_Real} specs by eliminating explicit support for creating “invalid” values. No more +@code{Optional_Big_[Integer,Real]} types. + +RM references: A.05.06 (0) A.05.07 (0) +@end itemize + +@geindex AI12-0367 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0367 Glitches in aspect specifications (0000-00-00)' + +The AI clarifies a few wording omissions. For example, a specified Small value for a fixed point type has to be positive. + +RM references: 3.05.09 (8/2) 3.05.10 (2/1) 13.01 (9.1/5) 13.14 (10) +@end itemize + +@geindex AI12-0368 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0368 Declare expressions can be static (2020-05-30)' + +AI12-0368 allows declare expressions to be static in Ada 2022. + +RM references: 4.09 (8) 4.09 (12.1/3) 4.09 (17) 6.01.01 (24.2/5) 6.01.01 +(24.3/5) 6.01.01 (24.4/5) 6.01.01 (24.5/5) C.04 (9) +@end itemize + +@geindex AI12-0369 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0369 Relaxing barrier restrictions (2020-03-25)' + +The definitions of the @code{Simple_Barriers} and @code{Pure_Barriers} restrictions were modified by this AI, replacing uses of “statically denotes” with “statically names”. This means that in many cases (but not all) a barrier expression that references a subcomponent of a component of the protected type while subject to either of the two restrictions is now allowed; with the previous restriction definitions, such a barrier expression would not have been legal. + +RM references: D.07 (1.3/5) D.07 (10.12/5) +@end itemize + +@geindex AI12-0372 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0372 Static accessibility of “master of the call” (0000-00-00)' + +Add an extra compile-time accessibility check for explicitly aliased parameters needed to prevent dangling references. + +RM references: 3.10.02 (10.5/5) 3.10.02 (19.3/4) 6.04.01 (6.4/3) +@end itemize + +@geindex AI12-0373 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0373 Bunch of fixes (0000-00-00)' + +Small clarifications to various RM entries with minor impact on compiler implementation. + +RM references: 3.01 (1) 4.02 (4) 4.02 (8/2) 4.02.01 (3/5) 4.02.01 (4/5) +4.02.01 (5/5) 4.09 (17.3/5) 6.01.01 (41/5) 8.05.04 (4/3) 13.01.01 +(4/3) 13.01.01 (11/3) 13.14 (3/5) +@end itemize + +@geindex AI12-0376 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0376 Representation changes finally allowed for untagged derived types (0000-00-00)' + +A change of representation for a derived type is allowed in some previously-illegal cases where a change of representation is required to implement a call to a derived subprogram. + +RM references: 13.01 (10/4) +@end itemize + +@geindex AI12-0377 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0377 View conversions and out parameters of types with Default_Value revisited (2020-06-17)' + +This AI clarifies that an actual of an out parameter that is a view conversion +is illegal if either the target or operand type has Default_Value specified while the other does not. + +RM references: 6.04.01 (5.1/4) 6.04.01 (5.2/4) 6.04.01 (5.3/4) 6.04.01 +(13.1/4) 6.04.01 (13.2/4) 6.04.01 (13.3/4) 6.04.01 (13.4/4) 6.04.01 (15/3) +@end itemize + +@geindex AI12-0381 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0381 Tag of a delta aggregate (0000-00-00)' + +In the case of a delta aggregate of a specific tagged type, the tag of the aggregate comes from the specific type (as opposed to somehow from the base object). + +RM references: 4.03.04 (14/5) +@end itemize + +@geindex AI12-0382 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0382 Loosen type-invariant overriding requirement of AI12-0042-1 (0000-00-00)' + +The AI relaxes some corner-case legality rules about type invariants that were added by AI12-0042-1. + +RM references: 7.3.2(6.1/4) +@end itemize + +@geindex AI12-0383 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0383 Renaming values (2020-06-17)' + +This AI allow names that denote values rather than objects to nevertheless be +renamed using an object renaming. + +RM references: 8.05.01 (1) 8.05.01 (4) 8.05.01 (4.1/2) 8.05.01 (6/2) 8.05.01 (8) +@end itemize + +@geindex AI12-0384-2 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0384-2 Fixups for Put_Image and Text_Buffers (2021-04-29)' + +In GNAT’s initial implementation of the Ada 2022 @code{Put_Image} aspect and +attribute, buffering was performed using a GNAT-defined package, +@code{Ada.Strings.Text_Output}. Ada 2022 requires a different package, Ada.`@w{`}Strings.Text_Buffers`@w{`}, for this role, and that package is now provided, and the older package is eliminated. + +RM references: 4.10 (0) A.04.12 (0) +@end itemize + +@geindex AI12-0385 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0385 Predefined shifts and rotates should be static (0000-00-00)' + +This AI allows Shift and Rotate operations in static expressions. GNAT implements this AI partially. + +RM references: 4.09 (20) +@end itemize + +@geindex AI12-0389 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0389 Ignoring unrecognized aspects (2020-10-08)' + +Two new restrictions, @code{No_Unrecognized_Aspects} and @code{No_Unrecognized_Pragmas}, are available to make the compiler emit error messages on unrecognized pragmas and aspects. + +RM references: 13.01.01 (38/3) 13.12.01 (6.3/3) +@end itemize + +@geindex AI12-0394 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0394 Named Numbers and User-Defined Numeric Literals (2020-10-05)' + +Ada 2022 allows using integer named numbers with types that have an +@code{Integer_Literal} aspect. Similarly, real named numbers may now be used with types that have a @code{Real_Literal} aspect with an overloading that takes two strings, to be used in particular with +@code{Ada.Numerics.Big_Numbers.Big_Reals}. + +RM references: 3.03.02 (3) 4.02.01 (4/5) 4.02.01 (8/5) 4.02.01 (12/5) +4.02.01 (13/5) 4.09 (5) +@end itemize + +@geindex AI12-0395 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0395 Allow aspect_specifications on formal parameters (0000-00-00)' + +Change syntax rules to allow aspect_specifications on formal parameters, if an implementation if an implementation wants to define one. Currently, GNAT doesn’t define any such aspect_specifications. + +RM references: 6.01 (15/3) +@end itemize + +@geindex AI12-0397 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0397 Default_Initial_Condition applied to derived type (2020-12-09)' + +The compiler now implements the rules for resolving @code{Default_Initial_Condition} +expressions that involve references to the current instance of types with the aspect, as specified by this AI. The type of the current instance is defined to be like a formal derived type, so for a derived type that inherits the aspect, a call passing the current instance to a primitive means that the call will resolve to invoke the corresponding primitive of the descendant type. This also now permits calls to abstract primitives to occur within the aspect expression of an abstract type. + +RM references: 7.03.03 (3/5) 7.03.03 (6/5) 7.03.03 (8/5) +@end itemize + +@geindex AI12-0398 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0398 Most declarations should have aspect specifications (2020-11-19)' + +It is now possible to specify aspects for discriminant specifications, extended return object declarations, and entry index specifications. This is an extension added for Ada 2022 by this AI. + +RM references: 3.07 (5/2) 6.03.01 (25) 6.05 (2.1/3) 9.05.02 (8) +@end itemize + +@geindex AI12-0399 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0399 Aspect specification for Preelaborable_Initialization (0000-00-00)' + +Semantics-preserving presentation change. Replace @code{Preelaborable_Initialization} pragmas with equivalent aspect specs in the listed predefined packages. GNAT follows the guidance of this AI partially. + +RM references: 9.05 (53/5) 3.09 (6/5) 7.06 (5/2) 7.06 (7/2) 11.04.01 (2/5) +11.04.01 (3/2) 13.11 (6/2) 13.11.04 (4/5) 13.11.04 (5/5) 13.13.01 +(3/2) A.04.02 (4/2) A.04.02 (20/2) A.04.05 (4/2) A.04.07 (4/2) +A.04.07 (20/2) A.04.08 (4/2) A.04.08 (20/2) A.12.01 (5/4) A.18.02 +(8/5) A.18.02 (9/2) A.18.02 (79.2/5) A.18.02 (79.3/5) A.18.03 +(6/5) A.18.03 (7/2) A.18.03 (50.2/5) A.18.03 (50.3/5) A.18.05 +(3/5) A.18.05 (4/2) A.18.05 (37.3/5) A.18.05 (37.4/5) A.18.06 +(4/5) A.18.06 (5/2) A.18.06 (51.4/5) A.18.06 (51.5/5) A.18.08 +(3/5) A.18.08 (4/2) A.18.08 (58.2/5) A.18.08 (58.3/5) A.18.09 +(4/5) A.18.09 (5/2) A.18.09 (74.2/5) A.18.09 (74.3/5) A.18.10 +(8/5) A.18.10 (9/3) A.18.10 (70.2/5) A.18.10 (70.3/5) A.18.18 +(6/5) B.03.01 (5/2) C.07.01 (2/5) G.01.01 (4/2) +@end itemize + +@geindex AI12-0400 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0400 Ambiguities associated with Vector Append and container aggregates (0000-00-00)' + +Change the names of subprograms in the predefined Vector containers from @code{Append} to @code{Append_Vector} and from @code{Prepend} to @code{Prepend_Vector} in order to resolve some ambiguity problems. GNAT adds the subprograms with new names but also keeps the old ones for backward compatibility. + +RM references: A.18.02 (8/5) A.18.02 (36/5) A.18.02 (37/5) A.18.02 (38/5) +A.18.02 (44/5) A.18.02 (46/5) A.18.02 (47/5) A.18.02 (58/5) +A.18.02 (79.2/5) A.18.02 (150/5) A.18.02 (151/5) A.18.02 (152/5) +A.18.02 (153/5) A.18.02 (154/5) A.18.02 (155/5) A.18.02 (156/5) +A.18.02 (168/5) A.18.02 (169/5) A.18.02 (172/5) A.18.02 (173/5) +A.18.02 (174/5) A.18.02 (175.1/5) A.18.03 (23/5) A.18.03 (23.1/5) +A.18.03 (58.2/5) A.18.03 (96/5) A.18.03 (97.1/5) +@end itemize + +@geindex AI12-0401 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0401 Renaming of qualified expression of variable (2020-10-31)' + +Ada 2022 AI12-0401 restricts renaming of a qualified expression to cases where +the operand is a constant, or the target subtype statically matches the nominal subtype of the operand, or is unconstrained with no predicates, to prevent setting variables to values outside their range or constraints. + +RM references: 3.03 (23.2/3) 8.05.01 (4.7/5) 8.05.01 (5/3) +@end itemize + +@geindex AI12-0409 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0409 Preelaborable_Initialization and bounded containers (2021-06-23)' + +As defined by this AI, the @code{Preelaborable_Initializatio} aspect now has a +corresponding attribute of the same name. Types declared within a generic package specification are permitted to specify the expression of a @code{Prelaborable_Initialization} aspect by including one or more references to the attribute applied to a formal private or formal derived type conjoined by @code{and} operators. This permits the full type of a private type with such an aspect expression to have components of the named formal types, and such a type will have preelaborable initialization in an instance when the +actual types for all referenced formal types have preelaborable initialization. + +RM references: 10.02.01 (4.1/2) 10.02.01 (4.2/2) 10.02.01 (11.1/2) +10.02.01 (11.2/2) 10.02.01 (11.6/2) 10.02.01 (11.7/2) 10.02.01 +(11.8/2) 13.01 (11/3) A.18.19 (5/5) A.18.20 (5/5) A.18.21 (5/5) +A.18.22 (5/5) A.18.23 (5/5) A.18.24 (5/5) A.18.25 (5/5) A.18.32 +(6/5) J.15.14 (0) +@end itemize + +@geindex AI12-0411 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0411 Add “bool” to Interfaces.C (0000-00-00)' + +RM references: B.03 (13) B.03 (43/2) B.03 (65.1/4) +@end itemize + +@geindex AI12-0412 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0412 Abstract Pre/Post’Class on primitive of abstract type (2021-05-19)' + +In Ada 2022, by AI12-0412, it’s legal to specify Pre’Class and Post’Class +aspects on nonabstract primitive subprograms of an abstract type, but if the +expression of such an aspect is nonstatic, then it’s illegal to make a nondispatching call to such a primitive, to apply @code{'Access} to it, or to pass such a primitive as an actual subprogram for a concrete formal subprogram in a generic instantiation. + +RM references: 6.01.01 (18.2/4) +@end itemize + +@geindex AI12-0413 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0413 Reemergence of “=” when defined to be abstract (0000-00-00)' + +The AI clarifies rules about operator reemergence in instances, and nondispatching calls to abstract subprograms. + +RM references: 3.09.03 (7) 4.05.02 (14.1/3) 4.05.02 (24.1/3) 12.05 (8/3) +@end itemize + +@geindex AI12-0423 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0423 Aspect inheritance fixups (0000-00-00)' + +Clarify that the No_Return aspect behaves as one would expect for an inherited subprogram and that inheritance works as one would expect for a multi-part aspect whose value is specified via an aggregate (e.g., the Aggregate aspect). + +RM references: 6.05.01 (3.3/3) 13.01 (15.7/5) 13.01 (15.8/5) +@end itemize + +@geindex AI12-0432 (Ada 2022 feature) + + +@itemize * + +@item +`AI12-0432 View conversions of assignments and predicate checks (2021-05-05)' + +When a predicate applies to a tagged type, a view conversion to that type +normally requires a predicate check. However, as specified by AI12-0432, when the view conversion appears as the target of an assignment, a predicate check is not applied to the object in the conversion. + +RM references: 3.02.04 (31/5) 4.06 (51.1/5) +@end itemize + +@node GNAT language extensions,Security Hardening Features,Implementation of Ada 2022 Features,Top +@anchor{gnat_rm/gnat_language_extensions doc}@anchor{446}@anchor{gnat_rm/gnat_language_extensions gnat-language-extensions}@anchor{447}@anchor{gnat_rm/gnat_language_extensions id1}@anchor{448} +@chapter GNAT language extensions + + +The GNAT compiler implements a certain number of language extensions on top of +the latest Ada standard, implementing its own extended superset of Ada. There are two sets of language extensions: @@ -29126,7 +30455,7 @@ These features might be removed or heavily modified at any time. @end menu @node How to activate the extended GNAT Ada superset,Curated Extensions,,GNAT language extensions -@anchor{gnat_rm/gnat_language_extensions how-to-activate-the-extended-gnat-ada-superset}@anchor{445} +@anchor{gnat_rm/gnat_language_extensions how-to-activate-the-extended-gnat-ada-superset}@anchor{449} @section How to activate the extended GNAT Ada superset @@ -29167,7 +30496,7 @@ for use in playground experiments. @end cartouche @node Curated Extensions,Experimental Language Extensions,How to activate the extended GNAT Ada superset,GNAT language extensions -@anchor{gnat_rm/gnat_language_extensions curated-extensions}@anchor{446}@anchor{gnat_rm/gnat_language_extensions curated-language-extensions}@anchor{6a} +@anchor{gnat_rm/gnat_language_extensions curated-extensions}@anchor{44a}@anchor{gnat_rm/gnat_language_extensions curated-language-extensions}@anchor{6a} @section Curated Extensions @@ -29188,7 +30517,7 @@ Features activated via @code{-gnatX} or @end menu @node Local Declarations Without Block,Deep delta Aggregates,,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions local-declarations-without-block}@anchor{447} +@anchor{gnat_rm/gnat_language_extensions local-declarations-without-block}@anchor{44b} @subsection Local Declarations Without Block @@ -29281,7 +30610,7 @@ And as such the second `@w{`}A`@w{`} declaration is hiding the first one. @end cartouche @node Deep delta Aggregates,Fixed lower bounds for array types and subtypes,Local Declarations Without Block,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions deep-delta-aggregates}@anchor{448} +@anchor{gnat_rm/gnat_language_extensions deep-delta-aggregates}@anchor{44c} @subsection Deep delta Aggregates @@ -29303,7 +30632,7 @@ The syntax of delta aggregates in the extended version is the following: @end menu @node Syntax,Legality Rules,,Deep delta Aggregates -@anchor{gnat_rm/gnat_language_extensions syntax}@anchor{449} +@anchor{gnat_rm/gnat_language_extensions syntax}@anchor{44d} @subsubsection Syntax @@ -29349,7 +30678,7 @@ array_subcomponent_choice ::= @end example @node Legality Rules,Dynamic Semantics,Syntax,Deep delta Aggregates -@anchor{gnat_rm/gnat_language_extensions legality-rules}@anchor{44a} +@anchor{gnat_rm/gnat_language_extensions legality-rules}@anchor{44e} @subsubsection Legality Rules @@ -29386,7 +30715,7 @@ the object denoted by the base_expression, prior to any update.] @end enumerate @node Dynamic Semantics,Examples,Legality Rules,Deep delta Aggregates -@anchor{gnat_rm/gnat_language_extensions dynamic-semantics}@anchor{44b} +@anchor{gnat_rm/gnat_language_extensions dynamic-semantics}@anchor{44f} @subsubsection Dynamic Semantics @@ -29443,7 +30772,7 @@ and assigned to the corresponding subcomponent of the anonymous object. @end itemize @node Examples,,Dynamic Semantics,Deep delta Aggregates -@anchor{gnat_rm/gnat_language_extensions examples}@anchor{44c} +@anchor{gnat_rm/gnat_language_extensions examples}@anchor{450} @subsubsection Examples @@ -29471,7 +30800,7 @@ end; @end example @node Fixed lower bounds for array types and subtypes,Prefixed-view notation for calls to primitive subprograms of untagged types,Deep delta Aggregates,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions fixed-lower-bounds-for-array-types-and-subtypes}@anchor{44d} +@anchor{gnat_rm/gnat_language_extensions fixed-lower-bounds-for-array-types-and-subtypes}@anchor{451} @subsection Fixed lower bounds for array types and subtypes @@ -29522,7 +30851,7 @@ lower bound of unconstrained array formals when the formal’s subtype has index ranges with static fixed lower bounds. @node Prefixed-view notation for calls to primitive subprograms of untagged types,Expression defaults for generic formal functions,Fixed lower bounds for array types and subtypes,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions prefixed-view-notation-for-calls-to-primitive-subprograms-of-untagged-types}@anchor{44e} +@anchor{gnat_rm/gnat_language_extensions prefixed-view-notation-for-calls-to-primitive-subprograms-of-untagged-types}@anchor{452} @subsection Prefixed-view notation for calls to primitive subprograms of untagged types @@ -29572,7 +30901,7 @@ pragma Assert (V.Nth_Element(1) = 42); @end example @node Expression defaults for generic formal functions,String interpolation,Prefixed-view notation for calls to primitive subprograms of untagged types,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions expression-defaults-for-generic-formal-functions}@anchor{44f} +@anchor{gnat_rm/gnat_language_extensions expression-defaults-for-generic-formal-functions}@anchor{453} @subsection Expression defaults for generic formal functions @@ -29603,7 +30932,7 @@ If the default is used (i.e. there is no actual corresponding to Copy), then calls to Copy in the instance will simply return Item. @node String interpolation,Constrained attribute for generic objects,Expression defaults for generic formal functions,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions string-interpolation}@anchor{450} +@anchor{gnat_rm/gnat_language_extensions string-interpolation}@anchor{454} @subsection String interpolation @@ -29770,7 +31099,7 @@ a double quote is " and an open brace is @{ @end example @node Constrained attribute for generic objects,Static aspect on intrinsic functions,String interpolation,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions constrained-attribute-for-generic-objects}@anchor{451} +@anchor{gnat_rm/gnat_language_extensions constrained-attribute-for-generic-objects}@anchor{455} @subsection Constrained attribute for generic objects @@ -29778,7 +31107,7 @@ The @code{Constrained} attribute is permitted for objects of generic types. The result indicates whether the corresponding actual is constrained. @node Static aspect on intrinsic functions,First Controlling Parameter,Constrained attribute for generic objects,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions static-aspect-on-intrinsic-functions}@anchor{452} +@anchor{gnat_rm/gnat_language_extensions static-aspect-on-intrinsic-functions}@anchor{456} @subsection @code{Static} aspect on intrinsic functions @@ -29787,7 +31116,7 @@ and the compiler will evaluate some of these intrinsics statically, in particular the @code{Shift_Left} and @code{Shift_Right} intrinsics. @node First Controlling Parameter,,Static aspect on intrinsic functions,Curated Extensions -@anchor{gnat_rm/gnat_language_extensions first-controlling-parameter}@anchor{453} +@anchor{gnat_rm/gnat_language_extensions first-controlling-parameter}@anchor{457} @subsection First Controlling Parameter @@ -29887,7 +31216,7 @@ The result of a function is never a controlling result. @end itemize @node Experimental Language Extensions,,Curated Extensions,GNAT language extensions -@anchor{gnat_rm/gnat_language_extensions experimental-language-extensions}@anchor{6b}@anchor{gnat_rm/gnat_language_extensions id2}@anchor{454} +@anchor{gnat_rm/gnat_language_extensions experimental-language-extensions}@anchor{6b}@anchor{gnat_rm/gnat_language_extensions id2}@anchor{458} @section Experimental Language Extensions @@ -29896,6 +31225,7 @@ Features activated via @code{-gnatX0} or @menu * Conditional when constructs:: +* Implicit With:: * Storage Model:: * Attribute Super:: * Simpler Accessibility Model:: @@ -29906,11 +31236,13 @@ Features activated via @code{-gnatX0} or * Inference of Dependent Types in Generic Instantiations:: * External_Initialization Aspect:: * Finally construct:: +* Continue statement:: +* Destructors:: @end menu -@node Conditional when constructs,Storage Model,,Experimental Language Extensions -@anchor{gnat_rm/gnat_language_extensions conditional-when-constructs}@anchor{455} +@node Conditional when constructs,Implicit With,,Experimental Language Extensions +@anchor{gnat_rm/gnat_language_extensions conditional-when-constructs}@anchor{459} @subsection Conditional when constructs @@ -29978,8 +31310,25 @@ begin end; @end example -@node Storage Model,Attribute Super,Conditional when constructs,Experimental Language Extensions -@anchor{gnat_rm/gnat_language_extensions storage-model}@anchor{456} +@node Implicit With,Storage Model,Conditional when constructs,Experimental Language Extensions +@anchor{gnat_rm/gnat_language_extensions implicit-with}@anchor{45a} +@subsection Implicit With + + +This feature allows a standalone @code{use} clause in the context clause of a +compilation unit to imply an implicit @code{with} of the same library unit where +an equivalent @code{with} clause would be allowed. + +@example +use Ada.Text_IO; +procedure Main is +begin + Put_Line ("Hello"); +end; +@end example + +@node Storage Model,Attribute Super,Implicit With,Experimental Language Extensions +@anchor{gnat_rm/gnat_language_extensions storage-model}@anchor{45b} @subsection Storage Model @@ -29996,7 +31345,7 @@ memory models, in particular to support interactions with GPU. @end menu @node Aspect Storage_Model_Type,Aspect Designated_Storage_Model,,Storage Model -@anchor{gnat_rm/gnat_language_extensions aspect-storage-model-type}@anchor{457} +@anchor{gnat_rm/gnat_language_extensions aspect-storage-model-type}@anchor{45c} @subsubsection Aspect Storage_Model_Type @@ -30130,7 +31479,7 @@ end CUDA_Memory; @end example @node Aspect Designated_Storage_Model,Legacy Storage Pools,Aspect Storage_Model_Type,Storage Model -@anchor{gnat_rm/gnat_language_extensions aspect-designated-storage-model}@anchor{458} +@anchor{gnat_rm/gnat_language_extensions aspect-designated-storage-model}@anchor{45d} @subsubsection Aspect Designated_Storage_Model @@ -30208,7 +31557,7 @@ begin @end example @node Legacy Storage Pools,,Aspect Designated_Storage_Model,Storage Model -@anchor{gnat_rm/gnat_language_extensions legacy-storage-pools}@anchor{459} +@anchor{gnat_rm/gnat_language_extensions legacy-storage-pools}@anchor{45e} @subsubsection Legacy Storage Pools @@ -30259,7 +31608,7 @@ type Acc is access Integer_Array with Storage_Pool => My_Pool; can still be accepted as a shortcut for the new syntax. @node Attribute Super,Simpler Accessibility Model,Storage Model,Experimental Language Extensions -@anchor{gnat_rm/gnat_language_extensions attribute-super}@anchor{45a} +@anchor{gnat_rm/gnat_language_extensions attribute-super}@anchor{45f} @subsection Attribute Super @@ -30294,7 +31643,7 @@ end; @end example @node Simpler Accessibility Model,Case pattern matching,Attribute Super,Experimental Language Extensions -@anchor{gnat_rm/gnat_language_extensions simpler-accessibility-model}@anchor{45b} +@anchor{gnat_rm/gnat_language_extensions simpler-accessibility-model}@anchor{460} @subsection Simpler Accessibility Model @@ -30325,7 +31674,7 @@ All of the refined rules are compatible with the [use of anonymous access types @end menu @node Stand-alone objects,Subprogram parameters,,Simpler Accessibility Model -@anchor{gnat_rm/gnat_language_extensions stand-alone-objects}@anchor{45c} +@anchor{gnat_rm/gnat_language_extensions stand-alone-objects}@anchor{461} @subsubsection Stand-alone objects @@ -30373,7 +31722,7 @@ of the RM 4.6 rule “The accessibility level of the operand type shall not be statically deeper than that of the target type …”. @node Subprogram parameters,Function results,Stand-alone objects,Simpler Accessibility Model -@anchor{gnat_rm/gnat_language_extensions subprogram-parameters}@anchor{45d} +@anchor{gnat_rm/gnat_language_extensions subprogram-parameters}@anchor{462} @subsubsection Subprogram parameters @@ -30466,7 +31815,7 @@ end; @end example @node Function results,,Subprogram parameters,Simpler Accessibility Model -@anchor{gnat_rm/gnat_language_extensions function-results}@anchor{45e} +@anchor{gnat_rm/gnat_language_extensions function-results}@anchor{463} @subsubsection Function results @@ -30594,7 +31943,7 @@ end; @end example @node Case pattern matching,Mutably Tagged Types with Size’Class Aspect,Simpler Accessibility Model,Experimental Language Extensions -@anchor{gnat_rm/gnat_language_extensions case-pattern-matching}@anchor{45f} +@anchor{gnat_rm/gnat_language_extensions case-pattern-matching}@anchor{464} @subsection Case pattern matching @@ -30724,81 +32073,111 @@ message generated in such cases is usually “Capacity exceeded in compiling case statement with composite selector type”. @node Mutably Tagged Types with Size’Class Aspect,Generalized Finalization,Case pattern matching,Experimental Language Extensions -@anchor{gnat_rm/gnat_language_extensions mutably-tagged-types-with-size-class-aspect}@anchor{460} +@anchor{gnat_rm/gnat_language_extensions mutably-tagged-types-with-size-class-aspect}@anchor{465} @subsection Mutably Tagged Types with Size’Class Aspect -The @code{Size'Class} aspect can be applied to a tagged type to specify a size -constraint for the type and its descendants. When this aspect is specified -on a tagged type, the class-wide type of that type is considered to be a -“mutably tagged” type - meaning that objects of the class-wide type can have -their tag changed by assignment from objects with a different tag. - -Example: - -@example -type Base is tagged null record - with Size'Class => 16 * 8; -- Size in bits (128 bits, or 16 bytes) - -type Derived_Type is new Base with record - Data_Field : Integer; -end record; -- ERROR if Derived_Type exceeds 16 bytes -@end example - -Class-wide types with a specified @code{Size'Class} can be used as the type of -array components, record components, and stand-alone objects. +For a specific tagged nonformal type T that satisfies some conditions +described later in this section, the universal-integer-valued type-related +representation aspect @code{Size'Class} may be specified; any such specified +aspect value shall be static. -@example -Inst : Base'Class; -type Array_of_Base is array (Positive range <>) of Base'Class; -@end example +Specifying this aspect imposes an upper bound on the sizes of all specific +descendants of T (including T itself). T’Class (but not T) is then said to be +a “mutably tagged” type - meaning that T’Class is a definite subtype and that +the tag of a variable of type T’Class may be modified by assignment in some +cases described later in this section. An inherited @code{Size'Class} aspect +value may be overridden, but not with a larger value. -If the @code{Size'Class} aspect is specified for a type @code{T}, then every -specific descendant of @code{T} [redundant: (including @code{T})] +If the @code{Size'Class} aspect is specified for a type T, then every specific +descendant of T (including T itself) -@itemize - +@itemize * @item shall have a Size that does not exceed the specified value; and @item -shall be undiscriminated; and +shall have a (possibly inherited) @code{Size'Class} aspect that does not exceed +the specifed value; and @item -shall have no composite subcomponent whose subtype is subject to a -dynamic constraint; and +shall be undiscriminated; and @item -shall have no interface progenitors; and +shall have no composite subcomponent whose subtype is subject to a nonstatic +constraint; and @item shall not have a tagged partial view other than a private extension; and @item -shall not have a statically deeper accessibility level than that of @code{T}. +shall not be a descendant of an interface type; and + +@item +shall not have a statically deeper accessibility level than that of T. @end itemize -In addition to the places where Legality Rules normally apply (see 12.3), -these legality rules apply also in the private part and in the body of an -instance of a generic unit. +If the @code{Size'Class} aspect is not specified for a type T (either explicitly +or by inheritance), then it shall not be specified for any descendant of T. + +Example: + +@example +type Root_Type is tagged null record with Size'Class => 16 * 8; + +type Derived_Type is new Root_Type with record + Stuff : Some_Type; +end record; -- ERROR if Derived_Type exceeds 16 bytes +@end example -For any subtype @code{S} that is a subtype of a descendant of @code{T}, @code{S'Class'Size} is -defined to yield the specified value [redundant:, although @code{S'Class'Size} is -not a static expression]. +Because any subtype of a mutably tagged type is definite, it can be used as a +component subtype for enclosing array or record types, as the subtype of a +default-initialized stand-alone object, or as the subtype of an uninitialized +allocator, as in this example: -A class-wide descendant of a type with a specified @code{Size'Class} aspect is -defined to be a “mutably tagged” type. Any subtype of a mutably tagged type is, -by definition, a definite subtype (RM 3.3 notwithstanding). Default -initialization of an object of such a definite subtype proceeds as for the -corresponding specific type, except that @code{Program_Error} is raised if the -specific type is abstract. [In particular, the initial tag of the object is -that of the corresponding specific type.] +@example +Obj : Root_Type'Class; +type Array_of_Roots is array (Positive range <>) of Root_Type'Class; +@end example -An object of a tagged type is defined to be “tag-constrained” if it is +Default initialization of an object of such a definite subtype proceeds as +for the corresponding specific type, except that Program_Error is raised if +the specific type is abstract. In particular, the initial tag of the object +is that of the corresponding specific type. +There is a general design principle that if a type has a tagged partial view, +then the type’s @code{Size'Class} aspect (or lack thereof) should be determinable +by looking only at the partial view. That provides the motivation for the +rules of the next two paragraphs. -@itemize - +If a type has a tagged partial view, then a @code{Size'Class} aspect specification +may be provided only at the point of the partial view declaration (in other +words, no such aspect specification may be provided when the full view of +the type is declared). All of the above rules (in particular, the rule that +an overriding @code{Size'Class} aspect value shall not be larger than the +overridden inherited value) are also enforced when the full view (which may +have a different ancestor type than that of the partial view) is declared. +If a partial view for a type inherits a @code{Size'Class} aspect value and does +not override that value with an explicit aspect specification, then the +(static) aspect values inherited by the partial view and by the full view +shall be equal. + +An actual parameter of an instantiation whose corresponding formal parameter +is a formal tagged private type shall not be either mutably tagged or the +corresponding specific type of a mutably tagged type. + +For the legality rules in this section, the RM 12.3(11) rule about legality +checking in the visible part and formal part of an instance is extended (in +the same way that it is extended in many other places in the RM) to include +the private part of an instance. + +An object (or a view thereof) of a tagged type is defined to be +“tag-constrained” if it is + + +@itemize * @item an object whose type is not mutably tagged; or @@ -30810,52 +32189,62 @@ a constant object; or a view conversion of a tag-constrained object; or @item -a formal @code{in out} or @code{out} parameter whose corresponding -actual parameter is tag-constrained. +a view conversion to a type that is not a descendant of the operand’s +type; or + +@item +a formal in out or out parameter whose corresponding actual parameter is +tag-constrained; or + +@item +a dereference of an access value. @end itemize -In the case of an assignment to a tagged variable that -is not tag-constrained, no check is performed that the tag of the value of -the expression is the same as that of the target (RM 5.2 notwithstanding). +In the case of an assignment to a tagged variable that is not +tag-constrained, no check is performed that the tag of the value +of the expression is the same as that of the target (RM 5.2 notwithstanding). Instead, the tag of the target object becomes that of the source object of -the assignment. +the assignment. Note that the tag of an object of a mutably tagged type MT +will always be the tag of some specific type that is a descendant of MT. An assignment to a composite object similarly copies the tags of any -subcomponents of the source object that have a mutably-tagged type. - -The @code{Constrained} attribute is defined for any name denoting an object of a -mutably tagged type (RM 3.7.2 notwithstanding). In this case, the Constrained -attribute yields the value True if the object is tag-constrained and False -otherwise. - -Renaming is not allowed (see 8.5.1) for a type conversion having an operand of -a mutably tagged type @code{MT} and a target type @code{TT} such that @code{TT'Class} -does not cover @code{MT}, nor for any part of such an object, nor for any slice -of such an object. This rule also applies in any context where a name is -required to be one for which “renaming is allowed” (for example, see RM 12.4). - -A name denoting a view of a variable of a mutably tagged type shall not -occur as an operative constituent of the prefix of a name denoting a -prefixed view of a callable entity, except as the callee name in a call to -the callable entity. - -For a type conversion between two general access types, either both or neither -of the designated types shall be mutably tagged. For an @code{Access} (or -@code{Unchecked_Access}) attribute reference, the designated type of the type of the -attribute reference and the type of the prefix of the attribute shall either -both or neither be mutably tagged. +subcomponents of the source object that have a mutably tagged type. + +The Constrained attribute is defined for any name denoting an object of a +mutably tagged type (RM 3.7.2 notwithstanding). In this case, the +Constrained attribute yields the value True if the object is +tag-constrained and False otherwise. + +Renaming is not allowed (see RM 8.5.1) for a type conversion having an operand +of a mutably tagged type MT and a target type TT such that TT (or its +corresponding specific type if TT is class-wide) is not an ancestor of MT +(this is sometimes called a “downward” conversion), nor for any part of +such an object, nor for any slice of any part of such an object. This +rule also applies in any context where a name is required to be one for +which “renaming is allowed” (for example, see RM 12.4). +[This is analogous to the way that renaming is not allowed for a +discriminant-dependent component of an unconstrained variable.] + +A name denoting a view of a variable of a mutably tagged type shall not occur +as an operative constituent of the prefix of a name denoting a prefixed +view of a callable entity, except as the callee name in a call to the +callable entity. This disallows, for example, renaming such a prefixed view, +passing the prefixed view name as a generic actual parameter, or using the +prefixed view name as the prefix of an attribute. The execution of a construct is erroneous if the construct has a constituent that is a name denoting a subcomponent of a tagged object and the object’s -tag is changed by this execution between evaluating the name and the last use -(within this execution) of the subcomponent denoted by the name. +tag is changed by this execution between evaluating the name and the last +use (within this execution) of the subcomponent denoted by the name. +This is analogous to the RM 3.7.2(4) rule about discriminant-dependent +subcomponents. -If the type of a formal parameter is a specific tagged type then the execution +If the type of a formal parameter is a specific tagged type, then the execution of the call is erroneous if the tag of the actual is changed while the formal -parameter exists (that is, before leaving the corresponding callable -construct). +parameter exists (that is, before leaving the corresponding callable construct). +This is analogous to the RM 6.4.1(18) rule about discriminated parameters. @node Generalized Finalization,No_Raise aspect,Mutably Tagged Types with Size’Class Aspect,Experimental Language Extensions -@anchor{gnat_rm/gnat_language_extensions generalized-finalization}@anchor{461} +@anchor{gnat_rm/gnat_language_extensions generalized-finalization}@anchor{466} @subsection Generalized Finalization @@ -30867,27 +32256,24 @@ that the record type must be a root type, in other words not a derived type. The aspect additionally makes it possible to specify relaxed semantics for the finalization operations by means of the @code{Relaxed_Finalization} setting. - -Example: +Here is the archetypal example: @example -type Ctrl is record - Id : Natural := 0; +type T is record + ... end record with Finalizable => (Initialize => Initialize, Adjust => Adjust, Finalize => Finalize, Relaxed_Finalization => True); -procedure Adjust (Obj : in out Ctrl); -procedure Finalize (Obj : in out Ctrl); -procedure Initialize (Obj : in out Ctrl); +procedure Adjust (Obj : in out T); +procedure Finalize (Obj : in out T); +procedure Initialize (Obj : in out T); @end example -The three procedures have the same profile, taking a single @code{in out T} -parameter. - -We follow the same dynamic semantics as controlled objects: +The three procedures have the same profile, with a single @code{in out} parameter, +and also have the same dynamic semantics as for controlled types: @quotation @@ -30896,98 +32282,49 @@ We follow the same dynamic semantics as controlled objects: @item @code{Initialize} is called when an object of type @code{T} is declared without -default expression. +initialization expression. @item @code{Adjust} is called after an object of type @code{T} is assigned a new value. @item @code{Finalize} is called when an object of type @code{T} goes out of scope (for -stack-allocated objects) or is explicitly deallocated (for heap-allocated -objects). It is also called when on the value being replaced in an -assignment. +stack-allocated objects) or is deallocated (for heap-allocated objects). +It is also called when the value is replaced by an assignment. @end itemize @end quotation -However the following differences are enforced by default when compared to the -current Ada controlled-objects finalization model: +However, when @code{Relaxed_Finalization} is either @code{True} or not explicitly +specified, the following differences are implemented relative to the semantics +of controlled types: @itemize * @item -No automatic finalization of heap allocated objects: @code{Finalize} is only -called when an object is implicitly deallocated. As a consequence, no-runtime -support is needed for the implicit case, and no header will be maintained for -this in heap-allocated controlled objects. - -Heap-allocated objects allocated through a nested access type definition will -hence `not' be deallocated either. The result is simply that memory will be -leaked in those cases. - -@item -The @code{Finalize} procedure should have have the @ref{462,,No_Raise aspect} specified. -If that’s not the case, a compilation error will be raised. -@end itemize - -Additionally, two other configuration aspects are added, -@code{Legacy_Heap_Finalization} and @code{Exceptions_In_Finalize}: - - -@itemize * +The compiler has permission to perform no automatic finalization of +heap-allocated objects: @code{Finalize} is only called when such an object +is explicitly deallocated, or when the designated object is assigned a new +value. As a consequence, no runtime support is needed for performing +implicit deallocation. In particular, no per-object header data is needed +for heap-allocated objects. -@item -@code{Legacy_Heap_Finalization}: Uses the legacy automatic finalization of -heap-allocated objects +Heap-allocated objects allocated through a nested access type will therefore +`not' be deallocated either. The result is simply that memory will be leaked +in this case. @item -@code{Exceptions_In_Finalize}: Allow users to have a finalizer that raises exceptions -`NB!' note that using this aspect introduces execution time penalities. +The @code{Adjust} and @code{Finalize} procedures are automatically considered as +having the @ref{467,,No_Raise aspect} specified for them. In particular, the +compiler has permission to enforce none of the guarantees specified by the +RM 7.6.1 (14/1) and subsequent subclauses. @end itemize -@node No_Raise aspect,Inference of Dependent Types in Generic Instantiations,Generalized Finalization,Experimental Language Extensions -@anchor{gnat_rm/gnat_language_extensions id3}@anchor{463}@anchor{gnat_rm/gnat_language_extensions no-raise-aspect}@anchor{462} -@subsection No_Raise aspect - - -The @code{No_Raise} aspect can be applied to a subprogram to declare that this subprogram is not -expected to raise any exceptions. Should an exception still occur during the execution of -this subprogram, @code{Program_Error} is raised. - -@menu -* New specification for Ada.Finalization.Controlled: New specification for Ada Finalization Controlled. -* Finalized tagged types:: -* Composite types:: -* Interoperability with controlled types:: - -@end menu - -@node New specification for Ada Finalization Controlled,Finalized tagged types,,No_Raise aspect -@anchor{gnat_rm/gnat_language_extensions new-specification-for-ada-finalization-controlled}@anchor{464} -@subsubsection New specification for @code{Ada.Finalization.Controlled} - - -@code{Ada.Finalization.Controlled} is now specified as: - -@example -type Controlled is abstract tagged null record - with Initialize => Initialize, - Adjust => Adjust, - Finalize => Finalize, - Legacy_Heap_Finalization, Exceptions_In_Finalize; - - procedure Initialize (Self : in out Controlled) is abstract; - procedure Adjust (Self : in out Controlled) is abstract; - procedure Finalize (Self : in out Controlled) is abstract; -@end example - -### Examples - -A simple example of a ref-counted type: +Simple example of ref-counted type: @example type T is record - Value : Integer; + Value : Integer; Ref_Count : Natural := 0; end record; @@ -30999,8 +32336,8 @@ type T_Access is access all T; type T_Ref is record Value : T_Access; end record - with Adjust => Adjust, - Finalize => Finalize; + with Finalizable => (Adjust => Adjust, + Finalize => Finalize); procedure Adjust (Ref : in out T_Ref) is begin @@ -31013,7 +32350,7 @@ begin end Finalize; @end example -A simple file handle that ensures resources are properly released: +Simple file handle that ensures resources are properly released: @example package P is @@ -31022,66 +32359,64 @@ package P is function Open (Path : String) return File; procedure Close (F : in out File); + private type File is limited record Handle : ...; end record - with Finalize => Close; + with Finalizable (Finalize => Close); +end P; @end example -@node Finalized tagged types,Composite types,New specification for Ada Finalization Controlled,No_Raise aspect -@anchor{gnat_rm/gnat_language_extensions finalized-tagged-types}@anchor{465} -@subsubsection Finalized tagged types - +@menu +* Finalizable tagged types:: +* Composite types:: +* Interoperability with controlled types:: -Aspects are inherited by derived types and optionally overriden by those. The -compiler-generated calls to the user-defined operations are then -dispatching whenever it makes sense, i.e. the object in question is of -class-wide type and the class includes at least one finalized tagged type. +@end menu -However note that for simplicity, it is forbidden to change the value of any of -those new aspects in derived types. +@node Finalizable tagged types,Composite types,,Generalized Finalization +@anchor{gnat_rm/gnat_language_extensions finalizable-tagged-types}@anchor{468} +@subsubsection Finalizable tagged types -@node Composite types,Interoperability with controlled types,Finalized tagged types,No_Raise aspect -@anchor{gnat_rm/gnat_language_extensions composite-types}@anchor{466} -@subsubsection Composite types +The aspect is inherited by derived types and the primitives may be overridden +by the derivation. The compiler-generated calls to these operations are then +dispatching whenever it makes sense, i.e. when the object in question is of a +class-wide type and the class includes at least one finalizable tagged type. -When a finalized type is used as a component of a composite type, the latter -becomes finalized as well. The three primitives are derived automatically -in order to call the primitives of their components. +@node Composite types,Interoperability with controlled types,Finalizable tagged types,Generalized Finalization +@anchor{gnat_rm/gnat_language_extensions composite-types}@anchor{469} +@subsubsection Composite types -If that composite type was already user-finalized, then the compiler -calls the primitives of the components so as to stay consistent with today’s -controlled types’s behavior. -So, @code{Initialize} and @code{Adjust} are called on components before they -are called on the composite object, but @code{Finalize} is called on the composite -object first. +When a finalizable type is used as a component of a composite type, the latter +becomes finalizable as well. The three primitives are derived automatically +in order to call the primitives of their components. The dynamic semantics is +the same as for controlled components of composite types. -@node Interoperability with controlled types,,Composite types,No_Raise aspect -@anchor{gnat_rm/gnat_language_extensions interoperability-with-controlled-types}@anchor{467} +@node Interoperability with controlled types,,Composite types,Generalized Finalization +@anchor{gnat_rm/gnat_language_extensions interoperability-with-controlled-types}@anchor{46a} @subsubsection Interoperability with controlled types -As a consequence of the redefinition of the @code{Controlled} type as a base type -with the new aspects defined, interoperability with controlled type naturally -follows the definition of the above rules. In particular: +Finalizable types are fully interoperable with controlled types, in particular +it is possible for a finalizable type to have a controlled component and vice +versa, but the stricter dynamic semantics, in other words that of controlled +types, is applied in this case. +@node No_Raise aspect,Inference of Dependent Types in Generic Instantiations,Generalized Finalization,Experimental Language Extensions +@anchor{gnat_rm/gnat_language_extensions id3}@anchor{46b}@anchor{gnat_rm/gnat_language_extensions no-raise-aspect}@anchor{467} +@subsection No_Raise aspect -@itemize * - -@item -It is possible to have a new finalized type have a controlled type -component -@item -It is possible to have a controlled type have a finalized type -component -@end itemize +The @code{No_Raise} aspect can be applied to a subprogram to declare that this +subprogram is not expected to raise an exception. Should an exception still +be raised during the execution of the subprogram, it is caught at the end of +this execution and @code{Program_Error} is propagated to the caller. @node Inference of Dependent Types in Generic Instantiations,External_Initialization Aspect,No_Raise aspect,Experimental Language Extensions -@anchor{gnat_rm/gnat_language_extensions inference-of-dependent-types-in-generic-instantiations}@anchor{468} +@anchor{gnat_rm/gnat_language_extensions inference-of-dependent-types-in-generic-instantiations}@anchor{46c} @subsection Inference of Dependent Types in Generic Instantiations @@ -31158,7 +32493,7 @@ package Int_Array_Operations is new Array_Operations @end example @node External_Initialization Aspect,Finally construct,Inference of Dependent Types in Generic Instantiations,Experimental Language Extensions -@anchor{gnat_rm/gnat_language_extensions external-initialization-aspect}@anchor{469} +@anchor{gnat_rm/gnat_language_extensions external-initialization-aspect}@anchor{46d} @subsection External_Initialization Aspect @@ -31198,8 +32533,8 @@ The maximum size of loaded files is limited to 2@w{^31} bytes. @end quotation @end cartouche -@node Finally construct,,External_Initialization Aspect,Experimental Language Extensions -@anchor{gnat_rm/gnat_language_extensions finally-construct}@anchor{46a} +@node Finally construct,Continue statement,External_Initialization Aspect,Experimental Language Extensions +@anchor{gnat_rm/gnat_language_extensions finally-construct}@anchor{46e} @subsection Finally construct @@ -31216,7 +32551,7 @@ This feature is similar to the one with the same name in other languages such as @end menu @node Syntax<2>,Legality Rules<2>,,Finally construct -@anchor{gnat_rm/gnat_language_extensions id4}@anchor{46b} +@anchor{gnat_rm/gnat_language_extensions id4}@anchor{46f} @subsubsection Syntax @@ -31231,7 +32566,7 @@ handled_sequence_of_statements ::= @end example @node Legality Rules<2>,Dynamic Semantics<2>,Syntax<2>,Finally construct -@anchor{gnat_rm/gnat_language_extensions id5}@anchor{46c} +@anchor{gnat_rm/gnat_language_extensions id5}@anchor{470} @subsubsection Legality Rules @@ -31241,7 +32576,7 @@ to be transferred outside the finally part are forbidden. Goto & exit where the target is outside of the finally’s @code{sequence_of_statements} are forbidden @node Dynamic Semantics<2>,,Legality Rules<2>,Finally construct -@anchor{gnat_rm/gnat_language_extensions id6}@anchor{46d} +@anchor{gnat_rm/gnat_language_extensions id6}@anchor{471} @subsubsection Dynamic Semantics @@ -31255,8 +32590,96 @@ Abort/ATC (asynchronous transfer of control) cannot interrupt a finally block, n execution, that is the finally block must be executed in full even if the containing task is aborted, or if the control is transferred out of the block. +@node Continue statement,Destructors,Finally construct,Experimental Language Extensions +@anchor{gnat_rm/gnat_language_extensions continue-statement}@anchor{472} +@subsection Continue statement + + +The @code{continue} keyword makes it possible to stop execution of a loop iteration +and continue with the next one. A continue statement has the same syntax +(except “exit” is replaced with “continue”), static semantics, and legality +rules as an exit statement. The difference is in the dynamic semantics: where an +exit statement would cause a transfer of control that completes the (implicitly +or explicitly) specified loop_statement, a continue statement would instead +cause a transfer of control that completes only the current iteration of that +loop_statement, like a goto statement targeting a label following the last +statement in the sequence of statements of the specified loop_statement. + +Note that @code{continue} is a keyword but it is not a reserved word. This is a +configuration that does not exist in standard Ada. + +@node Destructors,,Continue statement,Experimental Language Extensions +@anchor{gnat_rm/gnat_language_extensions destructors}@anchor{473} +@subsection Destructors + + +The @code{Destructor} aspect can be applied to any record type, tagged or not. +It must denote a primitive of the type that is a procedure with one parameter +of the type and of mode @code{in out}: + +@example +type T is record + ... +end record with Destructor => Foo; + +procedure Foo (X : in out T); +@end example + +This is equivalent to the following code that uses @code{Finalizable}: + +@example +type T is record + ... +end record with Finalizable => (Finalize => Foo); + +procedure Foo (X : in out T); +@end example + +Unlike @code{Finalizable}, however, @code{Destructor} can be specified on a derived +type. And when it is, the effect of the aspect combines with the destructors of +the parent type. Take, for example: + +@example +type T1 is record + ... +end record with Destructor => Foo; + +procedure Foo (X : in out T1); + +type T2 is new T1 with Destructor => Bar; + +procedure Bar (X : in out T2); +@end example + +Here, when an object of type @code{T2} is finalized, a call to @code{Bar} +will be performed and it will be followed by a call to @code{Foo}. + +The @code{Destructor} aspect comes with a legality rule: if a primitive procedure +of a type is denoted by a @code{Destructor} aspect specification, it is illegal to +override this procedure in a derived type. For example, the following is illegal: + +@example +type T1 is record + ... +end record with Destructor => Foo; + +procedure Foo (X : in out T1); + +type T2 is new T1; + +overriding +procedure Foo (X : in out T2); -- Error here +@end example + +It is possible to specify @code{Destructor} on the completion of a private type, +but there is one more restriction in that case: the denoted primitive must +be private to the enclosing package. This is necessary due to the previously +mentioned legality rule, to prevent breaking the privacy of the type when +imposing that rule on outside types that derive from the private view of the +type. + @node Security Hardening Features,Obsolescent Features,GNAT language extensions,Top -@anchor{gnat_rm/security_hardening_features doc}@anchor{46e}@anchor{gnat_rm/security_hardening_features id1}@anchor{46f}@anchor{gnat_rm/security_hardening_features security-hardening-features}@anchor{15} +@anchor{gnat_rm/security_hardening_features doc}@anchor{474}@anchor{gnat_rm/security_hardening_features id1}@anchor{475}@anchor{gnat_rm/security_hardening_features security-hardening-features}@anchor{15} @chapter Security Hardening Features @@ -31278,7 +32701,7 @@ change. @end menu @node Register Scrubbing,Stack Scrubbing,,Security Hardening Features -@anchor{gnat_rm/security_hardening_features register-scrubbing}@anchor{470} +@anchor{gnat_rm/security_hardening_features register-scrubbing}@anchor{476} @section Register Scrubbing @@ -31314,7 +32737,7 @@ programming languages, see @cite{Using the GNU Compiler Collection (GCC)}. @c Stack Scrubbing: @node Stack Scrubbing,Hardened Conditionals,Register Scrubbing,Security Hardening Features -@anchor{gnat_rm/security_hardening_features stack-scrubbing}@anchor{471} +@anchor{gnat_rm/security_hardening_features stack-scrubbing}@anchor{477} @section Stack Scrubbing @@ -31458,7 +32881,7 @@ Bar_Callable_Ptr. @c Hardened Conditionals: @node Hardened Conditionals,Hardened Booleans,Stack Scrubbing,Security Hardening Features -@anchor{gnat_rm/security_hardening_features hardened-conditionals}@anchor{472} +@anchor{gnat_rm/security_hardening_features hardened-conditionals}@anchor{478} @section Hardened Conditionals @@ -31548,7 +32971,7 @@ be used with other programming languages supported by GCC. @c Hardened Booleans: @node Hardened Booleans,Control Flow Redundancy,Hardened Conditionals,Security Hardening Features -@anchor{gnat_rm/security_hardening_features hardened-booleans}@anchor{473} +@anchor{gnat_rm/security_hardening_features hardened-booleans}@anchor{479} @section Hardened Booleans @@ -31609,7 +33032,7 @@ and more details on that attribute, see @cite{Using the GNU Compiler Collection @c Control Flow Redundancy: @node Control Flow Redundancy,,Hardened Booleans,Security Hardening Features -@anchor{gnat_rm/security_hardening_features control-flow-redundancy}@anchor{474} +@anchor{gnat_rm/security_hardening_features control-flow-redundancy}@anchor{47a} @section Control Flow Redundancy @@ -31777,7 +33200,7 @@ see @cite{Using the GNU Compiler Collection (GCC)}. These options can be used with other programming languages supported by GCC. @node Obsolescent Features,Compatibility and Porting Guide,Security Hardening Features,Top -@anchor{gnat_rm/obsolescent_features doc}@anchor{475}@anchor{gnat_rm/obsolescent_features id1}@anchor{476}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{16} +@anchor{gnat_rm/obsolescent_features doc}@anchor{47b}@anchor{gnat_rm/obsolescent_features id1}@anchor{47c}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{16} @chapter Obsolescent Features @@ -31796,7 +33219,7 @@ compatibility purposes. @end menu @node pragma No_Run_Time,pragma Ravenscar,,Obsolescent Features -@anchor{gnat_rm/obsolescent_features id2}@anchor{477}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{478} +@anchor{gnat_rm/obsolescent_features id2}@anchor{47d}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{47e} @section pragma No_Run_Time @@ -31809,7 +33232,7 @@ preferred usage is to use an appropriately configured run-time that includes just those features that are to be made accessible. @node pragma Ravenscar,pragma Restricted_Run_Time,pragma No_Run_Time,Obsolescent Features -@anchor{gnat_rm/obsolescent_features id3}@anchor{479}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{47a} +@anchor{gnat_rm/obsolescent_features id3}@anchor{47f}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{480} @section pragma Ravenscar @@ -31818,7 +33241,7 @@ The pragma @code{Ravenscar} has exactly the same effect as pragma is part of the new Ada 2005 standard. @node pragma Restricted_Run_Time,pragma Task_Info,pragma Ravenscar,Obsolescent Features -@anchor{gnat_rm/obsolescent_features id4}@anchor{47b}@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{47c} +@anchor{gnat_rm/obsolescent_features id4}@anchor{481}@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{482} @section pragma Restricted_Run_Time @@ -31828,7 +33251,7 @@ preferred since the Ada 2005 pragma @code{Profile} is intended for this kind of implementation dependent addition. @node pragma Task_Info,package System Task_Info s-tasinf ads,pragma Restricted_Run_Time,Obsolescent Features -@anchor{gnat_rm/obsolescent_features id5}@anchor{47d}@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{47e} +@anchor{gnat_rm/obsolescent_features id5}@anchor{483}@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{484} @section pragma Task_Info @@ -31854,7 +33277,7 @@ in the spec of package System.Task_Info in the runtime library. @node package System Task_Info s-tasinf ads,,pragma Task_Info,Obsolescent Features -@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{47f}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{480} +@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{485}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{486} @section package System.Task_Info (@code{s-tasinf.ads}) @@ -31864,7 +33287,7 @@ to support the @code{Task_Info} pragma. The predefined Ada package standard replacement for GNAT’s @code{Task_Info} functionality. @node Compatibility and Porting Guide,GNU Free Documentation License,Obsolescent Features,Top -@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{481}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{17}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{482} +@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{487}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{17}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{488} @chapter Compatibility and Porting Guide @@ -31886,7 +33309,7 @@ applications developed in other Ada environments. @end menu @node Writing Portable Fixed-Point Declarations,Compatibility with Ada 83,,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{483}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{484} +@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{489}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{48a} @section Writing Portable Fixed-Point Declarations @@ -32008,13 +33431,13 @@ If you follow this scheme you will be guaranteed that your fixed-point types will be portable. @node Compatibility with Ada 83,Compatibility between Ada 95 and Ada 2005,Writing Portable Fixed-Point Declarations,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{485}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{486} +@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{48b}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{48c} @section Compatibility with Ada 83 -@geindex Compatibility (between Ada 83 and Ada 95 / Ada 2005 / Ada 2012) +@geindex Compatibility (between Ada 83 and Ada 95 / Ada 2005 / Ada 2012 / Ada 2022) -Ada 95 and the subsequent revisions Ada 2005 and Ada 2012 +Ada 95 and the subsequent revisions Ada 2005, Ada 2012, Ada 2022 are highly upwards compatible with Ada 83. In particular, the design intention was that the difficulties associated with moving from Ada 83 to later versions of the standard should be no greater @@ -32036,7 +33459,7 @@ following subsections treat the most likely issues to be encountered. @end menu @node Legal Ada 83 programs that are illegal in Ada 95,More deterministic semantics,,Compatibility with Ada 83 -@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{487}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{488} +@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{48d}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{48e} @subsection Legal Ada 83 programs that are illegal in Ada 95 @@ -32136,7 +33559,7 @@ the fix is usually simply to add the @code{(<>)} to the generic declaration. @end itemize @node More deterministic semantics,Changed semantics,Legal Ada 83 programs that are illegal in Ada 95,Compatibility with Ada 83 -@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{489}@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{48a} +@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{48f}@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{490} @subsection More deterministic semantics @@ -32164,7 +33587,7 @@ which open select branches are executed. @end itemize @node Changed semantics,Other language compatibility issues,More deterministic semantics,Compatibility with Ada 83 -@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{48b}@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{48c} +@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{491}@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{492} @subsection Changed semantics @@ -32206,7 +33629,7 @@ covers only the restricted range. @end itemize @node Other language compatibility issues,,Changed semantics,Compatibility with Ada 83 -@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{48d}@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{48e} +@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{493}@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{494} @subsection Other language compatibility issues @@ -32239,7 +33662,7 @@ include @code{pragma Interface} and the floating point type attributes @end itemize @node Compatibility between Ada 95 and Ada 2005,Implementation-dependent characteristics,Compatibility with Ada 83,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{48f}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{490} +@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{495}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{496} @section Compatibility between Ada 95 and Ada 2005 @@ -32311,7 +33734,7 @@ can declare a function returning a value from an anonymous access type. @end itemize @node Implementation-dependent characteristics,Compatibility with Other Ada Systems,Compatibility between Ada 95 and Ada 2005,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{491}@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{492} +@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{497}@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{498} @section Implementation-dependent characteristics @@ -32334,7 +33757,7 @@ transition from certain Ada 83 compilers. @end menu @node Implementation-defined pragmas,Implementation-defined attributes,,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{493}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{494} +@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{499}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{49a} @subsection Implementation-defined pragmas @@ -32356,7 +33779,7 @@ avoiding compiler rejection of units that contain such pragmas; they are not relevant in a GNAT context and hence are not otherwise implemented. @node Implementation-defined attributes,Libraries,Implementation-defined pragmas,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{495}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{496} +@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{49b}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{49c} @subsection Implementation-defined attributes @@ -32370,7 +33793,7 @@ Ada 83, GNAT supplies the attributes @code{Bit}, @code{Machine_Size} and @code{Type_Class}. @node Libraries,Elaboration order,Implementation-defined attributes,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{497}@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{498} +@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{49d}@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{49e} @subsection Libraries @@ -32399,7 +33822,7 @@ be preferable to retrofit the application using modular types. @end itemize @node Elaboration order,Target-specific aspects,Libraries,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{499}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{49a} +@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{49f}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{4a0} @subsection Elaboration order @@ -32435,7 +33858,7 @@ pragmas either globally (as an effect of the `-gnatE' switch) or locally @end itemize @node Target-specific aspects,,Elaboration order,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{49b}@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{49c} +@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{4a1}@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{4a2} @subsection Target-specific aspects @@ -32445,13 +33868,13 @@ such an Ada 83 application is being ported to different target hardware (for example where the byte endianness has changed) then you will need to carefully examine the program logic; the porting effort will heavily depend on the robustness of the original design. Moreover, Ada 95 (and thus -Ada 2005 and Ada 2012) are sometimes +Ada 2005, Ada 2012, and Ada 2022) are sometimes incompatible with typical Ada 83 compiler practices regarding implicit packing, the meaning of the Size attribute, and the size of access values. -GNAT’s approach to these issues is described in @ref{49d,,Representation Clauses}. +GNAT’s approach to these issues is described in @ref{4a3,,Representation Clauses}. @node Compatibility with Other Ada Systems,Representation Clauses,Implementation-dependent characteristics,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{49e}@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{49f} +@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{4a4}@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{4a5} @section Compatibility with Other Ada Systems @@ -32494,7 +33917,7 @@ far beyond this minimal set, as described in the next section. @end itemize @node Representation Clauses,Compatibility with HP Ada 83,Compatibility with Other Ada Systems,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{4a0}@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{49d} +@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{4a6}@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{4a3} @section Representation Clauses @@ -32587,7 +34010,7 @@ with thin pointers. @end itemize @node Compatibility with HP Ada 83,,Representation Clauses,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{4a1}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{4a2} +@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{4a7}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{4a8} @section Compatibility with HP Ada 83 @@ -32617,7 +34040,7 @@ extension of package System. @end itemize @node GNU Free Documentation License,Index,Compatibility and Porting Guide,Top -@anchor{share/gnu_free_documentation_license doc}@anchor{4a3}@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{4a4} +@anchor{share/gnu_free_documentation_license doc}@anchor{4a9}@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{4aa} @chapter GNU Free Documentation License diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi index 2579b31a7fcc..7b3175e3d279 100644 --- a/gcc/ada/gnat_ugn.texi +++ b/gcc/ada/gnat_ugn.texi @@ -3,7 +3,7 @@ @setfilename gnat_ugn.info @documentencoding UTF-8 @ifinfo -@*Generated by Sphinx 8.0.2.@* +@*Generated by Sphinx 8.2.3.@* @end ifinfo @settitle GNAT User's Guide for Native Platforms @defindex ge @@ -19,7 +19,7 @@ @copying @quotation -GNAT User's Guide for Native Platforms , Jan 13, 2025 +GNAT User's Guide for Native Platforms , Jun 27, 2025 AdaCore @@ -334,6 +334,7 @@ GNAT and Program Execution * Performing Dimensionality Analysis in GNAT:: * Stack Related Facilities:: * Memory Management Issues:: +* Sanitizers for Ada:: Running and Debugging Ada Programs @@ -415,6 +416,12 @@ Memory Management Issues * Some Useful Memory Pools:: * The GNAT Debug Pool Facility:: +Sanitizers for Ada + +* AddressSanitizer:: +* UndefinedBehaviorSanitizer:: +* Sanitizers in mixed-language applications:: + Platform-Specific Information * Run-Time Libraries:: @@ -2911,6 +2918,10 @@ You can place configuration pragmas either appear at the start of a compilation unit or in a configuration pragma file that applies to all compilations performed in a given compilation environment. +Configuration pragmas placed before a library level package specification +are not propagated to the corresponding package body (see RM 10.1.5(8)); +they must be added explicitly to the package body. + GNAT includes the @code{gnatchop} utility to provide an automatic way to handle configuration pragmas that follows the semantics for compilations (that is, files with multiple units) described in the RM. @@ -9846,7 +9857,7 @@ Treat pragma Restrictions as Restriction_Warnings. @table @asis -@item @code{-gnatR[0|1|2|3|4][e][j][m][s]} +@item @code{-gnatR[0|1|2|3|4][e][h][m][j][s]} Output representation information for declared types, objects and subprograms. Note that this switch is not allowed if a previous @@ -10072,7 +10083,7 @@ Library (RTL) ALI files. @code{n} controls the optimization level: -@multitable {xxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} +@multitable {xxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} @item `n' @@ -10087,7 +10098,7 @@ Effect @tab -No optimization, the default setting if no @code{-O} appears +No optimization, the default setting if no @code{-O} appears. @item @@ -10095,9 +10106,8 @@ No optimization, the default setting if no @code{-O} appears @tab -Normal optimization, the default if you specify @code{-O} without an -operand. A good compromise between code quality and compilation -time. +Moderate optimization, same as @code{-O} without an operand. +A good compromise between code quality and compilation time. @item @@ -10105,7 +10115,7 @@ time. @tab -Extensive optimization, may improve execution time, possibly at +Extensive optimization, should improve execution time, possibly at the cost of substantially increased compilation time. @item @@ -10114,8 +10124,8 @@ the cost of substantially increased compilation time. @tab -Same as @code{-O2}, and also includes inline expansion for small -subprograms in the same unit. +Full optimization, may further improve execution time, possibly at +the cost of substantially larger generated code. @item @@ -10123,7 +10133,23 @@ subprograms in the same unit. @tab -Optimize space usage +Optimize for size (code and data) rather than speed. + +@item + +`z' + +@tab + +Optimize aggressively for size (code and data) rather than speed. + +@item + +`g' + +@tab + +Optimize for debugging experience rather than speed. @end multitable @@ -15266,7 +15292,7 @@ restriction warnings rather than restrictions. @table @asis -@item @code{-gnatR[0|1|2|3|4][e][j][m][s]} +@item @code{-gnatR[0|1|2|3|4][e][h][m][j][s]} This switch controls output from the compiler of a listing showing representation information for declared types, objects and subprograms. @@ -15295,17 +15321,21 @@ If the switch is followed by an @code{e} (e.g. @code{-gnatR2e}), then extended representation information for record sub-components of records is included. +If the switch is followed by a @code{h} (e.g. @code{-gnatR3h}), then +the components of records are sorted by increasing offsets and holes +between consecutive components are flagged. + If the switch is followed by an @code{m} (e.g. @code{-gnatRm}), then subprogram conventions and parameter passing mechanisms for all the subprograms are included. -If the switch is followed by a @code{j} (e.g., @code{-gnatRj}), then +If the switch is followed by a @code{j} (e.g. @code{-gnatRj}), then the output is in the JSON data interchange format specified by the ECMA-404 standard. The semantic description of this JSON output is available in the specification of the Repinfo unit present in the compiler sources. -If the switch is followed by an @code{s} (e.g., @code{-gnatR3s}), then +If the switch is followed by an @code{s} (e.g. @code{-gnatR3s}), then the output is to a file with the name @code{file.rep} where @code{file} is the name of the corresponding source file, except if @code{j} is also specified, in which case the file name is @code{file.json}. @@ -17634,6 +17664,9 @@ file with @code{gprconfig} and using it with @code{gprbuild}; see the can determine from the first line of the @code{.ali} file which version of GNAT built that file because it contains either @code{GNAT} or @code{GNAT-LLVM}. + +You can also explicitly select GNAT LLVM in your existing GPR project +file by adding @code{for Toolchain_Name("Ada") use "GNAT_LLVM";} @end itemize @@ -18331,6 +18364,9 @@ This chapter covers several topics: @item @ref{151,,Memory Management Issues} + +@item +@ref{152,,Sanitizers for Ada} @end itemize @menu @@ -18341,11 +18377,12 @@ This chapter covers several topics: * Performing Dimensionality Analysis in GNAT:: * Stack Related Facilities:: * Memory Management Issues:: +* Sanitizers for Ada:: @end menu @node Running and Debugging Ada Programs,Profiling,,GNAT and Program Execution -@anchor{gnat_ugn/gnat_and_program_execution id2}@anchor{14b}@anchor{gnat_ugn/gnat_and_program_execution running-and-debugging-ada-programs}@anchor{152} +@anchor{gnat_ugn/gnat_and_program_execution id2}@anchor{14b}@anchor{gnat_ugn/gnat_and_program_execution running-and-debugging-ada-programs}@anchor{153} @section Running and Debugging Ada Programs @@ -18399,7 +18436,7 @@ the incorrect user program. @end menu @node The GNAT Debugger GDB,Running GDB,,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution id3}@anchor{153}@anchor{gnat_ugn/gnat_and_program_execution the-gnat-debugger-gdb}@anchor{154} +@anchor{gnat_ugn/gnat_and_program_execution id3}@anchor{154}@anchor{gnat_ugn/gnat_and_program_execution the-gnat-debugger-gdb}@anchor{155} @subsection The GNAT Debugger GDB @@ -18457,7 +18494,7 @@ the debugging information and can respond to user commands to inspect variables and more generally to report on the state of execution. @node Running GDB,Introduction to GDB Commands,The GNAT Debugger GDB,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution id4}@anchor{155}@anchor{gnat_ugn/gnat_and_program_execution running-gdb}@anchor{156} +@anchor{gnat_ugn/gnat_and_program_execution id4}@anchor{156}@anchor{gnat_ugn/gnat_and_program_execution running-gdb}@anchor{157} @subsection Running GDB @@ -18484,7 +18521,7 @@ exactly as if the debugger were not present. The following section describes some of the additional commands that you can give to @code{GDB}. @node Introduction to GDB Commands,Using Ada Expressions,Running GDB,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution id5}@anchor{157}@anchor{gnat_ugn/gnat_and_program_execution introduction-to-gdb-commands}@anchor{158} +@anchor{gnat_ugn/gnat_and_program_execution id5}@anchor{158}@anchor{gnat_ugn/gnat_and_program_execution introduction-to-gdb-commands}@anchor{159} @subsection Introduction to GDB Commands @@ -18698,7 +18735,7 @@ characters need be typed to disambiguate the command (e.g., “br” for @code{breakpoint}). @node Using Ada Expressions,Calling User-Defined Subprograms,Introduction to GDB Commands,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution id6}@anchor{159}@anchor{gnat_ugn/gnat_and_program_execution using-ada-expressions}@anchor{15a} +@anchor{gnat_ugn/gnat_and_program_execution id6}@anchor{15a}@anchor{gnat_ugn/gnat_and_program_execution using-ada-expressions}@anchor{15b} @subsection Using Ada Expressions @@ -18736,7 +18773,7 @@ their packages, regardless of context. Where this causes ambiguity, For details on the supported Ada syntax, see @cite{Debugging with GDB}. @node Calling User-Defined Subprograms,Using the next Command in a Function,Using Ada Expressions,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution calling-user-defined-subprograms}@anchor{15b}@anchor{gnat_ugn/gnat_and_program_execution id7}@anchor{15c} +@anchor{gnat_ugn/gnat_and_program_execution calling-user-defined-subprograms}@anchor{15c}@anchor{gnat_ugn/gnat_and_program_execution id7}@anchor{15d} @subsection Calling User-Defined Subprograms @@ -18795,7 +18832,7 @@ elements directly from GDB, you can write a callable procedure that prints the elements in the format you desire. @node Using the next Command in a Function,Stopping When Ada Exceptions Are Raised,Calling User-Defined Subprograms,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution id8}@anchor{15d}@anchor{gnat_ugn/gnat_and_program_execution using-the-next-command-in-a-function}@anchor{15e} +@anchor{gnat_ugn/gnat_and_program_execution id8}@anchor{15e}@anchor{gnat_ugn/gnat_and_program_execution using-the-next-command-in-a-function}@anchor{15f} @subsection Using the `next' Command in a Function @@ -18818,7 +18855,7 @@ The value returned is always that from the first return statement that was stepped through. @node Stopping When Ada Exceptions Are Raised,Ada Tasks,Using the next Command in a Function,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution id9}@anchor{15f}@anchor{gnat_ugn/gnat_and_program_execution stopping-when-ada-exceptions-are-raised}@anchor{160} +@anchor{gnat_ugn/gnat_and_program_execution id9}@anchor{160}@anchor{gnat_ugn/gnat_and_program_execution stopping-when-ada-exceptions-are-raised}@anchor{161} @subsection Stopping When Ada Exceptions Are Raised @@ -18875,7 +18912,7 @@ argument, prints out only those exceptions whose name matches `regexp'. @geindex Tasks (in gdb) @node Ada Tasks,Debugging Generic Units,Stopping When Ada Exceptions Are Raised,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution ada-tasks}@anchor{161}@anchor{gnat_ugn/gnat_and_program_execution id10}@anchor{162} +@anchor{gnat_ugn/gnat_and_program_execution ada-tasks}@anchor{162}@anchor{gnat_ugn/gnat_and_program_execution id10}@anchor{163} @subsection Ada Tasks @@ -18962,7 +18999,7 @@ see @cite{Debugging with GDB}. @geindex Generics @node Debugging Generic Units,Remote Debugging with gdbserver,Ada Tasks,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution debugging-generic-units}@anchor{163}@anchor{gnat_ugn/gnat_and_program_execution id11}@anchor{164} +@anchor{gnat_ugn/gnat_and_program_execution debugging-generic-units}@anchor{164}@anchor{gnat_ugn/gnat_and_program_execution id11}@anchor{165} @subsection Debugging Generic Units @@ -19022,7 +19059,7 @@ variables, as you do for other units. @geindex Remote Debugging with gdbserver @node Remote Debugging with gdbserver,GNAT Abnormal Termination or Failure to Terminate,Debugging Generic Units,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution id12}@anchor{165}@anchor{gnat_ugn/gnat_and_program_execution remote-debugging-with-gdbserver}@anchor{166} +@anchor{gnat_ugn/gnat_and_program_execution id12}@anchor{166}@anchor{gnat_ugn/gnat_and_program_execution remote-debugging-with-gdbserver}@anchor{167} @subsection Remote Debugging with gdbserver @@ -19081,7 +19118,7 @@ x86_64-linux. @geindex Abnormal Termination or Failure to Terminate @node GNAT Abnormal Termination or Failure to Terminate,Naming Conventions for GNAT Source Files,Remote Debugging with gdbserver,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution gnat-abnormal-termination-or-failure-to-terminate}@anchor{167}@anchor{gnat_ugn/gnat_and_program_execution id13}@anchor{168} +@anchor{gnat_ugn/gnat_and_program_execution gnat-abnormal-termination-or-failure-to-terminate}@anchor{168}@anchor{gnat_ugn/gnat_and_program_execution id13}@anchor{169} @subsection GNAT Abnormal Termination or Failure to Terminate @@ -19136,7 +19173,7 @@ Finally, you can start @code{gdb} directly on the @code{gnat1} executable. @code{gnat1} is the front-end of GNAT and can be run independently (normally it is just called from @code{gcc}). You can use @code{gdb} on @code{gnat1} as you -would on a C program (but @ref{154,,The GNAT Debugger GDB} for caveats). The +would on a C program (but @ref{155,,The GNAT Debugger GDB} for caveats). The @code{where} command is the first line of attack; the variable @code{lineno} (seen by @code{print lineno}), used by the second phase of @code{gnat1} and by the @code{gcc} back end, indicates the source line at @@ -19145,7 +19182,7 @@ the source file. @end itemize @node Naming Conventions for GNAT Source Files,Getting Internal Debugging Information,GNAT Abnormal Termination or Failure to Terminate,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution id14}@anchor{169}@anchor{gnat_ugn/gnat_and_program_execution naming-conventions-for-gnat-source-files}@anchor{16a} +@anchor{gnat_ugn/gnat_and_program_execution id14}@anchor{16a}@anchor{gnat_ugn/gnat_and_program_execution naming-conventions-for-gnat-source-files}@anchor{16b} @subsection Naming Conventions for GNAT Source Files @@ -19235,7 +19272,7 @@ the other @code{.c} files are modifications of common @code{gcc} files. @end itemize @node Getting Internal Debugging Information,Stack Traceback,Naming Conventions for GNAT Source Files,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution getting-internal-debugging-information}@anchor{16b}@anchor{gnat_ugn/gnat_and_program_execution id15}@anchor{16c} +@anchor{gnat_ugn/gnat_and_program_execution getting-internal-debugging-information}@anchor{16c}@anchor{gnat_ugn/gnat_and_program_execution id15}@anchor{16d} @subsection Getting Internal Debugging Information @@ -19263,7 +19300,7 @@ are replaced with run-time calls. @geindex stack unwinding @node Stack Traceback,Pretty-Printers for the GNAT runtime,Getting Internal Debugging Information,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution id16}@anchor{16d}@anchor{gnat_ugn/gnat_and_program_execution stack-traceback}@anchor{16e} +@anchor{gnat_ugn/gnat_and_program_execution id16}@anchor{16e}@anchor{gnat_ugn/gnat_and_program_execution stack-traceback}@anchor{16f} @subsection Stack Traceback @@ -19292,7 +19329,7 @@ is enabled and no exception is raised during program execution. @end menu @node Non-Symbolic Traceback,Symbolic Traceback,,Stack Traceback -@anchor{gnat_ugn/gnat_and_program_execution id17}@anchor{16f}@anchor{gnat_ugn/gnat_and_program_execution non-symbolic-traceback}@anchor{170} +@anchor{gnat_ugn/gnat_and_program_execution id17}@anchor{170}@anchor{gnat_ugn/gnat_and_program_execution non-symbolic-traceback}@anchor{171} @subsubsection Non-Symbolic Traceback @@ -19614,7 +19651,7 @@ addresses need to be specified in C format, with a leading ‘0x’). @geindex symbolic @node Symbolic Traceback,,Non-Symbolic Traceback,Stack Traceback -@anchor{gnat_ugn/gnat_and_program_execution id18}@anchor{171}@anchor{gnat_ugn/gnat_and_program_execution symbolic-traceback}@anchor{172} +@anchor{gnat_ugn/gnat_and_program_execution id18}@anchor{172}@anchor{gnat_ugn/gnat_and_program_execution symbolic-traceback}@anchor{173} @subsubsection Symbolic Traceback @@ -19733,7 +19770,7 @@ traceback, which will also be printed if an unhandled exception terminates the program. @node Pretty-Printers for the GNAT runtime,,Stack Traceback,Running and Debugging Ada Programs -@anchor{gnat_ugn/gnat_and_program_execution id19}@anchor{173}@anchor{gnat_ugn/gnat_and_program_execution pretty-printers-for-the-gnat-runtime}@anchor{174} +@anchor{gnat_ugn/gnat_and_program_execution id19}@anchor{174}@anchor{gnat_ugn/gnat_and_program_execution pretty-printers-for-the-gnat-runtime}@anchor{175} @subsection Pretty-Printers for the GNAT runtime @@ -19842,7 +19879,7 @@ for more information. @geindex Profiling @node Profiling,Improving Performance,Running and Debugging Ada Programs,GNAT and Program Execution -@anchor{gnat_ugn/gnat_and_program_execution id20}@anchor{175}@anchor{gnat_ugn/gnat_and_program_execution profiling}@anchor{14c} +@anchor{gnat_ugn/gnat_and_program_execution id20}@anchor{176}@anchor{gnat_ugn/gnat_and_program_execution profiling}@anchor{14c} @section Profiling @@ -19858,7 +19895,7 @@ This section describes how to use the @code{gprof} profiler tool on Ada programs @end menu @node Profiling an Ada Program with gprof,,,Profiling -@anchor{gnat_ugn/gnat_and_program_execution id21}@anchor{176}@anchor{gnat_ugn/gnat_and_program_execution profiling-an-ada-program-with-gprof}@anchor{177} +@anchor{gnat_ugn/gnat_and_program_execution id21}@anchor{177}@anchor{gnat_ugn/gnat_and_program_execution profiling-an-ada-program-with-gprof}@anchor{178} @subsection Profiling an Ada Program with gprof @@ -19913,7 +19950,7 @@ to interpret the results. @end menu @node Compilation for profiling,Program execution,,Profiling an Ada Program with gprof -@anchor{gnat_ugn/gnat_and_program_execution compilation-for-profiling}@anchor{178}@anchor{gnat_ugn/gnat_and_program_execution id22}@anchor{179} +@anchor{gnat_ugn/gnat_and_program_execution compilation-for-profiling}@anchor{179}@anchor{gnat_ugn/gnat_and_program_execution id22}@anchor{17a} @subsubsection Compilation for profiling @@ -19944,7 +19981,7 @@ Note that on Windows, @code{gprof} does not support PIE. You should add the @code{-no-pie} switch to the linker flags to disable PIE. @node Program execution,Running gprof,Compilation for profiling,Profiling an Ada Program with gprof -@anchor{gnat_ugn/gnat_and_program_execution id23}@anchor{17a}@anchor{gnat_ugn/gnat_and_program_execution program-execution}@anchor{17b} +@anchor{gnat_ugn/gnat_and_program_execution id23}@anchor{17b}@anchor{gnat_ugn/gnat_and_program_execution program-execution}@anchor{17c} @subsubsection Program execution @@ -19959,7 +19996,7 @@ generated in the directory where the program was launched from. If this file already exists, it will be overwritten by running the program. @node Running gprof,Interpretation of profiling results,Program execution,Profiling an Ada Program with gprof -@anchor{gnat_ugn/gnat_and_program_execution id24}@anchor{17c}@anchor{gnat_ugn/gnat_and_program_execution running-gprof}@anchor{17d} +@anchor{gnat_ugn/gnat_and_program_execution id24}@anchor{17d}@anchor{gnat_ugn/gnat_and_program_execution running-gprof}@anchor{17e} @subsubsection Running gprof @@ -20071,7 +20108,7 @@ switch. @end table @node Interpretation of profiling results,,Running gprof,Profiling an Ada Program with gprof -@anchor{gnat_ugn/gnat_and_program_execution id25}@anchor{17e}@anchor{gnat_ugn/gnat_and_program_execution interpretation-of-profiling-results}@anchor{17f} +@anchor{gnat_ugn/gnat_and_program_execution id25}@anchor{17f}@anchor{gnat_ugn/gnat_and_program_execution interpretation-of-profiling-results}@anchor{180} @subsubsection Interpretation of profiling results @@ -20088,7 +20125,7 @@ and the subprograms that it calls. It also provides an estimate of the time spent in each of those callers and called subprograms. @node Improving Performance,Overflow Check Handling in GNAT,Profiling,GNAT and Program Execution -@anchor{gnat_ugn/gnat_and_program_execution id26}@anchor{14d}@anchor{gnat_ugn/gnat_and_program_execution improving-performance}@anchor{180} +@anchor{gnat_ugn/gnat_and_program_execution id26}@anchor{14d}@anchor{gnat_ugn/gnat_and_program_execution improving-performance}@anchor{181} @section Improving Performance @@ -20109,7 +20146,7 @@ which can reduce the size of program executables. @end menu @node Performance Considerations,Text_IO Suggestions,,Improving Performance -@anchor{gnat_ugn/gnat_and_program_execution id27}@anchor{181}@anchor{gnat_ugn/gnat_and_program_execution performance-considerations}@anchor{182} +@anchor{gnat_ugn/gnat_and_program_execution id27}@anchor{182}@anchor{gnat_ugn/gnat_and_program_execution performance-considerations}@anchor{183} @subsection Performance Considerations @@ -20170,7 +20207,7 @@ some guidelines on debugging optimized code. @end menu @node Controlling Run-Time Checks,Use of Restrictions,,Performance Considerations -@anchor{gnat_ugn/gnat_and_program_execution controlling-run-time-checks}@anchor{183}@anchor{gnat_ugn/gnat_and_program_execution id28}@anchor{184} +@anchor{gnat_ugn/gnat_and_program_execution controlling-run-time-checks}@anchor{184}@anchor{gnat_ugn/gnat_and_program_execution id28}@anchor{185} @subsubsection Controlling Run-Time Checks @@ -20222,7 +20259,7 @@ remove checks) or @code{pragma Unsuppress} (to add back suppressed checks) in your program source. @node Use of Restrictions,Optimization Levels,Controlling Run-Time Checks,Performance Considerations -@anchor{gnat_ugn/gnat_and_program_execution id29}@anchor{185}@anchor{gnat_ugn/gnat_and_program_execution use-of-restrictions}@anchor{186} +@anchor{gnat_ugn/gnat_and_program_execution id29}@anchor{186}@anchor{gnat_ugn/gnat_and_program_execution use-of-restrictions}@anchor{187} @subsubsection Use of Restrictions @@ -20258,7 +20295,7 @@ this, it also means you can write code without worrying about the possibility of an immediate abort at any point. @node Optimization Levels,Debugging Optimized Code,Use of Restrictions,Performance Considerations -@anchor{gnat_ugn/gnat_and_program_execution id30}@anchor{187}@anchor{gnat_ugn/gnat_and_program_execution optimization-levels}@anchor{f0} +@anchor{gnat_ugn/gnat_and_program_execution id30}@anchor{188}@anchor{gnat_ugn/gnat_and_program_execution optimization-levels}@anchor{f0} @subsubsection Optimization Levels @@ -20277,13 +20314,12 @@ Turning on optimization makes the compiler attempt to improve the performance and/or code size at the expense of compilation time and possibly the ability to debug the program. -If you use multiple @code{-O} switches, with or without level -numbers, the last such switch is the one that’s used. - -You can use the -@code{-O} switch (the permitted forms are @code{-O0}, @code{-O1} -@code{-O2}, @code{-O3}, and @code{-Os}) -to @code{gcc} to control the optimization level: +You can pass the @code{-O} switch, with or without an operand +(the permitted forms with an operand are @code{-O0}, @code{-O1}, +@code{-O2}, @code{-O3}, @code{-Os}, @code{-Oz}, and +@code{-Og}) to @code{gcc} to control the optimization level. If you +pass multiple @code{-O} switches, with or without an operand, +the last such switch is the one that’s used: @itemize * @@ -20294,8 +20330,7 @@ to @code{gcc} to control the optimization level: @item @code{-O0} -No optimization (the default); -generates unoptimized code but has +No optimization (the default); generates unoptimized code but has the fastest compilation time. Debugging is easiest with this switch. Note that many other compilers do substantial optimization even if @@ -20312,10 +20347,11 @@ mind when doing performance comparisons. @item @code{-O1} -Moderate optimization; optimizes reasonably well but does not -degrade compilation time significantly. You may not be able to see -some variables in the debugger and changing the value of some -variables in the debugger may not have the effect you desire. +Moderate optimization (same as @code{-O} without an operand); +optimizes reasonably well but does not degrade compilation time +significantly. You may not be able to see some variables in the +debugger, and changing the value of some variables in the debugger +may not have the effect you desire. @end table @item @@ -20324,9 +20360,8 @@ variables in the debugger may not have the effect you desire. @item @code{-O2} -Full optimization; -generates highly optimized code and has -the slowest compilation time. You may see significant impacts on +Extensive optimization; generates highly optimized code but has +an increased compilation time. You may see significant impacts on your ability to display and modify variables in the debugger. @end table @@ -20336,9 +20371,9 @@ your ability to display and modify variables in the debugger. @item @code{-O3} -Full optimization as in @code{-O2}; -also uses more aggressive automatic inlining of subprograms within a unit -(@ref{104,,Inlining of Subprograms}) and attempts to vectorize loops. +Full optimization; attempts more sophisticated transformations, in +particular on loops, possibly at the cost of larger generated code. +You may be hardly able to use the debugger at this optimization level. @end table @item @@ -20347,16 +20382,41 @@ also uses more aggressive automatic inlining of subprograms within a unit @item @code{-Os} -Optimize space usage (code and data) of resulting program. +Optimize for size (code and data) of resulting binary rather than +speed; based on the @code{-O2} optimization level, but disables +some of its transformations that often increase code size, as well +as performs further optimizations designed to reduce code size. +@end table + +@item + +@table @asis + +@item @code{-Oz} + +Optimize aggressively for size (code and data) of resulting binary +rather than speed; may increase the number of instructions executed +if these instructions require fewer bytes to be encoded. +@end table + +@item + +@table @asis + +@item @code{-Og} + +Optimize for debugging experience rather than speed; based on the +@code{-O1} optimization level, but attempts to eliminate all the +negative effects of optimization on debugging. @end table @end itemize Higher optimization levels perform more global transformations on the program and apply more expensive analysis algorithms in order to generate faster and more compact code. The price in compilation time, and the -resulting improvement in execution time, -both depend on the particular application and the hardware environment. -You should experiment to find the best level for your application. +resulting improvement in execution time, both depend on the particular +application and the hardware environment. You should experiment to find +the best level for your application. Since the precise set of optimizations done at each level will vary from release to release (and sometime from target to target), it is best to think @@ -20381,7 +20441,7 @@ since it often results in larger executables which may run more slowly. See further discussion of this point in @ref{104,,Inlining of Subprograms}. @node Debugging Optimized Code,Inlining of Subprograms,Optimization Levels,Performance Considerations -@anchor{gnat_ugn/gnat_and_program_execution debugging-optimized-code}@anchor{188}@anchor{gnat_ugn/gnat_and_program_execution id31}@anchor{189} +@anchor{gnat_ugn/gnat_and_program_execution debugging-optimized-code}@anchor{189}@anchor{gnat_ugn/gnat_and_program_execution id31}@anchor{18a} @subsubsection Debugging Optimized Code @@ -20509,7 +20569,7 @@ on the resulting executable, which removes both debugging information and global symbols. @node Inlining of Subprograms,Floating Point Operations,Debugging Optimized Code,Performance Considerations -@anchor{gnat_ugn/gnat_and_program_execution id32}@anchor{18a}@anchor{gnat_ugn/gnat_and_program_execution inlining-of-subprograms}@anchor{104} +@anchor{gnat_ugn/gnat_and_program_execution id32}@anchor{18b}@anchor{gnat_ugn/gnat_and_program_execution inlining-of-subprograms}@anchor{104} @subsubsection Inlining of Subprograms @@ -20653,7 +20713,7 @@ indeed you should use @code{-O3} only if tests show that it actually improves performance for your program. @node Floating Point Operations,Vectorization of loops,Inlining of Subprograms,Performance Considerations -@anchor{gnat_ugn/gnat_and_program_execution floating-point-operations}@anchor{18b}@anchor{gnat_ugn/gnat_and_program_execution id33}@anchor{18c} +@anchor{gnat_ugn/gnat_and_program_execution floating-point-operations}@anchor{18c}@anchor{gnat_ugn/gnat_and_program_execution id33}@anchor{18d} @subsubsection Floating Point Operations @@ -20700,7 +20760,7 @@ Note that the ABI has the same form for both floating-point models, so you can mix units compiled with and without these switches. @node Vectorization of loops,Other Optimization Switches,Floating Point Operations,Performance Considerations -@anchor{gnat_ugn/gnat_and_program_execution id34}@anchor{18d}@anchor{gnat_ugn/gnat_and_program_execution vectorization-of-loops}@anchor{18e} +@anchor{gnat_ugn/gnat_and_program_execution id34}@anchor{18e}@anchor{gnat_ugn/gnat_and_program_execution vectorization-of-loops}@anchor{18f} @subsubsection Vectorization of loops @@ -20856,7 +20916,7 @@ omit the non-vectorized version of the loop as well as the run-time test. This is also currently only supported by the GCC back end. @node Other Optimization Switches,Optimization and Strict Aliasing,Vectorization of loops,Performance Considerations -@anchor{gnat_ugn/gnat_and_program_execution id35}@anchor{18f}@anchor{gnat_ugn/gnat_and_program_execution other-optimization-switches}@anchor{190} +@anchor{gnat_ugn/gnat_and_program_execution id35}@anchor{190}@anchor{gnat_ugn/gnat_and_program_execution other-optimization-switches}@anchor{191} @subsubsection Other Optimization Switches @@ -20873,7 +20933,7 @@ full details of these switches, see the `Submodel Options' section in the `Hardware Models and Configurations' chapter of @cite{Using the GNU Compiler Collection (GCC)}. @node Optimization and Strict Aliasing,Aliased Variables and Optimization,Other Optimization Switches,Performance Considerations -@anchor{gnat_ugn/gnat_and_program_execution id36}@anchor{191}@anchor{gnat_ugn/gnat_and_program_execution optimization-and-strict-aliasing}@anchor{e7} +@anchor{gnat_ugn/gnat_and_program_execution id36}@anchor{192}@anchor{gnat_ugn/gnat_and_program_execution optimization-and-strict-aliasing}@anchor{e7} @subsubsection Optimization and Strict Aliasing @@ -21167,7 +21227,7 @@ review any uses of unchecked conversion, particularly if you are getting the warnings described above. @node Aliased Variables and Optimization,Atomic Variables and Optimization,Optimization and Strict Aliasing,Performance Considerations -@anchor{gnat_ugn/gnat_and_program_execution aliased-variables-and-optimization}@anchor{192}@anchor{gnat_ugn/gnat_and_program_execution id37}@anchor{193} +@anchor{gnat_ugn/gnat_and_program_execution aliased-variables-and-optimization}@anchor{193}@anchor{gnat_ugn/gnat_and_program_execution id37}@anchor{194} @subsubsection Aliased Variables and Optimization @@ -21227,7 +21287,7 @@ avoid code such as this if possible because it’s not portable and may not functin as you expect with all compilers. @node Atomic Variables and Optimization,Passive Task Optimization,Aliased Variables and Optimization,Performance Considerations -@anchor{gnat_ugn/gnat_and_program_execution atomic-variables-and-optimization}@anchor{194}@anchor{gnat_ugn/gnat_and_program_execution id38}@anchor{195} +@anchor{gnat_ugn/gnat_and_program_execution atomic-variables-and-optimization}@anchor{195}@anchor{gnat_ugn/gnat_and_program_execution id38}@anchor{196} @subsubsection Atomic Variables and Optimization @@ -21308,7 +21368,7 @@ such synchronization code is not required, you may find it useful to disable it. @node Passive Task Optimization,,Atomic Variables and Optimization,Performance Considerations -@anchor{gnat_ugn/gnat_and_program_execution id39}@anchor{196}@anchor{gnat_ugn/gnat_and_program_execution passive-task-optimization}@anchor{197} +@anchor{gnat_ugn/gnat_and_program_execution id39}@anchor{197}@anchor{gnat_ugn/gnat_and_program_execution passive-task-optimization}@anchor{198} @subsubsection Passive Task Optimization @@ -21353,7 +21413,7 @@ that typically clients of the tasks who call entries will not have to be modified, only the task definitions themselves. @node Text_IO Suggestions,Reducing Size of Executables with Unused Subprogram/Data Elimination,Performance Considerations,Improving Performance -@anchor{gnat_ugn/gnat_and_program_execution id40}@anchor{198}@anchor{gnat_ugn/gnat_and_program_execution text-io-suggestions}@anchor{199} +@anchor{gnat_ugn/gnat_and_program_execution id40}@anchor{199}@anchor{gnat_ugn/gnat_and_program_execution text-io-suggestions}@anchor{19a} @subsection @code{Text_IO} Suggestions @@ -21376,7 +21436,7 @@ of the standard output file or change the standard output file to be buffered using @code{Interfaces.C_Streams.setvbuf}. @node Reducing Size of Executables with Unused Subprogram/Data Elimination,,Text_IO Suggestions,Improving Performance -@anchor{gnat_ugn/gnat_and_program_execution id41}@anchor{19a}@anchor{gnat_ugn/gnat_and_program_execution reducing-size-of-executables-with-unused-subprogram-data-elimination}@anchor{19b} +@anchor{gnat_ugn/gnat_and_program_execution id41}@anchor{19b}@anchor{gnat_ugn/gnat_and_program_execution reducing-size-of-executables-with-unused-subprogram-data-elimination}@anchor{19c} @subsection Reducing Size of Executables with Unused Subprogram/Data Elimination @@ -21393,7 +21453,7 @@ your executable just by setting options at compilation time. @end menu @node About unused subprogram/data elimination,Compilation options,,Reducing Size of Executables with Unused Subprogram/Data Elimination -@anchor{gnat_ugn/gnat_and_program_execution about-unused-subprogram-data-elimination}@anchor{19c}@anchor{gnat_ugn/gnat_and_program_execution id42}@anchor{19d} +@anchor{gnat_ugn/gnat_and_program_execution about-unused-subprogram-data-elimination}@anchor{19d}@anchor{gnat_ugn/gnat_and_program_execution id42}@anchor{19e} @subsubsection About unused subprogram/data elimination @@ -21407,7 +21467,7 @@ architecture and on all cross platforms using the ELF binary file format. In both cases, GNU binutils version 2.16 or later are required to enable it. @node Compilation options,Example of unused subprogram/data elimination,About unused subprogram/data elimination,Reducing Size of Executables with Unused Subprogram/Data Elimination -@anchor{gnat_ugn/gnat_and_program_execution compilation-options}@anchor{19e}@anchor{gnat_ugn/gnat_and_program_execution id43}@anchor{19f} +@anchor{gnat_ugn/gnat_and_program_execution compilation-options}@anchor{19f}@anchor{gnat_ugn/gnat_and_program_execution id43}@anchor{1a0} @subsubsection Compilation options @@ -21448,7 +21508,7 @@ eliminate the unused code and data of the GNAT library from your executable. @node Example of unused subprogram/data elimination,,Compilation options,Reducing Size of Executables with Unused Subprogram/Data Elimination -@anchor{gnat_ugn/gnat_and_program_execution example-of-unused-subprogram-data-elimination}@anchor{1a0}@anchor{gnat_ugn/gnat_and_program_execution id44}@anchor{1a1} +@anchor{gnat_ugn/gnat_and_program_execution example-of-unused-subprogram-data-elimination}@anchor{1a1}@anchor{gnat_ugn/gnat_and_program_execution id44}@anchor{1a2} @subsubsection Example of unused subprogram/data elimination @@ -21518,7 +21578,7 @@ appropriate switches. @geindex Checks (overflow) @node Overflow Check Handling in GNAT,Performing Dimensionality Analysis in GNAT,Improving Performance,GNAT and Program Execution -@anchor{gnat_ugn/gnat_and_program_execution id45}@anchor{14e}@anchor{gnat_ugn/gnat_and_program_execution overflow-check-handling-in-gnat}@anchor{1a2} +@anchor{gnat_ugn/gnat_and_program_execution id45}@anchor{14e}@anchor{gnat_ugn/gnat_and_program_execution overflow-check-handling-in-gnat}@anchor{1a3} @section Overflow Check Handling in GNAT @@ -21534,7 +21594,7 @@ This section explains how to control the handling of overflow checks. @end menu @node Background,Management of Overflows in GNAT,,Overflow Check Handling in GNAT -@anchor{gnat_ugn/gnat_and_program_execution background}@anchor{1a3}@anchor{gnat_ugn/gnat_and_program_execution id46}@anchor{1a4} +@anchor{gnat_ugn/gnat_and_program_execution background}@anchor{1a4}@anchor{gnat_ugn/gnat_and_program_execution id46}@anchor{1a5} @subsection Background @@ -21660,7 +21720,7 @@ exception raised because of the intermediate overflow (and we really would prefer this precondition to be considered @code{True} at run time). @node Management of Overflows in GNAT,Specifying the Desired Mode,Background,Overflow Check Handling in GNAT -@anchor{gnat_ugn/gnat_and_program_execution id47}@anchor{1a5}@anchor{gnat_ugn/gnat_and_program_execution management-of-overflows-in-gnat}@anchor{1a6} +@anchor{gnat_ugn/gnat_and_program_execution id47}@anchor{1a6}@anchor{gnat_ugn/gnat_and_program_execution management-of-overflows-in-gnat}@anchor{1a7} @subsection Management of Overflows in GNAT @@ -21774,7 +21834,7 @@ out in the normal manner (with infinite values always failing all range checks). @node Specifying the Desired Mode,Default Settings,Management of Overflows in GNAT,Overflow Check Handling in GNAT -@anchor{gnat_ugn/gnat_and_program_execution id48}@anchor{1a7}@anchor{gnat_ugn/gnat_and_program_execution specifying-the-desired-mode}@anchor{ec} +@anchor{gnat_ugn/gnat_and_program_execution id48}@anchor{1a8}@anchor{gnat_ugn/gnat_and_program_execution specifying-the-desired-mode}@anchor{ec} @subsection Specifying the Desired Mode @@ -21898,7 +21958,7 @@ equivalent to @code{-gnato11}, causing all intermediate operations to be computed using the base type (@code{STRICT} mode). @node Default Settings,Implementation Notes,Specifying the Desired Mode,Overflow Check Handling in GNAT -@anchor{gnat_ugn/gnat_and_program_execution default-settings}@anchor{1a8}@anchor{gnat_ugn/gnat_and_program_execution id49}@anchor{1a9} +@anchor{gnat_ugn/gnat_and_program_execution default-settings}@anchor{1a9}@anchor{gnat_ugn/gnat_and_program_execution id49}@anchor{1aa} @subsection Default Settings @@ -21922,7 +21982,7 @@ checking but has no effect on the method used for computing intermediate results. @node Implementation Notes,,Default Settings,Overflow Check Handling in GNAT -@anchor{gnat_ugn/gnat_and_program_execution id50}@anchor{1aa}@anchor{gnat_ugn/gnat_and_program_execution implementation-notes}@anchor{1ab} +@anchor{gnat_ugn/gnat_and_program_execution id50}@anchor{1ab}@anchor{gnat_ugn/gnat_and_program_execution implementation-notes}@anchor{1ac} @subsection Implementation Notes @@ -21970,7 +22030,7 @@ platforms for which @code{Long_Long_Integer} is at least 64-bits (nearly all GNA platforms). @node Performing Dimensionality Analysis in GNAT,Stack Related Facilities,Overflow Check Handling in GNAT,GNAT and Program Execution -@anchor{gnat_ugn/gnat_and_program_execution id51}@anchor{14f}@anchor{gnat_ugn/gnat_and_program_execution performing-dimensionality-analysis-in-gnat}@anchor{1ac} +@anchor{gnat_ugn/gnat_and_program_execution id51}@anchor{14f}@anchor{gnat_ugn/gnat_and_program_execution performing-dimensionality-analysis-in-gnat}@anchor{1ad} @section Performing Dimensionality Analysis in GNAT @@ -22373,7 +22433,7 @@ package Mks_Numerics is new @end quotation @node Stack Related Facilities,Memory Management Issues,Performing Dimensionality Analysis in GNAT,GNAT and Program Execution -@anchor{gnat_ugn/gnat_and_program_execution id52}@anchor{150}@anchor{gnat_ugn/gnat_and_program_execution stack-related-facilities}@anchor{1ad} +@anchor{gnat_ugn/gnat_and_program_execution id52}@anchor{150}@anchor{gnat_ugn/gnat_and_program_execution stack-related-facilities}@anchor{1ae} @section Stack Related Facilities @@ -22389,7 +22449,7 @@ particular, it deals with dynamic and static stack usage measurements. @end menu @node Stack Overflow Checking,Static Stack Usage Analysis,,Stack Related Facilities -@anchor{gnat_ugn/gnat_and_program_execution id53}@anchor{1ae}@anchor{gnat_ugn/gnat_and_program_execution stack-overflow-checking}@anchor{e8} +@anchor{gnat_ugn/gnat_and_program_execution id53}@anchor{1af}@anchor{gnat_ugn/gnat_and_program_execution stack-overflow-checking}@anchor{e8} @subsection Stack Overflow Checking @@ -22437,7 +22497,7 @@ When using the LLVM back end, this switch doesn’t perform full stack overflow checking, but just checks for very large local dynamic allocations. @node Static Stack Usage Analysis,Dynamic Stack Usage Analysis,Stack Overflow Checking,Stack Related Facilities -@anchor{gnat_ugn/gnat_and_program_execution id54}@anchor{1af}@anchor{gnat_ugn/gnat_and_program_execution static-stack-usage-analysis}@anchor{e9} +@anchor{gnat_ugn/gnat_and_program_execution id54}@anchor{1b0}@anchor{gnat_ugn/gnat_and_program_execution static-stack-usage-analysis}@anchor{e9} @subsection Static Stack Usage Analysis @@ -22489,7 +22549,7 @@ consistent with that in the file documented above. This is not supported by the LLVM back end. @node Dynamic Stack Usage Analysis,,Static Stack Usage Analysis,Stack Related Facilities -@anchor{gnat_ugn/gnat_and_program_execution dynamic-stack-usage-analysis}@anchor{117}@anchor{gnat_ugn/gnat_and_program_execution id55}@anchor{1b0} +@anchor{gnat_ugn/gnat_and_program_execution dynamic-stack-usage-analysis}@anchor{117}@anchor{gnat_ugn/gnat_and_program_execution id55}@anchor{1b1} @subsection Dynamic Stack Usage Analysis @@ -22573,8 +22633,8 @@ This is not suppored by the LLVM back end. The package @code{GNAT.Task_Stack_Usage} provides facilities to get stack-usage reports at run time. See its body for the details. -@node Memory Management Issues,,Stack Related Facilities,GNAT and Program Execution -@anchor{gnat_ugn/gnat_and_program_execution id56}@anchor{151}@anchor{gnat_ugn/gnat_and_program_execution memory-management-issues}@anchor{1b1} +@node Memory Management Issues,Sanitizers for Ada,Stack Related Facilities,GNAT and Program Execution +@anchor{gnat_ugn/gnat_and_program_execution id56}@anchor{151}@anchor{gnat_ugn/gnat_and_program_execution memory-management-issues}@anchor{1b2} @section Memory Management Issues @@ -22590,7 +22650,7 @@ incorrect uses of access values (including ‘dangling references’). @end menu @node Some Useful Memory Pools,The GNAT Debug Pool Facility,,Memory Management Issues -@anchor{gnat_ugn/gnat_and_program_execution id57}@anchor{1b2}@anchor{gnat_ugn/gnat_and_program_execution some-useful-memory-pools}@anchor{1b3} +@anchor{gnat_ugn/gnat_and_program_execution id57}@anchor{1b3}@anchor{gnat_ugn/gnat_and_program_execution some-useful-memory-pools}@anchor{1b4} @subsection Some Useful Memory Pools @@ -22672,7 +22732,7 @@ for T1'Storage_Size use 10_000; @end quotation @node The GNAT Debug Pool Facility,,Some Useful Memory Pools,Memory Management Issues -@anchor{gnat_ugn/gnat_and_program_execution id58}@anchor{1b4}@anchor{gnat_ugn/gnat_and_program_execution the-gnat-debug-pool-facility}@anchor{1b5} +@anchor{gnat_ugn/gnat_and_program_execution id58}@anchor{1b5}@anchor{gnat_ugn/gnat_and_program_execution the-gnat-debug-pool-facility}@anchor{1b6} @subsection The GNAT Debug Pool Facility @@ -22831,11 +22891,415 @@ Debug Pool info: @end quotation +@node Sanitizers for Ada,,Memory Management Issues,GNAT and Program Execution +@anchor{gnat_ugn/gnat_and_program_execution id63}@anchor{152}@anchor{gnat_ugn/gnat_and_program_execution sanitizers-for-ada}@anchor{1b7} +@section Sanitizers for Ada + + +@geindex Sanitizers + +This section explains how to use sanitizers with Ada code. Sanitizers offer code +instrumentation and run-time libraries that detect certain memory issues and +undefined behaviors during execution. They provide dynamic analysis capabilities +useful for debugging and testing. + +While many sanitizer capabilities overlap with Ada’s built-in runtime checks, +they are particularly valuable for identifying issues that arise from unchecked +features or low-level operations. + +@menu +* AddressSanitizer:: +* UndefinedBehaviorSanitizer:: +* Sanitizers in mixed-language applications:: + +@end menu + +@node AddressSanitizer,UndefinedBehaviorSanitizer,,Sanitizers for Ada +@anchor{gnat_ugn/gnat_and_program_execution addresssanitizer}@anchor{1b8}@anchor{gnat_ugn/gnat_and_program_execution id64}@anchor{1b9} +@subsection AddressSanitizer + + +@geindex AddressSanitizer + +@geindex ASan + +@geindex -fsanitize=address + +AddressSanitizer (aka ASan) is a memory error detector activated with the +@code{-fsanitize=address} switch. Note that many of the typical memory errors, +such as use after free or buffer overflow, are detected by Ada’s @code{Access_Check} +and @code{Index_Check}. + +It can detect the following types of problems: + + +@itemize * + +@item +Wrong memory overlay + +A memory overlay is a situation in which an object of one type is placed at the +same memory location as a distinct object of a different type, thus overlaying +one object over the other in memory. When there is an overflow because the +objects do not overlap (like in the following example), the sanitizer can signal +it. + +@quotation + +@example +procedure Wrong_Size_Overlay is + type Block is array (Natural range <>) of Integer; + + Block4 : aliased Block := (1 .. 4 => 4); + Block5 : Block (1 .. 5) with Address => Block4'Address; +begin + Block5 (Block5'Last) := 5; -- Outside the object +end Wrong_Size_Overlay; +@end example +@end quotation + +If the code is built with the @code{-fsanitize=address} and @code{-g} options, +the following error is shown at execution time: + +@quotation + +@example +... +SUMMARY: AddressSanitizer: stack-buffer-overflow wrong_size_overlay.adb:7 in _ada_wrong_size_overlay +... +@end example +@end quotation + +@item +Buffer overflow + +Ada’s @code{Index_Check} detects buffer overflows caused by out-of-bounds array +access. If run-time checks are disabled, the sanitizer can still detect such +overflows at execution time the same way as it signalled the previous wrong +memory overlay. Note that if both the Ada run-time checks and the sanitizer +are enabled, the Ada run-time exception takes precedence. + +@quotation + +@example +procedure Buffer_Overrun is + Size : constant := 100; + Buffer : array (1 .. Size) of Integer := (others => 0); + Wrong_Index : Integer := Size + 1 with Export; +begin + -- Access outside the boundaries + Put_Line ("Value: " & Integer'Image (Buffer (Wrong_Index))); +end Buffer_Overrun; +@end example +@end quotation + +@item +Use after lifetime + +Ada’s @code{Accessibility_Check} helps prevent use-after-return and +use-after-scope errors by enforcing lifetime rules. When these checks are +bypassed using @code{Unchecked_Access}, sanitizers can still detect such +violations during execution. + +@quotation + +@example +with Ada.Text_IO; use Ada.Text_IO; + +procedure Use_After_Return is + type Integer_Access is access all Integer; + Ptr : Integer_Access; + + procedure Inner; + + procedure Inner is + Local : aliased Integer := 42; + begin + Ptr := Local'Unchecked_Access; + end Inner; + +begin + Inner; + -- Accessing Local after it has gone out of scope + Put_Line ("Value: " & Integer'Image (Ptr.all)); +end Use_After_Return; +@end example +@end quotation + +If the code is built with the @code{-fsanitize=address} and @code{-g} +options, the following error is shown at execution time: + +@quotation + +@example +... +==1793927==ERROR: AddressSanitizer: stack-use-after-return on address 0xf6fa1a409060 at pc 0xb20b6cb6cac0 bp 0xffffcc89c8b0 sp 0xffffcc89c8c8 +READ of size 4 at 0xf6fa1a409060 thread T0 + #0 0xb20b6cb6cabc in _ada_use_after_return use_after_return.adb:18 + ... + +Address 0xf6fa1a409060 is located in stack of thread T0 at offset 32 in frame + #0 0xb20b6cb6c794 in use_after_return__inner use_after_return.adb:9 + + This frame has 1 object(s): + [32, 36) 'local' (line 10) <== Memory access at offset 32 is inside this variable +SUMMARY: AddressSanitizer: stack-use-after-return use_after_return.adb:18 in _ada_use_after_return +... +@end example +@end quotation + +@item +Memory leak + +A memory leak happens when a program allocates memory from the heap but fails +to release it after it is no longer needed and loses all references to it like +in the following example. + +@quotation + +@example +procedure Memory_Leak is + type Integer_Access is access Integer; + + procedure Allocate is + Ptr : Integer_Access := new Integer'(42); + begin + null; + end Allocate; +begin + -- Memory leak occurs in the following procedure + Allocate; +end Memory_Leak; +@end example +@end quotation + +If the code is built with the @code{-fsanitize=address} and @code{-g} +options, the following error is emitted at execution time showing the +location of the offending allocation. + +@quotation + +@example +==1810634==ERROR: LeakSanitizer: detected memory leaks + +Direct leak of 4 byte(s) in 1 object(s) allocated from: + #0 0xe3cbee4bb4a8 in __interceptor_malloc asan_malloc_linux.cpp:69 + #1 0xc15bb25d0af8 in __gnat_malloc (memory_leak+0x10af8) (BuildId: f5914a6eac10824f81d512de50b514e7d5f733be) + #2 0xc15bb25c9060 in memory_leak__allocate memory_leak.adb:5 + ... + +SUMMARY: AddressSanitizer: 4 byte(s) leaked in 1 allocation(s). +@end example +@end quotation +@end itemize + +@node UndefinedBehaviorSanitizer,Sanitizers in mixed-language applications,AddressSanitizer,Sanitizers for Ada +@anchor{gnat_ugn/gnat_and_program_execution id65}@anchor{1ba}@anchor{gnat_ugn/gnat_and_program_execution undefinedbehaviorsanitizer}@anchor{1bb} +@subsection UndefinedBehaviorSanitizer + + +@geindex UndefinedBehaviorSanitizer + +@geindex UBSan + +@geindex -fsanitize=undefined + +UndefinedBehaviorSanitizer (aka UBSan) modifies the program at compile-time to +catch various kinds of undefined behavior during program execution. + +Different sanitize options (@code{-fsanitize=alignment,float-cast-overflow,signed-integer-overflow}) +detect the following types of problems: + + +@itemize * + +@item +Wrong alignment + +The @code{-fsanitize=alignment} flag (included also in +@code{-fsanitize=undefined}) enables run-time checks for misaligned memory +accesses, ensuring that objects are accessed at addresses that conform to the +alignment constraints of their declared types. Violations may lead to crashes +or performance penalties on certain architectures. + +In the following example: + +@quotation + +@example +with Ada.Text_IO; use Ada.Text_IO; +with System.Storage_Elements; use System.Storage_Elements; + +procedure Misaligned_Address is + type Aligned_Integer is new Integer with + Alignment => 4; -- Ensure 4-byte alignment + + Reference : Aligned_Integer := 42; -- Properly aligned object + + -- Create a misaligned object by modifying the address manually + Misaligned : Aligned_Integer with Address => Reference'Address + 1; + +begin + -- This causes undefined behavior or an alignment exception on strict architectures + Put_Line ("Misaligned Value: " & Aligned_Integer'Image (Misaligned)); +end Misaligned_Address; +@end example +@end quotation + +If the code is built with the @code{-fsanitize=alignment} and @code{-g} +options, the following error is shown at execution time. + +@quotation + +@example +misaligned_address.adb:15:51: runtime error: load of misaligned address 0xffffd836dd45 for type 'volatile misaligned_address__aligned_integer', which requires 4 byte alignment +@end example +@end quotation + +@item +Signed integer overflow + +Ada performs range checks at runtime in arithmetic operation on signed integers +to ensure the value is within the target type’s bounds. If this check is removed, +the @code{-fsanitize=signed-integer-overflow} flag (included also in +@code{-fsanitize=undefined}) enables run-time checks for signed integer +overflows. + +In the following example: + +@quotation + +@example +procedure Signed_Integer_Overflow is + type Small_Int is range -128 .. 127; + X, Y, Z : Small_Int with Export; +begin + X := 100; + Y := 50; + -- This addition will exceed 127, causing an overflow + Z := X + Y; +end Signed_Integer_Overflow; +@end example +@end quotation + +If the code is built with the @code{-fsanitize=signed-integer-overflow} and +@code{-g} options, the following error is shown at execution time. + +@quotation + +@example +signed_integer_overflow.adb:8:11: runtime error: signed integer overflow: 100 + 50 cannot be represented in type 'signed_integer_overflow__small_int' +@end example +@end quotation + +@item +Float to integer overflow + +When converting a floating-point value to an integer type, Ada performs a range +check at runtime to ensure the value is within the target type’s bounds. If this +check is removed, the sanitizer can detect overflows in conversions from +floating point to integer types. + +In the following code: + +@quotation + +@example +procedure Float_Cast_Overflow is + Flt : Float := Float'Last with Export; + Int : Integer; +begin + Int := Integer (Flt); -- Overflow +end Float_Cast_Overflow; +@end example +@end quotation + +If the code is built with the @code{-fsanitize=float-cast-overflow} and +@code{-g} options, the following error is shown at execution time. + +@quotation + +@example +float_cast_overflow.adb:5:20: runtime error: 3.40282e+38 is outside the range of representable values of type 'integer' +@end example +@end quotation +@end itemize + +@node Sanitizers in mixed-language applications,,UndefinedBehaviorSanitizer,Sanitizers for Ada +@anchor{gnat_ugn/gnat_and_program_execution sanitizers-in-mixed-language-applications}@anchor{1bc} +@subsection Sanitizers in mixed-language applications + + +Most of the checks performed by sanitizers operate at a global level, which +means they can detect issues even when they span across language boundaries. +This applies notably to: + + +@itemize * + +@item +All checks performed by the AddressSanitizer: wrong memory overlays, buffer +overflows, uses after lifetime, memory leaks. These checks apply globally, +regardless of where the objects are allocated or defined, or where they are +destroyed + +@item +Wrong alignment checks performed by the UndefinedBehaviorSanitizer. It will +check whether an object created in a given language is accessed in another +with an incompatible alignment +@end itemize + +An interesting case that highlights the benefit of global sanitization is a +buffer overflow caused by a mismatch in language bindings. Consider the +following C function, which allocates an array of 4 characters: + +@quotation + +@example +char *get_str (void) @{ + char *str = malloc (4 * sizeof (char)); +@} +@end example +@end quotation + +This function is then bound to Ada code, which incorrectly assumes the buffer +is of size 5: + +@quotation + +@example +type Buffer is array (1 .. 5) of Character; + +function Get_Str return access Buffer + with Import => True, Convention => C, External_Name => "get_str"; + +Str : access Buffer := Get_Str; +Ch : Character := S (S'Last); -- Detected by AddressSanitizer as erroneous +@end example +@end quotation + +On the Ada side, accessing @code{Str (5)} appears valid because the array type +declares five elements. However, the actual memory allocated in C only holds +four. This mismatch is not detectable by Ada run-time checks, because Ada has +no visibility into how the memory was allocated. + +However, the AddressSanitizer will detect the heap buffer overflow at runtime, +halting execution and providing a clear diagnostic: + +@quotation + +@example +... +SUMMARY: AddressSanitizer: heap-buffer-overflow buffer_overflow.adb:20 in _ada_buffer_overflow +... +@end example +@end quotation + @c -- Non-breaking space in running text @c -- E.g. Ada |nbsp| 95 @node Platform-Specific Information,Example of Binder Output File,GNAT and Program Execution,Top -@anchor{gnat_ugn/platform_specific_information doc}@anchor{1b6}@anchor{gnat_ugn/platform_specific_information id1}@anchor{1b7}@anchor{gnat_ugn/platform_specific_information platform-specific-information}@anchor{e} +@anchor{gnat_ugn/platform_specific_information doc}@anchor{1bd}@anchor{gnat_ugn/platform_specific_information id1}@anchor{1be}@anchor{gnat_ugn/platform_specific_information platform-specific-information}@anchor{e} @chapter Platform-Specific Information @@ -22853,7 +23317,7 @@ related to the GNAT implementation on specific Operating Systems. @end menu @node Run-Time Libraries,Specifying a Run-Time Library,,Platform-Specific Information -@anchor{gnat_ugn/platform_specific_information id2}@anchor{1b8}@anchor{gnat_ugn/platform_specific_information run-time-libraries}@anchor{1b9} +@anchor{gnat_ugn/platform_specific_information id2}@anchor{1bf}@anchor{gnat_ugn/platform_specific_information run-time-libraries}@anchor{1c0} @section Run-Time Libraries @@ -22914,7 +23378,7 @@ are supplied on various GNAT platforms. @end menu @node Summary of Run-Time Configurations,,,Run-Time Libraries -@anchor{gnat_ugn/platform_specific_information id3}@anchor{1ba}@anchor{gnat_ugn/platform_specific_information summary-of-run-time-configurations}@anchor{1bb} +@anchor{gnat_ugn/platform_specific_information id3}@anchor{1c1}@anchor{gnat_ugn/platform_specific_information summary-of-run-time-configurations}@anchor{1c2} @subsection Summary of Run-Time Configurations @@ -23014,7 +23478,7 @@ ZCX @node Specifying a Run-Time Library,GNU/Linux Topics,Run-Time Libraries,Platform-Specific Information -@anchor{gnat_ugn/platform_specific_information id4}@anchor{1bc}@anchor{gnat_ugn/platform_specific_information specifying-a-run-time-library}@anchor{1bd} +@anchor{gnat_ugn/platform_specific_information id4}@anchor{1c3}@anchor{gnat_ugn/platform_specific_information specifying-a-run-time-library}@anchor{1c4} @section Specifying a Run-Time Library @@ -23107,7 +23571,7 @@ by using the @code{--RTS} switch, e.g., @code{--RTS=sjlj} @geindex GNU/Linux @node GNU/Linux Topics,Microsoft Windows Topics,Specifying a Run-Time Library,Platform-Specific Information -@anchor{gnat_ugn/platform_specific_information gnu-linux-topics}@anchor{1be}@anchor{gnat_ugn/platform_specific_information id5}@anchor{1bf} +@anchor{gnat_ugn/platform_specific_information gnu-linux-topics}@anchor{1c5}@anchor{gnat_ugn/platform_specific_information id5}@anchor{1c6} @section GNU/Linux Topics @@ -23122,7 +23586,7 @@ This section describes topics that are specific to GNU/Linux platforms. @end menu @node Required Packages on GNU/Linux,Position Independent Executable PIE Enabled by Default on Linux,,GNU/Linux Topics -@anchor{gnat_ugn/platform_specific_information id6}@anchor{1c0}@anchor{gnat_ugn/platform_specific_information required-packages-on-gnu-linux}@anchor{1c1} +@anchor{gnat_ugn/platform_specific_information id6}@anchor{1c7}@anchor{gnat_ugn/platform_specific_information required-packages-on-gnu-linux}@anchor{1c8} @subsection Required Packages on GNU/Linux @@ -23159,7 +23623,7 @@ Other GNU/Linux distributions might choose different name for those packages. @node Position Independent Executable PIE Enabled by Default on Linux,Choosing the Scheduling Policy with GNU/Linux,Required Packages on GNU/Linux,GNU/Linux Topics -@anchor{gnat_ugn/platform_specific_information pie-enabled-by-default-on-linux}@anchor{1c2}@anchor{gnat_ugn/platform_specific_information position-independent-executable-pie-enabled-by-default-on-linux}@anchor{1c3} +@anchor{gnat_ugn/platform_specific_information pie-enabled-by-default-on-linux}@anchor{1c9}@anchor{gnat_ugn/platform_specific_information position-independent-executable-pie-enabled-by-default-on-linux}@anchor{1ca} @subsection Position Independent Executable (PIE) Enabled by Default on Linux @@ -23207,9 +23671,9 @@ and linked with @code{-pie}). @geindex SCHED_RR scheduling policy @geindex SCHED_OTHER scheduling policy -@anchor{gnat_ugn/platform_specific_information choosing-the-scheduling-policy-with-gnu-linux}@anchor{1c4} +@anchor{gnat_ugn/platform_specific_information choosing-the-scheduling-policy-with-gnu-linux}@anchor{1cb} @node Choosing the Scheduling Policy with GNU/Linux,A GNU/Linux Debug Quirk,Position Independent Executable PIE Enabled by Default on Linux,GNU/Linux Topics -@anchor{gnat_ugn/platform_specific_information id7}@anchor{1c5} +@anchor{gnat_ugn/platform_specific_information id7}@anchor{1cc} @subsection Choosing the Scheduling Policy with GNU/Linux @@ -23267,7 +23731,7 @@ but not on the host machine running the container, so check that you also have sufficient priviledge for running the container image. @node A GNU/Linux Debug Quirk,,Choosing the Scheduling Policy with GNU/Linux,GNU/Linux Topics -@anchor{gnat_ugn/platform_specific_information a-gnu-linux-debug-quirk}@anchor{1c6}@anchor{gnat_ugn/platform_specific_information id8}@anchor{1c7} +@anchor{gnat_ugn/platform_specific_information a-gnu-linux-debug-quirk}@anchor{1cd}@anchor{gnat_ugn/platform_specific_information id8}@anchor{1ce} @subsection A GNU/Linux Debug Quirk @@ -23287,7 +23751,7 @@ the symptoms most commonly observed. @geindex Windows @node Microsoft Windows Topics,Mac OS Topics,GNU/Linux Topics,Platform-Specific Information -@anchor{gnat_ugn/platform_specific_information id9}@anchor{1c8}@anchor{gnat_ugn/platform_specific_information microsoft-windows-topics}@anchor{1c9} +@anchor{gnat_ugn/platform_specific_information id9}@anchor{1cf}@anchor{gnat_ugn/platform_specific_information microsoft-windows-topics}@anchor{1d0} @section Microsoft Windows Topics @@ -23309,7 +23773,7 @@ platforms. @end menu @node Using GNAT on Windows,Using a network installation of GNAT,,Microsoft Windows Topics -@anchor{gnat_ugn/platform_specific_information id10}@anchor{1ca}@anchor{gnat_ugn/platform_specific_information using-gnat-on-windows}@anchor{1cb} +@anchor{gnat_ugn/platform_specific_information id10}@anchor{1d1}@anchor{gnat_ugn/platform_specific_information using-gnat-on-windows}@anchor{1d2} @subsection Using GNAT on Windows @@ -23388,7 +23852,7 @@ different GNAT products. @end itemize @node Using a network installation of GNAT,CONSOLE and WINDOWS subsystems,Using GNAT on Windows,Microsoft Windows Topics -@anchor{gnat_ugn/platform_specific_information id11}@anchor{1cc}@anchor{gnat_ugn/platform_specific_information using-a-network-installation-of-gnat}@anchor{1cd} +@anchor{gnat_ugn/platform_specific_information id11}@anchor{1d3}@anchor{gnat_ugn/platform_specific_information using-a-network-installation-of-gnat}@anchor{1d4} @subsection Using a network installation of GNAT @@ -23415,7 +23879,7 @@ transfer of large amounts of data across the network and will likely cause a serious performance penalty. @node CONSOLE and WINDOWS subsystems,Temporary Files,Using a network installation of GNAT,Microsoft Windows Topics -@anchor{gnat_ugn/platform_specific_information console-and-windows-subsystems}@anchor{1ce}@anchor{gnat_ugn/platform_specific_information id12}@anchor{1cf} +@anchor{gnat_ugn/platform_specific_information console-and-windows-subsystems}@anchor{1d5}@anchor{gnat_ugn/platform_specific_information id12}@anchor{1d6} @subsection CONSOLE and WINDOWS subsystems @@ -23440,7 +23904,7 @@ $ gnatmake winprog -largs -mwindows @end quotation @node Temporary Files,Disabling Command Line Argument Expansion,CONSOLE and WINDOWS subsystems,Microsoft Windows Topics -@anchor{gnat_ugn/platform_specific_information id13}@anchor{1d0}@anchor{gnat_ugn/platform_specific_information temporary-files}@anchor{1d1} +@anchor{gnat_ugn/platform_specific_information id13}@anchor{1d7}@anchor{gnat_ugn/platform_specific_information temporary-files}@anchor{1d8} @subsection Temporary Files @@ -23478,7 +23942,7 @@ environments where you may not have write access to some directories. @node Disabling Command Line Argument Expansion,Choosing the Scheduling Policy with Windows,Temporary Files,Microsoft Windows Topics -@anchor{gnat_ugn/platform_specific_information disabling-command-line-argument-expansion}@anchor{1d2} +@anchor{gnat_ugn/platform_specific_information disabling-command-line-argument-expansion}@anchor{1d9} @subsection Disabling Command Line Argument Expansion @@ -23549,7 +24013,7 @@ Ada.Command_Line.Argument (1) -> "'*.txt'" @end example @node Choosing the Scheduling Policy with Windows,Windows Socket Timeouts,Disabling Command Line Argument Expansion,Microsoft Windows Topics -@anchor{gnat_ugn/platform_specific_information choosing-the-scheduling-policy-with-windows}@anchor{1d3}@anchor{gnat_ugn/platform_specific_information id14}@anchor{1d4} +@anchor{gnat_ugn/platform_specific_information choosing-the-scheduling-policy-with-windows}@anchor{1da}@anchor{gnat_ugn/platform_specific_information id14}@anchor{1db} @subsection Choosing the Scheduling Policy with Windows @@ -23567,7 +24031,7 @@ in @code{system.ads}. For more information about Windows priorities, please refer to Microsoft documentation. @node Windows Socket Timeouts,Mixed-Language Programming on Windows,Choosing the Scheduling Policy with Windows,Microsoft Windows Topics -@anchor{gnat_ugn/platform_specific_information windows-socket-timeouts}@anchor{1d5} +@anchor{gnat_ugn/platform_specific_information windows-socket-timeouts}@anchor{1dc} @subsection Windows Socket Timeouts @@ -23615,7 +24079,7 @@ socket timeout shorter than 500 ms. If a socket timeout shorter than operations. @node Mixed-Language Programming on Windows,Windows Specific Add-Ons,Windows Socket Timeouts,Microsoft Windows Topics -@anchor{gnat_ugn/platform_specific_information id15}@anchor{1d6}@anchor{gnat_ugn/platform_specific_information mixed-language-programming-on-windows}@anchor{1d7} +@anchor{gnat_ugn/platform_specific_information id15}@anchor{1dd}@anchor{gnat_ugn/platform_specific_information mixed-language-programming-on-windows}@anchor{1de} @subsection Mixed-Language Programming on Windows @@ -23637,12 +24101,12 @@ to use the Microsoft tools for your C++ code, you have two choices: You can encapsulate your C++ code in a DLL to be linked with your Ada application. In this case, use the Microsoft or other environment to build the DLL and use GNAT to build your executable -(@ref{1d8,,Using DLLs with GNAT}). +(@ref{1df,,Using DLLs with GNAT}). @item You can encapsulate your Ada code in a DLL to be linked with the other part of your application. In this case, use GNAT to build the DLL -(@ref{1d9,,Building DLLs with GNAT Project files}) and use the Microsoft +(@ref{1e0,,Building DLLs with GNAT Project files}) and use the Microsoft or other environment to build your executable. @end itemize @@ -23699,7 +24163,7 @@ native SEH support is used. @end menu @node Windows Calling Conventions,Introduction to Dynamic Link Libraries DLLs,,Mixed-Language Programming on Windows -@anchor{gnat_ugn/platform_specific_information id16}@anchor{1da}@anchor{gnat_ugn/platform_specific_information windows-calling-conventions}@anchor{1db} +@anchor{gnat_ugn/platform_specific_information id16}@anchor{1e1}@anchor{gnat_ugn/platform_specific_information windows-calling-conventions}@anchor{1e2} @subsubsection Windows Calling Conventions @@ -23744,7 +24208,7 @@ are available for Windows: @end menu @node C Calling Convention,Stdcall Calling Convention,,Windows Calling Conventions -@anchor{gnat_ugn/platform_specific_information c-calling-convention}@anchor{1dc}@anchor{gnat_ugn/platform_specific_information id17}@anchor{1dd} +@anchor{gnat_ugn/platform_specific_information c-calling-convention}@anchor{1e3}@anchor{gnat_ugn/platform_specific_information id17}@anchor{1e4} @subsubsection @code{C} Calling Convention @@ -23786,10 +24250,10 @@ the @code{External_Name} with a leading underscore. When importing a variable defined in C, you should always use the @code{C} calling convention unless the object containing the variable is part of a DLL (in which case you should use the @code{Stdcall} calling -convention, @ref{1de,,Stdcall Calling Convention}). +convention, @ref{1e5,,Stdcall Calling Convention}). @node Stdcall Calling Convention,Win32 Calling Convention,C Calling Convention,Windows Calling Conventions -@anchor{gnat_ugn/platform_specific_information id18}@anchor{1df}@anchor{gnat_ugn/platform_specific_information stdcall-calling-convention}@anchor{1de} +@anchor{gnat_ugn/platform_specific_information id18}@anchor{1e6}@anchor{gnat_ugn/platform_specific_information stdcall-calling-convention}@anchor{1e5} @subsubsection @code{Stdcall} Calling Convention @@ -23887,7 +24351,7 @@ Note that to ease building cross-platform bindings, this convention will be handled as a @code{C} calling convention on non-Windows platforms. @node Win32 Calling Convention,DLL Calling Convention,Stdcall Calling Convention,Windows Calling Conventions -@anchor{gnat_ugn/platform_specific_information id19}@anchor{1e0}@anchor{gnat_ugn/platform_specific_information win32-calling-convention}@anchor{1e1} +@anchor{gnat_ugn/platform_specific_information id19}@anchor{1e7}@anchor{gnat_ugn/platform_specific_information win32-calling-convention}@anchor{1e8} @subsubsection @code{Win32} Calling Convention @@ -23895,7 +24359,7 @@ This convention, which is GNAT-specific, is fully equivalent to the @code{Stdcall} calling convention described above. @node DLL Calling Convention,,Win32 Calling Convention,Windows Calling Conventions -@anchor{gnat_ugn/platform_specific_information dll-calling-convention}@anchor{1e2}@anchor{gnat_ugn/platform_specific_information id20}@anchor{1e3} +@anchor{gnat_ugn/platform_specific_information dll-calling-convention}@anchor{1e9}@anchor{gnat_ugn/platform_specific_information id20}@anchor{1ea} @subsubsection @code{DLL} Calling Convention @@ -23903,7 +24367,7 @@ This convention, which is GNAT-specific, is fully equivalent to the @code{Stdcall} calling convention described above. @node Introduction to Dynamic Link Libraries DLLs,Using DLLs with GNAT,Windows Calling Conventions,Mixed-Language Programming on Windows -@anchor{gnat_ugn/platform_specific_information id21}@anchor{1e4}@anchor{gnat_ugn/platform_specific_information introduction-to-dynamic-link-libraries-dlls}@anchor{1e5} +@anchor{gnat_ugn/platform_specific_information id21}@anchor{1eb}@anchor{gnat_ugn/platform_specific_information introduction-to-dynamic-link-libraries-dlls}@anchor{1ec} @subsubsection Introduction to Dynamic Link Libraries (DLLs) @@ -23987,10 +24451,10 @@ As a side note, an interesting difference between Microsoft DLLs and Unix shared libraries is the fact that on most Unix systems all public routines are exported by default in a Unix shared library, while under Windows it is possible (but not required) to list exported routines in -a definition file (see @ref{1e6,,The Definition File}). +a definition file (see @ref{1ed,,The Definition File}). @node Using DLLs with GNAT,Building DLLs with GNAT Project files,Introduction to Dynamic Link Libraries DLLs,Mixed-Language Programming on Windows -@anchor{gnat_ugn/platform_specific_information id22}@anchor{1e7}@anchor{gnat_ugn/platform_specific_information using-dlls-with-gnat}@anchor{1d8} +@anchor{gnat_ugn/platform_specific_information id22}@anchor{1ee}@anchor{gnat_ugn/platform_specific_information using-dlls-with-gnat}@anchor{1df} @subsubsection Using DLLs with GNAT @@ -24081,7 +24545,7 @@ example a fictitious DLL called @code{API.dll}. @end menu @node Creating an Ada Spec for the DLL Services,Creating an Import Library,,Using DLLs with GNAT -@anchor{gnat_ugn/platform_specific_information creating-an-ada-spec-for-the-dll-services}@anchor{1e8}@anchor{gnat_ugn/platform_specific_information id23}@anchor{1e9} +@anchor{gnat_ugn/platform_specific_information creating-an-ada-spec-for-the-dll-services}@anchor{1ef}@anchor{gnat_ugn/platform_specific_information id23}@anchor{1f0} @subsubsection Creating an Ada Spec for the DLL Services @@ -24121,7 +24585,7 @@ end API; @end quotation @node Creating an Import Library,,Creating an Ada Spec for the DLL Services,Using DLLs with GNAT -@anchor{gnat_ugn/platform_specific_information creating-an-import-library}@anchor{1ea}@anchor{gnat_ugn/platform_specific_information id24}@anchor{1eb} +@anchor{gnat_ugn/platform_specific_information creating-an-import-library}@anchor{1f1}@anchor{gnat_ugn/platform_specific_information id24}@anchor{1f2} @subsubsection Creating an Import Library @@ -24135,7 +24599,7 @@ as in this case it is possible to link directly against the DLL. Otherwise read on. @geindex Definition file -@anchor{gnat_ugn/platform_specific_information the-definition-file}@anchor{1e6} +@anchor{gnat_ugn/platform_specific_information the-definition-file}@anchor{1ed} @subsubheading The Definition File @@ -24183,17 +24647,17 @@ EXPORTS @end table Note that you must specify the correct suffix (@code{@@@var{nn}}) -(see @ref{1db,,Windows Calling Conventions}) for a Stdcall +(see @ref{1e2,,Windows Calling Conventions}) for a Stdcall calling convention function in the exported symbols list. There can actually be other sections in a definition file, but these sections are not relevant to the discussion at hand. -@anchor{gnat_ugn/platform_specific_information create-def-file-automatically}@anchor{1ec} +@anchor{gnat_ugn/platform_specific_information create-def-file-automatically}@anchor{1f3} @subsubheading Creating a Definition File Automatically You can automatically create the definition file @code{API.def} -(see @ref{1e6,,The Definition File}) from a DLL. +(see @ref{1ed,,The Definition File}) from a DLL. To do that, use the @code{dlltool} program as follows: @quotation @@ -24203,7 +24667,7 @@ $ dlltool API.dll -z API.def --export-all-symbols @end example Note that if some routines in the DLL have the @code{Stdcall} convention -(@ref{1db,,Windows Calling Conventions}) with stripped @code{@@@var{nn}} +(@ref{1e2,,Windows Calling Conventions}) with stripped @code{@@@var{nn}} suffix then you’ll have to edit @code{api.def} to add it and specify @code{-k} to @code{gnatdll} when creating the import library. @@ -24228,13 +24692,13 @@ tells you what symbol is expected. You then can go back to the definition file and add the right suffix. @end itemize @end quotation -@anchor{gnat_ugn/platform_specific_information gnat-style-import-library}@anchor{1ed} +@anchor{gnat_ugn/platform_specific_information gnat-style-import-library}@anchor{1f4} @subsubheading GNAT-Style Import Library To create a static import library from @code{API.dll} with the GNAT tools, you should create the @code{.def} file and use the @code{gnatdll} tool -(see @ref{1ee,,Using gnatdll}) as follows: +(see @ref{1f5,,Using gnatdll}) as follows: @quotation @@ -24250,15 +24714,15 @@ definition file name is @code{xyz.def}, the import library name will be @code{libxyz.a}. Note that in the previous example, the switch @code{-e} could have been removed because the name of the definition file (before the @code{.def} suffix) is the same as the name of the -DLL (@ref{1ee,,Using gnatdll} for more information about @code{gnatdll}). +DLL (@ref{1f5,,Using gnatdll} for more information about @code{gnatdll}). @end quotation -@anchor{gnat_ugn/platform_specific_information msvs-style-import-library}@anchor{1ef} +@anchor{gnat_ugn/platform_specific_information msvs-style-import-library}@anchor{1f6} @subsubheading Microsoft-Style Import Library A Microsoft import library is needed only if you plan to make an Ada DLL available to applications developed with Microsoft -tools (@ref{1d7,,Mixed-Language Programming on Windows}). +tools (@ref{1de,,Mixed-Language Programming on Windows}). To create a Microsoft-style import library for @code{API.dll} you should create the @code{.def} file, then build the actual import library using @@ -24282,7 +24746,7 @@ See the Microsoft documentation for further details about the usage of @end quotation @node Building DLLs with GNAT Project files,Building DLLs with GNAT,Using DLLs with GNAT,Mixed-Language Programming on Windows -@anchor{gnat_ugn/platform_specific_information building-dlls-with-gnat-project-files}@anchor{1d9}@anchor{gnat_ugn/platform_specific_information id25}@anchor{1f0} +@anchor{gnat_ugn/platform_specific_information building-dlls-with-gnat-project-files}@anchor{1e0}@anchor{gnat_ugn/platform_specific_information id25}@anchor{1f7} @subsubsection Building DLLs with GNAT Project files @@ -24298,7 +24762,7 @@ when inside the @code{DllMain} routine which is used for auto-initialization of shared libraries, so you can’t have library level tasks in SALs. @node Building DLLs with GNAT,Building DLLs with gnatdll,Building DLLs with GNAT Project files,Mixed-Language Programming on Windows -@anchor{gnat_ugn/platform_specific_information building-dlls-with-gnat}@anchor{1f1}@anchor{gnat_ugn/platform_specific_information id26}@anchor{1f2} +@anchor{gnat_ugn/platform_specific_information building-dlls-with-gnat}@anchor{1f8}@anchor{gnat_ugn/platform_specific_information id26}@anchor{1f9} @subsubsection Building DLLs with GNAT @@ -24329,7 +24793,7 @@ $ gcc -shared -shared-libgcc -o api.dll obj1.o obj2.o ... It’s important to note that in this case all symbols found in the object files are automatically exported. You can restrict the set of symbols to export by passing to @code{gcc} a definition -file (see @ref{1e6,,The Definition File}). +file (see @ref{1ed,,The Definition File}). For example: @example @@ -24367,7 +24831,7 @@ $ gnatmake main -Iapilib -bargs -shared -largs -Lapilib -lAPI @end quotation @node Building DLLs with gnatdll,Ada DLLs and Finalization,Building DLLs with GNAT,Mixed-Language Programming on Windows -@anchor{gnat_ugn/platform_specific_information building-dlls-with-gnatdll}@anchor{1f3}@anchor{gnat_ugn/platform_specific_information id27}@anchor{1f4} +@anchor{gnat_ugn/platform_specific_information building-dlls-with-gnatdll}@anchor{1fa}@anchor{gnat_ugn/platform_specific_information id27}@anchor{1fb} @subsubsection Building DLLs with gnatdll @@ -24375,8 +24839,8 @@ $ gnatmake main -Iapilib -bargs -shared -largs -Lapilib -lAPI @geindex building Note that it is preferred to use GNAT Project files -(@ref{1d9,,Building DLLs with GNAT Project files}) or the built-in GNAT -DLL support (@ref{1f1,,Building DLLs with GNAT}) to build DLLs. +(@ref{1e0,,Building DLLs with GNAT Project files}) or the built-in GNAT +DLL support (@ref{1f8,,Building DLLs with GNAT}) to build DLLs. This section explains how to build DLLs containing Ada code using @code{gnatdll}. These DLLs will be referred to as Ada DLLs in the @@ -24392,20 +24856,20 @@ non-Ada applications are as follows: You need to mark each Ada entity exported by the DLL with a @code{C} or @code{Stdcall} calling convention to avoid any Ada name mangling for the entities exported by the DLL -(see @ref{1f5,,Exporting Ada Entities}). You can +(see @ref{1fc,,Exporting Ada Entities}). You can skip this step if you plan to use the Ada DLL only from Ada applications. @item Your Ada code must export an initialization routine which calls the routine @code{adainit} (generated by @code{gnatbind}) to perform the elaboration of -the Ada code in the DLL (@ref{1f6,,Ada DLLs and Elaboration}). The initialization +the Ada code in the DLL (@ref{1fd,,Ada DLLs and Elaboration}). The initialization routine exported by the Ada DLL must be invoked by the clients of the DLL to initialize the DLL. @item When useful, the DLL should also export a finalization routine which calls routine @code{adafinal} (also generated by @code{gnatbind}) to perform the -finalization of the Ada code in the DLL (@ref{1f7,,Ada DLLs and Finalization}). +finalization of the Ada code in the DLL (@ref{1fe,,Ada DLLs and Finalization}). The finalization routine exported by the Ada DLL must be invoked by the clients of the DLL when the DLL services are no further needed. @@ -24415,11 +24879,11 @@ of the programming languages to which you plan to make the DLL available. @item You must provide a definition file listing the exported entities -(@ref{1e6,,The Definition File}). +(@ref{1ed,,The Definition File}). @item Finally, you must use @code{gnatdll} to produce the DLL and the import -library (@ref{1ee,,Using gnatdll}). +library (@ref{1f5,,Using gnatdll}). @end itemize Note that a relocatable DLL stripped using the @code{strip} @@ -24439,7 +24903,7 @@ chapter of the `GPRbuild User’s Guide'. @end menu @node Limitations When Using Ada DLLs from Ada,Exporting Ada Entities,,Building DLLs with gnatdll -@anchor{gnat_ugn/platform_specific_information limitations-when-using-ada-dlls-from-ada}@anchor{1f8} +@anchor{gnat_ugn/platform_specific_information limitations-when-using-ada-dlls-from-ada}@anchor{1ff} @subsubsection Limitations When Using Ada DLLs from Ada @@ -24460,7 +24924,7 @@ It is completely safe to exchange plain elementary, array or record types, Windows object handles, etc. @node Exporting Ada Entities,Ada DLLs and Elaboration,Limitations When Using Ada DLLs from Ada,Building DLLs with gnatdll -@anchor{gnat_ugn/platform_specific_information exporting-ada-entities}@anchor{1f5}@anchor{gnat_ugn/platform_specific_information id28}@anchor{1f9} +@anchor{gnat_ugn/platform_specific_information exporting-ada-entities}@anchor{1fc}@anchor{gnat_ugn/platform_specific_information id28}@anchor{200} @subsubsection Exporting Ada Entities @@ -24560,10 +25024,10 @@ end API; Note that if you do not export the Ada entities with a @code{C} or @code{Stdcall} convention, you will have to provide the mangled Ada names in the definition file of the Ada DLL -(@ref{1fa,,Creating the Definition File}). +(@ref{201,,Creating the Definition File}). @node Ada DLLs and Elaboration,,Exporting Ada Entities,Building DLLs with gnatdll -@anchor{gnat_ugn/platform_specific_information ada-dlls-and-elaboration}@anchor{1f6}@anchor{gnat_ugn/platform_specific_information id29}@anchor{1fb} +@anchor{gnat_ugn/platform_specific_information ada-dlls-and-elaboration}@anchor{1fd}@anchor{gnat_ugn/platform_specific_information id29}@anchor{202} @subsubsection Ada DLLs and Elaboration @@ -24581,7 +25045,7 @@ the Ada elaboration routine @code{adainit} generated by the GNAT binder (@ref{7f,,Binding with Non-Ada Main Programs}). See the body of @code{Initialize_Api} for an example. Note that the GNAT binder is automatically invoked during the DLL build process by the @code{gnatdll} -tool (@ref{1ee,,Using gnatdll}). +tool (@ref{1f5,,Using gnatdll}). When a DLL is loaded, Windows systematically invokes a routine called @code{DllMain}. It should therefore be possible to call @code{adainit} @@ -24594,7 +25058,7 @@ time), which means that the GNAT run-time will deadlock waiting for a newly created task to complete its initialization. @node Ada DLLs and Finalization,Creating a Spec for Ada DLLs,Building DLLs with gnatdll,Mixed-Language Programming on Windows -@anchor{gnat_ugn/platform_specific_information ada-dlls-and-finalization}@anchor{1f7}@anchor{gnat_ugn/platform_specific_information id30}@anchor{1fc} +@anchor{gnat_ugn/platform_specific_information ada-dlls-and-finalization}@anchor{1fe}@anchor{gnat_ugn/platform_specific_information id30}@anchor{203} @subsubsection Ada DLLs and Finalization @@ -24609,10 +25073,10 @@ routine @code{adafinal} generated by the GNAT binder See the body of @code{Finalize_Api} for an example. As already pointed out the GNAT binder is automatically invoked during the DLL build process by the @code{gnatdll} tool -(@ref{1ee,,Using gnatdll}). +(@ref{1f5,,Using gnatdll}). @node Creating a Spec for Ada DLLs,GNAT and Windows Resources,Ada DLLs and Finalization,Mixed-Language Programming on Windows -@anchor{gnat_ugn/platform_specific_information creating-a-spec-for-ada-dlls}@anchor{1fd}@anchor{gnat_ugn/platform_specific_information id31}@anchor{1fe} +@anchor{gnat_ugn/platform_specific_information creating-a-spec-for-ada-dlls}@anchor{204}@anchor{gnat_ugn/platform_specific_information id31}@anchor{205} @subsubsection Creating a Spec for Ada DLLs @@ -24670,7 +25134,7 @@ end API; @end menu @node Creating the Definition File,Using gnatdll,,Creating a Spec for Ada DLLs -@anchor{gnat_ugn/platform_specific_information creating-the-definition-file}@anchor{1fa}@anchor{gnat_ugn/platform_specific_information id32}@anchor{1ff} +@anchor{gnat_ugn/platform_specific_information creating-the-definition-file}@anchor{201}@anchor{gnat_ugn/platform_specific_information id32}@anchor{206} @subsubsection Creating the Definition File @@ -24706,7 +25170,7 @@ EXPORTS @end quotation @node Using gnatdll,,Creating the Definition File,Creating a Spec for Ada DLLs -@anchor{gnat_ugn/platform_specific_information id33}@anchor{200}@anchor{gnat_ugn/platform_specific_information using-gnatdll}@anchor{1ee} +@anchor{gnat_ugn/platform_specific_information id33}@anchor{207}@anchor{gnat_ugn/platform_specific_information using-gnatdll}@anchor{1f5} @subsubsection Using @code{gnatdll} @@ -24910,7 +25374,7 @@ asks @code{gnatlink} to generate the routines @code{DllMain} and is loaded into memory. @item -uses @code{dlltool} (see @ref{201,,Using dlltool}) to build the +uses @code{dlltool} (see @ref{208,,Using dlltool}) to build the export table (@code{api.exp}). The export table contains the relocation information in a form which can be used during the final link to ensure that the Windows loader is able to place the DLL anywhere in memory. @@ -24948,7 +25412,7 @@ $ gnatbind -n api $ gnatlink api api.exp -o api.dll -mdll @end example @end itemize -@anchor{gnat_ugn/platform_specific_information using-dlltool}@anchor{201} +@anchor{gnat_ugn/platform_specific_information using-dlltool}@anchor{208} @subsubheading Using @code{dlltool} @@ -25006,7 +25470,7 @@ DLL in the static import library generated by @code{dlltool} with switch @item @code{-k} Kill @code{@@@var{nn}} from exported names -(@ref{1db,,Windows Calling Conventions} +(@ref{1e2,,Windows Calling Conventions} for a discussion about @code{Stdcall}-style symbols). @end table @@ -25062,7 +25526,7 @@ Use @code{assembler-name} as the assembler. The default is @code{as}. @end table @node GNAT and Windows Resources,Using GNAT DLLs from Microsoft Visual Studio Applications,Creating a Spec for Ada DLLs,Mixed-Language Programming on Windows -@anchor{gnat_ugn/platform_specific_information gnat-and-windows-resources}@anchor{202}@anchor{gnat_ugn/platform_specific_information id34}@anchor{203} +@anchor{gnat_ugn/platform_specific_information gnat-and-windows-resources}@anchor{209}@anchor{gnat_ugn/platform_specific_information id34}@anchor{20a} @subsubsection GNAT and Windows Resources @@ -25154,7 +25618,7 @@ the corresponding Microsoft documentation. @end menu @node Building Resources,Compiling Resources,,GNAT and Windows Resources -@anchor{gnat_ugn/platform_specific_information building-resources}@anchor{204}@anchor{gnat_ugn/platform_specific_information id35}@anchor{205} +@anchor{gnat_ugn/platform_specific_information building-resources}@anchor{20b}@anchor{gnat_ugn/platform_specific_information id35}@anchor{20c} @subsubsection Building Resources @@ -25174,7 +25638,7 @@ complete description of the resource script language can be found in the Microsoft documentation. @node Compiling Resources,Using Resources,Building Resources,GNAT and Windows Resources -@anchor{gnat_ugn/platform_specific_information compiling-resources}@anchor{206}@anchor{gnat_ugn/platform_specific_information id36}@anchor{207} +@anchor{gnat_ugn/platform_specific_information compiling-resources}@anchor{20d}@anchor{gnat_ugn/platform_specific_information id36}@anchor{20e} @subsubsection Compiling Resources @@ -25216,7 +25680,7 @@ $ windres -i myres.res -o myres.o @end quotation @node Using Resources,,Compiling Resources,GNAT and Windows Resources -@anchor{gnat_ugn/platform_specific_information id37}@anchor{208}@anchor{gnat_ugn/platform_specific_information using-resources}@anchor{209} +@anchor{gnat_ugn/platform_specific_information id37}@anchor{20f}@anchor{gnat_ugn/platform_specific_information using-resources}@anchor{210} @subsubsection Using Resources @@ -25236,7 +25700,7 @@ $ gnatmake myprog -largs myres.o @end quotation @node Using GNAT DLLs from Microsoft Visual Studio Applications,Debugging a DLL,GNAT and Windows Resources,Mixed-Language Programming on Windows -@anchor{gnat_ugn/platform_specific_information using-gnat-dll-from-msvs}@anchor{20a}@anchor{gnat_ugn/platform_specific_information using-gnat-dlls-from-microsoft-visual-studio-applications}@anchor{20b} +@anchor{gnat_ugn/platform_specific_information using-gnat-dll-from-msvs}@anchor{211}@anchor{gnat_ugn/platform_specific_information using-gnat-dlls-from-microsoft-visual-studio-applications}@anchor{212} @subsubsection Using GNAT DLLs from Microsoft Visual Studio Applications @@ -25271,7 +25735,7 @@ $ gprbuild -p mylib.gpr @item Produce a @code{.def} file for the symbols you need to interface with, either by hand or automatically with possibly some manual -adjustments (see @ref{1ec,,Creating Definition File Automatically}): +adjustments (see @ref{1f3,,Creating Definition File Automatically}): @end enumerate @quotation @@ -25288,7 +25752,7 @@ $ dlltool libmylib.dll -z libmylib.def --export-all-symbols Make sure that MSVS command-line tools are accessible on the path. @item -Create the Microsoft-style import library (see @ref{1ef,,MSVS-Style Import Library}): +Create the Microsoft-style import library (see @ref{1f6,,MSVS-Style Import Library}): @end enumerate @quotation @@ -25331,7 +25795,7 @@ the @code{.exe}. @end enumerate @node Debugging a DLL,Setting Stack Size from gnatlink,Using GNAT DLLs from Microsoft Visual Studio Applications,Mixed-Language Programming on Windows -@anchor{gnat_ugn/platform_specific_information debugging-a-dll}@anchor{20c}@anchor{gnat_ugn/platform_specific_information id38}@anchor{20d} +@anchor{gnat_ugn/platform_specific_information debugging-a-dll}@anchor{213}@anchor{gnat_ugn/platform_specific_information id38}@anchor{214} @subsubsection Debugging a DLL @@ -25368,7 +25832,7 @@ debugger compatible with the tools suite used to build the DLL. @end menu @node Program and DLL Both Built with GCC/GNAT,Program Built with Foreign Tools and DLL Built with GCC/GNAT,,Debugging a DLL -@anchor{gnat_ugn/platform_specific_information id39}@anchor{20e}@anchor{gnat_ugn/platform_specific_information program-and-dll-both-built-with-gcc-gnat}@anchor{20f} +@anchor{gnat_ugn/platform_specific_information id39}@anchor{215}@anchor{gnat_ugn/platform_specific_information program-and-dll-both-built-with-gcc-gnat}@anchor{216} @subsubsection Program and DLL Both Built with GCC/GNAT @@ -25378,7 +25842,7 @@ the process. Let’s suppose the main procedure is named @code{ada_main} and in the DLL there’s an entry point named @code{ada_dll}. -The DLL (@ref{1e5,,Introduction to Dynamic Link Libraries (DLLs)}) and +The DLL (@ref{1ec,,Introduction to Dynamic Link Libraries (DLLs)}) and program must have been built with the debugging information (see the GNAT @code{-g} switch). Here are the step-by-step instructions for debugging it: @@ -25415,10 +25879,10 @@ Set a breakpoint inside the DLL At this stage, a breakpoint is set inside the DLL. From there on you can use standard @code{GDB} commands to debug the whole program -(@ref{152,,Running and Debugging Ada Programs}). +(@ref{153,,Running and Debugging Ada Programs}). @node Program Built with Foreign Tools and DLL Built with GCC/GNAT,,Program and DLL Both Built with GCC/GNAT,Debugging a DLL -@anchor{gnat_ugn/platform_specific_information id40}@anchor{210}@anchor{gnat_ugn/platform_specific_information program-built-with-foreign-tools-and-dll-built-with-gcc-gnat}@anchor{211} +@anchor{gnat_ugn/platform_specific_information id40}@anchor{217}@anchor{gnat_ugn/platform_specific_information program-built-with-foreign-tools-and-dll-built-with-gcc-gnat}@anchor{218} @subsubsection Program Built with Foreign Tools and DLL Built with GCC/GNAT @@ -25435,7 +25899,7 @@ case, for example, for some C code built with Microsoft Visual C) and that there’s a DLL named @code{test.dll} containing an Ada entry point named @code{ada_dll}. -The DLL (see @ref{1e5,,Introduction to Dynamic Link Libraries (DLLs)}) must have +The DLL (see @ref{1ec,,Introduction to Dynamic Link Libraries (DLLs)}) must have been built with debugging information (see the GNAT @code{-g} switch). @subsubheading Debugging the DLL Directly @@ -25502,7 +25966,7 @@ Continue the program. This runs the program until it reaches the breakpoint that you’ve set. From that point, you can use standard @code{GDB} commands to debug a program as described in -(@ref{152,,Running and Debugging Ada Programs}). +(@ref{153,,Running and Debugging Ada Programs}). @end itemize You can also debug the DLL by attaching @code{GDB} to a running process. @@ -25572,21 +26036,22 @@ Continue process execution. This last step will resume the process execution and stop at the breakpoint we have set. From there you can use standard @code{GDB} commands to debug a program, as described in -@ref{152,,Running and Debugging Ada Programs}. +@ref{153,,Running and Debugging Ada Programs}. @node Setting Stack Size from gnatlink,Setting Heap Size from gnatlink,Debugging a DLL,Mixed-Language Programming on Windows -@anchor{gnat_ugn/platform_specific_information id41}@anchor{212}@anchor{gnat_ugn/platform_specific_information setting-stack-size-from-gnatlink}@anchor{12b} +@anchor{gnat_ugn/platform_specific_information id41}@anchor{219}@anchor{gnat_ugn/platform_specific_information setting-stack-size-from-gnatlink}@anchor{12b} @subsubsection Setting Stack Size from @code{gnatlink} You can specify the program stack size at link time. On most versions of Windows, starting with XP, this is mostly useful to set the size of the main stack (environment task). The other task stacks are set with -pragma Storage_Size or with the `gnatbind -d' command. +pragma Storage_Size or with the `gnatbind -d' command. The specified size will +become the reserved memory size of the underlying thread. Since very old versions of Windows (2000, NT4, etc.) don’t allow setting the -reserve size of individual tasks, the link-time stack size applies to all -tasks, and pragma Storage_Size has no effect. +reserve size of individual tasks, for those versions the link-time stack size +applies to all tasks, and pragma Storage_Size has no effect. In particular, Stack Overflow checks are made against this link-time specified size. @@ -25618,7 +26083,7 @@ because the comma is a separator for this switch. @end itemize @node Setting Heap Size from gnatlink,,Setting Stack Size from gnatlink,Mixed-Language Programming on Windows -@anchor{gnat_ugn/platform_specific_information id42}@anchor{213}@anchor{gnat_ugn/platform_specific_information setting-heap-size-from-gnatlink}@anchor{12c} +@anchor{gnat_ugn/platform_specific_information id42}@anchor{21a}@anchor{gnat_ugn/platform_specific_information setting-heap-size-from-gnatlink}@anchor{12c} @subsubsection Setting Heap Size from @code{gnatlink} @@ -25651,7 +26116,7 @@ because the comma is a separator for this switch. @end itemize @node Windows Specific Add-Ons,,Mixed-Language Programming on Windows,Microsoft Windows Topics -@anchor{gnat_ugn/platform_specific_information win32-specific-addons}@anchor{214}@anchor{gnat_ugn/platform_specific_information windows-specific-add-ons}@anchor{215} +@anchor{gnat_ugn/platform_specific_information win32-specific-addons}@anchor{21b}@anchor{gnat_ugn/platform_specific_information windows-specific-add-ons}@anchor{21c} @subsection Windows Specific Add-Ons @@ -25664,7 +26129,7 @@ This section describes the Windows specific add-ons. @end menu @node Win32Ada,wPOSIX,,Windows Specific Add-Ons -@anchor{gnat_ugn/platform_specific_information id43}@anchor{216}@anchor{gnat_ugn/platform_specific_information win32ada}@anchor{217} +@anchor{gnat_ugn/platform_specific_information id43}@anchor{21d}@anchor{gnat_ugn/platform_specific_information win32ada}@anchor{21e} @subsubsection Win32Ada @@ -25695,7 +26160,7 @@ gprbuild p.gpr @end quotation @node wPOSIX,,Win32Ada,Windows Specific Add-Ons -@anchor{gnat_ugn/platform_specific_information id44}@anchor{218}@anchor{gnat_ugn/platform_specific_information wposix}@anchor{219} +@anchor{gnat_ugn/platform_specific_information id44}@anchor{21f}@anchor{gnat_ugn/platform_specific_information wposix}@anchor{220} @subsubsection wPOSIX @@ -25728,7 +26193,7 @@ gprbuild p.gpr @end quotation @node Mac OS Topics,,Microsoft Windows Topics,Platform-Specific Information -@anchor{gnat_ugn/platform_specific_information id45}@anchor{21a}@anchor{gnat_ugn/platform_specific_information mac-os-topics}@anchor{21b} +@anchor{gnat_ugn/platform_specific_information id45}@anchor{221}@anchor{gnat_ugn/platform_specific_information mac-os-topics}@anchor{222} @section Mac OS Topics @@ -25743,7 +26208,7 @@ platform. @end menu @node Codesigning the Debugger,,,Mac OS Topics -@anchor{gnat_ugn/platform_specific_information codesigning-the-debugger}@anchor{21c} +@anchor{gnat_ugn/platform_specific_information codesigning-the-debugger}@anchor{223} @subsection Codesigning the Debugger @@ -25825,7 +26290,7 @@ installed GNAT. Also, be sure that users of @code{GDB} are in the Unix group @code{_developer}. @node Example of Binder Output File,Elaboration Order Handling in GNAT,Platform-Specific Information,Top -@anchor{gnat_ugn/example_of_binder_output doc}@anchor{21d}@anchor{gnat_ugn/example_of_binder_output example-of-binder-output-file}@anchor{f}@anchor{gnat_ugn/example_of_binder_output id1}@anchor{21e} +@anchor{gnat_ugn/example_of_binder_output doc}@anchor{224}@anchor{gnat_ugn/example_of_binder_output example-of-binder-output-file}@anchor{f}@anchor{gnat_ugn/example_of_binder_output id1}@anchor{225} @chapter Example of Binder Output File @@ -26575,7 +27040,7 @@ elaboration code in your own application). @c -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit @node Elaboration Order Handling in GNAT,Inline Assembler,Example of Binder Output File,Top -@anchor{gnat_ugn/elaboration_order_handling_in_gnat doc}@anchor{21f}@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-order-handling-in-gnat}@anchor{10}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id1}@anchor{220} +@anchor{gnat_ugn/elaboration_order_handling_in_gnat doc}@anchor{226}@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-order-handling-in-gnat}@anchor{10}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id1}@anchor{227} @chapter Elaboration Order Handling in GNAT @@ -26605,7 +27070,7 @@ GNAT, either automatically or with explicit programming features. @end menu @node Elaboration Code,Elaboration Order,,Elaboration Order Handling in GNAT -@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-code}@anchor{221}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id2}@anchor{222} +@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-code}@anchor{228}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id2}@anchor{229} @section Elaboration Code @@ -26754,7 +27219,7 @@ elaborated. @end itemize @node Elaboration Order,Checking the Elaboration Order,Elaboration Code,Elaboration Order Handling in GNAT -@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-order}@anchor{223}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id3}@anchor{224} +@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-order}@anchor{22a}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id3}@anchor{22b} @section Elaboration Order @@ -26924,7 +27389,7 @@ however a compiler may not always find such an order due to complications with respect to control and data flow. @node Checking the Elaboration Order,Controlling the Elaboration Order in Ada,Elaboration Order,Elaboration Order Handling in GNAT -@anchor{gnat_ugn/elaboration_order_handling_in_gnat checking-the-elaboration-order}@anchor{225}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id4}@anchor{226} +@anchor{gnat_ugn/elaboration_order_handling_in_gnat checking-the-elaboration-order}@anchor{22c}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id4}@anchor{22d} @section Checking the Elaboration Order @@ -26985,7 +27450,7 @@ order. @end itemize @node Controlling the Elaboration Order in Ada,Controlling the Elaboration Order in GNAT,Checking the Elaboration Order,Elaboration Order Handling in GNAT -@anchor{gnat_ugn/elaboration_order_handling_in_gnat controlling-the-elaboration-order-in-ada}@anchor{227}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id5}@anchor{228} +@anchor{gnat_ugn/elaboration_order_handling_in_gnat controlling-the-elaboration-order-in-ada}@anchor{22e}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id5}@anchor{22f} @section Controlling the Elaboration Order in Ada @@ -27314,7 +27779,7 @@ is that the program continues to stay in the last state (one or more correct orders exist) even if maintenance changes the bodies of targets. @node Controlling the Elaboration Order in GNAT,Mixing Elaboration Models,Controlling the Elaboration Order in Ada,Elaboration Order Handling in GNAT -@anchor{gnat_ugn/elaboration_order_handling_in_gnat controlling-the-elaboration-order-in-gnat}@anchor{229}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id6}@anchor{22a} +@anchor{gnat_ugn/elaboration_order_handling_in_gnat controlling-the-elaboration-order-in-gnat}@anchor{230}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id6}@anchor{231} @section Controlling the Elaboration Order in GNAT @@ -27445,7 +27910,7 @@ that in this mode, GNAT may not diagnose certain elaboration issues or install run-time checks. @node Mixing Elaboration Models,ABE Diagnostics,Controlling the Elaboration Order in GNAT,Elaboration Order Handling in GNAT -@anchor{gnat_ugn/elaboration_order_handling_in_gnat id7}@anchor{22b}@anchor{gnat_ugn/elaboration_order_handling_in_gnat mixing-elaboration-models}@anchor{22c} +@anchor{gnat_ugn/elaboration_order_handling_in_gnat id7}@anchor{232}@anchor{gnat_ugn/elaboration_order_handling_in_gnat mixing-elaboration-models}@anchor{233} @section Mixing Elaboration Models @@ -27492,7 +27957,7 @@ warning: "y.ads" which has static elaboration checks You can suppress these warnings by specifying binder switch @code{-ws}. @node ABE Diagnostics,SPARK Diagnostics,Mixing Elaboration Models,Elaboration Order Handling in GNAT -@anchor{gnat_ugn/elaboration_order_handling_in_gnat abe-diagnostics}@anchor{22d}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id8}@anchor{22e} +@anchor{gnat_ugn/elaboration_order_handling_in_gnat abe-diagnostics}@anchor{234}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id8}@anchor{235} @section ABE Diagnostics @@ -27599,7 +28064,7 @@ declaration @code{Safe} because the body of function @code{ABE} has already been elaborated at that point. @node SPARK Diagnostics,Elaboration Circularities,ABE Diagnostics,Elaboration Order Handling in GNAT -@anchor{gnat_ugn/elaboration_order_handling_in_gnat id9}@anchor{22f}@anchor{gnat_ugn/elaboration_order_handling_in_gnat spark-diagnostics}@anchor{230} +@anchor{gnat_ugn/elaboration_order_handling_in_gnat id9}@anchor{236}@anchor{gnat_ugn/elaboration_order_handling_in_gnat spark-diagnostics}@anchor{237} @section SPARK Diagnostics @@ -27625,7 +28090,7 @@ rules. @end quotation @node Elaboration Circularities,Resolving Elaboration Circularities,SPARK Diagnostics,Elaboration Order Handling in GNAT -@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-circularities}@anchor{231}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id10}@anchor{232} +@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-circularities}@anchor{238}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id10}@anchor{239} @section Elaboration Circularities @@ -27725,7 +28190,7 @@ This section enumerates various tactics for eliminating the circularity. @end itemize @node Resolving Elaboration Circularities,Elaboration-related Compiler Switches,Elaboration Circularities,Elaboration Order Handling in GNAT -@anchor{gnat_ugn/elaboration_order_handling_in_gnat id11}@anchor{233}@anchor{gnat_ugn/elaboration_order_handling_in_gnat resolving-elaboration-circularities}@anchor{234} +@anchor{gnat_ugn/elaboration_order_handling_in_gnat id11}@anchor{23a}@anchor{gnat_ugn/elaboration_order_handling_in_gnat resolving-elaboration-circularities}@anchor{23b} @section Resolving Elaboration Circularities @@ -27996,7 +28461,7 @@ Use the relaxed dynamic-elaboration model, with compiler switches @end itemize @node Elaboration-related Compiler Switches,Summary of Procedures for Elaboration Control,Resolving Elaboration Circularities,Elaboration Order Handling in GNAT -@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-related-compiler-switches}@anchor{235}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id12}@anchor{236} +@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-related-compiler-switches}@anchor{23c}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id12}@anchor{23d} @section Elaboration-related Compiler Switches @@ -28177,7 +28642,7 @@ checks. The example above will still fail at run time with an ABE. @end table @node Summary of Procedures for Elaboration Control,Inspecting the Chosen Elaboration Order,Elaboration-related Compiler Switches,Elaboration Order Handling in GNAT -@anchor{gnat_ugn/elaboration_order_handling_in_gnat id13}@anchor{237}@anchor{gnat_ugn/elaboration_order_handling_in_gnat summary-of-procedures-for-elaboration-control}@anchor{238} +@anchor{gnat_ugn/elaboration_order_handling_in_gnat id13}@anchor{23e}@anchor{gnat_ugn/elaboration_order_handling_in_gnat summary-of-procedures-for-elaboration-control}@anchor{23f} @section Summary of Procedures for Elaboration Control @@ -28235,7 +28700,7 @@ Use the relaxed dynamic elaboration model, with compiler switches @end itemize @node Inspecting the Chosen Elaboration Order,,Summary of Procedures for Elaboration Control,Elaboration Order Handling in GNAT -@anchor{gnat_ugn/elaboration_order_handling_in_gnat id14}@anchor{239}@anchor{gnat_ugn/elaboration_order_handling_in_gnat inspecting-the-chosen-elaboration-order}@anchor{23a} +@anchor{gnat_ugn/elaboration_order_handling_in_gnat id14}@anchor{240}@anchor{gnat_ugn/elaboration_order_handling_in_gnat inspecting-the-chosen-elaboration-order}@anchor{241} @section Inspecting the Chosen Elaboration Order @@ -28378,7 +28843,7 @@ gdbstr (body) @end quotation @node Inline Assembler,GNU Free Documentation License,Elaboration Order Handling in GNAT,Top -@anchor{gnat_ugn/inline_assembler doc}@anchor{23b}@anchor{gnat_ugn/inline_assembler id1}@anchor{23c}@anchor{gnat_ugn/inline_assembler inline-assembler}@anchor{11} +@anchor{gnat_ugn/inline_assembler doc}@anchor{242}@anchor{gnat_ugn/inline_assembler id1}@anchor{243}@anchor{gnat_ugn/inline_assembler inline-assembler}@anchor{11} @chapter Inline Assembler @@ -28437,7 +28902,7 @@ and assembly language programming. @end menu @node Basic Assembler Syntax,A Simple Example of Inline Assembler,,Inline Assembler -@anchor{gnat_ugn/inline_assembler basic-assembler-syntax}@anchor{23d}@anchor{gnat_ugn/inline_assembler id2}@anchor{23e} +@anchor{gnat_ugn/inline_assembler basic-assembler-syntax}@anchor{244}@anchor{gnat_ugn/inline_assembler id2}@anchor{245} @section Basic Assembler Syntax @@ -28553,7 +29018,7 @@ Intel: Destination first; for example @code{mov eax, 4}@w{ } @node A Simple Example of Inline Assembler,Output Variables in Inline Assembler,Basic Assembler Syntax,Inline Assembler -@anchor{gnat_ugn/inline_assembler a-simple-example-of-inline-assembler}@anchor{23f}@anchor{gnat_ugn/inline_assembler id3}@anchor{240} +@anchor{gnat_ugn/inline_assembler a-simple-example-of-inline-assembler}@anchor{246}@anchor{gnat_ugn/inline_assembler id3}@anchor{247} @section A Simple Example of Inline Assembler @@ -28702,7 +29167,7 @@ If there are no errors, @code{as} generates an object file called @code{nothing.out}. @node Output Variables in Inline Assembler,Input Variables in Inline Assembler,A Simple Example of Inline Assembler,Inline Assembler -@anchor{gnat_ugn/inline_assembler id4}@anchor{241}@anchor{gnat_ugn/inline_assembler output-variables-in-inline-assembler}@anchor{242} +@anchor{gnat_ugn/inline_assembler id4}@anchor{248}@anchor{gnat_ugn/inline_assembler output-variables-in-inline-assembler}@anchor{249} @section Output Variables in Inline Assembler @@ -29069,7 +29534,7 @@ end Get_Flags_3; @end quotation @node Input Variables in Inline Assembler,Inlining Inline Assembler Code,Output Variables in Inline Assembler,Inline Assembler -@anchor{gnat_ugn/inline_assembler id5}@anchor{243}@anchor{gnat_ugn/inline_assembler input-variables-in-inline-assembler}@anchor{244} +@anchor{gnat_ugn/inline_assembler id5}@anchor{24a}@anchor{gnat_ugn/inline_assembler input-variables-in-inline-assembler}@anchor{24b} @section Input Variables in Inline Assembler @@ -29158,7 +29623,7 @@ _increment__incr.1: @end quotation @node Inlining Inline Assembler Code,Other Asm Functionality,Input Variables in Inline Assembler,Inline Assembler -@anchor{gnat_ugn/inline_assembler id6}@anchor{245}@anchor{gnat_ugn/inline_assembler inlining-inline-assembler-code}@anchor{246} +@anchor{gnat_ugn/inline_assembler id6}@anchor{24c}@anchor{gnat_ugn/inline_assembler inlining-inline-assembler-code}@anchor{24d} @section Inlining Inline Assembler Code @@ -29229,7 +29694,7 @@ movl %esi,%eax thus saving the overhead of stack frame setup and an out-of-line call. @node Other Asm Functionality,,Inlining Inline Assembler Code,Inline Assembler -@anchor{gnat_ugn/inline_assembler id7}@anchor{247}@anchor{gnat_ugn/inline_assembler other-asm-functionality}@anchor{248} +@anchor{gnat_ugn/inline_assembler id7}@anchor{24e}@anchor{gnat_ugn/inline_assembler other-asm-functionality}@anchor{24f} @section Other @code{Asm} Functionality @@ -29244,7 +29709,7 @@ and @code{Volatile}, which inhibits unwanted optimizations. @end menu @node The Clobber Parameter,The Volatile Parameter,,Other Asm Functionality -@anchor{gnat_ugn/inline_assembler id8}@anchor{249}@anchor{gnat_ugn/inline_assembler the-clobber-parameter}@anchor{24a} +@anchor{gnat_ugn/inline_assembler id8}@anchor{250}@anchor{gnat_ugn/inline_assembler the-clobber-parameter}@anchor{251} @subsection The @code{Clobber} Parameter @@ -29308,7 +29773,7 @@ Use ‘register’ name @code{memory} if you changed a memory location @end itemize @node The Volatile Parameter,,The Clobber Parameter,Other Asm Functionality -@anchor{gnat_ugn/inline_assembler id9}@anchor{24b}@anchor{gnat_ugn/inline_assembler the-volatile-parameter}@anchor{24c} +@anchor{gnat_ugn/inline_assembler id9}@anchor{252}@anchor{gnat_ugn/inline_assembler the-volatile-parameter}@anchor{253} @subsection The @code{Volatile} Parameter @@ -29344,7 +29809,7 @@ to @code{True} only if the compiler’s optimizations have created problems. @node GNU Free Documentation License,Index,Inline Assembler,Top -@anchor{share/gnu_free_documentation_license doc}@anchor{24d}@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{24e} +@anchor{share/gnu_free_documentation_license doc}@anchor{254}@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{255} @chapter GNU Free Documentation License diff --git a/gcc/ada/gnatcmd.adb b/gcc/ada/gnatcmd.adb index 546dbca87f4d..5e3802e7f8ae 100644 --- a/gcc/ada/gnatcmd.adb +++ b/gcc/ada/gnatcmd.adb @@ -368,7 +368,7 @@ begin -- --help flag. Set_Standard_Output; Write_Eol; - Write_Line ("Report bugs to report@adacore.com"); + Write_Line ("Report bugs to support@adacore.com"); return; end if; diff --git a/gcc/ada/gnatls.adb b/gcc/ada/gnatls.adb index 4e549a98c297..5f7e490c1c56 100644 --- a/gcc/ada/gnatls.adb +++ b/gcc/ada/gnatls.adb @@ -117,7 +117,6 @@ procedure Gnatls is Also_Predef : Boolean := False; -- -a Dependable : Boolean := False; -- -d - License : Boolean := False; -- -l Very_Verbose_Mode : Boolean := False; -- -V -- Command line flags @@ -188,9 +187,6 @@ procedure Gnatls is procedure Usage; -- Print usage message - procedure Output_License_Information; - -- Output license statement, and if not found, output reference to COPYING - function Image (Restriction : Restriction_Id) return String; -- Returns the capitalized image of Restriction @@ -881,20 +877,6 @@ procedure Gnatls is return Normalize_Pathname (Path); end Normalize; - -------------------------------- - -- Output_License_Information -- - -------------------------------- - - procedure Output_License_Information is - begin - case Build_Type is - when others => - Write_Str ("Please refer to file COPYING in your distribution" - & " for license terms."); - Write_Eol; - end case; - end Output_License_Information; - ------------------- -- Output_Object -- ------------------- @@ -1605,7 +1587,9 @@ procedure Gnatls is Name_Len := 0; if not Is_Absolute_Path (Self (First .. Last)) then - Add_Str_To_Name_Buffer (Get_Current_Dir); -- ??? System call + Add_Str_To_Name_Buffer + (GNAT.Directory_Operations.Get_Current_Dir); + Add_Char_To_Name_Buffer (Directory_Separator); end if; @@ -1792,7 +1776,6 @@ procedure Gnatls is when 'o' => Reset_Print; Print_Object := True; when 'v' => Verbose_Mode := True; when 'd' => Dependable := True; - when 'l' => License := True; when 'V' => Very_Verbose_Mode := True; when others => OK := False; @@ -1946,11 +1929,6 @@ procedure Gnatls is "depend"); Write_Eol; - -- Line for -l - - Write_Str (" -l output license information"); - Write_Eol; - -- Line for -v Write_Str (" -v verbose output, full path and unit " & @@ -2046,21 +2024,6 @@ begin Next_Arg := Next_Arg + 1; end loop Scan_Args; - -- If -l (output license information) is given, it must be the only switch - - if License then - if Arg_Count = 2 then - Output_License_Information; - - else - Set_Standard_Error; - Write_Str ("Can't use -l with another switch"); - Write_Eol; - Try_Help; - Exit_Program (E_Fatal); - end if; - end if; - -- Handle --RTS switch if RTS_Specified /= null then diff --git a/gcc/ada/init.c b/gcc/ada/init.c index 1be90ec58121..35b77736a607 100644 --- a/gcc/ada/init.c +++ b/gcc/ada/init.c @@ -47,6 +47,7 @@ #ifdef __vxworks #include "vxWorks.h" #include "version.h" /* for _WRS_VXWORKS_MAJOR */ +#include <string.h> /* for strncmp */ #endif #ifdef __ANDROID__ diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb index 494f1f8f004f..5e2f033b913d 100644 --- a/gcc/ada/inline.adb +++ b/gcc/ada/inline.adb @@ -320,6 +320,7 @@ package body Inline is -- Exit_Cases -- Postcondition -- Precondition + -- Program_Exit -- Refined_Global -- Refined_Depends -- Refined_Post @@ -1005,9 +1006,9 @@ package body Inline is end loop; -- The list of inlined subprograms is an overestimate, because it - -- includes inlined functions called from functions that are compiled - -- as part of an inlined package, but are not themselves called. An - -- accurate computation of just those subprograms that are needed + -- includes inlined subprograms called from subprograms that are + -- declared in an inlined package, but are not themselves called. + -- An accurate computation of just those subprograms that are needed -- requires that we perform a transitive closure over the call graph, -- starting from calls in the main compilation unit. @@ -3396,10 +3397,6 @@ package body Inline is -- If the function body is a single expression, replace call with -- expression, else insert block appropriately. - procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id); - -- If procedure body has no local variables, inline body without - -- creating block, otherwise rewrite call with block. - --------------------- -- Make_Exit_Label -- --------------------- @@ -3784,35 +3781,6 @@ package body Inline is end if; end Rewrite_Function_Call; - ---------------------------- - -- Rewrite_Procedure_Call -- - ---------------------------- - - procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id) is - HSS : constant Node_Id := Handled_Statement_Sequence (Blk); - - begin - -- If there is a transient scope for N, this will be the scope of the - -- actions for N, and the statements in Blk need to be within this - -- scope. For example, they need to have visibility on the constant - -- declarations created for the formals. - - -- If N needs no transient scope, and if there are no declarations in - -- the inlined body, we can do a little optimization and insert the - -- statements for the body directly after N, and rewrite N to a - -- null statement, instead of rewriting N into a full-blown block - -- statement. - - if not Scope_Is_Transient - and then Is_Empty_List (Declarations (Blk)) - then - Insert_List_After (N, Statements (HSS)); - Rewrite (N, Make_Null_Statement (Loc)); - else - Rewrite (N, Blk); - end if; - end Rewrite_Procedure_Call; - -- Start of processing for Expand_Inlined_Call begin @@ -3829,6 +3797,17 @@ package body Inline is and then Is_Unc; end if; + -- Inlining function calls returning an object of unconstrained type as + -- function actuals or in a return statement is not supported: a + -- temporary variable will be declared of unconstrained type without + -- initializing expression. + + pragma Assert + (not Uses_Back_End + or else Nkind (Parent (N)) not in + N_Function_Call | N_Simple_Return_Statement + or else not Is_Unc); + -- Check for an illegal attempt to inline a recursive procedure. If the -- subprogram has parameters this is detected when trying to supply a -- binding for parameters that already have one. For parameterless @@ -4077,6 +4056,7 @@ package body Inline is -- Replace call with temporary and create its declaration Temp := Make_Temporary (Loc, 'C'); + Mutate_Ekind (Temp, E_Constant); Set_Is_Internal (Temp); -- For the unconstrained case, the generated temporary has the @@ -4271,7 +4251,7 @@ package body Inline is end; if Ekind (Subp) = E_Procedure then - Rewrite_Procedure_Call (N, Blk); + Rewrite (N, Blk); else Rewrite_Function_Call (N, Blk); @@ -4922,11 +4902,17 @@ package body Inline is and then Ekind (Info.Fin_Scop) = E_Package_Body then Set_In_Package_Body (Spec_Entity (Info.Fin_Scop), True); + Instantiate_Package_Body (Info); + Set_In_Package_Body (Spec_Entity (Info.Fin_Scop), False); + else + Instantiate_Package_Body (Info); end if; - Instantiate_Package_Body (Info); + -- No need to generate cleanups if the main unit is generic - if Present (Info.Fin_Scop) then + if Present (Info.Fin_Scop) + and then not Is_Generic_Unit (Main_Unit_Entity) + then Scop := Info.Fin_Scop; -- If the enclosing finalization scope is dynamic, the instance @@ -4939,12 +4925,6 @@ package body Inline is end if; Add_Scope_To_Clean (Scop); - - -- Reset the In_Package_Body flag if it was set above - - if Ekind (Info.Fin_Scop) = E_Package_Body then - Set_In_Package_Body (Spec_Entity (Info.Fin_Scop), False); - end if; end if; -- For subprogram instances, always instantiate the body @@ -4965,10 +4945,6 @@ package body Inline is Push_Scope (Standard_Standard); To_Clean := New_Elmt_List; - if Is_Generic_Unit (Cunit_Entity (Main_Unit)) then - Start_Generic; - end if; - -- A body instantiation may generate additional instantiations, so -- the following loop must scan to the end of a possibly expanding -- set (that's why we cannot simply use a FOR loop here). We must @@ -5007,16 +4983,10 @@ package body Inline is Pending_Instantiations.Init; end if; - -- We can now complete the cleanup actions of scopes that contain - -- pending instantiations (skipped for generic units, since we - -- never need any cleanups in generic units). + -- Expand the cleanup actions of scopes that contain instantiations - if Expander_Active - and then not Is_Generic_Unit (Main_Unit_Entity) - then + if Expander_Active then Cleanup_Scopes; - elsif Is_Generic_Unit (Cunit_Entity (Main_Unit)) then - End_Generic; end if; Pop_Scope; @@ -5271,6 +5241,7 @@ package body Inline is | Name_Exit_Cases | Name_Postcondition | Name_Precondition + | Name_Program_Exit | Name_Refined_Global | Name_Refined_Depends | Name_Refined_Post diff --git a/gcc/ada/diagnostics-json_utils.adb b/gcc/ada/json_utils.adb similarity index 50% rename from gcc/ada/diagnostics-json_utils.adb rename to gcc/ada/json_utils.adb index 072cab4a4928..9d289fb45ff2 100644 --- a/gcc/ada/diagnostics-json_utils.adb +++ b/gcc/ada/json_utils.adb @@ -2,7 +2,7 @@ -- -- -- GNAT COMPILER COMPONENTS -- -- -- --- D I A G N O S T I C S . J S O N _ U T I L S -- +-- J S O N _ U T I L S -- -- -- -- B o d y -- -- -- @@ -22,9 +22,13 @@ -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ + +with Namet; use Namet; +with Osint; with Output; use Output; +with System.OS_Lib; -package body Diagnostics.JSON_Utils is +package body JSON_Utils is ----------------- -- Begin_Block -- @@ -64,6 +68,141 @@ package body Diagnostics.JSON_Utils is end if; end NL_And_Indent; + ----------------- + -- To_File_Uri -- + ----------------- + + function To_File_Uri (Path : String) return String is + + function Normalize_Uri (Path : String) return String; + -- Construct a normalized URI from the path name by replacing reserved + -- URI characters that can appear in paths with their escape character + -- combinations. + -- + -- According to the URI standard reserved charcthers within the paths + -- should be percent encoded: + -- + -- https://www.rfc-editor.org/info/rfc3986 + -- + -- Reserved charcters are defined as: + -- + -- reserved = gen-delims / sub-delims + -- gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" + -- sub-delims = "!" / "$" / "&" / "’" / "(" / ")" + -- / "*" / "+" / "," / ";" / "=" + + ------------------- + -- Normalize_Uri -- + ------------------- + + function Normalize_Uri (Path : String) return String is + Buf : Bounded_String; + begin + for C of Path loop + case C is + when '\' => + + -- Use forward slashes instead of backward slashes as + -- separators on Windows and on Linux simply encode the + -- symbol if part of a directory name. + + if Osint.On_Windows then + Append (Buf, '/'); + else + Append (Buf, "%5C"); + end if; + + when ' ' => + Append (Buf, "%20"); + + when '!' => + Append (Buf, "%21"); + + when '#' => + Append (Buf, "%23"); + + when '$' => + Append (Buf, "%24"); + + when '&' => + Append (Buf, "%26"); + + when ''' => + Append (Buf, "%27"); + + when '(' => + Append (Buf, "%28"); + + when ')' => + Append (Buf, "%29"); + + when '*' => + Append (Buf, "%2A"); + + when '+' => + Append (Buf, "%2A"); + + when ',' => + Append (Buf, "%2A"); + + when '/' => + -- Forward slash is a valid file separator on both Unix and + -- Windows based machines and should be treated as such + -- within a path. + Append (Buf, '/'); + + when ':' => + Append (Buf, "%3A"); + + when ';' => + Append (Buf, "%3B"); + + when '=' => + Append (Buf, "%3D"); + + when '?' => + Append (Buf, "%3F"); + + when '@' => + Append (Buf, "%40"); + + when '[' => + Append (Buf, "%5B"); + + when ']' => + Append (Buf, "%5D"); + + when others => + Append (Buf, C); + end case; + end loop; + + return To_String (Buf); + end Normalize_Uri; + + Norm_Uri : constant String := Normalize_Uri (Path); + + -- Start of processing for To_File_Uri + + begin + if System.OS_Lib.Is_Absolute_Path (Path) then + -- URI-s using the file scheme should start with the following + -- prefix: + -- + -- "file:///" + + if Osint.On_Windows then + return "file:///" & Norm_Uri; + else + -- Full paths on linux based systems already start with '/' + + return "file://" & Norm_Uri; + end if; + else + return Norm_Uri; + end if; + end To_File_Uri; + ----------------------------- -- Write_Boolean_Attribute -- ----------------------------- @@ -112,4 +251,4 @@ package body Diagnostics.JSON_Utils is Write_Char ('"'); end Write_String_Attribute; -end Diagnostics.JSON_Utils; +end JSON_Utils; diff --git a/gcc/ada/diagnostics-json_utils.ads b/gcc/ada/json_utils.ads similarity index 90% rename from gcc/ada/diagnostics-json_utils.ads rename to gcc/ada/json_utils.ads index 526e09e49cd6..7a8251c97a49 100644 --- a/gcc/ada/diagnostics-json_utils.ads +++ b/gcc/ada/json_utils.ads @@ -2,7 +2,7 @@ -- -- -- GNAT COMPILER COMPONENTS -- -- -- --- D I A G N O S T I C S . J S O N _ U T I L S -- +-- J S O N _ U T I L S -- -- -- -- S p e c -- -- -- @@ -23,7 +23,9 @@ -- -- ------------------------------------------------------------------------------ -package Diagnostics.JSON_Utils is +with Types; use Types; + +package JSON_Utils is JSON_FORMATTING : constant Boolean := True; -- Adds newlines and indentation to the output JSON. @@ -49,6 +51,11 @@ package Diagnostics.JSON_Utils is procedure NL_And_Indent; -- Print a new line + function To_File_Uri (Path : String) return String; + -- Converts an absolute Path into a file URI string by adding the file + -- schema prefix "file:///" and replacing all of the URI reserved + -- characters in the absolute path. + procedure Write_Boolean_Attribute (Name : String; Value : Boolean); -- Write a JSON attribute with a boolean value. -- @@ -72,4 +79,4 @@ package Diagnostics.JSON_Utils is -- The Value is surrounded by double quotes ("") and the special characters -- within the string are escaped. -end Diagnostics.JSON_Utils; +end JSON_Utils; diff --git a/gcc/ada/krunch.adb b/gcc/ada/krunch.adb index 35df625f3bf9..409431d5a695 100644 --- a/gcc/ada/krunch.adb +++ b/gcc/ada/krunch.adb @@ -271,6 +271,4 @@ begin Buffer (Len) := Buffer (J); end if; end loop; - - return; end Krunch; diff --git a/gcc/ada/layout.adb b/gcc/ada/layout.adb index 08bbcc0d9a42..099ea49656d9 100644 --- a/gcc/ada/layout.adb +++ b/gcc/ada/layout.adb @@ -227,9 +227,7 @@ package body Layout is procedure Layout_Object (E : Entity_Id) is pragma Unreferenced (E); begin - -- Nothing to do for now, assume backend does the layout - - return; + null; -- Nothing to do for now, assume backend does the layout end Layout_Object; ----------------- diff --git a/gcc/ada/lib-load.adb b/gcc/ada/lib-load.adb index 46de9111147c..bdeea1c8a75d 100644 --- a/gcc/ada/lib-load.adb +++ b/gcc/ada/lib-load.adb @@ -226,13 +226,11 @@ package body Lib.Load is Fatal_Error => Error_Detected, Generate_Code => False, Has_RACW => False, - Filler => False, Ident_String => Empty, Is_Predefined_Renaming => Ren_Name, Is_Predefined_Unit => Pre_Name or Ren_Name, Is_Internal_Unit => Pre_Name or Ren_Name or GNAT_Name, - Filler2 => False, Loading => False, Main_Priority => Default_Main_Priority, @@ -374,13 +372,11 @@ package body Lib.Load is Fatal_Error => None, Generate_Code => True, Has_RACW => False, - Filler => False, Ident_String => Empty, Is_Predefined_Renaming => Ren_Name, Is_Predefined_Unit => Pre_Name or Ren_Name, Is_Internal_Unit => Pre_Name or Ren_Name or GNAT_Name, - Filler2 => False, Loading => True, Main_Priority => Default_Main_Priority, @@ -760,13 +756,11 @@ package body Lib.Load is Fatal_Error => None, Generate_Code => False, Has_RACW => False, - Filler => False, Ident_String => Empty, Is_Predefined_Renaming => Ren_Name, Is_Predefined_Unit => Pre_Name or Ren_Name, Is_Internal_Unit => Pre_Name or Ren_Name or GNAT_Name, - Filler2 => False, Loading => True, Main_Priority => Default_Main_Priority, diff --git a/gcc/ada/lib-writ.adb b/gcc/ada/lib-writ.adb index ccb0bd2a175a..b7a7f129de95 100644 --- a/gcc/ada/lib-writ.adb +++ b/gcc/ada/lib-writ.adb @@ -116,12 +116,10 @@ package body Lib.Writ is Fatal_Error => None, Generate_Code => False, Has_RACW => False, - Filler => False, Ident_String => Empty, Is_Predefined_Renaming => False, Is_Internal_Unit => False, Is_Predefined_Unit => False, - Filler2 => False, Loading => False, Main_Priority => -1, Main_CPU => -1, @@ -175,12 +173,10 @@ package body Lib.Writ is Fatal_Error => None, Generate_Code => False, Has_RACW => False, - Filler => False, Ident_String => Empty, Is_Predefined_Renaming => False, Is_Internal_Unit => True, Is_Predefined_Unit => True, - Filler2 => False, Loading => False, Main_Priority => -1, Main_CPU => -1, diff --git a/gcc/ada/lib-xref-spark_specific.adb b/gcc/ada/lib-xref-spark_specific.adb index d77d6aa4dd02..03693a96bae7 100644 --- a/gcc/ada/lib-xref-spark_specific.adb +++ b/gcc/ada/lib-xref-spark_specific.adb @@ -258,6 +258,13 @@ package body SPARK_Specific is Context := Defining_Entity (Context); exit; + when N_Subunit => + Context := Corresponding_Stub (Context); + + when N_Body_Stub => + Context := Corresponding_Spec_Of_Stub (Context); + exit; + when others => Context := Parent (Context); end case; diff --git a/gcc/ada/lib.adb b/gcc/ada/lib.adb index 2c6a6823ebad..3fd9540acb37 100644 --- a/gcc/ada/lib.adb +++ b/gcc/ada/lib.adb @@ -1062,7 +1062,7 @@ package body Lib is ----------------------------- function Increment_Serial_Number return Nat is - TSN : Int renames Units.Table (Current_Sem_Unit).Serial_Number; + TSN : Nat renames Units.Table (Current_Sem_Unit).Serial_Number; begin TSN := TSN + 1; return TSN; @@ -1129,15 +1129,6 @@ package body Lib is Units.Locked := True; end Lock; - --------------- - -- Num_Units -- - --------------- - - function Num_Units return Nat is - begin - return Int (Units.Last) - Int (Main_Unit) + 1; - end Num_Units; - ----------------- -- Remove_Unit -- ----------------- @@ -1232,7 +1223,7 @@ package body Lib is ------------------------------- procedure Synchronize_Serial_Number (SN : Nat) is - TSN : Int renames Units.Table (Current_Sem_Unit).Serial_Number; + TSN : Nat renames Units.Table (Current_Sem_Unit).Serial_Number; begin -- We should not be trying to synchronize downward diff --git a/gcc/ada/lib.ads b/gcc/ada/lib.ads index c902ca217a66..928f6f840c87 100644 --- a/gcc/ada/lib.ads +++ b/gcc/ada/lib.ads @@ -633,10 +633,8 @@ package Lib is -- Same as above, but for Source_Ptr function ipu (N : Node_Or_Entity_Id) return Boolean; - -- Same as In_Predefined_Unit, but renamed so it can assist debugging. - -- Otherwise, there is a disambiguous name conflict in the two versions of - -- In_Predefined_Unit which makes it inconvient to set as a breakpoint - -- condition. + -- Same as In_Predefined_Unit, but renamed to this unambiguous name for use + -- in the debugger. function In_Predefined_Unit (N : Node_Or_Entity_Id) return Boolean; -- Returns True if the given node or entity appears within the source text @@ -720,12 +718,9 @@ package Lib is procedure Lock; -- Lock internal tables before calling back end - function Num_Units return Nat; - -- Number of units currently in unit table - procedure Remove_Unit (U : Unit_Number_Type); - -- Remove unit U from unit table. Currently this is effective only if U is - -- the last unit currently stored in the unit table. + -- Remove unit U from unit table. U must be the last unit currently stored + -- in the unit table. procedure Replace_Linker_Option_String (S : String_Id; @@ -857,7 +852,7 @@ private Source_Index : Source_File_Index; Cunit : Node_Id; Cunit_Entity : Entity_Id; - Dependency_Num : Int; + Dependency_Num : Nat; Ident_String : Node_Id; Main_Priority : Int; Main_CPU : Int; @@ -871,55 +866,14 @@ private Has_RACW : Boolean; Dynamic_Elab : Boolean; No_Elab_Code_All : Boolean; - Filler : Boolean; Loading : Boolean; OA_Setting : Character; Is_Predefined_Renaming : Boolean; Is_Internal_Unit : Boolean; Is_Predefined_Unit : Boolean; - Filler2 : Boolean; - end record; - - -- The following representation clause ensures that the above record - -- has no holes. We do this so that when instances of this record are - -- written by Tree_Gen, we do not write uninitialized values to the file. - - for Unit_Record use record - Unit_File_Name at 0 range 0 .. 31; - Unit_Name at 4 range 0 .. 31; - Munit_Index at 8 range 0 .. 31; - Expected_Unit at 12 range 0 .. 31; - Source_Index at 16 range 0 .. 31; - Cunit at 20 range 0 .. 31; - Cunit_Entity at 24 range 0 .. 31; - Dependency_Num at 28 range 0 .. 31; - Ident_String at 32 range 0 .. 31; - Main_Priority at 36 range 0 .. 31; - Main_CPU at 40 range 0 .. 31; - Primary_Stack_Count at 44 range 0 .. 31; - Sec_Stack_Count at 48 range 0 .. 31; - Serial_Number at 52 range 0 .. 31; - Version at 56 range 0 .. 31; - Error_Location at 60 range 0 .. 31; - Fatal_Error at 64 range 0 .. 7; - Generate_Code at 65 range 0 .. 7; - Has_RACW at 66 range 0 .. 7; - Dynamic_Elab at 67 range 0 .. 7; - No_Elab_Code_All at 68 range 0 .. 7; - Filler at 69 range 0 .. 7; - OA_Setting at 70 range 0 .. 7; - Loading at 71 range 0 .. 7; - - Is_Predefined_Renaming at 72 range 0 .. 7; - Is_Internal_Unit at 73 range 0 .. 7; - Is_Predefined_Unit at 74 range 0 .. 7; - Filler2 at 75 range 0 .. 7; end record; - for Unit_Record'Size use 76 * 8; - -- This ensures that we did not leave out any fields - package Units is new Table.Table ( Table_Component_Type => Unit_Record, Table_Index_Type => Unit_Number_Type, diff --git a/gcc/ada/libgnarl/s-linux__android-aarch64.ads b/gcc/ada/libgnarl/s-linux__android-aarch64.ads index 4f9e81ddf656..537c46b5d3cc 100644 --- a/gcc/ada/libgnarl/s-linux__android-aarch64.ads +++ b/gcc/ada/libgnarl/s-linux__android-aarch64.ads @@ -118,13 +118,19 @@ package System.Linux is SIG33 : constant := 33; -- glibc internal signal SIG34 : constant := 34; -- glibc internal signal - -- struct_sigaction offsets - - -- sa_flags come first on aarch64-android (sa_flags, sa_handler, sa_mask) - - sa_flags_pos : constant := 0; - sa_handler_pos : constant := sa_flags_pos + Interfaces.C.int'Size / 8; - sa_mask_pos : constant := sa_handler_pos + Standard'Address_Size / 8; + -- struct_sigaction + + generic + type sigset_t is private; + package Android_Sigaction is + type struct_sigaction is record + sa_flags : Interfaces.C.int; + sa_handler : System.Address; + sa_mask : sigset_t; + sa_restorer : System.Address; + end record; + pragma Convention (C, struct_sigaction); + end Android_Sigaction; SA_SIGINFO : constant := 16#00000004#; SA_ONSTACK : constant := 16#08000000#; diff --git a/gcc/ada/libgnarl/s-linux__android-arm.ads b/gcc/ada/libgnarl/s-linux__android-arm.ads index 3e0325e1902d..07bca55f6c47 100644 --- a/gcc/ada/libgnarl/s-linux__android-arm.ads +++ b/gcc/ada/libgnarl/s-linux__android-arm.ads @@ -118,11 +118,19 @@ package System.Linux is SIG33 : constant := 33; -- glibc internal signal SIG34 : constant := 34; -- glibc internal signal - -- struct_sigaction offsets - - sa_handler_pos : constant := 0; - sa_mask_pos : constant := Standard'Address_Size / 8; - sa_flags_pos : constant := 4 + sa_mask_pos; + -- struct_sigaction + + generic + type sigset_t is private; + package Android_Sigaction is + type struct_sigaction is record + sa_handler : System.Address; + sa_mask : sigset_t; + sa_flags : Interfaces.C.int; + sa_restorer : System.Address; + end record; + pragma Convention (C, struct_sigaction); + end Android_Sigaction; SA_SIGINFO : constant := 16#00000004#; SA_ONSTACK : constant := 16#08000000#; diff --git a/gcc/ada/libgnarl/s-osinte__android.ads b/gcc/ada/libgnarl/s-osinte__android.ads index cd7e148933d9..4383860ed2b1 100644 --- a/gcc/ada/libgnarl/s-osinte__android.ads +++ b/gcc/ada/libgnarl/s-osinte__android.ads @@ -147,7 +147,20 @@ package System.OS_Interface is -- Not clear why these two signals are reserved. Perhaps they are not -- supported by this version of GNU/Linux ??? - type sigset_t is private; + -- struct sigaction fields are of different sizes and come in different + -- order on ARM vs aarch64. As this source is shared by the two + -- configurations, fetch the type definition through System.Linux, which + -- is specialized. + + type sigset_t is + array (0 .. OS_Constants.SIZEOF_sigset - 1) of Interfaces.C.unsigned_char; + pragma Convention (C, sigset_t); + for sigset_t'Alignment use Interfaces.C.unsigned_long'Alignment; + + package Android_Sigaction is new + System.Linux.Android_Sigaction (sigset_t => sigset_t); + + type struct_sigaction is new Android_Sigaction.struct_sigaction; function sigaddset (set : access sigset_t; sig : Signal) return int; pragma Import (C, sigaddset, "_sigaddset"); @@ -173,14 +186,6 @@ package System.OS_Interface is end record; pragma Convention (C, siginfo_t); - type struct_sigaction is record - sa_handler : System.Address; - sa_mask : sigset_t; - sa_flags : Interfaces.C.int; - sa_restorer : System.Address; - end record; - pragma Convention (C, struct_sigaction); - type struct_sigaction_ptr is access all struct_sigaction; SA_SIGINFO : constant := System.Linux.SA_SIGINFO; @@ -258,6 +263,14 @@ package System.OS_Interface is function getpid return pid_t; pragma Import (C, getpid, "getpid"); + PR_SET_NAME : constant := 15; + PR_GET_NAME : constant := 16; + + function prctl + (option : int; + arg : unsigned_long) return int; + pragma Import (C_Variadic_1, prctl, "prctl"); + ------------- -- Threads -- ------------- @@ -276,9 +289,11 @@ package System.OS_Interface is new Ada.Unchecked_Conversion (unsigned_long, pthread_t); subtype pthread_mutex_t is System.OS_Locks.pthread_mutex_t; + type pthread_rwlock_t is limited private; type pthread_cond_t is limited private; type pthread_attr_t is limited private; type pthread_mutexattr_t is limited private; + type pthread_rwlockattr_t is limited private; type pthread_condattr_t is limited private; type pthread_key_t is private; @@ -287,11 +302,6 @@ package System.OS_Interface is PTHREAD_SCOPE_PROCESS : constant := 1; PTHREAD_SCOPE_SYSTEM : constant := 0; - -- Read/Write lock not supported on Android. - - subtype pthread_rwlock_t is pthread_mutex_t; - subtype pthread_rwlockattr_t is pthread_mutexattr_t; - ----------- -- Stack -- ----------- @@ -389,6 +399,43 @@ package System.OS_Interface is function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int; pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock"); + function pthread_rwlockattr_init + (attr : access pthread_rwlockattr_t) return int; + pragma Import (C, pthread_rwlockattr_init, "pthread_rwlockattr_init"); + + function pthread_rwlockattr_destroy + (attr : access pthread_rwlockattr_t) return int; + pragma Import (C, pthread_rwlockattr_destroy, "pthread_rwlockattr_destroy"); + + PTHREAD_RWLOCK_PREFER_READER_NP : constant := 0; + PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP : constant := 1; + + -- No PTHREAD_RWLOCK_PREFER_WRITER_NP in Android's pthread.h API level 29 + + function pthread_rwlockattr_setkind_np + (attr : access pthread_rwlockattr_t; + pref : int) return int; + pragma Import + (C, pthread_rwlockattr_setkind_np, "pthread_rwlockattr_setkind_np"); + + function pthread_rwlock_init + (mutex : access pthread_rwlock_t; + attr : access pthread_rwlockattr_t) return int; + pragma Import (C, pthread_rwlock_init, "pthread_rwlock_init"); + + function pthread_rwlock_destroy + (mutex : access pthread_rwlock_t) return int; + pragma Import (C, pthread_rwlock_destroy, "pthread_rwlock_destroy"); + + function pthread_rwlock_rdlock (mutex : access pthread_rwlock_t) return int; + pragma Import (C, pthread_rwlock_rdlock, "pthread_rwlock_rdlock"); + + function pthread_rwlock_wrlock (mutex : access pthread_rwlock_t) return int; + pragma Import (C, pthread_rwlock_wrlock, "pthread_rwlock_wrlock"); + + function pthread_rwlock_unlock (mutex : access pthread_rwlock_t) return int; + pragma Import (C, pthread_rwlock_unlock, "pthread_rwlock_unlock"); + function pthread_condattr_init (attr : access pthread_condattr_t) return int; pragma Import (C, pthread_condattr_init, "pthread_condattr_init"); @@ -581,23 +628,6 @@ package System.OS_Interface is private - type sigset_t is - array (0 .. OS_Constants.SIZEOF_sigset - 1) of unsigned_char; - pragma Convention (C, sigset_t); - for sigset_t'Alignment use Interfaces.C.unsigned_long'Alignment; - - pragma Warnings (Off); - for struct_sigaction use record - sa_handler at Linux.sa_handler_pos range 0 .. Standard'Address_Size - 1; - sa_mask at Linux.sa_mask_pos - range 0 .. OS_Constants.SIZEOF_sigset * 8 - 1; - sa_flags at Linux.sa_flags_pos - range 0 .. Interfaces.C.int'Size - 1; - end record; - -- We intentionally leave sa_restorer unspecified and let the compiler - -- append it after the last field, so disable corresponding warning. - pragma Warnings (On); - type pid_t is new int; type time_t is range -2 ** (System.Parameters.time_t_bits - 1) @@ -632,6 +662,18 @@ private pragma Convention (C, pthread_mutexattr_t); for pthread_mutexattr_t'Alignment use Interfaces.C.int'Alignment; + type pthread_rwlockattr_t is record + Data : char_array (1 .. OS_Constants.PTHREAD_RWLOCKATTR_SIZE); + end record; + pragma Convention (C, pthread_rwlockattr_t); + for pthread_rwlockattr_t'Alignment use Interfaces.C.unsigned_long'Alignment; + + type pthread_rwlock_t is record + Data : char_array (1 .. OS_Constants.PTHREAD_RWLOCK_SIZE); + end record; + pragma Convention (C, pthread_rwlock_t); + for pthread_rwlock_t'Alignment use Interfaces.C.unsigned_long'Alignment; + type pthread_cond_t is record Data : char_array (1 .. OS_Constants.PTHREAD_COND_SIZE); end record; diff --git a/gcc/ada/libgnarl/s-stusta.adb b/gcc/ada/libgnarl/s-stusta.adb index 5aca435e68c8..c9848a060c20 100644 --- a/gcc/ada/libgnarl/s-stusta.adb +++ b/gcc/ada/libgnarl/s-stusta.adb @@ -32,6 +32,7 @@ -- This is why this package is part of GNARL: with System.Tasking.Debug; +with System.Tasking.Stages; with System.Task_Primitives.Operations; with System.IO; @@ -103,7 +104,9 @@ package body System.Stack_Usage.Tasking is -- Calculate the task usage for a given task - Report_For_Task (Id); + if not System.Tasking.Stages.Terminated (Id) then + Report_For_Task (Id); + end if; end loop; end if; diff --git a/gcc/ada/libgnarl/s-taskin.ads b/gcc/ada/libgnarl/s-taskin.ads index d68e199e6262..dbf2e7bf91ec 100644 --- a/gcc/ada/libgnarl/s-taskin.ads +++ b/gcc/ada/libgnarl/s-taskin.ads @@ -390,7 +390,7 @@ package System.Tasking is System_Domain : Dispatching_Domain_Access; -- All processors belong to default system dispatching domain at start up. -- We use a pointer which creates the actual variable for the reasons - -- explained bellow in Dispatching_Domain_Tasks. + -- explained below in Dispatching_Domain_Tasks. Dispatching_Domains_Frozen : Boolean := False; -- True when the main procedure has been called. Hence, no new dispatching diff --git a/gcc/ada/libgnarl/s-tassta.adb b/gcc/ada/libgnarl/s-tassta.adb index b1eb842ea609..98ee15b4baf2 100644 --- a/gcc/ada/libgnarl/s-tassta.adb +++ b/gcc/ada/libgnarl/s-tassta.adb @@ -133,6 +133,11 @@ package body System.Tasking.Stages is -- Different code is used at master completion, in Terminate_Dependents, -- due to a need for tighter synchronization with the master. + function Get_Stack_Base (Self_ID : Task_Id) return System.Address; + -- Get the stack base of Self. + -- + -- If the stack base cannot be determined, then Null_Address is returned. + ---------------------- -- Abort_Dependents -- ---------------------- @@ -1113,7 +1118,7 @@ package body System.Tasking.Stages is -- Address of the base of the stack begin - Stack_Base := Self_ID.Common.Compiler_Data.Pri_Stack_Info.Base; + Stack_Base := Get_Stack_Base (Self_ID); if Stack_Base = Null_Address then @@ -1139,7 +1144,7 @@ package body System.Tasking.Stages is (Self_ID.Common.Analyzer, Self_ID.Common.Task_Image (1 .. Self_ID.Common.Task_Image_Len), Natural (Self_ID.Common.Compiler_Data.Pri_Stack_Info.Size), - SSE.To_Integer (Stack_Base), + Stack_Base, Pattern_Size); STPO.Unlock_RTS; Fill_Stack (Self_ID.Common.Analyzer); @@ -1966,6 +1971,15 @@ package body System.Tasking.Stages is System.Task_Primitives.Operations.Finalize_TCB (T); end Vulnerable_Free_Task; + -------------------- + -- Get_Stack_Base -- + -------------------- + + -- Get_Stack_Base is architecture-specific + + function Get_Stack_Base (Self_ID : Task_Id) return System.Address + is separate; + -- Package elaboration code begin diff --git a/gcc/ada/libgnat/s-spcuop.adb b/gcc/ada/libgnarl/s-tsgsba.adb similarity index 70% rename from gcc/ada/libgnat/s-spcuop.adb rename to gcc/ada/libgnarl/s-tsgsba.adb index 74422ea7a1e3..450513db1321 100644 --- a/gcc/ada/libgnat/s-spcuop.adb +++ b/gcc/ada/libgnarl/s-tsgsba.adb @@ -1,14 +1,14 @@ ------------------------------------------------------------------------------ -- -- --- GNAT COMPILER COMPONENTS -- +-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS -- -- -- --- S Y S T E M . S P A R K . C U T _ O P E R A T I O N S -- +-- S Y S T E M . T A S K I N G . S T A G E S . G E T _ S T A C K _ B A S E -- -- -- --- B o d y -- +-- B o d y -- -- -- --- Copyright (C) 2022-2025, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2025, Free Software Foundation, Inc. -- -- -- --- GNAT is free software; you can redistribute it and/or modify it under -- +-- GNARL is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- @@ -24,19 +24,17 @@ -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- <http://www.gnu.org/licenses/>. -- -- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- GNARL was developed by the GNARL team at Florida State University. -- +-- Extensive contributions were provided by Ada Core Technologies, Inc. -- -- -- ------------------------------------------------------------------------------ -package body System.SPARK.Cut_Operations with - SPARK_Mode => Off -is +-- This is the default version for most platforms which tries to get the +-- stack base from the compiler info. It returns Null_Address if the stack +-- base is not available. - function By (Consequence, Premise : Boolean) return Boolean is - (Premise and then Consequence); - - function So (Premise, Consequence : Boolean) return Boolean is - (Premise and then Consequence); - -end System.SPARK.Cut_Operations; +separate (System.Tasking.Stages) +function Get_Stack_Base (Self_ID : Task_Id) return System.Address is +begin + return Self_ID.Common.Compiler_Data.Pri_Stack_Info.Base; +end Get_Stack_Base; diff --git a/gcc/ada/libgnat/s-spark.ads b/gcc/ada/libgnarl/s-tsgsba__cheri.adb similarity index 63% rename from gcc/ada/libgnat/s-spark.ads rename to gcc/ada/libgnarl/s-tsgsba__cheri.adb index c46409fdf8fe..5c1783675b42 100644 --- a/gcc/ada/libgnat/s-spark.ads +++ b/gcc/ada/libgnarl/s-tsgsba__cheri.adb @@ -1,14 +1,14 @@ ------------------------------------------------------------------------------ -- -- --- GNAT COMPILER COMPONENTS -- +-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS -- -- -- --- S Y S T E M . S P A R K -- +-- S Y S T E M . T A S K I N G . S T A G E S . G E T _ S T A C K _ B A S E -- -- -- --- S p e c -- +-- B o d y -- -- -- --- Copyright (C) 2022-2025, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2025, Free Software Foundation, Inc. -- -- -- --- GNAT is free software; you can redistribute it and/or modify it under -- +-- GNARL is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- @@ -24,16 +24,26 @@ -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- <http://www.gnu.org/licenses/>. -- -- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- GNARL was developed by the GNARL team at Florida State University. -- +-- Extensive contributions were provided by Ada Core Technologies, Inc. -- -- -- ------------------------------------------------------------------------------ +with Interfaces.CHERI; --- This is the top level unit of the SPARK package. Its children --- contain helper functions to aid proofs. +-- This is the version for CHERI targets where we can derive the stack base +-- from the upper bound of the capability stack pointer (CSP). -package System.SPARK with - SPARK_Mode, - Pure -is -end System.SPARK; +separate (System.Tasking.Stages) +function Get_Stack_Base (Self_ID : Task_Id) return System.Address is + pragma Unreferenced (Self_ID); + + use type SSE.Integer_Address; + + CSP : constant System.Address := Interfaces.CHERI.Get_CSP; +begin + return Interfaces.CHERI.Capability_With_Address + (Cap => CSP, + Addr => Interfaces.CHERI.Get_Base (CSP) + + SSE.Integer_Address + (Interfaces.CHERI.Get_Length (CSP))); +end Get_Stack_Base; diff --git a/gcc/ada/libgnat/a-cbhama.adb b/gcc/ada/libgnat/a-cbhama.adb index ee6584dc3b10..b2d796446fdd 100644 --- a/gcc/ada/libgnat/a-cbhama.adb +++ b/gcc/ada/libgnat/a-cbhama.adb @@ -368,7 +368,7 @@ is -- Empty -- ----------- - function Empty (Capacity : Count_Type) return Map is + function Empty (Capacity : Count_Type := 10) return Map is begin return Result : Map (Capacity, 0) do null; diff --git a/gcc/ada/libgnat/a-cbhama.ads b/gcc/ada/libgnat/a-cbhama.ads index 6ffc8157e85f..c741b404da4d 100644 --- a/gcc/ada/libgnat/a-cbhama.ads +++ b/gcc/ada/libgnat/a-cbhama.ads @@ -71,7 +71,7 @@ is -- Map objects declared without an initialization expression are -- initialized to the value Empty_Map. - function Empty (Capacity : Count_Type) return Map; + function Empty (Capacity : Count_Type := 10) return Map; No_Element : constant Cursor; -- Cursor objects declared without an initialization expression are diff --git a/gcc/ada/libgnat/a-except.adb b/gcc/ada/libgnat/a-except.adb index c7766232785c..d0a1d7f98e2f 100644 --- a/gcc/ada/libgnat/a-except.adb +++ b/gcc/ada/libgnat/a-except.adb @@ -450,6 +450,8 @@ package body Ada.Exceptions is (File : System.Address; Line : Integer); procedure Rcheck_CE_Tag_Check (File : System.Address; Line : Integer); + procedure Rcheck_PE_Abstract_Type_Component + (File : System.Address; Line : Integer); procedure Rcheck_PE_Access_Before_Elaboration (File : System.Address; Line : Integer); procedure Rcheck_PE_Accessibility_Check @@ -542,6 +544,8 @@ package body Ada.Exceptions is "__gnat_rcheck_CE_Range_Check"); pragma Export (C, Rcheck_CE_Tag_Check, "__gnat_rcheck_CE_Tag_Check"); + pragma Export (C, Rcheck_PE_Abstract_Type_Component, + "__gnat_rcheck_PE_Abstract_Type_Component"); pragma Export (C, Rcheck_PE_Access_Before_Elaboration, "__gnat_rcheck_PE_Access_Before_Elaboration"); pragma Export (C, Rcheck_PE_Accessibility_Check, @@ -620,6 +624,7 @@ package body Ada.Exceptions is pragma No_Return (Rcheck_CE_Partition_Check); pragma No_Return (Rcheck_CE_Range_Check); pragma No_Return (Rcheck_CE_Tag_Check); + pragma No_Return (Rcheck_PE_Abstract_Type_Component); pragma No_Return (Rcheck_PE_Access_Before_Elaboration); pragma No_Return (Rcheck_PE_Accessibility_Check); pragma No_Return (Rcheck_PE_Address_Of_Intrinsic); @@ -683,6 +688,8 @@ package body Ada.Exceptions is "expected_throw"); pragma Machine_Attribute (Rcheck_CE_Tag_Check, "expected_throw"); + pragma Machine_Attribute (Rcheck_PE_Abstract_Type_Component, + "expected_throw"); pragma Machine_Attribute (Rcheck_PE_Access_Before_Elaboration, "expected_throw"); pragma Machine_Attribute (Rcheck_PE_Accessibility_Check, @@ -775,6 +782,8 @@ package body Ada.Exceptions is "strub", "callable"); pragma Machine_Attribute (Rcheck_CE_Tag_Check, "strub", "callable"); + pragma Machine_Attribute (Rcheck_PE_Abstract_Type_Component, + "strub", "callable"); pragma Machine_Attribute (Rcheck_PE_Access_Before_Elaboration, "strub", "callable"); pragma Machine_Attribute (Rcheck_PE_Accessibility_Check, @@ -885,6 +894,8 @@ package body Ada.Exceptions is Rmsg_36 : constant String := "stream operation not allowed" & NUL; Rmsg_37 : constant String := "build-in-place mismatch" & NUL; Rmsg_38 : constant String := "raise check failed" & NUL; + Rmsg_39 : constant String := "initialization of abstract type" & + " component not allowed" & NUL; --------- -- AAA -- @@ -1471,6 +1482,13 @@ package body Ada.Exceptions is Raise_Constraint_Error_Msg (File, Line, 0, Rmsg_13'Address); end Rcheck_CE_Tag_Check; + procedure Rcheck_PE_Abstract_Type_Component + (File : System.Address; Line : Integer) + is + begin + Raise_Program_Error_Msg (File, Line, Rmsg_39'Address); + end Rcheck_PE_Abstract_Type_Component; + procedure Rcheck_PE_Access_Before_Elaboration (File : System.Address; Line : Integer) is diff --git a/gcc/ada/libgnat/a-nbnbig.adb b/gcc/ada/libgnat/a-nbnbig.adb deleted file mode 100644 index e487a05f02ea..000000000000 --- a/gcc/ada/libgnat/a-nbnbig.adb +++ /dev/null @@ -1,81 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT RUN-TIME COMPONENTS -- --- -- --- ADA.NUMERICS.BIG_NUMBERS.BIG_INTEGERS_GHOST -- --- -- --- B o d y -- --- -- --- Copyright (C) 2021-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - --- This body is provided as a work-around for a GNAT compiler bug, as GNAT --- currently does not compile instantiations of the spec with imported ghost --- generics for packages Signed_Conversions and Unsigned_Conversions. - --- Ghost code in this unit is meant for analysis only, not for run-time --- checking. This is enforced by setting the assertion policy to Ignore. - -pragma Assertion_Policy (Ghost => Ignore); - -package body Ada.Numerics.Big_Numbers.Big_Integers_Ghost with - SPARK_Mode => Off -is - - package body Signed_Conversions with - SPARK_Mode => Off - is - - function To_Big_Integer (Arg : Int) return Valid_Big_Integer is - begin - raise Program_Error; - return (null record); - end To_Big_Integer; - - function From_Big_Integer (Arg : Valid_Big_Integer) return Int is - begin - raise Program_Error; - return 0; - end From_Big_Integer; - - end Signed_Conversions; - - package body Unsigned_Conversions with - SPARK_Mode => Off - is - - function To_Big_Integer (Arg : Int) return Valid_Big_Integer is - begin - raise Program_Error; - return (null record); - end To_Big_Integer; - - function From_Big_Integer (Arg : Valid_Big_Integer) return Int is - begin - raise Program_Error; - return 0; - end From_Big_Integer; - - end Unsigned_Conversions; - -end Ada.Numerics.Big_Numbers.Big_Integers_Ghost; diff --git a/gcc/ada/libgnat/a-nbnbig.ads b/gcc/ada/libgnat/a-nbnbig.ads deleted file mode 100644 index 04aa62a928eb..000000000000 --- a/gcc/ada/libgnat/a-nbnbig.ads +++ /dev/null @@ -1,241 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT RUN-TIME COMPONENTS -- --- -- --- ADA.NUMERICS.BIG_NUMBERS.BIG_INTEGERS_GHOST -- --- -- --- S p e c -- --- -- --- This specification is derived from the Ada Reference Manual for use with -- --- GNAT. In accordance with the copyright of that document, you can freely -- --- copy and modify this specification, provided that if you redistribute a -- --- modified version, any changes that you have made are clearly indicated. -- --- -- ------------------------------------------------------------------------------- - --- This package provides a reduced and non-executable implementation of the --- ARM A.5.6 defined ``Ada.Numerics.Big_Numbers.Big_Integers`` for use in --- SPARK proofs in the runtime. As it is only intended for SPARK proofs, this --- package is marked as a Ghost package and consequently does not have a --- runtime footprint. - --- Contrary to Ada.Numerics.Big_Numbers.Big_Integers, this unit does not --- depend on System or Ada.Finalization, which makes it more convenient for --- use in run-time units. Note, since it is a ghost unit, all subprograms are --- marked as imported. - --- Ghost code in this unit is meant for analysis only, not for run-time --- checking. This is enforced by setting the assertion policy to Ignore. - -pragma Assertion_Policy (Ghost => Ignore); - -package Ada.Numerics.Big_Numbers.Big_Integers_Ghost with - SPARK_Mode, - Ghost, - Pure, - Always_Terminates -is - - type Big_Integer is private - with Integer_Literal => From_Universal_Image; - -- Private type that holds the integer value - - function Is_Valid (Arg : Big_Integer) return Boolean - with - Import, - Global => null; - -- Return whether a passed big integer is valid - - subtype Valid_Big_Integer is Big_Integer - with Dynamic_Predicate => Is_Valid (Valid_Big_Integer), - Predicate_Failure => raise Program_Error; - -- Holds a valid Big_Integer - - -- Comparison operators defined for valid Big_Integer values - function "=" (L, R : Valid_Big_Integer) return Boolean with - Import, - Global => null; - - function "<" (L, R : Valid_Big_Integer) return Boolean with - Import, - Global => null; - - function "<=" (L, R : Valid_Big_Integer) return Boolean with - Import, - Global => null; - - function ">" (L, R : Valid_Big_Integer) return Boolean with - Import, - Global => null; - - function ">=" (L, R : Valid_Big_Integer) return Boolean with - Import, - Global => null; - - function To_Big_Integer (Arg : Integer) return Valid_Big_Integer - with - Import, - Global => null; - -- Create a Big_Integer from an Integer value - - subtype Big_Positive is Big_Integer - with Dynamic_Predicate => - (if Is_Valid (Big_Positive) - then Big_Positive > To_Big_Integer (0)), - Predicate_Failure => raise Constraint_Error; - -- Positive subtype of Big_Integers, analogous to Positive and Integer - - subtype Big_Natural is Big_Integer - with Dynamic_Predicate => - (if Is_Valid (Big_Natural) - then Big_Natural >= To_Big_Integer (0)), - Predicate_Failure => raise Constraint_Error; - -- Natural subtype of Big_Integers, analogous to Natural and Integer - - function In_Range - (Arg : Valid_Big_Integer; Low, High : Big_Integer) return Boolean - is (Low <= Arg and Arg <= High) - with - Import, - Global => null; - -- Check whether Arg is in the range Low .. High - - function To_Integer (Arg : Valid_Big_Integer) return Integer - with - Import, - Pre => In_Range (Arg, - Low => To_Big_Integer (Integer'First), - High => To_Big_Integer (Integer'Last)) - or else raise Constraint_Error, - Global => null; - -- Convert a valid Big_Integer into an Integer - - generic - type Int is range <>; - package Signed_Conversions is - -- Generic package to implement conversion functions for - -- arbitrary ranged types. - - function To_Big_Integer (Arg : Int) return Valid_Big_Integer - with - Global => null; - -- Convert a ranged type into a valid Big_Integer - - function From_Big_Integer (Arg : Valid_Big_Integer) return Int - with - Pre => In_Range (Arg, - Low => To_Big_Integer (Int'First), - High => To_Big_Integer (Int'Last)) - or else raise Constraint_Error, - Global => null; - -- Convert a valid Big_Integer into a ranged type - end Signed_Conversions; - - generic - type Int is mod <>; - package Unsigned_Conversions is - -- Generic package to implement conversion functions for - -- arbitrary modular types. - - function To_Big_Integer (Arg : Int) return Valid_Big_Integer - with - Global => null; - -- Convert a modular type into a valid Big_Integer - - function From_Big_Integer (Arg : Valid_Big_Integer) return Int - with - Pre => In_Range (Arg, - Low => To_Big_Integer (Int'First), - High => To_Big_Integer (Int'Last)) - or else raise Constraint_Error, - Global => null; - -- Convert a valid Big_Integer into a modular type - - end Unsigned_Conversions; - - function From_String (Arg : String) return Valid_Big_Integer - with - Import, - Global => null; - -- Create a valid Big_Integer from a String - - function From_Universal_Image (Arg : String) return Valid_Big_Integer - renames From_String; - - -- Mathematical operators defined for valid Big_Integer values - function "+" (L : Valid_Big_Integer) return Valid_Big_Integer - with - Import, - Global => null; - - function "-" (L : Valid_Big_Integer) return Valid_Big_Integer - with - Import, - Global => null; - - function "abs" (L : Valid_Big_Integer) return Valid_Big_Integer - with - Import, - Global => null; - - function "+" (L, R : Valid_Big_Integer) return Valid_Big_Integer - with - Import, - Global => null; - - function "-" (L, R : Valid_Big_Integer) return Valid_Big_Integer - with - Import, - Global => null; - - function "*" (L, R : Valid_Big_Integer) return Valid_Big_Integer - with - Import, - Global => null; - - function "/" (L, R : Valid_Big_Integer) return Valid_Big_Integer - with - Import, - Global => null; - - function "mod" (L, R : Valid_Big_Integer) return Valid_Big_Integer - with - Import, - Global => null; - - function "rem" (L, R : Valid_Big_Integer) return Valid_Big_Integer - with - Import, - Global => null; - - function "**" (L : Valid_Big_Integer; R : Natural) return Valid_Big_Integer - with - Import, - Global => null; - - function Min (L, R : Valid_Big_Integer) return Valid_Big_Integer - with - Import, - Global => null; - - function Max (L, R : Valid_Big_Integer) return Valid_Big_Integer - with - Import, - Global => null; - - function Greatest_Common_Divisor - (L, R : Valid_Big_Integer) return Big_Positive - with - Import, - Pre => (L /= To_Big_Integer (0) and R /= To_Big_Integer (0)) - or else raise Constraint_Error, - Global => null; - -- Calculate the greatest common divisor for two Big_Integer values - -private - pragma SPARK_Mode (Off); - - type Big_Integer is null record; - -- Solely consists of Ghost code - -end Ada.Numerics.Big_Numbers.Big_Integers_Ghost; diff --git a/gcc/ada/libgnat/a-ngelfu.adb b/gcc/ada/libgnat/a-ngelfu.adb index 7ce2a4c87cef..d7b6c0c47f09 100644 --- a/gcc/ada/libgnat/a-ngelfu.adb +++ b/gcc/ada/libgnat/a-ngelfu.adb @@ -965,7 +965,6 @@ is P, Q, R : Float_Type'Base; Y : constant Float_Type'Base := abs X; - G : constant Float_Type'Base := Y * Y; Float_Type_Digits_15_Or_More : constant Boolean := Float_Type'Digits > 14; @@ -983,10 +982,14 @@ is elsif Y < Half_Ln3 and then Float_Type_Digits_15_Or_More then - P := (P2 * G + P1) * G + P0; - Q := ((Q3 * G + Q2) * G + Q1) * G + Q0; - R := G * (P / Q); - return X + X * R; + declare + G : constant Float_Type'Base := Y * Y; + begin + P := (P2 * G + P1) * G + P0; + Q := ((Q3 * G + Q2) * G + Q1) * G + Q0; + R := G * (P / Q); + return X + X * R; + end; else return Aux.Tanh (X); diff --git a/gcc/ada/libgnat/a-nudira.ads b/gcc/ada/libgnat/a-nudira.ads index 647470b7890e..3b2ca1868e8d 100644 --- a/gcc/ada/libgnat/a-nudira.ads +++ b/gcc/ada/libgnat/a-nudira.ads @@ -44,38 +44,60 @@ generic type Result_Subtype is (<>); package Ada.Numerics.Discrete_Random with - SPARK_Mode => Off + SPARK_Mode => On, + Always_Terminates is -- Basic facilities - type Generator is limited private; + type Generator is limited private with Default_Initial_Condition; - function Random (Gen : Generator) return Result_Subtype; + function Random (Gen : Generator) return Result_Subtype with + Global => null, + Side_Effects; + pragma Annotate (GNATprove, Mutable_In_Parameters, Generator); function Random (Gen : Generator; First : Result_Subtype; Last : Result_Subtype) return Result_Subtype - with Post => Random'Result in First .. Last; + with + Post => Random'Result in First .. Last, + Global => null, + Side_Effects; + pragma Annotate (GNATprove, Mutable_In_Parameters, Generator); - procedure Reset (Gen : Generator; Initiator : Integer); - procedure Reset (Gen : Generator); + procedure Reset (Gen : Generator; Initiator : Integer) with + Global => null; + pragma Annotate (GNATprove, Mutable_In_Parameters, Generator); + + procedure Reset (Gen : Generator) with + Global => null; + pragma Annotate (GNATprove, Mutable_In_Parameters, Generator); -- Advanced facilities type State is private; - procedure Save (Gen : Generator; To_State : out State); - procedure Reset (Gen : Generator; From_State : State); + procedure Save (Gen : Generator; To_State : out State) with + Global => null; + pragma Annotate (GNATprove, Mutable_In_Parameters, Generator); + + procedure Reset (Gen : Generator; From_State : State) with + Global => null; + pragma Annotate (GNATprove, Mutable_In_Parameters, Generator); Max_Image_Width : constant := System.Random_Numbers.Max_Image_Width; - function Image (Of_State : State) return String; - function Value (Coded_State : String) return State; + function Image (Of_State : State) return String with + Global => null; + function Value (Coded_State : String) return State with + Global => null; private + pragma SPARK_Mode (Off); + type Generator is new System.Random_Numbers.Generator; type State is new System.Random_Numbers.State; diff --git a/gcc/ada/libgnat/a-nuflra.ads b/gcc/ada/libgnat/a-nuflra.ads index 7eb0494bded0..9ea73d432a6f 100644 --- a/gcc/ada/libgnat/a-nuflra.ads +++ b/gcc/ada/libgnat/a-nuflra.ads @@ -39,34 +39,50 @@ with System.Random_Numbers; package Ada.Numerics.Float_Random with - SPARK_Mode => Off + SPARK_Mode => On, + Always_Terminates is -- Basic facilities - type Generator is limited private; + type Generator is limited private with Default_Initial_Condition; subtype Uniformly_Distributed is Float range 0.0 .. 1.0; - function Random (Gen : Generator) return Uniformly_Distributed; + function Random (Gen : Generator) return Uniformly_Distributed with + Global => null, + Side_Effects; + pragma Annotate (GNATprove, Mutable_In_Parameters, Generator); + procedure Reset (Gen : Generator) with + Global => null; + pragma Annotate (GNATprove, Mutable_In_Parameters, Generator); - procedure Reset (Gen : Generator); - procedure Reset (Gen : Generator; Initiator : Integer); + procedure Reset (Gen : Generator; Initiator : Integer) with + Global => null; + pragma Annotate (GNATprove, Mutable_In_Parameters, Generator); -- Advanced facilities type State is private; - procedure Save (Gen : Generator; To_State : out State); - procedure Reset (Gen : Generator; From_State : State); + procedure Save (Gen : Generator; To_State : out State) with + Global => null; + pragma Annotate (GNATprove, Mutable_In_Parameters, Generator); + procedure Reset (Gen : Generator; From_State : State) with + Global => null; + pragma Annotate (GNATprove, Mutable_In_Parameters, Generator); Max_Image_Width : constant := System.Random_Numbers.Max_Image_Width; - function Image (Of_State : State) return String; - function Value (Coded_State : String) return State; + function Image (Of_State : State) return String with + Global => null; + function Value (Coded_State : String) return State with + Global => null; private + pragma SPARK_Mode (Off); + type Generator is new System.Random_Numbers.Generator; type State is new System.Random_Numbers.State; diff --git a/gcc/ada/libgnat/a-strfix.adb b/gcc/ada/libgnat/a-strfix.adb index 5acfef41210f..50bb21485ab6 100644 --- a/gcc/ada/libgnat/a-strfix.adb +++ b/gcc/ada/libgnat/a-strfix.adb @@ -38,14 +38,6 @@ -- bounds of function return results were also fixed, and use of & removed for -- efficiency reasons. --- Ghost code, loop invariants and assertions in this unit are meant for --- analysis only, not for run-time checking, as it would be too costly --- otherwise. This is enforced by setting the assertion policy to Ignore. - -pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - with Ada.Strings.Maps; use Ada.Strings.Maps; package body Ada.Strings.Fixed with SPARK_Mode is @@ -153,12 +145,9 @@ package body Ada.Strings.Fixed with SPARK_Mode is Right : Character) return String is begin - return Result : String (1 .. Left) with Relaxed_Initialization do + return Result : String (1 .. Left) do for J in Result'Range loop Result (J) := Right; - pragma Loop_Invariant - (for all K in 1 .. J => - Result (K)'Initialized and then Result (K) = Right); end loop; end return; end "*"; @@ -168,82 +157,15 @@ package body Ada.Strings.Fixed with SPARK_Mode is Right : String) return String is Ptr : Integer := 0; - - -- Parts of the proof involving manipulations with the modulo operator - -- are complicated for the prover and can't be done automatically in - -- the global subprogram. That's why we isolate them in these two ghost - -- lemmas. - - procedure Lemma_Mod (K : Integer) with - Ghost, - Pre => - Right'Length /= 0 - and then Ptr mod Right'Length = 0 - and then Ptr in 0 .. Natural'Last - Right'Length - and then K in Ptr .. Ptr + Right'Length - 1, - Post => K mod Right'Length = K - Ptr; - -- Lemma_Mod is applied to an index considered in Lemma_Split to prove - -- that it has the right value modulo Right'Length. - - procedure Lemma_Split (Result : String) with - Ghost, - Relaxed_Initialization => Result, - Pre => - Right'Length /= 0 - and then Result'First = 1 - and then Result'Last >= 0 - and then Ptr mod Right'Length = 0 - and then Ptr in 0 .. Result'Last - Right'Length - and then Result (Result'First .. Ptr + Right'Length)'Initialized - and then Result (Ptr + 1 .. Ptr + Right'Length) = Right, - Post => - (for all K in Ptr + 1 .. Ptr + Right'Length => - Result (K) = Right (Right'First + (K - 1) mod Right'Length)); - -- Lemma_Split is used after Result (Ptr + 1 .. Ptr + Right'Length) is - -- updated to Right and concludes that the characters match for each - -- index when taken modulo Right'Length, as the considered slice starts - -- at index 1 modulo Right'Length. - - --------------- - -- Lemma_Mod -- - --------------- - - procedure Lemma_Mod (K : Integer) is null; - - ----------------- - -- Lemma_Split -- - ----------------- - - procedure Lemma_Split (Result : String) - is - begin - for K in Ptr + 1 .. Ptr + Right'Length loop - Lemma_Mod (K - 1); - pragma Loop_Invariant - (for all J in Ptr + 1 .. K => - Result (J) = Right (Right'First + (J - 1) mod Right'Length)); - end loop; - end Lemma_Split; - - -- Start of processing for "*" - begin if Right'Length = 0 then return ""; end if; - return Result : String (1 .. Left * Right'Length) - with Relaxed_Initialization - do + return Result : String (1 .. Left * Right'Length) do for J in 1 .. Left loop Result (Ptr + 1 .. Ptr + Right'Length) := Right; - Lemma_Split (Result); Ptr := Ptr + Right'Length; - pragma Loop_Invariant (Ptr = J * Right'Length); - pragma Loop_Invariant (Result (1 .. Ptr)'Initialized); - pragma Loop_Invariant - (for all K in 1 .. Ptr => - Result (K) = Right (Right'First + (K - 1) mod Right'Length)); end loop; end return; end "*"; @@ -255,8 +177,7 @@ package body Ada.Strings.Fixed with SPARK_Mode is function Delete (Source : String; From : Positive; - Through : Natural) return String - is + Through : Natural) return String is begin if From > Through then declare @@ -279,9 +200,7 @@ package body Ada.Strings.Fixed with SPARK_Mode is Result_Length : constant Integer := Front_Len + Back_Len; -- Length of result begin - return Result : String (1 .. Result_Length) - with Relaxed_Initialization - do + return Result : String (1 .. Result_Length) do Result (1 .. Front_Len) := Source (Source'First .. From - 1); @@ -325,14 +244,11 @@ package body Ada.Strings.Fixed with SPARK_Mode is Result_Type (Source (Source'First .. Source'First + (Count - 1))); else - return Result : Result_Type with Relaxed_Initialization do + return Result : Result_Type do Result (1 .. Source'Length) := Source; for J in Source'Length + 1 .. Count loop Result (J) := Pad; - pragma Loop_Invariant - (for all K in Source'Length + 1 .. J => - Result (K)'Initialized and then Result (K) = Pad); end loop; end return; end if; @@ -342,8 +258,7 @@ package body Ada.Strings.Fixed with SPARK_Mode is (Source : in out String; Count : Natural; Justify : Alignment := Left; - Pad : Character := Space) - is + Pad : Character := Space) is begin Move (Source => Head (Source, Count, Pad), Target => Source, @@ -362,37 +277,21 @@ package body Ada.Strings.Fixed with SPARK_Mode is New_Item : String) return String is Front : constant Integer := Before - Source'First; - begin if Before - 1 not in Source'First - 1 .. Source'Last then raise Index_Error; end if; - return Result : String (1 .. Source'Length + New_Item'Length) - with Relaxed_Initialization - do + return Result : String (1 .. Source'Length + New_Item'Length) do Result (1 .. Front) := Source (Source'First .. Before - 1); Result (Front + 1 .. Front + New_Item'Length) := New_Item; - pragma Assert - (Result (1 .. Before - Source'First) - = Source (Source'First .. Before - 1)); - pragma Assert - (Result - (Before - Source'First + 1 - .. Before - Source'First + New_Item'Length) - = New_Item); - if Before <= Source'Last then Result (Front + New_Item'Length + 1 .. Result'Last) := Source (Before .. Source'Last); end if; - - pragma Assert - (Result (1 .. Before - Source'First) - = Source (Source'First .. Before - 1)); end return; end Insert; @@ -400,8 +299,7 @@ package body Ada.Strings.Fixed with SPARK_Mode is (Source : in out String; Before : Positive; New_Item : String; - Drop : Truncation := Error) - is + Drop : Truncation := Error) is begin Move (Source => Insert (Source, Before, New_Item), Target => Source, @@ -536,38 +434,14 @@ package body Ada.Strings.Fixed with SPARK_Mode is Front : constant Integer := Position - Source'First; begin - return Result : String (1 .. Result_Length) - with Relaxed_Initialization - do + return Result : String (1 .. Result_Length) do Result (1 .. Front) := Source (Source'First .. Position - 1); - pragma Assert - (Result (1 .. Position - Source'First) - = Source (Source'First .. Position - 1)); Result (Front + 1 .. Front + New_Item'Length) := New_Item; - pragma Assert - (Result - (Position - Source'First + 1 - .. Position - Source'First + New_Item'Length) - = New_Item); if Position <= Source'Last - New_Item'Length then Result (Front + New_Item'Length + 1 .. Result'Last) := Source (Position + New_Item'Length .. Source'Last); - - pragma Assert - (Result - (Position - Source'First + New_Item'Length + 1 - .. Result'Last) - = Source (Position + New_Item'Length .. Source'Last)); end if; - - pragma Assert - (if Position <= Source'Last - New_Item'Length - then - Result - (Position - Source'First + New_Item'Length + 1 - .. Result'Last) - = Source (Position + New_Item'Length .. Source'Last)); end return; end; end Overwrite; @@ -576,8 +450,7 @@ package body Ada.Strings.Fixed with SPARK_Mode is (Source : in out String; Position : Positive; New_Item : String; - Drop : Truncation := Right) - is + Drop : Truncation := Right) is begin Move (Source => Overwrite (Source, Position, New_Item), Target => Source, @@ -612,39 +485,14 @@ package body Ada.Strings.Fixed with SPARK_Mode is -- Length of result begin - return Result : String (1 .. Result_Length) - with Relaxed_Initialization do + return Result : String (1 .. Result_Length) do Result (1 .. Front_Len) := Source (Source'First .. Low - 1); - pragma Assert - (Result (1 .. Integer'Max (0, Low - Source'First)) - = Source (Source'First .. Low - 1)); Result (Front_Len + 1 .. Front_Len + By'Length) := By; - pragma Assert - (Result - (Integer'Max (0, Low - Source'First) + 1 - .. Integer'Max (0, Low - Source'First) + By'Length) - = By); if High < Source'Last then Result (Front_Len + By'Length + 1 .. Result'Last) := Source (High + 1 .. Source'Last); end if; - - pragma Assert - (Result (1 .. Integer'Max (0, Low - Source'First)) - = Source (Source'First .. Low - 1)); - pragma Assert - (Result - (Integer'Max (0, Low - Source'First) + 1 - .. Integer'Max (0, Low - Source'First) + By'Length) - = By); - pragma Assert - (if High < Source'Last - then - Result - (Integer'Max (0, Low - Source'First) + By'Length + 1 - .. Result'Last) - = Source (High + 1 .. Source'Last)); end return; end; else @@ -659,8 +507,7 @@ package body Ada.Strings.Fixed with SPARK_Mode is By : String; Drop : Truncation := Error; Justify : Alignment := Left; - Pad : Character := Space) - is + Pad : Character := Space) is begin Move (Replace_Slice (Source, Low, High, By), Source, Drop, Justify, Pad); end Replace_Slice; @@ -675,7 +522,6 @@ package body Ada.Strings.Fixed with SPARK_Mode is Pad : Character := Space) return String is subtype Result_Type is String (1 .. Count); - begin if Count = 0 then return ""; @@ -686,12 +532,9 @@ package body Ada.Strings.Fixed with SPARK_Mode is -- Pad on left else - return Result : Result_Type with Relaxed_Initialization do + return Result : Result_Type do for J in 1 .. Count - Source'Length loop Result (J) := Pad; - pragma Loop_Invariant - (for all K in 1 .. J => - Result (K)'Initialized and then Result (K) = Pad); end loop; if Source'Length /= 0 then @@ -705,8 +548,7 @@ package body Ada.Strings.Fixed with SPARK_Mode is (Source : in out String; Count : Natural; Justify : Alignment := Left; - Pad : Character := Space) - is + Pad : Character := Space) is begin Move (Source => Tail (Source, Count, Pad), Target => Source, @@ -721,35 +563,21 @@ package body Ada.Strings.Fixed with SPARK_Mode is function Translate (Source : String; - Mapping : Maps.Character_Mapping) return String - is + Mapping : Maps.Character_Mapping) return String is begin - return Result : String (1 .. Source'Length) - with Relaxed_Initialization - do + return Result : String (1 .. Source'Length) do for J in Source'Range loop Result (J - (Source'First - 1)) := Value (Mapping, Source (J)); - pragma Loop_Invariant - (for all K in Source'First .. J => - Result (K - (Source'First - 1))'Initialized); - pragma Loop_Invariant - (for all K in Source'First .. J => - Result (K - (Source'First - 1)) = - Value (Mapping, Source (K))); end loop; end return; end Translate; procedure Translate (Source : in out String; - Mapping : Maps.Character_Mapping) - is + Mapping : Maps.Character_Mapping) is begin for J in Source'Range loop Source (J) := Value (Mapping, Source (J)); - pragma Loop_Invariant - (for all K in Source'First .. J => - Source (K) = Value (Mapping, Source'Loop_Entry (K))); end loop; end Translate; @@ -759,23 +587,9 @@ package body Ada.Strings.Fixed with SPARK_Mode is is pragma Unsuppress (Access_Check); begin - return Result : String (1 .. Source'Length) - with Relaxed_Initialization - do + return Result : String (1 .. Source'Length) do for J in Source'Range loop Result (J - (Source'First - 1)) := Mapping.all (Source (J)); - pragma Annotate (GNATprove, False_Positive, - "call via access-to-subprogram", - "function Mapping must always terminate"); - pragma Loop_Invariant - (for all K in Source'First .. J => - Result (K - (Source'First - 1))'Initialized); - pragma Loop_Invariant - (for all K in Source'First .. J => - Result (K - (Source'First - 1)) = Mapping (Source (K))); - pragma Annotate (GNATprove, False_Positive, - "call via access-to-subprogram", - "function Mapping must always terminate"); end loop; end return; end Translate; @@ -788,15 +602,6 @@ package body Ada.Strings.Fixed with SPARK_Mode is begin for J in Source'Range loop Source (J) := Mapping.all (Source (J)); - pragma Annotate (GNATprove, False_Positive, - "call via access-to-subprogram", - "function Mapping must always terminate"); - pragma Loop_Invariant - (for all K in Source'First .. J => - Source (K) = Mapping (Source'Loop_Entry (K))); - pragma Annotate (GNATprove, False_Positive, - "call via access-to-subprogram", - "function Mapping must always terminate"); end loop; end Translate; @@ -872,8 +677,7 @@ package body Ada.Strings.Fixed with SPARK_Mode is (Source : in out String; Side : Trim_End; Justify : Alignment := Left; - Pad : Character := Space) - is + Pad : Character := Space) is begin Move (Trim (Source, Side), Source, @@ -887,7 +691,6 @@ package body Ada.Strings.Fixed with SPARK_Mode is Right : Maps.Character_Set) return String is High, Low : Integer; - begin Low := Index (Source, Set => Left, Test => Outside, Going => Forward); @@ -908,7 +711,6 @@ package body Ada.Strings.Fixed with SPARK_Mode is declare Result_Length : constant Integer := High - Low + 1; subtype Result_Type is String (1 .. Result_Length); - begin return Result_Type (Source (Low .. High)); end; @@ -919,8 +721,7 @@ package body Ada.Strings.Fixed with SPARK_Mode is Left : Maps.Character_Set; Right : Maps.Character_Set; Justify : Alignment := Strings.Left; - Pad : Character := Space) - is + Pad : Character := Space) is begin Move (Source => Trim (Source, Left, Right), Target => Source, diff --git a/gcc/ada/libgnat/a-strmap.adb b/gcc/ada/libgnat/a-strmap.adb index 7490780d6e6c..2f4cceb4908c 100644 --- a/gcc/ada/libgnat/a-strmap.adb +++ b/gcc/ada/libgnat/a-strmap.adb @@ -35,14 +35,6 @@ -- is bit-by-bit or character-by-character and therefore rather slow. -- Generally for character sets we favor the full 32-byte representation. --- Assertions, ghost code and loop invariants in this unit are meant for --- analysis only, not for run-time checking, as it would be too costly --- otherwise. This is enforced by setting the assertion policy to Ignore. - -pragma Assertion_Policy (Assert => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore); - package body Ada.Strings.Maps with SPARK_Mode is @@ -131,36 +123,15 @@ is --------------- function To_Domain (Map : Character_Mapping) return Character_Sequence is - Result : String (1 .. Map'Length) with Relaxed_Initialization; + Result : String (1 .. Map'Length); J : Natural; - - type Character_Index is array (Character) of Natural with Ghost; - Indexes : Character_Index := [others => 0] with Ghost; - begin J := 0; for C in Map'Range loop if Map (C) /= C then J := J + 1; Result (J) := C; - Indexes (C) := J; end if; - - pragma Loop_Invariant (if Map = Identity then J = 0); - pragma Loop_Invariant (J <= Character'Pos (C) + 1); - pragma Loop_Invariant (for all K in 1 .. J => Result (K)'Initialized); - pragma Loop_Invariant (for all K in 1 .. J => Result (K) <= C); - pragma Loop_Invariant - (SPARK_Proof_Sorted_Character_Sequence (Result (1 .. J))); - pragma Loop_Invariant - (for all D in Map'First .. C => - (if Map (D) = D then - Indexes (D) = 0 - else - Indexes (D) in 1 .. J - and then Result (Indexes (D)) = D)); - pragma Loop_Invariant - (for all Char of Result (1 .. J) => Map (Char) /= Char); end loop; return Result (1 .. J); @@ -173,7 +144,7 @@ is function To_Mapping (From, To : Character_Sequence) return Character_Mapping is - Result : Character_Mapping with Relaxed_Initialization; + Result : Character_Mapping; Inserted : Character_Set := Null_Set; From_Len : constant Natural := From'Length; To_Len : constant Natural := To'Length; @@ -185,9 +156,6 @@ is for Char in Character loop Result (Char) := Char; - pragma Loop_Invariant (Result (Result'First .. Char)'Initialized); - pragma Loop_Invariant - (for all C in Result'First .. Char => Result (C) = C); end loop; for J in From'Range loop @@ -197,23 +165,6 @@ is Result (From (J)) := To (J - From'First + To'First); Inserted (From (J)) := True; - - pragma Loop_Invariant (Result'Initialized); - pragma Loop_Invariant - (for all K in From'First .. J => - Result (From (K)) = To (K - From'First + To'First) - and then Inserted (From (K))); - pragma Loop_Invariant - (for all Char in Character => - (Inserted (Char) = - (for some K in From'First .. J => Char = From (K)))); - pragma Loop_Invariant - (for all Char in Character => - (if not Inserted (Char) then Result (Char) = Char)); - pragma Loop_Invariant - (if (for all K in From'First .. J => - From (K) = To (J - From'First + To'First)) - then Result = Identity); end loop; return Result; @@ -224,195 +175,16 @@ is -------------- function To_Range (Map : Character_Mapping) return Character_Sequence is - - -- Extract from the postcondition of To_Domain the essential properties - -- that define Seq as the domain of Map. - function Is_Domain - (Map : Character_Mapping; - Seq : Character_Sequence) - return Boolean - is - (Seq'First = 1 - and then - SPARK_Proof_Sorted_Character_Sequence (Seq) - and then - (for all Char in Character => - (if (for all X of Seq => X /= Char) - then Map (Char) = Char)) - and then - (for all Char of Seq => Map (Char) /= Char)) - with - Ghost; - - -- Given Map, there is a unique sequence Seq for which - -- Is_Domain(Map,Seq) holds. - procedure Lemma_Domain_Unicity - (Map : Character_Mapping; - Seq1, Seq2 : Character_Sequence) - with - Ghost, - Pre => Is_Domain (Map, Seq1) - and then Is_Domain (Map, Seq2), - Post => Seq1 = Seq2; - - -- Isolate the proof that To_Domain(Map) returns a sequence for which - -- Is_Domain holds. - procedure Lemma_Is_Domain (Map : Character_Mapping) - with - Ghost, - Post => Is_Domain (Map, To_Domain (Map)); - - -- Deduce the alternative expression of sortedness from the one in - -- SPARK_Proof_Sorted_Character_Sequence which compares consecutive - -- elements. - procedure Lemma_Is_Sorted (Seq : Character_Sequence) - with - Ghost, - Pre => SPARK_Proof_Sorted_Character_Sequence (Seq), - Post => (for all J in Seq'Range => - (for all K in Seq'Range => - (if J < K then Seq (J) < Seq (K)))); - - -------------------------- - -- Lemma_Domain_Unicity -- - -------------------------- - - procedure Lemma_Domain_Unicity - (Map : Character_Mapping; - Seq1, Seq2 : Character_Sequence) - is - J : Positive := 1; - - begin - while J <= Seq1'Last - and then J <= Seq2'Last - and then Seq1 (J) = Seq2 (J) - loop - pragma Loop_Invariant - (Seq1 (Seq1'First .. J) = Seq2 (Seq2'First .. J)); - pragma Loop_Variant (Increases => J); - - if J = Positive'Last then - return; - end if; - - J := J + 1; - end loop; - - Lemma_Is_Sorted (Seq1); - Lemma_Is_Sorted (Seq2); - - if J <= Seq1'Last - and then J <= Seq2'Last - then - if Seq1 (J) < Seq2 (J) then - pragma Assert (for all X of Seq2 => X /= Seq1 (J)); - pragma Assert (Map (Seq1 (J)) = Seq1 (J)); - pragma Assert (False); - else - pragma Assert (for all X of Seq1 => X /= Seq2 (J)); - pragma Assert (Map (Seq2 (J)) = Seq2 (J)); - pragma Assert (False); - end if; - - elsif J <= Seq1'Last then - pragma Assert (for all X of Seq2 => X /= Seq1 (J)); - pragma Assert (Map (Seq1 (J)) = Seq1 (J)); - pragma Assert (False); - - elsif J <= Seq2'Last then - pragma Assert (for all X of Seq1 => X /= Seq2 (J)); - pragma Assert (Map (Seq2 (J)) = Seq2 (J)); - pragma Assert (False); - end if; - end Lemma_Domain_Unicity; - - --------------------- - -- Lemma_Is_Domain -- - --------------------- - - procedure Lemma_Is_Domain (Map : Character_Mapping) is - Ignore : constant Character_Sequence := To_Domain (Map); - begin - null; - end Lemma_Is_Domain; - - --------------------- - -- Lemma_Is_Sorted -- - --------------------- - - procedure Lemma_Is_Sorted (Seq : Character_Sequence) is - begin - for A in Seq'Range loop - exit when A = Positive'Last; - - for B in A + 1 .. Seq'Last loop - pragma Loop_Invariant - (for all K in A + 1 .. B => Seq (A) < Seq (K)); - end loop; - - pragma Loop_Invariant - (for all J in Seq'First .. A => - (for all K in Seq'Range => - (if J < K then Seq (J) < Seq (K)))); - end loop; - end Lemma_Is_Sorted; - - -- Local variables - - Result : String (1 .. Map'Length) with Relaxed_Initialization; + Result : String (1 .. Map'Length); J : Natural; - - -- Repeat the computation from To_Domain in ghost code, in order to - -- prove the relationship between Result and To_Domain(Map). - - Domain : String (1 .. Map'Length) with Ghost, Relaxed_Initialization; - type Character_Index is array (Character) of Natural with Ghost; - Indexes : Character_Index := [others => 0] with Ghost; - - -- Start of processing for To_Range - begin J := 0; for C in Map'Range loop if Map (C) /= C then J := J + 1; Result (J) := Map (C); - Domain (J) := C; - Indexes (C) := J; end if; - - -- Repeat the loop invariants from To_Domain regarding Domain and - -- Indexes. Add similar loop invariants for Result and Indexes. - - pragma Loop_Invariant (J <= Character'Pos (C) + 1); - pragma Loop_Invariant (Result (1 .. J)'Initialized); - pragma Loop_Invariant (Domain (1 .. J)'Initialized); - pragma Loop_Invariant (for all K in 1 .. J => Domain (K) <= C); - pragma Loop_Invariant - (SPARK_Proof_Sorted_Character_Sequence (Domain (1 .. J))); - pragma Loop_Invariant - (for all D in Map'First .. C => - (if Map (D) = D then - Indexes (D) = 0 - else - Indexes (D) in 1 .. J - and then Domain (Indexes (D)) = D - and then Result (Indexes (D)) = Map (D))); - pragma Loop_Invariant - (for all Char of Domain (1 .. J) => Map (Char) /= Char); - pragma Loop_Invariant - (for all K in 1 .. J => Result (K) = Map (Domain (K))); end loop; - pragma Assert (Is_Domain (Map, Domain (1 .. J))); - - -- Show the equality of Domain and To_Domain(Map) - - Lemma_Is_Domain (Map); - Lemma_Domain_Unicity (Map, Domain (1 .. J), To_Domain (Map)); - pragma Assert - (for all K in 1 .. J => Domain (K) = To_Domain (Map) (K)); - pragma Assert (To_Domain (Map)'Length = J); return Result (1 .. J); end To_Range; @@ -422,27 +194,18 @@ is --------------- function To_Ranges (Set : Character_Set) return Character_Ranges is - Max_Ranges : Character_Ranges (1 .. Set'Length / 2 + 1) - with Relaxed_Initialization; + Max_Ranges : Character_Ranges (1 .. Set'Length / 2 + 1); Range_Num : Natural; C : Character; - C_Iter : Character with Ghost; begin C := Character'First; Range_Num := 0; loop - C_Iter := C; - -- Skip gap between subsets while not Set (C) loop - pragma Loop_Invariant - (Character'Pos (C) >= Character'Pos (C'Loop_Entry)); - pragma Loop_Invariant - (for all Char in C'Loop_Entry .. C => not Set (Char)); - pragma Loop_Variant (Increases => C); exit when C = Character'Last; C := Character'Succ (C); end loop; @@ -455,12 +218,6 @@ is -- Span a subset loop - pragma Loop_Invariant - (Character'Pos (C) >= Character'Pos (C'Loop_Entry)); - pragma Loop_Invariant - (for all Char in C'Loop_Entry .. C => - (if Char /= C then Set (Char))); - pragma Loop_Variant (Increases => C); exit when not Set (C) or else C = Character'Last; C := Character'Succ (C); end loop; @@ -471,31 +228,6 @@ is else Max_Ranges (Range_Num).High := Character'Pred (C); end if; - - pragma Assert - (for all Char in C_Iter .. C => - (Set (Char) = - (Char in Max_Ranges (Range_Num).Low .. - Max_Ranges (Range_Num).High))); - pragma Assert - (for all Char in Character'First .. C_Iter => - (if Char /= C_Iter then - (Set (Char) = - (for some Span of Max_Ranges (1 .. Range_Num - 1) => - Char in Span.Low .. Span.High)))); - - pragma Loop_Invariant (2 * Range_Num <= Character'Pos (C) + 1); - pragma Loop_Invariant (Max_Ranges (1 .. Range_Num)'Initialized); - pragma Loop_Invariant (not Set (C)); - pragma Loop_Invariant - (for all Char in Character'First .. C => - (Set (Char) = - (for some Span of Max_Ranges (1 .. Range_Num) => - Char in Span.Low .. Span.High))); - pragma Loop_Invariant - (for all Span of Max_Ranges (1 .. Range_Num) => - (for all Char in Span.Low .. Span.High => Set (Char))); - pragma Loop_Variant (Increases => Range_Num); end loop; return Max_Ranges (1 .. Range_Num); @@ -506,8 +238,7 @@ is ----------------- function To_Sequence (Set : Character_Set) return Character_Sequence is - Result : String (1 .. Character'Pos (Character'Last) + 1) - with Relaxed_Initialization; + Result : String (1 .. Character'Pos (Character'Last) + 1); Count : Natural := 0; begin for Char in Set'Range loop @@ -515,17 +246,6 @@ is Count := Count + 1; Result (Count) := Char; end if; - - pragma Loop_Invariant (Count <= Character'Pos (Char) + 1); - pragma Loop_Invariant (Result (1 .. Count)'Initialized); - pragma Loop_Invariant (for all K in 1 .. Count => Result (K) <= Char); - pragma Loop_Invariant - (SPARK_Proof_Sorted_Character_Sequence (Result (1 .. Count))); - pragma Loop_Invariant - (for all C in Set'First .. Char => - (Set (C) = (for some X of Result (1 .. Count) => C = X))); - pragma Loop_Invariant - (for all Char of Result (1 .. Count) => Is_In (Char, Set)); end loop; return Result (1 .. Count); @@ -541,19 +261,7 @@ is for R in Ranges'Range loop for C in Ranges (R).Low .. Ranges (R).High loop Result (C) := True; - pragma Loop_Invariant - (for all Char in Character => - Result (Char) = - ((for some Prev in Ranges'First .. R - 1 => - Char in Ranges (Prev).Low .. Ranges (Prev).High) - or else Char in Ranges (R).Low .. C)); end loop; - - pragma Loop_Invariant - (for all Char in Character => - Result (Char) = - (for some Prev in Ranges'First .. R => - Char in Ranges (Prev).Low .. Ranges (Prev).High)); end loop; return Result; @@ -564,9 +272,6 @@ is begin for C in Span.Low .. Span.High loop Result (C) := True; - pragma Loop_Invariant - (for all Char in Character => - Result (Char) = (Char in Span.Low .. C)); end loop; return Result; @@ -577,10 +282,6 @@ is begin for J in Sequence'Range loop Result (Sequence (J)) := True; - pragma Loop_Invariant - (for all Char in Character => - Result (Char) = - (for some K in Sequence'First .. J => Char = Sequence (K))); end loop; return Result; @@ -599,8 +300,6 @@ is function Value (Map : Character_Mapping; - Element : Character) return Character - is - (Map (Element)); + Element : Character) return Character is (Map (Element)); end Ada.Strings.Maps; diff --git a/gcc/ada/libgnat/a-strsea.adb b/gcc/ada/libgnat/a-strsea.adb index 45fb68297c99..55bf7670f0e8 100644 --- a/gcc/ada/libgnat/a-strsea.adb +++ b/gcc/ada/libgnat/a-strsea.adb @@ -35,14 +35,6 @@ -- case of identity mappings for Count and Index, and also Index_Non_Blank -- is specialized (rather than using the general Index routine). --- Ghost code, loop invariants and assertions in this unit are meant for --- analysis only, not for run-time checking, as it would be too costly --- otherwise. This is enforced by setting the assertion policy to Ignore. - -pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - with Ada.Strings.Maps; use Ada.Strings.Maps; with System; use System; @@ -110,10 +102,6 @@ package body Ada.Strings.Search with SPARK_Mode is Num := Num + 1; Ind := Ind + PL1; end if; - - pragma Loop_Invariant (Num <= Ind - (Source'First - 1)); - pragma Loop_Invariant (Ind >= Source'First); - pragma Loop_Variant (Increases => Ind); end loop; -- Mapped case @@ -125,25 +113,15 @@ package body Ada.Strings.Search with SPARK_Mode is if Pattern (K) /= Value (Mapping, Source (Ind + (K - Pattern'First))) then - pragma Assert (not Match (Source, Pattern, Mapping, Ind)); goto Cont; end if; - - pragma Loop_Invariant - (for all J in Pattern'First .. K => - Pattern (J) = Value (Mapping, - Source (Ind + (J - Pattern'First)))); end loop; - pragma Assert (Match (Source, Pattern, Mapping, Ind)); Num := Num + 1; Ind := Ind + PL1; <<Cont>> null; - pragma Loop_Invariant (Num <= Ind - (Source'First - 1)); - pragma Loop_Invariant (Ind >= Source'First); - pragma Loop_Variant (Increases => Ind); end loop; end if; @@ -185,30 +163,15 @@ package body Ada.Strings.Search with SPARK_Mode is Ind := Ind + 1; for K in Pattern'Range loop if Pattern (K) /= Mapping (Source (Ind + (K - Pattern'First))) then - pragma Annotate (GNATprove, False_Positive, - "call via access-to-subprogram", - "function Mapping must always terminate"); - pragma Assert (not Match (Source, Pattern, Mapping, Ind)); goto Cont; end if; - - pragma Loop_Invariant - (for all J in Pattern'First .. K => - Pattern (J) = Mapping (Source (Ind + (J - Pattern'First)))); - pragma Annotate (GNATprove, False_Positive, - "call via access-to-subprogram", - "function Mapping must always terminate"); end loop; - pragma Assert (Match (Source, Pattern, Mapping, Ind)); Num := Num + 1; Ind := Ind + PL1; <<Cont>> null; - pragma Loop_Invariant (Num <= Ind - (Source'First - 1)); - pragma Loop_Invariant (Ind >= Source'First); - pragma Loop_Variant (Increases => Ind); end loop; return Num; @@ -219,10 +182,8 @@ package body Ada.Strings.Search with SPARK_Mode is Set : Maps.Character_Set) return Natural is N : Natural := 0; - begin for J in Source'Range loop - pragma Loop_Invariant (N <= J - Source'First); if Is_In (Source (J), Set) then N := N + 1; end if; @@ -241,8 +202,7 @@ package body Ada.Strings.Search with SPARK_Mode is From : Positive; Test : Membership; First : out Positive; - Last : out Natural) - is + Last : out Natural) is begin -- AI05-031: Raise Index error if Source non-empty and From not in range @@ -264,10 +224,6 @@ package body Ada.Strings.Search with SPARK_Mode is Last := K - 1; return; end if; - - pragma Loop_Invariant - (for all L in J .. K => - Belongs (Source (L), Set, Test)); end loop; end if; @@ -277,10 +233,6 @@ package body Ada.Strings.Search with SPARK_Mode is Last := Source'Last; return; end if; - - pragma Loop_Invariant - (for all K in Integer'Max (From, Source'First) .. J => - not Belongs (Source (K), Set, Test)); end loop; -- Here if no token found @@ -294,8 +246,7 @@ package body Ada.Strings.Search with SPARK_Mode is Set : Maps.Character_Set; Test : Membership; First : out Positive; - Last : out Natural) - is + Last : out Natural) is begin for J in Source'Range loop if Belongs (Source (J), Set, Test) then @@ -307,10 +258,6 @@ package body Ada.Strings.Search with SPARK_Mode is Last := K - 1; return; end if; - - pragma Loop_Invariant - (for all L in J .. K => - Belongs (Source (L), Set, Test)); end loop; end if; @@ -320,10 +267,6 @@ package body Ada.Strings.Search with SPARK_Mode is Last := Source'Last; return; end if; - - pragma Loop_Invariant - (for all K in Source'First .. J => - not Belongs (Source (K), Set, Test)); end loop; -- Here if no token found @@ -335,7 +278,6 @@ package body Ada.Strings.Search with SPARK_Mode is if Source'First not in Positive then raise Constraint_Error; - else First := Source'First; Last := 0; @@ -353,7 +295,6 @@ package body Ada.Strings.Search with SPARK_Mode is Mapping : Maps.Character_Mapping := Maps.Identity) return Natural is PL1 : constant Integer := Pattern'Length - 1; - begin if Pattern = "" then raise Pattern_Error; @@ -374,13 +315,8 @@ package body Ada.Strings.Search with SPARK_Mode is if Is_Identity (Mapping) then for Ind in Source'First .. Source'Last - PL1 loop if Pattern = Source (Ind .. Ind + PL1) then - pragma Assert (Match (Source, Pattern, Mapping, Ind)); return Ind; end if; - - pragma Loop_Invariant - (for all J in Source'First .. Ind => - not Match (Source, Pattern, Mapping, J)); end loop; -- Mapped forward case @@ -393,20 +329,11 @@ package body Ada.Strings.Search with SPARK_Mode is then goto Cont1; end if; - - pragma Loop_Invariant - (for all J in Pattern'First .. K => - Pattern (J) = Value (Mapping, - Source (Ind + (J - Pattern'First)))); end loop; - pragma Assert (Match (Source, Pattern, Mapping, Ind)); return Ind; <<Cont1>> - pragma Loop_Invariant - (for all J in Source'First .. Ind => - not Match (Source, Pattern, Mapping, J)); null; end loop; end if; @@ -419,13 +346,8 @@ package body Ada.Strings.Search with SPARK_Mode is if Is_Identity (Mapping) then for Ind in reverse Source'First .. Source'Last - PL1 loop if Pattern = Source (Ind .. Ind + PL1) then - pragma Assert (Match (Source, Pattern, Mapping, Ind)); return Ind; end if; - - pragma Loop_Invariant - (for all J in Ind .. Source'Last - PL1 => - not Match (Source, Pattern, Mapping, J)); end loop; -- Mapped backward case @@ -438,20 +360,11 @@ package body Ada.Strings.Search with SPARK_Mode is then goto Cont2; end if; - - pragma Loop_Invariant - (for all J in Pattern'First .. K => - Pattern (J) = Value (Mapping, - Source (Ind + (J - Pattern'First)))); end loop; - pragma Assert (Match (Source, Pattern, Mapping, Ind)); return Ind; <<Cont2>> - pragma Loop_Invariant - (for all J in Ind .. Source'Last - PL1 => - not Match (Source, Pattern, Mapping, J)); null; end loop; end if; @@ -495,27 +408,17 @@ package body Ada.Strings.Search with SPARK_Mode is if Pattern (K) /= Mapping.all (Source (Ind + (K - Pattern'First))) then - pragma Annotate (GNATprove, False_Positive, - "call via access-to-subprogram", - "function Mapping must always terminate"); goto Cont1; end if; pragma Loop_Invariant (for all J in Pattern'First .. K => Pattern (J) = Mapping (Source (Ind + (J - Pattern'First)))); - pragma Annotate (GNATprove, False_Positive, - "call via access-to-subprogram", - "function Mapping must always terminate"); end loop; - pragma Assert (Match (Source, Pattern, Mapping, Ind)); return Ind; <<Cont1>> - pragma Loop_Invariant - (for all J in Source'First .. Ind => - not Match (Source, Pattern, Mapping, J)); null; end loop; @@ -527,26 +430,13 @@ package body Ada.Strings.Search with SPARK_Mode is if Pattern (K) /= Mapping.all (Source (Ind + (K - Pattern'First))) then - pragma Annotate (GNATprove, False_Positive, - "call via access-to-subprogram", - "function Mapping must always terminate"); goto Cont2; end if; - - pragma Loop_Invariant - (for all J in Pattern'First .. K => - Pattern (J) = Mapping (Source (Ind + (J - Pattern'First)))); - pragma Annotate (GNATprove, False_Positive, - "call via access-to-subprogram", - "function Mapping must always terminate"); end loop; return Ind; <<Cont2>> - pragma Loop_Invariant - (for all J in Ind .. Source'Last - PL1 => - not Match (Source, Pattern, Mapping, J)); null; end loop; end if; @@ -561,8 +451,7 @@ package body Ada.Strings.Search with SPARK_Mode is (Source : String; Set : Maps.Character_Set; Test : Membership := Inside; - Going : Direction := Forward) return Natural - is + Going : Direction := Forward) return Natural is begin -- Forwards case @@ -571,10 +460,6 @@ package body Ada.Strings.Search with SPARK_Mode is if Belongs (Source (J), Set, Test) then return J; end if; - - pragma Loop_Invariant - (for all C of Source (Source'First .. J) => - not Belongs (C, Set, Test)); end loop; -- Backwards case @@ -584,10 +469,6 @@ package body Ada.Strings.Search with SPARK_Mode is if Belongs (Source (J), Set, Test) then return J; end if; - - pragma Loop_Invariant - (for all C of Source (J .. Source'Last) => - not Belongs (C, Set, Test)); end loop; end if; @@ -604,7 +485,6 @@ package body Ada.Strings.Search with SPARK_Mode is Mapping : Maps.Character_Mapping := Maps.Identity) return Natural is Result : Natural; - PL1 : constant Integer := Pattern'Length - 1; begin -- AI05-056: If source is empty result is always zero @@ -619,12 +499,6 @@ package body Ada.Strings.Search with SPARK_Mode is Result := Index (Source (From .. Source'Last), Pattern, Forward, Mapping); - pragma Assert - (if (for some J in From .. Source'Last - PL1 => - Match (Source, Pattern, Mapping, J)) - then Result in From .. Source'Last - PL1 - and then Match (Source, Pattern, Mapping, Result) - else Result = 0); else if From > Source'Last then @@ -633,12 +507,6 @@ package body Ada.Strings.Search with SPARK_Mode is Result := Index (Source (Source'First .. From), Pattern, Backward, Mapping); - pragma Assert - (if (for some J in Source'First .. From - PL1 => - Match (Source, Pattern, Mapping, J)) - then Result in Source'First .. From - PL1 - and then Match (Source, Pattern, Mapping, Result) - else Result = 0); end if; return Result; @@ -722,9 +590,6 @@ package body Ada.Strings.Search with SPARK_Mode is if Source (J) /= ' ' then return J; end if; - - pragma Loop_Invariant - (for all C of Source (Source'First .. J) => C = ' '); end loop; else -- Going = Backward @@ -732,9 +597,6 @@ package body Ada.Strings.Search with SPARK_Mode is if Source (J) /= ' ' then return J; end if; - - pragma Loop_Invariant - (for all C of Source (J .. Source'Last) => C = ' '); end loop; end if; diff --git a/gcc/ada/libgnat/a-strsup.adb b/gcc/ada/libgnat/a-strsup.adb index 6540924d8bfd..3ac1a5ac7249 100644 --- a/gcc/ada/libgnat/a-strsup.adb +++ b/gcc/ada/libgnat/a-strsup.adb @@ -29,15 +29,6 @@ -- -- ------------------------------------------------------------------------------ --- Ghost code, loop (in)variants and assertions in this unit are meant for --- analysis only, not for run-time checking, as it would be too costly --- otherwise. This is enforced by setting the assertion policy to Ignore. - -pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Loop_Variant => Ignore, - Assert => Ignore); - with Ada.Strings.Maps; use Ada.Strings.Maps; package body Ada.Strings.Superbounded with SPARK_Mode is @@ -764,7 +755,7 @@ package body Ada.Strings.Superbounded with SPARK_Mode is if Num_Delete <= 0 then return Source; - elsif From - 1 > Slen then + elsif From > Slen then raise Ada.Strings.Index_Error; elsif Through >= Slen then @@ -793,7 +784,7 @@ package body Ada.Strings.Superbounded with SPARK_Mode is if Num_Delete <= 0 then return; - elsif From - 1 > Slen then + elsif From > Slen then raise Ada.Strings.Index_Error; elsif Through >= Slen then @@ -1438,91 +1429,6 @@ package body Ada.Strings.Superbounded with SPARK_Mode is Indx : Natural; Ilen : constant Natural := Item'Length; - -- Parts of the proof involving manipulations with the modulo operator - -- are complicated for the prover and can't be done automatically in - -- the global subprogram. That's why we isolate them in these two ghost - -- lemmas. - - procedure Lemma_Mod (K : Natural; Q : Natural) with - Ghost, - Pre => Ilen /= 0 - and then Q mod Ilen = 0 - and then K - Q in 0 .. Ilen - 1, - Post => K mod Ilen = K - Q; - -- Lemma_Mod is applied to an index considered in Lemma_Split to prove - -- that it has the right value modulo Item'Length. - - procedure Lemma_Mod_Zero (X : Natural) with - Ghost, - Pre => Ilen /= 0 - and then X mod Ilen = 0 - and then X <= Natural'Last - Ilen, - Post => (X + Ilen) mod Ilen = 0; - -- Lemma_Mod_Zero is applied to prove that the length of the range - -- of indexes considered in the loop, when dropping on the Left, is - -- a multiple of Item'Length. - - procedure Lemma_Split (Going : Direction) with - Ghost, - Pre => - Ilen /= 0 - and then Indx in 0 .. Max_Length - Ilen - and then - (if Going = Forward - then Indx mod Ilen = 0 - else (Max_Length - Indx - Ilen) mod Ilen = 0) - and then Result.Data (Indx + 1 .. Indx + Ilen)'Initialized - and then String (Result.Data (Indx + 1 .. Indx + Ilen)) = Item, - Post => - (if Going = Forward then - (for all J in Indx + 1 .. Indx + Ilen => - Result.Data (J) = Item (Item'First + (J - 1) mod Ilen)) - else - (for all J in Indx + 1 .. Indx + Ilen => - Result.Data (J) = - Item (Item'Last - (Max_Length - J) mod Ilen))); - -- Lemma_Split is used after Result.Data (Indx + 1 .. Indx + Ilen) is - -- updated to Item and concludes that the characters match for each - -- index when taken modulo Item'Length, as the considered slice starts - -- at index 1 (or ends at index Max_Length, if Going = Backward) modulo - -- Item'Length. - - --------------- - -- Lemma_Mod -- - --------------- - - procedure Lemma_Mod (K : Natural; Q : Natural) is null; - - -------------------- - -- Lemma_Mod_Zero -- - -------------------- - - procedure Lemma_Mod_Zero (X : Natural) is null; - - ----------------- - -- Lemma_Split -- - ----------------- - - procedure Lemma_Split (Going : Direction) is - begin - if Going = Forward then - for K in Indx + 1 .. Indx + Ilen loop - Lemma_Mod (K - 1, Indx); - pragma Loop_Invariant - (for all J in Indx + 1 .. K => - Result.Data (J) = Item (Item'First + (J - 1) mod Ilen)); - end loop; - else - for K in Indx + 1 .. Indx + Ilen loop - Lemma_Mod (Max_Length - K, Max_Length - Indx - Ilen); - pragma Loop_Invariant - (for all J in Indx + 1 .. K => - Result.Data (J) = - Item (Item'Last - (Max_Length - J) mod Ilen)); - end loop; - end if; - end Lemma_Split; - begin if Count = 0 or else Ilen <= Max_Length / Count then if Count * Ilen > 0 then @@ -1531,19 +1437,7 @@ package body Ada.Strings.Superbounded with SPARK_Mode is for J in 1 .. Count loop Result.Data (Indx + 1 .. Indx + Ilen) := Super_String_Data (Item); - pragma Assert - (for all K in 1 .. Ilen => - Result.Data (Indx + K) = Item (Item'First - 1 + K)); - pragma Assert - (String (Result.Data (Indx + 1 .. Indx + Ilen)) = Item); - Lemma_Split (Forward); Indx := Indx + Ilen; - pragma Loop_Invariant (Indx = J * Ilen); - pragma Loop_Invariant (Result.Data (1 .. Indx)'Initialized); - pragma Loop_Invariant - (for all K in 1 .. Indx => - Result.Data (K) = - Item (Item'First + (K - 1) mod Ilen)); end loop; end if; @@ -1557,36 +1451,11 @@ package body Ada.Strings.Superbounded with SPARK_Mode is while Indx < Max_Length - Ilen loop Result.Data (Indx + 1 .. Indx + Ilen) := Super_String_Data (Item); - pragma Assert - (for all K in 1 .. Ilen => - Result.Data (Indx + K) = Item (Item'First - 1 + K)); - pragma Assert - (String (Result.Data (Indx + 1 .. Indx + Ilen)) = Item); - Lemma_Split (Forward); Indx := Indx + Ilen; - pragma Loop_Invariant (Indx mod Ilen = 0); - pragma Loop_Invariant (Indx in 0 .. Max_Length - 1); - pragma Loop_Invariant (Result.Data (1 .. Indx)'Initialized); - pragma Loop_Invariant - (for all K in 1 .. Indx => - Result.Data (K) = - Item (Item'First + (K - 1) mod Ilen)); - pragma Loop_Variant (Increases => Indx); end loop; Result.Data (Indx + 1 .. Max_Length) := Super_String_Data (Item (Item'First .. Item'First + (Max_Length - Indx - 1))); - pragma Assert - (for all J in Indx + 1 .. Max_Length => - Result.Data (J) = Item (Item'First - 1 - Indx + J)); - - for J in Indx + 1 .. Max_Length loop - Lemma_Mod (J - 1, Indx); - pragma Loop_Invariant - (for all K in 1 .. J => - Result.Data (K) = - Item (Item'First + (K - 1) mod Ilen)); - end loop; when Strings.Left => Indx := Max_Length; @@ -1595,40 +1464,10 @@ package body Ada.Strings.Superbounded with SPARK_Mode is Indx := Indx - Ilen; Result.Data (Indx + 1 .. Indx + Ilen) := Super_String_Data (Item); - pragma Assert - (for all K in 1 .. Ilen => - Result.Data (Indx + K) = Item (Item'First - 1 + K)); - pragma Assert - (String (Result.Data (Indx + 1 .. Indx + Ilen)) = Item); - Lemma_Split (Backward); - Lemma_Mod_Zero (Max_Length - Indx - Ilen); - pragma Loop_Invariant - ((Max_Length - Indx) mod Ilen = 0); - pragma Loop_Invariant (Indx in 1 .. Max_Length); - pragma Loop_Invariant - (Result.Data (Indx + 1 .. Max_Length)'Initialized); - pragma Loop_Invariant - (for all K in Indx + 1 .. Max_Length => - Result.Data (K) = - Item (Item'Last - (Max_Length - K) mod Ilen)); - pragma Loop_Variant (Decreases => Indx); end loop; Result.Data (1 .. Indx) := Super_String_Data (Item (Item'Last - Indx + 1 .. Item'Last)); - pragma Assert - (for all J in 1 .. Indx => - Result.Data (J) = Item (Item'Last - Indx + J)); - - for J in reverse 1 .. Indx loop - Lemma_Mod (Max_Length - J, Max_Length - Indx); - pragma Loop_Invariant - (for all K in J .. Max_Length => - Result.Data (K) = - Item (Item'Last - (Max_Length - K) mod Ilen)); - end loop; - pragma Assert - (Result.Data (1 .. Max_Length)'Initialized); when Strings.Error => raise Ada.Strings.Length_Error; @@ -1643,8 +1482,7 @@ package body Ada.Strings.Superbounded with SPARK_Mode is function Super_Replicate (Count : Natural; Item : Super_String; - Drop : Strings.Truncation := Strings.Error) return Super_String - is + Drop : Strings.Truncation := Strings.Error) return Super_String is begin return Super_Replicate (Count, Super_To_String (Item), Drop, Item.Max_Length); @@ -1820,14 +1658,9 @@ package body Ada.Strings.Superbounded with SPARK_Mode is Mapping : Maps.Character_Mapping) return Super_String is Result : Super_String (Source.Max_Length); - begin for J in 1 .. Source.Current_Length loop Result.Data (J) := Value (Mapping, Source.Data (J)); - pragma Loop_Invariant (Result.Data (1 .. J)'Initialized); - pragma Loop_Invariant - (for all K in 1 .. J => - Result.Data (K) = Value (Mapping, Source.Data (K))); end loop; Result.Current_Length := Source.Current_Length; @@ -1836,14 +1669,10 @@ package body Ada.Strings.Superbounded with SPARK_Mode is procedure Super_Translate (Source : in out Super_String; - Mapping : Maps.Character_Mapping) - is + Mapping : Maps.Character_Mapping) is begin for J in 1 .. Source.Current_Length loop Source.Data (J) := Value (Mapping, Source.Data (J)); - pragma Loop_Invariant - (for all K in 1 .. J => - Source.Data (K) = Value (Mapping, Source'Loop_Entry.Data (K))); end loop; end Super_Translate; @@ -1852,20 +1681,9 @@ package body Ada.Strings.Superbounded with SPARK_Mode is Mapping : Maps.Character_Mapping_Function) return Super_String is Result : Super_String (Source.Max_Length); - begin for J in 1 .. Source.Current_Length loop Result.Data (J) := Mapping.all (Source.Data (J)); - pragma Annotate (GNATprove, False_Positive, - "call via access-to-subprogram", - "function Mapping must always terminate"); - pragma Loop_Invariant (Result.Data (1 .. J)'Initialized); - pragma Loop_Invariant - (for all K in 1 .. J => - Result.Data (K) = Mapping (Source.Data (K))); - pragma Annotate (GNATprove, False_Positive, - "call via access-to-subprogram", - "function Mapping must always terminate"); end loop; Result.Current_Length := Source.Current_Length; @@ -1874,20 +1692,10 @@ package body Ada.Strings.Superbounded with SPARK_Mode is procedure Super_Translate (Source : in out Super_String; - Mapping : Maps.Character_Mapping_Function) - is + Mapping : Maps.Character_Mapping_Function) is begin for J in 1 .. Source.Current_Length loop Source.Data (J) := Mapping.all (Source.Data (J)); - pragma Annotate (GNATprove, False_Positive, - "call via access-to-subprogram", - "function Mapping must always terminate"); - pragma Loop_Invariant - (for all K in 1 .. J => - Source.Data (K) = Mapping (Source'Loop_Entry.Data (K))); - pragma Annotate (GNATprove, False_Positive, - "call via access-to-subprogram", - "function Mapping must always terminate"); end loop; end Super_Translate; @@ -1901,7 +1709,6 @@ package body Ada.Strings.Superbounded with SPARK_Mode is is Result : Super_String (Source.Max_Length); Last : constant Natural := Source.Current_Length; - begin case Side is when Strings.Left => @@ -2101,13 +1908,9 @@ package body Ada.Strings.Superbounded with SPARK_Mode is begin if Left > Max_Length then raise Ada.Strings.Length_Error; - else for J in 1 .. Left loop Result.Data (J) := Right; - pragma Loop_Invariant (Result.Data (1 .. J)'Initialized); - pragma Loop_Invariant - (for all K in 1 .. J => Result.Data (K) = Right); end loop; Result.Current_Length := Left; @@ -2126,80 +1929,15 @@ package body Ada.Strings.Superbounded with SPARK_Mode is Rlen : constant Natural := Right'Length; Nlen : constant Natural := Left * Rlen; - -- Parts of the proof involving manipulations with the modulo operator - -- are complicated for the prover and can't be done automatically in - -- the global subprogram. That's why we isolate them in these two ghost - -- lemmas. - - procedure Lemma_Mod (K : Integer) with - Ghost, - Pre => - Rlen /= 0 - and then Pos mod Rlen = 0 - and then Pos in 0 .. Max_Length - Rlen - and then K in Pos .. Pos + Rlen - 1, - Post => K mod Rlen = K - Pos; - -- Lemma_Mod is applied to an index considered in Lemma_Split to prove - -- that it has the right value modulo Right'Length. - - procedure Lemma_Split with - Ghost, - Pre => - Rlen /= 0 - and then Pos mod Rlen = 0 - and then Pos in 0 .. Max_Length - Rlen - and then Result.Data (1 .. Pos + Rlen)'Initialized - and then String (Result.Data (Pos + 1 .. Pos + Rlen)) = Right, - Post => - (for all K in Pos + 1 .. Pos + Rlen => - Result.Data (K) = Right (Right'First + (K - 1) mod Rlen)); - -- Lemma_Split is used after Result.Data (Pos + 1 .. Pos + Rlen) is - -- updated to Right and concludes that the characters match for each - -- index when taken modulo Right'Length, as the considered slice starts - -- at index 1 modulo Right'Length. - - --------------- - -- Lemma_Mod -- - --------------- - - procedure Lemma_Mod (K : Integer) is null; - - ----------------- - -- Lemma_Split -- - ----------------- - - procedure Lemma_Split is - begin - for K in Pos + 1 .. Pos + Rlen loop - Lemma_Mod (K - 1); - pragma Loop_Invariant - (for all J in Pos + 1 .. K => - Result.Data (J) = Right (Right'First + (J - 1) mod Rlen)); - end loop; - end Lemma_Split; - begin if Nlen > Max_Length then raise Ada.Strings.Length_Error; - else if Nlen > 0 then for J in 1 .. Left loop Result.Data (Pos + 1 .. Pos + Rlen) := Super_String_Data (Right); - pragma Assert - (for all K in 1 .. Rlen => Result.Data (Pos + K) = - Right (Right'First - 1 + K)); - pragma Assert - (String (Result.Data (Pos + 1 .. Pos + Rlen)) = Right); - Lemma_Split; Pos := Pos + Rlen; - pragma Loop_Invariant (Pos = J * Rlen); - pragma Loop_Invariant (Result.Data (1 .. Pos)'Initialized); - pragma Loop_Invariant - (for all K in 1 .. Pos => - Result.Data (K) = - Right (Right'First + (K - 1) mod Rlen)); end loop; end if; @@ -2221,19 +1959,12 @@ package body Ada.Strings.Superbounded with SPARK_Mode is begin if Nlen > Right.Max_Length then raise Ada.Strings.Length_Error; - else if Nlen > 0 then for J in 1 .. Left loop Result.Data (Pos + 1 .. Pos + Rlen) := Right.Data (1 .. Rlen); Pos := Pos + Rlen; - pragma Loop_Invariant (Pos = J * Rlen); - pragma Loop_Invariant (Result.Data (1 .. Pos)'Initialized); - pragma Loop_Invariant - (for all K in 1 .. Pos => - Result.Data (K) = - Right.Data (1 + (K - 1) mod Rlen)); end loop; end if; @@ -2259,7 +1990,6 @@ package body Ada.Strings.Superbounded with SPARK_Mode is if Slen <= Max_Length then Result.Data (1 .. Slen) := Super_String_Data (Source); Result.Current_Length := Slen; - else case Drop is when Strings.Right => diff --git a/gcc/ada/libgnat/a-strsup.ads b/gcc/ada/libgnat/a-strsup.ads index 65d13ed2cbe4..68098ea89413 100644 --- a/gcc/ada/libgnat/a-strsup.ads +++ b/gcc/ada/libgnat/a-strsup.ads @@ -42,10 +42,11 @@ -- contract cases should not be executed at runtime as well, in order not to -- slow down the execution of these functions. -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); +pragma Assertion_Policy (Pre => Ignore, + Post => Ignore, + Contract_Cases => Ignore, + Ghost => Ignore, + Ghost_Predicate => Ignore); with Ada.Strings.Maps; use type Ada.Strings.Maps.Character_Mapping_Function; with Ada.Strings.Search; diff --git a/gcc/ada/libgnat/a-stwisu.adb b/gcc/ada/libgnat/a-stwisu.adb index e7e6b1f75c19..28ae887cc5a9 100644 --- a/gcc/ada/libgnat/a-stwisu.adb +++ b/gcc/ada/libgnat/a-stwisu.adb @@ -753,7 +753,7 @@ package body Ada.Strings.Wide_Superbounded is if Num_Delete <= 0 then return Source; - elsif From > Slen + 1 then + elsif From > Slen then raise Ada.Strings.Index_Error; elsif Through >= Slen then @@ -782,7 +782,7 @@ package body Ada.Strings.Wide_Superbounded is if Num_Delete <= 0 then return; - elsif From > Slen + 1 then + elsif From > Slen then raise Ada.Strings.Index_Error; elsif Through >= Slen then diff --git a/gcc/ada/libgnat/a-stzsup.adb b/gcc/ada/libgnat/a-stzsup.adb index fb1baf6c62cf..5dcbadf3c030 100644 --- a/gcc/ada/libgnat/a-stzsup.adb +++ b/gcc/ada/libgnat/a-stzsup.adb @@ -754,7 +754,7 @@ package body Ada.Strings.Wide_Wide_Superbounded is if Num_Delete <= 0 then return Source; - elsif From > Slen + 1 then + elsif From > Slen then raise Ada.Strings.Index_Error; elsif Through >= Slen then @@ -783,7 +783,7 @@ package body Ada.Strings.Wide_Wide_Superbounded is if Num_Delete <= 0 then return; - elsif From > Slen + 1 then + elsif From > Slen then raise Ada.Strings.Index_Error; elsif Through >= Slen then diff --git a/gcc/ada/libgnat/a-tifiio.adb b/gcc/ada/libgnat/a-tifiio.adb index 735859c3f150..26f04ed726ee 100644 --- a/gcc/ada/libgnat/a-tifiio.adb +++ b/gcc/ada/libgnat/a-tifiio.adb @@ -194,9 +194,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**31) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**31) - or else (Num'Base'Small_Numerator <= 2**27 and then Num'Base'Small_Denominator <= 2**27)); -- These conditions are derived from the prerequisites of System.Value_F @@ -223,9 +220,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**63) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**63) - or else (Num'Base'Small_Numerator <= 2**59 and then Num'Base'Small_Denominator <= 2**59)); -- These conditions are derived from the prerequisites of System.Value_F diff --git a/gcc/ada/libgnat/a-tifiio__128.adb b/gcc/ada/libgnat/a-tifiio__128.adb index 7424346fe3d6..78c25f29bc8b 100644 --- a/gcc/ada/libgnat/a-tifiio__128.adb +++ b/gcc/ada/libgnat/a-tifiio__128.adb @@ -201,9 +201,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**31) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**31) - or else (Num'Base'Small_Numerator <= 2**27 and then Num'Base'Small_Denominator <= 2**27)); -- These conditions are derived from the prerequisites of System.Value_F @@ -230,9 +227,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**63) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**63) - or else (Num'Base'Small_Numerator <= 2**59 and then Num'Base'Small_Denominator <= 2**59)); -- These conditions are derived from the prerequisites of System.Value_F @@ -259,9 +253,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**127) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**127) - or else (Num'Base'Small_Numerator <= 2**123 and then Num'Base'Small_Denominator <= 2**123)); -- These conditions are derived from the prerequisites of System.Value_F diff --git a/gcc/ada/libgnat/a-wtfiio.adb b/gcc/ada/libgnat/a-wtfiio.adb index ed69d65df09d..3ceda12b9ec3 100644 --- a/gcc/ada/libgnat/a-wtfiio.adb +++ b/gcc/ada/libgnat/a-wtfiio.adb @@ -73,9 +73,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**31) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**31) - or else (Num'Base'Small_Numerator <= 2**27 and then Num'Base'Small_Denominator <= 2**27)); -- These conditions are derived from the prerequisites of System.Value_F @@ -102,9 +99,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**63) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**63) - or else (Num'Base'Small_Numerator <= 2**59 and then Num'Base'Small_Denominator <= 2**59)); -- These conditions are derived from the prerequisites of System.Value_F diff --git a/gcc/ada/libgnat/a-wtfiio__128.adb b/gcc/ada/libgnat/a-wtfiio__128.adb index ec8deca6ca4e..8757ffb25149 100644 --- a/gcc/ada/libgnat/a-wtfiio__128.adb +++ b/gcc/ada/libgnat/a-wtfiio__128.adb @@ -80,9 +80,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**31) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**31) - or else (Num'Base'Small_Numerator <= 2**27 and then Num'Base'Small_Denominator <= 2**27)); -- These conditions are derived from the prerequisites of System.Value_F @@ -109,9 +106,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**63) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**63) - or else (Num'Base'Small_Numerator <= 2**59 and then Num'Base'Small_Denominator <= 2**59)); -- These conditions are derived from the prerequisites of System.Value_F @@ -138,9 +132,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**127) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**127) - or else (Num'Base'Small_Numerator <= 2**123 and then Num'Base'Small_Denominator <= 2**123)); -- These conditions are derived from the prerequisites of System.Value_F diff --git a/gcc/ada/libgnat/a-ztfiio.adb b/gcc/ada/libgnat/a-ztfiio.adb index edf58ad85ead..b9f4f43226f0 100644 --- a/gcc/ada/libgnat/a-ztfiio.adb +++ b/gcc/ada/libgnat/a-ztfiio.adb @@ -73,9 +73,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**31) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**31) - or else (Num'Base'Small_Numerator <= 2**27 and then Num'Base'Small_Denominator <= 2**27)); -- These conditions are derived from the prerequisites of System.Value_F @@ -102,9 +99,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**63) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**63) - or else (Num'Base'Small_Numerator <= 2**59 and then Num'Base'Small_Denominator <= 2**59)); -- These conditions are derived from the prerequisites of System.Value_F diff --git a/gcc/ada/libgnat/a-ztfiio__128.adb b/gcc/ada/libgnat/a-ztfiio__128.adb index bc0062f9d9f8..eb02a4a2cece 100644 --- a/gcc/ada/libgnat/a-ztfiio__128.adb +++ b/gcc/ada/libgnat/a-ztfiio__128.adb @@ -81,9 +81,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**31) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**31) - or else (Num'Base'Small_Numerator <= 2**27 and then Num'Base'Small_Denominator <= 2**27)); -- These conditions are derived from the prerequisites of System.Value_F @@ -110,9 +107,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**63) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**63) - or else (Num'Base'Small_Numerator <= 2**59 and then Num'Base'Small_Denominator <= 2**59)); -- These conditions are derived from the prerequisites of System.Value_F @@ -139,9 +133,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is ((Num'Base'Small_Numerator = 1 and then Num'Base'Small_Denominator <= 2**127) or else - (Num'Base'Small_Denominator = 1 - and then Num'Base'Small_Numerator <= 2**127) - or else (Num'Base'Small_Numerator <= 2**123 and then Num'Base'Small_Denominator <= 2**123)); -- These conditions are derived from the prerequisites of System.Value_F diff --git a/gcc/ada/libgnat/g-dyntab.ads b/gcc/ada/libgnat/g-dyntab.ads index 7e2e3b22be4a..78109867ec26 100644 --- a/gcc/ada/libgnat/g-dyntab.ads +++ b/gcc/ada/libgnat/g-dyntab.ads @@ -168,8 +168,9 @@ package GNAT.Dynamic_Tables is -- -- Tab : Table_Type renames X.Table (First .. X.Last); -- - -- Note: The Table component must come first. See declarations of - -- SCO_Unit_Table and SCO_Table in scos.h. + -- Note: The Table component must come first to simplify interfacing + -- with C, similar to how we do it for the Table unit; see declarations + -- of Names_Ptr and Names_Char_Ptr in namet.h. Locked : Boolean := False; -- Table reallocation is permitted only if this is False. A client may diff --git a/gcc/ada/libgnat/i-c.adb b/gcc/ada/libgnat/i-c.adb index d248ceb3a655..e63c014af8e1 100644 --- a/gcc/ada/libgnat/i-c.adb +++ b/gcc/ada/libgnat/i-c.adb @@ -29,78 +29,10 @@ -- -- ------------------------------------------------------------------------------ --- Ghost code, loop invariants and assertions in this unit are meant for --- analysis only, not for run-time checking, as it would be too costly --- otherwise. This is enforced by setting the assertion policy to Ignore. - -pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - package body Interfaces.C with SPARK_Mode is - -------------------- - -- C_Length_Ghost -- - -------------------- - - function C_Length_Ghost (Item : char_array) return size_t is - begin - for J in Item'Range loop - if Item (J) = nul then - return J - Item'First; - end if; - - pragma Loop_Invariant - (for all K in Item'First .. J => Item (K) /= nul); - end loop; - - raise Program_Error; - end C_Length_Ghost; - - function C_Length_Ghost (Item : wchar_array) return size_t is - begin - for J in Item'Range loop - if Item (J) = wide_nul then - return J - Item'First; - end if; - - pragma Loop_Invariant - (for all K in Item'First .. J => Item (K) /= wide_nul); - end loop; - - raise Program_Error; - end C_Length_Ghost; - - function C_Length_Ghost (Item : char16_array) return size_t is - begin - for J in Item'Range loop - if Item (J) = char16_nul then - return J - Item'First; - end if; - - pragma Loop_Invariant - (for all K in Item'First .. J => Item (K) /= char16_nul); - end loop; - - raise Program_Error; - end C_Length_Ghost; - - function C_Length_Ghost (Item : char32_array) return size_t is - begin - for J in Item'Range loop - if Item (J) = char32_nul then - return J - Item'First; - end if; - - pragma Loop_Invariant - (for all K in Item'First .. J => Item (K) /= char32_nul); - end loop; - - raise Program_Error; - end C_Length_Ghost; - ----------------------- -- Is_Nul_Terminated -- ----------------------- @@ -113,9 +45,6 @@ is if Item (J) = nul then return True; end if; - - pragma Loop_Invariant - (for all K in Item'First .. J => Item (K) /= nul); end loop; return False; @@ -129,9 +58,6 @@ is if Item (J) = wide_nul then return True; end if; - - pragma Loop_Invariant - (for all K in Item'First .. J => Item (K) /= wide_nul); end loop; return False; @@ -145,9 +71,6 @@ is if Item (J) = char16_nul then return True; end if; - - pragma Loop_Invariant - (for all K in Item'First .. J => Item (K) /= char16_nul); end loop; return False; @@ -161,9 +84,6 @@ is if Item (J) = char32_nul then return True; end if; - - pragma Loop_Invariant - (for all K in Item'First .. J => Item (K) /= char32_nul); end loop; return False; @@ -194,14 +114,6 @@ is From := Item'First; loop - pragma Loop_Invariant (From in Item'Range); - pragma Loop_Invariant - (for some J in From .. Item'Last => Item (J) = nul); - pragma Loop_Invariant - (for all J in Item'First .. From when J /= From => - Item (J) /= nul); - pragma Loop_Variant (Increases => From); - if From > Item'Last then raise Terminator_Error; elsif Item (From) = nul then @@ -211,8 +123,6 @@ is end if; end loop; - pragma Assert (From = Item'First + C_Length_Ghost (Item)); - Count := Natural (From - Item'First); else @@ -220,17 +130,10 @@ is end if; declare - Count_Cst : constant Natural := Count; - R : String (1 .. Count_Cst) with Relaxed_Initialization; - + R : String (1 .. Count); begin for J in R'Range loop R (J) := To_Ada (Item (size_t (J) - 1 + Item'First)); - - pragma Loop_Invariant (for all K in 1 .. J => R (K)'Initialized); - pragma Loop_Invariant - (for all K in 1 .. J => - R (K) = To_Ada (Item (size_t (K) - 1 + Item'First))); end loop; return R; @@ -252,14 +155,6 @@ is if Trim_Nul then From := Item'First; loop - pragma Loop_Invariant (From in Item'Range); - pragma Loop_Invariant - (for some J in From .. Item'Last => Item (J) = nul); - pragma Loop_Invariant - (for all J in Item'First .. From when J /= From => - Item (J) /= nul); - pragma Loop_Variant (Increases => From); - if From > Item'Last then raise Terminator_Error; elsif Item (From) = nul then @@ -285,19 +180,6 @@ is for J in 1 .. Count loop Target (To) := Character (Item (From)); - pragma Loop_Invariant (From in Item'Range); - pragma Loop_Invariant (To in Target'Range); - pragma Loop_Invariant (To = Target'First + (J - 1)); - pragma Loop_Invariant (From = Item'First + size_t (J - 1)); - pragma Loop_Invariant - (for all J in Target'First .. To => Target (J)'Initialized); - pragma Loop_Invariant - (Target (Target'First .. To)'Initialized); - pragma Loop_Invariant - (for all K in Target'First .. To => - Target (K) = - To_Ada (Item (size_t (K - Target'First) + Item'First))); - -- Avoid possible overflow when incrementing To in the last -- iteration of the loop. exit when J = Count; @@ -329,14 +211,6 @@ is From := Item'First; loop - pragma Loop_Invariant (From in Item'Range); - pragma Loop_Invariant - (for some J in From .. Item'Last => Item (J) = wide_nul); - pragma Loop_Invariant - (for all J in Item'First .. From when J /= From => - Item (J) /= wide_nul); - pragma Loop_Variant (Increases => From); - if From > Item'Last then raise Terminator_Error; elsif Item (From) = wide_nul then @@ -346,8 +220,6 @@ is end if; end loop; - pragma Assert (From = Item'First + C_Length_Ghost (Item)); - Count := Natural (From - Item'First); else @@ -355,17 +227,10 @@ is end if; declare - Count_Cst : constant Natural := Count; - R : Wide_String (1 .. Count_Cst) with Relaxed_Initialization; - + R : Wide_String (1 .. Count); begin for J in R'Range loop R (J) := To_Ada (Item (size_t (J) - 1 + Item'First)); - - pragma Loop_Invariant (for all K in 1 .. J => R (K)'Initialized); - pragma Loop_Invariant - (for all K in 1 .. J => - R (K) = To_Ada (Item (size_t (K) - 1 + Item'First))); end loop; return R; @@ -387,14 +252,6 @@ is if Trim_Nul then From := Item'First; loop - pragma Loop_Invariant (From in Item'Range); - pragma Loop_Invariant - (for some J in From .. Item'Last => Item (J) = wide_nul); - pragma Loop_Invariant - (for all J in Item'First .. From when J /= From => - Item (J) /= wide_nul); - pragma Loop_Variant (Increases => From); - if From > Item'Last then raise Terminator_Error; elsif Item (From) = wide_nul then @@ -420,19 +277,6 @@ is for J in 1 .. Count loop Target (To) := To_Ada (Item (From)); - pragma Loop_Invariant (From in Item'Range); - pragma Loop_Invariant (To in Target'Range); - pragma Loop_Invariant (To = Target'First + (J - 1)); - pragma Loop_Invariant (From = Item'First + size_t (J - 1)); - pragma Loop_Invariant - (for all J in Target'First .. To => Target (J)'Initialized); - pragma Loop_Invariant - (Target (Target'First .. To)'Initialized); - pragma Loop_Invariant - (for all K in Target'First .. To => - Target (K) = - To_Ada (Item (size_t (K - Target'First) + Item'First))); - -- Avoid possible overflow when incrementing To in the last -- iteration of the loop. exit when J = Count; @@ -464,14 +308,6 @@ is From := Item'First; loop - pragma Loop_Invariant (From in Item'Range); - pragma Loop_Invariant - (for some J in From .. Item'Last => Item (J) = char16_nul); - pragma Loop_Invariant - (for all J in Item'First .. From when J /= From => - Item (J) /= char16_nul); - pragma Loop_Variant (Increases => From); - if From > Item'Last then raise Terminator_Error; elsif Item (From) = char16_nul then @@ -481,8 +317,6 @@ is end if; end loop; - pragma Assert (From = Item'First + C_Length_Ghost (Item)); - Count := Natural (From - Item'First); else @@ -490,17 +324,10 @@ is end if; declare - Count_Cst : constant Natural := Count; - R : Wide_String (1 .. Count_Cst) with Relaxed_Initialization; - + R : Wide_String (1 .. Count); begin for J in R'Range loop R (J) := To_Ada (Item (size_t (J) - 1 + Item'First)); - - pragma Loop_Invariant (for all K in 1 .. J => R (K)'Initialized); - pragma Loop_Invariant - (for all K in 1 .. J => - R (K) = To_Ada (Item (size_t (K) - 1 + Item'First))); end loop; return R; @@ -522,14 +349,6 @@ is if Trim_Nul then From := Item'First; loop - pragma Loop_Invariant (From in Item'Range); - pragma Loop_Invariant - (for some J in From .. Item'Last => Item (J) = char16_nul); - pragma Loop_Invariant - (for all J in Item'First .. From when J /= From => - Item (J) /= char16_nul); - pragma Loop_Variant (Increases => From); - if From > Item'Last then raise Terminator_Error; elsif Item (From) = char16_nul then @@ -555,19 +374,6 @@ is for J in 1 .. Count loop Target (To) := To_Ada (Item (From)); - pragma Loop_Invariant (From in Item'Range); - pragma Loop_Invariant (To in Target'Range); - pragma Loop_Invariant (To = Target'First + (J - 1)); - pragma Loop_Invariant (From = Item'First + size_t (J - 1)); - pragma Loop_Invariant - (for all J in Target'First .. To => Target (J)'Initialized); - pragma Loop_Invariant - (Target (Target'First .. To)'Initialized); - pragma Loop_Invariant - (for all K in Target'First .. To => - Target (K) = - To_Ada (Item (size_t (K - Target'First) + Item'First))); - -- Avoid possible overflow when incrementing To in the last -- iteration of the loop. exit when J = Count; @@ -599,15 +405,6 @@ is From := Item'First; loop - pragma Loop_Invariant (From in Item'Range); - pragma Loop_Invariant - (for some J in From .. Item'Last => Item (J) = char32_nul); - pragma Loop_Invariant - (for all J in Item'First .. From when J /= From => - Item (J) /= char32_nul); - pragma Loop_Invariant (From <= Item'First + C_Length_Ghost (Item)); - pragma Loop_Variant (Increases => From); - if From > Item'Last then raise Terminator_Error; elsif Item (From) = char32_nul then @@ -617,8 +414,6 @@ is end if; end loop; - pragma Assert (From = Item'First + C_Length_Ghost (Item)); - Count := Natural (From - Item'First); else @@ -626,17 +421,11 @@ is end if; declare - Count_Cst : constant Natural := Count; - R : Wide_Wide_String (1 .. Count_Cst) with Relaxed_Initialization; + R : Wide_Wide_String (1 .. Count); begin for J in R'Range loop R (J) := To_Ada (Item (size_t (J) - 1 + Item'First)); - - pragma Loop_Invariant (for all K in 1 .. J => R (K)'Initialized); - pragma Loop_Invariant - (for all K in 1 .. J => - R (K) = To_Ada (Item (size_t (K) - 1 + Item'First))); end loop; return R; @@ -658,14 +447,6 @@ is if Trim_Nul then From := Item'First; loop - pragma Loop_Invariant (From in Item'Range); - pragma Loop_Invariant - (for some J in From .. Item'Last => Item (J) = char32_nul); - pragma Loop_Invariant - (for all J in Item'First .. From when J /= From => - Item (J) /= char32_nul); - pragma Loop_Variant (Increases => From); - if From > Item'Last then raise Terminator_Error; elsif Item (From) = char32_nul then @@ -691,19 +472,6 @@ is for J in 1 .. Count loop Target (To) := To_Ada (Item (From)); - pragma Loop_Invariant (From in Item'Range); - pragma Loop_Invariant (To in Target'Range); - pragma Loop_Invariant (To = Target'First + (J - 1)); - pragma Loop_Invariant (From = Item'First + size_t (J - 1)); - pragma Loop_Invariant - (for all J in Target'First .. To => Target (J)'Initialized); - pragma Loop_Invariant - (Target (Target'First .. To)'Initialized); - pragma Loop_Invariant - (for all K in Target'First .. To => - Target (K) = - To_Ada (Item (size_t (K - Target'First) + Item'First))); - -- Avoid possible overflow when incrementing To in the last -- iteration of the loop. exit when J = Count; @@ -734,26 +502,14 @@ is begin if Append_Nul then declare - R : char_array (0 .. Item'Length) with Relaxed_Initialization; - + R : char_array (0 .. Item'Length); begin for J in Item'Range loop R (size_t (J - Item'First)) := To_C (Item (J)); - - pragma Loop_Invariant - (for all K in 0 .. size_t (J - Item'First) => - R (K)'Initialized); - pragma Loop_Invariant - (for all K in Item'First .. J => - R (size_t (K - Item'First)) = To_C (Item (K))); end loop; R (R'Last) := nul; - pragma Assert - (for all J in Item'Range => - R (size_t (J - Item'First)) = To_C (Item (J))); - return R; end; @@ -774,19 +530,10 @@ is else declare - R : char_array (0 .. Item'Length - 1) - with Relaxed_Initialization; - + R : char_array (0 .. Item'Length - 1); begin for J in Item'Range loop R (size_t (J - Item'First)) := To_C (Item (J)); - - pragma Loop_Invariant - (for all K in 0 .. size_t (J - Item'First) => - R (K)'Initialized); - pragma Loop_Invariant - (for all K in Item'First .. J => - R (size_t (K - Item'First)) = To_C (Item (K))); end loop; return R; @@ -814,18 +561,6 @@ is for From in Item'Range loop Target (To) := char (Item (From)); - pragma Loop_Invariant (To in Target'Range); - pragma Loop_Invariant - (To - Target'First = size_t (From - Item'First)); - pragma Loop_Invariant - (for all J in Target'First .. To => Target (J)'Initialized); - pragma Loop_Invariant - (Target (Target'First .. To)'Initialized); - pragma Loop_Invariant - (for all J in Item'First .. From => - Target (Target'First + size_t (J - Item'First)) = - To_C (Item (J))); - To := To + 1; end loop; @@ -836,7 +571,6 @@ is Target (To) := nul; Count := Item'Length + 1; end if; - else Count := Item'Length; end if; @@ -859,26 +593,14 @@ is begin if Append_Nul then declare - R : wchar_array (0 .. Item'Length) with Relaxed_Initialization; - + R : wchar_array (0 .. Item'Length); begin for J in Item'Range loop R (size_t (J - Item'First)) := To_C (Item (J)); - - pragma Loop_Invariant - (for all K in 0 .. size_t (J - Item'First) => - R (K)'Initialized); - pragma Loop_Invariant - (for all K in Item'First .. J => - R (size_t (K - Item'First)) = To_C (Item (K))); end loop; R (R'Last) := wide_nul; - pragma Assert - (for all J in Item'Range => - R (size_t (J - Item'First)) = To_C (Item (J))); - return R; end; @@ -895,19 +617,10 @@ is else declare - R : wchar_array (0 .. Item'Length - 1) - with Relaxed_Initialization; - + R : wchar_array (0 .. Item'Length - 1); begin for J in Item'Range loop R (size_t (J - Item'First)) := To_C (Item (J)); - - pragma Loop_Invariant - (for all K in 0 .. size_t (J - Item'First) => - R (K)'Initialized); - pragma Loop_Invariant - (for all K in Item'First .. J => - R (size_t (K - Item'First)) = To_C (Item (K))); end loop; return R; @@ -925,40 +638,17 @@ is Append_Nul : Boolean := True) is To : size_t; - begin if Target'Length < Item'Length then raise Constraint_Error; - else To := Target'First; for From in Item'Range loop Target (To) := To_C (Item (From)); - pragma Loop_Invariant (To in Target'Range); - pragma Loop_Invariant - (To - Target'First = size_t (From - Item'First)); - pragma Loop_Invariant - (for all J in Target'First .. To => Target (J)'Initialized); - pragma Loop_Invariant - (Target (Target'First .. To)'Initialized); - pragma Loop_Invariant - (for all J in Item'First .. From => - Target (Target'First + size_t (J - Item'First)) = - To_C (Item (J))); - To := To + 1; end loop; - pragma Assert - (for all J in Item'Range => - Target (Target'First + size_t (J - Item'First)) = - To_C (Item (J))); - pragma Assert - (if Item'Length /= 0 then - Target (Target'First .. - Target'First + (Item'Length - 1))'Initialized); - if Append_Nul then if To > Target'Last then raise Constraint_Error; @@ -966,7 +656,6 @@ is Target (To) := wide_nul; Count := Item'Length + 1; end if; - else Count := Item'Length; end if; @@ -989,26 +678,14 @@ is begin if Append_Nul then declare - R : char16_array (0 .. Item'Length) with Relaxed_Initialization; - + R : char16_array (0 .. Item'Length); begin for J in Item'Range loop R (size_t (J - Item'First)) := To_C (Item (J)); - - pragma Loop_Invariant - (for all K in 0 .. size_t (J - Item'First) => - R (K)'Initialized); - pragma Loop_Invariant - (for all K in Item'First .. J => - R (size_t (K - Item'First)) = To_C (Item (K))); end loop; R (R'Last) := char16_nul; - pragma Assert - (for all J in Item'Range => - R (size_t (J - Item'First)) = To_C (Item (J))); - return R; end; @@ -1022,22 +699,12 @@ is if Item'Length = 0 then raise Constraint_Error; - else declare - R : char16_array (0 .. Item'Length - 1) - with Relaxed_Initialization; - + R : char16_array (0 .. Item'Length - 1); begin for J in Item'Range loop R (size_t (J - Item'First)) := To_C (Item (J)); - - pragma Loop_Invariant - (for all K in 0 .. size_t (J - Item'First) => - R (K)'Initialized); - pragma Loop_Invariant - (for all K in Item'First .. J => - R (size_t (K - Item'First)) = To_C (Item (K))); end loop; return R; @@ -1055,7 +722,6 @@ is Append_Nul : Boolean := True) is To : size_t; - begin if Target'Length < Item'Length then raise Constraint_Error; @@ -1065,30 +731,9 @@ is for From in Item'Range loop Target (To) := To_C (Item (From)); - pragma Loop_Invariant (To in Target'Range); - pragma Loop_Invariant - (To - Target'First = size_t (From - Item'First)); - pragma Loop_Invariant - (for all J in Target'First .. To => Target (J)'Initialized); - pragma Loop_Invariant - (Target (Target'First .. To)'Initialized); - pragma Loop_Invariant - (for all J in Item'First .. From => - Target (Target'First + size_t (J - Item'First)) = - To_C (Item (J))); - To := To + 1; end loop; - pragma Assert - (for all J in Item'Range => - Target (Target'First + size_t (J - Item'First)) = - To_C (Item (J))); - pragma Assert - (if Item'Length /= 0 then - Target (Target'First .. - Target'First + (Item'Length - 1))'Initialized); - if Append_Nul then if To > Target'Last then raise Constraint_Error; @@ -1096,7 +741,6 @@ is Target (To) := char16_nul; Count := Item'Length + 1; end if; - else Count := Item'Length; end if; @@ -1119,26 +763,14 @@ is begin if Append_Nul then declare - R : char32_array (0 .. Item'Length) with Relaxed_Initialization; - + R : char32_array (0 .. Item'Length); begin for J in Item'Range loop R (size_t (J - Item'First)) := To_C (Item (J)); - - pragma Loop_Invariant - (for all K in 0 .. size_t (J - Item'First) => - R (K)'Initialized); - pragma Loop_Invariant - (for all K in Item'First .. J => - R (size_t (K - Item'First)) = To_C (Item (K))); end loop; R (R'Last) := char32_nul; - pragma Assert - (for all J in Item'Range => - R (size_t (J - Item'First)) = To_C (Item (J))); - return R; end; @@ -1154,19 +786,10 @@ is else declare - R : char32_array (0 .. Item'Length - 1) - with Relaxed_Initialization; - + R : char32_array (0 .. Item'Length - 1); begin for J in Item'Range loop R (size_t (J - Item'First)) := To_C (Item (J)); - - pragma Loop_Invariant - (for all K in 0 .. size_t (J - Item'First) => - R (K)'Initialized); - pragma Loop_Invariant - (for all K in Item'First .. J => - R (size_t (K - Item'First)) = To_C (Item (K))); end loop; return R; @@ -1188,36 +811,15 @@ is begin if Target'Length < Item'Length + (if Append_Nul then 1 else 0) then raise Constraint_Error; - else To := Target'First; + for From in Item'Range loop Target (To) := To_C (Item (From)); - pragma Loop_Invariant (To in Target'Range); - pragma Loop_Invariant - (To - Target'First = size_t (From - Item'First)); - pragma Loop_Invariant - (for all J in Target'First .. To => Target (J)'Initialized); - pragma Loop_Invariant - (Target (Target'First .. To)'Initialized); - pragma Loop_Invariant - (for all J in Item'First .. From => - Target (Target'First + size_t (J - Item'First)) = - To_C (Item (J))); - To := To + 1; end loop; - pragma Assert - (for all J in Item'Range => - Target (Target'First + size_t (J - Item'First)) = - To_C (Item (J))); - pragma Assert - (if Item'Length /= 0 then - Target (Target'First .. - Target'First + (Item'Length - 1))'Initialized); - if Append_Nul then Target (To) := char32_nul; Count := Item'Length + 1; @@ -1226,7 +828,5 @@ is end if; end if; end To_C; - pragma Annotate (CodePeer, False_Positive, "validity check", - "Count is only uninitialized on abnormal return."); end Interfaces.C; diff --git a/gcc/ada/libgnat/i-c.ads b/gcc/ada/libgnat/i-c.ads index f9f9f75fc037..fc77cafaaffe 100644 --- a/gcc/ada/libgnat/i-c.ads +++ b/gcc/ada/libgnat/i-c.ads @@ -133,6 +133,7 @@ is function C_Length_Ghost (Item : char_array) return size_t with Ghost, + Import, Pre => Is_Nul_Terminated (Item), Post => C_Length_Ghost'Result <= Item'Last - Item'First and then Item (Item'First + C_Length_Ghost'Result) = nul @@ -274,6 +275,7 @@ is function C_Length_Ghost (Item : wchar_array) return size_t with Ghost, + Import, Pre => Is_Nul_Terminated (Item), Post => C_Length_Ghost'Result <= Item'Last - Item'First and then Item (Item'First + C_Length_Ghost'Result) = wide_nul @@ -395,6 +397,7 @@ is function C_Length_Ghost (Item : char16_array) return size_t with Ghost, + Import, Pre => Is_Nul_Terminated (Item), Post => C_Length_Ghost'Result <= Item'Last - Item'First and then Item (Item'First + C_Length_Ghost'Result) = char16_nul @@ -510,6 +513,7 @@ is function C_Length_Ghost (Item : char32_array) return size_t with Ghost, + Import, Pre => Is_Nul_Terminated (Item), Post => C_Length_Ghost'Result <= Item'Last - Item'First and then Item (Item'First + C_Length_Ghost'Result) = char32_nul diff --git a/gcc/ada/libgnat/i-cheri.adb b/gcc/ada/libgnat/i-cheri.adb index 37e5c3d28889..157570577168 100644 --- a/gcc/ada/libgnat/i-cheri.adb +++ b/gcc/ada/libgnat/i-cheri.adb @@ -31,6 +31,30 @@ package body Interfaces.CHERI is + ---------------- + -- Set_Bounds -- + ---------------- + + procedure Set_Bounds + (Cap : in out Capability; + Length : Bounds_Length) + is + begin + Cap := Capability_With_Bounds (Cap, Length); + end Set_Bounds; + + ---------------------- + -- Set_Exact_Bounds -- + ---------------------- + + procedure Set_Exact_Bounds + (Cap : in out Capability; + Length : Bounds_Length) + is + begin + Cap := Capability_With_Exact_Bounds (Cap, Length); + end Set_Exact_Bounds; + ---------------------------- -- Set_Address_And_Bounds -- ---------------------------- diff --git a/gcc/ada/libgnat/i-cheri.ads b/gcc/ada/libgnat/i-cheri.ads index ed26e55c7972..4186b6d47a9a 100644 --- a/gcc/ada/libgnat/i-cheri.ads +++ b/gcc/ada/libgnat/i-cheri.ads @@ -273,8 +273,7 @@ is (Cap : in out Capability; Length : Bounds_Length) with - Import, Convention => Intrinsic, - External_Name => "__builtin_cheri_bounds_set"; + Inline; -- Narrow the bounds of a capability so that the lower bound is the -- current address and the upper bound is suitable for the Length. -- @@ -287,8 +286,7 @@ is (Cap : in out Capability; Length : Bounds_Length) with - Import, Convention => Intrinsic, - External_Name => "__builtin_cheri_bounds_set_exact"; + Inline; -- Narrow the bounds of a capability so that the lower bound is the -- current address and the upper bound is suitable for the Length. -- diff --git a/gcc/ada/libgnat/i-cpoint.adb b/gcc/ada/libgnat/i-cpoint.adb index 40a5834edd05..994e639e2f99 100644 --- a/gcc/ada/libgnat/i-cpoint.adb +++ b/gcc/ada/libgnat/i-cpoint.adb @@ -148,7 +148,7 @@ package body Interfaces.C.Pointers is S : Pointer := Source; begin - if Source = null or Target = null then + if Source = null or else Target = null then raise Dereference_Error; end if; diff --git a/gcc/ada/libgnat/i-cstrin.adb b/gcc/ada/libgnat/i-cstrin.adb index 7bf881f87167..82795627a290 100644 --- a/gcc/ada/libgnat/i-cstrin.adb +++ b/gcc/ada/libgnat/i-cstrin.adb @@ -66,8 +66,11 @@ is pragma Inline ("+"); -- Address arithmetic on chars_ptr value - function Position_Of_Nul (Into : char_array) return size_t; - -- Returns position of the first Nul in Into or Into'Last + 1 if none + procedure Position_Of_Nul + (Into : char_array; Found : out Boolean; Index : out size_t); + -- If into contains a Nul character, Found is set to True and Index + -- contains the position of the first Nul character in Into. Otherwise + -- Found is set to False and the value of Index is not meaningful. -- We can't use directly System.Memory because the categorization is not -- compatible, so we directly import here the malloc and free routines. @@ -107,6 +110,7 @@ is -------------------- function New_Char_Array (Chars : char_array) return chars_ptr is + Found : Boolean; Index : size_t; Pointer : chars_ptr; @@ -114,24 +118,25 @@ is -- Get index of position of null. If Index > Chars'Last, -- nul is absent and must be added explicitly. - Index := Position_Of_Nul (Into => Chars); - Pointer := Memory_Alloc ((Index - Chars'First + 1)); + Position_Of_Nul (Into => Chars, Found => Found, Index => Index); -- If nul is present, transfer string up to and including nul - if Index <= Chars'Last then - Update (Item => Pointer, - Offset => 0, - Chars => Chars (Chars'First .. Index), - Check => False); + if Found then + Pointer := Memory_Alloc (Index - Chars'First + 1); + + Update + (Item => Pointer, + Offset => 0, + Chars => Chars (Chars'First .. Index), + Check => False); else -- If original string has no nul, transfer whole string and add -- terminator explicitly. - Update (Item => Pointer, - Offset => 0, - Chars => Chars, - Check => False); + Pointer := Memory_Alloc (Chars'Length + 1); + + Update (Item => Pointer, Offset => 0, Chars => Chars, Check => False); Poke (nul, Into => Pointer + size_t'(Chars'Length)); end if; @@ -148,20 +153,33 @@ is -- the result, and doesn't copy the string on the stack, otherwise its -- use is limited when used from tasks on large strings. - Result : constant chars_ptr := Memory_Alloc (Str'Length + 1); + Len : Natural := 0; + -- Length of the longest prefix of Str that doesn't contain NUL - Result_Array : char_array (1 .. Str'Length + 1); - for Result_Array'Address use To_Address (Result); - pragma Import (Ada, Result_Array); + Result : chars_ptr; + begin + for C of Str loop + if C = ASCII.NUL then + exit; + end if; + Len := Len + 1; + end loop; - Count : size_t; + Result := Memory_Alloc (size_t (Len) + 1); + + declare + Result_Array : char_array (1 .. size_t (Len) + 1) + with Address => To_Address (Result), Import, Convention => Ada; + + Count : size_t; + begin + To_C + (Item => Str (Str'First .. Str'First + Len - 1), + Target => Result_Array, + Count => Count, + Append_Nul => True); + end; - begin - To_C - (Item => Str, - Target => Result_Array, - Count => Count, - Append_Nul => True); return Result; end New_String; @@ -187,19 +205,19 @@ is -- Position_Of_Nul -- --------------------- - function Position_Of_Nul (Into : char_array) return size_t is + procedure Position_Of_Nul + (Into : char_array; Found : out Boolean; Index : out size_t) is begin - pragma Annotate (Gnatcheck, Exempt_On, "Improper_Returns", - "early returns for performance"); + Found := False; + Index := 0; + for J in Into'Range loop if Into (J) = nul then - return J; + Found := True; + Index := J; + return; end if; end loop; - - return Into'Last + 1; - - pragma Annotate (Gnatcheck, Exempt_Off, "Improper_Returns"); end Position_Of_Nul; ------------ @@ -231,19 +249,22 @@ is (Item : char_array_access; Nul_Check : Boolean := False) return chars_ptr is + Found : Boolean; + Index : size_t; begin pragma Annotate (Gnatcheck, Exempt_On, "Improper_Returns", "early returns for performance"); if Item = null then return Null_Ptr; - elsif Nul_Check - and then Position_Of_Nul (Into => Item.all) > Item'Last - then - raise Terminator_Error; - else - return To_chars_ptr (Item (Item'First)'Address); + elsif Nul_Check then + Position_Of_Nul (Item.all, Found, Index); + if not Found then + raise Terminator_Error; + end if; end if; + return To_chars_ptr (Item (Item'First)'Address); + pragma Annotate (Gnatcheck, Exempt_Off, "Improper_Returns"); end To_Chars_Ptr; @@ -260,6 +281,11 @@ is Index : chars_ptr := Item + Offset; begin + -- Check for null pointer as mandated by the RM. + if Item = Null_Ptr then + raise Dereference_Error; + end if; + if Check and then Offset + Chars'Length > Strlen (Item) then raise Update_Error; end if; diff --git a/gcc/ada/libgnat/i-cstrin.ads b/gcc/ada/libgnat/i-cstrin.ads index 0d057d074e5d..5939fe041a47 100644 --- a/gcc/ada/libgnat/i-cstrin.ads +++ b/gcc/ada/libgnat/i-cstrin.ads @@ -100,6 +100,17 @@ is -- The Value functions copy the contents of a chars_ptr object -- into a char_array/String. + -- There is a guard for a storage error on an object declaration for + -- an array type with a modular index type with the size of + -- Long_Long_Integer. The special processing is needed in this case + -- to compute reliably the size of the object, and eventually, to + -- raise Storage_Error, when wrap-around arithmetic might compute + -- a meangingless size for the object. + -- + -- The guard raises Storage_Error when + -- + -- (Arr'Last / 2 - Arr'First / 2) > (2 ** 30) + -- function Value (Item : chars_ptr) return char_array with Pre => Item /= Null_Ptr, Global => (Input => C_Memory); diff --git a/gcc/ada/libgnat/s-aridou.adb b/gcc/ada/libgnat/s-aridou.adb index e4140e837799..dd2f150252a9 100644 --- a/gcc/ada/libgnat/s-aridou.adb +++ b/gcc/ada/libgnat/s-aridou.adb @@ -29,74 +29,20 @@ -- -- ------------------------------------------------------------------------------ -pragma Annotate (Gnatcheck, Exempt_On, "Metrics_LSLOC", - "limit exceeded due to proof code"); - with Ada.Unchecked_Conversion; -with System.SPARK.Cut_Operations; use System.SPARK.Cut_Operations; package body System.Arith_Double with SPARK_Mode is - -- Contracts, ghost code, loop invariants and assertions in this unit are - -- meant for analysis only, not for run-time checking, as it would be too - -- costly otherwise. This is enforced by setting the assertion policy to - -- Ignore. - - pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore, - Assert_And_Cut => Ignore); - pragma Suppress (Overflow_Check); pragma Suppress (Range_Check); - pragma Warnings - (Off, "statement has no effect", - Reason => "Ghost code on dead paths is used for verification only"); - function To_Uns is new Ada.Unchecked_Conversion (Double_Int, Double_Uns); function To_Int is new Ada.Unchecked_Conversion (Double_Uns, Double_Int); Double_Size : constant Natural := Double_Int'Size; Single_Size : constant Natural := Double_Int'Size / 2; - -- Log of Single_Size in base 2, so that Single_Size = 2 ** Log_Single_Size - Log_Single_Size : constant Natural := - (case Single_Size is - when 32 => 5, - when 64 => 6, - when 128 => 7, - when others => raise Program_Error) - with Ghost; - - -- Power-of-two constants - - pragma Warnings - (Off, "non-preelaborable call not allowed in preelaborated unit", - Reason => "Ghost code is not compiled"); - pragma Warnings - (Off, "non-static constant in preelaborated unit", - Reason => "Ghost code is not compiled"); - Big_0 : constant Big_Integer := - Big (Double_Uns'(0)) - with Ghost; - Big_2xxSingle : constant Big_Integer := - Big (Double_Int'(2 ** Single_Size)) - with Ghost; - Big_2xxDouble_Minus_1 : constant Big_Integer := - Big (Double_Uns'(2 ** (Double_Size - 1))) - with Ghost; - Big_2xxDouble : constant Big_Integer := - Big (Double_Uns'(2 ** Double_Size - 1)) + 1 - with Ghost; - pragma Warnings - (On, "non-preelaborable call not allowed in preelaborated unit"); - pragma Warnings (On, "non-static constant in preelaborated unit"); - pragma Annotate (Gnatcheck, Exempt_On, "Improper_Returns", "early returns for performance"); @@ -115,9 +61,7 @@ is -- Length doubling multiplication function "/" (A : Double_Uns; B : Single_Uns) return Double_Uns is - (A / Double_Uns (B)) - with - Pre => B /= 0; + (A / Double_Uns (B)); -- Length doubling division function "&" (Hi, Lo : Single_Uns) return Double_Uns is @@ -127,37 +71,15 @@ is function "abs" (X : Double_Int) return Double_Uns is (if X = Double_Int'First then Double_Uns'(2 ** (Double_Size - 1)) - else Double_Uns (Double_Int'(abs X))) - with Post => abs Big (X) = Big ("abs"'Result), - Annotate => (GNATprove, Hide_Info, "Expression_Function_Body"); + else Double_Uns (Double_Int'(abs X))); -- Convert absolute value of X to unsigned. Note that we can't just use -- the expression of the Else since it overflows for X = Double_Int'First. function "rem" (A : Double_Uns; B : Single_Uns) return Double_Uns is - (A rem Double_Uns (B)) - with - Pre => B /= 0; + (A rem Double_Uns (B)); -- Length doubling remainder - function Big_2xx (N : Natural) return Big_Positive is - (Big (Double_Uns'(2 ** N))) - with - Ghost, - Pre => N < Double_Size, - Post => Big_2xx'Result > 0; - -- 2**N as a big integer - - function Big3 (X1, X2, X3 : Single_Uns) return Big_Natural is - (Big_2xxSingle * Big_2xxSingle * Big (Double_Uns (X1)) - + Big_2xxSingle * Big (Double_Uns (X2)) - + Big (Double_Uns (X3))) - with - Ghost; - -- X1&X2&X3 as a big integer - - function Le3 (X1, X2, X3, Y1, Y2, Y3 : Single_Uns) return Boolean - with - Post => Le3'Result = (Big3 (X1, X2, X3) <= Big3 (Y1, Y2, Y3)); + function Le3 (X1, X2, X3, Y1, Y2, Y3 : Single_Uns) return Boolean; -- Determines if (3 * Single_Size)-bit value X1&X2&X3 <= Y1&Y2&Y3 function Lo (A : Double_Uns) return Single_Uns is @@ -168,654 +90,41 @@ is (Single_Uns (Shift_Right (A, Single_Size))); -- High order half of double value - procedure Sub3 (X1, X2, X3 : in out Single_Uns; Y1, Y2, Y3 : Single_Uns) - with - Pre => Big3 (X1, X2, X3) >= Big3 (Y1, Y2, Y3), - Post => Big3 (X1, X2, X3) = Big3 (X1, X2, X3)'Old - Big3 (Y1, Y2, Y3); + procedure Sub3 (X1, X2, X3 : in out Single_Uns; Y1, Y2, Y3 : Single_Uns); -- Computes X1&X2&X3 := X1&X2&X3 - Y1&Y1&Y3 mod 2 ** (3 * Single_Size) - function To_Neg_Int (A : Double_Uns) return Double_Int - with - Pre => In_Double_Int_Range (-Big (A)), - Post => Big (To_Neg_Int'Result) = -Big (A); + function To_Neg_Int (A : Double_Uns) return Double_Int; -- Convert to negative integer equivalent. If the input is in the range -- 0 .. 2 ** (Double_Size - 1), then the corresponding nonpositive signed -- integer (obtained by negating the given value) is returned, otherwise -- constraint error is raised. - function To_Pos_Int (A : Double_Uns) return Double_Int - with - Pre => In_Double_Int_Range (Big (A)), - Post => Big (To_Pos_Int'Result) = Big (A); + function To_Pos_Int (A : Double_Uns) return Double_Int; -- Convert to positive integer equivalent. If the input is in the range -- 0 .. 2 ** (Double_Size - 1) - 1, then the corresponding non-negative -- signed integer is returned, otherwise constraint error is raised. - procedure Raise_Error with - Exceptional_Cases => (Constraint_Error => True); - pragma No_Return (Raise_Error); + procedure Raise_Error with No_Return; -- Raise constraint error with appropriate message - ------------------ - -- Local Lemmas -- - ------------------ - - procedure Inline_Le3 (X1, X2, X3, Y1, Y2, Y3 : Single_Uns) - with - Ghost, - Pre => Le3 (X1, X2, X3, Y1, Y2, Y3), - Post => Big3 (X1, X2, X3) <= Big3 (Y1, Y2, Y3); - - procedure Lemma_Abs_Commutation (X : Double_Int) - with - Ghost, - Post => abs Big (X) = Big (Double_Uns'(abs X)); - - procedure Lemma_Abs_Div_Commutation (X, Y : Big_Integer) - with - Ghost, - Pre => Y /= 0, - Post => abs (X / Y) = abs X / abs Y; - - procedure Lemma_Abs_Mult_Commutation (X, Y : Big_Integer) - with - Ghost, - Post => abs (X * Y) = abs X * abs Y; - - procedure Lemma_Abs_Range (X : Big_Integer) - with - Ghost, - Pre => In_Double_Int_Range (X), - Post => abs X <= Big_2xxDouble_Minus_1 - and then In_Double_Int_Range (-abs X); - - procedure Lemma_Abs_Rem_Commutation (X, Y : Big_Integer) - with - Ghost, - Pre => Y /= 0, - Post => abs (X rem Y) = (abs X) rem (abs Y); - - procedure Lemma_Add_Commutation (X : Double_Uns; Y : Single_Uns) - with - Ghost, - Pre => X <= 2 ** Double_Size - 2 ** Single_Size, - Post => Big (X) + Big (Double_Uns (Y)) = Big (X + Double_Uns (Y)); - - procedure Lemma_Add_One (X : Double_Uns) - with - Ghost, - Pre => X /= Double_Uns'Last, - Post => Big (X + Double_Uns'(1)) = Big (X) + 1; - - procedure Lemma_Big_Of_Double_Uns (X : Double_Uns) - with - Ghost, - Post => Big (X) < Big_2xxDouble; - - procedure Lemma_Big_Of_Double_Uns_Of_Single_Uns (X : Single_Uns) - with - Ghost, - Post => Big (Double_Uns (X)) >= 0 - and then Big (Double_Uns (X)) < Big_2xxSingle; - - procedure Lemma_Bounded_Powers_Of_2_Increasing (M, N : Natural) - with - Ghost, - Pre => M < N and then N < Double_Size, - Post => Double_Uns'(2)**M < Double_Uns'(2)**N; - - procedure Lemma_Concat_Definition (X, Y : Single_Uns) - with - Ghost, - Post => Big (X & Y) = Big_2xxSingle * Big (Double_Uns (X)) - + Big (Double_Uns (Y)); - - procedure Lemma_Deep_Mult_Commutation - (Factor : Big_Integer; - X, Y : Single_Uns) - with - Ghost, - Post => - Factor * Big (Double_Uns (X)) * Big (Double_Uns (Y)) = - Factor * Big (Double_Uns (X) * Double_Uns (Y)); - - procedure Lemma_Div_Commutation (X, Y : Double_Uns) - with - Ghost, - Pre => Y /= 0, - Post => Big (X) / Big (Y) = Big (X / Y); - - procedure Lemma_Div_Definition - (A : Double_Uns; - B : Single_Uns; - Q : Double_Uns; - R : Double_Uns) - with - Ghost, - Pre => B /= 0 and then Q = A / B and then R = A rem B, - Post => Big (A) = Big (Double_Uns (B)) * Big (Q) + Big (R); - - procedure Lemma_Div_Ge (X, Y, Z : Big_Integer) - with - Ghost, - Pre => Z > 0 and then X >= Y * Z, - Post => X / Z >= Y; - - procedure Lemma_Div_Lt (X, Y, Z : Big_Natural) - with - Ghost, - Pre => Z > 0 and then X < Y * Z, - Post => X / Z < Y; - - procedure Lemma_Div_Eq (A, B, S, R : Big_Integer) - with - Ghost, - Pre => A * S = B * S + R and then S /= 0, - Post => A = B + R / S; - - procedure Lemma_Div_Mult (X : Big_Natural; Y : Big_Positive) - with - Ghost, - Post => X / Y * Y > X - Y; - - procedure Lemma_Double_Big_2xxSingle - with - Ghost, - Post => Big_2xxSingle * Big_2xxSingle = Big_2xxDouble; - - procedure Lemma_Double_Shift (X : Double_Uns; S, S1 : Double_Uns) - with - Ghost, - Pre => S <= Double_Uns (Double_Size) - and then S1 <= Double_Uns (Double_Size), - Post => Shift_Left (Shift_Left (X, Natural (S)), Natural (S1)) = - Shift_Left (X, Natural (S + S1)); - - procedure Lemma_Double_Shift (X : Single_Uns; S, S1 : Natural) - with - Ghost, - Pre => S <= Single_Size - S1, - Post => Shift_Left (Shift_Left (X, S), S1) = Shift_Left (X, S + S1); - - procedure Lemma_Double_Shift (X : Double_Uns; S, S1 : Natural) - with - Ghost, - Pre => S <= Double_Size - S1, - Post => Shift_Left (Shift_Left (X, S), S1) = Shift_Left (X, S + S1); - - procedure Lemma_Double_Shift_Left (X : Double_Uns; S, S1 : Double_Uns) - with - Ghost, - Pre => S <= Double_Uns (Double_Size) - and then S1 <= Double_Uns (Double_Size), - Post => Shift_Left (Shift_Left (X, Natural (S)), Natural (S1)) = - Shift_Left (X, Natural (S + S1)); - - procedure Lemma_Double_Shift_Left (X : Double_Uns; S, S1 : Natural) - with - Ghost, - Pre => S <= Double_Size - S1, - Post => Shift_Left (Shift_Left (X, S), S1) = Shift_Left (X, S + S1); - - procedure Lemma_Double_Shift_Right (X : Double_Uns; S, S1 : Double_Uns) - with - Ghost, - Pre => S <= Double_Uns (Double_Size) - and then S1 <= Double_Uns (Double_Size), - Post => Shift_Right (Shift_Right (X, Natural (S)), Natural (S1)) = - Shift_Right (X, Natural (S + S1)); - - procedure Lemma_Double_Shift_Right (X : Double_Uns; S, S1 : Natural) - with - Ghost, - Pre => S <= Double_Size - S1, - Post => Shift_Right (Shift_Right (X, S), S1) = Shift_Right (X, S + S1); - - procedure Lemma_Ge_Commutation (A, B : Double_Uns) - with - Ghost, - Pre => A >= B, - Post => Big (A) >= Big (B); - - procedure Lemma_Ge_Mult (A, B, C, D : Big_Integer) - with - Ghost, - Pre => A >= B and then B * C >= D and then C > 0, - Post => A * C >= D; - - procedure Lemma_Gt_Commutation (A, B : Double_Uns) - with - Ghost, - Pre => A > B, - Post => Big (A) > Big (B); - - procedure Lemma_Gt_Mult (A, B, C, D : Big_Integer) - with - Ghost, - Pre => A >= B and then B * C > D and then C > 0, - Post => A * C > D; - - procedure Lemma_Hi_Lo (Xu : Double_Uns; Xhi, Xlo : Single_Uns) - with - Ghost, - Pre => Xhi = Hi (Xu) and Xlo = Lo (Xu), - Post => Big (Xu) = - Big_2xxSingle * Big (Double_Uns (Xhi)) + Big (Double_Uns (Xlo)); - - procedure Lemma_Hi_Lo_3 (Xu : Double_Uns; Xhi, Xlo : Single_Uns) - with - Ghost, - Pre => Xhi = Hi (Xu) and then Xlo = Lo (Xu), - Post => Big (Xu) = Big3 (0, Xhi, Xlo); - - procedure Lemma_Lo_Is_Ident (X : Double_Uns) - with - Ghost, - Pre => Big (X) < Big_2xxSingle, - Post => Double_Uns (Lo (X)) = X; - - procedure Lemma_Lt_Commutation (A, B : Double_Uns) - with - Ghost, - Pre => A < B, - Post => Big (A) < Big (B); - - procedure Lemma_Lt_Mult (A, B, C, D : Big_Integer) - with - Ghost, - Pre => A < B and then B * C <= D and then C > 0, - Post => A * C < D; - - procedure Lemma_Mult_Commutation (X, Y : Single_Uns) - with - Ghost, - Post => - Big (Double_Uns (X)) * Big (Double_Uns (Y)) = - Big (Double_Uns (X) * Double_Uns (Y)); - - procedure Lemma_Mult_Commutation (X, Y : Double_Int) - with - Ghost, - Pre => In_Double_Int_Range (Big (X) * Big (Y)), - Post => Big (X) * Big (Y) = Big (X * Y); - - procedure Lemma_Mult_Commutation (X, Y, Z : Double_Uns) - with - Ghost, - Pre => Big (X) * Big (Y) < Big_2xxDouble and then Z = X * Y, - Post => Big (X) * Big (Y) = Big (Z); - - procedure Lemma_Mult_Decomposition - (Mult : Big_Integer; - Xu, Yu : Double_Uns; - Xhi, Xlo, Yhi, Ylo : Single_Uns) - with - Ghost, - Pre => Mult = Big (Xu) * Big (Yu) - and then Xhi = Hi (Xu) - and then Xlo = Lo (Xu) - and then Yhi = Hi (Yu) - and then Ylo = Lo (Yu), - Post => Mult = - Big_2xxSingle * Big_2xxSingle * (Big (Double_Uns'(Xhi * Yhi))) - + Big_2xxSingle * (Big (Double_Uns'(Xhi * Ylo))) - + Big_2xxSingle * (Big (Double_Uns'(Xlo * Yhi))) - + (Big (Double_Uns'(Xlo * Ylo))); - - procedure Lemma_Mult_Distribution (X, Y, Z : Big_Integer) - with - Ghost, - Post => X * (Y + Z) = X * Y + X * Z; - - procedure Lemma_Mult_Div (A, B : Big_Integer) - with - Ghost, - Pre => B /= 0, - Post => A * B / B = A; - - procedure Lemma_Mult_Non_Negative (X, Y : Big_Integer) - with - Ghost, - Pre => (X >= 0 and then Y >= 0) - or else (X <= 0 and then Y <= 0), - Post => X * Y >= 0; - - procedure Lemma_Mult_Non_Positive (X, Y : Big_Integer) - with - Ghost, - Pre => (X <= Big_0 and then Y >= Big_0) - or else (X >= Big_0 and then Y <= Big_0), - Post => X * Y <= Big_0; - - procedure Lemma_Mult_Positive (X, Y : Big_Integer) - with - Ghost, - Pre => (X > Big_0 and then Y > Big_0) - or else (X < Big_0 and then Y < Big_0), - Post => X * Y > Big_0; - - procedure Lemma_Neg_Div (X, Y : Big_Integer) - with - Ghost, - Pre => Y /= 0, - Post => X / Y = (-X) / (-Y); - - procedure Lemma_Neg_Rem (X, Y : Big_Integer) - with - Ghost, - Pre => Y /= 0, - Post => X rem Y = X rem (-Y); - - procedure Lemma_Not_In_Range_Big2xx64 - with - Post => not In_Double_Int_Range (Big_2xxDouble) - and then not In_Double_Int_Range (-Big_2xxDouble); - - procedure Lemma_Powers (A : Big_Natural; B, C : Natural) - with - Ghost, - Pre => B <= Natural'Last - C, - Post => A**B * A**C = A**(B + C); - - procedure Lemma_Powers_Of_2 (M, N : Natural) - with - Ghost, - Pre => M < Double_Size - and then N < Double_Size - and then M + N <= Double_Size, - Post => - Big_2xx (M) * Big_2xx (N) = - (if M + N = Double_Size then Big_2xxDouble else Big_2xx (M + N)); - - procedure Lemma_Powers_Of_2_Commutation (M : Natural) - with - Ghost, - Subprogram_Variant => (Decreases => M), - Pre => M <= Double_Size, - Post => Big (Double_Uns'(2))**M = - (if M < Double_Size then Big_2xx (M) else Big_2xxDouble); - - procedure Lemma_Powers_Of_2_Increasing (M, N : Natural) - with - Ghost, - Subprogram_Variant => (Increases => M), - Pre => M < N, - Post => Big (Double_Uns'(2))**M < Big (Double_Uns'(2))**N; - - procedure Lemma_Rem_Abs (X, Y : Big_Integer) - with - Ghost, - Pre => Y /= 0, - Post => X rem Y = X rem (abs Y); - pragma Unreferenced (Lemma_Rem_Abs); - - procedure Lemma_Rem_Commutation (X, Y : Double_Uns) - with - Ghost, - Pre => Y /= 0, - Post => Big (X) rem Big (Y) = Big (X rem Y); - - procedure Lemma_Rem_Is_Ident (X, Y : Big_Integer) - with - Ghost, - Pre => abs X < abs Y, - Post => X rem Y = X; - pragma Unreferenced (Lemma_Rem_Is_Ident); - - procedure Lemma_Rem_Sign (X, Y : Big_Integer) - with - Ghost, - Pre => Y /= 0, - Post => Same_Sign (X rem Y, X); - pragma Unreferenced (Lemma_Rem_Sign); - - procedure Lemma_Rev_Div_Definition (A, B, Q, R : Big_Natural) - with - Ghost, - Pre => A = B * Q + R and then R < B, - Post => Q = A / B and then R = A rem B; - - procedure Lemma_Shift_Left (X : Double_Uns; Shift : Natural) - with - Ghost, - Pre => Shift < Double_Size - and then Big (X) * Big_2xx (Shift) < Big_2xxDouble, - Post => Big (Shift_Left (X, Shift)) = Big (X) * Big_2xx (Shift); - - procedure Lemma_Shift_Right (X : Double_Uns; Shift : Natural) - with - Ghost, - Pre => Shift < Double_Size, - Post => Big (Shift_Right (X, Shift)) = Big (X) / Big_2xx (Shift); - - procedure Lemma_Shift_Without_Drop - (X, Y : Double_Uns; - Mask : Single_Uns; - Shift : Natural) - with - Ghost, - Pre => (Hi (X) and Mask) = 0 -- X has the first Shift bits off - and then Shift <= Single_Size - and then Mask = Shift_Left (Single_Uns'Last, Single_Size - Shift) - and then Y = Shift_Left (X, Shift), - Post => Big (Y) = Big_2xx (Shift) * Big (X); - - procedure Lemma_Simplify (X, Y : Big_Integer) - with - Ghost, - Pre => Y /= 0, - Post => X * Y / Y = X; - - procedure Lemma_Substitution (A, B, C, C1, D : Big_Integer) - with - Ghost, - Pre => C = C1 and then A = B * C + D, - Post => A = B * C1 + D; - - procedure Lemma_Subtract_Commutation (X, Y : Double_Uns) - with - Ghost, - Pre => X >= Y, - Post => Big (X) - Big (Y) = Big (X - Y); - - procedure Lemma_Subtract_Double_Uns (X, Y : Double_Int) - with - Ghost, - Pre => X >= 0 and then X <= Y, - Post => Double_Uns (Y - X) = Double_Uns (Y) - Double_Uns (X); - - procedure Lemma_Word_Commutation (X : Single_Uns) - with - Ghost, - Post => Big_2xxSingle * Big (Double_Uns (X)) - = Big (2**Single_Size * Double_Uns (X)); - - ----------------------------- - -- Local lemma null bodies -- - ----------------------------- - - procedure Inline_Le3 (X1, X2, X3, Y1, Y2, Y3 : Single_Uns) is null; - procedure Lemma_Abs_Commutation (X : Double_Int) is null; - procedure Lemma_Abs_Mult_Commutation (X, Y : Big_Integer) is null; - procedure Lemma_Abs_Range (X : Big_Integer) is null; - procedure Lemma_Add_Commutation (X : Double_Uns; Y : Single_Uns) is null; - procedure Lemma_Add_One (X : Double_Uns) is null; - procedure Lemma_Big_Of_Double_Uns (X : Double_Uns) is null; - procedure Lemma_Big_Of_Double_Uns_Of_Single_Uns (X : Single_Uns) is null; - procedure Lemma_Bounded_Powers_Of_2_Increasing (M, N : Natural) is null; - procedure Lemma_Deep_Mult_Commutation - (Factor : Big_Integer; - X, Y : Single_Uns) - is null; - procedure Lemma_Div_Commutation (X, Y : Double_Uns) is null; - procedure Lemma_Div_Definition - (A : Double_Uns; - B : Single_Uns; - Q : Double_Uns; - R : Double_Uns) - is null; - procedure Lemma_Div_Ge (X, Y, Z : Big_Integer) is null; - procedure Lemma_Div_Lt (X, Y, Z : Big_Natural) is null; - procedure Lemma_Div_Mult (X : Big_Natural; Y : Big_Positive) is null; - procedure Lemma_Double_Big_2xxSingle is null; - procedure Lemma_Double_Shift (X : Double_Uns; S, S1 : Double_Uns) is null; - procedure Lemma_Double_Shift (X : Single_Uns; S, S1 : Natural) is null; - procedure Lemma_Double_Shift_Left (X : Double_Uns; S, S1 : Double_Uns) - is null; - procedure Lemma_Double_Shift_Right (X : Double_Uns; S, S1 : Double_Uns) - is null; - procedure Lemma_Ge_Commutation (A, B : Double_Uns) is null; - procedure Lemma_Ge_Mult (A, B, C, D : Big_Integer) is null; - procedure Lemma_Gt_Commutation (A, B : Double_Uns) is null; - procedure Lemma_Gt_Mult (A, B, C, D : Big_Integer) is null; - procedure Lemma_Lo_Is_Ident (X : Double_Uns) is null; - procedure Lemma_Lt_Commutation (A, B : Double_Uns) is null; - procedure Lemma_Lt_Mult (A, B, C, D : Big_Integer) is null; - procedure Lemma_Mult_Commutation (X, Y : Single_Uns) is null; - procedure Lemma_Mult_Commutation (X, Y : Double_Int) is null; - procedure Lemma_Mult_Commutation (X, Y, Z : Double_Uns) is null; - procedure Lemma_Mult_Distribution (X, Y, Z : Big_Integer) is null; - procedure Lemma_Mult_Non_Negative (X, Y : Big_Integer) is null; - procedure Lemma_Mult_Non_Positive (X, Y : Big_Integer) is null; - procedure Lemma_Mult_Positive (X, Y : Big_Integer) is null; - procedure Lemma_Neg_Rem (X, Y : Big_Integer) is null; - procedure Lemma_Not_In_Range_Big2xx64 is null; - procedure Lemma_Powers (A : Big_Natural; B, C : Natural) is null; - procedure Lemma_Rem_Commutation (X, Y : Double_Uns) is null; - procedure Lemma_Rem_Is_Ident (X, Y : Big_Integer) is null; - procedure Lemma_Rem_Sign (X, Y : Big_Integer) is null; - procedure Lemma_Rev_Div_Definition (A, B, Q, R : Big_Natural) is null; - procedure Lemma_Simplify (X, Y : Big_Integer) is null; - procedure Lemma_Substitution (A, B, C, C1, D : Big_Integer) is null; - procedure Lemma_Subtract_Commutation (X, Y : Double_Uns) is null; - procedure Lemma_Subtract_Double_Uns (X, Y : Double_Int) is null; - procedure Lemma_Word_Commutation (X : Single_Uns) is null; - -------------------------- -- Add_With_Ovflo_Check -- -------------------------- function Add_With_Ovflo_Check (X, Y : Double_Int) return Double_Int is R : constant Double_Int := To_Int (To_Uns (X) + To_Uns (Y)); - - -- Local lemmas - - procedure Prove_Negative_X - with - Ghost, - Pre => X < 0 and then (Y > 0 or else R < 0), - Post => R = X + Y; - - procedure Prove_Non_Negative_X - with - Ghost, - Pre => X >= 0 and then (Y < 0 or else R >= 0), - Post => R = X + Y; - - procedure Prove_Overflow_Case - with - Ghost, - Pre => - (if X >= 0 then Y >= 0 and then R < 0 - else Y <= 0 and then R >= 0), - Post => not In_Double_Int_Range (Big (X) + Big (Y)); - - ---------------------- - -- Prove_Negative_X -- - ---------------------- - - procedure Prove_Negative_X is - begin - if X = Double_Int'First then - if Y > 0 then - null; - else - pragma Assert - (To_Uns (X) + To_Uns (Y) = - 2 ** (Double_Size - 1) - Double_Uns (-Y)); - pragma Assert -- as R < 0 - (To_Uns (X) + To_Uns (Y) >= 2 ** (Double_Size - 1)); - pragma Assert (Y = 0); - end if; - - elsif Y = Double_Int'First then - pragma Assert - (To_Uns (X) + To_Uns (Y) = - 2 ** (Double_Size - 1) - Double_Uns (-X)); - pragma Assert (False); - - elsif Y <= 0 then - pragma Assert - (To_Uns (X) + To_Uns (Y) = -Double_Uns (-X) - Double_Uns (-Y)); - - else -- Y > 0, 0 > X > Double_Int'First - declare - Ru : constant Double_Uns := To_Uns (X) + To_Uns (Y); - begin - pragma Assert (Ru = -Double_Uns (-X) + Double_Uns (Y)); - if Ru < 2 ** (Double_Size - 1) then -- R >= 0 - Lemma_Subtract_Double_Uns (-X, Y); - pragma Assert (Ru = Double_Uns (X + Y)); - - elsif Ru = 2 ** (Double_Size - 1) then - pragma Assert (Double_Uns (Y) < 2 ** (Double_Size - 1)); - pragma Assert (Double_Uns (-X) < 2 ** (Double_Size - 1)); - pragma Assert (False); - - else - pragma Assert - (R = -Double_Int (-(-Double_Uns (-X) + Double_Uns (Y)))); - pragma Assert - (R = -Double_Int (-Double_Uns (Y) + Double_Uns (-X))); - end if; - end; - end if; - end Prove_Negative_X; - - -------------------------- - -- Prove_Non_Negative_X -- - -------------------------- - - procedure Prove_Non_Negative_X is - begin - if Y >= 0 or else Y = Double_Int'First then - null; - else - pragma Assert - (To_Uns (X) + To_Uns (Y) = Double_Uns (X) - Double_Uns (-Y)); - end if; - end Prove_Non_Negative_X; - - ------------------------- - -- Prove_Overflow_Case -- - ------------------------- - - procedure Prove_Overflow_Case is - begin - if X < 0 and then X /= Double_Int'First and then Y /= Double_Int'First - then - pragma Assert - (To_Uns (X) + To_Uns (Y) = -Double_Uns (-X) - Double_Uns (-Y)); - end if; - end Prove_Overflow_Case; - - -- Start of processing for Add_With_Ovflo_Check - begin if X >= 0 then if Y < 0 or else R >= 0 then - Prove_Non_Negative_X; return R; end if; else -- X < 0 if Y > 0 or else R < 0 then - Prove_Negative_X; return R; end if; end if; - Prove_Overflow_Case; Raise_Error; end Add_With_Ovflo_Check; @@ -823,8 +132,6 @@ is -- Double_Divide -- ------------------- - pragma Annotate (Gnatcheck, Exempt_On, "Metrics_Cyclomatic_Complexity", - "limit exceeded due to proof code"); procedure Double_Divide (X, Y, Z : Double_Int; Q, R : out Double_Int; @@ -844,183 +151,11 @@ is Du, Qu, Ru : Double_Uns; Den_Pos : constant Boolean := (Y < 0) = (Z < 0); - -- Local ghost variables - - Mult : constant Big_Integer := abs (Big (Y) * Big (Z)) with Ghost; - Quot : Big_Integer with Ghost; - Big_R : Big_Integer with Ghost; - Big_Q : Big_Integer with Ghost; - - -- Local lemmas - - procedure Prove_Overflow_Case - with - Ghost, - Pre => X = Double_Int'First and then Big (Y) * Big (Z) = -1, - Post => not In_Double_Int_Range (Big (X) / (Big (Y) * Big (Z))) - and then not In_Double_Int_Range - (Round_Quotient (Big (X), Big (Y) * Big (Z), - Big (X) / (Big (Y) * Big (Z)), - Big (X) rem (Big (Y) * Big (Z)))); - -- Proves the special case where -2**(Double_Size - 1) is divided by -1, - -- generating an overflow. - - procedure Prove_Quotient_Zero - with - Ghost, - Pre => Mult >= Big_2xxDouble - and then - not (Mult = Big_2xxDouble - and then X = Double_Int'First - and then Round) - and then Q = 0 - and then R = X, - Post => Big (R) = Big (X) rem (Big (Y) * Big (Z)) - and then - (if Round then - Big (Q) = Round_Quotient (Big (X), Big (Y) * Big (Z), - Big (X) / (Big (Y) * Big (Z)), - Big (R)) - else Big (Q) = Big (X) / (Big (Y) * Big (Z))); - -- Proves the general case where divisor doesn't fit in Double_Uns and - -- quotient is 0. - - procedure Prove_Round_To_One - with - Ghost, - Pre => Mult = Big_2xxDouble - and then X = Double_Int'First - and then Q = (if Den_Pos then -1 else 1) - and then R = X - and then Round, - Post => Big (R) = Big (X) rem (Big (Y) * Big (Z)) - and then Big (Q) = Round_Quotient (Big (X), Big (Y) * Big (Z), - Big (X) / (Big (Y) * Big (Z)), - Big (R)); - -- Proves the special case where the divisor doesn't fit in Double_Uns - -- but quotient is still 1 or -1 due to rounding - -- (abs (Y*Z) = 2**Double_Size and X = -2**(Double_Size - 1) and Round). - - procedure Prove_Rounding_Case - with - Ghost, - Pre => Mult /= 0 - and then Quot = Big (X) / (Big (Y) * Big (Z)) - and then Big_R = Big (X) rem (Big (Y) * Big (Z)) - and then Big_Q = - Round_Quotient (Big (X), Big (Y) * Big (Z), Quot, Big_R) - and then Big (Ru) = abs Big_R - and then Big (Du) = Mult - and then Big (Qu) = - (if Ru > (Du - Double_Uns'(1)) / Double_Uns'(2) - then abs Quot + 1 - else abs Quot), - Post => abs Big_Q = Big (Qu); - -- Proves correctness of the rounding of the unsigned quotient - - procedure Prove_Sign_Quotient - with - Ghost, - Pre => Mult /= 0 - and then Quot = Big (X) / (Big (Y) * Big (Z)) - and then Big_R = Big (X) rem (Big (Y) * Big (Z)) - and then Big_Q = - (if Round then - Round_Quotient (Big (X), Big (Y) * Big (Z), Quot, Big_R) - else Quot), - Post => - (if X >= 0 then - (if Den_Pos then Big_Q >= 0 else Big_Q <= 0) - else - (if Den_Pos then Big_Q <= 0 else Big_Q >= 0)); - -- Proves the correct sign of the signed quotient Big_Q - - procedure Prove_Signs - with - Ghost, - Pre => Mult /= 0 - and then Quot = Big (X) / (Big (Y) * Big (Z)) - and then Big_R = Big (X) rem (Big (Y) * Big (Z)) - and then Big_Q = - (if Round then - Round_Quotient (Big (X), Big (Y) * Big (Z), Quot, Big_R) - else Quot) - and then Big (Ru) = abs Big_R - and then Big (Qu) = abs Big_Q - and then R = (if X >= 0 then To_Int (Ru) else To_Int (-Ru)) - and then - Q = (if (X >= 0) = Den_Pos then To_Int (Qu) else To_Int (-Qu)) - and then not (X = Double_Int'First and then Big (Y) * Big (Z) = -1), - Post => Big (R) = Big (X) rem (Big (Y) * Big (Z)) - and then - (if Round then - Big (Q) = Round_Quotient (Big (X), Big (Y) * Big (Z), - Big (X) / (Big (Y) * Big (Z)), - Big (R)) - else Big (Q) = Big (X) / (Big (Y) * Big (Z))); - -- Proves final signs match the intended result after the unsigned - -- division is done. - - ----------------------------- - -- Local lemma null bodies -- - ----------------------------- - - procedure Prove_Overflow_Case is null; - procedure Prove_Quotient_Zero is null; - procedure Prove_Round_To_One is null; - procedure Prove_Sign_Quotient is null; - - ------------------------- - -- Prove_Rounding_Case -- - ------------------------- - - procedure Prove_Rounding_Case is - begin - if Same_Sign (Big (X), Big (Y) * Big (Z)) then - pragma Assert (abs Big_Q = Big (Qu)); - end if; - end Prove_Rounding_Case; - - ----------------- - -- Prove_Signs -- - ----------------- - - procedure Prove_Signs is - begin - if (X >= 0) = Den_Pos then - pragma Assert (Quot >= 0); - pragma Assert (Big_Q >= 0); - pragma Assert (Q >= 0); - pragma Assert (Big (Q) = Big_Q); - else - pragma Assert ((X >= 0) /= (Big (Y) * Big (Z) >= 0)); - pragma Assert (Quot <= 0); - pragma Assert (Big_Q <= 0); - pragma Assert (if X >= 0 then R >= 0); - pragma Assert (if X < 0 then R <= 0); - pragma Assert (Big (R) = Big_R); - end if; - end Prove_Signs; - - -- Start of processing for Double_Divide - begin if Yu = 0 or else Zu = 0 then Raise_Error; end if; - pragma Assert (Mult /= 0); - pragma Assert (Den_Pos = (Big (Y) * Big (Z) > 0)); - Quot := Big (X) / (Big (Y) * Big (Z)); - Big_R := Big (X) rem (Big (Y) * Big (Z)); - if Round then - Big_Q := Round_Quotient (Big (X), Big (Y) * Big (Z), Quot, Big_R); - else - Big_Q := Quot; - end if; - Lemma_Abs_Mult_Commutation (Big (Y), Big (Z)); - Lemma_Mult_Decomposition (Mult, Yu, Zu, Yhi, Ylo, Zhi, Zlo); - -- Compute Y * Z. Note that if the result overflows Double_Uns, then -- the rounded result is zero, except for the very special case where -- X = -2 ** (Double_Size - 1) and abs (Y * Z) = 2 ** Double_Size, when @@ -1040,66 +175,21 @@ is and then Round then Q := (if Den_Pos then -1 else 1); - - Prove_Round_To_One; - else Q := 0; - - pragma Assert (Double_Uns'(Yhi * Zhi) >= Double_Uns (Yhi)); - pragma Assert (Double_Uns'(Yhi * Zhi) >= Double_Uns (Zhi)); - pragma Assert (Big (Double_Uns'(Yhi * Zhi)) >= 1); - if Yhi > 1 or else Zhi > 1 then - pragma Assert (Big (Double_Uns'(Yhi * Zhi)) > 1); - pragma Assert (if X = Double_Int'First and then Round then - Mult > Big_2xxDouble); - elsif Zlo > 0 then - pragma Assert (Big (Double_Uns'(Yhi * Zlo)) > 0); - pragma Assert (if X = Double_Int'First and then Round then - Mult > Big_2xxDouble); - elsif Ylo > 0 then - pragma Assert (Double_Uns'(Ylo * Zhi) > 0); - pragma Assert (Big (Double_Uns'(Ylo * Zhi)) > 0); - pragma Assert (if X = Double_Int'First and then Round then - Mult > Big_2xxDouble); - else - pragma Assert (not (X = Double_Int'First and then Round)); - end if; - Prove_Quotient_Zero; end if; return; else T2 := Yhi * Zlo; - pragma Assert (Big (T2) = Big (Double_Uns'(Yhi * Zlo))); - pragma Assert (Big_0 = Big (Double_Uns'(Ylo * Zhi))); end if; - else T2 := Ylo * Zhi; - pragma Assert (Big (T2) = Big (Double_Uns'(Ylo * Zhi))); - pragma Assert (Big_0 = Big (Double_Uns'(Yhi * Zlo))); end if; T1 := Ylo * Zlo; - - Lemma_Mult_Distribution (Big_2xxSingle, - Big (Double_Uns'(Yhi * Zlo)), - Big (Double_Uns'(Ylo * Zhi))); - Lemma_Hi_Lo (T1, Hi (T1), Lo (T1)); - Lemma_Mult_Distribution (Big_2xxSingle, - Big (T2), - Big (Double_Uns (Hi (T1)))); - Lemma_Add_Commutation (T2, Hi (T1)); - T2 := T2 + Hi (T1); - Lemma_Hi_Lo (T2, Hi (T2), Lo (T2)); - Lemma_Mult_Distribution (Big_2xxSingle, - Big (Double_Uns (Hi (T2))), - Big (Double_Uns (Lo (T2)))); - Lemma_Double_Big_2xxSingle; - if Hi (T2) /= 0 then R := X; @@ -1112,41 +202,8 @@ is and then Round then Q := (if Den_Pos then -1 else 1); - - Prove_Round_To_One; - else Q := 0; - - pragma Assert (Big (Double_Uns (Hi (T2))) >= 1); - pragma Assert (Big (Double_Uns (Lo (T2))) >= 0); - pragma Assert (Big (Double_Uns (Lo (T1))) >= 0); - pragma Assert (Big_2xxSingle * Big (Double_Uns (Lo (T2))) - + Big (Double_Uns (Lo (T1))) >= 0); - pragma Assert (Mult >= Big_2xxDouble * Big (Double_Uns (Hi (T2)))); - pragma Assert (Mult >= Big_2xxDouble); - if Hi (T2) > 1 then - pragma Assert (Big (Double_Uns (Hi (T2))) > 1); - pragma Assert (if X = Double_Int'First and then Round then - Mult > Big_2xxDouble); - elsif Lo (T2) > 0 then - pragma Assert (Big (Double_Uns (Lo (T2))) > 0); - pragma Assert (Big_2xxSingle > 0); - pragma Assert (Big_2xxSingle * Big (Double_Uns (Lo (T2))) > 0); - pragma Assert (Big_2xxSingle * Big (Double_Uns (Lo (T2))) - + Big (Double_Uns (Lo (T1))) > 0); - pragma Assert (if X = Double_Int'First and then Round then - Mult > Big_2xxDouble); - elsif Lo (T1) > 0 then - pragma Assert (Double_Uns (Lo (T1)) > 0); - Lemma_Gt_Commutation (Double_Uns (Lo (T1)), 0); - pragma Assert (Big (Double_Uns (Lo (T1))) > 0); - pragma Assert (if X = Double_Int'First and then Round then - Mult > Big_2xxDouble); - else - pragma Assert (not (X = Double_Int'First and then Round)); - end if; - Prove_Quotient_Zero; end if; return; @@ -1154,22 +211,9 @@ is Du := Lo (T2) & Lo (T1); - Lemma_Hi_Lo (Du, Lo (T2), Lo (T1)); - pragma Assert (Mult = Big (Du)); - pragma Assert (Du /= 0); - -- Multiplication of 2-limb arguments Yu and Zu leads to 4-limb result - -- (where each limb is a single value). Cases where 4 limbs are needed - -- require Yhi /= 0 and Zhi /= 0 and lead to early exit. Remaining cases - -- where 3 limbs are needed correspond to Hi(T2) /= 0 and lead to early - -- exit. Thus, at this point, the result fits in 2 limbs which are - -- exactly Lo (T2) and Lo (T1), which corresponds to the value of Du. - -- As the case where one of Yu or Zu is null also led to early exit, - -- we have Du /= 0 here. - -- Check overflow case of largest negative number divided by -1 if X = Double_Int'First and then Du = 1 and then not Den_Pos then - Prove_Overflow_Case; Raise_Error; end if; @@ -1188,29 +232,14 @@ is Qu := Xu / Du; Ru := Xu rem Du; - Lemma_Div_Commutation (Xu, Du); - Lemma_Abs_Div_Commutation (Big (X), Big (Y) * Big (Z)); - Lemma_Abs_Commutation (X); - pragma Assert (abs Quot = Big (Qu)); - Lemma_Rem_Commutation (Xu, Du); - Lemma_Abs_Rem_Commutation (Big (X), Big (Y) * Big (Z)); - pragma Assert (abs Big_R = Big (Ru)); - -- Deal with rounding case if Round then if Ru > (Du - Double_Uns'(1)) / Double_Uns'(2) then - Lemma_Add_Commutation (Qu, 1); - Qu := Qu + Double_Uns'(1); end if; - - Prove_Rounding_Case; end if; - pragma Assert (abs Big_Q = Big (Qu)); - Prove_Sign_Quotient; - -- Set final signs (RM 4.5.5(27-30)) -- Case of dividend (X) sign positive @@ -1229,10 +258,7 @@ is R := To_Int (-Ru); Q := (if Den_Pos then To_Int (-Qu) else To_Int (Qu)); end if; - - Prove_Signs; end Double_Divide; - pragma Annotate (Gnatcheck, Exempt_Off, "Metrics_Cyclomatic_Complexity"); --------- -- Le3 -- @@ -1253,418 +279,6 @@ is end if; end Le3; - ------------------------------- - -- Lemma_Abs_Div_Commutation -- - ------------------------------- - - procedure Lemma_Abs_Div_Commutation (X, Y : Big_Integer) is - begin - if Y < 0 then - if X < 0 then - pragma Assert (abs (X / Y) = abs (X / (-Y))); - else - Lemma_Neg_Div (X, Y); - pragma Assert (abs (X / Y) = abs ((-X) / (-Y))); - end if; - end if; - end Lemma_Abs_Div_Commutation; - - ------------------------------- - -- Lemma_Abs_Rem_Commutation -- - ------------------------------- - - procedure Lemma_Abs_Rem_Commutation (X, Y : Big_Integer) is - begin - if Y < 0 then - Lemma_Neg_Rem (X, Y); - if X < 0 then - pragma Assert (X rem Y = -((-X) rem (-Y))); - pragma Assert (abs (X rem Y) = (abs X) rem (abs Y)); - else - pragma Assert (abs (X rem Y) = (abs X) rem (abs Y)); - end if; - end if; - end Lemma_Abs_Rem_Commutation; - - ----------------------------- - -- Lemma_Concat_Definition -- - ----------------------------- - - procedure Lemma_Concat_Definition (X, Y : Single_Uns) is - Hi : constant Double_Uns := Shift_Left (Double_Uns (X), Single_Size); - Lo : constant Double_Uns := Double_Uns (Y); - begin - pragma Assert (Hi = Double_Uns'(2 ** Single_Size) * Double_Uns (X)); - pragma Assert ((Hi or Lo) = Hi + Lo); - end Lemma_Concat_Definition; - - ------------------ - -- Lemma_Div_Eq -- - ------------------ - - procedure Lemma_Div_Eq (A, B, S, R : Big_Integer) is - begin - pragma Assert ((A - B) * S = R); - pragma Assert ((A - B) * S / S = R / S); - Lemma_Mult_Div (A - B, S); - pragma Assert (A - B = R / S); - end Lemma_Div_Eq; - - ------------------------ - -- Lemma_Double_Shift -- - ------------------------ - - procedure Lemma_Double_Shift (X : Double_Uns; S, S1 : Natural) is - begin - Lemma_Double_Shift (X, Double_Uns (S), Double_Uns (S1)); - pragma Assert (Shift_Left (Shift_Left (X, S), S1) - = Shift_Left (Shift_Left (X, S), Natural (Double_Uns (S1)))); - pragma Assert (Shift_Left (X, S + S1) - = Shift_Left (X, Natural (Double_Uns (S + S1)))); - end Lemma_Double_Shift; - - ----------------------------- - -- Lemma_Double_Shift_Left -- - ----------------------------- - - procedure Lemma_Double_Shift_Left (X : Double_Uns; S, S1 : Natural) is - begin - Lemma_Double_Shift_Left (X, Double_Uns (S), Double_Uns (S1)); - pragma Assert (Shift_Left (Shift_Left (X, S), S1) - = Shift_Left (Shift_Left (X, S), Natural (Double_Uns (S1)))); - pragma Assert (Shift_Left (X, S + S1) - = Shift_Left (X, Natural (Double_Uns (S + S1)))); - end Lemma_Double_Shift_Left; - - ------------------------------ - -- Lemma_Double_Shift_Right -- - ------------------------------ - - procedure Lemma_Double_Shift_Right (X : Double_Uns; S, S1 : Natural) is - begin - Lemma_Double_Shift_Right (X, Double_Uns (S), Double_Uns (S1)); - pragma Assert (Shift_Right (Shift_Right (X, S), S1) - = Shift_Right (Shift_Right (X, S), Natural (Double_Uns (S1)))); - pragma Assert (Shift_Right (X, S + S1) - = Shift_Right (X, Natural (Double_Uns (S + S1)))); - end Lemma_Double_Shift_Right; - - ----------------- - -- Lemma_Hi_Lo -- - ----------------- - - procedure Lemma_Hi_Lo (Xu : Double_Uns; Xhi, Xlo : Single_Uns) is - begin - pragma Assert (Double_Uns (Xhi) = Xu / Double_Uns'(2 ** Single_Size)); - pragma Assert (Double_Uns (Xlo) = Xu mod 2 ** Single_Size); - end Lemma_Hi_Lo; - - ------------------- - -- Lemma_Hi_Lo_3 -- - ------------------- - - procedure Lemma_Hi_Lo_3 (Xu : Double_Uns; Xhi, Xlo : Single_Uns) is - begin - Lemma_Hi_Lo (Xu, Xhi, Xlo); - end Lemma_Hi_Lo_3; - - ------------------------------ - -- Lemma_Mult_Decomposition -- - ------------------------------ - - procedure Lemma_Mult_Decomposition - (Mult : Big_Integer; - Xu, Yu : Double_Uns; - Xhi, Xlo, Yhi, Ylo : Single_Uns) - is - begin - Lemma_Hi_Lo (Xu, Xhi, Xlo); - Lemma_Hi_Lo (Yu, Yhi, Ylo); - - pragma Assert - (Mult = - (Big_2xxSingle * Big (Double_Uns (Xhi)) + Big (Double_Uns (Xlo))) * - (Big_2xxSingle * Big (Double_Uns (Yhi)) + Big (Double_Uns (Ylo)))); - pragma Assert (Mult = - Big_2xxSingle - * Big_2xxSingle * Big (Double_Uns (Xhi)) * Big (Double_Uns (Yhi)) - + Big_2xxSingle * Big (Double_Uns (Xhi)) * Big (Double_Uns (Ylo)) - + Big_2xxSingle * Big (Double_Uns (Xlo)) * Big (Double_Uns (Yhi)) - + Big (Double_Uns (Xlo)) * Big (Double_Uns (Ylo))); - Lemma_Deep_Mult_Commutation (Big_2xxSingle * Big_2xxSingle, Xhi, Yhi); - Lemma_Deep_Mult_Commutation (Big_2xxSingle, Xhi, Ylo); - Lemma_Deep_Mult_Commutation (Big_2xxSingle, Xlo, Yhi); - Lemma_Mult_Commutation (Xlo, Ylo); - pragma Assert (Mult = - Big_2xxSingle * Big_2xxSingle * Big (Double_Uns'(Xhi * Yhi)) - + Big_2xxSingle * Big (Double_Uns'(Xhi * Ylo)) - + Big_2xxSingle * Big (Double_Uns'(Xlo * Yhi)) - + Big (Double_Uns'(Xlo * Ylo))); - end Lemma_Mult_Decomposition; - - -------------------- - -- Lemma_Mult_Div -- - -------------------- - - procedure Lemma_Mult_Div (A, B : Big_Integer) is - begin - if B > 0 then - pragma Assert (A * B / B = A); - else - pragma Assert (A * (-B) / (-B) = A); - end if; - end Lemma_Mult_Div; - - ------------------- - -- Lemma_Neg_Div -- - ------------------- - - procedure Lemma_Neg_Div (X, Y : Big_Integer) is - begin - pragma Assert ((-X) / (-Y) = -(X / (-Y))); - pragma Assert (X / (-Y) = -(X / Y)); - end Lemma_Neg_Div; - - ----------------------- - -- Lemma_Powers_Of_2 -- - ----------------------- - - procedure Lemma_Powers_Of_2 (M, N : Natural) is - begin - if M + N < Double_Size then - pragma Assert (Double_Uns'(2**M) * Double_Uns'(2**N) - = Double_Uns'(2**(M + N))); - end if; - - Lemma_Powers_Of_2_Commutation (M); - Lemma_Powers_Of_2_Commutation (N); - Lemma_Powers_Of_2_Commutation (M + N); - Lemma_Powers (Big (Double_Uns'(2)), M, N); - - if M + N < Double_Size then - pragma Assert (Big (Double_Uns'(2))**M * Big (Double_Uns'(2))**N - = Big (Double_Uns'(2))**(M + N)); - Lemma_Powers_Of_2_Increasing (M + N, Double_Size); - Lemma_Mult_Commutation (2 ** M, 2 ** N, 2 ** (M + N)); - else - pragma Assert (Big (Double_Uns'(2))**M * Big (Double_Uns'(2))**N - = Big (Double_Uns'(2))**(M + N)); - end if; - end Lemma_Powers_Of_2; - - ----------------------------------- - -- Lemma_Powers_Of_2_Commutation -- - ----------------------------------- - - procedure Lemma_Powers_Of_2_Commutation (M : Natural) is - begin - if M > 0 then - Lemma_Powers_Of_2_Commutation (M - 1); - pragma Assert (Big (Double_Uns'(2))**(M - 1) = Big_2xx (M - 1)); - pragma Assert (Big (Double_Uns'(2))**M = Big_2xx (M - 1) * 2); - if M < Double_Size then - Lemma_Powers_Of_2_Increasing (M - 1, Double_Size - 1); - Lemma_Bounded_Powers_Of_2_Increasing (M - 1, Double_Size - 1); - pragma Assert (Double_Uns'(2 ** (M - 1)) * 2 = Double_Uns'(2**M)); - Lemma_Mult_Commutation - (Double_Uns'(2 ** (M - 1)), 2, Double_Uns'(2**M)); - pragma Assert (Big (Double_Uns'(2))**M = Big_2xx (M)); - end if; - else - pragma Assert (Big (Double_Uns'(2))**M = Big_2xx (M)); - end if; - end Lemma_Powers_Of_2_Commutation; - - ---------------------------------- - -- Lemma_Powers_Of_2_Increasing -- - ---------------------------------- - - procedure Lemma_Powers_Of_2_Increasing (M, N : Natural) is - begin - if M + 1 < N then - Lemma_Powers_Of_2_Increasing (M + 1, N); - end if; - end Lemma_Powers_Of_2_Increasing; - - ------------------- - -- Lemma_Rem_Abs -- - ------------------- - - procedure Lemma_Rem_Abs (X, Y : Big_Integer) is - begin - Lemma_Neg_Rem (X, Y); - end Lemma_Rem_Abs; - - ---------------------- - -- Lemma_Shift_Left -- - ---------------------- - - procedure Lemma_Shift_Left (X : Double_Uns; Shift : Natural) is - - procedure Lemma_Mult_Pow2 (X : Double_Uns; I : Natural) - with - Ghost, - Pre => I < Double_Size - 1, - Post => X * Double_Uns'(2) ** I * Double_Uns'(2) - = X * Double_Uns'(2) ** (I + 1); - - procedure Lemma_Mult_Pow2 (X : Double_Uns; I : Natural) is - Mul1 : constant Double_Uns := Double_Uns'(2) ** I; - Mul2 : constant Double_Uns := Double_Uns'(2); - Left : constant Double_Uns := X * Mul1 * Mul2; - begin - pragma Assert (Left = X * (Mul1 * Mul2)); - pragma Assert (Mul1 * Mul2 = Double_Uns'(2) ** (I + 1)); - end Lemma_Mult_Pow2; - - XX : Double_Uns := X; - - begin - for J in 1 .. Shift loop - declare - Cur_XX : constant Double_Uns := XX; - begin - XX := Shift_Left (XX, 1); - pragma Assert (XX = Cur_XX * Double_Uns'(2)); - Lemma_Mult_Pow2 (X, J - 1); - end; - Lemma_Double_Shift_Left (X, J - 1, 1); - pragma Loop_Invariant (XX = Shift_Left (X, J)); - pragma Loop_Invariant (XX = X * Double_Uns'(2) ** J); - end loop; - end Lemma_Shift_Left; - - ----------------------- - -- Lemma_Shift_Right -- - ----------------------- - - procedure Lemma_Shift_Right (X : Double_Uns; Shift : Natural) is - - procedure Lemma_Div_Pow2 (X : Double_Uns; I : Natural) - with - Ghost, - Pre => I < Double_Size - 1, - Post => X / Double_Uns'(2) ** I / Double_Uns'(2) - = X / Double_Uns'(2) ** (I + 1); - - procedure Lemma_Quot_Rem (X, Div, Q, R : Double_Uns) - with - Ghost, - Pre => Div /= 0 - and then X = Q * Div + R - and then Q <= Double_Uns'Last / Div - and then R <= Double_Uns'Last - Q * Div - and then R < Div, - Post => Q = X / Div; - pragma Annotate (GNATprove, False_Positive, "postcondition might fail", - "Q is the quotient of X by Div"); - - procedure Lemma_Div_Pow2 (X : Double_Uns; I : Natural) is - - -- Local lemmas - - procedure Lemma_Mult_Le (X, Y, Z : Double_Uns) - with - Ghost, - Pre => X <= 1, - Post => X * Z <= Z; - - procedure Lemma_Mult_Le (X, Y, Z : Double_Uns) is null; - - -- Local variables - - Div1 : constant Double_Uns := Double_Uns'(2) ** I; - Div2 : constant Double_Uns := Double_Uns'(2); - Left : constant Double_Uns := X / Div1 / Div2; - R2 : constant Double_Uns := X / Div1 - Left * Div2; - pragma Assert (R2 <= Div2 - 1); - R1 : constant Double_Uns := X - X / Div1 * Div1; - pragma Assert (R1 < Div1); - - -- Start of processing for Lemma_Div_Pow2 - - begin - pragma Assert (X = Left * (Div1 * Div2) + R2 * Div1 + R1); - Lemma_Mult_Le (R2, Div2 - 1, Div1); - pragma Assert (R2 * Div1 + R1 < Div1 * Div2); - Lemma_Quot_Rem (X, Div1 * Div2, Left, R2 * Div1 + R1); - pragma Assert (Left = X / (Div1 * Div2)); - pragma Assert (Div1 * Div2 = Double_Uns'(2) ** (I + 1)); - end Lemma_Div_Pow2; - - procedure Lemma_Quot_Rem (X, Div, Q, R : Double_Uns) is null; - - XX : Double_Uns := X; - - begin - for J in 1 .. Shift loop - declare - Cur_XX : constant Double_Uns := XX; - begin - XX := Shift_Right (XX, 1); - pragma Assert (XX = Cur_XX / Double_Uns'(2)); - Lemma_Div_Pow2 (X, J - 1); - end; - Lemma_Double_Shift_Right (X, J - 1, 1); - pragma Loop_Invariant (XX = Shift_Right (X, J)); - pragma Loop_Invariant (XX = X / Double_Uns'(2) ** J); - end loop; - Lemma_Div_Commutation (X, Double_Uns'(2) ** Shift); - end Lemma_Shift_Right; - - ------------------------------ - -- Lemma_Shift_Without_Drop -- - ------------------------------ - - procedure Lemma_Shift_Without_Drop - (X, Y : Double_Uns; - Mask : Single_Uns; - Shift : Natural) - is - pragma Unreferenced (Mask); - - procedure Lemma_Bound - with - Pre => Shift <= Single_Size - and then X <= 2**Single_Size - * Double_Uns'(2**(Single_Size - Shift) - 1) - + Single_Uns'(2**Single_Size - 1), - Post => X <= 2**(Double_Size - Shift) - 1; - - procedure Lemma_Exp_Pos (N : Integer) - with - Pre => N in 0 .. Double_Size - 1, - Post => Double_Uns'(2**N) > 0; - - ----------------------------- - -- Local lemma null bodies -- - ----------------------------- - - procedure Lemma_Bound is null; - procedure Lemma_Exp_Pos (N : Integer) is null; - - -- Start of processing for Lemma_Shift_Without_Drop - - begin - if Shift = 0 then - pragma Assert (Big (Y) = Big_2xx (Shift) * Big (X)); - return; - end if; - - Lemma_Bound; - Lemma_Exp_Pos (Double_Size - Shift); - pragma Assert (X < 2**(Double_Size - Shift)); - pragma Assert (Big (X) < Big_2xx (Double_Size - Shift)); - pragma Assert (Y = 2**Shift * X); - Lemma_Lt_Mult (Big (X), Big_2xx (Double_Size - Shift), Big_2xx (Shift), - Big_2xx (Shift) * Big_2xx (Double_Size - Shift)); - pragma Assert (Big_2xx (Shift) * Big (X) - < Big_2xx (Shift) * Big_2xx (Double_Size - Shift)); - Lemma_Powers_Of_2 (Shift, Double_Size - Shift); - Lemma_Mult_Commutation (2**Shift, X, Y); - pragma Assert (Big (Y) = Big_2xx (Shift) * Big (X)); - end Lemma_Shift_Without_Drop; - ------------------------------- -- Multiply_With_Ovflo_Check -- ------------------------------- @@ -1680,160 +294,16 @@ is T1, T2 : Double_Uns; - -- Local ghost variables - - Mult : constant Big_Integer := abs (Big (X) * Big (Y)) with Ghost; - - -- Local lemmas - - procedure Prove_Both_Too_Large - with - Ghost, - Pre => Xhi /= 0 - and then Yhi /= 0 - and then Mult = - Big_2xxSingle * Big_2xxSingle * (Big (Double_Uns'(Xhi * Yhi))) - + Big_2xxSingle * (Big (Double_Uns'(Xhi * Ylo))) - + Big_2xxSingle * (Big (Double_Uns'(Xlo * Yhi))) - + (Big (Double_Uns'(Xlo * Ylo))), - Post => not In_Double_Int_Range (Big (X) * Big (Y)); - - procedure Prove_Final_Decomposition - with - Ghost, - Pre => In_Double_Int_Range (Big (X) * Big (Y)) - and then Mult = Big_2xxSingle * Big (T2) + Big (Double_Uns (Lo (T1))) - and then Hi (T2) = 0, - Post => Mult = Big (Lo (T2) & Lo (T1)); - - procedure Prove_Neg_Int - with - Ghost, - Pre => In_Double_Int_Range (Big (X) * Big (Y)) - and then Mult = Big (T2) - and then ((X >= 0 and then Y < 0) or else (X < 0 and then Y >= 0)), - Post => To_Neg_Int (T2) = X * Y; - - procedure Prove_Pos_Int - with - Ghost, - Pre => In_Double_Int_Range (Big (X) * Big (Y)) - and then Mult = Big (T2) - and then ((X >= 0 and then Y >= 0) or else (X < 0 and then Y < 0)), - Post => In_Double_Int_Range (Big (T2)) - and then To_Pos_Int (T2) = X * Y; - - procedure Prove_Result_Too_Large - with - Ghost, - Pre => Mult = Big_2xxSingle * Big (T2) + Big (Double_Uns (Lo (T1))) - and then Hi (T2) /= 0, - Post => not In_Double_Int_Range (Big (X) * Big (Y)); - - procedure Prove_Too_Large - with - Ghost, - Pre => abs (Big (X) * Big (Y)) >= Big_2xxDouble, - Post => not In_Double_Int_Range (Big (X) * Big (Y)); - - -------------------------- - -- Prove_Both_Too_Large -- - -------------------------- - - procedure Prove_Both_Too_Large is - begin - pragma Assert (Mult >= - Big_2xxSingle * Big_2xxSingle * Big (Double_Uns'(Xhi * Yhi))); - pragma Assert (Double_Uns (Xhi) * Double_Uns (Yhi) >= 1); - pragma Assert (Mult >= Big_2xxSingle * Big_2xxSingle); - Prove_Too_Large; - end Prove_Both_Too_Large; - - ------------------------------- - -- Prove_Final_Decomposition -- - ------------------------------- - - procedure Prove_Final_Decomposition is - begin - Lemma_Hi_Lo (T2, Hi (T2), Lo (T2)); - pragma Assert (Mult = Big_2xxSingle * Big (Double_Uns (Lo (T2))) - + Big (Double_Uns (Lo (T1)))); - pragma Assert (Mult <= Big_2xxDouble_Minus_1); - Lemma_Mult_Commutation (X, Y); - pragma Assert (Mult = abs Big (X * Y)); - Lemma_Word_Commutation (Lo (T2)); - pragma Assert (Mult = Big (Double_Uns'(2 ** Single_Size) - * Double_Uns (Lo (T2))) - + Big (Double_Uns (Lo (T1)))); - Lemma_Add_Commutation (Double_Uns'(2 ** Single_Size) - * Double_Uns (Lo (T2)), - Lo (T1)); - pragma Assert (Mult = Big (Double_Uns'(2 ** Single_Size) - * Double_Uns (Lo (T2)) + Lo (T1))); - pragma Assert (Lo (T2) & Lo (T1) = Double_Uns'(2 ** Single_Size) - * Double_Uns (Lo (T2)) + Lo (T1)); - end Prove_Final_Decomposition; - - ------------------- - -- Prove_Neg_Int -- - ------------------- - - procedure Prove_Neg_Int is - begin - pragma Assert (X * Y <= 0); - pragma Assert (Mult = -Big (X * Y)); - end Prove_Neg_Int; - - ------------------- - -- Prove_Pos_Int -- - ------------------- - - procedure Prove_Pos_Int is - begin - pragma Assert (X * Y >= 0); - pragma Assert (Mult = Big (X * Y)); - end Prove_Pos_Int; - - ---------------------------- - -- Prove_Result_Too_Large -- - ---------------------------- - - procedure Prove_Result_Too_Large is - begin - pragma Assert (Mult >= Big_2xxSingle * Big (T2)); - Lemma_Hi_Lo (T2, Hi (T2), Lo (T2)); - pragma Assert (Mult >= - Big_2xxSingle * Big_2xxSingle * Big (Double_Uns (Hi (T2)))); - pragma Assert (Double_Uns (Hi (T2)) >= 1); - pragma Assert (Mult >= Big_2xxSingle * Big_2xxSingle); - Prove_Too_Large; - end Prove_Result_Too_Large; - - --------------------- - -- Prove_Too_Large -- - --------------------- - - procedure Prove_Too_Large is null; - - -- Start of processing for Multiply_With_Ovflo_Check - begin - Lemma_Mult_Decomposition (Mult, Xu, Yu, Xhi, Xlo, Yhi, Ylo); - if Xhi /= 0 then if Yhi /= 0 then - Prove_Both_Too_Large; Raise_Error; else T2 := Xhi * Ylo; - pragma Assert (Big (T2) = Big (Double_Uns'(Xhi * Ylo)) - + Big (Double_Uns'(Xlo * Yhi))); end if; elsif Yhi /= 0 then T2 := Xlo * Yhi; - pragma Assert (Big (T2) = Big (Double_Uns'(Xhi * Ylo)) - + Big (Double_Uns'(Xlo * Yhi))); else -- Yhi = Xhi = 0 T2 := 0; @@ -1843,57 +313,27 @@ is -- result from the upper halves of the input values. T1 := Xlo * Ylo; - - pragma Assert (Big (T2) = Big (Double_Uns'(Xhi * Ylo)) - + Big (Double_Uns'(Xlo * Yhi))); - Lemma_Mult_Distribution (Big_2xxSingle, Big (Double_Uns'(Xhi * Ylo)), - Big (Double_Uns'(Xlo * Yhi))); - pragma Assert (Mult = Big_2xxSingle * Big (T2) + Big (T1)); - Lemma_Add_Commutation (T2, Hi (T1)); - pragma Assert - (Big (T2 + Hi (T1)) = Big (T2) + Big (Double_Uns (Hi (T1)))); - T2 := T2 + Hi (T1); - Lemma_Hi_Lo (T1, Hi (T1), Lo (T1)); - pragma Assert - (Mult = Big_2xxSingle * Big (T2) + Big (Double_Uns (Lo (T1)))); - if Hi (T2) /= 0 then - Prove_Result_Too_Large; Raise_Error; end if; - Prove_Final_Decomposition; - T2 := Lo (T2) & Lo (T1); - pragma Assert (Mult = Big (T2)); - if X >= 0 then if Y >= 0 then - Prove_Pos_Int; return To_Pos_Int (T2); - pragma Annotate (CodePeer, Intentional, "precondition", - "Intentional Unsigned->Signed conversion"); else - Prove_Neg_Int; - Lemma_Abs_Range (Big (X) * Big (Y)); return To_Neg_Int (T2); end if; else -- X < 0 if Y < 0 then - Prove_Pos_Int; return To_Pos_Int (T2); - pragma Annotate (CodePeer, Intentional, "precondition", - "Intentional Unsigned->Signed conversion"); else - Prove_Neg_Int; - Lemma_Abs_Range (Big (X) * Big (Y)); return To_Neg_Int (T2); end if; end if; - end Multiply_With_Ovflo_Check; ----------------- @@ -1909,8 +349,6 @@ is -- Scaled_Divide -- ------------------- - pragma Annotate (Gnatcheck, Exempt_On, "Metrics_Cyclomatic_Complexity", - "limit exceeded due to proof code"); procedure Scaled_Divide (X, Y, Z : Double_Int; Q, R : out Double_Int; @@ -1928,10 +366,10 @@ is Zhi : Single_Uns := Hi (Zu); Zlo : Single_Uns := Lo (Zu); - D : array (1 .. 4) of Single_Uns with Relaxed_Initialization; + D : array (1 .. 4) of Single_Uns; -- The dividend, four digits (D(1) is high order) - Qd : array (1 .. 2) of Single_Uns with Relaxed_Initialization; + Qd : array (1 .. 2) of Single_Uns; -- The quotient digits, two digits (Qd(1) is high order) S1, S2, S3 : Single_Uns; @@ -1956,605 +394,6 @@ is T1, T2, T3 : Double_Uns; -- Temporary values - -- Local ghost variables - - Mult : constant Big_Natural := abs (Big (X) * Big (Y)) with Ghost; - Quot : Big_Integer with Ghost; - Big_R : Big_Integer with Ghost; - Big_Q : Big_Integer with Ghost; - Inter : Natural with Ghost; - - -- Local ghost functions - - function Is_Mult_Decomposition - (D1, D2, D3, D4 : Big_Integer) - return Boolean - is - (Mult = Big_2xxSingle * Big_2xxSingle * Big_2xxSingle * D1 - + Big_2xxSingle * Big_2xxSingle * D2 - + Big_2xxSingle * D3 - + D4) - with - Ghost, - Annotate => (GNATprove, Inline_For_Proof); - - function Is_Scaled_Mult_Decomposition - (D1, D2, D3, D4 : Big_Integer) - return Boolean - is - (Mult * Big_2xx (Scale) - = Big_2xxSingle * Big_2xxSingle * Big_2xxSingle * D1 - + Big_2xxSingle * Big_2xxSingle * D2 - + Big_2xxSingle * D3 - + D4) - with - Ghost, - Annotate => (GNATprove, Inline_For_Proof), - Pre => Scale < Double_Size; - - -- Local lemmas - - procedure Prove_Dividend_Scaling - with - Ghost, - Pre => D'Initialized - and then Scale <= Single_Size - and then Is_Mult_Decomposition (Big (Double_Uns (D (1))), - Big (Double_Uns (D (2))), - Big (Double_Uns (D (3))), - Big (Double_Uns (D (4)))) - and then Big (D (1) & D (2)) * Big_2xx (Scale) < Big_2xxDouble - and then T1 = Shift_Left (D (1) & D (2), Scale) - and then T2 = Shift_Left (Double_Uns (D (3)), Scale) - and then T3 = Shift_Left (Double_Uns (D (4)), Scale), - Post => Is_Scaled_Mult_Decomposition - (Big (Double_Uns (Hi (T1))), - Big (Double_Uns (Lo (T1) or Hi (T2))), - Big (Double_Uns (Lo (T2) or Hi (T3))), - Big (Double_Uns (Lo (T3)))); - -- Proves the scaling of the 4-digit dividend actually multiplies it by - -- 2**Scale. - - procedure Prove_Multiplication (Q : Single_Uns) - with - Ghost, - Pre => T1 = Q * Lo (Zu) - and then T2 = Q * Hi (Zu) - and then S3 = Lo (T1) - and then T3 = Hi (T1) + Lo (T2) - and then S2 = Lo (T3) - and then S1 = Hi (T3) + Hi (T2), - Post => Big3 (S1, S2, S3) = Big (Double_Uns (Q)) * Big (Zu); - -- Proves correctness of the multiplication of divisor by quotient to - -- compute amount to subtract. - - procedure Prove_Mult_Decomposition_Split2 - (D1, D2, D2_Hi, D2_Lo, D3, D4 : Big_Integer) - with - Ghost, - Pre => Is_Mult_Decomposition (D1, D2, D3, D4) - and then D2 = Big_2xxSingle * D2_Hi + D2_Lo, - Post => Is_Mult_Decomposition (D1 + D2_Hi, D2_Lo, D3, D4); - -- Proves decomposition of Mult after splitting second component - - procedure Prove_Mult_Decomposition_Split3 - (D1, D2, D3, D3_Hi, D3_Lo, D4 : Big_Integer) - with - Ghost, - Pre => Is_Mult_Decomposition (D1, D2, D3, D4) - and then D3 = Big_2xxSingle * D3_Hi + D3_Lo, - Post => Is_Mult_Decomposition (D1, D2 + D3_Hi, D3_Lo, D4); - -- Proves decomposition of Mult after splitting third component - - procedure Prove_Negative_Dividend - with - Ghost, - Pre => Z /= 0 - and then Big (Qu) = abs Big_Q - and then In_Double_Int_Range (Big_Q) - and then Big (Ru) = abs Big_R - and then ((X >= 0 and Y < 0) or (X < 0 and Y >= 0)) - and then Big_Q = - (if Round then Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), - Big (X) * Big (Y) rem Big (Z)) - else Big (X) * Big (Y) / Big (Z)) - and then Big_R = Big (X) * Big (Y) rem Big (Z), - Post => - (if Z > 0 then Big_Q <= Big_0 - and then In_Double_Int_Range (-Big (Qu)) - else Big_Q >= Big_0 - and then In_Double_Int_Range (Big (Qu))) - and then In_Double_Int_Range (-Big (Ru)); - -- Proves the sign of rounded quotient when dividend is non-positive - - procedure Prove_Overflow - with - Ghost, - Pre => Z /= 0 - and then Mult >= Big_2xxDouble * Big (Double_Uns'(abs Z)), - Post => not In_Double_Int_Range (Big (X) * Big (Y) / Big (Z)) - and then not In_Double_Int_Range - (Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), - Big (X) * Big (Y) rem Big (Z))); - -- Proves overflow case when the quotient has at least 3 digits - - procedure Prove_Positive_Dividend - with - Ghost, - Pre => Z /= 0 - and then Big (Qu) = abs Big_Q - and then In_Double_Int_Range (Big_Q) - and then Big (Ru) = abs Big_R - and then ((X >= 0 and Y >= 0) or (X < 0 and Y < 0)) - and then Big_Q = - (if Round then Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), - Big (X) * Big (Y) rem Big (Z)) - else Big (X) * Big (Y) / Big (Z)) - and then Big_R = Big (X) * Big (Y) rem Big (Z), - Post => - (if Z > 0 then Big_Q >= Big_0 - and then In_Double_Int_Range (Big (Qu)) - else Big_Q <= Big_0 - and then In_Double_Int_Range (-Big (Qu))) - and then In_Double_Int_Range (Big (Ru)); - -- Proves the sign of rounded quotient when dividend is non-negative - - procedure Prove_Qd_Calculation_Part_1 (J : Integer) - with - Ghost, - Pre => J in 1 .. 2 - and then D'Initialized - and then D (J) < Zhi - and then Hi (Zu) = Zhi - and then Qd (J)'Initialized - and then Qd (J) = Lo ((D (J) & D (J + 1)) / Zhi), - Post => Big (Double_Uns (Qd (J))) >= - Big3 (D (J), D (J + 1), D (J + 2)) / Big (Zu); - -- When dividing 3 digits by 2 digits, proves the initial calculation - -- of the quotient given by dividing the first 2 digits of the dividend - -- by the first digit of the divisor is not an underestimate (so - -- readjusting down works). - - procedure Prove_Q_Too_Big - with - Ghost, - Pre => In_Double_Int_Range (Big_Q) - and then abs Big_Q = Big_2xxDouble, - Post => False; - -- Proves the inconsistency when Q is equal to Big_2xx64 - - procedure Prove_Rescaling - with - Ghost, - Pre => Scale <= Single_Size - and then Z /= 0 - and then Mult * Big_2xx (Scale) = Big (Zu) * Big (Qu) + Big (Ru) - and then Big (Ru) < Big (Zu) - and then Big (Zu) = Big (Double_Uns'(abs Z)) * Big_2xx (Scale) - and then Quot = Big (X) * Big (Y) / Big (Z) - and then Big_R = Big (X) * Big (Y) rem Big (Z), - Post => abs Quot = Big (Qu) - and then abs Big_R = Big (Shift_Right (Ru, Scale)); - -- Proves scaling back only the remainder is the right thing to do after - -- computing the scaled division. - - procedure Prove_Rounding_Case - with - Ghost, - Pre => Z /= 0 - and then Quot = Big (X) * Big (Y) / Big (Z) - and then Big_R = Big (X) * Big (Y) rem Big (Z) - and then Big_Q = - Round_Quotient (Big (X) * Big (Y), Big (Z), Quot, Big_R) - and then Big (Ru) = abs Big_R - and then Big (Zu) = Big (Double_Uns'(abs Z)), - Post => abs Big_Q = - (if Ru > (Zu - Double_Uns'(1)) / Double_Uns'(2) - then abs Quot + 1 - else abs Quot); - -- Proves correctness of the rounding of the unsigned quotient - - procedure Prove_Scaled_Mult_Decomposition_Regroup24 - (D1, D2, D3, D4 : Big_Integer) - with - Ghost, - Pre => Scale < Double_Size - and then Is_Scaled_Mult_Decomposition (D1, D2, D3, D4), - Post => Is_Scaled_Mult_Decomposition - (0, Big_2xxSingle * D1 + D2, 0, Big_2xxSingle * D3 + D4); - -- Proves scaled decomposition of Mult after regrouping on second and - -- fourth component. - - procedure Prove_Scaled_Mult_Decomposition_Regroup3 - (D1, D2, D3, D4 : Single_Uns) - with - Ghost, - Pre => Scale < Double_Size - and then Is_Scaled_Mult_Decomposition - (Big (Double_Uns (D1)), Big (Double_Uns (D2)), - Big (Double_Uns (D3)), Big (Double_Uns (D4))), - Post => Is_Scaled_Mult_Decomposition (0, 0, Big3 (D1, D2, D3), - Big (Double_Uns (D4))); - -- Proves scaled decomposition of Mult after regrouping on third - -- component. - - procedure Prove_Sign_R - with - Ghost, - Pre => Z /= 0 and then Big_R = Big (X) * Big (Y) rem Big (Z), - Post => In_Double_Int_Range (Big_R); - - procedure Prove_Signs - with - Ghost, - Pre => Z /= 0 - and then Quot = Big (X) * Big (Y) / Big (Z) - and then Big_R = Big (X) * Big (Y) rem Big (Z) - and then Big_Q = - (if Round then - Round_Quotient (Big (X) * Big (Y), Big (Z), Quot, Big_R) - else Quot) - and then Big (Ru) = abs Big_R - and then Big (Qu) = abs Big_Q - and then In_Double_Int_Range (Big_Q) - and then In_Double_Int_Range (Big_R) - and then R = - (if (X >= 0) = (Y >= 0) then To_Pos_Int (Ru) else To_Neg_Int (Ru)) - and then Q = - (if ((X >= 0) = (Y >= 0)) = (Z >= 0) then To_Pos_Int (Qu) - else To_Neg_Int (Qu)), -- need to ensure To_Pos_Int precondition - Post => Big (R) = Big_R and then Big (Q) = Big_Q; - -- Proves final signs match the intended result after the unsigned - -- division is done. - - procedure Prove_Z_Low - with - Ghost, - Pre => Z /= 0 - and then D'Initialized - and then Hi (abs Z) = 0 - and then Lo (abs Z) = Zlo - and then Mult = - Big_2xxSingle * Big_2xxSingle * Big (Double_Uns (D (2))) - + Big_2xxSingle * Big (Double_Uns (D (3))) - + Big (Double_Uns (D (4))) - and then D (2) < Zlo - and then Quot = (Big (X) * Big (Y)) / Big (Z) - and then Big_R = (Big (X) * Big (Y)) rem Big (Z) - and then T1 = D (2) & D (3) - and then T2 = Lo (T1 rem Zlo) & D (4) - and then Qu = Lo (T1 / Zlo) & Lo (T2 / Zlo) - and then Ru = T2 rem Zlo, - Post => Big (Qu) = abs Quot - and then Big (Ru) = abs Big_R; - -- Proves the case where the divisor is only one digit - - ---------------------------- - -- Prove_Dividend_Scaling -- - ---------------------------- - - procedure Prove_Dividend_Scaling is - Big_D12 : constant Big_Integer := - Big_2xx (Scale) * Big (D (1) & D (2)); - Big_T1 : constant Big_Integer := Big (T1); - Big_D3 : constant Big_Integer := - Big_2xx (Scale) * Big (Double_Uns (D (3))); - Big_T2 : constant Big_Integer := Big (T2); - Big_D4 : constant Big_Integer := - Big_2xx (Scale) * Big (Double_Uns (D (4))); - Big_T3 : constant Big_Integer := Big (T3); - - begin - Lemma_Shift_Left (D (1) & D (2), Scale); - Lemma_Ge_Mult (Big_2xxSingle, Big_2xx (Scale), Big_2xxSingle, - Big_2xxSingle * Big_2xx (Scale)); - Lemma_Lt_Mult (Big (Double_Uns (D (3))), Big_2xxSingle, - Big_2xx (Scale), Big_2xxDouble); - Lemma_Shift_Left (Double_Uns (D (3)), Scale); - Lemma_Lt_Mult (Big (Double_Uns (D (4))), Big_2xxSingle, - Big_2xx (Scale), Big_2xxDouble); - Lemma_Shift_Left (Double_Uns (D (4)), Scale); - Lemma_Hi_Lo (D (1) & D (2), D (1), D (2)); - pragma Assert (Mult * Big_2xx (Scale) = - Big_2xxSingle * Big_2xxSingle * Big_D12 - + Big_2xxSingle * Big_D3 - + Big_D4); - pragma Assert (Big_2xx (Scale) > 0); - declare - Two_xx_Scale : constant Double_Uns := Double_Uns'(2 ** Scale); - D12 : constant Double_Uns := D (1) & D (2); - begin - pragma Assert (Big_2xx (Scale) * Big (D12) < Big_2xxDouble); - pragma Assert (Big (Two_xx_Scale) * Big (D12) < Big_2xxDouble); - Lemma_Mult_Commutation (Two_xx_Scale, D12, T1); - end; - pragma Assert (Big_D12 = Big_T1); - pragma Assert (Big_2xxSingle * Big_2xxSingle * Big_D12 - = Big_2xxSingle * Big_2xxSingle * Big_T1); - Lemma_Mult_Commutation (2 ** Scale, Double_Uns (D (3)), T2); - pragma Assert (Big_D3 = Big_T2); - pragma Assert (Big_2xxSingle * Big_D3 = Big_2xxSingle * Big_T2); - Lemma_Mult_Commutation (2 ** Scale, Double_Uns (D (4)), T3); - pragma Assert - (Is_Scaled_Mult_Decomposition (0, Big_T1, Big_T2, Big_T3)); - Lemma_Hi_Lo (T1, Hi (T1), Lo (T1)); - Lemma_Hi_Lo (T2, Hi (T2), Lo (T2)); - Lemma_Hi_Lo (T3, Hi (T3), Lo (T3)); - Lemma_Mult_Distribution (Big_2xxSingle * Big_2xxSingle, - Big_2xxSingle * Big (Double_Uns (Hi (T1))), - Big (Double_Uns (Lo (T1)))); - Lemma_Mult_Distribution (Big_2xxSingle, - Big_2xxSingle * Big (Double_Uns (Hi (T2))), - Big (Double_Uns (Lo (T2)))); - Lemma_Mult_Distribution (Big_2xxSingle * Big_2xxSingle, - Big (Double_Uns (Lo (T1))), - Big (Double_Uns (Hi (T2)))); - Lemma_Mult_Distribution (Big_2xxSingle, - Big (Double_Uns (Lo (T2))), - Big (Double_Uns (Hi (T3)))); - Lemma_Mult_Distribution (Big_2xxSingle * Big_2xxSingle, - Big (Double_Uns (Lo (T1))), - Big (Double_Uns (Hi (T2)))); - pragma Assert (Double_Uns (Lo (T1) or Hi (T2)) = - Double_Uns (Lo (T1)) + Double_Uns (Hi (T2))); - pragma Assert (Double_Uns (Lo (T2) or Hi (T3)) = - Double_Uns (Lo (T2)) + Double_Uns (Hi (T3))); - Lemma_Add_Commutation (Double_Uns (Lo (T1)), Hi (T2)); - Lemma_Add_Commutation (Double_Uns (Lo (T2)), Hi (T3)); - end Prove_Dividend_Scaling; - - -------------------------- - -- Prove_Multiplication -- - -------------------------- - - procedure Prove_Multiplication (Q : Single_Uns) is - begin - Lemma_Hi_Lo (Zu, Hi (Zu), Lo (Zu)); - Lemma_Hi_Lo (T1, Hi (T1), S3); - Lemma_Hi_Lo (T2, Hi (T2), Lo (T2)); - Lemma_Hi_Lo (T3, Hi (T3), S2); - Lemma_Mult_Commutation (Double_Uns (Q), Double_Uns (Lo (Zu)), T1); - Lemma_Mult_Commutation (Double_Uns (Q), Double_Uns (Hi (Zu)), T2); - Lemma_Mult_Distribution (Big (Double_Uns (Q)), - Big_2xxSingle * Big (Double_Uns (Hi (Zu))), - Big (Double_Uns (Lo (Zu)))); - Lemma_Substitution - (Big (Double_Uns (Q)) * Big (Zu), - Big (Double_Uns (Q)), - Big (Zu), - Big_2xxSingle * Big (Double_Uns (Hi (Zu))) - + Big (Double_Uns (Lo (Zu))), - Big_0); - pragma Assert (Big (Double_Uns (Q)) * Big (Zu) = - Big_2xxSingle * Big_2xxSingle * Big (Double_Uns (Hi (T2))) - + Big_2xxSingle * Big (Double_Uns (Lo (T2))) - + Big_2xxSingle * Big (Double_Uns (Hi (T1))) - + Big (Double_Uns (S3))); - Lemma_Add_Commutation (Double_Uns (Lo (T2)), Hi (T1)); - pragma Assert - (By (Big (Double_Uns (Q)) * Big (Zu) = - Big_2xxSingle * Big_2xxSingle * Big (Double_Uns (Hi (T2))) - + Big_2xxSingle * Big (T3) - + Big (Double_Uns (S3)), - By (Big_2xxSingle * Big (Double_Uns (Lo (T2))) - + Big_2xxSingle * Big (Double_Uns (Hi (T1))) - = Big_2xxSingle * Big (T3), - Double_Uns (Lo (T2)) - + Double_Uns (Hi (T1)) = T3))); - pragma Assert (Double_Uns (Hi (T3)) + Hi (T2) = Double_Uns (S1)); - Lemma_Add_Commutation (Double_Uns (Hi (T3)), Hi (T2)); - pragma Assert - (Big (Double_Uns (Hi (T3))) + Big (Double_Uns (Hi (T2))) = - Big (Double_Uns (S1))); - Lemma_Mult_Distribution (Big_2xxSingle * Big_2xxSingle, - Big (Double_Uns (Hi (T3))), - Big (Double_Uns (Hi (T2)))); - end Prove_Multiplication; - - ------------------------------------- - -- Prove_Mult_Decomposition_Split2 -- - ------------------------------------- - - procedure Prove_Mult_Decomposition_Split2 - (D1, D2, D2_Hi, D2_Lo, D3, D4 : Big_Integer) - is null; - - ------------------------------------- - -- Prove_Mult_Decomposition_Split3 -- - ------------------------------------- - - procedure Prove_Mult_Decomposition_Split3 - (D1, D2, D3, D3_Hi, D3_Lo, D4 : Big_Integer) - is null; - - ----------------------------- - -- Prove_Negative_Dividend -- - ----------------------------- - - procedure Prove_Negative_Dividend is - begin - Lemma_Mult_Non_Positive (Big (X), Big (Y)); - end Prove_Negative_Dividend; - - -------------------- - -- Prove_Overflow -- - -------------------- - - procedure Prove_Overflow is - begin - Lemma_Div_Ge (Mult, Big_2xxDouble, Big (Double_Uns'(abs Z))); - Lemma_Abs_Commutation (Z); - Lemma_Abs_Div_Commutation (Big (X) * Big (Y), Big (Z)); - end Prove_Overflow; - - ----------------------------- - -- Prove_Positive_Dividend -- - ----------------------------- - - procedure Prove_Positive_Dividend is - begin - Lemma_Mult_Non_Negative (Big (X), Big (Y)); - end Prove_Positive_Dividend; - - --------------------------------- - -- Prove_Qd_Calculation_Part_1 -- - --------------------------------- - - procedure Prove_Qd_Calculation_Part_1 (J : Integer) is - begin - Lemma_Hi_Lo (D (J) & D (J + 1), D (J), D (J + 1)); - Lemma_Lt_Commutation (Double_Uns (D (J)), Double_Uns (Zhi)); - Lemma_Gt_Mult (Big (Double_Uns (Zhi)), - Big (Double_Uns (D (J))) + 1, - Big_2xxSingle, Big (D (J) & D (J + 1))); - Lemma_Div_Lt - (Big (D (J) & D (J + 1)), Big_2xxSingle, Big (Double_Uns (Zhi))); - Lemma_Div_Commutation (D (J) & D (J + 1), Double_Uns (Zhi)); - Lemma_Lo_Is_Ident ((D (J) & D (J + 1)) / Zhi); - Lemma_Div_Definition (D (J) & D (J + 1), Zhi, Double_Uns (Qd (J)), - (D (J) & D (J + 1)) rem Zhi); - Lemma_Lt_Commutation - ((D (J) & D (J + 1)) rem Zhi, Double_Uns (Zhi)); - Lemma_Gt_Mult - ((Big (Double_Uns (Qd (J))) + 1) * Big (Double_Uns (Zhi)), - Big (D (J) & D (J + 1)) + 1, Big_2xxSingle, - Big3 (D (J), D (J + 1), D (J + 2))); - Lemma_Hi_Lo (Zu, Zhi, Lo (Zu)); - Lemma_Gt_Mult (Big (Zu), Big_2xxSingle * Big (Double_Uns (Zhi)), - Big (Double_Uns (Qd (J))) + 1, - Big3 (D (J), D (J + 1), D (J + 2))); - Lemma_Div_Lt (Big3 (D (J), D (J + 1), D (J + 2)), - Big (Double_Uns (Qd (J))) + 1, Big (Zu)); - end Prove_Qd_Calculation_Part_1; - - --------------------- - -- Prove_Q_Too_Big -- - --------------------- - - procedure Prove_Q_Too_Big is - begin - pragma Assert (Big_Q = Big_2xxDouble or Big_Q = -Big_2xxDouble); - Lemma_Not_In_Range_Big2xx64; - end Prove_Q_Too_Big; - - --------------------- - -- Prove_Rescaling -- - --------------------- - - procedure Prove_Rescaling is - begin - Lemma_Div_Lt (Big (Ru), Big (Double_Uns'(abs Z)), Big_2xx (Scale)); - Lemma_Div_Eq (Mult, Big (Double_Uns'(abs Z)) * Big (Qu), - Big_2xx (Scale), Big (Ru)); - Lemma_Rev_Div_Definition (Mult, Big (Double_Uns'(abs Z)), - Big (Qu), Big (Ru) / Big_2xx (Scale)); - Lemma_Abs_Div_Commutation (Big (X) * Big (Y), Big (Z)); - Lemma_Abs_Rem_Commutation (Big (X) * Big (Y), Big (Z)); - Lemma_Abs_Commutation (Z); - Lemma_Shift_Right (Ru, Scale); - end Prove_Rescaling; - - ------------------------- - -- Prove_Rounding_Case -- - ------------------------- - - procedure Prove_Rounding_Case is - begin - if Same_Sign (Big (X) * Big (Y), Big (Z)) then - pragma Assert - (abs Big_Q = - (if Ru > (Zu - Double_Uns'(1)) / Double_Uns'(2) - then abs Quot + 1 - else abs Quot)); - end if; - end Prove_Rounding_Case; - - ----------------------------------------------- - -- Prove_Scaled_Mult_Decomposition_Regroup24 -- - ----------------------------------------------- - - procedure Prove_Scaled_Mult_Decomposition_Regroup24 - (D1, D2, D3, D4 : Big_Integer) - is null; - - ---------------------------------------------- - -- Prove_Scaled_Mult_Decomposition_Regroup3 -- - ---------------------------------------------- - - procedure Prove_Scaled_Mult_Decomposition_Regroup3 - (D1, D2, D3, D4 : Single_Uns) - is null; - - ------------------ - -- Prove_Sign_R -- - ------------------ - - procedure Prove_Sign_R is - begin - pragma Assert (In_Double_Int_Range (Big (Z))); - end Prove_Sign_R; - - ----------------- - -- Prove_Signs -- - ----------------- - - procedure Prove_Signs is null; - - ----------------- - -- Prove_Z_Low -- - ----------------- - - procedure Prove_Z_Low is - begin - Lemma_Hi_Lo (T1, D (2), D (3)); - Lemma_Add_Commutation (Double_Uns (D (2)), 1); - pragma Assert - (Big (Double_Uns (D (2))) + 1 <= Big (Double_Uns (Zlo))); - Lemma_Div_Definition (T1, Zlo, T1 / Zlo, T1 rem Zlo); - pragma Assert - (By (Lo (T1 rem Zlo) = Hi (T2), - By (Double_Uns (Lo (T1 rem Zlo)) = T1 rem Zlo, - T1 rem Zlo <= Double_Uns (Zlo)))); - Lemma_Hi_Lo (T2, Lo (T1 rem Zlo), D (4)); - pragma Assert (T1 rem Zlo < Double_Uns (Zlo)); - pragma Assert (T1 rem Zlo + Double_Uns'(1) <= Double_Uns (Zlo)); - Lemma_Ge_Commutation (Double_Uns (Zlo), T1 rem Zlo + Double_Uns'(1)); - Lemma_Add_Commutation (T1 rem Zlo, 1); - pragma Assert (Big (T1 rem Zlo) + 1 <= Big (Double_Uns (Zlo))); - Lemma_Div_Definition (T2, Zlo, T2 / Zlo, Ru); - pragma Assert - (By (Big_2xxSingle * Big (Double_Uns (D (2))) - + Big (Double_Uns (D (3))) - < Big_2xxSingle * (Big (Double_Uns (D (2))) + 1), - Mult = Big (Double_Uns (Zlo)) * - (Big_2xxSingle * Big (T1 / Zlo) + Big (T2 / Zlo)) + Big (Ru))); - Lemma_Div_Lt (Big (T1), Big_2xxSingle, Big (Double_Uns (Zlo))); - Lemma_Div_Commutation (T1, Double_Uns (Zlo)); - Lemma_Lo_Is_Ident (T1 / Zlo); - pragma Assert - (Big (T2) <= Big_2xxSingle * (Big (Double_Uns (Zlo)) - 1) - + Big (Double_Uns (D (4)))); - Lemma_Hi_Lo (Qu, Lo (T1 / Zlo), Lo (T2 / Zlo)); - Lemma_Div_Lt (Big (T2), Big_2xxSingle, Big (Double_Uns (Zlo))); - Lemma_Div_Commutation (T2, Double_Uns (Zlo)); - Lemma_Lo_Is_Ident (T2 / Zlo); - Lemma_Substitution (Mult, Big (Double_Uns (Zlo)), - Big_2xxSingle * Big (T1 / Zlo) + Big (T2 / Zlo), - Big (Qu), Big (Ru)); - pragma Assert - (By (Ru < Double_Uns (Zlo), Ru = T2 rem Zlo)); - Lemma_Lt_Commutation (Ru, Double_Uns (Zlo)); - Lemma_Rev_Div_Definition - (Mult, Big (Double_Uns (Zlo)), Big (Qu), Big (Ru)); - pragma Assert (Double_Uns (Zlo) = abs Z); - Lemma_Abs_Commutation (Z); - Lemma_Abs_Div_Commutation (Big (X) * Big (Y), Big (Z)); - Lemma_Abs_Rem_Commutation (Big (X) * Big (Y), Big (Z)); - end Prove_Z_Low; - -- Start of processing for Scaled_Divide begin @@ -2562,237 +401,56 @@ is Raise_Error; end if; - Quot := Big (X) * Big (Y) / Big (Z); - Big_R := Big (X) * Big (Y) rem Big (Z); - if Round then - Big_Q := Round_Quotient (Big (X) * Big (Y), Big (Z), Quot, Big_R); - else - Big_Q := Quot; - end if; - -- First do the multiplication, giving the four digit dividend - Lemma_Abs_Mult_Commutation (Big (X), Big (Y)); - Lemma_Abs_Commutation (X); - Lemma_Abs_Commutation (Y); - Lemma_Mult_Decomposition (Mult, Xu, Yu, Xhi, Xlo, Yhi, Ylo); - T1 := Xlo * Ylo; D (4) := Lo (T1); D (3) := Hi (T1); - Lemma_Hi_Lo (T1, D (3), D (4)); - if Yhi /= 0 then T1 := Xlo * Yhi; - - Lemma_Hi_Lo (T1, Hi (T1), Lo (T1)); - T2 := D (3) + Lo (T1); - Lemma_Add_Commutation (Double_Uns (Lo (T1)), D (3)); - Lemma_Mult_Distribution (Big_2xxSingle, - Big (Double_Uns (D (3))), - Big (Double_Uns (Lo (T1)))); - Lemma_Hi_Lo (T2, Hi (T2), Lo (T2)); - D (3) := Lo (T2); D (2) := Hi (T1) + Hi (T2); - pragma Assert (Double_Uns (Hi (T1)) + Hi (T2) = Double_Uns (D (2))); - Lemma_Add_Commutation (Double_Uns (Hi (T1)), Hi (T2)); - pragma Assert - (Big (Double_Uns (Hi (T1))) + Big (Double_Uns (Hi (T2))) = - Big (Double_Uns (D (2)))); - if Xhi /= 0 then T1 := Xhi * Ylo; - - Lemma_Hi_Lo (T1, Hi (T1), Lo (T1)); - T2 := D (3) + Lo (T1); - Lemma_Add_Commutation (Double_Uns (D (3)), Lo (T1)); - Lemma_Hi_Lo (T2, Hi (T2), Lo (T2)); - Prove_Mult_Decomposition_Split3 - (D1 => 0, - D2 => Big (Double_Uns'(Xhi * Yhi)) + Big (Double_Uns (D (2))) - + Big (Double_Uns (Hi (T1))), - D3 => Big (T2), - D3_Hi => Big (Double_Uns (Hi (T2))), - D3_Lo => Big (Double_Uns (Lo (T2))), - D4 => Big (Double_Uns (D (4)))); - D (3) := Lo (T2); T3 := D (2) + Hi (T1); - Lemma_Add_Commutation (Double_Uns (D (2)), Hi (T1)); - Lemma_Add_Commutation (T3, Hi (T2)); - T3 := T3 + Hi (T2); T2 := Double_Uns'(Xhi * Yhi); - Lemma_Hi_Lo (T2, Hi (T2), Lo (T2)); - pragma Assert - (Is_Mult_Decomposition - (D1 => Big (Double_Uns (Hi (T2))), - D2 => Big (T3) + Big (Double_Uns (Lo (T2))), - D3 => Big (Double_Uns (D (3))), - D4 => Big (Double_Uns (D (4))))); - T1 := T3 + Lo (T2); D (2) := Lo (T1); - - Lemma_Add_Commutation (T3, Lo (T2)); - Lemma_Hi_Lo (T1, Hi (T1), Lo (T1)); - Prove_Mult_Decomposition_Split2 - (D1 => Big (Double_Uns (Hi (T2))), - D2 => Big (T1), - D2_Lo => Big (Double_Uns (Lo (T1))), - D2_Hi => Big (Double_Uns (Hi (T1))), - D3 => Big (Double_Uns (D (3))), - D4 => Big (Double_Uns (D (4)))); - D (1) := Hi (T2) + Hi (T1); - pragma Assert_And_Cut - (D'Initialized - and Is_Mult_Decomposition (D1 => Big (Double_Uns (D (1))), - D2 => Big (Double_Uns (D (2))), - D3 => Big (Double_Uns (D (3))), - D4 => Big (Double_Uns (D (4))))); else - pragma Assert - (Is_Mult_Decomposition - (D1 => 0, - D2 => Big (Double_Uns (D (2))), - D3 => Big (Double_Uns (D (3))) - + Big (Double_Uns (Xhi)) * Big (Yu), - D4 => Big (Double_Uns (D (4))))); - D (1) := 0; - - pragma Assert_And_Cut - (D'Initialized - and Is_Mult_Decomposition (D1 => Big (Double_Uns (D (1))), - D2 => Big (Double_Uns (D (2))), - D3 => Big (Double_Uns (D (3))), - D4 => Big (Double_Uns (D (4))))); end if; - else if Xhi /= 0 then T1 := Xhi * Ylo; - - Lemma_Hi_Lo (T1, Hi (T1), Lo (T1)); - pragma Assert - (Is_Mult_Decomposition - (D1 => 0, - D2 => Big (Double_Uns (Hi (T1))), - D3 => Big (Double_Uns (Lo (T1))) + Big (Double_Uns (D (3))), - D4 => Big (Double_Uns (D (4))))); - T2 := D (3) + Lo (T1); - Lemma_Add_Commutation (Double_Uns (Lo (T1)), D (3)); - pragma Assert - (Is_Mult_Decomposition - (D1 => 0, - D2 => Big (Double_Uns (Hi (T1))), - D3 => Big (T2), - D4 => Big (Double_Uns (D (4))))); - Lemma_Hi_Lo (T2, Hi (T2), Lo (T2)); - D (3) := Lo (T2); D (2) := Hi (T1) + Hi (T2); - pragma Assert - (Double_Uns (Hi (T1)) + Hi (T2) = Double_Uns (D (2))); - Lemma_Add_Commutation (Double_Uns (Hi (T1)), Hi (T2)); - pragma Assert - (Big (Double_Uns (Hi (T1))) + Big (Double_Uns (Hi (T2))) = - Big (Double_Uns (D (2)))); - pragma Assert - (Is_Mult_Decomposition - (D1 => 0, - D2 => Big (Double_Uns (D (2))), - D3 => Big (Double_Uns (D (3))), - D4 => Big (Double_Uns (D (4))))); else D (2) := 0; - - pragma Assert - (Is_Mult_Decomposition - (D1 => 0, - D2 => Big (Double_Uns (D (2))), - D3 => Big (Double_Uns (D (3))), - D4 => Big (Double_Uns (D (4))))); end if; D (1) := 0; - - pragma Assert_And_Cut - (D'Initialized - and Is_Mult_Decomposition (D1 => Big (Double_Uns (D (1))), - D2 => Big (Double_Uns (D (2))), - D3 => Big (Double_Uns (D (3))), - D4 => Big (Double_Uns (D (4))))); end if; - pragma Assert_And_Cut - -- Restate the precondition - (Z /= 0 - and then In_Double_Int_Range - (if Round then Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), - Big (X) * Big (Y) rem Big (Z)) - else Big (X) * Big (Y) / Big (Z)) - -- Restate the value of local variables - and then Zu = abs Z - and then Zhi = Hi (Zu) - and then Zlo = Lo (Zu) - and then Mult = abs (Big (X) * Big (Y)) - and then Quot = Big (X) * Big (Y) / Big (Z) - and then Big_R = Big (X) * Big (Y) rem Big (Z) - and then - (if Round then - Big_Q = Round_Quotient (Big (X) * Big (Y), Big (Z), Quot, Big_R) - else - Big_Q = Quot) - -- Summarize first part of the procedure - and then D'Initialized - and then Is_Mult_Decomposition (D1 => Big (Double_Uns (D (1))), - D2 => Big (Double_Uns (D (2))), - D3 => Big (Double_Uns (D (3))), - D4 => Big (Double_Uns (D (4))))); - -- Now it is time for the dreaded multiple precision division. First an -- easy case, check for the simple case of a one digit divisor. if Zhi = 0 then if D (1) /= 0 or else D (2) >= Zlo then - if D (1) > 0 then - Lemma_Double_Big_2xxSingle; - Lemma_Mult_Positive (Big_2xxDouble, Big_2xxSingle); - Lemma_Ge_Mult (Big (Double_Uns (D (1))), - 1, - Big_2xxDouble * Big_2xxSingle, - Big_2xxDouble * Big_2xxSingle); - Lemma_Mult_Positive (Big_2xxSingle, Big (Double_Uns (D (1)))); - Lemma_Ge_Mult (Big_2xxSingle * Big_2xxSingle, Big_2xxDouble, - Big_2xxSingle * Big (Double_Uns (D (1))), - Big_2xxDouble * Big_2xxSingle); - pragma Assert (Mult >= Big_2xxDouble * Big_2xxSingle); - Lemma_Ge_Commutation (2 ** Single_Size, Zu); - Lemma_Ge_Mult (Big_2xxSingle, Big (Zu), Big_2xxDouble, - Big_2xxDouble * Big (Zu)); - pragma Assert (Mult >= Big_2xxDouble * Big (Zu)); - else - Lemma_Ge_Commutation (Double_Uns (D (2)), Zu); - pragma Assert (Mult >= Big_2xxDouble * Big (Zu)); - end if; - - Prove_Overflow; Raise_Error; -- Here we are dividing at most three digits by one digit @@ -2803,18 +461,11 @@ is Qu := Lo (T1 / Zlo) & Lo (T2 / Zlo); Ru := T2 rem Zlo; - - Prove_Z_Low; end if; -- If divisor is double digit and dividend is too large, raise error elsif (D (1) & D (2)) >= Zu then - Lemma_Hi_Lo (D (1) & D (2), D (1), D (2)); - Lemma_Ge_Commutation (D (1) & D (2), Zu); - pragma Assert - (Mult >= Big_2xxSingle * Big_2xxSingle * Big (D (1) & D (2))); - Prove_Overflow; Raise_Error; -- This is the complex case where we definitely have a double digit @@ -2827,489 +478,87 @@ is -- First normalize the divisor so that it has the leading bit on. -- We do this by finding the appropriate left shift amount. - Lemma_Hi_Lo (D (1) & D (2), D (1), D (2)); - Lemma_Lt_Commutation (D (1) & D (2), Zu); - pragma Assert - (Mult < Big_2xxDouble * Big (Zu)); - Shift := Single_Size; Mask := Single_Uns'Last; Scale := 0; - Inter := 0; - pragma Assert (Big_2xx (Scale) = 1); - while Shift > 1 loop - pragma Loop_Invariant (Scale <= Single_Size - Shift); - pragma Loop_Invariant ((Hi (Zu) and Mask) /= 0); - pragma Loop_Invariant - (Mask = Shift_Left (Single_Uns'Last, Single_Size - Shift)); - pragma Loop_Invariant (Zu = Shift_Left (abs Z, Scale)); - pragma Loop_Invariant (Big (Zu) = - Big (Double_Uns'(abs Z)) * Big_2xx (Scale)); - pragma Loop_Invariant (Inter in 0 .. Log_Single_Size - 1); - pragma Loop_Invariant (Shift = 2 ** (Log_Single_Size - Inter)); - pragma Loop_Invariant (Shift mod 2 = 0); - - declare - -- Local ghost variables - - Shift_Prev : constant Natural := Shift with Ghost; - Mask_Prev : constant Single_Uns := Mask with Ghost; - Zu_Prev : constant Double_Uns := Zu with Ghost; - - -- Local lemmas - - procedure Prove_Power - with - Ghost, - Pre => Inter in 0 .. Log_Single_Size - 1 - and then Shift = 2 ** (Log_Single_Size - Inter), - Post => Shift / 2 = 2 ** (Log_Single_Size - (Inter + 1)) - and then (Shift = 2 or (Shift / 2) mod 2 = 0); - - procedure Prove_Prev_And_Mask (Prev, Mask : Single_Uns) - with - Ghost, - Pre => Prev /= 0 - and then (Prev and Mask) = 0, - Post => (Prev and not Mask) /= 0; - - procedure Prove_Shift_Progress - with - Ghost, - Pre => Shift <= Single_Size / 2 - and then Shift_Prev = 2 * Shift - and then Mask_Prev = - Shift_Left (Single_Uns'Last, Single_Size - Shift_Prev) - and then Mask = - Shift_Left (Single_Uns'Last, - Single_Size - Shift_Prev + Shift), - Post => Mask_Prev = - Shift_Left (Single_Uns'Last, Single_Size - 2 * Shift) - and then Mask = - Shift_Left (Single_Uns'Last, Single_Size - Shift); - - procedure Prove_Shifting - with - Ghost, - Pre => Shift <= Single_Size / 2 - and then Zu = Shift_Left (Zu_Prev, Shift) - and then Mask_Prev = - Shift_Left (Single_Uns'Last, Single_Size - 2 * Shift) - and then Mask = - Shift_Left (Single_Uns'Last, Single_Size - Shift) - and then (Hi (Zu_Prev) and Mask_Prev and not Mask) /= 0, - Post => (Hi (Zu) and Mask) /= 0; - - ----------------------------- - -- Local lemma null bodies -- - ----------------------------- - - procedure Prove_Prev_And_Mask (Prev, Mask : Single_Uns) is null; - procedure Prove_Power is null; - procedure Prove_Shifting is null; - procedure Prove_Shift_Progress is null; - - begin - pragma Assert (Mask = Shift_Left (Single_Uns'Last, - Single_Size - Shift_Prev)); - Prove_Power; - - Shift := Shift / 2; - - Inter := Inter + 1; - pragma Assert (Shift_Prev = 2 * Shift); - - Mask := Shift_Left (Mask, Shift); - - Lemma_Double_Shift - (Single_Uns'Last, Single_Size - Shift_Prev, Shift); - Prove_Shift_Progress; - - if (Hi (Zu) and Mask) = 0 then - Zu := Shift_Left (Zu, Shift); - - pragma Assert ((Hi (Zu_Prev) and Mask_Prev) /= 0); - pragma Assert - (By ((Hi (Zu_Prev) and Mask_Prev and Mask) = 0, - (Hi (Zu_Prev) and Mask) = 0 - and then - (Hi (Zu_Prev) and Mask_Prev and Mask) - = (Hi (Zu_Prev) and Mask and Mask_Prev) - )); - Prove_Prev_And_Mask (Hi (Zu_Prev) and Mask_Prev, Mask); - Prove_Shifting; - pragma Assert (Big (Zu_Prev) = - Big (Double_Uns'(abs Z)) * Big_2xx (Scale)); - Lemma_Shift_Without_Drop (Zu_Prev, Zu, Mask, Shift); - Lemma_Substitution - (Big (Zu), Big_2xx (Shift), - Big (Zu_Prev), Big (Double_Uns'(abs Z)) * Big_2xx (Scale), - 0); - Lemma_Powers_Of_2 (Shift, Scale); - Lemma_Substitution - (Big (Zu), Big (Double_Uns'(abs Z)), - Big_2xx (Shift) * Big_2xx (Scale), - Big_2xx (Shift + Scale), 0); - Lemma_Double_Shift (abs Z, Scale, Shift); - - Scale := Scale + Shift; - - pragma Assert (Zu = Shift_Left (abs Z, Scale)); - pragma Assert - (Big (Zu) = Big (Double_Uns'(abs Z)) * Big_2xx (Scale)); - end if; - - pragma Assert - (Big (Zu) = Big (Double_Uns'(abs Z)) * Big_2xx (Scale)); - end; + Shift := Shift / 2; + Mask := Shift_Left (Mask, Shift); + + if (Hi (Zu) and Mask) = 0 then + Zu := Shift_Left (Zu, Shift); + Scale := Scale + Shift; + end if; end loop; - pragma Assert_And_Cut - (Scale <= Single_Size - 1 - and then (Hi (Zu) and Mask) /= 0 - and then Mask = Shift_Left (Single_Uns'Last, Single_Size - 1) - and then Zu = Shift_Left (abs Z, Scale) - and then Big (Zu) = Big (Double_Uns'(abs Z)) * Big_2xx (Scale) - and then Mult < Big_2xxDouble * Big (Double_Uns'(abs Z))); Zhi := Hi (Zu); Zlo := Lo (Zu); - pragma Assert ((Zhi and Mask) /= 0); - pragma Assert (Zhi >= 2 ** (Single_Size - 1)); - pragma Assert (Big (Zu) = Big (Double_Uns'(abs Z)) * Big_2xx (Scale)); - -- We have Hi (Zu) /= 0 before normalization. The sequence of - -- Shift_Left operations results in the leading bit of Zu being 1 by - -- moving the leftmost 1-bit in Zu to leading position, thus - -- Zhi = Hi (Zu) >= 2 ** (Single_Size - 1) here. - -- Note that when we scale up the dividend, it still fits in four -- digits, since we already tested for overflow, and scaling does -- not change the invariant that (D (1) & D (2)) < Zu. - Lemma_Lt_Commutation (D (1) & D (2), abs Z); - Lemma_Big_Of_Double_Uns (Zu); - Lemma_Lt_Mult (Big (D (1) & D (2)), - Big (Double_Uns'(abs Z)), Big_2xx (Scale), - Big_2xxDouble); - T1 := Shift_Left (D (1) & D (2), Scale); T2 := Shift_Left (Double_Uns (D (3)), Scale); T3 := Shift_Left (Double_Uns (D (4)), Scale); - Prove_Dividend_Scaling; - D (1) := Hi (T1); D (2) := Lo (T1) or Hi (T2); D (3) := Lo (T2) or Hi (T3); D (4) := Lo (T3); - pragma Assert (D (1) = Hi (T1) and D (2) = (Lo (T1) or Hi (T2)) - and D (3) = (Lo (T2) or Hi (T3)) and D (4) = Lo (T3)); - Lemma_Substitution (Big_2xxDouble * Big (Zu), Big_2xxDouble, Big (Zu), - Big (Double_Uns'(abs Z)) * Big_2xx (Scale), 0); - pragma Assert (Mult < Big_2xxDouble * Big (Double_Uns'(abs Z))); - Lemma_Lt_Mult (Mult, Big_2xxDouble * Big (Double_Uns'(abs Z)), - Big_2xx (Scale), Big_2xxDouble * Big (Zu)); - pragma Assert (Mult >= Big_0); - pragma Assert (Big_2xx (Scale) >= Big_0); - Lemma_Mult_Non_Negative (Mult, Big_2xx (Scale)); - Lemma_Div_Lt (Mult * Big_2xx (Scale), Big (Zu), Big_2xxDouble); - Lemma_Concat_Definition (D (1), D (2)); - Lemma_Double_Big_2xxSingle; - Prove_Scaled_Mult_Decomposition_Regroup24 - (Big (Double_Uns (D (1))), - Big (Double_Uns (D (2))), - Big (Double_Uns (D (3))), - Big (Double_Uns (D (4)))); - Lemma_Substitution - (Mult * Big_2xx (Scale), Big_2xxSingle * Big_2xxSingle, - Big_2xxSingle * Big (Double_Uns (D (1))) - + Big (Double_Uns (D (2))), - Big (D (1) & D (2)), - Big_2xxSingle * Big (Double_Uns (D (3))) - + Big (Double_Uns (D (4)))); - pragma Assert - (By (Big (D (1) & D (2)) < Big (Zu), - Big_2xxDouble * (Big (Zu) - Big (D (1) & D (2))) > - Big_2xxSingle * Big (Double_Uns (D (3))) - + Big (Double_Uns (D (4))))); - -- Loop to compute quotient digits, runs twice for Qd (1) and Qd (2) - declare - -- Local lemmas - - procedure Prove_First_Iteration (X1, X2, X3, X4 : Single_Uns) - with - Ghost, - Pre => X1 = 0, - Post => - Big_2xxSingle * Big3 (X1, X2, X3) + Big (Double_Uns (X4)) - = Big3 (X2, X3, X4); - - --------------------------- - -- Prove_First_Iteration -- - --------------------------- - - procedure Prove_First_Iteration (X1, X2, X3, X4 : Single_Uns) is - null; - - -- Local ghost variables - - Qd1 : Single_Uns := 0 with Ghost; - D234 : Big_Integer with Ghost, Relaxed_Initialization; - D123 : constant Big_Integer := Big3 (D (1), D (2), D (3)) - with Ghost; - D4 : constant Big_Integer := Big (Double_Uns (D (4))) - with Ghost; - - begin - Prove_Scaled_Mult_Decomposition_Regroup3 - (D (1), D (2), D (3), D (4)); - pragma Assert - (By (Mult * Big_2xx (Scale) = Big_2xxSingle * D123 + D4, - Is_Scaled_Mult_Decomposition (0, 0, D123, D4))); - - for J in 1 .. 2 loop - Lemma_Hi_Lo (D (J) & D (J + 1), D (J), D (J + 1)); - pragma Assert (Big (D (J) & D (J + 1)) < Big (Zu)); - - -- Compute next quotient digit. We have to divide three digits - -- by two digits. We estimate the quotient by dividing the - -- leading two digits by the leading digit. Given the scaling - -- we did above which ensured the first bit of the divisor is - -- set, this gives an estimate of the quotient that is at most - -- two too high. - - if D (J) > Zhi then - Lemma_Lt_Commutation (Zu, D (J) & D (J + 1)); - pragma Assert (False); - - elsif D (J) = Zhi then - Qd (J) := Single_Uns'Last; - - Lemma_Concat_Definition (D (J), D (J + 1)); - Lemma_Big_Of_Double_Uns_Of_Single_Uns (D (J + 2)); - pragma Assert (Big_2xxSingle > Big (Double_Uns (D (J + 2)))); - pragma Assert - (By (Big3 (D (J), D (J + 1), 0) + Big_2xxSingle - > Big3 (D (J), D (J + 1), D (J + 2)), - Big3 (D (J), D (J + 1), 0) = - Big_2xxSingle * Big_2xxSingle * Big (Double_Uns (D (J))) - + Big_2xxSingle * Big (Double_Uns (D (J + 1))))); - pragma Assert (Big (Double_Uns'(0)) = 0); - pragma Assert (Big (D (J) & D (J + 1)) * Big_2xxSingle = - Big_2xxSingle * (Big_2xxSingle * Big (Double_Uns (D (J))) - + Big (Double_Uns (D (J + 1))))); - pragma Assert (Big (D (J) & D (J + 1)) * Big_2xxSingle = - Big_2xxSingle * Big_2xxSingle * Big (Double_Uns (D (J))) - + Big_2xxSingle * Big (Double_Uns (D (J + 1)))); - pragma Assert (Big (D (J) & D (J + 1)) * Big_2xxSingle - = Big3 (D (J), D (J + 1), 0)); - pragma Assert ((Big (D (J) & D (J + 1)) + 1) * Big_2xxSingle - = Big3 (D (J), D (J + 1), 0) + Big_2xxSingle); - Lemma_Gt_Mult (Big (Zu), Big (D (J) & D (J + 1)) + 1, - Big_2xxSingle, - Big3 (D (J), D (J + 1), D (J + 2))); - Lemma_Div_Lt - (Big3 (D (J), D (J + 1), D (J + 2)), - Big_2xxSingle, Big (Zu)); - pragma Assert - (By (Big (Double_Uns (Qd (J))) >= - Big3 (D (J), D (J + 1), D (J + 2)) / Big (Zu), - Big (Double_Uns (Qd (J))) = Big_2xxSingle - 1)); - - else - Qd (J) := Lo ((D (J) & D (J + 1)) / Zhi); - - Prove_Qd_Calculation_Part_1 (J); - end if; - - pragma Assert (for all K in 1 .. J => Qd (K)'Initialized); - Lemma_Div_Mult (Big3 (D (J), D (J + 1), D (J + 2)), Big (Zu)); - Lemma_Gt_Mult - (Big (Double_Uns (Qd (J))), - Big3 (D (J), D (J + 1), D (J + 2)) / Big (Zu), - Big (Zu), Big3 (D (J), D (J + 1), D (J + 2)) - Big (Zu)); - - -- Compute amount to subtract - - T1 := Qd (J) * Zlo; - T2 := Qd (J) * Zhi; - S3 := Lo (T1); - T3 := Hi (T1) + Lo (T2); - S2 := Lo (T3); - S1 := Hi (T3) + Hi (T2); - - Prove_Multiplication (Qd (J)); - - -- Adjust quotient digit if it was too high - - -- We use the version of the algorithm in the 2nd Edition - -- of "The Art of Computer Programming". This had a bug not - -- discovered till 1995, see Vol 2 errata: - -- http://www-cs-faculty.stanford.edu/~uno/err2-2e.ps.gz. - -- Under rare circumstances the expression in the test could - -- overflow. This version was further corrected in 2005, see - -- Vol 2 errata: - -- http://www-cs-faculty.stanford.edu/~uno/all2-pre.ps.gz. - -- This implementation is not impacted by these bugs, due - -- to the use of a word-size comparison done in function Le3 - -- instead of a comparison on two-word integer quantities in - -- the original algorithm. - - Lemma_Hi_Lo_3 (Zu, Zhi, Zlo); - - while not Le3 (S1, S2, S3, D (J), D (J + 1), D (J + 2)) loop - pragma Loop_Invariant - (Qd (1)'Initialized - and (if J = 2 then Qd (2)'Initialized)); - pragma Loop_Invariant (if J = 2 then Qd (1) = Qd1); - pragma Loop_Invariant - (Big3 (S1, S2, S3) = Big (Double_Uns (Qd (J))) * Big (Zu)); - pragma Loop_Invariant - (Big3 (S1, S2, S3) > Big3 (D (J), D (J + 1), D (J + 2))); - pragma Assert (Big3 (S1, S2, S3) > 0); - if Qd (J) = 0 then - pragma Assert (Big3 (S1, S2, S3) = 0); - pragma Assert (False); - end if; - Lemma_Ge_Commutation (Double_Uns (Qd (J)), 1); - Lemma_Ge_Mult - (Big (Double_Uns (Qd (J))), 1, Big (Zu), Big (Zu)); - - Sub3 (S1, S2, S3, 0, Zhi, Zlo); - - pragma Assert - (Big3 (S1, S2, S3) > - Big3 (D (J), D (J + 1), D (J + 2)) - Big (Zu)); - Lemma_Subtract_Commutation (Double_Uns (Qd (J)), 1); - pragma Assert (Double_Uns (Qd (J)) - Double_Uns'(1) - = Double_Uns (Qd (J) - 1)); - pragma Assert (Big (Double_Uns'(1)) = 1); - - declare - Prev : constant Single_Uns := Qd (J) with Ghost; - begin - Qd (J) := Qd (J) - 1; - Lemma_Substitution (Big3 (S1, S2, S3), Big (Zu), - Big (Double_Uns (Prev)) - 1, - Big (Double_Uns (Qd (J))), 0); - end; - - pragma Assert - (Big3 (S1, S2, S3) = Big (Double_Uns (Qd (J))) * Big (Zu)); - end loop; - - pragma Assert_And_Cut - (Qd (1)'Initialized - and then (if J = 2 then Qd (2)'Initialized and Qd (1) = Qd1) - and then D'Initialized - and then (if J = 2 then D234'Initialized) - and then Big3 (D (J), D (J + 1), D (J + 2)) = - (if J = 1 then D123 else D234) - and then (if J = 1 then D4 = Big (Double_Uns (D (4)))) - and then Big3 (S1, S2, S3) = - Big (Double_Uns (Qd (J))) * Big (Zu) - and then Le3 (S1, S2, S3, D (J), D (J + 1), D (J + 2)) - and then Big3 (D (J), D (J + 1), D (J + 2)) - - Big3 (S1, S2, S3) < Big (Zu)); - - -- Now subtract S1&S2&S3 from D1&D2&D3 ready for next step - - Inline_Le3 (S1, S2, S3, D (J), D (J + 1), D (J + 2)); - - declare - D4_G : constant Single_Uns := D (4) with Ghost; - begin - Sub3 (D (J), D (J + 1), D (J + 2), S1, S2, S3); - pragma Assert (if J = 1 then D (4) = D4_G); - pragma Assert - (By - (D'Initialized, - D (1)'Initialized and D (2)'Initialized - and D (3)'Initialized and D (4)'Initialized)); - pragma Assert - (Big3 (D (J), D (J + 1), D (J + 2)) = - (if J = 1 then D123 else D234) - - Big3 (S1, S2, S3)); - end; - - pragma Assert - (Big3 (D (J), D (J + 1), D (J + 2)) < Big (Zu)); - - if D (J) > 0 then - Lemma_Double_Big_2xxSingle; - pragma Assert (Big3 (D (J), D (J + 1), D (J + 2)) = - Big_2xxSingle - * Big_2xxSingle * Big (Double_Uns (D (J))) - + Big_2xxSingle * Big (Double_Uns (D (J + 1))) - + Big (Double_Uns (D (J + 2)))); - pragma Assert (Big_2xxSingle >= 0); - Lemma_Big_Of_Double_Uns_Of_Single_Uns (D (J + 1)); - pragma Assert (Big (Double_Uns (D (J + 1))) >= 0); - Lemma_Mult_Non_Negative - (Big_2xxSingle, Big (Double_Uns (D (J + 1)))); - pragma Assert - (Big3 (D (J), D (J + 1), D (J + 2)) >= - Big_2xxSingle * Big_2xxSingle - * Big (Double_Uns (D (J)))); - Lemma_Ge_Commutation (Double_Uns (D (J)), Double_Uns'(1)); - Lemma_Ge_Mult (Big (Double_Uns (D (J))), - Big (Double_Uns'(1)), - Big_2xxDouble, - Big (Double_Uns'(1)) * Big_2xxDouble); - pragma Assert - (Big_2xxDouble * Big (Double_Uns'(1)) = Big_2xxDouble); - pragma Assert - (Big3 (D (J), D (J + 1), D (J + 2)) >= Big_2xxDouble); - pragma Assert (False); - end if; - - if J = 1 then - Qd1 := Qd (1); - D234 := Big3 (D (2), D (3), D (4)); - pragma Assert (D4 = Big (Double_Uns (D (4)))); - Lemma_Substitution - (Mult * Big_2xx (Scale), Big_2xxSingle, D123, - Big3 (D (1), D (2), D (3)) + Big3 (S1, S2, S3), - Big (Double_Uns (D (4)))); - Prove_First_Iteration (D (1), D (2), D (3), D (4)); - Lemma_Substitution (Mult * Big_2xx (Scale), Big_2xxSingle, - Big3 (S1, S2, S3), - Big (Double_Uns (Qd1)) * Big (Zu), - D234); - else - pragma Assert (Qd1 = Qd (1)); - pragma Assert - (By (Mult * Big_2xx (Scale) = - Big_2xxSingle * Big (Double_Uns (Qd (1))) * Big (Zu) - + Big (Double_Uns (Qd (2))) * Big (Zu) - + Big_2xxSingle * Big (Double_Uns (D (3))) - + Big (Double_Uns (D (4))), - By (Mult * Big_2xx (Scale) = - Big_2xxSingle * Big (Double_Uns (Qd (1))) * Big (Zu) - + Big3 (D (2), D (3), D (4)) + Big3 (S1, S2, S3), - Mult * Big_2xx (Scale) = - Big_2xxSingle * Big (Double_Uns (Qd (1))) * Big (Zu) - + D234))); - - end if; + for J in 1 .. 2 loop + -- Compute next quotient digit. We have to divide three digits + -- by two digits. We estimate the quotient by dividing the + -- leading two digits by the leading digit. Given the scaling + -- we did above which ensured the first bit of the divisor is + -- set, this gives an estimate of the quotient that is at most + -- two too high. + + pragma Assert (D (J) <= Zhi); + + if D (J) = Zhi then + Qd (J) := Single_Uns'Last; + else + Qd (J) := Lo ((D (J) & D (J + 1)) / Zhi); + end if; + + -- Compute amount to subtract + + T1 := Qd (J) * Zlo; + T2 := Qd (J) * Zhi; + S3 := Lo (T1); + T3 := Hi (T1) + Lo (T2); + S2 := Lo (T3); + S1 := Hi (T3) + Hi (T2); + + -- Adjust quotient digit if it was too high + + -- We use the version of the algorithm in the 2nd Edition + -- of "The Art of Computer Programming". This had a bug not + -- discovered till 1995, see Vol 2 errata: + -- http://www-cs-faculty.stanford.edu/~uno/err2-2e.ps.gz. + -- Under rare circumstances the expression in the test could + -- overflow. This version was further corrected in 2005, see + -- Vol 2 errata: + -- http://www-cs-faculty.stanford.edu/~uno/all2-pre.ps.gz. + -- This implementation is not impacted by these bugs, due + -- to the use of a word-size comparison done in function Le3 + -- instead of a comparison on two-word integer quantities in + -- the original algorithm. + + while not Le3 (S1, S2, S3, D (J), D (J + 1), D (J + 2)) loop + Sub3 (S1, S2, S3, 0, Zhi, Zlo); + Qd (J) := Qd (J) - 1; end loop; - pragma Assert_And_Cut - (Qd (1)'Initialized and then Qd (2)'Initialized - and then D'Initialized - and then Big_2xxSingle * Big (Double_Uns (D (3))) - + Big (Double_Uns (D (4))) < Big (Zu) - and then Mult * Big_2xx (Scale) = - Big_2xxSingle * Big (Double_Uns (Qd (1))) * Big (Zu) - + Big (Double_Uns (Qd (2))) * Big (Zu) - + Big_2xxSingle * Big (Double_Uns (D (3))) - + Big (Double_Uns (D (4)))); - end; + -- Now subtract S1&S2&S3 from D1&D2&D3 ready for next step + + Sub3 (D (J), D (J + 1), D (J + 2), S1, S2, S3); + end loop; -- The two quotient digits are now set, and the remainder of the -- scaled division is in D3&D4. To get the remainder for the @@ -3321,271 +570,68 @@ is Qu := Qd (1) & Qd (2); Ru := D (3) & D (4); - Lemma_Hi_Lo (Qu, Qd (1), Qd (2)); - Lemma_Hi_Lo (Ru, D (3), D (4)); - Lemma_Substitution - (Mult * Big_2xx (Scale), Big (Zu), - Big_2xxSingle * Big (Double_Uns (Qd (1))) - + Big (Double_Uns (Qd (2))), - Big (Qu), Big (Ru)); - Prove_Rescaling; - Ru := Shift_Right (Ru, Scale); - declare - -- Local lemma required to help automatic provers - procedure Lemma_Div_Congruent - (X, Y : Big_Natural; - Z : Big_Positive) - with - Ghost, - Pre => X = Y, - Post => X / Z = Y / Z; - - procedure Lemma_Div_Congruent - (X, Y : Big_Natural; - Z : Big_Positive) - is null; - - begin - Lemma_Shift_Right (Zu, Scale); - Lemma_Div_Congruent (Big (Zu), - Big (Double_Uns'(abs Z)) * Big_2xx (Scale), - Big_2xx (Scale)); - - Zu := Shift_Right (Zu, Scale); - - Lemma_Simplify (Big (Double_Uns'(abs Z)), Big_2xx (Scale)); - pragma Assert (Big (Zu) = Big (Double_Uns'(abs Z))); - end; + Zu := Shift_Right (Zu, Scale); end if; - pragma Assert (Big (Ru) = abs Big_R); - pragma Assert (Big (Qu) = abs Quot); - pragma Assert (Big (Zu) = Big (Double_Uns'(abs Z))); - -- Deal with rounding case if Round then - Prove_Rounding_Case; - if Ru > (Zu - Double_Uns'(1)) / Double_Uns'(2) then - pragma Assert (abs Big_Q = Big (Qu) + 1); - -- Protect against wrapping around when rounding, by signaling -- an overflow when the quotient is too large. if Qu = Double_Uns'Last then - Prove_Q_Too_Big; Raise_Error; end if; - Lemma_Add_One (Qu); - Qu := Qu + Double_Uns'(1); end if; end if; - pragma Assert (Big (Qu) = abs Big_Q); - -- Set final signs (RM 4.5.5(27-30)) -- Case of dividend (X * Y) sign positive if (X >= 0 and then Y >= 0) or else (X < 0 and then Y < 0) then - Prove_Positive_Dividend; - R := To_Pos_Int (Ru); Q := (if Z > 0 then To_Pos_Int (Qu) else To_Neg_Int (Qu)); -- Case of dividend (X * Y) sign negative else - Prove_Negative_Dividend; - R := To_Neg_Int (Ru); Q := (if Z > 0 then To_Neg_Int (Qu) else To_Pos_Int (Qu)); end if; - - Prove_Sign_R; - Prove_Signs; end Scaled_Divide; - pragma Annotate (Gnatcheck, Exempt_Off, "Metrics_Cyclomatic_Complexity"); ---------- -- Sub3 -- ---------- procedure Sub3 (X1, X2, X3 : in out Single_Uns; Y1, Y2, Y3 : Single_Uns) is - - -- Local ghost variables - - XX1 : constant Single_Uns := X1 with Ghost; - XX2 : constant Single_Uns := X2 with Ghost; - XX3 : constant Single_Uns := X3 with Ghost; - - -- Local lemmas - - procedure Lemma_Add3_No_Carry (X1, X2, X3, Y1, Y2, Y3 : Single_Uns) - with - Ghost, - Pre => X1 <= Single_Uns'Last - Y1 - and then X2 <= Single_Uns'Last - Y2 - and then X3 <= Single_Uns'Last - Y3, - Post => Big3 (X1 + Y1, X2 + Y2, X3 + Y3) - = Big3 (X1, X2, X3) + Big3 (Y1, Y2, Y3); - - procedure Lemma_Ge_Expand (X1, X2, X3, Y1, Y2, Y3 : Single_Uns) - with - Ghost, - Pre => Big3 (X1, X2, X3) >= Big3 (Y1, Y2, Y3), - Post => X1 > Y1 - or else (X1 = Y1 and then X2 > Y2) - or else (X1 = Y1 and then X2 = Y2 and then X3 >= Y3); - - procedure Lemma_Sub3_No_Carry (X1, X2, X3, Y1, Y2, Y3 : Single_Uns) - with - Ghost, - Pre => X1 >= Y1 and then X2 >= Y2 and then X3 >= Y3, - Post => Big3 (X1 - Y1, X2 - Y2, X3 - Y3) - = Big3 (X1, X2, X3) - Big3 (Y1, Y2, Y3); - - procedure Lemma_Sub3_With_Carry2 (X1, X2, X3, Y2 : Single_Uns) - with - Ghost, - Pre => X2 < Y2, - Post => Big3 (X1, X2 - Y2, X3) - = Big3 (X1, X2, X3) + Big3 (Single_Uns'(1), 0, 0) - Big3 (0, Y2, 0); - - procedure Lemma_Sub3_With_Carry3 (X1, X2, X3, Y3 : Single_Uns) - with - Ghost, - Pre => X3 < Y3, - Post => Big3 (X1, X2, X3 - Y3) - = Big3 (X1, X2, X3) + Big3 (Single_Uns'(0), 1, 0) - Big3 (0, 0, Y3); - - ------------------------- - -- Lemma_Add3_No_Carry -- - ------------------------- - - procedure Lemma_Add3_No_Carry (X1, X2, X3, Y1, Y2, Y3 : Single_Uns) is - begin - Lemma_Add_Commutation (Double_Uns (X1), Y1); - Lemma_Add_Commutation (Double_Uns (X2), Y2); - Lemma_Add_Commutation (Double_Uns (X3), Y3); - end Lemma_Add3_No_Carry; - - --------------------- - -- Lemma_Ge_Expand -- - --------------------- - - procedure Lemma_Ge_Expand (X1, X2, X3, Y1, Y2, Y3 : Single_Uns) is null; - - ------------------------- - -- Lemma_Sub3_No_Carry -- - ------------------------- - - procedure Lemma_Sub3_No_Carry (X1, X2, X3, Y1, Y2, Y3 : Single_Uns) is - begin - Lemma_Subtract_Commutation (Double_Uns (X1), Double_Uns (Y1)); - Lemma_Subtract_Commutation (Double_Uns (X2), Double_Uns (Y2)); - Lemma_Subtract_Commutation (Double_Uns (X3), Double_Uns (Y3)); - end Lemma_Sub3_No_Carry; - - ---------------------------- - -- Lemma_Sub3_With_Carry2 -- - ---------------------------- - - procedure Lemma_Sub3_With_Carry2 (X1, X2, X3, Y2 : Single_Uns) is - pragma Unreferenced (X1, X3); - begin - Lemma_Add_Commutation - (Double_Uns'(2 ** Single_Size) - Double_Uns (Y2), X2); - Lemma_Subtract_Commutation - (Double_Uns'(2 ** Single_Size), Double_Uns (Y2)); - end Lemma_Sub3_With_Carry2; - - ---------------------------- - -- Lemma_Sub3_With_Carry3 -- - ---------------------------- - - procedure Lemma_Sub3_With_Carry3 (X1, X2, X3, Y3 : Single_Uns) is - pragma Unreferenced (X1, X2); - begin - Lemma_Add_Commutation - (Double_Uns'(2 ** Single_Size) - Double_Uns (Y3), X3); - Lemma_Subtract_Commutation - (Double_Uns'(2 ** Single_Size), Double_Uns (Y3)); - end Lemma_Sub3_With_Carry3; - - -- Start of processing for Sub3 - begin - Lemma_Ge_Expand (X1, X2, X3, Y1, Y2, Y3); - if Y3 > X3 then if X2 = 0 then pragma Assert (X1 >= 1); - Lemma_Sub3_No_Carry (X1, X2, X3, 1, 0, 0); X1 := X1 - 1; - - pragma Assert - (Big3 (X1, X2, X3) = - Big3 (XX1, XX2, XX3) - Big3 (Single_Uns'(1), 0, 0)); - pragma Assert - (Big3 (X1, X2, X3) = Big3 (XX1, XX2, XX3) - - Big3 (Single_Uns'(0), Single_Uns'Last, 0) - - Big3 (Single_Uns'(0), 1, 0)); - Lemma_Add3_No_Carry (X1, X2, X3, 0, Single_Uns'Last, 0); - else - Lemma_Sub3_No_Carry (X1, X2, X3, 0, 1, 0); end if; X2 := X2 - 1; - - pragma Assert - (Big3 (X1, X2, X3) = - Big3 (XX1, XX2, XX3) - Big3 (Single_Uns'(0), 1, 0)); - Lemma_Sub3_With_Carry3 (X1, X2, X3, Y3); - else - Lemma_Sub3_No_Carry (X1, X2, X3, 0, 0, Y3); end if; X3 := X3 - Y3; - pragma Assert - (Big3 (X1, X2, X3) = Big3 (XX1, XX2, XX3) - Big3 (0, 0, Y3)); - if Y2 > X2 then pragma Assert (X1 >= 1); - Lemma_Sub3_No_Carry (X1, X2, X3, 1, 0, 0); X1 := X1 - 1; - - pragma Assert - (Big3 (X1, X2, X3) = Big3 (XX1, XX2, XX3) - - Big3 (0, 0, Y3) - Big3 (Single_Uns'(1), 0, 0)); - Lemma_Sub3_With_Carry2 (X1, X2, X3, Y2); - else - Lemma_Sub3_No_Carry (X1, X2, X3, 0, Y2, 0); end if; X2 := X2 - Y2; - - pragma Assert - (Big3 (X1, X2, X3) = Big3 (XX1, XX2, XX3) - Big3 (0, Y2, Y3)); - pragma Assert (X1 >= Y1); - Lemma_Sub3_No_Carry (X1, Y2, X3, Y1, 0, 0); - X1 := X1 - Y1; - - pragma Assert - (Big3 (X1, X2, X3) = Big3 (XX1, XX2, XX3) - - Big3 (0, Y2, Y3) - Big3 (Y1, 0, 0)); - Lemma_Add3_No_Carry (0, Y2, Y3, Y1, 0, 0); - pragma Assert - (Big3 (X1, X2, X3) = Big3 (XX1, XX2, XX3) - Big3 (Y1, Y2, Y3)); end Sub3; ------------------------------- @@ -3594,128 +640,18 @@ is function Subtract_With_Ovflo_Check (X, Y : Double_Int) return Double_Int is R : constant Double_Int := To_Int (To_Uns (X) - To_Uns (Y)); - - -- Local lemmas - - procedure Prove_Negative_X - with - Ghost, - Pre => X < 0 and then (Y <= 0 or else R < 0), - Post => R = X - Y; - - procedure Prove_Non_Negative_X - with - Ghost, - Pre => X >= 0 and then (Y > 0 or else R >= 0), - Post => R = X - Y; - - procedure Prove_Overflow_Case - with - Ghost, - Pre => - (if X >= 0 then Y <= 0 and then R < 0 - else Y > 0 and then R >= 0), - Post => not In_Double_Int_Range (Big (X) - Big (Y)); - - ---------------------- - -- Prove_Negative_X -- - ---------------------- - - procedure Prove_Negative_X is - begin - if X = Double_Int'First then - if Y = Double_Int'First or else Y > 0 then - null; - else - pragma Assert - (To_Uns (X) - To_Uns (Y) = - 2 ** (Double_Size - 1) + Double_Uns (-Y)); - end if; - - elsif Y >= 0 or else Y = Double_Int'First then - null; - - else - pragma Assert - (To_Uns (X) - To_Uns (Y) = -Double_Uns (-X) + Double_Uns (-Y)); - end if; - end Prove_Negative_X; - - -------------------------- - -- Prove_Non_Negative_X -- - -------------------------- - - procedure Prove_Non_Negative_X is - begin - if Y > 0 then - declare - Ru : constant Double_Uns := To_Uns (X) - To_Uns (Y); - begin - pragma Assert (Ru = Double_Uns (X) - Double_Uns (Y)); - if Ru < 2 ** (Double_Size - 1) then -- R >= 0 - pragma Assert (To_Uns (Y) <= To_Uns (X)); - Lemma_Subtract_Double_Uns (X => Y, Y => X); - pragma Assert (Ru = Double_Uns (X - Y)); - - elsif Ru = 2 ** (Double_Size - 1) then - pragma Assert (Double_Uns (Y) < 2 ** (Double_Size - 1)); - pragma Assert (False); - - else - pragma Assert - (R = -Double_Int (-(Double_Uns (X) - Double_Uns (Y)))); - pragma Assert - (R = -Double_Int (-Double_Uns (X) + Double_Uns (Y))); - pragma Assert - (R = -Double_Int (Double_Uns (Y) - Double_Uns (X))); - end if; - end; - - elsif Y = Double_Int'First then - pragma Assert - (To_Uns (X) - To_Uns (Y) = - Double_Uns (X) - 2 ** (Double_Size - 1)); - pragma Assert (False); - - else - pragma Assert - (To_Uns (X) - To_Uns (Y) = Double_Uns (X) + Double_Uns (-Y)); - end if; - end Prove_Non_Negative_X; - - ------------------------- - -- Prove_Overflow_Case -- - ------------------------- - - procedure Prove_Overflow_Case is - begin - if X >= 0 and then Y /= Double_Int'First then - pragma Assert - (To_Uns (X) - To_Uns (Y) = Double_Uns (X) + Double_Uns (-Y)); - - elsif X < 0 and then X /= Double_Int'First then - pragma Assert - (To_Uns (X) - To_Uns (Y) = -Double_Uns (-X) - Double_Uns (Y)); - end if; - end Prove_Overflow_Case; - - -- Start of processing for Subtract_With_Ovflo_Check - begin if X >= 0 then if Y > 0 or else R >= 0 then - Prove_Non_Negative_X; return R; end if; else -- X < 0 if Y <= 0 or else R < 0 then - Prove_Negative_X; return R; end if; end if; - Prove_Overflow_Case; Raise_Error; end Subtract_With_Ovflo_Check; @@ -3752,5 +688,3 @@ is pragma Annotate (Gnatcheck, Exempt_Off, "Improper_Returns"); end System.Arith_Double; - -pragma Annotate (Gnatcheck, Exempt_Off, "Metrics_LSLOC"); diff --git a/gcc/ada/libgnat/s-aridou.ads b/gcc/ada/libgnat/s-aridou.ads index 5524cd085350..f7240ded4d83 100644 --- a/gcc/ada/libgnat/s-aridou.ads +++ b/gcc/ada/libgnat/s-aridou.ads @@ -33,8 +33,6 @@ -- double word signed integer values in cases where either overflow checking -- is required, or intermediate results are longer than the result type. -with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; - generic type Double_Int is range <>; @@ -55,51 +53,7 @@ generic package System.Arith_Double with Pure, SPARK_Mode is - -- Preconditions in this unit are meant for analysis only, not for run-time - -- checking, so that the expected exceptions are raised. This is enforced - -- by setting the corresponding assertion policy to Ignore. Postconditions - -- and contract cases should not be executed at runtime as well, in order - -- not to slow down the execution of these functions. - - pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - - package BI_Ghost renames Ada.Numerics.Big_Numbers.Big_Integers_Ghost; - subtype Big_Integer is BI_Ghost.Big_Integer with Ghost; - subtype Big_Natural is BI_Ghost.Big_Natural with Ghost; - subtype Big_Positive is BI_Ghost.Big_Positive with Ghost; - use type BI_Ghost.Big_Integer; - - package Signed_Conversion is - new BI_Ghost.Signed_Conversions (Int => Double_Int); - - function Big (Arg : Double_Int) return Big_Integer is - (Signed_Conversion.To_Big_Integer (Arg)) - with - Ghost, - Annotate => (GNATprove, Inline_For_Proof); - - package Unsigned_Conversion is - new BI_Ghost.Unsigned_Conversions (Int => Double_Uns); - - function Big (Arg : Double_Uns) return Big_Integer is - (Unsigned_Conversion.To_Big_Integer (Arg)) - with - Ghost, - Annotate => (GNATprove, Inline_For_Proof); - - function In_Double_Int_Range (Arg : Big_Integer) return Boolean is - (BI_Ghost.In_Range (Arg, Big (Double_Int'First), Big (Double_Int'Last))) - with - Ghost, - Annotate => (GNATprove, Inline_For_Proof); - - function Add_With_Ovflo_Check (X, Y : Double_Int) return Double_Int - with - Pre => In_Double_Int_Range (Big (X) + Big (Y)), - Post => Add_With_Ovflo_Check'Result = X + Y; + function Add_With_Ovflo_Check (X, Y : Double_Int) return Double_Int; -- Raises Constraint_Error if sum of operands overflows Double_Int, -- otherwise returns this sum of operands as Double_Int. -- @@ -114,10 +68,7 @@ is -- the exception *Constraint_Error* is raised; otherwise the result is -- correct. - function Subtract_With_Ovflo_Check (X, Y : Double_Int) return Double_Int - with - Pre => In_Double_Int_Range (Big (X) - Big (Y)), - Post => Subtract_With_Ovflo_Check'Result = X - Y; + function Subtract_With_Ovflo_Check (X, Y : Double_Int) return Double_Int; -- Raises Constraint_Error if difference of operands overflows Double_Int, -- otherwise returns this difference of operands as Double_Int. -- @@ -127,10 +78,7 @@ is -- overflow. function Multiply_With_Ovflo_Check (X, Y : Double_Int) return Double_Int - with - Pre => In_Double_Int_Range (Big (X) * Big (Y)), - Post => Multiply_With_Ovflo_Check'Result = X * Y; - pragma Convention (C, Multiply_With_Ovflo_Check); + with Convention => C; -- Raises Constraint_Error if product of operands overflows Double_Int, -- otherwise returns this product of operands as Double_Int. The code -- generator may also generate direct calls to this routine. @@ -140,40 +88,10 @@ is -- signed value is returned. Overflow check is performed by looking at -- higher digits. - function Same_Sign (X, Y : Big_Integer) return Boolean is - (X = Big (Double_Int'(0)) - or else Y = Big (Double_Int'(0)) - or else (X < Big (Double_Int'(0))) = (Y < Big (Double_Int'(0)))) - with Ghost; - - function Round_Quotient (X, Y, Q, R : Big_Integer) return Big_Integer is - (if abs R > (abs Y - Big (Double_Int'(1))) / Big (Double_Int'(2)) then - (if Same_Sign (X, Y) then Q + Big (Double_Int'(1)) - else Q - Big (Double_Int'(1))) - else - Q) - with - Ghost, - Pre => Y /= 0 and then Q = X / Y and then R = X rem Y; - procedure Scaled_Divide (X, Y, Z : Double_Int; Q, R : out Double_Int; - Round : Boolean) - with - Pre => Z /= 0 - and then In_Double_Int_Range - (if Round then Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), - Big (X) * Big (Y) rem Big (Z)) - else Big (X) * Big (Y) / Big (Z)), - Post => Big (R) = Big (X) * Big (Y) rem Big (Z) - and then - (if Round then - Big (Q) = Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), Big (R)) - else - Big (Q) = Big (X) * Big (Y) / Big (Z)); + Round : Boolean); -- Performs the division of (``X`` * ``Y``) / ``Z``, storing the quotient -- in ``Q`` and the remainder in ``R``. -- @@ -204,22 +122,7 @@ is procedure Double_Divide (X, Y, Z : Double_Int; Q, R : out Double_Int; - Round : Boolean) - with - Pre => Y /= 0 - and then Z /= 0 - and then In_Double_Int_Range - (if Round then Round_Quotient (Big (X), Big (Y) * Big (Z), - Big (X) / (Big (Y) * Big (Z)), - Big (X) rem (Big (Y) * Big (Z))) - else Big (X) / (Big (Y) * Big (Z))), - Post => Big (R) = Big (X) rem (Big (Y) * Big (Z)) - and then - (if Round then - Big (Q) = Round_Quotient (Big (X), Big (Y) * Big (Z), - Big (X) / (Big (Y) * Big (Z)), Big (R)) - else - Big (Q) = Big (X) / (Big (Y) * Big (Z))); + Round : Boolean); -- Performs the division ``X`` / (``Y`` * ``Z``), storing the quotient in -- ``Q`` and the remainder in ``R``. Constraint_Error is raised if ``Y`` or -- ``Z`` is zero, or if the quotient does not fit in ``Double_Int``. diff --git a/gcc/ada/libgnat/s-arit128.adb b/gcc/ada/libgnat/s-arit128.adb index b9fcbd9cd739..c4ef40dcaf04 100644 --- a/gcc/ada/libgnat/s-arit128.adb +++ b/gcc/ada/libgnat/s-arit128.adb @@ -34,7 +34,6 @@ with System.Arith_Double; package body System.Arith_128 with SPARK_Mode is - subtype Uns128 is Interfaces.Unsigned_128; subtype Uns64 is Interfaces.Unsigned_64; diff --git a/gcc/ada/libgnat/s-arit128.ads b/gcc/ada/libgnat/s-arit128.ads index 9181f0b43629..ea4ef6b3fa9f 100644 --- a/gcc/ada/libgnat/s-arit128.ads +++ b/gcc/ada/libgnat/s-arit128.ads @@ -36,102 +36,31 @@ pragma Restrictions (No_Elaboration_Code); -- Allow direct call from gigi generated code --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced --- by setting the corresponding assertion policy to Ignore. Postconditions --- and contract cases should not be executed at runtime as well, in order --- not to slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - -with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; with Interfaces; package System.Arith_128 with Pure, SPARK_Mode is - use type Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Big_Integer; - use type Interfaces.Integer_128; - subtype Int128 is Interfaces.Integer_128; - subtype Big_Integer is - Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Big_Integer - with Ghost; - - package Signed_Conversion is new - Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Signed_Conversions - (Int => Int128); - - function Big (Arg : Int128) return Big_Integer is - (Signed_Conversion.To_Big_Integer (Arg)) - with Ghost; - - function In_Int128_Range (Arg : Big_Integer) return Boolean is - (Ada.Numerics.Big_Numbers.Big_Integers_Ghost.In_Range - (Arg, Big (Int128'First), Big (Int128'Last))) - with Ghost; - - function Add_With_Ovflo_Check128 (X, Y : Int128) return Int128 - with - Pre => In_Int128_Range (Big (X) + Big (Y)), - Post => Add_With_Ovflo_Check128'Result = X + Y; + function Add_With_Ovflo_Check128 (X, Y : Int128) return Int128; -- Raises Constraint_Error if sum of operands overflows 128 bits, -- otherwise returns the 128-bit signed integer sum. - function Subtract_With_Ovflo_Check128 (X, Y : Int128) return Int128 - with - Pre => In_Int128_Range (Big (X) - Big (Y)), - Post => Subtract_With_Ovflo_Check128'Result = X - Y; + function Subtract_With_Ovflo_Check128 (X, Y : Int128) return Int128; -- Raises Constraint_Error if difference of operands overflows 128 -- bits, otherwise returns the 128-bit signed integer difference. - function Multiply_With_Ovflo_Check128 (X, Y : Int128) return Int128 - with - Pre => In_Int128_Range (Big (X) * Big (Y)), - Post => Multiply_With_Ovflo_Check128'Result = X * Y; + function Multiply_With_Ovflo_Check128 (X, Y : Int128) return Int128; pragma Export (C, Multiply_With_Ovflo_Check128, "__gnat_mulv128"); -- Raises Constraint_Error if product of operands overflows 128 -- bits, otherwise returns the 128-bit signed integer product. -- The code generator may also generate direct calls to this routine. - function Same_Sign (X, Y : Big_Integer) return Boolean is - (X = Big (Int128'(0)) - or else Y = Big (Int128'(0)) - or else (X < Big (Int128'(0))) = (Y < Big (Int128'(0)))) - with Ghost; - - function Round_Quotient (X, Y, Q, R : Big_Integer) return Big_Integer is - (if abs R > (abs Y - Big (Int128'(1))) / Big (Int128'(2)) then - (if Same_Sign (X, Y) then Q + Big (Int128'(1)) - else Q - Big (Int128'(1))) - else - Q) - with - Ghost, - Pre => Y /= 0 and then Q = X / Y and then R = X rem Y; - procedure Scaled_Divide128 (X, Y, Z : Int128; Q, R : out Int128; - Round : Boolean) - with - Pre => Z /= 0 - and then In_Int128_Range - (if Round then Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), - Big (X) * Big (Y) rem Big (Z)) - else Big (X) * Big (Y) / Big (Z)), - Post => Big (R) = Big (X) * Big (Y) rem Big (Z) - and then - (if Round then - Big (Q) = Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), Big (R)) - else - Big (Q) = Big (X) * Big (Y) / Big (Z)); + Round : Boolean); -- Performs the division of (X * Y) / Z, storing the quotient in Q -- and the remainder in R. Constraint_Error is raised if Z is zero, -- or if the quotient does not fit in 128 bits. Round indicates if @@ -143,22 +72,7 @@ is procedure Double_Divide128 (X, Y, Z : Int128; Q, R : out Int128; - Round : Boolean) - with - Pre => Y /= 0 - and then Z /= 0 - and then In_Int128_Range - (if Round then Round_Quotient (Big (X), Big (Y) * Big (Z), - Big (X) / (Big (Y) * Big (Z)), - Big (X) rem (Big (Y) * Big (Z))) - else Big (X) / (Big (Y) * Big (Z))), - Post => Big (R) = Big (X) rem (Big (Y) * Big (Z)) - and then - (if Round then - Big (Q) = Round_Quotient (Big (X), Big (Y) * Big (Z), - Big (X) / (Big (Y) * Big (Z)), Big (R)) - else - Big (Q) = Big (X) / (Big (Y) * Big (Z))); + Round : Boolean); -- Performs the division X / (Y * Z), storing the quotient in Q and -- the remainder in R. Constraint_Error is raised if Y or Z is zero, -- or if the quotient does not fit in 128 bits. Round indicates if the diff --git a/gcc/ada/libgnat/s-arit32.adb b/gcc/ada/libgnat/s-arit32.adb index 91082e7692ab..0cc88edf3052 100644 --- a/gcc/ada/libgnat/s-arit32.adb +++ b/gcc/ada/libgnat/s-arit32.adb @@ -34,20 +34,11 @@ -- would be too costly otherwise. This is enforced by setting the assertion -- policy to Ignore. -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - -with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; -use Ada.Numerics.Big_Numbers.Big_Integers_Ghost; with Ada.Unchecked_Conversion; package body System.Arith_32 with SPARK_Mode is - pragma Suppress (Overflow_Check); pragma Suppress (Range_Check); @@ -58,33 +49,6 @@ is function To_Int is new Ada.Unchecked_Conversion (Uns32, Int32); - package Unsigned_Conversion is new Unsigned_Conversions (Int => Uns32); - - function Big (Arg : Uns32) return Big_Integer is - (Unsigned_Conversion.To_Big_Integer (Arg)) - with Ghost; - - package Unsigned_Conversion_64 is new Unsigned_Conversions (Int => Uns64); - - function Big (Arg : Uns64) return Big_Integer is - (Unsigned_Conversion_64.To_Big_Integer (Arg)) - with Ghost; - - pragma Warnings - (Off, "non-preelaborable call not allowed in preelaborated unit", - Reason => "Ghost code is not compiled"); - Big_0 : constant Big_Integer := - Big (Uns32'(0)) - with Ghost; - Big_2xx32 : constant Big_Integer := - Big (Uns32'(2 ** 32 - 1)) + 1 - with Ghost; - Big_2xx64 : constant Big_Integer := - Big (Uns64'(2 ** 64 - 1)) + 1 - with Ghost; - pragma Warnings - (On, "non-preelaborable call not allowed in preelaborated unit"); - ----------------------- -- Local Subprograms -- ----------------------- @@ -96,166 +60,23 @@ is -- Convert absolute value of X to unsigned. Note that we can't just use -- the expression of the Else since it overflows for X = Int32'First. - function Lo (A : Uns64) return Uns32 is (Uns32 (A and (2 ** 32 - 1))); - -- Low order half of 64-bit value - function Hi (A : Uns64) return Uns32 is (Uns32 (Shift_Right (A, 32))); -- High order half of 64-bit value - function To_Neg_Int (A : Uns32) return Int32 - with - Pre => In_Int32_Range (-Big (A)), - Post => Big (To_Neg_Int'Result) = -Big (A); + function To_Neg_Int (A : Uns32) return Int32; -- Convert to negative integer equivalent. If the input is in the range -- 0 .. 2**31, then the corresponding nonpositive signed integer (obtained -- by negating the given value) is returned, otherwise constraint error is -- raised. - function To_Pos_Int (A : Uns32) return Int32 - with - Pre => In_Int32_Range (Big (A)), - Post => Big (To_Pos_Int'Result) = Big (A); + function To_Pos_Int (A : Uns32) return Int32; -- Convert to positive integer equivalent. If the input is in the range -- 0 .. 2**31 - 1, then the corresponding nonnegative signed integer is -- returned, otherwise constraint error is raised. - procedure Raise_Error with - Always_Terminates, - Exceptional_Cases => (Constraint_Error => True); - pragma No_Return (Raise_Error); + procedure Raise_Error with No_Return; -- Raise constraint error with appropriate message - ------------------ - -- Local Lemmas -- - ------------------ - - procedure Lemma_Abs_Commutation (X : Int32) - with - Ghost, - Post => abs Big (X) = Big (Uns32'(abs X)); - - procedure Lemma_Abs_Div_Commutation (X, Y : Big_Integer) - with - Ghost, - Pre => Y /= 0, - Post => abs (X / Y) = abs X / abs Y; - - procedure Lemma_Abs_Mult_Commutation (X, Y : Big_Integer) - with - Ghost, - Post => abs (X * Y) = abs X * abs Y; - - procedure Lemma_Abs_Rem_Commutation (X, Y : Big_Integer) - with - Ghost, - Pre => Y /= 0, - Post => abs (X rem Y) = (abs X) rem (abs Y); - - procedure Lemma_Div_Commutation (X, Y : Uns64) - with - Ghost, - Pre => Y /= 0, - Post => Big (X) / Big (Y) = Big (X / Y); - - procedure Lemma_Div_Ge (X, Y, Z : Big_Integer) - with - Ghost, - Pre => Z > 0 and then X >= Y * Z, - Post => X / Z >= Y; - - procedure Lemma_Ge_Commutation (A, B : Uns32) - with - Ghost, - Pre => A >= B, - Post => Big (A) >= Big (B); - - procedure Lemma_Hi_Lo (Xu : Uns64; Xhi, Xlo : Uns32) - with - Ghost, - Pre => Xhi = Hi (Xu) and Xlo = Lo (Xu), - Post => Big (Xu) = Big_2xx32 * Big (Xhi) + Big (Xlo); - - procedure Lemma_Mult_Commutation (X, Y, Z : Uns64) - with - Ghost, - Pre => Big (X) * Big (Y) < Big_2xx64 and then Z = X * Y, - Post => Big (X) * Big (Y) = Big (Z); - - procedure Lemma_Mult_Non_Negative (X, Y : Big_Integer) - with - Ghost, - Pre => (X >= Big_0 and then Y >= Big_0) - or else (X <= Big_0 and then Y <= Big_0), - Post => X * Y >= Big_0; - - procedure Lemma_Mult_Non_Positive (X, Y : Big_Integer) - with - Ghost, - Pre => (X <= Big_0 and then Y >= Big_0) - or else (X >= Big_0 and then Y <= Big_0), - Post => X * Y <= Big_0; - - procedure Lemma_Neg_Rem (X, Y : Big_Integer) - with - Ghost, - Pre => Y /= 0, - Post => X rem Y = X rem (-Y); - - procedure Lemma_Not_In_Range_Big2xx32 - with - Post => not In_Int32_Range (Big_2xx32) - and then not In_Int32_Range (-Big_2xx32); - - procedure Lemma_Rem_Commutation (X, Y : Uns64) - with - Ghost, - Pre => Y /= 0, - Post => Big (X) rem Big (Y) = Big (X rem Y); - - ----------------------------- - -- Local lemma null bodies -- - ----------------------------- - - procedure Lemma_Abs_Commutation (X : Int32) is null; - procedure Lemma_Abs_Div_Commutation (X, Y : Big_Integer) is null; - procedure Lemma_Abs_Mult_Commutation (X, Y : Big_Integer) is null; - procedure Lemma_Div_Commutation (X, Y : Uns64) is null; - procedure Lemma_Div_Ge (X, Y, Z : Big_Integer) is null; - procedure Lemma_Ge_Commutation (A, B : Uns32) is null; - procedure Lemma_Mult_Commutation (X, Y, Z : Uns64) is null; - procedure Lemma_Mult_Non_Negative (X, Y : Big_Integer) is null; - procedure Lemma_Mult_Non_Positive (X, Y : Big_Integer) is null; - procedure Lemma_Neg_Rem (X, Y : Big_Integer) is null; - procedure Lemma_Not_In_Range_Big2xx32 is null; - procedure Lemma_Rem_Commutation (X, Y : Uns64) is null; - - ------------------------------- - -- Lemma_Abs_Rem_Commutation -- - ------------------------------- - - procedure Lemma_Abs_Rem_Commutation (X, Y : Big_Integer) is - begin - if Y < 0 then - Lemma_Neg_Rem (X, Y); - if X < 0 then - pragma Assert (X rem Y = -((-X) rem (-Y))); - pragma Assert (abs (X rem Y) = (abs X) rem (abs Y)); - else - pragma Assert (abs (X rem Y) = (abs X) rem (abs Y)); - end if; - end if; - end Lemma_Abs_Rem_Commutation; - - ----------------- - -- Lemma_Hi_Lo -- - ----------------- - - procedure Lemma_Hi_Lo (Xu : Uns64; Xhi, Xlo : Uns32) is - begin - pragma Assert (Uns64 (Xhi) = Xu / Uns64'(2 ** 32)); - pragma Assert (Uns64 (Xlo) = Xu mod 2 ** 32); - end Lemma_Hi_Lo; - ----------------- -- Raise_Error -- ----------------- @@ -263,9 +84,6 @@ is procedure Raise_Error is begin raise Constraint_Error with "32-bit arithmetic overflow"; - pragma Annotate - (GNATprove, Intentional, "exception might be raised", - "Procedure Raise_Error is called to signal input errors"); end Raise_Error; ------------------- @@ -288,197 +106,20 @@ is Ru : Uns32; -- Unsigned quotient and remainder - -- Local ghost variables - - Mult : constant Big_Integer := abs (Big (X) * Big (Y)) with Ghost; - Quot : Big_Integer with Ghost; - Big_R : Big_Integer with Ghost; - Big_Q : Big_Integer with Ghost; - - -- Local lemmas - - procedure Prove_Negative_Dividend - with - Ghost, - Pre => Z /= 0 - and then ((X >= 0 and Y < 0) or (X < 0 and Y >= 0)) - and then Big_Q = - (if Round then Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), - Big (X) * Big (Y) rem Big (Z)) - else Big (X) * Big (Y) / Big (Z)), - Post => - (if Z > 0 then Big_Q <= Big_0 else Big_Q >= Big_0); - -- Proves the sign of rounded quotient when dividend is non-positive - - procedure Prove_Overflow - with - Ghost, - Pre => Z /= 0 and then Mult >= Big_2xx32 * Big (Uns32'(abs Z)), - Post => not In_Int32_Range (Big (X) * Big (Y) / Big (Z)) - and then not In_Int32_Range - (Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), - Big (X) * Big (Y) rem Big (Z))); - -- Proves overflow case - - procedure Prove_Positive_Dividend - with - Ghost, - Pre => Z /= 0 - and then ((X >= 0 and Y >= 0) or (X < 0 and Y < 0)) - and then Big_Q = - (if Round then Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), - Big (X) * Big (Y) rem Big (Z)) - else Big (X) * Big (Y) / Big (Z)), - Post => - (if Z > 0 then Big_Q >= Big_0 else Big_Q <= Big_0); - -- Proves the sign of rounded quotient when dividend is non-negative - - procedure Prove_Rounding_Case - with - Ghost, - Pre => Z /= 0 - and then Quot = Big (X) * Big (Y) / Big (Z) - and then Big_R = Big (X) * Big (Y) rem Big (Z) - and then Big_Q = - Round_Quotient (Big (X) * Big (Y), Big (Z), Quot, Big_R) - and then Big (Ru) = abs Big_R - and then Big (Zu) = Big (Uns32'(abs Z)), - Post => abs Big_Q = - (if Ru > (Zu - Uns32'(1)) / Uns32'(2) - then abs Quot + 1 - else abs Quot); - -- Proves correctness of the rounding of the unsigned quotient - - procedure Prove_Sign_R - with - Ghost, - Pre => Z /= 0 and then Big_R = Big (X) * Big (Y) rem Big (Z), - Post => In_Int32_Range (Big_R); - - procedure Prove_Signs - with - Ghost, - Pre => Z /= 0 - and then Quot = Big (X) * Big (Y) / Big (Z) - and then Big_R = Big (X) * Big (Y) rem Big (Z) - and then Big_Q = - (if Round then - Round_Quotient (Big (X) * Big (Y), Big (Z), Quot, Big_R) - else Quot) - and then Big (Ru) = abs Big_R - and then Big (Qu) = abs Big_Q - and then In_Int32_Range (Big_Q) - and then In_Int32_Range (Big_R) - and then R = - (if (X >= 0) = (Y >= 0) then To_Pos_Int (Ru) else To_Neg_Int (Ru)) - and then Q = - (if ((X >= 0) = (Y >= 0)) = (Z >= 0) then To_Pos_Int (Qu) - else To_Neg_Int (Qu)), -- need to ensure To_Pos_Int precondition - Post => Big (R) = Big_R and then Big (Q) = Big_Q; - -- Proves final signs match the intended result after the unsigned - -- division is done. - - ----------------------------- - -- Prove_Negative_Dividend -- - ----------------------------- - - procedure Prove_Negative_Dividend is - begin - Lemma_Mult_Non_Positive (Big (X), Big (Y)); - end Prove_Negative_Dividend; - - -------------------- - -- Prove_Overflow -- - -------------------- - - procedure Prove_Overflow is - begin - Lemma_Div_Ge (Mult, Big_2xx32, Big (Uns32'(abs Z))); - Lemma_Abs_Commutation (Z); - Lemma_Abs_Div_Commutation (Big (X) * Big (Y), Big (Z)); - end Prove_Overflow; - - ----------------------------- - -- Prove_Positive_Dividend -- - ----------------------------- - - procedure Prove_Positive_Dividend is - begin - Lemma_Mult_Non_Negative (Big (X), Big (Y)); - end Prove_Positive_Dividend; - - ------------------------- - -- Prove_Rounding_Case -- - ------------------------- - - procedure Prove_Rounding_Case is - begin - if Same_Sign (Big (X) * Big (Y), Big (Z)) then - pragma Assert - (abs Big_Q = - (if Ru > (Zu - Uns32'(1)) / Uns32'(2) - then abs Quot + 1 - else abs Quot)); - end if; - end Prove_Rounding_Case; - - ------------------ - -- Prove_Sign_R -- - ------------------ - - procedure Prove_Sign_R is - begin - pragma Assert (In_Int32_Range (Big (Z))); - end Prove_Sign_R; - - ----------------- - -- Prove_Signs -- - ----------------- - - procedure Prove_Signs is - begin - if (X >= 0) = (Y >= 0) then - pragma Assert (Big (R) = Big_R and then Big (Q) = Big_Q); - else - pragma Assert (Big (R) = Big_R and then Big (Q) = Big_Q); - end if; - end Prove_Signs; - - -- Start of processing for Scaled_Divide32 - begin -- First do the 64-bit multiplication D := Uns64 (Xu) * Uns64 (Yu); - Lemma_Abs_Mult_Commutation (Big (X), Big (Y)); - pragma Assert (Mult = Big (D)); - Lemma_Hi_Lo (D, Hi (D), Lo (D)); - pragma Assert (Mult = Big_2xx32 * Big (Hi (D)) + Big (Lo (D))); - -- If divisor is zero, raise error if Z = 0 then Raise_Error; end if; - Quot := Big (X) * Big (Y) / Big (Z); - Big_R := Big (X) * Big (Y) rem Big (Z); - if Round then - Big_Q := Round_Quotient (Big (X) * Big (Y), Big (Z), Quot, Big_R); - else - Big_Q := Quot; - end if; - -- If dividend is too large, raise error if Hi (D) >= Zu then - Lemma_Ge_Commutation (Hi (D), Zu); - pragma Assert (Mult >= Big_2xx32 * Big (Zu)); - Prove_Overflow; Raise_Error; end if; @@ -487,35 +128,14 @@ is Qu := Uns32 (D / Uns64 (Zu)); Ru := Uns32 (D rem Uns64 (Zu)); - Lemma_Abs_Div_Commutation (Big (X) * Big (Y), Big (Z)); - Lemma_Abs_Rem_Commutation (Big (X) * Big (Y), Big (Z)); - Lemma_Abs_Commutation (X); - Lemma_Abs_Commutation (Y); - Lemma_Abs_Commutation (Z); - Lemma_Mult_Commutation (Uns64 (Xu), Uns64 (Yu), D); - Lemma_Div_Commutation (D, Uns64 (Zu)); - Lemma_Rem_Commutation (D, Uns64 (Zu)); - - pragma Assert (Uns64 (Qu) = D / Uns64 (Zu)); - pragma Assert (Uns64 (Ru) = D rem Uns64 (Zu)); - pragma Assert (Big (Ru) = abs Big_R); - pragma Assert (Big (Qu) = abs Quot); - pragma Assert (Big (Zu) = Big (Uns32'(abs Z))); - -- Deal with rounding case if Round then - Prove_Rounding_Case; - if Ru > (Zu - Uns32'(1)) / Uns32'(2) then - pragma Assert (abs Big_Q = Big (Qu) + 1); - -- Protect against wrapping around when rounding, by signaling -- an overflow when the quotient is too large. if Qu = Uns32'Last then - pragma Assert (abs Big_Q = Big_2xx32); - Lemma_Not_In_Range_Big2xx32; Raise_Error; end if; @@ -523,31 +143,20 @@ is end if; end if; - pragma Assert (In_Int32_Range (Big_Q)); - pragma Assert (Big (Qu) = abs Big_Q); - pragma Assert (Big (Ru) = abs Big_R); - Prove_Sign_R; - -- Set final signs (RM 4.5.5(27-30)) -- Case of dividend (X * Y) sign positive if (X >= 0 and then Y >= 0) or else (X < 0 and then Y < 0) then - Prove_Positive_Dividend; - R := To_Pos_Int (Ru); Q := (if Z > 0 then To_Pos_Int (Qu) else To_Neg_Int (Qu)); -- Case of dividend (X * Y) sign negative else - Prove_Negative_Dividend; - R := To_Neg_Int (Ru); Q := (if Z > 0 then To_Neg_Int (Qu) else To_Pos_Int (Qu)); end if; - - Prove_Signs; end Scaled_Divide32; ---------------- @@ -559,6 +168,7 @@ is (if A = 2**31 then Int32'First else -To_Int (A)); -- Note that we can't just use the expression of the Else, because it -- overflows for A = 2**31. + begin if R <= 0 then return R; diff --git a/gcc/ada/libgnat/s-arit32.ads b/gcc/ada/libgnat/s-arit32.ads index a8abbdc4d33e..856dd594873f 100644 --- a/gcc/ada/libgnat/s-arit32.ads +++ b/gcc/ada/libgnat/s-arit32.ads @@ -33,79 +33,19 @@ -- signed integer values in cases where either overflow checking is -- required, or intermediate results are longer than 32 bits. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced --- by setting the corresponding assertion policy to Ignore. Postconditions --- and contract cases should not be executed at runtime as well, in order --- not to slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - with Interfaces; -with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; package System.Arith_32 with Pure, SPARK_Mode is - use type Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Big_Integer; use type Interfaces.Integer_32; subtype Int32 is Interfaces.Integer_32; - subtype Big_Integer is - Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Big_Integer - with Ghost; - - package Signed_Conversion is new - Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Signed_Conversions - (Int => Int32); - - function Big (Arg : Int32) return Big_Integer is - (Signed_Conversion.To_Big_Integer (Arg)) - with Ghost; - - function In_Int32_Range (Arg : Big_Integer) return Boolean is - (Ada.Numerics.Big_Numbers.Big_Integers_Ghost.In_Range - (Arg, Big (Int32'First), Big (Int32'Last))) - with Ghost; - - function Same_Sign (X, Y : Big_Integer) return Boolean is - (X = Big (Int32'(0)) - or else Y = Big (Int32'(0)) - or else (X < Big (Int32'(0))) = (Y < Big (Int32'(0)))) - with Ghost; - - function Round_Quotient (X, Y, Q, R : Big_Integer) return Big_Integer is - (if abs R > (abs Y - Big (Int32'(1))) / Big (Int32'(2)) then - (if Same_Sign (X, Y) then Q + Big (Int32'(1)) - else Q - Big (Int32'(1))) - else - Q) - with - Ghost, - Pre => Y /= 0 and then Q = X / Y and then R = X rem Y; - procedure Scaled_Divide32 (X, Y, Z : Int32; Q, R : out Int32; - Round : Boolean) - with - Pre => Z /= 0 - and then In_Int32_Range - (if Round then Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), - Big (X) * Big (Y) rem Big (Z)) - else Big (X) * Big (Y) / Big (Z)), - Post => Big (R) = Big (X) * Big (Y) rem Big (Z) - and then - (if Round then - Big (Q) = Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), Big (R)) - else - Big (Q) = Big (X) * Big (Y) / Big (Z)); + Round : Boolean); -- Performs the division of (``X`` * ``Y``) / ``Z``, storing the quotient -- in ``Q`` and the remainder in ``R``. -- diff --git a/gcc/ada/libgnat/s-arit64.adb b/gcc/ada/libgnat/s-arit64.adb index 331f328ec496..4e0336f4f166 100644 --- a/gcc/ada/libgnat/s-arit64.adb +++ b/gcc/ada/libgnat/s-arit64.adb @@ -28,14 +28,12 @@ -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -pragma Assertion_Policy (Ghost => Ignore); with System.Arith_Double; package body System.Arith_64 with SPARK_Mode is - subtype Uns64 is Interfaces.Unsigned_64; subtype Uns32 is Interfaces.Unsigned_32; @@ -52,9 +50,6 @@ is function Multiply_With_Ovflo_Check64 (X, Y : Int64) return Int64 renames Impl.Multiply_With_Ovflo_Check; - function Round_Quotient (X, Y, Q, R : Big_Integer) return Big_Integer - renames Impl.Round_Quotient; - procedure Scaled_Divide64 (X, Y, Z : Int64; Q, R : out Int64; diff --git a/gcc/ada/libgnat/s-arit64.ads b/gcc/ada/libgnat/s-arit64.ads index 2ddd15cbcb60..6e1278988bcf 100644 --- a/gcc/ada/libgnat/s-arit64.ads +++ b/gcc/ada/libgnat/s-arit64.ads @@ -36,49 +36,14 @@ pragma Restrictions (No_Elaboration_Code); -- Allow direct call from gigi generated code --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced --- by setting the corresponding assertion policy to Ignore. Postconditions --- and contract cases should not be executed at runtime as well, in order --- not to slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - -with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; with Interfaces; package System.Arith_64 with Pure, SPARK_Mode is - use type Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Big_Integer; - use type Interfaces.Integer_64; - subtype Int64 is Interfaces.Integer_64; - subtype Big_Integer is - Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Big_Integer - with Ghost; - - package Signed_Conversion is new - Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Signed_Conversions - (Int => Int64); - - function Big (Arg : Int64) return Big_Integer is - (Signed_Conversion.To_Big_Integer (Arg)) - with Ghost; - - function In_Int64_Range (Arg : Big_Integer) return Boolean is - (Ada.Numerics.Big_Numbers.Big_Integers_Ghost.In_Range - (Arg, Big (Int64'First), Big (Int64'Last))) - with Ghost; - - function Add_With_Ovflo_Check64 (X, Y : Int64) return Int64 - with - Pre => In_Int64_Range (Big (X) + Big (Y)), - Post => Add_With_Ovflo_Check64'Result = X + Y; + function Add_With_Ovflo_Check64 (X, Y : Int64) return Int64; -- Raises Constraint_Error if sum of operands overflows 64 bits, -- otherwise returns the 64-bit signed integer sum. -- @@ -93,10 +58,7 @@ is -- the exception *Constraint_Error* is raised; otherwise the result is -- correct. - function Subtract_With_Ovflo_Check64 (X, Y : Int64) return Int64 - with - Pre => In_Int64_Range (Big (X) - Big (Y)), - Post => Subtract_With_Ovflo_Check64'Result = X - Y; + function Subtract_With_Ovflo_Check64 (X, Y : Int64) return Int64; -- Raises Constraint_Error if difference of operands overflows 64 -- bits, otherwise returns the 64-bit signed integer difference. -- @@ -105,10 +67,7 @@ is -- a sign of the result is compared with the sign of ``X`` to check for -- overflow. - function Multiply_With_Ovflo_Check64 (X, Y : Int64) return Int64 - with - Pre => In_Int64_Range (Big (X) * Big (Y)), - Post => Multiply_With_Ovflo_Check64'Result = X * Y; + function Multiply_With_Ovflo_Check64 (X, Y : Int64) return Int64; pragma Export (C, Multiply_With_Ovflo_Check64, "__gnat_mulv64"); -- Raises Constraint_Error if product of operands overflows 64 -- bits, otherwise returns the 64-bit signed integer product. @@ -119,40 +78,10 @@ is -- signed value is returned. Overflow check is performed by looking at -- higher digits. - function Same_Sign (X, Y : Big_Integer) return Boolean is - (X = Big (Int64'(0)) - or else Y = Big (Int64'(0)) - or else (X < Big (Int64'(0))) = (Y < Big (Int64'(0)))) - with Ghost; - - function Round_Quotient (X, Y, Q, R : Big_Integer) return Big_Integer with - Ghost, - Pre => Y /= 0 and then Q = X / Y and then R = X rem Y, - Post => Round_Quotient'Result = - (if abs R > (abs Y - Big (Int64'(1))) / Big (Int64'(2)) then - (if Same_Sign (X, Y) then Q + Big (Int64'(1)) - else Q - Big (Int64'(1))) - else - Q); - procedure Scaled_Divide64 (X, Y, Z : Int64; Q, R : out Int64; - Round : Boolean) - with - Pre => Z /= 0 - and then In_Int64_Range - (if Round then Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), - Big (X) * Big (Y) rem Big (Z)) - else Big (X) * Big (Y) / Big (Z)), - Post => Big (R) = Big (X) * Big (Y) rem Big (Z) - and then - (if Round then - Big (Q) = Round_Quotient (Big (X) * Big (Y), Big (Z), - Big (X) * Big (Y) / Big (Z), Big (R)) - else - Big (Q) = Big (X) * Big (Y) / Big (Z)); + Round : Boolean); -- Performs the division of (``X`` * ``Y``) / ``Z``, storing the quotient -- in ``Q`` and the remainder in ``R``. -- @@ -189,22 +118,7 @@ is procedure Double_Divide64 (X, Y, Z : Int64; Q, R : out Int64; - Round : Boolean) - with - Pre => Y /= 0 - and then Z /= 0 - and then In_Int64_Range - (if Round then Round_Quotient (Big (X), Big (Y) * Big (Z), - Big (X) / (Big (Y) * Big (Z)), - Big (X) rem (Big (Y) * Big (Z))) - else Big (X) / (Big (Y) * Big (Z))), - Post => Big (R) = Big (X) rem (Big (Y) * Big (Z)) - and then - (if Round then - Big (Q) = Round_Quotient (Big (X), Big (Y) * Big (Z), - Big (X) / (Big (Y) * Big (Z)), Big (R)) - else - Big (Q) = Big (X) / (Big (Y) * Big (Z))); + Round : Boolean); -- Performs the division ``X`` / (``Y`` * ``Z``), storing the quotient in -- ``Q`` and the remainder in ``R``. Constraint_Error is raised if ``Y`` or -- ``Z`` is zero, or if the quotient does not fit in 64-bits. diff --git a/gcc/ada/libgnat/s-casuti.adb b/gcc/ada/libgnat/s-casuti.adb index 58c358c90dde..887cbbf57707 100644 --- a/gcc/ada/libgnat/s-casuti.adb +++ b/gcc/ada/libgnat/s-casuti.adb @@ -29,14 +29,6 @@ -- -- ------------------------------------------------------------------------------ --- Ghost code, loop invariants and assertions in this unit are meant for --- analysis only, not for run-time checking, as it would be too costly --- otherwise. This is enforced by setting the assertion policy to Ignore. - -pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - package body System.Case_Util with SPARK_Mode is @@ -44,30 +36,6 @@ is -- To_Lower -- -------------- - function To_Lower (A : Character) return Character is - A_Val : constant Natural := Character'Pos (A); - - begin - if A in 'A' .. 'Z' - or else A_Val in 16#C0# .. 16#D6# - or else A_Val in 16#D8# .. 16#DE# - then - return Character'Val (A_Val + 16#20#); - else - return A; - end if; - end To_Lower; - - procedure To_Lower (A : in out String) is - begin - for J in A'Range loop - A (J) := To_Lower (A (J)); - - pragma Loop_Invariant - (for all K in A'First .. J => A (K) = To_Lower (A'Loop_Entry (K))); - end loop; - end To_Lower; - function To_Lower (A : String) return String is Result : String := A; begin @@ -79,30 +47,6 @@ is -- To_Mixed -- -------------- - procedure To_Mixed (A : in out String) is - Ucase : Boolean := True; - - begin - for J in A'Range loop - if Ucase then - A (J) := To_Upper (A (J)); - else - A (J) := To_Lower (A (J)); - end if; - - pragma Loop_Invariant - (for all K in A'First .. J => - (if K = A'First - or else A'Loop_Entry (K - 1) = '_' - then - A (K) = To_Upper (A'Loop_Entry (K)) - else - A (K) = To_Lower (A'Loop_Entry (K)))); - - Ucase := A (J) = '_'; - end loop; - end To_Mixed; - function To_Mixed (A : String) return String is Result : String := A; begin @@ -114,30 +58,6 @@ is -- To_Upper -- -------------- - function To_Upper (A : Character) return Character is - A_Val : constant Natural := Character'Pos (A); - - begin - if A in 'a' .. 'z' - or else A_Val in 16#E0# .. 16#F6# - or else A_Val in 16#F8# .. 16#FE# - then - return Character'Val (A_Val - 16#20#); - else - return A; - end if; - end To_Upper; - - procedure To_Upper (A : in out String) is - begin - for J in A'Range loop - A (J) := To_Upper (A (J)); - - pragma Loop_Invariant - (for all K in A'First .. J => A (K) = To_Upper (A'Loop_Entry (K))); - end loop; - end To_Upper; - function To_Upper (A : String) return String is Result : String := A; begin diff --git a/gcc/ada/libgnat/s-casuti.ads b/gcc/ada/libgnat/s-casuti.ads index fbdec17dd54e..967abe090e7d 100644 --- a/gcc/ada/libgnat/s-casuti.ads +++ b/gcc/ada/libgnat/s-casuti.ads @@ -40,34 +40,30 @@ -- contract cases should not be executed at runtime as well, in order not to -- slow down the execution of these functions. +-- The portion of this package that does not require use of the secondary +-- stack (so all the subprograms except functions that return String) +-- has been moved into a sibling package, Case_Util_NSS. See comments there. +-- Clients who don't care about avoiding secondary stack usage can +-- continue to use this package and are unaffected by this reorganization. + pragma Assertion_Policy (Pre => Ignore, Post => Ignore, Contract_Cases => Ignore, Ghost => Ignore); +with System.Case_Util_NSS; + package System.Case_Util with Pure, SPARK_Mode is -- Note: all the following functions handle the full Latin-1 set function To_Upper (A : Character) return Character - with - Post => (declare - A_Val : constant Natural := Character'Pos (A); - begin - (if A in 'a' .. 'z' - or else A_Val in 16#E0# .. 16#F6# - or else A_Val in 16#F8# .. 16#FE# - then - To_Upper'Result = Character'Val (A_Val - 16#20#) - else - To_Upper'Result = A)); + renames Case_Util_NSS.To_Upper; -- Converts A to upper case if it is a lower case letter, otherwise -- returns the input argument unchanged. - procedure To_Upper (A : in out String) - with - Post => (for all J in A'Range => A (J) = To_Upper (A'Old (J))); + procedure To_Upper (A : in out String) renames Case_Util_NSS.To_Upper; function To_Upper (A : String) return String with @@ -78,23 +74,12 @@ is -- Folds all characters of string A to upper case function To_Lower (A : Character) return Character - with - Post => (declare - A_Val : constant Natural := Character'Pos (A); - begin - (if A in 'A' .. 'Z' - or else A_Val in 16#C0# .. 16#D6# - or else A_Val in 16#D8# .. 16#DE# - then - To_Lower'Result = Character'Val (A_Val + 16#20#) - else - To_Lower'Result = A)); + renames Case_Util_NSS.To_Lower; -- Converts A to lower case if it is an upper case letter, otherwise -- returns the input argument unchanged. procedure To_Lower (A : in out String) - with - Post => (for all J in A'Range => A (J) = To_Lower (A'Old (J))); + renames Case_Util_NSS.To_Lower; function To_Lower (A : String) return String with @@ -105,15 +90,7 @@ is -- Folds all characters of string A to lower case procedure To_Mixed (A : in out String) - with - Post => - (for all J in A'Range => - (if J = A'First - or else A'Old (J - 1) = '_' - then - A (J) = To_Upper (A'Old (J)) - else - A (J) = To_Lower (A'Old (J)))); + renames Case_Util_NSS.To_Mixed; function To_Mixed (A : String) return String with diff --git a/gcc/ada/libgnat/s-valspe.adb b/gcc/ada/libgnat/s-cautns.adb similarity index 55% rename from gcc/ada/libgnat/s-valspe.adb rename to gcc/ada/libgnat/s-cautns.adb index b47e818d5851..3e2d996dd560 100644 --- a/gcc/ada/libgnat/s-valspe.adb +++ b/gcc/ada/libgnat/s-cautns.adb @@ -1,12 +1,12 @@ ------------------------------------------------------------------------------ -- -- --- GNAT COMPILER COMPONENTS -- +-- GNAT RUN-TIME COMPONENTS -- -- -- --- S Y S T E M . V A L _ S P E C -- +-- S Y S T E M . C A S E _ U T I L _ N S S -- -- -- -- B o d y -- -- -- --- Copyright (C) 2023-2025, Free Software Foundation, Inc. -- +-- Copyright (C) 1995-2025, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -37,51 +37,91 @@ pragma Assertion_Policy (Ghost => Ignore, Loop_Invariant => Ignore, Assert => Ignore); -package body System.Val_Spec +package body System.Case_Util_NSS with SPARK_Mode is + -------------- + -- To_Lower -- + -------------- - --------------------------- - -- First_Non_Space_Ghost -- - --------------------------- + function To_Lower (A : Character) return Character is + A_Val : constant Natural := Character'Pos (A); - function First_Non_Space_Ghost - (S : String; - From, To : Integer) return Positive - is begin - for J in From .. To loop - if S (J) /= ' ' then - return J; - end if; + if A in 'A' .. 'Z' + or else A_Val in 16#C0# .. 16#D6# + or else A_Val in 16#D8# .. 16#DE# + then + return Character'Val (A_Val + 16#20#); + else + return A; + end if; + end To_Lower; + + procedure To_Lower (A : in out String) is + begin + for J in A'Range loop + A (J) := To_Lower (A (J)); - pragma Loop_Invariant (for all K in From .. J => S (K) = ' '); + pragma Loop_Invariant + (for all K in A'First .. J => A (K) = To_Lower (A'Loop_Entry (K))); end loop; + end To_Lower; - raise Program_Error; - end First_Non_Space_Ghost; + -------------- + -- To_Mixed -- + -------------- - ----------------------- - -- Last_Number_Ghost -- - ----------------------- + procedure To_Mixed (A : in out String) is + Ucase : Boolean := True; - function Last_Number_Ghost (Str : String) return Positive is begin - pragma Annotate (Gnatcheck, Exempt_On, "Improper_Returns", - "occurs in ghost code, not executable"); - - for J in Str'Range loop - if Str (J) not in '0' .. '9' | '_' then - return J - 1; + for J in A'Range loop + if Ucase then + A (J) := To_Upper (A (J)); + else + A (J) := To_Lower (A (J)); end if; pragma Loop_Invariant - (for all K in Str'First .. J => Str (K) in '0' .. '9' | '_'); + (for all K in A'First .. J => + (if K = A'First + or else A'Loop_Entry (K - 1) = '_' + then + A (K) = To_Upper (A'Loop_Entry (K)) + else + A (K) = To_Lower (A'Loop_Entry (K)))); + + Ucase := A (J) = '_'; end loop; + end To_Mixed; + + -------------- + -- To_Upper -- + -------------- - return Str'Last; + function To_Upper (A : Character) return Character is + A_Val : constant Natural := Character'Pos (A); - pragma Annotate (Gnatcheck, Exempt_Off, "Improper_Returns"); - end Last_Number_Ghost; + begin + if A in 'a' .. 'z' + or else A_Val in 16#E0# .. 16#F6# + or else A_Val in 16#F8# .. 16#FE# + then + return Character'Val (A_Val - 16#20#); + else + return A; + end if; + end To_Upper; + + procedure To_Upper (A : in out String) is + begin + for J in A'Range loop + A (J) := To_Upper (A (J)); + + pragma Loop_Invariant + (for all K in A'First .. J => A (K) = To_Upper (A'Loop_Entry (K))); + end loop; + end To_Upper; -end System.Val_Spec; +end System.Case_Util_NSS; diff --git a/gcc/ada/libgnat/s-cautns.ads b/gcc/ada/libgnat/s-cautns.ads new file mode 100644 index 000000000000..5c9c67bc9856 --- /dev/null +++ b/gcc/ada/libgnat/s-cautns.ads @@ -0,0 +1,106 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT RUN-TIME COMPONENTS -- +-- -- +-- S Y S T E M . C A S E _ U T I L _ N S S -- +-- -- +-- S p e c -- +-- -- +-- Copyright (C) 1995-2025, Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- You should have received a copy of the GNU General Public License and -- +-- a copy of the GCC Runtime Library Exception along with this program; -- +-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- +-- <http://www.gnu.org/licenses/>. -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +-- The No_Secondary_Stack portion of System.Case_Util. Some of the functions +-- provided in System.Case_Util make use of the secondary stack, and some +-- do not. Lumping them all together makes even the non-secondary-stack +-- portion of the package unusable in cases where references to +-- secondary-stack-related code must be avoided (for example, if linking with +-- a reduced version of the runtimes where that code is missing). That's a +-- problem in some cases, so Case_Util is split into two parts. The first +-- part (named Case_Util_NSS) is a subset of the original version which +-- does not use the secondary stack; the second part presents the same +-- complete interface to users as before, but avoids code duplication by +-- renaming entities out of the first part. +-- +-- See comments in s-casuti.ads for further explanations (e.g., of +-- the Assertion_Policy specified here). + +pragma Assertion_Policy (Pre => Ignore, + Post => Ignore, + Contract_Cases => Ignore, + Ghost => Ignore); + +package System.Case_Util_NSS + with Pure, SPARK_Mode +is + -- Note: all the following functions handle the full Latin-1 set + + function To_Upper (A : Character) return Character + with + Post => (declare + A_Val : constant Natural := Character'Pos (A); + begin + (if A in 'a' .. 'z' + or else A_Val in 16#E0# .. 16#F6# + or else A_Val in 16#F8# .. 16#FE# + then + To_Upper'Result = Character'Val (A_Val - 16#20#) + else + To_Upper'Result = A)); + -- Converts A to upper case if it is a lower case letter, otherwise + -- returns the input argument unchanged. + + procedure To_Upper (A : in out String) + with + Post => (for all J in A'Range => A (J) = To_Upper (A'Old (J))); + + function To_Lower (A : Character) return Character + with + Post => (declare + A_Val : constant Natural := Character'Pos (A); + begin + (if A in 'A' .. 'Z' + or else A_Val in 16#C0# .. 16#D6# + or else A_Val in 16#D8# .. 16#DE# + then + To_Lower'Result = Character'Val (A_Val + 16#20#) + else + To_Lower'Result = A)); + -- Converts A to lower case if it is an upper case letter, otherwise + -- returns the input argument unchanged. + + procedure To_Lower (A : in out String) + with + Post => (for all J in A'Range => A (J) = To_Lower (A'Old (J))); + + procedure To_Mixed (A : in out String) + with + Post => + (for all J in A'Range => + (if J = A'First + or else A'Old (J - 1) = '_' + then + A (J) = To_Upper (A'Old (J)) + else + A (J) = To_Lower (A'Old (J)))); + +end System.Case_Util_NSS; diff --git a/gcc/ada/libgnat/s-dorepr.adb b/gcc/ada/libgnat/s-dorepr.adb index ddc7c1dad17e..1d9604aa1fda 100644 --- a/gcc/ada/libgnat/s-dorepr.adb +++ b/gcc/ada/libgnat/s-dorepr.adb @@ -134,7 +134,7 @@ package body Product is Ahi, Alo, Bhi, Blo, E : Num; begin - if Is_Infinity (P) or else Is_Zero (P) then + if Is_Infinity_Or_NaN (P) or else Is_Zero (P) then return (P, 0.0); else @@ -157,7 +157,7 @@ package body Product is Hi, Lo, E : Num; begin - if Is_Infinity (Q) or else Is_Zero (Q) then + if Is_Infinity_Or_NaN (Q) or else Is_Zero (Q) then return (Q, 0.0); else diff --git a/gcc/ada/libgnat/s-dorepr__fma.adb b/gcc/ada/libgnat/s-dorepr__fma.adb index 0d3dc5382447..45a92238e829 100644 --- a/gcc/ada/libgnat/s-dorepr__fma.adb +++ b/gcc/ada/libgnat/s-dorepr__fma.adb @@ -78,7 +78,7 @@ package body Product is E : Num; begin - if Is_Infinity (P) or else Is_Zero (P) then + if Is_Infinity_Or_NaN (P) or else Is_Zero (P) then return (P, 0.0); else diff --git a/gcc/ada/libgnat/s-dourea.adb b/gcc/ada/libgnat/s-dourea.adb index a37f2eb03c3f..68d4d9a02d88 100644 --- a/gcc/ada/libgnat/s-dourea.adb +++ b/gcc/ada/libgnat/s-dourea.adb @@ -34,12 +34,12 @@ package body System.Double_Real is function Is_NaN (N : Num) return Boolean is (N /= N); -- Return True if N is a NaN - function Is_Infinity (N : Num) return Boolean is (Is_NaN (N - N)); - -- Return True if N is an infinity. Used to avoid propagating meaningless - -- errors when the result of a product is an infinity. + function Is_Infinity_Or_NaN (N : Num) return Boolean is (Is_NaN (N - N)); + -- Return True if N is either an infinity or NaN. Used to avoid propagating + -- meaningless errors when the result of a product is an infinity or NaN. function Is_Zero (N : Num) return Boolean is (N = -N); - -- Return True if N is a Zero. Used to preserve the sign when the result of + -- Return True if N is a zero. Used to preserve the sign when the result of -- a product is a zero. package Product is @@ -151,7 +151,7 @@ package body System.Double_Real is P : constant Double_T := Two_Prod (A.Hi, B); begin - if Is_Infinity (P.Hi) or else Is_Zero (P.Hi) then + if Is_Infinity_Or_NaN (P.Hi) or else Is_Zero (P.Hi) then return (P.Hi, 0.0); else return Quick_Two_Sum (P.Hi, P.Lo + A.Lo * B); @@ -162,7 +162,7 @@ package body System.Double_Real is P : constant Double_T := Two_Prod (A.Hi, B.Hi); begin - if Is_Infinity (P.Hi) or else Is_Zero (P.Hi) then + if Is_Infinity_Or_NaN (P.Hi) or else Is_Zero (P.Hi) then return (P.Hi, 0.0); else return Quick_Two_Sum (P.Hi, P.Lo + A.Hi * B.Lo + A.Lo * B.Hi); @@ -178,7 +178,7 @@ package body System.Double_Real is P, R : Double_T; begin - if Is_Infinity (B) or else Is_Zero (B) then + if Is_Infinity_Or_NaN (B) or else Is_Zero (B) then return (A.Hi / B, 0.0); end if; pragma Annotate (CodePeer, Intentional, "test always false", @@ -202,7 +202,7 @@ package body System.Double_Real is R, S : Double_T; begin - if Is_Infinity (B.Hi) or else Is_Zero (B.Hi) then + if Is_Infinity_Or_NaN (B.Hi) or else Is_Zero (B.Hi) then return (A.Hi / B.Hi, 0.0); end if; pragma Annotate (CodePeer, Intentional, "test always false", @@ -228,7 +228,7 @@ package body System.Double_Real is Q : constant Double_T := Two_Sqr (A.Hi); begin - if Is_Infinity (Q.Hi) or else Is_Zero (Q.Hi) then + if Is_Infinity_Or_NaN (Q.Hi) or else Is_Zero (Q.Hi) then return (Q.Hi, 0.0); else return Quick_Two_Sum (Q.Hi, Q.Lo + 2.0 * A.Hi * A.Lo + A.Lo * A.Lo); diff --git a/gcc/ada/libgnat/s-excdeb.adb b/gcc/ada/libgnat/s-excdeb.adb index 5cbd6c09d830..4ad847817bf6 100644 --- a/gcc/ada/libgnat/s-excdeb.adb +++ b/gcc/ada/libgnat/s-excdeb.adb @@ -69,7 +69,7 @@ package body System.Exceptions_Debug is procedure Local_Raise (Excep : System.Address) is pragma Warnings (Off, Excep); begin - return; + null; end Local_Raise; end System.Exceptions_Debug; diff --git a/gcc/ada/libgnat/s-exnint.ads b/gcc/ada/libgnat/s-exnint.ads index 3a11f2c9ea28..fa46217318ba 100644 --- a/gcc/ada/libgnat/s-exnint.ads +++ b/gcc/ada/libgnat/s-exnint.ads @@ -31,17 +31,6 @@ -- This package implements Integer exponentiation (checks off) --- Preconditions, postconditions, ghost code, loop invariants and assertions --- in this unit are meant for analysis only, not for run-time checking, as it --- would be too costly otherwise. This is enforced by setting the assertion --- policy to Ignore. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - with System.Exponn; package System.Exn_Int diff --git a/gcc/ada/libgnat/s-exnlli.ads b/gcc/ada/libgnat/s-exnlli.ads index ba67b761d51e..63c4b887b2b9 100644 --- a/gcc/ada/libgnat/s-exnlli.ads +++ b/gcc/ada/libgnat/s-exnlli.ads @@ -31,17 +31,6 @@ -- This package implements Long_Long_Integer exponentiation (checks off) --- Preconditions, postconditions, ghost code, loop invariants and assertions --- in this unit are meant for analysis only, not for run-time checking, as it --- would be too costly otherwise. This is enforced by setting the assertion --- policy to Ignore. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - with System.Exponn; package System.Exn_LLI diff --git a/gcc/ada/libgnat/s-exnllli.ads b/gcc/ada/libgnat/s-exnllli.ads index 5ff963c3c0e9..e94efe0b2b3b 100644 --- a/gcc/ada/libgnat/s-exnllli.ads +++ b/gcc/ada/libgnat/s-exnllli.ads @@ -31,23 +31,11 @@ -- Long_Long_Long_Integer exponentiation (checks off) --- Preconditions, postconditions, ghost code, loop invariants and assertions --- in this unit are meant for analysis only, not for run-time checking, as it --- would be too costly otherwise. This is enforced by setting the assertion --- policy to Ignore. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - with System.Exponn; package System.Exn_LLLI with SPARK_Mode is - package Exponn_Integer is new Exponn (Long_Long_Long_Integer); function Exn_Long_Long_Long_Integer diff --git a/gcc/ada/libgnat/s-expint.ads b/gcc/ada/libgnat/s-expint.ads index a69c8d6f025e..d349330c404a 100644 --- a/gcc/ada/libgnat/s-expint.ads +++ b/gcc/ada/libgnat/s-expint.ads @@ -31,23 +31,11 @@ -- This package implements Integer exponentiation (checks on) --- Preconditions, postconditions, ghost code, loop invariants and assertions --- in this unit are meant for analysis only, not for run-time checking, as it --- would be too costly otherwise. This is enforced by setting the assertion --- policy to Ignore. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - with System.Expont; package System.Exp_Int with SPARK_Mode is - package Expont_Integer is new Expont (Integer); function Exp_Integer (Left : Integer; Right : Natural) return Integer diff --git a/gcc/ada/libgnat/s-explli.ads b/gcc/ada/libgnat/s-explli.ads index 9ea38de0ff29..af3da9c019e3 100644 --- a/gcc/ada/libgnat/s-explli.ads +++ b/gcc/ada/libgnat/s-explli.ads @@ -31,23 +31,11 @@ -- This package implements Long_Long_Integer exponentiation --- Preconditions, postconditions, ghost code, loop invariants and assertions --- in this unit are meant for analysis only, not for run-time checking, as it --- would be too costly otherwise. This is enforced by setting the assertion --- policy to Ignore. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - with System.Expont; package System.Exp_LLI with SPARK_Mode is - package Expont_Integer is new Expont (Long_Long_Integer); function Exp_Long_Long_Integer diff --git a/gcc/ada/libgnat/s-expllli.ads b/gcc/ada/libgnat/s-expllli.ads index 273c33c01cd1..ed100b94206b 100644 --- a/gcc/ada/libgnat/s-expllli.ads +++ b/gcc/ada/libgnat/s-expllli.ads @@ -31,23 +31,11 @@ -- Long_Long_Long_Integer exponentiation (checks on) --- Preconditions, postconditions, ghost code, loop invariants and assertions --- in this unit are meant for analysis only, not for run-time checking, as it --- would be too costly otherwise. This is enforced by setting the assertion --- policy to Ignore. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - with System.Expont; package System.Exp_LLLI with SPARK_Mode is - package Expont_Integer is new Expont (Long_Long_Long_Integer); function Exp_Long_Long_Long_Integer diff --git a/gcc/ada/libgnat/s-explllu.ads b/gcc/ada/libgnat/s-explllu.ads index a0b5d4708f56..88aa9af9e2d4 100644 --- a/gcc/ada/libgnat/s-explllu.ads +++ b/gcc/ada/libgnat/s-explllu.ads @@ -34,24 +34,12 @@ -- The result is always full width, the caller must do a masking operation if -- the modulus is less than 2 ** Long_Long_Long_Unsigned'Size. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced --- by setting the corresponding assertion policy to Ignore. Postconditions --- and contract cases should not be executed at runtime as well, in order --- not to slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - with System.Exponu; with System.Unsigned_Types; package System.Exp_LLLU with SPARK_Mode is - subtype Long_Long_Long_Unsigned is Unsigned_Types.Long_Long_Long_Unsigned; function Exp_Long_Long_Long_Unsigned is diff --git a/gcc/ada/libgnat/s-expllu.ads b/gcc/ada/libgnat/s-expllu.ads index 98fc85121e6d..3e2b2a7cce0b 100644 --- a/gcc/ada/libgnat/s-expllu.ads +++ b/gcc/ada/libgnat/s-expllu.ads @@ -34,24 +34,12 @@ -- is always full width, the caller must do a masking operation if the -- modulus is less than 2 ** (Long_Long_Unsigned'Size). --- Note: preconditions in this unit are meant for analysis only, not for --- run-time checking, so that the expected exceptions are raised. This is --- enforced by setting the corresponding assertion policy to Ignore. --- Postconditions and contract cases should not be executed at run-time as --- well, in order not to slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - with System.Exponu; with System.Unsigned_Types; package System.Exp_LLU with SPARK_Mode is - subtype Long_Long_Unsigned is Unsigned_Types.Long_Long_Unsigned; function Exp_Long_Long_Unsigned is new Exponu (Long_Long_Unsigned); diff --git a/gcc/ada/libgnat/s-expmod.adb b/gcc/ada/libgnat/s-expmod.adb index 28c07a1f7fa7..16d6b5f09b61 100644 --- a/gcc/ada/libgnat/s-expmod.adb +++ b/gcc/ada/libgnat/s-expmod.adb @@ -29,203 +29,11 @@ -- -- ------------------------------------------------------------------------------ --- Preconditions, postconditions, ghost code, loop invariants and assertions --- in this unit are meant for analysis only, not for run-time checking, as it --- would be too costly otherwise. This is enforced by setting the assertion --- policy to Ignore. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - -with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; -use Ada.Numerics.Big_Numbers.Big_Integers_Ghost; - package body System.Exp_Mod with SPARK_Mode is use System.Unsigned_Types; - -- Local lemmas - - procedure Lemma_Add_Mod (X, Y : Big_Natural; B : Big_Positive) - with - Ghost, - Post => (X + Y) mod B = ((X mod B) + (Y mod B)) mod B; - - procedure Lemma_Exp_Expand (A : Big_Integer; Exp : Natural) - with - Ghost, - Post => - (if Exp rem 2 = 0 then - A ** Exp = A ** (Exp / 2) * A ** (Exp / 2) - else - A ** Exp = A ** (Exp / 2) * A ** (Exp / 2) * A); - - procedure Lemma_Exp_Mod (A : Big_Natural; Exp : Natural; B : Big_Positive) - with - Ghost, - Subprogram_Variant => (Decreases => Exp), - Post => ((A mod B) ** Exp) mod B = (A ** Exp) mod B; - - procedure Lemma_Mod_Ident (A : Big_Natural; B : Big_Positive) - with - Ghost, - Pre => A < B, - Post => A mod B = A; - - procedure Lemma_Mod_Mod (A : Big_Integer; B : Big_Positive) - with - Ghost, - Post => A mod B mod B = A mod B; - - procedure Lemma_Mult_Div (X : Big_Natural; Y : Big_Positive) - with - Ghost, - Post => X * Y / Y = X; - - procedure Lemma_Mult_Mod (X, Y : Big_Natural; B : Big_Positive) - with - Ghost, - -- The following subprogram variant can be added as soon as supported - -- Subprogram_Variant => (Decreases => Y), - Post => (X * Y) mod B = ((X mod B) * (Y mod B)) mod B; - - ----------------------------- - -- Local lemma null bodies -- - ----------------------------- - - procedure Lemma_Mod_Ident (A : Big_Natural; B : Big_Positive) is null; - procedure Lemma_Mod_Mod (A : Big_Integer; B : Big_Positive) is null; - procedure Lemma_Mult_Div (X : Big_Natural; Y : Big_Positive) is null; - - ------------------- - -- Lemma_Add_Mod -- - ------------------- - - procedure Lemma_Add_Mod (X, Y : Big_Natural; B : Big_Positive) is - - procedure Lemma_Euclidean_Mod (Q, F, R : Big_Natural) with - Pre => F /= 0, - Post => (Q * F + R) mod F = R mod F, - Subprogram_Variant => (Decreases => Q); - - ------------------------- - -- Lemma_Euclidean_Mod -- - ------------------------- - - procedure Lemma_Euclidean_Mod (Q, F, R : Big_Natural) is - begin - if Q > 0 then - Lemma_Euclidean_Mod (Q - 1, F, R); - end if; - end Lemma_Euclidean_Mod; - - -- Local variables - - Left : constant Big_Natural := (X + Y) mod B; - Right : constant Big_Natural := ((X mod B) + (Y mod B)) mod B; - XQuot : constant Big_Natural := X / B; - YQuot : constant Big_Natural := Y / B; - AQuot : constant Big_Natural := (X mod B + Y mod B) / B; - begin - if Y /= 0 and B > 1 then - pragma Assert (X = XQuot * B + X mod B); - pragma Assert (Y = YQuot * B + Y mod B); - pragma Assert - (Left = ((XQuot + YQuot) * B + X mod B + Y mod B) mod B); - pragma Assert (X mod B + Y mod B = AQuot * B + Right); - pragma Assert (Left = ((XQuot + YQuot + AQuot) * B + Right) mod B); - Lemma_Euclidean_Mod (XQuot + YQuot + AQuot, B, Right); - pragma Assert (Left = (Right mod B)); - pragma Assert (Left = Right); - end if; - end Lemma_Add_Mod; - - ---------------------- - -- Lemma_Exp_Expand -- - ---------------------- - - procedure Lemma_Exp_Expand (A : Big_Integer; Exp : Natural) is - - procedure Lemma_Exp_Distribution (Exp_1, Exp_2 : Natural) with - Pre => Natural'Last - Exp_2 >= Exp_1, - Post => A ** (Exp_1 + Exp_2) = A ** (Exp_1) * A ** (Exp_2); - - ---------------------------- - -- Lemma_Exp_Distribution -- - ---------------------------- - - procedure Lemma_Exp_Distribution (Exp_1, Exp_2 : Natural) is null; - - begin - if Exp rem 2 = 0 then - pragma Assert (Exp = Exp / 2 + Exp / 2); - else - pragma Assert (Exp = Exp / 2 + Exp / 2 + 1); - Lemma_Exp_Distribution (Exp / 2, Exp / 2 + 1); - Lemma_Exp_Distribution (Exp / 2, 1); - end if; - end Lemma_Exp_Expand; - - ------------------- - -- Lemma_Exp_Mod -- - ------------------- - - procedure Lemma_Exp_Mod (A : Big_Natural; Exp : Natural; B : Big_Positive) - is - begin - if Exp /= 0 then - declare - Left : constant Big_Integer := ((A mod B) ** Exp) mod B; - Right : constant Big_Integer := (A ** Exp) mod B; - begin - Lemma_Mult_Mod (A mod B, (A mod B) ** (Exp - 1), B); - Lemma_Mod_Mod (A, B); - Lemma_Exp_Mod (A, Exp - 1, B); - Lemma_Mult_Mod (A, A ** (Exp - 1), B); - pragma Assert - ((A mod B) * (A mod B) ** (Exp - 1) = (A mod B) ** Exp); - pragma Assert (A * A ** (Exp - 1) = A ** Exp); - pragma Assert (Left = Right); - end; - end if; - end Lemma_Exp_Mod; - - -------------------- - -- Lemma_Mult_Mod -- - -------------------- - - procedure Lemma_Mult_Mod (X, Y : Big_Natural; B : Big_Positive) is - Left : constant Big_Natural := (X * Y) mod B; - Right : constant Big_Natural := ((X mod B) * (Y mod B)) mod B; - begin - if Y /= 0 and B > 1 then - Lemma_Add_Mod (X * (Y - 1), X, B); - Lemma_Mult_Mod (X, Y - 1, B); - Lemma_Mod_Mod (X, B); - Lemma_Add_Mod ((X mod B) * ((Y - 1) mod B), X mod B, B); - Lemma_Add_Mod (Y - 1, 1, B); - pragma Assert (((Y - 1) mod B + 1) mod B = Y mod B); - if (Y - 1) mod B + 1 < B then - Lemma_Mod_Ident ((Y - 1) mod B + 1, B); - Lemma_Mod_Mod ((X mod B) * (Y mod B), B); - pragma Assert (Left = Right); - else - pragma Assert (Y mod B = 0); - pragma Assert (Y / B * B = Y); - pragma Assert ((X * Y) mod B = (X * Y) - (X * Y) / B * B); - pragma Assert - ((X * Y) mod B = (X * Y) - (X * (Y / B) * B) / B * B); - Lemma_Mult_Div (X * (Y / B), B); - pragma Assert (Left = 0); - pragma Assert (Left = Right); - end if; - end if; - end Lemma_Mult_Mod; - ----------------- -- Exp_Modular -- ----------------- @@ -241,35 +49,7 @@ is function Mult (X, Y : Unsigned) return Unsigned is (Unsigned (Long_Long_Unsigned (X) * Long_Long_Unsigned (Y) - mod Long_Long_Unsigned (Modulus))) - with - Pre => Modulus /= 0; - -- Modular multiplication. Note that we can't take advantage of the - -- compiler's circuit, because the modulus is not known statically. - - -- Local ghost variables, functions and lemmas - - M : constant Big_Positive := Big (Modulus) with Ghost; - - function Equal_Modulo (X, Y : Big_Integer) return Boolean is - (X mod M = Y mod M) - with - Ghost, - Pre => Modulus /= 0; - - procedure Lemma_Mult (X, Y : Unsigned) - with - Ghost, - Post => Big (Mult (X, Y)) = (Big (X) * Big (Y)) mod M - and then Big (Mult (X, Y)) < M; - - procedure Lemma_Mult (X, Y : Unsigned) is - begin - pragma Assert (Big (Mult (X, Y)) = (Big (X) * Big (Y)) mod M); - end Lemma_Mult; - - Rest : Big_Integer with Ghost; - -- Ghost variable to hold Factor**Exp between Exp and Factor updates + mod Long_Long_Unsigned (Modulus))); begin pragma Assert (Modulus /= 1); @@ -284,72 +64,18 @@ is if Exp /= 0 then loop - pragma Loop_Invariant (Exp > 0); - pragma Loop_Invariant (Result < Modulus); - pragma Loop_Invariant (Equal_Modulo - (Big (Result) * Big (Factor) ** Exp, Big (Left) ** Right)); - pragma Loop_Variant (Decreases => Exp); - if Exp rem 2 /= 0 then - pragma Assert - (Big (Factor) ** Exp - = Big (Factor) * Big (Factor) ** (Exp - 1)); - pragma Assert (Equal_Modulo - ((Big (Result) * Big (Factor)) * Big (Factor) ** (Exp - 1), - Big (Left) ** Right)); - pragma Assert (Big (Factor) >= 0); - Lemma_Mult_Mod (Big (Result) * Big (Factor), - Big (Factor) ** (Exp - 1), - Big (Modulus)); - Lemma_Mult (Result, Factor); - Result := Mult (Result, Factor); - - Lemma_Mod_Ident (Big (Result), Big (Modulus)); - Lemma_Mod_Mod (Big (Factor) ** (Exp - 1), Big (Modulus)); - Lemma_Mult_Mod (Big (Result), - Big (Factor) ** (Exp - 1), - Big (Modulus)); - pragma Assert (Equal_Modulo - (Big (Result) * Big (Factor) ** (Exp - 1), - Big (Left) ** Right)); - Lemma_Exp_Expand (Big (Factor), Exp - 1); - pragma Assert (Exp / 2 = (Exp - 1) / 2); end if; - Lemma_Exp_Expand (Big (Factor), Exp); - Exp := Exp / 2; exit when Exp = 0; - Rest := Big (Factor) ** Exp; - pragma Assert (Equal_Modulo - (Big (Result) * (Rest * Rest), Big (Left) ** Right)); - Lemma_Exp_Mod (Big (Factor) * Big (Factor), Exp, Big (Modulus)); - pragma Assert - ((Big (Factor) * Big (Factor)) ** Exp = Rest * Rest); - pragma Assert (Equal_Modulo - ((Big (Factor) * Big (Factor)) ** Exp, - Rest * Rest)); - Lemma_Mult (Factor, Factor); - Factor := Mult (Factor, Factor); - - Lemma_Mod_Mod (Rest * Rest, Big (Modulus)); - Lemma_Mod_Ident (Big (Result), Big (Modulus)); - Lemma_Mult_Mod (Big (Result), Rest * Rest, Big (Modulus)); - pragma Assert (Big (Factor) >= 0); - Lemma_Mult_Mod (Big (Result), Big (Factor) ** Exp, - Big (Modulus)); - pragma Assert (Equal_Modulo - (Big (Result) * Big (Factor) ** Exp, Big (Left) ** Right)); end loop; - - pragma Assert (Big (Result) = Big (Left) ** Right mod Big (Modulus)); end if; return Result; - end Exp_Modular; end System.Exp_Mod; diff --git a/gcc/ada/libgnat/s-expmod.ads b/gcc/ada/libgnat/s-expmod.ads index 47ba39eaef6c..509ffa4111fc 100644 --- a/gcc/ada/libgnat/s-expmod.ads +++ b/gcc/ada/libgnat/s-expmod.ads @@ -36,19 +36,6 @@ -- Note that 1 is a binary modulus (2**0), so the compiler should not (and -- will not) call this function with Modulus equal to 1. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - -with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; - with System.Unsigned_Types; package System.Exp_Mod @@ -57,30 +44,10 @@ is use type System.Unsigned_Types.Unsigned; subtype Unsigned is System.Unsigned_Types.Unsigned; - use type Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Big_Integer; - subtype Big_Integer is - Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Big_Integer - with Ghost; - - package Unsigned_Conversion is - new Ada.Numerics.Big_Numbers.Big_Integers_Ghost.Unsigned_Conversions - (Int => Unsigned); - - function Big (Arg : Unsigned) return Big_Integer is - (Unsigned_Conversion.To_Big_Integer (Arg)) - with Ghost; - - subtype Power_Of_2 is Unsigned with - Dynamic_Predicate => - Power_Of_2 /= 0 and then (Power_Of_2 and (Power_Of_2 - 1)) = 0; - function Exp_Modular (Left : Unsigned; Modulus : Unsigned; - Right : Natural) return Unsigned - with - Pre => Modulus /= 0 and then Modulus not in Power_Of_2, - Post => Big (Exp_Modular'Result) = Big (Left) ** Right mod Big (Modulus); + Right : Natural) return Unsigned; -- Return the power of ``Left`` by ``Right` modulo ``Modulus``. -- -- This function is implemented using the standard logarithmic approach: diff --git a/gcc/ada/libgnat/s-exponn.adb b/gcc/ada/libgnat/s-exponn.adb index ff79f5acc30a..2aeb199be78c 100644 --- a/gcc/ada/libgnat/s-exponn.adb +++ b/gcc/ada/libgnat/s-exponn.adb @@ -32,65 +32,6 @@ package body System.Exponn with SPARK_Mode is - - -- Preconditions, postconditions, ghost code, loop invariants and - -- assertions in this unit are meant for analysis only, not for run-time - -- checking, as it would be too costly otherwise. This is enforced by - -- setting the assertion policy to Ignore. - - pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - - -- Local lemmas - - procedure Lemma_Exp_Expand (A : Big_Integer; Exp : Natural) - with - Ghost, - Pre => A /= 0, - Post => - (if Exp rem 2 = 0 then - A ** Exp = A ** (Exp / 2) * A ** (Exp / 2) - else - A ** Exp = A ** (Exp / 2) * A ** (Exp / 2) * A); - - procedure Lemma_Exp_In_Range (A : Big_Integer; Exp : Positive) - with - Ghost, - Pre => In_Int_Range (A ** Exp * A ** Exp), - Post => In_Int_Range (A * A); - - procedure Lemma_Exp_Not_Zero (A : Big_Integer; Exp : Natural) - with - Ghost, - Pre => A /= 0, - Post => A ** Exp /= 0; - - procedure Lemma_Exp_Positive (A : Big_Integer; Exp : Natural) - with - Ghost, - Pre => A /= 0 - and then Exp rem 2 = 0, - Post => A ** Exp > 0; - - procedure Lemma_Mult_In_Range (X, Y, Z : Big_Integer) - with - Ghost, - Pre => Y /= 0 - and then not (X = -Big (Int'First) and Y = -1) - and then X * Y = Z - and then In_Int_Range (Z), - Post => In_Int_Range (X); - - ----------------------------- - -- Local lemma null bodies -- - ----------------------------- - - procedure Lemma_Exp_Not_Zero (A : Big_Integer; Exp : Natural) is null; - procedure Lemma_Mult_In_Range (X, Y, Z : Big_Integer) is null; - ----------- -- Expon -- ----------- @@ -104,13 +45,7 @@ is Factor : Int := Left; Exp : Natural := Right; - Rest : Big_Integer with Ghost; - -- Ghost variable to hold Factor**Exp between Exp and Factor updates - begin - pragma Annotate (Gnatcheck, Exempt_On, "Improper_Returns", - "early returns for performance"); - -- We use the standard logarithmic approach, Exp gets shifted right -- testing successive low order bits and Factor is the value of the -- base raised to the next power of 2. @@ -122,117 +57,31 @@ is -- simpler, so we do it. if Right = 0 then - return 1; + Result := 1; elsif Left = 0 then - return 0; - end if; - - loop - pragma Loop_Invariant (Exp > 0); - pragma Loop_Invariant (Factor /= 0); - pragma Loop_Invariant - (Big (Result) * Big (Factor) ** Exp = Big (Left) ** Right); - pragma Loop_Variant (Decreases => Exp); + Result := 0; + else + loop + if Exp rem 2 /= 0 then + declare + pragma Suppress (Overflow_Check); + begin + Result := Result * Factor; + end; + end if; + + Exp := Exp / 2; + exit when Exp = 0; - if Exp rem 2 /= 0 then declare pragma Suppress (Overflow_Check); begin - pragma Assert - (Big (Factor) ** Exp - = Big (Factor) * Big (Factor) ** (Exp - 1)); - Lemma_Exp_Positive (Big (Factor), Exp - 1); - Lemma_Mult_In_Range (Big (Result) * Big (Factor), - Big (Factor) ** (Exp - 1), - Big (Left) ** Right); - - Result := Result * Factor; + Factor := Factor * Factor; end; - end if; - - Lemma_Exp_Expand (Big (Factor), Exp); - - Exp := Exp / 2; - exit when Exp = 0; - - Rest := Big (Factor) ** Exp; - pragma Assert - (Big (Result) * (Rest * Rest) = Big (Left) ** Right); - - declare - pragma Suppress (Overflow_Check); - begin - Lemma_Mult_In_Range (Rest * Rest, - Big (Result), - Big (Left) ** Right); - Lemma_Exp_In_Range (Big (Factor), Exp); - - Factor := Factor * Factor; - end; - - pragma Assert (Big (Factor) ** Exp = Rest * Rest); - end loop; - - pragma Assert (Big (Result) = Big (Left) ** Right); + end loop; + end if; return Result; - - pragma Annotate (Gnatcheck, Exempt_Off, "Improper_Returns"); end Expon; - ---------------------- - -- Lemma_Exp_Expand -- - ---------------------- - - procedure Lemma_Exp_Expand (A : Big_Integer; Exp : Natural) is - - procedure Lemma_Exp_Distribution (Exp_1, Exp_2 : Natural) with - Pre => A /= 0 and then Natural'Last - Exp_2 >= Exp_1, - Post => A ** (Exp_1 + Exp_2) = A ** (Exp_1) * A ** (Exp_2); - - ---------------------------- - -- Lemma_Exp_Distribution -- - ---------------------------- - - procedure Lemma_Exp_Distribution (Exp_1, Exp_2 : Natural) is null; - - begin - if Exp rem 2 = 0 then - pragma Assert (Exp = Exp / 2 + Exp / 2); - else - pragma Assert (Exp = Exp / 2 + Exp / 2 + 1); - Lemma_Exp_Distribution (Exp / 2, Exp / 2 + 1); - Lemma_Exp_Distribution (Exp / 2, 1); - end if; - end Lemma_Exp_Expand; - - ------------------------ - -- Lemma_Exp_In_Range -- - ------------------------ - - procedure Lemma_Exp_In_Range (A : Big_Integer; Exp : Positive) is - begin - if A /= 0 and Exp /= 1 then - pragma Assert (A ** Exp = A * A ** (Exp - 1)); - Lemma_Mult_In_Range - (A * A, A ** (Exp - 1) * A ** (Exp - 1), A ** Exp * A ** Exp); - end if; - end Lemma_Exp_In_Range; - - ------------------------ - -- Lemma_Exp_Positive -- - ------------------------ - - procedure Lemma_Exp_Positive (A : Big_Integer; Exp : Natural) is - begin - if Exp = 0 then - pragma Assert (A ** Exp = 1); - else - pragma Assert (Exp = 2 * (Exp / 2)); - pragma Assert (A ** Exp = A ** (Exp / 2) * A ** (Exp / 2)); - pragma Assert (A ** Exp = (A ** (Exp / 2)) ** 2); - Lemma_Exp_Not_Zero (A, Exp / 2); - end if; - end Lemma_Exp_Positive; - end System.Exponn; diff --git a/gcc/ada/libgnat/s-exponn.ads b/gcc/ada/libgnat/s-exponn.ads index 16bd393ea50d..94da5d27ee1b 100644 --- a/gcc/ada/libgnat/s-exponn.ads +++ b/gcc/ada/libgnat/s-exponn.ads @@ -32,44 +32,13 @@ -- This package provides functions for signed integer exponentiation. This -- is the version of the package with checks disabled. -with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; - generic - type Int is range <>; package System.Exponn with Pure, SPARK_Mode is - -- Preconditions in this unit are meant for analysis only, not for run-time - -- checking, so that the expected exceptions are raised. This is enforced - -- by setting the corresponding assertion policy to Ignore. Postconditions - -- and contract cases should not be executed at runtime as well, in order - -- not to slow down the execution of these functions. - - pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - - package BI_Ghost renames Ada.Numerics.Big_Numbers.Big_Integers_Ghost; - subtype Big_Integer is BI_Ghost.Big_Integer with Ghost; - use type BI_Ghost.Big_Integer; - - package Signed_Conversion is new BI_Ghost.Signed_Conversions (Int => Int); - - function Big (Arg : Int) return Big_Integer is - (Signed_Conversion.To_Big_Integer (Arg)) - with Ghost; - - function In_Int_Range (Arg : Big_Integer) return Boolean is - (BI_Ghost.In_Range (Arg, Big (Int'First), Big (Int'Last))) - with Ghost; - - function Expon (Left : Int; Right : Natural) return Int - with - Pre => In_Int_Range (Big (Left) ** Right), - Post => Expon'Result = Left ** Right; + function Expon (Left : Int; Right : Natural) return Int; -- Calculate ``Left`` ** ``Right``. If ``Left`` is 0 then 0 is returned -- and if ``Right`` is 0 then 1 is returned. In all other cases the result -- is set to 1 and then computed in a loop as follows: diff --git a/gcc/ada/libgnat/s-expont.adb b/gcc/ada/libgnat/s-expont.adb index 39476a9eaa4e..368dd0b01338 100644 --- a/gcc/ada/libgnat/s-expont.adb +++ b/gcc/ada/libgnat/s-expont.adb @@ -32,65 +32,6 @@ package body System.Expont with SPARK_Mode is - - -- Preconditions, postconditions, ghost code, loop invariants and - -- assertions in this unit are meant for analysis only, not for run-time - -- checking, as it would be too costly otherwise. This is enforced by - -- setting the assertion policy to Ignore. - - pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - - -- Local lemmas - - procedure Lemma_Exp_Expand (A : Big_Integer; Exp : Natural) - with - Ghost, - Pre => A /= 0, - Post => - (if Exp rem 2 = 0 then - A ** Exp = A ** (Exp / 2) * A ** (Exp / 2) - else - A ** Exp = A ** (Exp / 2) * A ** (Exp / 2) * A); - - procedure Lemma_Exp_In_Range (A : Big_Integer; Exp : Positive) - with - Ghost, - Pre => In_Int_Range (A ** Exp * A ** Exp), - Post => In_Int_Range (A * A); - - procedure Lemma_Exp_Not_Zero (A : Big_Integer; Exp : Natural) - with - Ghost, - Pre => A /= 0, - Post => A ** Exp /= 0; - - procedure Lemma_Exp_Positive (A : Big_Integer; Exp : Natural) - with - Ghost, - Pre => A /= 0 - and then Exp rem 2 = 0, - Post => A ** Exp > 0; - - procedure Lemma_Mult_In_Range (X, Y, Z : Big_Integer) - with - Ghost, - Pre => Y /= 0 - and then not (X = -Big (Int'First) and Y = -1) - and then X * Y = Z - and then In_Int_Range (Z), - Post => In_Int_Range (X); - - ----------------------------- - -- Local lemma null bodies -- - ----------------------------- - - procedure Lemma_Exp_Not_Zero (A : Big_Integer; Exp : Natural) is null; - procedure Lemma_Mult_In_Range (X, Y, Z : Big_Integer) is null; - ----------- -- Expon -- ----------- @@ -104,13 +45,7 @@ is Factor : Int := Left; Exp : Natural := Right; - Rest : Big_Integer with Ghost; - -- Ghost variable to hold Factor**Exp between Exp and Factor updates - begin - pragma Annotate (Gnatcheck, Exempt_On, "Improper_Returns", - "early returns for performance"); - -- We use the standard logarithmic approach, Exp gets shifted right -- testing successive low order bits and Factor is the value of the -- base raised to the next power of 2. @@ -122,117 +57,31 @@ is -- simpler, so we do it. if Right = 0 then - return 1; + Result := 1; elsif Left = 0 then - return 0; - end if; - - loop - pragma Loop_Invariant (Exp > 0); - pragma Loop_Invariant (Factor /= 0); - pragma Loop_Invariant - (Big (Result) * Big (Factor) ** Exp = Big (Left) ** Right); - pragma Loop_Variant (Decreases => Exp); + Result := 0; + else + loop + if Exp rem 2 /= 0 then + declare + pragma Unsuppress (Overflow_Check); + begin + Result := Result * Factor; + end; + end if; + + Exp := Exp / 2; + exit when Exp = 0; - if Exp rem 2 /= 0 then declare pragma Unsuppress (Overflow_Check); begin - pragma Assert - (Big (Factor) ** Exp - = Big (Factor) * Big (Factor) ** (Exp - 1)); - Lemma_Exp_Positive (Big (Factor), Exp - 1); - Lemma_Mult_In_Range (Big (Result) * Big (Factor), - Big (Factor) ** (Exp - 1), - Big (Left) ** Right); - - Result := Result * Factor; + Factor := Factor * Factor; end; - end if; - - Lemma_Exp_Expand (Big (Factor), Exp); - - Exp := Exp / 2; - exit when Exp = 0; - - Rest := Big (Factor) ** Exp; - pragma Assert - (Big (Result) * (Rest * Rest) = Big (Left) ** Right); - - declare - pragma Unsuppress (Overflow_Check); - begin - Lemma_Mult_In_Range (Rest * Rest, - Big (Result), - Big (Left) ** Right); - Lemma_Exp_In_Range (Big (Factor), Exp); - - Factor := Factor * Factor; - end; - - pragma Assert (Big (Factor) ** Exp = Rest * Rest); - end loop; - - pragma Assert (Big (Result) = Big (Left) ** Right); + end loop; + end if; return Result; - - pragma Annotate (Gnatcheck, Exempt_Off, "Improper_Returns"); end Expon; - ---------------------- - -- Lemma_Exp_Expand -- - ---------------------- - - procedure Lemma_Exp_Expand (A : Big_Integer; Exp : Natural) is - - procedure Lemma_Exp_Distribution (Exp_1, Exp_2 : Natural) with - Pre => A /= 0 and then Natural'Last - Exp_2 >= Exp_1, - Post => A ** (Exp_1 + Exp_2) = A ** (Exp_1) * A ** (Exp_2); - - ---------------------------- - -- Lemma_Exp_Distribution -- - ---------------------------- - - procedure Lemma_Exp_Distribution (Exp_1, Exp_2 : Natural) is null; - - begin - if Exp rem 2 = 0 then - pragma Assert (Exp = Exp / 2 + Exp / 2); - else - pragma Assert (Exp = Exp / 2 + Exp / 2 + 1); - Lemma_Exp_Distribution (Exp / 2, Exp / 2 + 1); - Lemma_Exp_Distribution (Exp / 2, 1); - end if; - end Lemma_Exp_Expand; - - ------------------------ - -- Lemma_Exp_In_Range -- - ------------------------ - - procedure Lemma_Exp_In_Range (A : Big_Integer; Exp : Positive) is - begin - if A /= 0 and Exp /= 1 then - pragma Assert (A ** Exp = A * A ** (Exp - 1)); - Lemma_Mult_In_Range - (A * A, A ** (Exp - 1) * A ** (Exp - 1), A ** Exp * A ** Exp); - end if; - end Lemma_Exp_In_Range; - - ------------------------ - -- Lemma_Exp_Positive -- - ------------------------ - - procedure Lemma_Exp_Positive (A : Big_Integer; Exp : Natural) is - begin - if Exp = 0 then - pragma Assert (A ** Exp = 1); - else - pragma Assert (Exp = 2 * (Exp / 2)); - pragma Assert (A ** Exp = A ** (Exp / 2) * A ** (Exp / 2)); - pragma Assert (A ** Exp = (A ** (Exp / 2)) ** 2); - Lemma_Exp_Not_Zero (A, Exp / 2); - end if; - end Lemma_Exp_Positive; - end System.Expont; diff --git a/gcc/ada/libgnat/s-expont.ads b/gcc/ada/libgnat/s-expont.ads index 880e05459222..2cf6dc0cdabf 100644 --- a/gcc/ada/libgnat/s-expont.ads +++ b/gcc/ada/libgnat/s-expont.ads @@ -32,44 +32,13 @@ -- This package provides functions for signed integer exponentiation. This -- is the version of the package with checks enabled. -with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; - generic - type Int is range <>; package System.Expont with Pure, SPARK_Mode is - -- Preconditions in this unit are meant for analysis only, not for run-time - -- checking, so that the expected exceptions are raised. This is enforced - -- by setting the corresponding assertion policy to Ignore. Postconditions - -- and contract cases should not be executed at runtime as well, in order - -- not to slow down the execution of these functions. - - pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - - package BI_Ghost renames Ada.Numerics.Big_Numbers.Big_Integers_Ghost; - subtype Big_Integer is BI_Ghost.Big_Integer with Ghost; - use type BI_Ghost.Big_Integer; - - package Signed_Conversion is new BI_Ghost.Signed_Conversions (Int => Int); - - function Big (Arg : Int) return Big_Integer is - (Signed_Conversion.To_Big_Integer (Arg)) - with Ghost; - - function In_Int_Range (Arg : Big_Integer) return Boolean is - (BI_Ghost.In_Range (Arg, Big (Int'First), Big (Int'Last))) - with Ghost; - - function Expon (Left : Int; Right : Natural) return Int - with - Pre => In_Int_Range (Big (Left) ** Right), - Post => Expon'Result = Left ** Right; + function Expon (Left : Int; Right : Natural) return Int; -- Calculate ``Left`` ** ``Right``. If ``Left`` is 0 then 0 is returned -- and if ``Right`` is 0 then 1 is returned. In all other cases the result -- is set to 1 and then computed in a loop as follows: diff --git a/gcc/ada/libgnat/s-exponu.adb b/gcc/ada/libgnat/s-exponu.adb index abb19307b5dd..0c528333f15b 100644 --- a/gcc/ada/libgnat/s-exponu.adb +++ b/gcc/ada/libgnat/s-exponu.adb @@ -29,20 +29,7 @@ -- -- ------------------------------------------------------------------------------ -function System.Exponu (Left : Int; Right : Natural) return Int - with SPARK_Mode -is - -- Preconditions, postconditions, ghost code, loop invariants and - -- assertions in this unit are meant for analysis only, not for run-time - -- checking, as it would be too costly otherwise. This is enforced by - -- setting the assertion policy to Ignore. - - pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - +function System.Exponu (Left : Int; Right : Natural) return Int is -- Note that negative exponents get a constraint error because the -- subtype of the Right argument (the exponent) is Natural. @@ -61,16 +48,7 @@ begin if Exp /= 0 then loop - pragma Loop_Invariant (Exp > 0); - pragma Loop_Invariant (Result * Factor ** Exp = Left ** Right); - pragma Loop_Variant (Decreases => Exp); - if Exp rem 2 /= 0 then - pragma Assert - (Result * (Factor * Factor ** (Exp - 1)) = Left ** Right); - pragma Assert - ((Result * Factor) * Factor ** (Exp - 1) = Left ** Right); - Result := Result * Factor; end if; diff --git a/gcc/ada/libgnat/s-exponu.ads b/gcc/ada/libgnat/s-exponu.ads index cfa6d78b7ec7..7cc2f9c46659 100644 --- a/gcc/ada/libgnat/s-exponu.ads +++ b/gcc/ada/libgnat/s-exponu.ads @@ -31,25 +31,10 @@ -- This function implements unsigned integer exponentiation --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced --- by setting the corresponding assertion policy to Ignore. Postconditions --- and contract cases should not be executed at runtime as well, in order --- not to slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - generic - type Int is mod <>; -function System.Exponu (Left : Int; Right : Natural) return Int -with - SPARK_Mode, - Post => System.Exponu'Result = Left ** Right; +function System.Exponu (Left : Int; Right : Natural) return Int; -- Calculate ``Left`` ** ``Right``. If ``Left`` is 0 then 0 is returned -- and if ``Right`` is 0 then 1 is returned. In all other cases the result -- is set to 1 and then computed in a loop as follows: diff --git a/gcc/ada/libgnat/s-expuns.ads b/gcc/ada/libgnat/s-expuns.ads index 98ad60787be6..d1dcc25b2c3c 100644 --- a/gcc/ada/libgnat/s-expuns.ads +++ b/gcc/ada/libgnat/s-expuns.ads @@ -35,24 +35,12 @@ -- The result is always full width, the caller must do a masking operation -- the modulus is less than 2 ** (Unsigned'Size). --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced --- by setting the corresponding assertion policy to Ignore. Postconditions --- and contract cases should not be executed at runtime as well, in order --- not to slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - with System.Exponu; with System.Unsigned_Types; package System.Exp_Uns with SPARK_Mode is - subtype Unsigned is Unsigned_Types.Unsigned; function Exp_Unsigned is new Exponu (Unsigned); diff --git a/gcc/ada/libgnat/s-imaged.adb b/gcc/ada/libgnat/s-imaged.adb index 34c15b0afce1..638e37b4b772 100644 --- a/gcc/ada/libgnat/s-imaged.adb +++ b/gcc/ada/libgnat/s-imaged.adb @@ -31,33 +31,10 @@ with System.Image_I; with System.Img_Util; use System.Img_Util; -with System.Value_I_Spec; -with System.Value_U_Spec; package body System.Image_D is - -- Contracts, ghost code, loop invariants and assertions in this unit are - -- meant for analysis only, not for run-time checking, as it would be too - -- costly otherwise. This is enforced by setting the assertion policy to - -- Ignore. - - pragma Assertion_Policy (Assert => Ignore, - Assert_And_Cut => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore, - Pre => Ignore, - Post => Ignore, - Subprogram_Variant => Ignore); - - package Uns_Spec is new System.Value_U_Spec (Uns); - package Int_Spec is new System.Value_I_Spec (Int, Uns, Uns_Spec); - - package Image_I is new System.Image_I - (Int => Int, - Uns => Uns, - U_Spec => Uns_Spec, - I_Spec => Int_Spec); + package Image_I is new System.Image_I (Int); procedure Set_Image_Integer (V : Int; @@ -76,7 +53,6 @@ package body System.Image_D is Scale : Integer) is pragma Assert (S'First = 1); - begin -- Add space at start for non-negative numbers diff --git a/gcc/ada/libgnat/s-imaged.ads b/gcc/ada/libgnat/s-imaged.ads index 1b83a678baa9..48d4b002cc90 100644 --- a/gcc/ada/libgnat/s-imaged.ads +++ b/gcc/ada/libgnat/s-imaged.ads @@ -34,10 +34,7 @@ -- types. generic - type Int is range <>; - type Uns is mod <>; - package System.Image_D is procedure Image_Decimal diff --git a/gcc/ada/libgnat/s-imagef.adb b/gcc/ada/libgnat/s-imagef.adb index 00b4ac558f56..c84f424b7724 100644 --- a/gcc/ada/libgnat/s-imagef.adb +++ b/gcc/ada/libgnat/s-imagef.adb @@ -31,25 +31,9 @@ with System.Image_I; with System.Img_Util; use System.Img_Util; -with System.Value_I_Spec; -with System.Value_U_Spec; package body System.Image_F is - -- Contracts, ghost code, loop invariants and assertions in this unit are - -- meant for analysis only, not for run-time checking, as it would be too - -- costly otherwise. This is enforced by setting the assertion policy to - -- Ignore. - - pragma Assertion_Policy (Assert => Ignore, - Assert_And_Cut => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Loop_Invariant => Ignore, - Pre => Ignore, - Post => Ignore, - Subprogram_Variant => Ignore); - Maxdigs : constant Natural := Int'Width - 2; -- Maximum number of decimal digits that can be represented in an Int. -- The "-2" accounts for the sign and one extra digit, since we need the @@ -70,14 +54,7 @@ package body System.Image_F is -- if the small is larger than 1, and smaller than 2**(Int'Size - 1) / 10 -- if the small is smaller than 1. - package Uns_Spec is new System.Value_U_Spec (Uns); - package Int_Spec is new System.Value_I_Spec (Int, Uns, Uns_Spec); - - package Image_I is new System.Image_I - (Int => Int, - Uns => Uns, - U_Spec => Uns_Spec, - I_Spec => Int_Spec); + package Image_I is new System.Image_I (Int); procedure Set_Image_Integer (V : Int; @@ -233,7 +210,6 @@ package body System.Image_F is Aft0 : Natural) is pragma Assert (S'First = 1); - begin -- Add space at start for non-negative numbers diff --git a/gcc/ada/libgnat/s-imagef.ads b/gcc/ada/libgnat/s-imagef.ads index fea63c67e3ac..f73eed804099 100644 --- a/gcc/ada/libgnat/s-imagef.ads +++ b/gcc/ada/libgnat/s-imagef.ads @@ -34,9 +34,7 @@ -- point types whose Small is the ratio of two Int values. generic - type Int is range <>; - type Uns is mod <>; with procedure Scaled_Divide (X, Y, Z : Int; diff --git a/gcc/ada/libgnat/s-imagei.adb b/gcc/ada/libgnat/s-imagei.adb index e6aaf83aee4a..0f2211b48055 100644 --- a/gcc/ada/libgnat/s-imagei.adb +++ b/gcc/ada/libgnat/s-imagei.adb @@ -29,106 +29,18 @@ -- -- ------------------------------------------------------------------------------ -with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; -use Ada.Numerics.Big_Numbers.Big_Integers_Ghost; - -with System.Val_Spec; - package body System.Image_I is - -- Ghost code, loop invariants and assertions in this unit are meant for - -- analysis only, not for run-time checking, as it would be too costly - -- otherwise. This is enforced by setting the assertion policy to Ignore. - - pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore, - Assert_And_Cut => Ignore, - Pre => Ignore, - Post => Ignore, - Subprogram_Variant => Ignore); - subtype Non_Positive is Int range Int'First .. 0; - function Uns_Of_Non_Positive (T : Non_Positive) return Uns is - (if T = Int'First then Uns (Int'Last) + 1 else Uns (-T)); - procedure Set_Digits (T : Non_Positive; S : in out String; - P : in out Natural) - with - Pre => P < Integer'Last - and then S'Last < Integer'Last - and then S'First <= P + 1 - and then S'First <= S'Last - and then P <= S'Last - Unsigned_Width_Ghost + 1, - Post => S (S'First .. P'Old) = S'Old (S'First .. P'Old) - and then P in P'Old + 1 .. S'Last - and then UP.Only_Decimal_Ghost (S, From => P'Old + 1, To => P) - and then UP.Scan_Based_Number_Ghost (S, From => P'Old + 1, To => P) - = UP.Wrap_Option (Uns_Of_Non_Positive (T)); + P : in out Natural); -- Set digits of absolute value of T, which is zero or negative. We work -- with the negative of the value so that the largest negative number is -- not a special case. - package Unsigned_Conversion is new Unsigned_Conversions (Int => Uns); - - function Big (Arg : Uns) return Big_Integer renames - Unsigned_Conversion.To_Big_Integer; - - function From_Big (Arg : Big_Integer) return Uns renames - Unsigned_Conversion.From_Big_Integer; - - Big_10 : constant Big_Integer := Big (10) with Ghost; - - ------------------ - -- Local Lemmas -- - ------------------ - - procedure Lemma_Non_Zero (X : Uns) - with - Ghost, - Pre => X /= 0, - Post => Big (X) /= 0; - - procedure Lemma_Div_Commutation (X, Y : Uns) - with - Ghost, - Pre => Y /= 0, - Post => Big (X) / Big (Y) = Big (X / Y); - - procedure Lemma_Div_Twice (X : Big_Natural; Y, Z : Big_Positive) - with - Ghost, - Post => X / Y / Z = X / (Y * Z); - - --------------------------- - -- Lemma_Div_Commutation -- - --------------------------- - - procedure Lemma_Non_Zero (X : Uns) is null; - procedure Lemma_Div_Commutation (X, Y : Uns) is null; - - --------------------- - -- Lemma_Div_Twice -- - --------------------- - - procedure Lemma_Div_Twice (X : Big_Natural; Y, Z : Big_Positive) is - XY : constant Big_Natural := X / Y; - YZ : constant Big_Natural := Y * Z; - XYZ : constant Big_Natural := X / Y / Z; - R : constant Big_Natural := (XY rem Z) * Y + (X rem Y); - begin - pragma Assert (X = XY * Y + (X rem Y)); - pragma Assert (XY = XY / Z * Z + (XY rem Z)); - pragma Assert (X = XYZ * YZ + R); - pragma Assert ((XY rem Z) * Y <= (Z - 1) * Y); - pragma Assert (R <= YZ - 1); - pragma Assert (X / YZ = (XYZ * YZ + R) / YZ); - pragma Assert (X / YZ = XYZ + R / YZ); - end Lemma_Div_Twice; - ------------------- -- Image_Integer -- ------------------- @@ -139,44 +51,6 @@ package body System.Image_I is P : out Natural) is pragma Assert (S'First = 1); - - procedure Prove_Value_Integer - with - Ghost, - Pre => S'First = 1 - and then S'Last < Integer'Last - and then P in 2 .. S'Last - and then S (1) in ' ' | '-' - and then (S (1) = '-') = (V < 0) - and then UP.Only_Decimal_Ghost (S, From => 2, To => P) - and then UP.Scan_Based_Number_Ghost (S, From => 2, To => P) - = UP.Wrap_Option (IP.Abs_Uns_Of_Int (V)), - Post => not System.Val_Spec.Only_Space_Ghost (S, 1, P) - and then IP.Is_Integer_Ghost (S (1 .. P)) - and then IP.Is_Value_Integer_Ghost (S (1 .. P), V); - -- Ghost lemma to prove the value of Value_Integer from the value of - -- Scan_Based_Number_Ghost and the sign on a decimal string. - - ------------------------- - -- Prove_Value_Integer -- - ------------------------- - - procedure Prove_Value_Integer is - Str : constant String := S (1 .. P); - begin - pragma Assert (Str'First = 1); - pragma Assert (Str (2) /= ' '); - pragma Assert - (UP.Only_Decimal_Ghost (Str, From => 2, To => P)); - UP.Prove_Scan_Based_Number_Ghost_Eq (S, Str, From => 2, To => P); - pragma Assert - (UP.Scan_Based_Number_Ghost (Str, From => 2, To => P) - = UP.Wrap_Option (IP.Abs_Uns_Of_Int (V))); - IP.Prove_Scan_Only_Decimal_Ghost (Str, V); - end Prove_Value_Integer; - - -- Start of processing for Image_Integer - begin if V >= 0 then pragma Annotate (CodePeer, False_Positive, "test always false", @@ -190,18 +64,7 @@ package body System.Image_I is pragma Assert (P < S'Last - 1); end if; - declare - P_Prev : constant Integer := P with Ghost; - Offset : constant Positive := (if V >= 0 then 1 else 2) with Ghost; - begin - Set_Image_Integer (V, S, P); - - pragma Assert (P_Prev + Offset = 2); - end; - pragma Assert (if V >= 0 then S (1) = ' '); - pragma Assert (S (1) in ' ' | '-'); - - Prove_Value_Integer; + Set_Image_Integer (V, S, P); end Image_Integer; ---------------- @@ -215,136 +78,6 @@ package body System.Image_I is is Nb_Digits : Natural := 0; Value : Non_Positive := T; - - -- Local ghost variables - - Pow : Big_Positive := 1 with Ghost; - S_Init : constant String := S with Ghost; - Uns_T : constant Uns := Uns_Of_Non_Positive (T) with Ghost; - Uns_Value : Uns := Uns_Of_Non_Positive (Value) with Ghost; - Prev_Value : Uns with Ghost; - Prev_S : String := S with Ghost; - - -- Local ghost lemmas - - procedure Prove_Character_Val (RU : Uns; RI : Non_Positive) - with - Ghost, - Post => RU rem 10 in 0 .. 9 - and then -(RI rem 10) in 0 .. 9 - and then Character'Val (48 + RU rem 10) in '0' .. '9' - and then Character'Val (48 - RI rem 10) in '0' .. '9'; - -- Ghost lemma to prove the value of a character corresponding to the - -- next figure. - - procedure Prove_Euclidian (Val, Quot, Rest : Uns) - with - Ghost, - Pre => Quot = Val / 10 - and then Rest = Val rem 10, - Post => Uns'Last - Rest >= 10 * Quot and then Val = 10 * Quot + Rest; - -- Ghost lemma to prove the relation between the quotient/remainder of - -- division by 10 and the initial value. - - procedure Prove_Hexa_To_Unsigned_Ghost (RU : Uns; RI : Int) - with - Ghost, - Pre => RU in 0 .. 9 - and then RI in 0 .. 9, - Post => UP.Hexa_To_Unsigned_Ghost - (Character'Val (48 + RU)) = RU - and then UP.Hexa_To_Unsigned_Ghost - (Character'Val (48 + RI)) = Uns (RI); - -- Ghost lemma to prove that Hexa_To_Unsigned_Ghost returns the source - -- figure when applied to the corresponding character. - - procedure Prove_Scan_Iter - (S, Prev_S : String; - V, Prev_V, Res : Uns; - P, Max : Natural) - with - Ghost, - Pre => - S'First = Prev_S'First and then S'Last = Prev_S'Last - and then S'Last < Natural'Last and then - Max in S'Range and then P in S'First .. Max and then - (for all I in P + 1 .. Max => Prev_S (I) in '0' .. '9') - and then (for all I in P + 1 .. Max => Prev_S (I) = S (I)) - and then S (P) in '0' .. '9' - and then V <= Uns'Last / 10 - and then Uns'Last - UP.Hexa_To_Unsigned_Ghost (S (P)) - >= 10 * V - and then Prev_V = - V * 10 + UP.Hexa_To_Unsigned_Ghost (S (P)) - and then - (if P = Max then Prev_V = Res - else UP.Scan_Based_Number_Ghost - (Str => Prev_S, - From => P + 1, - To => Max, - Base => 10, - Acc => Prev_V) = UP.Wrap_Option (Res)), - Post => - (for all I in P .. Max => S (I) in '0' .. '9') - and then UP.Scan_Based_Number_Ghost - (Str => S, - From => P, - To => Max, - Base => 10, - Acc => V) = UP.Wrap_Option (Res); - -- Ghost lemma to prove that Scan_Based_Number_Ghost is preserved - -- through an iteration of the loop. - - procedure Prove_Uns_Of_Non_Positive_Value - with - Ghost, - Pre => Uns_Value = Uns_Of_Non_Positive (Value), - Post => Uns_Value / 10 = Uns_Of_Non_Positive (Value / 10) - and then Uns_Value rem 10 = Uns_Of_Non_Positive (Value rem 10); - -- Ghost lemma to prove that the relation between Value and its unsigned - -- version is preserved. - - ----------------------------- - -- Local lemma null bodies -- - ----------------------------- - - procedure Prove_Character_Val (RU : Uns; RI : Non_Positive) is null; - procedure Prove_Euclidian (Val, Quot, Rest : Uns) is null; - procedure Prove_Hexa_To_Unsigned_Ghost (RU : Uns; RI : Int) is null; - procedure Prove_Uns_Of_Non_Positive_Value is null; - - --------------------- - -- Prove_Scan_Iter -- - --------------------- - - procedure Prove_Scan_Iter - (S, Prev_S : String; - V, Prev_V, Res : Uns; - P, Max : Natural) - is - pragma Unreferenced (Res); - begin - UP.Lemma_Scan_Based_Number_Ghost_Step - (Str => S, - From => P, - To => Max, - Base => 10, - Acc => V); - if P < Max then - UP.Prove_Scan_Based_Number_Ghost_Eq - (Prev_S, S, P + 1, Max, 10, Prev_V); - else - UP.Lemma_Scan_Based_Number_Ghost_Base - (Str => S, - From => P + 1, - To => Max, - Base => 10, - Acc => Prev_V); - end if; - end Prove_Scan_Iter; - - -- Start of processing for Set_Digits - begin pragma Assert (P >= S'First - 1 and P < S'Last); -- No check is done since, as documented in the Set_Image_Integer @@ -354,90 +87,20 @@ package body System.Image_I is -- First we compute the number of characters needed for representing -- the number. loop - Lemma_Div_Commutation (Uns_Of_Non_Positive (Value), 10); - Lemma_Div_Twice (Big (Uns_Of_Non_Positive (T)), - Big_10 ** Nb_Digits, Big_10); - Prove_Uns_Of_Non_Positive_Value; - Value := Value / 10; Nb_Digits := Nb_Digits + 1; - Uns_Value := Uns_Value / 10; - Pow := Pow * 10; - - pragma Loop_Invariant (Uns_Value = Uns_Of_Non_Positive (Value)); - pragma Loop_Invariant (Nb_Digits in 1 .. Unsigned_Width_Ghost - 1); - pragma Loop_Invariant (Pow = Big_10 ** Nb_Digits); - pragma Loop_Invariant (Big (Uns_Value) = Big (Uns_T) / Pow); - pragma Loop_Variant (Increases => Value); - exit when Value = 0; - - Lemma_Non_Zero (Uns_Value); - pragma Assert (Pow <= Big (Uns'Last)); end loop; Value := T; - Uns_Value := Uns_Of_Non_Positive (T); - Pow := 1; - - pragma Assert (Uns_Value = From_Big (Big (Uns_T) / Big_10 ** 0)); -- We now populate digits from the end of the string to the beginning for J in reverse 1 .. Nb_Digits loop - Lemma_Div_Commutation (Uns_Value, 10); - Lemma_Div_Twice (Big (Uns_T), Big_10 ** (Nb_Digits - J), Big_10); - Prove_Character_Val (Uns_Value, Value); - Prove_Hexa_To_Unsigned_Ghost (Uns_Value rem 10, -(Value rem 10)); - Prove_Uns_Of_Non_Positive_Value; - - Prev_Value := Uns_Value; - Prev_S := S; - Pow := Pow * 10; - Uns_Value := Uns_Value / 10; - S (P + J) := Character'Val (48 - (Value rem 10)); Value := Value / 10; - - Prove_Euclidian - (Val => Prev_Value, - Quot => Uns_Value, - Rest => UP.Hexa_To_Unsigned_Ghost (S (P + J))); - - Prove_Scan_Iter - (S, Prev_S, Uns_Value, Prev_Value, Uns_T, P + J, P + Nb_Digits); - - pragma Loop_Invariant (Uns_Value = Uns_Of_Non_Positive (Value)); - pragma Loop_Invariant (Uns_Value <= Uns'Last / 10); - pragma Loop_Invariant - (for all K in S'First .. P => S (K) = S_Init (K)); - pragma Loop_Invariant - (UP.Only_Decimal_Ghost (S, P + J, P + Nb_Digits)); - pragma Loop_Invariant - (for all K in P + J .. P + Nb_Digits => S (K) in '0' .. '9'); - pragma Loop_Invariant (Pow = Big_10 ** (Nb_Digits - J + 1)); - pragma Loop_Invariant (Big (Uns_Value) = Big (Uns_T) / Pow); - pragma Loop_Invariant - (UP.Scan_Based_Number_Ghost - (Str => S, - From => P + J, - To => P + Nb_Digits, - Base => 10, - Acc => Uns_Value) - = UP.Wrap_Option (Uns_T)); end loop; - pragma Assert (Big (Uns_Value) = Big (Uns_T) / Big_10 ** (Nb_Digits)); - pragma Assert (Uns_Value = 0); - pragma Assert - (UP.Scan_Based_Number_Ghost - (Str => S, - From => P + 1, - To => P + Nb_Digits, - Base => 10, - Acc => Uns_Value) - = UP.Wrap_Option (Uns_T)); - P := P + Nb_Digits; end Set_Digits; @@ -448,12 +111,10 @@ package body System.Image_I is procedure Set_Image_Integer (V : Int; S : in out String; - P : in out Natural) - is + P : in out Natural) is begin if V >= 0 then Set_Digits (-V, S, P); - else pragma Assert (P >= S'First - 1 and P < S'Last); -- No check is done since, as documented in the specification, diff --git a/gcc/ada/libgnat/s-imagei.ads b/gcc/ada/libgnat/s-imagei.ads index e500f745e0ee..8d3b9393bc7d 100644 --- a/gcc/ada/libgnat/s-imagei.ads +++ b/gcc/ada/libgnat/s-imagei.ads @@ -33,48 +33,14 @@ -- and ``Ada.Text_IO.Integer_IO`` conversions routines for signed integer -- types. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -with System.Value_I_Spec; -with System.Value_U_Spec; - generic type Int is range <>; - type Uns is mod <>; - - -- Additional parameters for ghost subprograms used inside contracts - - with package U_Spec is new System.Value_U_Spec (Uns => Uns) with Ghost; - with package I_Spec is new System.Value_I_Spec - (Int => Int, Uns => Uns, U_Spec => U_Spec) with Ghost; - package System.Image_I is - package IP renames I_Spec; - package UP renames U_Spec; - use type UP.Uns_Option; - - Unsigned_Width_Ghost : constant Natural := U_Spec.Max_Log10 + 2 with Ghost; procedure Image_Integer (V : Int; S : in out String; - P : out Natural) - with - Pre => S'First = 1 - and then S'Last < Integer'Last - and then S'Last >= Unsigned_Width_Ghost, - Post => P in S'Range - and then IP.Is_Value_Integer_Ghost (S (1 .. P), V); + P : out Natural); -- Computes Int'Image (V) and stores the result in S (1 .. P) -- setting the resulting value of P. The caller guarantees that S -- is long enough to hold the result, and that S'First is 1. @@ -82,31 +48,7 @@ package System.Image_I is procedure Set_Image_Integer (V : Int; S : in out String; - P : in out Natural) - with - Pre => P < Integer'Last - and then S'Last < Integer'Last - and then S'First <= P + 1 - and then S'First <= S'Last - and then - (if V >= 0 then - P <= S'Last - Unsigned_Width_Ghost + 1 - else - P <= S'Last - Unsigned_Width_Ghost), - Post => S (S'First .. P'Old) = S'Old (S'First .. P'Old) - and then - (declare - Minus : constant Boolean := S (P'Old + 1) = '-'; - Offset : constant Positive := (if V >= 0 then 1 else 2); - Abs_V : constant Uns := IP.Abs_Uns_Of_Int (V); - begin - Minus = (V < 0) - and then P in P'Old + Offset .. S'Last - and then UP.Only_Decimal_Ghost - (S, From => P'Old + Offset, To => P) - and then UP.Scan_Based_Number_Ghost - (S, From => P'Old + Offset, To => P) - = UP.Wrap_Option (Abs_V)); + P : in out Natural); -- Stores the image of V in S starting at S (P + 1), P is updated to point -- to the last character stored. The value stored is identical to the value -- of Int'Image (V) except that no leading space is stored when V is diff --git a/gcc/ada/libgnat/s-imageu.adb b/gcc/ada/libgnat/s-imageu.adb index 820156b8787b..a6cdfed09a60 100644 --- a/gcc/ada/libgnat/s-imageu.adb +++ b/gcc/ada/libgnat/s-imageu.adb @@ -29,79 +29,8 @@ -- -- ------------------------------------------------------------------------------ -with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; -use Ada.Numerics.Big_Numbers.Big_Integers_Ghost; -with System.Val_Spec; - package body System.Image_U is - -- Ghost code, loop invariants and assertions in this unit are meant for - -- analysis only, not for run-time checking, as it would be too costly - -- otherwise. This is enforced by setting the assertion policy to Ignore. - - pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore, - Assert_And_Cut => Ignore, - Subprogram_Variant => Ignore); - - package Unsigned_Conversion is new Unsigned_Conversions (Int => Uns); - - function Big (Arg : Uns) return Big_Integer renames - Unsigned_Conversion.To_Big_Integer; - - function From_Big (Arg : Big_Integer) return Uns renames - Unsigned_Conversion.From_Big_Integer; - - Big_10 : constant Big_Integer := Big (10) with Ghost; - - ------------------ - -- Local Lemmas -- - ------------------ - - procedure Lemma_Non_Zero (X : Uns) - with - Ghost, - Pre => X /= 0, - Post => Big (X) /= 0; - - procedure Lemma_Div_Commutation (X, Y : Uns) - with - Ghost, - Pre => Y /= 0, - Post => Big (X) / Big (Y) = Big (X / Y); - - procedure Lemma_Div_Twice (X : Big_Natural; Y, Z : Big_Positive) - with - Ghost, - Post => X / Y / Z = X / (Y * Z); - - --------------------------- - -- Lemma_Div_Commutation -- - --------------------------- - - procedure Lemma_Non_Zero (X : Uns) is null; - procedure Lemma_Div_Commutation (X, Y : Uns) is null; - - --------------------- - -- Lemma_Div_Twice -- - --------------------- - - procedure Lemma_Div_Twice (X : Big_Natural; Y, Z : Big_Positive) is - XY : constant Big_Natural := X / Y; - YZ : constant Big_Natural := Y * Z; - XYZ : constant Big_Natural := X / Y / Z; - R : constant Big_Natural := (XY rem Z) * Y + (X rem Y); - begin - pragma Assert (X = XY * Y + (X rem Y)); - pragma Assert (XY = XY / Z * Z + (XY rem Z)); - pragma Assert (X = XYZ * YZ + R); - pragma Assert ((XY rem Z) * Y <= (Z - 1) * Y); - pragma Assert (R <= YZ - 1); - pragma Assert (X / YZ = (XYZ * YZ + R) / YZ); - pragma Assert (X / YZ = XYZ + R / YZ); - end Lemma_Div_Twice; - -------------------- -- Image_Unsigned -- -------------------- @@ -112,50 +41,10 @@ package body System.Image_U is P : out Natural) is pragma Assert (S'First = 1); - - procedure Prove_Value_Unsigned - with - Ghost, - Pre => S'First = 1 - and then S'Last < Integer'Last - and then P in 2 .. S'Last - and then S (1) = ' ' - and then U_Spec.Only_Decimal_Ghost (S, From => 2, To => P) - and then U_Spec.Scan_Based_Number_Ghost (S, From => 2, To => P) - = U_Spec.Wrap_Option (V), - Post => not System.Val_Spec.Only_Space_Ghost (S, 1, P) - and then U_Spec.Is_Unsigned_Ghost (S (1 .. P)) - and then U_Spec.Is_Value_Unsigned_Ghost (S (1 .. P), V); - -- Ghost lemma to prove the value of Value_Unsigned from the value of - -- Scan_Based_Number_Ghost on a decimal string. - - -------------------------- - -- Prove_Value_Unsigned -- - -------------------------- - - procedure Prove_Value_Unsigned is - Str : constant String := S (1 .. P); - begin - pragma Assert (Str'First = 1); - pragma Assert (S (2) /= ' '); - pragma Assert - (U_Spec.Only_Decimal_Ghost (Str, From => 2, To => P)); - U_Spec.Prove_Scan_Based_Number_Ghost_Eq - (S, Str, From => 2, To => P); - pragma Assert - (U_Spec.Scan_Based_Number_Ghost (Str, From => 2, To => P) - = U_Spec.Wrap_Option (V)); - U_Spec.Prove_Scan_Only_Decimal_Ghost (Str, V); - end Prove_Value_Unsigned; - - -- Start of processing for Image_Unsigned - begin S (1) := ' '; P := 1; Set_Image_Unsigned (V, S, P); - - Prove_Value_Unsigned; end Image_Unsigned; ------------------------ @@ -169,118 +58,6 @@ package body System.Image_U is is Nb_Digits : Natural := 0; Value : Uns := V; - - -- Local ghost variables - - Pow : Big_Positive := 1 with Ghost; - S_Init : constant String := S with Ghost; - Prev_Value : Uns with Ghost; - Prev_S : String := S with Ghost; - - -- Local ghost lemmas - - procedure Prove_Character_Val (R : Uns) - with - Ghost, - Post => R rem 10 in 0 .. 9 - and then Character'Val (48 + R rem 10) in '0' .. '9'; - -- Ghost lemma to prove the value of a character corresponding to the - -- next figure. - - procedure Prove_Euclidian (Val, Quot, Rest : Uns) - with - Ghost, - Pre => Quot = Val / 10 - and then Rest = Val rem 10, - Post => Uns'Last - Rest >= 10 * Quot and then Val = 10 * Quot + Rest; - -- Ghost lemma to prove the relation between the quotient/remainder of - -- division by 10 and the initial value. - - procedure Prove_Hexa_To_Unsigned_Ghost (R : Uns) - with - Ghost, - Pre => R in 0 .. 9, - Post => U_Spec.Hexa_To_Unsigned_Ghost (Character'Val (48 + R)) = R; - -- Ghost lemma to prove that Hexa_To_Unsigned_Ghost returns the source - -- figure when applied to the corresponding character. - - procedure Prove_Scan_Iter - (S, Prev_S : String; - V, Prev_V, Res : Uns; - P, Max : Natural) - with - Ghost, - Pre => - S'First = Prev_S'First and then S'Last = Prev_S'Last - and then S'Last < Natural'Last and then - Max in S'Range and then P in S'First .. Max and then - (for all I in P + 1 .. Max => Prev_S (I) in '0' .. '9') - and then (for all I in P + 1 .. Max => Prev_S (I) = S (I)) - and then S (P) in '0' .. '9' - and then V <= Uns'Last / 10 - and then Uns'Last - U_Spec.Hexa_To_Unsigned_Ghost (S (P)) - >= 10 * V - and then Prev_V = - V * 10 + U_Spec.Hexa_To_Unsigned_Ghost (S (P)) - and then - (if P = Max then Prev_V = Res - else U_Spec.Scan_Based_Number_Ghost - (Str => Prev_S, - From => P + 1, - To => Max, - Base => 10, - Acc => Prev_V) = U_Spec.Wrap_Option (Res)), - Post => - (for all I in P .. Max => S (I) in '0' .. '9') - and then U_Spec.Scan_Based_Number_Ghost - (Str => S, - From => P, - To => Max, - Base => 10, - Acc => V) = U_Spec.Wrap_Option (Res); - -- Ghost lemma to prove that Scan_Based_Number_Ghost is preserved - -- through an iteration of the loop. - - ----------------------------- - -- Local lemma null bodies -- - ----------------------------- - - procedure Prove_Character_Val (R : Uns) is null; - procedure Prove_Euclidian (Val, Quot, Rest : Uns) is null; - procedure Prove_Hexa_To_Unsigned_Ghost (R : Uns) is null; - - --------------------- - -- Prove_Scan_Iter -- - --------------------- - - procedure Prove_Scan_Iter - (S, Prev_S : String; - V, Prev_V, Res : Uns; - P, Max : Natural) - is - pragma Unreferenced (Res); - begin - U_Spec.Lemma_Scan_Based_Number_Ghost_Step - (Str => S, - From => P, - To => Max, - Base => 10, - Acc => V); - if P < Max then - U_Spec.Prove_Scan_Based_Number_Ghost_Eq - (Prev_S, S, P + 1, Max, 10, Prev_V); - else - U_Spec.Lemma_Scan_Based_Number_Ghost_Base - (Str => S, - From => P + 1, - To => Max, - Base => 10, - Acc => Prev_V); - end if; - end Prove_Scan_Iter; - - -- Start of processing for Set_Image_Unsigned - begin pragma Assert (P >= S'First - 1 and then P < S'Last and then P < Natural'Last); @@ -290,70 +67,19 @@ package body System.Image_U is -- First we compute the number of characters needed for representing -- the number. loop - Lemma_Div_Commutation (Value, 10); - Lemma_Div_Twice (Big (V), Big_10 ** Nb_Digits, Big_10); - Value := Value / 10; Nb_Digits := Nb_Digits + 1; - Pow := Pow * 10; - - pragma Loop_Invariant (Nb_Digits in 1 .. Unsigned_Width_Ghost - 1); - pragma Loop_Invariant (Pow = Big_10 ** Nb_Digits); - pragma Loop_Invariant (Big (Value) = Big (V) / Pow); - pragma Loop_Variant (Decreases => Value); exit when Value = 0; - - Lemma_Non_Zero (Value); - pragma Assert (Pow <= Big (Uns'Last)); end loop; - pragma Assert (Big (V) / (Big_10 ** Nb_Digits) = 0); Value := V; - Pow := 1; - - pragma Assert (Value = From_Big (Big (V) / Big_10 ** 0)); -- We now populate digits from the end of the string to the beginning for J in reverse 1 .. Nb_Digits loop - Lemma_Div_Commutation (Value, 10); - Lemma_Div_Twice (Big (V), Big_10 ** (Nb_Digits - J), Big_10); - Prove_Character_Val (Value); - Prove_Hexa_To_Unsigned_Ghost (Value rem 10); - - Prev_Value := Value; - Prev_S := S; - Pow := Pow * 10; S (P + J) := Character'Val (48 + (Value rem 10)); Value := Value / 10; - - Prove_Euclidian - (Val => Prev_Value, - Quot => Value, - Rest => U_Spec.Hexa_To_Unsigned_Ghost (S (P + J))); - - Prove_Scan_Iter - (S, Prev_S, Value, Prev_Value, V, P + J, P + Nb_Digits); - - pragma Loop_Invariant (Value <= Uns'Last / 10); - pragma Loop_Invariant - (for all K in S'First .. P => S (K) = S_Init (K)); - pragma Loop_Invariant - (U_Spec.Only_Decimal_Ghost - (S, From => P + J, To => P + Nb_Digits)); - pragma Loop_Invariant (Pow = Big_10 ** (Nb_Digits - J + 1)); - pragma Loop_Invariant (Big (Value) = Big (V) / Pow); - pragma Loop_Invariant - (U_Spec.Scan_Based_Number_Ghost - (Str => S, - From => P + J, - To => P + Nb_Digits, - Base => 10, - Acc => Value) - = U_Spec.Wrap_Option (V)); end loop; - pragma Assert (Big (Value) = Big (V) / (Big_10 ** Nb_Digits)); - pragma Assert (Value = 0); P := P + Nb_Digits; end Set_Image_Unsigned; diff --git a/gcc/ada/libgnat/s-imageu.ads b/gcc/ada/libgnat/s-imageu.ads index 720de408d35b..8640a5b856ca 100644 --- a/gcc/ada/libgnat/s-imageu.ads +++ b/gcc/ada/libgnat/s-imageu.ads @@ -33,44 +33,15 @@ -- and ``Ada.Text_IO.Modular_IO`` conversions routines for modular integer -- types. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -with System.Value_U_Spec; - generic - type Uns is mod <>; - -- Additional parameters for ghost subprograms used inside contracts - - with package U_Spec is new System.Value_U_Spec (Uns => Uns) with Ghost; - package System.Image_U is - use all type U_Spec.Uns_Option; - - Unsigned_Width_Ghost : constant Natural := U_Spec.Max_Log10 + 2 with Ghost; procedure Image_Unsigned (V : Uns; S : in out String; - P : out Natural) - with - Pre => S'First = 1 - and then S'Last < Integer'Last - and then S'Last >= Unsigned_Width_Ghost, - Post => P in S'Range - and then U_Spec.Is_Value_Unsigned_Ghost (S (1 .. P), V); - pragma Inline (Image_Unsigned); + P : out Natural) with Inline; -- Computes Uns'Image (V) and stores the result in S (1 .. P) setting -- the resulting value of P. The caller guarantees that S is long enough to -- hold the result, and that S'First is 1. @@ -78,19 +49,7 @@ package System.Image_U is procedure Set_Image_Unsigned (V : Uns; S : in out String; - P : in out Natural) - with - Pre => P < Integer'Last - and then S'Last < Integer'Last - and then S'First <= P + 1 - and then S'First <= S'Last - and then P <= S'Last - Unsigned_Width_Ghost + 1, - Post => S (S'First .. P'Old) = S'Old (S'First .. P'Old) - and then P in P'Old + 1 .. S'Last - and then U_Spec.Only_Decimal_Ghost (S, From => P'Old + 1, To => P) - and then U_Spec.Scan_Based_Number_Ghost - (S, From => P'Old + 1, To => P) - = U_Spec.Wrap_Option (V); + P : in out Natural); -- Stores the image of V in S starting at S (P + 1), P is updated to point -- to the last character stored. The value stored is identical to the value -- of Uns'Image (V) except that no leading space is stored. The caller diff --git a/gcc/ada/libgnat/s-imde128.ads b/gcc/ada/libgnat/s-imde128.ads index f353f572203a..03485b99e9a7 100644 --- a/gcc/ada/libgnat/s-imde128.ads +++ b/gcc/ada/libgnat/s-imde128.ads @@ -39,9 +39,8 @@ with System.Image_D; package System.Img_Decimal_128 is subtype Int128 is Interfaces.Integer_128; - subtype Uns128 is Interfaces.Unsigned_128; - package Impl is new Image_D (Int128, Uns128); + package Impl is new Image_D (Int128); procedure Image_Decimal128 (V : Int128; diff --git a/gcc/ada/libgnat/s-imde32.ads b/gcc/ada/libgnat/s-imde32.ads index 442f3437ae3d..40fd5e98f4e3 100644 --- a/gcc/ada/libgnat/s-imde32.ads +++ b/gcc/ada/libgnat/s-imde32.ads @@ -39,9 +39,8 @@ with System.Image_D; package System.Img_Decimal_32 is subtype Int32 is Interfaces.Integer_32; - subtype Uns32 is Interfaces.Unsigned_32; - package Impl is new Image_D (Int32, Uns32); + package Impl is new Image_D (Int32); procedure Image_Decimal32 (V : Int32; diff --git a/gcc/ada/libgnat/s-imde64.ads b/gcc/ada/libgnat/s-imde64.ads index a69e02ff55d5..5264c43cb213 100644 --- a/gcc/ada/libgnat/s-imde64.ads +++ b/gcc/ada/libgnat/s-imde64.ads @@ -39,9 +39,8 @@ with System.Image_D; package System.Img_Decimal_64 is subtype Int64 is Interfaces.Integer_64; - subtype Uns64 is Interfaces.Unsigned_64; - package Impl is new Image_D (Int64, Uns64); + package Impl is new Image_D (Int64); procedure Image_Decimal64 (V : Int64; diff --git a/gcc/ada/libgnat/s-imfi128.ads b/gcc/ada/libgnat/s-imfi128.ads index 9bb383a25cc3..23cd059e7429 100644 --- a/gcc/ada/libgnat/s-imfi128.ads +++ b/gcc/ada/libgnat/s-imfi128.ads @@ -39,9 +39,8 @@ with System.Image_F; package System.Img_Fixed_128 is subtype Int128 is Interfaces.Integer_128; - subtype Uns128 is Interfaces.Unsigned_128; - package Impl is new Image_F (Int128, Uns128, Arith_128.Scaled_Divide128); + package Impl is new Image_F (Int128, Arith_128.Scaled_Divide128); procedure Image_Fixed128 (V : Int128; diff --git a/gcc/ada/libgnat/s-imfi32.ads b/gcc/ada/libgnat/s-imfi32.ads index f66b0faef16c..ba46e8d6b118 100644 --- a/gcc/ada/libgnat/s-imfi32.ads +++ b/gcc/ada/libgnat/s-imfi32.ads @@ -39,9 +39,8 @@ with System.Image_F; package System.Img_Fixed_32 is subtype Int32 is Interfaces.Integer_32; - subtype Uns32 is Interfaces.Unsigned_32; - package Impl is new Image_F (Int32, Uns32, Arith_32.Scaled_Divide32); + package Impl is new Image_F (Int32, Arith_32.Scaled_Divide32); procedure Image_Fixed32 (V : Int32; diff --git a/gcc/ada/libgnat/s-imfi64.ads b/gcc/ada/libgnat/s-imfi64.ads index ecb70ad517a4..c7f7aa112280 100644 --- a/gcc/ada/libgnat/s-imfi64.ads +++ b/gcc/ada/libgnat/s-imfi64.ads @@ -39,9 +39,8 @@ with System.Image_F; package System.Img_Fixed_64 is subtype Int64 is Interfaces.Integer_64; - subtype Uns64 is Interfaces.Unsigned_64; - package Impl is new Image_F (Int64, Uns64, Arith_64.Scaled_Divide64); + package Impl is new Image_F (Int64, Arith_64.Scaled_Divide64); procedure Image_Fixed64 (V : Int64; diff --git a/gcc/ada/libgnat/s-imgboo.adb b/gcc/ada/libgnat/s-imgboo.adb index 436818c3cc3a..c4d85bf2a6b6 100644 --- a/gcc/ada/libgnat/s-imgboo.adb +++ b/gcc/ada/libgnat/s-imgboo.adb @@ -29,32 +29,9 @@ -- -- ------------------------------------------------------------------------------ --- Ghost code, loop invariants and assertions in this unit are meant for --- analysis only, not for run-time checking, as it would be too costly --- otherwise. This is enforced by setting the assertion policy to Ignore. - -pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - package body System.Img_Bool with SPARK_Mode is - - -- Local lemmas - - procedure Lemma_Is_First_Non_Space_Ghost (S : String; R : Positive) with - Ghost, - Pre => R in S'Range and then S (R) /= ' ' - and then System.Val_Spec.Only_Space_Ghost (S, S'First, R - 1), - Post => System.Val_Spec.First_Non_Space_Ghost (S, S'First, S'Last) = R; - - ------------------------------------ - -- Lemma_Is_First_Non_Space_Ghost -- - ------------------------------------ - - procedure Lemma_Is_First_Non_Space_Ghost (S : String; R : Positive) is null; - ------------------- -- Image_Boolean -- ------------------- @@ -69,11 +46,9 @@ is if V then S (1 .. 4) := "TRUE"; P := 4; - Lemma_Is_First_Non_Space_Ghost (S, 1); else S (1 .. 5) := "FALSE"; P := 5; - Lemma_Is_First_Non_Space_Ghost (S, 1); end if; end Image_Boolean; diff --git a/gcc/ada/libgnat/s-imgboo.ads b/gcc/ada/libgnat/s-imgboo.ads index 9d8b1f7c5f04..af19c2edc1e3 100644 --- a/gcc/ada/libgnat/s-imgboo.ads +++ b/gcc/ada/libgnat/s-imgboo.ads @@ -34,32 +34,13 @@ -- This package provides support for ``Image`` attribute on ``Boolean``. The -- compiler performs direct calls to this unit to implement the attribute. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - -with System.Val_Spec; - package System.Img_Bool with SPARK_Mode, Preelaborate is - procedure Image_Boolean (V : Boolean; S : in out String; - P : out Natural) - with - Pre => S'First = 1 - and then (if V then S'Length >= 4 else S'Length >= 5), - Post => (if V then P = 4 else P = 5) - and then System.Val_Spec.Is_Boolean_Image_Ghost (S (1 .. P), V); + P : out Natural); -- Computes Boolean'Image (``V``) and stores the result in -- ``S`` (1 .. ``P``) setting the resulting value of ``P``. The caller -- guarantees that ``S`` is long enough to hold the result, and that diff --git a/gcc/ada/libgnat/s-imgint.ads b/gcc/ada/libgnat/s-imgint.ads index 1ccf1732bd01..55df149dcf4a 100644 --- a/gcc/ada/libgnat/s-imgint.ads +++ b/gcc/ada/libgnat/s-imgint.ads @@ -33,33 +33,12 @@ -- and ``Ada.Text_IO.Integer_IO`` conversions routines for signed integer -- types up to Size ``Integer'Size``. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - with System.Image_I; -with System.Unsigned_Types; -with System.Vs_Int; -with System.Vs_Uns; package System.Img_Int with SPARK_Mode is - subtype Unsigned is Unsigned_Types.Unsigned; - - package Impl is new Image_I - (Int => Integer, - Uns => Unsigned, - U_Spec => System.Vs_Uns.Spec, - I_Spec => System.Vs_Int.Spec); + package Impl is new Image_I (Integer); procedure Image_Integer (V : Integer; diff --git a/gcc/ada/libgnat/s-imglli.ads b/gcc/ada/libgnat/s-imglli.ads index 32be4dcb0842..28fd5630820c 100644 --- a/gcc/ada/libgnat/s-imglli.ads +++ b/gcc/ada/libgnat/s-imglli.ads @@ -33,33 +33,12 @@ -- and ``Ada.Text_IO.Integer_IO`` conversions routines for signed integer -- types larger than Size ``Integer'Size``. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - with System.Image_I; -with System.Unsigned_Types; -with System.Vs_LLI; -with System.Vs_LLU; package System.Img_LLI with SPARK_Mode is - subtype Long_Long_Unsigned is Unsigned_Types.Long_Long_Unsigned; - - package Impl is new Image_I - (Int => Long_Long_Integer, - Uns => Long_Long_Unsigned, - U_Spec => System.Vs_LLU.Spec, - I_Spec => System.Vs_LLI.Spec); + package Impl is new Image_I (Long_Long_Integer); procedure Image_Long_Long_Integer (V : Long_Long_Integer; diff --git a/gcc/ada/libgnat/s-imgllli.ads b/gcc/ada/libgnat/s-imgllli.ads index 47c75b07742a..cecbdff78c63 100644 --- a/gcc/ada/libgnat/s-imgllli.ads +++ b/gcc/ada/libgnat/s-imgllli.ads @@ -33,33 +33,12 @@ -- signed integer types larger than Long_Long_Integer, and also for conversion -- operations required in Text_IO.Integer_IO for such types. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - with System.Image_I; -with System.Unsigned_Types; -with System.Vs_LLLI; -with System.Vs_LLLU; package System.Img_LLLI with SPARK_Mode is - subtype Long_Long_Long_Unsigned is Unsigned_Types.Long_Long_Long_Unsigned; - - package Impl is new Image_I - (Int => Long_Long_Long_Integer, - Uns => Long_Long_Long_Unsigned, - U_Spec => System.Vs_LLLU.Spec, - I_Spec => System.Vs_LLLI.Spec); + package Impl is new Image_I (Long_Long_Long_Integer); procedure Image_Long_Long_Long_Integer (V : Long_Long_Long_Integer; diff --git a/gcc/ada/libgnat/s-imglllu.ads b/gcc/ada/libgnat/s-imglllu.ads index 0dbe1f21ca52..e581d3767dab 100644 --- a/gcc/ada/libgnat/s-imglllu.ads +++ b/gcc/ada/libgnat/s-imglllu.ads @@ -33,30 +33,15 @@ -- modular integer types larger than Long_Long_Unsigned, and also for -- conversion operations required in Text_IO.Modular_IO for such types. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - with System.Image_U; with System.Unsigned_Types; -with System.Vs_LLLU; package System.Img_LLLU with SPARK_Mode is subtype Long_Long_Long_Unsigned is Unsigned_Types.Long_Long_Long_Unsigned; - package Impl is new Image_U - (Uns => Long_Long_Long_Unsigned, - U_Spec => System.Vs_LLLU.Spec); + package Impl is new Image_U (Uns => Long_Long_Long_Unsigned); procedure Image_Long_Long_Long_Unsigned (V : Long_Long_Long_Unsigned; diff --git a/gcc/ada/libgnat/s-imgllu.ads b/gcc/ada/libgnat/s-imgllu.ads index 82d372d3cd2d..729e6e841e9b 100644 --- a/gcc/ada/libgnat/s-imgllu.ads +++ b/gcc/ada/libgnat/s-imgllu.ads @@ -33,30 +33,15 @@ -- and ``Ada.Text_IO.Modular_IO`` conversions routines for unsigned (modular) -- integer types larger than Size ``Unsigned'Size``. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - with System.Image_U; with System.Unsigned_Types; -with System.Vs_LLU; package System.Img_LLU with SPARK_Mode is subtype Long_Long_Unsigned is Unsigned_Types.Long_Long_Unsigned; - package Impl is new Image_U - (Uns => Long_Long_Unsigned, - U_Spec => System.Vs_LLU.Spec); + package Impl is new Image_U (Uns => Long_Long_Unsigned); procedure Image_Long_Long_Unsigned (V : Long_Long_Unsigned; diff --git a/gcc/ada/libgnat/s-imguns.ads b/gcc/ada/libgnat/s-imguns.ads index 142591affb15..dbab67e4bf2c 100644 --- a/gcc/ada/libgnat/s-imguns.ads +++ b/gcc/ada/libgnat/s-imguns.ads @@ -33,30 +33,15 @@ -- and ``Ada.Text_IO.Modular_IO`` conversions routines for modular integer -- types up to size ``Unsigned'Size``. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - with System.Image_U; with System.Unsigned_Types; -with System.Vs_Uns; package System.Img_Uns with SPARK_Mode is subtype Unsigned is Unsigned_Types.Unsigned; - package Impl is new Image_U - (Uns => Unsigned, - U_Spec => System.Vs_Uns.Spec); + package Impl is new Image_U (Uns => Unsigned); procedure Image_Unsigned (V : Unsigned; diff --git a/gcc/ada/libgnat/s-secsta.adb b/gcc/ada/libgnat/s-secsta.adb index 2749658114af..9d78b868b7ef 100644 --- a/gcc/ada/libgnat/s-secsta.adb +++ b/gcc/ada/libgnat/s-secsta.adb @@ -633,6 +633,15 @@ package body System.Secondary_Stack is if Over_Aligning then Padding := Alignment; + + -- Typically the padding would be + -- Alignment - (Addr mod Alignment) + -- however Addr in this case is not known yet. It depends on the + -- type of the secondary stack (Dynamic/Static). The allocation + -- routine for the respective type of stack requires to know the + -- allocation size before the address is known. To ensure a + -- sufficient allocation size to fit the padding, the padding is + -- calculated conservatively. end if; -- Round the requested size (plus the needed padding in case of diff --git a/gcc/ada/libgnat/s-secsta__cheri.adb b/gcc/ada/libgnat/s-secsta__cheri.adb index a24b50e2f744..9a65ed2879c9 100644 --- a/gcc/ada/libgnat/s-secsta__cheri.adb +++ b/gcc/ada/libgnat/s-secsta__cheri.adb @@ -662,6 +662,15 @@ package body System.Secondary_Stack is if Over_Aligning then Over_Align_Padding := Alignment; + + -- Typically the padding would be + -- Alignment - (Addr mod Alignment) + -- however Addr in this case is not known yet. It depends on the + -- type of the secondary stack (Dynamic/Static). The allocation + -- routine for the respective type of stack requires to know the + -- allocation size before the address is known. To ensure a + -- sufficient allocation size to fit the padding, the padding is + -- calculated conservatively. end if; -- It should not be possible to request an allocation of negative diff --git a/gcc/ada/libgnat/s-spcuop.ads b/gcc/ada/libgnat/s-spcuop.ads deleted file mode 100644 index 04a94a50d21c..000000000000 --- a/gcc/ada/libgnat/s-spcuop.ads +++ /dev/null @@ -1,57 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- S Y S T E M . S P A R K . C U T _ O P E R A T I O N S -- --- -- --- S p e c -- --- -- --- Copyright (C) 2022-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - --- This package provides connectors used to manually help the proof of --- assertions by introducing intermediate steps. They can only be used inside --- pragmas Assert or Assert_And_Cut. - -package System.SPARK.Cut_Operations with - SPARK_Mode, - Pure, - Always_Terminates -is - - function By (Consequence, Premise : Boolean) return Boolean with - Ghost, - Global => null; - -- If A and B are two boolean expressions, proving By (A, B) requires - -- proving B, the premise, and then A assuming B, the side-condition. When - -- By (A, B) is assumed on the other hand, we only assume A. B is used - -- for the proof, but is not visible afterward. - - function So (Premise, Consequence : Boolean) return Boolean with - Ghost, - Global => null; - -- If A and B are two boolean expressions, proving So (A, B) requires - -- proving A, the premise, and then B assuming A, the side-condition. When - -- So (A, B) is assumed both A and B are assumed to be true. - -end System.SPARK.Cut_Operations; diff --git a/gcc/ada/libgnat/s-stausa.adb b/gcc/ada/libgnat/s-stausa.adb index 6bdbc4342f13..cbecc0bb20ed 100644 --- a/gcc/ada/libgnat/s-stausa.adb +++ b/gcc/ada/libgnat/s-stausa.adb @@ -188,7 +188,8 @@ package body System.Stack_Usage is -- allocated byte on the stack. begin if Parameters.Stack_Grows_Down then - if Analyzer.Stack_Base - Stack_Address (Analyzer.Pattern_Size) > + if To_Stack_Address (Analyzer.Stack_Base) - + Stack_Address (Analyzer.Pattern_Size) > To_Stack_Address (Current_Stack_Level'Address) - Guard then -- No room for a pattern @@ -198,22 +199,22 @@ package body System.Stack_Usage is end if; Analyzer.Pattern_Limit := - Analyzer.Stack_Base - Stack_Address (Analyzer.Pattern_Size); + Analyzer.Stack_Base - Storage_Offset (Analyzer.Pattern_Size); - if Analyzer.Stack_Base > + if To_Stack_Address (Analyzer.Stack_Base) > To_Stack_Address (Current_Stack_Level'Address) - Guard then -- Reduce pattern size to prevent local frame overwrite Analyzer.Pattern_Size := Integer (To_Stack_Address (Current_Stack_Level'Address) - Guard - - Analyzer.Pattern_Limit); + - To_Stack_Address (Analyzer.Pattern_Limit)); end if; - Analyzer.Pattern_Overlay_Address := - To_Address (Analyzer.Pattern_Limit); + Analyzer.Pattern_Overlay_Address := Analyzer.Pattern_Limit; else - if Analyzer.Stack_Base + Stack_Address (Analyzer.Pattern_Size) < + if To_Stack_Address (Analyzer.Stack_Base) + + Stack_Address (Analyzer.Pattern_Size) < To_Stack_Address (Current_Stack_Level'Address) + Guard then -- No room for a pattern @@ -223,22 +224,21 @@ package body System.Stack_Usage is end if; Analyzer.Pattern_Limit := - Analyzer.Stack_Base + Stack_Address (Analyzer.Pattern_Size); + Analyzer.Stack_Base + Storage_Offset (Analyzer.Pattern_Size); - if Analyzer.Stack_Base < + if To_Stack_Address (Analyzer.Stack_Base) < To_Stack_Address (Current_Stack_Level'Address) + Guard then -- Reduce pattern size to prevent local frame overwrite Analyzer.Pattern_Size := Integer - (Analyzer.Pattern_Limit - + (To_Stack_Address (Analyzer.Pattern_Limit) - (To_Stack_Address (Current_Stack_Level'Address) + Guard)); end if; Analyzer.Pattern_Overlay_Address := - To_Address (Analyzer.Pattern_Limit - - Stack_Address (Analyzer.Pattern_Size)); + Analyzer.Pattern_Limit - Storage_Offset (Analyzer.Pattern_Size); end if; -- Declare and fill the pattern buffer @@ -270,7 +270,7 @@ package body System.Stack_Usage is (Analyzer : in out Stack_Analyzer; Task_Name : String; Stack_Size : Natural; - Stack_Base : Stack_Address; + Stack_Base : System.Address; Pattern_Size : Natural; Pattern : Interfaces.Unsigned_32 := 16#DEAD_BEEF#) is @@ -332,10 +332,10 @@ package body System.Stack_Usage is if Parameters.Stack_Grows_Down then Analyzer.Topmost_Touched_Mark := - Analyzer.Pattern_Limit + Stack_Address (Analyzer.Pattern_Size); + Analyzer.Pattern_Limit + Storage_Offset (Analyzer.Pattern_Size); else Analyzer.Topmost_Touched_Mark := - Analyzer.Pattern_Limit - Stack_Address (Analyzer.Pattern_Size); + Analyzer.Pattern_Limit - Storage_Offset (Analyzer.Pattern_Size); end if; if Analyzer.Pattern_Size = 0 then @@ -349,8 +349,7 @@ package body System.Stack_Usage is if System.Parameters.Stack_Grows_Down then for J in Stack'Range loop if Stack (J) /= Analyzer.Pattern then - Analyzer.Topmost_Touched_Mark := - To_Stack_Address (Stack (J)'Address); + Analyzer.Topmost_Touched_Mark := Stack (J)'Address; exit; end if; end loop; @@ -358,8 +357,7 @@ package body System.Stack_Usage is else for J in reverse Stack'Range loop if Stack (J) /= Analyzer.Pattern then - Analyzer.Topmost_Touched_Mark := - To_Stack_Address (Stack (J)'Address); + Analyzer.Topmost_Touched_Mark := Stack (J)'Address; exit; end if; end loop; @@ -514,8 +512,9 @@ package body System.Stack_Usage is Result.Value := Analyzer.Stack_Size; else - Result.Value := Stack_Size (Analyzer.Topmost_Touched_Mark, - Analyzer.Stack_Base); + Result.Value := + Stack_Size (To_Stack_Address (Analyzer.Topmost_Touched_Mark), + To_Stack_Address (Analyzer.Stack_Base)); end if; if Analyzer.Result_Id in Result_Array'Range then diff --git a/gcc/ada/libgnat/s-stausa.ads b/gcc/ada/libgnat/s-stausa.ads index c67b1240ac47..36cebd7cde07 100644 --- a/gcc/ada/libgnat/s-stausa.ads +++ b/gcc/ada/libgnat/s-stausa.ads @@ -230,7 +230,7 @@ package System.Stack_Usage is (Analyzer : in out Stack_Analyzer; Task_Name : String; Stack_Size : Natural; - Stack_Base : Stack_Address; + Stack_Base : System.Address; Pattern_Size : Natural; Pattern : Interfaces.Unsigned_32 := 16#DEAD_BEEF#); -- Should be called before any use of a Stack_Analyzer, to initialize it. @@ -287,7 +287,7 @@ private Task_Name : String (1 .. Task_Name_Length); -- Name of the task - Stack_Base : Stack_Address; + Stack_Base : System.Address; -- Address of the base of the stack, as given by the caller of -- Initialize_Analyzer. @@ -300,10 +300,10 @@ private Pattern : Pattern_Type; -- Pattern used to recognize untouched memory - Pattern_Limit : Stack_Address; + Pattern_Limit : System.Address; -- Bound of the pattern area farthest to the base - Topmost_Touched_Mark : Stack_Address; + Topmost_Touched_Mark : System.Address; -- Topmost address of the pattern area whose value it is pointing -- at has been modified during execution. If the systematic error are -- compensated, it is the topmost value of the stack pointer during diff --git a/gcc/ada/libgnat/s-trasym__dwarf.adb b/gcc/ada/libgnat/s-trasym__dwarf.adb index 45af884b61fe..479b5d34d118 100644 --- a/gcc/ada/libgnat/s-trasym__dwarf.adb +++ b/gcc/ada/libgnat/s-trasym__dwarf.adb @@ -41,6 +41,7 @@ with System.Soft_Links; with System.CRTL; with System.Dwarf_Lines; with System.Exception_Traces; +with System.OS_Lib; with System.Standard_Library; with System.Traceback_Entries; with System.Strings; @@ -413,6 +414,23 @@ package body System.Traceback.Symbolic is return; end if; + -- On some platforms, we use dladdr and the dli_fname field to get the + -- pathname, but that pathname might be relative and not point to the + -- right thing in our context. That happens when the executable is + -- dynamically linked and was started through execvp; dli_fname only + -- contains the executable name passed to execvp in that case. + -- + -- Because of this, we might be about to open a file that's in fact not + -- a shared object but something completely unrelated. It's hard to + -- detect this in general, but we perform a sanity check that + -- Module_Name does not designate a directory; if it does, it's + -- definitely not a shared object. + + if System.OS_Lib.Is_Directory (Module_Name) then + Success := False; + return; + end if; + Open (Module_Name, Module.C, Success); -- If a module can't be opened just return now, we just cannot give more @@ -461,7 +479,7 @@ package body System.Traceback.Symbolic is exception when others => - return; + null; end Module_Symbolic_Traceback; ------------------------------------- diff --git a/gcc/ada/libgnat/s-vafi128.ads b/gcc/ada/libgnat/s-vafi128.ads index 7518c6c348ad..d75857acedab 100644 --- a/gcc/ada/libgnat/s-vafi128.ads +++ b/gcc/ada/libgnat/s-vafi128.ads @@ -29,9 +29,9 @@ -- -- ------------------------------------------------------------------------------ --- This package contains routines for scanning values for ordinary fixed point --- types up to 128-bit small and mantissa, for use in Text_IO.Decimal_IO, and --- the Value attribute for such decimal types. +-- This package contains the routines for supporting the Value attribute for +-- ordinary fixed point types up to 128-bit small and mantissa, and also for +-- conversion operations required in Text_IO.Fixed_IO for such types. with Interfaces; with System.Arith_128; diff --git a/gcc/ada/libgnat/s-vafi32.ads b/gcc/ada/libgnat/s-vafi32.ads index e3ad5c2b46ab..7ed22c6ecbeb 100644 --- a/gcc/ada/libgnat/s-vafi32.ads +++ b/gcc/ada/libgnat/s-vafi32.ads @@ -29,9 +29,9 @@ -- -- ------------------------------------------------------------------------------ --- This package contains routines for scanning values for decimal fixed point --- types up to 32-bit small and mantissa, for use in Text_IO.Decimal_IO, and --- the Value attribute for such decimal types. +-- This package contains the routines for supporting the Value attribute for +-- ordinary fixed point types up to 32-bit small and mantissa, and also for +-- conversion operations required in Text_IO.Fixed_IO for such types. with Interfaces; with System.Arith_32; diff --git a/gcc/ada/libgnat/s-vafi64.ads b/gcc/ada/libgnat/s-vafi64.ads index 4d86939a90ef..43197bb34ce8 100644 --- a/gcc/ada/libgnat/s-vafi64.ads +++ b/gcc/ada/libgnat/s-vafi64.ads @@ -29,9 +29,9 @@ -- -- ------------------------------------------------------------------------------ --- This package contains routines for scanning values for decimal fixed point --- types up to 64-bit small and mantissa, for use in Text_IO.Decimal_IO, and --- the Value attribute for such decimal types. +-- This package contains the routines for supporting the Value attribute for +-- ordinary fixed point types up to 64-bit small and mantissa, and also for +-- conversion operations required in Text_IO.Fixed_IO for such types. with Interfaces; with System.Arith_64; diff --git a/gcc/ada/libgnat/s-vaispe.adb b/gcc/ada/libgnat/s-vaispe.adb deleted file mode 100644 index 0b09f75c4e70..000000000000 --- a/gcc/ada/libgnat/s-vaispe.adb +++ /dev/null @@ -1,87 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- S Y S T E M . V A L U E _ I _ S P E C -- --- -- --- B o d y -- --- -- --- Copyright (C) 2022-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -package body System.Value_I_Spec is - - ----------------------------------- - -- Prove_Scan_Only_Decimal_Ghost -- - ----------------------------------- - - procedure Prove_Scan_Only_Decimal_Ghost (Str : String; Val : Int) is - Non_Blank : constant Positive := First_Non_Space_Ghost - (Str, Str'First, Str'Last); - pragma Assert (Str (Str'First + 1) /= ' '); - pragma Assert - (if Val < 0 then Non_Blank = Str'First - else - Str (Str'First) = ' ' - and then Non_Blank = Str'First + 1); - Minus : constant Boolean := Str (Non_Blank) = '-'; - Fst_Num : constant Positive := - (if Minus then Non_Blank + 1 else Non_Blank); - pragma Assert (Fst_Num = Str'First + 1); - Uval : constant Uns := Abs_Uns_Of_Int (Val); - - procedure Prove_Conversion_Is_Identity (Val : Int; Uval : Uns) - with - Pre => Minus = (Val < 0) - and then Uval = Abs_Uns_Of_Int (Val), - Post => Uns_Is_Valid_Int (Minus, Uval) - and then Is_Int_Of_Uns (Minus, Uval, Val); - -- Local proof of the unicity of the signed representation - - procedure Prove_Conversion_Is_Identity (Val : Int; Uval : Uns) is null; - - -- Start of processing for Prove_Scan_Only_Decimal_Ghost - - begin - Prove_Conversion_Is_Identity (Val, Uval); - pragma Assert - (U_Spec.Is_Raw_Unsigned_Format_Ghost (Str (Fst_Num .. Str'Last))); - pragma Assert - (U_Spec.Scan_Split_No_Overflow_Ghost (Str, Fst_Num, Str'Last)); - U_Spec.Lemma_Exponent_Unsigned_Ghost_Base (Uval, 0, 10); - pragma Assert - (U_Spec.Raw_Unsigned_No_Overflow_Ghost (Str, Fst_Num, Str'Last)); - pragma Assert (Only_Space_Ghost - (Str, U_Spec.Raw_Unsigned_Last_Ghost - (Str, Fst_Num, Str'Last), Str'Last)); - pragma Assert (Is_Integer_Ghost (Str)); - pragma Assert (Is_Value_Integer_Ghost (Str, Val)); - end Prove_Scan_Only_Decimal_Ghost; - -end System.Value_I_Spec; diff --git a/gcc/ada/libgnat/s-vaispe.ads b/gcc/ada/libgnat/s-vaispe.ads deleted file mode 100644 index 2e729aacf3e0..000000000000 --- a/gcc/ada/libgnat/s-vaispe.ads +++ /dev/null @@ -1,185 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- S Y S T E M . V A L U E _ I _ S P E C -- --- -- --- S p e c -- --- -- --- Copyright (C) 2022-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - --- This package is part of a set of Ghost code packages used to proof the --- implementations of the Image and Value attributes. It provides the --- specification entities using for the formal verification of the routines --- for scanning signed integer values. - --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -with System.Value_U_Spec; -with System.Val_Spec; use System.Val_Spec; - -generic - - type Int is range <>; - - type Uns is mod <>; - - -- Additional parameters for ghost subprograms used inside contracts - - with package U_Spec is new System.Value_U_Spec (Uns => Uns) with Ghost; - -package System.Value_I_Spec with - Ghost, - SPARK_Mode, - Always_Terminates -is - pragma Preelaborate; - use all type U_Spec.Uns_Option; - - function Uns_Is_Valid_Int (Minus : Boolean; Uval : Uns) return Boolean is - (if Minus then Uval <= Uns (Int'Last) + 1 - else Uval <= Uns (Int'Last)) - with Post => True; - -- Return True if Uval (or -Uval when Minus is True) is a valid number of - -- type Int. - - function Is_Int_Of_Uns - (Minus : Boolean; - Uval : Uns; - Val : Int) - return Boolean - is - (if Minus and then Uval = Uns (Int'Last) + 1 then Val = Int'First - elsif Minus then Val = -(Int (Uval)) - else Val = Int (Uval)) - with - Pre => Uns_Is_Valid_Int (Minus, Uval), - Post => True; - -- Return True if Uval (or -Uval when Minus is True) is equal to Val - - function Abs_Uns_Of_Int (Val : Int) return Uns is - (if Val = Int'First then Uns (Int'Last) + 1 - elsif Val < 0 then Uns (-Val) - else Uns (Val)); - -- Return the unsigned absolute value of Val - - function Slide_To_1 (Str : String) return String - with - Post => - Only_Space_Ghost (Str, Str'First, Str'Last) = - (for all J in Str'First .. Str'Last => - Slide_To_1'Result (J - Str'First + 1) = ' '); - -- Slides Str so that it starts at 1 - - function Slide_If_Necessary (Str : String) return String is - (if Str'Last = Positive'Last then Slide_To_1 (Str) else Str); - -- If Str'Last = Positive'Last then slides Str so that it starts at 1 - - function Is_Integer_Ghost (Str : String) return Boolean is - (declare - Non_Blank : constant Positive := First_Non_Space_Ghost - (Str, Str'First, Str'Last); - Fst_Num : constant Positive := - (if Str (Non_Blank) in '+' | '-' then Non_Blank + 1 else Non_Blank); - begin - U_Spec.Is_Raw_Unsigned_Format_Ghost (Str (Fst_Num .. Str'Last)) - and then U_Spec.Raw_Unsigned_No_Overflow_Ghost - (Str, Fst_Num, Str'Last) - and then - Uns_Is_Valid_Int - (Minus => Str (Non_Blank) = '-', - Uval => U_Spec.Scan_Raw_Unsigned_Ghost - (Str, Fst_Num, Str'Last)) - and then Only_Space_Ghost - (Str, U_Spec.Raw_Unsigned_Last_Ghost - (Str, Fst_Num, Str'Last), Str'Last)) - with - Pre => not Only_Space_Ghost (Str, Str'First, Str'Last) - and then Str'Last /= Positive'Last, - Post => True; - -- Ghost function that determines if Str has the correct format for a - -- signed number, consisting in some blank characters, an optional - -- sign, a raw unsigned number which does not overflow and then some - -- more blank characters. - - function Is_Value_Integer_Ghost (Str : String; Val : Int) return Boolean is - (declare - Non_Blank : constant Positive := First_Non_Space_Ghost - (Str, Str'First, Str'Last); - Fst_Num : constant Positive := - (if Str (Non_Blank) in '+' | '-' then Non_Blank + 1 else Non_Blank); - Uval : constant Uns := - U_Spec.Scan_Raw_Unsigned_Ghost (Str, Fst_Num, Str'Last); - begin - Is_Int_Of_Uns (Minus => Str (Non_Blank) = '-', - Uval => Uval, - Val => Val)) - with - Pre => not Only_Space_Ghost (Str, Str'First, Str'Last) - and then Str'Last /= Positive'Last - and then Is_Integer_Ghost (Str), - Post => True; - -- Ghost function that returns True if Val is the value corresponding to - -- the signed number represented by Str. - - procedure Prove_Scan_Only_Decimal_Ghost (Str : String; Val : Int) - with - Ghost, - Pre => Str'Last /= Positive'Last - and then Str'Length >= 2 - and then Str (Str'First) in ' ' | '-' - and then (Str (Str'First) = '-') = (Val < 0) - and then U_Spec.Only_Decimal_Ghost (Str, Str'First + 1, Str'Last) - and then U_Spec.Scan_Based_Number_Ghost - (Str, Str'First + 1, Str'Last) - = U_Spec.Wrap_Option (Abs_Uns_Of_Int (Val)), - Post => Is_Integer_Ghost (Slide_If_Necessary (Str)) - and then Is_Value_Integer_Ghost (Str, Val); - -- Ghost lemma used in the proof of 'Image implementation, to prove that - -- the result of Value_Integer on a decimal string is the same as the - -- signing the result of Scan_Based_Number_Ghost. - -private - - ---------------- - -- Slide_To_1 -- - ---------------- - - function Slide_To_1 (Str : String) return String is - (declare - Res : constant String (1 .. Str'Length) := Str; - begin - Res); - -end System.Value_I_Spec; diff --git a/gcc/ada/libgnat/s-valboo.adb b/gcc/ada/libgnat/s-valboo.adb index 8db33167c0fa..93d6fb2dbaf0 100644 --- a/gcc/ada/libgnat/s-valboo.adb +++ b/gcc/ada/libgnat/s-valboo.adb @@ -29,14 +29,6 @@ -- -- ------------------------------------------------------------------------------ --- Ghost code, loop invariants and assertions in this unit are meant for --- analysis only, not for run-time checking, as it would be too costly --- otherwise. This is enforced by setting the assertion policy to Ignore. - -pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - with System.Val_Util; use System.Val_Util; package body System.Val_Bool @@ -55,9 +47,6 @@ is begin Normalize_String (S, F, L, To_Upper_Case => True); - pragma Assert (F = System.Val_Spec.First_Non_Space_Ghost - (S, Str'First, Str'Last)); - if S (F .. L) = "TRUE" then return True; diff --git a/gcc/ada/libgnat/s-valboo.ads b/gcc/ada/libgnat/s-valboo.ads index fdd8a3fe1006..b2fd558716d7 100644 --- a/gcc/ada/libgnat/s-valboo.ads +++ b/gcc/ada/libgnat/s-valboo.ads @@ -29,32 +29,12 @@ -- -- ------------------------------------------------------------------------------ --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - -with System.Val_Spec; - package System.Val_Bool with SPARK_Mode is pragma Preelaborate; - function Value_Boolean (Str : String) return Boolean - with - Pre => System.Val_Spec.Is_Boolean_Image_Ghost (Str, True) - or else System.Val_Spec.Is_Boolean_Image_Ghost (Str, False), - Post => - Value_Boolean'Result = - (Str (System.Val_Spec.First_Non_Space_Ghost - (Str, Str'First, Str'Last)) in 't' | 'T'); + function Value_Boolean (Str : String) return Boolean; -- Computes Boolean'Value (Str) end System.Val_Bool; diff --git a/gcc/ada/libgnat/s-valint.ads b/gcc/ada/libgnat/s-valint.ads index 6045cd6bc006..164bbfe16888 100644 --- a/gcc/ada/libgnat/s-valint.ads +++ b/gcc/ada/libgnat/s-valint.ads @@ -32,23 +32,9 @@ -- This package contains routines for scanning signed Integer values for use -- in Text_IO.Integer_IO, and the Value attribute. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - with System.Unsigned_Types; with System.Val_Uns; with System.Value_I; -with System.Vs_Int; -with System.Vs_Uns; package System.Val_Int with SPARK_Mode is pragma Preelaborate; @@ -58,9 +44,7 @@ package System.Val_Int with SPARK_Mode is package Impl is new Value_I (Int => Integer, Uns => Unsigned, - Scan_Raw_Unsigned => Val_Uns.Scan_Raw_Unsigned, - U_Spec => System.Vs_Uns.Spec, - Spec => System.Vs_Int.Spec); + Scan_Raw_Unsigned => Val_Uns.Scan_Raw_Unsigned); procedure Scan_Integer (Str : String; diff --git a/gcc/ada/libgnat/s-vallli.ads b/gcc/ada/libgnat/s-vallli.ads index 7672cc53f951..a3b48e39e762 100644 --- a/gcc/ada/libgnat/s-vallli.ads +++ b/gcc/ada/libgnat/s-vallli.ads @@ -32,23 +32,9 @@ -- This package contains routines for scanning signed Long_Long_Integer -- values for use in Text_IO.Integer_IO, and the Value attribute. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - with System.Unsigned_Types; with System.Val_LLU; with System.Value_I; -with System.Vs_LLI; -with System.Vs_LLU; package System.Val_LLI with SPARK_Mode is pragma Preelaborate; @@ -58,9 +44,7 @@ package System.Val_LLI with SPARK_Mode is package Impl is new Value_I (Int => Long_Long_Integer, Uns => Long_Long_Unsigned, - Scan_Raw_Unsigned => Val_LLU.Scan_Raw_Long_Long_Unsigned, - U_Spec => System.Vs_LLU.Spec, - Spec => System.Vs_LLI.Spec); + Scan_Raw_Unsigned => Val_LLU.Scan_Raw_Long_Long_Unsigned); procedure Scan_Long_Long_Integer (Str : String; diff --git a/gcc/ada/libgnat/s-valllli.ads b/gcc/ada/libgnat/s-valllli.ads index e2cae26d2450..719d4f42781c 100644 --- a/gcc/ada/libgnat/s-valllli.ads +++ b/gcc/ada/libgnat/s-valllli.ads @@ -32,23 +32,9 @@ -- This package contains routines for scanning signed Long_Long_Long_Integer -- values for use in Text_IO.Integer_IO, and the Value attribute. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - with System.Unsigned_Types; with System.Val_LLLU; with System.Value_I; -with System.Vs_LLLI; -with System.Vs_LLLU; package System.Val_LLLI with SPARK_Mode is pragma Preelaborate; @@ -58,9 +44,7 @@ package System.Val_LLLI with SPARK_Mode is package Impl is new Value_I (Int => Long_Long_Long_Integer, Uns => Long_Long_Long_Unsigned, - Scan_Raw_Unsigned => Val_LLLU.Scan_Raw_Long_Long_Long_Unsigned, - U_Spec => System.Vs_LLLU.Spec, - Spec => System.Vs_LLLI.Spec); + Scan_Raw_Unsigned => Val_LLLU.Scan_Raw_Long_Long_Long_Unsigned); procedure Scan_Long_Long_Long_Integer (Str : String; diff --git a/gcc/ada/libgnat/s-vallllu.ads b/gcc/ada/libgnat/s-vallllu.ads index 8e57e51ed8c9..50a061bf30d5 100644 --- a/gcc/ada/libgnat/s-vallllu.ads +++ b/gcc/ada/libgnat/s-vallllu.ads @@ -32,28 +32,15 @@ -- This package contains routines for scanning modular Long_Long_Unsigned -- values for use in Text_IO.Modular_IO, and the Value attribute. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - with System.Unsigned_Types; with System.Value_U; -with System.Vs_LLLU; package System.Val_LLLU with SPARK_Mode is pragma Preelaborate; subtype Long_Long_Long_Unsigned is Unsigned_Types.Long_Long_Long_Unsigned; - package Impl is new Value_U (Long_Long_Long_Unsigned, System.Vs_LLLU.Spec); + package Impl is new Value_U (Long_Long_Long_Unsigned); procedure Scan_Raw_Long_Long_Long_Unsigned (Str : String; diff --git a/gcc/ada/libgnat/s-valllu.ads b/gcc/ada/libgnat/s-valllu.ads index a7e37fcb1709..eeb9a25f0a21 100644 --- a/gcc/ada/libgnat/s-valllu.ads +++ b/gcc/ada/libgnat/s-valllu.ads @@ -32,28 +32,15 @@ -- This package contains routines for scanning modular Long_Long_Unsigned -- values for use in Text_IO.Modular_IO, and the Value attribute. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - with System.Unsigned_Types; with System.Value_U; -with System.Vs_LLU; package System.Val_LLU with SPARK_Mode is pragma Preelaborate; subtype Long_Long_Unsigned is Unsigned_Types.Long_Long_Unsigned; - package Impl is new Value_U (Long_Long_Unsigned, System.Vs_LLU.Spec); + package Impl is new Value_U (Long_Long_Unsigned); procedure Scan_Raw_Long_Long_Unsigned (Str : String; diff --git a/gcc/ada/libgnat/s-valrea.adb b/gcc/ada/libgnat/s-valrea.adb index aff694dd7219..aaa82d4e2c1b 100644 --- a/gcc/ada/libgnat/s-valrea.adb +++ b/gcc/ada/libgnat/s-valrea.adb @@ -49,7 +49,8 @@ package body System.Val_Real is Precision_Limit : constant Uns := 2**Num'Machine_Mantissa - 1; -- See below for the rationale - package Impl is new Value_R (Uns, 2, Precision_Limit, Round => False); + package Impl is new Value_R (Uns, 2, Precision_Limit); + -- We do not use the Extra digits for floating-point types subtype Base_T is Unsigned range 2 .. 16; @@ -90,7 +91,7 @@ package body System.Val_Real is when others => raise Program_Error); -- Return the exponent of a power of 2 - function Integer_to_Real + function Integer_To_Real (Str : String; Val : Impl.Value_Array; Base : Unsigned; @@ -105,10 +106,10 @@ package body System.Val_Real is -- Return Num'Scaling (5.0**Exp, -S) as a double number where Exp > Maxexp --------------------- - -- Integer_to_Real -- + -- Integer_To_Real -- --------------------- - function Integer_to_Real + function Integer_To_Real (Str : String; Val : Impl.Value_Array; Base : Unsigned; @@ -213,7 +214,7 @@ package body System.Val_Real is -- Compute the final value by applying the scaling, if any - if (Val (1) = 0 and then Val (2) = 0) or else S = 0 then + if Val (1) = 0 or else S = 0 then R_Val := Double_Real.To_Single (D_Val); else @@ -313,7 +314,7 @@ package body System.Val_Real is exception when Constraint_Error => Bad_Value (Str); - end Integer_to_Real; + end Integer_To_Real; ------------------- -- Large_Powfive -- @@ -456,7 +457,7 @@ package body System.Val_Real is begin Val := Impl.Scan_Raw_Real (Str, Ptr, Max, Base, Scale, Extra, Minus); - return Integer_to_Real (Str, Val, Base, Scale, Minus); + return Integer_To_Real (Str, Val, Base, Scale, Minus); end Scan_Real; ---------------- @@ -473,7 +474,7 @@ package body System.Val_Real is begin Val := Impl.Value_Raw_Real (Str, Base, Scale, Extra, Minus); - return Integer_to_Real (Str, Val, Base, Scale, Minus); + return Integer_To_Real (Str, Val, Base, Scale, Minus); end Value_Real; end System.Val_Real; diff --git a/gcc/ada/libgnat/s-valspe.ads b/gcc/ada/libgnat/s-valspe.ads deleted file mode 100644 index fbd3ba531220..000000000000 --- a/gcc/ada/libgnat/s-valspe.ads +++ /dev/null @@ -1,246 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- S Y S T E M . V A L _ S P E C -- --- -- --- S p e c -- --- -- --- Copyright (C) 2023-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - --- This package is part of a set of Ghost code packages used to proof the --- implementations of the Image and Value attributes. It provides some common --- specification functions used by the s-valxxx files. - --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - -package System.Val_Spec with - SPARK_Mode, - Pure, - Ghost -is - function Only_Space_Ghost (S : String; From, To : Integer) return Boolean is - (for all J in From .. To => S (J) = ' ') - with - Pre => From > To or else (From >= S'First and then To <= S'Last), - Post => True; - -- Ghost function that returns True if S has only space characters from - -- index From to index To. - - function First_Non_Space_Ghost - (S : String; - From, To : Integer) return Positive - with - Pre => From in S'Range - and then To in S'Range - and then not Only_Space_Ghost (S, From, To), - Post => First_Non_Space_Ghost'Result in From .. To - and then S (First_Non_Space_Ghost'Result) /= ' ' - and then Only_Space_Ghost - (S, From, First_Non_Space_Ghost'Result - 1); - -- Ghost function that returns the index of the first non-space character - -- in S, which necessarily exists given the precondition on S. - - function Is_Boolean_Image_Ghost - (Str : String; - Val : Boolean) return Boolean - is - (not Only_Space_Ghost (Str, Str'First, Str'Last) - and then - (declare - F : constant Positive := First_Non_Space_Ghost - (Str, Str'First, Str'Last); - begin - (Val - and then F <= Str'Last - 3 - and then Str (F) in 't' | 'T' - and then Str (F + 1) in 'r' | 'R' - and then Str (F + 2) in 'u' | 'U' - and then Str (F + 3) in 'e' | 'E' - and then - (if F + 3 < Str'Last then - Only_Space_Ghost (Str, F + 4, Str'Last))) - or else - (not Val - and then F <= Str'Last - 4 - and then Str (F) in 'f' | 'F' - and then Str (F + 1) in 'a' | 'A' - and then Str (F + 2) in 'l' | 'L' - and then Str (F + 3) in 's' | 'S' - and then Str (F + 4) in 'e' | 'E' - and then - (if F + 4 < Str'Last then - Only_Space_Ghost (Str, F + 5, Str'Last))))) - with - Ghost; - -- Ghost function that returns True iff Str is the image of boolean Val, - -- that is "true" or "false" in any capitalization, possibly surounded by - -- space characters. - - function Only_Number_Ghost (Str : String; From, To : Integer) return Boolean - is - (for all J in From .. To => Str (J) in '0' .. '9' | '_') - with - Pre => From > To or else (From >= Str'First and then To <= Str'Last); - -- Ghost function that returns True if S has only number characters from - -- index From to index To. - - function Last_Number_Ghost (Str : String) return Positive - with - Pre => Str /= "" and then Str (Str'First) in '0' .. '9', - Post => Last_Number_Ghost'Result in Str'Range - and then (if Last_Number_Ghost'Result < Str'Last then - Str (Last_Number_Ghost'Result + 1) not in '0' .. '9' | '_') - and then Only_Number_Ghost (Str, Str'First, Last_Number_Ghost'Result); - -- Ghost function that returns the index of the last character in S that - -- is either a figure or underscore, which necessarily exists given the - -- precondition on Str. - - function Is_Natural_Format_Ghost (Str : String) return Boolean is - (Str /= "" - and then Str (Str'First) in '0' .. '9' - and then - (declare - L : constant Positive := Last_Number_Ghost (Str); - begin - Str (L) in '0' .. '9' - and then (for all J in Str'First .. L => - (if Str (J) = '_' then Str (J + 1) /= '_')))); - -- Ghost function that determines if Str has the correct format for a - -- natural number, consisting in a sequence of figures possibly separated - -- by single underscores. It may be followed by other characters. - - function Starts_As_Exponent_Format_Ghost - (Str : String; - Real : Boolean := False) return Boolean - is - (Str'Length > 1 - and then Str (Str'First) in 'E' | 'e' - and then - (declare - Plus_Sign : constant Boolean := Str (Str'First + 1) = '+'; - Minus_Sign : constant Boolean := Str (Str'First + 1) = '-'; - Sign : constant Boolean := Plus_Sign or Minus_Sign; - begin - (if Minus_Sign then Real) - and then (if Sign then Str'Length > 2) - and then - (declare - Start : constant Natural := - (if Sign then Str'First + 2 else Str'First + 1); - begin - Str (Start) in '0' .. '9'))); - -- Ghost function that determines if Str is recognized as something which - -- might be an exponent, ie. it starts with an 'e', capitalized or not, - -- followed by an optional sign which can only be '-' if we are working on - -- real numbers (Real is True), and then a digit in decimal notation. - - function Is_Opt_Exponent_Format_Ghost - (Str : String; - Real : Boolean := False) return Boolean - is - (not Starts_As_Exponent_Format_Ghost (Str, Real) - or else - (declare - Start : constant Natural := - (if Str (Str'First + 1) in '+' | '-' then Str'First + 2 - else Str'First + 1); - begin Is_Natural_Format_Ghost (Str (Start .. Str'Last)))); - -- Ghost function that determines if Str has the correct format for an - -- optional exponent, that is, either it does not start as an exponent, or - -- it is in a correct format for a natural number. - - function Scan_Natural_Ghost - (Str : String; - P : Natural; - Acc : Natural) - return Natural - with - Subprogram_Variant => (Increases => P), - Pre => Str /= "" and then Str (Str'First) in '0' .. '9' - and then Str'Last < Natural'Last - and then P in Str'First .. Last_Number_Ghost (Str) + 1; - -- Ghost function that recursively computes the natural number in Str, up - -- to the first number greater or equal to Natural'Last / 10, assuming Acc - -- has been scanned already and scanning continues at index P. - - function Scan_Exponent_Ghost - (Str : String; - Real : Boolean := False) - return Integer - is - (declare - Plus_Sign : constant Boolean := Str (Str'First + 1) = '+'; - Minus_Sign : constant Boolean := Str (Str'First + 1) = '-'; - Sign : constant Boolean := Plus_Sign or Minus_Sign; - Start : constant Natural := - (if Sign then Str'First + 2 else Str'First + 1); - Value : constant Natural := - Scan_Natural_Ghost (Str (Start .. Str'Last), Start, 0); - begin - (if Minus_Sign then -Value else Value)) - with - Pre => Str'Last < Natural'Last - and then Starts_As_Exponent_Format_Ghost (Str, Real), - Post => (if not Real then Scan_Exponent_Ghost'Result >= 0); - -- Ghost function that scans an exponent - -private - - ------------------------ - -- Scan_Natural_Ghost -- - ------------------------ - - function Scan_Natural_Ghost - (Str : String; - P : Natural; - Acc : Natural) - return Natural - is - (if P > Str'Last - or else Str (P) not in '0' .. '9' | '_' - or else Acc >= Integer'Last / 10 - then - Acc - elsif Str (P) = '_' then - Scan_Natural_Ghost (Str, P + 1, Acc) - else - (declare - Shift_Acc : constant Natural := - Acc * 10 + - (Integer'(Character'Pos (Str (P))) - - Integer'(Character'Pos ('0'))); - begin - Scan_Natural_Ghost (Str, P + 1, Shift_Acc))); - -end System.Val_Spec; diff --git a/gcc/ada/libgnat/s-valued.adb b/gcc/ada/libgnat/s-valued.adb index dfef9a885e52..b7982b6046f7 100644 --- a/gcc/ada/libgnat/s-valued.adb +++ b/gcc/ada/libgnat/s-valued.adb @@ -38,14 +38,16 @@ package body System.Value_D is pragma Assert (Int'Size <= Uns'Size); -- We need an unsigned type large enough to represent the mantissa - package Impl is new Value_R (Uns, 1, 2**(Int'Size - 1), Round => False); - -- We do not use the Extra digit for decimal fixed-point types + package Impl is new Value_R (Uns, 1, 2**(Int'Size - 1)); + -- We do not use the Extra digits for decimal fixed-point types, except to + -- effectively ensure that overflow is detected near the boundaries. function Integer_to_Decimal (Str : String; Val : Uns; Base : Unsigned; ScaleB : Integer; + Extra2 : Unsigned; Minus : Boolean; Scale : Integer) return Int; -- Convert the real value from integer to decimal representation @@ -59,6 +61,7 @@ package body System.Value_D is Val : Uns; Base : Unsigned; ScaleB : Integer; + Extra2 : Unsigned; Minus : Boolean; Scale : Integer) return Int is @@ -72,7 +75,7 @@ package body System.Value_D is -- updated to contain the remaining power in the computation. Note that -- Factor is expected to be positive in this context. - function Unsigned_To_Signed (Val : Uns) return Int; + function To_Signed (Val : Uns) return Int; -- Convert an integer value from unsigned to signed representation ----------------- @@ -99,11 +102,11 @@ package body System.Value_D is return Result; end Safe_Expont; - ------------------------ - -- Unsigned_To_Signed -- - ------------------------ + --------------- + -- To_Signed -- + --------------- - function Unsigned_To_Signed (Val : Uns) return Int is + function To_Signed (Val : Uns) return Int is begin -- Deal with overflow cases, and also with largest negative number @@ -124,34 +127,51 @@ package body System.Value_D is else return Int (Val); end if; - end Unsigned_To_Signed; + end To_Signed; + + -- Local variables + + V : Uns := Val; + S : Integer := ScaleB; + E : Unsigned := Extra2 / Base; begin + -- The implementation of Value_R uses fully symmetric arithmetics + -- but here we cannot handle 2**(Int'Size - 1) if Minus is not set. + + if V = 2**(Int'Size - 1) and then not Minus then + E := Unsigned (V rem Uns (Base)); + V := V / Uns (Base); + S := S + 1; + end if; + -- If the base of the value is 10 or its scaling factor is zero, then -- add the scales (they are defined in the opposite sense) and apply -- the result to the value, checking for overflow in the process. - if Base = 10 or else ScaleB = 0 then - declare - S : Integer := ScaleB + Scale; - V : Uns := Val; - + if Base = 10 or else S = 0 then begin + S := S + Scale; + while S < 0 loop + if V = 0 then + exit; + end if; V := V / 10; S := S + 1; end loop; while S > 0 loop - if V <= Uns'Last / 10 then - V := V * 10; + if V <= (Uns'Last - Uns (E)) / 10 then + V := V * 10 + Uns (E); S := S - 1; + E := 0; else Bad_Value (Str); end if; end loop; - return Unsigned_To_Signed (V); + return To_Signed (V); end; -- If the base of the value is not 10, use a scaled divide operation @@ -159,10 +179,7 @@ package body System.Value_D is else declare - B : constant Int := Int (Base); - S : constant Integer := ScaleB; - - V : Uns := Val; + B : constant Int := Int (Base); Y, Z, Q, R : Int; @@ -178,7 +195,10 @@ package body System.Value_D is Z := Safe_Expont (B, LS, 10 ** Integer'Max (0, -Scale)); for J in 1 .. LS loop - V := V / Uns (B); + if V = 0 then + exit; + end if; + V := V / Uns (Base); end loop; end; @@ -193,8 +213,9 @@ package body System.Value_D is Z := 10 ** Integer'Max (0, -Scale); for J in 1 .. LS loop - if V <= Uns'Last / Uns (B) then - V := V * Uns (B); + if V <= (Uns'Last - Uns (E)) / Uns (Base) then + V := V * Uns (Base) + Uns (E); + E := 0; else Bad_Value (Str); end if; @@ -207,9 +228,9 @@ package body System.Value_D is raise Program_Error; end if; - -- Perform a scale divide operation with rounding to match 'Image + -- Perform a scaled divide operation with truncation - Scaled_Divide (Unsigned_To_Signed (V), Y, Z, Q, R, Round => True); + Scaled_Divide (To_Signed (V), Y, Z, Q, R, Round => False); return Q; end; @@ -229,16 +250,17 @@ package body System.Value_D is Max : Integer; Scale : Integer) return Int is - Base : Unsigned; - Scl : Impl.Scale_Array; - Extra : Unsigned; - Minus : Boolean; - Val : Impl.Value_Array; + Base : Unsigned; + Scl : Impl.Scale_Array; + Extra2 : Unsigned; + Minus : Boolean; + Val : Impl.Value_Array; begin - Val := Impl.Scan_Raw_Real (Str, Ptr, Max, Base, Scl, Extra, Minus); + Val := Impl.Scan_Raw_Real (Str, Ptr, Max, Base, Scl, Extra2, Minus); - return Integer_to_Decimal (Str, Val (1), Base, Scl (1), Minus, Scale); + return + Integer_to_Decimal (Str, Val (1), Base, Scl (1), Extra2, Minus, Scale); end Scan_Decimal; ------------------- @@ -246,16 +268,17 @@ package body System.Value_D is ------------------- function Value_Decimal (Str : String; Scale : Integer) return Int is - Base : Unsigned; - Scl : Impl.Scale_Array; - Extra : Unsigned; - Minus : Boolean; - Val : Impl.Value_Array; + Base : Unsigned; + Scl : Impl.Scale_Array; + Extra2 : Unsigned; + Minus : Boolean; + Val : Impl.Value_Array; begin - Val := Impl.Value_Raw_Real (Str, Base, Scl, Extra, Minus); + Val := Impl.Value_Raw_Real (Str, Base, Scl, Extra2, Minus); - return Integer_to_Decimal (Str, Val (1), Base, Scl (1), Minus, Scale); + return + Integer_to_Decimal (Str, Val (1), Base, Scl (1), Extra2, Minus, Scale); end Value_Decimal; end System.Value_D; diff --git a/gcc/ada/libgnat/s-valuef.adb b/gcc/ada/libgnat/s-valuef.adb index 993074041af0..f38f2cc66ac3 100644 --- a/gcc/ada/libgnat/s-valuef.adb +++ b/gcc/ada/libgnat/s-valuef.adb @@ -36,25 +36,26 @@ with System.Value_R; package body System.Value_F is -- The prerequisite of the implementation is that the computation of the - -- operands of the scaled divide does not unduly overflow when the small - -- is neither an integer nor the reciprocal of an integer, which means - -- that its numerator and denominator must be both not larger than the - -- smallest divide 2**(Int'Size - 1) / Base where Base ranges over the - -- supported values for the base of the literal. Given that the largest - -- supported base is 16, this gives a limit of 2**(Int'Size - 5). + -- operands of the scaled divide does not unduly overflow, which means + -- that the numerator and the denominator of the small must be both not + -- larger than the smallest divide 2**(Int'Size - 1) / Base where Base + -- ranges over the supported values for the base of the literal, except + -- when the numerator is 1, in which case up to 2**(Int'Size - 1) is + -- permitted for the denominator. Given that the largest supported base + -- is 16, this gives a limit of 2**(Int'Size - 5) in the general case. pragma Assert (Int'Size <= Uns'Size); -- We need an unsigned type large enough to represent the mantissa - package Impl is new Value_R (Uns, 1, 2**(Int'Size - 1), Round => True); - -- We use the Extra digit for ordinary fixed-point types + package Impl is new Value_R (Uns, 1, 2**(Int'Size - 1)); + -- We use the Extra digits for ordinary fixed-point types function Integer_To_Fixed (Str : String; Val : Uns; Base : Unsigned; ScaleB : Integer; - Extra : Unsigned; + Extra2 : Unsigned; Minus : Boolean; Num : Int; Den : Int) return Int; @@ -79,23 +80,25 @@ package body System.Value_F is -- Of course N1 = N2 + 1 holds, which means both that Val may not contain -- enough significant bits to represent all the values of the type and that - -- 1 extra decimal digit contains the information for the missing bits. + -- 1 extra decimal digit contains the information for the missing bits. But + -- in practice we need 2 extra decimal digits to avoid multiple roundings. -- Therefore the actual computation to be performed is - -- V = (Val * Base + Extra) * (Base ** (ScaleB - 1)) / (Num / Den) + -- V = (Val * Base ** 2 + Extra2) * (Base ** (ScaleB - 2)) / (Num / Den) - -- using two steps of scaled divide if Extra is positive and ScaleB too + -- using two steps of scaled divide if Extra2 is positive and ScaleB too - -- (1) Val * (Den * (Base ** ScaleB)) = Q1 * Num + R1 + -- (1a) Val * (Den * (Base ** ScaleB)) = Q1 * Num + R1 - -- (2) Extra * (Den * (Base ** ScaleB)) = Q2 * -Base + R2 + -- (2a) Extra2 * (Den * (Base ** ScaleB)) = Q2 * Base ** 2 + R2 - -- which yields after dividing (1) by Num and (2) by Num * Base and summing + -- which yields after dividing (1a) by Num and (2a) by Num * (Base ** 2) + -- and summing - -- V = Q1 + (R1 - Q2) / Num + R2 / (Num * Base) + -- V = Q1 + (Q2 + R1) / Num + R2 / (Num * (Base ** 2)) - -- but we get rid of the third term by using a rounding divide for (2). + -- but we get rid of the third term by using a rounding divide for (2a). -- This works only if Den * (Base ** ScaleB) does not overflow for inputs -- corresponding to 'Image. Let S = Num / Den, B = Base and N the scale in @@ -113,17 +116,17 @@ package body System.Value_F is -- which means that the product does not overflow if Num <= 2**(M-1) / B. - -- On the other hand, if Extra is positive and ScaleB negative, the above + -- On the other hand, if Extra2 is positive and ScaleB negative, the above -- two steps are -- (1b) Val * Den = Q1 * (Num * (Base ** -ScaleB)) + R1 - -- (2b) Extra * Den = Q2 * -Base + R2 + -- (2b) Extra2 * Den = Q2 * Base ** 2 + R2 -- which yields after dividing (1b) by Num * (Base ** -ScaleB) and (2b) by - -- Num * (Base ** (1 - ScaleB)) and summing + -- Num * (Base ** (2 - ScaleB)) and summing - -- V = Q1 + (R1 - Q2) / (Num * (Base ** -ScaleB)) + R2 / ... + -- V = Q1 + (Q2 + R1) / (Num * (Base ** -ScaleB)) + R2 / (Num * (...)) -- but we get rid of the third term by using a rounding divide for (2b). @@ -133,6 +136,9 @@ package body System.Value_F is -- Num * (Base ** -ScaleB) <= Num * (B ** N) < Den * B -- which means that the product does not overflow if Den <= 2**(M-1) / B. + -- Moreover, if 2**(M-1) / B < Den <= 2**(M-1), we can add 1 to ScaleB and + -- divide Val by B while preserving the rightmost B-digit of Val in Extra2 + -- without changing the computation when Num = 1. ---------------------- -- Integer_To_Fixed -- @@ -143,19 +149,22 @@ package body System.Value_F is Val : Uns; Base : Unsigned; ScaleB : Integer; - Extra : Unsigned; + Extra2 : Unsigned; Minus : Boolean; Num : Int; Den : Int) return Int is pragma Assert (Base in 2 .. 16); - pragma Assert (Extra < Base); - -- Accept only one extra digit after those used for Val + pragma Assert (Extra2 < Base ** 2); + -- Accept only two extra digits after those used for Val pragma Assert (Num < 0 and then Den < 0); -- Accept only negative numbers to allow -2**(Int'Size - 1) + pragma Unsuppress (Overflow_Check); + -- Use overflow check to catch bad values + function Safe_Expont (Base : Int; Exp : in out Natural; @@ -166,7 +175,7 @@ package body System.Value_F is -- updated to contain the remaining power in the computation. Note that -- Factor is expected to be negative in this context. - function Unsigned_To_Signed (Val : Uns) return Int; + function To_Signed (Val : Uns) return Int; -- Convert an integer value from unsigned to signed representation ----------------- @@ -193,11 +202,11 @@ package body System.Value_F is return Result; end Safe_Expont; - ------------------------ - -- Unsigned_To_Signed -- - ------------------------ + --------------- + -- To_Signed -- + --------------- - function Unsigned_To_Signed (Val : Uns) return Int is + function To_Signed (Val : Uns) return Int is begin -- Deal with overflow cases, and also with largest negative number @@ -218,60 +227,74 @@ package body System.Value_F is else return Int (Val); end if; - end Unsigned_To_Signed; + end To_Signed; -- Local variables B : constant Int := Int (Base); - V : Uns := Val; - E : Uns := Uns (Extra); + V : Uns := Val; + S : Integer := ScaleB; + E : Unsigned := Extra2; Y, Z, Q1, R1, Q2, R2 : Int; begin + -- The implementation of Value_R uses fully symmetric arithmetics + -- but here we cannot handle 2**(Int'Size - 1) if Minus is not set. + + if V = 2**(Int'Size - 1) and then not Minus then + E := Unsigned (V rem Uns (Base)) * Base + E / Base; + V := V / Uns (Base); + S := S + 1; + end if; + -- We will use a scaled divide operation for which we must control the -- magnitude of operands so that an overflow exception is not unduly -- raised during the computation. The only real concern is the exponent. - -- If ScaleB is too negative, then drop trailing digits, but preserve - -- the last dropped digit. + -- If S is too negative, then drop trailing digits, but preserve the + -- last two dropped digits, until V saturates to 0. - if ScaleB < 0 then + if S < 0 then declare - LS : Integer := -ScaleB; + LS : Integer := -S; begin Y := Den; Z := Safe_Expont (B, LS, Num); for J in 1 .. LS loop - E := V rem Uns (B); - V := V / Uns (B); + if V = 0 then + E := 0; + exit; + end if; + E := Unsigned (V rem Uns (Base)) * Base + E / Base; + V := V / Uns (Base); end loop; end; - -- If ScaleB is too positive, then scale V up, which may then overflow + -- If S is too positive, then scale V up, which may then overflow - elsif ScaleB > 0 then + elsif S > 0 then declare - LS : Integer := ScaleB; + LS : Integer := S; begin Y := Safe_Expont (B, LS, Den); Z := Num; for J in 1 .. LS loop - if V <= (Uns'Last - E) / Uns (B) then - V := V * Uns (B) + E; - E := 0; + if V <= (Uns'Last - Uns (E / Base)) / Uns (Base) then + V := V * Uns (Base) + Uns (E / Base); + E := (E rem Base) * Base; else Bad_Value (Str); end if; end loop; end; - -- If ScaleB is zero, then proceed directly + -- If S is zero, then proceed directly else Y := Den; @@ -284,8 +307,8 @@ package body System.Value_F is -- sign of the first operand and the sign of the remainder the opposite. if E > 0 then - Scaled_Divide (Unsigned_To_Signed (V), Y, Z, Q1, R1, Round => False); - Scaled_Divide (Unsigned_To_Signed (E), Y, -B, Q2, R2, Round => True); + Scaled_Divide (To_Signed (V), Y, Z, Q1, R1, Round => False); + Scaled_Divide (To_Signed (Uns (E)), Y, -B**2, Q2, R2, Round => True); -- Avoid an overflow during the subtraction. Note that Q2 is smaller -- than Y and R1 smaller than Z in magnitude, so it is safe to take @@ -312,7 +335,7 @@ package body System.Value_F is return Q1 + Q2; else - Scaled_Divide (Unsigned_To_Signed (V), Y, Z, Q1, R1, Round => True); + Scaled_Divide (To_Signed (V), Y, Z, Q1, R1, Round => True); return Q1; end if; @@ -332,17 +355,17 @@ package body System.Value_F is Num : Int; Den : Int) return Int is - Base : Unsigned; - Scl : Impl.Scale_Array; - Extra : Unsigned; - Minus : Boolean; - Val : Impl.Value_Array; + Bas : Unsigned; + Scl : Impl.Scale_Array; + Extra2 : Unsigned; + Minus : Boolean; + Val : Impl.Value_Array; begin - Val := Impl.Scan_Raw_Real (Str, Ptr, Max, Base, Scl, Extra, Minus); + Val := Impl.Scan_Raw_Real (Str, Ptr, Max, Bas, Scl, Extra2, Minus); return - Integer_To_Fixed (Str, Val (1), Base, Scl (1), Extra, Minus, Num, Den); + Integer_To_Fixed (Str, Val (1), Bas, Scl (1), Extra2, Minus, Num, Den); end Scan_Fixed; ----------------- @@ -354,17 +377,17 @@ package body System.Value_F is Num : Int; Den : Int) return Int is - Base : Unsigned; - Scl : Impl.Scale_Array; - Extra : Unsigned; - Minus : Boolean; - Val : Impl.Value_Array; + Bas : Unsigned; + Scl : Impl.Scale_Array; + Extra2 : Unsigned; + Minus : Boolean; + Val : Impl.Value_Array; begin - Val := Impl.Value_Raw_Real (Str, Base, Scl, Extra, Minus); + Val := Impl.Value_Raw_Real (Str, Bas, Scl, Extra2, Minus); return - Integer_To_Fixed (Str, Val (1), Base, Scl (1), Extra, Minus, Num, Den); + Integer_To_Fixed (Str, Val (1), Bas, Scl (1), Extra2, Minus, Num, Den); end Value_Fixed; end System.Value_F; diff --git a/gcc/ada/libgnat/s-valuei.adb b/gcc/ada/libgnat/s-valuei.adb index 2c4fe099eab0..53790a08094f 100644 --- a/gcc/ada/libgnat/s-valuei.adb +++ b/gcc/ada/libgnat/s-valuei.adb @@ -33,16 +33,6 @@ with System.Val_Util; use System.Val_Util; package body System.Value_I is - -- Ghost code, loop invariants and assertions in this unit are meant for - -- analysis only, not for run-time checking, as it would be too costly - -- otherwise. This is enforced by setting the assertion policy to Ignore. - - pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore, - Assert_And_Cut => Ignore, - Subprogram_Variant => Ignore); - ------------------ -- Scan_Integer -- ------------------ @@ -53,25 +43,6 @@ package body System.Value_I is Max : Integer; Res : out Int) is - procedure Prove_Is_Int_Of_Uns - (Minus : Boolean; - Uval : Uns; - Val : Int) - with Ghost, - Pre => Spec.Uns_Is_Valid_Int (Minus, Uval) - and then - (if Minus and then Uval = Uns (Int'Last) + 1 then Val = Int'First - elsif Minus then Val = -(Int (Uval)) - else Val = Int (Uval)), - Post => Spec.Is_Int_Of_Uns (Minus, Uval, Val); - -- Unfold the definition of Is_Int_Of_Uns - - procedure Prove_Is_Int_Of_Uns - (Minus : Boolean; - Uval : Uns; - Val : Int) - is null; - Uval : Uns; -- Unsigned result @@ -81,15 +52,6 @@ package body System.Value_I is Unused_Start : Positive; -- Saves location of first non-blank (not used in this case) - Non_Blank : constant Positive := - First_Non_Space_Ghost (Str, Ptr.all, Max) - with Ghost; - - Fst_Num : constant Positive := - (if Str (Non_Blank) in '+' | '-' then Non_Blank + 1 - else Non_Blank) - with Ghost; - begin Scan_Sign (Str, Ptr, Max, Minus, Unused_Start); @@ -99,8 +61,6 @@ package body System.Value_I is end if; Scan_Raw_Unsigned (Str, Ptr, Max, Uval); - pragma Assert - (Uval = U_Spec.Scan_Raw_Unsigned_Ghost (Str, Fst_Num, Max)); -- Deal with overflow cases, and also with largest negative number @@ -121,11 +81,6 @@ package body System.Value_I is else Res := Int (Uval); end if; - - Prove_Is_Int_Of_Uns - (Minus => Str (Non_Blank) = '-', - Uval => Uval, - Val => Res); end Scan_Integer; ------------------- @@ -141,15 +96,7 @@ package body System.Value_I is if Str'Last = Positive'Last then declare subtype NT is String (1 .. Str'Length); - procedure Prove_Is_Integer_Ghost with - Ghost, - Pre => Str'Length < Natural'Last - and then not Only_Space_Ghost (Str, Str'First, Str'Last) - and then Spec.Is_Integer_Ghost (Spec.Slide_To_1 (Str)), - Post => Spec.Is_Integer_Ghost (NT (Str)); - procedure Prove_Is_Integer_Ghost is null; begin - Prove_Is_Integer_Ghost; return Value_Integer (NT (Str)); end; @@ -159,31 +106,14 @@ package body System.Value_I is declare V : Int; P : aliased Integer := Str'First; - - Non_Blank : constant Positive := First_Non_Space_Ghost - (Str, Str'First, Str'Last) - with Ghost; - - Fst_Num : constant Positive := - (if Str (Non_Blank) in '+' | '-' then Non_Blank + 1 - else Non_Blank) - with Ghost; begin - declare P_Acc : constant not null access Integer := P'Access; begin Scan_Integer (Str, P_Acc, Str'Last, V); end; - pragma Assert - (P = U_Spec.Raw_Unsigned_Last_Ghost - (Str, Fst_Num, Str'Last)); - Scan_Trailing_Blanks (Str, P); - - pragma Assert - (Spec.Is_Value_Integer_Ghost (Spec.Slide_If_Necessary (Str), V)); return V; end; end if; diff --git a/gcc/ada/libgnat/s-valuei.ads b/gcc/ada/libgnat/s-valuei.ads index 531eae144004..08619c85a634 100644 --- a/gcc/ada/libgnat/s-valuei.ads +++ b/gcc/ada/libgnat/s-valuei.ads @@ -32,16 +32,6 @@ -- This package contains routines for scanning signed integer values for use -- in Text_IO.Integer_IO, and the Value attribute. -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -with System.Val_Spec; use System.Val_Spec; -with System.Value_I_Spec; -with System.Value_U_Spec; - generic type Int is range <>; @@ -54,13 +44,6 @@ generic Max : Integer; Res : out Uns); - -- Additional parameters for ghost subprograms used inside contracts - - with package U_Spec is new System.Value_U_Spec (Uns => Uns) with Ghost; - with package Spec is new System.Value_I_Spec - (Int => Int, Uns => Uns, U_Spec => U_Spec) - with Ghost; - package System.Value_I is pragma Preelaborate; @@ -68,43 +51,7 @@ package System.Value_I is (Str : String; Ptr : not null access Integer; Max : Integer; - Res : out Int) - with - Pre => Str'Last /= Positive'Last - -- Ptr.all .. Max is either an empty range, or a valid range in Str - and then (Ptr.all > Max - or else (Ptr.all >= Str'First and then Max <= Str'Last)) - and then not Only_Space_Ghost (Str, Ptr.all, Max) - and then - (declare - Non_Blank : constant Positive := First_Non_Space_Ghost - (Str, Ptr.all, Max); - Fst_Num : constant Positive := - (if Str (Non_Blank) in '+' | '-' then Non_Blank + 1 - else Non_Blank); - begin - U_Spec.Is_Raw_Unsigned_Format_Ghost (Str (Fst_Num .. Max)) - and then U_Spec.Raw_Unsigned_No_Overflow_Ghost - (Str, Fst_Num, Max) - and then Spec.Uns_Is_Valid_Int - (Minus => Str (Non_Blank) = '-', - Uval => U_Spec.Scan_Raw_Unsigned_Ghost - (Str, Fst_Num, Max))), - Post => - (declare - Non_Blank : constant Positive := First_Non_Space_Ghost - (Str, Ptr.all'Old, Max); - Fst_Num : constant Positive := - (if Str (Non_Blank) in '+' | '-' then Non_Blank + 1 - else Non_Blank); - Uval : constant Uns := - U_Spec.Scan_Raw_Unsigned_Ghost (Str, Fst_Num, Max); - begin - Spec.Is_Int_Of_Uns (Minus => Str (Non_Blank) = '-', - Uval => Uval, - Val => Res) - and then Ptr.all = U_Spec.Raw_Unsigned_Last_Ghost - (Str, Fst_Num, Max)); + Res : out Int); -- This procedure scans the string starting at Str (Ptr.all) for a valid -- integer according to the syntax described in (RM 3.5(43)). The substring -- scanned extends no further than Str (Max). There are three cases for the @@ -130,14 +77,7 @@ package System.Value_I is -- special case of an all-blank string, and Ptr is unchanged, and hence -- is greater than Max as required in this case. - function Value_Integer (Str : String) return Int - with - Pre => not Only_Space_Ghost (Str, Str'First, Str'Last) - and then Str'Length /= Positive'Last - and then Spec.Is_Integer_Ghost (Spec.Slide_If_Necessary (Str)), - Post => Spec.Is_Value_Integer_Ghost - (Spec.Slide_If_Necessary (Str), Value_Integer'Result), - Subprogram_Variant => (Decreases => Str'First); + function Value_Integer (Str : String) return Int; -- Used in computing X'Value (Str) where X is a signed integer type whose -- base range does not exceed the base range of Integer. Str is the string -- argument of the attribute. Constraint_Error is raised if the string is diff --git a/gcc/ada/libgnat/s-valuen.ads b/gcc/ada/libgnat/s-valuen.ads index 047ded6204bd..a57ee5567acb 100644 --- a/gcc/ada/libgnat/s-valuen.ads +++ b/gcc/ada/libgnat/s-valuen.ads @@ -30,8 +30,8 @@ ------------------------------------------------------------------------------ -- This package is used to compute the Value attribute for enumeration types --- other than those in packages Standard and System. See unit Exp_Imgv for --- details of the format of constructed image tables. +-- other than those in package Standard. See unit Exp_Imgv for details of the +-- format of constructed image tables. generic diff --git a/gcc/ada/libgnat/s-valuer.adb b/gcc/ada/libgnat/s-valuer.adb index 6f557e932079..961dda47d771 100644 --- a/gcc/ada/libgnat/s-valuer.adb +++ b/gcc/ada/libgnat/s-valuer.adb @@ -42,14 +42,6 @@ package body System.Value_R is function As_Digit (C : Character) return Char_As_Digit; -- Given a character return the digit it represents - procedure Round_Extra - (Digit : Char_As_Digit; - Base : Unsigned; - Value : in out Uns; - Scale : in out Integer; - Extra : in out Char_As_Digit); - -- Round the triplet (Value, Scale, Extra) according to Digit in Base - procedure Scan_Decimal_Digits (Str : String; Index : in out Integer; @@ -59,7 +51,7 @@ package body System.Value_R is Value : in out Value_Array; Scale : in out Scale_Array; N : in out Positive; - Extra : in out Char_As_Digit; + Extra2 : in out Unsigned; Base_Violation : in out Boolean); -- Scan the decimal part of a real (i.e. after decimal separator) -- @@ -68,7 +60,8 @@ package body System.Value_R is -- -- For each digit parsed, Value = Value * Base + Digit and Scale is -- decremented by 1. If precision limit is reached, remaining digits are - -- still parsed but ignored, except for the first which is stored in Extra. + -- still parsed but ignored, except for the first two of them which are + -- stored in Extra2. -- -- Base_Violation is set to True if a digit found is not part of the Base -- @@ -83,7 +76,8 @@ package body System.Value_R is Value : out Value_Array; Scale : out Scale_Array; N : out Positive; - Extra : out Char_As_Digit; + Extra2 : out Unsigned; + Extra2_Filled : out Boolean; Base_Violation : in out Boolean); -- Scan the integral part of a real (i.e. before decimal separator) -- @@ -93,7 +87,7 @@ package body System.Value_R is -- For each digit parsed, either Value := Value * Base + Digit or Scale -- is incremented by 1 if precision limit is reached, in which case the -- remaining digits are still parsed but ignored, except for the first - -- which is stored in Extra. + -- two of them which are stored in Extra2 if Extra2_Filled is True. -- -- Base_Violation is set to True if a digit found is not part of the Base -- @@ -119,47 +113,6 @@ package body System.Value_R is end case; end As_Digit; - ----------------- - -- Round_Extra -- - ----------------- - - procedure Round_Extra - (Digit : Char_As_Digit; - Base : Unsigned; - Value : in out Uns; - Scale : in out Integer; - Extra : in out Char_As_Digit) - is - pragma Assert (Base in 2 .. 16); - - B : constant Uns := Uns (Base); - - begin - if Digit >= Base / 2 then - - -- If Extra is maximum, round Value - - if Extra = Base - 1 then - - -- If Value is maximum, scale it up - - if Value = Precision_Limit then - Extra := Char_As_Digit (Value mod B); - Value := Value / B; - Scale := Scale + 1; - Round_Extra (Digit, Base, Value, Scale, Extra); - - else - Extra := 0; - Value := Value + 1; - end if; - - else - Extra := Extra + 1; - end if; - end if; - end Round_Extra; - ------------------------- -- Scan_Decimal_Digits -- ------------------------- @@ -173,7 +126,7 @@ package body System.Value_R is Value : in out Value_Array; Scale : in out Scale_Array; N : in out Positive; - Extra : in out Char_As_Digit; + Extra2 : in out Unsigned; Base_Violation : in out Boolean) is @@ -192,8 +145,7 @@ package body System.Value_R is -- to Precision_Limit. Precision_Limit_Just_Reached : Boolean; - -- Set to True if Precision_Limit_Reached was just set to True, but only - -- used when Round is True. + -- Set to True if Precision_Limit_Reached was just set to True Digit : Char_As_Digit; -- The current digit @@ -205,17 +157,16 @@ package body System.Value_R is -- Number of trailing zeros at a given point begin - -- If initial Scale is not 0 then it means that Precision_Limit was + -- If initial Scale is not 0, then this means that Precision_Limit was -- reached during scanning of the integral part. if Scale (Data_Index'Last) > 0 then Precision_Limit_Reached := True; + Precision_Limit_Just_Reached := True; + else - Extra := 0; + Extra2 := 0; Precision_Limit_Reached := False; - end if; - - if Round then Precision_Limit_Just_Reached := False; end if; @@ -229,28 +180,27 @@ package body System.Value_R is Digit := As_Digit (Str (Index)); loop - -- Check if base is correct. If the base is not specified, the digit - -- E or e cannot be considered as a base violation as it can be used - -- for exponentiation. + -- If the base is not explicitly specified, 'e' or 'E' marks the + -- beginning of the exponent part. + + if not Base_Specified and then Digit = E_Digit then + return; + end if; + + -- Check that Digit is a valid digit with respect to Base if Digit >= Base then - if Base_Specified then - Base_Violation := True; - elsif Digit = E_Digit then - return; - else - Base_Violation := True; - end if; + Base_Violation := True; end if; -- If precision limit has been reached, just ignore any remaining -- digits for the computation of Value and Scale, but store the - -- first in Extra and use the second to round Extra. The scanning - -- should continue only to assess the validity of the string. + -- first two digits in Extra2. The scanning should continue only + -- to assess the validity of the string. if Precision_Limit_Reached then - if Round and then Precision_Limit_Just_Reached then - Round_Extra (Digit, Base, Value (N), Scale (N), Extra); + if Precision_Limit_Just_Reached then + Extra2 := Extra2 + Digit; Precision_Limit_Just_Reached := False; end if; @@ -273,11 +223,8 @@ package body System.Value_R is Scale (N) := Scale (N - 1) - 1; else - Extra := 0; + Extra2 := (if J = Trailing_Zeros then Digit else 0); Precision_Limit_Reached := True; - if Round and then J = Trailing_Zeros then - Round_Extra (Digit, Base, Value (N), Scale (N), Extra); - end if; exit; end if; @@ -316,11 +263,9 @@ package body System.Value_R is Scale (N) := Scale (N - 1) - 1; else - Extra := Digit; + Extra2 := Digit * Base; Precision_Limit_Reached := True; - if Round then - Precision_Limit_Just_Reached := True; - end if; + Precision_Limit_Just_Reached := True; end if; end if; end if; @@ -339,10 +284,12 @@ package body System.Value_R is -- Underscore is only allowed if followed by a digit - if Digit = Underscore and Index + 1 <= Max then + if Digit = Underscore and then Index + 1 <= Max then Digit := As_Digit (Str (Index + 1)); - if Digit in Valid_Digit then + if Digit in Valid_Digit and then + (Digit /= E_Digit or else Base > E_Digit) + then Index := Index + 1; else return; @@ -370,7 +317,8 @@ package body System.Value_R is Value : out Value_Array; Scale : out Scale_Array; N : out Positive; - Extra : out Char_As_Digit; + Extra2 : out Unsigned; + Extra2_Filled : out Boolean; Base_Violation : in out Boolean) is pragma Assert (Base in 2 .. 16); @@ -386,8 +334,7 @@ package body System.Value_R is -- to Precision_Limit. Precision_Limit_Just_Reached : Boolean; - -- Set to True if Precision_Limit_Reached was just set to True, but only - -- used when Round is True. + -- Set to True if Precision_Limit_Reached was just set to True Digit : Char_As_Digit; -- The current digit @@ -396,18 +343,16 @@ package body System.Value_R is -- Temporary begin - -- Initialize N, Value, Scale and Extra + -- Initialize N, Value, Scale, Extra2 and Extra2_Filled N := 1; Value := (others => 0); Scale := (others => 0); - Extra := 0; + Extra2 := 0; + Extra2_Filled := False; Precision_Limit_Reached := False; - - if Round then - Precision_Limit_Just_Reached := False; - end if; + Precision_Limit_Just_Reached := False; pragma Assert (Max <= Str'Last); @@ -417,30 +362,30 @@ package body System.Value_R is Digit := As_Digit (Str (Index)); loop - -- Check if base is correct. If the base is not specified, the digit - -- E or e cannot be considered as a base violation as it can be used - -- for exponentiation. + -- If the base is not explicitly specified, 'e' or 'E' marks the + -- beginning of the exponent part. + + if not Base_Specified and then Digit = E_Digit then + return; + end if; + + -- Check that Digit is a valid digit with respect to Base if Digit >= Base then - if Base_Specified then - Base_Violation := True; - elsif Digit = E_Digit then - return; - else - Base_Violation := True; - end if; + Base_Violation := True; end if; -- If precision limit has been reached, just ignore any remaining -- digits for the computation of Value and Scale, but store the - -- first in Extra and use the second to round Extra. The scanning - -- should continue only to assess the validity of the string. + -- first two digits in Extra2. The scanning should continue only + -- to assess the validity of the string. if Precision_Limit_Reached then Scale (N) := Scale (N) + 1; - if Round and then Precision_Limit_Just_Reached then - Round_Extra (Digit, Base, Value (N), Scale (N), Extra); + if Precision_Limit_Just_Reached then + Extra2 := Extra2 + Digit; + Extra2_Filled := True; Precision_Limit_Just_Reached := False; end if; @@ -465,11 +410,9 @@ package body System.Value_R is Value (N) := Uns (Digit); else - Extra := Digit; + Extra2 := Digit * Base; Precision_Limit_Reached := True; - if Round then - Precision_Limit_Just_Reached := True; - end if; + Precision_Limit_Just_Reached := True; Scale (N) := Scale (N) + 1; end if; end if; @@ -494,9 +437,11 @@ package body System.Value_R is -- Next character is not a digit. In that case stop scanning -- unless the next chracter is an underscore followed by a digit. - if Digit = Underscore and Index + 1 <= Max then + if Digit = Underscore and then Index + 1 <= Max then Digit := As_Digit (Str (Index + 1)); - if Digit in Valid_Digit then + if Digit in Valid_Digit and then + (Digit /= E_Digit or else Base > E_Digit) + then Index := Index + 1; else return; @@ -513,13 +458,13 @@ package body System.Value_R is ------------------- function Scan_Raw_Real - (Str : String; - Ptr : not null access Integer; - Max : Integer; - Base : out Unsigned; - Scale : out Scale_Array; - Extra : out Unsigned; - Minus : out Boolean) return Value_Array + (Str : String; + Ptr : not null access Integer; + Max : Integer; + Base : out Unsigned; + Scale : out Scale_Array; + Extra2 : out Unsigned; + Minus : out Boolean) return Value_Array is pragma Assert (Max <= Str'Last); @@ -534,6 +479,9 @@ package body System.Value_R is -- If True some digits where not in the base. The real is still scanned -- till the end even if an error will be raised. + Extra2_Filled : Boolean; + -- True if Extra2 has been filled + N : Positive; -- Index number of the current part @@ -578,12 +526,12 @@ package body System.Value_R is if Str (Index) in '0' .. '9' then After_Point := False; - -- If this is a digit it can indicates either the float decimal - -- part or the base to use. + -- If this is a digit it can indicate either the integral part or the + -- base to use. Scan_Integral_Digits (Str, Index, Max, Base, False, Value, Scale, N, - Char_As_Digit (Extra), Base_Violation); + Extra2, Extra2_Filled, Base_Violation); -- A dot is allowed only if followed by a digit (RM 3.5(39.8)) @@ -596,13 +544,15 @@ package body System.Value_R is N := 1; Value := (others => 0); Scale := (others => 0); - Extra := 0; + Extra2 := 0; + Extra2_Filled := False; else Bad_Value (Str); end if; - -- Check if the first number encountered is a base + -- Check if the first number encountered is a base. ':' is allowed in + -- place of '#' in virtue of RM J.2 (3). pragma Assert (Index >= Str'First); @@ -611,7 +561,13 @@ package body System.Value_R is then Base_Char := Str (Index); - if N = 1 and then Value (1) in 2 .. 16 then + -- Functionally, "(Parts = 1 or else N = 1)" in the condition of the + -- following if statement could replaced by the simpler "N = 1". The + -- reason we use a more complicated expression is to accommodate + -- machine-code-based coverage tools: the simple version makes it + -- impossible to fully cover generic instances of System.Value_R with + -- Parts = 1. + if (Parts = 1 or else N = 1) and then Value (1) in 2 .. 16 then Base := Unsigned (Value (1)); else Base_Violation := True; @@ -630,16 +586,16 @@ package body System.Value_R is end if; end if; - -- Scan the integral part if still necessary + -- Scan the integral part if there was a base and no point right after if Base_Char /= ASCII.NUL and then not After_Point then - if Index > Max or else As_Digit (Str (Index)) not in Valid_Digit then + if As_Digit (Str (Index)) not in Valid_Digit then Bad_Value (Str); end if; Scan_Integral_Digits (Str, Index, Max, Base, Base_Char /= ASCII.NUL, Value, Scale, - N, Char_As_Digit (Extra), Base_Violation); + N, Extra2, Extra2_Filled, Base_Violation); end if; -- Do we have a dot? @@ -664,9 +620,22 @@ package body System.Value_R is if After_Point then pragma Assert (Index <= Max); - Scan_Decimal_Digits - (Str, Index, Max, Base, Base_Char /= ASCII.NUL, Value, Scale, - N, Char_As_Digit (Extra), Base_Violation); + -- If Extra2 has been filled, we are done with it + + if Extra2_Filled then + declare + Dummy : Unsigned := 0; + begin + Scan_Decimal_Digits + (Str, Index, Max, Base, Base_Char /= ASCII.NUL, Value, Scale, + N, Dummy, Base_Violation); + end; + + else + Scan_Decimal_Digits + (Str, Index, Max, Base, Base_Char /= ASCII.NUL, Value, Scale, + N, Extra2, Base_Violation); + end if; end if; -- If an explicit base was specified ensure that the delimiter is found @@ -714,11 +683,11 @@ package body System.Value_R is -------------------- function Value_Raw_Real - (Str : String; - Base : out Unsigned; - Scale : out Scale_Array; - Extra : out Unsigned; - Minus : out Boolean) return Value_Array + (Str : String; + Base : out Unsigned; + Scale : out Scale_Array; + Extra2 : out Unsigned; + Minus : out Boolean) return Value_Array is P : aliased Integer; V : Value_Array; @@ -732,14 +701,14 @@ package body System.Value_R is declare subtype NT is String (1 .. Str'Length); begin - return Value_Raw_Real (NT (Str), Base, Scale, Extra, Minus); + return Value_Raw_Real (NT (Str), Base, Scale, Extra2, Minus); end; end if; -- Normal case P := Str'First; - V := Scan_Raw_Real (Str, P'Access, Str'Last, Base, Scale, Extra, Minus); + V := Scan_Raw_Real (Str, P'Access, Str'Last, Base, Scale, Extra2, Minus); Scan_Trailing_Blanks (Str, P); return V; diff --git a/gcc/ada/libgnat/s-valuer.ads b/gcc/ada/libgnat/s-valuer.ads index 9f2799828121..e48241eba570 100644 --- a/gcc/ada/libgnat/s-valuer.ads +++ b/gcc/ada/libgnat/s-valuer.ads @@ -45,9 +45,6 @@ generic Precision_Limit : Uns; -- Precision limit for each part of the value - Round : Boolean; - -- If Parts = 1, True if the extra digit must be rounded - package System.Value_R is pragma Preelaborate; @@ -61,13 +58,13 @@ package System.Value_R is -- The value split into parts function Scan_Raw_Real - (Str : String; - Ptr : not null access Integer; - Max : Integer; - Base : out Unsigned; - Scale : out Scale_Array; - Extra : out Unsigned; - Minus : out Boolean) return Value_Array; + (Str : String; + Ptr : not null access Integer; + Max : Integer; + Base : out Unsigned; + Scale : out Scale_Array; + Extra2 : out Unsigned; + Minus : out Boolean) return Value_Array; -- This function scans the string starting at Str (Ptr.all) for a valid -- real literal according to the syntax described in (RM 3.5(43)). The -- substring scanned extends no further than Str (Max). There are three @@ -75,17 +72,18 @@ package System.Value_R is -- -- If a valid real is found after scanning past any initial spaces, then -- Ptr.all is updated past the last character of the real (but trailing - -- spaces are not scanned out) and the Base, Scale, Extra and Minus out + -- spaces are not scanned out) and the Base, Scale, Extra2 and Minus out -- parameters are set; if Val is the result of the call, then the real -- represented by the literal is equal to -- - -- (Val (1) * Base + Extra) * (Base ** (Scale (1) - 1)) + -- (Val (1) * Base ** 2 + Extra2) * (Base ** (Scale (1) - 2)) -- -- when Parts = 1 and -- -- Sum [Val (N) * (Base ** Scale (N)), N in 1 .. Parts] -- - -- when Parts > 1, with the negative sign if Minus is true. + -- when Parts > 1, with the negative sign if Minus is true. Note that + -- Val (1) cannot be zero unless Val is entirely filled with zero. -- -- If no valid real is found, then Ptr.all points either to an initial -- non-blank character, or to Max + 1 if the field is all spaces and the @@ -108,11 +106,11 @@ package System.Value_R is -- case is not supported. Most such cases are eliminated by the caller. function Value_Raw_Real - (Str : String; - Base : out Unsigned; - Scale : out Scale_Array; - Extra : out Unsigned; - Minus : out Boolean) return Value_Array; + (Str : String; + Base : out Unsigned; + Scale : out Scale_Array; + Extra2 : out Unsigned; + Minus : out Boolean) return Value_Array; -- Used in computing X'Value (Str) where X is a real type. Str is the -- string argument of the attribute. Constraint_Error is raised if the -- string is malformed. diff --git a/gcc/ada/libgnat/s-valueu.adb b/gcc/ada/libgnat/s-valueu.adb index e6f1d5ee1ca9..a27e00f1c6ae 100644 --- a/gcc/ada/libgnat/s-valueu.adb +++ b/gcc/ada/libgnat/s-valueu.adb @@ -29,78 +29,10 @@ -- -- ------------------------------------------------------------------------------ -with System.SPARK.Cut_Operations; use System.SPARK.Cut_Operations; with System.Val_Util; use System.Val_Util; package body System.Value_U is - -- Ghost code, loop invariants and assertions in this unit are meant for - -- analysis only, not for run-time checking, as it would be too costly - -- otherwise. This is enforced by setting the assertion policy to Ignore. - - pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore, - Assert_And_Cut => Ignore, - Subprogram_Variant => Ignore); - - use type Spec.Uns_Option; - use type Spec.Split_Value_Ghost; - - -- Local lemmas - - procedure Lemma_Digit_Not_Last - (Str : String; - P : Integer; - From : Integer; - To : Integer) - with Ghost, - Pre => Str'Last /= Positive'Last - and then From in Str'Range - and then To in From .. Str'Last - and then Str (From) in '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' - and then P in From .. To - and then P <= Spec.Last_Hexa_Ghost (Str (From .. To)) + 1 - and then Spec.Is_Based_Format_Ghost (Str (From .. To)), - Post => - (if Str (P) in '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' - then P <= Spec.Last_Hexa_Ghost (Str (From .. To))); - - procedure Lemma_Underscore_Not_Last - (Str : String; - P : Integer; - From : Integer; - To : Integer) - with Ghost, - Pre => Str'Last /= Positive'Last - and then From in Str'Range - and then To in From .. Str'Last - and then Str (From) in '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' - and then P in From .. To - and then Str (P) = '_' - and then P <= Spec.Last_Hexa_Ghost (Str (From .. To)) + 1 - and then Spec.Is_Based_Format_Ghost (Str (From .. To)), - Post => P + 1 <= Spec.Last_Hexa_Ghost (Str (From .. To)) - and then Str (P + 1) in '0' .. '9' | 'a' .. 'f' | 'A' .. 'F'; - - ----------------------------- - -- Local lemma null bodies -- - ----------------------------- - - procedure Lemma_Digit_Not_Last - (Str : String; - P : Integer; - From : Integer; - To : Integer) - is null; - - procedure Lemma_Underscore_Not_Last - (Str : String; - P : Integer; - From : Integer; - To : Integer) - is null; - ----------------------- -- Scan_Raw_Unsigned -- ----------------------- @@ -132,36 +64,6 @@ package body System.Value_U is Digit : Uns; -- Digit value - Ptr_Old : constant Integer := Ptr.all - with Ghost; - Last_Num_Init : constant Integer := - Last_Number_Ghost (Str (Ptr.all .. Max)) - with Ghost; - Init_Val : constant Spec.Uns_Option := - Spec.Scan_Based_Number_Ghost (Str, Ptr.all, Last_Num_Init) - with Ghost; - Starts_As_Based : constant Boolean := - Spec.Raw_Unsigned_Starts_As_Based_Ghost (Str, Last_Num_Init, Max) - with Ghost; - Last_Num_Based : constant Integer := - (if Starts_As_Based - then Spec.Last_Hexa_Ghost (Str (Last_Num_Init + 2 .. Max)) - else Last_Num_Init) - with Ghost; - Is_Based : constant Boolean := - Spec.Raw_Unsigned_Is_Based_Ghost - (Str, Last_Num_Init, Last_Num_Based, Max) - with Ghost; - Based_Val : constant Spec.Uns_Option := - (if Starts_As_Based and then not Init_Val.Overflow - then Spec.Scan_Based_Number_Ghost - (Str, Last_Num_Init + 2, Last_Num_Based, Init_Val.Value) - else Init_Val) - with Ghost; - First_Exp : constant Integer := - (if Is_Based then Last_Num_Based + 2 else Last_Num_Init + 1) - with Ghost; - begin -- We do not tolerate strings with Str'Last = Positive'Last @@ -171,7 +73,15 @@ package body System.Value_U is end if; P := Ptr.all; - Spec.Lemma_Scan_Based_Number_Ghost_Step (Str, P, Last_Num_Init); + + -- Exit when the initial string to parse is empty + + if Max < P then + raise Program_Error with + "Scan end Max=" & Max'Img & + " is smaller than scan end Ptr=" & P'Img; + end if; + Uval := Character'Pos (Str (P)) - Character'Pos ('0'); pragma Assert (Str (P) in '0' .. '9'); P := P + 1; @@ -189,14 +99,6 @@ package body System.Value_U is begin -- Loop through decimal digits loop - pragma Loop_Invariant (P in P'Loop_Entry .. Last_Num_Init + 1); - pragma Loop_Invariant - (if Overflow then Init_Val.Overflow); - pragma Loop_Invariant - (if not Overflow - then Init_Val = Spec.Scan_Based_Number_Ghost - (Str, P, Last_Num_Init, Acc => Uval)); - exit when P > Max; Digit := Character'Pos (Str (P)) - Character'Pos ('0'); @@ -205,8 +107,6 @@ package body System.Value_U is if Digit > 9 then if Str (P) = '_' then - Spec.Lemma_Scan_Based_Number_Ghost_Underscore - (Str, P, Last_Num_Init, Acc => Uval); Scan_Underscore (Str, P, Ptr, Max, False); else exit; @@ -215,55 +115,23 @@ package body System.Value_U is -- Accumulate result, checking for overflow else - pragma Assert - (By - (Str (P) in '0' .. '9', - By - (Character'Pos (Str (P)) >= Character'Pos ('0'), - Uns '(Character'Pos (Str (P))) >= - Character'Pos ('0')))); - Spec.Lemma_Scan_Based_Number_Ghost_Step - (Str, P, Last_Num_Init, Acc => Uval); - Spec.Lemma_Scan_Based_Number_Ghost_Overflow - (Str, P, Last_Num_Init, Acc => Uval); - if Uval <= Umax then Uval := 10 * Uval + Digit; - pragma Assert - (if not Overflow - then Init_Val = Spec.Scan_Based_Number_Ghost - (Str, P + 1, Last_Num_Init, Acc => Uval)); - elsif Uval > Umax10 then Overflow := True; - else Uval := 10 * Uval + Digit; if Uval < Umax10 then Overflow := True; end if; - pragma Assert - (if not Overflow - then Init_Val = Spec.Scan_Based_Number_Ghost - (Str, P + 1, Last_Num_Init, Acc => Uval)); - end if; P := P + 1; end if; end loop; - Spec.Lemma_Scan_Based_Number_Ghost_Base - (Str, P, Last_Num_Init, Acc => Uval); end; - pragma Assert_And_Cut - (By - (P = Last_Num_Init + 1, - P > Max or else Str (P) not in '_' | '0' .. '9') - and then Overflow = Init_Val.Overflow - and then (if not Overflow then Init_Val.Value = Uval)); - Ptr.all := P; -- Deal with based case. We recognize either the standard '#' or the @@ -295,10 +163,6 @@ package body System.Value_U is -- Numbers bigger than UmaxB overflow if multiplied by base begin - pragma Assert - (if Str (P) in '0' .. '9' | 'A' .. 'F' | 'a' .. 'f' - then Spec.Is_Based_Format_Ghost (Str (P .. Max))); - -- Loop to scan out based integer value loop @@ -321,49 +185,11 @@ package body System.Value_U is -- already stored in Ptr.all. else - pragma Assert - (By - (Spec.Only_Hexa_Ghost (Str, P, Last_Num_Based), - P > Last_Num_Init + 1 - and Spec.Only_Hexa_Ghost - (Str, Last_Num_Init + 2, Last_Num_Based))); - Spec.Lemma_Scan_Based_Number_Ghost_Base - (Str, P, Last_Num_Based, Base, Uval); Uval := Base; Base := 10; - pragma Assert (Ptr.all = Last_Num_Init + 1); - pragma Assert - (if Starts_As_Based - then By - (P = Last_Num_Based + 1, - P <= Last_Num_Based + 1 - and Str (P) not in - '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' | '_')); - pragma Assert (not Is_Based); - pragma Assert (if not Overflow then Uval = Init_Val.Value); exit; end if; - pragma Loop_Invariant (P in P'Loop_Entry .. Last_Num_Based); - pragma Loop_Invariant - (Str (P) in '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' - and then Digit = Spec.Hexa_To_Unsigned_Ghost (Str (P))); - pragma Loop_Invariant - (if Overflow'Loop_Entry then Overflow); - pragma Loop_Invariant - (if Overflow then - (Overflow'Loop_Entry or else Based_Val.Overflow)); - pragma Loop_Invariant - (if not Overflow - then Based_Val = Spec.Scan_Based_Number_Ghost - (Str, P, Last_Num_Based, Base, Uval)); - pragma Loop_Invariant (Ptr.all = Last_Num_Init + 1); - - Spec.Lemma_Scan_Based_Number_Ghost_Step - (Str, P, Last_Num_Based, Base, Uval); - Spec.Lemma_Scan_Based_Number_Ghost_Overflow - (Str, P, Last_Num_Based, Base, Uval); - -- If digit is too large, just signal overflow and continue. -- The idea here is to keep scanning as long as the input is -- syntactically valid, even if we have detected overflow @@ -375,24 +201,14 @@ package body System.Value_U is elsif Uval <= Umax then Uval := Base * Uval + Digit; - pragma Assert - (if not Overflow - then Based_Val = Spec.Scan_Based_Number_Ghost - (Str, P + 1, Last_Num_Based, Base, Uval)); - elsif Uval > UmaxB then Overflow := True; - else Uval := Base * Uval + Digit; if Uval < UmaxB then Overflow := True; end if; - pragma Assert - (if not Overflow - then Based_Val = Spec.Scan_Based_Number_Ghost - (Str, P + 1, Last_Num_Based, Base, Uval)); end if; -- If at end of string with no base char, not a based number @@ -411,86 +227,22 @@ package body System.Value_U is if Str (P) = Base_Char then Ptr.all := P + 1; - pragma Assert (P = Last_Num_Based + 1); - pragma Assert (Ptr.all = Last_Num_Based + 2); - pragma Assert - (By - (Is_Based, - So - (Starts_As_Based, - So - (Last_Num_Based < Max, - Str (Last_Num_Based + 1) = Base_Char - and Base_Char = Str (Last_Num_Init + 1))))); - Spec.Lemma_Scan_Based_Number_Ghost_Base - (Str, P, Last_Num_Based, Base, Uval); exit; -- Deal with underscore elsif Str (P) = '_' then - Lemma_Underscore_Not_Last (Str, P, Last_Num_Init + 2, Max); - Spec.Lemma_Scan_Based_Number_Ghost_Underscore - (Str, P, Last_Num_Based, Base, Uval); Scan_Underscore (Str, P, Ptr, Max, True); - pragma Assert - (if not Overflow - then Based_Val = Spec.Scan_Based_Number_Ghost - (Str, P, Last_Num_Based, Base, Uval)); - pragma Assert (Str (P) not in '_' | Base_Char); end if; - - Lemma_Digit_Not_Last (Str, P, Last_Num_Init + 2, Max); - pragma Assert (Str (P) not in '_' | Base_Char); end loop; end; - pragma Assert - (if Starts_As_Based then P = Last_Num_Based + 1 - else P = Last_Num_Init + 2); - pragma Assert - (By - (Overflow /= Spec.Scan_Split_No_Overflow_Ghost - (Str, Ptr_Old, Max), - So - (Last_Num_Init < Max - 1 - and then Str (Last_Num_Init + 1) in '#' | ':', - Overflow = - (Init_Val.Overflow - or else Init_Val.Value not in 2 .. 16 - or else (Starts_As_Based and Based_Val.Overflow))))); end if; - pragma Assert_And_Cut - (Overflow /= Spec.Scan_Split_No_Overflow_Ghost (Str, Ptr_Old, Max) - and then Ptr.all = First_Exp - and then Base in 2 .. 16 - and then - (if not Overflow then - (if Is_Based then Base = Init_Val.Value else Base = 10)) - and then - (if not Overflow then - (if Is_Based then Uval = Based_Val.Value - else Uval = Init_Val.Value))); - -- Come here with scanned unsigned value in Uval. The only remaining -- required step is to deal with exponent if one is present. Scan_Exponent (Str, Ptr, Max, Expon); - pragma Assert - (By - (Ptr.all = Spec.Raw_Unsigned_Last_Ghost (Str, Ptr_Old, Max), - Ptr.all = - (if not Starts_As_Exponent_Format_Ghost (Str (First_Exp .. Max)) - then First_Exp - elsif Str (First_Exp + 1) in '-' | '+' then - Last_Number_Ghost (Str (First_Exp + 2 .. Max)) + 1 - else Last_Number_Ghost (Str (First_Exp + 1 .. Max)) + 1))); - pragma Assert - (if not Overflow - then Spec.Scan_Split_Value_Ghost (Str, Ptr_Old, Max) = - (Uval, Base, Expon)); - if Expon /= 0 and then Uval /= 0 then -- For non-zero value, scale by exponent value. No need to do this @@ -500,66 +252,22 @@ package body System.Value_U is declare UmaxB : constant Uns := Uns'Last / Base; -- Numbers bigger than UmaxB overflow if multiplied by base - - Res_Val : constant Spec.Uns_Option := - Spec.Exponent_Unsigned_Ghost (Uval, Expon, Base) - with Ghost; begin for J in 1 .. Expon loop - pragma Loop_Invariant - (if Overflow'Loop_Entry then Overflow); - pragma Loop_Invariant - (if Overflow - then Overflow'Loop_Entry or else Res_Val.Overflow); - pragma Loop_Invariant (Uval /= 0); - pragma Loop_Invariant - (if not Overflow - then Res_Val = Spec.Exponent_Unsigned_Ghost - (Uval, Expon - J + 1, Base)); - - pragma Assert - ((Uval > UmaxB) = Spec.Scan_Overflows_Ghost (0, Base, Uval)); - if Uval > UmaxB then - Spec.Lemma_Exponent_Unsigned_Ghost_Overflow - (Uval, Expon - J + 1, Base); Overflow := True; exit; end if; - Spec.Lemma_Exponent_Unsigned_Ghost_Step - (Uval, Expon - J + 1, Base); - Uval := Uval * Base; end loop; - Spec.Lemma_Exponent_Unsigned_Ghost_Base (Uval, 0, Base); - - pragma Assert - (Overflow /= - Spec.Raw_Unsigned_No_Overflow_Ghost (Str, Ptr_Old, Max)); - pragma Assert (if not Overflow then Res_Val = (False, Uval)); end; end if; - Spec.Lemma_Exponent_Unsigned_Ghost_Base (Uval, Expon, Base); - pragma Assert - (if Expon = 0 or else Uval = 0 then - Spec.Exponent_Unsigned_Ghost (Uval, Expon, Base) = (False, Uval)); - pragma Assert - (Overflow /= - Spec.Raw_Unsigned_No_Overflow_Ghost (Str, Ptr_Old, Max)); - pragma Assert - (if not Overflow then - Uval = Spec.Scan_Raw_Unsigned_Ghost (Str, Ptr_Old, Max)); -- Return result, dealing with overflow if Overflow then Bad_Value (Str); - pragma Annotate - (GNATprove, Intentional, - "call to nonreturning subprogram might be executed", - "it is expected that Constraint_Error is raised in case of" - & " overflow"); else Res := Uval; end if; @@ -608,15 +316,7 @@ package body System.Value_U is if Str'Last = Positive'Last then declare subtype NT is String (1 .. Str'Length); - procedure Prove_Is_Unsigned_Ghost with - Ghost, - Pre => Str'Length < Natural'Last - and then not Only_Space_Ghost (Str, Str'First, Str'Last) - and then Spec.Is_Unsigned_Ghost (Spec.Slide_To_1 (Str)), - Post => Spec.Is_Unsigned_Ghost (NT (Str)); - procedure Prove_Is_Unsigned_Ghost is null; begin - Prove_Is_Unsigned_Ghost; return Value_Unsigned (NT (Str)); end; @@ -626,12 +326,6 @@ package body System.Value_U is declare V : Uns; P : aliased Integer := Str'First; - Non_Blank : constant Positive := First_Non_Space_Ghost - (Str, Str'First, Str'Last) - with Ghost; - Fst_Num : constant Positive := - (if Str (Non_Blank) = '+' then Non_Blank + 1 else Non_Blank) - with Ghost; begin declare P_Acc : constant not null access Integer := P'Access; @@ -639,16 +333,7 @@ package body System.Value_U is Scan_Unsigned (Str, P_Acc, Str'Last, V); end; - pragma Assert - (P = Spec.Raw_Unsigned_Last_Ghost (Str, Fst_Num, Str'Last)); - pragma Assert - (V = Spec.Scan_Raw_Unsigned_Ghost (Str, Fst_Num, Str'Last)); - Scan_Trailing_Blanks (Str, P); - - pragma Assert - (Spec.Is_Value_Unsigned_Ghost - (Spec.Slide_If_Necessary (Str), V)); return V; end; end if; diff --git a/gcc/ada/libgnat/s-valueu.ads b/gcc/ada/libgnat/s-valueu.ads index 92e3ffebbecb..488c342e6b82 100644 --- a/gcc/ada/libgnat/s-valueu.ads +++ b/gcc/ada/libgnat/s-valueu.ads @@ -32,29 +32,8 @@ -- This package contains routines for scanning modular Unsigned -- values for use in Text_IO.Modular_IO, and the Value attribute. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -with System.Value_U_Spec; -with System.Val_Spec; use System.Val_Spec; - generic - type Uns is mod <>; - - -- Additional parameters for ghost subprograms used inside contracts - - with package Spec is new System.Value_U_Spec (Uns => Uns) with Ghost; - package System.Value_U is pragma Preelaborate; @@ -62,15 +41,7 @@ package System.Value_U is (Str : String; Ptr : not null access Integer; Max : Integer; - Res : out Uns) - with Pre => Str'Last /= Positive'Last - and then Ptr.all in Str'Range - and then Max in Ptr.all .. Str'Last - and then Spec.Is_Raw_Unsigned_Format_Ghost (Str (Ptr.all .. Max)), - Post => Spec.Raw_Unsigned_No_Overflow_Ghost (Str, Ptr.all'Old, Max) - and Res = Spec.Scan_Raw_Unsigned_Ghost (Str, Ptr.all'Old, Max) - and Ptr.all = Spec.Raw_Unsigned_Last_Ghost (Str, Ptr.all'Old, Max); - + Res : out Uns); -- This function scans the string starting at Str (Ptr.all) for a valid -- integer according to the syntax described in (RM 3.5(43)). The substring -- scanned extends no further than Str (Max). Note: this does not scan @@ -131,11 +102,9 @@ package System.Value_U is -- This string results in a Constraint_Error with the pointer pointing -- past the second 2. -- - -- Note: if Str is empty, i.e. if Max is less than Ptr, then this is a - -- special case of an all-blank string, and Ptr is unchanged, and hence - -- is greater than Max as required in this case. - -- ??? This is not the case. We will read Str (Ptr.all) without checking - -- and increase Ptr.all by one. + -- Note: If Max is less than Ptr, then Ptr is left unchanged and + -- Program_Error is raised to indicate that a valid integer cannot + -- be parsed. -- -- Note: this routine should not be called with Str'Last = Positive'Last. -- If this occurs Program_Error is raised with a message noting that this @@ -145,45 +114,14 @@ package System.Value_U is (Str : String; Ptr : not null access Integer; Max : Integer; - Res : out Uns) - with Pre => Str'Last /= Positive'Last - and then Ptr.all in Str'Range - and then Max in Ptr.all .. Str'Last - and then not Only_Space_Ghost (Str, Ptr.all, Max) - and then - (declare - Non_Blank : constant Positive := - First_Non_Space_Ghost (Str, Ptr.all, Max); - Fst_Num : constant Positive := - (if Str (Non_Blank) = '+' then Non_Blank + 1 else Non_Blank); - begin - Spec.Is_Raw_Unsigned_Format_Ghost (Str (Fst_Num .. Max))), - Post => - (declare - Non_Blank : constant Positive := - First_Non_Space_Ghost (Str, Ptr.all'Old, Max); - Fst_Num : constant Positive := - (if Str (Non_Blank) = '+' then Non_Blank + 1 else Non_Blank); - begin - Spec.Raw_Unsigned_No_Overflow_Ghost (Str, Fst_Num, Max) - and then Res = Spec.Scan_Raw_Unsigned_Ghost (Str, Fst_Num, Max) - and then Ptr.all = Spec.Raw_Unsigned_Last_Ghost (Str, Fst_Num, Max)); - + Res : out Uns); -- Same as Scan_Raw_Unsigned, except scans optional leading -- blanks, and an optional leading plus sign. -- -- Note: if a minus sign is present, Constraint_Error will be raised. -- Note: trailing blanks are not scanned. - function Value_Unsigned - (Str : String) return Uns - with Pre => Str'Length /= Positive'Last - and then not Only_Space_Ghost (Str, Str'First, Str'Last) - and then Spec.Is_Unsigned_Ghost (Spec.Slide_If_Necessary (Str)), - Post => - Spec.Is_Value_Unsigned_Ghost - (Spec.Slide_If_Necessary (Str), Value_Unsigned'Result), - Subprogram_Variant => (Decreases => Str'First); + function Value_Unsigned (Str : String) return Uns; -- Used in computing X'Value (Str) where X is a modular integer type whose -- modulus does not exceed the range of System.Unsigned_Types.Unsigned. Str -- is the string argument of the attribute. Constraint_Error is raised if diff --git a/gcc/ada/libgnat/s-valuns.ads b/gcc/ada/libgnat/s-valuns.ads index 8bbb7fbe7fdf..a015c120c3c5 100644 --- a/gcc/ada/libgnat/s-valuns.ads +++ b/gcc/ada/libgnat/s-valuns.ads @@ -32,28 +32,15 @@ -- This package contains routines for scanning modular Unsigned -- values for use in Text_IO.Modular_IO, and the Value attribute. --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - with System.Unsigned_Types; with System.Value_U; -with System.Vs_Uns; package System.Val_Uns with SPARK_Mode is pragma Preelaborate; subtype Unsigned is Unsigned_Types.Unsigned; - package Impl is new Value_U (Unsigned, System.Vs_Uns.Spec); + package Impl is new Value_U (Unsigned); procedure Scan_Raw_Unsigned (Str : String; diff --git a/gcc/ada/libgnat/s-valuti.adb b/gcc/ada/libgnat/s-valuti.adb index a2b79f199b64..a97ab002e7fb 100644 --- a/gcc/ada/libgnat/s-valuti.adb +++ b/gcc/ada/libgnat/s-valuti.adb @@ -29,15 +29,7 @@ -- -- ------------------------------------------------------------------------------ --- Ghost code, loop invariants and assertions in this unit are meant for --- analysis only, not for run-time checking, as it would be too costly --- otherwise. This is enforced by setting the assertion policy to Ignore. - -pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - -with System.Case_Util; use System.Case_Util; +with System.Case_Util_NSS; use System.Case_Util_NSS; package body System.Val_Util with SPARK_Mode @@ -48,12 +40,11 @@ is --------------- procedure Bad_Value (S : String) is - pragma Annotate (GNATprove, Intentional, "exception might be raised", - "Intentional exception from Bad_Value"); begin -- Bad_Value might be called with very long strings allocated on the -- heap. Limit the size of the message so that we avoid creating a -- Storage_Error during error handling. + if S'Length > 127 then raise Constraint_Error with "bad input for 'Value: """ & S (S'First .. S'First + 127) & "..."""; @@ -69,8 +60,7 @@ is procedure Normalize_String (S : in out String; F, L : out Integer; - To_Upper_Case : Boolean) - is + To_Upper_Case : Boolean) is begin F := S'First; L := S'Last; @@ -84,9 +74,6 @@ is -- Scan for leading spaces while F < L and then S (F) = ' ' loop - pragma Loop_Invariant (F in S'First .. L - 1); - pragma Loop_Invariant (for all J in S'First .. F => S (J) = ' '); - pragma Loop_Variant (Increases => F); F := F + 1; end loop; @@ -101,9 +88,6 @@ is -- Scan for trailing spaces while S (L) = ' ' loop - pragma Loop_Invariant (L in F + 1 .. S'Last); - pragma Loop_Invariant (for all J in L .. S'Last => S (J) = ' '); - pragma Loop_Variant (Decreases => L); L := L - 1; end loop; @@ -112,8 +96,6 @@ is if To_Upper_Case and then S (F) /= ''' then for J in F .. L loop S (J) := To_Upper (S (J)); - pragma Loop_Invariant - (for all K in F .. J => S (K) = To_Upper (S'Loop_Entry (K))); end loop; end if; end Normalize_String; @@ -185,40 +167,23 @@ is X := 0; - declare - Rest : constant String := Str (P .. Max) with Ghost; - Last : constant Natural := Sp.Last_Number_Ghost (Rest) with Ghost; - - begin - pragma Assert (Sp.Is_Natural_Format_Ghost (Rest)); - - loop - pragma Assert (Str (P) in '0' .. '9'); + loop + pragma Assert (Str (P) in '0' .. '9'); - if X < (Integer'Last / 10) then - X := X * 10 + (Character'Pos (Str (P)) - Character'Pos ('0')); - end if; - - pragma Loop_Invariant (X >= 0); - pragma Loop_Invariant (P in Rest'First .. Last); - pragma Loop_Invariant (Str (P) in '0' .. '9'); - pragma Loop_Invariant - (Sp.Scan_Natural_Ghost (Rest, Rest'First, 0) - = Sp.Scan_Natural_Ghost (Rest, P + 1, X)); - - P := P + 1; + if X < (Integer'Last / 10) then + X := X * 10 + (Character'Pos (Str (P)) - Character'Pos ('0')); + end if; - exit when P > Max; + P := P + 1; - if Str (P) = '_' then - Scan_Underscore (Str, P, Ptr, Max, False); - else - exit when Str (P) not in '0' .. '9'; - end if; - end loop; + exit when P > Max; - pragma Assert (P = Last + 1); - end; + if Str (P) = '_' then + Scan_Underscore (Str, P, Ptr, Max, False); + else + exit when Str (P) not in '0' .. '9'; + end if; + end loop; if M then X := -X; @@ -250,12 +215,6 @@ is while Str (P) = ' ' loop P := P + 1; - pragma Loop_Invariant (Ptr.all = Ptr.all'Loop_Entry); - pragma Loop_Invariant (P in Ptr.all .. Max); - pragma Loop_Invariant (for some J in P .. Max => Str (J) /= ' '); - pragma Loop_Invariant - (for all J in Ptr.all .. P - 1 => Str (J) = ' '); - if P > Max then Ptr.all := P; Bad_Value (Str); @@ -264,8 +223,6 @@ is Start := P; - pragma Assert (Start = Sp.First_Non_Space_Ghost (Str, Ptr.all, Max)); - -- Skip past an initial plus sign if Str (P) = '+' then @@ -292,7 +249,6 @@ is Start : out Positive) is P : Integer := Ptr.all; - begin -- Deal with case of null string (all blanks). As per spec, we raise -- constraint error, with Ptr unchanged, and thus > Max. @@ -306,12 +262,6 @@ is while Str (P) = ' ' loop P := P + 1; - pragma Loop_Invariant (Ptr.all = Ptr.all'Loop_Entry); - pragma Loop_Invariant (P in Ptr.all .. Max); - pragma Loop_Invariant (for some J in P .. Max => Str (J) /= ' '); - pragma Loop_Invariant - (for all J in Ptr.all .. P - 1 => Str (J) = ' '); - if P > Max then Ptr.all := P; Bad_Value (Str); @@ -320,8 +270,6 @@ is Start := P; - pragma Assert (Start = Sp.First_Non_Space_Ghost (Str, Ptr.all, Max)); - -- Remember an initial minus sign if Str (P) = '-' then @@ -361,8 +309,6 @@ is if Str (J) /= ' ' then Bad_Value (Str); end if; - - pragma Loop_Invariant (for all K in P .. J => Str (K) = ' '); end loop; end Scan_Trailing_Blanks; @@ -378,7 +324,6 @@ is Ext : Boolean) is C : Character; - begin P := P + 1; diff --git a/gcc/ada/libgnat/s-valuti.ads b/gcc/ada/libgnat/s-valuti.ads index 8720c4146e59..4a299ca5b9ff 100644 --- a/gcc/ada/libgnat/s-valuti.ads +++ b/gcc/ada/libgnat/s-valuti.ads @@ -31,59 +31,16 @@ -- This package provides some common utilities used by the s-valxxx files --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - -with System.Case_Util; -with System.Val_Spec; - package System.Val_Util with SPARK_Mode, Pure is - pragma Unevaluated_Use_Of_Old (Allow); - - package Sp renames System.Val_Spec; - - procedure Bad_Value (S : String) - with - Always_Terminates, - Depends => (null => S), - Exceptional_Cases => (others => Standard.False); - pragma No_Return (Bad_Value); + procedure Bad_Value (S : String) with No_Return; -- Raises constraint error with message: bad input for 'Value: "xxx" procedure Normalize_String (S : in out String; F, L : out Integer; - To_Upper_Case : Boolean) - with - Post => (if Sp.Only_Space_Ghost (S'Old, S'First, S'Last) then - F > L - else - F >= S'First - and then L <= S'Last - and then F <= L - and then Sp.Only_Space_Ghost (S'Old, S'First, F - 1) - and then S'Old (F) /= ' ' - and then S'Old (L) /= ' ' - and then - (if L < S'Last then - Sp.Only_Space_Ghost (S'Old, L + 1, S'Last)) - and then - (if To_Upper_Case and then S'Old (F) /= ''' then - (for all J in S'Range => - (if J in F .. L then - S (J) = System.Case_Util.To_Upper (S'Old (J)) - else - S (J) = S'Old (J))))); + To_Upper_Case : Boolean); -- This procedure scans the string S setting F to be the index of the first -- non-blank character of S and L to be the index of the last non-blank -- character of S. If To_Upper_Case is True and S does not represent a @@ -96,27 +53,7 @@ is Ptr : not null access Integer; Max : Integer; Minus : out Boolean; - Start : out Positive) - with - Pre => - -- Ptr.all .. Max is either an empty range, or a valid range in Str - (Ptr.all > Max or else (Ptr.all >= Str'First and then Max <= Str'Last)) - and then not Sp.Only_Space_Ghost (Str, Ptr.all, Max) - and then - (declare - F : constant Positive := - Sp.First_Non_Space_Ghost (Str, Ptr.all, Max); - begin - (if Str (F) in '+' | '-' then - F <= Max - 1 and then Str (F + 1) /= ' ')), - Post => - (declare - F : constant Positive := - Sp.First_Non_Space_Ghost (Str, Ptr.all'Old, Max); - begin - Minus = (Str (F) = '-') - and then Ptr.all = (if Str (F) in '+' | '-' then F + 1 else F) - and then Start = F); + Start : out Positive); -- The Str, Ptr, Max parameters are as for the scan routines (Str is the -- string to be scanned starting at Ptr.all, and Max is the index of the -- last character in the string). Scan_Sign first scans out any initial @@ -140,26 +77,7 @@ is (Str : String; Ptr : not null access Integer; Max : Integer; - Start : out Positive) - with - Pre => - -- Ptr.all .. Max is either an empty range, or a valid range in Str - (Ptr.all > Max or else (Ptr.all >= Str'First and then Max <= Str'Last)) - and then not Sp.Only_Space_Ghost (Str, Ptr.all, Max) - and then - (declare - F : constant Positive := - Sp.First_Non_Space_Ghost (Str, Ptr.all, Max); - begin - (if Str (F) = '+' then - F <= Max - 1 and then Str (F + 1) /= ' ')), - Post => - (declare - F : constant Positive := - Sp.First_Non_Space_Ghost (Str, Ptr.all'Old, Max); - begin - Ptr.all = (if Str (F) = '+' then F + 1 else F) - and then Start = F); + Start : out Positive); -- Same as Scan_Sign, but allows only plus, not minus. This is used for -- modular types. @@ -168,22 +86,7 @@ is Ptr : not null access Integer; Max : Integer; Exp : out Integer; - Real : Boolean := False) - with - Pre => - -- Ptr.all .. Max is either an empty range, or a valid range in Str - (Ptr.all > Max or else (Ptr.all >= Str'First and then Max <= Str'Last)) - and then Max < Natural'Last - and then Sp.Is_Opt_Exponent_Format_Ghost (Str (Ptr.all .. Max), Real), - Post => - (if Sp.Starts_As_Exponent_Format_Ghost (Str (Ptr.all'Old .. Max), Real) - then Exp = Sp.Scan_Exponent_Ghost (Str (Ptr.all'Old .. Max), Real) - and then - (if Str (Ptr.all'Old + 1) in '-' | '+' then - Ptr.all = Sp.Last_Number_Ghost (Str (Ptr.all'Old + 2 .. Max)) + 1 - else - Ptr.all = Sp.Last_Number_Ghost (Str (Ptr.all'Old + 1 .. Max)) + 1) - else Exp = 0 and Ptr.all = Ptr.all'Old); + Real : Boolean := False); -- Called to scan a possible exponent. Str, Ptr, Max are as described above -- for Scan_Sign. If Ptr.all < Max and Str (Ptr.all) = 'E' or 'e', then an -- exponent is scanned out, with the exponent value returned in Exp, and @@ -198,35 +101,16 @@ is -- This routine must not be called with Str'Last = Positive'Last. There is -- no check for this case, the caller must ensure this condition is met. - procedure Scan_Trailing_Blanks (Str : String; P : Positive) - with - Pre => P >= Str'First - and then Sp.Only_Space_Ghost (Str, P, Str'Last); + procedure Scan_Trailing_Blanks (Str : String; P : Positive); -- Checks that the remainder of the field Str (P .. Str'Last) is all -- blanks. Raises Constraint_Error if a non-blank character is found. - pragma Warnings - (GNATprove, Off, """Ptr"" is not modified", - Reason => "Ptr is actually modified when raising an exception"); procedure Scan_Underscore (Str : String; P : in out Natural; Ptr : not null access Integer; Max : Integer; - Ext : Boolean) - with - Pre => P in Str'Range - and then Str (P) = '_' - and then Max in Str'Range - and then P < Max - and then - (if Ext then - Str (P + 1) in '0' .. '9' | 'A' .. 'F' | 'a' .. 'f' - else - Str (P + 1) in '0' .. '9'), - Post => - P = P'Old + 1 - and then Ptr.all'Old = Ptr.all; + Ext : Boolean); -- Called if an underscore is encountered while scanning digits. Str (P) -- contains the underscore. Ptr is the pointer to be returned to the -- ultimate caller of the scan routine, Max is the maximum subscript in @@ -237,6 +121,5 @@ is -- -- This routine must not be called with Str'Last = Positive'Last. There is -- no check for this case, the caller must ensure this condition is met. - pragma Warnings (GNATprove, On, """Ptr"" is not modified"); end System.Val_Util; diff --git a/gcc/ada/libgnat/s-vauspe.adb b/gcc/ada/libgnat/s-vauspe.adb deleted file mode 100644 index a350a566a433..000000000000 --- a/gcc/ada/libgnat/s-vauspe.adb +++ /dev/null @@ -1,203 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- S Y S T E M . V A L U E _ U _ S P E C -- --- -- --- B o d y -- --- -- --- Copyright (C) 2022-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -package body System.Value_U_Spec with SPARK_Mode is - - ----------------------------- - -- Exponent_Unsigned_Ghost -- - ----------------------------- - - function Exponent_Unsigned_Ghost - (Value : Uns; - Exp : Natural; - Base : Uns := 10) return Uns_Option - is - (if Exp = 0 or Value = 0 then (Overflow => False, Value => Value) - elsif Scan_Overflows_Ghost (0, Base, Value) then (Overflow => True) - else Exponent_Unsigned_Ghost (Value * Base, Exp - 1, Base)); - - --------------------- - -- Last_Hexa_Ghost -- - --------------------- - - function Last_Hexa_Ghost (Str : String) return Positive is - begin - pragma Annotate (Gnatcheck, Exempt_On, "Improper_Returns", - "occurs in ghost code, not executable"); - - for J in Str'Range loop - if Str (J) not in '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' | '_' then - return J - 1; - end if; - - pragma Loop_Invariant - (for all K in Str'First .. J => - Str (K) in '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' | '_'); - end loop; - - return Str'Last; - - pragma Annotate (Gnatcheck, Exempt_Off, "Improper_Returns"); - end Last_Hexa_Ghost; - - ----------------------------- - -- Lemmas with null bodies -- - ----------------------------- - - procedure Lemma_Scan_Based_Number_Ghost_Base - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - is null; - - procedure Lemma_Scan_Based_Number_Ghost_Underscore - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - is null; - - procedure Lemma_Scan_Based_Number_Ghost_Overflow - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - is null; - - procedure Lemma_Scan_Based_Number_Ghost_Step - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - is null; - - procedure Lemma_Exponent_Unsigned_Ghost_Base - (Value : Uns; - Exp : Natural; - Base : Uns := 10) - is null; - - procedure Lemma_Exponent_Unsigned_Ghost_Overflow - (Value : Uns; - Exp : Natural; - Base : Uns := 10) - is null; - - procedure Lemma_Exponent_Unsigned_Ghost_Step - (Value : Uns; - Exp : Natural; - Base : Uns := 10) - is null; - - -------------------------------------- - -- Prove_Scan_Based_Number_Ghost_Eq -- - -------------------------------------- - - procedure Prove_Scan_Based_Number_Ghost_Eq - (Str1, Str2 : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - is - begin - if From > To then - null; - elsif Str1 (From) = '_' then - Prove_Scan_Based_Number_Ghost_Eq - (Str1, Str2, From + 1, To, Base, Acc); - elsif Scan_Overflows_Ghost - (Hexa_To_Unsigned_Ghost (Str1 (From)), Base, Acc) - then - null; - else - Prove_Scan_Based_Number_Ghost_Eq - (Str1, Str2, From + 1, To, Base, - Base * Acc + Hexa_To_Unsigned_Ghost (Str1 (From))); - end if; - end Prove_Scan_Based_Number_Ghost_Eq; - - ----------------------------------- - -- Prove_Scan_Only_Decimal_Ghost -- - ----------------------------------- - - procedure Prove_Scan_Only_Decimal_Ghost - (Str : String; - Val : Uns) - is - pragma Assert (Str (Str'First + 1) /= ' '); - Non_Blank : constant Positive := First_Non_Space_Ghost - (Str, Str'First, Str'Last); - pragma Assert (Non_Blank = Str'First + 1); - Fst_Num : constant Positive := - (if Str (Non_Blank) = '+' then Non_Blank + 1 else Non_Blank); - pragma Assert (Fst_Num = Str'First + 1); - begin - pragma Assert - (Is_Raw_Unsigned_Format_Ghost (Str (Fst_Num .. Str'Last))); - pragma Assert - (Scan_Split_No_Overflow_Ghost (Str, Str'First + 1, Str'Last)); - pragma Assert - ((Val, 10, 0) = Scan_Split_Value_Ghost (Str, Str'First + 1, Str'Last)); - pragma Assert - (Raw_Unsigned_No_Overflow_Ghost (Str, Fst_Num, Str'Last)); - pragma Assert (Val = Exponent_Unsigned_Ghost (Val, 0, 10).Value); - pragma Assert (Is_Unsigned_Ghost (Str)); - pragma Assert (Is_Value_Unsigned_Ghost (Str, Val)); - end Prove_Scan_Only_Decimal_Ghost; - - ----------------------------- - -- Scan_Based_Number_Ghost -- - ----------------------------- - - function Scan_Based_Number_Ghost - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) return Uns_Option - is - (if From > To then (Overflow => False, Value => Acc) - elsif Str (From) = '_' - then Scan_Based_Number_Ghost (Str, From + 1, To, Base, Acc) - elsif Scan_Overflows_Ghost - (Hexa_To_Unsigned_Ghost (Str (From)), Base, Acc) - then (Overflow => True) - else Scan_Based_Number_Ghost - (Str, From + 1, To, Base, - Base * Acc + Hexa_To_Unsigned_Ghost (Str (From)))); - -end System.Value_U_Spec; diff --git a/gcc/ada/libgnat/s-vauspe.ads b/gcc/ada/libgnat/s-vauspe.ads deleted file mode 100644 index 5dbb57d0d365..000000000000 --- a/gcc/ada/libgnat/s-vauspe.ads +++ /dev/null @@ -1,629 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- S Y S T E M . V A L U E _ U _ S P E C -- --- -- --- S p e c -- --- -- --- Copyright (C) 2022-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - --- This package is part of a set of Ghost code packages used to proof the --- implementations of the Image and Value attributes. It provides the --- specification entities using for the formal verification of the routines --- for scanning modular unsigned integer values. - --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -with System.Val_Spec; use System.Val_Spec; - -generic - - type Uns is mod <>; - -package System.Value_U_Spec with - Ghost, - SPARK_Mode, - Always_Terminates -is - pragma Preelaborate; - - -- Maximum value of exponent for 10 that fits in Uns'Base - function Max_Log10 return Natural is - (case Uns'Base'Size is - when 8 => 2, - when 16 => 4, - when 32 => 9, - when 64 => 19, - when 128 => 38, - when others => raise Program_Error) - with Ghost; - - pragma Annotate (Gnatcheck, Exempt_On, "Discriminated_Records", - "variant record only used in proof code"); - type Uns_Option (Overflow : Boolean := False) is record - case Overflow is - when True => - null; - when False => - Value : Uns := 0; - end case; - end record; - pragma Annotate (Gnatcheck, Exempt_Off, "Discriminated_Records"); - - function Wrap_Option (Value : Uns) return Uns_Option is - (Overflow => False, Value => Value); - - function Only_Decimal_Ghost - (Str : String; - From, To : Integer) - return Boolean - is - (for all J in From .. To => Str (J) in '0' .. '9') - with - Pre => From > To or else (From >= Str'First and then To <= Str'Last); - -- Ghost function that returns True if S has only decimal characters - -- from index From to index To. - - function Only_Hexa_Ghost (Str : String; From, To : Integer) return Boolean - is - (for all J in From .. To => - Str (J) in '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' | '_') - with - Pre => From > To or else (From >= Str'First and then To <= Str'Last); - -- Ghost function that returns True if S has only hexadecimal characters - -- from index From to index To. - - function Last_Hexa_Ghost (Str : String) return Positive - with - Pre => Str /= "" - and then Str (Str'First) in '0' .. '9' | 'a' .. 'f' | 'A' .. 'F', - Post => Last_Hexa_Ghost'Result in Str'Range - and then (if Last_Hexa_Ghost'Result < Str'Last then - Str (Last_Hexa_Ghost'Result + 1) not in - '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' | '_') - and then Only_Hexa_Ghost (Str, Str'First, Last_Hexa_Ghost'Result); - -- Ghost function that returns the index of the last character in S that - -- is either an hexadecimal digit or an underscore, which necessarily - -- exists given the precondition on Str. - - function Is_Based_Format_Ghost (Str : String) return Boolean - is - (Str /= "" - and then Str (Str'First) in '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' - and then - (declare - L : constant Positive := Last_Hexa_Ghost (Str); - begin - Str (L) /= '_' - and then (for all J in Str'First .. L => - (if Str (J) = '_' then Str (J + 1) /= '_')))); - -- Ghost function that determines if Str has the correct format for a - -- based number, consisting in a sequence of hexadecimal digits possibly - -- separated by single underscores. It may be followed by other characters. - - function Hexa_To_Unsigned_Ghost (X : Character) return Uns is - (case X is - when '0' .. '9' => Character'Pos (X) - Character'Pos ('0'), - when 'a' .. 'f' => Character'Pos (X) - Character'Pos ('a') + 10, - when 'A' .. 'F' => Character'Pos (X) - Character'Pos ('A') + 10, - when others => raise Program_Error) - with - Pre => X in '0' .. '9' | 'a' .. 'f' | 'A' .. 'F'; - -- Ghost function that computes the value corresponding to an hexadecimal - -- digit. - - function Scan_Overflows_Ghost - (Digit : Uns; - Base : Uns; - Acc : Uns) return Boolean - is - (Digit >= Base - or else Acc > Uns'Last / Base - or else Uns'Last - Digit < Base * Acc); - -- Ghost function which returns True if Digit + Base * Acc overflows or - -- Digit is greater than Base, as this is used by the algorithm for the - -- test of overflow. - - function Scan_Based_Number_Ghost - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) return Uns_Option - with - Subprogram_Variant => (Increases => From), - Pre => Str'Last /= Positive'Last - and then - (From > To or else (From >= Str'First and then To <= Str'Last)) - and then Only_Hexa_Ghost (Str, From, To); - -- Ghost function that recursively computes the based number in Str, - -- assuming Acc has been scanned already and scanning continues at index - -- From. - - -- Lemmas unfolding the recursive definition of Scan_Based_Number_Ghost - - procedure Lemma_Scan_Based_Number_Ghost_Base - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - with - Global => null, - Pre => Str'Last /= Positive'Last - and then - (From > To or else (From >= Str'First and then To <= Str'Last)) - and then Only_Hexa_Ghost (Str, From, To), - Post => - (if From > To - then Scan_Based_Number_Ghost (Str, From, To, Base, Acc) = - (Overflow => False, Value => Acc)); - -- Base case: Scan_Based_Number_Ghost returns Acc if From is bigger than To - - procedure Lemma_Scan_Based_Number_Ghost_Underscore - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - with - Global => null, - Pre => Str'Last /= Positive'Last - and then - (From > To or else (From >= Str'First and then To <= Str'Last)) - and then Only_Hexa_Ghost (Str, From, To), - Post => - (if From <= To and then Str (From) = '_' - then Scan_Based_Number_Ghost (Str, From, To, Base, Acc) = - Scan_Based_Number_Ghost (Str, From + 1, To, Base, Acc)); - -- Underscore case: underscores are ignored while scanning - - procedure Lemma_Scan_Based_Number_Ghost_Overflow - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - with - Global => null, - Pre => Str'Last /= Positive'Last - and then - (From > To or else (From >= Str'First and then To <= Str'Last)) - and then Only_Hexa_Ghost (Str, From, To), - Post => - (if From <= To - and then Str (From) /= '_' - and then Scan_Overflows_Ghost - (Hexa_To_Unsigned_Ghost (Str (From)), Base, Acc) - then Scan_Based_Number_Ghost (Str, From, To, Base, Acc) = - (Overflow => True)); - -- Overflow case: scanning a digit which causes an overflow - - procedure Lemma_Scan_Based_Number_Ghost_Step - (Str : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - with - Global => null, - Pre => Str'Last /= Positive'Last - and then - (From > To or else (From >= Str'First and then To <= Str'Last)) - and then Only_Hexa_Ghost (Str, From, To), - Post => - (if From <= To - and then Str (From) /= '_' - and then not Scan_Overflows_Ghost - (Hexa_To_Unsigned_Ghost (Str (From)), Base, Acc) - then Scan_Based_Number_Ghost (Str, From, To, Base, Acc) = - Scan_Based_Number_Ghost - (Str, From + 1, To, Base, - Base * Acc + Hexa_To_Unsigned_Ghost (Str (From)))); - -- Normal case: scanning a digit without overflows - - function Exponent_Unsigned_Ghost - (Value : Uns; - Exp : Natural; - Base : Uns := 10) return Uns_Option - with - Subprogram_Variant => (Decreases => Exp); - -- Ghost function that recursively computes Value * Base ** Exp - - -- Lemmas unfolding the recursive definition of Exponent_Unsigned_Ghost - - procedure Lemma_Exponent_Unsigned_Ghost_Base - (Value : Uns; - Exp : Natural; - Base : Uns := 10) - with - Post => - (if Exp = 0 or Value = 0 - then Exponent_Unsigned_Ghost (Value, Exp, Base) = - (Overflow => False, Value => Value)); - -- Base case: Exponent_Unsigned_Ghost returns 0 if Value or Exp is 0 - - procedure Lemma_Exponent_Unsigned_Ghost_Overflow - (Value : Uns; - Exp : Natural; - Base : Uns := 10) - with - Post => - (if Exp /= 0 - and then Value /= 0 - and then Scan_Overflows_Ghost (0, Base, Value) - then Exponent_Unsigned_Ghost (Value, Exp, Base) = (Overflow => True)); - -- Overflow case: the next multiplication overflows - - procedure Lemma_Exponent_Unsigned_Ghost_Step - (Value : Uns; - Exp : Natural; - Base : Uns := 10) - with - Post => - (if Exp /= 0 - and then Value /= 0 - and then not Scan_Overflows_Ghost (0, Base, Value) - then Exponent_Unsigned_Ghost (Value, Exp, Base) = - Exponent_Unsigned_Ghost (Value * Base, Exp - 1, Base)); - -- Normal case: exponentiation without overflows - - function Raw_Unsigned_Starts_As_Based_Ghost - (Str : String; - Last_Num_Init, To : Integer) - return Boolean - is - (Last_Num_Init < To - 1 - and then Str (Last_Num_Init + 1) in '#' | ':' - and then Str (Last_Num_Init + 2) in - '0' .. '9' | 'a' .. 'f' | 'A' .. 'F') - with Ghost, - Pre => Last_Num_Init in Str'Range - and then To in Str'Range; - -- Return True if Str starts as a based number - - function Raw_Unsigned_Is_Based_Ghost - (Str : String; - Last_Num_Init : Integer; - Last_Num_Based : Integer; - To : Integer) - return Boolean - is - (Raw_Unsigned_Starts_As_Based_Ghost (Str, Last_Num_Init, To) - and then Last_Num_Based < To - and then Str (Last_Num_Based + 1) = Str (Last_Num_Init + 1)) - with Ghost, - Pre => Last_Num_Init in Str'Range - and then Last_Num_Based in Last_Num_Init .. Str'Last - and then To in Str'Range; - -- Return True if Str is a based number - - function Is_Raw_Unsigned_Format_Ghost (Str : String) return Boolean is - (Is_Natural_Format_Ghost (Str) - and then - (declare - Last_Num_Init : constant Integer := Last_Number_Ghost (Str); - Starts_As_Based : constant Boolean := - Raw_Unsigned_Starts_As_Based_Ghost (Str, Last_Num_Init, Str'Last); - Last_Num_Based : constant Integer := - (if Starts_As_Based - then Last_Hexa_Ghost (Str (Last_Num_Init + 2 .. Str'Last)) - else Last_Num_Init); - Is_Based : constant Boolean := - Raw_Unsigned_Is_Based_Ghost - (Str, Last_Num_Init, Last_Num_Based, Str'Last); - First_Exp : constant Integer := - (if Is_Based then Last_Num_Based + 2 else Last_Num_Init + 1); - begin - (if Starts_As_Based then - Is_Based_Format_Ghost (Str (Last_Num_Init + 2 .. Str'Last)) - and then Last_Num_Based < Str'Last) - and then Is_Opt_Exponent_Format_Ghost - (Str (First_Exp .. Str'Last)))) - with - Pre => Str'Last /= Positive'Last; - -- Ghost function that determines if Str has the correct format for an - -- unsigned number without a sign character. - -- It is a natural number in base 10, optionally followed by a based - -- number surrounded by delimiters # or :, optionally followed by an - -- exponent part. - - type Split_Value_Ghost is record - Value : Uns; - Base : Uns; - Expon : Natural; - end record; - - function Scan_Split_No_Overflow_Ghost - (Str : String; - From, To : Integer) - return Boolean - is - (declare - Last_Num_Init : constant Integer := - Last_Number_Ghost (Str (From .. To)); - Init_Val : constant Uns_Option := - Scan_Based_Number_Ghost (Str, From, Last_Num_Init); - Starts_As_Based : constant Boolean := - Raw_Unsigned_Starts_As_Based_Ghost (Str, Last_Num_Init, To); - Last_Num_Based : constant Integer := - (if Starts_As_Based - then Last_Hexa_Ghost (Str (Last_Num_Init + 2 .. To)) - else Last_Num_Init); - Based_Val : constant Uns_Option := - (if Starts_As_Based and then not Init_Val.Overflow - then Scan_Based_Number_Ghost - (Str, Last_Num_Init + 2, Last_Num_Based, Init_Val.Value) - else Init_Val); - begin - not Init_Val.Overflow - and then - (Last_Num_Init >= To - 1 - or else Str (Last_Num_Init + 1) not in '#' | ':' - or else Init_Val.Value in 2 .. 16) - and then - (not Starts_As_Based - or else not Based_Val.Overflow)) - with - Pre => Str'Last /= Positive'Last - and then From in Str'Range - and then To in From .. Str'Last - and then Str (From) in '0' .. '9'; - -- Ghost function that determines if an overflow might occur while scanning - -- the representation of an unsigned number. The computation overflows if - -- either: - -- * The computation of the decimal part overflows, - -- * The decimal part is followed by a valid delimiter for a based - -- part, and the number corresponding to the base is not a valid base, - -- or - -- * The computation of the based part overflows. - - pragma Warnings (Off, "constant * is not referenced"); - function Scan_Split_Value_Ghost - (Str : String; - From, To : Integer) - return Split_Value_Ghost - is - (declare - Last_Num_Init : constant Integer := - Last_Number_Ghost (Str (From .. To)); - Init_Val : constant Uns_Option := - Scan_Based_Number_Ghost (Str, From, Last_Num_Init); - Starts_As_Based : constant Boolean := - Raw_Unsigned_Starts_As_Based_Ghost (Str, Last_Num_Init, To); - Last_Num_Based : constant Integer := - (if Starts_As_Based - then Last_Hexa_Ghost (Str (Last_Num_Init + 2 .. To)) - else Last_Num_Init); - Is_Based : constant Boolean := - Raw_Unsigned_Is_Based_Ghost (Str, Last_Num_Init, Last_Num_Based, To); - Based_Val : constant Uns_Option := - (if Starts_As_Based and then not Init_Val.Overflow - then Scan_Based_Number_Ghost - (Str, Last_Num_Init + 2, Last_Num_Based, Init_Val.Value) - else Init_Val); - First_Exp : constant Integer := - (if Is_Based then Last_Num_Based + 2 else Last_Num_Init + 1); - Expon : constant Natural := - (if Starts_As_Exponent_Format_Ghost (Str (First_Exp .. To)) - then Scan_Exponent_Ghost (Str (First_Exp .. To)) - else 0); - Base : constant Uns := - (if Is_Based then Init_Val.Value else 10); - Value : constant Uns := - (if Is_Based then Based_Val.Value else Init_Val.Value); - begin - (Value => Value, Base => Base, Expon => Expon)) - with - Pre => Str'Last /= Positive'Last - and then From in Str'Range - and then To in From .. Str'Last - and then Str (From) in '0' .. '9' - and then Scan_Split_No_Overflow_Ghost (Str, From, To); - -- Ghost function that scans an unsigned number without a sign character - -- and return a record containing the values scanned for its value, its - -- base, and its exponent. - pragma Warnings (On, "constant * is not referenced"); - - function Raw_Unsigned_No_Overflow_Ghost - (Str : String; - From, To : Integer) - return Boolean - is - (Scan_Split_No_Overflow_Ghost (Str, From, To) - and then - (declare - Val : constant Split_Value_Ghost := Scan_Split_Value_Ghost - (Str, From, To); - begin - not Exponent_Unsigned_Ghost - (Val.Value, Val.Expon, Val.Base).Overflow)) - with - Pre => Str'Last /= Positive'Last - and then From in Str'Range - and then To in From .. Str'Last - and then Str (From) in '0' .. '9'; - -- Ghost function that determines if the computation of the unsigned number - -- represented by Str will overflow. The computation overflows if either: - -- * The scan of the string overflows, or - -- * The computation of the exponentiation overflows. - - function Scan_Raw_Unsigned_Ghost - (Str : String; - From, To : Integer) - return Uns - is - (declare - Val : constant Split_Value_Ghost := Scan_Split_Value_Ghost - (Str, From, To); - begin - Exponent_Unsigned_Ghost (Val.Value, Val.Expon, Val.Base).Value) - with - Pre => Str'Last /= Positive'Last - and then From in Str'Range - and then To in From .. Str'Last - and then Str (From) in '0' .. '9' - and then Raw_Unsigned_No_Overflow_Ghost (Str, From, To); - -- Ghost function that scans an unsigned number without a sign character - - function Raw_Unsigned_Last_Ghost - (Str : String; - From, To : Integer) - return Positive - is - (declare - Last_Num_Init : constant Integer := - Last_Number_Ghost (Str (From .. To)); - Starts_As_Based : constant Boolean := - Raw_Unsigned_Starts_As_Based_Ghost (Str, Last_Num_Init, To); - Last_Num_Based : constant Integer := - (if Starts_As_Based - then Last_Hexa_Ghost (Str (Last_Num_Init + 2 .. To)) - else Last_Num_Init); - Is_Based : constant Boolean := - Raw_Unsigned_Is_Based_Ghost (Str, Last_Num_Init, Last_Num_Based, To); - First_Exp : constant Integer := - (if Is_Based then Last_Num_Based + 2 else Last_Num_Init + 1); - begin - (if not Starts_As_Exponent_Format_Ghost (Str (First_Exp .. To)) - then First_Exp - elsif Str (First_Exp + 1) in '-' | '+' then - Last_Number_Ghost (Str (First_Exp + 2 .. To)) + 1 - else Last_Number_Ghost (Str (First_Exp + 1 .. To)) + 1)) - with - Pre => Str'Last /= Positive'Last - and then From in Str'Range - and then To in From .. Str'Last - and then Str (From) in '0' .. '9', - Post => Raw_Unsigned_Last_Ghost'Result >= From; - -- Ghost function that returns the position of the cursor once an unsigned - -- number has been seen. - - function Slide_To_1 (Str : String) return String - with - Post => - Only_Space_Ghost (Str, Str'First, Str'Last) = - (for all J in Str'First .. Str'Last => - Slide_To_1'Result (J - Str'First + 1) = ' '); - -- Slides Str so that it starts at 1 - - function Slide_If_Necessary (Str : String) return String is - (if Str'Last = Positive'Last then Slide_To_1 (Str) else Str); - -- If Str'Last = Positive'Last then slides Str so that it starts at 1 - - function Is_Unsigned_Ghost (Str : String) return Boolean is - (declare - Non_Blank : constant Positive := First_Non_Space_Ghost - (Str, Str'First, Str'Last); - Fst_Num : constant Positive := - (if Str (Non_Blank) = '+' then Non_Blank + 1 else Non_Blank); - begin - Is_Raw_Unsigned_Format_Ghost (Str (Fst_Num .. Str'Last)) - and then Raw_Unsigned_No_Overflow_Ghost (Str, Fst_Num, Str'Last) - and then Only_Space_Ghost - (Str, Raw_Unsigned_Last_Ghost (Str, Fst_Num, Str'Last), Str'Last)) - with - Pre => not Only_Space_Ghost (Str, Str'First, Str'Last) - and then Str'Last /= Positive'Last; - -- Ghost function that determines if Str has the correct format for an - -- unsigned number, consisting in some blank characters, an optional - -- + sign, a raw unsigned number which does not overflow and then some - -- more blank characters. - - function Is_Value_Unsigned_Ghost (Str : String; Val : Uns) return Boolean is - (declare - Non_Blank : constant Positive := First_Non_Space_Ghost - (Str, Str'First, Str'Last); - Fst_Num : constant Positive := - (if Str (Non_Blank) = '+' then Non_Blank + 1 else Non_Blank); - begin - Val = Scan_Raw_Unsigned_Ghost (Str, Fst_Num, Str'Last)) - with - Pre => not Only_Space_Ghost (Str, Str'First, Str'Last) - and then Str'Last /= Positive'Last - and then Is_Unsigned_Ghost (Str); - -- Ghost function that returns True if Val is the value corresponding to - -- the unsigned number represented by Str. - - procedure Prove_Scan_Based_Number_Ghost_Eq - (Str1, Str2 : String; - From, To : Integer; - Base : Uns := 10; - Acc : Uns := 0) - with - Subprogram_Variant => (Increases => From), - Pre => Str1'Last /= Positive'Last - and then Str2'Last /= Positive'Last - and then - (From > To or else (From >= Str1'First and then To <= Str1'Last)) - and then - (From > To or else (From >= Str2'First and then To <= Str2'Last)) - and then Only_Hexa_Ghost (Str1, From, To) - and then (for all J in From .. To => Str1 (J) = Str2 (J)), - Post => - Scan_Based_Number_Ghost (Str1, From, To, Base, Acc) - = Scan_Based_Number_Ghost (Str2, From, To, Base, Acc); - -- Scan_Based_Number_Ghost returns the same value on two slices which are - -- equal. - - procedure Prove_Scan_Only_Decimal_Ghost - (Str : String; - Val : Uns) - with - Pre => Str'Last /= Positive'Last - and then Str'Length >= 2 - and then Str (Str'First) = ' ' - and then Only_Decimal_Ghost (Str, Str'First + 1, Str'Last) - and then Scan_Based_Number_Ghost (Str, Str'First + 1, Str'Last) - = Wrap_Option (Val), - Post => Is_Unsigned_Ghost (Slide_If_Necessary (Str)) - and then - Is_Value_Unsigned_Ghost (Slide_If_Necessary (Str), Val); - -- Ghost lemma used in the proof of 'Image implementation, to prove that - -- the result of Value_Unsigned on a decimal string is the same as the - -- result of Scan_Based_Number_Ghost. - - -- Bundle Uns type with other types, constants and subprograms used in - -- ghost code, so that this package can be instantiated once and used - -- multiple times as generic formal for a given Int type. - -private - - ---------------- - -- Slide_To_1 -- - ---------------- - - function Slide_To_1 (Str : String) return String is - (declare - Res : constant String (1 .. Str'Length) := Str; - begin - Res); - -end System.Value_U_Spec; diff --git a/gcc/ada/libgnat/s-veboop.adb b/gcc/ada/libgnat/s-veboop.adb index fb92f1c2add0..edff48526eb9 100644 --- a/gcc/ada/libgnat/s-veboop.adb +++ b/gcc/ada/libgnat/s-veboop.adb @@ -29,14 +29,6 @@ -- -- ------------------------------------------------------------------------------ --- Ghost code, loop invariants and assertions in this unit are meant for --- analysis only, not for run-time checking, as it would be too costly --- otherwise. This is enforced by setting the assertion policy to Ignore. - -pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - package body System.Vectors.Boolean_Operations with SPARK_Mode is @@ -86,26 +78,7 @@ is ----------- function "not" (Item : Vectors.Vector) return Vectors.Vector is - - procedure Prove_Not (Result : Vectors.Vector) - with - Ghost, - Pre => Valid (Item) - and then Result = (Item xor True_Val), - Post => Valid (Result) - and then (for all J in 1 .. Vector_Boolean_Size => - Model (Result) (J) = not Model (Item) (J)); - - procedure Prove_Not (Result : Vectors.Vector) is - begin - for J in 1 .. Vector_Boolean_Size loop - pragma Assert - (Element (Result, J) = 1 - Element (Item, J)); - end loop; - end Prove_Not; - begin - Prove_Not (Item xor True_Val); return Item xor True_Val; end "not"; @@ -119,32 +92,7 @@ is end Nand; function Nand (Left, Right : Vectors.Vector) return Vectors.Vector is - - procedure Prove_And (Result : Vectors.Vector) - with - Ghost, - Pre => Valid (Left) - and then Valid (Right) - and then Result = (Left and Right), - Post => Valid (Result) - and then (for all J in 1 .. Vector_Boolean_Size => - Model (Result) (J) = - (Model (Left) (J) and Model (Right) (J))); - - procedure Prove_And (Result : Vectors.Vector) is - begin - for J in 1 .. Vector_Boolean_Size loop - pragma Assert - (Element (Result, J) = - (if Element (Left, J) = 1 - and Element (Right, J) = 1 - then 1 - else 0)); - end loop; - end Prove_And; - begin - Prove_And (Left and Right); return not (Left and Right); end Nand; @@ -158,32 +106,7 @@ is end Nor; function Nor (Left, Right : Vectors.Vector) return Vectors.Vector is - - procedure Prove_Or (Result : Vectors.Vector) - with - Ghost, - Pre => Valid (Left) - and then Valid (Right) - and then Result = (Left or Right), - Post => Valid (Result) - and then (for all J in 1 .. Vector_Boolean_Size => - Model (Result) (J) = - (Model (Left) (J) or Model (Right) (J))); - - procedure Prove_Or (Result : Vectors.Vector) is - begin - for J in 1 .. Vector_Boolean_Size loop - pragma Assert - (Element (Result, J) = - (if Element (Left, J) = 1 - or Element (Right, J) = 1 - then 1 - else 0)); - end loop; - end Prove_Or; - begin - Prove_Or (Left or Right); return not (Left or Right); end Nor; @@ -197,32 +120,7 @@ is end Nxor; function Nxor (Left, Right : Vectors.Vector) return Vectors.Vector is - - procedure Prove_Xor (Result : Vectors.Vector) - with - Ghost, - Pre => Valid (Left) - and then Valid (Right) - and then Result = (Left xor Right), - Post => Valid (Result) - and then (for all J in 1 .. Vector_Boolean_Size => - Model (Result) (J) = - (Model (Left) (J) xor Model (Right) (J))); - - procedure Prove_Xor (Result : Vectors.Vector) is - begin - for J in 1 .. Vector_Boolean_Size loop - pragma Assert - (Element (Result, J) = - (if Element (Left, J) = 1 - xor Element (Right, J) = 1 - then 1 - else 0)); - end loop; - end Prove_Xor; - begin - Prove_Xor (Left xor Right); return not (Left xor Right); end Nxor; diff --git a/gcc/ada/libgnat/s-veboop.ads b/gcc/ada/libgnat/s-veboop.ads index 6283d1902b6b..0b4f89474a97 100644 --- a/gcc/ada/libgnat/s-veboop.ads +++ b/gcc/ada/libgnat/s-veboop.ads @@ -31,116 +31,21 @@ -- This package contains functions for runtime operations on boolean vectors --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - package System.Vectors.Boolean_Operations with Pure, SPARK_Mode is - pragma Warnings (Off, "aspect ""Pre"" not enforced on inlined subprogram", - Reason => "Pre only used in proof"); - pragma Warnings (Off, "aspect ""Post"" not enforced on inlined subprogram", - Reason => "Post only used in proof"); - -- Type Vectors.Vector represents an array of Boolean, each of which - -- takes 8 bits of the representation, with the 7 msb set to zero. Express - -- in contracts the constraint on valid vectors and the model that they - -- represent, and the relationship between input models and output model. - - Vector_Boolean_Size : constant Positive := - System.Word_Size / System.Storage_Unit - with Ghost; - - type Vector_Element is mod 2 ** System.Storage_Unit with Ghost; - - type Vector_Boolean_Array is array (1 .. Vector_Boolean_Size) of Boolean - with Ghost; - - function Shift_Right (V : Vectors.Vector; N : Natural) return Vectors.Vector - with Ghost, Import, Convention => Intrinsic; - - function Element (V : Vectors.Vector; N : Positive) return Vector_Element is - (Vector_Element (Shift_Right (V, (N - 1) * System.Storage_Unit) - and (2 ** System.Storage_Unit - 1))) - with - Ghost, - Pre => N <= Vector_Boolean_Size; - -- Return the Nth element represented by the vector - - function Valid (V : Vectors.Vector) return Boolean is - (for all J in 1 .. Vector_Boolean_Size => - Element (V, J) in 0 .. 1) - with Ghost; - -- A valid vector is one for which all elements are 0 (representing False) - -- or 1 (representing True). - - function Model (V : Vectors.Vector) return Vector_Boolean_Array - with - Ghost, - Pre => Valid (V); - - function Model (V : Vectors.Vector) return Vector_Boolean_Array is - (for J in 1 .. Vector_Boolean_Size => Element (V, J) = 1); - -- The model of a valid vector is the corresponding array of Boolean values - - -- Although in general the boolean operations on arrays of booleans are - -- identical to operations on arrays of unsigned words of the same size, - -- for the "not" operator this is not the case as False is typically - -- represented by 0 and true by 1. - - function "not" (Item : Vectors.Vector) return Vectors.Vector - with - Pre => Valid (Item), - Post => Valid ("not"'Result) - and then (for all J in 1 .. Vector_Boolean_Size => - Model ("not"'Result) (J) = not Model (Item) (J)); - - function Nand (Left, Right : Boolean) return Boolean - with - Post => Nand'Result = not (Left and Right); - - function Nor (Left, Right : Boolean) return Boolean - with - Post => Nor'Result = not (Left or Right); - - function Nxor (Left, Right : Boolean) return Boolean - with - Post => Nxor'Result = not (Left xor Right); + -- takes 8 bits of the representation, with the 7 msb set to zero. - function Nand (Left, Right : Vectors.Vector) return Vectors.Vector - with - Pre => Valid (Left) - and then Valid (Right), - Post => Valid (Nand'Result) - and then (for all J in 1 .. Vector_Boolean_Size => - Model (Nand'Result) (J) = - Nand (Model (Left) (J), Model (Right) (J))); + function "not" (Item : Vectors.Vector) return Vectors.Vector; - function Nor (Left, Right : Vectors.Vector) return Vectors.Vector - with - Pre => Valid (Left) - and then Valid (Right), - Post => Valid (Nor'Result) - and then (for all J in 1 .. Vector_Boolean_Size => - Model (Nor'Result) (J) = - Nor (Model (Left) (J), Model (Right) (J))); + function Nand (Left, Right : Boolean) return Boolean; + function Nor (Left, Right : Boolean) return Boolean; + function Nxor (Left, Right : Boolean) return Boolean; - function Nxor (Left, Right : Vectors.Vector) return Vectors.Vector - with - Pre => Valid (Left) - and then Valid (Right), - Post => Valid (Nxor'Result) - and then (for all J in 1 .. Vector_Boolean_Size => - Model (Nxor'Result) (J) = - Nxor (Model (Left) (J), Model (Right) (J))); + function Nand (Left, Right : Vectors.Vector) return Vectors.Vector; + function Nor (Left, Right : Vectors.Vector) return Vectors.Vector; + function Nxor (Left, Right : Vectors.Vector) return Vectors.Vector; -- The three boolean operations "nand", "nor" and "nxor" are needed -- for cases where the compiler moves boolean array operations into -- the body of the loop that iterates over the array elements. diff --git a/gcc/ada/libgnat/s-vs_int.ads b/gcc/ada/libgnat/s-vs_int.ads deleted file mode 100644 index a4cc0dc4b374..000000000000 --- a/gcc/ada/libgnat/s-vs_int.ads +++ /dev/null @@ -1,59 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- S Y S T E M . V S _ I N T -- --- -- --- S p e c -- --- -- --- Copyright (C) 2023-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - --- This package contains specification functions for scanning signed Integer --- values for use in ``Text_IO.Integer_IO``, and the Value attribute. - --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -with System.Unsigned_Types; -with System.Value_I_Spec; -with System.Vs_Uns; - -package System.Vs_Int with SPARK_Mode, Ghost is - pragma Preelaborate; - - subtype Unsigned is Unsigned_Types.Unsigned; - - package Spec is new System.Value_I_Spec - (Integer, Unsigned, System.Vs_Uns.Spec); - -end System.Vs_Int; diff --git a/gcc/ada/libgnat/s-vs_lli.ads b/gcc/ada/libgnat/s-vs_lli.ads deleted file mode 100644 index 3a4a0104efaa..000000000000 --- a/gcc/ada/libgnat/s-vs_lli.ads +++ /dev/null @@ -1,60 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- S Y S T E M . V S _ L L I -- --- -- --- S p e c -- --- -- --- Copyright (C) 2023-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - --- This package contains specification functions for scanning --- Long_Long_Integer values for use in ``Text_IO.Integer_IO``, and the Value --- attribute. - --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -with System.Unsigned_Types; -with System.Value_I_Spec; -with System.Vs_LLU; - -package System.Vs_LLI with SPARK_Mode, Ghost is - pragma Preelaborate; - - subtype Long_Long_Unsigned is Unsigned_Types.Long_Long_Unsigned; - - package Spec is new System.Value_I_Spec - (Long_Long_Integer, Long_Long_Unsigned, System.Vs_LLU.Spec); - -end System.Vs_LLI; diff --git a/gcc/ada/libgnat/s-vs_llu.ads b/gcc/ada/libgnat/s-vs_llu.ads deleted file mode 100644 index e1c0fec1a3ce..000000000000 --- a/gcc/ada/libgnat/s-vs_llu.ads +++ /dev/null @@ -1,58 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- S Y S T E M . V S _ L L U -- --- -- --- S p e c -- --- -- --- Copyright (C) 2023-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - --- This package contains specification functions for scanning --- Long_Long_Unsigned values for use in ``Text_IO.Modular_IO``, and the Value --- attribute. - --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -with System.Unsigned_Types; -with System.Value_U_Spec; - -package System.Vs_LLU with SPARK_Mode, Ghost is - pragma Preelaborate; - - subtype Long_Long_Unsigned is Unsigned_Types.Long_Long_Unsigned; - - package Spec is new System.Value_U_Spec (Long_Long_Unsigned); - -end System.Vs_LLU; diff --git a/gcc/ada/libgnat/s-vs_uns.ads b/gcc/ada/libgnat/s-vs_uns.ads deleted file mode 100644 index 7e5aac3e4ee1..000000000000 --- a/gcc/ada/libgnat/s-vs_uns.ads +++ /dev/null @@ -1,57 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- S Y S T E M . V S _ U N S -- --- -- --- S p e c -- --- -- --- Copyright (C) 2023-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - --- This package contains specification functions for scanning modular Unsigned --- values for use in ``Text_IO.Modular_IO``, and the Value attribute. - --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -with System.Unsigned_Types; -with System.Value_U_Spec; - -package System.Vs_Uns with SPARK_Mode, Ghost is - pragma Preelaborate; - - subtype Unsigned is Unsigned_Types.Unsigned; - - package Spec is new System.Value_U_Spec (Unsigned); - -end System.Vs_Uns; diff --git a/gcc/ada/libgnat/s-vsllli.ads b/gcc/ada/libgnat/s-vsllli.ads deleted file mode 100644 index 5648060f45a1..000000000000 --- a/gcc/ada/libgnat/s-vsllli.ads +++ /dev/null @@ -1,60 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- S Y S T E M . V S _ L L L I -- --- -- --- S p e c -- --- -- --- Copyright (C) 2023-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - --- This package contains specification functions for scanning --- ``Long_Long_Long_Integer`` values for use in ``Text_IO.Integer_IO``, and --- the Value attribute. - --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -with System.Unsigned_Types; -with System.Value_I_Spec; -with System.Vs_LLLU; - -package System.Vs_LLLI with SPARK_Mode, Ghost is - pragma Preelaborate; - - subtype Long_Long_Long_Unsigned is Unsigned_Types.Long_Long_Long_Unsigned; - - package Spec is new System.Value_I_Spec - (Long_Long_Long_Integer, Long_Long_Long_Unsigned, System.Vs_LLLU.Spec); - -end System.Vs_LLLI; diff --git a/gcc/ada/libgnat/s-vslllu.ads b/gcc/ada/libgnat/s-vslllu.ads deleted file mode 100644 index 7fe1235e2fd9..000000000000 --- a/gcc/ada/libgnat/s-vslllu.ads +++ /dev/null @@ -1,58 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- S Y S T E M . V S _ L L L U -- --- -- --- S p e c -- --- -- --- Copyright (C) 2023-2025, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - --- This package contains specification functions for scanning --- Long_Long_Long_Unsigned values for use in Text_IO.Modular_IO, and the Value --- attribute. - --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -with System.Unsigned_Types; -with System.Value_U_Spec; - -package System.Vs_LLLU with SPARK_Mode, Ghost is - pragma Preelaborate; - - subtype Long_Long_Long_Unsigned is Unsigned_Types.Long_Long_Long_Unsigned; - - package Spec is new System.Value_U_Spec (Long_Long_Long_Unsigned); - -end System.Vs_LLLU; diff --git a/gcc/ada/libgnat/s-widint.ads b/gcc/ada/libgnat/s-widint.ads index 22e342cca908..8af8d91180e5 100644 --- a/gcc/ada/libgnat/s-widint.ads +++ b/gcc/ada/libgnat/s-widint.ads @@ -31,24 +31,11 @@ -- Width attribute for signed integers up to Integer --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - with System.Width_I; package System.Wid_Int with SPARK_Mode is - function Width_Integer is new Width_I (Integer); pragma Pure_Function (Width_Integer); - end System.Wid_Int; diff --git a/gcc/ada/libgnat/s-widlli.ads b/gcc/ada/libgnat/s-widlli.ads index 3490b3f71e09..a977096c1b52 100644 --- a/gcc/ada/libgnat/s-widlli.ads +++ b/gcc/ada/libgnat/s-widlli.ads @@ -31,24 +31,11 @@ -- Width attribute for signed integers larger than Integer --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - with System.Width_I; package System.Wid_LLI with SPARK_Mode is - function Width_Long_Long_Integer is new Width_I (Long_Long_Integer); pragma Pure_Function (Width_Long_Long_Integer); - end System.Wid_LLI; diff --git a/gcc/ada/libgnat/s-widllli.ads b/gcc/ada/libgnat/s-widllli.ads index ee8f7af055e2..325e80fc01e7 100644 --- a/gcc/ada/libgnat/s-widllli.ads +++ b/gcc/ada/libgnat/s-widllli.ads @@ -31,25 +31,12 @@ -- Width attribute for signed integers larger than Long_Long_Integer --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - with System.Width_I; package System.Wid_LLLI with SPARK_Mode is - function Width_Long_Long_Long_Integer is new Width_I (Long_Long_Long_Integer); pragma Pure_Function (Width_Long_Long_Long_Integer); - end System.Wid_LLLI; diff --git a/gcc/ada/libgnat/s-widlllu.ads b/gcc/ada/libgnat/s-widlllu.ads index db5b9d168262..8a5c04f4b8be 100644 --- a/gcc/ada/libgnat/s-widlllu.ads +++ b/gcc/ada/libgnat/s-widlllu.ads @@ -31,17 +31,6 @@ -- Width attribute for modular integers larger than Long_Long_Integer --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - with System.Width_U; with System.Unsigned_Types; diff --git a/gcc/ada/libgnat/s-widllu.ads b/gcc/ada/libgnat/s-widllu.ads index 0fd31356d0d5..f8c82844963a 100644 --- a/gcc/ada/libgnat/s-widllu.ads +++ b/gcc/ada/libgnat/s-widllu.ads @@ -31,17 +31,6 @@ -- Width attribute for modular integers larger than Integer --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - with System.Width_U; with System.Unsigned_Types; diff --git a/gcc/ada/libgnat/s-widthi.adb b/gcc/ada/libgnat/s-widthi.adb index 959579047d1a..c66d662f74f2 100644 --- a/gcc/ada/libgnat/s-widthi.adb +++ b/gcc/ada/libgnat/s-widthi.adb @@ -29,109 +29,9 @@ -- -- ------------------------------------------------------------------------------ -with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; -use Ada.Numerics.Big_Numbers.Big_Integers_Ghost; - function System.Width_I (Lo, Hi : Int) return Natural is - - -- Ghost code, loop invariants and assertions in this unit are meant for - -- analysis only, not for run-time checking, as it would be too costly - -- otherwise. This is enforced by setting the assertion policy to Ignore. - - pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - - ----------------------- - -- Local Subprograms -- - ----------------------- - - package Signed_Conversion is new Signed_Conversions (Int => Int); - - function Big (Arg : Int) return Big_Integer renames - Signed_Conversion.To_Big_Integer; - - -- Maximum value of exponent for 10 that fits in Uns'Base - function Max_Log10 return Natural is - (case Int'Base'Size is - when 8 => 2, - when 16 => 4, - when 32 => 9, - when 64 => 19, - when 128 => 38, - when others => raise Program_Error) - with Ghost; - - ------------------ - -- Local Lemmas -- - ------------------ - - procedure Lemma_Lower_Mult (A, B, C : Big_Natural) - with - Ghost, - Pre => A <= B, - Post => A * C <= B * C; - - procedure Lemma_Div_Commutation (X, Y : Int) - with - Ghost, - Pre => X >= 0 and Y > 0, - Post => Big (X) / Big (Y) = Big (X / Y); - - procedure Lemma_Div_Twice (X : Big_Natural; Y, Z : Big_Positive) - with - Ghost, - Post => X / Y / Z = X / (Y * Z); - - ---------------------- - -- Lemma_Lower_Mult -- - ---------------------- - - procedure Lemma_Lower_Mult (A, B, C : Big_Natural) is null; - - --------------------------- - -- Lemma_Div_Commutation -- - --------------------------- - - procedure Lemma_Div_Commutation (X, Y : Int) is null; - - --------------------- - -- Lemma_Div_Twice -- - --------------------- - - procedure Lemma_Div_Twice (X : Big_Natural; Y, Z : Big_Positive) is - XY : constant Big_Natural := X / Y; - YZ : constant Big_Natural := Y * Z; - XYZ : constant Big_Natural := X / Y / Z; - R : constant Big_Natural := (XY rem Z) * Y + (X rem Y); - begin - pragma Assert (X = XY * Y + (X rem Y)); - pragma Assert (XY = XY / Z * Z + (XY rem Z)); - pragma Assert (X = XYZ * YZ + R); - pragma Assert ((XY rem Z) * Y <= (Z - 1) * Y); - pragma Assert (R <= YZ - 1); - pragma Assert (X / YZ = (XYZ * YZ + R) / YZ); - pragma Assert (X / YZ = XYZ + R / YZ); - end Lemma_Div_Twice; - - -- Local variables - W : Natural; T : Int; - - -- Local ghost variables - - Max_W : constant Natural := Max_Log10 with Ghost; - Big_10 : constant Big_Integer := Big (10) with Ghost; - - Pow : Big_Integer := 1 with Ghost; - T_Init : constant Int := - Int'Max (abs Int'Max (Lo, Int'First + 1), - abs Int'Max (Hi, Int'First + 1)) - with Ghost; - --- Start of processing for System.Width_I - begin if Lo > Hi then return 0; @@ -151,41 +51,10 @@ begin -- Increase value if more digits required while T >= 10 loop - Lemma_Div_Commutation (T, 10); - Lemma_Div_Twice (Big (T_Init), Big_10 ** (W - 2), Big_10); - T := T / 10; W := W + 1; - Pow := Pow * 10; - - pragma Loop_Invariant (T >= 0); - pragma Loop_Invariant (W in 3 .. Max_W + 3); - pragma Loop_Invariant (Pow = Big_10 ** (W - 2)); - pragma Loop_Invariant (Big (T) = Big (T_Init) / Pow); - pragma Loop_Variant (Decreases => T); end loop; - declare - F : constant Big_Positive := Big_10 ** (W - 2) with Ghost; - Q : constant Big_Natural := Big (T_Init) / F with Ghost; - R : constant Big_Natural := Big (T_Init) rem F with Ghost; - begin - pragma Assert (Q < Big_10); - pragma Assert (Big (T_Init) = Q * F + R); - Lemma_Lower_Mult (Q, Big (9), F); - pragma Assert (Big (T_Init) <= Big (9) * F + F - 1); - pragma Assert (Big (T_Init) < Big_10 * F); - pragma Assert (Big_10 * F = Big_10 ** (W - 1)); - end; - - -- This is an expression of the functional postcondition for Width_I, - -- which cannot be expressed readily as a postcondition as this would - -- require making the instantiation Signed_Conversion and function Big - -- available from the spec. - - pragma Assert (Big (Int'Max (Lo, Int'First + 1)) < Big_10 ** (W - 1)); - pragma Assert (Big (Int'Max (Hi, Int'First + 1)) < Big_10 ** (W - 1)); - return W; end if; diff --git a/gcc/ada/libgnat/s-widthu.adb b/gcc/ada/libgnat/s-widthu.adb index df27e50d814e..fe51d611740a 100644 --- a/gcc/ada/libgnat/s-widthu.adb +++ b/gcc/ada/libgnat/s-widthu.adb @@ -31,110 +31,12 @@ package body System.Width_U is - -- Ghost code, loop invariants and assertions in this unit are meant for - -- analysis only, not for run-time checking, as it would be too costly - -- otherwise. This is enforced by setting the assertion policy to Ignore. - - pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore, - Assert_And_Cut => Ignore, - Subprogram_Variant => Ignore); - function Width (Lo, Hi : Uns) return Natural is - - -- Ghost code, loop invariants and assertions in this unit are meant for - -- analysis only, not for run-time checking, as it would be too costly - -- otherwise. This is enforced by setting the assertion policy to - -- Ignore. - - pragma Assertion_Policy (Ghost => Ignore, - Loop_Invariant => Ignore, - Assert => Ignore); - - ------------------ - -- Local Lemmas -- - ------------------ - - procedure Lemma_Lower_Mult (A, B, C : Big_Natural) - with - Ghost, - Pre => A <= B, - Post => A * C <= B * C; - - procedure Lemma_Div_Commutation (X, Y : Uns) - with - Ghost, - Pre => Y /= 0, - Post => Big (X) / Big (Y) = Big (X / Y); - - procedure Lemma_Div_Twice (X : Big_Natural; Y, Z : Big_Positive) - with - Ghost, - Post => X / Y / Z = X / (Y * Z); - - procedure Lemma_Euclidian (V, Q, F, R : Big_Integer) - with - Ghost, - Pre => F > 0 and then Q = V / F and then R = V rem F, - Post => V = Q * F + R; - -- Ghost lemma to prove the relation between the quotient/remainder of - -- division by F and the value V. - - ---------------------- - -- Lemma_Lower_Mult -- - ---------------------- - - procedure Lemma_Lower_Mult (A, B, C : Big_Natural) is null; - - --------------------------- - -- Lemma_Div_Commutation -- - --------------------------- - - procedure Lemma_Div_Commutation (X, Y : Uns) is null; - - --------------------- - -- Lemma_Div_Twice -- - --------------------- - - procedure Lemma_Div_Twice (X : Big_Natural; Y, Z : Big_Positive) is - XY : constant Big_Natural := X / Y; - YZ : constant Big_Natural := Y * Z; - XYZ : constant Big_Natural := X / Y / Z; - R : constant Big_Natural := (XY rem Z) * Y + (X rem Y); - begin - pragma Assert (X = XY * Y + (X rem Y)); - pragma Assert (XY = XY / Z * Z + (XY rem Z)); - pragma Assert (X = XYZ * YZ + R); - pragma Assert ((XY rem Z) * Y <= (Z - 1) * Y); - pragma Assert (R <= YZ - 1); - pragma Assert (X / YZ = (XYZ * YZ + R) / YZ); - pragma Assert (X / YZ = XYZ + R / YZ); - end Lemma_Div_Twice; - - --------------------- - -- Lemma_Euclidian -- - --------------------- - - procedure Lemma_Euclidian (V, Q, F, R : Big_Integer) is null; - - -- Local variables - W : Natural; T : Uns; - - -- Local ghost variables - - Max_W : constant Natural := Max_Log10 with Ghost; - Pow : Big_Integer := 1 with Ghost; - T_Init : constant Uns := Uns'Max (Lo, Hi) with Ghost; - - -- Start of processing for System.Width_U - begin if Lo > Hi then return 0; - else -- Minimum value is 2, one for space, one for digit @@ -147,32 +49,10 @@ package body System.Width_U is -- Increase value if more digits required while T >= 10 loop - Lemma_Div_Commutation (T, 10); - Lemma_Div_Twice (Big (T_Init), Big_10 ** (W - 2), Big_10); - T := T / 10; W := W + 1; - Pow := Pow * 10; - - pragma Loop_Invariant (W in 3 .. Max_W + 2); - pragma Loop_Invariant (Pow = Big_10 ** (W - 2)); - pragma Loop_Invariant (Big (T) = Big (T_Init) / Pow); - pragma Loop_Variant (Decreases => T); end loop; - declare - F : constant Big_Integer := Big_10 ** (W - 2) with Ghost; - Q : constant Big_Integer := Big (T_Init) / F with Ghost; - R : constant Big_Integer := Big (T_Init) rem F with Ghost; - begin - pragma Assert (Q < Big_10); - Lemma_Euclidian (Big (T_Init), Q, F, R); - Lemma_Lower_Mult (Q, Big (9), F); - pragma Assert (Big (T_Init) <= Big (9) * F + F - 1); - pragma Assert (Big (T_Init) < Big_10 * F); - pragma Assert (Big_10 * F = Big_10 ** (W - 1)); - end; - return W; end if; end Width; diff --git a/gcc/ada/libgnat/s-widthu.ads b/gcc/ada/libgnat/s-widthu.ads index 56da0a29b892..076dace903f6 100644 --- a/gcc/ada/libgnat/s-widthu.ads +++ b/gcc/ada/libgnat/s-widthu.ads @@ -29,65 +29,14 @@ -- -- ------------------------------------------------------------------------------ --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore, - Subprogram_Variant => Ignore); - -- Compute Width attribute for non-static type derived from a modular integer -- type. The arguments Lo, Hi are the bounds of the type. -with Ada.Numerics.Big_Numbers.Big_Integers_Ghost; - generic - type Uns is mod <>; package System.Width_U with Pure is - package BI_Ghost renames Ada.Numerics.Big_Numbers.Big_Integers_Ghost; - subtype Big_Integer is BI_Ghost.Big_Integer with Ghost; - subtype Big_Natural is BI_Ghost.Big_Natural with Ghost; - subtype Big_Positive is BI_Ghost.Big_Positive with Ghost; - use type BI_Ghost.Big_Integer; - - package Unsigned_Conversion is - new BI_Ghost.Unsigned_Conversions (Int => Uns); - - function Big (Arg : Uns) return Big_Integer renames - Unsigned_Conversion.To_Big_Integer; - - Big_10 : constant Big_Integer := Big (Uns'(10)) with Ghost; - - -- Maximum value of exponent for 10 that fits in Uns'Base - function Max_Log10 return Natural is - (case Uns'Base'Size is - when 8 => 2, - when 16 => 4, - when 32 => 9, - when 64 => 19, - when 128 => 38, - when others => raise Program_Error) - with Ghost; - - function Width (Lo, Hi : Uns) return Natural - with - Post => - (declare - W : constant Natural := System.Width_U.Width'Result; - begin - (if Lo > Hi then W = 0 - else W > 0 - and then W <= Max_Log10 + 2 - and then Big (Lo) < Big_10 ** (W - 1) - and then Big (Hi) < Big_10 ** (W - 1))); - + function Width (Lo, Hi : Uns) return Natural; end System.Width_U; diff --git a/gcc/ada/libgnat/s-widuns.ads b/gcc/ada/libgnat/s-widuns.ads index d81b8621ea16..6ac292846c45 100644 --- a/gcc/ada/libgnat/s-widuns.ads +++ b/gcc/ada/libgnat/s-widuns.ads @@ -31,17 +31,6 @@ -- Width attribute for modular integers up to Integer --- Preconditions in this unit are meant for analysis only, not for run-time --- checking, so that the expected exceptions are raised. This is enforced by --- setting the corresponding assertion policy to Ignore. Postconditions and --- contract cases should not be executed at runtime as well, in order not to --- slow down the execution of these functions. - -pragma Assertion_Policy (Pre => Ignore, - Post => Ignore, - Contract_Cases => Ignore, - Ghost => Ignore); - with System.Width_U; with System.Unsigned_Types; diff --git a/gcc/ada/libgnat/system-linux-loongarch.ads b/gcc/ada/libgnat/system-linux-loongarch.ads index 77a213962550..683b7a441558 100644 --- a/gcc/ada/libgnat/system-linux-loongarch.ads +++ b/gcc/ada/libgnat/system-linux-loongarch.ads @@ -139,7 +139,6 @@ private Always_Compatible_Rep : constant Boolean := False; Suppress_Standard_Library : constant Boolean := False; Use_Ada_Main_Program_Name : constant Boolean := False; - Frontend_Exceptions : constant Boolean := False; ZCX_By_Default : constant Boolean := True; end System; diff --git a/gcc/ada/mutably_tagged.adb b/gcc/ada/mutably_tagged.adb index 153d1683d13a..b04ba92e5aa8 100644 --- a/gcc/ada/mutably_tagged.adb +++ b/gcc/ada/mutably_tagged.adb @@ -40,6 +40,7 @@ with Sinfo.Nodes; use Sinfo.Nodes; with Sinfo.Utils; use Sinfo.Utils; with Stringt; use Stringt; with Tbuild; use Tbuild; +with Uintp; use Uintp; package body Mutably_Tagged is @@ -205,21 +206,41 @@ package body Mutably_Tagged is Mut_Tag_Typ : Entity_Id) return Node_Id is Loc : constant Source_Ptr := Sloc (New_Typ); + + CW_Size : constant Uint := RM_Size (Mut_Tag_Typ); + + function To_Mixed_Case (S : String) return String; + -- convert string to mixed case + + ------------------- + -- To_Mixed_Case -- + ------------------- + + function To_Mixed_Case (S : String) return String is + Buf : Bounded_String; + begin + Append (Buf, S); + Set_Casing (Buf, Mixed_Case); + return +Buf; + end To_Mixed_Case; + + -- Start of processing for Make_CW_Size_Compile_Check + begin - -- Generate a string literal for New_Typ's name which is needed for - -- printing within the Compile_Time_Error. + -- Build a Compile_Time_Error pragma in order to defer the + -- (compile-time) size check until after the back end has + -- determined sizes. + -- + -- It would be nice if we could somehow include the value of + -- New_Type'Size in the error message, but it is not clear how to + -- accomplish that with the current FE/BE interfaces. + + -- Get New_Typ's name (in mixed case) into the name buffer; + -- this is used immediately afterwards in the Make_Pragma call. Get_Decoded_Name_String (Chars (New_Typ)); Set_Casing (Mixed_Case); - -- Build a pragma Compile_Time_Error to force the backend to - -- preform appropriate sizing checks. - - -- Generate: - -- pragma Compile_Time_Error - -- (New_Typ'Size < Mut_Tag_Typ'Size, - -- "class size for by-reference type ""New_Typ"" too small") - return Make_Pragma (Loc, Chars => Name_Compile_Time_Error, @@ -233,19 +254,18 @@ package body Mutably_Tagged is Prefix => New_Occurrence_Of (New_Typ, Loc)), Right_Opnd => - Make_Integer_Literal (Loc, - RM_Size (Mut_Tag_Typ))))), + Make_Integer_Literal (Loc, CW_Size)))), Make_Pragma_Argument_Association (Loc, Expression => - - -- Is it possible to print the size of New_Typ via - -- Validate_Compile_Time_Warning_Or_Error after the back-end - -- has run to generate the error message manually ??? - Make_String_Literal (Loc, - "class size for by-reference type """ - & To_String (String_From_Name_Buffer) - & """ too small")))); + To_String (String_From_Name_Buffer) + & "'Size exceeds " + & To_Mixed_Case ( + To_String (Fully_Qualified_Name_String + (Find_Specific_Type (Mut_Tag_Typ), + Append_NUL => False))) + & "'Size'Class limit of " + & UI_Image (CW_Size))))); end Make_CW_Size_Compile_Check; ------------------------------------ diff --git a/gcc/ada/namet.adb b/gcc/ada/namet.adb index e27669ef68d6..b7d3abd899ea 100644 --- a/gcc/ada/namet.adb +++ b/gcc/ada/namet.adb @@ -1297,29 +1297,11 @@ package body Namet is -- Present -- ------------- - function Present (Nam : File_Name_Type) return Boolean is - begin - return Nam /= No_File; - end Present; - - ------------- - -- Present -- - ------------- - function Present (Nam : Name_Id) return Boolean is begin return Nam /= No_Name; end Present; - ------------- - -- Present -- - ------------- - - function Present (Nam : Unit_Name_Type) return Boolean is - begin - return Nam /= No_Unit_Name; - end Present; - ------------------ -- Reinitialize -- ------------------ diff --git a/gcc/ada/namet.ads b/gcc/ada/namet.ads index daa87d91caa6..b05e4b506e69 100644 --- a/gcc/ada/namet.ads +++ b/gcc/ada/namet.ads @@ -504,10 +504,6 @@ package Namet is -- Constant used to indicate no file is present (this is used for example -- when a search for a file indicates that no file of the name exists). - function Present (Nam : File_Name_Type) return Boolean; - pragma Inline (Present); - -- Determine whether file name Nam exists - Error_File_Name : constant File_Name_Type := File_Name_Type (Error_Name); -- The special File_Name_Type value Error_File_Name is used to indicate -- a unit name where some previous processing has found an error. @@ -532,10 +528,6 @@ package Namet is No_Unit_Name : constant Unit_Name_Type := Unit_Name_Type (No_Name); -- Constant used to indicate no file name present - function Present (Nam : Unit_Name_Type) return Boolean; - pragma Inline (Present); - -- Determine whether unit name Nam exists - Error_Unit_Name : constant Unit_Name_Type := Unit_Name_Type (Error_Name); -- The special Unit_Name_Type value Error_Unit_Name is used to indicate -- a unit name where some previous processing has found an error. @@ -609,6 +601,7 @@ private -- Int Value associated with this name end record; + -- The aliased non-boolean components are required to match the C structure for Name_Entry use record Name_Chars_Index at 0 range 0 .. 31; @@ -622,9 +615,10 @@ private Hash_Link at 8 range 0 .. 31; Int_Info at 12 range 0 .. 31; end record; + -- This ensures a matching layout between Ada and C for Name_Entry'Size use 16 * 8; - -- This ensures that we did not leave out any fields + -- This ensures that record is reasonably small -- This is the table that is referenced by Valid_Name_Id entries. -- It contains one entry for each unique name in the table. diff --git a/gcc/ada/nlists.adb b/gcc/ada/nlists.adb index e5228f5a6f12..a01819902f0b 100644 --- a/gcc/ada/nlists.adb +++ b/gcc/ada/nlists.adb @@ -125,19 +125,10 @@ package body Nlists is -------------------------- procedure Allocate_List_Tables (N : Node_Or_Entity_Id) is - Old_Last : constant Node_Or_Entity_Id'Base := Next_Node.Last; - begin - pragma Assert (N >= Old_Last); + pragma Assert (N >= Next_Node.Last); Next_Node.Set_Last (N); Prev_Node.Set_Last (N); - - -- Make sure we have no uninitialized junk in any new entries added. - - for J in Old_Last + 1 .. N loop - Next_Node.Table (J) := Empty; - Prev_Node.Table (J) := Empty; - end loop; end Allocate_List_Tables; ------------ diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads index 687d1ed8836a..e595b0841195 100644 --- a/gcc/ada/opt.ads +++ b/gcc/ada/opt.ads @@ -308,6 +308,10 @@ package Opt is -- GNATMAKE -- Set to True to check readonly files during the make process + Check_Semantics_Only_Mode : Boolean := False; + -- GNATMAKE + -- Set to True when -gnatc is present to only perform semantic checking. + Check_Source_Files : Boolean := True; -- GNATBIND, GNATMAKE -- Set to True to enable consistency checking for any source files that @@ -939,6 +943,21 @@ package Opt is -- WARNING: There is a matching C declaration of this variable in fe.h + List_Representation_Info_Extended : Boolean := False; + -- GNAT + -- Set true by -gnatRe switch. Causes extended information for record types + -- to be included in the representation output information. + + List_Representation_Info_Holes : Boolean := False; + -- GNAT + -- Set true by -gnatRh switch. Causes information for holes between record + -- components to be included in the representation output information. + + List_Representation_Info_Mechanisms : Boolean := False; + -- GNAT + -- Set true by -gnatRm switch. Causes information on mechanisms to be + -- included in the representation output information. + List_Representation_Info_To_File : Boolean := False; -- GNAT -- Set true by -gnatRs switch. Causes information from -gnatR[1-4]m to be @@ -951,16 +970,6 @@ package Opt is -- Set true by -gnatRj switch. Causes information from -gnatR[1-4]m to be -- output in the JSON data interchange format. - List_Representation_Info_Mechanisms : Boolean := False; - -- GNAT - -- Set true by -gnatRm switch. Causes information on mechanisms to be - -- included in the representation output information. - - List_Representation_Info_Extended : Boolean := False; - -- GNAT - -- Set true by -gnatRe switch. Causes extended information for record types - -- to be included in the representation output information. - List_Preprocessing_Symbols : Boolean := False; -- GNAT, GNATPREP -- Set to True if symbols for preprocessing a source are to be listed @@ -1518,10 +1527,6 @@ package Opt is -- used for inconsistency error messages. A value of System_Location is -- used if the policy is set in package System. - Tasking_Used : Boolean := False; - -- Set True if any tasking construct is encountered. Used to activate the - -- output of the Q, L and T lines in ALI files. - Time_Slice_Set : Boolean := False; -- GNATBIND -- Set True if a pragma Time_Slice is processed in the main unit, or diff --git a/gcc/ada/osint.adb b/gcc/ada/osint.adb index bf2affed70f7..26b0dbb1ae46 100644 --- a/gcc/ada/osint.adb +++ b/gcc/ada/osint.adb @@ -64,6 +64,14 @@ package body Osint is -- Used in Locate_File as a fake directory when Name is already an -- absolute path. + procedure Get_Current_Dir + (Dir : System.Address; Length : System.Address); + pragma Import (C, Get_Current_Dir, "__gnat_get_current_dir"); + + Max_Path : Integer; + pragma Import (C, Max_Path, "__gnat_max_path_len"); + -- Maximum length of a path name + ------------------------------------- -- Use of Name_Find and Name_Enter -- ------------------------------------- @@ -1426,6 +1434,24 @@ package body Osint is Smart_Find_File (N, Source, Full_File, Attr.all); end Full_Source_Name; + --------------------- + -- Get_Current_Dir -- + --------------------- + + function Get_Current_Dir return String is + Path_Len : Natural := Max_Path; + Buffer : String (1 .. 1 + Max_Path + 1); + + begin + Get_Current_Dir (Buffer'Address, Path_Len'Address); + + if Path_Len = 0 then + raise Program_Error; + end if; + + return Buffer (1 .. Path_Len); + end Get_Current_Dir; + ------------------- -- Get_Directory -- ------------------- @@ -1517,15 +1543,6 @@ package body Osint is (Search_Dir : String; File_Type : Search_File_Type) return String_Ptr is - procedure Get_Current_Dir - (Dir : System.Address; - Length : System.Address); - pragma Import (C, Get_Current_Dir, "__gnat_get_current_dir"); - - Max_Path : Integer; - pragma Import (C, Max_Path, "__gnat_max_path_len"); - -- Maximum length of a path name - Current_Dir : String_Ptr; Default_Search_Dir : String_Access; Default_Suffix_Dir : String_Access; @@ -2731,6 +2748,84 @@ package body Osint is pragma Assert (Hi = Src'Last); end Read_Source_File; + ------------------- + -- Relative_Path -- + ------------------- + + function Relative_Path (Path : String; Ref : String) return String is + Norm_Path : constant String := + Normalize_Pathname (Name => Path, Resolve_Links => False); + Norm_Ref : constant String := + Normalize_Pathname (Name => Ref, Resolve_Links => False); + Rel_Path : Bounded_String; + Last : Natural := Norm_Ref'Last; + Old : Natural; + Depth : Natural := 0; + + begin + pragma Assert (System.OS_Lib.Is_Absolute_Path (Norm_Path)); + pragma Assert (System.OS_Lib.Is_Absolute_Path (Norm_Ref)); + pragma Assert (System.OS_Lib.Is_Directory (Norm_Ref)); + + -- If the root drives are different on Windows then we cannot create a + -- relative path. + + if Root (Norm_Path) /= Root (Norm_Ref) then + return Norm_Path; + end if; + + if Norm_Path = Norm_Ref then + return "."; + end if; + + loop + exit when Last - Norm_Ref'First + 1 <= Norm_Path'Length + and then + Norm_Path + (Norm_Path'First .. + Norm_Path'First + Last - Norm_Ref'First) = + Norm_Ref (Norm_Ref'First .. Last); + + Old := Last; + for J in reverse Norm_Ref'First .. Last - 1 loop + if Is_Directory_Separator (Norm_Ref (J)) then + Depth := Depth + 1; + Last := J; + exit; + end if; + end loop; + + if Old = Last then + -- No Dir_Separator in Ref... Let's return Path + return Norm_Path; + end if; + end loop; + + -- Move up the directory chain to the common point + + for I in 1 .. Depth loop + Append (Rel_Path, ".." & System.OS_Lib.Directory_Separator); + end loop; + + -- Avoid starting the relative path with a directory separator + + if Last < Norm_Path'Length + and then Is_Directory_Separator (Norm_Path (Norm_Path'First + Last)) + then + Last := Last + 1; + end if; + + -- Add the rest of the path from the common point + + Append + (Rel_Path, + Norm_Path + (Norm_Path'First + Last - Norm_Ref'First + 1 .. + Norm_Path'Last)); + + return To_String (Rel_Path); + end Relative_Path; + ------------------- -- Relocate_Path -- ------------------- @@ -2788,6 +2883,25 @@ package body Osint is return new String'(Path); end Relocate_Path; + ---------- + -- Root -- + ---------- + + function Root (Path : String) return String is + Last : Natural := Path'First; + begin + pragma Assert (System.OS_Lib.Is_Absolute_Path (Path)); + + for I in Path'Range loop + if Is_Directory_Separator (Path (I)) then + Last := I; + exit; + end if; + end loop; + + return Path (Path'First .. Last); + end Root; + ----------------- -- Set_Program -- ----------------- diff --git a/gcc/ada/osint.ads b/gcc/ada/osint.ads index 041af4101dd8..77aaf04a7712 100644 --- a/gcc/ada/osint.ads +++ b/gcc/ada/osint.ads @@ -166,6 +166,9 @@ package Osint is function Is_Directory_Separator (C : Character) return Boolean; -- Returns True if C is a directory separator + function Get_Current_Dir return String; + -- Returns the current working directory for the execution environment + function Get_Directory (Name : File_Name_Type) return File_Name_Type; -- Get the prefix directory name (if any) from Name. The last separator -- is preserved. Return the normalized current directory if there is no @@ -230,6 +233,15 @@ package Osint is (Canonical_File : String) return String_Access; -- Convert a canonical syntax file specification to host syntax + function Relative_Path (Path : String; Ref : String) return String; + -- Given an absolute path Path calculate its relative path from a reference + -- directory Ref. + -- + -- If the paths are the same it will return ".". + -- + -- If the paths are on different drives on Windows based systems then it + -- will return the normalized version of Path. + function Relocate_Path (Prefix : String; Path : String) return String_Ptr; @@ -243,6 +255,9 @@ package Osint is -- If the above computation fails, return Path. This function assumes -- Prefix'First = Path'First. + function Root (Path : String) return String; + -- Return the root of an absolute Path. + function Shared_Lib (Name : String) return String; -- Returns the runtime shared library in the form -l<name>-<version> where -- version is the GNAT runtime library option for the platform. For example diff --git a/gcc/ada/par-ch13.adb b/gcc/ada/par-ch13.adb index f52136c916a7..dbb894f79cd3 100644 --- a/gcc/ada/par-ch13.adb +++ b/gcc/ada/par-ch13.adb @@ -503,6 +503,8 @@ package body Ch13 is or else A_Id = Aspect_Refined_Depends then Inside_Depends := True; + elsif A_Id = Aspect_Abstract_State then + Inside_Abstract_State := True; end if; -- Note that we have seen an Import aspect specification. @@ -529,9 +531,10 @@ package body Ch13 is Set_Expression (Aspect, P_Expression); end if; - -- Unconditionally reset flag for Inside_Depends + -- Unconditionally reset flag for being inside aspects - Inside_Depends := False; + Inside_Depends := False; + Inside_Abstract_State := False; end if; -- Add the aspect to the resulting list only when it was properly diff --git a/gcc/ada/par-ch2.adb b/gcc/ada/par-ch2.adb index 20640d5547b8..11c9a8384df4 100644 --- a/gcc/ada/par-ch2.adb +++ b/gcc/ada/par-ch2.adb @@ -385,6 +385,8 @@ package body Ch2 is or else Chars (Ident_Node) = Name_Refined_Depends then Inside_Depends := True; + elsif Chars (Ident_Node) = Name_Abstract_State then + Inside_Abstract_State := True; end if; -- Scan arguments. We assume that arguments are present if there is @@ -441,11 +443,11 @@ package body Ch2 is Semicolon_Loc := Token_Ptr; - -- Cancel indication of being within a pragma or in particular a Depends - -- pragma. + -- Cancel indication of being within a pragma - Inside_Depends := False; - Inside_Pragma := False; + Inside_Depends := False; + Inside_Abstract_State := False; + Inside_Pragma := False; -- Now we have two tasks left, we need to scan out the semicolon -- following the pragma, and we have to call Par.Prag to process @@ -472,8 +474,9 @@ package body Ch2 is exception when Error_Resync => Resync_Past_Semicolon; - Inside_Depends := False; - Inside_Pragma := False; + Inside_Depends := False; + Inside_Abstract_State := False; + Inside_Pragma := False; return Error; end P_Pragma; diff --git a/gcc/ada/par-ch4.adb b/gcc/ada/par-ch4.adb index ca02f1baac18..ebdc587f0e15 100644 --- a/gcc/ada/par-ch4.adb +++ b/gcc/ada/par-ch4.adb @@ -592,6 +592,20 @@ package body Ch4 is Explicit_Actual_Parameter => Rnam)); exit; + -- 'Make is a special attribute that takes a variable + -- amount of parameters. + + elsif All_Extensions_Allowed + and then Attr_Name = Name_Make + then + Scan; + Rnam := P_Expression; + Append_To (Expressions (Name_Node), + Make_Parameter_Association (Sloc (Rnam), + Selector_Name => Expr, + Explicit_Actual_Parameter => Rnam)); + exit; + -- For all other cases named notation is illegal else @@ -654,13 +668,13 @@ package body Ch4 is -- (discrete_range) - -- This is a slice. This case is handled in LP_State_Init + -- This is a slice -- (expression, expression, ..) -- This is interpreted as an indexed component, i.e. as a -- case of a name which can be extended in the normal manner. - -- This case is handled by LP_State_Name or LP_State_Expr. + -- This case is handled by LP_State_Expr. -- Note: if and case expressions (without an extra level of -- parentheses) are permitted in this context). @@ -921,129 +935,9 @@ package body Ch4 is -- Error recovery: cannot raise Error_Resync - function P_Function_Name return Node_Id is - Designator_Node : Node_Id; - Prefix_Node : Node_Id; - Selector_Node : Node_Id; - Dot_Sloc : Source_Ptr := No_Location; - - begin - -- Prefix_Node is set to the gathered prefix so far, Empty means that - -- no prefix has been scanned. This allows us to build up the result - -- in the required right recursive manner. - - Prefix_Node := Empty; - - -- Loop through prefixes - - loop - Designator_Node := Token_Node; - - if Token not in Token_Class_Desig then - return P_Identifier; -- let P_Identifier issue the error message - - else -- Token in Token_Class_Desig - Scan; -- past designator - exit when Token /= Tok_Dot; - end if; - - -- Here at a dot, with token just before it in Designator_Node - - if No (Prefix_Node) then - Prefix_Node := Designator_Node; - else - Selector_Node := New_Node (N_Selected_Component, Dot_Sloc); - Set_Prefix (Selector_Node, Prefix_Node); - Set_Selector_Name (Selector_Node, Designator_Node); - Prefix_Node := Selector_Node; - end if; - - Dot_Sloc := Token_Ptr; - Scan; -- past dot - end loop; - - -- Fall out of the loop having just scanned a designator - - if No (Prefix_Node) then - return Designator_Node; - else - Selector_Node := New_Node (N_Selected_Component, Dot_Sloc); - Set_Prefix (Selector_Node, Prefix_Node); - Set_Selector_Name (Selector_Node, Designator_Node); - return Selector_Node; - end if; - - exception - when Error_Resync => - return Error; - end P_Function_Name; - - -- This function parses a restricted form of Names which are either - -- identifiers, or identifiers preceded by a sequence of prefixes - -- that are direct names. - - -- Error recovery: cannot raise Error_Resync - function P_Qualified_Simple_Name return Node_Id is - Designator_Node : Node_Id; - Prefix_Node : Node_Id; - Selector_Node : Node_Id; - Dot_Sloc : Source_Ptr := No_Location; - begin - -- Prefix node is set to the gathered prefix so far, Empty means that - -- no prefix has been scanned. This allows us to build up the result - -- in the required right recursive manner. - - Prefix_Node := Empty; - - -- Loop through prefixes - - loop - Designator_Node := Token_Node; - - if Token = Tok_Identifier then - Scan; -- past identifier - exit when Token /= Tok_Dot; - - elsif Token not in Token_Class_Desig then - return P_Identifier; -- let P_Identifier issue the error message - - else - Scan; -- past designator - - if Token /= Tok_Dot then - Error_Msg_SP ("identifier expected"); - return Error; - end if; - end if; - - -- Here at a dot, with token just before it in Designator_Node - - if No (Prefix_Node) then - Prefix_Node := Designator_Node; - else - Selector_Node := New_Node (N_Selected_Component, Dot_Sloc); - Set_Prefix (Selector_Node, Prefix_Node); - Set_Selector_Name (Selector_Node, Designator_Node); - Prefix_Node := Selector_Node; - end if; - - Dot_Sloc := Token_Ptr; - Scan; -- past dot - end loop; - - -- Fall out of the loop having just scanned an identifier - - if No (Prefix_Node) then - return Designator_Node; - else - Selector_Node := New_Node (N_Selected_Component, Dot_Sloc); - Set_Prefix (Selector_Node, Prefix_Node); - Set_Selector_Name (Selector_Node, Designator_Node); - return Selector_Node; - end if; - + return P_Qualified_Simple_Name_Resync; exception when Error_Resync => return Error; @@ -1062,6 +956,10 @@ package body Ch4 is Dot_Sloc : Source_Ptr := No_Location; begin + -- Prefix_Node is set to the gathered prefix so far, Empty means that + -- no prefix has been scanned. This allows us to build up the result + -- in the required right recursive manner. + Prefix_Node := Empty; -- Loop through prefixes @@ -1069,21 +967,13 @@ package body Ch4 is loop Designator_Node := Token_Node; - if Token = Tok_Identifier then - Scan; -- past identifier - exit when Token /= Tok_Dot; - - elsif Token not in Token_Class_Desig then + if Token not in Token_Class_Desig then Discard_Junk_Node (P_Identifier); -- to issue the error message raise Error_Resync; else Scan; -- past designator - - if Token /= Tok_Dot then - Error_Msg_SP ("identifier expected"); - raise Error_Resync; - end if; + exit when Token /= Tok_Dot; end if; -- Here at a dot, with token just before it in Designator_Node @@ -1098,7 +988,7 @@ package body Ch4 is end if; Dot_Sloc := Token_Ptr; - Scan; -- past period + Scan; -- past dot end loop; -- Fall out of the loop having just scanned an identifier @@ -1593,8 +1483,13 @@ package body Ch4 is -- Improper use of WITH elsif Token = Tok_With then - Error_Msg_SC ("WITH must be preceded by single expression in " & - "extension aggregate"); + if Inside_Abstract_State then + Error_Msg_SC ("state name with options must be enclosed in " & + "parentheses"); + else + Error_Msg_SC ("WITH must be preceded by single expression in " & + "extension aggregate"); + end if; raise Error_Resync; -- Range attribute can only appear as part of a discrete choice list @@ -3473,8 +3368,9 @@ package body Ch4 is function P_Allocator return Node_Id is Alloc_Node : Node_Id; - Type_Node : Node_Id; Null_Exclusion_Present : Boolean; + Scan_State : Saved_Scan_State; + Type_Node : Node_Id; begin Alloc_Node := New_Node (N_Allocator, Token_Ptr); @@ -3496,6 +3392,31 @@ package body Ch4 is Null_Exclusion_Present := P_Null_Exclusion; Set_Null_Exclusion_Present (Alloc_Node, Null_Exclusion_Present); + + -- Check for 'Make + + if All_Extensions_Allowed + and then Token = Tok_Identifier + then + Save_Scan_State (Scan_State); + Type_Node := P_Qualified_Simple_Name_Resync; + if Token = Tok_Apostrophe then + Scan; + if Token_Name = Name_Make then + Restore_Scan_State (Scan_State); + Set_Expression + (Alloc_Node, + Make_Qualified_Expression (Token_Ptr, + Subtype_Mark => Check_Subtype_Mark (Type_Node), + Expression => P_Expression_Or_Range_Attribute)); + return Alloc_Node; + end if; + end if; + Restore_Scan_State (Scan_State); + end if; + + -- Otherwise continue parsing the subtype + Type_Node := P_Subtype_Mark_Resync; if Token = Tok_Apostrophe then diff --git a/gcc/ada/par-ch5.adb b/gcc/ada/par-ch5.adb index a46fe4408aaa..cc0e6c167fc2 100644 --- a/gcc/ada/par-ch5.adb +++ b/gcc/ada/par-ch5.adb @@ -32,6 +32,7 @@ package body Ch5 is function P_Case_Statement return Node_Id; function P_Case_Statement_Alternative return Node_Id; + function P_Continue_Statement return Node_Id; function P_Exit_Statement return Node_Id; function P_Goto_Statement return Node_Id; function P_If_Statement return Node_Id; @@ -76,6 +77,9 @@ package body Ch5 is procedure Then_Scan; -- Scan past THEN token, testing for illegal junk after it + procedure Parse_Loop_Flow_Statement (N : N_Loop_Flow_Statement_Id); + -- Common processing for Parse_Continue_Statement and Parse_Exit_Statement. + --------------------------------- -- 5.1 Sequence of Statements -- --------------------------------- @@ -511,6 +515,13 @@ package body Ch5 is P_Assignment_Statement (Id_Node)); Statement_Required := False; + elsif Block_Label = Name_Continue + and then Token in Tok_Semicolon | Tok_When | Tok_Identifier + then + Restore_Scan_State (Scan_State_Label); -- to Id + Append_To (Statement_List, P_Continue_Statement); + Statement_Required := False; + -- Check common case of procedure call, another case that -- we want to speed up as much as possible. @@ -1899,11 +1910,11 @@ package body Ch5 is (Block_Name : Node_Id := Empty) return Node_Id is - Block_Node : Node_Id; + Block : Node_Id; Created_Name : Node_Id; begin - Block_Node := New_Node (N_Block_Statement, Token_Ptr); + Block := New_Node (N_Block_Statement, Token_Ptr); Push_Scope_Stack; Scopes (Scope.Last).Etyp := E_Name; @@ -1916,18 +1927,18 @@ package body Ch5 is if No (Block_Name) then Created_Name := - Make_Identifier (Sloc (Block_Node), Set_Loop_Block_Name ('B')); + Make_Identifier (Sloc (Block), Set_Loop_Block_Name ('B')); Set_Comes_From_Source (Created_Name, False); - Set_Has_Created_Identifier (Block_Node, True); - Set_Identifier (Block_Node, Created_Name); + Set_Has_Created_Identifier (Block, True); + Set_Identifier (Block, Created_Name); Scopes (Scope.Last).Labl := Created_Name; else - Set_Identifier (Block_Node, Block_Name); + Set_Identifier (Block, Block_Name); end if; - Append_Elmt (Block_Node, Label_List); - Parse_Decls_Begin_End (Block_Node); - return Block_Node; + Append_Elmt (Block, Label_List); + Parse_Decls_Begin_End (Block); + return Block; end P_Declare_Statement; -- P_Begin_Statement @@ -1942,11 +1953,11 @@ package body Ch5 is (Block_Name : Node_Id := Empty) return Node_Id is - Block_Node : Node_Id; + Block : Node_Id; Created_Name : Node_Id; begin - Block_Node := New_Node (N_Block_Statement, Token_Ptr); + Block := New_Node (N_Block_Statement, Token_Ptr); Push_Scope_Stack; Scopes (Scope.Last).Etyp := E_Name; @@ -1957,24 +1968,24 @@ package body Ch5 is if No (Block_Name) then Created_Name := - Make_Identifier (Sloc (Block_Node), Set_Loop_Block_Name ('B')); + Make_Identifier (Sloc (Block), Set_Loop_Block_Name ('B')); Set_Comes_From_Source (Created_Name, False); - Set_Has_Created_Identifier (Block_Node, True); - Set_Identifier (Block_Node, Created_Name); + Set_Has_Created_Identifier (Block, True); + Set_Identifier (Block, Created_Name); Scopes (Scope.Last).Labl := Created_Name; else - Set_Identifier (Block_Node, Block_Name); + Set_Identifier (Block, Block_Name); end if; - Append_Elmt (Block_Node, Label_List); + Append_Elmt (Block, Label_List); Scopes (Scope.Last).Ecol := Start_Column; Scopes (Scope.Last).Sloc := Token_Ptr; Scan; -- past BEGIN Set_Handled_Statement_Sequence - (Block_Node, P_Handled_Sequence_Of_Statements); - End_Statements (Handled_Statement_Sequence (Block_Node)); - return Block_Node; + (Block, P_Handled_Sequence_Of_Statements); + End_Statements (Handled_Statement_Sequence (Block)); + return Block; end P_Begin_Statement; ------------------------- @@ -1995,46 +2006,24 @@ package body Ch5 is begin Exit_Node := New_Node (N_Exit_Statement, Token_Ptr); - Scan; -- past EXIT - - if Token = Tok_Identifier then - Set_Name (Exit_Node, P_Qualified_Simple_Name); - - elsif Style_Check then - -- This EXIT has no name, so check that - -- the innermost loop is unnamed too. - - Check_No_Exit_Name : - for J in reverse 1 .. Scope.Last loop - if Scopes (J).Etyp = E_Loop then - if Present (Scopes (J).Labl) - and then Comes_From_Source (Scopes (J).Labl) - then - -- Innermost loop in fact had a name, style check fails - - Style.No_Exit_Name (Scopes (J).Labl); - end if; - exit Check_No_Exit_Name; - end if; - end loop Check_No_Exit_Name; - end if; + Parse_Loop_Flow_Statement (Exit_Node); - if Token = Tok_When and then not Missing_Semicolon_On_When then - Scan; -- past WHEN - Set_Condition (Exit_Node, P_Condition); + return Exit_Node; + end P_Exit_Statement; - -- Allow IF instead of WHEN, giving error message + -------------------------------------- + -- GNAT-specific Continue Statement -- + -------------------------------------- - elsif Token = Tok_If then - T_When; - Scan; -- past IF used in place of WHEN - Set_Condition (Exit_Node, P_Expression_No_Right_Paren); - end if; + function P_Continue_Statement return Node_Id is + Continue_Node : constant Node_Id := + New_Node (N_Continue_Statement, Token_Ptr); + begin + Parse_Loop_Flow_Statement (Continue_Node); - TF_Semicolon; - return Exit_Node; - end P_Exit_Statement; + return Continue_Node; + end P_Continue_Statement; ------------------------- -- 5.8 Goto Statement -- @@ -2395,4 +2384,48 @@ package body Ch5 is end if; end Then_Scan; + ------------------------------- + -- Parse_Loop_Flow_Statement -- + ------------------------------- + + procedure Parse_Loop_Flow_Statement (N : N_Loop_Flow_Statement_Id) is + begin + Scan; -- past EXIT or CONTINUE + + if Token = Tok_Identifier then + Set_Name (N, P_Qualified_Simple_Name); + elsif Style_Check and then Nkind (N) = N_Exit_Statement then + -- This statement has no name, so check that + -- the innermost loop is unnamed too. + + Check_No_Exit_Name : + for J in reverse 1 .. Scope.Last loop + if Scopes (J).Etyp = E_Loop then + if Present (Scopes (J).Labl) + and then Comes_From_Source (Scopes (J).Labl) + then + -- Innermost loop in fact had a name, style check fails + + Style.No_Exit_Name (Scopes (J).Labl); + end if; + + exit Check_No_Exit_Name; + end if; + end loop Check_No_Exit_Name; + end if; + + if Token = Tok_When and then not Missing_Semicolon_On_When then + Scan; -- past WHEN + Set_Condition (N, P_Condition); + + -- Allow IF instead of WHEN, giving error message + + elsif Token = Tok_If then + T_When; + Scan; -- past IF used in place of WHEN + Set_Condition (N, P_Expression_No_Right_Paren); + end if; + + TF_Semicolon; + end Parse_Loop_Flow_Statement; end Ch5; diff --git a/gcc/ada/par-ch6.adb b/gcc/ada/par-ch6.adb index 55591fdc0335..0f7765ba300d 100644 --- a/gcc/ada/par-ch6.adb +++ b/gcc/ada/par-ch6.adb @@ -362,12 +362,11 @@ package body Ch6 is if Func then Inst_Node := New_Node (N_Function_Instantiation, Fproc_Sloc); - Set_Name (Inst_Node, P_Function_Name); else Inst_Node := New_Node (N_Procedure_Instantiation, Fproc_Sloc); - Set_Name (Inst_Node, P_Qualified_Simple_Name); end if; + Set_Name (Inst_Node, P_Qualified_Simple_Name); Set_Defining_Unit_Name (Inst_Node, Name_Node); Set_Generic_Associations (Inst_Node, P_Generic_Actual_Part_Opt); P_Aspect_Specifications (Inst_Node, Semicolon => True); diff --git a/gcc/ada/par-endh.adb b/gcc/ada/par-endh.adb index ac78b60094dc..816670568a67 100644 --- a/gcc/ada/par-endh.adb +++ b/gcc/ada/par-endh.adb @@ -23,12 +23,12 @@ -- -- ------------------------------------------------------------------------------ +with Errid; use Errid; with Namet.Sp; use Namet.Sp; with Stringt; use Stringt; with Uintp; use Uintp; with GNAT.Spelling_Checker; use GNAT.Spelling_Checker; -with Diagnostics.Constructors; use Diagnostics.Constructors; separate (Par) package body Endh is @@ -300,7 +300,7 @@ package body Endh is else End_Labl := Scopes (Scope.Last).Labl; - if End_Labl > Empty_Or_Error then + if End_Labl not in Empty | Error then -- The task here is to construct a designator from the -- opening label, with the components all marked as not @@ -658,8 +658,6 @@ package body Endh is Scan; -- past junk token on same line end loop; end if; - - return; end End_Skip; -------------------- @@ -899,6 +897,8 @@ package body Endh is Wrong_End_Start : Source_Ptr; Wrong_End_Finish : Source_Ptr; + + Wrong_End_Span : Source_Span; begin -- Suppress message if this was a potentially junk entry (e.g. a record -- entry where no record keyword was present). @@ -919,7 +919,7 @@ package body Endh is -- Suppress message if error was posted on opening label - if Error_Msg_Node_1 > Empty_Or_Error + if Error_Msg_Node_1 not in Empty | Error and then Error_Posted (Error_Msg_Node_1) then return; @@ -936,31 +936,38 @@ package body Endh is elsif End_Type = E_Loop then if Error_Msg_Node_1 = Empty then - if Debug_Flag_Underscore_DD then - - -- TODO: This is a quick hack to get the location of the - -- END LOOP for the demonstration. - - Wrong_End_Start := Token_Ptr; - - while Token /= Tok_Semicolon loop - Scan; -- past semicolon - end loop; + Wrong_End_Start := Token_Ptr; - Wrong_End_Finish := Token_Ptr; - - Restore_Scan_State (Scan_State); - - Record_End_Loop_Expected_Error - (End_Loc => To_Span (First => Wrong_End_Start, - Ptr => Wrong_End_Start, - Last => Wrong_End_Finish), - Start_Loc => Error_Msg_Sloc); + while Token /= Tok_Semicolon loop + Scan; -- past semicolon + end loop; - else - Error_Msg_SC -- CODEFIX - ("`END LOOP;` expected@ for LOOP#!"); - end if; + Wrong_End_Finish := Token_Ptr; + + Wrong_End_Span := + To_Span + (First => Wrong_End_Start, + Ptr => Wrong_End_Start, + Last => Wrong_End_Finish); + + Restore_Scan_State (Scan_State); + + Error_Msg -- CODEFIX + (Msg => "`END LOOP;` expected@ for LOOP#!", + Flag_Span => Wrong_End_Span, + N => Empty, + Error_Code => GNAT0004, + Spans => + (1 => Secondary_Labeled_Span (To_Span (Error_Msg_Sloc))), + Fixes => + (1 => + Fix + (Description => "Replace with 'end loop;'", + Edits => + (1 => + Edit + (Text => "end loop;", + Span => Wrong_End_Span))))); else Error_Msg_SC -- CODEFIX ("`END LOOP &;` expected@!"); diff --git a/gcc/ada/par-load.adb b/gcc/ada/par-load.adb index 96fa7e85938d..4a97f14ffb51 100644 --- a/gcc/ada/par-load.adb +++ b/gcc/ada/par-load.adb @@ -83,7 +83,7 @@ procedure Load is -- withed units and the second round handles Ada 2005 limited-withed units. -- This is required to allow the low-level circuitry that detects circular -- dependencies of units the correct notification of errors (see comment - -- bellow). This variable is used to indicate that the second round is + -- below). This variable is used to indicate that the second round is -- required. function Same_File_Name_Except_For_Case diff --git a/gcc/ada/par-prag.adb b/gcc/ada/par-prag.adb index 6efb16d9722b..4d0ffe625497 100644 --- a/gcc/ada/par-prag.adb +++ b/gcc/ada/par-prag.adb @@ -1548,6 +1548,7 @@ begin | Pragma_Priority_Specific_Dispatching | Pragma_Profile | Pragma_Profile_Warnings + | Pragma_Program_Exit | Pragma_Propagate_Exceptions | Pragma_Provide_Shift_Operators | Pragma_Psect_Object diff --git a/gcc/ada/par-tchk.adb b/gcc/ada/par-tchk.adb index 803d3a22f2df..e59d6b496a7f 100644 --- a/gcc/ada/par-tchk.adb +++ b/gcc/ada/par-tchk.adb @@ -513,7 +513,6 @@ package body Tchk is Error_Msg_AP -- CODEFIX ("|missing "";"""); - return; end T_Semicolon; ------------ diff --git a/gcc/ada/par-util.adb b/gcc/ada/par-util.adb index 53b57e4c1bf3..78a76b3b1f14 100644 --- a/gcc/ada/par-util.adb +++ b/gcc/ada/par-util.adb @@ -176,14 +176,17 @@ package body Util is procedure Check_Future_Keyword is begin -- Ada 2005 (AI-284): Compiling in Ada 95 mode we warn that INTERFACE, - -- OVERRIDING, and SYNCHRONIZED are new reserved words. + -- OVERRIDING, and SYNCHRONIZED are new reserved words. We make an + -- exception if INTERFACE is used in the context of the GNAT-specific + -- pragma Interface, since we accept that pragma regardless of the Ada + -- version. if Ada_Version = Ada_95 and then Warn_On_Ada_2005_Compatibility then - if Token_Name in Name_Overriding | Name_Synchronized - or else (Token_Name = Name_Interface - and then Prev_Token /= Tok_Pragma) + if Token_Name in Ada_2005_Reserved_Words + and then not (Token_Name = Name_Interface + and then Prev_Token = Tok_Pragma) then Error_Msg_N ("& is a reserved word in Ada 2005?y?", Token_Node); end if; @@ -194,13 +197,13 @@ package body Util is if Ada_Version in Ada_95 .. Ada_2005 and then Warn_On_Ada_2012_Compatibility then - if Token_Name = Name_Some then + if Token_Name in Ada_2012_Reserved_Words then Error_Msg_N ("& is a reserved word in Ada 2012?y?", Token_Node); end if; end if; if Ada_Version < Ada_With_All_Extensions then - if Token_Name = Name_Finally then + if Token_Name in GNAT_Extensions_Reserved_Words then Error_Msg_N ("& is a reserved word with all extensions enabled?", Token_Node); diff --git a/gcc/ada/par.adb b/gcc/ada/par.adb index 5d61fac3c113..e11ec7e7ff44 100644 --- a/gcc/ada/par.adb +++ b/gcc/ada/par.adb @@ -80,6 +80,11 @@ function Par (Configuration_Pragmas : Boolean) return List_Id is -- True within a delta aggregate (but only after the "delta" token has -- been scanned). Used to distinguish syntax errors from syntactically -- correct "deep" delta aggregates (enabled via -gnatX0). + + Inside_Abstract_State : Boolean := False; + -- True within an Abstract_State contract. Used to distinguish syntax error + -- about extended aggregates and about a malformed contract. + Save_Style_Checks : Style_Check_Options; Save_Style_Check : Boolean; -- Variables for storing the original state of whether style checks should @@ -825,7 +830,6 @@ function Par (Configuration_Pragmas : Boolean) return List_Id is function P_Aggregate return Node_Id; function P_Expression return Node_Id; function P_Expression_Or_Range_Attribute return Node_Id; - function P_Function_Name return Node_Id; function P_Name return Node_Id; function P_Qualified_Simple_Name return Node_Id; function P_Qualified_Simple_Name_Resync return Node_Id; diff --git a/gcc/ada/prepcomp.adb b/gcc/ada/prepcomp.adb index ea7760a713b7..35dd4cbf53ae 100644 --- a/gcc/ada/prepcomp.adb +++ b/gcc/ada/prepcomp.adb @@ -545,7 +545,7 @@ package body Prepcomp is if Total_Errors_Detected > T then Errout.Finalize (Last_Call => True); - Errout.Output_Messages; + Errout.Output_Messages (E_Fatal); Fail ("errors found in preprocessing data file """ & Get_Name_String (N) & """"); end if; @@ -668,7 +668,7 @@ package body Prepcomp is if T /= Total_Errors_Detected then Errout.Finalize (Last_Call => True); - Errout.Output_Messages; + Errout.Output_Messages (E_Fatal); Fail ("errors found in definition file """ & Get_Name_String (N) & """"); diff --git a/gcc/ada/repinfo.adb b/gcc/ada/repinfo.adb index cd4b66439741..bbf92a778007 100644 --- a/gcc/ada/repinfo.adb +++ b/gcc/ada/repinfo.adb @@ -30,6 +30,7 @@ with Debug; use Debug; with Einfo; use Einfo; with Einfo.Entities; use Einfo.Entities; with Einfo.Utils; use Einfo.Utils; +with GNAT.Heap_Sort_G; with Lib; use Lib; with Namet; use Namet; with Nlists; use Nlists; @@ -77,20 +78,6 @@ package body Repinfo is Op3 : Node_Ref_Or_Val; end record; - -- The following representation clause ensures that the above record - -- has no holes. We do this so that when instances of this record are - -- written, we do not write uninitialized values to the file. - - for Exp_Node use record - Expr at 0 range 0 .. 31; - Op1 at 4 range 0 .. 31; - Op2 at 8 range 0 .. 31; - Op3 at 12 range 0 .. 31; - end record; - - for Exp_Node'Size use 16 * 8; - -- This ensures that we did not leave out any fields - package Rep_Table is new Table.Table ( Table_Component_Type => Exp_Node, Table_Index_Type => Nat, @@ -427,9 +414,9 @@ package body Repinfo is Write_Line (";"); end if; - -- Alignment is not always set for task, protected, and class-wide - -- types, or when doing semantic analysis only. Representation aspects - -- are not computed for types in a generic unit. + -- Alignment is not always set for concurrent types, class-wide types, + -- cloned subtypes, or when doing semantic analysis only. Representation + -- aspects are not computed for types declared in a generic unit. else -- Add unknown alignment entry in JSON format to ensure the format is @@ -440,11 +427,13 @@ package body Repinfo is Write_Unknown_Val; end if; - pragma Assert - (not Expander_Active or else - Is_Concurrent_Type (Ent) or else - Is_Class_Wide_Type (Ent) or else - Sem_Util.In_Generic_Scope (Ent)); + pragma Assert (not Expander_Active + or else Is_Concurrent_Type (Ent) + or else Is_Class_Wide_Type (Ent) + or else (Ekind (Ent) = E_Record_Subtype + and then Present (Cloned_Subtype (Ent)) + and then Has_Delayed_Freeze (Cloned_Subtype (Ent))) + or else Sem_Util.In_Generic_Scope (Ent)); end if; end List_Common_Type_Info; @@ -544,11 +533,13 @@ package body Repinfo is List_Type_Info (E); end if; - -- Note that formals are not annotated so we skip them here + -- Formals and renamings are not annotated, so we skip them + -- here. elsif Ekind (E) in E_Constant | E_Loop_Parameter | E_Variable + and then Nkind (Parent (E)) /= N_Object_Renaming_Declaration then if List_Representation_Info >= 2 then List_Object_Info (E); @@ -870,8 +861,7 @@ package body Repinfo is -- generic unit, or if the back end is not being run), don't try to -- print them. - pragma Assert (Known_Esize (Ent) = Known_Alignment (Ent)); - if not Known_Alignment (Ent) then + if not Known_Esize (Ent) or else not Known_Alignment (Ent) then return; end if; @@ -896,6 +886,7 @@ package body Repinfo is Write_Eol; Write_Line ("}"); + else Write_Str ("for "); List_Name (Ent); @@ -1237,11 +1228,145 @@ package body Repinfo is Starting_First_Bit : Uint := Uint_0; Prefix : String := "") is - Comp : Entity_Id; - First : Boolean := True; + function First_Comp_Or_Discr (Ent : Entity_Id) return Entity_Id; + -- Like First_Component_Or_Discriminant, but reorder the components + -- according to their bit offset if need be. + + ------------------------- + -- First_Comp_Or_Discr -- + ------------------------- + + function First_Comp_Or_Discr (Ent : Entity_Id) return Entity_Id is + + function Is_Placed_Before (C1, C2 : Entity_Id) return Boolean; + -- Return True if components C1 and C2 are in the same component + -- list and component C1 is placed before component C2 in there. + + ---------------------- + -- Is_Placed_Before -- + ---------------------- + + function Is_Placed_Before (C1, C2 : Entity_Id) return Boolean is + L1 : constant Node_Id := Parent (Parent (C1)); + L2 : constant Node_Id := Parent (Parent (C2)); + + begin + -- Discriminants and top-level components are considered to be + -- in the same list, although this is not syntactically true. + + return (L1 = L2 + or else (Nkind (Parent (L1)) /= N_Variant + and then Nkind (Parent (L2)) /= N_Variant)) + and then Known_Static_Component_Bit_Offset (C1) + and then Known_Static_Component_Bit_Offset (C2) + and then + Component_Bit_Offset (C1) < Component_Bit_Offset (C2); + end Is_Placed_Before; + + -- Local variables + + Comp : Entity_Id; + N_Comp : Natural := 0; + Prev : Entity_Id; + Reorder : Boolean := False; + + -- Start of processing for First_Comp_Or_Discr + + begin + -- Reordering is needed only for -gnatRh + + if not List_Representation_Info_Holes then + return First_Component_Or_Discriminant (Ent); + end if; + + -- Count the number of components and whether reordering is needed + + Comp := First_Component_Or_Discriminant (Ent); + Prev := Comp; + + while Present (Comp) loop + N_Comp := N_Comp + 1; + + if not Reorder then + Reorder := Is_Placed_Before (Comp, Prev); + end if; + + Prev := Comp; + Next_Component_Or_Discriminant (Comp); + end loop; + + -- Reorder the components, if need be, by directly reshuffling the + -- list of entities between First_Entity and Last_Entity, which is + -- safe because we are invoked after compilation is finished. + + if Reorder then + declare + Comps : array (Natural range 0 .. N_Comp) of Entity_Id; + -- Support array for the heapsort + + function Lt (Op1, Op2 : Natural) return Boolean is + (Is_Placed_Before (Comps (Op1), Comps (Op2))); + -- Compare function for the heapsort + + procedure Move (From : Natural; To : Natural); + pragma Inline (Move); + -- Move procedure for the heapsort + + ---------- + -- Move -- + ---------- + + procedure Move (From : Natural; To : Natural) is + begin + Comps (To) := Comps (From); + end Move; + + package HS is new GNAT.Heap_Sort_G (Lt => Lt, Move => Move); + -- The heapsort for record components + + begin + -- Pack the components into the array + + N_Comp := 0; + Comp := First_Component_Or_Discriminant (Ent); + + while Present (Comp) loop + N_Comp := N_Comp + 1; + Comps (N_Comp) := Comp; + + Next_Component_Or_Discriminant (Comp); + end loop; + + -- Sort the array + + HS.Sort (N_Comp); + + -- Unpack the component into the list of entities + + Set_First_Entity (Ent, Comps (1)); + Set_Prev_Entity (Comps (1), Empty); + for J in 1 .. N_Comp - 1 loop + Set_Next_Entity (Comps (J), Comps (J + 1)); + Set_Prev_Entity (Comps (J + 1), Comps (J)); + end loop; + Set_Next_Entity (Comps (N_Comp), Empty); + Set_Last_Entity (Ent, Comps (N_Comp)); + end; + end if; + + return First_Component_Or_Discriminant (Ent); + end First_Comp_Or_Discr; + + -- Local variables + + Bit_Offset : Uint := Uint_0; + Comp : Entity_Id; + First : Boolean := True; + + -- Start of processing for List_Record_Layout begin - Comp := First_Component_Or_Discriminant (Ent); + Comp := First_Comp_Or_Discr (Ent); while Present (Comp) loop -- Skip a completely hidden discriminant or a discriminant in an @@ -1251,69 +1376,98 @@ package body Repinfo is and then (Is_Completely_Hidden (Comp) or else Is_Unchecked_Union (Ent)) then - goto Continue; - end if; + null; -- Skip _Parent component in extension (to avoid overlap) - if Chars (Comp) = Name_uParent then - goto Continue; - end if; + elsif Chars (Comp) = Name_uParent then + null; -- All other cases - declare - Ctyp : constant Entity_Id := Underlying_Type (Etype (Comp)); - Npos : constant Uint := Normalized_Position (Comp); - Fbit : constant Uint := Normalized_First_Bit (Comp); - Spos : Uint; - Sbit : Uint; + else + declare + C : constant Entity_Id := + (if Known_Normalized_Position (Comp) + then Comp + else Original_Record_Component (Comp)); + -- The Parent_Subtype in an extension is not back-annotated + -- but its layout is the same as that of the parent type. - begin - Get_Decoded_Name_String (Chars (Comp)); - Set_Casing (Unit_Casing); + Ctyp : constant Entity_Id := Underlying_Type (Etype (C)); - -- If extended information is requested, recurse fully into - -- record components, i.e. skip the outer level. + begin + Get_Decoded_Name_String (Chars (C)); + Set_Casing (Unit_Casing); - if List_Representation_Info_Extended - and then Is_Record_Type (Ctyp) - and then Known_Static_Normalized_Position (Comp) - and then Known_Static_Normalized_First_Bit (Comp) - then - Spos := Starting_Position + Npos; - Sbit := Starting_First_Bit + Fbit; + -- If extended information is requested, recurse fully into + -- record components, i.e. skip the outer level. - if Sbit >= SSU then - Spos := Spos + 1; - Sbit := Sbit - SSU; - end if; + if List_Representation_Info_Extended + and then Is_Record_Type (Ctyp) + and then Known_Static_Normalized_Position (C) + and then Known_Static_Normalized_First_Bit (C) + then + declare + Npos : constant Uint := Normalized_Position (C); + Fbit : constant Uint := Normalized_First_Bit (C); + Pref : constant String := + Prefix & Name_Buffer (1 .. Name_Len) & "."; - List_Record_Layout (Ctyp, - Spos, Sbit, Prefix & Name_Buffer (1 .. Name_Len) & "."); + Spos : Uint; + Sbit : Uint; - goto Continue; - end if; + begin + Spos := Starting_Position + Npos; + Sbit := Starting_First_Bit + Fbit; + + if Sbit >= SSU then + Spos := Spos + 1; + Sbit := Sbit - SSU; + end if; + + List_Record_Layout (Ctyp, Spos, Sbit, Pref); + end; - if List_Representation_Info_To_JSON then - if First then - Write_Eol; - First := False; else - Write_Line (","); - end if; - end if; + if List_Representation_Info_To_JSON then + if First then + Write_Eol; + First := False; + else + Write_Line (","); + end if; + end if; - -- The Parent_Subtype in an extension is not back-annotated + -- If information about holes is requested, update the + -- current bit offset and report any (static) gap. - List_Component_Layout ( - (if Known_Normalized_Position (Comp) - then Comp - else Original_Record_Component (Comp)), - Starting_Position, Starting_First_Bit, Prefix); - end; + if List_Representation_Info_Holes + and then Known_Static_Component_Bit_Offset (C) + then + declare + Gap : constant Uint := + Component_Bit_Offset (C) - Bit_Offset; + begin + if Gap > Uint_0 then + Write_Str (" -- "); + UI_Write (Gap, Decimal); + Write_Line (" bits unused --"); + end if; + + if Known_Static_Esize (C) then + Bit_Offset := + Component_Bit_Offset (C) + Esize (C); + end if; + end; + end if; + + List_Component_Layout + (C, Starting_Position, Starting_First_Bit, Prefix); + end if; + end; + end if; - <<Continue>> Next_Component_Or_Discriminant (Comp); end loop; end List_Record_Layout; @@ -1624,6 +1778,17 @@ package body Repinfo is end loop; end List_Structural_Record_Layout; + -- Use the original record type giving the layout of components + -- to avoid repeated reordering when -gnatRh is specified. + + Rec : constant Entity_Id := + (if Ekind (Ent) = E_Record_Subtype + and then Present (Cloned_Subtype (Ent)) + then (if Is_Private_Type (Cloned_Subtype (Ent)) + then Full_View (Cloned_Subtype (Ent)) + else Cloned_Subtype (Ent)) + else Ent); + -- Start of processing for List_Record_Info begin @@ -1638,7 +1803,7 @@ package body Repinfo is -- First find out max line length and max starting position -- length, for the purpose of lining things up nicely. - Compute_Max_Length (Ent); + Compute_Max_Length (Rec); -- Then do actual output based on those values @@ -1650,21 +1815,21 @@ package body Repinfo is -- declared in the extended main source unit for the time being, -- because otherwise declarations might not be processed at all. - if Is_Base_Type (Ent) then + if Is_Base_Type (Rec) then begin - List_Structural_Record_Layout (Ent, Ent); + List_Structural_Record_Layout (Rec, Rec); exception when Incomplete_Layout | Not_In_Extended_Main => - List_Record_Layout (Ent); + List_Record_Layout (Rec); when others => raise Program_Error; end; else - List_Record_Layout (Ent); + List_Record_Layout (Rec); end if; Write_Eol; @@ -1674,7 +1839,7 @@ package body Repinfo is List_Name (Ent); Write_Line (" use record"); - List_Record_Layout (Ent); + List_Record_Layout (Rec); Write_Line ("end record;"); end if; diff --git a/gcc/ada/rtsfind.adb b/gcc/ada/rtsfind.adb index 70a6f1201e6d..86713ff955ab 100644 --- a/gcc/ada/rtsfind.adb +++ b/gcc/ada/rtsfind.adb @@ -566,11 +566,11 @@ package body Rtsfind is subtype Ada_Numerics_Descendant is Ada_Descendant range Ada_Numerics_Big_Numbers .. - Ada_Numerics_Big_Numbers_Big_Integers_Ghost; + Ada_Numerics_Big_Numbers_Big_Integers; subtype Ada_Numerics_Big_Numbers_Descendant is Ada_Descendant range Ada_Numerics_Big_Numbers_Big_Integers .. - Ada_Numerics_Big_Numbers_Big_Integers_Ghost; + Ada_Numerics_Big_Numbers_Big_Integers; subtype Ada_Real_Time_Descendant is Ada_Descendant range Ada_Real_Time_Delays .. Ada_Real_Time_Timing_Events; diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads index d57d4faeb124..37ed22b1c87d 100644 --- a/gcc/ada/rtsfind.ads +++ b/gcc/ada/rtsfind.ads @@ -121,7 +121,6 @@ package Rtsfind is -- Children of Ada.Numerics.Big_Numbers Ada_Numerics_Big_Numbers_Big_Integers, - Ada_Numerics_Big_Numbers_Big_Integers_Ghost, -- Children of Ada.Real_Time @@ -582,7 +581,6 @@ package Rtsfind is RE_Reference, -- Ada.Interrupts RE_Big_Integer, -- Ada.Numerics.Big_Numbers.Big_Integers - RO_GH_Big_Integer, -- Ada.Numerics.Big_Numbers.Big_Integers_Ghost RO_SP_Big_Integer, -- SPARK.Big_Integers RE_Names, -- Ada.Interrupts.Names @@ -2231,7 +2229,6 @@ package Rtsfind is RE_Reference => Ada_Interrupts, RE_Big_Integer => Ada_Numerics_Big_Numbers_Big_Integers, - RO_GH_Big_Integer => Ada_Numerics_Big_Numbers_Big_Integers_Ghost, RO_SP_Big_Integer => SPARK_Big_Integers, RE_Names => Ada_Interrupts_Names, diff --git a/gcc/ada/scos.ads b/gcc/ada/scos.ads index a2ade8a0907a..b5f39c9632e3 100644 --- a/gcc/ada/scos.ads +++ b/gcc/ada/scos.ads @@ -28,9 +28,6 @@ -- the ALI file, and by Get_SCO/Put_SCO to read and write the text form that -- is used in the ALI file. --- WARNING: There is a C version of this package. Any changes to this --- source file must be properly reflected in the C header file scos.h - with Namet; use Namet; with Table; with Types; use Types; diff --git a/gcc/ada/scos.h b/gcc/ada/scos.h deleted file mode 100644 index 3d800bf12b15..000000000000 --- a/gcc/ada/scos.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** - * * - * GNAT COMPILER COMPONENTS * - * * - * S C O S * - * * - * C Header File * - * * - * Copyright (C) 2014-2025, Free Software Foundation, Inc. * - * * - * GNAT is free software; you can redistribute it and/or modify it under * - * terms of the GNU General Public License as published by the Free Soft- * - * ware Foundation; either version 3, or (at your option) any later ver- * - * sion. GNAT is distributed in the hope that it will be useful, but WITH- * - * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * - * for more details. You should have received a copy of the GNU General * - * Public License distributed with GNAT; see file COPYING3. If not, go to * - * http://www.gnu.org/licenses for a complete copy of the license. * - * * - * GNAT was originally developed by the GNAT team at New York University. * - * Extensive contributions were provided by Ada Core Technologies Inc. * - * * - ****************************************************************************/ - -/* This is the C header that corresponds to the Ada package specification for - Scos. It was created manually from scos.ads and must be kept synchronized - with changes in this file. */ - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Unit table: */ - -typedef Int SCO_Unit_Index; - -struct SCO_Unit_Table_Entry - { - String_Pointer File_Name; - Int File_Index; - Nat Dep_Num; - Nat From, To; - }; - -typedef struct SCO_Unit_Table_Entry *SCO_Unit_Table_Type; - -extern SCO_Unit_Table_Type scos__sco_unit_table__table; -#define SCO_Unit_Table scos__sco_unit_table__table - -extern Int scos__sco_unit_table__min; -#define SCO_Unit_Table_Min scos__sco_unit_table__min - -extern Int scos__sco_unit_table__last_val; -#define SCO_Unit_Table_Last_Val scos__sco_unit_table__last_val - - -/* SCOs table: */ - -struct Source_Location - { - Line_Number_Type Line; - Column_Number_Type Col; - }; - -struct SCO_Table_Entry - { - struct Source_Location From, To; - char C1, C2; - bool Last; - Source_Ptr Pragma_Sloc; - Name_Id Pragma_Aspect_Name; - }; - -typedef struct SCO_Table_Entry *SCO_Table_Type; - -extern SCO_Table_Type scos__sco_table__table; -#define SCO_Table scos__sco_table__table - -extern Int scos__sco_table__min; -#define SCO_Table_Min scos__sco_table__min - -extern Int scos__sco_table__last_val; -#define SCO_Table_Last_Val scos__sco_table__last_val - -#ifdef __cplusplus -} -#endif diff --git a/gcc/ada/sem.adb b/gcc/ada/sem.adb index 06df00ec8718..e168d62eafbb 100644 --- a/gcc/ada/sem.adb +++ b/gcc/ada/sem.adb @@ -192,6 +192,9 @@ package body Sem is when N_Conditional_Entry_Call => Analyze_Conditional_Entry_Call (N); + when N_Continue_Statement => + Analyze_Continue_Statement (N); + when N_Delay_Alternative => Analyze_Delay_Alternative (N); @@ -765,12 +768,11 @@ package body Sem is E : constant Entity_Id := Defining_Entity_Or_Empty (N); begin if Present (E) then - if Ekind (E) = E_Void - and then Nkind (N) = N_Component_Declaration + if Nkind (N) = N_Component_Declaration and then Present (Scope (E)) and then Ekind (Scope (E)) = E_Record_Type then - null; -- Set it later, in Analyze_Component_Declaration + null; -- Set it later, in Record_Type_Definition elsif not Is_Not_Self_Hidden (E) then Set_Is_Not_Self_Hidden (E); end if; @@ -1399,7 +1401,6 @@ package body Sem is Prev => Global_Suppress_Stack_Top, Next => Suppress_Stack_Entries); Suppress_Stack_Entries := Global_Suppress_Stack_Top; - return; end Push_Global_Suppress_Stack_Entry; ------------------------------------- @@ -1420,8 +1421,6 @@ package body Sem is Prev => Local_Suppress_Stack_Top, Next => Suppress_Stack_Entries); Suppress_Stack_Entries := Local_Suppress_Stack_Top; - - return; end Push_Local_Suppress_Stack_Entry; --------------- diff --git a/gcc/ada/sem.ads b/gcc/ada/sem.ads index f8a67a9a746f..611309775279 100644 --- a/gcc/ada/sem.ads +++ b/gcc/ada/sem.ads @@ -109,7 +109,7 @@ -- pragmas that appear with subprogram specifications rather than in the body. -- Collectively we call these Spec_Expressions. The routine that performs the --- special analysis is called Preanalyze_Spec_Expression. +-- special analysis is called Preanalyze_And_Resolve_Spec_Expression. -- Expansion has to be deferred since you can't generate code for expressions -- that reference types that have not been frozen yet. As an example, consider @@ -198,11 +198,11 @@ -- strict preanalysis of other expressions is that we do carry out freezing -- in the former (for static scalar expressions) but not in the latter. The -- routine that performs preanalysis of default expressions is called --- Preanalyze_Spec_Expression and is in Sem_Ch3. The routine that performs --- strict preanalysis and corresponding resolution is in Sem_Res and it is --- called Preanalyze_And_Resolve. Preanalyze_Spec_Expression relaxes the --- strictness of Preanalyze_And_Resolve setting to True the global boolean --- variable In_Spec_Expression before calling Preanalyze_And_Resolve. +-- Preanalyze_And_Resolve_Spec_Expression and is in Sem_Ch3. The routine that +-- performs strict preanalysis and corresponding resolution is in Sem_Res and +-- it is called Preanalyze_And_Resolve. Preanalyze_And_Resolve_Spec_Expression +-- relaxes the strictness of Preanalyze_And_Resolve setting to True the global +-- boolean variable In_Spec_Expression before calling Preanalyze_And_Resolve. with Alloc; with Einfo.Entities; use Einfo.Entities; diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb index a7ec772823f6..58460b8e3bb8 100644 --- a/gcc/ada/sem_aggr.adb +++ b/gcc/ada/sem_aggr.adb @@ -26,11 +26,10 @@ with Aspects; use Aspects; with Atree; use Atree; with Checks; use Checks; -with Debug; use Debug; -with Diagnostics.Constructors; use Diagnostics.Constructors; with Einfo; use Einfo; with Einfo.Utils; use Einfo.Utils; with Elists; use Elists; +with Errid; use Errid; with Errout; use Errout; with Expander; use Expander; with Exp_Tss; use Exp_Tss; @@ -4038,22 +4037,25 @@ package body Sem_Aggr is if Present (First (Expressions (N))) and then Present (First (Component_Associations (N))) then - if Debug_Flag_Underscore_DD then - Record_Mixed_Container_Aggregate_Error - (Aggr => N, - Pos_Elem => First (Expressions (N)), - Named_Elem => First (Component_Associations (N))); - else - Error_Msg_N - ("container aggregate cannot be both positional and named", N); - end if; + Error_Msg_N + (Msg => + "container aggregate cannot be both positional and named", + N => N, + Error_Code => GNAT0006, + Spans => + (1 => + Secondary_Labeled_Span + (First (Expressions (N)), "positional element "), + 2 => + Secondary_Labeled_Span + (First (Component_Associations (N)), "named element"))); return; end if; if Present (Add_Unnamed_Subp) and then No (New_Indexed_Subp) - and then Present (Etype (Add_Unnamed_Subp)) - and then Etype (Add_Unnamed_Subp) /= Any_Type + and then Present (Entity (Add_Unnamed_Subp)) + and then Entity (Add_Unnamed_Subp) /= Any_Id then declare Elmt_Type : constant Entity_Id := @@ -4099,7 +4101,8 @@ package body Sem_Aggr is end; elsif Present (Add_Named_Subp) - and then Etype (Add_Named_Subp) /= Any_Type + and then Present (Entity (Add_Named_Subp)) + and then Entity (Add_Named_Subp) /= Any_Id then declare -- Retrieves types of container, key, and element from the @@ -4153,7 +4156,8 @@ package body Sem_Aggr is end; elsif Present (Assign_Indexed_Subp) - and then Etype (Assign_Indexed_Subp) /= Any_Type + and then Present (Entity (Assign_Indexed_Subp)) + and then Entity (Assign_Indexed_Subp) /= Any_Id then -- Indexed Aggregate. Positional or indexed component -- can be present, but not both. Choices must be static @@ -6351,7 +6355,12 @@ package body Sem_Aggr is & "has unknown discriminants", N, Typ); end if; - if Has_Unknown_Discriminants (Typ) + -- Mutably tagged class-wide types do not have discriminants; + -- however, all class-wide types are considered to have unknown + -- discriminants. + + if not Is_Mutably_Tagged_Type (Typ) + and then Has_Unknown_Discriminants (Typ) and then Present (Underlying_Record_View (Typ)) then Discrim := First_Discriminant (Underlying_Record_View (Typ)); @@ -6423,7 +6432,13 @@ package body Sem_Aggr is -- STEP 4: Set the Etype of the record aggregate if Has_Discriminants (Typ) - or else (Has_Unknown_Discriminants (Typ) + + -- Handle types with unknown discriminants, excluding mutably tagged + -- class-wide types because, although they do not have discriminants, + -- all class-wide types are considered to have unknown discriminants. + + or else (not Is_Mutably_Tagged_Type (Typ) + and then Has_Unknown_Discriminants (Typ) and then Present (Underlying_Record_View (Typ))) then Build_Constrained_Itype (N, Typ, New_Assoc_List); @@ -6594,7 +6609,13 @@ package body Sem_Aggr is if Null_Present (Record_Def) then null; - elsif not Has_Unknown_Discriminants (Typ) then + -- Explicitly add here mutably class-wide types because they do + -- not have discriminants; however, all class-wide types are + -- considered to have unknown discriminants. + + elsif not Has_Unknown_Discriminants (Typ) + or else Is_Mutably_Tagged_Type (Typ) + then Gather_Components (Base_Type (Typ), Component_List (Record_Def), @@ -6780,6 +6801,11 @@ package body Sem_Aggr is Set_Has_Self_Reference (N); elsif Needs_Simple_Initialization (Ctyp) + + -- Mutably tagged class-wide type components are initialized + -- by the expander calling their IP subprogram. + + or else Is_Mutably_Tagged_CW_Equivalent_Type (Ctyp) or else Has_Non_Null_Base_Init_Proc (Ctyp) or else not Expander_Active then @@ -6984,6 +7010,30 @@ package body Sem_Aggr is -- Check the dimensions of the components in the record aggregate Analyze_Dimension_Extension_Or_Record_Aggregate (N); + + -- Do a pass for constructors which rely on things being fully expanded + + declare + function Resolve_Make_Expr (N : Node_Id) return Traverse_Result; + -- Recurse in the aggregate and resolve references to 'Make + + function Resolve_Make_Expr (N : Node_Id) return Traverse_Result is + begin + if Nkind (N) = N_Attribute_Reference + and then Attribute_Name (N) = Name_Make + then + Set_Analyzed (N, False); + Resolve (N); + end if; + + return OK; + end Resolve_Make_Expr; + + procedure Search_And_Resolve_Make_Expr is new + Traverse_Proc (Resolve_Make_Expr); + begin + Search_And_Resolve_Make_Expr (N); + end; end Resolve_Record_Aggregate; ----------------------------- diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb index af08fdb2e33f..f38380c381f6 100644 --- a/gcc/ada/sem_attr.adb +++ b/gcc/ada/sem_attr.adb @@ -1448,9 +1448,10 @@ package body Sem_Attr is null; -- Attribute 'Result is allowed to appear in aspect - -- Relaxed_Initialization (SPARK RM 6.10). + -- Relaxed_Initialization (SPARK RM 6.10) and Potentially_Invalid. - elsif Prag_Nam = Name_Relaxed_Initialization + elsif (Prag_Nam = Name_Relaxed_Initialization + or else Prag_Nam = Name_Potentially_Invalid) and then Aname = Name_Result then null; @@ -1462,6 +1463,13 @@ package body Sem_Attr is then null; + -- Attribute 'Old is allowed to appear in Program_Exit + + elsif Prag_Nam = Name_Program_Exit + and then Aname = Name_Old + then + null; + elsif Prag_Nam = Name_Test_Case then Check_Placement_In_Test_Case (Prag); @@ -3317,7 +3325,7 @@ package body Sem_Attr is E1 := Empty; E2 := Empty; - else + elsif Aname /= Name_Make then E1 := First (Exprs); -- Skip analysis for case of Restriction_Set, we do not expect @@ -5164,6 +5172,36 @@ package body Sem_Attr is Check_Not_Incomplete_Type; Set_Etype (N, Universal_Integer); + ---------- + -- Make -- + ---------- + + when Attribute_Make => declare + Expr : Entity_Id; + begin + -- Should this be assert? Parsing should fail if it hits 'Make + -- and all extensions aren't enabled ??? + + if not All_Extensions_Allowed then + return; + end if; + + Set_Etype (N, Etype (P)); + + if Present (Expressions (N)) then + Expr := First (Expressions (N)); + while Present (Expr) loop + if Nkind (Expr) = N_Parameter_Association then + Analyze (Explicit_Actual_Parameter (Expr)); + else + Analyze (Expr); + end if; + + Next (Expr); + end loop; + end if; + end; + -------------- -- Mantissa -- -------------- @@ -5656,19 +5694,15 @@ package body Sem_Attr is when Attribute_Partition_ID => Check_E0; - if P_Type /= Any_Type then - if not Is_Library_Level_Entity (Entity (P)) then - Error_Attr_P - ("prefix of % attribute must be library-level entity"); + if not Is_Library_Level_Entity (Entity (P)) then + Error_Attr_P + ("prefix of % attribute must be library-level entity"); - -- The defining entity of prefix should not be declared inside a - -- Pure unit. RM E.1(8). Is_Pure was set during declaration. + -- The defining entity of prefix should not be declared inside a + -- Pure unit. RM E.1(8). Is_Pure was set during declaration. - elsif Is_Entity_Name (P) - and then Is_Pure (Entity (P)) - then - Error_Attr_P ("prefix of% attribute must not be declared pure"); - end if; + elsif Is_Entity_Name (P) and then Is_Pure (Entity (P)) then + Error_Attr_P ("prefix of% attribute must not be declared pure"); end if; Set_Etype (N, Universal_Integer); @@ -7511,13 +7545,14 @@ package body Sem_Attr is Set_Etype (N, Standard_Boolean); Validate_Non_Static_Attribute_Function_Call; - if P_Type in Standard_Boolean + if Root_Type (P_Type) in Standard_Boolean | Standard_Character | Standard_Wide_Character | Standard_Wide_Wide_Character then Error_Attr_P - ("prefix of % attribute must not be a type in Standard"); + ("prefix of % attribute must not be a type originating from " & + "Standard"); end if; if Discard_Names (First_Subtype (P_Type)) then @@ -7732,7 +7767,6 @@ package body Sem_Attr is when Bad_Attribute => Set_Analyzed (N); Set_Etype (N, Any_Type); - return; end Analyze_Attribute; -------------------- @@ -8712,6 +8746,13 @@ package body Sem_Attr is Set_Etype (N, C_Type); return; + -- Handle 'Make constructor calls + + elsif All_Extensions_Allowed + and then Id = Attribute_Make + then + P_Type := P_Entity; + -- No other cases are foldable (they certainly aren't static, and at -- the moment we don't try to fold any cases other than the ones above). @@ -8723,9 +8764,10 @@ package body Sem_Attr is -- If either attribute or the prefix is Any_Type, then propagate -- Any_Type to the result and don't do anything else at all. - if P_Type = Any_Type + if Id /= Attribute_Make + and then (P_Type = Any_Type or else (Present (E1) and then Etype (E1) = Any_Type) - or else (Present (E2) and then Etype (E2) = Any_Type) + or else (Present (E2) and then Etype (E2) = Any_Type)) then Set_Etype (N, Any_Type); return; @@ -8838,7 +8880,9 @@ package body Sem_Attr is Static := False; Set_Is_Static_Expression (N, False); - elsif Id /= Attribute_Max_Alignment_For_Allocation then + elsif Id not in Attribute_Max_Alignment_For_Allocation + | Attribute_Make + then if not Is_Constrained (P_Type) or else (Id /= Attribute_First and then Id /= Attribute_Last and then @@ -8914,53 +8958,55 @@ package body Sem_Attr is -- of the expressions to be scalar in order for the attribute to be -- considered to be static. - declare - E : Node_Id; + if Id /= Attribute_Make then + declare + E : Node_Id; - begin - E := E1; + begin + E := E1; - while Present (E) loop + while Present (E) loop - -- If expression is not static, then the attribute reference - -- result certainly cannot be static. + -- If expression is not static, then the attribute reference + -- result certainly cannot be static. - if not Is_Static_Expression (E) then - Static := False; - Set_Is_Static_Expression (N, False); - end if; + if not Is_Static_Expression (E) then + Static := False; + Set_Is_Static_Expression (N, False); + end if; - if Raises_Constraint_Error (E) then - Set_Raises_Constraint_Error (N); - end if; + if Raises_Constraint_Error (E) then + Set_Raises_Constraint_Error (N); + end if; - -- If the result is not known at compile time, or is not of - -- a scalar type, then the result is definitely not static, - -- so we can quit now. + -- If the result is not known at compile time, or is not of + -- a scalar type, then the result is definitely not static, + -- so we can quit now. - if not Compile_Time_Known_Value (E) - or else not Is_Scalar_Type (Etype (E)) - then - Check_Expressions; - return; + if not Compile_Time_Known_Value (E) + or else not Is_Scalar_Type (Etype (E)) + then + Check_Expressions; + return; - -- If the expression raises a constraint error, then so does - -- the attribute reference. We keep going in this case because - -- we are still interested in whether the attribute reference - -- is static even if it is not static. + -- If the expression raises a constraint error, then so does + -- the attribute reference. We keep going in this case because + -- we are still interested in whether the attribute reference + -- is static even if it is not static. - elsif Raises_Constraint_Error (E) then - Set_Raises_Constraint_Error (N); - end if; + elsif Raises_Constraint_Error (E) then + Set_Raises_Constraint_Error (N); + end if; - Next (E); - end loop; + Next (E); + end loop; - if Raises_Constraint_Error (Prefix (N)) then - Set_Is_Static_Expression (N, False); - return; - end if; - end; + if Raises_Constraint_Error (Prefix (N)) then + Set_Is_Static_Expression (N, False); + return; + end if; + end; + end if; -- Deal with the case of a static attribute reference that raises -- constraint error. The Raises_Constraint_Error flag will already @@ -9313,6 +9359,20 @@ package body Sem_Attr is when Attribute_First => Set_Bounds; + -- In GNATprove mode we only fold array attributes when prefix is + -- static (because that's required by the Ada rules) or at least can + -- be evaluated without checks (because GNATprove would miss them). + + if GNATprove_Mode + and then + not (Static + or else (Is_Entity_Name (P) and then Is_Type (Entity (P))) + or else Statically_Names_Object (P) + or else Ekind (P_Type) = E_String_Literal_Subtype) + then + return; + end if; + if Compile_Time_Known_Value (Lo_Bound) then if Is_Real_Type (P_Type) then Fold_Ureal (N, Expr_Value_R (Lo_Bound), Static); @@ -9526,6 +9586,20 @@ package body Sem_Attr is when Attribute_Last => Set_Bounds; + -- In GNATprove mode we only fold array attributes when prefix is + -- static (because that's required by the Ada rules) or at least can + -- be evaluated without checks (because GNATprove would miss them). + + if GNATprove_Mode + and then + not (Static + or else (Is_Entity_Name (P) and then Is_Type (Entity (P))) + or else Statically_Names_Object (P) + or else Ekind (P_Type) = E_String_Literal_Subtype) + then + return; + end if; + if Compile_Time_Known_Value (Hi_Bound) then if Is_Real_Type (P_Type) then Fold_Ureal (N, Expr_Value_R (Hi_Bound), Static); @@ -9609,6 +9683,20 @@ package body Sem_Attr is Set_Bounds; + -- In GNATprove mode we only fold array attributes when prefix is + -- static (because that's required by the Ada rules) or at least can + -- be evaluated without checks (because GNATprove would miss them). + + if GNATprove_Mode + and then + not (Static + or else (Is_Entity_Name (P) and then Is_Type (Entity (P))) + or else Statically_Names_Object (P) + or else Ekind (P_Type) = E_String_Literal_Subtype) + then + return; + end if; + -- For two compile time values, we can compute length if Compile_Time_Known_Value (Lo_Bound) @@ -9778,6 +9866,13 @@ package body Sem_Attr is end if; end Machine_Size; + ---------- + -- Make -- + ---------- + + when Attribute_Make => + Set_Etype (N, Etype (Prefix (N))); + -------------- -- Mantissa -- -------------- @@ -11095,7 +11190,9 @@ package body Sem_Attr is -- If this is still an attribute reference, then it has not been folded -- and that means that its expressions are in a non-static context. - elsif Nkind (N) = N_Attribute_Reference then + elsif Nkind (N) = N_Attribute_Reference + and then Attribute_Name (N) /= Name_Make + then Check_Expressions; -- Note: the else case not covered here are odd cases where the @@ -12959,7 +13056,7 @@ package body Sem_Attr is -- their Entity attribute to reference their discriminal. if Expander_Active - and then Present (Expressions (N)) + and then Attr_Id /= Attribute_Make then declare Expr : Node_Id := First (Expressions (N)); diff --git a/gcc/ada/sem_attr.ads b/gcc/ada/sem_attr.ads index 8208048d8137..1c54370316ef 100644 --- a/gcc/ada/sem_attr.ads +++ b/gcc/ada/sem_attr.ads @@ -319,6 +319,12 @@ package Sem_Attr is -- This attribute is identical to the Object_Size attribute. It is -- provided for compatibility with the DEC attribute of this name. + ---------- + -- Make -- + ---------- + + Attribute_Make => True, + ---------------------- -- Max_Integer_Size -- ---------------------- diff --git a/gcc/ada/sem_aux.adb b/gcc/ada/sem_aux.adb index bb1624da5b74..0aa74e39050a 100644 --- a/gcc/ada/sem_aux.adb +++ b/gcc/ada/sem_aux.adb @@ -25,7 +25,6 @@ with Atree; use Atree; with Einfo; use Einfo; -with Einfo.Entities; use Einfo.Entities; with Einfo.Utils; use Einfo.Utils; with Nlists; use Nlists; with Sinfo; use Sinfo; @@ -454,16 +453,28 @@ package body Sem_Aux is Id : Entity_Id; begin + -- Call using access to subprogram with explicit dereference + if Nkind (Nam) = N_Explicit_Dereference then Id := Etype (Nam); pragma Assert (Ekind (Id) = E_Subprogram_Type); + -- Case of call to simple entry, where the Name is a selected component + -- whose prefix is the task or protected record, and whose selector name + -- is the entry name. + elsif Nkind (Nam) = N_Selected_Component then Id := Entity (Selector_Name (Nam)); + -- Case of call to member of entry family, where Name is an indexed + -- component, with the prefix being a selected component giving the + -- task and entry family name, and the index being the entry index. + elsif Nkind (Nam) = N_Indexed_Component then Id := Entity (Selector_Name (Prefix (Nam))); + -- Normal case + else Id := Entity (Nam); end if; @@ -1546,6 +1557,81 @@ package body Sem_Aux is return E; end Ultimate_Alias; + --------------------------- + -- Unique_Component_Name -- + --------------------------- + + function Unique_Component_Name + (Component : Record_Field_Kind_Id) return Name_Id + is + Homographic_Component_Count : Pos := 1; + Hcc : Pos renames Homographic_Component_Count; + Enclosing_Type : Entity_Id := + Underlying_Type (Base_Type (Scope (Component))); + begin + if Ekind (Enclosing_Type) = E_Record_Type + and then Is_Tagged_Type (Enclosing_Type) + and then Has_Private_Ancestor (Enclosing_Type) + then + -- traverse ancestors to determine Hcc value + loop + declare + Type_Decl : constant Node_Id := + Parent (Underlying_Type (Base_Type (Enclosing_Type))); + Type_Def : constant Node_Id := Type_Definition (Type_Decl); + begin + exit when Nkind (Type_Def) /= N_Derived_Type_Definition; + Enclosing_Type := + Underlying_Type (Base_Type (Etype (Enclosing_Type))); + + declare + Ancestor_Comp : Opt_Record_Field_Kind_Id := + First_Component_Or_Discriminant (Enclosing_Type); + begin + while Present (Ancestor_Comp) loop + if Chars (Ancestor_Comp) = Chars (Component) then + Hcc := Hcc + 1; + exit; -- exit not required, but might as well + end if; + Next_Component_Or_Discriminant (Ancestor_Comp); + end loop; + end; + end; + end loop; + end if; + + if Hcc = 1 then + -- the usual case + return Chars (Component); + else + declare + Buff : Bounded_String; + begin + Append (Buff, Chars (Component)); + + Append (Buff, "__"); + -- A double underscore in an identifier is legal in C, not in Ada. + -- Returning a result that is not a legal Ada identifier + -- ensures that we won't have problems with collisions. + -- If we have a component named Foo and we just append a + -- number (without any underscores), that new name might match + -- the name of another component (which would be bad). + -- The result of this function is intended for use as an + -- identifier in generated C code, so it needs to be a + -- legal C identifer. + + Append (Buff, Hcc); + -- Should we instead append Hcc - 1 here? This is a human + -- readability question. If parent type and extension each + -- have a Foo component, do we want the name returned for the + -- second Foo to be "foo__2" or "foo__1" ? Does it matter? + -- Either way, the name returned for the first Foo will be "foo". + + return Name_Find (Buff); + end; + end if; + end Unique_Component_Name; + -------------------------- -- Unit_Declaration_Node -- -------------------------- diff --git a/gcc/ada/sem_aux.ads b/gcc/ada/sem_aux.ads index 5a6300281d7c..1a298a9a33fb 100644 --- a/gcc/ada/sem_aux.ads +++ b/gcc/ada/sem_aux.ads @@ -31,6 +31,7 @@ -- require more than minimal semantic knowledge. with Alloc; +with Einfo.Entities; use Einfo.Entities; with Namet; use Namet; with Table; with Types; use Types; @@ -105,7 +106,7 @@ package Sem_Aux is -- this is equivalent to First_Entity. The exception arises for tagged -- types, where the tag itself is prepended to the front of the entity -- chain, so the First_Discriminant function steps past the tag if it is - -- present. When called on a private type with unknown discriminants, the + -- present. When called on a private type with unknown discriminants, the -- function always returns Empty. -- WARNING: There is a matching C declaration of this subprogram in fe.h @@ -405,6 +406,19 @@ package Sem_Aux is -- Return the last entity in the chain of aliased entities of Prim. If Prim -- has no alias return Prim. + function Unique_Component_Name + (Component : Record_Field_Kind_Id) return Name_Id; + -- Usually, a record type cannot have two components with the same name. + -- But in the case of a component declared in an extension of a tagged + -- private (or private extension) parent type, it is possible that some + -- ancestor type also has a (non-visible) component with the same name. + -- In the common case, this function simply returns the Chars attribute + -- of its argument. + -- But in the multiple-components-with-the-same-name case, it appends + -- a uniquifying suffix. The result in this case will not be a + -- syntactically valid Ada identifier, but it will be a syntactically + -- valid C identifier. + function Unit_Declaration_Node (Unit_Id : Entity_Id) return Node_Id; -- Unit_Id is the simple name of a program unit, this function returns the -- corresponding xxx_Declaration node for the entity. Also applies to the diff --git a/gcc/ada/sem_case.adb b/gcc/ada/sem_case.adb index 3399a41343e8..c81b56337f6a 100644 --- a/gcc/ada/sem_case.adb +++ b/gcc/ada/sem_case.adb @@ -3684,13 +3684,15 @@ package body Sem_Case is -- Use of nonstatic predicate is an error if not Is_Discrete_Type (E) - or else not Has_Static_Predicate (E) + or else (not Has_Static_Predicate (E) + and then + not Has_Static_Predicate_Aspect (E)) or else Has_Dynamic_Predicate_Aspect (E) or else Has_Ghost_Predicate_Aspect (E) then Bad_Predicated_Subtype_Use - ("cannot use subtype& with non-static " - & "predicate as case alternative", + ("cannot use subtype& with nonstatic " + & "predicate as choice in case alternative", Choice, E, Suggest_Static => True); -- Static predicate case. The bounds are those of diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb index de5a8c846ba7..f58513d115fb 100644 --- a/gcc/ada/sem_ch10.adb +++ b/gcc/ada/sem_ch10.adb @@ -123,15 +123,6 @@ package body Sem_Ch10 is -- Verify that a stub is declared immediately within a compilation unit, -- and not in an inner frame. - procedure Expand_With_Clause (Item : Node_Id; Nam : Node_Id; N : Node_Id); - -- When a child unit appears in a context clause, the implicit withs on - -- parents are made explicit, and with clauses are inserted in the context - -- clause before the one for the child. If a parent in the with_clause - -- is a renaming, the implicit with_clause is on the renaming whose name - -- is mentioned in the with_clause, and not on the package it renames. - -- N is the compilation unit whose list of context items receives the - -- implicit with_clauses. - procedure Generate_Parent_References (N : Node_Id; P_Id : Entity_Id); -- Generate cross-reference information for the parents of child units -- and of subunits. N is a defining_program_unit_name, and P_Id is the @@ -1234,9 +1225,15 @@ package body Sem_Ch10 is if Expander_Active and then Tagged_Type_Expansion then case Nkind (Unit_Node) is - when N_Package_Declaration | N_Package_Body => + when N_Package_Declaration => Build_Static_Dispatch_Tables (Unit_Node); + when N_Package_Body => + if Ekind (Corresponding_Spec (Unit_Node)) /= E_Generic_Package + then + Build_Static_Dispatch_Tables (Unit_Node); + end if; + when N_Package_Instantiation => Build_Static_Dispatch_Tables (Instance_Spec (Unit_Node)); @@ -1494,6 +1491,10 @@ package body Sem_Ch10 is -- No checks required if no separate spec or else Acts_As_Spec (N) + + -- No checked needed for ignored ghost units + + or else Is_Ignored_Ghost_Entity (Spec_Id) ) then -- This is a case where we only need the entity for checking to @@ -2955,6 +2956,7 @@ package body Sem_Ch10 is if Ada_Version >= Ada_95 and then In_Predefined_Renaming (U) + and then Comes_From_Source (N) then if Restriction_Check_Required (No_Obsolescent_Features) then Check_Restriction (No_Obsolescent_Features, N); @@ -3297,7 +3299,7 @@ package body Sem_Ch10 is -- the renamed unit, and the renaming declaration itself has not -- been analyzed. - Analyze (Parent (Parent (Entity (Pref)))); + Semantics (Parent (Parent (Entity (Pref)))); pragma Assert (Renamed_Entity (Entity (Pref)) = Par_Name); Par_Name := Entity (Pref); end if; @@ -4932,6 +4934,8 @@ package body Sem_Ch10 is if Entity (Name (Clause)) = Id or else (Nkind (Name (Clause)) = N_Expanded_Name + and then + Is_Entity_Name (Prefix (Name (Clause))) and then Entity (Prefix (Name (Clause))) = Id) then return True; diff --git a/gcc/ada/sem_ch10.ads b/gcc/ada/sem_ch10.ads index c80c41295064..9585785f10a6 100644 --- a/gcc/ada/sem_ch10.ads +++ b/gcc/ada/sem_ch10.ads @@ -45,6 +45,15 @@ package Sem_Ch10 is -- set when Ent is a tagged type and its class-wide type needs to appear -- in the tree. + procedure Expand_With_Clause (Item : Node_Id; Nam : Node_Id; N : Node_Id); + -- When a child unit appears in a context clause, the implicit withs on + -- parents are made explicit, and with clauses are inserted in the context + -- clause before the one for the child. If a parent in the with_clause + -- is a renaming, the implicit with_clause is on the renaming whose name + -- is mentioned in the with_clause, and not on the package it renames. + -- N is the compilation unit whose list of context items receives the + -- implicit with_clauses. + procedure Install_Context (N : Node_Id; Chain : Boolean := True); -- Installs the entities from the context clause of the given compilation -- unit into the visibility chains. This is done before analyzing a unit. diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb index 5768e28e90fc..1cb9d115cc58 100644 --- a/gcc/ada/sem_ch12.adb +++ b/gcc/ada/sem_ch12.adb @@ -276,6 +276,7 @@ package body Sem_Ch12 is -- Pre -- Pre_Class -- Precondition + -- Program_Exit -- Refined_Depends -- Refined_Global -- Refined_Post @@ -478,18 +479,19 @@ package body Sem_Ch12 is -- Create a new access type with the given designated type function Analyze_Associations - (I_Node : Node_Id; + (N : Node_Id; Formals : List_Id; F_Copy : List_Id) return List_Id; -- At instantiation time, build the list of associations between formals -- and actuals. Each association becomes a renaming declaration for the - -- formal entity. F_Copy is the analyzed list of formals in the generic - -- copy. It is used to apply legality checks to the actuals. I_Node is the - -- instantiation node. + -- formal entity. N is the instantiation node. Formals is the list of + -- unanalyzed formals. F_Copy is the analyzed list of formals in the + -- generic copy. procedure Analyze_Subprogram_Instantiation (N : Node_Id; K : Entity_Kind); + -- Analyze subprogram instantiation N, either a function or a procedure procedure Build_Instance_Compilation_Unit_Nodes (N : Node_Id; @@ -608,12 +610,12 @@ package body Sem_Ch12 is (Inner : Entity_Id; Outer : Entity_Id; N : Node_Id) return Boolean; - -- Inner is instantiated within the generic Outer. Check whether Inner - -- directly or indirectly contains an instance of Outer or of one of its - -- parents, in the case of a subunit. Each generic unit holds a list of - -- the entities instantiated within (at any depth). This procedure - -- determines whether the set of such lists contains a cycle, i.e. an - -- illegal circular instantiation. + -- Inner is being instantiated within Outer. If Outer is also a generic + -- unit, check whether Inner directly or indirectly contains an instance + -- of Outer or of one of its parents (case of subunit). Each generic unit + -- holds a list of the entities instantiated within (at any depth). This + -- procedure determines whether the set of such lists contains a cycle, + -- i.e. an illegal circular instantiation. function Denotes_Formal_Package (Pack : Entity_Id; @@ -1008,8 +1010,8 @@ package body Sem_Ch12 is procedure Set_Next_Assoc (E : Assoc_Ptr; Next : Assoc_Ptr); function Next_Assoc (E : Assoc_Ptr) return Assoc_Ptr; - function Get_Gen_Id (E : Assoc_Ptr) return Entity_Id; - function Hash (F : Entity_Id) return HTable_Range; + function Get_Gen_Id (E : Assoc_Ptr) return Entity_Id; + function Hash (F : Entity_Id) return HTable_Range; package Generic_Renamings_HTable is new GNAT.HTable.Static_HTable ( Header_Num => HTable_Range, @@ -1157,19 +1159,29 @@ package body Sem_Ch12 is -- kinds for N_Box_Subp_Default, N_Box_Actual, N_Null_Default, and -- N_Exp_Func_Default. - type Generic_Actual_Rec (Kind : Actual_Kind := None) is record - -- Representation of one generic actual parameter + type Actual_Rec (Kind : Actual_Kind := None) is record case Kind is - when None | None_Use_Clause | Box_Subp_Default | Box_Actual | - Null_Default | Dummy_Assoc => + when None + | None_Use_Clause + | Box_Subp_Default + | Box_Actual + | Null_Default + | Dummy_Assoc + => null; - when Name_Exp | Exp_Func_Default => + when Name_Exp + | Exp_Func_Default + => Name_Exp : Node_Id; end case; end record; + -- Representation of one generic actual parameter type Actual_Origin_Enum is - (None, From_Explicit_Actual, From_Default, From_Inference, + (None, + From_Explicit_Actual, + From_Default, + From_Inference, From_Others_Box); -- Indication of where the Actual came from -- explicitly in the -- instantiation, inferred from some other type, or defaulted. @@ -1178,16 +1190,16 @@ package body Sem_Ch12 is -- Reason an actual type corresponding to a formal type was (or could -- be) inferred from the actual type corresponding to another formal -- type. - (Designated_Type, -- designated type from formal access - Index_Type, -- index type from formal array - Component_Type, -- component type from formal array + (Designated_Type, -- designated type from formal access + Index_Type, -- index type from formal array + Component_Type, -- component type from formal array Discriminant_Type); -- discriminant type from formal discriminated function Image (Reason : Inference_Reason) return String is (case Reason is - when Designated_Type => "designated type", - when Index_Type => "index type", - when Component_Type => "component type", + when Designated_Type => "designated type", + when Index_Type => "index type", + when Component_Type => "component type", when Discriminant_Type => "discriminant type"); type Assoc_Index is new Pos; @@ -1209,7 +1221,7 @@ package body Sem_Ch12 is Explicit_Assoc : Opt_N_Generic_Association_Id; -- Explicit association, if any, from the source or generated. - Actual : Generic_Actual_Rec; + Actual : Actual_Rec; -- Generic actual parameter corresponding to Un_Formal/An_Formal, -- possibly from defaults or others/boxes. @@ -1223,7 +1235,7 @@ package body Sem_Ch12 is -- inferred. Inferred_From : Assoc_Index; - -- Index of a later Assoc_Rec in the same Gen_Assocs_Rec from which + -- Index of a later Assoc_Rec in the same Match_Rec from which -- this one was inferred, or could be inferred. -- Valid only if Info_Inferred_Actual is present. @@ -1236,10 +1248,10 @@ package body Sem_Ch12 is -- One element for each formal and (if legal) for each corresponding -- actual. - type Gen_Assocs_Rec (Num_Assocs : Assoc_Count) is record - -- Representation of formal/actual matching. Num_Assocs - -- is the number of formals and (if legal) the number - -- of actuals. + type Match_Rec (Num_Assocs : Assoc_Count) is record + -- Representation of formal/actual matching. Num_Assocs is the + -- number of formals and (if legal) the number of actuals. + Gen_Unit : Entity_Id; -- the generic unit being instantiated Others_Present : Boolean; @@ -1250,25 +1262,26 @@ package body Sem_Ch12 is end record; function Match_Assocs - (I_Node : Node_Id; Formals : List_Id; F_Copy : List_Id) - return Gen_Assocs_Rec; - -- I_Node is the instantiation node. Formals is the list of unanalyzed + (N : Node_Id; + Formals : List_Id; + F_Copy : List_Id) return Match_Rec; + -- N is the instantiation node. Formals is the list of unanalyzed -- formals. F_Copy is the analyzed list of formals in the generic copy. - -- Return a Gen_Assocs_Rec with formals, explicit actuals, and default + -- Return a Match_Rec with formals, explicit actuals, and default -- actuals filled in. Check legality rules related to formal/actual -- matching. procedure Note_Potential_Inference - (I_Node : Node_Id; Gen_Assocs : Gen_Assocs_Rec); + (N : Node_Id; + Match : Match_Rec); -- If -gnatd_I, print "info:" messages about type inference that could -- have been done. end Associations; procedure Analyze_One_Association - (I_Node : Node_Id; -- instantiation node - Assoc : Associations.Assoc_Rec; - -- Logical 'in out' parameters: + (N : Node_Id; + Assoc : Associations.Assoc_Rec; Result_Renamings : List_Id; Default_Actuals : List_Id; Actuals_To_Freeze : Elist_Id); @@ -1278,12 +1291,12 @@ package body Sem_Ch12 is -- appended onto Actuals_To_Freeze. procedure Check_Fixed_Point_Warning - (Gen_Assocs : Associations.Gen_Assocs_Rec; + (Match : Associations.Match_Rec; Renamings : List_Id); -- Warn if any actual is a fixed-point type that has user-defined -- arithmetic operators, but there is no corresponding formal in the -- generic, in which case the predefined operators will be used. This - -- merits a warning because of the special semantics of fixed point + -- deserves a warning because of the special semantics of fixed point -- operators. However, do not warn if the formal is private, because there -- can be no arithmetic operators in the generic so there no danger of -- confusion. @@ -1314,27 +1327,29 @@ package body Sem_Ch12 is -- analyzed formals in cases where there are multiple ones -- corresponding to a particular unanalyzed one. - function Num_An_Formals (F_Copy : List_Id) return Assoc_Count; + function Num_An_Formals (F_Copy : List_Id) return Assoc_Count; -- Number of analyzed formals that correspond directly to unanalyzed -- formals. There are all sorts of other things in F_Copy, which -- are not counted. - procedure Check_Box (I_Node, Actual : Node_Id); + procedure Check_Box (N, Actual : Node_Id); -- Check for errors in "others => <>" and "Name => <>" - function Default (Un_Formal : Node_Id) return Generic_Actual_Rec; + function Default (Un_Formal : Node_Id) return Actual_Rec; -- Return the default for a given formal, which can be a name, -- expression, box, etc. procedure Match_Positional - (Src_Assoc : in out Node_Id; Assoc : in out Assoc_Rec); + (Src_Assoc : in out Node_Id; + Assoc : in out Assoc_Rec); -- Called by Match_Assocs to match one positional parameter association. -- If the current formal (in Assoc) is not a use clause, then there is a -- match, and we set Assoc.Actual and move Src_Assoc to the next one. procedure Match_Named - (Src_Assoc : Node_Id; Assoc : in out Assoc_Rec; - Found : in out Boolean); + (Src_Assoc : Node_Id; + Assoc : in out Assoc_Rec; + Found : in out Boolean); -- Called by Match_Assocs to match one named parameter association. -- If the current formal (in Assoc) is not a use clause, and the -- selector name matches the formal name, then there is a match, @@ -1342,48 +1357,50 @@ package body Sem_Ch12 is -- the matched formal, and set Found to True. procedure Inference_Msg - (Gen_Unit : Entity_Id; - Inferred_To, Inferred_From : Assoc_Rec; - Was_Inferred : Boolean); + (Gen_Unit : Entity_Id; + Inferred_To : Assoc_Rec; + Inferred_From : Assoc_Rec; + Was_Inferred : Boolean); -- If Was_Inferred is True, this prints out an "info:" message -- showing the inference. -- If Was_Inferred is False, the message says that it could have -- been inferred. function Find_Assoc - (Gen_Assocs : Gen_Assocs_Rec; F : Entity_Id) return Assoc_Index; - -- Return the index of F in Gen_Assocs.Assocs, which must be - -- present. + (Match : Match_Rec; + F : Entity_Id) return Assoc_Index; + -- Return the index of F in Match.Assocs, which must be present procedure Maybe_Infer_One - (Gen_Assocs : in out Gen_Assocs_Rec; - FF, AA : N_Entity_Id; Inferred_From : Assoc_Index; - Reason : Inference_Reason); + (Match : in out Match_Rec; + FF, AA : N_Entity_Id; + Inferred_From : Assoc_Index; + Reason : Inference_Reason); -- If it makes sense to infer that formal FF is associated with -- actual AA, then do so. procedure Infer_From_Access - (Gen_Assocs : in out Gen_Assocs_Rec; - Index : Assoc_Index; - F : Node_Id; + (Match : in out Match_Rec; + Index : Assoc_Index; + F : Node_Id; A_Full : Entity_Id); -- Try to infer the designated type procedure Infer_From_Array - (Gen_Assocs : in out Gen_Assocs_Rec; - Index : Assoc_Index; - F : Node_Id; + (Match : in out Match_Rec; + Index : Assoc_Index; + F : Node_Id; A_Full : Entity_Id); -- Try to infer the index and component types procedure Infer_From_Discriminated - (Gen_Assocs : in out Gen_Assocs_Rec; - Index : Assoc_Index; - F : Node_Id; + (Match : in out Match_Rec; + Index : Assoc_Index; + F : Node_Id; A_Full : Entity_Id); -- Try to infer the types of discriminants - procedure Infer_Actuals (Gen_Assocs : in out Gen_Assocs_Rec); + procedure Infer_Actuals (Match : in out Match_Rec); -- Called by Match_Assocs after processing explicit and defaulted -- parameters to infer any that are still missing. @@ -1541,13 +1558,13 @@ package body Sem_Ch12 is -- Check_Box -- --------------- - procedure Check_Box (I_Node, Actual : Node_Id) is + procedure Check_Box (N, Actual : Node_Id) is begin -- "... => <>" is allowed only in formal packages, not old-fashioned -- instantiations. - if Nkind (I_Node) /= N_Formal_Package_Declaration - and then Comes_From_Source (I_Node) + if Nkind (N) /= N_Formal_Package_Declaration + and then Comes_From_Source (N) then if Actual in N_Others_Choice_Id then Error_Msg_N @@ -1572,9 +1589,9 @@ package body Sem_Ch12 is -- Default -- ------------- - function Default (Un_Formal : Node_Id) return Generic_Actual_Rec is + function Default (Un_Formal : Node_Id) return Actual_Rec is begin - return Result : Generic_Actual_Rec do + return Result : Actual_Rec do case Nkind (Un_Formal) is when N_Formal_Object_Declaration => if Present (Default_Expression (Un_Formal)) then @@ -1726,22 +1743,24 @@ package body Sem_Ch12 is ------------------ function Match_Assocs - (I_Node : Node_Id; Formals : List_Id; F_Copy : List_Id) - return Gen_Assocs_Rec + (N : Node_Id; + Formals : List_Id; + F_Copy : List_Id) return Match_Rec is - Src_Assocs : constant List_Id := Generic_Associations (I_Node); - Gen_Unit : constant Entity_Id := Defining_Entity (Parent (F_Copy)); + Src_Assocs : constant List_Id := Generic_Associations (N); + Gen_Unit : constant Entity_Id := Defining_Entity (Parent (F_Copy)); + begin pragma Assert (Num_An_Formals (F_Copy) = Num_Formals (Formals) or else Serious_Errors_Detected > 0); - return Result : Gen_Assocs_Rec (Num_Assocs => Num_Formals (Formals)) + return Result : Match_Rec (Num_Assocs => Num_Formals (Formals)) do Result.Gen_Unit := Gen_Unit; Result.Others_Present := False; - -- Loop through the unanalyzed formals: + -- Loop through the unanalyzed formals declare procedure Set_Formal (F : Node_Id; Index : Assoc_Index); @@ -1778,7 +1797,7 @@ package body Sem_Ch12 is Iter (Formals); end; - -- Loop through the analyzed copy of the formals: + -- Loop through the analyzed copy of the formals declare procedure Set_An_Formal (F : Node_Id; Index : Assoc_Index); @@ -1835,7 +1854,7 @@ package body Sem_Ch12 is Iter (F_Copy); end; - -- Loop through actual source associations: + -- Loop through actual source associations declare Src_Assoc : Node_Id := First (Src_Assocs); @@ -1863,7 +1882,7 @@ package body Sem_Ch12 is -- Loop through named actuals and "others => <>": while Present (Src_Assoc) loop - Check_Box (I_Node, Src_Assoc); + Check_Box (N, Src_Assoc); if Src_Assoc in N_Others_Choice_Id then Result.Others_Present := True; exit; @@ -1941,8 +1960,8 @@ package body Sem_Ch12 is end; end loop; - if Nkind (I_Node) /= N_Formal_Package_Declaration then - Infer_Actuals (Gen_Assocs => Result); + if Nkind (N) /= N_Formal_Package_Declaration then + Infer_Actuals (Result); end if; -- Check for missing actuals @@ -1968,9 +1987,10 @@ package body Sem_Ch12 is ------------------- procedure Inference_Msg - (Gen_Unit : Entity_Id; - Inferred_To, Inferred_From : Assoc_Rec; - Was_Inferred : Boolean) + (Gen_Unit : Entity_Id; + Inferred_To : Assoc_Rec; + Inferred_From : Assoc_Rec; + Was_Inferred : Boolean) is pragma Assert (Debug_Flag_Underscore_II); -- This is only for -gnatd_I @@ -2008,7 +2028,8 @@ package body Sem_Ch12 is ------------------------------ procedure Note_Potential_Inference - (I_Node : Node_Id; Gen_Assocs : Gen_Assocs_Rec) + (N : Node_Id; + Match : Match_Rec) is begin if not Debug_Flag_Underscore_II or else Serious_Errors_Detected > 0 @@ -2016,20 +2037,21 @@ package body Sem_Ch12 is return; end if; - for Index in Gen_Assocs.Assocs'Range loop + for Index in Match.Assocs'Range loop declare - Assoc : Assoc_Rec renames Gen_Assocs.Assocs (Index); + Assoc : Assoc_Rec renames Match.Assocs (Index); + begin if Assoc.Actual_Origin = From_Explicit_Actual and then Present (Assoc.Info_Inferred_Actual) - and then In_Extended_Main_Source_Unit (I_Node) - and then not In_Internal_Unit (I_Node) + and then In_Extended_Main_Source_Unit (N) + and then not In_Internal_Unit (N) then Inference_Msg - (Gen_Assocs.Gen_Unit, - Inferred_To => Assoc, - Inferred_From => Gen_Assocs.Assocs (Assoc.Inferred_From), - Was_Inferred => False); + (Match.Gen_Unit, + Inferred_To => Assoc, + Inferred_From => Match.Assocs (Assoc.Inferred_From), + Was_Inferred => False); end if; end; end loop; @@ -2040,11 +2062,12 @@ package body Sem_Ch12 is -------------- function Find_Assoc - (Gen_Assocs : Gen_Assocs_Rec; F : Entity_Id) return Assoc_Index + (Match : Match_Rec; + F : Entity_Id) return Assoc_Index is begin - for Index in Gen_Assocs.Assocs'Range loop - if Defining_Entity (Gen_Assocs.Assocs (Index).An_Formal) = F then + for Index in Match.Assocs'Range loop + if Defining_Entity (Match.Assocs (Index).An_Formal) = F then return Index; end if; end loop; @@ -2057,13 +2080,14 @@ package body Sem_Ch12 is --------------------- procedure Maybe_Infer_One - (Gen_Assocs : in out Gen_Assocs_Rec; - FF, AA : N_Entity_Id; Inferred_From : Assoc_Index; - Reason : Inference_Reason) + (Match : in out Match_Rec; + FF, AA : N_Entity_Id; + Inferred_From : Assoc_Index; + Reason : Inference_Reason) is begin if not (Is_Generic_Type (FF) - and then Scope (FF) = Gen_Assocs.Gen_Unit) + and then Scope (FF) = Match.Gen_Unit) then return; -- no inference if not a formal type of this generic end if; @@ -2073,12 +2097,12 @@ package body Sem_Ch12 is end if; declare - Index : constant Assoc_Index := Find_Assoc (Gen_Assocs, FF); - Assoc : Assoc_Rec renames Gen_Assocs.Assocs (Index); + Index : constant Assoc_Index := Find_Assoc (Match, FF); + Assoc : Assoc_Rec renames Match.Assocs (Index); pragma Assert (Defining_Entity (Assoc.An_Formal) = FF); From_Actual : constant Node_Id := - Gen_Assocs.Assocs (Inferred_From).Actual.Name_Exp; + Match.Assocs (Inferred_From).Actual.Name_Exp; begin Assoc.Info_Inferred_Actual := AA; @@ -2096,23 +2120,23 @@ package body Sem_Ch12 is if Debug_Flag_Underscore_II then Inference_Msg - (Gen_Assocs.Gen_Unit, - Inferred_To => Assoc, - Inferred_From => Gen_Assocs.Assocs (Assoc.Inferred_From), - Was_Inferred => True); + (Match.Gen_Unit, + Inferred_To => Assoc, + Inferred_From => Match.Assocs (Assoc.Inferred_From), + Was_Inferred => True); end if; end if; end; end Maybe_Infer_One; - ------------------- - -- Infer_Actuals -- - ------------------- + ----------------------- + -- Infer_From_Access -- + ----------------------- procedure Infer_From_Access - (Gen_Assocs : in out Gen_Assocs_Rec; - Index : Assoc_Index; - F : Node_Id; + (Match : in out Match_Rec; + Index : Assoc_Index; + F : Node_Id; A_Full : Entity_Id) is begin @@ -2123,7 +2147,7 @@ package body Sem_Ch12 is AA : constant Entity_Id := Designated_Type (A_Full); begin Maybe_Infer_One - (Gen_Assocs, + (Match, FF, AA, Inferred_From => Index, @@ -2132,10 +2156,14 @@ package body Sem_Ch12 is end if; end Infer_From_Access; + ---------------------- + -- Infer_From_Array -- + ---------------------- + procedure Infer_From_Array - (Gen_Assocs : in out Gen_Assocs_Rec; - Index : Assoc_Index; - F : Node_Id; + (Match : in out Match_Rec; + Index : Assoc_Index; + F : Node_Id; A_Full : Entity_Id) is begin @@ -2149,7 +2177,7 @@ package body Sem_Ch12 is while Present (F_Index_Type) and then Present (A_Index_Type) loop Maybe_Infer_One - (Gen_Assocs, + (Match, Etype (F_Index_Type), Etype (A_Index_Type), Inferred_From => Index, @@ -2167,7 +2195,7 @@ package body Sem_Ch12 is Component_Type (A_Full); begin Maybe_Infer_One - (Gen_Assocs, + (Match, F_Comp_Type, A_Comp_Type, Inferred_From => Index, @@ -2176,10 +2204,14 @@ package body Sem_Ch12 is end if; end Infer_From_Array; + ------------------------------ + -- Infer_From_Discriminated -- + ------------------------------ + procedure Infer_From_Discriminated - (Gen_Assocs : in out Gen_Assocs_Rec; - Index : Assoc_Index; - F : Node_Id; + (Match : in out Match_Rec; + Index : Assoc_Index; + F : Node_Id; A_Full : Entity_Id) is begin @@ -2195,7 +2227,7 @@ package body Sem_Ch12 is begin while Present (F_Discrim) loop Maybe_Infer_One - (Gen_Assocs, + (Match, Etype (F_Discrim), Etype (A_Discrim), Inferred_From => Index, @@ -2209,23 +2241,27 @@ package body Sem_Ch12 is end if; end Infer_From_Discriminated; - procedure Infer_Actuals (Gen_Assocs : in out Gen_Assocs_Rec) is - -- Note that we can infer FROM defaults, but we cannot infer TO a - -- parameter that has a default. We can also infer from inferred - -- types. + ------------------- + -- Infer_Actuals -- + ------------------- + + -- Note that we can infer FROM defaults, but we cannot infer TO a + -- parameter that has a default. We can also infer from inferred + -- types. - -- We don't need to check that multiple inferences get the same - -- answer; the second one will get a type mismatch or nonstatically - -- matching error. + -- We don't need to check that multiple inferences get the same + -- answer; the second one will get a type mismatch or nonstatically + -- matching error. - -- This code needs to be robust, in the sense of tolerating illegal - -- code, because we have not yet checked all legality rules. For - -- example, if a formal type F has a discriminant whose type is - -- another formal type, then we want to infer the type of the - -- discriminant from the actual for F. That actual must have - -- discriminants, but we have not checked that rule yet, so we - -- need to tolerate an actual for F that has no discriminants. + -- This code needs to be robust, in the sense of tolerating illegal + -- code, because we have not yet checked all legality rules. For + -- example, if a formal type F has a discriminant whose type is + -- another formal type, then we want to infer the type of the + -- discriminant from the actual for F. That actual must have + -- discriminants, but we have not checked that rule yet, so we + -- need to tolerate an actual for F that has no discriminants. + procedure Infer_Actuals (Match : in out Match_Rec) is begin -- For each parameter, check whether we can infer FROM that one TO -- other ones. @@ -2239,12 +2275,12 @@ package body Sem_Ch12 is -- designated type. The reverse loop implies that we will see the -- array type, then the access type, then the designated type. - for Index in reverse Gen_Assocs.Assocs'Range loop -- NB: "reverse" - if Gen_Assocs.Assocs (Index).Actual.Kind = Name_Exp then + for Index in reverse Match.Assocs'Range loop -- NB: "reverse" + if Match.Assocs (Index).Actual.Kind = Name_Exp then declare - F : constant Node_Id := Gen_Assocs.Assocs (Index).An_Formal; + F : constant Node_Id := Match.Assocs (Index).An_Formal; A_E : constant Node_Id := - Gen_Assocs.Assocs (Index).Actual.Name_Exp; + Match.Assocs (Index).Actual.Name_Exp; A_Full : Entity_Id := Empty; begin if Nkind (A_E) in N_Has_Entity then @@ -2263,7 +2299,7 @@ package body Sem_Ch12 is then case Ekind (Defining_Entity (F)) is when E_Access_Type | E_General_Access_Type => - Infer_From_Access (Gen_Assocs, Index, F, A_Full); + Infer_From_Access (Match, Index, F, A_Full); when E_Access_Subtype | E_Access_Attribute_Type @@ -2273,7 +2309,7 @@ package body Sem_Ch12 is raise Program_Error; when E_Array_Type | E_Array_Subtype => - Infer_From_Array (Gen_Assocs, Index, F, A_Full); + Infer_From_Array (Match, Index, F, A_Full); when E_String_Literal_Subtype => raise Program_Error; @@ -2282,13 +2318,12 @@ package body Sem_Ch12 is null; end case; - Infer_From_Discriminated (Gen_Assocs, Index, F, A_Full); + Infer_From_Discriminated (Match, Index, F, A_Full); end if; end; end if; end loop; end Infer_Actuals; - end Associations; --------------------------- @@ -2315,46 +2350,49 @@ package body Sem_Ch12 is -------------------------- function Analyze_Associations - (I_Node : Node_Id; + (N : Node_Id; Formals : List_Id; F_Copy : List_Id) return List_Id is use Associations; - Result_Renamings : constant List_Id := New_List; + Actuals_To_Freeze : constant Elist_Id := New_Elmt_List; + Default_Actuals : constant List_Id := New_List; + Result_Renamings : constant List_Id := New_List; -- To be returned. Includes "renamings" broadly interpreted -- (e.g. subtypes are used for types). - Actuals_To_Freeze : constant Elist_Id := New_Elmt_List; - Default_Actuals : constant List_Id := New_List; - - Gen_Assocs : constant Gen_Assocs_Rec := - Match_Assocs (I_Node, Formals, F_Copy); + Match : constant Match_Rec := Match_Assocs (N, Formals, F_Copy); begin - for Matching_Actual_Index in Gen_Assocs.Assocs'Range loop + for Index in Match.Assocs'Range loop declare - Assoc : Assoc_Rec renames - Gen_Assocs.Assocs (Matching_Actual_Index); + Assoc : Assoc_Rec renames Match.Assocs (Index); + begin if Nkind (Assoc.Un_Formal) = N_Formal_Package_Declaration and then Error_Posted (Assoc.An_Formal) then -- Restrict this to N_Formal_Package_Declaration, -- because otherwise we miss errors. + Abandon_Instantiation (Instantiation_Node); end if; - if Nkind (Assoc.Un_Formal) in - N_Use_Package_Clause | N_Use_Type_Clause + if Nkind (Assoc.Un_Formal) in N_Use_Package_Clause + | N_Use_Type_Clause then - -- Copy the use clause to where it belongs: + -- Copy the use clause to where it belongs + Append (New_Copy_Tree (Assoc.Un_Formal), Result_Renamings); else Analyze_One_Association - (I_Node, Assoc, - Result_Renamings, Default_Actuals, Actuals_To_Freeze); + (N, + Assoc, + Result_Renamings, + Default_Actuals, + Actuals_To_Freeze); end if; end; end loop; @@ -2365,9 +2403,10 @@ package body Sem_Ch12 is declare Elmt : Elmt_Id := First_Elmt (Actuals_To_Freeze); + begin while Present (Elmt) loop - Freeze_Before (I_Node, Node (Elmt)); + Freeze_Before (N, Node (Elmt)); Next_Elmt (Elmt); end loop; end; @@ -2387,17 +2426,17 @@ package body Sem_Ch12 is Next (Default); end loop; - if No (Generic_Associations (I_Node)) then - Set_Generic_Associations (I_Node, Default_Actuals); + if No (Generic_Associations (N)) then + Set_Generic_Associations (N, Default_Actuals); else - Append_List_To (Generic_Associations (I_Node), Default_Actuals); + Append_List_To (Generic_Associations (N), Default_Actuals); end if; end; end if; - Note_Potential_Inference (I_Node, Gen_Assocs); + Note_Potential_Inference (N, Match); - Check_Fixed_Point_Warning (Gen_Assocs, Result_Renamings); + Check_Fixed_Point_Warning (Match, Result_Renamings); return Result_Renamings; end Analyze_Associations; @@ -2407,9 +2446,8 @@ package body Sem_Ch12 is ----------------------------- procedure Analyze_One_Association - (I_Node : Node_Id; - Assoc : Associations.Assoc_Rec; - -- Logical 'in out' parameters: + (N : Node_Id; + Assoc : Associations.Assoc_Rec; Result_Renamings : List_Id; Default_Actuals : List_Id; Actuals_To_Freeze : Elist_Id) @@ -2481,11 +2519,11 @@ package body Sem_Ch12 is if No (Match) and then not Inside_A_Generic then Append_To (Default_Actuals, - Make_Generic_Association (Sloc (I_Node), + Make_Generic_Association (Sloc (N), Selector_Name => New_Occurrence_Of (Defining_Identifier - (Assoc.Un_Formal), Sloc (I_Node)), + (Assoc.Un_Formal), Sloc (N)), Explicit_Generic_Actual_Parameter => New_Copy_Tree (Default_Expression (Assoc.Un_Formal)))); end if; @@ -2606,7 +2644,7 @@ package body Sem_Ch12 is -- unless this is a rewritten formal package, or the -- formal is an Ada 2012 formal incomplete type. - if Nkind (I_Node) = N_Formal_Package_Declaration + if Nkind (N) = N_Formal_Package_Declaration or else (Ada_Version >= Ada_2012 and then @@ -2692,7 +2730,7 @@ package body Sem_Ch12 is -- An instantiation is a freeze point for the actuals, -- unless this is a rewritten formal package. - if Nkind (I_Node) /= N_Formal_Package_Declaration + if Nkind (N) /= N_Formal_Package_Declaration and then Nkind (Match) = N_Identifier and then Is_Subprogram (Entity (Match)) @@ -2710,7 +2748,7 @@ package body Sem_Ch12 is -- subprograms defined in Standard which are used -- as generic actuals. - and then In_Same_Code_Unit (Entity (Match), I_Node) + and then In_Same_Code_Unit (Entity (Match), N) and then Has_Fully_Defined_Profile (Entity (Match)) then -- Mark the subprogram as having a delayed freeze @@ -2733,11 +2771,11 @@ package body Sem_Ch12 is begin Append_To (Default_Actuals, - Make_Generic_Association (Sloc (I_Node), + Make_Generic_Association (Sloc (N), Selector_Name => - New_Occurrence_Of (Subp, Sloc (I_Node)), + New_Occurrence_Of (Subp, Sloc (N)), Explicit_Generic_Actual_Parameter => - New_Occurrence_Of (Subp, Sloc (I_Node)))); + New_Occurrence_Of (Subp, Sloc (N)))); end; end if; @@ -2850,13 +2888,13 @@ package body Sem_Ch12 is if not Expander_Active or else not Has_Completion (Actual) - or else not In_Same_Source_Unit (I_Node, Actual) + or else not In_Same_Source_Unit (N, Actual) or else Is_Frozen (Actual) or else (Present (Renamed_Entity (Actual)) and then not In_Same_Source_Unit - (I_Node, (Renamed_Entity (Actual)))) + (N, (Renamed_Entity (Actual)))) then null; @@ -2868,7 +2906,7 @@ package body Sem_Ch12 is Needs_Freezing := True; - P := Parent (I_Node); + P := Parent (N); while Nkind (P) /= N_Compilation_Unit loop if Nkind (P) = N_Handled_Sequence_Of_Statements then @@ -3133,7 +3171,7 @@ package body Sem_Ch12 is end if; end if; - if Subtype_Mark (Def) <= Empty_Or_Error then + if Subtype_Mark (Def) in Empty | Error then pragma Assert (Serious_Errors_Detected > 0); -- avoid passing bad argument to Entity return; @@ -3371,7 +3409,7 @@ package body Sem_Ch12 is end if; if Present (E) then - Preanalyze_Spec_Expression (E, T); + Preanalyze_And_Resolve_Spec_Expression (E, T); -- The default for a ghost generic formal IN parameter of -- access-to-variable type should be a ghost object (SPARK @@ -3585,7 +3623,7 @@ package body Sem_Ch12 is Decls := Analyze_Associations - (I_Node => Original_Node (N), + (N => Original_Node (N), Formals => Generic_Formal_Declarations (Act_Tree), F_Copy => Generic_Formal_Declarations (Gen_Decl)); @@ -3601,9 +3639,8 @@ package body Sem_Ch12 is if No (Visible_Declarations (Specification (Pack_Decl))) then Set_Visible_Declarations (Specification (Pack_Decl), Decls); else - Insert_List_Before - (First (Visible_Declarations (Specification (Pack_Decl))), - Decls); + Prepend_List_To + (Visible_Declarations (Specification (Pack_Decl)), Decls); end if; return Pack_Decl; @@ -4195,7 +4232,7 @@ package body Sem_Ch12 is elsif Present (Expr) then Push_Scope (Nam); Install_Formals (Nam); - Preanalyze_Spec_Expression (Expr, Etype (Nam)); + Preanalyze_And_Resolve_Spec_Expression (Expr, Etype (Nam)); End_Scope; end if; @@ -4859,11 +4896,10 @@ package body Sem_Ch12 is -- Local declarations - Gen_Id : constant Node_Id := Name (N); - Inst_Id : constant Entity_Id := Defining_Entity (N); - Is_Actual_Pack : constant Boolean := Is_Internal (Inst_Id); - Loc : constant Source_Ptr := Sloc (N); - + Gen_Id : constant Node_Id := Name (N); + Loc : constant Source_Ptr := Sloc (N); + Is_Abbrev : constant Boolean := + Is_Abbreviated_Instance (Defining_Entity (N)); Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; Saved_IGR : constant Node_Id := Ignored_Ghost_Region; Saved_ISMP : constant Boolean := @@ -4876,7 +4912,6 @@ package body Sem_Ch12 is -- Save style check mode for restore on exit Act_Decl : Node_Id; - Act_Decl_Name : Node_Id; Act_Decl_Id : Entity_Id; Act_Spec : Node_Id; Act_Tree : Node_Id; @@ -4917,29 +4952,7 @@ package body Sem_Ch12 is Instantiation_Node := N; - -- Case of instantiation of a generic package - - if Nkind (N) = N_Package_Instantiation then - Act_Decl_Id := New_Copy (Defining_Entity (N)); - - if Nkind (Defining_Unit_Name (N)) = N_Defining_Program_Unit_Name then - Act_Decl_Name := - Make_Defining_Program_Unit_Name (Loc, - Name => - New_Copy_Tree (Name (Defining_Unit_Name (N))), - Defining_Identifier => Act_Decl_Id); - else - Act_Decl_Name := Act_Decl_Id; - end if; - - -- Case of instantiation of a formal package - - else - Act_Decl_Id := Defining_Identifier (N); - Act_Decl_Name := Act_Decl_Id; - end if; - - Generate_Definition (Act_Decl_Id); + Act_Decl_Id := New_Copy (Defining_Entity (N)); Mutate_Ekind (Act_Decl_Id, E_Package); Set_Is_Not_Self_Hidden (Act_Decl_Id); @@ -4971,7 +4984,7 @@ package body Sem_Ch12 is -- Except for an abbreviated instance created to check a formal package, -- install the parent if this is a generic child unit. - if not Is_Abbreviated_Instance (Inst_Id) then + if not Is_Abbrev then Check_Generic_Child_Unit (Gen_Id, Parent_Installed); end if; @@ -5074,9 +5087,6 @@ package body Sem_Ch12 is goto Leave; else - Mutate_Ekind (Inst_Id, E_Package); - Set_Scope (Inst_Id, Current_Scope); - -- If the context of the instance is subject to SPARK_Mode "off" or -- the annotation is altogether missing, set the global flag which -- signals Analyze_Pragma to ignore all SPARK_Mode pragmas within @@ -5114,22 +5124,38 @@ package body Sem_Ch12 is -- If this is the instance created to validate an actual package, -- only the formals matter, do not examine the package spec itself. - if Is_Actual_Pack then + if Is_Abbrev then Set_Visible_Declarations (Act_Spec, New_List); Set_Private_Declarations (Act_Spec, New_List); end if; Renamings := Analyze_Associations - (I_Node => N, + (N => N, Formals => Generic_Formal_Declarations (Act_Tree), F_Copy => Generic_Formal_Declarations (Gen_Decl)); Vis_Prims_List := Check_Hidden_Primitives (Renamings); + -- Set minimal decoration on the original entity + + Mutate_Ekind (Defining_Entity (N), E_Package); + Set_Scope (Defining_Entity (N), Current_Scope); + Set_Instance_Env (Gen_Unit, Act_Decl_Id); - Set_Defining_Unit_Name (Act_Spec, Act_Decl_Name); Set_Is_Generic_Instance (Act_Decl_Id); + Generate_Definition (Act_Decl_Id); + + if Nkind (Defining_Unit_Name (N)) = N_Defining_Program_Unit_Name then + Set_Defining_Unit_Name (Act_Spec, + Make_Defining_Program_Unit_Name (Loc, + Name => + New_Copy_Tree (Name (Defining_Unit_Name (N))), + Defining_Identifier => Act_Decl_Id)); + else + Set_Defining_Unit_Name (Act_Spec, Act_Decl_Id); + end if; + Set_Generic_Parent (Act_Spec, Gen_Unit); -- References to the generic in its own declaration or its body are @@ -5273,7 +5299,7 @@ package body Sem_Ch12 is and then (not Is_Child_Unit (Gen_Unit) or else not Is_Generic_Unit (Scope (Gen_Unit))) and then Might_Inline_Subp (Gen_Unit) - and then not Is_Actual_Pack + and then not Is_Abbrev then if not Back_End_Inlining and then (Front_End_Inlining or else Has_Inline_Always) @@ -5318,7 +5344,7 @@ package body Sem_Ch12 is or else Enclosing_Body_Present or else Present (Corresponding_Body (Gen_Decl))) and then Needs_Body_Instantiated (Gen_Unit) - and then not Is_Actual_Pack + and then not Is_Abbrev and then not Inline_Now and then (Operating_Mode = Generate_Code or else (Operating_Mode = Check_Semantics @@ -6031,6 +6057,10 @@ package body Sem_Ch12 is if (Is_In_Main_Unit (N) or else Is_Inlined_Or_Child_Of_Inlined (Subp)) + -- No need to instantiate bodies in generic units + + and then not Is_Generic_Unit (Cunit_Entity (Main_Unit)) + -- Must be generating code or analyzing code in GNATprove mode and then (Operating_Mode = Generate_Code @@ -6450,7 +6480,7 @@ package body Sem_Ch12 is Renamings := Analyze_Associations - (I_Node => N, + (N => N, Formals => Generic_Formal_Declarations (Act_Tree), F_Copy => Generic_Formal_Declarations (Gen_Decl)); @@ -6674,6 +6704,7 @@ package body Sem_Ch12 is elsif Nkind (Parent (N)) = N_Compilation_Unit then Rewrite (N, Unit (Parent (N))); + Move_Aspects (From => Original_Node (N), To => N); Set_Unit (Parent (N), N); end if; @@ -6682,6 +6713,7 @@ package body Sem_Ch12 is elsif Nkind (Parent (N)) = N_Compilation_Unit then Rewrite (N, Unit (Parent (N))); + Move_Aspects (From => Original_Node (N), To => N); Set_Unit (Parent (N), N); end if; @@ -7558,14 +7590,15 @@ package body Sem_Ch12 is ------------------------------- procedure Check_Fixed_Point_Warning - (Gen_Assocs : Associations.Gen_Assocs_Rec; + (Match : Associations.Match_Rec; Renamings : List_Id) is use Associations; + begin - for Type_Index in Gen_Assocs.Assocs'Range loop + for Type_Index in Match.Assocs'Range loop declare - Assoc : Assoc_Rec renames Gen_Assocs.Assocs (Type_Index); + Assoc : Assoc_Rec renames Match.Assocs (Type_Index); begin if Nkind (Assoc.An_Formal) = N_Formal_Type_Declaration and then Is_Fixed_Point_Type (Defining_Entity (Assoc.An_Formal)) @@ -7594,9 +7627,9 @@ package body Sem_Ch12 is Op := Alias (Node (Elem)); for Op_Index in Type_Index + 1 .. - Gen_Assocs.Assocs'Last + Match.Assocs'Last loop - Formal := Gen_Assocs.Assocs (Op_Index).Un_Formal; + Formal := Match.Assocs (Op_Index).Un_Formal; if Nkind (Formal) = N_Formal_Concrete_Subprogram_Declaration @@ -9340,9 +9373,6 @@ package body Sem_Ch12 is and then Nkind (Ancestor_Type (N)) in N_Entity then declare - Root_Typ : constant Entity_Id := - Root_Type (Ancestor_Type (N)); - Typ : Entity_Id := Ancestor_Type (N); begin @@ -9351,7 +9381,7 @@ package body Sem_Ch12 is Switch_View (Typ); end if; - exit when Typ = Root_Typ; + exit when Etype (Typ) = Typ; Typ := Etype (Typ); end loop; @@ -10056,13 +10086,12 @@ package body Sem_Ch12 is -- the freeze node for Inst must be inserted after that of -- Parent_Inst. This relation is established by comparing -- the Slocs of Parent_Inst freeze node and Inst. - -- We examine the parents of the enclosing lists to handle + -- We examine the parents (of the enclosing lists) to handle -- the case where the parent instance is in the visible part -- of a package declaration, and the inner instance is in -- the corresponding private part. - if Parent (List_Containing (Freeze_Node (Par_Id))) - = Parent (List_Containing (N)) + if Parent (Freeze_Node (Par_Id)) = Parent (N) and then Sloc (Freeze_Node (Par_Id)) <= Sloc (N) then Insert_Freeze_Node_For_Instance (N, F_Node); @@ -10381,7 +10410,8 @@ package body Sem_Ch12 is -- investigated, and would allow this function to be significantly -- simplified. ??? - Inst := Package_Instantiation (A); + Inst := + (if Ekind (A) = E_Package then Package_Instantiation (A) else Empty); if Present (Inst) then if Nkind (Inst) = N_Package_Instantiation then @@ -10428,10 +10458,11 @@ package body Sem_Ch12 is else Inst := Next (Decl); - while Nkind (Inst) not in N_Formal_Package_Declaration - | N_Function_Instantiation - | N_Package_Instantiation - | N_Procedure_Instantiation + while Present (Inst) + and then Nkind (Inst) not in N_Formal_Package_Declaration + | N_Function_Instantiation + | N_Package_Instantiation + | N_Procedure_Instantiation loop Next (Inst); end loop; @@ -11100,13 +11131,9 @@ package body Sem_Ch12 is begin -- If this parent of the child instance is a top-level unit, -- then record the unit and its visibility for later resetting in - -- Remove_Parent. We exclude units that are generic instances, as we - -- only want to record this information for the ultimate top-level - -- noninstance parent (is that always correct???). + -- Remove_Parent. - if Scope (Par) = Standard_Standard - and then not Is_Generic_Instance (Par) - then + if Scope (Par) = Standard_Standard then Parent_Unit_Visible := Is_Immediately_Visible (Par); Instance_Parent_Unit := Par; end if; @@ -13034,10 +13061,6 @@ package body Sem_Ch12 is Make_Defining_Identifier (Sloc (Act_Decl_Id), Chars (Act_Decl_Id)); Preserve_Comes_From_Source (Act_Body_Id, Act_Decl_Id); - -- Some attributes of spec entity are not inherited by body entity - - Set_Handler_Records (Act_Body_Id, No_List); - if Nkind (Defining_Unit_Name (Act_Spec)) = N_Defining_Program_Unit_Name then @@ -14132,6 +14155,16 @@ package body Sem_Ch12 is T2 := Etype (I2); end if; + -- In the case of a fixed-lower-bound subtype, we want to check + -- against the index type's range rather than the range of the + -- subtype (which will be seen as unconstrained, and whose bounds + -- won't generally match those of the formal unconstrained array + -- type's corresponding index type). + + if Is_Fixed_Lower_Bound_Index_Subtype (T2) then + T2 := Etype (Scalar_Range (T2)); + end if; + if not Subtypes_Match (Find_Actual_Type (Etype (I1), A_Gen_T), T2) then @@ -14338,8 +14371,21 @@ package body Sem_Ch12 is elsif Scope (Scope (Base_Type (Etype (A_Gen_T)))) = Scope (A_Gen_T) then - Ancestor := - Get_Instance_Of (Base_Type (Etype (A_Gen_T))); + declare + Formal_Ancestor : constant Entity_Id := + Base_Type (Etype (A_Gen_T)); + begin + Ancestor := Get_Instance_Of (Formal_Ancestor); + + -- Handle (rare) case where Get_Instance_Of found nothing in + -- the map. + + if Ancestor = Formal_Ancestor then + Ancestor := + Get_Instance_Of + (Base_Type (Etype (Get_Instance_Of (A_Gen_T)))); + end if; + end; -- The type may be a local derivation, or a type extension of a -- previous formal, or of a formal of a parent package. @@ -16301,39 +16347,43 @@ package body Sem_Ch12 is Install_Private_Declarations (P); end if; - -- If the ultimate parent is a top-level unit recorded in - -- Instance_Parent_Unit, then reset its visibility to what it was - -- before instantiation. (It's not clear what the purpose is of - -- testing whether Scope (P) is In_Open_Scopes, but that test was - -- present before the ultimate parent test was added.???) - - elsif not In_Open_Scopes (Scope (P)) - or else (P = Instance_Parent_Unit - and then not Parent_Unit_Visible) - then - Set_Is_Immediately_Visible (P, False); + else + -- If the ultimate parent is a top-level unit recorded in + -- Instance_Parent_Unit, then reset its visibility to what + -- it was before instantiation. (It's not clear what the + -- purpose is of testing whether Scope (P) is In_Open_Scopes, + -- but that test was present before the ultimate parent test + -- was added.???) + + if not In_Open_Scopes (Scope (P)) + or else (P = Instance_Parent_Unit + and then not Parent_Unit_Visible) + then + Set_Is_Immediately_Visible (P, False); + end if; - -- If the current scope is itself an instantiation of a generic - -- nested within P, and we are in the private part of body of this - -- instantiation, restore the full views of P, that were removed - -- in End_Package_Scope above. This obscure case can occur when a - -- subunit of a generic contains an instance of a child unit of - -- its generic parent unit. + -- If the current scope is itself an instantiation of a generic + -- nested within P, and we are in the private part of body of + -- the instantiation, restore the full views of P, which were + -- removed in End_Package_Scope above. This obscure case can + -- occur when a subunit of a generic contains an instance of + -- a child unit of its generic parent unit. - elsif S = Current_Scope and then Is_Generic_Instance (S) - and then (In_Package_Body (S) or else In_Private_Part (S)) - then - declare - Par : constant Entity_Id := - Generic_Parent (Package_Specification (S)); - begin - if Present (Par) - and then P = Scope (Par) - then - Set_In_Private_Part (P); - Install_Private_Declarations (P); - end if; - end; + if S = Current_Scope and then Is_Generic_Instance (S) + and then (In_Package_Body (S) or else In_Private_Part (S)) + then + declare + Par : constant Entity_Id := + Generic_Parent (Package_Specification (S)); + begin + if Present (Par) + and then P = Scope (Par) + then + Set_In_Private_Part (P); + Install_Private_Declarations (P); + end if; + end; + end if; end if; end loop; diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb index 072ec66a8f3d..b7ada50456a4 100644 --- a/gcc/ada/sem_ch13.adb +++ b/gcc/ada/sem_ch13.adb @@ -29,11 +29,11 @@ with Atree; use Atree; with Checks; use Checks; with Contracts; use Contracts; with Debug; use Debug; -with Diagnostics.Constructors; use Diagnostics.Constructors; with Einfo; use Einfo; with Einfo.Entities; use Einfo.Entities; with Einfo.Utils; use Einfo.Utils; with Elists; use Elists; +with Errid; use Errid; with Errout; use Errout; with Exp_Ch3; use Exp_Ch3; with Exp_Disp; use Exp_Disp; @@ -54,6 +54,7 @@ with Restrict; use Restrict; with Rident; use Rident; with Rtsfind; use Rtsfind; with Sem; use Sem; +with Sem_Aggr; use Sem_Aggr; with Sem_Aux; use Sem_Aux; with Sem_Case; use Sem_Case; with Sem_Cat; use Sem_Cat; @@ -336,6 +337,13 @@ package body Sem_Ch13 is -- Resolve each one of the arguments specified in the specification of -- aspect Finalizable. + function Resolve_Finalization_Procedure + (N : Node_Id; + Typ : Entity_Id) return Boolean; + -- Resolve a procedure argument specified in the specification of one of + -- the finalization aspects, i.e. Finalizable and Destructor. Returns True + -- if successful, False otherwise. + procedure Resolve_Iterable_Operation (N : Node_Id; Cursor : Entity_Id; @@ -1620,6 +1628,7 @@ package body Sem_Ch13 is -- Part_Of -- Post -- Pre + -- Program_Exit -- Refined_Depends -- Refined_Global -- Refined_Post @@ -1872,11 +1881,11 @@ package body Sem_Ch13 is -- analyzed right now. -- Note that there is a special handling for Pre, Post, Test_Case, - -- Contract_Cases, Always_Terminates, Exit_Cases, Exceptional_Cases and - -- Subprogram_Variant aspects. In these cases, we do not have to worry - -- about delay issues, since the pragmas themselves deal with delay of - -- visibility for the expression analysis. Thus, we just insert the - -- pragma after the node N. + -- Contract_Cases, Always_Terminates, Exit_Cases, Exceptional_Cases, + -- Program_Exit and Subprogram_Variant aspects. In these cases, we do + -- not have to worry about delay issues, since the pragmas themselves + -- deal with delay of visibility for the expression analysis. Thus, we + -- just insert the pragma after the node N. if No (L) then return; @@ -1928,6 +1937,9 @@ package body Sem_Ch13 is procedure Analyze_Aspect_Implicit_Dereference; -- Perform analysis of the Implicit_Dereference aspects + procedure Analyze_Aspect_Potentially_Invalid; + -- Perform analysis of aspect Potentially_Invalid + procedure Analyze_Aspect_Relaxed_Initialization; -- Perform analysis of aspect Relaxed_Initialization @@ -2295,6 +2307,267 @@ package body Sem_Ch13 is end Analyze_Aspect_Implicit_Dereference; + ---------------------------------------- + -- Analyze_Aspect_Potentially_Invalid -- + ---------------------------------------- + + procedure Analyze_Aspect_Potentially_Invalid is + procedure Analyze_Aspect_Parameter + (Subp_Id : Entity_Id; + Param : Node_Id; + Seen : in out Elist_Id); + -- Analyze parameter that appears in the expression of the + -- aspect Potentially_Invalid. + + ------------------------------ + -- Analyze_Aspect_Parameter -- + ------------------------------ + + procedure Analyze_Aspect_Parameter + (Subp_Id : Entity_Id; + Param : Node_Id; + Seen : in out Elist_Id) + is + begin + -- Set name of the aspect for error messages + Error_Msg_Name_1 := Nam; + + -- The potentially invalid parameter is a formal parameter + + if Nkind (Param) in N_Identifier | N_Expanded_Name then + Analyze (Param); + + declare + Item : constant Entity_Id := Entity (Param); + begin + -- It must be a formal of the analyzed subprogram + + if Scope (Item) = Subp_Id then + + pragma Assert (Is_Formal (Item)); + + -- It must not have scalar type + + if Is_Scalar_Type (Underlying_Type (Etype (Item))) + then + Error_Msg_N ("illegal aspect % item", Param); + Error_Msg_N + ("\item must not have scalar type", Param); + end if; + + -- Detect duplicated items + + if Contains (Seen, Item) then + Error_Msg_N ("duplicate aspect % item", Param); + else + Append_New_Elmt (Item, Seen); + end if; + else + Error_Msg_N ("illegal aspect % item", Param); + end if; + end; + + -- The potentially invalid parameter is the function's + -- Result attribute. + + elsif Is_Attribute_Result (Param) then + Analyze (Param); + + declare + Pref : constant Node_Id := Prefix (Param); + begin + if Present (Pref) + and then + Nkind (Pref) in N_Identifier | N_Expanded_Name + and then + Entity (Pref) = Subp_Id + then + -- Detect duplicated items + + if Contains (Seen, Subp_Id) then + Error_Msg_N ("duplicate aspect % item", Param); + else + Append_New_Elmt (Entity (Pref), Seen); + end if; + + else + Error_Msg_N ("illegal aspect % item", Param); + end if; + end; + else + Error_Msg_N ("illegal aspect % item", Param); + end if; + end Analyze_Aspect_Parameter; + + -- Local variables + + Seen : Elist_Id := No_Elist; + -- Items that appear in the potentially invalid aspect + -- expression of a subprogram; for detecting duplicates. + + Restore_Scope : Boolean; + -- Will be set to True if we need to restore the scope table + -- after analyzing the aspect expression. + + -- Start of processing for Analyze_Aspect_Potentially_Invalid + + begin + -- Set name of the aspect for error messages + Error_Msg_Name_1 := Nam; + + -- Annotation of a variable; no aspect expression is allowed + + if Ekind (E) = E_Variable then + if Present (Expr) then + Error_Msg_N ("illegal aspect % expression", Expr); + end if; + + -- Annotation of a constant; no aspect expression is allowed. + -- For a deferred constant, the aspect must be attached to the + -- partial view. + + elsif Ekind (E) = E_Constant then + if Present (Incomplete_Or_Partial_View (E)) then + Error_Msg_N + ("aspect % must apply to deferred constant", N); + + elsif Present (Expr) then + Error_Msg_N ("illegal aspect % expression", Expr); + end if; + + -- Annotation of a subprogram; aspect expression is required + + elsif Is_Subprogram_Or_Entry (E) + or else Is_Generic_Subprogram (E) + then + + -- Not allowed for renaming declarations. Examine the + -- original node because a subprogram renaming may have been + -- rewritten as a body. + + if Nkind (Original_Node (N)) in N_Renaming_Declaration then + Error_Msg_N + ("aspect % not allowed for renaming declaration", + Aspect); + end if; + + if Present (Expr) then + + -- If we analyze subprogram body that acts as its own + -- spec, then the subprogram itself and its formals are + -- already installed; otherwise, we need to install them, + -- as they must be visible when analyzing the aspect + -- expression. + + if In_Open_Scopes (E) then + Restore_Scope := False; + else + Restore_Scope := True; + Push_Scope (E); + + -- Only formals of the subprogram itself can appear + -- in Potentially_Invalid aspect expression, not + -- formals of the enclosing generic unit. (This is + -- different than in Precondition or Depends aspects, + -- where both kinds of formals are allowed.) + + Install_Formals (E); + end if; + + -- Aspect expression is either an aggregate with list of + -- parameters (and possibly the Result attribute for a + -- function). + + if Nkind (Expr) = N_Aggregate then + + -- Component associations in the aggregate must be a + -- parameter name followed by a static boolean + -- expression. + + if Present (Component_Associations (Expr)) then + declare + Assoc : Node_Id := + First (Component_Associations (Expr)); + begin + while Present (Assoc) loop + if List_Length (Choices (Assoc)) = 1 then + Analyze_Aspect_Parameter + (E, First (Choices (Assoc)), Seen); + + if Inside_A_Generic then + Preanalyze_And_Resolve + (Expression (Assoc), Any_Boolean); + else + Analyze_And_Resolve + (Expression (Assoc), Any_Boolean); + end if; + + if not Is_OK_Static_Expression + (Expression (Assoc)) + then + Error_Msg_Name_1 := Nam; + Flag_Non_Static_Expr + ("expression of aspect % " & + "must be static!", Aspect); + end if; + + else + Error_Msg_Name_1 := Nam; + Error_Msg_N + ("illegal aspect % expression", Expr); + end if; + Next (Assoc); + end loop; + end; + end if; + + -- Expressions of the aggregate are parameter names + + if Present (Expressions (Expr)) then + declare + Param : Node_Id := First (Expressions (Expr)); + + begin + while Present (Param) loop + Analyze_Aspect_Parameter (E, Param, Seen); + Next (Param); + end loop; + end; + end if; + + -- Mark the aggregate expression itself as analyzed; + -- its subexpressions were marked when they themselves + -- were analyzed. + + Set_Analyzed (Expr); + + -- Otherwise, it is a single name of a subprogram + -- parameter (or possibly the Result attribute for + -- a function). + + else + Analyze_Aspect_Parameter (E, Expr, Seen); + end if; + + if Restore_Scope then + End_Scope; + end if; + + -- For instances of Ada.Unchecked_Conversion, allow a + -- parameterless aspect, as the 'Result attribute is not + -- defined there. + + elsif Is_Unchecked_Conversion_Instance (E) then + null; + else + Error_Msg_N ("missing expression for aspect %", N); + end if; + + else + Error_Msg_N ("inappropriate entity for aspect %", E); + end if; + end Analyze_Aspect_Potentially_Invalid; + ------------------------------------------- -- Analyze_Aspect_Relaxed_Initialization -- ------------------------------------------- @@ -3873,6 +4146,89 @@ package body Sem_Ch13 is goto Continue; end Initial_Condition; + -- Initialize + + when Aspect_Initialize => Initialize : declare + Aspect_Comp : Node_Id; + Type_Comp : Node_Id; + Typ : Entity_Id; + Dummy_Aggr : Node_Id; + begin + -- Error checking + + if not All_Extensions_Allowed then + goto Continue; + end if; + + if Ekind (E) /= E_Procedure then + Error_Msg_N ("Initialize must apply to a constructor", N); + end if; + + if Present (Expressions (Expression (Aspect))) then + Error_Msg_N ("only component associations allowed", N); + end if; + + -- Install the others for the aggregate if necessary + + Typ := Etype (First_Entity (E)); + + if No (First_Entity (Typ)) then + Error_Msg_N + ("Initialize can only apply to contructors" + & " whose type has one or more components", N); + end if; + + Aspect_Comp := + First (Component_Associations (Expression (Aspect))); + Type_Comp := First_Entity (Typ); + while Present (Type_Comp) loop + if No (Aspect_Comp) then + Append_To + (Component_Associations (Expression (Aspect)), + Make_Component_Association (Loc, + Choices => + New_List (Make_Others_Choice (Loc)), + Box_Present => True)); + exit; + elsif Nkind (First (Choices (Aspect_Comp))) + = N_Others_Choice + then + exit; + end if; + + Next (Aspect_Comp); + Next_Entity (Type_Comp); + end loop; + + -- Push the scope and formals for analysis + + Push_Scope (E); + Install_Formals (Defining_Unit_Name (Specification (N))); + + -- Analyze the components + + Aspect_Comp := + First (Component_Associations (Expression (Aspect))); + while Present (Aspect_Comp) loop + if Present (Expression (Aspect_Comp)) then + Analyze (Expression (Aspect_Comp)); + end if; + + Next (Aspect_Comp); + end loop; + + -- Do a psuedo pass over the aggregate to ensure it is valid + + Expander_Active := False; + Dummy_Aggr := New_Copy_Tree (Expression (Aspect)); + Resolve_Aggregate (Dummy_Aggr, Typ); + Expander_Active := True; + + -- Return the scope + + End_Scope; + end Initialize; + -- Initializes -- Aspect Initializes is never delayed because it is equivalent @@ -3990,6 +4346,12 @@ package body Sem_Ch13 is goto Continue; + -- Potentially_Invalid + + when Aspect_Potentially_Invalid => + Analyze_Aspect_Potentially_Invalid; + goto Continue; + -- SPARK_Mode when Aspect_SPARK_Mode => @@ -4279,6 +4641,7 @@ package body Sem_Ch13 is when Aspect_Designated_Storage_Model => if not All_Extensions_Allowed then + Error_Msg_Name_1 := Nam; Error_Msg_GNAT_Extension ("aspect %", Loc); goto Continue; @@ -4291,6 +4654,20 @@ package body Sem_Ch13 is goto Continue; end if; + when Aspect_Destructor => + if not All_Extensions_Allowed then + Error_Msg_Name_1 := Nam; + Error_Msg_GNAT_Extension ("aspect %", Loc); + goto Continue; + + elsif not Is_Type (E) then + Error_Msg_N ("can only be specified for a type", Aspect); + goto Continue; + end if; + + Set_Has_Destructor (E); + Set_Is_Controlled_Active (E); + when Aspect_Storage_Model_Type => if not All_Extensions_Allowed then Error_Msg_Name_1 := Nam; @@ -4346,6 +4723,10 @@ package body Sem_Ch13 is Analyze_Aspect_Implicit_Dereference; goto Continue; + when Aspect_Constructor => + Set_Constructor_Name (E, Expr); + Set_Needs_Construction (E); + -- Dimension when Aspect_Dimension => @@ -4366,8 +4747,9 @@ package body Sem_Ch13 is -- Case 4: Aspects requiring special handling -- Pre/Post/Test_Case/Contract_Cases/Always_Terminates/ - -- Exceptional_Cases/Exit_Cases and Subprogram_Variant whose - -- corresponding pragmas take care of the delay. + -- Exceptional_Cases/Exit_Cases/Program_Exit and + -- Subprogram_Variant whose corresponding pragmas take care of + -- the delay. -- Pre/Post @@ -4573,6 +4955,19 @@ package body Sem_Ch13 is Insert_Pragma (Aitem); goto Continue; + -- Program_Exit + + when Aspect_Program_Exit => + Aitem := Make_Aitem_Pragma + (Pragma_Argument_Associations => New_List ( + Make_Pragma_Argument_Association (Loc, + Expression => Relocate_Node (Expr))), + Pragma_Name => Name_Program_Exit); + + Decorate (Aspect, Aitem); + Insert_Pragma (Aitem); + goto Continue; + -- Subprogram_Variant when Aspect_Subprogram_Variant => @@ -4690,6 +5085,14 @@ package body Sem_Ch13 is Check_Expr_Is_OK_Static_Expression (Expr, Any_Boolean); end if; + -- Record the No_Task_Parts aspects as a rep item so it + -- can be consistently looked up on the full view of the + -- type. + + if Is_Private_Type (E) then + Record_Rep_Item (E, Aspect); + end if; + goto Continue; -- Ada 2022 (AI12-0075): static expression functions @@ -6105,6 +6508,7 @@ package body Sem_Ch13 is declare Expr : constant Node_Id := Expression (N); O_Ent : Entity_Id; + O_Typ : Entity_Id; Off : Boolean; begin @@ -6117,7 +6521,7 @@ package body Sem_Ch13 is return; end if; - Find_Overlaid_Entity (N, O_Ent, Off); + Find_Overlaid_Entity (N, O_Ent, O_Typ, Off); if Present (O_Ent) then @@ -6170,10 +6574,10 @@ package body Sem_Ch13 is if (Is_Record_Type (Etype (U_Ent)) or else Is_Array_Type (Etype (U_Ent))) - and then (Is_Record_Type (Etype (O_Ent)) - or else Is_Array_Type (Etype (O_Ent))) + and then (Is_Record_Type (O_Typ) + or else Is_Array_Type (O_Typ)) and then Reverse_Storage_Order (Etype (U_Ent)) /= - Reverse_Storage_Order (Etype (O_Ent)) + Reverse_Storage_Order (O_Typ) then Error_Msg_N ("??overlay changes scalar storage order", Expr); @@ -6278,11 +6682,6 @@ package body Sem_Ch13 is then Set_Check_Address_Alignment (N); end if; - - -- Kill the size check code, since we are not allocating - -- the variable, it is somewhere else. - - Kill_Size_Check_Code (U_Ent); end; -- Not a valid entity for an address clause @@ -6502,7 +6901,8 @@ package body Sem_Ch13 is -- and restored before and after analysis. Push_Type (U_Ent); - Preanalyze_Spec_Expression (Expr, RTE (RE_CPU_Range)); + Preanalyze_And_Resolve_Spec_Expression + (Expr, RTE (RE_CPU_Range)); Pop_Type (U_Ent); -- AI12-0117-1, "Restriction No_Tasks_Unassigned_To_CPU": @@ -6592,10 +6992,8 @@ package body Sem_Ch13 is -- The visibility to the components must be restored Push_Type (U_Ent); - - Preanalyze_Spec_Expression + Preanalyze_And_Resolve_Spec_Expression (Expr, RTE (RE_Dispatching_Domain)); - Pop_Type (U_Ent); end if; @@ -6674,10 +7072,8 @@ package body Sem_Ch13 is -- The visibility to the components must be restored Push_Type (U_Ent); - - Preanalyze_Spec_Expression + Preanalyze_And_Resolve_Spec_Expression (Expr, RTE (RE_Interrupt_Priority)); - Pop_Type (U_Ent); -- Check the No_Task_At_Interrupt_Priority restriction @@ -6843,7 +7239,8 @@ package body Sem_Ch13 is -- The visibility to the components must be restored Push_Type (U_Ent); - Preanalyze_Spec_Expression (Expr, Standard_Integer); + Preanalyze_And_Resolve_Spec_Expression + (Expr, Standard_Integer); Pop_Type (U_Ent); if not Is_OK_Static_Expression (Expr) then @@ -7154,7 +7551,7 @@ package body Sem_Ch13 is else Small := Expr_Value_R (Expr); - if Small <= Ureal_0 then + if not UR_Is_Positive (Small) then Error_Msg_N ("small value must be greater than zero", Expr); return; end if; @@ -8494,6 +8891,43 @@ package body Sem_Ch13 is Num_Repped_Components : Nat := 0; Num_Unrepped_Components : Nat := 0; + function Unchecked_Union_Pragma_Pending return Boolean; + -- Return True in the corner case of an Unchecked_Union pragma + -- occuring after the record representation clause (which + -- means that Is_Unchecked_Union will return False for Rectype, + -- even though it would return True if called later after the + -- pragma is analyzed). + + ------------------------------------ + -- Unchecked_Union_Pragma_Pending -- + ------------------------------------ + + function Unchecked_Union_Pragma_Pending return Boolean is + Decl_List_Element : Node_Id := N; + Pragma_Arg : Node_Id; + begin + while Present (Decl_List_Element) loop + if Nkind (Decl_List_Element) = N_Pragma + and then Get_Pragma_Id (Decl_List_Element) = + Pragma_Unchecked_Union + and then not Is_Empty_List (Pragma_Argument_Associations + (Decl_List_Element)) + then + Pragma_Arg := Get_Pragma_Arg + (First (Pragma_Argument_Associations + (Decl_List_Element))); + if Nkind (Pragma_Arg) = N_Identifier + and then Chars (Pragma_Arg) = Chars (Rectype) + then + return True; + end if; + end if; + + Next (Decl_List_Element); + end loop; + return False; + end Unchecked_Union_Pragma_Pending; + begin -- First count number of repped and unrepped components @@ -8532,8 +8966,10 @@ package body Sem_Ch13 is -- Ignore discriminant in unchecked union, since it is -- not there, and cannot have a component clause. - and then (not Is_Unchecked_Union (Rectype) - or else Ekind (Comp) /= E_Discriminant) + and then (Ekind (Comp) /= E_Discriminant + or else not (Is_Unchecked_Union (Rectype) + or else + Unchecked_Union_Pragma_Pending)) then Error_Msg_Sloc := Sloc (Comp); Error_Msg_NE @@ -9889,6 +10325,12 @@ package body Sem_Ch13 is -- Includes a call to the predicate function for type T in Expr if -- Predicate_Function (T) is non-empty. + function Has_Source_Predicate (T : Entity_Id) return Boolean; + -- Return True if one of the 3 predicate aspects is specified + -- explicitly (either via a pragma or an aspect specification, but + -- not implicitly via propagation from some other type/subtype via + -- RM 3.2.4(5)) for the type/subtype T. + procedure Replace_Current_Instance_References (N : Node_Id; Typ, New_Entity : Entity_Id); -- Replace all references to Typ in the tree rooted at N with @@ -10039,8 +10481,8 @@ package body Sem_Ch13 is -- If the predicate pragma comes from an aspect, replace the -- saved expression because we need the subtype references - -- replaced for the calls to Preanalyze_Spec_Expression in - -- Check_Aspect_At_xxx routines. + -- replaced for the calls to Preanalyze_And_Resolve_Spec_ + -- Expression in Check_Aspect_At_xxx routines. if Present (Asp) then Set_Expression_Copy (Asp, New_Copy_Tree (Arg2_Copy)); @@ -10105,6 +10547,41 @@ package body Sem_Ch13 is end loop; end Add_Predicates; + -------------------------- + -- Has_Source_Predicate -- + -------------------------- + + function Has_Source_Predicate (T : Entity_Id) return Boolean is + Rep_Item : Node_Id := First_Rep_Item (T); + begin + while Present (Rep_Item) loop + case Nkind (Rep_Item) is + when N_Pragma => + if Get_Pragma_Id (Rep_Item) = Pragma_Predicate + and then T = Entity (Expression + (First (Pragma_Argument_Associations (Rep_Item)))) + then + return True; + end if; + + when N_Aspect_Specification => + if Get_Aspect_Id (Rep_Item) in + Aspect_Static_Predicate + | Aspect_Dynamic_Predicate | Aspect_Predicate + and then Entity (Rep_Item) = T + then + return True; + end if; + + when others => + null; + end case; + + Next_Rep_Item (Rep_Item); + end loop; + return False; + end Has_Source_Predicate; + ----------------------------------------- -- Replace_Current_Instance_References -- ----------------------------------------- @@ -10148,6 +10625,21 @@ package body Sem_Ch13 is -- context where expansion and tests are enabled. SId := Predicate_Function (Typ); + + -- When declaring a subtype S whose "predecessor" subtype PS (that is, + -- the subtype denoted by the subtype_mark in the declaration of S) + -- already has a predicate function, do not confuse that existing + -- function for PS with the function we need to build for S if + -- Has_Source_Predicate returns True for S. + + if Present (SId) + and then Nkind (Parent (Typ)) = N_Subtype_Declaration + and then Etype (First_Entity (SId)) /= Typ + and then Has_Source_Predicate (Typ) + then + SId := Empty; + end if; + if not Has_Predicates (Typ) or else (Present (SId) and then Has_Completion (SId)) or else @@ -10778,6 +11270,13 @@ package body Sem_Ch13 is -- Start of processing for Check_Aspect_At_End_Of_Declarations begin + -- Indicate that the expression comes from an aspect specification, + -- which is used in subsequent analysis even if expansion is off. + + if Present (End_Decl_Expr) then + Set_Parent (End_Decl_Expr, ASN); + end if; + -- In an instance we do not perform the consistency check between freeze -- point and end of declarations, because it was done already in the -- analysis of the generic. Furthermore, the delayed analysis of an @@ -10806,7 +11305,9 @@ package body Sem_Ch13 is -- name, so we need to verify that one of these interpretations is -- the one available at at the freeze point. - elsif A_Id in Aspect_Input + elsif A_Id in Aspect_Constructor + | Aspect_Destructor + | Aspect_Input | Aspect_Output | Aspect_Read | Aspect_Write @@ -10853,12 +11354,14 @@ package body Sem_Ch13 is | Aspect_Static_Predicate then Push_Type (Ent); - Preanalyze_Spec_Expression (Freeze_Expr, Standard_Boolean); + Preanalyze_And_Resolve_Spec_Expression + (Freeze_Expr, Standard_Boolean); Pop_Type (Ent); elsif A_Id = Aspect_Priority then Push_Type (Ent); - Preanalyze_Spec_Expression (Freeze_Expr, Any_Integer); + Preanalyze_And_Resolve_Spec_Expression + (Freeze_Expr, Any_Integer); Pop_Type (Ent); else @@ -10866,13 +11369,6 @@ package body Sem_Ch13 is end if; end if; - -- Indicate that the expression comes from an aspect specification, - -- which is used in subsequent analysis even if expansion is off. - - if Present (End_Decl_Expr) then - Set_Parent (End_Decl_Expr, ASN); - end if; - -- In a generic context the original aspect expressions have not -- been preanalyzed, so do it now. There are no conformance checks -- to perform in this case. As before, we have to make components @@ -10908,7 +11404,8 @@ package body Sem_Ch13 is elsif A_Id in Aspect_Default_Component_Value | Aspect_Default_Value and then Is_Private_Type (T) then - Preanalyze_Spec_Expression (End_Decl_Expr, Full_View (T)); + Preanalyze_And_Resolve_Spec_Expression + (End_Decl_Expr, Full_View (T)); -- The following aspect expressions may contain references to -- components and discriminants of the type. @@ -10922,14 +11419,15 @@ package body Sem_Ch13 is | Aspect_Static_Predicate then Push_Type (Ent); - Preanalyze_Spec_Expression (End_Decl_Expr, T); + Preanalyze_And_Resolve_Spec_Expression (End_Decl_Expr, T); Pop_Type (Ent); elsif A_Id = Aspect_Predicate_Failure then - Preanalyze_Spec_Expression (End_Decl_Expr, Standard_String); + Preanalyze_And_Resolve_Spec_Expression + (End_Decl_Expr, Standard_String); elsif Present (End_Decl_Expr) then - Preanalyze_Spec_Expression (End_Decl_Expr, T); + Preanalyze_And_Resolve_Spec_Expression (End_Decl_Expr, T); end if; Err := @@ -10978,24 +11476,16 @@ package body Sem_Ch13 is ---------------------------------- procedure Check_Aspect_At_Freeze_Point (ASN : Node_Id) is - Ident : constant Node_Id := Identifier (ASN); - -- Identifier (use Entity field to save expression) - Expr : constant Node_Id := Expression (ASN); - -- For cases where using Entity (Identifier) doesn't work - A_Id : constant Aspect_Id := Get_Aspect_Id (Chars (Ident)); + A_Id : constant Aspect_Id := Get_Aspect_Id (Chars (Identifier (ASN))); T : Entity_Id := Empty; -- Type required for preanalyze call begin - -- On entry to this procedure, Entity (Ident) contains a copy of the - -- original expression from the aspect, saved for this purpose. - - -- On exit from this procedure Entity (Ident) is unchanged, still - -- containing that copy, but Expression (Ident) is a preanalyzed copy - -- of the expression, preanalyzed just after the freeze point. + -- On exit from this procedure, Expression (ASN) is a copy of the + -- original expression, preanalyzed just after the freeze point. -- Make a copy of the expression to be preanalyzed @@ -11112,7 +11602,8 @@ package body Sem_Ch13 is -- Special case, the expression of these aspects is just an entity -- that does not need any resolution, so just analyze. - when Aspect_Input + when Aspect_Constructor + | Aspect_Input | Aspect_Output | Aspect_Put_Image | Aspect_Read @@ -11273,6 +11764,67 @@ package body Sem_Ch13 is Analyze (Expression (ASN)); return; + when Aspect_Destructor => + if not Is_Record_Type (Entity (ASN)) then + Error_Msg_N + ("aspect Destructor can only be specified for a " + & "record type", + ASN); + return; + end if; + + Set_Has_Destructor (Entity (ASN)); + Set_Is_Controlled_Active (Entity (ASN)); + + Analyze (Expression (ASN)); + + if not Resolve_Finalization_Procedure + (Expression (ASN), Entity (ASN)) + then + Error_Msg_N + ("destructor must be local procedure whose only formal " + & "parameter has mode `IN OUT` and is of the type the " + & "destructor is for", + Expression (ASN)); + end if; + + Set_Is_Destructor (Entity (Expression (ASN))); + + declare + Proc : constant Entity_Id := Entity (Expression (ASN)); + Overr : constant Opt_N_Entity_Id := + Overridden_Inherited_Operation (Proc); + Orig : constant Entity_Id := + (if Present (Overr) then Overr else Proc); + + Decl : constant Node_Id := + Parent + (if Nkind (Parent (Orig)) = N_Procedure_Specification + then Parent (Orig) + else Orig); + + Encl : constant Node_Id := Parent (Decl); + + Is_Private : constant Boolean := + Nkind (Encl) = N_Package_Specification + and then Is_List_Member (Decl) + and then List_Containing (Decl) = Private_Declarations (Encl); + + begin + + if Has_Private_Declaration (Entity (ASN)) + and then not Aspect_On_Partial_View (ASN) + and then not Is_Private + then + Error_Msg_N + ("aspect Destructor on full view cannot denote public " + & "primitive", + ASN); + end if; + end; + + return; + when Aspect_Storage_Model_Type => -- The aggregate argument of Storage_Model_Type is optional, and @@ -11324,6 +11876,7 @@ package body Sem_Ch13 is | Aspect_GNAT_Annotate | Aspect_Implicit_Dereference | Aspect_Initial_Condition + | Aspect_Initialize | Aspect_Initializes | Aspect_Max_Entry_Queue_Length | Aspect_Max_Queue_Length @@ -11331,8 +11884,10 @@ package body Sem_Ch13 is | Aspect_Part_Of | Aspect_Post | Aspect_Postcondition + | Aspect_Potentially_Invalid | Aspect_Pre | Aspect_Precondition + | Aspect_Program_Exit | Aspect_Refined_Depends | Aspect_Refined_Global | Aspect_Refined_Post @@ -11359,7 +11914,7 @@ package body Sem_Ch13 is -- the aspect_specification cause freezing (RM 13.14(7.2/5)). if Present (Expression (ASN)) then - Preanalyze_Spec_Expression (Expression (ASN), T); + Preanalyze_And_Resolve_Spec_Expression (Expression (ASN), T); end if; end Check_Aspect_At_Freeze_Point; @@ -12082,18 +12637,15 @@ package body Sem_Ch13 is if not Check_Primitive_Function (Subp, Typ) then if Present (Ref_Node) then - if Debug_Flag_Underscore_DD then - Record_Default_Iterator_Not_Primitive_Error - (Ref_Node, Subp); - else - Error_Msg_N ("improper function for default iterator!", - Ref_Node); - Error_Msg_Sloc := Sloc (Subp); - Error_Msg_NE - ("\\default iterator defined # " - & "must be a local primitive or class-wide function", - Ref_Node, Subp); - end if; + Error_Msg_N + ("improper function for default iterator!", + Ref_Node, + GNAT0001); + Error_Msg_Sloc := Sloc (Subp); + Error_Msg_NE + ("\\default iterator defined # " + & "must be a local primitive or class-wide function", + Ref_Node, Subp); end if; return False; @@ -13928,7 +14480,7 @@ package body Sem_Ch13 is Next (First (Pragma_Argument_Associations (Ritem))); begin Push_Type (E); - Preanalyze_Spec_Expression + Preanalyze_And_Resolve_Spec_Expression (Expression (Arg), Standard_Boolean); Pop_Type (E); end; @@ -15426,6 +15978,8 @@ package body Sem_Ch13 is -- We may freeze Subp_Id immediately since Ent has just been frozen. -- This will help to shield us from potential late freezing issues. + Mutate_Ekind (Subp_Id, E_Procedure); + Freeze_Extra_Formals (Subp_Id); Set_Is_Frozen (Subp_Id); else @@ -15786,27 +16340,36 @@ package body Sem_Ch13 is -- anyway, no reason to be too strict about this. if not Relaxed_RM_Semantics then - if Debug_Flag_Underscore_DD then - - S := First_Subtype (T); - if Present (Freeze_Node (S)) then - Record_Representation_Too_Late_Error - (Rep => N, - Freeze => Freeze_Node (S), - Def => S); - else - Error_Msg_N ("|representation item appears too late!", N); - end if; - + S := First_Subtype (T); + if Present (Freeze_Node (S)) then + Error_Msg_N + (Msg => + "record representation cannot be specified" & + " after the type is frozen", + N => N, + Error_Code => GNAT0005, + Label => + "record representation clause specified here", + Spans => + (1 => + Secondary_Labeled_Span + (N => Freeze_Node (S), + Label => + "Type " & To_Name (S) & + " is frozen here"), + 2 => + Secondary_Labeled_Span + (N => S, + Label => + "Type " & To_Name (S) & + " is declared here"))); + Error_Msg_Sloc := Sloc (Freeze_Node (S)); + Error_Msg_N + ("\\move the record representation clause" & + " before the freeze point #", + N); else Error_Msg_N ("|representation item appears too late!", N); - - S := First_Subtype (T); - if Present (Freeze_Node (S)) then - Error_Msg_NE - ("??no more representation items for }", - Freeze_Node (S), S); - end if; end if; end if; end Too_Late; @@ -16345,6 +16908,9 @@ package body Sem_Ch13 is => null; + when Aspect_Constructor => + null; + when Aspect_Dynamic_Predicate | Aspect_Ghost_Predicate | Aspect_Predicate @@ -16860,6 +17426,35 @@ package body Sem_Ch13 is (N : Node_Id; Typ : Entity_Id; Nam : Name_Id) + is + begin + if Nam = Name_Relaxed_Finalization then + Resolve (N, Any_Boolean); + + if Is_OK_Static_Expression (N) then + Set_Has_Relaxed_Finalization (Typ, Is_True (Static_Boolean (N))); + + else + Flag_Non_Static_Expr + ("expression of aspect Finalizable must be static!", N); + end if; + + return; + end if; + + if Resolve_Finalization_Procedure (N, Typ) then + return; + end if; + + Error_Msg_N + ("finalizable primitive must be local procedure whose only formal " & + "parameter has mode `IN OUT` and is of the finalizable type", N); + end Resolve_Finalizable_Argument; + + function Resolve_Finalization_Procedure + (N : Node_Id; + Typ : Entity_Id) + return Boolean is function Is_Finalizable_Primitive (E : Entity_Id) return Boolean; -- Check whether E is a finalizable primitive for Typ @@ -16878,29 +17473,15 @@ package body Sem_Ch13 is and then No (Next_Formal (First_Formal (E))); end Is_Finalizable_Primitive; - -- Start of processing for Resolve_Finalizable_Argument + -- Start of processing for Resolve_Finalization_Procedure begin - if Nam = Name_Relaxed_Finalization then - Resolve (N, Any_Boolean); - - if Is_OK_Static_Expression (N) then - Set_Has_Relaxed_Finalization (Typ, Is_True (Static_Boolean (N))); - - else - Flag_Non_Static_Expr - ("expression of aspect Finalizable must be static!", N); - end if; - - return; - end if; - if not Is_Entity_Name (N) then null; elsif not Is_Overloaded (N) then if Is_Finalizable_Primitive (Entity (N)) then - return; + return True; end if; else @@ -16916,7 +17497,7 @@ package body Sem_Ch13 is while Present (It.Typ) loop if Is_Finalizable_Primitive (It.Nam) then Set_Entity (N, It.Nam); - return; + return True; end if; Get_Next_Interp (I, It); @@ -16924,10 +17505,8 @@ package body Sem_Ch13 is end; end if; - Error_Msg_N - ("finalizable primitive must be local procedure whose only formal " & - "parameter has mode `IN OUT` and is of the finalizable type", N); - end Resolve_Finalizable_Argument; + return False; + end Resolve_Finalization_Procedure; -------------------------------- -- Resolve_Iterable_Operation -- diff --git a/gcc/ada/sem_ch13.ads b/gcc/ada/sem_ch13.ads index 9bf1ce310c5a..f2c5f7062007 100644 --- a/gcc/ada/sem_ch13.ads +++ b/gcc/ada/sem_ch13.ads @@ -43,8 +43,7 @@ package Sem_Ch13 is procedure Analyze_Aspect_Specifications (N : Node_Id; E : Entity_Id); -- This procedure is called to analyze aspect specifications for node N. E - -- is the corresponding entity declared by the declaration node N. Callers - -- should check that Has_Aspects (N) is True before calling this routine. + -- is the corresponding entity declared by the declaration node N. procedure Analyze_Aspects_On_Subprogram_Body_Or_Stub (N : Node_Id); -- Analyze the aspect specifications of [generic] subprogram body or stub diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index 74eac9c9789c..55d2795f2b12 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -41,7 +41,6 @@ with Exp_Disp; use Exp_Disp; with Exp_Dist; use Exp_Dist; with Exp_Tss; use Exp_Tss; with Exp_Util; use Exp_Util; -with Expander; use Expander; with Fmap; with Freeze; use Freeze; with Ghost; use Ghost; @@ -291,6 +290,15 @@ package body Sem_Ch3 is -- Check that the expression represented by E is suitable for use as a -- digits expression, i.e. it is of integer type, positive and static. + procedure Check_Discriminant_Conformance + (N : Node_Id; + Prev : Entity_Id; + Prev_Loc : Node_Id); + -- Check that the discriminants of a full type N fully conform to the + -- discriminants of the corresponding partial view Prev. Prev_Loc indicates + -- the source location of the partial view, which may be different than + -- Prev in the case of private types. + procedure Check_Initialization (T : Entity_Id; Exp : Node_Id); -- Validate the initialization of an object declaration. T is the required -- type, and Exp is the initialization expression. @@ -383,7 +391,7 @@ package body Sem_Ch3 is -- created in the procedure and attached to Related_Nod. procedure Constrain_Array - (Def_Id : in out Entity_Id; + (Def_Id : Entity_Id; SI : Node_Id; Related_Nod : Node_Id; Related_Id : Entity_Id; @@ -623,9 +631,11 @@ package body Sem_Ch3 is -- Create a new ordinary fixed point type, and apply the constraint to -- obtain subtype of it. - procedure Preanalyze_Default_Expression (N : Node_Id; T : Entity_Id); - -- Wrapper on Preanalyze_Spec_Expression for default expressions, so that - -- In_Default_Expr can be properly adjusted. + procedure Preanalyze_And_Resolve_Default_Expression + (N : Node_Id; + T : Entity_Id); + -- Wrapper on Preanalyze_And_Resolve_Spec_Expression for default + -- expressions, so that In_Default_Expr can be properly adjusted. procedure Prepare_Private_Subtype_Completion (Id : Entity_Id; @@ -1307,14 +1317,6 @@ package body Sem_Ch3 is Reinit_Size_Align (T_Name); Set_Directly_Designated_Type (T_Name, Desig_Type); - -- If the access_to_subprogram is not declared at the library level, - -- it can only point to subprograms that are at the same or deeper - -- accessibility level. The corresponding subprogram type might - -- require an activation record when compiling for C. - - Set_Needs_Activation_Record (Desig_Type, - not Is_Library_Level_Entity (T_Name)); - Generate_Reference_To_Formals (T_Name); -- Ada 2005 (AI-231): Propagate the null-excluding attribute @@ -1421,7 +1423,9 @@ package body Sem_Ch3 is end if; else - Setup_Access_Type (Desig_Typ => Process_Subtype (S, P, T, 'P')); + Setup_Access_Type + (Desig_Typ => + Process_Subtype (S, P, T, 'P', Incomplete_Type_OK => True)); end if; if not Error_Posted (T) then @@ -1958,7 +1962,7 @@ package body Sem_Ch3 is procedure Analyze_Component_Declaration (N : Node_Id) is Id : constant Entity_Id := Defining_Identifier (N); E : constant Node_Id := Expression (N); - Typ : constant Node_Id := + Ind : constant Node_Id := Subtype_Indication (Component_Definition (N)); T : Entity_Id; P : Entity_Id; @@ -2053,10 +2057,11 @@ package body Sem_Ch3 is -- Start of processing for Analyze_Component_Declaration begin + Mutate_Ekind (Id, E_Component); Generate_Definition (Id); Enter_Name (Id); - if Present (Typ) then + if Present (Ind) then T := Find_Type_Of_Object (Subtype_Indication (Component_Definition (N)), N); @@ -2110,7 +2115,7 @@ package body Sem_Ch3 is -- package Sem). if Present (E) then - Preanalyze_Default_Expression (E, T); + Preanalyze_And_Resolve_Default_Expression (E, T); Check_Initialization (T, E); if Ada_Version >= Ada_2005 @@ -2507,7 +2512,8 @@ package body Sem_Ch3 is (First (Pragma_Argument_Associations (ASN)))); Set_Parent (Exp, ASN); - Preanalyze_Assert_Expression (Exp, Standard_Boolean); + Preanalyze_And_Resolve_Assert_Expression + (Exp, Standard_Boolean); end if; ASN := Next_Pragma (ASN); @@ -3014,6 +3020,8 @@ package body Sem_Ch3 is ----------------------------------- procedure Analyze_Full_Type_Declaration (N : Node_Id) is + use Deferred_Extra_Formals_Support; + Def : constant Node_Id := Type_Definition (N); Def_Id : constant Entity_Id := Defining_Identifier (N); T : Entity_Id; @@ -3200,7 +3208,7 @@ package body Sem_Ch3 is and then Present (Full_View (Prev)) then T := Full_View (Prev); - Set_Incomplete_View (N, Prev); + Set_Incomplete_View (T, Prev); else T := Prev; end if; @@ -3551,6 +3559,23 @@ package body Sem_Ch3 is end; end if; end if; + + -- If we have some subprogram, subprogram type, or entry, with deferred + -- addition of its extra formals (because the underlying type of this + -- type was not previously available), then try creating now its extra + -- formals. Create also the extra actuals of deferred calls to entities + -- with deferred extra formals. + + if Has_Deferred_Extra_Formals (T) then + Add_Deferred_Extra_Params (T); + end if; + + if Ekind (T) = E_Record_Type + and then Is_Large_Unconstrained_Definite (T) + and then not Is_Limited_Type (T) + then + Error_Msg_N ("??creation of & object may raise Storage_Error!", T); + end if; end Analyze_Full_Type_Declaration; ---------------------------------- @@ -3700,8 +3725,8 @@ package body Sem_Ch3 is Set_Is_Static_Expression (E, True); Set_Etype (E, Universal_Integer); - Set_Etype (Id, Universal_Integer); Mutate_Ekind (Id, E_Named_Integer); + Set_Etype (Id, Universal_Integer); Set_Is_Frozen (Id, True); Set_Debug_Info_Needed (Id); @@ -3761,8 +3786,8 @@ package body Sem_Ch3 is if Is_Integer_Type (T) then Resolve (E, T); - Set_Etype (Id, Universal_Integer); Mutate_Ekind (Id, E_Named_Integer); + Set_Etype (Id, Universal_Integer); elsif Is_Real_Type (T) then @@ -3793,15 +3818,15 @@ package body Sem_Ch3 is end if; Resolve (E, T); - Set_Etype (Id, Universal_Real); Mutate_Ekind (Id, E_Named_Real); + Set_Etype (Id, Universal_Real); else Wrong_Type (E, Any_Numeric); Resolve (E, T); - Set_Etype (Id, T); Mutate_Ekind (Id, E_Constant); + Set_Etype (Id, T); Set_Never_Set_In_Source (Id, True); Set_Is_True_Constant (Id, True); return; @@ -3950,7 +3975,7 @@ package body Sem_Ch3 is Data_Path_String : constant String := Absolute_Dir & System.OS_Lib.Directory_Separator - & Stringt.To_String (Strval (Def)); + & S; begin Data_Path := Name_Find (Data_Path_String); @@ -4150,7 +4175,7 @@ package body Sem_Ch3 is procedure Check_Return_Subtype_Indication (Obj_Decl : Node_Id) is Obj_Id : constant Entity_Id := Defining_Identifier (Obj_Decl); - Obj_Typ : constant Entity_Id := Etype (Obj_Id); + Obj_Typ : Entity_Id := Etype (Obj_Id); Func_Id : constant Entity_Id := Return_Applies_To (Scope (Obj_Id)); R_Typ : constant Entity_Id := Etype (Func_Id); Indic : constant Node_Id := @@ -4186,6 +4211,15 @@ package body Sem_Ch3 is return; end if; + -- The return object type could have been rewritten into a + -- constrained type, so for the legality checks that follow we need + -- to recover the nominal unconstrained type. + + if Is_Constr_Subt_For_U_Nominal (Obj_Typ) then + Obj_Typ := Entity (Original_Node (Object_Definition (Obj_Decl))); + pragma Assert (not Is_Constrained (Obj_Typ)); + end if; + -- "return access T" case; check that the return statement also has -- "access T", and that the subtypes statically match: -- if this is an access to subprogram the signatures must match. @@ -4254,7 +4288,7 @@ package body Sem_Ch3 is -- AI05-103: for elementary types, subtypes must statically match - if Is_Constrained (R_Typ) or else Is_Access_Type (R_Typ) then + if Is_Elementary_Type (R_Typ) then if not Subtypes_Statically_Match (Obj_Typ, R_Typ) then Error_No_Match (Indic); end if; @@ -4270,13 +4304,12 @@ package body Sem_Ch3 is -- code is expanded on the basis of the base type (see subprogram -- Stream_Base_Type). - elsif Nkind (Indic) = N_Subtype_Indication - and then not Subtypes_Statically_Compatible (Obj_Typ, R_Typ) + elsif not Subtypes_Statically_Compatible (Obj_Typ, R_Typ) and then not Is_TSS (Func_Id, TSS_Stream_Input) then Error_Msg_N ("result subtype must be statically compatible with the " & - "function result type", Indic); + "function result subtype", Indic); if not Predicates_Compatible (Obj_Typ, R_Typ) then Error_Msg_NE @@ -4363,6 +4396,12 @@ package body Sem_Ch3 is -- Start of processing for Analyze_Object_Declaration begin + if Constant_Present (N) then + Mutate_Ekind (Id, E_Constant); + else + Mutate_Ekind (Id, E_Variable); + end if; + -- There are three kinds of implicit types generated by an -- object declaration: @@ -4442,7 +4481,6 @@ package body Sem_Ch3 is T := Find_Type_Of_Object (Object_Definition (N), N); Set_Etype (Id, T); - Mutate_Ekind (Id, E_Variable); goto Leave; end if; @@ -4468,7 +4506,6 @@ package body Sem_Ch3 is if Error_Posted (Id) then Set_Etype (Id, T); - Mutate_Ekind (Id, E_Variable); goto Leave; end if; end if; @@ -4551,7 +4588,6 @@ package body Sem_Ch3 is Error_Msg_N ("\declaration requires an initialization expression", N); - Set_Constant_Present (N, False); -- In Ada 83, deferred constant must be of private type @@ -4658,9 +4694,7 @@ package body Sem_Ch3 is Set_Has_Completion (Id); end if; - -- Set type and resolve (type may be overridden later on). Note: - -- Ekind (Id) must still be E_Void at this point so that incorrect - -- early usage within E is properly diagnosed. + -- Set type and resolve (type may be overridden later on) Set_Etype (Id, T); @@ -4760,7 +4794,6 @@ package body Sem_Ch3 is and then In_Subrange_Of (Etype (Entity (E)), T) then Set_Is_Known_Valid (Id); - Mutate_Ekind (Id, E_Constant); Set_Actual_Subtype (Id, Etype (Entity (E))); end if; @@ -4991,7 +5024,7 @@ package body Sem_Ch3 is if Is_Array_Type (T) and then No_Initialization (N) - and then Nkind (Original_Node (E)) = N_Aggregate + and then Nkind (Unqualify (Original_Node (E))) = N_Aggregate then Act_T := Etype (E); @@ -5009,12 +5042,6 @@ package body Sem_Ch3 is -- for discriminants and are thus not indefinite. elsif Is_Unchecked_Union (T) then - if Constant_Present (N) or else Nkind (E) = N_Function_Call then - Mutate_Ekind (Id, E_Constant); - else - Mutate_Ekind (Id, E_Variable); - end if; - -- If the expression is an aggregate it contains the required -- discriminant values but it has not been resolved yet, so do -- it now, and treat it as the initial expression of an object @@ -5075,10 +5102,8 @@ package body Sem_Ch3 is -- "X : Integer := X;". if Constant_Present (N) then - Mutate_Ekind (Id, E_Constant); Set_Is_True_Constant (Id); else - Mutate_Ekind (Id, E_Variable); if Present (E) then Set_Has_Initial_Value (Id); end if; @@ -5137,10 +5162,7 @@ package body Sem_Ch3 is elsif Is_Array_Type (T) and then No_Initialization (N) - and then (Nkind (Original_Node (E)) = N_Aggregate - or else (Nkind (Original_Node (E)) = N_Qualified_Expression - and then Nkind (Original_Node (Expression - (Original_Node (E)))) = N_Aggregate)) + and then Nkind (Unqualify (Original_Node (E))) = N_Aggregate then if not Is_Entity_Name (Object_Definition (N)) then Act_T := Etype (E); @@ -5223,12 +5245,9 @@ package body Sem_Ch3 is end if; if Constant_Present (N) then - Mutate_Ekind (Id, E_Constant); Set_Is_True_Constant (Id); else - Mutate_Ekind (Id, E_Variable); - -- A variable is set as shared passive if it appears in a shared -- passive package, and is at the outer level. This is not done for -- entities generated during expansion, because those are always @@ -5329,17 +5348,14 @@ package body Sem_Ch3 is else Validate_Controlled_Object (Id); end if; + end if; - -- If the type of a constrained array has an unconstrained first - -- subtype, its Finalize_Address primitive expects the address of - -- an object with a dope vector (see Make_Finalize_Address_Stmts). + -- If the type of a constrained array has an unconstrained first + -- subtype, its Finalize_Address primitive expects the address of + -- an object with a dope vector (see Make_Finalize_Address_Stmts). - if Is_Array_Type (Etype (Id)) - and then Is_Constrained (Etype (Id)) - and then not Is_Constrained (First_Subtype (Etype (Id))) - then - Set_Is_Constr_Array_Subt_With_Bounds (Etype (Id)); - end if; + if Is_Constr_Array_Subt_Of_Unc_With_Controlled (Etype (Id)) then + Set_Is_Constr_Array_Subt_With_Bounds (Etype (Id)); end if; if Has_Task (Etype (Id)) then @@ -5738,6 +5754,25 @@ package body Sem_Ch3 is Id : constant Entity_Id := Defining_Identifier (N); T : Entity_Id; + procedure Copy_Parent_Attributes; + -- Copy fields that don't depend on the type kind from the subtype + -- denoted by the subtype mark. + + ---------------------------- + -- Copy_Parent_Attributes -- + ---------------------------- + + procedure Copy_Parent_Attributes is + begin + Set_Etype (Id, Base_Type (T)); + Set_Is_Volatile (Id, Is_Volatile (T)); + Set_Treat_As_Volatile (Id, Treat_As_Volatile (T)); + Set_Is_Generic_Type (Id, Is_Generic_Type (Base_Type (T))); + Set_Convention (Id, Convention (T)); + end Copy_Parent_Attributes; + + -- Start of processing for Analyze_Subtype_Declaration + begin Generate_Definition (Id); Set_Is_Pure (Id, Is_Pure (Current_Scope)); @@ -5781,7 +5816,15 @@ package body Sem_Ch3 is Enter_Name (Id); end if; - T := Process_Subtype (Subtype_Indication (N), N, Id, 'P'); + T := + Process_Subtype + (Subtype_Indication (N), + N, + Id, + 'P', + Excludes_Null => Null_Exclusion_Present (N), + Incomplete_Type_OK => + Ada_Version >= Ada_2005 or else Is_Itype (Id)); -- Class-wide equivalent types of records with unknown discriminants -- involve the generation of an itype which serves as the private view @@ -5796,13 +5839,6 @@ package body Sem_Ch3 is T := Full_View (T); end if; - -- Inherit common attributes - - Set_Is_Volatile (Id, Is_Volatile (T)); - Set_Treat_As_Volatile (Id, Treat_As_Volatile (T)); - Set_Is_Generic_Type (Id, Is_Generic_Type (Base_Type (T))); - Set_Convention (Id, Convention (T)); - -- If ancestor has predicates then so does the subtype, and in addition -- we must delay the freeze to properly arrange predicate inheritance. @@ -5842,16 +5878,16 @@ package body Sem_Ch3 is -- semantic attributes must be established here. if Nkind (Subtype_Indication (N)) /= N_Subtype_Indication then - Set_Etype (Id, Base_Type (T)); - case Ekind (T) is when Array_Kind => Mutate_Ekind (Id, E_Array_Subtype); + Copy_Parent_Attributes; Copy_Array_Subtype_Attributes (Id, T); Set_Packed_Array_Impl_Type (Id, Packed_Array_Impl_Type (T)); when Decimal_Fixed_Point_Kind => Mutate_Ekind (Id, E_Decimal_Fixed_Point_Subtype); + Copy_Parent_Attributes; Set_Digits_Value (Id, Digits_Value (T)); Set_Delta_Value (Id, Delta_Value (T)); Set_Scale_Value (Id, Scale_Value (T)); @@ -5864,6 +5900,7 @@ package body Sem_Ch3 is when Enumeration_Kind => Mutate_Ekind (Id, E_Enumeration_Subtype); + Copy_Parent_Attributes; Set_First_Literal (Id, First_Literal (Base_Type (T))); Set_Scalar_Range (Id, Scalar_Range (T)); Set_Is_Character_Type (Id, Is_Character_Type (T)); @@ -5873,6 +5910,7 @@ package body Sem_Ch3 is when Ordinary_Fixed_Point_Kind => Mutate_Ekind (Id, E_Ordinary_Fixed_Point_Subtype); + Copy_Parent_Attributes; Set_Scalar_Range (Id, Scalar_Range (T)); Set_Small_Value (Id, Small_Value (T)); Set_Delta_Value (Id, Delta_Value (T)); @@ -5882,6 +5920,7 @@ package body Sem_Ch3 is when Float_Kind => Mutate_Ekind (Id, E_Floating_Point_Subtype); + Copy_Parent_Attributes; Set_Scalar_Range (Id, Scalar_Range (T)); Set_Digits_Value (Id, Digits_Value (T)); Set_Is_Constrained (Id, Is_Constrained (T)); @@ -5891,6 +5930,7 @@ package body Sem_Ch3 is when Signed_Integer_Kind => Mutate_Ekind (Id, E_Signed_Integer_Subtype); + Copy_Parent_Attributes; Set_Scalar_Range (Id, Scalar_Range (T)); Set_Is_Constrained (Id, Is_Constrained (T)); Set_Is_Known_Valid (Id, Is_Known_Valid (T)); @@ -5898,6 +5938,7 @@ package body Sem_Ch3 is when Modular_Integer_Kind => Mutate_Ekind (Id, E_Modular_Integer_Subtype); + Copy_Parent_Attributes; Set_Scalar_Range (Id, Scalar_Range (T)); Set_Is_Constrained (Id, Is_Constrained (T)); Set_Is_Known_Valid (Id, Is_Known_Valid (T)); @@ -5905,6 +5946,7 @@ package body Sem_Ch3 is when Class_Wide_Kind => Mutate_Ekind (Id, E_Class_Wide_Subtype); + Copy_Parent_Attributes; Set_Class_Wide_Type (Id, Class_Wide_Type (T)); Set_Cloned_Subtype (Id, T); Set_Is_Tagged_Type (Id, True); @@ -5922,6 +5964,7 @@ package body Sem_Ch3 is | E_Record_Type => Mutate_Ekind (Id, E_Record_Subtype); + Copy_Parent_Attributes; -- Subtype declarations introduced for formal type parameters -- in generic instantiations should inherit the Size value of @@ -5973,6 +6016,7 @@ package body Sem_Ch3 is when Private_Kind => Mutate_Ekind (Id, Subtype_Kind (Ekind (T))); + Copy_Parent_Attributes; Set_Has_Discriminants (Id, Has_Discriminants (T)); Set_Is_Constrained (Id, Is_Constrained (T)); Set_First_Entity (Id, First_Entity (T)); @@ -6036,6 +6080,7 @@ package body Sem_Ch3 is when Access_Kind => Mutate_Ekind (Id, E_Access_Subtype); + Copy_Parent_Attributes; Set_Is_Constrained (Id, Is_Constrained (T)); Set_Is_Access_Constant (Id, Is_Access_Constant (T)); @@ -6059,6 +6104,7 @@ package body Sem_Ch3 is when Concurrent_Kind => Mutate_Ekind (Id, Subtype_Kind (Ekind (T))); + Copy_Parent_Attributes; Set_Corresponding_Record_Type (Id, Corresponding_Record_Type (T)); Set_First_Entity (Id, First_Entity (T)); @@ -6087,6 +6133,7 @@ package body Sem_Ch3 is -- subtypes for Ada 2012 extended use of incomplete types. Mutate_Ekind (Id, E_Incomplete_Subtype); + Copy_Parent_Attributes; Set_Is_Tagged_Type (Id, Is_Tagged_Type (T)); Set_Private_Dependents (Id, New_Elmt_List); @@ -6127,6 +6174,8 @@ package body Sem_Ch3 is -- declared entity inherits predicates from the parent. Inherit_Predicate_Flags (Id, T); + else + Copy_Parent_Attributes; end if; if Etype (Id) = Any_Type then @@ -6461,12 +6510,15 @@ package body Sem_Ch3 is Priv : Entity_Id; Related_Id : Entity_Id; Has_FLB_Index : Boolean := False; + K : Entity_Kind; begin if Nkind (Def) = N_Constrained_Array_Definition then Index := First (Discrete_Subtype_Definitions (Def)); + K := E_Array_Subtype; else Index := First (Subtype_Marks (Def)); + K := E_Array_Type; end if; -- Find proper names for the implicit types which may be public. In case @@ -6598,7 +6650,13 @@ package body Sem_Ch3 is -- Process subtype indication if one is present if Present (Component_Typ) then - Element_Type := Process_Subtype (Component_Typ, P, Related_Id, 'C'); + Element_Type := + Process_Subtype + (Component_Typ, + P, + Related_Id, + 'C', + Excludes_Null => Null_Exclusion_Present (Component_Def)); Set_Etype (Component_Typ, Element_Type); -- Ada 2005 (AI-230): Access Definition case @@ -6633,17 +6691,17 @@ package body Sem_Ch3 is end; end if; - -- Constrained array case - if No (T) then -- We might be creating more than one itype with the same Related_Id, -- e.g. for an array object definition and its initial value. Give -- them unique suffixes, because GNATprove require distinct types to -- have different names. - T := Create_Itype (E_Void, P, Related_Id, 'T', Suffix_Index => -1); + T := Create_Itype (K, P, Related_Id, 'T', Suffix_Index => -1); end if; + -- Constrained array case + if Nkind (Def) = N_Constrained_Array_Definition then Index := First (Discrete_Subtype_Definitions (Def)); @@ -6773,7 +6831,7 @@ package body Sem_Ch3 is -- that the element type is constrained. if Is_Mutably_Tagged_Type (Element_Type) then - Set_Component_Type (T, + Set_Component_Type (Base_Type (T), Class_Wide_Equivalent_Type (Element_Type)); elsif not Is_Definite_Subtype (Element_Type) then @@ -7214,7 +7272,11 @@ package body Sem_Ch3 is Set_Directly_Designated_Type (Derived_Type, Designated_Type (Parent_Type)); - Subt := Process_Subtype (S, N); + Subt := + Process_Subtype + (S, + N, + Excludes_Null => Null_Exclusion_Present (Type_Definition (N))); if Nkind (S) /= N_Subtype_Indication and then Subt /= Base_Type (Subt) @@ -8116,9 +8178,6 @@ package body Sem_Ch3 is Set_Non_Binary_Modulus (Implicit_Base, Non_Binary_Modulus (Parent_Base)); - Set_Is_Known_Valid - (Implicit_Base, Is_Known_Valid (Parent_Base)); - elsif Is_Floating_Point_Type (Parent_Type) then -- Digits of base type is always copied from the digits value of @@ -8393,15 +8452,17 @@ package body Sem_Ch3 is Set_Has_Private_Declaration (Full_Der); Set_Has_Private_Declaration (Derived_Type); - Set_Scope (Full_Der, Scope (Derived_Type)); - Set_Is_First_Subtype (Full_Der, Is_First_Subtype (Derived_Type)); - Set_Has_Size_Clause (Full_Der, False); - Set_Has_Alignment_Clause (Full_Der, False); - Set_Has_Delayed_Freeze (Full_Der); - Set_Is_Frozen (Full_Der, False); - Set_Freeze_Node (Full_Der, Empty); - Set_Depends_On_Private (Full_Der, Has_Private_Component (Full_Der)); - Set_Is_Public (Full_Der, Is_Public (Derived_Type)); + Set_Scope (Full_Der, Scope (Derived_Type)); + Set_Is_First_Subtype (Full_Der, Is_First_Subtype (Derived_Type)); + Set_Has_Size_Clause (Full_Der, False); + Set_Has_Alignment_Clause (Full_Der, False); + Set_Has_Delayed_Freeze (Full_Der); + Set_Is_Frozen (Full_Der, False); + Set_Freeze_Node (Full_Der, Empty); + Set_Depends_On_Private + (Full_Der, Has_Private_Component (Full_Der)); + Set_Is_Public (Full_Der, Is_Public (Derived_Type)); + Set_Is_Implicit_Full_View (Full_Der); -- The convention on the base type may be set in the private part -- and not propagated to the subtype until later, so we obtain the @@ -8491,11 +8552,19 @@ package body Sem_Ch3 is Analyze (Decl); - pragma Assert (Has_Discriminants (Full_Der) - and then not Has_Unknown_Discriminants (Full_Der)); + pragma + Assert + ((Has_Discriminants (Full_Der) + and then not Has_Unknown_Discriminants (Full_Der)) + or else Serious_Errors_Detected > 0); Uninstall_Declarations (Par_Scope); + if Etype (Full_Der) = Any_Type then + pragma Assert (Serious_Errors_Detected > 0); + return; + end if; + -- Freeze the underlying record view, to prevent generation of -- useless dispatching information, which is simply shared with -- the real derived type. @@ -9460,8 +9529,8 @@ package body Sem_Ch3 is if Constraint_Present then if not Has_Discriminants (Parent_Base) or else - (Has_Unknown_Discriminants (Parent_Base) - and then Is_Private_Type (Parent_Base)) + (Has_Unknown_Discriminants (Parent_Type) + and then Is_Private_Type (Parent_Type)) then Error_Msg_N ("invalid constraint: type has no discriminant", @@ -11985,7 +12054,7 @@ package body Sem_Ch3 is Insert_Before (Typ_Decl, Decl); Analyze (Decl); Set_Full_View (Inc_T, Typ); - Set_Incomplete_View (Typ_Decl, Inc_T); + Set_Incomplete_View (Typ, Inc_T); -- If the type is tagged, create a common class-wide type for -- both views, and set the Etype of the class-wide type to the @@ -12670,6 +12739,249 @@ package body Sem_Ch3 is end Check_Digits_Expression; + ------------------------------------ + -- Check_Discriminant_Conformance -- + ------------------------------------ + + procedure Check_Discriminant_Conformance + (N : Node_Id; + Prev : Entity_Id; + Prev_Loc : Node_Id) + is + Old_Discr : Entity_Id := First_Discriminant (Prev); + New_Discr : Node_Id := First (Discriminant_Specifications (N)); + New_Discr_Id : Entity_Id; + New_Discr_Type : Entity_Id; + + procedure Conformance_Error (Msg : String; N : Node_Id); + -- Post error message for conformance error on given node. Two messages + -- are output. The first points to the previous declaration with a + -- general "no conformance" message. The second is the detailed reason, + -- supplied as Msg. The parameter N provide information for a possible + -- & insertion in the message. + + ----------------------- + -- Conformance_Error -- + ----------------------- + + procedure Conformance_Error (Msg : String; N : Node_Id) is + begin + Error_Msg_Sloc := Sloc (Prev_Loc); + Error_Msg_N -- CODEFIX + ("not fully conformant with declaration#!", N); + Error_Msg_NE (Msg, N, N); + end Conformance_Error; + + -- Start of processing for Check_Discriminant_Conformance + + begin + while Present (Old_Discr) and then Present (New_Discr) loop + New_Discr_Id := Defining_Identifier (New_Discr); + + -- The subtype mark of the discriminant on the full type has not + -- been analyzed so we do it here. For an access discriminant a new + -- type is created. + + if Nkind (Discriminant_Type (New_Discr)) = N_Access_Definition then + New_Discr_Type := + Access_Definition (N, Discriminant_Type (New_Discr)); + + else + Find_Type (Discriminant_Type (New_Discr)); + New_Discr_Type := Etype (Discriminant_Type (New_Discr)); + + -- Ada 2005: if the discriminant definition carries a null + -- exclusion, create an itype to check properly for consistency + -- with partial declaration. + + if Is_Access_Type (New_Discr_Type) + and then Null_Exclusion_Present (New_Discr) + then + New_Discr_Type := + Create_Null_Excluding_Itype + (T => New_Discr_Type, + Related_Nod => New_Discr, + Scope_Id => Current_Scope); + end if; + end if; + + if not Conforming_Types + (Etype (Old_Discr), New_Discr_Type, Fully_Conformant) + then + Conformance_Error ("type of & does not match!", New_Discr_Id); + return; + else + -- Treat the new discriminant as an occurrence of the old one, + -- for navigation purposes, and fill in some semantic + -- information, for completeness. + + Generate_Reference (Old_Discr, New_Discr_Id, 'r'); + Set_Etype (New_Discr_Id, Etype (Old_Discr)); + Set_Scope (New_Discr_Id, Scope (Old_Discr)); + end if; + + -- Names must match + + if Chars (Old_Discr) /= Chars (Defining_Identifier (New_Discr)) then + Conformance_Error ("name & does not match!", New_Discr_Id); + return; + end if; + + -- Default expressions must match + + declare + NewD : constant Boolean := + Present (Expression (New_Discr)); + OldD : constant Boolean := + Present (Expression (Parent (Old_Discr))); + + function Has_Tagged_Limited_Partial_View + (Typ : Entity_Id) return Boolean; + -- Returns True iff Typ has a tagged limited partial view. + + function Is_Derived_From_Immutably_Limited_Type + (Typ : Entity_Id) return Boolean; + -- Returns True iff Typ is a derived type (tagged or not) + -- whose ancestor type is immutably limited. The unusual + -- ("unusual" is one word for it) thing about this function + -- is that it handles the case where the ancestor name's Entity + -- attribute has not been set yet. + + ------------------------------------- + -- Has_Tagged_Limited_Partial_View -- + ------------------------------------- + + function Has_Tagged_Limited_Partial_View + (Typ : Entity_Id) return Boolean + is + Priv : constant Entity_Id := Incomplete_Or_Partial_View (Typ); + begin + return Present (Priv) + and then not Is_Incomplete_Type (Priv) + and then Is_Tagged_Type (Priv) + and then Limited_Present (Parent (Priv)); + end Has_Tagged_Limited_Partial_View; + + -------------------------------------------- + -- Is_Derived_From_Immutably_Limited_Type -- + -------------------------------------------- + + function Is_Derived_From_Immutably_Limited_Type + (Typ : Entity_Id) return Boolean + is + Type_Def : constant Node_Id := Type_Definition (Parent (Typ)); + Parent_Name : Node_Id; + begin + if Nkind (Type_Def) /= N_Derived_Type_Definition then + return False; + end if; + Parent_Name := Subtype_Indication (Type_Def); + if Nkind (Parent_Name) = N_Subtype_Indication then + Parent_Name := Subtype_Mark (Parent_Name); + end if; + if Parent_Name not in N_Has_Entity_Id + or else No (Entity (Parent_Name)) + then + Find_Type (Parent_Name); + end if; + return Is_Immutably_Limited_Type (Entity (Parent_Name)); + end Is_Derived_From_Immutably_Limited_Type; + + begin + if NewD or OldD then + + -- The old default value has been analyzed and expanded, + -- because the current full declaration will have frozen + -- everything before. The new default values have not been + -- expanded, so expand now to check conformance. + + if NewD then + Preanalyze_And_Resolve_Spec_Expression + (Expression (New_Discr), New_Discr_Type); + end if; + + if not (NewD and OldD) + or else not Fully_Conformant_Expressions + (Expression (Parent (Old_Discr)), + Expression (New_Discr)) + + then + Conformance_Error + ("default expression for & does not match!", + New_Discr_Id); + return; + end if; + + if NewD + and then Ada_Version >= Ada_2005 + and then Nkind (Discriminant_Type (New_Discr)) = + N_Access_Definition + and then not Is_Immutably_Limited_Type + (Defining_Identifier (N)) + + -- Check for a case that would be awkward to handle in + -- Is_Immutably_Limited_Type (because sem_aux can't + -- "with" sem_util). + + and then not Has_Tagged_Limited_Partial_View + (Defining_Identifier (N)) + + -- Check for another case that would be awkward to handle + -- in Is_Immutably_Limited_Type + + and then not Is_Derived_From_Immutably_Limited_Type + (Defining_Identifier (N)) + then + Error_Msg_N + ("(Ada 2005) default value for access discriminant " + & "requires immutably limited type", + Expression (New_Discr)); + return; + end if; + end if; + end; + + -- In Ada 83 case, grouping must match: (A,B : X) /= (A : X; B : X) + + if Ada_Version = Ada_83 then + declare + Old_Disc : constant Node_Id := Declaration_Node (Old_Discr); + + begin + -- Grouping (use of comma in param lists) must be the same + -- This is where we catch a misconformance like: + + -- A, B : Integer + -- A : Integer; B : Integer + + -- which are represented identically in the tree except + -- for the setting of the flags More_Ids and Prev_Ids. + + if More_Ids (Old_Disc) /= More_Ids (New_Discr) + or else Prev_Ids (Old_Disc) /= Prev_Ids (New_Discr) + then + Conformance_Error + ("grouping of & does not match!", New_Discr_Id); + return; + end if; + end; + end if; + + Next_Discriminant (Old_Discr); + Next (New_Discr); + end loop; + + if Present (Old_Discr) then + Conformance_Error ("too few discriminants!", Defining_Identifier (N)); + return; + + elsif Present (New_Discr) then + Conformance_Error + ("too many discriminants!", Defining_Identifier (New_Discr)); + return; + end if; + end Check_Discriminant_Conformance; + -------------------------- -- Check_Initialization -- -------------------------- @@ -13972,7 +14284,7 @@ package body Sem_Ch3 is --------------------- procedure Constrain_Array - (Def_Id : in out Entity_Id; + (Def_Id : Entity_Id; SI : Node_Id; Related_Nod : Node_Id; Related_Id : Entity_Id; @@ -14072,14 +14384,7 @@ package body Sem_Ch3 is end if; end if; - if No (Def_Id) then - Def_Id := - Create_Itype (E_Array_Subtype, Related_Nod, Related_Id, Suffix); - Set_Parent (Def_Id, Related_Nod); - - else - Mutate_Ekind (Def_Id, E_Array_Subtype); - end if; + Mutate_Ekind (Def_Id, E_Array_Subtype); Set_Size_Info (Def_Id, (T)); Set_First_Rep_Item (Def_Id, First_Rep_Item (T)); @@ -14599,6 +14904,7 @@ package body Sem_Ch3 is Set_Etype (T_Sub, Corr_Rec); Set_Has_Discriminants (T_Sub, Has_Discriminants (Prot_Subt)); Set_Is_Tagged_Type (T_Sub, Is_Tagged_Type (Corr_Rec)); + Set_Class_Wide_Type (T_Sub, Class_Wide_Type (Corr_Rec)); Set_Is_Constrained (T_Sub, True); Set_First_Entity (T_Sub, First_Entity (Corr_Rec)); Set_Last_Entity (T_Sub, Last_Entity (Corr_Rec)); @@ -14965,17 +15271,24 @@ package body Sem_Ch3 is R : Node_Id := Empty; T : constant Entity_Id := Etype (Index); Is_FLB_Index : Boolean := False; + Is_Range : constant Boolean := + Nkind (S) = N_Range + or else (Nkind (S) = N_Attribute_Reference + and then Attribute_Name (S) = Name_Range); + Is_Indic : constant Boolean := Nkind (S) = N_Subtype_Indication; + K : constant Entity_Kind := + (if Is_Modular_Integer_Type (T) then E_Modular_Integer_Subtype + elsif Is_Integer_Type (T) then E_Signed_Integer_Subtype + else E_Enumeration_Subtype); begin - Def_Id := - Create_Itype (E_Void, Related_Nod, Related_Id, Suffix, Suffix_Index); - Set_Etype (Def_Id, Base_Type (T)); + if Is_Range or else Is_Indic then + Def_Id := + Create_Itype (K, Related_Nod, Related_Id, Suffix, Suffix_Index); + Set_Etype (Def_Id, Base_Type (T)); + end if; - if Nkind (S) = N_Range - or else - (Nkind (S) = N_Attribute_Reference - and then Attribute_Name (S) = Name_Range) - then + if Is_Range then -- A Range attribute will be transformed into N_Range by Resolve -- If a range has an Empty upper bound, then remember that for later @@ -15010,7 +15323,7 @@ package body Sem_Ch3 is end if; end if; - elsif Nkind (S) = N_Subtype_Indication then + elsif Is_Indic then -- The parser has verified that this is a discrete indication @@ -15065,27 +15378,19 @@ package body Sem_Ch3 is S, Entity (S)); end if; - return; - else Error_Msg_N ("invalid index constraint", S); Rewrite (S, New_Occurrence_Of (T, Sloc (S))); - return; end if; + + return; end if; -- Complete construction of the Itype - if Is_Modular_Integer_Type (T) then - Mutate_Ekind (Def_Id, E_Modular_Integer_Subtype); - - elsif Is_Integer_Type (T) then - Mutate_Ekind (Def_Id, E_Signed_Integer_Subtype); - - else - Mutate_Ekind (Def_Id, E_Enumeration_Subtype); + if K = E_Enumeration_Subtype then Set_Is_Character_Type (Def_Id, Is_Character_Type (T)); - Set_First_Literal (Def_Id, First_Literal (T)); + Set_First_Literal (Def_Id, First_Literal (T)); end if; Set_Size_Info (Def_Id, (T)); @@ -15095,7 +15400,8 @@ package body Sem_Ch3 is -- If this is a range for a fixed-lower-bound subtype, then set the -- index itype's low bound to the FLB and the index itype's upper bound -- to the high bound of the parent array type's index subtype. Also, - -- mark the itype as an FLB index subtype. + -- set the Etype of the new scalar range and mark the itype as an FLB + -- index subtype. if Nkind (S) = N_Range and then Is_FLB_Index then Set_Scalar_Range @@ -15103,6 +15409,7 @@ package body Sem_Ch3 is Make_Range (Sloc (S), Low_Bound => Low_Bound (S), High_Bound => Type_High_Bound (T))); + Set_Etype (Scalar_Range (Def_Id), Etype (Index)); Set_Is_Fixed_Lower_Bound_Index_Subtype (Def_Id); else @@ -18835,10 +19142,15 @@ package body Sem_Ch3 is or else Nkind (P) /= N_Object_Declaration or else Is_Library_Level_Entity (Defining_Identifier (P))); - -- Otherwise, the object definition is just a subtype_mark + -- Otherwise, either the object definition is just a subtype_mark or we + -- are analyzing a component declaration. else - T := Process_Subtype (Obj_Def, Related_Nod); + T := + Process_Subtype + (Obj_Def, + Related_Nod, + Excludes_Null => Null_Exclusion_Present (Parent (Obj_Def))); end if; return T; @@ -18869,8 +19181,7 @@ package body Sem_Ch3 is -- Otherwise we have a subtype mark without a constraint elsif Error_Posted (S) then - -- Don't rewrite if S is Empty or Error - if S > Empty_Or_Error then + if S not in Empty | Error then Rewrite (S, New_Occurrence_Of (Any_Id, Sloc (S))); end if; return Any_Type; @@ -19846,7 +20157,9 @@ package body Sem_Ch3 is -- Start of processing for Is_Visible_Component begin - if Ekind (C) in E_Component | E_Discriminant then + if Ekind (C) in E_Component | E_Discriminant + and then Is_Not_Self_Hidden (C) + then Original_Comp := Original_Record_Component (C); end if; @@ -20341,17 +20654,17 @@ package body Sem_Ch3 is if No (Def_Id) then Def_Id := - Create_Itype (E_Void, Related_Nod, Related_Id, 'D', Suffix_Index); + Create_Itype + ((if Is_Signed_Integer_Type (T) then E_Signed_Integer_Subtype + elsif Is_Modular_Integer_Type (T) then E_Modular_Integer_Subtype + else E_Enumeration_Subtype), + Related_Nod, + Related_Id, + 'D', + Suffix_Index); Set_Etype (Def_Id, Base_Type (T)); - if Is_Signed_Integer_Type (T) then - Mutate_Ekind (Def_Id, E_Signed_Integer_Subtype); - - elsif Is_Modular_Integer_Type (T) then - Mutate_Ekind (Def_Id, E_Modular_Integer_Subtype); - - else - Mutate_Ekind (Def_Id, E_Enumeration_Subtype); + if Ekind (Def_Id) = E_Enumeration_Subtype then Set_Is_Character_Type (Def_Id, Is_Character_Type (T)); Set_First_Literal (Def_Id, First_Literal (T)); end if; @@ -20802,7 +21115,7 @@ package body Sem_Ch3 is -- If no range was given, set a dummy range - if RRS <= Empty_Or_Error then + if RRS in Empty | Error then Low_Val := -Small_Val; High_Val := Small_Val; @@ -20857,67 +21170,71 @@ package body Sem_Ch3 is Set_Is_Constrained (T); end Ordinary_Fixed_Point_Type_Declaration; - ---------------------------------- - -- Preanalyze_Assert_Expression -- - ---------------------------------- + ---------------------------------------------- + -- Preanalyze_And_Resolve_Assert_Expression -- + ---------------------------------------------- - procedure Preanalyze_Assert_Expression (N : Node_Id; T : Entity_Id) is + procedure Preanalyze_And_Resolve_Assert_Expression + (N : Node_Id; + T : Entity_Id) is begin In_Assertion_Expr := In_Assertion_Expr + 1; - Preanalyze_Spec_Expression (N, T); + Preanalyze_And_Resolve_Spec_Expression (N, T); In_Assertion_Expr := In_Assertion_Expr - 1; - end Preanalyze_Assert_Expression; + end Preanalyze_And_Resolve_Assert_Expression; - -- ??? The variant below explicitly saves and restores all the flags, - -- because it is impossible to compose the existing variety of - -- Analyze/Resolve (and their wrappers, e.g. Preanalyze_Spec_Expression) - -- to achieve the desired semantics. - - procedure Preanalyze_Assert_Expression (N : Node_Id) is - Save_In_Spec_Expression : constant Boolean := In_Spec_Expression; - Save_Full_Analysis : constant Boolean := Full_Analysis; + ---------------------------------------------- + -- Preanalyze_And_Resolve_Assert_Expression -- + ---------------------------------------------- + procedure Preanalyze_And_Resolve_Assert_Expression (N : Node_Id) is begin In_Assertion_Expr := In_Assertion_Expr + 1; - In_Spec_Expression := True; - Full_Analysis := False; - Expander_Mode_Save_And_Set (False); - - if GNATprove_Mode then - Analyze_And_Resolve (N); - else - Analyze_And_Resolve (N, Suppress => All_Checks); - end if; - - Expander_Mode_Restore; - Full_Analysis := Save_Full_Analysis; - In_Spec_Expression := Save_In_Spec_Expression; + Preanalyze_And_Resolve_Spec_Expression (N); In_Assertion_Expr := In_Assertion_Expr - 1; - end Preanalyze_Assert_Expression; + end Preanalyze_And_Resolve_Assert_Expression; - ----------------------------------- - -- Preanalyze_Default_Expression -- - ----------------------------------- + ----------------------------------------------- + -- Preanalyze_And_Resolve_Default_Expression -- + ----------------------------------------------- - procedure Preanalyze_Default_Expression (N : Node_Id; T : Entity_Id) is + procedure Preanalyze_And_Resolve_Default_Expression + (N : Node_Id; + T : Entity_Id) + is Save_In_Default_Expr : constant Boolean := In_Default_Expr; begin In_Default_Expr := True; - Preanalyze_Spec_Expression (N, T); + Preanalyze_And_Resolve_Spec_Expression (N, T); In_Default_Expr := Save_In_Default_Expr; - end Preanalyze_Default_Expression; + end Preanalyze_And_Resolve_Default_Expression; - -------------------------------- - -- Preanalyze_Spec_Expression -- - -------------------------------- + -------------------------------------------- + -- Preanalyze_And_Resolve_Spec_Expression -- + -------------------------------------------- - procedure Preanalyze_Spec_Expression (N : Node_Id; T : Entity_Id) is + procedure Preanalyze_And_Resolve_Spec_Expression + (N : Node_Id; + T : Entity_Id) + is Save_In_Spec_Expression : constant Boolean := In_Spec_Expression; begin In_Spec_Expression := True; Preanalyze_And_Resolve (N, T); In_Spec_Expression := Save_In_Spec_Expression; - end Preanalyze_Spec_Expression; + end Preanalyze_And_Resolve_Spec_Expression; + + -------------------------------------------- + -- Preanalyze_And_Resolve_Spec_Expression -- + -------------------------------------------- + + procedure Preanalyze_And_Resolve_Spec_Expression (N : Node_Id) is + Save_In_Spec_Expression : constant Boolean := In_Spec_Expression; + begin + In_Spec_Expression := True; + Preanalyze_And_Resolve (N); + In_Spec_Expression := Save_In_Spec_Expression; + end Preanalyze_And_Resolve_Spec_Expression; ---------------------------------------- -- Prepare_Private_Subtype_Completion -- @@ -20981,6 +21298,12 @@ package body Sem_Ch3 is Discr := First (Discriminant_Specifications (N)); while Present (Discr) loop + if Ekind (Defining_Identifier (Discr)) = E_In_Parameter then + Reinit_Field_To_Zero + (Defining_Identifier (Discr), F_Discriminal_Link); + end if; + + Mutate_Ekind (Defining_Identifier (Discr), E_Discriminant); Enter_Name (Defining_Identifier (Discr)); -- For navigation purposes we add a reference to the discriminant @@ -21076,7 +21399,8 @@ package body Sem_Ch3 is -- Per-Object Expressions" in spec of package Sem). if Present (Expression (Discr)) then - Preanalyze_Default_Expression (Expression (Discr), Discr_Type); + Preanalyze_And_Resolve_Default_Expression + (Expression (Discr), Discr_Type); -- Legaity checks @@ -21255,11 +21579,6 @@ package body Sem_Ch3 is while Present (Discr) loop Id := Defining_Identifier (Discr); - if Ekind (Id) = E_In_Parameter then - Reinit_Field_To_Zero (Id, F_Discriminal_Link); - end if; - - Mutate_Ekind (Id, E_Discriminant); Set_Is_Not_Self_Hidden (Id); Reinit_Component_Location (Id); Reinit_Esize (Id); @@ -22506,10 +22825,12 @@ package body Sem_Ch3 is --------------------- function Process_Subtype - (S : Node_Id; - Related_Nod : Node_Id; - Related_Id : Entity_Id := Empty; - Suffix : Character := ' ') return Entity_Id + (S : Node_Id; + Related_Nod : Node_Id; + Related_Id : Entity_Id := Empty; + Suffix : Character := ' '; + Excludes_Null : Boolean := False; + Incomplete_Type_OK : Boolean := False) return Entity_Id is procedure Check_Incomplete (T : Node_Id); -- Called to verify that an incomplete type is not used prematurely @@ -22523,13 +22844,7 @@ package body Sem_Ch3 is -- Ada 2005 (AI-412): Incomplete subtypes are legal if Ekind (Root_Type (Entity (T))) = E_Incomplete_Type - and then - not (Ada_Version >= Ada_2005 - and then - (Nkind (Parent (T)) = N_Subtype_Declaration - or else (Nkind (Parent (T)) = N_Subtype_Indication - and then Nkind (Parent (Parent (T))) = - N_Subtype_Declaration))) + and then not Incomplete_Type_OK then Error_Msg_N ("invalid use of type before its full declaration", T); end if; @@ -22537,126 +22852,91 @@ package body Sem_Ch3 is -- Local variables - P : Node_Id; + P : constant Node_Id := Parent (S); + Mark : Node_Id; Def_Id : Entity_Id; Error_Node : Node_Id; Full_View_Id : Entity_Id; Subtype_Mark_Id : Entity_Id; - May_Have_Null_Exclusion : Boolean; - -- Start of processing for Process_Subtype begin - -- Case of no constraints present - - if Nkind (S) /= N_Subtype_Indication then - Find_Type (S); - - -- No way to proceed if the subtype indication is malformed. This - -- will happen for example when the subtype indication in an object - -- declaration is missing altogether and the expression is analyzed - -- as if it were that indication. - - if not Is_Entity_Name (S) then - return Any_Type; - end if; + if Nkind (S) = N_Subtype_Indication then + Mark := Subtype_Mark (S); + else + Mark := S; + end if; - Check_Incomplete (S); - P := Parent (S); + Find_Type (Mark); - -- The following mirroring of assertion in Null_Exclusion_Present is - -- ugly, can't we have a range, a static predicate or even a flag??? + -- No way to proceed if the subtype indication is malformed. This will + -- happen for example when the subtype indication in an object + -- declaration is missing altogether and the expression is analyzed as + -- if it were that indication. - May_Have_Null_Exclusion := - Present (P) - and then - Nkind (P) in N_Access_Definition - | N_Access_Function_Definition - | N_Access_Procedure_Definition - | N_Access_To_Object_Definition - | N_Allocator - | N_Component_Definition - | N_Derived_Type_Definition - | N_Discriminant_Specification - | N_Formal_Object_Declaration - | N_Function_Specification - | N_Object_Declaration - | N_Object_Renaming_Declaration - | N_Parameter_Specification - | N_Subtype_Declaration; - - -- Ada 2005 (AI-231): Static check + if not Is_Entity_Name (Mark) then + return Any_Type; + end if; - if Ada_Version >= Ada_2005 - and then May_Have_Null_Exclusion - and then Null_Exclusion_Present (P) - and then Nkind (P) /= N_Access_To_Object_Definition - and then not Is_Access_Type (Entity (S)) - then - Error_Msg_N ("`NOT NULL` only allowed for an access type", S); - end if; + Check_Incomplete (Mark); - -- Create an Itype that is a duplicate of Entity (S) but with the - -- null-exclusion attribute. + -- Case of no constraints present - if May_Have_Null_Exclusion - and then Is_Access_Type (Entity (S)) - and then Null_Exclusion_Present (P) + if Nkind (S) /= N_Subtype_Indication then + if Excludes_Null then + -- Create an Itype that is a duplicate of Entity (S) but with the + -- null-exclusion attribute. + if Is_Access_Type (Entity (S)) then + if Can_Never_Be_Null (Entity (S)) then + case Nkind (Related_Nod) is + when N_Full_Type_Declaration => + if Nkind (Type_Definition (Related_Nod)) + in N_Array_Type_Definition + then + Error_Node := + Subtype_Indication + (Component_Definition + (Type_Definition (Related_Nod))); + else + Error_Node := + Subtype_Indication + (Type_Definition (Related_Nod)); + end if; - -- No need to check the case of an access to object definition. - -- It is correct to define double not-null pointers. + when N_Subtype_Declaration => + Error_Node := Subtype_Indication (Related_Nod); - -- Example: - -- type Not_Null_Int_Ptr is not null access Integer; - -- type Acc is not null access Not_Null_Int_Ptr; + when N_Object_Declaration => + Error_Node := Object_Definition (Related_Nod); - and then Nkind (P) /= N_Access_To_Object_Definition - then - if Can_Never_Be_Null (Entity (S)) then - case Nkind (Related_Nod) is - when N_Full_Type_Declaration => - if Nkind (Type_Definition (Related_Nod)) - in N_Array_Type_Definition - then + when N_Component_Declaration => Error_Node := Subtype_Indication - (Component_Definition - (Type_Definition (Related_Nod))); - else - Error_Node := - Subtype_Indication (Type_Definition (Related_Nod)); - end if; - - when N_Subtype_Declaration => - Error_Node := Subtype_Indication (Related_Nod); + (Component_Definition (Related_Nod)); - when N_Object_Declaration => - Error_Node := Object_Definition (Related_Nod); + when N_Allocator => + Error_Node := Expression (Related_Nod); - when N_Component_Declaration => - Error_Node := - Subtype_Indication (Component_Definition (Related_Nod)); + when others => + pragma Assert (False); + Error_Node := Related_Nod; + end case; - when N_Allocator => - Error_Node := Expression (Related_Nod); - - when others => - pragma Assert (False); - Error_Node := Related_Nod; - end case; + Error_Msg_NE + ("`NOT NULL` not allowed (& already excludes null)", + Error_Node, + Entity (S)); + end if; - Error_Msg_NE - ("`NOT NULL` not allowed (& already excludes null)", - Error_Node, - Entity (S)); + Set_Etype + (S, + Create_Null_Excluding_Itype + (T => Entity (S), Related_Nod => P)); + Set_Entity (S, Etype (S)); + elsif Ada_Version >= Ada_2005 then + Error_Msg_N ("`NOT NULL` only allowed for an access type", S); end if; - - Set_Etype (S, - Create_Null_Excluding_Itype - (T => Entity (S), - Related_Nod => P)); - Set_Entity (S, Etype (S)); end if; return Entity (S); @@ -22665,18 +22945,7 @@ package body Sem_Ch3 is -- node (this node is created only if constraints are present). else - Find_Type (Subtype_Mark (S)); - - if Nkind (Parent (S)) /= N_Access_To_Object_Definition - and then not - (Nkind (Parent (S)) = N_Subtype_Declaration - and then Is_Itype (Defining_Identifier (Parent (S)))) - then - Check_Incomplete (Subtype_Mark (S)); - end if; - - P := Parent (S); - Subtype_Mark_Id := Entity (Subtype_Mark (S)); + Subtype_Mark_Id := Entity (Mark); -- Explicit subtype declaration case @@ -22696,8 +22965,7 @@ package body Sem_Ch3 is -- has not yet been called to create Def_Id. else - if Is_Array_Type (Subtype_Mark_Id) - or else Is_Concurrent_Type (Subtype_Mark_Id) + if Is_Concurrent_Type (Subtype_Mark_Id) or else Is_Access_Type (Subtype_Mark_Id) then Def_Id := Empty; @@ -22730,7 +22998,14 @@ package body Sem_Ch3 is -- Make recursive call, having got rid of the bogus constraint - return Process_Subtype (S, Related_Nod, Related_Id, Suffix); + return + Process_Subtype + (S, + Related_Nod, + Related_Id, + Suffix, + Excludes_Null, + Incomplete_Type_OK); end if; -- Remaining processing depends on type. Select on Base_Type kind to @@ -22750,6 +23025,8 @@ package body Sem_Ch3 is Error_Msg_N ("constraint on class-wide type ignored??", Constraint (S)); + else + pragma Assert (False); end if; if Nkind (P) = N_Subtype_Declaration then @@ -22878,8 +23155,8 @@ package body Sem_Ch3 is -- Size, Alignment, Representation aspects and Convention are always -- inherited from the base type. - Set_Size_Info (Def_Id, (Subtype_Mark_Id)); - Set_Rep_Info (Def_Id, (Subtype_Mark_Id)); + Set_Size_Info (Def_Id, Subtype_Mark_Id); + Set_Rep_Info (Def_Id, Subtype_Mark_Id); Set_Convention (Def_Id, Convention (Subtype_Mark_Id)); -- The anonymous subtype created for the subtype indication @@ -23131,16 +23408,22 @@ package body Sem_Ch3 is Component := First_Entity (Current_Scope); while Present (Component) loop - if Ekind (Component) = E_Void - and then not Is_Itype (Component) + if Ekind (Component) = E_Component and then not Is_Itype (Component) then - Mutate_Ekind (Component, E_Component); Reinit_Component_Location (Component); Set_Is_Not_Self_Hidden (Component); end if; Propagate_Concurrent_Flags (T, Etype (Component)); + -- Propagate information about constructor dependence + + if Ekind (Etype (Component)) /= E_Void + and then Needs_Construction (Etype (Component)) + then + Set_Needs_Construction (T); + end if; + if Ekind (Component) /= E_Component then null; diff --git a/gcc/ada/sem_ch3.ads b/gcc/ada/sem_ch3.ads index 3d9aa0a963a0..a97393d3cfe8 100644 --- a/gcc/ada/sem_ch3.ads +++ b/gcc/ada/sem_ch3.ads @@ -236,19 +236,23 @@ package Sem_Ch3 is -- Always False in Ada 95 mode. Equivalent to OK_For_Limited_Init_In_05 in -- Ada 2005 mode. - procedure Preanalyze_Assert_Expression (N : Node_Id; T : Entity_Id); - -- Wrapper on Preanalyze_Spec_Expression for assertion expressions, so that - -- In_Assertion_Expr can be properly adjusted. + procedure Preanalyze_And_Resolve_Assert_Expression + (N : Node_Id; + T : Entity_Id); + -- Wrapper on Preanalyze_And_Resolve_Spec_Expression for assertion + -- expressions, so that In_Assertion_Expr can be properly adjusted. -- -- This routine must not be called when N is the root of a subtree that is -- not in its final place since it freezes static expression entities, -- which would be misplaced in the tree. Preanalyze_And_Resolve must be -- used in such a case to avoid reporting spurious errors. - procedure Preanalyze_Assert_Expression (N : Node_Id); + procedure Preanalyze_And_Resolve_Assert_Expression (N : Node_Id); -- Similar to the above, but without forcing N to be of a particular type - procedure Preanalyze_Spec_Expression (N : Node_Id; T : Entity_Id); + procedure Preanalyze_And_Resolve_Spec_Expression + (N : Node_Id; + T : Entity_Id); -- Default and per object expressions do not freeze their components, and -- must be analyzed and resolved accordingly. The analysis is done by -- calling the Preanalyze_And_Resolve routine and setting the global @@ -263,6 +267,9 @@ package Sem_Ch3 is -- which would be misplaced in the tree. Preanalyze_And_Resolve must be -- used in such a case to avoid reporting spurious errors. + procedure Preanalyze_And_Resolve_Spec_Expression (N : Node_Id); + -- Similar to the above, but without forcing N to be of a particular type + procedure Process_Full_View (N : Node_Id; Full_T, Priv_T : Entity_Id); -- Process some semantic actions when the full view of a private type is -- encountered and analyzed. The first action is to create the full views @@ -294,10 +301,12 @@ package Sem_Ch3 is -- in this case the bounds are captured if necessary using this name. function Process_Subtype - (S : Node_Id; - Related_Nod : Node_Id; - Related_Id : Entity_Id := Empty; - Suffix : Character := ' ') return Entity_Id; + (S : Node_Id; + Related_Nod : Node_Id; + Related_Id : Entity_Id := Empty; + Suffix : Character := ' '; + Excludes_Null : Boolean := False; + Incomplete_Type_OK : Boolean := False) return Entity_Id; -- Process a subtype indication S and return corresponding entity. -- Related_Nod is the node where the potential generated implicit types -- will be inserted. The Related_Id and Suffix parameters are used to diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb index 406983995f3d..018c8a079324 100644 --- a/gcc/ada/sem_ch4.adb +++ b/gcc/ada/sem_ch4.adb @@ -27,11 +27,11 @@ with Accessibility; use Accessibility; with Aspects; use Aspects; with Atree; use Atree; with Debug; use Debug; -with Diagnostics.Constructors; use Diagnostics.Constructors; with Einfo; use Einfo; with Einfo.Entities; use Einfo.Entities; with Einfo.Utils; use Einfo.Utils; with Elists; use Elists; +with Errid; use Errid; with Errout; use Errout; with Exp_Util; use Exp_Util; with Itypes; use Itypes; @@ -308,8 +308,12 @@ package body Sem_Ch4 is (N : Node_Id; Prefix : Node_Id; Exprs : List_Id) return Boolean; - -- AI05-0139: Generalized indexing to support iterators over containers - -- ??? Need to provide a more detailed spec of what this function does + -- AI05-0139: Generalized indexing to support iterators over containers. + -- Given the N_Indexed_Component node N, with the given prefix and + -- expressions list, check if the generalized indexing is applicable; + -- if applicable then build its indexing function, link it to N through + -- attribute Generalized_Indexing, and return True; otherwise return + -- False. function Try_Indexed_Call (N : Node_Id; @@ -590,8 +594,6 @@ package body Sem_Ch4 is -- part of the allocator. It is fully analyzed and resolved when -- the allocator is resolved with the context type. - Set_Etype (E, Type_Id); - -- Case where allocator has a subtype indication else @@ -724,7 +726,8 @@ package body Sem_Ch4 is end; end if; - Type_Id := Process_Subtype (E, N); + Type_Id := + Process_Subtype (E, N, Excludes_Null => Null_Exclusion_Present (N)); Acc_Type := Create_Itype (E_Allocator_Type, N); Set_Etype (Acc_Type, Acc_Type); Set_Directly_Designated_Type (Acc_Type, Type_Id); @@ -831,6 +834,14 @@ package body Sem_Ch4 is Error_Msg_N ("cannot allocate abstract object", E); end if; + -- If the type of a constrained array has an unconstrained first + -- subtype, its Finalize_Address primitive expects the address of + -- an object with a dope vector (see Make_Finalize_Address_Stmts). + + if Is_Constr_Array_Subt_Of_Unc_With_Controlled (Type_Id) then + Set_Is_Constr_Array_Subt_With_Bounds (Type_Id); + end if; + Set_Etype (N, Acc_Type); -- If this is an allocator for the return stack, then no restriction may @@ -5592,6 +5603,10 @@ package body Sem_Ch4 is if No (Act_Decl) then Set_Etype (N, Etype (Comp)); + if Is_Mutably_Tagged_CW_Equivalent_Type (Etype (N)) then + Make_Mutably_Tagged_Conversion (N); + end if; + else -- If discriminants were present in the component -- declaration, they have been replaced by the @@ -6040,9 +6055,10 @@ package body Sem_Ch4 is Error_Msg_NE ("invalid prefix in selected component&", N, Sel); end if; - -- If N still has no type, the component is not defined in the prefix + -- If the selector is not labelled with an entity at this point, the + -- component is not defined in the prefix. - if Etype (N) = Any_Type then + if No (Entity (Sel)) then if Is_Single_Concurrent_Object then Error_Msg_Node_2 := Entity (Pref); @@ -7642,35 +7658,14 @@ package body Sem_Ch4 is begin if not Is_Overloaded (R) then if Is_Numeric_Type (Etype (R)) then - - -- In an instance a generic actual may be a numeric type even if - -- the formal in the generic unit was not. In that case, the - -- predefined operator was not a possible interpretation in the - -- generic, and cannot be one in the instance, unless the operator - -- is an actual of an instance. - - if In_Instance - and then - not Is_Numeric_Type (Corresponding_Generic_Type (Etype (R))) - then - null; - else - Add_One_Interp (N, Op_Id, Base_Type (Etype (R))); - end if; + Add_One_Interp (N, Op_Id, Base_Type (Etype (R))); end if; else Get_First_Interp (R, Index, It); while Present (It.Typ) loop if Is_Numeric_Type (It.Typ) then - if In_Instance - and then - not Is_Numeric_Type - (Corresponding_Generic_Type (Etype (It.Typ))) - then - null; - - elsif Is_Effectively_Visible_Operator (N, Base_Type (It.Typ)) + if Is_Effectively_Visible_Operator (N, Base_Type (It.Typ)) then Add_One_Interp (N, Op_Id, Base_Type (It.Typ)); end if; @@ -8533,21 +8528,29 @@ package body Sem_Ch4 is Prefix : Node_Id; Exprs : List_Id) return Boolean is - Pref_Typ : Entity_Id := Etype (Prefix); + Heuristic : Boolean := False; + Pref_Typ : Entity_Id := Etype (Prefix); function Constant_Indexing_OK return Boolean; - -- Constant_Indexing is legal if there is no Variable_Indexing defined - -- for the type, or else node not a target of assignment, or an actual - -- for an IN OUT or OUT formal (RM 4.1.6 (11)). - - function Expr_Matches_In_Formal - (Subp : Entity_Id; - Par : Node_Id) return Boolean; - -- Find formal corresponding to given indexed component that is an - -- actual in a call. Note that the enclosing subprogram call has not - -- been analyzed yet, and the parameter list is not normalized, so - -- that if the argument is a parameter association we must match it - -- by name and not by position. + -- Determines whether the Constant_Indexing aspect has been specified + -- for the type of the prefix and can be interpreted as constant + -- indexing; that is, there is no Variable_Indexing defined for the + -- type, or else the node is not a target of an assignment, or an + -- actual for an IN OUT or OUT formal, or the name in an object + -- renaming (RM 4.1.6 (12/3..15/3)). + -- + -- Given that prefix notation calls have not yet been resolved, if the + -- type of the prefix has both aspects present (Constant_Indexing and + -- Variable_Indexing), and context analysis performed by this routine + -- identifies a potential prefix notation call (i.e., an N_Selected_ + -- Component node), this function may rely on heuristics to decide + -- between constant or variable indexing. In such cases, if the + -- decision is later found to be incorrect, Try_Container_Indexing + -- will retry using the alternative indexing aspect. + + -- When heuristics are used to compute the result of this function + -- the behavior of Try_Container_Indexing might not be strictly + -- following the rules of the RM. function Indexing_Interpretations (T : Entity_Id; @@ -8555,59 +8558,429 @@ package body Sem_Ch4 is -- Return a set of interpretations reflecting all of the functions -- associated with an indexing aspect of type T of the given kind. + function Try_Indexing_Function + (Func_Name : Node_Id; + Assoc : List_Id) return Entity_Id; + -- Build a call to the given indexing function name with the given + -- parameter associations; if there are several indexing functions + -- the call is analyzed for each of the interpretation; if there are + -- several successfull candidates, resolution is handled by result. + -- Return the Etype of the built function call. + -------------------------- -- Constant_Indexing_OK -- -------------------------- function Constant_Indexing_OK return Boolean is - Par : Node_Id; + + function Expr_Matches_In_Formal + (Subp : Entity_Id; + Subp_Call : Node_Id; + Param : Node_Id; + Skip_Controlling_Formal : Boolean := False) return Boolean; + -- Find formal corresponding to given indexed component that is an + -- actual in a call. Note that the enclosing subprogram call has not + -- been analyzed yet, and the parameter list is not normalized, so + -- that if the argument is a parameter association we must match it + -- by name and not by position. In the traversal up the tree done by + -- Constant_Indexing_OK, the previous node in the traversal (that is, + -- the actual parameter used to ascend to the subprogram call node), + -- is passed to this function in formal Param, and it is used to + -- determine wether the argument is passed by name or by position. + -- Skip_Controlling_Formal is set to True to skip the first formal + -- of Subp. + + procedure Handle_Selected_Component + (Current_Node : Node_Id; + Sel_Comp : Node_Id; + Candidate : out Entity_Id; + Is_Constant_Idx : out Boolean); + -- Current_Node is the current node climbing up the tree. Determine + -- if Sel_Comp is a candidate for a prefixed call using constant + -- indexing; if no candidate is found Candidate is returned Empty + -- and Is_Constant_Idx is returned False. + + function Has_IN_Mode (Formal : Node_Id) return Boolean is + (Ekind (Formal) = E_In_Parameter); + -- Return True if the given formal has mode IN + + ---------------------------- + -- Expr_Matches_In_Formal -- + ---------------------------- + + function Expr_Matches_In_Formal + (Subp : Entity_Id; + Subp_Call : Node_Id; + Param : Node_Id; + Skip_Controlling_Formal : Boolean := False) return Boolean + is + pragma Assert (Nkind (Subp_Call) in N_Subprogram_Call); + + Actual : Node_Id := First (Parameter_Associations (Subp_Call)); + Formal : Node_Id := First_Formal (Subp); + + begin + if Skip_Controlling_Formal then + Next_Formal (Formal); + end if; + + -- Match by position + + if Nkind (Param) /= N_Parameter_Association then + while Present (Actual) and then Present (Formal) loop + exit when Actual = Param; + Next (Actual); + + if Present (Formal) then + Next_Formal (Formal); + + -- Otherwise this is a parameter mismatch, the error is + -- reported elsewhere, or else variable indexing is implied. + + else + return False; + end if; + end loop; + + -- Match by name + + else + while Present (Formal) loop + exit when Chars (Formal) = Chars (Selector_Name (Param)); + Next_Formal (Formal); + + if No (Formal) then + return False; + end if; + end loop; + end if; + + return Present (Formal) and then Has_IN_Mode (Formal); + end Expr_Matches_In_Formal; + + ------------------------------- + -- Handle_Selected_Component -- + ------------------------------- + + procedure Handle_Selected_Component + (Current_Node : Node_Id; + Sel_Comp : Node_Id; + Candidate : out Entity_Id; + Is_Constant_Idx : out Boolean) + is + procedure Search_Constant_Interpretation + (Call : Node_Id; + Target_Name : Node_Id; + Candidate : out Entity_Id; + Is_Unique : out Boolean; + Unique_Mode : out Boolean); + -- Given a subprogram call, search in the homonyms chain for + -- visible (or potentially visible) dispatching primitives that + -- have at least one formal. Candidate is the entity of the first + -- found candidate; Is_Unique is returned True when the mode of + -- the first formal of all the candidates match. If no candidate + -- is found the out parameter Candidate is returned Empty, and + -- Is_Unique is returned False. + + procedure Search_Enclosing_Call + (Call_Node : out Node_Id; + Prev_Node : out Node_Id); + -- Climb up to the tree looking for an enclosing subprogram call + -- of a prefixed notation call. If found then the Call_Node and + -- its Prev_Node in such traversal are returned; otherwise + -- Call_Node and Prev_Node are returned Empty. + + ------------------------------------ + -- Search_Constant_Interpretation -- + ------------------------------------ + + procedure Search_Constant_Interpretation + (Call : Node_Id; + Target_Name : Node_Id; + Candidate : out Entity_Id; + Is_Unique : out Boolean; + Unique_Mode : out Boolean) + is + Constant_Idx : Boolean; + In_Proc_Call : constant Boolean := + Present (Call) + and then + Nkind (Call) = N_Procedure_Call_Statement; + Kind : constant Entity_Kind := + (if In_Proc_Call then E_Procedure + else E_Function); + Target_Subp : constant Entity_Id := + Current_Entity (Target_Name); + begin + Candidate := Empty; + Is_Unique := False; + Unique_Mode := False; + + if Present (Target_Subp) then + declare + Hom : Entity_Id := Target_Subp; + + begin + while Present (Hom) loop + if Is_Overloadable (Hom) + and then Is_Dispatching_Operation (Hom) + and then + (Is_Immediately_Visible (Scope (Hom)) + or else + Is_Potentially_Use_Visible (Scope (Hom))) + and then Ekind (Hom) = Kind + and then Present (First_Formal (Hom)) + then + if No (Candidate) then + Candidate := Hom; + Is_Unique := True; + Unique_Mode := True; + Constant_Idx := + Has_IN_Mode (First_Formal (Candidate)); + + else + Is_Unique := False; + + if Ekind (First_Formal (Hom)) + /= Ekind (First_Formal (Candidate)) + or else Has_IN_Mode (First_Formal (Hom)) + /= Constant_Idx + then + Unique_Mode := False; + exit; + end if; + end if; + end if; + + Hom := Homonym (Hom); + end loop; + end; + end if; + end Search_Constant_Interpretation; + + --------------------------- + -- Search_Enclosing_Call -- + --------------------------- + + procedure Search_Enclosing_Call + (Call_Node : out Node_Id; + Prev_Node : out Node_Id) + is + Prev : Node_Id := Current_Node; + Par : Node_Id := Parent (N); + + begin + while Present (Par) + and then Nkind (Par) not in N_Subprogram_Call + | N_Handled_Sequence_Of_Statements + | N_Assignment_Statement + | N_Iterator_Specification + | N_Object_Declaration + | N_Case_Statement + | N_Declaration + | N_Elsif_Part + | N_If_Statement + | N_Simple_Return_Statement + loop + Prev := Par; + Par := Parent (Par); + end loop; + + if Present (Par) + and then Nkind (Par) in N_Subprogram_Call + and then Nkind (Name (Par)) = N_Selected_Component + then + Call_Node := Par; + Prev_Node := Prev; + else + Call_Node := Empty; + Prev_Node := Empty; + end if; + end Search_Enclosing_Call; + + -- Local variables + + Is_Unique : Boolean; + Unique_Mode : Boolean; + Call_Node : Node_Id; + Prev_Node : Node_Id; + + -- Start of processing for Handle_Selected_Component + + begin + pragma Assert (Nkind (Sel_Comp) = N_Selected_Component); + + -- Climb up the tree starting from Current_Node searching for the + -- enclosing subprogram call of a prefixed notation call. + + Search_Enclosing_Call (Call_Node, Prev_Node); + + -- Search for a candidate visible (or potentially visible) + -- dispatching primitive that has at least one formal, and may + -- be called using the prefix notation. This must be done even + -- if we did not found an enclosing call since the prefix notation + -- call has not been transformed yet into a subprogram call. The + -- found Call_Node (if any) is passed now to help identifying if + -- the prefix notation call corresponds with a procedure call or + -- a function call. + + Search_Constant_Interpretation + (Call => Call_Node, + Target_Name => Selector_Name (Sel_Comp), + Candidate => Candidate, + Is_Unique => Is_Unique, + Unique_Mode => Unique_Mode); + + -- If there is no candidate to interpret this node as a prefixed + -- call to a subprogram we return no candidate, and the caller + -- will continue ascending in the tree. + + if No (Candidate) then + Is_Constant_Idx := False; + + -- If we found an unique candidate and also found the enclosing + -- call node, we differentiate two cases: either we climbed up + -- the tree through the first actual parameter of the call (that + -- is, the name of the selected component), or we climbed up the + -- tree though another actual parameter of the prefixed call and + -- we must skip the controlling formal of the call. + + elsif Is_Unique + and then Present (Call_Node) + then + -- First actual parameter + + if Name (Call_Node) = Prev_Node + and then Nkind (Prev_Node) = N_Selected_Component + and then Nkind (Selector_Name (Prev_Node)) in N_Has_Chars + and then Chars (Selector_Name (Prev_Node)) = Chars (Candidate) + then + Is_Constant_Idx := Has_IN_Mode (First_Formal (Candidate)); + + -- Any other actual parameter + + else + Is_Constant_Idx := + Expr_Matches_In_Formal (Candidate, + Subp_Call => Call_Node, + Param => Prev_Node, + Skip_Controlling_Formal => True); + end if; + + -- The mode of the first formal of all the candidates match but, + -- given that we have several candidates, we cannot check if + -- indexing is used in the first actual parameter of the call + -- or in another actual parameter. Heuristically assume here + -- that indexing is used in the prefix of a call. + + elsif Unique_Mode then + Heuristic := True; + Is_Constant_Idx := Has_IN_Mode (First_Formal (Candidate)); + + -- The target candidate subprogram has several possible + -- interpretations; we don't know what to do with an + -- N_Selected_Component node for a prefixed notation call + -- to AA.BB that has several candidate targets and it has + -- not yet been resolved. For now we maintain the + -- behavior that we have had so far; to be improved??? + + else + Heuristic := True; + + if Nkind (Call_Node) = N_Procedure_Call_Statement then + Is_Constant_Idx := False; + + -- For function calls we rely on the mode of the + -- first formal of the first found candidate??? + + else + Is_Constant_Idx := Has_IN_Mode (First_Formal (Candidate)); + end if; + end if; + end Handle_Selected_Component; + + -- Local variables + + Asp_Constant : constant Node_Id := + Find_Value_Of_Aspect (Pref_Typ, + Aspect_Constant_Indexing); + Asp_Variable : constant Node_Id := + Find_Value_Of_Aspect (Pref_Typ, + Aspect_Variable_Indexing); + Par : Node_Id; + + -- Start of processing for Constant_Indexing_OK begin - if No (Find_Value_Of_Aspect (Pref_Typ, Aspect_Variable_Indexing)) then + if No (Asp_Constant) then + return False; + + -- It is interpreted as constant indexing when the prefix has the + -- Constant_Indexing aspect and the Variable_Indexing aspect is not + -- specified for the type of the prefix. + + elsif No (Asp_Variable) then return True; + -- It is interpreted as constant indexing when the prefix denotes + -- a constant. + elsif not Is_Variable (Prefix) then return True; end if; + -- Both aspects are present + + pragma Assert (Present (Asp_Constant) and Present (Asp_Variable)); + + -- The prefix must be interpreted as a constant indexing when it + -- is used within a primary where a name denoting a constant is + -- permitted. + Par := N; while Present (Par) loop - if Nkind (Parent (Par)) = N_Assignment_Statement - and then Par = Name (Parent (Par)) + + -- Avoid climbing more than needed + + exit when Nkind (Parent (Par)) in N_Iterator_Specification + | N_Handled_Sequence_Of_Statements; + + if Nkind (Parent (Par)) in N_Case_Statement + | N_Declaration + | N_Elsif_Part + | N_If_Statement + | N_Simple_Return_Statement then - return False; + return True; + + -- It is not interpreted as constant indexing for the variable + -- name in the LHS of an assignment. + + elsif Nkind (Parent (Par)) = N_Assignment_Statement then + return Par /= Name (Parent (Par)); -- The call may be overloaded, in which case we assume that its -- resolution does not depend on the type of the parameter that - -- includes the indexing operation. + -- includes the indexing operation because we cannot invoke + -- Preanalyze_And_Resolve (since it would cause a never-ending + -- loop). elsif Nkind (Parent (Par)) in N_Subprogram_Call then - if not Is_Entity_Name (Name (Parent (Par))) then + -- Regular subprogram call - -- ??? We don't know what to do with an N_Selected_Component - -- node for a prefixed-notation call to AA.BB where AA's - -- type is known, but BB has not yet been resolved. In that - -- case, the preceding Is_Entity_Name call returns False. - -- Incorrectly returning False here will usually work - -- better than incorrectly returning True, so that's what - -- we do for now. + -- It is not interpreted as constant indexing for the name + -- used for an OUT or IN OUT parameter. - return False; - end if; - - declare - Proc : Entity_Id; - - begin - -- We should look for an interpretation with the proper - -- number of formals, and determine whether it is an - -- In_Parameter, but for now we examine the formal that - -- corresponds to the indexing, and assume that variable - -- indexing is required if some interpretation has an - -- assignable formal at that position. Still does not - -- cover the most complex cases ??? + -- We should look for an interpretation with the proper + -- number of formals, and determine whether it is an + -- In_Parameter, but for now we examine the formal that + -- corresponds to the indexing, and assume that variable + -- indexing is required if some interpretation has an + -- assignable formal at that position. Still does not + -- cover the most complex cases ??? + if Is_Entity_Name (Name (Parent (Par))) then if Is_Overloaded (Name (Parent (Par))) then declare Proc : constant Node_Id := Name (Parent (Par)); @@ -8617,57 +8990,103 @@ package body Sem_Ch4 is begin Get_First_Interp (Proc, I, It); while Present (It.Nam) loop - if not Expr_Matches_In_Formal (It.Nam, Par) then + if not Expr_Matches_In_Formal + (Subp => It.Nam, + Subp_Call => Parent (Par), + Param => Par) + then return False; end if; Get_Next_Interp (I, It); end loop; - end; - -- All interpretations have a matching in-mode formal + -- All interpretations have a matching in-mode formal - return True; + return True; + end; else - Proc := Entity (Name (Parent (Par))); + declare + Proc : Entity_Id := Entity (Name (Parent (Par))); - -- If this is an indirect call, get formals from - -- designated type. + begin + -- If this is an indirect call, get formals from + -- designated type. - if Is_Access_Subprogram_Type (Etype (Proc)) then - Proc := Designated_Type (Etype (Proc)); - end if; + if Is_Access_Subprogram_Type (Etype (Proc)) then + Proc := Designated_Type (Etype (Proc)); + end if; + + return Expr_Matches_In_Formal + (Subp => Proc, + Subp_Call => Parent (Par), + Param => Par); + end; end if; - return Expr_Matches_In_Formal (Proc, Par); - end; + -- Continue climbing + + elsif Nkind (Name (Parent (Par))) = N_Explicit_Dereference then + null; + + -- Not a regular call; we know that we are in a subprogram + -- call, we also know that the name of the call may be a + -- prefixed call, and we know the name of the target + -- subprogram. Search for an unique target candidate in the + -- homonym chain. + + elsif Nkind (Name (Parent (Par))) = N_Selected_Component then + declare + Candidate : Entity_Id; + Is_Constant_Idx : Boolean; + + begin + Handle_Selected_Component + (Current_Node => Par, + Sel_Comp => Name (Parent (Par)), + Candidate => Candidate, + Is_Constant_Idx => Is_Constant_Idx); + + if Present (Candidate) then + return Is_Constant_Idx; + + -- Continue climbing + + else + null; + end if; + end; + end if; + + -- It is not interpreted as constant indexing for the name in + -- an object renaming. elsif Nkind (Parent (Par)) = N_Object_Renaming_Declaration then return False; - -- If the indexed component is a prefix it may be the first actual - -- of a prefixed call. Retrieve the called entity, if any, and - -- check its first formal. Determine if the context is a procedure - -- or function call. + -- If the indexed component is a prefix it may be an actual of + -- of a prefixed call. elsif Nkind (Parent (Par)) = N_Selected_Component then declare - Sel : constant Node_Id := Selector_Name (Parent (Par)); - Nam : constant Entity_Id := Current_Entity (Sel); + Candidate : Entity_Id; + Is_Constant_Idx : Boolean; begin - if Present (Nam) and then Is_Overloadable (Nam) then - if Nkind (Parent (Parent (Par))) = - N_Procedure_Call_Statement - then - return False; + Handle_Selected_Component + (Current_Node => Par, + Sel_Comp => Parent (Par), + Candidate => Candidate, + Is_Constant_Idx => Is_Constant_Idx); - elsif Ekind (Nam) = E_Function - and then Present (First_Formal (Nam)) - then - return Ekind (First_Formal (Nam)) = E_In_Parameter; - end if; + if Present (Candidate) then + return Is_Constant_Idx; + + -- Continue climbing + + else + null; end if; end; @@ -8678,61 +9097,12 @@ package body Sem_Ch4 is Par := Parent (Par); end loop; - -- In all other cases, constant indexing is legal + -- It is not interpreted as constant indexing when both aspects + -- are present (RM 4.1.6(13/3)). - return True; + return False; end Constant_Indexing_OK; - ---------------------------- - -- Expr_Matches_In_Formal -- - ---------------------------- - - function Expr_Matches_In_Formal - (Subp : Entity_Id; - Par : Node_Id) return Boolean - is - Actual : Node_Id; - Formal : Node_Id; - - begin - Formal := First_Formal (Subp); - Actual := First (Parameter_Associations ((Parent (Par)))); - - if Nkind (Par) /= N_Parameter_Association then - - -- Match by position - - while Present (Actual) and then Present (Formal) loop - exit when Actual = Par; - Next (Actual); - - if Present (Formal) then - Next_Formal (Formal); - - -- Otherwise this is a parameter mismatch, the error is - -- reported elsewhere, or else variable indexing is implied. - - else - return False; - end if; - end loop; - - else - -- Match by name - - while Present (Formal) loop - exit when Chars (Formal) = Chars (Selector_Name (Par)); - Next_Formal (Formal); - - if No (Formal) then - return False; - end if; - end loop; - end if; - - return Present (Formal) and then Ekind (Formal) = E_In_Parameter; - end Expr_Matches_In_Formal; - ------------------------------ -- Indexing_Interpretations -- ------------------------------ @@ -8782,14 +9152,127 @@ package body Sem_Ch4 is return Indexing_Func; end Indexing_Interpretations; + --------------------------- + -- Try_Indexing_Function -- + --------------------------- + + function Try_Indexing_Function + (Func_Name : Node_Id; + Assoc : List_Id) return Entity_Id + is + Loc : constant Source_Ptr := Sloc (N); + Func : Entity_Id; + Indexing : Node_Id; + + begin + if not Is_Overloaded (Func_Name) then + Func := Entity (Func_Name); + + Indexing := + Make_Function_Call (Loc, + Name => New_Occurrence_Of (Func, Loc), + Parameter_Associations => Assoc); + + Set_Parent (Indexing, Parent (N)); + Set_Generalized_Indexing (N, Indexing); + Analyze (Indexing); + Set_Etype (N, Etype (Indexing)); + + -- If the return type of the indexing function is a reference + -- type, add the dereference as a possible interpretation. Note + -- that the indexing aspect may be a function that returns the + -- element type with no intervening implicit dereference, and + -- that the reference discriminant is not the first discriminant. + + if Has_Discriminants (Etype (Func)) then + Check_Implicit_Dereference (N, Etype (Func)); + end if; + + else + -- If there are multiple indexing functions, build a function + -- call and analyze it for each of the possible interpretations. + + Indexing := + Make_Function_Call (Loc, + Name => + Make_Identifier (Loc, Chars (Func_Name)), + Parameter_Associations => Assoc); + Set_Parent (Indexing, Parent (N)); + Set_Generalized_Indexing (N, Indexing); + Set_Etype (N, Any_Type); + Set_Etype (Name (Indexing), Any_Type); + + declare + I : Interp_Index; + It : Interp; + Success : Boolean; + + begin + Get_First_Interp (Func_Name, I, It); + Set_Etype (Indexing, Any_Type); + + -- Analyze each candidate function with the given actuals + + while Present (It.Nam) loop + Analyze_One_Call (Indexing, It.Nam, False, Success); + Get_Next_Interp (I, It); + end loop; + + -- If there are several successful candidates, resolution will + -- be by result. Mark the interpretations of the function name + -- itself. + + if Is_Overloaded (Indexing) then + Get_First_Interp (Indexing, I, It); + + while Present (It.Nam) loop + Add_One_Interp (Name (Indexing), It.Nam, It.Typ); + Get_Next_Interp (I, It); + end loop; + + else + Set_Etype (Name (Indexing), Etype (Indexing)); + end if; + + -- Now add the candidate interpretations to the indexing node + -- itself, to be replaced later by the function call. + + if Is_Overloaded (Name (Indexing)) then + Get_First_Interp (Name (Indexing), I, It); + + while Present (It.Nam) loop + Add_One_Interp (N, It.Nam, It.Typ); + + -- Add dereference interpretation if the result type has + -- implicit reference discriminants. + + if Has_Discriminants (Etype (It.Nam)) then + Check_Implicit_Dereference (N, Etype (It.Nam)); + end if; + + Get_Next_Interp (I, It); + end loop; + + else + Set_Etype (N, Etype (Name (Indexing))); + + if Has_Discriminants (Etype (N)) then + Check_Implicit_Dereference (N, Etype (N)); + end if; + end if; + end; + end if; + + return Etype (Indexing); + end Try_Indexing_Function; + -- Local variables Loc : constant Source_Ptr := Sloc (N); Assoc : List_Id; C_Type : Entity_Id; - Func : Entity_Id; Func_Name : Node_Id; - Indexing : Node_Id; + Idx_Type : Entity_Id; -- Start of processing for Try_Container_Indexing @@ -8799,6 +9282,13 @@ package body Sem_Ch4 is if Present (Generalized_Indexing (N)) then return True; + + -- Old language version or unknown type require no action + + elsif Ada_Version < Ada_2012 + or else Pref_Typ = Any_Type + then + return False; end if; -- An explicit dereference needs to be created in the case of a prefix @@ -8833,8 +9323,8 @@ package body Sem_Ch4 is Func_Name := Empty; - -- The context is suitable for constant indexing, so obtain the name of - -- the indexing functions from aspect Constant_Indexing. + -- The context is suitable for constant indexing, so obtain the name + -- of the indexing functions from aspect Constant_Indexing. if Constant_Indexing_OK then Func_Name := @@ -8867,6 +9357,11 @@ package body Sem_Ch4 is else return False; end if; + + -- Handle cascaded errors + + elsif No (Entity (Func_Name)) then + return False; end if; Assoc := New_List (Relocate_Node (Prefix)); @@ -8907,110 +9402,54 @@ package body Sem_Ch4 is end loop; end; - if not Is_Overloaded (Func_Name) then - Func := Entity (Func_Name); - - -- Can happen in case of e.g. cascaded errors - - if No (Func) then - return False; - end if; - - Indexing := - Make_Function_Call (Loc, - Name => New_Occurrence_Of (Func, Loc), - Parameter_Associations => Assoc); - - Set_Parent (Indexing, Parent (N)); - Set_Generalized_Indexing (N, Indexing); - Analyze (Indexing); - Set_Etype (N, Etype (Indexing)); - - -- If the return type of the indexing function is a reference type, - -- add the dereference as a possible interpretation. Note that the - -- indexing aspect may be a function that returns the element type - -- with no intervening implicit dereference, and that the reference - -- discriminant is not the first discriminant. - - if Has_Discriminants (Etype (Func)) then - Check_Implicit_Dereference (N, Etype (Func)); - end if; - - else - -- If there are multiple indexing functions, build a function call - -- and analyze it for each of the possible interpretations. - - Indexing := - Make_Function_Call (Loc, - Name => - Make_Identifier (Loc, Chars (Func_Name)), - Parameter_Associations => Assoc); - Set_Parent (Indexing, Parent (N)); - Set_Generalized_Indexing (N, Indexing); - Set_Etype (N, Any_Type); - Set_Etype (Name (Indexing), Any_Type); - + Idx_Type := Try_Indexing_Function (Func_Name, Assoc); + + -- Last chance handling for heuristics: Given that prefix notation + -- calls have not yet been resolved, when the type of the prefix has + -- both operational aspects present (Constant_Indexing and Variable_ + -- Indexing), and the analysis of the context identified a potential + -- prefix notation call (i.e. an N_Selected_Component node), the + -- evaluation of Constant_Indexing_OK is based on heuristics; in such + -- case, if the chosen indexing approach is noticed now to be wrong + -- we retry with the other alternative before leaving. + + -- Retrying means that the heuristic decision taken when analyzing + -- the context failed in this case, and therefore we should adjust + -- the code of Handle_Selected_Component to improve identification + -- of prefix notation calls. This last chance handling handler is + -- left here for the purpose of improving such routine because it + -- proved to be usefull for identified such cases when the function + -- Handle_Selected_Component was added. + + if Idx_Type = Any_Type and then Heuristic then declare - I : Interp_Index; - It : Interp; - Success : Boolean; + Tried_Func_Name : constant Node_Id := Func_Name; begin - Get_First_Interp (Func_Name, I, It); - Set_Etype (Indexing, Any_Type); + Func_Name := + Indexing_Interpretations (C_Type, + Aspect_Constant_Indexing); - -- Analyze each candidate function with the given actuals - - while Present (It.Nam) loop - Analyze_One_Call (Indexing, It.Nam, False, Success); - Get_Next_Interp (I, It); - end loop; - - -- If there are several successful candidates, resolution will - -- be by result. Mark the interpretations of the function name - -- itself. - - if Is_Overloaded (Indexing) then - Get_First_Interp (Indexing, I, It); - - while Present (It.Nam) loop - Add_One_Interp (Name (Indexing), It.Nam, It.Typ); - Get_Next_Interp (I, It); - end loop; + if Present (Func_Name) + and then Func_Name /= Tried_Func_Name + then + Idx_Type := Try_Indexing_Function (Func_Name, Assoc); else - Set_Etype (Name (Indexing), Etype (Indexing)); - end if; - - -- Now add the candidate interpretations to the indexing node - -- itself, to be replaced later by the function call. - - if Is_Overloaded (Name (Indexing)) then - Get_First_Interp (Name (Indexing), I, It); - - while Present (It.Nam) loop - Add_One_Interp (N, It.Nam, It.Typ); - - -- Add dereference interpretation if the result type has - -- implicit reference discriminants. - - if Has_Discriminants (Etype (It.Nam)) then - Check_Implicit_Dereference (N, Etype (It.Nam)); - end if; - - Get_Next_Interp (I, It); - end loop; + Func_Name := + Indexing_Interpretations (C_Type, + Aspect_Variable_Indexing); - else - Set_Etype (N, Etype (Name (Indexing))); - if Has_Discriminants (Etype (N)) then - Check_Implicit_Dereference (N, Etype (N)); + if Present (Func_Name) + and then Func_Name /= Tried_Func_Name + then + Idx_Type := Try_Indexing_Function (Func_Name, Assoc); end if; end if; end; end if; - if Etype (Indexing) = Any_Type then + if Idx_Type = Any_Type then Error_Msg_NE ("container cannot be indexed with&", N, Etype (First (Exprs))); Rewrite (N, New_Occurrence_Of (Any_Id, Loc)); @@ -9971,11 +10410,14 @@ package body Sem_Ch4 is -- may be candidates, so that Try_Primitive_Operations can examine -- them if no real primitive is found. - function Is_Private_Overriding (Op : Entity_Id) return Boolean; + function Is_Callable_Private_Overriding + (Op : Entity_Id) return Boolean; -- An operation that overrides an inherited operation in the private -- part of its package may be hidden, but if the inherited operation - -- is visible a direct call to it will dispatch to the private one, - -- which is therefore a valid candidate. + -- that it overrides is visible, then a direct call to it will + -- dispatch to the private one, which is therefore a valid candidate. + -- Returns True if the operation can be called from outside the + -- enclosing package. function Names_Match (Obj_Type : Entity_Id; @@ -10146,11 +10588,13 @@ package body Sem_Ch4 is return Op_List; end Extended_Primitive_Ops; - --------------------------- - -- Is_Private_Overriding -- - --------------------------- + ------------------------------------ + -- Is_Callable_Private_Overriding -- + ------------------------------------ - function Is_Private_Overriding (Op : Entity_Id) return Boolean is + function Is_Callable_Private_Overriding + (Op : Entity_Id) return Boolean + is Visible_Op : Entity_Id; begin @@ -10172,7 +10616,10 @@ package body Sem_Ch4 is -- have found what we're looking for. if not Is_Hidden (Visible_Op) - or else not Is_Hidden (Overridden_Operation (Op)) + or else + (Present (Overridden_Inherited_Operation (Op)) + and then not Is_Hidden + (Overridden_Inherited_Operation (Op))) then return True; end if; @@ -10182,7 +10629,7 @@ package body Sem_Ch4 is end loop; return False; - end Is_Private_Overriding; + end Is_Callable_Private_Overriding; ----------------- -- Names_Match -- @@ -10257,6 +10704,7 @@ package body Sem_Ch4 is or else (Has_Unknown_Discriminants (Typ) + and then Is_Record_Type (Base_Type (Obj_Type)) and then Typ = Underlying_Record_View (Base_Type (Obj_Type))) -- Prefix can be dereferenced @@ -10324,13 +10772,15 @@ package body Sem_Ch4 is -- Do not consider hidden primitives unless the type is in an -- open scope or we are within an instance, where visibility - -- is known to be correct, or else if this is an overriding - -- operation in the private part for an inherited operation. + -- is known to be correct, or else if this is an operation + -- declared in the private part that overrides a visible + -- inherited operation. or else (Is_Hidden (Prim_Op) and then not Is_Immediately_Visible (Obj_Type) and then not In_Instance - and then not Is_Private_Overriding (Prim_Op)) + and then + not Is_Callable_Private_Overriding (Prim_Op)) then goto Continue; end if; @@ -10480,6 +10930,10 @@ package body Sem_Ch4 is -- Start of processing for Try_Object_Operation begin + if Is_Class_Wide_Equivalent_Type (Obj_Type) then + Obj_Type := Corresponding_Mutably_Tagged_Type (Obj_Type); + end if; + Analyze_Expression (Obj); -- Analyze the actuals if node is known to be a subprogram call @@ -10667,86 +11121,46 @@ package body Sem_Ch4 is end loop; if No (Op_Id) then - if Debug_Flag_Underscore_DD then - if Nkind (N) /= N_Op_Concat then - if Nkind (N) in N_Op_Multiply | N_Op_Divide - and then Is_Fixed_Point_Type (Etype (L)) - and then Is_Integer_Type (Etype (R)) - then - Record_Invalid_Operand_Types_For_Operator_R_Int_Error - (Op => N, - L => L, - L_Type => Etype (L), - R => R, - R_Type => Etype (R)); - - elsif Nkind (N) = N_Op_Multiply - and then Is_Fixed_Point_Type (Etype (R)) - and then Is_Integer_Type (Etype (L)) - then - Record_Invalid_Operand_Types_For_Operator_L_Int_Error - (Op => N, - L => L, - L_Type => Etype (L), - R => R, - R_Type => Etype (R)); - else - Record_Invalid_Operand_Types_For_Operator_Error - (Op => N, - L => L, - L_Type => Etype (L), - R => R, - R_Type => Etype (R)); - end if; - elsif Is_Access_Type (Etype (L)) then - Record_Invalid_Operand_Types_For_Operator_L_Acc_Error - (Op => N, - L => L); - - elsif Is_Access_Type (Etype (R)) then - Record_Invalid_Operand_Types_For_Operator_R_Acc_Error - (Op => N, - R => R); - else - Record_Invalid_Operand_Types_For_Operator_General_Error - (N); - end if; - else - Error_Msg_N ("invalid operand types for operator&", N); + Error_Msg_N + ("invalid operand types for operator&", N, + GNAT0002); - if Nkind (N) /= N_Op_Concat then - Error_Msg_NE ("\left operand has}!", N, Etype (L)); - Error_Msg_NE ("\right operand has}!", N, Etype (R)); + if Nkind (N) /= N_Op_Concat then + Error_Msg_NE + ("\left operand has}!", N, Etype (L)); + Error_Msg_NE + ("\right operand has}!", N, Etype (R)); - -- For multiplication and division operators with - -- a fixed-point operand and an integer operand, - -- indicate that the integer operand should be of - -- type Integer. + -- For multiplication and division operators with + -- a fixed-point operand and an integer operand, + -- indicate that the integer operand should be of + -- type Integer. - if Nkind (N) in N_Op_Multiply | N_Op_Divide - and then Is_Fixed_Point_Type (Etype (L)) - and then Is_Integer_Type (Etype (R)) - then - Error_Msg_N ("\convert right operand to `Integer`", N); + if Nkind (N) in N_Op_Multiply | N_Op_Divide + and then Is_Fixed_Point_Type (Etype (L)) + and then Is_Integer_Type (Etype (R)) + then + Error_Msg_N + ("\convert right operand to `Integer`", N); - elsif Nkind (N) = N_Op_Multiply - and then Is_Fixed_Point_Type (Etype (R)) - and then Is_Integer_Type (Etype (L)) - then - Error_Msg_N ("\convert left operand to `Integer`", N); - end if; + elsif Nkind (N) = N_Op_Multiply + and then Is_Fixed_Point_Type (Etype (R)) + and then Is_Integer_Type (Etype (L)) + then + Error_Msg_N + ("\convert left operand to `Integer`", N); + end if; -- For concatenation operators it is more difficult to -- determine which is the wrong operand. It is worth -- flagging explicitly an access type, for those who -- might think that a dereference happens here. - elsif Is_Access_Type (Etype (L)) then - Error_Msg_N ("\left operand is access type", N); + elsif Is_Access_Type (Etype (L)) then + Error_Msg_N ("\left operand is access type", N); - elsif Is_Access_Type (Etype (R)) then - Error_Msg_N ("\right operand is access type", N); - end if; + elsif Is_Access_Type (Etype (R)) then + Error_Msg_N ("\right operand is access type", N); end if; end if; end if; diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb index 12d6426671e7..0661e64d095d 100644 --- a/gcc/ada/sem_ch5.adb +++ b/gcc/ada/sem_ch5.adb @@ -90,6 +90,12 @@ package body Sem_Ch5 is -- messages. This variable is recursively saved on entry to processing the -- construct, and restored on exit. + function Analyze_Loop_Flow_Statement + (N : N_Loop_Flow_Statement_Id) return Opt_E_Loop_Id; + -- Perform analysis that is common to continue statements and exit + -- statements. On success, the return value is the entity of the loop + -- referenced by the statement. + function Has_Sec_Stack_Call (N : Node_Id) return Boolean; -- N is the node for an arbitrary construct. This function searches the -- construct N to see if it contains a function call that returns on the @@ -534,7 +540,11 @@ package body Sem_Ch5 is if In_Inlined_Body then null; - elsif not Is_Variable (Lhs) then + elsif not Is_Variable (Lhs) + and then not (not Comes_From_Source (Lhs) + and then Nkind (Lhs) in N_Has_Etype + and then Needs_Construction (Etype (Lhs))) + then -- Ada 2005 (AI-327): Check assignment to the attribute Priority of a -- protected object. @@ -797,7 +807,14 @@ package body Sem_Ch5 is if Is_Tag_Indeterminate (Rhs) then if Is_Class_Wide_Type (T1) then - Propagate_Tag (Lhs, Rhs); + + -- No need to propagate the tag when the RHS has function calls + -- that already propagated it (see Expand_Call_Helper), or if + -- some error was reported analyzing RHS. + + if not (Error_Posted (Rhs) or else Tag_Propagated (Lhs)) then + Propagate_Tag (Lhs, Rhs); + end if; elsif Nkind (Rhs) = N_Function_Call and then Is_Entity_Name (Name (Rhs)) @@ -1659,6 +1676,112 @@ package body Sem_Ch5 is end if; end Analyze_Case_Statement; + -------------------------------- + -- Analyze_Continue_Statement -- + -------------------------------- + + procedure Analyze_Continue_Statement (N : Node_Id) is + Ignore_Errors_On_Entry : constant Boolean := Get_Ignore_Errors; + + Loc : constant Source_Ptr := Sloc (N); + + Nam : constant Node_Id := Name (N); + Cond : constant Node_Id := Condition (N); + + function Make_Call return N_Procedure_Call_Statement_Id; + -- Build a node that corresponds to the procedure call interpretation of + -- N. + + function Make_Stmt return N_Continue_Statement_Id; + -- Build a node that corresponds to the continue statement + -- interpretation of N. + + function Make_Call return N_Procedure_Call_Statement_Id is + begin + return + Make_Procedure_Call_Statement + (Loc, Make_Identifier (Loc, Name_Continue)); + end Make_Call; + + function Make_Stmt return N_Continue_Statement_Id is + begin + return Make_Continue_Statement (Loc, Nam, Cond); + end Make_Stmt; + + Continue_Is_Available : constant Boolean := + Ada_Version = Ada_With_All_Extensions; + + Maybe_Procedure_Call : constant Boolean := + No (Name (N)) and then No (Condition (N)); + begin + if Maybe_Procedure_Call and then Continue_Is_Available then + -- This is the tricky case. The idea is to do a kind of overload + -- resolution of a procedure call, but with "continue statement" as + -- an additional possible interpretation. To achieve this, we + -- temporarily replace N with a procedure call statement and analyze + -- it in "ignore errors" mode. + Replace (N, Make_Call); + Set_Ignore_Errors (True); + Analyze (N); + Set_Ignore_Errors (Ignore_Errors_On_Entry); + + declare + C : constant N_Procedure_Call_Statement_Id := New_Copy (N); + -- C is the result of our procedure call interpretation analysis + begin + -- We restore N to a continue statement + Replace (N, Make_Stmt); + + if Is_Overloaded (Name (C)) then + -- There are multiple valid procedure call interpretations; we + -- don't mention the possible interpretation as a continue + -- statement for now. It might be possible to add this in the + -- future. + + Set_Call_Or_Target_Loop (N, Make_Call); + elsif Etype (C) = Any_Type then + -- There is no valid procedure call interpretation. We go for + -- the continue statement interpretation. It might not be valid + -- either, but we make the assumption that the user meant to + -- write a continue statement and not a procedure call and emit + -- error messages accordingly. + + Set_Call_Or_Target_Loop (N, Analyze_Loop_Flow_Statement (N)); + else + -- There is a unique valid procedure call interpretation. We + -- test whether the interpretation as a continue statement is + -- valid. + + declare + L : Opt_E_Loop_Id; + begin + Set_Ignore_Errors (True); + L := Analyze_Loop_Flow_Statement (N); + Set_Ignore_Errors (Ignore_Errors_On_Entry); + + if Present (L) then + -- If the continue statement interpretation makes sense, + -- we post an ad hoc ambiguity error. + Error_Msg_N + ("ambiguity between continue statement and call", N); + else + Set_Call_Or_Target_Loop (N, Make_Call); + end if; + end; + end if; + end; + elsif Maybe_Procedure_Call then + Set_Call_Or_Target_Loop (N, Make_Call); + elsif Continue_Is_Available then + Set_Call_Or_Target_Loop (N, Analyze_Loop_Flow_Statement (N)); + else + Error_Msg_GNAT_Extension + (Extension => "continue", + Loc => Sloc (N), + Is_Core_Extension => False); + end if; + end Analyze_Continue_Statement; + ---------------------------- -- Analyze_Exit_Statement -- ---------------------------- @@ -1678,99 +1801,16 @@ package body Sem_Ch5 is -- in a loop. The exit must be the last statement in the if-statement. procedure Analyze_Exit_Statement (N : Node_Id) is - Target : constant Node_Id := Name (N); - Cond : constant Node_Id := Condition (N); - Scope_Id : Entity_Id := Empty; -- initialize to prevent warning - U_Name : Entity_Id; - Kind : Entity_Kind; - + L : constant Opt_E_Loop_Id := Analyze_Loop_Flow_Statement (N); begin - if No (Cond) then - Check_Unreachable_Code (N); - end if; - - if Present (Target) then - Analyze (Target); - U_Name := Entity (Target); - - if not In_Open_Scopes (U_Name) or else Ekind (U_Name) /= E_Loop then - Error_Msg_N ("invalid loop name in exit statement", N); - return; - - else - Set_Has_Exit (U_Name); - end if; - - else - U_Name := Empty; - end if; - - for J in reverse 0 .. Scope_Stack.Last loop - Scope_Id := Scope_Stack.Table (J).Entity; - Kind := Ekind (Scope_Id); - - if Kind = E_Loop and then (No (Target) or else Scope_Id = U_Name) then - Set_Has_Exit (Scope_Id); - exit; - - elsif Kind = E_Block - or else Kind = E_Loop - or else Kind = E_Return_Statement - then - null; - - else - Error_Msg_N - ("cannot exit from program unit or accept statement", N); - return; - end if; - end loop; - - Finally_Legality_Check : declare - -- The following value can actually be a block statement due to - -- expansion, but we call it Target_Loop_Statement because it was - -- originally a loop statement. - Target_Loop_Statement : constant Node_Id := - (if Present (U_Name) then Label_Construct ((Parent (U_Name))) - else Empty); - - X : Node_Id := N; - begin - while Present (X) loop - if Nkind (X) = N_Loop_Statement - and then (No (Target_Loop_Statement) - or else X = Target_Loop_Statement) - then - exit; - elsif Nkind (Parent (X)) = N_Handled_Sequence_Of_Statements - and then Is_List_Member (X) - and then List_Containing (X) = Finally_Statements (Parent (X)) - then - Error_Msg_N ("cannot exit out of finally part", N); - exit; - end if; - X := Parent (X); - end loop; - end Finally_Legality_Check; + if Present (L) then + Set_Has_Exit (L); - -- Verify that if present the condition is a Boolean expression + -- Chain exit statement to associated loop entity - if Present (Cond) then - Analyze_And_Resolve (Cond, Any_Boolean); - Check_Unset_Reference (Cond); + Set_Next_Exit_Statement (N, First_Exit_Statement (L)); + Set_First_Exit_Statement (L, N); end if; - - -- Chain exit statement to associated loop entity - - Set_Next_Exit_Statement (N, First_Exit_Statement (Scope_Id)); - Set_First_Exit_Statement (Scope_Id, N); - - -- Since the exit may take us out of a loop, any previous assignment - -- statement is not useless, so clear last assignment indications. It - -- is OK to keep other current values, since if the exit statement - -- does not exit, then the current values are still valid. - - Kill_Current_Values (Last_Assignment_Only => True); end Analyze_Exit_Statement; ---------------------------- @@ -3145,6 +3185,7 @@ package body Sem_Ch5 is -- Start of processing for Analyze_Loop_Parameter_Specification begin + Mutate_Ekind (Id, E_Loop_Parameter); Enter_Name (Id); -- We always consider the loop variable to be referenced, since the loop @@ -3250,7 +3291,6 @@ package body Sem_Ch5 is -- subsequent analysis of the condition in a quantified -- expression. - Mutate_Ekind (Id, E_Loop_Parameter); return; end; @@ -3313,7 +3353,6 @@ package body Sem_Ch5 is Make_Index (DS, N); end if; - Mutate_Ekind (Id, E_Loop_Parameter); Set_Etype (Id, Etype (DS)); Set_Is_Not_Self_Hidden (Id); @@ -3557,10 +3596,6 @@ package body Sem_Ch5 is ---------------------------- procedure Analyze_Loop_Statement (N : Node_Id) is - - -- The following exception is raised by routine Prepare_Loop_Statement - -- to avoid further analysis of a transformed loop. - procedure Prepare_Loop_Statement (Iter : Node_Id; Stop_Processing : out Boolean); @@ -3998,6 +4033,18 @@ package body Sem_Ch5 is Set_Has_Created_Identifier (N); end if; + if No (Continue_Mark (Ent)) then + -- If Continue_Mark wasn't set on the loop entity, we know that N + -- does not come from the expansion of iterators that append + -- statements to advance the loop, so right after the last statement + -- in the list is where continue statements must jump to. + Set_Continue_Mark (Ent, Last (Statements (N))); + else + -- Otherwise, N somehow derives from another loop statement, the + -- analysis of which set Continue_Mark adequately already. + null; + end if; + -- Determine whether the loop statement must be transformed prior to -- analysis, and if so, perform it. This early modification is needed -- when: @@ -4207,6 +4254,105 @@ package body Sem_Ch5 is end if; end Analyze_Loop_Statement; + --------------------------------- + -- Analyze_Loop_Flow_Statement -- + --------------------------------- + + function Analyze_Loop_Flow_Statement + (N : N_Loop_Flow_Statement_Id) return Opt_E_Loop_Id + is + Target : constant Node_Id := Name (N); + Cond : constant Node_Id := Condition (N); + Scope_Id : Entity_Id := Empty; + U_Name : Entity_Id; + Kind : Entity_Kind; + + S : constant String := Loop_Flow_Keyword (N); + begin + if No (Cond) then + Check_Unreachable_Code (N); + end if; + + if Present (Target) then + Analyze (Target); + U_Name := Entity (Target); + + if not In_Open_Scopes (U_Name) or else Ekind (U_Name) /= E_Loop then + Error_Msg_N ("invalid loop name in " & S & " statement", N); + return Empty; + end if; + + else + U_Name := Empty; + end if; + + for J in reverse 0 .. Scope_Stack.Last loop + Scope_Id := Scope_Stack.Table (J).Entity; + Kind := Ekind (Scope_Id); + + if Kind = E_Loop and then (No (Target) or else Scope_Id = U_Name) then + exit; + + elsif Kind = E_Block + or else Kind = E_Loop + or else Kind = E_Return_Statement + then + null; + + else + Error_Msg_N + ("cannot " & S & " from program unit or accept statement", N); + return Empty; + end if; + end loop; + + Finally_Legality_Check : + declare + -- The following value can actually be a block statement due to + -- expansion, but we call it Target_Loop_Statement because it was + -- originally a loop statement. + Target_Loop_Statement : constant Node_Id := + (if Present (U_Name) + then Label_Construct ((Parent (U_Name))) + else Empty); + + X : Node_Id := N; + begin + while Present (X) loop + if Nkind (X) = N_Loop_Statement + and then (No (Target_Loop_Statement) + or else X = Target_Loop_Statement) + then + exit; + elsif Nkind (Parent (X)) = N_Handled_Sequence_Of_Statements + and then Is_List_Member (X) + and then List_Containing (X) = Finally_Statements (Parent (X)) + then + Error_Msg_N ("cannot " & S & " out of finally part", N); + exit; + end if; + X := Parent (X); + end loop; + end Finally_Legality_Check; + + -- Verify that if present the condition is a Boolean expression + + if Present (Cond) then + Analyze_And_Resolve (Cond, Any_Boolean); + Check_Unset_Reference (Cond); + end if; + + -- Since the statement may take us out of the current iteration of the + -- loop, any previous assignment statement is not useless, so clear last + -- assignment indications. It is OK to keep other current values, since + -- if the statement does not stop the current iteration, then the + -- current values are still valid. + + Kill_Current_Values (Last_Assignment_Only => True); + + return Scope_Id; + end Analyze_Loop_Flow_Statement; + ---------------------------- -- Analyze_Null_Statement -- ---------------------------- diff --git a/gcc/ada/sem_ch5.ads b/gcc/ada/sem_ch5.ads index 03bfc01d25ef..3a6c90e0460c 100644 --- a/gcc/ada/sem_ch5.ads +++ b/gcc/ada/sem_ch5.ads @@ -31,6 +31,7 @@ package Sem_Ch5 is procedure Analyze_Block_Statement (N : Node_Id); procedure Analyze_Case_Statement (N : Node_Id); procedure Analyze_Compound_Statement (N : Node_Id); + procedure Analyze_Continue_Statement (N : Node_Id); procedure Analyze_Exit_Statement (N : Node_Id); procedure Analyze_Goto_Statement (N : Node_Id); procedure Analyze_Goto_When_Statement (N : Node_Id); diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index 05bbeeddae41..709f6254b5ec 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -225,7 +225,10 @@ package body Sem_Ch6 is -- Create the declaration for an inequality operator that is implicitly -- created by a user-defined equality operator that yields a boolean. - procedure Set_Formal_Mode (Formal_Id : Entity_Id); + procedure Set_Formal_Mode + (Formal_Id : Entity_Id; + Spec : N_Parameter_Specification_Id; + Subp_Id : Entity_Id); -- Set proper Ekind to reflect formal mode (in, out, in out), and set -- miscellaneous other attributes. @@ -581,16 +584,21 @@ package body Sem_Ch6 is Set_Has_Completion (Def_Id, not Is_Ignored_Ghost_Entity (Def_Id)); Push_Scope (Def_Id); Install_Formals (Def_Id); - Preanalyze_Spec_Expression (Expr, Typ); + Preanalyze_And_Resolve_Spec_Expression (Expr, Typ); End_Scope; else Push_Scope (Def_Id); Install_Formals (Def_Id); - Preanalyze_Spec_Expression (Expr, Typ); + Preanalyze_And_Resolve_Spec_Expression (Expr, Typ); Check_Limited_Return (Orig_N, Expr, Typ); End_Scope; end if; + if Is_Incomplete_Type (Typ) then + Error_Msg_NE + ("premature usage of incomplete}", Expr, First_Subtype (Typ)); + end if; + -- In the case of an expression function marked with the aspect -- Static, we need to check the requirement that the function's -- expression is a potentially static expression. This is done @@ -617,7 +625,7 @@ package body Sem_Ch6 is begin Set_Checking_Potentially_Static_Expression (True); - Preanalyze_Spec_Expression (Exp_Copy, Typ); + Preanalyze_And_Resolve_Spec_Expression (Exp_Copy, Typ); if not Is_Static_Expression (Exp_Copy) then Error_Msg_N @@ -2270,6 +2278,23 @@ package body Sem_Ch6 is end if; Formal := First_Formal (Spec_Id); + + -- The first parameter of a borrowing traversal function might be an IN + -- or an IN OUT parameter. + + if Present (Formal) + and then Ekind (Etype (Spec_Id)) = E_Anonymous_Access_Type + and then not Is_Access_Constant (Etype (Spec_Id)) + then + if Ekind (Formal) = E_Out_Parameter then + Error_Msg_Code := GEC_Out_Parameter_In_Function; + Error_Msg_N + ("first parameter of traversal function cannot have mode `OUT` " + & "in SPARK '[[]']", Formal); + end if; + Next_Formal (Formal); + end if; + while Present (Formal) loop if Ekind (Spec_Id) in E_Function | E_Generic_Function and then not Is_Function_With_Side_Effects (Spec_Id) @@ -3839,9 +3864,14 @@ package body Sem_Ch6 is Spec_Id := Build_Internal_Protected_Declaration (N); end if; - -- If a separate spec is present, then deal with freezing issues + -- Separate spec is not present - if Present (Spec_Id) then + if No (Spec_Id) then + Create_Extra_Formals (Body_Id); + + -- Separate spec is present; deal with freezing issues + + else Spec_Decl := Unit_Declaration_Node (Spec_Id); Verify_Overriding_Indicator; @@ -3857,6 +3887,8 @@ package body Sem_Ch6 is and then not Has_BIP_Formals (Spec_Id) then Create_Extra_Formals (Spec_Id); + pragma Assert (not Expander_Active + or else Extra_Formals_Known (Spec_Id)); Compute_Returns_By_Ref (Spec_Id); end if; @@ -4581,7 +4613,7 @@ package body Sem_Ch6 is Analyze_SPARK_Subprogram_Specification (Specification (N)); -- A function with side effects shall not be an expression function - -- (SPARK RM 6.1.11(6)). + -- (SPARK RM 6.1.12(6)). if Present (Spec_Id) and then (Is_Expression_Function (Spec_Id) @@ -4644,10 +4676,8 @@ package body Sem_Ch6 is -- an incomplete tagged type declaration, get the class-wide -- type of the incomplete tagged type to match Find_Type_Name. - if Nkind (Parent (Etyp)) = N_Full_Type_Declaration - and then Present (Incomplete_View (Parent (Etyp))) - then - Etyp := Class_Wide_Type (Incomplete_View (Parent (Etyp))); + if Present (Incomplete_View (Etype (Etyp))) then + Etyp := Class_Wide_Type (Incomplete_View (Etype (Etyp))); end if; Set_Directly_Designated_Type (Etype (Spec_Id), Etyp); @@ -5379,6 +5409,89 @@ package body Sem_Ch6 is End_Scope; + -- Register the subprogram in a Constructor_List when it is a valid + -- constructor. + + if All_Extensions_Allowed + and then Present (First_Formal (Designator)) + then + + declare + First_Form_Type : constant Entity_Id := + Etype (First_Formal (Designator)); + + Construct : Elmt_Id; + begin + -- Valid constructors have a "controlling" formal of a type + -- with the Constructor aspect specified. Additionally, the + -- subprogram name must match value described by the aspect. + + -- Additionally, constructor declarations must exist within the + -- same scope as the type declaration and before the type is + -- frozen. + + -- For example: + -- + -- type Foo is null record with Constructor => Bar; + -- + -- procedure Bar (Self : in out Foo); + -- + + if Present (Constructor_Name (First_Form_Type)) + and then Current_Scope = Scope (First_Form_Type) + and then Chars (Constructor_Name (First_Form_Type)) + = Chars (Designator) + and then Ekind (Designator) = E_Procedure + and then Nkind (Parent (N)) = N_Subprogram_Declaration + then + -- If the constructor list is empty than we don't have to + -- look for duplicates - we simply create the list and + -- add it. + + if No (Constructor_List (First_Form_Type)) then + Set_Constructor_List + (First_Form_Type, New_Elmt_List (Designator)); + + -- Otherwise, we need to check the constructor hasen't + -- already been added (e.g. a specification and body) and + -- that there isn't a constructor with the same number of + -- type of formals. + + -- NOTE: The Constructor_List is sorted by the number of + -- parameters. + + else + Construct := First_Elmt + (Constructor_List (First_Form_Type)); + + -- Skip over constructors with less than the number of + -- parameters than Designator ??? + + -- Loop through the constructors looking for ones which + -- "match." + + Outter : loop + + -- When we are at the end of the constructor list we + -- know there are no matches, so it is safe to add. + + if No (Construct) then + Append_Elmt + (Designator, + Constructor_List (First_Form_Type)); + exit Outter; + end if; + + -- Loop through the formals and check the formals + -- match on type ??? + + Next_Elmt (Construct); + end loop Outter; + end if; + end if; + end; + end if; + -- The subprogram scope is pushed and popped around the processing of -- the return type for consistency with call above to Process_Formals -- (which itself can call Analyze_Return_Type), and to ensure that any @@ -6094,7 +6207,7 @@ package body Sem_Ch6 is if NewD then Push_Scope (New_Id); - Preanalyze_Spec_Expression + Preanalyze_And_Resolve_Spec_Expression (Default_Value (New_Formal), Etype (New_Formal)); End_Scope; end if; @@ -6319,12 +6432,6 @@ package body Sem_Ch6 is elsif Has_Delayed_Freeze (T) and then not Is_Frozen (T) then Set_Has_Delayed_Freeze (Designator); - - elsif Is_Access_Type (T) - and then Has_Delayed_Freeze (Designated_Type (T)) - and then not Is_Frozen (Designated_Type (T)) - then - Set_Has_Delayed_Freeze (Designator); end if; end Possible_Freeze; @@ -6351,6 +6458,13 @@ package body Sem_Ch6 is Next_Formal (F); end loop; + -- RM 13.14 (15.1/6): the primitive subprograms of a tagged type are + -- frozen at the place where the type is frozen. + + if Is_Dispatching_Operation (Designator) then + Set_Has_Delayed_Freeze (Designator); + end if; + -- Mark functions that return by reference. Note that it cannot be done -- for delayed_freeze subprograms because the underlying returned type -- may not be known yet (for private types). @@ -6360,249 +6474,6 @@ package body Sem_Ch6 is end if; end Check_Delayed_Subprogram; - ------------------------------------ - -- Check_Discriminant_Conformance -- - ------------------------------------ - - procedure Check_Discriminant_Conformance - (N : Node_Id; - Prev : Entity_Id; - Prev_Loc : Node_Id) - is - Old_Discr : Entity_Id := First_Discriminant (Prev); - New_Discr : Node_Id := First (Discriminant_Specifications (N)); - New_Discr_Id : Entity_Id; - New_Discr_Type : Entity_Id; - - procedure Conformance_Error (Msg : String; N : Node_Id); - -- Post error message for conformance error on given node. Two messages - -- are output. The first points to the previous declaration with a - -- general "no conformance" message. The second is the detailed reason, - -- supplied as Msg. The parameter N provide information for a possible - -- & insertion in the message. - - ----------------------- - -- Conformance_Error -- - ----------------------- - - procedure Conformance_Error (Msg : String; N : Node_Id) is - begin - Error_Msg_Sloc := Sloc (Prev_Loc); - Error_Msg_N -- CODEFIX - ("not fully conformant with declaration#!", N); - Error_Msg_NE (Msg, N, N); - end Conformance_Error; - - -- Start of processing for Check_Discriminant_Conformance - - begin - while Present (Old_Discr) and then Present (New_Discr) loop - New_Discr_Id := Defining_Identifier (New_Discr); - - -- The subtype mark of the discriminant on the full type has not - -- been analyzed so we do it here. For an access discriminant a new - -- type is created. - - if Nkind (Discriminant_Type (New_Discr)) = N_Access_Definition then - New_Discr_Type := - Access_Definition (N, Discriminant_Type (New_Discr)); - - else - Find_Type (Discriminant_Type (New_Discr)); - New_Discr_Type := Etype (Discriminant_Type (New_Discr)); - - -- Ada 2005: if the discriminant definition carries a null - -- exclusion, create an itype to check properly for consistency - -- with partial declaration. - - if Is_Access_Type (New_Discr_Type) - and then Null_Exclusion_Present (New_Discr) - then - New_Discr_Type := - Create_Null_Excluding_Itype - (T => New_Discr_Type, - Related_Nod => New_Discr, - Scope_Id => Current_Scope); - end if; - end if; - - if not Conforming_Types - (Etype (Old_Discr), New_Discr_Type, Fully_Conformant) - then - Conformance_Error ("type of & does not match!", New_Discr_Id); - return; - else - -- Treat the new discriminant as an occurrence of the old one, - -- for navigation purposes, and fill in some semantic - -- information, for completeness. - - Generate_Reference (Old_Discr, New_Discr_Id, 'r'); - Set_Etype (New_Discr_Id, Etype (Old_Discr)); - Set_Scope (New_Discr_Id, Scope (Old_Discr)); - end if; - - -- Names must match - - if Chars (Old_Discr) /= Chars (Defining_Identifier (New_Discr)) then - Conformance_Error ("name & does not match!", New_Discr_Id); - return; - end if; - - -- Default expressions must match - - declare - NewD : constant Boolean := - Present (Expression (New_Discr)); - OldD : constant Boolean := - Present (Expression (Parent (Old_Discr))); - - function Has_Tagged_Limited_Partial_View - (Typ : Entity_Id) return Boolean; - -- Returns True iff Typ has a tagged limited partial view. - - function Is_Derived_From_Immutably_Limited_Type - (Typ : Entity_Id) return Boolean; - -- Returns True iff Typ is a derived type (tagged or not) - -- whose ancestor type is immutably limited. The unusual - -- ("unusual" is one word for it) thing about this function - -- is that it handles the case where the ancestor name's Entity - -- attribute has not been set yet. - - ------------------------------------- - -- Has_Tagged_Limited_Partial_View -- - ------------------------------------- - - function Has_Tagged_Limited_Partial_View - (Typ : Entity_Id) return Boolean - is - Priv : constant Entity_Id := Incomplete_Or_Partial_View (Typ); - begin - return Present (Priv) - and then not Is_Incomplete_Type (Priv) - and then Is_Tagged_Type (Priv) - and then Limited_Present (Parent (Priv)); - end Has_Tagged_Limited_Partial_View; - - -------------------------------------------- - -- Is_Derived_From_Immutably_Limited_Type -- - -------------------------------------------- - - function Is_Derived_From_Immutably_Limited_Type - (Typ : Entity_Id) return Boolean - is - Type_Def : constant Node_Id := Type_Definition (Parent (Typ)); - Parent_Name : Node_Id; - begin - if Nkind (Type_Def) /= N_Derived_Type_Definition then - return False; - end if; - Parent_Name := Subtype_Indication (Type_Def); - if Nkind (Parent_Name) = N_Subtype_Indication then - Parent_Name := Subtype_Mark (Parent_Name); - end if; - if Parent_Name not in N_Has_Entity_Id - or else No (Entity (Parent_Name)) - then - Find_Type (Parent_Name); - end if; - return Is_Immutably_Limited_Type (Entity (Parent_Name)); - end Is_Derived_From_Immutably_Limited_Type; - - begin - if NewD or OldD then - - -- The old default value has been analyzed and expanded, - -- because the current full declaration will have frozen - -- everything before. The new default values have not been - -- expanded, so expand now to check conformance. - - if NewD then - Preanalyze_Spec_Expression - (Expression (New_Discr), New_Discr_Type); - end if; - - if not (NewD and OldD) - or else not Fully_Conformant_Expressions - (Expression (Parent (Old_Discr)), - Expression (New_Discr)) - - then - Conformance_Error - ("default expression for & does not match!", - New_Discr_Id); - return; - end if; - - if NewD - and then Ada_Version >= Ada_2005 - and then Nkind (Discriminant_Type (New_Discr)) = - N_Access_Definition - and then not Is_Immutably_Limited_Type - (Defining_Identifier (N)) - - -- Check for a case that would be awkward to handle in - -- Is_Immutably_Limited_Type (because sem_aux can't - -- "with" sem_util). - - and then not Has_Tagged_Limited_Partial_View - (Defining_Identifier (N)) - - -- Check for another case that would be awkward to handle - -- in Is_Immutably_Limited_Type - - and then not Is_Derived_From_Immutably_Limited_Type - (Defining_Identifier (N)) - then - Error_Msg_N - ("(Ada 2005) default value for access discriminant " - & "requires immutably limited type", - Expression (New_Discr)); - return; - end if; - end if; - end; - - -- In Ada 83 case, grouping must match: (A,B : X) /= (A : X; B : X) - - if Ada_Version = Ada_83 then - declare - Old_Disc : constant Node_Id := Declaration_Node (Old_Discr); - - begin - -- Grouping (use of comma in param lists) must be the same - -- This is where we catch a misconformance like: - - -- A, B : Integer - -- A : Integer; B : Integer - - -- which are represented identically in the tree except - -- for the setting of the flags More_Ids and Prev_Ids. - - if More_Ids (Old_Disc) /= More_Ids (New_Discr) - or else Prev_Ids (Old_Disc) /= Prev_Ids (New_Discr) - then - Conformance_Error - ("grouping of & does not match!", New_Discr_Id); - return; - end if; - end; - end if; - - Next_Discriminant (Old_Discr); - Next (New_Discr); - end loop; - - if Present (Old_Discr) then - Conformance_Error ("too few discriminants!", Defining_Identifier (N)); - return; - - elsif Present (New_Discr) then - Conformance_Error - ("too many discriminants!", Defining_Identifier (New_Discr)); - return; - end if; - end Check_Discriminant_Conformance; - ----------------------------------------- -- Check_Formal_Subprogram_Conformance -- ----------------------------------------- @@ -7967,7 +7838,6 @@ package body Sem_Ch6 is end if; Overridden_Subp := Candidate; - return; end; end Check_Synchronized_Overriding; @@ -8701,14 +8571,13 @@ package body Sem_Ch6 is -- without coordinating with CodePeer, which makes use of these to -- provide better messages. + -- A and B denote extra formals for unchecked unions equality. See + -- exp_ch3.Build_Variant_Record_Equality. -- O denotes the Constrained bit. -- L denotes the accessibility level. -- BIP_xxx denotes an extra formal for a build-in-place function. See -- the full list in exp_ch6.BIP_Formal_Kind. - function Has_Extra_Formals (E : Entity_Id) return Boolean; - -- Determines if E has its extra formals - function Might_Need_BIP_Task_Actuals (E : Entity_Id) return Boolean; -- Determines if E is a function or an access to a function returning a -- limited tagged type object. On dispatching primitives this predicate @@ -8747,14 +8616,6 @@ package body Sem_Ch6 is EF : Entity_Id; begin - -- A little optimization. Never generate an extra formal for the - -- _init operand of an initialization procedure, since it could - -- never be used. - - if Chars (Formal) = Name_uInit then - return Empty; - end if; - EF := Make_Defining_Identifier (Sloc (Assoc_Entity), Chars => New_External_Name (Chars (Assoc_Entity), Suffix => Suffix)); @@ -8780,25 +8641,22 @@ package body Sem_Ch6 is return EF; end Add_Extra_Formal; - ----------------------- - -- Has_Extra_Formals -- - ----------------------- - - function Has_Extra_Formals (E : Entity_Id) return Boolean is - begin - return Present (Extra_Formals (E)) - or else - (Ekind (E) = E_Function - and then Present (Extra_Accessibility_Of_Result (E))); - end Has_Extra_Formals; - --------------------------------- -- Might_Need_BIP_Task_Actuals -- --------------------------------- function Might_Need_BIP_Task_Actuals (E : Entity_Id) return Boolean is Subp_Id : Entity_Id; - Func_Typ : Entity_Id; + Original : Entity_Id; + Root : Entity_Id; + + function Has_No_Task_Parts_Enabled (E : Entity_Id) return Boolean + is (Has_Enabled_Aspect (E, Aspect_No_Task_Parts)); + + function Collect_Ancestors_With_No_Task_Parts is new + Collect_Types_In_Hierarchy (Predicate => Has_No_Task_Parts_Enabled); + + -- Start of processing for Might_Need_BIP_Task_Actuals begin if Global_No_Tasking or else No_Run_Time_Mode then @@ -8826,21 +8684,29 @@ package body Sem_Ch6 is then Subp_Id := Protected_Body_Subprogram (E); - else + -- For access-to-subprogram types we look at the return type of the + -- subprogram type itself, as it cannot be overridden or inherited. + + elsif Ekind (E) = E_Subprogram_Type then Subp_Id := E; - end if; - -- We check the root type of the return type since the same - -- decision must be taken for all descendants overriding a - -- dispatching operation. + -- Otherwise, we need to return the same value we would return for + -- the original corresponding operation of the root of the aliased + -- chain. - Func_Typ := Root_Type (Underlying_Type (Etype (Subp_Id))); + else + Subp_Id := Original_Corresponding_Operation (Ultimate_Alias (E)); + end if; + + Original := Underlying_Type (Etype (Subp_Id)); + Root := Underlying_Type (Root_Type (Original)); return Ekind (Subp_Id) in E_Function | E_Subprogram_Type - and then not Has_Foreign_Convention (Func_Typ) - and then Is_Tagged_Type (Func_Typ) - and then Is_Limited_Type (Func_Typ) - and then not Has_Aspect (Func_Typ, Aspect_No_Task_Parts); + and then Is_Inherently_Limited_Type (Original) + and then not Has_Foreign_Convention (Root) + and then Is_Tagged_Type (Root) + and then Is_Empty_Elmt_List + (Collect_Ancestors_With_No_Task_Parts (Original)); end Might_Need_BIP_Task_Actuals; ------------------------------------- @@ -8929,10 +8795,12 @@ package body Sem_Ch6 is -- we have no direct way to climb to the corresponding parent -- subprogram but this internal entity has the extra formals -- (if any) required for the purpose of checking the extra - -- formals of Subp_Id. + -- formals of Subp_Id because its extra formals are shared + -- with its parent subprogram (see Sem_Ch3.Derive_Subprogram). else pragma Assert (not Comes_From_Source (Ovr_E)); + Freeze_Extra_Formals (Ovr_E); end if; -- Use as our reference entity the ultimate renaming of the @@ -8955,10 +8823,14 @@ package body Sem_Ch6 is -- Local variables - Formal_Type : Entity_Id; - May_Have_Alias : Boolean; + use Deferred_Extra_Formals_Support; + + Can_Be_Deferred : constant Boolean := + not Is_Unsupported_Extra_Formals_Entity (E); Alias_Formal : Entity_Id := Empty; Alias_Subp : Entity_Id := Empty; + Formal_Type : Entity_Id; + May_Have_Alias : Boolean; Parent_Formal : Entity_Id := Empty; Parent_Subp : Entity_Id := Empty; Ref_E : Entity_Id; @@ -8969,10 +8841,18 @@ package body Sem_Ch6 is pragma Assert (Is_Subprogram_Or_Entry (E) or else Ekind (E) in E_Subprogram_Type); + -- No action needed if extra formals were already handled. This + -- situation may arise because of a previous call to create the + -- extra formals, and also for subprogram types created as part + -- of dispatching calls (see Expand_Dispatching_Call). + + if Extra_Formals_Known (E) then + return; + -- We never generate extra formals if expansion is not active because we -- don't need them unless we are generating code. - if not Expander_Active then + elsif not Expander_Active then return; -- Enumeration literals have no extra formal; this case occurs when @@ -8981,25 +8861,38 @@ package body Sem_Ch6 is elsif Ekind (E) = E_Function and then Ekind (Ultimate_Alias (E)) = E_Enumeration_Literal then + Freeze_Extra_Formals (E); return; - -- Extra formals of Initialization procedures are added by the function - -- Exp_Ch3.Init_Formals + -- Extra formals of init procs are added by Exp_Ch3.Init_Formals and + -- Set_CPP_Constructors when they are built, but we must handle here + -- aliased init procs. elsif Is_Init_Proc (E) then + pragma Assert (Present (Alias (E))); + pragma Assert (Extra_Formals_Known (Ultimate_Alias (E))); + Freeze_Extra_Formals (E); return; -- No need to generate extra formals in thunks whose target has no extra -- formals, but we can have two of them chained (interface and stack). - elsif Is_Thunk (E) and then No (Extra_Formals (Thunk_Target (E))) then + elsif Is_Thunk (E) + and then Extra_Formals_Known (Thunk_Target (E)) + and then No (Extra_Formals (Thunk_Target (E))) + then + Freeze_Extra_Formals (E); return; - -- If Extra_Formals were already created, don't do it again. This - -- situation may arise for subprogram types created as part of - -- dispatching calls (see Expand_Dispatching_Call). + -- Handle alias of unchecked union equality with frozen extra formals - elsif Has_Extra_Formals (E) then + elsif Is_Overloadable (E) + and then Present (Alias (E)) + and then Extra_Formals_Known (Ultimate_Alias (E)) + and then Is_Unchecked_Union_Equality (Ultimate_Alias (E)) + then + Set_Extra_Formals (E, Extra_Formals (Ultimate_Alias (E))); + Freeze_Extra_Formals (E); return; -- Extra formals of renamings of generic actual subprograms and @@ -9017,6 +8910,8 @@ package body Sem_Ch6 is = Is_Generic_Instance (Ultimate_Alias (E))); Create_Extra_Formals (Ultimate_Alias (E)); + pragma Assert (not Expander_Active + or else Extra_Formals_Known (Ultimate_Alias (E))); -- Share the extra formals @@ -9028,17 +8923,72 @@ package body Sem_Ch6 is end if; pragma Assert (Extra_Formals_OK (E)); + Freeze_Extra_Formals (E); return; end if; - -- Locate the last formal; required by Add_Extra_Formal. + -- Check if the addition of the extra formals must be deferred Formal := First_Formal (E); while Present (Formal) loop - Last_Extra := Formal; + if No (Underlying_Type (Etype (Formal))) + and then Can_Be_Deferred + then + Register_Deferred_Extra_Formals_Entity (E); + return; + end if; + Next_Formal (Formal); end loop; + if Ekind (E) in E_Function + | E_Subprogram_Type + and then No (Underlying_Type (Etype (E))) + and then Can_Be_Deferred + then + Register_Deferred_Extra_Formals_Entity (E); + return; + end if; + + -- Here we start adding the extra formals + + -- We we know that either the underlying type of all the formals and + -- returned results of E are known, or this is an special case where + -- some underlying type is still not available. + + -- In the former case, we can already mark functions that return their + -- result by reference; in the latter case, we can mark them only if the + -- underlying return type is available (and it will be marked later). + + if not Is_Unsupported_Extra_Formals_Entity (E) + or else (Ekind (E) in E_Function | E_Subprogram_Type + and then Present (Underlying_Type (Etype (E)))) + then + Compute_Returns_By_Ref (E); + end if; + + -- Locate the last formal (required by Add_Extra_Formal) + + if Present (First_Formal (E)) + and then Is_Unchecked_Union (Etype (First_Formal (E))) + and then Present (Extra_Formals (E)) + and then Has_Suffix (Extra_Formals (E), 'A') + then + -- An unchecked union equality has two extra formals per discriminant + + First_Extra := Extra_Formals (E); + Last_Extra := First_Extra; + while Present (Last_Extra) loop + pragma Assert (Has_Suffix (Last_Extra, 'A')); + Last_Extra := Extra_Formal (Last_Extra); + + pragma Assert (Has_Suffix (Last_Extra, 'B')); + Last_Extra := Extra_Formal (Last_Extra); + end loop; + else + Last_Extra := Last_Formal (E); + end if; + -- We rely on three entities to ensure consistency of extra formals of -- entity E: -- @@ -9098,6 +9048,7 @@ package body Sem_Ch6 is or else (Present (Alias_Subp) and then Has_Foreign_Convention (Alias_Subp)) then + Freeze_Extra_Formals (E); return; end if; @@ -9176,14 +9127,44 @@ package body Sem_Ch6 is -- Here we establish our priority for deciding on the extra -- formals: 1) Parent primitive 2) Aliased primitive 3) Identity - if Present (Parent_Formal) then - Formal_Type := Etype (Parent_Formal); + -- Common case: the underlying type of all the formals is known + -- to be available. - elsif Present (Alias_Formal) then - Formal_Type := Etype (Alias_Formal); + if Can_Be_Deferred then + if Present (Parent_Formal) then + Formal_Type := Underlying_Type (Etype (Parent_Formal)); + elsif Present (Alias_Formal) then + Formal_Type := Underlying_Type (Etype (Alias_Formal)); + else + Formal_Type := Underlying_Type (Etype (Formal)); + end if; + + pragma Assert (Present (Formal_Type)); + + -- Special case: The underlying type of some formal is not available. + -- We use the underlying type when present. More work needed here??? else - Formal_Type := Etype (Formal); + if Present (Parent_Formal) then + Formal_Type := Etype (Parent_Formal); + + if Present (Underlying_Type (Formal_Type)) then + Formal_Type := Underlying_Type (Formal_Type); + end if; + + elsif Present (Alias_Formal) then + Formal_Type := Etype (Alias_Formal); + + if Present (Underlying_Type (Formal_Type)) then + Formal_Type := Underlying_Type (Formal_Type); + end if; + else + Formal_Type := Etype (Formal); + + if Present (Underlying_Type (Formal_Type)) then + Formal_Type := Underlying_Type (Formal_Type); + end if; + end if; end if; -- Create extra formal for supporting the attribute 'Constrained. @@ -9230,12 +9211,13 @@ package body Sem_Ch6 is and then (Is_Definite_Subtype (Formal_Type) or else Is_Mutably_Tagged_Type (Formal_Type)) and then (Ada_Version < Ada_2012 - or else No (Underlying_Type (Formal_Type)) + or else + (not Can_Be_Deferred + and then No (Underlying_Type (Formal_Type))) or else not (Is_Limited_Type (Formal_Type) and then - Is_Tagged_Type - (Underlying_Type (Formal_Type)))) + Is_Tagged_Type (Formal_Type))) then Set_Extra_Constrained (Formal, Add_Extra_Formal (Formal, Standard_Boolean, E, "O")); @@ -9474,6 +9456,8 @@ package body Sem_Ch6 is Set_Extra_Formals (Alias (E), Extra_Formals (E)); end if; + Freeze_Extra_Formals (E); + pragma Assert (No (Alias_Subp) or else Extra_Formals_Match_OK (E, Alias_Subp)); @@ -9788,6 +9772,19 @@ package body Sem_Ch6 is return False; end if; + -- Extra formals (A and B) of Unchecked_Unions (see Build_Variant_ + -- Record_Equality) + + elsif Has_Suffix (Formal_1, 'A') then + if not Has_Suffix (Formal_2, 'A') then + return False; + end if; + + elsif Has_Suffix (Formal_1, 'B') then + if not Has_Suffix (Formal_2, 'B') then + return False; + end if; + elsif BIP_Suffix_Kind (Formal_1) /= BIP_Suffix_Kind (Formal_2) then return False; end if; @@ -10140,6 +10137,16 @@ package body Sem_Ch6 is return Empty; end Find_Corresponding_Spec; + -------------------------- + -- Freeze_Extra_Formals -- + -------------------------- + + procedure Freeze_Extra_Formals (E : Entity_Id) is + begin + pragma Assert (not Extra_Formals_Known (E)); + Set_Extra_Formals_Known (E); + end Freeze_Extra_Formals; + ---------------------- -- Fully_Conformant -- ---------------------- @@ -10759,6 +10766,10 @@ package body Sem_Ch6 is Formal : Entity_Id := First_Formal_With_Extras (E); begin + -- It makes no sense to perform this check if the extra formals + -- have not been added. + pragma Assert (Extra_Formals_Known (E)); + while Present (Formal) loop if Is_Build_In_Place_Entity (Formal) then return True; @@ -12270,36 +12281,51 @@ package body Sem_Ch6 is and then Present (Find_Dispatching_Type (Alias (S))) and then Is_Interface (Find_Dispatching_Type (Alias (S))) then - -- For private types, when the full-view is processed we propagate to - -- the full view the non-overridden entities whose attribute "alias" - -- references an interface primitive. These entities were added by - -- Derive_Subprograms to ensure that interface primitives are - -- covered. - - -- Inside_Freeze_Actions is non zero when S corresponds with an - -- internal entity that links an interface primitive with its - -- covering primitive through attribute Interface_Alias (see - -- Add_Internal_Interface_Entities). - - if Inside_Freezing_Actions = 0 - and then Is_Package_Or_Generic_Package (Current_Scope) - and then In_Private_Part (Current_Scope) - and then Parent_Kind (E) = N_Private_Extension_Declaration - and then Nkind (Parent (S)) = N_Full_Type_Declaration - and then Full_View (Defining_Identifier (Parent (E))) - = Defining_Identifier (Parent (S)) - and then Alias (E) = Alias (S) - then - Check_Operation_From_Private_View (S, E); - Set_Is_Dispatching_Operation (S); + declare + Private_Operation_Exported_By_Visible_Part : constant Boolean := + Is_Package_Or_Generic_Package (Current_Scope) + and then In_Private_Part (Current_Scope) + and then Parent_Kind (E) = N_Private_Extension_Declaration + and then Nkind (Parent (S)) = N_Full_Type_Declaration + and then Full_View (Defining_Identifier (Parent (E))) + = Defining_Identifier (Parent (S)); - -- Common case + begin + -- For private types, when the full view is processed we propagate + -- to the full view the nonoverridden entities whose attribute + -- "alias" references an interface primitive. These entities were + -- added by Derive_Subprograms to ensure that interface primitives + -- are covered. + + -- Inside_Freeze_Actions is nonzero when S corresponds to an + -- internal entity that links an interface primitive with its + -- covering primitive through attribute Interface_Alias (see + -- Add_Internal_Interface_Entities). + + if Inside_Freezing_Actions = 0 + and then Private_Operation_Exported_By_Visible_Part + and then Alias (E) = Alias (S) + then + Check_Operation_From_Private_View (S, E); + Set_Is_Dispatching_Operation (S); - else - Enter_Overloaded_Entity (S); - Check_Dispatching_Operation (S, Empty); - Check_For_Primitive_Subprogram (Is_Primitive_Subp); - end if; + -- Common case + + else + Enter_Overloaded_Entity (S); + Check_Dispatching_Operation (S, Empty); + Check_For_Primitive_Subprogram (Is_Primitive_Subp); + end if; + + if Private_Operation_Exported_By_Visible_Part + and then Type_Conformant (E, S) + then + -- Record the actual inherited subprogram that's being + -- overridden. + + Set_Overridden_Inherited_Operation (S, E); + end if; + end; return; end if; @@ -12738,6 +12764,26 @@ package body Sem_Ch6 is and then not Is_Dispatch_Table_Wrapper (S))) then Set_Overridden_Operation (S, Alias (E)); + + -- Record the actual inherited subprogram that's being + -- overridden. In the case where a subprogram declared + -- in a private part overrides an inherited subprogram + -- that itself is also declared in the private part, + -- and that subprogram in turns overrides a subprogram + -- declared in a package visible part (inherited via + -- a private extension), we record the visible subprogram + -- as the overridden one, so that we can determine + -- visibility properly for prefixed calls to the + -- subprogram made from outside the package. (See + -- Try_Primitive_Operation in Sem_Ch4.) + + if Present (Overridden_Inherited_Operation (E)) then + Set_Overridden_Inherited_Operation + (S, Overridden_Inherited_Operation (E)); + else + Set_Overridden_Inherited_Operation (S, E); + end if; + Inherit_Subprogram_Contract (S, Alias (E)); Set_Is_Ada_2022_Only (S, Is_Ada_2022_Only (Alias (E))); @@ -12897,6 +12943,530 @@ package body Sem_Ch6 is end if; end New_Overloaded_Entity; + ------------------------------------ + -- Deferred_Extra_Formals_Support -- + ------------------------------------ + + package body Deferred_Extra_Formals_Support is + Calls_List : Elist_Id := No_Elist; + Calls_Scope_List : Elist_Id := No_Elist; + -- Calls to subprograms or entries with some unknown underlying type + -- in their parameters or result type, and the scope where each call + -- is performed. + + Entities_List : Elist_Id := No_Elist; + -- Subprograms, entries, and subprogram types with some unknown + -- underlying type in their formals or result type. + + Types_List : Elist_Id := No_Elist; + -- Types with no underlying type + + function Underlying_Types_Available (E : Entity_Id) return Boolean; + -- Determines if the underlying type of all the formals and result + -- type of the given subprogram, subprogram type, or entry are + -- available. + + ------------------------------- + -- Add_Deferred_Extra_Params -- + ------------------------------- + + procedure Add_Deferred_Extra_Params (Typ : Entity_Id) is + + procedure Check_Registered_Calls; + -- Check all the registered calls; for each registered call that + -- has the underlying type of all the parameters and result types + -- of the called entity available, call Create_Extra_Actuals, and + -- unregister the call. + + procedure Check_Registered_Entities; + -- Check all the registered entities (subprograms, entries and + -- subprogram types); for each registered entity E that has all + -- its underlying types available, call Create_Extra_Formals, + -- and unregister E. + + ---------------------------- + -- Check_Registered_Calls -- + ---------------------------- + + procedure Check_Registered_Calls is + + function Get_Relocated_Function_Call (N : Node_Id) return Node_Id; + -- Given a node N that references a function call that has been + -- relocated to remove possible side effects of the call (see + -- Remove_Side_Effects) or to wrap the call in a transient scope + -- (see Wrap_Transient_Expression), search and return the function + -- call. Notice that this function does not use the Original_Node + -- field of N; it searchs for the actual call associated with N + -- in the expanded code (since we need to add to such call its + -- missing extra actuals). + + --------------------------------- + -- Get_Relocated_Function_Call -- + --------------------------------- + + function Get_Relocated_Function_Call (N : Node_Id) return Node_Id + is + Current_Node : Node_Id; + Decl : Node_Id; + Id : Entity_Id; + + begin + Current_Node := N; + + while Nkind (Current_Node) /= N_Function_Call loop + case Nkind (Current_Node) is + when N_Identifier => + Id := Entity (Current_Node); + Decl := Parent (Id); + + if Nkind (Decl) = N_Object_Renaming_Declaration then + Current_Node := Name (Decl); + + else + pragma Assert (Nkind (Decl) = N_Object_Declaration); + + if Present (Expression (Decl)) then + Current_Node := Expression (Decl); + + elsif Present (BIP_Initialization_Call (Id)) then + Decl := BIP_Initialization_Call (Id); + pragma Assert (Present (Expression (Decl))); + Current_Node := Expression (Decl); + + elsif Present (Related_Expression (Id)) then + Current_Node := Related_Expression (Id); + + else + pragma Assert (False); + raise Program_Error; + end if; + end if; + + when N_Explicit_Dereference | N_Reference => + Current_Node := Prefix (Current_Node); + + when others => + pragma Assert (False); + raise Program_Error; + end case; + end loop; + + return Current_Node; + end Get_Relocated_Function_Call; + + -- Local variables + + Call_Node : Node_Id; + Call_Id : Entity_Id; + Elmt_Call : Elmt_Id; + Elmt_Scope : Elmt_Id; + Remove_Call : Boolean; + Scop_Id : Entity_Id; + + -- Start of processing for Check_Registered_Calls + + begin + -- Perform a single traversal of both lists simultaneously, + -- since they have the same number of elements with a 1-to-1 + -- relationship. + + Elmt_Scope := First_Elmt (Calls_Scope_List); + Elmt_Call := First_Elmt (Calls_List); + + while Present (Elmt_Scope) loop + Scop_Id := Node (Elmt_Scope); + Remove_Call := False; + + -- Check the enclosing scope of the call: if the underlying + -- type of some formal or return type of the enclosing scope + -- of this call is not available then we must skip processing + -- this call. + + if Underlying_Types_Available (Scop_Id) then + Call_Node := Node (Elmt_Call); + + if Nkind (Call_Node) in N_Entry_Call_Statement + | N_Function_Call + | N_Procedure_Call_Statement + then + Call_Id := Get_Called_Entity (Call_Node); + + -- Handle expanded function calls that could have side + -- effects. + + else + pragma Assert + (Nkind (Original_Node (Call_Node)) = N_Function_Call); + + Call_Node := Get_Relocated_Function_Call (Call_Node); + Call_Id := Get_Called_Entity (Call_Node); + end if; + + -- If the underlying types of all the formal and return + -- types of this called entity are available then create + -- its extra actuals and remove it from the list of + -- registered calls. + + if Underlying_Types_Available (Call_Id) then + + -- Given that the call is placed in the body of an + -- internally built subprogram, ensure that the extra + -- formals of the enclosing scope are available before + -- adding the extra actuals of this call. + + Create_Extra_Formals (Scop_Id); + Create_Extra_Formals (Call_Id); + + pragma Assert (Extra_Formals_Known (Scop_Id)); + pragma Assert (Extra_Formals_Known (Call_Id)); + + -- Mark functions that return a result by reference + + Compute_Returns_By_Ref (Scop_Id); + Compute_Returns_By_Ref (Call_Id); + + Push_Scope (Scop_Id); + Create_Extra_Actuals (Call_Node); + Pop_Scope; + + Remove_Call := True; + end if; + end if; + + -- In order to safely remove these elements from their + -- containing lists, remember these elements before moving + -- to the next list elements. + + if Remove_Call then + declare + Removed_Call : constant Elmt_Id := Elmt_Call; + Removed_Scope : constant Elmt_Id := Elmt_Scope; + + begin + Next_Elmt (Elmt_Scope); + Next_Elmt (Elmt_Call); + + Remove_Elmt (Calls_List, Removed_Call); + Remove_Elmt (Calls_Scope_List, Removed_Scope); + end; + else + Next_Elmt (Elmt_Scope); + Next_Elmt (Elmt_Call); + end if; + + end loop; + end Check_Registered_Calls; + + ------------------------------- + -- Check_Registered_Entities -- + ------------------------------- + + procedure Check_Registered_Entities is + Elmt : Elmt_Id; + Found_Elmt : Elmt_Id; + Id : Entity_Id; + + begin + Elmt := First_Elmt (Entities_List); + + while Present (Elmt) loop + Id := Node (Elmt); + + -- If the underlying type of some formal or return type of this + -- entity is not available then skip this element. + + if not Underlying_Types_Available (Id) then + Next_Elmt (Elmt); + + -- Otherwise, create its extra formals and remove it from the + -- list of entities that require adding the extra formals. + + else + -- In order to safely remove this element from the list, + -- temporarily remember this element, and move to the next + -- element. + + Found_Elmt := Elmt; + Next_Elmt (Elmt); + + -- Create the extra formals, and mark functions that return + -- by reference (not be done before if the underying return + -- type was previously unknown). + + Create_Extra_Formals (Id); + Compute_Returns_By_Ref (Id); + + Remove_Elmt (Entities_List, Found_Elmt); + + -- For deferred entries and entry families, the expansion of + -- their entry declaration was deferred, and must be done + -- now (after adding their extra formals). + + if Ekind (Id) in E_Entry | E_Entry_Family then + Expand_N_Entry_Declaration (Parent (Id), + Was_Deferred => True); + end if; + end if; + end loop; + end Check_Registered_Entities; + + -- Start of processing for Add_Deferred_Extra_Params + + begin + pragma Assert (Present (Underlying_Type (Typ))); + + if Present (Entities_List) then + Check_Registered_Entities; + end if; + + if Present (Calls_List) then + Check_Registered_Calls; + end if; + + Remove (Types_List, Typ); + end Add_Deferred_Extra_Params; + + -------------------------------- + -- Has_Deferred_Extra_Formals -- + -------------------------------- + + function Has_Deferred_Extra_Formals (Typ : Entity_Id) return Boolean is + begin + return Contains (Types_List, Typ); + end Has_Deferred_Extra_Formals; + + -------------------------------------- + -- Is_Deferred_Extra_Formals_Entity -- + -------------------------------------- + + function Is_Deferred_Extra_Formals_Entity + (Id : Entity_Id) return Boolean is + begin + return Contains (Entities_List, Id); + end Is_Deferred_Extra_Formals_Entity; + + --------------------------------------- + -- Is_Unsupported_Extra_Actuals_Call -- + --------------------------------------- + + -- Similarly to Is_Unsupported_Extra_Formals_Entity, we cannot + -- determine if the extra formals are needed when the underlying + -- type of some formal or result type is not available, and we are + -- compiling the body of a subprogram or package. However, for calls + -- we must also handle internal calls generated by the compiler as + -- part of compiling a package spec. For example, internal calls + -- performed in thunks of secondary dispatch table entries. + -- + -- Example + -- ------- + -- package P is + -- type T is tagged null record; + -- end; + -- + -- limited with P; + -- package Q is + -- type Iface is interface; + -- procedure Prim (Self : Iface; Current : P.T) is abstract; + -- end; + -- + -- limited with P; + -- with Q; + -- package R is + -- type Root is tagged null record; + -- type DT is new Root and Q.Iface with null record; + -- + -- procedure Prim (Self : DT; Current : P.T); + -- end; + -- + -- The initialization of the secondary dispatch table of tagged type + -- DT has an internally generated thunk that displaces the pointer to + -- the object and calls the primitive Prim (and the underlying type + -- of type T is not available). + + function Is_Unsupported_Extra_Actuals_Call + (Call_Node : Node_Id; Id : Entity_Id) return Boolean + is + Comp_Unit : constant Entity_Id := + Cunit_Entity (Get_Source_Unit (Call_Node)); + begin + return not Underlying_Types_Available (Id) + and then Is_Compilation_Unit (Comp_Unit) + and then Ekind (Comp_Unit) in E_Package + | E_Package_Body + | E_Subprogram_Body; + end Is_Unsupported_Extra_Actuals_Call; + + ----------------------------------------- + -- Is_Unsupported_Extra_Formals_Entity -- + ----------------------------------------- + + -- We cannot determine if the extra formals are needed when the + -- underlying type of some formal or result type is not available, + -- and we are compiling the body of a subprogram or package. The + -- scenery for this case is a package spec that has a limited_with_ + -- clause on unit Q, and its body has no regular with-clause on Q + -- (AI05-0151-1/08). + + function Is_Unsupported_Extra_Formals_Entity + (Id : Entity_Id) return Boolean + is + Comp_Unit : constant Entity_Id := + Cunit_Entity (Get_Source_Unit (Id)); + begin + return not Underlying_Types_Available (Id) + and then Is_Compilation_Unit (Comp_Unit) + and then Ekind (Comp_Unit) in E_Package_Body + | E_Subprogram_Body; + end Is_Unsupported_Extra_Formals_Entity; + + -------------------------------------------- + -- Register_Deferred_Extra_Formals_Entity -- + -------------------------------------------- + + procedure Register_Deferred_Extra_Formals_Entity (Id : Entity_Id) is + + procedure Register_Type (Typ : Entity_Id); + -- Register the given type in Types_List; for types visible though + -- limited_with_clauses, register their non-limited view. + + ------------------- + -- Register_Type -- + ------------------- + + procedure Register_Type (Typ : Entity_Id) is + begin + -- Handle entities visible through limited_with_clauses + + if Has_Non_Limited_View (Typ) then + Append_Unique_Elmt (Non_Limited_View (Typ), Types_List); + else + Append_Unique_Elmt (Typ, Types_List); + end if; + end Register_Type; + + -- Local variables + + Formal : Entity_Id; + + -- Start of processing for Register_Deferred_Extra_Formals_Entity + + begin + pragma Assert (Is_Subprogram_Or_Entry (Id) + or else Ekind (Id) in E_Subprogram_Type); + + if not Is_Deferred_Extra_Formals_Entity (Id) then + if No (Types_List) then + Types_List := New_Elmt_List; + end if; + + if No (Entities_List) then + Entities_List := New_Elmt_List; + end if; + + -- Register all the types of the subprogram profile that are not + -- fully known. + + Formal := First_Formal (Id); + while Present (Formal) loop + + if No (Underlying_Type (Etype (Formal))) then + Register_Type (Etype (Formal)); + end if; + + Next_Formal (Formal); + end loop; + + if Ekind (Id) in E_Function | E_Subprogram_Type + and then No (Underlying_Type (Etype (Id))) + then + Register_Type (Etype (Id)); + end if; + + -- Register this subprogram + + Append_Elmt (Id, Entities_List); + end if; + end Register_Deferred_Extra_Formals_Entity; + + ------------------------------------------ + -- Register_Deferred_Extra_Formals_Call -- + ------------------------------------------ + + procedure Register_Deferred_Extra_Formals_Call + (Call_Node : Node_Id; + Scope_Id : Entity_Id) is + begin + pragma Assert (Nkind (Call_Node) in N_Subprogram_Call + | N_Entry_Call_Statement); + if No (Calls_List) then + Calls_List := New_Elmt_List; + Calls_Scope_List := New_Elmt_List; + end if; + + -- Avoid registering any call twice; this may occur in dispatching + -- calls with deferred extra actuals because Expand_Call_Helper + -- registers the call and invokes Expand_Dispatching_Call (which + -- tries again to register the expanded call). + + if not Contains (Calls_List, Call_Node) then + Append_Elmt (Call_Node, Calls_List); + Append_Elmt (Scope_Id, Calls_Scope_List); + end if; + end Register_Deferred_Extra_Formals_Call; + + -------------------------------- + -- Underlying_Types_Available -- + -------------------------------- + + function Underlying_Types_Available (E : Entity_Id) return Boolean is + Formal : Entity_Id; + Formal_Typ : Entity_Id; + Func_Typ : Entity_Id; + + begin + -- If the extra formals are available, then the nonlimited view + -- of all the types referenced in the profile are available. + + if Extra_Formals_Known (E) then + return True; + end if; + + -- Check the return type + + if Ekind (E) in E_Function | E_Subprogram_Type then + Func_Typ := Etype (E); + + if Has_Non_Limited_View (Func_Typ) then + Func_Typ := Non_Limited_View (Func_Typ); + end if; + + if No (Underlying_Type (Func_Typ)) then + return False; + end if; + end if; + + -- Check the type of the formals + + Formal := First_Formal (E); + while Present (Formal) loop + Formal_Typ := Etype (Formal); + + if Has_Non_Limited_View (Formal_Typ) then + Formal_Typ := Non_Limited_View (Formal_Typ); + end if; + + if No (Underlying_Type (Formal_Typ)) then + return False; + end if; + + Next_Formal (Formal); + end loop; + + return True; + end Underlying_Types_Available; + + end Deferred_Extra_Formals_Support; + --------------------- -- Process_Formals -- --------------------- @@ -12963,13 +13533,10 @@ package body Sem_Ch6 is -- Start of processing for Process_Formals begin - -- In order to prevent premature use of the formals in the same formal - -- part, the Ekind is left undefined until all default expressions are - -- analyzed. The Ekind is established in a separate loop at the end. - Param_Spec := First (T); while Present (Param_Spec) loop Formal := Defining_Identifier (Param_Spec); + Set_Formal_Mode (Formal, Param_Spec, Current_Scope); Set_Never_Set_In_Source (Formal, True); Enter_Name (Formal); @@ -13207,7 +13774,7 @@ package body Sem_Ch6 is -- Do the special preanalysis of the expression (see section on -- "Handling of Default Expressions" in the spec of package Sem). - Preanalyze_Spec_Expression (Default, Formal_Type); + Preanalyze_And_Resolve_Spec_Expression (Default, Formal_Type); -- An access to constant cannot be the default for -- an access parameter that is an access to variable. @@ -13287,12 +13854,48 @@ package body Sem_Ch6 is Analyze_Return_Type (Related_Nod); end if; - -- Now set the kind (mode) of each formal - Param_Spec := First (T); while Present (Param_Spec) loop Formal := Defining_Identifier (Param_Spec); - Set_Formal_Mode (Formal); + Set_Is_Not_Self_Hidden (Formal); + + -- Set Is_Known_Non_Null for access parameters since the language + -- guarantees that access parameters are always non-null. We also set + -- Can_Never_Be_Null, since there is no way to change the value. + + if Nkind (Parameter_Type (Param_Spec)) = N_Access_Definition then + + -- Ada 2005 (AI-231): In Ada 95, access parameters are always non- + -- null; In Ada 2005, only if then null_exclusion is explicit. + + if Ada_Version < Ada_2005 + or else Can_Never_Be_Null (Etype (Formal)) + then + Set_Is_Known_Non_Null (Formal); + Set_Can_Never_Be_Null (Formal); + end if; + + -- Ada 2005 (AI-231): Null-exclusion access subtype + + elsif Is_Access_Type (Etype (Formal)) + and then Can_Never_Be_Null (Etype (Formal)) + then + Set_Is_Known_Non_Null (Formal); + + -- We can also set Can_Never_Be_Null (thus preventing some junk + -- access checks) for the case of an IN parameter, which cannot + -- be changed, or for an IN OUT parameter, which can be changed + -- but not to a null value. But for an OUT parameter, the initial + -- value passed in can be null, so we can't set this flag in that + -- case. + + if Ekind (Formal) /= E_Out_Parameter then + Set_Can_Never_Be_Null (Formal); + end if; + end if; + + Set_Mechanism (Formal, Default_Mechanism); + Set_Formal_Validity (Formal); if Ekind (Formal) = E_In_Parameter then Default := Expression (Param_Spec); @@ -13563,23 +14166,23 @@ package body Sem_Ch6 is -- Set_Formal_Mode -- --------------------- - procedure Set_Formal_Mode (Formal_Id : Entity_Id) is - Spec : constant Node_Id := Parent (Formal_Id); - Id : constant Entity_Id := Scope (Formal_Id); - + procedure Set_Formal_Mode + (Formal_Id : Entity_Id; + Spec : N_Parameter_Specification_Id; + Subp_Id : Entity_Id) is begin -- Note: we set Is_Known_Valid for IN parameters and IN OUT parameters -- since we ensure that corresponding actuals are always valid at the -- point of the call. if Out_Present (Spec) then - if Is_Entry (Id) - or else Is_Subprogram_Or_Generic_Subprogram (Id) + if Is_Entry (Subp_Id) + or else Is_Subprogram_Or_Generic_Subprogram (Subp_Id) then - Set_Has_Out_Or_In_Out_Parameter (Id, True); + Set_Has_Out_Or_In_Out_Parameter (Subp_Id, True); end if; - if Ekind (Id) in E_Function | E_Generic_Function then + if Ekind (Subp_Id) in E_Function | E_Generic_Function then -- [IN] OUT parameters allowed for functions in Ada 2012 @@ -13616,45 +14219,6 @@ package body Sem_Ch6 is else Mutate_Ekind (Formal_Id, E_In_Parameter); end if; - - Set_Is_Not_Self_Hidden (Formal_Id); - - -- Set Is_Known_Non_Null for access parameters since the language - -- guarantees that access parameters are always non-null. We also set - -- Can_Never_Be_Null, since there is no way to change the value. - - if Nkind (Parameter_Type (Spec)) = N_Access_Definition then - - -- Ada 2005 (AI-231): In Ada 95, access parameters are always non- - -- null; In Ada 2005, only if then null_exclusion is explicit. - - if Ada_Version < Ada_2005 - or else Can_Never_Be_Null (Etype (Formal_Id)) - then - Set_Is_Known_Non_Null (Formal_Id); - Set_Can_Never_Be_Null (Formal_Id); - end if; - - -- Ada 2005 (AI-231): Null-exclusion access subtype - - elsif Is_Access_Type (Etype (Formal_Id)) - and then Can_Never_Be_Null (Etype (Formal_Id)) - then - Set_Is_Known_Non_Null (Formal_Id); - - -- We can also set Can_Never_Be_Null (thus preventing some junk - -- access checks) for the case of an IN parameter, which cannot - -- be changed, or for an IN OUT parameter, which can be changed but - -- not to a null value. But for an OUT parameter, the initial value - -- passed in can be null, so we can't set this flag in that case. - - if Ekind (Formal_Id) /= E_Out_Parameter then - Set_Can_Never_Be_Null (Formal_Id); - end if; - end if; - - Set_Mechanism (Formal_Id, Default_Mechanism); - Set_Formal_Validity (Formal_Id); end Set_Formal_Mode; ------------------------- diff --git a/gcc/ada/sem_ch6.ads b/gcc/ada/sem_ch6.ads index bd4b730dc607..4ef5b654bb01 100644 --- a/gcc/ada/sem_ch6.ads +++ b/gcc/ada/sem_ch6.ads @@ -64,18 +64,8 @@ package Sem_Ch6 is -- respective counterparts. procedure Check_Delayed_Subprogram (Designator : Entity_Id); - -- Designator can be a E_Subprogram_Type, E_Procedure or E_Function. If a - -- type in its profile depends on a private type without a full - -- declaration, indicate that the subprogram or type is delayed. - - procedure Check_Discriminant_Conformance - (N : Node_Id; - Prev : Entity_Id; - Prev_Loc : Node_Id); - -- Check that the discriminants of a full type N fully conform to the - -- discriminants of the corresponding partial view Prev. Prev_Loc indicates - -- the source location of the partial view, which may be different than - -- Prev in the case of private types. + -- Designator can be a E_Subprogram_Type, E_Procedure or E_Function. Set + -- Has_Delayed_Freeze on Designator if its freezing needs to be delayed. procedure Check_Formal_Subprogram_Conformance (New_Id : Entity_Id; @@ -200,6 +190,14 @@ package Sem_Ch6 is -- Use the subprogram specification in the body to retrieve the previous -- subprogram declaration, if any. + procedure Freeze_Extra_Formals (E : Entity_Id); + -- Given a subprogram, subprogram type, or entry, flag E to indicate that + -- its extra formals (if any) are known (by setting Extra_Formals_Known). + -- This subprogram serves three purposes: (1) Document the places where + -- the extra formals are known, (2) Ensure that extra formals are added + -- only once, and (3) Provide a convenient place for setting a debugger + -- breakpoint to locate when extra formals are known. + function Fully_Conformant (New_Id, Old_Id : Entity_Id) return Boolean; -- Determine whether two callable entities (subprograms, entries, -- literals) are fully conformant (RM 6.3.1(17)) @@ -309,4 +307,156 @@ package Sem_Ch6 is procedure Valid_Operator_Definition (Designator : Entity_Id); -- Verify that an operator definition has the proper number of formals + ------------------------------------ + -- Deferred_Extra_Formals_Support -- + ------------------------------------ + + -- This package provides support for deferring the addition of extra + -- formals to subprograms, entries, and subprogram types; it also provides + -- support for deferring the addition of extra actuals to direct calls to + -- subprograms and entries, and indirect calls through subprogram types. + -- The addition of the extra formals and actuals is deferred until the + -- underlying type of all the parameters and result types of registered + -- subprograms, entries, and subprogram types is known. + + -- Functional Description + -- ---------------------- + -- + -- When Create_Extra_Formals identifies that the underlying type of + -- some parameter or result type of an entity E is not available, E is + -- registered by this package, and the addition of its extra formals is + -- deferred. As part of this registration, the types of all the params + -- and result types of E with no underlying type are also registered. + -- + -- When Expand_Call_Helper identifies that the underlying type of some + -- parameter or result type of a called entity is not available, the call + -- is registered by Register_Deferred_Extra_Formals_Call, and the addition + -- of its extra actuals is deferred. + -- + -- When the full type declaration of some registered type T is analyzed, + -- the subprogram Add_Deferred_Extra_Params is invoked; this subprogram + -- does the following actions: + -- 1) Check all the registered entities (subprograms, entries, and + -- subprogram types); for each registered entity that has all its + -- underlying types available, call Create_Extra_Formals, and + -- unregister the entity. + -- 2) Check all the registered calls; for each registered call that + -- has available the underlying type of all the parameters and result + -- types of the called entity, call Create_Extra_Actuals, and + -- unregister the call. + -- 3) Unregister T. + -- + -- Example 1 + -- --------- + -- A package spec has a private type declaration T, and declarations of + -- expression functions and/or primitives with class-wide conditions + -- invoking primitives of type T before the full view of T is defined. + -- + -- As part of processing the early freezing of the called subprograms + -- (and as part of processing the calls) the functions are registered as + -- subprograms with deferred extra formals, and the calls are registered + -- as calls with deferred extra actuals. + -- + -- When the full type declaration of T is analyzed, extra formals are + -- added to all the registered subprograms, and extra actuals are added + -- to all the registered calls with deferred extra actuals. + -- + -- Example 2 + -- --------- + -- The specification of package P has a limited_with_clause on package Q, + -- and the type of the formals of subprograms defined in P are types + -- defined in Q. + -- + -- When compiling the spec of P, similarly to the previous example, + -- subprograms with incomplete formals are registered as subprograms + -- with deferred extra formals; if the spec of P has calls to these + -- subprograms, then these calls are registered as calls with deferred + -- extra actuals. That is, when the analysis of package P completes, + -- deferred extra formals and actuals have not been added. + -- + -- When another compilation unit is analyzed (including the body of + -- package P), and a regular with-clause on Q is processed, when the + -- full type declaration of deferred entities is analyzed, deferred + -- extra formals and deferred extra actuals are added. + -- + -- This machinery relies on the GNAT Compilation Model; that is, when + -- we analyze the spec of P (for which we generally don't generate code), + -- it is safe to complete the compilation and still have entities with + -- deferred extra formals, and calls with deferred extra actuals. + -- + -- The body package P generally has a regular with-clause on package Q. + -- Hence, when we compile the body of package P, the implicit dependence + -- on its package spec causes the analysis of the spec of P (thus + -- registering deferred entities), followed by the analysis of context + -- clauses in the body of P. When the regular with-clause on package Q + -- is analyzed, we add the extra formals and extra actuals to deferred + -- entities. Thus, the generated code will have all the needed formals. + -- + -- The (still) unsupported case is when the body of package P does not + -- have a regular with-clause on package Q (AI05-0151-1/08). This case + -- is left documented in the front-end sources by means of calls to + -- the following subprograms: Is_Unsupported_Extra_Formals_Entity, and + -- Is_Unsupported_Extra_Actuals_Call. + + package Deferred_Extra_Formals_Support is + + procedure Add_Deferred_Extra_Params (Typ : Entity_Id); + -- Check all the registered subprograms, entries, and subprogram types + -- with deferred addition of their extra formals; if the underlying + -- types of all their formals is available then add their extra formals. + -- Check also all the registered calls with deferred addition of their + -- extra actuals; add their extra actuals if the underlying types of all + -- their parameters and result types are available. Finally unregister + -- Typ from the list of types used for the deferral of extra formals/ + -- actuals. + + procedure Register_Deferred_Extra_Formals_Entity (Id : Entity_Id); + -- Register the given subprogram, entry, or subprogram type to defer the + -- addition of its extra formals. + + procedure Register_Deferred_Extra_Formals_Call + (Call_Node : Node_Id; + Scope_Id : Entity_Id); + -- Register the given call, performed from the given scope, to defer the + -- addition of its extra actuals. + + function Has_Deferred_Extra_Formals (Typ : Entity_Id) return Boolean; + -- Return True if there some registered subprogram, subprogram type, or + -- entry with deferred extra formals that has some formal type or + -- result type of type Typ (i.e. which depends on the given type to + -- add its extra formals). + + function Is_Deferred_Extra_Formals_Entity + (Id : Entity_Id) return Boolean; + -- Return True if Id is a subprogram, subprogram type, or entry that has + -- been registered to defer the addition of its extra formals. + + function Is_Unsupported_Extra_Formals_Entity + (Id : Entity_Id) return Boolean; + -- Id is a subprogram, subprogram type, or entry. Return True if Id is + -- unsupported for deferring the addition of its extra formals; that is, + -- it is defined in a compilation unit that is a package body or a + -- subprogram body, and the underlying type of some of its parameters + -- or result type is not available. + -- + -- The context for this case is an unsupported case of AI05-0151-1/08 + -- that allows incomplete tagged types as parameter and result types. + -- More concretely, a type T is visible in a package spec through a + -- limited_with_clause, and the body of the package has no regular + -- with_clause. In such a case, the machinery for deferring the + -- addition of extra formals does not work because the underlying + -- type of the type is not seen during the compilation of the + -- package body. + -- + -- The purpose of this function is to facilitate locating in the sources + -- the places where the front end performs the current (incomplete) + -- management of such case (to facilitate further work) ??? + + function Is_Unsupported_Extra_Actuals_Call + (Call_Node : Node_Id; Id : Entity_Id) return Boolean; + -- Same as previous function but applicable to a call to the given + -- entity Id. + + end Deferred_Extra_Formals_Support; + end Sem_Ch6; diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb index 0a9ef419db78..e6ef65860d63 100644 --- a/gcc/ada/sem_ch8.adb +++ b/gcc/ada/sem_ch8.adb @@ -77,6 +77,7 @@ with Style; with Table; with Tbuild; use Tbuild; with Uintp; use Uintp; +with Uname; use Uname; with Warnsw; use Warnsw; package body Sem_Ch8 is @@ -4269,6 +4270,40 @@ package body Sem_Ch8 is Local_Restrict.Check_Actual_Subprogram_For_Instance (Actual_Subp_Name => Nam, Formal_Subp => Formal_Spec); end if; + + -- If pragma Short_Circuit_And_Or is specified, then we give an error + -- for renaming an operator that is made short circuit. + -- For example, this is illegal: + -- + -- function My_And (X, Y: Boolean) return Boolean renames "and"; + -- + -- if "and" denotes the usual predefined Boolean operator. Otherwise, + -- the semantics are confusing (sometimes short circuit, and sometimes + -- not, for calls to My_And). If we ever relax this rule, we will need + -- to clean up that run-time semantics. + + if Short_Circuit_And_Or + and then Chars (Old_S) in Name_Op_And | Name_Op_Or + and then In_Extended_Main_Source_Unit (N) + and then Etype (Old_S) = Standard_Boolean + and then Is_Intrinsic_Subprogram (Old_S) + then + if Comes_From_Source (N) then + Error_Msg_N + ("pragma Short_Circuit_And_Or disallows renaming of " & + "operator", N); + + -- Same error in case of an instantiation with My_And => "and" + + elsif Present (Corresponding_Formal_Spec (N)) then + Error_Msg_N + ("pragma Short_Circuit_And_Or disallows passing of " & + "operator as a generic actual", N); + + else + raise Program_Error; + end if; + end if; end Analyze_Subprogram_Renaming; ------------------------- @@ -4300,6 +4335,44 @@ package body Sem_Ch8 is begin pragma Assert (Nkind (Clause) = N_Use_Package_Clause); + + -- Perform "use implies with" expansion (when extensions are enabled) + -- by inserting an extra with clause since redundant clauses don't + -- really matter. + + if All_Extensions_Allowed and then Is_In_Context_Clause (Clause) then + declare + Unum : Unit_Number_Type; + With_Clause : constant Node_Id := + Make_With_Clause (Sloc (Clause), + Name => New_Copy_Tree (Pack)); + begin + -- Attempt to load the unit mentioned in the use clause + + Unum := Load_Unit + (Load_Name => Get_Unit_Name (With_Clause), + Required => False, + Subunit => False, + Error_Node => Clause, + With_Node => With_Clause); + + -- Either we can't file the unit or the use clause is a + -- reference to a nested package - in that case just handle + -- the use clause normally. + + if Unum /= No_Unit then + + Set_Library_Unit (With_Clause, Cunit (Unum)); + Set_Is_Implicit_With (With_Clause); + + Analyze (With_Clause); + Expand_With_Clause + (With_Clause, Name (With_Clause), + Enclosing_Comp_Unit_Node (Clause)); + end if; + end; + end if; + Analyze (Pack); -- Verify that the package standard is not directly named in a @@ -5371,7 +5444,15 @@ package body Sem_Ch8 is elsif In_Open_Scopes (Scope (Base_Type (T))) then null; - elsif not Redundant_Use (Id) then + -- Turn off the use_type_clause on the type unless the clause is + -- redundant, or there's a previous use_type_clause. (The case where + -- a use_type_clause without "all" is followed by one with "all" in + -- a more nested scope is not considered redundant, necessitating + -- the test for a previous clause. One might expect the latter test + -- to suffice, but it turns out there are cases where Redundant_Use + -- is set, but Prev_Use_Clause is not set. ???) + + elsif not Redundant_Use (Id) and then No (Prev_Use_Clause (N)) then Set_In_Use (T, False); Set_In_Use (Base_Type (T), False); Set_Current_Use_Clause (T, Empty); @@ -8365,7 +8446,8 @@ package body Sem_Ch8 is if Is_Overloaded (P) then - -- The prefix must resolve to a unique enclosing construct + -- The prefix must resolve to a unique enclosing construct, per + -- the last sentence of RM 4.1.3 (13). declare Found : Boolean := False; @@ -8379,6 +8461,7 @@ package body Sem_Ch8 is if Found then Error_Msg_N ( "prefix must be unique enclosing scope", N); + Change_Selected_Component_To_Expanded_Name (N); Set_Entity (N, Any_Id); Set_Etype (N, Any_Type); return; @@ -9504,6 +9587,11 @@ package body Sem_Ch8 is and then Present (Scope (Entity (E))) then Mark_Use_Package (Scope (Entity (E))); + + -- Additionally mark the types of the formals and the return + -- types as used when dealing with an overloaded operator. + + Mark_Parameters (Entity (E)); end if; Curr := Current_Use_Clause (Base); @@ -9878,28 +9966,8 @@ package body Sem_Ch8 is procedure Premature_Usage (N : Node_Id) is Kind : constant Node_Kind := Nkind (Parent (Entity (N))); - E : Entity_Id := Entity (N); begin - -- Within an instance, the analysis of the actual for a formal object - -- does not see the name of the object itself. This is significant only - -- if the object is an aggregate, where its analysis does not do any - -- name resolution on component associations. (see 4717-008). In such a - -- case, look for the visible homonym on the chain. - - if In_Instance and then Present (Homonym (E)) then - E := Homonym (E); - while Present (E) and then not In_Open_Scopes (Scope (E)) loop - E := Homonym (E); - end loop; - - if Present (E) then - Set_Entity (N, E); - Set_Etype (N, Etype (E)); - return; - end if; - end if; - case Kind is when N_Component_Declaration => Error_Msg_N diff --git a/gcc/ada/sem_ch8.ads b/gcc/ada/sem_ch8.ads index 70fbcf2b54f1..f915f2cb0f20 100644 --- a/gcc/ada/sem_ch8.ads +++ b/gcc/ada/sem_ch8.ads @@ -100,11 +100,6 @@ package Sem_Ch8 is -- entries in the current scope, and that will give all homonyms that are -- declared before the point of call in the current scope. This is useful -- for example in the processing for pragma Inline. - -- - -- Flag Errors_OK should be set when error diagnostics are desired. Flag - -- Marker_OK should be set when a N_Variable_Reference_Marker needs to be - -- generated for a SPARK object in order to detect elaboration issues. Flag - -- Reference_OK should be set when N must generate a cross reference. procedure Find_Selected_Component (N : Node_Id); -- Resolve various cases of selected components, recognize expanded names diff --git a/gcc/ada/sem_ch9.adb b/gcc/ada/sem_ch9.adb index 71394aa563ff..bf387d35a657 100644 --- a/gcc/ada/sem_ch9.adb +++ b/gcc/ada/sem_ch9.adb @@ -28,11 +28,10 @@ with Aspects; use Aspects; with Atree; use Atree; with Checks; use Checks; with Contracts; use Contracts; -with Debug; use Debug; -with Diagnostics.Constructors; use Diagnostics.Constructors; with Einfo; use Einfo; with Einfo.Entities; use Einfo.Entities; with Einfo.Utils; use Einfo.Utils; +with Errid; use Errid; with Errout; use Errout; with Exp_Ch9; use Exp_Ch9; with Elists; use Elists; @@ -753,8 +752,6 @@ package body Sem_Ch9 is T_Name : Node_Id; begin - Tasking_Used := True; - T_Name := First (Names (N)); while Present (T_Name) loop Analyze (T_Name); @@ -790,8 +787,6 @@ package body Sem_Ch9 is procedure Analyze_Accept_Alternative (N : Node_Id) is begin - Tasking_Used := True; - if Present (Pragmas_Before (N)) then Analyze_List (Pragmas_Before (N)); end if; @@ -823,8 +818,6 @@ package body Sem_Ch9 is Task_Nam : Entity_Id := Empty; -- initialize to prevent warning begin - Tasking_Used := True; - -- Entry name is initialized to Any_Id. It should get reset to the -- matching entry entity. An error is signalled if it is not reset. @@ -1064,7 +1057,6 @@ package body Sem_Ch9 is Trigger : Node_Id; begin - Tasking_Used := True; Check_Restriction (Max_Asynchronous_Select_Nesting, N); Check_Restriction (No_Select_Statements, N); @@ -1109,7 +1101,6 @@ package body Sem_Ch9 is Is_Disp_Select : Boolean := False; begin - Tasking_Used := True; Check_Restriction (No_Select_Statements, N); -- Ada 2005 (AI-345): The trigger may be a dispatching call @@ -1154,7 +1145,6 @@ package body Sem_Ch9 is Typ : Entity_Id; begin - Tasking_Used := True; Check_Restriction (No_Delay, N); if Present (Pragmas_Before (N)) then @@ -1206,7 +1196,6 @@ package body Sem_Ch9 is E : constant Node_Id := Expression (N); begin - Tasking_Used := True; Check_Restriction (No_Relative_Delay, N); Check_Restriction (No_Delay, N); Check_Potentially_Blocking_Operation (N); @@ -1231,7 +1220,6 @@ package body Sem_Ch9 is Typ : Entity_Id; begin - Tasking_Used := True; Check_Restriction (No_Delay, N); Check_Potentially_Blocking_Operation (N); Analyze_And_Resolve (E); @@ -1266,8 +1254,6 @@ package body Sem_Ch9 is Freeze_Previous_Contracts (N); - Tasking_Used := True; - -- Entry_Name is initialized to Any_Id. It should get reset to the -- matching entry entity. An error is signalled if it is not reset. @@ -1518,8 +1504,6 @@ package body Sem_Ch9 is Formals : constant List_Id := Parameter_Specifications (N); begin - Tasking_Used := True; - if Present (Index) then Analyze (Index); @@ -1545,8 +1529,6 @@ package body Sem_Ch9 is Call : constant Node_Id := Entry_Call_Statement (N); begin - Tasking_Used := True; - if Present (Pragmas_Before (N)) then Analyze_List (Pragmas_Before (N)); end if; @@ -1589,8 +1571,6 @@ package body Sem_Ch9 is begin Generate_Definition (Def_Id); - Tasking_Used := True; - -- Case of no discrete subtype definition if No (D_Sdef) then @@ -1720,6 +1700,12 @@ package body Sem_Ch9 is Process_Formals (Formals, N); Create_Extra_Formals (Def_Id); End_Scope; + + -- If the entry has no formals, extra formals are definitely not + -- required. + + else + Freeze_Extra_Formals (Def_Id); end if; if Ekind (Def_Id) = E_Entry then @@ -1751,7 +1737,6 @@ package body Sem_Ch9 is Loop_Id : constant Entity_Id := Make_Temporary (Sloc (N), 'L'); begin - Tasking_Used := True; Analyze (Def); -- There is no elaboration of the entry index specification. Therefore, @@ -1848,7 +1833,6 @@ package body Sem_Ch9 is Freeze_Previous_Contracts (N); - Tasking_Used := True; Mutate_Ekind (Body_Id, E_Protected_Body); Set_Etype (Body_Id, Standard_Void_Type); Spec_Id := Find_Concurrent_Spec (Body_Id); @@ -1991,7 +1975,6 @@ package body Sem_Ch9 is -- Start of processing for Analyze_Protected_Definition begin - Tasking_Used := True; Analyze_Declarations (Visible_Declarations (N)); if not Is_Empty_List (Private_Declarations (N)) then @@ -2047,7 +2030,6 @@ package body Sem_Ch9 is return; end if; - Tasking_Used := True; Check_Restriction (No_Protected_Types, N); T := Find_Type_Name (N); @@ -2223,18 +2205,21 @@ package body Sem_Ch9 is -- Pragma case else - if Debug_Flag_Underscore_DD then - Record_Pragma_No_Effect_With_Lock_Free_Warning - (Pragma_Node => Prio_Item, - Pragma_Name => Pragma_Name (Prio_Item), - Lock_Free_Node => Id, - Lock_Free_Range => Parent (Id)); - else - Error_Msg_Name_1 := Pragma_Name (Prio_Item); - Error_Msg_NE - ("pragma% for & has no effect when Lock_Free given??", - Prio_Item, Id); - end if; + Error_Msg_Name_1 := Pragma_Name (Prio_Item); + Error_Msg_NE + (Msg => + "pragma% for & has no effect when Lock_Free given??", + N => Prio_Item, + E => Id, + Error_Code => GNAT0003, + Label => "No effect", + Spans => + (1 => + Labeled_Span + (Span => To_Full_Span (Parent (Id)), + Label => "Lock_Free in effect here", + Is_Primary => False, + Is_Region => True))); end if; end if; end; @@ -2422,7 +2407,6 @@ package body Sem_Ch9 is Modes => True, Warnings => True); - Tasking_Used := True; Check_Restriction (No_Requeue_Statements, N); Check_Unreachable_Code (N); @@ -2754,7 +2738,6 @@ package body Sem_Ch9 is Alt_Count : Uint := Uint_0; begin - Tasking_Used := True; Check_Restriction (No_Select_Statements, N); -- Loop to analyze alternatives @@ -2871,7 +2854,6 @@ package body Sem_Ch9 is begin Generate_Definition (Obj_Id); - Tasking_Used := True; -- A single protected declaration is transformed into a pair of an -- anonymous protected type and an object of that type. Generate: @@ -2959,7 +2941,6 @@ package body Sem_Ch9 is begin Generate_Definition (Obj_Id); - Tasking_Used := True; -- A single task declaration is transformed into a pair of an anonymous -- task type and an object of that type. Generate: @@ -3074,7 +3055,6 @@ package body Sem_Ch9 is Freeze_Previous_Contracts (N); - Tasking_Used := True; Set_Scope (Body_Id, Current_Scope); Mutate_Ekind (Body_Id, E_Task_Body); Set_Etype (Body_Id, Standard_Void_Type); @@ -3219,8 +3199,6 @@ package body Sem_Ch9 is L : Entity_Id; begin - Tasking_Used := True; - if Present (Visible_Declarations (N)) then Analyze_Declarations (Visible_Declarations (N)); end if; @@ -3265,8 +3243,6 @@ package body Sem_Ch9 is -- Proceed ahead with analysis of task type declaration - Tasking_Used := True; - -- The sequential partition elaboration policy is supported only in the -- restricted profile. @@ -3448,8 +3424,6 @@ package body Sem_Ch9 is procedure Analyze_Terminate_Alternative (N : Node_Id) is begin - Tasking_Used := True; - if Present (Pragmas_Before (N)) then Analyze_List (Pragmas_Before (N)); end if; @@ -3469,7 +3443,6 @@ package body Sem_Ch9 is Is_Disp_Select : Boolean := False; begin - Tasking_Used := True; Check_Restriction (No_Select_Statements, N); -- Ada 2005 (AI-345): The trigger may be a dispatching call @@ -3504,8 +3477,6 @@ package body Sem_Ch9 is Trigger : constant Node_Id := Triggering_Statement (N); begin - Tasking_Used := True; - if Present (Pragmas_Before (N)) then Analyze_List (Pragmas_Before (N)); end if; diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb index 4881d6f2f8b3..5a8bd58b8b81 100644 --- a/gcc/ada/sem_disp.adb +++ b/gcc/ada/sem_disp.adb @@ -80,7 +80,7 @@ package body Sem_Disp is -- parameter); otherwise returns empty. function Find_Hidden_Overridden_Primitive (S : Entity_Id) return Entity_Id; - -- [Ada 2012:AI-0125] Find an inherited hidden primitive of the dispatching + -- [AI05-0125] Find an inherited hidden primitive of the dispatching -- type of S that has the same name of S, a type-conformant profile, an -- original corresponding operation O that is a primitive of a visible -- ancestor of the dispatching type of S and O is visible at the point of @@ -91,7 +91,8 @@ package body Sem_Disp is -- This routine does not search for non-hidden primitives since they are -- covered by the normal Ada 2005 rules. Its name was motivated by an -- intermediate version of AI05-0125 where this term was proposed to - -- name these entities in the RM. + -- name these entities in the RM. FWIW, note that AI05-0125 was + -- not approved; it was voted "No Action". function Is_Inherited_Public_Operation (Op : Entity_Id) return Boolean; -- Check whether a primitive operation is inherited from an operation @@ -586,7 +587,7 @@ package body Sem_Disp is Formal : Entity_Id; Control : Node_Id := Empty; Func : Entity_Id; - Subp_Entity : Entity_Id; + Subp_Entity : constant Entity_Id := Entity (Name (N)); Indeterm_Ctrl_Type : Entity_Id := Empty; -- Type of a controlling formal whose actual is a tag-indeterminate call @@ -967,7 +968,6 @@ package body Sem_Disp is -- Find a controlling argument, if any if Present (Parameter_Associations (N)) then - Subp_Entity := Entity (Name (N)); Actual := First_Actual (N); Formal := First_Formal (Subp_Entity); @@ -1710,9 +1710,8 @@ package body Sem_Disp is Ovr_Subp := Old_Subp; - -- [Ada 2012:AI-0125]: Search for inherited hidden primitive that may be - -- overridden by Subp. This only applies to source subprograms, and - -- their declaration must carry an explicit overriding indicator. + -- Search for inherited hidden primitive that may be + -- overridden by Subp. This only applies to source subprograms. if No (Ovr_Subp) and then Ada_Version >= Ada_2012 @@ -1721,16 +1720,6 @@ package body Sem_Disp is Nkind (Unit_Declaration_Node (Subp)) = N_Subprogram_Declaration then Ovr_Subp := Find_Hidden_Overridden_Primitive (Subp); - - -- Warn if the proper overriding indicator has not been supplied. - - if Present (Ovr_Subp) - and then - not Must_Override (Specification (Unit_Declaration_Node (Subp))) - and then not In_Instance - then - Error_Msg_NE ("missing overriding indicator for&??", Subp, Subp); - end if; end if; -- Now it should be a correct primitive operation, put it in the list @@ -2427,6 +2416,8 @@ package body Sem_Disp is Formal : Entity_Id; Ctrl_Type : Entity_Id; + -- Start of processing for Find_Dispatching_Type + begin if Ekind (Subp) in E_Function | E_Procedure and then Present (DTC_Entity (Subp)) @@ -3094,6 +3085,52 @@ package body Sem_Disp is then return Is_Tag_Indeterminate (Prefix (Orig_Node)); + -- An if-expression is tag-indeterminate if all of the dependent + -- expressions are tag-indeterminate (RM 4.5.7 (17/3)). + + elsif Nkind (Orig_Node) = N_If_Expression then + declare + Cond : constant Node_Id := First (Expressions (Orig_Node)); + Expr : Node_Id := Next (Cond); + + begin + if not Is_Tag_Indeterminate (Original_Node (Expr)) then + return False; + end if; + + Next (Expr); + + if Present (Expr) + and then not Is_Tag_Indeterminate (Original_Node (Expr)) + then + return False; + end if; + + return True; + end; + + -- A case-expression is tag-indeterminate if all of the dependent + -- expressions are tag-indeterminate (RM 4.5.7 (17/3)). + + elsif Nkind (Orig_Node) = N_Case_Expression then + declare + Alt : Node_Id := First (Alternatives (Orig_Node)); + Expr : Node_Id; + + begin + while Present (Alt) loop + Expr := Expression (Alt); + + if not Is_Tag_Indeterminate (Original_Node (Expr)) then + return False; + end if; + + Next (Alt); + end loop; + + return True; + end; + else return False; end if; @@ -3254,6 +3291,7 @@ package body Sem_Disp is elsif Nkind (Actual) = N_Explicit_Dereference and then Nkind (Original_Node (Prefix (Actual))) = N_Function_Call then + pragma Assert (Is_Expanded_Dispatching_Call (Actual)); return; -- When expansion is suppressed, an unexpanded call to 'Input can occur, diff --git a/gcc/ada/sem_elab.adb b/gcc/ada/sem_elab.adb index 6547813a8e2e..77b1e120b800 100644 --- a/gcc/ada/sem_elab.adb +++ b/gcc/ada/sem_elab.adb @@ -15236,7 +15236,15 @@ package body Sem_Elab is end if; Body_Decl := Unit_Declaration_Node (Body_Id); - Region := Find_Early_Call_Region (Body_Decl); + + -- For subprogram bodies in subunits we check where the subprogram + -- body stub is declared. + + if Nkind (Parent (Body_Decl)) = N_Subunit then + Body_Decl := Corresponding_Stub (Parent (Body_Decl)); + end if; + + Region := Find_Early_Call_Region (Body_Decl); -- The freeze node appears prior to the early call region of the -- primitive body. diff --git a/gcc/ada/sem_elim.adb b/gcc/ada/sem_elim.adb index 6bd3b77e2d49..7d9dca824c02 100644 --- a/gcc/ada/sem_elim.adb +++ b/gcc/ada/sem_elim.adb @@ -713,8 +713,6 @@ package body Sem_Elim is <<Continue>> Elmt := Elmt.Homonym; end loop; - - return; end Check_Eliminated; ------------------------------------- diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb index b7dfe01f2973..f970932df8f9 100644 --- a/gcc/ada/sem_eval.adb +++ b/gcc/ada/sem_eval.adb @@ -144,7 +144,7 @@ package body Sem_Eval is Checking_For_Potentially_Static_Expression : Boolean := False; -- Global flag that is set True during Analyze_Static_Expression_Function -- in order to verify that the result expression of a static expression - -- function is a potentially static function (see RM2022 6.8(5.3)). + -- function is a potentially static function (see RM 2022 6.8(5.3)). ----------------------- -- Local Subprograms -- @@ -574,13 +574,11 @@ package body Sem_Eval is Rewrite (N, New_Copy (N)); - if not Is_Floating_Point_Type (T) then - Set_Realval - (N, Corresponding_Integer_Value (N) * Small_Value (T)); - - elsif not UR_Is_Zero (Realval (N)) then + if Is_Floating_Point_Type (T) then Set_Realval (N, Machine_Number (Base_Type (T), Realval (N), N)); Set_Is_Machine_Number (N); + else + Set_Realval (N, Corresponding_Integer_Value (N) * Small_Value (T)); end if; end if; @@ -3999,7 +3997,6 @@ package body Sem_Eval is -- Otherwise the result depends on the right operand Fold_Uint (N, Expr_Value (Right), Rstat); - return; end Eval_Short_Circuit; ---------------- @@ -4989,27 +4986,41 @@ package body Sem_Eval is end if; end Check_Elab_Call; - Modulus, Val : Uint; - begin - if Compile_Time_Known_Value (Left) - and then Compile_Time_Known_Value (Right) + if not (Compile_Time_Known_Value (Left) + and then Compile_Time_Known_Value (Right)) then - pragma Assert (not Non_Binary_Modulus (Typ)); + return; + end if; + + pragma Assert (not Non_Binary_Modulus (Typ)); + pragma Assert (Expr_Value (Right) >= Uint_0); -- Amount is always Natural + + -- Shift by zero bits is a no-op + + if Expr_Value (Right) = Uint_0 then + Fold_Uint (N, Expr_Value (Left), Static => Static); + return; + end if; + declare + Modulus : constant Uint := + (if Is_Modular_Integer_Type (Typ) then Einfo.Entities.Modulus (Typ) + else Uint_2 ** RM_Size (Typ)); + Amount : constant Uint := UI_Min (Expr_Value (Right), RM_Size (Typ)); + -- Shift by an Amount greater than the size is all-zeros or all-ones. + -- Without this "min", we could use huge amounts of time and memory + -- below (e.g. 2**Amount, if Amount were a billion). + + Val : Uint; + begin if Op = N_Op_Shift_Left then Check_Elab_Call; - if Is_Modular_Integer_Type (Typ) then - Modulus := Einfo.Entities.Modulus (Typ); - else - Modulus := Uint_2 ** RM_Size (Typ); - end if; - -- Fold Shift_Left (X, Y) by computing -- (X * 2**Y) rem modulus [- Modulus] - Val := (Expr_Value (Left) * (Uint_2 ** Expr_Value (Right))) + Val := (Expr_Value (Left) * (Uint_2 ** Amount)) rem Modulus; if Is_Modular_Integer_Type (Typ) @@ -5023,49 +5034,32 @@ package body Sem_Eval is elsif Op = N_Op_Shift_Right then Check_Elab_Call; - -- X >> 0 is a no-op + -- Fold X >> Y by computing (X [+ Modulus]) / 2**Y. + -- Note that after a Shift_Right operation (with Y > 0), the + -- result is always positive, even if the original operand was + -- negative. - if Expr_Value (Right) = Uint_0 then - Fold_Uint (N, Expr_Value (Left), Static => Static); - else - if Is_Modular_Integer_Type (Typ) then - Modulus := Einfo.Entities.Modulus (Typ); + declare + M : Unat; + begin + if Expr_Value (Left) >= Uint_0 then + M := Uint_0; else - Modulus := Uint_2 ** RM_Size (Typ); + M := Modulus; end if; - -- Fold X >> Y by computing (X [+ Modulus]) / 2**Y - -- Note that after a Shift_Right operation (with Y > 0), the - -- result is always positive, even if the original operand was - -- negative. - - declare - M : Unat; - begin - if Expr_Value (Left) >= Uint_0 then - M := Uint_0; - else - M := Modulus; - end if; + Fold_Uint + (N, + (Expr_Value (Left) + M) / (Uint_2 ** Amount), + Static => Static); + end; - Fold_Uint - (N, - (Expr_Value (Left) + M) / (Uint_2 ** Expr_Value (Right)), - Static => Static); - end; - end if; elsif Op = N_Op_Shift_Right_Arithmetic then Check_Elab_Call; declare - Two_Y : constant Uint := Uint_2 ** Expr_Value (Right); + Two_Y : constant Uint := Uint_2 ** Amount; begin - if Is_Modular_Integer_Type (Typ) then - Modulus := Einfo.Entities.Modulus (Typ); - else - Modulus := Uint_2 ** RM_Size (Typ); - end if; - -- X / 2**Y if X if positive or a small enough modular integer if (Is_Modular_Integer_Type (Typ) @@ -5096,7 +5090,7 @@ package body Sem_Eval is (N, (Expr_Value (Left)) / Two_Y + (Two_Y - Uint_1) - * Uint_2 ** (RM_Size (Typ) - Expr_Value (Right)), + * Uint_2 ** (RM_Size (Typ) - Amount), Static => Static); -- Negative signed integer, compute via multiple/divide the @@ -5108,13 +5102,15 @@ package body Sem_Eval is (N, (Modulus + Expr_Value (Left)) / Two_Y + (Two_Y - Uint_1) - * Uint_2 ** (RM_Size (Typ) - Expr_Value (Right)) + * Uint_2 ** (RM_Size (Typ) - Amount) - Modulus, Static => Static); end if; end; + else + raise Program_Error; end if; - end if; + end; end Fold_Shift; -------------- @@ -5290,9 +5286,16 @@ package body Sem_Eval is begin if Nkind (N) in N_String_Literal | N_Character_Literal then return N; - else - pragma Assert (Is_Entity_Name (N)); + elsif Is_Entity_Name (N) then return Get_String_Val (Constant_Value (Entity (N))); + elsif Nkind (N) = N_Integer_Literal then + pragma Assert (Serious_Errors_Detected /= 0); + return + Make_Character_Literal (Sloc (N), + Chars => Error_Name, + Char_Literal_Value => Intval (N)); + else + raise Program_Error; end if; end Get_String_Val; diff --git a/gcc/ada/sem_eval.ads b/gcc/ada/sem_eval.ads index 138278f7af3a..b6f44ef68332 100644 --- a/gcc/ada/sem_eval.ads +++ b/gcc/ada/sem_eval.ads @@ -301,34 +301,34 @@ package Sem_Eval is -- is static or its value is known at compile time. This version is used -- for string types and returns the corresponding N_String_Literal node. - procedure Eval_Actual (N : Node_Id); - procedure Eval_Allocator (N : Node_Id); - procedure Eval_Arithmetic_Op (N : Node_Id); - procedure Eval_Call (N : Node_Id); - procedure Eval_Case_Expression (N : Node_Id); - procedure Eval_Character_Literal (N : Node_Id); - procedure Eval_Concatenation (N : Node_Id); - procedure Eval_Entity_Name (N : Node_Id); - procedure Eval_If_Expression (N : Node_Id); - procedure Eval_Indexed_Component (N : Node_Id); - procedure Eval_Integer_Literal (N : Node_Id); - procedure Eval_Logical_Op (N : Node_Id); - procedure Eval_Membership_Op (N : Node_Id); - procedure Eval_Named_Integer (N : Node_Id); - procedure Eval_Named_Real (N : Node_Id); - procedure Eval_Op_Expon (N : Node_Id); - procedure Eval_Op_Not (N : Node_Id); - procedure Eval_Real_Literal (N : Node_Id); - procedure Eval_Relational_Op (N : Node_Id); - procedure Eval_Selected_Component (N : Node_Id); - procedure Eval_Shift (N : Node_Id); - procedure Eval_Short_Circuit (N : Node_Id); - procedure Eval_Slice (N : Node_Id); - procedure Eval_String_Literal (N : Node_Id); - procedure Eval_Qualified_Expression (N : Node_Id); - procedure Eval_Type_Conversion (N : Node_Id); - procedure Eval_Unary_Op (N : Node_Id); - procedure Eval_Unchecked_Conversion (N : Node_Id); + procedure Eval_Actual (N : Node_Id); + procedure Eval_Allocator (N : Node_Id); + procedure Eval_Arithmetic_Op (N : Node_Id); + procedure Eval_Call (N : Node_Id); + procedure Eval_Case_Expression (N : Node_Id); + procedure Eval_Character_Literal (N : Node_Id); + procedure Eval_Concatenation (N : Node_Id); + procedure Eval_Entity_Name (N : Node_Id); + procedure Eval_If_Expression (N : Node_Id); + procedure Eval_Indexed_Component (N : Node_Id); + procedure Eval_Integer_Literal (N : Node_Id); + procedure Eval_Logical_Op (N : Node_Id); + procedure Eval_Membership_Op (N : Node_Id); + procedure Eval_Named_Integer (N : Node_Id); + procedure Eval_Named_Real (N : Node_Id); + procedure Eval_Op_Expon (N : Node_Id); + procedure Eval_Op_Not (N : Node_Id); + procedure Eval_Real_Literal (N : Node_Id); + procedure Eval_Relational_Op (N : Node_Id); + procedure Eval_Selected_Component (N : Node_Id); + procedure Eval_Shift (N : Node_Id); + procedure Eval_Short_Circuit (N : Node_Id); + procedure Eval_Slice (N : Node_Id); + procedure Eval_String_Literal (N : Node_Id); + procedure Eval_Qualified_Expression (N : Node_Id); + procedure Eval_Type_Conversion (N : Node_Id); + procedure Eval_Unary_Op (N : Node_Id); + procedure Eval_Unchecked_Conversion (N : Node_Id); procedure Flag_Non_Static_Expr (Msg : String; Expr : Node_Id); -- This procedure is called after it has been determined that Expr is not @@ -342,41 +342,12 @@ package Sem_Eval is -- set of messages is all posted. procedure Fold_Str (N : Node_Id; Val : String_Id; Static : Boolean); - -- Rewrite N with a new N_String_Literal node as the result of the compile - -- time evaluation of the node N. Val is the resulting string value from - -- the folding operation. The Is_Static_Expression flag is set in the - -- result node. The result is fully analyzed and resolved. Static indicates - -- whether the result should be considered static or not (True = consider - -- static). The point here is that normally all string literals are static, - -- but if this was the result of some sequence of evaluation where values - -- were known at compile time but not static, then the result is not - -- static. The call has no effect if Raises_Constraint_Error (N) is True, - -- since there is no point in folding if we have an error. - procedure Fold_Uint (N : Node_Id; Val : Uint; Static : Boolean); - -- Rewrite N with a (N_Integer_Literal, N_Identifier, N_Character_Literal) - -- node as the result of the compile time evaluation of the node N. Val is - -- the result in the integer case and is the position of the literal in the - -- literals list for the enumeration case. Is_Static_Expression is set True - -- in the result node. The result is fully analyzed/resolved. Static - -- indicates whether the result should be considered static or not (True = - -- consider static). The point here is that normally all integer literals - -- are static, but if this was the result of some sequence of evaluation - -- where values were known at compile time but not static, then the result - -- is not static. The call has no effect if Raises_Constraint_Error (N) is - -- True, since there is no point in folding if we have an error. - procedure Fold_Ureal (N : Node_Id; Val : Ureal; Static : Boolean); - -- Rewrite N with a new N_Real_Literal node as the result of the compile - -- time evaluation of the node N. Val is the resulting real value from the - -- folding operation. The Is_Static_Expression flag is set in the result - -- node. The result is fully analyzed and result. Static indicates whether - -- the result should be considered static or not (True = consider static). - -- The point here is that normally all string literals are static, but if - -- this was the result of some sequence of evaluation where values were - -- known at compile time but not static, then the result is not static. - -- The call has no effect if Raises_Constraint_Error (N) is True, since - -- there is no point in folding if we have an error. + -- Rewrite N with a new literal node with compile-time-known value Val. + -- Is_Static_Expression is set to Static. This has no effect if + -- Raises_Constraint_Error (N) is True, since there is no point in + -- folding if we have an error. procedure Fold (N : Node_Id); -- Rewrite N with the relevant value if Compile_Time_Known_Value (N) is diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb index 621edc7725d8..2717c38cdfde 100644 --- a/gcc/ada/sem_prag.adb +++ b/gcc/ada/sem_prag.adb @@ -216,10 +216,10 @@ package body Sem_Prag is (Prag : Node_Id; Spec_Id : Entity_Id); -- Subsidiary to the analysis of pragmas Contract_Cases, Postcondition, - -- Precondition, Refined_Post, Subprogram_Variant, and Test_Case. Emit a - -- warning when pragma Prag is associated with subprogram Spec_Id subject - -- to Inline_Always, assertions are enabled and inling is done in the - -- frontend. + -- Precondition, Program_Exit, Refined_Post, Subprogram_Variant, and + -- Test_Case. Emit a warning when pragma Prag is associated with subprogram + -- Spec_Id subject to Inline_Always, assertions are enabled and inling is + -- done in the frontend. procedure Check_State_And_Constituent_Use (States : Elist_Id; @@ -234,9 +234,10 @@ package body Sem_Prag is (Contract_Id : Entity_Id; Freeze_Id : Entity_Id); -- Subsidiary to the analysis of pragmas Contract_Cases, Exceptional_Cases, - -- Part_Of, Post, Pre and Subprogram_Variant. Emit a freezing-related error - -- message where Freeze_Id is the entity of a body which caused contract - -- freezing and Contract_Id denotes the entity of the affected contstruct. + -- Part_Of, Post, Pre, Program_Exit and Subprogram_Variant. Emit a + -- freezing-related error message where Freeze_Id is the entity of a body + -- which caused contract freezing and Contract_Id denotes the entity of the + -- affected contstruct. procedure Duplication_Error (Prag : Node_Id; Prev : Node_Id); -- Subsidiary to all Find_Related_xxx routines. Emit an error on pragma @@ -474,7 +475,8 @@ package body Sem_Prag is end if; Errors := Serious_Errors_Detected; - Preanalyze_Assert_Expression (Expression (Arg1), Standard_Boolean); + Preanalyze_And_Resolve_Assert_Expression + (Expression (Arg1), Standard_Boolean); -- Emit a clarification message when the expression contains at least -- one undefined reference, possibly due to contract freezing. @@ -564,7 +566,8 @@ package body Sem_Prag is if Nkind (Case_Guard) /= N_Others_Choice then Errors := Serious_Errors_Detected; - Preanalyze_Assert_Expression (Case_Guard, Standard_Boolean); + Preanalyze_And_Resolve_Assert_Expression + (Case_Guard, Standard_Boolean); -- Emit a clarification message when the case guard contains -- at least one undefined reference, possibly due to contract @@ -579,7 +582,8 @@ package body Sem_Prag is end if; Errors := Serious_Errors_Detected; - Preanalyze_Assert_Expression (Conseq, Standard_Boolean); + Preanalyze_And_Resolve_Assert_Expression + (Conseq, Standard_Boolean); -- Emit a clarification message when the consequence contains -- at least one undefined reference, possibly due to contract @@ -2391,9 +2395,10 @@ package body Sem_Prag is Errors := Serious_Errors_Detected; - -- Preanalyze_Assert_Expression enforcing the expression type + -- Preanalyze_And_Resolve_Assert_Expression enforcing the expression + -- type. - Preanalyze_Assert_Expression (Consequence, Any_Boolean); + Preanalyze_And_Resolve_Assert_Expression (Consequence, Any_Boolean); Check_Params (Consequence); @@ -2621,7 +2626,8 @@ package body Sem_Prag is if Nkind (Case_Guard) /= N_Others_Choice then Errors := Serious_Errors_Detected; - Preanalyze_Assert_Expression (Case_Guard, Standard_Boolean); + Preanalyze_And_Resolve_Assert_Expression + (Case_Guard, Standard_Boolean); -- Emit a clarification message when the case guard contains -- at least one undefined reference, possibly due to contract @@ -2636,14 +2642,16 @@ package body Sem_Prag is end if; -- Check the exit kind. It shall be either an exception or the - -- identifiers Normal_Return or Any_Exception. + -- identifiers Normal_Return, Exception_Raised, or Program_Exit. if Nkind (Exit_Kind) = N_Identifier then if Chars (Exit_Kind) not in Name_Normal_Return | Name_Exception_Raised + | Name_Program_Exit then Error_Msg_N - ("exit kind should be Normal_Return or Exception_Raised", + ("exit kind should be Normal_Return, Exception_Raised, " & + "or Program_Exit", Exit_Kind); end if; @@ -5112,10 +5120,6 @@ package body Sem_Prag is -- Determines if the placement of the current pragma is appropriate -- for a configuration pragma. - function Is_In_Context_Clause return Boolean; - -- Returns True if pragma appears within the context clause of a unit, - -- and False for any other placement (does not generate any messages). - function Is_Static_String_Expression (Arg : Node_Id) return Boolean; -- Analyzes the argument, and determines if it is a static string -- expression, returns True if so, False if non-static or not String. @@ -5585,7 +5589,7 @@ package body Sem_Prag is if Present (Arg2) then Check_Optional_Identifier (Arg2, Name_Message); - Preanalyze_Assert_Expression + Preanalyze_And_Resolve_Assert_Expression (Get_Pragma_Arg (Arg2), Standard_String); end if; end if; @@ -6009,7 +6013,7 @@ package body Sem_Prag is -- Check case of appearing within context clause - if not Is_Unused and then Is_In_Context_Clause then + if not Is_Unused and then Is_In_Context_Clause (N) then -- The arguments must all be units mentioned in a with clause in -- the same context clause. Note that Par.Prag already checked @@ -8083,10 +8087,26 @@ package body Sem_Prag is -- the test below also permits use in a configuration pragma file. function Is_Configuration_Pragma return Boolean is + function Is_Pragma_Node (Prg : Node_Id) return Boolean is + (Nkind (Prg) = N_Pragma + or else + (Present (Original_Node (Prg)) + and then Nkind (Original_Node (Prg)) = N_Pragma)); + -- Returns true whether the node is a pragma or was originally a + -- pragma. + -- + -- Note that some pragmas like Assertion_Policy are rewritten as + -- Null_Statment nodes but we still need to make sure here that the + -- original node was a pragma node. + + -- Local variables + Lis : List_Id; Par : constant Node_Id := Parent (N); Prg : Node_Id; + -- Start of processing for Is_Configuration_Pragma + begin -- Don't evaluate List_Containing (N) if Parent (N) could be -- an N_Aspect_Specification node. @@ -8115,7 +8135,7 @@ package body Sem_Prag is loop if Prg = N then return True; - elsif Nkind (Prg) /= N_Pragma then + elsif not Is_Pragma_Node (Prg) then return False; end if; @@ -8127,27 +8147,6 @@ package body Sem_Prag is end if; end Is_Configuration_Pragma; - -------------------------- - -- Is_In_Context_Clause -- - -------------------------- - - function Is_In_Context_Clause return Boolean is - Plist : List_Id; - Parent_Node : Node_Id; - - begin - if Is_List_Member (N) then - Plist := List_Containing (N); - Parent_Node := Parent (Plist); - - return Present (Parent_Node) - and then Nkind (Parent_Node) = N_Compilation_Unit - and then Context_Items (Parent_Node) = Plist; - end if; - - return False; - end Is_In_Context_Clause; - --------------------------------- -- Is_Static_String_Expression -- --------------------------------- @@ -10049,7 +10048,6 @@ package body Sem_Prag is end if; Def_Id := Entity (Def_Id); - Kill_Size_Check_Code (Def_Id); if Ekind (Def_Id) /= E_Constant then Note_Possible_Modification (Get_Pragma_Arg (Arg1), Sure => False); @@ -10062,7 +10060,6 @@ package body Sem_Prag is -- purposes of legality checks and removal of ignored Ghost code. Mark_Ghost_Pragma (N, Def_Id); - Kill_Size_Check_Code (Def_Id); if Ekind (Def_Id) /= E_Constant then Note_Possible_Modification (Get_Pragma_Arg (Arg2), Sure => False); @@ -14065,7 +14062,7 @@ package body Sem_Prag is -- Perform preanalysis to deal with embedded Loop_Entry -- attributes. - Preanalyze_Assert_Expression (Expr, Any_Boolean); + Preanalyze_And_Resolve_Assert_Expression (Expr, Any_Boolean); end if; -- Implement Assert[_And_Cut]/Assume/Loop_Invariant by generating @@ -14696,19 +14693,18 @@ package body Sem_Prag is D := Declaration_Node (E); - if (Nkind (D) = N_Full_Type_Declaration and then Is_Array_Type (E)) + if (Nkind (D) in N_Full_Type_Declaration + | N_Formal_Type_Declaration + and then Is_Array_Type (E)) or else (Nkind (D) = N_Object_Declaration and then Ekind (E) in E_Constant | E_Variable and then Nkind (Object_Definition (D)) = N_Constrained_Array_Definition) - or else - (Ada_Version >= Ada_2022 - and then Nkind (D) = N_Formal_Type_Declaration) then -- The flag is set on the base type, or on the object - if Nkind (D) = N_Full_Type_Declaration then + if Is_Array_Type (E) then E := Base_Type (E); end if; @@ -16166,7 +16162,8 @@ package body Sem_Prag is -- described in "Handling of Default and Per-Object -- Expressions" in sem.ads. - Preanalyze_Spec_Expression (Arg, RTE (RE_CPU_Range)); + Preanalyze_And_Resolve_Spec_Expression + (Arg, RTE (RE_CPU_Range)); -- See comment in Sem_Ch13 about the following restrictions @@ -16212,7 +16209,7 @@ package body Sem_Prag is -- The expression must be analyzed in the special manner described -- in "Handling of Default and Per-Object Expressions" in sem.ads. - Preanalyze_Spec_Expression (Arg, RTE (RE_Time_Span)); + Preanalyze_And_Resolve_Spec_Expression (Arg, RTE (RE_Time_Span)); -- Only protected types allowed @@ -16841,7 +16838,8 @@ package body Sem_Prag is -- described in "Handling of Default and Per-Object -- Expressions" in sem.ads. - Preanalyze_Spec_Expression (Arg, RTE (RE_Dispatching_Domain)); + Preanalyze_And_Resolve_Spec_Expression + (Arg, RTE (RE_Dispatching_Domain)); -- Check duplicate pragma before we chain the pragma in the Rep -- Item chain of Ent. @@ -16869,7 +16867,7 @@ package body Sem_Prag is begin -- Pragma must be in context items list of a compilation unit - if not Is_In_Context_Clause then + if not Is_In_Context_Clause (N) then Pragma_Misplaced; end if; @@ -16965,7 +16963,7 @@ package body Sem_Prag is -- Pragma must be in context items list of a compilation unit - if not Is_In_Context_Clause then + if not Is_In_Context_Clause (N) then Pragma_Misplaced; end if; @@ -17457,6 +17455,7 @@ package body Sem_Prag is -- -- EXIT_KIND ::= -- Normal_Return + -- | Program_Exit -- | Exception_Raised -- | (Exception_Raised => exception_name) -- @@ -19964,7 +19963,6 @@ package body Sem_Prag is -- object to be imported. if Ekind (Def_Id) = E_Variable then - Kill_Size_Check_Code (Def_Id); Note_Possible_Modification (Id, Sure => False); -- Initialization is not allowed for imported variable @@ -20074,7 +20072,8 @@ package body Sem_Prag is -- described in "Handling of Default and Per-Object -- Expressions" in sem.ads. - Preanalyze_Spec_Expression (Arg, RTE (RE_Interrupt_Priority)); + Preanalyze_And_Resolve_Spec_Expression + (Arg, RTE (RE_Interrupt_Priority)); end if; if Nkind (P) not in N_Task_Definition | N_Protected_Definition then @@ -20979,10 +20978,10 @@ package body Sem_Prag is ("Structural variant shall be the only variant", Variant); end if; - -- Preanalyze_Assert_Expression, but without enforcing any of - -- the two acceptable types. + -- Preanalyze_And_Resolve_Assert_Expression, but without + -- enforcing any of the two acceptable types. - Preanalyze_Assert_Expression (Expression (Variant)); + Preanalyze_And_Resolve_Assert_Expression (Expression (Variant)); -- Expression of a discrete type is allowed. Nothing to -- check for structural variants. @@ -20992,16 +20991,13 @@ package body Sem_Prag is then null; - -- Expression of a Big_Integer type (or its ghost variant) is + -- Expression of a Big_Integer type (or its SPARK variant) is -- only allowed in Decreases clause. elsif Is_RTE (Base_Type (Etype (Expression (Variant))), RE_Big_Integer) or else - Is_RTE (Base_Type (Etype (Expression (Variant))), - RO_GH_Big_Integer) - or else Is_RTE (Base_Type (Etype (Expression (Variant))), RO_SP_Big_Integer) then @@ -21374,8 +21370,8 @@ package body Sem_Prag is -- pragma No_Component_Reordering [([Entity =>] type_LOCAL_NAME)]; when Pragma_No_Component_Reordering => No_Comp_Reordering : declare - E : Entity_Id; - E_Id : Node_Id; + Typ : Entity_Id; + Type_Id : Node_Id; begin GNAT_Pragma; @@ -21388,19 +21384,20 @@ package body Sem_Prag is else Check_Optional_Identifier (Arg2, Name_Entity); Check_Arg_Is_Local_Name (Arg1); - E_Id := Get_Pragma_Arg (Arg1); + Type_Id := Get_Pragma_Arg (Arg1); - if Etype (E_Id) = Any_Type then + Find_Type (Type_Id); + Typ := Entity (Type_Id); + + if Typ = Any_Type then return; end if; - E := Entity (E_Id); - - if not Is_Record_Type (E) then + if not Is_Record_Type (Typ) then Error_Pragma_Arg ("pragma% requires record type", Arg1); end if; - Set_No_Reordering (Base_Type (E)); + Set_No_Reordering (Base_Type (Typ)); end if; end No_Comp_Reordering; @@ -23410,7 +23407,8 @@ package body Sem_Prag is -- described in "Handling of Default and Per-Object -- Expressions" in sem.ads. - Preanalyze_Spec_Expression (Arg, RTE (RE_Any_Priority)); + Preanalyze_And_Resolve_Spec_Expression + (Arg, RTE (RE_Any_Priority)); if not Is_OK_Static_Expression (Arg) then Check_Restriction (Static_Priorities, Arg); @@ -23615,6 +23613,132 @@ package body Sem_Prag is end if; end; + ------------------ + -- Program_Exit -- + ------------------ + + -- pragma Program_Exit (Boolean_EXPRESSION); + + -- Characteristics: + + -- * Analysis - The annotation undergoes initial checks to verify + -- the legal placement and context. Secondary checks preanalyze the + -- expression in: + + -- Analyze_Program_Exit_In_Decl_Part + + -- * Expansion - The annotation is expanded during the expansion of + -- the related subprogram [body] contract as performed in: + + -- Expand_Subprogram_Contract + + -- * Template - The annotation utilizes the generic template of the + -- related subprogram [body] when it is: + + -- aspect on subprogram declaration + -- aspect on stand-alone subprogram body + -- pragma on stand-alone subprogram body + + -- The annotation must prepare its own template when it is: + + -- pragma on subprogram declaration + + -- * Globals - Capture of global references must occur after full + -- analysis. + + -- * Instance - The annotation is instantiated automatically when + -- the related generic subprogram [body] is instantiated except for + -- the "pragma on subprogram declaration" case. In that scenario + -- the annotation must instantiate itself. + + when Pragma_Program_Exit => Program_Exit : declare + Spec_Id : Entity_Id; + Subp_Decl : Node_Id; + Subp_Spec : Node_Id; + + begin + GNAT_Pragma; + Check_No_Identifiers; + Check_At_Most_N_Arguments (1); + + -- Ensure the proper placement of the pragma. Program_Exit must be + -- associated with a subprogram declaration or a body that acts as + -- a spec. + + Subp_Decl := + Find_Related_Declaration_Or_Body (N, Do_Checks => True); + + -- Generic subprogram + + if Nkind (Subp_Decl) = N_Generic_Subprogram_Declaration then + null; + + -- Body acts as spec + + elsif Nkind (Subp_Decl) = N_Subprogram_Body + and then No (Corresponding_Spec (Subp_Decl)) + then + null; + + -- Body stub acts as spec + + elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub + and then No (Corresponding_Spec_Of_Stub (Subp_Decl)) + then + null; + + -- Subprogram + + elsif Nkind (Subp_Decl) = N_Subprogram_Declaration then + Subp_Spec := Specification (Subp_Decl); + + -- Pragma Program_Exit is forbidden on null procedures, as this + -- may lead to potential ambiguities in behavior when interface + -- null procedures are involved. Also, it just wouldn't make + -- sense, because null procedure always exits. + + if Nkind (Subp_Spec) = N_Procedure_Specification + and then Null_Present (Subp_Spec) + then + Error_Msg_N (Fix_Error + ("pragma % cannot apply to null procedure"), N); + return; + end if; + + else + Pragma_Misplaced; + end if; + + Spec_Id := Unique_Defining_Entity (Subp_Decl); + + -- A pragma that applies to a Ghost entity becomes Ghost for the + -- purposes of legality checks and removal of ignored Ghost code. + + Mark_Ghost_Pragma (N, Spec_Id); + + -- Chain the pragma on the contract for further processing by + -- Analyze_Program_Exit. + + Add_Contract_Item (N, Defining_Entity (Subp_Decl)); + + -- Fully analyze the pragma when it appears inside a subprogram + -- body because it cannot benefit from forward references. + + if Nkind (Subp_Decl) in N_Subprogram_Body + | N_Subprogram_Body_Stub + then + -- The legality checks of pragma Program_Exit are affected by + -- the SPARK mode in effect and the volatility of the context. + -- Analyze all pragmas in a specific order. + + Analyze_If_Present (Pragma_SPARK_Mode); + Analyze_If_Present (Pragma_Volatile_Function); + Analyze_If_Present (Pragma_Global); + Analyze_If_Present (Pragma_Depends); + Analyze_Program_Exit_In_Decl_Part (N); + end if; + end Program_Exit; + ---------------------- -- Profile_Warnings -- ---------------------- @@ -23982,7 +24106,7 @@ package body Sem_Prag is Analyze_If_Present (Pragma_Side_Effects); -- A function with side effects shall not have a Pure_Function - -- aspect or pragma (SPARK RM 6.1.11(5)). + -- aspect or pragma (SPARK RM 6.1.12(5)). if Is_Function_With_Side_Effects (E) then Error_Pragma @@ -24397,7 +24521,7 @@ package body Sem_Prag is -- The expression must be analyzed in the special manner described -- in "Handling of Default and Per-Object Expressions" in sem.ads. - Preanalyze_Spec_Expression (Arg, RTE (RE_Time_Span)); + Preanalyze_And_Resolve_Spec_Expression (Arg, RTE (RE_Time_Span)); -- Subprogram case @@ -24657,7 +24781,7 @@ package body Sem_Prag is -- The expression must be analyzed in the special manner -- described in "Handling of Default Expressions" in sem.ads. - Preanalyze_Spec_Expression (Arg, Any_Integer); + Preanalyze_And_Resolve_Spec_Expression (Arg, Any_Integer); -- The pragma cannot appear if the No_Secondary_Stack -- restriction is in effect. @@ -25815,7 +25939,7 @@ package body Sem_Prag is -- in "Handling of Default Expressions" in sem.ads. Arg := Get_Pragma_Arg (Arg1); - Preanalyze_Spec_Expression (Arg, Any_Integer); + Preanalyze_And_Resolve_Spec_Expression (Arg, Any_Integer); if not Is_OK_Static_Expression (Arg) then Check_Restriction (Static_Storage_Size, Arg); @@ -26845,7 +26969,7 @@ package body Sem_Prag is Opt.Time_Slice_Set := True; Val := Expr_Value_R (Get_Pragma_Arg (Arg1)); - if Val <= Ureal_0 then + if not UR_Is_Positive (Val) then Opt.Time_Slice_Value := 0; elsif Val > UR_From_Uint (UI_From_Int (1000)) then @@ -28241,7 +28365,7 @@ package body Sem_Prag is end if; Errors := Serious_Errors_Detected; - Preanalyze_Assert_Expression (Expr, Standard_Boolean); + Preanalyze_And_Resolve_Assert_Expression (Expr, Standard_Boolean); -- Emit a clarification message when the expression contains at least -- one undefined reference, possibly due to contract freezing. @@ -28296,6 +28420,153 @@ package body Sem_Prag is Restore_Ghost_Region (Saved_GM, Saved_IGR); end Analyze_Pre_Post_Condition_In_Decl_Part; + --------------------------------------- + -- Analyze_Program_Exit_In_Decl_Part -- + --------------------------------------- + + -- WARNING: This routine manages Ghost regions. Return statements must be + -- replaced by gotos which jump to the end of the routine and restore the + -- Ghost mode. + + procedure Analyze_Program_Exit_In_Decl_Part + (N : Node_Id; + Freeze_Id : Entity_Id := Empty) + is + Subp_Decl : constant Node_Id := Find_Related_Declaration_Or_Body (N); + Spec_Id : constant Entity_Id := Unique_Defining_Entity (Subp_Decl); + Arg1 : constant Node_Id := + First (Pragma_Argument_Associations (N)); + + Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; + Saved_IGR : constant Node_Id := Ignored_Ghost_Region; + -- Save the Ghost-related attributes to restore on exit + + Errors : Nat; + Restore_Scope : Boolean := False; + Unused : Boolean; + + Subp_Inputs, Subp_Outputs : Elist_Id := No_Elist; + -- Inputs and outputs of the subprogram + + function Check_Reference (N : Node_Id) return Traverse_Result; + -- Check references to objects within the Program_Exit expression + + --------------------- + -- Check_Reference -- + --------------------- + + function Check_Reference (N : Node_Id) return Traverse_Result is + begin + -- If an output of a subprogram with side effects is mentioned + -- in the boolean expression of its aspect Program_Exit, then it + -- shall either occur inside the prefix of a reference to the Old + -- attribute or be a stand-alone object. + + if Is_Attribute_Old (N) then + return Skip; + end if; + + if Is_Entity_Name (N) then + declare + E : constant Entity_Id := Entity (N); + begin + if Appears_In (Subp_Outputs, E) + and then Ekind (E) not in E_Constant | E_Variable + then + Error_Msg_NE + ("reference to subprogram output & in Program_Exit", N, E); + end if; + end; + end if; + + return OK; + end Check_Reference; + + procedure Check_Exit_References is new Traverse_Proc (Check_Reference); + + -- Start of processing for Analyze_Pre_Post_Condition_In_Decl_Part + + begin + -- Do not analyze the pragma multiple times + + if Is_Analyzed_Pragma (N) then + return; + end if; + + if Ekind (Spec_Id) in E_Function | E_Generic_Function + and then not Is_Function_With_Side_Effects (Spec_Id) + then + Error_Msg_N + ("aspect Program_Exit is only allowed " & + "for subprograms with side effects", N); + end if; + + if Present (Arg1) then + + -- Set the Ghost mode in effect from the pragma. Due to the delayed + -- analysis of the pragma, the Ghost mode at point of declaration and + -- point of analysis may not necessarily be the same. Use the mode in + -- effect at the point of declaration. + + Set_Ghost_Mode (N); + + -- Ensure that the subprogram and its formals are visible when + -- analyzing the expression of the pragma. + + if not In_Open_Scopes (Spec_Id) then + Restore_Scope := True; + + if Is_Generic_Subprogram (Spec_Id) then + Push_Scope (Spec_Id); + Install_Generic_Formals (Spec_Id); + else + Push_Scope (Spec_Id); + Install_Formals (Spec_Id); + end if; + end if; + + Errors := Serious_Errors_Detected; + + -- Preanalyze_And_Resolve_Assert_Expression enforcing the expression + -- type. + + Preanalyze_And_Resolve_Assert_Expression + (Expression (Arg1), Any_Boolean); + + Collect_Subprogram_Inputs_Outputs + (Spec_Id, + Synthesize => True, + Subp_Inputs => Subp_Inputs, + Subp_Outputs => Subp_Outputs, + Global_Seen => Unused); + + Check_Exit_References (Expression (Arg1)); + + -- Emit a clarification message when the expression contains at least + -- one undefined reference, possibly due to contract freezing. + + if Errors /= Serious_Errors_Detected + and then Present (Freeze_Id) + and then Has_Undefined_Reference (Expression (Arg1)) + then + Contract_Freeze_Error (Spec_Id, Freeze_Id); + end if; + + if Restore_Scope then + End_Scope; + end if; + + -- Currently it is not possible to inline pre/postconditions on a + -- subprogram subject to pragma Inline_Always. + + Check_Postcondition_Use_In_Inlined_Subprogram (N, Spec_Id); + + Restore_Ghost_Region (Saved_GM, Saved_IGR); + end if; + + Set_Is_Analyzed_Pragma (N); + end Analyze_Program_Exit_In_Decl_Part; + ------------------------------------------ -- Analyze_Refined_Depends_In_Decl_Part -- ------------------------------------------ @@ -30956,34 +31227,67 @@ package body Sem_Prag is -- end Pack; if Constit_Id = Any_Id then - SPARK_Msg_NE ("& is undefined", Constit, Constit_Id); + -- A "Foo is undefined" message has already been + -- generated for this constituent. Emit an additional + -- message in the special case where the named + -- would-be constituent was declared too late in the + -- declaration list (as opposed to, for example, not + -- being declared at all). + + -- Look for named constituent after freezing point + if Present (Freeze_Id) then + declare + Decl : Node_Id; + begin + Decl := Enclosing_Declaration (Freeze_Id); - -- Emit a specialized info message when the contract of - -- the related package body was "frozen" by another body. - -- Note that it is not possible to precisely identify why - -- the constituent is undefined because it is not visible - -- when pragma Refined_State is analyzed. This message is - -- a reasonable approximation. + while Present (Decl) loop + if Nkind (Decl) = N_Object_Declaration + and then Same_Name (Defining_Identifier (Decl), + Constit) + and then not Constant_Present (Decl) + then + Error_Msg_Node_1 := Constit; + Error_Msg_Sloc := + Sloc (Defining_Identifier (Decl)); - if Present (Freeze_Id) and then not Freeze_Posted then - Freeze_Posted := True; + SPARK_Msg_NE + ("abstract state constituent & declared" + & " too late #!", Constit, Constit); - Error_Msg_Name_1 := Chars (Body_Id); - Error_Msg_Sloc := Sloc (Freeze_Id); - SPARK_Msg_NE - ("body & declared # freezes the contract of %", - N, Freeze_Id); - SPARK_Msg_N - ("\all constituents must be declared before body #", - N); + exit; + end if; + Next (Decl); + end loop; + end; + + -- Emit a specialized info message when the contract + -- of the related package body was "frozen" by + -- another body. If a "declared too late" message + -- is generated, this will clarify what is meant by + -- "too late". + + if not Freeze_Posted then + Freeze_Posted := True; - -- A misplaced constituent is a critical error because - -- pragma Refined_Depends or Refined_Global depends on - -- the proper link between a state and a constituent. - -- Stop the compilation, as this leads to a multitude - -- of misleading cascaded errors. + Error_Msg_Name_1 := Chars (Body_Id); + Error_Msg_Sloc := Sloc (Freeze_Id); + SPARK_Msg_NE + ("body & declared # freezes the contract of %", + N, Freeze_Id); + SPARK_Msg_N + ("\all constituents must be declared" & + " before body #", N); - raise Unrecoverable_Error; + -- A misplaced constituent is a critical error + -- because pragma Refined_Depends or + -- Refined_Global depends on the proper link + -- between a state and a constituent. Stop the + -- compilation, as this leads to a multitude of + -- misleading cascaded errors. + + raise Unrecoverable_Error; + end if; end if; -- The constituent is a valid state or object @@ -31452,10 +31756,10 @@ package body Sem_Prag is Errors := Serious_Errors_Detected; - -- Preanalyze_Assert_Expression, but without enforcing any of the - -- acceptable types. + -- Preanalyze_And_Resolve_Assert_Expression, but without enforcing + -- any of the acceptable types. - Preanalyze_Assert_Expression (Expr); + Preanalyze_And_Resolve_Assert_Expression (Expr); -- Expression of a discrete type is allowed. Nothing more to check -- for structural variants. @@ -31468,12 +31772,8 @@ package body Sem_Prag is -- Expression of a Big_Integer type (or its ghost variant) is only -- allowed in Decreases clause. - elsif - Is_RTE (Base_Type (Etype (Expr)), RE_Big_Integer) - or else - Is_RTE (Base_Type (Etype (Expr)), RO_GH_Big_Integer) - or else - Is_RTE (Base_Type (Etype (Expr)), RO_SP_Big_Integer) + elsif Is_RTE (Base_Type (Etype (Expr)), RE_Big_Integer) + or else Is_RTE (Base_Type (Etype (Expr)), RO_SP_Big_Integer) then if Chars (Direction) = Name_Increases then Error_Msg_N @@ -31633,7 +31933,7 @@ package body Sem_Prag is From_Aspect => True); if Present (Arg) then - Preanalyze_Assert_Expression + Preanalyze_And_Resolve_Assert_Expression (Expression (Arg), Standard_Boolean); end if; end if; @@ -31641,7 +31941,8 @@ package body Sem_Prag is Arg := Test_Case_Arg (N, Arg_Nam); if Present (Arg) then - Preanalyze_Assert_Expression (Expression (Arg), Standard_Boolean); + Preanalyze_And_Resolve_Assert_Expression + (Expression (Arg), Standard_Boolean); end if; end Preanalyze_Test_Case_Arg; @@ -33640,6 +33941,7 @@ package body Sem_Prag is Pragma_Profile => 0, Pragma_Profile_Warnings => 0, Pragma_Propagate_Exceptions => 0, + Pragma_Program_Exit => -1, Pragma_Provide_Shift_Operators => 0, Pragma_Psect_Object => 0, Pragma_Pure => 0, diff --git a/gcc/ada/sem_prag.ads b/gcc/ada/sem_prag.ads index 7c19d85386c3..9228a8774a5e 100644 --- a/gcc/ada/sem_prag.ads +++ b/gcc/ada/sem_prag.ads @@ -97,6 +97,7 @@ package Sem_Prag is Pragma_Preelaborable_Initialization => True, Pragma_Preelaborate => True, Pragma_Priority => True, + Pragma_Program_Exit => True, Pragma_Pure => True, Pragma_Pure_Function => True, Pragma_Refined_Depends => True, @@ -156,6 +157,7 @@ package Sem_Prag is Pragma_Pre_Class => True, Pragma_Precondition => True, Pragma_Predicate => True, + Pragma_Program_Exit => True, Pragma_Refined_Post => True, Pragma_Subprogram_Variant => True, Pragma_Test_Case => True, @@ -229,6 +231,7 @@ package Sem_Prag is Pragma_Pre => True, Pragma_Pre_Class => True, Pragma_Precondition => True, + Pragma_Program_Exit => True, Pragma_Pure => True, Pragma_Pure_Function => True, Pragma_Refined_Depends => True, @@ -326,6 +329,13 @@ package Sem_Prag is -- subprogram body which caused "freezing" of the related contract where -- the pragma resides. + procedure Analyze_Program_Exit_In_Decl_Part + (N : Node_Id; + Freeze_Id : Entity_Id := Empty); + -- Perform full analysis of delayed pragma Program_Exit. Freeze_Id is the + -- entity of [generic] package body or [generic] subprogram body which + -- caused "freezing" of the related contract where the pragma resides. + procedure Analyze_Refined_Depends_In_Decl_Part (N : Node_Id); -- Preform full analysis of delayed pragma Refined_Depends. This routine -- uses Analyze_Depends_In_Decl_Part as a starting point, then performs @@ -494,6 +504,7 @@ package Sem_Prag is -- Pre -- Pre_Class -- Precondition + -- Program_Exit -- Refined_Depends -- Refined_Global -- Refined_Post diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb index b73b947c9a25..29b776688023 100644 --- a/gcc/ada/sem_res.adb +++ b/gcc/ada/sem_res.adb @@ -757,14 +757,6 @@ package body Sem_Res is goto No_Danger; end if; - -- If the enclosing type is limited, we allocate only the - -- default value, not the maximum, and there is no need for - -- a warning. - - if Is_Limited_Type (Scope (Disc)) then - goto No_Danger; - end if; - -- Check that it is the high bound if N /= High_Bound (PN) @@ -811,11 +803,9 @@ package body Sem_Res is goto No_Danger; end if; - -- Warn about the danger - - Error_Msg_N - ("??creation of & object may raise Storage_Error!", - Scope (Disc)); + if Ekind (Scope (Disc)) = E_Record_Type then + Set_Is_Large_Unconstrained_Definite (Scope (Disc)); + end if; <<No_Danger>> null; @@ -2106,8 +2096,6 @@ package body Sem_Res is Full_Analysis := False; Expander_Mode_Save_And_Set (False); - -- See also Preanalyze_And_Resolve in sem.adb for similar handling - -- Normally, we suppress all checks for this preanalysis. There is no -- point in processing them now, since they will be applied properly -- and in the proper location when the default expressions reanalyzed @@ -2150,8 +2138,13 @@ package body Sem_Res is Full_Analysis := False; Expander_Mode_Save_And_Set (False); - Analyze (N); - Resolve (N, Etype (N), Suppress => All_Checks); + -- See previous version of Preanalyze_And_Resolve for similar handling + + if GNATprove_Mode then + Analyze_And_Resolve (N); + else + Analyze_And_Resolve (N, Suppress => All_Checks); + end if; Expander_Mode_Restore; Full_Analysis := Save_Full_Analysis; @@ -4849,6 +4842,7 @@ package body Sem_Res is if not Is_OK_Variable_For_Out_Formal (A) and then not Is_Init_Proc (Nam) + and then not Is_Expanded_Constructor_Call (N) then Error_Msg_NE ("actual for& must be a variable", A, F); @@ -6101,6 +6095,8 @@ package body Sem_Res is elsif Is_Fixed_Point_Type (It.Typ) then if Analyzed (N) then Error_Msg_N ("ambiguous operand in fixed operation", N); + elsif It.Typ = Any_Fixed then + Resolve (N, B_Typ); else Resolve (N, It.Typ); end if; @@ -7274,7 +7270,9 @@ package body Sem_Res is if Restriction_Check_Required (No_Relative_Delay) and then Is_RTE (Nam, RE_Set_Handler) - and then Is_RTE (Etype (Next_Actual (First_Actual (N))), RE_Time_Span) + and then + Is_RTE + (Base_Type (Etype (Next_Actual (First_Actual (N)))), RE_Time_Span) then Check_Restriction (No_Relative_Delay, N); end if; @@ -7801,6 +7799,7 @@ package body Sem_Res is then Set_Entity (N, Local); Set_Etype (N, Etype (Local)); + Generate_Reference (Local, N); end if; return OK; @@ -8150,6 +8149,7 @@ package body Sem_Res is and then not Preanalysis_Active and then not Is_Imported (E) and then Nkind (Parent (E)) /= N_Object_Renaming_Declaration + and then not Needs_Construction (Etype (E)) then if No_Initialization (Parent (E)) or else (Present (Full_View (E)) @@ -12465,16 +12465,6 @@ package body Sem_Res is Orig_N := Original_Node (Expression (Orig_N)); Orig_T := Target_Typ; - -- If the node is part of a larger expression, the Target_Type - -- may not be the original type of the node if the context is a - -- condition. Recover original type to see if conversion is needed. - - if Is_Boolean_Type (Orig_T) - and then Nkind (Parent (N)) in N_Op - then - Orig_T := Etype (Parent (N)); - end if; - -- If we have an entity name, then give the warning if the entity -- is the right type, or if it is a loop parameter covered by the -- original type (that's needed because loop parameters have an @@ -12550,6 +12540,16 @@ package body Sem_Res is then null; + -- Do not warn if original source-level conversion was + -- between two different types. + + elsif Nkind (Original_Node (N)) = N_Type_Conversion + and then + Base_Type (Etype (Subtype_Mark (Original_Node (N)))) + /= Base_Type (Etype (Expression (Original_Node (N)))) + then + null; + -- Here we give the redundant conversion warning. If it is an -- entity, give the name of the entity in the message. If not, -- just mention the expression. diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 0e1505bbdbe6..b2b4fed8c1e9 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -35,6 +35,7 @@ with Exp_Ch11; use Exp_Ch11; with Exp_Util; use Exp_Util; with Fname; use Fname; with Freeze; use Freeze; +with Ghost; use Ghost; with Itypes; use Itypes; with Lib; use Lib; with Lib.Xref; use Lib.Xref; @@ -52,6 +53,7 @@ with Sem_Attr; use Sem_Attr; with Sem_Cat; use Sem_Cat; with Sem_Ch6; use Sem_Ch6; with Sem_Ch8; use Sem_Ch8; +with Sem_Ch12; use Sem_Ch12; with Sem_Ch13; use Sem_Ch13; with Sem_Dim; use Sem_Dim; with Sem_Disp; use Sem_Disp; @@ -333,7 +335,7 @@ package body Sem_Util is -- Add_Global_Declaration -- ---------------------------- - procedure Add_Global_Declaration (N : Node_Id) is + procedure Add_Global_Declaration (Decl : Node_Id) is Aux_Node : constant Node_Id := Aux_Decls_Node (Cunit (Current_Sem_Unit)); begin @@ -341,8 +343,8 @@ package body Sem_Util is Set_Declarations (Aux_Node, New_List); end if; - Append_To (Declarations (Aux_Node), N); - Analyze (N); + Append_To (Declarations (Aux_Node), Decl); + Analyze (Decl); end Add_Global_Declaration; -------------------------------- @@ -1922,6 +1924,10 @@ package body Sem_Util is -- Build_Elaboration_Entity -- ------------------------------ + -- WARNING: This routine manages Ghost regions. Return statements must be + -- replaced by gotos which jump to the end of the routine and restore the + -- Ghost mode. + procedure Build_Elaboration_Entity (N : Node_Id; Spec_Id : Entity_Id) is Loc : constant Source_Ptr := Sloc (N); Decl : Node_Id; @@ -1955,6 +1961,12 @@ package body Sem_Util is end if; end Set_Package_Name; + -- Local variables + + Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; + Saved_IGR : constant Node_Id := Ignored_Ghost_Region; + -- Save the Ghost-related attributes to restore on exit + -- Start of processing for Build_Elaboration_Entity begin @@ -2002,6 +2014,11 @@ package body Sem_Util is return; end if; + -- Elaboration entity is never a ghost object, regardless of the context + -- in which this routine is called. + + Install_Ghost_Region (None, N); + -- Here we need the elaboration entity -- Construct name of elaboration entity as xxx_E, where xxx is the unit @@ -2042,6 +2059,8 @@ package body Sem_Util is Set_Has_Qualified_Name (Elab_Ent); Set_Has_Fully_Qualified_Name (Elab_Ent); + + Restore_Ghost_Region (Saved_GM, Saved_IGR); end Build_Elaboration_Entity; -------------------------------- @@ -2176,6 +2195,7 @@ package body Sem_Util is Def_Id : Entity_Id; Btyp : Entity_Id := Base_Type (Typ); + Predicated_Parent_Used : Boolean := False; begin -- The Related_Node better be here or else we won't be able to -- attach new itypes to a node in the tree. @@ -2190,6 +2210,25 @@ package body Sem_Util is and then Present (Underlying_Type (Btyp)) then Btyp := Underlying_Type (Btyp); + + -- If a predicate has been specified for an unconstrained + -- ancestor subtype, then that ancestor subtype needs to also + -- be an ancestor subtype for the subtype we are building so that + -- we don't lose the predicate. It is somewhat ugly here to have + -- to replicate the precondition for Predicated_Parent. + + elsif Typ in E_Array_Subtype_Id + | E_Record_Subtype_Id + | E_Record_Subtype_With_Private_Id + and then Present (Predicated_Parent (Typ)) + then + -- Assert that the following assignment is only changing the + -- subtype, not the type. + + pragma Assert (Base_Type (Predicated_Parent (Typ)) = Btyp); + + Btyp := Predicated_Parent (Typ); + Predicated_Parent_Used := True; end if; Indic := @@ -2211,7 +2250,10 @@ package body Sem_Util is Analyze (Subtyp_Decl, Suppress => All_Checks); - if Is_Itype (Def_Id) and then Has_Predicates (Typ) then + if Is_Itype (Def_Id) + and then Has_Predicates (Typ) + and then not Predicated_Parent_Used + then Inherit_Predicate_Flags (Def_Id, Typ); -- Indicate where the predicate function may be found @@ -2686,6 +2728,15 @@ package body Sem_Util is Append_Unique_Elmt (N, Identifiers_List); end if; + + -- Skip attribute references created by the compiler, typically + -- 'Constrained applied to one of the writable actuals, to avoid + -- spurious errors. + + elsif Nkind (N) = N_Attribute_Reference + and then not Comes_From_Source (N) + then + return Skip; end if; return OK; @@ -3025,7 +3076,7 @@ package body Sem_Util is -- For an array aggregate, a discrete_choice_list that has -- a nonstatic range is considered as two or more separate - -- occurrences of the expression (RM 6.4.1(20/3)). + -- occurrences of the expression (RM 6.4.1(6.20/3)). elsif Is_Array_Type (Etype (N)) and then Nkind (N) = N_Aggregate @@ -3110,48 +3161,105 @@ package body Sem_Util is end loop; end if; - -- Handle discrete associations + -- Handle named associations if Present (Component_Associations (N)) then Assoc := First (Component_Associations (N)); while Present (Assoc) loop - if not Box_Present (Assoc) then - Choice := First (Choices (Assoc)); - while Present (Choice) loop + Handle_Association : declare - -- For now we skip discriminants since it requires - -- performing the analysis in two phases: first one - -- analyzing discriminants and second one analyzing - -- the rest of components since discriminants are - -- evaluated prior to components: too much extra - -- work to detect a corner case??? + procedure Collect_Expression_Ids (Expr : Node_Id); + -- Collect identifiers in association expression Expr - if Nkind (Choice) in N_Has_Entity - and then Present (Entity (Choice)) - and then Ekind (Entity (Choice)) = E_Discriminant - then - null; + procedure Handle_Association_Choices + (Choices : List_Id; Expr : Node_Id); + -- Collect identifiers in an association expression + -- Expr for each choice in Choices. + + ---------------------------- + -- Collect_Expression_Ids -- + ---------------------------- - elsif Box_Present (Assoc) then - null; + procedure Collect_Expression_Ids (Expr : Node_Id) is + Comp_Expr : Node_Id; + begin + if not Analyzed (Expr) then + Comp_Expr := New_Copy_Tree (Expr); + Set_Parent (Comp_Expr, Parent (N)); + Preanalyze_Without_Errors (Comp_Expr); else - if not Analyzed (Expression (Assoc)) then - Comp_Expr := - New_Copy_Tree (Expression (Assoc)); - Set_Parent (Comp_Expr, Parent (N)); - Preanalyze_Without_Errors (Comp_Expr); + Comp_Expr := Expr; + end if; + + Collect_Identifiers (Comp_Expr); + end Collect_Expression_Ids; + + -------------------------------- + -- Handle_Association_Choices -- + -------------------------------- + + procedure Handle_Association_Choices + (Choices : List_Id; Expr : Node_Id) + is + Choice : Node_Id := First (Choices); + + begin + while Present (Choice) loop + + -- For now skip discriminants since it requires + -- performing analysis in two phases: first one + -- analyzing discriminants and second analyzing + -- the rest of components since discriminants + -- are evaluated prior to components: too much + -- extra work to detect a corner case??? + + if Nkind (Choice) in N_Has_Entity + and then Present (Entity (Choice)) + and then + Ekind (Entity (Choice)) = E_Discriminant + then + null; + else - Comp_Expr := Expression (Assoc); + Collect_Expression_Ids (Expr); end if; - Collect_Identifiers (Comp_Expr); - end if; + Next (Choice); + end loop; + end Handle_Association_Choices; - Next (Choice); - end loop; - end if; + begin + if not Box_Present (Assoc) then + if Nkind (Assoc) = N_Component_Association then + Handle_Association_Choices + (Choices (Assoc), Expression (Assoc)); + + elsif + Nkind (Assoc) = N_Iterated_Component_Association + and then Present (Defining_Identifier (Assoc)) + then + Handle_Association_Choices + (Discrete_Choices (Assoc), Expression (Assoc)); + + -- Nkind (Assoc) = N_Iterated_Component_Association + -- with iterator_specification, or + -- Nkind (Assoc) = N_Iterated_Element_Association + -- with loop_parameter_specification + -- or iterator_specification + -- + -- It seems that we might also need to deal with + -- iterable/iterator_names and iterator_filters + -- within iterator_specifications, and range bounds + -- within loop_parameter_specifications, but the + -- utility of doing that seems very low. ??? + + else + Collect_Expression_Ids (Expression (Assoc)); + end if; + end if; + end Handle_Association; Next (Assoc); end loop; @@ -3598,6 +3706,7 @@ package body Sem_Util is Aspect_Aggregate, Aspect_Max_Entry_Queue_Length -- , Aspect_No_Controlled_Parts + -- , Aspect_No_Task_Parts ); -- Note that none of these 8 aspects can be specified (for a type) @@ -5619,10 +5728,8 @@ package body Sem_Util is -- to start scanning from the incomplete view, which is earlier on -- the entity chain. - elsif Nkind (Parent (B_Type)) = N_Full_Type_Declaration - and then Present (Incomplete_View (Parent (B_Type))) - then - Id := Incomplete_View (Parent (B_Type)); + elsif Present (Incomplete_View (B_Type)) then + Id := Incomplete_View (B_Type); -- If T is a derived from a type with an incomplete view declared -- elsewhere, that incomplete view is irrelevant, we want the @@ -5662,6 +5769,7 @@ package body Sem_Util is or else Is_Primitive (Id)) and then Parent_Kind (Parent (Id)) not in N_Formal_Subprogram_Declaration + and then not Is_Child_Unit (Id) then Is_Prim := False; @@ -6578,6 +6686,30 @@ package body Sem_Util is return Is_Class_Wide_Type (Typ) or else Needs_Finalization (Typ); end CW_Or_Needs_Finalization; + ------------------------- + -- Default_Constructor -- + ------------------------- + + function Default_Constructor (Typ : Entity_Id) return Entity_Id is + Construct : Elmt_Id; + begin + pragma Assert (Is_Type (Typ)); + if No (Constructor_Name (Typ)) or else No (Constructor_List (Typ)) then + return Empty; + end if; + + Construct := First_Elmt (Constructor_List (Typ)); + while Present (Construct) loop + if Parameter_Count (Elists.Node (Construct)) = 1 then + return Elists.Node (Construct); + end if; + + Next_Elmt (Construct); + end loop; + + return Empty; + end Default_Constructor; + --------------------- -- Defining_Entity -- --------------------- @@ -7946,6 +8078,7 @@ package body Sem_Util is -- but the error should be posted on it, not on the component. elsif Ekind (E) = E_Discriminant + and then Is_Not_Self_Hidden (E) and then Present (Scope (Def_Id)) and then Scope (Def_Id) /= Current_Scope then @@ -7971,7 +8104,10 @@ package body Sem_Util is -- Avoid cascaded messages with duplicate components in -- derived types. - if Ekind (E) in E_Component | E_Discriminant then + if Ekind (E) = E_Component + or else (Ekind (E) = E_Discriminant + and then Is_Not_Self_Hidden (E)) + then return; end if; end if; @@ -8002,20 +8138,7 @@ package body Sem_Util is -- If we fall through, declaration is OK, at least OK enough to continue - -- If Def_Id is a discriminant or a record component we are in the midst - -- of inheriting components in a derived record definition. Preserve - -- their Ekind and Etype. - - if Ekind (Def_Id) in E_Discriminant | E_Component then - null; - - -- If a type is already set, leave it alone (happens when a type - -- declaration is reanalyzed following a call to the optimizer). - - elsif Present (Etype (Def_Id)) then - null; - - else + if No (Etype (Def_Id)) then Set_Etype (Def_Id, Any_Type); -- avoid cascaded errors end if; @@ -8063,12 +8186,20 @@ package body Sem_Util is loop Ren := Renamed_Object (Id); + -- The reference renames a function result. Check the original + -- node in case expansion relocates the function call. + + -- Ren : ... renames Func_Call; + + if Nkind (Original_Node (Ren)) = N_Function_Call then + exit; + -- The reference renames an abstract state or a whole object -- Obj : ...; -- Ren : ... renames Obj; - if Is_Entity_Name (Ren) then + elsif Is_Entity_Name (Ren) then -- Do not follow a renaming that goes through a generic formal, -- because these entities are hidden and must not be referenced @@ -8081,14 +8212,6 @@ package body Sem_Util is Id := Entity (Ren); end if; - -- The reference renames a function result. Check the original - -- node in case expansion relocates the function call. - - -- Ren : ... renames Func_Call; - - elsif Nkind (Original_Node (Ren)) = N_Function_Call then - exit; - -- Otherwise the reference renames something which does not yield -- an abstract state or a whole object. Treat the reference as not -- having a proper entity for SPARK legality purposes. @@ -8843,9 +8966,10 @@ package body Sem_Util is -------------------------- procedure Find_Overlaid_Entity - (N : Node_Id; - Ent : out Entity_Id; - Off : out Boolean) + (N : Node_Id; + Ent : out Entity_Id; + Ovrl_Typ : out Entity_Id; + Off : out Boolean) is pragma Assert (Nkind (N) = N_Attribute_Definition_Clause @@ -8867,8 +8991,9 @@ package body Sem_Util is -- In the second case, the expr is either Y'Address, or recursively a -- constant that eventually references Y'Address. - Ent := Empty; - Off := False; + Ent := Empty; + Ovrl_Typ := Empty; + Off := False; Expr := Expression (N); @@ -8898,6 +9023,8 @@ package body Sem_Util is end if; end loop; + Ovrl_Typ := Etype (Expr); + -- This loop checks the form of the prefix for an entity, using -- recursion to deal with intermediate components. @@ -8916,8 +9043,10 @@ package body Sem_Util is pragma Assert (not Expander_Active and then Is_Concurrent_Type (Scope (Ent))); - Ent := Empty; + Ent := Empty; + Ovrl_Typ := Empty; end if; + return; -- Check for components @@ -9933,16 +10062,19 @@ package body Sem_Util is and then not Has_Unknown_Discriminants (Utyp) and then not (Ekind (Utyp) = E_String_Literal_Subtype) then - -- Nothing to do if in spec expression (why not???) + -- If the type has no discriminants, there is no subtype to build, + -- even if the underlying type is discriminated. - if In_Spec_Expression then + if Is_Private_Type (Typ) and then not Has_Discriminants (Typ) then return Typ; - elsif Is_Private_Type (Typ) and then not Has_Discriminants (Typ) then - - -- If the type has no discriminants, there is no subtype to - -- build, even if the underlying type is discriminated. + -- If we are performing preanalysis on a conjured-up copy of a name + -- (see calls to Preanalyze_Range in sem_ch5.adb) then we don't want + -- to freeze Atyp, now or ever. In this case, the tree we eventually + -- pass to the back end should contain no references to Atyp (and a + -- freeze node would contain such a reference). + elsif not (Expander_Active or GNATprove_Mode) then return Typ; -- Else build the actual subtype @@ -9958,42 +10090,21 @@ package body Sem_Util is Atyp := Defining_Identifier (Decl); - -- If Build_Actual_Subtype generated a new declaration then use it - - if Atyp /= Typ then + -- The actual subtype is an Itype, so analyze the declaration + -- after attaching it to the tree, to get the type defined. - -- The actual subtype is an Itype, so analyze the declaration, - -- but do not attach it to the tree, to get the type defined. + Set_Parent (Decl, N); + Set_Is_Itype (Atyp); + Analyze (Decl, Suppress => All_Checks); + Set_Associated_Node_For_Itype (Atyp, N); - Set_Parent (Decl, N); - Set_Is_Itype (Atyp); - Analyze (Decl, Suppress => All_Checks); - Set_Associated_Node_For_Itype (Atyp, N); - if Expander_Active then - Set_Has_Delayed_Freeze (Atyp, False); + -- We need to freeze the actual subtype immediately. This is + -- needed because otherwise this Itype will not get frozen + -- at all; it is always safe to freeze on creation because + -- any associated types must be frozen at this point. - -- We need to freeze the actual subtype immediately. This is - -- needed because otherwise this Itype will not get frozen - -- at all; it is always safe to freeze on creation because - -- any associated types must be frozen at this point. - - -- On the other hand, if we are performing preanalysis on - -- a conjured-up copy of a name (see calls to - -- Preanalyze_Range in sem_ch5.adb) then we don't want - -- to freeze Atyp, now or ever. In this case, the tree - -- we eventually pass to the back end should contain no - -- references to Atyp (and a freeze node would contain - -- such a reference). That's why Expander_Active is tested. - - Freeze_Itype (Atyp, N); - end if; - return Atyp; - - -- Otherwise we did not build a declaration, so return original - - else - return Typ; - end if; + Freeze_Itype (Atyp, N); + return Atyp; end if; -- For all remaining cases, the actual subtype is the same as @@ -10152,63 +10263,69 @@ package body Sem_Util is Strval => String_From_Name_Buffer); end Get_Default_External_Name; - -------------------------- - -- Get_Enclosing_Object -- - -------------------------- + -------------------------------- + -- Get_Enclosing_Ghost_Entity -- + -------------------------------- - function Get_Enclosing_Object (N : Node_Id) return Entity_Id is + function Get_Enclosing_Ghost_Entity (N : Node_Id) return Entity_Id is begin if Is_Entity_Name (N) then return Entity (N); else case Nkind (N) is - when N_Indexed_Component + when N_Attribute_Reference + | N_Explicit_Dereference + | N_Indexed_Component | N_Selected_Component | N_Slice => - -- If not generating code, a dereference may be left implicit. - -- In thoses cases, return Empty. + return Get_Enclosing_Ghost_Entity (Prefix (N)); - if Is_Access_Type (Etype (Prefix (N))) then - return Empty; - else - return Get_Enclosing_Object (Prefix (N)); - end if; + when N_Function_Call => + return Get_Called_Entity (N); - when N_Type_Conversion => - return Get_Enclosing_Object (Expression (N)); + -- We are interested in the target type, because if it is ghost, + -- then the object is ghost as well and if it is non-ghost, then + -- its expression can't be ghost. + + when N_Qualified_Expression + | N_Type_Conversion + | N_Unchecked_Type_Conversion + => + return Entity (Subtype_Mark (N)); when others => return Empty; end case; end if; - end Get_Enclosing_Object; + end Get_Enclosing_Ghost_Entity; - ------------------------------- - -- Get_Enclosing_Deep_Object -- - ------------------------------- + -------------------------- + -- Get_Enclosing_Object -- + -------------------------- - function Get_Enclosing_Deep_Object (N : Node_Id) return Entity_Id is + function Get_Enclosing_Object (N : Node_Id) return Entity_Id is begin if Is_Entity_Name (N) then return Entity (N); else case Nkind (N) is - when N_Explicit_Dereference - | N_Indexed_Component + when N_Indexed_Component | N_Selected_Component | N_Slice => - return Get_Enclosing_Deep_Object (Prefix (N)); + return Get_Enclosing_Object (Prefix (N)); - when N_Type_Conversion => - return Get_Enclosing_Deep_Object (Expression (N)); + when N_Type_Conversion + | N_Unchecked_Type_Conversion + => + return Get_Enclosing_Object (Expression (N)); when others => return Empty; end case; end if; - end Get_Enclosing_Deep_Object; + end Get_Enclosing_Object; --------------------------- -- Get_Enum_Lit_From_Pos -- @@ -12368,9 +12485,14 @@ package body Sem_Util is while Present (Node) loop case Nkind (Node) is - when N_Null_Statement | N_Call_Marker | N_Raise_xxx_Error => + when N_Null_Statement | N_Call_Marker => null; + when N_Raise_xxx_Error => + if Comes_From_Source (Node) then + return False; + end if; + when N_Object_Declaration => if Present (Expression (Node)) and then not Side_Effect_Free (Expression (Node)) @@ -12717,6 +12839,150 @@ package body Sem_Util is return False; end Has_Overriding_Initialize; + ----------------------------- + -- Has_Potentially_Invalid -- + ----------------------------- + + function Has_Potentially_Invalid (E : Entity_Id) return Boolean is + + function Denotes_Invalid_Parameter + (Expr : Node_Id; + Param : Entity_Id) + return Boolean; + -- Returns True iff expression Expr denotes a formal parameter or + -- function Param (through its attribute Result). + + ------------------------------- + -- Denotes_Invalid_Parameter -- + ------------------------------- + + function Denotes_Invalid_Parameter + (Expr : Node_Id; + Param : Entity_Id) return Boolean is + begin + if Nkind (Expr) in N_Identifier | N_Expanded_Name then + return Entity (Expr) = Param; + else + pragma Assert (Is_Attribute_Result (Expr)); + return Entity (Prefix (Expr)) = Param; + end if; + end Denotes_Invalid_Parameter; + + -- Start of processing for Has_Potentially_Invalid + + begin + -- When analyzing, we checked all syntax legality rules for the aspect + -- Potentially_Invalid, but didn't store the property anywhere (e.g. as + -- an Einfo flag). To query the property we look directly at the AST, + -- but now without any syntactic checks. + + case Ekind (E) is + -- Constants have this aspect attached directly; for deferred + -- constants, the aspect is attached to the partial view. + + when E_Constant => + return Has_Aspect (E, Aspect_Potentially_Invalid); + + -- Variables have this aspect attached directly + + when E_Variable => + return Has_Aspect (E, Aspect_Potentially_Invalid); + + when Formal_Kind + | E_Function + => + -- Instances of Ada.Unchecked_Conversion is a special case. Look + -- for the aspect on the generic instance. The aspect necessarily + -- applies to the function result. + + if Is_Unchecked_Conversion_Instance (E) then + declare + Wrapper_Pkg : constant Node_Id := + Defining_Unit_Name (Parent (Subprogram_Spec (E))); + pragma Assert (Is_Wrapper_Package (Wrapper_Pkg)); + Instance : constant Entity_Id := Defining_Unit_Name + (Get_Unit_Instantiation_Node (Wrapper_Pkg)); + begin + return Has_Aspect (Instance, Aspect_Potentially_Invalid); + end; + end if; + + -- Formal parameters and functions have the Potentially_Invalid + -- aspect attached to the subprogram entity and must be listed in + -- the aspect expression. + + declare + Subp_Id : Entity_Id; + Aspect_Expr : Node_Id; + Param_Expr : Node_Id; + Assoc : Node_Id; + + begin + if Is_Formal (E) then + Subp_Id := Scope (E); + else + Subp_Id := E; + end if; + + if Has_Aspect (Subp_Id, Aspect_Potentially_Invalid) then + Aspect_Expr := + Find_Value_Of_Aspect + (Subp_Id, Aspect_Potentially_Invalid); + + -- Aspect expression is either an aggregate with an optional + -- Boolean expression (which defaults to True), e.g.: + -- + -- function F (X : Integer) return Integer + -- with Potentially_Invalid => (X => True, F'Result); + + if Nkind (Aspect_Expr) = N_Aggregate then + + if Present (Component_Associations (Aspect_Expr)) then + Assoc := First (Component_Associations (Aspect_Expr)); + + while Present (Assoc) loop + if Denotes_Invalid_Parameter + (First (Choices (Assoc)), E) + then + return + Is_True + (Static_Boolean (Expression (Assoc))); + end if; + + Next (Assoc); + end loop; + end if; + + Param_Expr := First (Expressions (Aspect_Expr)); + + while Present (Param_Expr) loop + if Denotes_Invalid_Parameter (Param_Expr, E) then + return True; + end if; + + Next (Param_Expr); + end loop; + + return False; + + -- or it is a single identifier, e.g.: + -- + -- function F (X : Integer) return Integer + -- with Potentially_Invalid => X; + + else + return Denotes_Invalid_Parameter (Aspect_Expr, E); + end if; + else + return False; + end if; + end; + + when others => + raise Program_Error; + end case; + end Has_Potentially_Invalid; + -------------------------------------- -- Has_Preelaborable_Initialization -- -------------------------------------- @@ -14752,6 +15018,7 @@ package body Sem_Util is | Aspect_Iterator_Element | Aspect_Max_Entry_Queue_Length | Aspect_No_Controlled_Parts + | Aspect_No_Task_Parts => return; end case; @@ -16011,8 +16278,9 @@ package body Sem_Util is Names_Match (Assign_Indexed_1, Assign_Indexed_2); end; - -- Checking for this aspect is performed elsewhere during freezing - when Aspect_No_Controlled_Parts => + -- Checking for these aspects is performed elsewhere during freezing + when Aspect_No_Controlled_Parts + | Aspect_No_Task_Parts => return True; -- scalar-valued aspects; compare (static) values. @@ -17815,6 +18083,27 @@ package body Sem_Util is return Nkind (Spec_Decl) in N_Generic_Declaration; end Is_Generic_Declaration_Or_Body; + -------------------------- + -- Is_In_Context_Clause -- + -------------------------- + + function Is_In_Context_Clause (N : Node_Id) return Boolean is + Plist : List_Id; + Parent_Node : Node_Id; + + begin + if Is_List_Member (N) then + Plist := List_Containing (N); + Parent_Node := Parent (Plist); + + return Present (Parent_Node) + and then Nkind (Parent_Node) = N_Compilation_Unit + and then Context_Items (Parent_Node) = Plist; + end if; + + return False; + end Is_In_Context_Clause; + --------------------------- -- Is_Independent_Object -- --------------------------- @@ -18276,6 +18565,7 @@ package body Sem_Util is case Nkind (N) is when N_Indexed_Component + | N_Selected_Component | N_Slice => return @@ -18287,13 +18577,6 @@ package body Sem_Util is when N_Attribute_Reference => return Attribute_Name (N) in Name_Input | Name_Old | Name_Result; - when N_Selected_Component => - return - Is_Name_Reference (Selector_Name (N)) - and then - (Is_Name_Reference (Prefix (N)) - or else Is_Access_Type (Etype (Prefix (N)))); - when N_Explicit_Dereference => return True; @@ -20863,6 +21146,7 @@ package body Sem_Util is or else Nam = Name_Pre or else Nam = Name_Pre_Class or else Nam = Name_Precondition + or else Nam = Name_Program_Exit or else Nam = Name_Refined_Depends or else Nam = Name_Refined_Global or else Nam = Name_Refined_Post @@ -21092,6 +21376,18 @@ package body Sem_Util is return False; end Is_Unchecked_Conversion_Instance; + --------------------------------- + -- Is_Unchecked_Union_Equality -- + --------------------------------- + + function Is_Unchecked_Union_Equality (Id : Entity_Id) return Boolean is + begin + return Ekind (Id) = E_Function + and then Present (First_Formal (Id)) + and then Is_Unchecked_Union (Etype (First_Formal (Id))) + and then Id = TSS (Etype (First_Formal (Id)), TSS_Composite_Equality); + end Is_Unchecked_Union_Equality; + ------------------------------- -- Is_Universal_Numeric_Type -- ------------------------------- @@ -21800,7 +22096,7 @@ package body Sem_Util is Set_Last_Assignment (Ent, Empty); end if; - if Is_Object (Ent) then + if Is_Object (Ent) and then Ekind (Ent) not in Record_Field_Kind then if not Last_Assignment_Only then Kill_Checks (Ent); Set_Current_Value (Ent, Empty); @@ -21876,20 +22172,6 @@ package body Sem_Util is end loop Scope_Loop; end Kill_Current_Values; - -------------------------- - -- Kill_Size_Check_Code -- - -------------------------- - - procedure Kill_Size_Check_Code (E : Entity_Id) is - begin - if (Ekind (E) = E_Constant or else Ekind (E) = E_Variable) - and then Present (Size_Check_Code (E)) - then - Remove (Size_Check_Code (E)); - Set_Size_Check_Code (E, Empty); - end if; - end Kill_Size_Check_Code; - -------------------- -- Known_Non_Null -- -------------------- @@ -23078,11 +23360,6 @@ package body Sem_Util is then return True; - -- Mutably tagged types require default initialization - - elsif Is_Mutably_Tagged_CW_Equivalent_Type (Typ) then - return True; - -- If Initialize/Normalize_Scalars is in effect, string objects also -- need initialization, unless they are created in the course of -- expanding an aggregate (since in the latter case they will be @@ -23850,7 +24127,7 @@ package body Sem_Util is Result := N; - if N > Empty_Or_Error then + if N not in Empty | Error then pragma Assert (Nkind (N) not in N_Entity); Result := New_Copy (N); @@ -23931,7 +24208,7 @@ package body Sem_Util is Result := Id; - if Id > Empty_Or_Error then + if Id not in Empty | Error then pragma Assert (Nkind (Id) in N_Entity); -- Determine whether the entity has a corresponding new entity @@ -24045,7 +24322,9 @@ package body Sem_Util is Next (Old_Act); end loop; - pragma Assert (Replaced); + if Nkind (Old_Call) /= N_Function_Call then + pragma Assert (Replaced); + end if; end Update_Controlling_Argument; ------------------------------- @@ -24902,7 +25181,7 @@ package body Sem_Util is -- In case of a call rewritten in GNATprove mode while "inlining -- for proof" go to the original call. - elsif Nkind (Par) = N_Null_Statement then + elsif Nkind (Par) in N_Null_Statement | N_Block_Statement then pragma Assert (GNATprove_Mode and then @@ -25336,6 +25615,8 @@ package body Sem_Util is end if; if Nkind (P) = N_Selected_Component + -- and then Ekind (Entity (Selector_Name (P))) + -- in Record_Field_Kind and then Present (Entry_Formal (Entity (Selector_Name (P)))) then -- Case of a reference to an entry formal @@ -25498,16 +25779,18 @@ package body Sem_Util is if Sure and then Modification_Comes_From_Source + and then Ekind (Ent) in E_Constant | E_Variable and then Overlays_Constant (Ent) and then Address_Clause_Overlay_Warnings then declare Addr : constant Node_Id := Address_Clause (Ent); O_Ent : Entity_Id; + O_Typ : Entity_Id; Off : Boolean; begin - Find_Overlaid_Entity (Addr, O_Ent, Off); + Find_Overlaid_Entity (Addr, O_Ent, O_Typ, Off); Error_Msg_Sloc := Sloc (Addr); Error_Msg_NE @@ -26066,6 +26349,24 @@ package body Sem_Util is return Empty; end Param_Entity; + --------------------- + -- Parameter_Count -- + --------------------- + + function Parameter_Count (Subp : Entity_Id) return Nat is + Result : Nat := 0; + Param : Entity_Id; + begin + Param := First_Entity (Subp); + while Present (Param) loop + Result := Result + 1; + + Param := Next_Entity (Param); + end loop; + + return Result; + end Parameter_Count; + ---------------------- -- Policy_In_Effect -- ---------------------- @@ -26669,6 +26970,10 @@ package body Sem_Util is if Has_Relaxed_Finalization (From_Typ) then Set_Has_Relaxed_Finalization (Typ); end if; + + if Deriv and then Has_Destructor (From_Typ) then + Set_Has_Destructor (Typ); + end if; end Propagate_Controlled_Flags; ------------------------------ @@ -28409,12 +28714,6 @@ package body Sem_Util is return False; end if; - if Ekind (Entity (Selector_Name (N))) not in - E_Component | E_Discriminant - then - return False; - end if; - declare Comp : constant Entity_Id := Original_Record_Component (Entity (Selector_Name (N))); @@ -28937,9 +29236,10 @@ package body Sem_Util is ------------------------------ function Ultimate_Overlaid_Entity (E : Entity_Id) return Entity_Id is - Address : Node_Id; - Alias : Entity_Id := E; - Offset : Boolean; + Address : Node_Id; + Alias : Entity_Id := E; + Offset : Boolean; + Ovrl_Typ : Entity_Id; begin -- Currently this routine is only called for stand-alone objects that @@ -28951,7 +29251,7 @@ package body Sem_Util is loop Address := Address_Clause (Alias); if Present (Address) then - Find_Overlaid_Entity (Address, Alias, Offset); + Find_Overlaid_Entity (Address, Alias, Ovrl_Typ, Offset); if Present (Alias) then null; else diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads index fd749c4b8d41..4554f2423e19 100644 --- a/gcc/ada/sem_util.ads +++ b/gcc/ada/sem_util.ads @@ -54,12 +54,12 @@ package Sem_Util is -- Add A to the list of access types to process when expanding the -- freeze node of E. - procedure Add_Global_Declaration (N : Node_Id); - -- These procedures adds a declaration N at the library level, to be + procedure Add_Global_Declaration (Decl : Node_Id); + -- This procedure adds a declaration Decl at the library level, to be -- elaborated before any other code in the unit. It is used for example -- for the entity that marks whether a unit has been elaborated. The -- declaration is added to the Declarations list of the Aux_Decls_Node - -- for the current unit. The declarations are added in the current scope, + -- for the current unit. The declared entity is added to current scope, -- so the caller should push a new scope as required before the call. function Add_Suffix (E : Entity_Id; Suffix : Character) return Name_Id; @@ -619,7 +619,21 @@ package Sem_Util is -- Find whether there is a previous definition for name or identifier N in -- the current scope. Because declarations for a scope are not necessarily -- contiguous (e.g. for packages) the first entry on the visibility chain - -- for N is not necessarily in the current scope. + -- for N is not necessarily in the current scope. Take, for example: + -- + -- package P is + -- X : constant := 13; + -- + -- package Q is + -- X : constant := 67; + -- end Q; + -- + -- Y : constant := X; + -- end P; + -- + -- When the declaration of Y is analyzed, the first entry on the visibility + -- chain is the X equal to 67, but Current_Entity_In_Scope returns the X + -- equal to 13. function Current_Scope return Entity_Id; -- Get entity representing current scope @@ -647,6 +661,10 @@ package Sem_Util is -- as Needs_Finalization except with pragma Restrictions (No_Finalization), -- in which case we know that class-wide objects do not need finalization. + function Default_Constructor (Typ : Entity_Id) return Entity_Id; + -- Determine the default constructor (e.g. the constructor with only one + -- formal parameter) for a given type Typ. + function Defining_Entity (N : Node_Id) return Entity_Id; -- Given a declaration N, returns the associated defining entity. If the -- declaration has a specification, the entity is obtained from the @@ -880,14 +898,18 @@ package Sem_Util is -- loop are nested within the block. procedure Find_Overlaid_Entity - (N : Node_Id; - Ent : out Entity_Id; - Off : out Boolean); + (N : Node_Id; + Ent : out Entity_Id; + Ovrl_Typ : out Entity_Id; + Off : out Boolean); -- The node N should be an address representation clause. Determines if the -- target expression is the address of an entity with an optional offset. -- If so, set Ent to the entity and, if there is an offset, set Off to -- True, otherwise to False. If it is not possible to determine that the -- address is of this form, then set Ent to Empty. + -- Ovrl_Typ is set to the type being overlaid and can be different than the + -- type of Ent, for example when the address clause is applied to a record + -- component or to an element of an array. function Find_Parameter_Type (Param : Node_Id) return Entity_Id; -- Return the type of formal parameter Param as determined by its @@ -1117,15 +1139,27 @@ package Sem_Util is -- identifier provided as the external name. Letters in the name are -- according to the setting of Opt.External_Name_Default_Casing. + function Get_Enclosing_Ghost_Entity (N : Node_Id) return Entity_Id; + -- If expression N references a name of either an object or of a + -- subprogram, then return its outermost entity that determines + -- whether this name denotes a ghost object. + function Get_Enclosing_Object (N : Node_Id) return Entity_Id; -- If expression N references a part of an object, return this object. -- Otherwise return Empty. Expression N should have been resolved already. - function Get_Enclosing_Deep_Object (N : Node_Id) return Entity_Id; - -- If expression N references a reachable part of an object (as defined in - -- SPARK RM 6.9), return this object. Otherwise return Empty. It is similar - -- to Get_Enclosing_Object, but treats pointer dereference like component - -- selection. Expression N should have been resolved already. + function Get_Enum_Lit_From_Pos + (T : Entity_Id; + Pos : Uint; + Loc : Source_Ptr) return Node_Id; + -- This function returns an identifier denoting the E_Enumeration_Literal + -- entity for the specified value from the enumeration type or subtype T. + -- The second argument is the Pos value. Constraint_Error is raised if + -- argument Pos is not in range. The third argument supplies a source + -- location for constructed nodes returned by this function. If No_Location + -- is supplied as source location, the location of the returned node is + -- copied from the original source location for the enumeration literal, + -- when available. function Get_Generic_Entity (N : Node_Id) return Entity_Id; -- Returns the true generic entity in an instantiation. If the name in the @@ -1192,19 +1226,6 @@ package Sem_Util is -- When flag Do_Checks is set, this routine will flag duplicate uses of -- aspects. - function Get_Enum_Lit_From_Pos - (T : Entity_Id; - Pos : Uint; - Loc : Source_Ptr) return Node_Id; - -- This function returns an identifier denoting the E_Enumeration_Literal - -- entity for the specified value from the enumeration type or subtype T. - -- The second argument is the Pos value. Constraint_Error is raised if - -- argument Pos is not in range. The third argument supplies a source - -- location for constructed nodes returned by this function. If No_Location - -- is supplied as source location, the location of the returned node is - -- copied from the original source location for the enumeration literal, - -- when available. - function Get_Iterable_Type_Primitive (Typ : Entity_Id; Nam : Name_Id) return Entity_Id; @@ -1500,6 +1521,12 @@ package Sem_Util is -- non-null), which causes the type to not have preelaborable -- initialization. + function Has_Potentially_Invalid (E : Entity_Id) return Boolean; + -- Returns True iff entity E is subject to the Potentially_Invalid aspect. + -- Entity E can be either variable, constant, subprogram or entry. For + -- private types and deferred constants E should be the private view, + -- because aspect can only be attached there. + function Has_Preelaborable_Initialization (E : Entity_Id; Preelab_Init_Expr : Node_Id := Empty) return Boolean; @@ -1551,7 +1578,7 @@ package Sem_Util is -- underlying type). function Has_Suffix (E : Entity_Id; Suffix : Character) return Boolean; - -- Returns true if the last character of E is Suffix. Used in Assertions. + -- Returns true if the last character of E is Suffix. function Has_Tagged_Component (Typ : Entity_Id) return Boolean; -- Returns True if Typ is a composite type (array or record) that is either @@ -2095,12 +2122,16 @@ package Sem_Util is -- Determine whether arbitrary declaration Decl denotes a generic package, -- a generic subprogram or a generic body. + function Is_In_Context_Clause (N : Node_Id) return Boolean; + -- Returns True if N appears within the context clause of a unit, and False + -- for any other placement. + function Is_Independent_Object (N : Node_Id) return Boolean; -- Determine whether arbitrary node N denotes a reference to an independent -- object as per RM C.6(8). function Is_Inherited_Operation (E : Entity_Id) return Boolean; - -- E is a subprogram. Return True is E is an implicit operation inherited + -- E is a subprogram. Return True if E is an implicit operation inherited -- by a derived type declaration. function Is_Inlinable_Expression_Function (Subp : Entity_Id) return Boolean; @@ -2165,7 +2196,7 @@ package Sem_Util is -- the encapsulated expression is nontrivial. function Is_Null_Extension - (T : Entity_Id; Ignore_Privacy : Boolean := False) return Boolean; + (T : Entity_Id; Ignore_Privacy : Boolean := False) return Boolean; -- Given a tagged type, returns True if argument is a type extension -- that introduces no new components (discriminant or nondiscriminant). -- Ignore_Privacy should be True for use in implementing dynamic semantics. @@ -2377,6 +2408,7 @@ package Sem_Util is -- Pre -- Pre_Class -- Precondition + -- Program_Exit -- Refined_Depends -- Refined_Global -- Refined_Post @@ -2417,15 +2449,19 @@ package Sem_Util is -- Determine whether an arbitrary entity denotes an instance of function -- Ada.Unchecked_Conversion. - function Is_Universal_Numeric_Type (T : Entity_Id) return Boolean; - pragma Inline (Is_Universal_Numeric_Type); - -- True if T is Universal_Integer or Universal_Real + function Is_Unchecked_Union_Equality (Id : Entity_Id) return Boolean; + -- Determine whether an arbitrary entity denotes the predefined equality + -- function of an Unchecked_Union type (see Build_Variant_Record_Equality). function Is_Unconstrained_Or_Tagged_Item (Item : Entity_Id) return Boolean; -- Subsidiary to Collect_Subprogram_Inputs_Outputs and the analysis of -- pragma Depends. Determine whether the type of dependency item Item is -- tagged, unconstrained array or unconstrained record. + function Is_Universal_Numeric_Type (T : Entity_Id) return Boolean; + pragma Inline (Is_Universal_Numeric_Type); + -- True if T is Universal_Integer or Universal_Real + function Is_User_Defined_Equality (Id : Entity_Id) return Boolean; -- Determine whether an entity denotes a user-defined equality @@ -2536,12 +2572,6 @@ package Sem_Util is -- if the entity Ent is not for an object. Last_Assignment_Only has the -- same meaning as for the call with no Ent. - procedure Kill_Size_Check_Code (E : Entity_Id); - -- Called when an address clause or pragma Import is applied to an entity. - -- If the entity is a variable or a constant, and size check code is - -- present, this size check code is killed, since the object will not be - -- allocated by the program. - function Known_Non_Null (N : Node_Id) return Boolean; -- Given a node N for a subexpression of an access type, determines if -- this subexpression yields a value that is known at compile time to @@ -2862,6 +2892,9 @@ package Sem_Util is -- WARNING: this routine should be used in debugging scenarios such as -- tracking down undefined symbols as it is fairly low level. + function Parameter_Count (Subp : Entity_Id) return Nat; + -- Return the number of parameters for a given subprogram Subp. + function Param_Entity (N : Node_Id) return Entity_Id; -- Given an expression N, determines if the expression is a reference -- to a formal (of a subprogram or entry), and if so returns the Id @@ -2944,11 +2977,11 @@ package Sem_Util is Comp : Boolean := False; Deriv : Boolean := False); -- Set Disable_Controlled, Finalize_Storage_Only, Has_Controlled_Component, - -- Has_Relaxed_Finalization, and Is_Controlled_Active on Typ when the flags - -- are set on From_Typ. If Comp is True, From_Typ is assumed to be the type - -- of a component of Typ while, if Deriv is True, From_Typ is assumed to be - -- the parent type of Typ. This procedure can only set flags for Typ, and - -- never clear them. + -- Has_Destructor, Has_Relaxed_Finalization, and Is_Controlled_Active on + -- Typ when the flags are set on From_Typ. If Comp is True, From_Typ is + -- assumed to be the type of a component of Typ while, if Deriv is True, + -- From_Typ is assumed to be the parent type of Typ. This procedure can + -- only set flags for Typ, and never clear them. procedure Propagate_DIC_Attributes (Typ : Entity_Id; diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb index 35ef61664723..156afc923075 100644 --- a/gcc/ada/sem_warn.adb +++ b/gcc/ada/sem_warn.adb @@ -1712,17 +1712,11 @@ package body Sem_Warn is and then Ekind (E1) /= E_Class_Wide_Type - -- Objects other than parameters of task types are allowed to - -- be non-referenced, since they start up tasks. + -- Objects that are not parameters and whose types have tasks + -- are allowed to be non-referenced since they start up tasks. - and then ((Ekind (E1) /= E_Variable - and then Ekind (E1) /= E_Constant - and then Ekind (E1) /= E_Component) - - -- Check that E1T is not a task or a composite type - -- with a task component. - - or else not Has_Task (E1T)) + and then not (Ekind (E1) in E_Variable | E_Constant | E_Component + and then Has_Task (E1T)) -- For subunits, only place warnings on the main unit itself, -- since parent units are not completely compiled. @@ -3470,6 +3464,24 @@ package body Sem_Warn is end if; end Warn_On_Constant_Valid_Condition; + --------------------------------------- + -- Warn_On_Ignored_Equality_Operator -- + --------------------------------------- + + procedure Warn_On_Ignored_Equality_Operator + (Typ : Entity_Id; + Comp_Typ : Entity_Id; + Loc : Source_Ptr) is + begin + if Warn_On_Ignored_Equality then + Error_Msg_Node_2 := Comp_Typ; + Error_Msg_N ("?_q?""="" for type & uses predefined ""="" for }", Typ); + + Error_Msg_Sloc := Loc; + Error_Msg_N ("\?_q?""="" # is ignored here", Typ); + end if; + end Warn_On_Ignored_Equality_Operator; + ----------------------------- -- Warn_On_Known_Condition -- ----------------------------- @@ -4670,9 +4682,11 @@ package body Sem_Warn is if Nkind (Parent (LA)) in N_Procedure_Call_Statement | N_Parameter_Association then - Error_Msg_NE - ("?m?& modified by call, but value overwritten #!", - LA, Ent); + if Warn_On_All_Unread_Out_Parameters then + Error_Msg_NE + ("?m?& modified by call, but value overwritten #!", + LA, Ent); + end if; else Error_Msg_NE -- CODEFIX ("?m?useless assignment to&, value overwritten #!", @@ -4747,7 +4761,7 @@ package body Sem_Warn is Ent : Entity_Id; begin - if Warn_On_Modified_Unread + if (Warn_On_Modified_Unread or Warn_On_All_Unread_Out_Parameters) and then In_Extended_Main_Source_Unit (E) then Ent := First_Entity (E); diff --git a/gcc/ada/sem_warn.ads b/gcc/ada/sem_warn.ads index edb872f3d976..3a347efa4b58 100644 --- a/gcc/ada/sem_warn.ads +++ b/gcc/ada/sem_warn.ads @@ -173,6 +173,15 @@ package Sem_Warn is -- Op assuming that its scalar operands are valid. Emit a warning when the -- result of the evaluation is True or False. + procedure Warn_On_Ignored_Equality_Operator + (Typ : Entity_Id; + Comp_Typ : Entity_Id; + Loc : Source_Ptr); + -- Typ is a composite type and Comp_Typ is the type of one of its + -- components. Output a warning notifying that the predefined "=" + -- for Comp_Typ takes precedence over the user-defined equality + -- defined at the given location. + procedure Warn_On_Known_Condition (C : Node_Id); -- C is a node for a boolean expression resulting from a relational -- or membership operation. If the expression has a compile time known diff --git a/gcc/ada/set_targ.ads b/gcc/ada/set_targ.ads index b2e598fbb96b..e465c3ff5a15 100644 --- a/gcc/ada/set_targ.ads +++ b/gcc/ada/set_targ.ads @@ -93,7 +93,7 @@ package Set_Targ is type FPT_Mode_Entry is record NAME : String_Ptr; -- Name of mode (no null character at end) - DIGS : Natural; -- Digits for floating-point type + DIGS : Positive; -- Digits for floating-point type FLOAT_REP : Float_Rep_Kind; -- Float representation PRECISION : Natural; -- Precision in bits SIZE : Natural; -- Size in bits diff --git a/gcc/ada/sfn_scan.adb b/gcc/ada/sfn_scan.adb index d96a5e9f914f..a0f26aa5fe3d 100644 --- a/gcc/ada/sfn_scan.adb +++ b/gcc/ada/sfn_scan.adb @@ -261,8 +261,6 @@ package body SFN_Scan is if At_EOF then Error ("unexpected end of file"); end if; - - return; end Check_Not_At_EOF; ----------------- diff --git a/gcc/ada/sinfo-utils.adb b/gcc/ada/sinfo-utils.adb index 184bb08db12a..d2e78a3b4b73 100644 --- a/gcc/ada/sinfo-utils.adb +++ b/gcc/ada/sinfo-utils.adb @@ -347,6 +347,19 @@ package body Sinfo.Utils is end if; end Get_Pragma_Arg; + ----------------------- + -- Loop_Flow_Keyword -- + ----------------------- + + function Loop_Flow_Keyword (N : N_Loop_Flow_Statement_Id) return String is + begin + case Nkind (N) is + when N_Continue_Statement => return "continue"; + when N_Exit_Statement => return "exit"; + when others => pragma Assert (False); + end case; + end Loop_Flow_Keyword; + procedure Destroy_Element (Elem : in out Union_Id); -- Does not do anything but is used to instantiate -- GNAT.Lists.Doubly_Linked_Lists. diff --git a/gcc/ada/sinfo-utils.ads b/gcc/ada/sinfo-utils.ads index 0e7399e08b79..3ef85e6926d3 100644 --- a/gcc/ada/sinfo-utils.ads +++ b/gcc/ada/sinfo-utils.ads @@ -137,6 +137,10 @@ package Sinfo.Utils is -- for the argument. This is Arg itself, or, in the case where Arg is a -- pragma argument association node, the expression from this node. + function Loop_Flow_Keyword (N : N_Loop_Flow_Statement_Id) return String; + -- Returns the keyword corresponding to N as a string, for use in + -- diagnostics. + function Lowest_Common_Ancestor (N1, N2 : Node_Id) return Union_Id; -- Returns the list or node that is the lowest common ancestor of N1 and -- N2 in the syntax tree. diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads index d22f1030d427..3d11d5c5aa67 100644 --- a/gcc/ada/sinfo.ads +++ b/gcc/ada/sinfo.ads @@ -402,16 +402,17 @@ package Sinfo is -- Has_Secondary_Private_View set in generic units -- "plus fields for expression" - -- Paren_Count number of parentheses levels - -- Etype type of the expression - -- Is_Overloaded >1 type interpretation exists - -- Is_Static_Expression set for static expression - -- Raises_Constraint_Error evaluation raises CE - -- Must_Not_Freeze set if must not freeze - -- Do_Range_Check set if a range check needed - -- Has_Dynamic_Length_Check set if length check inserted - -- Assignment_OK set if modification is OK - -- Is_Controlling_Actual set for controlling argument + -- Paren_Count number of parentheses levels + -- Etype type of the expression + -- Is_Overloaded >1 type interpretation exists + -- Is_Static_Expression set for static expression + -- Raises_Constraint_Error evaluation raises CE + -- Must_Not_Freeze set if must not freeze + -- Do_Range_Check set if a range check needed + -- Has_Dynamic_Length_Check set if length check inserted + -- Assignment_OK set if modification is OK + -- Is_Controlling_Actual set for controlling argument + -- Is_Expanded_Dispatching_Call set for expanded dispatching calls -- Note: see under (EXPRESSION) for further details on the use of -- the Paren_Count field to record the number of parentheses levels. @@ -737,14 +738,6 @@ package Sinfo is -- section describes the usage of the semantic fields, which are used to -- contain additional information determined during semantic analysis. - -- Accept_Handler_Records - -- This field is present only in an N_Accept_Alternative node. It is used - -- to temporarily hold the exception handler records from an accept - -- statement in a selective accept. These exception handlers will - -- eventually be placed in the Handler_Records list of the procedure - -- built for this accept (see Expand_N_Selective_Accept procedure in - -- Exp_Ch9 for further details). - -- Access_Types_To_Process -- Present in N_Freeze_Entity nodes for Incomplete or private types. -- Contains the list of access types which may require specific treatment @@ -1515,11 +1508,6 @@ package Sinfo is -- range is given by the programmer, even if that range is identical to -- the range for Float. - -- Incomplete_View - -- Present in full type declarations that are completions of incomplete - -- type declarations. Denotes the corresponding incomplete view declared - -- by the incomplete declaration. - -- Inherited_Discriminant -- This flag is present in N_Component_Association nodes. It indicates -- that a given component association in an extension aggregate is the @@ -1677,6 +1665,10 @@ package Sinfo is -- actuals to support a build-in-place style of call have been added to -- the call. + -- Is_Expanded_Dispatching_Call + -- This flag is set in N_Block_Statement, and expression nodes to + -- indicate that it is an expanded dispatching call. + -- Is_Expanded_Prefixed_Call -- This flag is set in N_Function_Call and N_Procedure_Call_Statement -- nodes to indicate that it is an expanded prefixed call. @@ -1701,6 +1693,7 @@ package Sinfo is -- Pre -- Pre_Class -- Precondition + -- Program_Exit -- Refined_Depends -- Refined_Global -- Refined_Post @@ -2324,6 +2317,22 @@ package Sinfo is -- entity of the original entity, operator, or subprogram being invoked, -- or the original variable being read or written. + -- Call_Or_Target_Loop + -- Present in continue statements. Set by Analyze_Continue_Statement and + -- used by Expand_Continue_Statement. If Analyze_Continue_Statement + -- concluded that its input node was in fact a call to a procedure named + -- "Continue", it contains the corresponding N_Procedure_Call_Statement + -- node. Otherwise it contains the E_Loop_Id of the loop the continue + -- statement applies to. Finally, if Analyze_Continue_Statement detects + -- an error, this field is set to Empty. + + -- Tag_Propagated + -- This flag is set in N_Identifier, N_Explicit_Dereference, and N_Type_ + -- Conversion nodes that are the LHS of an assignment statement. Used to + -- remember that the RHS of the assignment has tag indeterminate function + -- calls and the tag has been propagated to the calls (as part of the + -- bottom-up analysis of the RHS of the assignment statement). + -- Target_Type -- Used in an N_Validate_Unchecked_Conversion node to point to the target -- type entity for the unchecked conversion instantiation which gigi must @@ -2510,6 +2519,7 @@ package Sinfo is -- Has_Private_View (set in generic units) -- Has_Secondary_Private_View (set in generic units) -- Redundant_Use + -- Tag_Propagated -- Atomic_Sync_Required -- plus fields for expression @@ -3823,6 +3833,7 @@ package Sinfo is -- Prefix -- Actual_Designated_Subtype -- Has_Dereference_Action + -- Tag_Propagated -- Atomic_Sync_Required -- plus fields for expression @@ -4758,6 +4769,7 @@ package Sinfo is -- Conversion_OK -- Do_Overflow_Check -- Rounded_Result + -- Tag_Propagated -- plus fields for expression -- Note: if a range check is required, then the Do_Range_Check flag @@ -5199,6 +5211,7 @@ package Sinfo is -- Has_Created_Identifier -- Is_Abort_Block -- Is_Asynchronous_Call_Block + -- Is_Expanded_Dispatching_Call -- Is_Initialization_Block -- Is_Task_Allocation_Block -- Is_Task_Master @@ -5219,6 +5232,23 @@ package Sinfo is -- Condition (set to Empty if no WHEN part present) -- Next_Exit_Statement : Next exit on chain + ------------------------ + -- Continue Statement -- + ------------------------ + + -- This is a GNAT extension + + -- CONTINUE_STATEMENT ::= continue [loop_NAME] [when CONDITION]; + + -- Gigi restriction: The expander ensures that the type of the Condition + -- field is always Standard.Boolean, even if the type in the source is + -- some non-standard boolean type. + + -- N_Continue_Statement + -- Sloc points to CONTINUE + -- Name (set to Empty if no loop name present) + -- Condition (set to Empty if no WHEN part present) + ------------------------- -- 5.9 Goto Statement -- ------------------------- @@ -6381,7 +6411,6 @@ package Sinfo is -- Condition from the guard (set to Empty if no guard present) -- Statements (set to Empty_List if no statements) -- Pragmas_Before pragmas before alt (set to No_List if none) - -- Accept_Handler_Records ------------------------------ -- 9.7.1 Delay Alternative -- @@ -7966,8 +7995,9 @@ package Sinfo is -- operation) are also in this list. -- Contract_Test_Cases contains a collection of pragmas that correspond - -- to aspects/pragmas Contract_Cases, Exceptional_Cases, Test_Case and - -- Subprogram_Variant. The ordering in the list is in LIFO fashion. + -- to aspects/pragmas Contract_Cases, Exceptional_Cases, Program_Exit, + -- Test_Case and Subprogram_Variant. The ordering in the list is in LIFO + -- fashion. -- Classifications contains pragmas that either declare, categorize, or -- establish dependencies between subprogram or package inputs and @@ -8184,7 +8214,7 @@ package Sinfo is -- An implicit label declaration is created for every occurrence of a -- label on a statement or a label on a block or loop. It is chained -- in the declarations of the innermost enclosing block as specified - -- in RM section 5.1 (3). + -- in RM section 5.1 (12). -- The Defining_Identifier is the actual identifier for the statement -- identifier. Note that the occurrence of the label is a reference, NOT diff --git a/gcc/ada/sinput.ads b/gcc/ada/sinput.ads index 0a9602fd7e29..49423f072d6b 100644 --- a/gcc/ada/sinput.ads +++ b/gcc/ada/sinput.ads @@ -793,8 +793,9 @@ private Full_Ref_Name : File_Name_Type; Instance : Instance_Id; Num_SRef_Pragmas : Nat; - First_Mapped_Line : Logical_Line_Number; Source_Text : Source_Buffer_Ptr; + Inlined_Call : Source_Ptr; + First_Mapped_Line : Logical_Line_Number; Source_First : Source_Ptr; Source_Last : Source_Ptr; Source_Checksum : Word; @@ -803,7 +804,6 @@ private Unit : Unit_Number_Type; Time_Stamp : Time_Stamp_Type; File_Type : Type_Of_File; - Inlined_Call : Source_Ptr; Inlined_Body : Boolean; Inherited_Pragma : Boolean; License : License_Type; @@ -839,52 +839,6 @@ private Index : Source_File_Index := 123456789; -- for debugging end record; - -- The following representation clause ensures that the above record - -- has no holes. We do this so that when instances of this record are - -- written by Tree_Gen, we do not write uninitialized values to the file. - - AS : constant Pos := Standard'Address_Size; - - for Source_File_Record use record - File_Name at 0 range 0 .. 31; - Reference_Name at 4 range 0 .. 31; - Debug_Source_Name at 8 range 0 .. 31; - Full_Debug_Name at 12 range 0 .. 31; - Full_File_Name at 16 range 0 .. 31; - Full_Ref_Name at 20 range 0 .. 31; - Instance at 48 range 0 .. 31; - Num_SRef_Pragmas at 24 range 0 .. 31; - First_Mapped_Line at 28 range 0 .. 31; - Source_First at 32 range 0 .. 31; - Source_Last at 36 range 0 .. 31; - Source_Checksum at 40 range 0 .. 31; - Last_Source_Line at 44 range 0 .. 31; - Template at 52 range 0 .. 31; - Unit at 56 range 0 .. 31; - Time_Stamp at 60 range 0 .. 8 * Time_Stamp_Length - 1; - File_Type at 74 range 0 .. 7; - Inlined_Call at 88 range 0 .. 31; - Inlined_Body at 75 range 0 .. 0; - Inherited_Pragma at 75 range 1 .. 1; - License at 76 range 0 .. 7; - Keyword_Casing at 77 range 0 .. 7; - Identifier_Casing at 78 range 0 .. 15; - Sloc_Adjust at 80 range 0 .. 31; - Lines_Table_Max at 84 range 0 .. 31; - Index at 92 range 0 .. 31; - - -- The following fields are pointers, so we have to specialize their - -- lengths using pointer size, obtained above as Standard'Address_Size. - -- Note that Source_Text is a fat pointer, so it has size = AS*2. - - Source_Text at 96 range 0 .. AS * 2 - 1; - Lines_Table at 96 range AS * 2 .. AS * 3 - 1; - Logical_Lines_Table at 96 range AS * 3 .. AS * 4 - 1; - end record; -- Source_File_Record - - for Source_File_Record'Size use 96 * 8 + AS * 4; - -- This ensures that we did not leave out any fields - package Source_File is new Table.Table (Table_Component_Type => Source_File_Record, Table_Index_Type => Source_File_Index, diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl index 95ece32858c6..272e10ba1d58 100644 --- a/gcc/ada/snames.ads-tmpl +++ b/gcc/ada/snames.ads-tmpl @@ -147,9 +147,11 @@ package Snames is -- Names of aspects for which there are no matching pragmas or attributes -- so that they need to be included for aspect specification use. + Name_Constructor : constant Name_Id := N + $; Name_Default_Value : constant Name_Id := N + $; Name_Default_Component_Value : constant Name_Id := N + $; Name_Designated_Storage_Model : constant Name_Id := N + $; + Name_Destructor : constant Name_Id := N + $; Name_Dimension : constant Name_Id := N + $; Name_Dimension_System : constant Name_Id := N + $; Name_Disable_Controlled : constant Name_Id := N + $; @@ -163,6 +165,7 @@ package Snames is Name_Local_Restrictions : constant Name_Id := N + $; Name_No_Controlled_Parts : constant Name_Id := N + $; Name_No_Task_Parts : constant Name_Id := N + $; + Name_Potentially_Invalid : constant Name_Id := N + $; Name_Real_Literal : constant Name_Id := N + $; Name_Relaxed_Initialization : constant Name_Id := N + $; Name_Stable_Properties : constant Name_Id := N + $; @@ -659,6 +662,7 @@ package Snames is -- correctly recognize and process Priority. Priority is a standard Ada 95 -- pragma. + Name_Program_Exit : constant Name_Id := N + $; -- GNAT Name_Provide_Shift_Operators : constant Name_Id := N + $; -- GNAT Name_Psect_Object : constant Name_Id := N + $; -- GNAT Name_Pure : constant Name_Id := N + $; @@ -1080,6 +1084,7 @@ package Snames is Name_Img : constant Name_Id := N + $; -- GNAT Name_Input : constant Name_Id := N + $; Name_Machine : constant Name_Id := N + $; + Name_Make : constant Name_Id := N + $; -- GNAT Name_Max : constant Name_Id := N + $; Name_Min : constant Name_Id := N + $; Name_Model : constant Name_Id := N + $; @@ -1388,6 +1393,7 @@ package Snames is -- e.g. Name_UP_RESULT maps to "RESULT". Name_Synchronous_Task_Control : constant Name_Id := N + $; + Name_Continue : constant Name_Id := N + $; -- Names used to implement iterators over predefined containers @@ -1614,6 +1620,7 @@ package Snames is Attribute_Img, Attribute_Input, Attribute_Machine, + Attribute_Make, Attribute_Max, Attribute_Min, Attribute_Model, @@ -1952,6 +1959,7 @@ package Snames is Pragma_Predicate_Failure, Pragma_Preelaborate, Pragma_Pre_Class, + Pragma_Program_Exit, Pragma_Provide_Shift_Operators, Pragma_Psect_Object, Pragma_Pure, diff --git a/gcc/ada/socket.c b/gcc/ada/socket.c index 77bdde40a246..a22ed993862b 100644 --- a/gcc/ada/socket.c +++ b/gcc/ada/socket.c @@ -280,10 +280,10 @@ __gnat_gethostbyname (const char *name, return -1; } ret->h_name = name; - ret->h_aliases = &vxw_h_aliases; + ret->h_aliases = vxw_h_aliases; ret->h_addrtype = AF_INET; ret->h_length = 4; - ret->h_addr_list = &vxw_h_addr_list; + ret->h_addr_list = vxw_h_addr_list; return 0; } @@ -302,18 +302,18 @@ __gnat_gethostbyaddr (const char *addr, int len, int type, return -1; } - if (hostGetByAddr (*(int*)addr, &vxw_h_name) != OK) { + if (hostGetByAddr (*(int*)addr, vxw_h_name) != OK) { *h_errnop = __gnat_get_h_errno (); return -1; } vxw_h_addr = (long) addr; - ret->h_name = &vxw_h_name; - ret->h_aliases = &vxw_h_aliases; + ret->h_name = vxw_h_name; + ret->h_aliases = vxw_h_aliases; ret->h_addrtype = AF_INET; ret->h_length = 4; - ret->h_addr_list = &vxw_h_addr_list; + ret->h_addr_list = vxw_h_addr_list; return 0; } diff --git a/gcc/ada/sprint.adb b/gcc/ada/sprint.adb index 938d2b23910a..7a9749287af8 100644 --- a/gcc/ada/sprint.adb +++ b/gcc/ada/sprint.adb @@ -1772,8 +1772,8 @@ package body Sprint is Sprint_Node (Name (Node)); Write_Char (';'); - when N_Exit_Statement => - Write_Indent_Str_Sloc ("exit"); + when N_Loop_Flow_Statement => + Write_Indent_Str_Sloc (Loop_Flow_Keyword (Node)); Sprint_Opt_Node (Name (Node)); if Present (Condition (Node)) then @@ -4634,7 +4634,7 @@ package body Sprint is Param : Entity_Id; begin - Param := First_Entity (Typ); + Param := First_Formal (Typ); loop Write_Id (Param); Write_Str (" : "); @@ -4646,7 +4646,7 @@ package body Sprint is end if; Write_Id (Etype (Param)); - Next_Entity (Param); + Next_Formal (Param); exit when No (Param); Write_Str (", "); end loop; diff --git a/gcc/ada/styleg.adb b/gcc/ada/styleg.adb index 7b7f2524d924..20945fbb65f7 100644 --- a/gcc/ada/styleg.adb +++ b/gcc/ada/styleg.adb @@ -499,7 +499,8 @@ package body Styleg is if Is_Box_Comment or else Style_Check_Comments_Spacing = 1 then - Error_Space_Required (Scan_Ptr + 2); + Error_Msg -- CODEFIX + ("(style) space required?c?", Scan_Ptr + 2); else Error_Msg -- CODEFIX ("(style) two spaces required?c?", Scan_Ptr + 2); @@ -526,7 +527,8 @@ package body Styleg is -- box comment. elsif not Is_Box_Comment then - Error_Space_Required (Scan_Ptr + 3); + Error_Msg -- CODEFIX + ("(style) space required?c?", Scan_Ptr + 3); end if; end if; end Check_Comment; diff --git a/gcc/ada/switch-c.adb b/gcc/ada/switch-c.adb index 6344a0b3a3cf..efad12c9c408 100644 --- a/gcc/ada/switch-c.adb +++ b/gcc/ada/switch-c.adb @@ -335,6 +335,7 @@ package body Switch.C is end if; Ptr := Ptr + 1; + Check_Semantics_Only_Mode := True; Operating_Mode := Check_Semantics; -- -gnatC (Generate CodePeer information) @@ -1219,17 +1220,20 @@ package body Switch.C is List_Representation_Info := Character'Pos (C) - Character'Pos ('0'); - when 's' => - List_Representation_Info_To_File := True; + when 'e' => + List_Representation_Info_Extended := True; - when 'j' => - List_Representation_Info_To_JSON := True; + when 'h' => + List_Representation_Info_Holes := True; when 'm' => List_Representation_Info_Mechanisms := True; - when 'e' => - List_Representation_Info_Extended := True; + when 'j' => + List_Representation_Info_To_JSON := True; + + when 's' => + List_Representation_Info_To_File := True; when others => Bad_Switch ("-gnatR" & Switch_Chars (Ptr .. Max)); @@ -1244,6 +1248,12 @@ package body Switch.C is Osint.Fail ("-gnatRe is incompatible with -gnatRj"); end if; + if List_Representation_Info_To_JSON + and then List_Representation_Info_Holes + then + Osint.Fail ("-gnatRh is incompatible with -gnatRj"); + end if; + -- -gnats (syntax check only) when 's' => diff --git a/gcc/ada/switch.adb b/gcc/ada/switch.adb index b1abe1ea866a..691abc0f1416 100644 --- a/gcc/ada/switch.adb +++ b/gcc/ada/switch.adb @@ -93,7 +93,7 @@ package body Switch is Set_Standard_Output; Usage; Write_Eol; - Write_Line ("Report bugs to report@adacore.com"); + Write_Line ("Report bugs to support@adacore.com"); Exit_Program (E_Success); end if; end Check_Version_And_Help_G; diff --git a/gcc/ada/sysdep.c b/gcc/ada/sysdep.c index 04ca270f0858..3dc76f9ab1fd 100644 --- a/gcc/ada/sysdep.c +++ b/gcc/ada/sysdep.c @@ -331,7 +331,7 @@ __gnat_ttyname (int filedes ATTRIBUTE_UNUSED) #endif /* defined (__vxworks) */ } #endif - + #if defined (__linux__) || defined (__sun__) \ || defined (WINNT) \ || defined (__MACHTEN__) || defined (__hpux__) || defined (_AIX) \ @@ -1070,6 +1070,11 @@ _getpagesize (void) { return getpagesize (); } + +int +__gnat_has_cap_sys_nice () { + return 0; +} #endif int diff --git a/gcc/ada/treepr.adb b/gcc/ada/treepr.adb index b1a2c3479655..375608d2ba66 100644 --- a/gcc/ada/treepr.adb +++ b/gcc/ada/treepr.adb @@ -87,7 +87,7 @@ package body Treepr is procedure Destroy (Value : in out Nat) is null; pragma Annotate (CodePeer, False_Positive, "unassigned parameter", "in out parameter is required to instantiate generic"); - -- Dummy routine for destroing hashed values + -- Dummy routine for destroying hashed values package Serial_Numbers is new Dynamic_Hash_Tables (Key_Type => Int, @@ -412,6 +412,34 @@ package body Treepr is procedure pe (N : Union_Id) renames pn; + --------- + -- pec -- + --------- + + procedure pec (From : Entity_Id) is + begin + Push_Output; + Set_Standard_Output; + + Print_Entity_Chain (From); + + Pop_Output; + end pec; + + ---------- + -- rpec -- + ---------- + + procedure rpec (From : Entity_Id) is + begin + Push_Output; + Set_Standard_Output; + + Print_Entity_Chain (From, Rev => True); + + Pop_Output; + end rpec; + -------- -- pl -- -------- @@ -589,6 +617,36 @@ package body Treepr is end if; end Print_End_Span; + ------------------------ + -- Print_Entity_Chain -- + ------------------------ + + procedure Print_Entity_Chain (From : Entity_Id; Rev : Boolean := False) is + Ent : Entity_Id := From; + begin + Printing_Descendants := False; + Phase := Printing; + + loop + declare + Next_Ent : constant Entity_Id := + (if Rev then Prev_Entity (Ent) else Next_Entity (Ent)); + + Prefix_Char : constant Character := + (if Present (Next_Ent) then '|' else ' '); + begin + Print_Node (Ent, "", Prefix_Char); + + exit when No (Next_Ent); + + Ent := Next_Ent; + + Print_Char ('|'); + Print_Eol; + end; + end loop; + end Print_Entity_Chain; + ----------------------- -- Print_Entity_Info -- ----------------------- @@ -1144,8 +1202,8 @@ package body Treepr is end if; if not Is_List_Member (N) then - Print_Str (Prefix_Str); - Print_Str (" Parent = "); + Print_Str (Prefix); + Print_Str ("Parent = "); Print_Node_Ref (Parent (N)); Print_Eol; end if; @@ -1957,17 +2015,16 @@ package body Treepr is -- Case of descendant is a node if D in Node_Range then - - -- Don't bother about Empty or Error descendants - - if D <= Union_Id (Empty_Or_Error) then - return; - end if; - declare Nod : constant Node_Or_Entity_Id := Node_Or_Entity_Id (D); begin + -- Don't bother about Empty or Error descendants + + if Nod in Empty | Error then + return; + end if; + -- Descendants in one of the standardly compiled internal -- packages are normally ignored, unless the parent is also -- in such a package (happens when Standard itself is output) diff --git a/gcc/ada/treepr.ads b/gcc/ada/treepr.ads index f8a17fbfd79b..43e518711e6d 100644 --- a/gcc/ada/treepr.ads +++ b/gcc/ada/treepr.ads @@ -60,6 +60,12 @@ package Treepr is -- Prints the subtree consisting of the given element list and all its -- referenced descendants. + procedure Print_Entity_Chain (From : Entity_Id; Rev : Boolean := False); + -- Prints the entity chain From is on, starting from From. In other words, + -- prints From and then recursively follow the Next_Entity field. If Rev is + -- True, prints the chain backwards, i.e. follow the Last_Entity field + -- instead of Next_Entity. + -- The following debugging procedures are intended to be called from gdb. -- Note that in several cases there are synonyms which represent historical -- development, and we keep them because some people are used to them! @@ -103,4 +109,12 @@ package Treepr is -- on the left and add a minus sign. This just saves some typing in the -- debugger. + procedure pec (From : Entity_Id); + pragma Export (Ada, pec); + -- Print From and the entities that follow it on its entity chain + + procedure rpec (From : Entity_Id); + pragma Export (Ada, rpec); + -- Like pec, but walk the entity chain backwards. The 'r' stands for + -- "reverse". end Treepr; diff --git a/gcc/ada/types.ads b/gcc/ada/types.ads index 21701de7699b..6258ff90ba1e 100644 --- a/gcc/ada/types.ads +++ b/gcc/ada/types.ads @@ -431,11 +431,6 @@ package Types is -- Used to indicate an error in the source program. A node is actually -- allocated with this Id value, so that Nkind (Error) = N_Error. - Empty_Or_Error : constant Node_Id := Error; - -- Since Empty and Error are the first two Node_Id values, the test for - -- N <= Empty_Or_Error tests to see if N is Empty or Error. This definition - -- provides convenient self-documentation for such tests. - First_Node_Id : constant Node_Id := Node_Low_Bound; -- Subscript of first allocated node. Note that Empty and Error are both -- allocated nodes, whose Nkind fields can be accessed without error. @@ -947,7 +942,8 @@ package Types is SE_Object_Too_Large, -- 35 PE_Stream_Operation_Not_Allowed, -- 36 PE_Build_In_Place_Mismatch, -- 37 - PE_Raise_Check_Failed); -- 38 + PE_Raise_Check_Failed, -- 38 + PE_Abstract_Type_Component); -- 39 pragma Convention (C, RT_Exception_Code); Last_Reason_Code : constant := @@ -973,6 +969,7 @@ package Types is CE_Range_Check_Failed => CE_Reason, CE_Tag_Check_Failed => CE_Reason, + PE_Abstract_Type_Component => PE_Reason, PE_Access_Before_Elaboration => PE_Reason, PE_Accessibility_Check_Failed => PE_Reason, PE_Address_Of_Intrinsic => PE_Reason, diff --git a/gcc/ada/types.h b/gcc/ada/types.h index 007dc248b2c9..d0a1a04f979f 100644 --- a/gcc/ada/types.h +++ b/gcc/ada/types.h @@ -431,7 +431,8 @@ enum RT_Exception_Code SE_Object_Too_Large = 35, PE_Stream_Operation_Not_Allowed = 36, PE_Build_In_Place_Mismatch = 37, - PE_Raise_Check_Failed = 38 + PE_Raise_Check_Failed = 38, + PE_Abstract_Type_Component = 39 }; -#define LAST_REASON_CODE 38 +#define LAST_REASON_CODE 39 diff --git a/gcc/ada/urealp.adb b/gcc/ada/urealp.adb index cad1e662e189..d5fb4f55be7d 100644 --- a/gcc/ada/urealp.adb +++ b/gcc/ada/urealp.adb @@ -34,7 +34,7 @@ package body Urealp is -- add 1 to No_Ureal, since "+" means something different for Ureals). type Ureal_Entry is record - Num : Uint; + Num : Uint; -- Numerator (always non-negative) Den : Uint; @@ -48,20 +48,6 @@ package body Urealp is -- Flag set if value is negative end record; - -- The following representation clause ensures that the above record - -- has no holes. We do this so that when instances of this record are - -- written, we do not write uninitialized values to the file. - - for Ureal_Entry use record - Num at 0 range 0 .. 31; - Den at 4 range 0 .. 31; - Rbase at 8 range 0 .. 31; - Negative at 12 range 0 .. 31; - end record; - - for Ureal_Entry'Size use 16 * 8; - -- This ensures that we did not leave out any fields - package Ureals is new Table.Table ( Table_Component_Type => Ureal_Entry, Table_Index_Type => Ureal'Base, @@ -832,7 +818,7 @@ package body Urealp is return Store_Ureal ((Num => Uint_1, Den => -N, - Rbase => UI_To_Int (UR_Trunc (Bas)), + Rbase => UI_To_Int (IBas), Negative => Neg)); -- If the exponent is negative then we raise the numerator and the @@ -1251,12 +1237,13 @@ package body Urealp is --------------- function UR_Negate (Real : Ureal) return Ureal is + Val : constant Ureal_Entry := Ureals.Table (Real); begin return Store_Ureal - ((Num => Ureals.Table (Real).Num, - Den => Ureals.Table (Real).Den, - Rbase => Ureals.Table (Real).Rbase, - Negative => not Ureals.Table (Real).Negative)); + ((Num => Val.Num, + Den => Val.Den, + Rbase => Val.Rbase, + Negative => not Val.Negative)); end UR_Negate; ------------ diff --git a/gcc/ada/urealp.ads b/gcc/ada/urealp.ads index 323efc8b9281..c7725bf8da00 100644 --- a/gcc/ada/urealp.ads +++ b/gcc/ada/urealp.ads @@ -233,7 +233,7 @@ package Urealp is function UR_Sub (Left : Ureal; Right : Uint) return Ureal; -- Returns real difference of operands - function UR_Exponentiate (Real : Ureal; N : Uint) return Ureal; + function UR_Exponentiate (Real : Ureal; N : Uint) return Ureal; -- Returns result of raising Ureal to Uint power. -- Fatal error if Left is 0 and Right is negative. @@ -317,7 +317,7 @@ package Urealp is function "-" (Left : Uint; Right : Ureal) return Ureal renames UR_Sub; function "-" (Left : Ureal; Right : Uint) return Ureal renames UR_Sub; - function "**" (Real : Ureal; N : Uint) return Ureal + function "**" (Real : Ureal; N : Uint) return Ureal renames UR_Exponentiate; function "abs" (Real : Ureal) return Ureal renames UR_Abs; diff --git a/gcc/ada/usage.adb b/gcc/ada/usage.adb index efa38b540dd1..5b87bb54dcaa 100644 --- a/gcc/ada/usage.adb +++ b/gcc/ada/usage.adb @@ -92,17 +92,17 @@ begin -- Common switches available everywhere - Write_Switch_Char ("g ", ""); + Write_Switch_Char ("g ", ""); Write_Line ("Generate debugging information"); - Write_Switch_Char ("Idir ", ""); + Write_Switch_Char ("Idir ", ""); Write_Line ("Specify source files search path"); - Write_Switch_Char ("I- ", ""); + Write_Switch_Char ("I- ", ""); Write_Line ("Do not look for sources in current directory"); - Write_Switch_Char ("O[0123] ", ""); - Write_Line ("Control the optimization level"); + Write_Switch_Char ("O[?] ", ""); + Write_Line ("Control the optimization level (?=0/1/2/3/s/z/g)"); Write_Eol; @@ -402,7 +402,7 @@ begin Write_Switch_Char ("R?"); Write_Line - ("List rep info (?=0/1/2/3/4/e/m for none/types/all/sym/cg/ext/mech)"); + ("List rep info (?=1/2/3/4/e/h/m for types/all/sym/cg/ext/holes/mech)"); Write_Switch_Char ("R?j"); Write_Line ("List rep info in the JSON data interchange format"); Write_Switch_Char ("R?s"); diff --git a/gcc/ada/vast.adb b/gcc/ada/vast.adb index 302a89bd4a0a..59470fdd0f15 100644 --- a/gcc/ada/vast.adb +++ b/gcc/ada/vast.adb @@ -23,18 +23,598 @@ -- -- ------------------------------------------------------------------------------ --- Dummy implementation +pragma Unsuppress (All_Checks); +pragma Assertion_Policy (Check); +-- Enable checking. This isn't really necessary, but it might come in handy if +-- we want to run VAST with a compiler built without checks. Anyway, it's +-- harmless, because VAST is not run by default. + +with Ada.Unchecked_Deallocation; + +with System.Case_Util; + +with Atree; use Atree; +with Debug; +with Einfo.Entities; use Einfo.Entities; +with Lib; use Lib; +with Namet; use Namet; +with Nlists; use Nlists; +with Opt; use Opt; +with Output; +with Sinfo.Nodes; use Sinfo.Nodes; +with Sinput; +with Table; +with Types; use Types; package body VAST is + -- ???Basic tree properties not yet checked: + -- - No dangling trees. Every node that is reachable at all is reachable + -- by some syntactic path. + -- - Basic properties of Nlists/Elists (next/prev pointers make sense, + -- for example). + + Force_Enable_VAST : constant Boolean := False; + -- Normally, VAST is enabled by the the -gnatd_V switch. + -- To force it to be enabled independent of any switches, + -- set this to True. + + type Check_Enum is + (Check_Other, + Check_Sloc, + Check_Analyzed, + Check_Error_Nodes, + Check_Sharing, + Check_Parent_Present, + Check_Parent_Correct); + + type Check_Status is + -- Action in case of check failure: + (Disabled, -- Do nothing + Enabled, -- Print messages, and raise an exception + Print_And_Continue); -- Print a message + + pragma Warnings (Off, "Status*could be declared constant"); + Status : array (Check_Enum) of Check_Status := + (Check_Other => Enabled, + Check_Sloc => Disabled, + Check_Analyzed => Disabled, + Check_Error_Nodes => Print_And_Continue, + Check_Sharing => Disabled, + Check_Parent_Present => Print_And_Continue, + Check_Parent_Correct => Disabled); +-- others => Print_And_Continue); +-- others => Enabled); +-- others => Disabled); + -- Passing checks are Check_Other, which should always be Enabled. + -- Currently-failing checks are different enumerals in Check_Enum, + -- which can be disabled individually until we fix the bugs, or enabled + -- when debugging particular bugs. Pass a nondefault Check_Enum to + -- Assert in order to deal with bugs we have not yet fixed, + -- and play around with the value of Status above for + -- testing and debugging. + -- + -- Note: Once a bug is fixed, and the check passes reliably, we may choose + -- to remove that check from Check_Enum and use Check_Other instead. + + type Node_Stack_Index is new Pos; + subtype Node_Stack_Count is + Node_Stack_Index'Base range 0 .. Node_Stack_Index'Last; + + package Node_Stack is new Table.Table + (Table_Component_Type => Node_Id, + Table_Index_Type => Node_Stack_Index'Base, + Table_Low_Bound => 1, + Table_Initial => 1, + Table_Increment => 100, + Table_Name => "Node_Stack"); + + procedure Assert + (Condition : Boolean; + Check : Check_Enum := Check_Other; + Detail : String := ""); + -- Check that the Condition is True. Status determines action on failure. + + function To_Mixed (A : String) return String; + -- Copied from System.Case_Util; old versions of that package do not have + -- this function, so this is needed for bootstrapping. + + function Image (Kind : Node_Kind) return String is (To_Mixed (Kind'Img)); + function Image (Kind : Entity_Kind) return String is (To_Mixed (Kind'Img)); + + procedure Put (S : String); + procedure Put_Line (S : String); + procedure Put_Node (N : Node_Id); + procedure Put_Node_Stack; + -- Output routines; print only if -gnatd_W (VAST in verbose mode) is + -- enabled. + + procedure Put_Indentation; + -- Print spaces to indicate nesting depth of Node_Stack + + procedure Enter_Node (N : Node_Id); + procedure Leave_Node (N : Node_Id); + -- Called for each node while walking the tree. + -- Push/pop N to/from Node_Stack. + -- Print enter/leave debugging messages. + -- ???Possible improvements to messages: + -- Walk subtrees in a better order. + -- Print field names. + -- Don't print boring fields (such as N_Empty nodes). + -- Print more info (value of literals, "A.B.C" for expanded names, etc.). + -- Share some code with Treepr. + + procedure Do_Tree (N : Node_Id); + -- Do VAST checking on a tree of nodes + + function Has_Subtrees (N : Node_Id) return Boolean; + -- True if N has one or more syntactic fields + + procedure Do_Subtrees (N : Node_Id); + -- Call Do_Tree on all the subtrees (i.e. syntactic fields) of N + + procedure Do_List (L : List_Id); + -- Call Do_Tree on the list elements + + procedure Do_Unit (U : Unit_Number_Type); + -- Call Do_Tree on the root node of a compilation unit + + function Ancestor_Node (Count : Node_Stack_Count) return Node_Id; + -- Nth ancestor on the Node_Stack. Ancestor_Node(0) is the current node, + -- Ancestor_Node(1) is its parent, Ancestor_Node(2) is its grandparent, + -- and so on. + + function Top_Node return Node_Id is (Ancestor_Node (0)); + + type Node_Set is array (Node_Id range <>) of Boolean; + pragma Pack (Node_Set); + type Node_Set_Ptr is access all Node_Set; + procedure Free is new Ada.Unchecked_Deallocation (Node_Set, Node_Set_Ptr); + + Visited : Node_Set_Ptr; + -- Giant array of Booleans; Visited (N) is True if and only if we have + -- visited N in the tree walk. Used to detect incorrect sharing of subtrees + -- or (worse) cycles. We don't allocate the set on the stack, for fear of + -- Storage_Error. + + function Get_Node_Field_Union is new + Atree.Atree_Private_Part.Get_32_Bit_Field (Union_Id) with Inline; + + -------------- + -- To_Mixed -- + -------------- + + function To_Mixed (A : String) return String is + Result : String := A; + begin + System.Case_Util.To_Mixed (Result); + return Result; + end To_Mixed; + + --------- + -- Put -- + --------- + + procedure Put (S : String) is + begin + if Debug.Debug_Flag_Underscore_WW then + Output.Write_Str (S); + end if; + end Put; + + -------------- + -- Put_Line -- + -------------- + + procedure Put_Line (S : String) is + begin + if Debug.Debug_Flag_Underscore_WW then + Output.Write_Line (S); + end if; + end Put_Line; + + -------------- + -- Put_Node -- + -------------- + + procedure Put_Node (N : Node_Id) is + begin + if Debug.Debug_Flag_Underscore_WW then + if Nkind (N) in N_Entity then + Put (Image (Ekind (N))); + else + Put (Image (Nkind (N))); + end if; + + Put (N'Img & " "); + Sinput.Write_Location (Sloc (N)); + + if Comes_From_Source (N) then + Put (" (s)"); + end if; + + case Nkind (N) is + when N_Has_Chars => + Put (" "); + Write_Name_For_Debug (Chars (N), Quote => """"); + when others => null; + end case; + + end if; + end Put_Node; + + --------------------- + -- Put_Indentation -- + --------------------- + + procedure Put_Indentation is + begin + Put (String'(Natural (Node_Stack.First) .. + Natural (Node_Stack.Last) * 2 => ' ')); + end Put_Indentation; + + ---------------- + -- Enter_Node -- + ---------------- + + procedure Enter_Node (N : Node_Id) is + begin + Node_Stack.Append (N); -- push + + if Has_Subtrees (N) then + Put ("-->"); + else + -- If no subtrees, just print one line for enter/leave + Put (" "); + end if; + Put_Indentation; + Put_Node (N); + Put_Line (""); + end Enter_Node; + ---------------- - -- Check_Tree -- + -- Leave_Node -- ---------------- - procedure Check_Tree (GNAT_Root : Node_Id) is - pragma Unreferenced (GNAT_Root); + procedure Leave_Node (N : Node_Id) is + begin + if Has_Subtrees (N) then + Put ("<--"); + Put_Indentation; + Put_Node (N); + Put_Line (""); + end if; + + Node_Stack.Decrement_Last; -- pop + end Leave_Node; + + -------------------- + -- Put_Node_Stack -- + -------------------- + + procedure Put_Node_Stack is + begin + for J in reverse Node_Stack.First .. Node_Stack.Last loop + Put_Node (Node_Stack.Table (J)); + Put_Line (""); + end loop; + end Put_Node_Stack; + + ------------------- + -- Ancestor_Node -- + ------------------- + + function Ancestor_Node (Count : Node_Stack_Count) return Node_Id is + begin + return Node_Stack.Table (Node_Stack.Last - Count); + end Ancestor_Node; + + ------------ + -- Assert -- + ------------ + + VAST_Failure : exception; + + procedure Assert + (Condition : Boolean; + Check : Check_Enum := Check_Other; + Detail : String := "") + is begin - null; - end Check_Tree; + if not Condition then + declare + Part1 : constant String := "VAST fail"; + Part2 : constant String := + (if Check = Check_Other then "" + else ": " & To_Mixed (Check'Img)); + Part3 : constant String := + (if Detail = "" then "" else " -- " & Detail); + Message : constant String := Part1 & Part2 & Part3; + Save : constant Boolean := Debug.Debug_Flag_Underscore_WW; + begin + case Status (Check) is + when Disabled => null; + when Enabled | Print_And_Continue => + Debug.Debug_Flag_Underscore_WW := True; + -- ???We should probably avoid changing the debug flag here + Put (Message & ": "); + Put_Node (Top_Node); + Put_Line (""); + + if Status (Check) = Enabled then + Put_Node_Stack; + raise VAST_Failure with Message; + end if; + + Debug.Debug_Flag_Underscore_WW := Save; + end case; + end; + end if; + end Assert; + + ------------- + -- Do_Tree -- + ------------- + + procedure Do_Tree (N : Node_Id) is + begin + Enter_Node (N); + + -- Skip the rest if empty. Check Sloc: + + case Nkind (N) is + when N_Empty => + Assert (No (Sloc (N))); + goto Done; -- --------------> + -- Don't do any further checks on Empty + + -- ???Some nodes, including exception handlers, have no Sloc; + -- it's unclear why. + + when N_Exception_Handler => + Assert (if Comes_From_Source (N) then Present (Sloc (N))); + when others => + Assert (Present (Sloc (N)), Check_Sloc); + end case; + + -- All reachable nodes should have been analyzed by the time we get + -- here: + + Assert (Analyzed (N), Check_Analyzed); + + -- If we visit the same node more than once, then there are shared + -- nodes; the "tree" is not a tree: + + Assert (not Visited (N), Check_Sharing); + Visited (N) := True; + + -- Misc checks based on node/entity kind: + + case Nkind (N) is + when N_Unused_At_Start | N_Unused_At_End => + Assert (False); + + when N_Error => + -- VAST doesn't do anything when Serious_Errors_Detected > 0 (at + -- least for now), so we shouldn't encounter any N_Error nodes. + Assert (False, Check_Error_Nodes); + + when N_Entity => + case Ekind (N) is + when others => + null; -- more to be done here + end case; + + when others => + null; -- more to be done here + end case; + + -- Check that N has a Parent, except in certain cases: + + case Nkind (N) is + when N_Empty => + raise Program_Error; -- can't get here + + when N_Error => + Assert (False, Check_Error_Nodes); + -- The error node has no parent, but we shouldn't even be seeing + -- error nodes in VAST at all. See earlier "when N_Error". + + when N_Compilation_Unit => + Assert (No (Parent (N))); + -- The parent of the root of each unit is empty. + + when N_Entity => + if not Is_Itype (N) then + -- An Itype might or might not have a parent + + Assert + (Present (Parent (N)), Detail => "missing parent of entity"); + Assert (Parent (N) = Ancestor_Node (1), Check_Parent_Correct); + end if; + + when others => + Assert (Present (Parent (N)), Check_Parent_Present); + -- All other nodes should have a parent + if Status (Check_Parent_Present) = Enabled then + Assert (Parent (N) = Ancestor_Node (1), Check_Parent_Correct); + end if; + end case; + + Do_Subtrees (N); + + <<Done>> + Leave_Node (N); + end Do_Tree; + + ----------------- + -- Has_Subtrees -- + ----------------- + + function Has_Subtrees (N : Node_Id) return Boolean is + Offsets : Traversed_Offset_Array renames + Traversed_Fields (Nkind (N)); + begin + -- True if sentinel comes first + return Offsets (Offsets'First) /= No_Field_Offset; + end Has_Subtrees; + + ----------------- + -- Do_Subtrees -- + ----------------- + + procedure Do_Subtrees (N : Node_Id) is + -- ???Do we need tail recursion elimination here, + -- as in Atree.Traverse_Func? + Offsets : Traversed_Offset_Array renames + Traversed_Fields (Nkind (N)); + begin + for Cur_Field in Offset_Array_Index loop + exit when Offsets (Cur_Field) = No_Field_Offset; + + declare + F : constant Union_Id := + Get_Node_Field_Union (N, Offsets (Cur_Field)); + begin + if F in Node_Range then + Do_Tree (Node_Id (F)); + elsif F in List_Range then + Do_List (List_Id (F)); + else + raise Program_Error; + end if; + end; + end loop; + end Do_Subtrees; + + ------------- + -- Do_List -- + ------------- + + procedure Do_List (L : List_Id) is + Elmt : Node_Id := First (L); + Len : constant String := List_Length (L)'Img; + begin + if Is_Non_Empty_List (L) then + Put ("-->"); + Put_Indentation; + Put_Line ("list len=" & Len); + + while Present (Elmt) loop + Do_Tree (Elmt); + Next (Elmt); + end loop; + + Put ("<--"); + Put_Indentation; + Put_Line ("list len=" & Len); + end if; + end Do_List; + + ------------- + -- Do_Unit -- + ------------- + + procedure Do_Unit (U : Unit_Number_Type) is + U_Name : constant Unit_Name_Type := Unit_Name (U); + U_Name_S : constant String := + (if U_Name = No_Unit_Name then "<No_Unit_Name>" + else Get_Name_String (U_Name)); + Predef : constant String := + (if Is_Predefined_Unit (U) then " (predef)" + elsif Is_Internal_Unit (U) then " (gnat)" + else ""); + Is_Main : constant String := + (if U = Main_Unit then " (main unit)" else ""); + Msg : constant String := + "VAST for unit" & U'Img & " " & U_Name_S & Predef & Is_Main; + + Is_Preprocessing_Dependency : constant Boolean := + U_Name = No_Unit_Name; + -- True if this is a bogus unit added by Add_Preprocessing_Dependency. + -- ???Not sure what that's about, but these units have no name and + -- no associated tree, so we had better not try to walk those trees. + + Root : constant Node_Id := Cunit (U); + begin + pragma Assert (Node_Stack.Last = 0); + Assert (No (Root) = Is_Preprocessing_Dependency); + -- All compilation units except these bogus ones should have a Cunit. + + Put_Line (Msg); + + if Is_Preprocessing_Dependency then + Put_Line ("Skipping preprocessing dependency"); + return; + end if; + + Assert (Present (Root)); + Do_Tree (Root); + Put_Line (Msg & " (done)"); + pragma Assert (Node_Stack.Last = 0); + end Do_Unit; + + ---------- + -- VAST -- + ---------- + + procedure VAST is + pragma Assert (Expander_Active = (Operating_Mode = Generate_Code)); + -- ???So why do we need both Operating_Mode and Expander_Active? + use Debug; + begin + -- Do nothing if we're not calling the back end; the main point of VAST + -- is to protect against code-generation bugs. This includes the + -- case where legality errors were detected; the tree is known to be + -- malformed in some error cases. + + if Operating_Mode /= Generate_Code then + return; + end if; + + -- If -gnatd_W (VAST in verbose mode) is enabled, then that should imply + -- -gnatd_V (enable VAST). + + if Debug_Flag_Underscore_WW then + Debug_Flag_Underscore_VV := True; + end if; + + -- Do nothing if VAST is disabled + + if not (Debug_Flag_Underscore_VV or Force_Enable_VAST) then + return; + end if; + + -- Turn off output unless verbose mode is enabled + + Put_Line ("VAST"); + + -- Operating_Mode = Generate_Code implies there are no legality errors: + + Assert (Serious_Errors_Detected = 0); + + Put_Line ("VAST checking" & Last_Unit'Img & " units"); + + declare + use Atree_Private_Part; + Last_Node : constant Node_Id := Node_Offsets.Last; + begin + pragma Assert (Visited = null); + Visited := new Node_Set'(Node_Id'First .. Last_Node => False); + + for U in Main_Unit .. Last_Unit loop + -- Main_Unit is the one passed to the back end, but here we are + -- walking all the units. + Do_Unit (U); + end loop; + + -- We shouldn't have allocated any new nodes during VAST: + + pragma Assert (Node_Offsets.Last = Last_Node); + Free (Visited); + end; + + Put_Line ("VAST done."); + end VAST; end VAST; diff --git a/gcc/ada/vast.ads b/gcc/ada/vast.ads index 031ea2119d48..faecd9a33f3c 100644 --- a/gcc/ada/vast.ads +++ b/gcc/ada/vast.ads @@ -24,13 +24,10 @@ ------------------------------------------------------------------------------ -- This package is the entry point for VAST: Verifier for the Ada Semantic --- Tree. - -with Types; use Types; +-- Tree. It walks the expanded trees, and verifies their validity. package VAST is - procedure Check_Tree (GNAT_Root : Node_Id); - -- Check the validity of the given Root tree + procedure VAST; end VAST; diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index 1fbba5dcac6e..2c946f039aec 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,3 +1,283 @@ +2025-07-21 Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org> + + * region-model-asm.cc (region_model::on_asm_stmt): Pass null + pointer to parse_{input,output}_constraint(). + +2025-07-11 David Malcolm <dmalcolm@redhat.com> + + * ana-state-to-diagnostic-state.cc: Reimplement, replacing + XML-based implementation with one based on state graphs. + * ana-state-to-diagnostic-state.h: Likewise. + * checker-event.cc: Replace include of "xml.h" with include of + "diagnostic-state-graphs.h". + (checker_event::maybe_make_xml_state): Replace with... + (checker_event::maybe_make_diagnostic_state_graph): ...this. + * checker-event.h: Add include of "diagnostic-digraphs.h". + (checker_event::maybe_make_xml_state): Replace decl with... + (checker_event::maybe_make_diagnostic_state_graph): ...this. + * engine.cc (exploded_node::on_stmt_pre): Replace + "_analyzer_dump_xml" with "__analyzer_dump_sarif". + * program-state.cc: Replace include of "diagnostic-state.h" with + "diagnostic-state-graphs.h". + (program_state::dump_dot): Port from XML to state graphs. + * program-state.h: Drop reduntant forward decl of xml::document. + (program_state::make_xml): Replace decl with... + (program_state::make_diagnostic_state_graph): ...this. + (program_state::dump_xml_to_pp): Drop decl. + (program_state::dump_xml_to_file): Drop decl. + (program_state::dump_xml): Drop decl. + (program_state::dump_dump_sarif): New decl. + * sm-malloc.cc (get_dynalloc_state_for_state): New. + (malloc_state_machine::add_state_to_xml): Replace with... + (malloc_state_machine::add_state_to_state_graph): ...this. + * sm.cc (state_machine::add_state_to_xml): Replace with... + (state_machine::add_state_to_state_graph): ...this. + (state_machine::add_global_state_to_xml): Replace with... + (state_machine::add_global_state_to_state_graph): ...this. + * sm.h (class xml_state): Drop forward decl. + (class analyzer_state_graph): New forward decl. + (state_machine::add_state_to_xml): Replace decl with... + (state_machine::add_state_to_state_graph): ...this. + (state_machine::add_global_state_to_xml): Replace decl with... + (state_machine::add_global_state_to_state_graph): ...this. + +2025-06-30 David Malcolm <dmalcolm@redhat.com> + + * access-diagram.cc: Use nullptr rather than NULL where + appropriate. + * analyzer-language.cc: Likewise. + * analyzer-language.h: Likewise. + * analyzer-logging.h: Likewise. + * analyzer-pass.cc: Likewise. + * analyzer.cc: Likewise. + * bounds-checking.cc: Likewise. + * call-details.cc: Likewise. + * call-string.cc: Likewise. + * call-string.h: Likewise. + * call-summary.cc: Likewise. + * checker-event.cc: Likewise. + * common.h: Likewise. + * constraint-manager.cc: Likewise. + * constraint-manager.h: Likewise. + * diagnostic-manager.cc: Likewise. + * engine.cc: Likewise. + * exploded-graph.h: Likewise. + * function-set.cc: Likewise + * infinite-recursion.cc: Likewise + * inlining-iterator.h: Likewise + * kf.cc: Likewise + * known-function-manager.cc: Likewise + * pending-diagnostic.cc: Likewise + * program-point.cc: Likewise + * program-point.h: Likewise + * program-state.cc: Likewise + * program-state.h: Likewise + * record-layout.cc: Likewise + * region-model-asm.cc: Likewise + * region-model-manager.cc: Likewise + * region-model-manager.h: Likewise + * region-model-reachability.cc: Likewise + * region-model.cc: Likewise + * region-model.h: Likewise + * region.cc: Likewise + * region.h: Likewise + * sm-fd.cc: Likewise + * sm-malloc.cc: Likewise + * sm-pattern-test.cc: Likewise + * sm-signal.cc: Likewise + * sm-taint.cc: Likewise + * sm.cc: Likewise + * sm.h: Likewise + * state-purge.cc: Likewise + * state-purge.h: Likewise + * store.cc: Likewise + * store.h: Likewise + * supergraph.cc: Likewise + * supergraph.h: Likewise + * svalue.cc: Likewise + * svalue.h: Likewise + * varargs.cc: Likewise + +2025-06-30 David Malcolm <dmalcolm@redhat.com> + + * checker-event.cc (function_entry_event::get_meaning): Convert + diagnostic_event::meaning enums to enum class. + (cfg_edge_event::get_meaning): Likewise. + (call_event::get_meaning): Likewise. + (return_event::get_meaning): Likewise. + (start_consolidated_cfg_edges_event::get_meaning): Likewise. + (inlined_call_event::get_meaning): Likewise. + (warning_event::get_meaning): Likewise. + * sm-fd.cc (fd_diagnostic::get_meaning_for_state_change): + Likewise. + * sm-file.cc (file_diagnostic::get_meaning_for_state_change): + Likewise. + * sm-malloc.cc (malloc_diagnostic::get_meaning_for_state_change): + Likewise. + * sm-sensitive.cc + (exposure_through_output_file::get_meaning_for_state_change): + Likewise. + * sm-taint.cc (taint_diagnostic::get_meaning_for_state_change): + Likewise. + * varargs.cc + (va_list_sm_diagnostic::get_meaning_for_state_change): Likewise. + +2025-06-30 Jakub Jelinek <jakub@redhat.com> + + PR c/120520 + PR c/117023 + * sm-malloc.cc (malloc_state_machine::on_stmt): Handle 3 argument + nonnull_if_nonzero attribute. + +2025-06-23 David Malcolm <dmalcolm@redhat.com> + + * region-model.cc + (exception_thrown_from_unrecognized_call::print): Add + "final override" to vfunc. + +2025-06-23 David Malcolm <dmalcolm@redhat.com> + + PR other/116792 + * ana-state-to-diagnostic-state.cc: New file. + * ana-state-to-diagnostic-state.h: New file. + * checker-event.cc: Include "xml.h". + (checker_event::checker_event): Initialize m_path. + (checker_event::prepare_for_emission): Store the path pointer into + m_path. + (checker_event::maybe_make_xml_state): New. + (function_entry_event::function_entry_event): Add "state" param + and use it to initialize m_state. + (superedge_event::get_program_state): New. + (call_event::get_program_state): New. + (warning_event::get_program_state): New. + * checker-event.h (checker_event::get_program_state): New vfunc. + (checker_event::maybe_make_xml_state): New decl. + (checker_event::m_path): New field. + (statement_event::get_program_state): New vfunc impl. + (function_entry_event::function_entry_event): Add "state" param. + (function_entry_event::get_program_state): New vfunc impl. + (function_entry_event::m_state): New field. + (state_change_event::get_program_state): New vfunc impl. + (superedge_event::get_program_state): New vfunc decl. + (warning_event::warning_event): Add "program_state_" param and + copy it. + (warning_event::get_program_state): New vfunc decl. + (warning_event::m_program_state): New field. + * checker-path.h (checker_path::checker_path): Add ext_state param. + (checker_path::get_ext_state): New accessor. + (checker_path::m_ext_state): New field. + * common.h: Define INCLUDE_MAP and INCLUDE_STRING. + * diagnostic-manager.cc (saved_diagnostic::operator==): Don't + deduplicate dump_path_diagnostic instances. + (diagnostic_manager::emit_saved_diagnostic): Pass ext_state to + checker_path ctor. + * engine.cc: + (impl_region_model_context::on_state_leak): Pass old and new state + to state_machine::on_leak. + (exploded_node::on_stmt_pre): Implement __analyzer_dump_xml and + __analyzer_dump_dot. + * exploded-graph.h (impl_region_model_context::get_state): New. + * infinite-recursion.cc + (recursive_function_entry_event::recursive_function_entry_event): + Add "dst_state" param and pass to function_entry_event ctor. + (infinite_recursion_diagnostic::add_function_entry_event): Pass state + to event ctor. + * kf-analyzer.cc: Include "analyzer/program-state.h" + (dump_path_diagnostic::dump_path_diagnostic): Add "state" param. + (dump_path_diagnostic::get_final_state): New. + (dump_path_diagnostic::m_state): New field. + (kf_analyzer_dump_path::impl_call_pre): Pass state to warning. + * pending-diagnostic.cc + (pending_diagnostic::add_function_entry_event): Pass state to + function_entry_event. + (pending_diagnostic::add_final_event): Likewise to warning_event. + * pending-diagnostic.h (pending_diagnostic::get_final_state): New + vfunc decl. + * program-state.cc: Include "diagnostic-state.h", "graphviz.h" and + "analyzer/ana-state-to-diagnostic-state.h". + (program_state::dump_dot): New. + * program-state.h: Include "text-art/tree-widget.h" and + "analyzer/store.h". + (class xml::document): New forward decl. + (make_xml): New. + (dump_xml_to_pp): New. + (dump_xml_to_file): New. + (dump_xml): New. + (dump_dot): New. + * record-layout.cc (record_layout::record_layout): Make param + const_tree. + * record-layout.h (item::item): Likewise. + (item::m_field): Likewise. + (record_layout::record_layout): Likewise. + (record_layout::begin): New. + (record_layout::end): New. + * region-model.cc + (exposure_through_uninit_copy::complain_about_fully_uninit_item): + Use const_tree. + (exposure_through_uninit_copy::complain_about_partially_uninit_item): + Likewise. + * region-model.h (region_model_context::get_state): New vfunc. + (noop_region_model_context::get_state): New. + (region_model_context_decorator::get_state): New. + * sm-fd.cc (fd_leak::fd_leak): Add "final_state" param and capture + it if present. + (fd_leak::get_final_state): New. + (fd_leak::m_final_state): New. + (fd_state_machine::on_open): Pass nullptr for new "final_state" + param. + (fd_state_machine::on_creat): Likewise. + (fd_state_machine::on_socket): Likewise. + (fd_state_machine::on_accept): Likewise. + (fd_state_machine::on_leak): Add state params and pass new state + as final state to fd_leak ctor. + * sm-file.cc: Include "analyzer/program-state.h". + (file_leak::file_leak): Add "final_state" param and capture it if + present. + (file_leak::get_final_state): New. + (file_leak::m_final_state): New. + (fileptr_state_machine::on_leak): Add state params and pass new + state as final state to fd_leak ctor. + * sm-malloc.cc: Include + "analyzer/ana-state-to-diagnostic-state.h". + (malloc_leak::malloc_leak): Add "final_state" param and use it. + (malloc_leak::get_final_state): New vfunc impl. + (malloc_leak::m_final_state): New field. + (malloc_state_machine::on_leak): Add state params; capture final + state. + (malloc_state_machine::add_state_to_xml): New. + * sm.cc (state_machine::on_leak): Add "old_state" and "new_state" + params. Use nullptr. + (state_machine::add_state_to_xml): New. + (state_machine::add_global_state_to_xml): New. + * sm.h (class xml_state): New forward decl. + (state_machine::on_leak): Add state params. + (state_machine::add_state_to_xml): New vfunc decl. + (state_machine::add_global_state_to_xml): New vfunc decl. + * store.h (bit_range::operator<): New. + * varargs.cc (va_list_leak::va_list_leak): Add final_state param + and capture it if non-null. + (va_list_leak::get_final_state): New. + (va_list_leak::m_final_state): New. + (va_list_state_machine::on_leak): Add state params and pass final + state to va_list_leak ctor. + +2025-06-18 David Malcolm <dmalcolm@redhat.com> + + * checker-event.h (checker_event::get_kind): New accessor. + (checker_event::m_kind): Make private. + * checker-path.cc (checker_path::maybe_log): Use accessor for + checker_event::m_kind. + (checker_path::add_event): Likewise. + (checker_path::debug): Likewise. + (checker_path::cfg_edge_pair_at_p): Likewise. + (checker_path::inject_any_inlined_call_events): Likewise. + * diagnostic-manager.cc + (diagnostic_manager::prune_for_sm_diagnostic): Likewise. + (diagnostic_manager::prune_for_sm_diagnostic): Likewise. + (diagnostic_manager::consolidate_conditions): Likewise. + (diagnostic_manager::consolidate_unwind_events): Likewise. + (diagnostic_manager::finish_pruning): Likewise. + 2025-05-06 David Malcolm <dmalcolm@redhat.com> * checker-event.cc (checker_event::checker_event): Update diff --git a/gcc/analyzer/access-diagram.cc b/gcc/analyzer/access-diagram.cc index 42833603b0f6..90b396c0864f 100644 --- a/gcc/analyzer/access-diagram.cc +++ b/gcc/analyzer/access-diagram.cc @@ -1116,7 +1116,7 @@ class bit_to_table_map { logger.start_log_line (); logger.log_partial ("table_x: %i", table_x); - access_range range_for_column (NULL, bit_range (0, 0)); + access_range range_for_column (nullptr, bit_range (0, 0)); if (maybe_get_access_range_for_table_x (table_x, &range_for_column)) { logger.log_partial (": range: "); @@ -2244,7 +2244,7 @@ class access_diagram_impl : public vbox_widget for (int table_x = 0; table_x < t.get_size ().w; table_x++) { const int table_y = 1; - access_range range_for_column (NULL, bit_range (0, 0)); + access_range range_for_column (nullptr, bit_range (0, 0)); if (m_btm.maybe_get_access_range_for_table_x (table_x, &range_for_column)) { @@ -2495,7 +2495,7 @@ class access_diagram_impl : public vbox_widget std::vector<bit_offset_t> bit_sizes (num_columns); for (unsigned table_x = 0; table_x < num_columns; table_x++) { - access_range range_for_column (NULL, bit_range (0, 0)); + access_range range_for_column (nullptr, bit_range (0, 0)); if (m_btm.maybe_get_access_range_for_table_x (table_x, &range_for_column)) { diff --git a/gcc/analyzer/ana-state-to-diagnostic-state.cc b/gcc/analyzer/ana-state-to-diagnostic-state.cc new file mode 100644 index 000000000000..27012595c8ae --- /dev/null +++ b/gcc/analyzer/ana-state-to-diagnostic-state.cc @@ -0,0 +1,689 @@ +/* Creating diagnostic state graphs from ana::program_state. + Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by David Malcolm <dmalcolm@redhat.com>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#define INCLUDE_ALGORITHM +#define INCLUDE_MAP +#define INCLUDE_SET +#include "analyzer/common.h" + +#include "diagnostic-state-graphs.h" +#include "diagnostic-format-sarif.h" + +#include "analyzer/region-model.h" +#include "analyzer/program-state.h" +#include "analyzer/record-layout.h" +#include "analyzer/ana-state-to-diagnostic-state.h" + +#if ENABLE_ANALYZER + +#if __GNUC__ >= 10 +#pragma GCC diagnostic ignored "-Wformat" +#endif + +namespace ana { + +using namespace ::diagnostics::state_graphs; + +static void +set_wi_attr (state_node_ref state_node, + const char *attr_name, + const wide_int_ref &w, + signop sgn) +{ + pretty_printer pp; + pp_wide_int (&pp, w, sgn); + state_node.set_attr (attr_name, pp_formatted_text (&pp)); +} + +static void +set_type_attr (state_node_ref state_node, const_tree type) +{ + gcc_assert (type); + pretty_printer pp; + pp_format_decoder (&pp) = default_tree_printer; + pp_printf (&pp, "%T", type); + state_node.set_type (pp_formatted_text (&pp)); +} + +static void +set_bits_attr (state_node_ref state_node, + bit_range bits) +{ + pretty_printer pp; + bits.dump_to_pp (&pp); + state_node.set_attr ("bits", pp_formatted_text (&pp)); +} + +// class analyzer_state_graph : public diagnostics::digraphs::digraph + +analyzer_state_graph::analyzer_state_graph (const program_state &state, + const extrinsic_state &ext_state) +: m_state (state), + m_ext_state (ext_state), + m_mgr (*ext_state.get_engine ()->get_model_manager ()), + m_next_id (0) +{ + /* Find pointers to heap-allocated regions, and record their types, + so that we have a user-friendly way of showing the memory + (by field, rather than by byte offset). */ + for (auto cluster_iter : *state.m_region_model->get_store ()) + for (auto binding_iter : *cluster_iter.second) + { + const svalue *svalue = binding_iter.second; + if (const region *reg = svalue->maybe_get_region ()) + if (svalue->get_type () && !reg->get_type ()) + { + tree pointed_to_type = TREE_TYPE (svalue->get_type ()); + if (!VOID_TYPE_P (pointed_to_type)) + m_types_for_untyped_regions[reg] = pointed_to_type; + } + } + + /* TODO: look for vtable pointers at the top of dynamically-allocated + regions and use that type as a fallback. */ + + /* Find regions of interest. + Create elements per region, and build into hierarchy. + Add edges for pointers. */ + + /* Create stack, from top to bottom. */ + for (int i = state.m_region_model->get_stack_depth () - 1; i >= 0; --i) + { + const frame_region *reg = state.m_region_model->get_frame_at_index (i); + get_or_create_state_node (*reg); + } + + /* Create bound memory. */ + for (auto iter : *state.m_region_model->get_store ()) + { + const bool create_all = false; // "true" for verbose, for debugging + create_state_nodes_for_binding_cluster (*iter.second, create_all); + } + + /* TODO: Constraints. */ + + /* Annotate with information from state machines. */ + { + int i; + sm_state_map *smap; + FOR_EACH_VEC_ELT (state.m_checker_states, i, smap) + { + auto &sm = ext_state.get_sm (i); + for (const auto &iter : *smap) + sm.add_state_to_state_graph (*this, *iter.first, iter.second.m_state); + if (auto s = smap->get_global_state ()) + sm.add_global_state_to_state_graph (*this, s); + } + } + + /* Process pending edges. */ + while (m_pending_edges.size () > 0) + { + pending_edge item = m_pending_edges.back (); + m_pending_edges.pop_back (); + + /* Ensure we have a node for the dst region. This + could lead to additional pending edges. */ + auto dst_node = get_or_create_state_node (item.m_dst_reg); + add_edge (nullptr, item.m_src_node.m_node, dst_node.m_node); + } +} + +state_node_ref +analyzer_state_graph::get_or_create_state_node (const region ®) +{ + auto existing = m_region_to_state_node_map.find (®); + if (existing != m_region_to_state_node_map.end ()) + return *existing->second; + + auto ref = create_and_add_state_node (reg); + m_region_to_state_node_map[®] = &ref.m_node; + return ref; +} + +state_node_ref +analyzer_state_graph::create_and_add_state_node (const region ®) +{ + auto node = create_state_node (reg); + + state_node_ref result = *node; + if (auto parent_reg = reg.get_parent_region ()) + if (parent_reg->get_kind () != RK_ROOT) + { + auto parent_state_node = get_or_create_state_node (*parent_reg); + parent_state_node.m_node.add_child (std::move (node)); + return result; + } + add_node (std::move (node)); + return result; +} + +std::string +analyzer_state_graph::make_node_id (const char *prefix) +{ + return std::string (prefix) + "-" + std::to_string (m_next_id++); +} + +std::string +analyzer_state_graph::make_node_id (const region ®) +{ + const char *prefix = nullptr; + switch (reg.get_kind ()) + { + case RK_ROOT: + default: + gcc_unreachable (); + break; + + case RK_GLOBALS: + return "globals"; + case RK_CODE: + return "code"; + case RK_STACK: + return "stack"; + case RK_HEAP: + return "heap"; + + case RK_FRAME: + prefix = "frame-region"; + break; + case RK_FUNCTION: + prefix = "function-region"; + break; + case RK_LABEL: + prefix = "label-region"; + break; + case RK_THREAD_LOCAL: + prefix = "thread-local-region"; + break; + case RK_SYMBOLIC: + prefix = "symbolic-region"; + break; + case RK_DECL: + prefix = "decl-region"; + break; + case RK_FIELD: + prefix = "field-region"; + break; + case RK_ELEMENT: + prefix = "element-region"; + break; + case RK_OFFSET: + prefix = "offset-region"; + break; + case RK_SIZED: + prefix = "sized-region"; + break; + case RK_CAST: + prefix = "cast-region"; + break; + case RK_HEAP_ALLOCATED: + prefix = "heap-allocated-region"; + break; + case RK_ALLOCA: + prefix = "alloca-region"; + break; + case RK_STRING: + prefix = "string-region"; + break; + case RK_BIT_RANGE: + prefix = "bit-range-region"; + break; + case RK_VAR_ARG: + prefix = "var-arg-region"; + break; + case RK_ERRNO: + prefix = "errno-region"; + break; + case RK_PRIVATE: + prefix = "private-region"; + break; + case RK_UNKNOWN: + prefix = "unknown-region"; + break; + } + return std::string (prefix) + "-" + std::to_string (reg.get_id ()); +} + +std::unique_ptr<diagnostics::digraphs::node> +analyzer_state_graph:: +make_state_node (diagnostics::state_graphs::node_kind kind, + std::string id) +{ + auto node = std::make_unique<diagnostics::digraphs::node> (*this, std::move (id)); + state_node_ref node_ref (*node); + node_ref.set_node_kind (kind); + return node; +} + +std::unique_ptr<diagnostics::digraphs::node> +analyzer_state_graph:: +make_memspace_state_node (const region ®, + diagnostics::state_graphs::node_kind kind) +{ + return make_state_node (kind, make_node_id (reg)); +} + +std::unique_ptr<diagnostics::digraphs::node> +analyzer_state_graph::create_state_node (const region ®) +{ + std::unique_ptr<diagnostics::digraphs::node> node; + + switch (reg.get_kind ()) + { + default: + gcc_unreachable (); + + case RK_FRAME: + { + const frame_region &frame_reg + = static_cast<const frame_region &> (reg); + + node = make_state_node (diagnostics::state_graphs::node_kind::stack_frame, + make_node_id (reg)); + node->set_logical_loc + (m_logical_loc_mgr.key_from_tree (frame_reg.get_fndecl ())); + { + pretty_printer pp; + pp_format_decoder (&pp) = default_tree_printer; + pp_printf (&pp, "%E", frame_reg.get_fndecl ()); + node->set_attr (STATE_NODE_PREFIX, "function", + pp_formatted_text (&pp)); + } + } + break; + + case RK_GLOBALS: + node = make_memspace_state_node (reg, + diagnostics::state_graphs::node_kind::globals); + break; + case RK_CODE: + node = make_memspace_state_node (reg, + diagnostics::state_graphs::node_kind::code); + break; + case RK_FUNCTION: + node = make_memspace_state_node (reg, + diagnostics::state_graphs::node_kind::function); + // TODO + break; + + case RK_STACK: + node = make_memspace_state_node (reg, + diagnostics::state_graphs::node_kind::stack); + break; + case RK_HEAP: + node = make_memspace_state_node (reg, + diagnostics::state_graphs::node_kind::heap_); + break; + case RK_THREAD_LOCAL: + node = make_memspace_state_node (reg, + diagnostics::state_graphs::node_kind::thread_local_); + break; + case RK_ROOT: + gcc_unreachable (); + break; + case RK_SYMBOLIC: + node = make_memspace_state_node (reg, + diagnostics::state_graphs::node_kind::other); + break; + + case RK_DECL: + { + node = make_state_node (diagnostics::state_graphs::node_kind::variable, + make_node_id (reg)); + const decl_region &decl_reg + = static_cast<const decl_region &> (reg); + state_node_ref node_ref (*node); + { + pretty_printer pp; + pp_format_decoder (&pp) = default_tree_printer; + pp_printf (&pp, "%E", decl_reg.get_decl ()); + node_ref.set_name (pp_formatted_text (&pp)); + } + set_type_attr (*node, TREE_TYPE (decl_reg.get_decl ())); + } + break; + + case RK_FIELD: + case RK_ELEMENT: + /* These should be handled in populate_state_node_for_typed_region. */ + gcc_unreachable (); + break; + + case RK_LABEL: + case RK_OFFSET: + case RK_SIZED: + case RK_CAST: + case RK_STRING: + case RK_BIT_RANGE: + case RK_VAR_ARG: + case RK_ERRNO: + case RK_PRIVATE: + case RK_UNKNOWN: + node = make_state_node (diagnostics::state_graphs::node_kind::other, + make_node_id (reg)); + break; + + case RK_HEAP_ALLOCATED: + case RK_ALLOCA: + node = make_memspace_state_node (reg, + diagnostics::state_graphs::node_kind::dynalloc_buffer); + set_attr_for_dynamic_extents (reg, *node); + break; + } + gcc_assert (node); + + if (reg.get_base_region () == ®) + if (!reg.get_type ()) + { + auto search + = m_types_for_untyped_regions.find (®); + if (search != m_types_for_untyped_regions.end ()) + { + tree type_to_use = search->second; + set_type_attr (*node, type_to_use); + } + } + + return node; +} + +void +analyzer_state_graph:: +create_state_nodes_for_binding_cluster (const binding_cluster &cluster, + bool create_all) +{ + /* TODO: + - symbolic bindings + - get current svalue, so as to get "zeros" and "uninitialized". */ + + concrete_bindings_t conc_bindings; + for (auto iter : cluster) + { + const binding_key *key = iter.first; + const svalue *svalue = iter.second; + if (auto conc_key = key->dyn_cast_concrete_binding ()) + conc_bindings[conc_key->get_bit_range ()] = svalue; + if (const region *reg = svalue->maybe_get_region ()) + get_or_create_state_node (*reg); + } + + auto ref = get_or_create_state_node (*cluster.get_base_region ()); + + ref.m_node.add_child (create_state_node_for_conc_bindings (conc_bindings)); + + const region *typed_reg = cluster.get_base_region (); + if (!typed_reg->get_type ()) + { + auto search + = m_types_for_untyped_regions.find (cluster.get_base_region ()); + if (search != m_types_for_untyped_regions.end ()) + { + tree type_to_use = search->second; + typed_reg = m_mgr.get_cast_region (typed_reg, type_to_use); + } + } + + if (typed_reg->get_type ()) + populate_state_node_for_typed_region (ref, + *typed_reg, + conc_bindings, + create_all); + else + { + // TODO + } +} + +std::unique_ptr<diagnostics::digraphs::node> +analyzer_state_graph::create_state_node_for_conc_bindings (const concrete_bindings_t &conc_bindings) +{ + auto node = make_state_node (diagnostics::state_graphs::node_kind::other, + make_node_id ("concrete-bindings")); + for (auto iter : conc_bindings) + { + const bit_range bits = iter.first; + const svalue *sval = iter.second; + auto binding_state_node + = make_state_node (diagnostics::state_graphs::node_kind::other, + make_node_id ("binding")); + set_bits_attr (*binding_state_node, bits); + { + pretty_printer pp; + pp_format_decoder (&pp) = default_tree_printer; + sval->dump_to_pp (&pp, true); + binding_state_node->set_attr (STATE_NODE_PREFIX, "value", + pp_formatted_text (&pp)); + } + node->add_child (std::move (binding_state_node)); + } + return node; +} + +// Try to get the bit_range of REG within its base region +bool +analyzer_state_graph::get_bit_range_within_base_region (const region ®, + bit_range &out) +{ + region_offset start_offset = reg.get_offset (&m_mgr); + if (!start_offset.concrete_p ()) + return false; + region_offset next_offset = reg.get_next_offset (&m_mgr); + if (!next_offset.concrete_p ()) + return false; + out = bit_range (start_offset.get_bit_offset (), + next_offset.get_bit_offset () + - start_offset.get_bit_offset ()); + return true; +} + +void +analyzer_state_graph:: +populate_state_node_for_typed_region (state_node_ref node, + const region ®, + const concrete_bindings_t &conc_bindings, + bool create_all) +{ + const_tree reg_type = reg.get_type (); + gcc_assert (reg_type); + set_type_attr (node, reg_type); + + bit_range bits (0, 0); + if (get_bit_range_within_base_region (reg, bits)) + { + set_bits_attr (node, bits); + + auto search = conc_bindings.find (bits); + if (search != conc_bindings.end ()) + { + const svalue *bound_sval = search->second; + node.set_json_attr ("value", bound_sval->to_json ()); + if (const region *dst_reg = bound_sval->maybe_get_region ()) + m_pending_edges.push_back ({node, *dst_reg}); + } + } + + switch (TREE_CODE (reg_type)) + { + default: + break; + + case ARRAY_TYPE: + { + tree domain = TYPE_DOMAIN (reg_type); + if (!domain) + return; + const_tree max_idx = TYPE_MAX_VALUE (domain); + if (!max_idx) + return; + if (TREE_CODE (max_idx) != INTEGER_CST) + return; + const_tree min_idx = TYPE_MIN_VALUE (domain); + if (TREE_CODE (min_idx) != INTEGER_CST) + return; + for (offset_int idx = wi::to_offset (min_idx); + idx <= wi::to_offset (max_idx); + ++idx) + { + const_tree element_type = TREE_TYPE (reg_type); + const svalue *sval_index + = m_mgr.get_or_create_int_cst (domain, idx); + const region *child_reg + = m_mgr.get_element_region (®, + const_cast<tree> (element_type), + sval_index); + if (show_child_state_node_for_child_region_p (*child_reg, + conc_bindings, + create_all)) + { + auto child_state_node + = make_state_node + (diagnostics::state_graphs::node_kind::element, + make_node_id (*child_reg)); + set_wi_attr (*child_state_node, "index", idx, UNSIGNED); + + // Recurse: + gcc_assert (element_type); + populate_state_node_for_typed_region (*child_state_node, + *child_reg, + conc_bindings, + create_all); + node.m_node.add_child (std::move (child_state_node)); + } + } + } + break; + + case RECORD_TYPE: + { + const record_layout layout (reg_type); + for (auto item : layout) + { + if (item.m_is_padding) + { + const bit_range bits (0, item.m_bit_range.m_size_in_bits); + const region *child_reg + = m_mgr.get_bit_range (®, NULL_TREE, bits); + if (show_child_state_node_for_child_region_p (*child_reg, + conc_bindings, + create_all)) + { + auto child_state_node + = make_state_node + (diagnostics::state_graphs::node_kind::padding, + make_node_id (*child_reg)); + set_wi_attr (*child_state_node, "num_bits", + item.m_bit_range.m_size_in_bits, SIGNED); + node.m_node.add_child (std::move (child_state_node)); + } + } + else + { + const region *child_reg + = m_mgr.get_field_region (®, + const_cast<tree> (item.m_field)); + if (show_child_state_node_for_child_region_p (*child_reg, + conc_bindings, + create_all)) + { + auto child_state_node + = make_state_node + (diagnostics::state_graphs::node_kind::field, + make_node_id (*child_reg)); + { + pretty_printer pp; + pp_format_decoder (&pp) = default_tree_printer; + pp_printf (&pp, "%D", item.m_field); + child_state_node->set_attr (STATE_NODE_PREFIX, "name", + pp_formatted_text (&pp)); + } + + // Recurse: + populate_state_node_for_typed_region (*child_state_node, + *child_reg, + conc_bindings, + create_all); + node.m_node.add_child (std::move (child_state_node)); + } + } + } + } + break; + } +} + +void +analyzer_state_graph::set_attr_for_dynamic_extents (const region ®, + state_node_ref node_ref) +{ + const svalue *sval = m_state.m_region_model->get_dynamic_extents (®); + if (sval) + { + pretty_printer pp; + pp_format_decoder (&pp) = default_tree_printer; + if (auto cst = sval->maybe_get_constant ()) + pp_wide_int (&pp, wi::to_wide (cst), UNSIGNED); + else + sval->dump_to_pp (&pp, true); + node_ref.set_attr ("dynamic-extents", pp_formatted_text (&pp)); + } +} + +bool +analyzer_state_graph:: +show_child_state_node_for_child_region_p (const region ®, + const concrete_bindings_t &conc_bindings, + bool create_all) +{ + if (create_all) + return true; + bit_range reg_bits (0, 0); + if (!get_bit_range_within_base_region (reg, reg_bits)) + return true; + + /* Is any of "bits" bound? + TODO: ideally there would be a more efficient way to do this, using + spatial relationships. */ + for (auto iter : conc_bindings) + { + const bit_range bound_bits = iter.first; + if (bound_bits.intersects_p (reg_bits)) + return true; + } + return false; +} + +std::unique_ptr<diagnostics::digraphs::digraph> +program_state:: +make_diagnostic_state_graph (const extrinsic_state &ext_state) const +{ + return std::make_unique<analyzer_state_graph> (*this, ext_state); +} + +void +program_state::dump_sarif (const extrinsic_state &ext_state) const +{ + auto g = make_diagnostic_state_graph (ext_state); + g->dump (); +} + +} // namespace ana + +#endif /* #if ENABLE_ANALYZER */ diff --git a/gcc/analyzer/ana-state-to-diagnostic-state.h b/gcc/analyzer/ana-state-to-diagnostic-state.h new file mode 100644 index 000000000000..186e19d2f51e --- /dev/null +++ b/gcc/analyzer/ana-state-to-diagnostic-state.h @@ -0,0 +1,106 @@ +/* Creating diagnostic state graphs from ana::program_state. + Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by David Malcolm <dmalcolm@redhat.com>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_ANALYZER_ANA_STATE_TO_DIAGNOSTIC_STATE_H +#define GCC_ANALYZER_ANA_STATE_TO_DIAGNOSTIC_STATE_H + +#include "diagnostic-state-graphs.h" +#include "tree-logical-location.h" + +namespace ana { + +class analyzer_state_graph : public diagnostics::digraphs::digraph +{ +public: + analyzer_state_graph (const program_state &state, + const extrinsic_state &ext_state); + diagnostics::state_graphs::state_node_ref + get_or_create_state_node (const region ®); + +private: + struct pending_edge + { + diagnostics::state_graphs::state_node_ref m_src_node; + const region &m_dst_reg; + }; + + diagnostics::state_graphs::state_node_ref + create_and_add_state_node (const region ®); + + std::unique_ptr<diagnostics::digraphs::node> + make_state_node (diagnostics::state_graphs::node_kind kind, + std::string id); + + std::unique_ptr<diagnostics::digraphs::node> + make_memspace_state_node (const region ®, + enum diagnostics::state_graphs::node_kind kind); + + std::unique_ptr<diagnostics::digraphs::node> + create_state_node (const region ®); + + /* Spatially sorted concrete bindings. */ + typedef std::map<bit_range, const svalue *> concrete_bindings_t; + + void + create_state_nodes_for_binding_cluster (const binding_cluster &cluster, + bool create_all); + + std::unique_ptr<diagnostics::digraphs::node> + create_state_node_for_conc_bindings (const concrete_bindings_t &conc_bindings); + + // Try to get the bit_range of REG within its base region + bool + get_bit_range_within_base_region (const region ®, + bit_range &out); + + void + populate_state_node_for_typed_region (diagnostics::state_graphs::state_node_ref, + const region ®, + const concrete_bindings_t &conc_bindings, + bool create_all); + + void + set_attr_for_dynamic_extents (const region ®, + diagnostics::state_graphs::state_node_ref); + + bool + show_child_state_node_for_child_region_p (const region ®, + const concrete_bindings_t &conc_bindings, + bool create_all); + + std::unique_ptr<diagnostics::digraphs::node> + create_state_node_for_svalue (const svalue *sval); + + std::string make_node_id (const region ®); + std::string make_node_id (const char *prefix); + + tree_logical_location_manager m_logical_loc_mgr; + const program_state &m_state; + const extrinsic_state &m_ext_state; + region_model_manager &m_mgr; + std::map<const region *, diagnostics::digraphs::node *> m_region_to_state_node_map; + std::map<const region *, tree> m_types_for_untyped_regions; + unsigned m_next_id; + std::vector<pending_edge> m_pending_edges; +}; + +} // namespace ana + +#endif /* GCC_ANALYZER_ANA_STATE_TO_DIAGNOSTIC_STATE_H */ diff --git a/gcc/analyzer/analyzer-language.cc b/gcc/analyzer/analyzer-language.cc index 9a25baf67373..d4169f77cb85 100644 --- a/gcc/analyzer/analyzer-language.cc +++ b/gcc/analyzer/analyzer-language.cc @@ -114,7 +114,7 @@ on_finish_translation_unit (const translation_unit &tu) return; FILE *logfile = get_or_create_any_logfile (); - log_user the_logger (NULL); + log_user the_logger (nullptr); if (logfile) the_logger.set_logger (new logger (logfile, 0, 0, *global_dc->get_reference_printer ())); diff --git a/gcc/analyzer/analyzer-language.h b/gcc/analyzer/analyzer-language.h index 1987ee0bdb2a..a0c85a83a38f 100644 --- a/gcc/analyzer/analyzer-language.h +++ b/gcc/analyzer/analyzer-language.h @@ -35,7 +35,7 @@ class translation_unit public: /* Attempt to look up an value for identifier ID (e.g. in the headers that have been seen). If it is defined and an integer (e.g. either as a - macro or enum), return the INTEGER_CST value, otherwise return NULL. */ + macro or enum), return the INTEGER_CST value, otherwise return NULL_TREE. */ virtual tree lookup_constant_by_id (tree id) const = 0; virtual tree lookup_type_by_id (tree id) const = 0; virtual tree lookup_global_var_by_id (tree id) const = 0; diff --git a/gcc/analyzer/analyzer-logging.h b/gcc/analyzer/analyzer-logging.h index 3208989192bd..e85d293101d5 100644 --- a/gcc/analyzer/analyzer-logging.h +++ b/gcc/analyzer/analyzer-logging.h @@ -91,7 +91,7 @@ class log_scope /* The constructor for log_scope. - The normal case is that the logger is NULL, in which case this should + The normal case is that the logger is nullptr, in which case this should be largely a no-op. If we do have a logger, notify it that we're entering the given scope. @@ -139,7 +139,8 @@ log_scope::~log_scope () } } -/* A log_user is something that potentially uses a logger (which could be NULL). +/* A log_user is something that potentially uses a logger (which could be + nullptr). The log_user class keeps the reference-count of a logger up-to-date. */ @@ -169,8 +170,8 @@ class log_user FILE *get_logger_file () const { - if (m_logger == NULL) - return NULL; + if (m_logger == nullptr) + return nullptr; return m_logger->get_file (); } @@ -181,7 +182,7 @@ class log_user }; /* A shortcut for calling log from a log_user, handling the common - case where the underlying logger is NULL via a no-op. */ + case where the underlying logger is nullptr via a no-op. */ inline void log_user::log (const char *fmt, ...) const @@ -196,7 +197,7 @@ log_user::log (const char *fmt, ...) const } /* A shortcut for starting a log line from a log_user, - handling the common case where the underlying logger is NULL via + handling the common case where the underlying logger is nullptr via a no-op. */ inline void @@ -207,7 +208,7 @@ log_user::start_log_line () const } /* A shortcut for ending a log line from a log_user, - handling the common case where the underlying logger is NULL via + handling the common case where the underlying logger is nullptr via a no-op. */ inline void @@ -218,7 +219,7 @@ log_user::end_log_line () const } /* A shortcut for recording entry into a scope from a log_user, - handling the common case where the underlying logger is NULL via + handling the common case where the underlying logger is nullptr via a no-op. */ inline void @@ -229,7 +230,7 @@ log_user::enter_scope (const char *scope_name) } /* A shortcut for recording exit from a scope from a log_user, - handling the common case where the underlying logger is NULL via + handling the common case where the underlying logger is nullptr via a no-op. */ inline void diff --git a/gcc/analyzer/analyzer-pass.cc b/gcc/analyzer/analyzer-pass.cc index b3a0dfd9b1e5..559fb9439d24 100644 --- a/gcc/analyzer/analyzer-pass.cc +++ b/gcc/analyzer/analyzer-pass.cc @@ -48,15 +48,15 @@ class pass_analyzer : public ipa_opt_pass_d public: pass_analyzer(gcc::context *ctxt) : ipa_opt_pass_d (pass_data_analyzer, ctxt, - NULL, /* generate_summary */ - NULL, /* write_summary */ - NULL, /* read_summary */ - NULL, /* write_optimization_summary */ - NULL, /* read_optimization_summary */ - NULL, /* stmt_fixup */ + nullptr, /* generate_summary */ + nullptr, /* write_summary */ + nullptr, /* read_summary */ + nullptr, /* write_optimization_summary */ + nullptr, /* read_optimization_summary */ + nullptr, /* stmt_fixup */ 0, /* function_transform_todo_flags_start */ - NULL, /* function_transform */ - NULL) /* variable_transform */ + nullptr, /* function_transform */ + nullptr) /* variable_transform */ {} /* opt_pass methods: */ diff --git a/gcc/analyzer/analyzer.cc b/gcc/analyzer/analyzer.cc index 56cb370f147e..938ad6de89e4 100644 --- a/gcc/analyzer/analyzer.cc +++ b/gcc/analyzer/analyzer.cc @@ -518,7 +518,7 @@ make_label_text (bool can_colorize, const char *fmt, ...) va_start (ap, fmt); - text_info ti (_(fmt), &ap, 0, NULL, &rich_loc); + text_info ti (_(fmt), &ap, 0, nullptr, &rich_loc); pp_format (pp.get (), &ti); pp_output_formatted_text (pp.get ()); @@ -549,7 +549,7 @@ make_label_text_n (bool can_colorize, unsigned HOST_WIDE_INT n, const char *fmt = ngettext (singular_fmt, plural_fmt, n); - text_info ti (fmt, &ap, 0, NULL, &rich_loc); + text_info ti (fmt, &ap, 0, nullptr, &rich_loc); pp_format (pp.get (), &ti); pp_output_formatted_text (pp.get ()); diff --git a/gcc/analyzer/bounds-checking.cc b/gcc/analyzer/bounds-checking.cc index a3b134597c25..d2e2b34e2850 100644 --- a/gcc/analyzer/bounds-checking.cc +++ b/gcc/analyzer/bounds-checking.cc @@ -507,7 +507,7 @@ class concrete_buffer_over_read : public concrete_past_the_end concrete_buffer_over_read (const region_model &model, const region *reg, tree diag_arg, bit_range range, tree bit_bound) - : concrete_past_the_end (model, reg, diag_arg, range, bit_bound, NULL) + : concrete_past_the_end (model, reg, diag_arg, range, bit_bound, nullptr) {} const char *get_kind () const final override @@ -819,7 +819,7 @@ class concrete_buffer_under_read : public concrete_out_of_bounds concrete_buffer_under_read (const region_model &model, const region *reg, tree diag_arg, bit_range range) - : concrete_out_of_bounds (model, reg, diag_arg, range, NULL) + : concrete_out_of_bounds (model, reg, diag_arg, range, nullptr) {} const char *get_kind () const final override @@ -1119,7 +1119,7 @@ class symbolic_buffer_over_read : public symbolic_past_the_end const region *reg, tree diag_arg, tree offset, tree num_bytes, tree capacity) : symbolic_past_the_end (model, reg, diag_arg, offset, num_bytes, capacity, - NULL) + nullptr) { } diff --git a/gcc/analyzer/call-details.cc b/gcc/analyzer/call-details.cc index bca8658c2aaa..cb958436b334 100644 --- a/gcc/analyzer/call-details.cc +++ b/gcc/analyzer/call-details.cc @@ -43,7 +43,7 @@ namespace ana { call_details::call_details (const gcall &call, region_model *model, region_model_context *ctxt) : m_call (call), m_model (model), m_ctxt (ctxt), - m_lhs_type (NULL_TREE), m_lhs_region (NULL) + m_lhs_type (NULL_TREE), m_lhs_region (nullptr) { m_lhs_type = NULL_TREE; if (tree lhs = gimple_call_lhs (&call)) @@ -81,7 +81,7 @@ call_details::get_logger () const if (m_ctxt) return m_ctxt->get_logger (); else - return NULL; + return nullptr; } /* Get any uncertainty_t associated with the region_model_context. */ @@ -92,7 +92,7 @@ call_details::get_uncertainty () const if (m_ctxt) return m_ctxt->get_uncertainty (); else - return NULL; + return nullptr; } /* If the callsite has a left-hand-side region, set it to RESULT @@ -127,25 +127,25 @@ const_fn_p (const call_details &cd) /* If this CD is known to be a call to a function with __attribute__((const)), attempt to get a const_fn_result_svalue - based on the arguments, or return NULL otherwise. */ + based on the arguments, or return nullptr otherwise. */ static const svalue * maybe_get_const_fn_result (const call_details &cd) { if (!const_fn_p (cd)) - return NULL; + return nullptr; unsigned num_args = cd.num_args (); if (num_args > const_fn_result_svalue::MAX_INPUTS) /* Too many arguments. */ - return NULL; + return nullptr; auto_vec<const svalue *> inputs (num_args); for (unsigned arg_idx = 0; arg_idx < num_args; arg_idx++) { const svalue *arg_sval = cd.get_arg_svalue (arg_idx); if (!arg_sval->can_have_associated_state_p ()) - return NULL; + return nullptr; inputs.quick_push (arg_sval); } @@ -222,8 +222,8 @@ call_details::set_any_lhs_with_defaults () const if (lookup_function_attribute ("malloc")) { const region *new_reg - = m_model->get_or_create_region_for_heap_alloc (NULL, m_ctxt); - m_model->mark_region_as_unknown (new_reg, NULL); + = m_model->get_or_create_region_for_heap_alloc (nullptr, m_ctxt); + m_model->mark_region_as_unknown (new_reg, nullptr); sval = mgr->get_ptr_svalue (get_lhs_type (), new_reg); } else @@ -292,7 +292,7 @@ call_details::get_arg_svalue (unsigned idx) const /* If argument IDX's svalue at the callsite is of pointer type, return the region it points to. - Otherwise return NULL. */ + Otherwise return nullptr. */ const region * call_details::deref_ptr_arg (unsigned idx) const @@ -301,7 +301,7 @@ call_details::deref_ptr_arg (unsigned idx) const return m_model->deref_rvalue (ptr_sval, get_arg_tree (idx), m_ctxt); } -/* Attempt to get the string literal for argument IDX, or return NULL +/* Attempt to get the string literal for argument IDX, or return nullptr otherwise. For use when implementing "__analyzer_*" functions that take string literals. */ @@ -316,7 +316,7 @@ call_details::get_arg_string_literal (unsigned idx) const tree string_cst = string_reg->get_string_cst (); return TREE_STRING_POINTER (string_cst); } - return NULL; + return nullptr; } /* Attempt to get the fndecl used at this call, if known, or NULL_TREE diff --git a/gcc/analyzer/call-string.cc b/gcc/analyzer/call-string.cc index afa8004860b8..0bac8b437346 100644 --- a/gcc/analyzer/call-string.cc +++ b/gcc/analyzer/call-string.cc @@ -223,22 +223,22 @@ call_string::cmp_ptr_ptr (const void *pa, const void *pb) } /* Return the pointer to callee of the topmost call in the stack, - or NULL if stack is empty. */ + or nullptr if stack is empty. */ const supernode * call_string::get_callee_node () const { if(m_elements.is_empty ()) - return NULL; + return nullptr; return m_elements[m_elements.length () - 1].m_callee; } /* Return the pointer to caller of the topmost call in the stack, - or NULL if stack is empty. */ + or nullptr if stack is empty. */ const supernode * call_string::get_caller_node () const { if(m_elements.is_empty ()) - return NULL; + return nullptr; return m_elements[m_elements.length () - 1].m_caller; } @@ -266,7 +266,7 @@ call_string::validate () const /* ctor for the root/empty call_string. */ call_string::call_string () -: m_parent (NULL), m_elements () +: m_parent (nullptr), m_elements () { } diff --git a/gcc/analyzer/call-string.h b/gcc/analyzer/call-string.h index 642cf76e131d..f8c6a257cf50 100644 --- a/gcc/analyzer/call-string.h +++ b/gcc/analyzer/call-string.h @@ -129,12 +129,12 @@ class call_string } template <typename T> static inline void remove (T &entry) { - entry.m_key = element_t (NULL, NULL); + entry.m_key = element_t (nullptr, nullptr); } static const bool empty_zero_p = true; template <typename T> static inline bool is_empty (const T &entry) { - return entry.m_key.m_caller == NULL; + return entry.m_key.m_caller == nullptr; } template <typename T> static inline bool is_deleted (const T &entry) { @@ -142,8 +142,8 @@ class call_string } template <typename T> static inline void mark_empty (T &entry) { - entry.m_key = element_t (NULL, NULL); - entry.m_value = NULL; + entry.m_key = element_t (nullptr, nullptr); + entry.m_value = nullptr; } template <typename T> static inline void mark_deleted (T &entry) { diff --git a/gcc/analyzer/call-summary.cc b/gcc/analyzer/call-summary.cc index 33de3d638f2b..a094cbab87f0 100644 --- a/gcc/analyzer/call-summary.cc +++ b/gcc/analyzer/call-summary.cc @@ -71,9 +71,9 @@ call_summary::get_user_facing_desc (pretty_printer *pp) const if (tree result = DECL_RESULT (fndecl)) { const region *result_reg - = get_state ().m_region_model->get_lvalue (result, NULL); + = get_state ().m_region_model->get_lvalue (result, nullptr); const svalue *result_sval - = get_state ().m_region_model->get_store_value (result_reg, NULL); + = get_state ().m_region_model->get_store_value (result_reg, nullptr); switch (result_sval->get_kind ()) { default: @@ -172,7 +172,7 @@ call_summary_replay::call_summary_replay (const call_details &cd, This will be a top-level frame, since that's what's in the summary. */ const frame_region *summary_frame - = mgr->get_frame_region (NULL, called_fn); + = mgr->get_frame_region (nullptr, called_fn); unsigned idx = 0; for (tree iter_parm = DECL_ARGUMENTS (fndecl); iter_parm; @@ -210,7 +210,7 @@ call_summary_replay::call_summary_replay (const call_details &cd, /* Try to convert SUMMARY_SVAL in the summary to a corresponding svalue in the caller, caching the result. - Return NULL if the conversion is not possible. */ + Return nullptr if the conversion is not possible. */ const svalue * call_summary_replay::convert_svalue_from_summary (const svalue *summary_sval) @@ -252,7 +252,7 @@ call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval) const region *summary_reg = region_summary_sval->get_pointee (); const region *caller_reg = convert_region_from_summary (summary_reg); if (!caller_reg) - return NULL; + return nullptr; region_model_manager *mgr = get_manager (); const svalue *caller_ptr = mgr->get_ptr_svalue (summary_sval->get_type (), @@ -268,7 +268,7 @@ call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval) return summary_sval; case SK_SETJMP: - return NULL; // TODO + return nullptr; // TODO case SK_INITIAL: { @@ -282,7 +282,7 @@ call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval) const region *summary_reg = initial_summary_sval->get_region (); const region *caller_reg = convert_region_from_summary (summary_reg); if (!caller_reg) - return NULL; + return nullptr; const svalue *caller_sval = m_cd.get_model ()->get_store_value (caller_reg, m_cd.get_ctxt ()); return caller_sval; @@ -295,7 +295,7 @@ call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval) const svalue *summary_arg = unaryop_summary_sval->get_arg (); const svalue *caller_arg = convert_svalue_from_summary (summary_arg); if (!caller_arg) - return NULL; + return nullptr; region_model_manager *mgr = get_manager (); return mgr->get_or_create_unaryop (summary_sval->get_type (), unaryop_summary_sval->get_op (), @@ -309,11 +309,11 @@ call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval) const svalue *summary_arg0 = binop_summary_sval->get_arg0 (); const svalue *caller_arg0 = convert_svalue_from_summary (summary_arg0); if (!caller_arg0) - return NULL; + return nullptr; const svalue *summary_arg1 = binop_summary_sval->get_arg1 (); const svalue *caller_arg1 = convert_svalue_from_summary (summary_arg1); if (!caller_arg1) - return NULL; + return nullptr; region_model_manager *mgr = get_manager (); return mgr->get_or_create_binop (summary_sval->get_type (), binop_summary_sval->get_op (), @@ -328,10 +328,10 @@ call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval) region_model_manager *mgr = get_manager (); const svalue *summary_parent_sval = sub_summary_sval->get_parent (); if (!summary_parent_sval) - return NULL; + return nullptr; const region *summary_subregion = sub_summary_sval->get_subregion (); if (!summary_subregion) - return NULL; + return nullptr; return mgr->get_or_create_sub_svalue (summary_sval->get_type (), summary_parent_sval, summary_subregion); @@ -346,13 +346,13 @@ call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval) const svalue *caller_outer_size = convert_svalue_from_summary (summary_outer_size); if (!caller_outer_size) - return NULL; + return nullptr; const svalue *summary_inner_sval = repeated_summary_sval->get_inner_svalue (); const svalue *caller_inner_sval = convert_svalue_from_summary (summary_inner_sval); if (!caller_inner_sval) - return NULL; + return nullptr; region_model_manager *mgr = get_manager (); return mgr->get_or_create_repeated_svalue (summary_sval->get_type (), caller_outer_size, @@ -369,7 +369,7 @@ call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval) const svalue *caller_inner_sval = convert_svalue_from_summary (summary_inner_sval); if (!caller_inner_sval) - return NULL; + return nullptr; region_model_manager *mgr = get_manager (); return mgr->get_or_create_bits_within (summary_sval->get_type (), bits, @@ -384,7 +384,7 @@ call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval) const svalue *caller_arg_sval = convert_svalue_from_summary (summary_arg_sval); if (!caller_arg_sval) - return NULL; + return nullptr; region_model_manager *mgr = get_manager (); return mgr->get_or_create_unmergeable (caller_arg_sval); } @@ -400,14 +400,14 @@ call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval) = convert_svalue_from_summary (summary_base_sval); if (!(caller_base_sval && caller_base_sval->can_have_associated_state_p ())) - return NULL; + return nullptr; const svalue *summary_iter_sval = widening_summary_sval->get_iter_svalue (); const svalue *caller_iter_sval = convert_svalue_from_summary (summary_iter_sval); if (!(caller_iter_sval && caller_iter_sval->can_have_associated_state_p ())) - return NULL; + return nullptr; region_model_manager *mgr = get_manager (); return mgr->get_or_create_widening_svalue (summary_iter_sval->get_type (), @@ -491,7 +491,7 @@ call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval) const svalue *caller_input = convert_svalue_from_summary (summary_input); if (!caller_input) - return NULL; + return nullptr; inputs.safe_push (caller_input); } region_model_manager *mgr = get_manager (); @@ -516,7 +516,7 @@ call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval) const svalue *caller_input = convert_svalue_from_summary (summary_input); if (!caller_input) - return NULL; + return nullptr; inputs.safe_push (caller_input); } region_model_manager *mgr = get_manager (); @@ -532,7 +532,7 @@ call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval) /* Try to convert SUMMARY_REG in the summary to a corresponding region in the caller, caching the result. - Return NULL if the conversion is not possible. */ + Return nullptr if the conversion is not possible. */ const region * call_summary_replay::convert_region_from_summary (const region *summary_reg) @@ -596,7 +596,7 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg) const svalue *caller_ptr_sval = convert_svalue_from_summary (summary_ptr_sval); if (!caller_ptr_sval) - return NULL; + return nullptr; const region *caller_reg = get_caller_model ()->deref_rvalue (caller_ptr_sval, NULL_TREE, @@ -619,7 +619,7 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg) case SSA_NAME: /* We don't care about writes to locals within the summary. */ - return NULL; + return nullptr; case VAR_DECL: /* We don't care about writes to locals within the summary. */ @@ -628,12 +628,12 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg) return summary_reg; else /* Otherwise, we don't care about locals. */ - return NULL; + return nullptr; case RESULT_DECL: return m_cd.get_lhs_region (); case PARM_DECL: /* Writes (by value) to parms should be visible to the caller. */ - return NULL; + return nullptr; } } break; @@ -645,7 +645,7 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg) const region *caller_parent_reg = convert_region_from_summary (summary_parent_reg); if (!caller_parent_reg) - return NULL; + return nullptr; tree field = summary_field_reg->get_field (); return mgr->get_field_region (caller_parent_reg, field); } @@ -658,12 +658,12 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg) const region *caller_parent_reg = convert_region_from_summary (summary_parent_reg); if (!caller_parent_reg) - return NULL; + return nullptr; const svalue *summary_index = summary_element_reg->get_index (); const svalue *caller_index = convert_svalue_from_summary (summary_index); if (!caller_index) - return NULL; + return nullptr; return mgr->get_element_region (caller_parent_reg, summary_reg->get_type (), caller_index); @@ -677,13 +677,13 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg) const region *caller_parent_reg = convert_region_from_summary (summary_parent_reg); if (!caller_parent_reg) - return NULL; + return nullptr; const svalue *summary_byte_offset = summary_offset_reg->get_byte_offset (); const svalue *caller_byte_offset = convert_svalue_from_summary (summary_byte_offset); if (!caller_byte_offset) - return NULL; + return nullptr; return mgr->get_offset_region (caller_parent_reg, summary_reg->get_type (), caller_byte_offset); @@ -697,13 +697,13 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg) const region *caller_parent_reg = convert_region_from_summary (summary_parent_reg); if (!caller_parent_reg) - return NULL; + return nullptr; const svalue *summary_byte_size = summary_sized_reg->get_byte_size_sval (mgr); const svalue *caller_byte_size = convert_svalue_from_summary (summary_byte_size); if (!caller_byte_size) - return NULL; + return nullptr; return mgr->get_sized_region (caller_parent_reg, summary_reg->get_type (), caller_byte_size); @@ -715,7 +715,7 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg) const region *caller_parent_reg = convert_region_from_summary (summary_parent_reg); if (!caller_parent_reg) - return NULL; + return nullptr; return mgr->get_cast_region (caller_parent_reg, summary_reg->get_type ()); } @@ -731,7 +731,7 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg) } break; case RK_ALLOCA: - return NULL; + return nullptr; case RK_BIT_RANGE: { const bit_range_region *summary_bit_range_reg @@ -740,7 +740,7 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg) const region *caller_parent_reg = convert_region_from_summary (summary_parent_reg); if (!caller_parent_reg) - return NULL; + return nullptr; const bit_range &bits = summary_bit_range_reg->get_bits (); return mgr->get_bit_range (caller_parent_reg, summary_reg->get_type (), @@ -748,14 +748,14 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg) } break; case RK_VAR_ARG: - return NULL; + return nullptr; } } /* Try to convert SUMMARY_KEY in the summary to a corresponding binding key in the caller. - Return NULL if the conversion is not possible. */ + Return nullptr if the conversion is not possible. */ const binding_key * call_summary_replay::convert_key_from_summary (const binding_key *summary_key) @@ -767,7 +767,7 @@ call_summary_replay::convert_key_from_summary (const binding_key *summary_key) const region *summary_reg = symbolic_key->get_region (); const region *caller_reg = convert_region_from_summary (summary_reg); if (!caller_reg) - return NULL; + return nullptr; region_model_manager *mgr = get_manager (); store_manager *store_mgr = mgr->get_store_manager (); return store_mgr->get_symbolic_binding (caller_reg); @@ -780,7 +780,7 @@ call_summary_replay::add_svalue_mapping (const svalue *summary_sval, const svalue *caller_sval) { gcc_assert (summary_sval); - // CALLER_SVAL can be NULL + // CALLER_SVAL can be nullptr m_map_svalue_from_summary_to_caller.put (summary_sval, caller_sval); } @@ -791,7 +791,7 @@ call_summary_replay::add_region_mapping (const region *summary_reg, const region *caller_reg) { gcc_assert (summary_reg); - // CALLER_REG can be NULL + // CALLER_REG can be nullptr m_map_region_from_summary_to_caller.put (summary_reg, caller_reg); } diff --git a/gcc/analyzer/checker-event.cc b/gcc/analyzer/checker-event.cc index e041778e8d19..8cc5ac2b1da3 100644 --- a/gcc/analyzer/checker-event.cc +++ b/gcc/analyzer/checker-event.cc @@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "inlining-iterator.h" #include "tree-logical-location.h" #include "diagnostic-format-sarif.h" +#include "diagnostic-state-graphs.h" #include "analyzer/analyzer-logging.h" #include "analyzer/sm.h" @@ -106,12 +107,13 @@ event_kind_to_string (enum event_kind ek) checker_event::checker_event (enum event_kind kind, const event_loc_info &loc_info) -: m_kind (kind), m_loc (loc_info.m_loc), +: m_path (nullptr), + m_kind (kind), m_loc (loc_info.m_loc), m_original_fndecl (loc_info.m_fndecl), m_effective_fndecl (loc_info.m_fndecl), m_original_depth (loc_info.m_depth), m_effective_depth (loc_info.m_depth), - m_pending_diagnostic (NULL), m_emission_id (), + m_pending_diagnostic (nullptr), m_emission_id (), m_logical_loc (tree_logical_location_manager::key_from_tree (loc_info.m_fndecl)) { @@ -211,10 +213,11 @@ checker_event::debug () const pertinent data within the sm-state). */ void -checker_event::prepare_for_emission (checker_path *, +checker_event::prepare_for_emission (checker_path *path, pending_diagnostic *pd, diagnostic_event_id_t emission_id) { + m_path = path; m_pending_diagnostic = pd; m_emission_id = emission_id; @@ -222,6 +225,31 @@ checker_event::prepare_for_emission (checker_path *, print_desc (*pp.get ()); } +std::unique_ptr<diagnostics::digraphs::digraph> +checker_event::maybe_make_diagnostic_state_graph (bool debug) const +{ + const program_state *state = get_program_state (); + if (!state) + return nullptr; + + gcc_assert (m_path); + const extrinsic_state &ext_state = m_path->get_ext_state (); + + auto result = state->make_diagnostic_state_graph (ext_state); + + if (debug) + { + pretty_printer pp; + text_art::theme *theme = global_dc->get_diagram_theme (); + text_art::dump_to_pp (*state, theme, &pp); + result->set_attr (STATE_GRAPH_PREFIX, + "analyzer/program_state/", + pp_formatted_text (&pp)); + } + + return result; +} + /* class debug_event : public checker_event. */ /* Implementation of diagnostic_event::print_desc vfunc for @@ -344,12 +372,14 @@ region_creation_event_debug::print_desc (pretty_printer &pp) const /* class function_entry_event : public checker_event. */ -function_entry_event::function_entry_event (const program_point &dst_point) +function_entry_event::function_entry_event (const program_point &dst_point, + const program_state &state) : checker_event (event_kind::function_entry, event_loc_info (dst_point.get_supernode ()->get_start_location (), dst_point.get_fndecl (), - dst_point.get_stack_depth ())) + dst_point.get_stack_depth ())), + m_state (state) { } @@ -370,7 +400,7 @@ function_entry_event::print_desc (pretty_printer &pp) const diagnostic_event::meaning function_entry_event::get_meaning () const { - return meaning (VERB_enter, NOUN_function); + return meaning (verb::enter, noun::function); } /* class state_change_event : public checker_event. */ @@ -470,7 +500,7 @@ state_change_event::print_desc (pretty_printer &pp) const } else { - gcc_assert (m_origin == NULL); + gcc_assert (m_origin == nullptr); pp_printf (&pp, "global state: %qs -> %qs", m_from->get_name (), @@ -557,6 +587,12 @@ superedge_event::should_filter_p (int verbosity) const return false; } +const program_state * +superedge_event::get_program_state () const +{ + return &m_eedge.m_dest->get_state (); +} + /* superedge_event's ctor. */ superedge_event::superedge_event (enum event_kind kind, @@ -598,9 +634,9 @@ cfg_edge_event::get_meaning () const { const cfg_superedge& cfg_sedge = get_cfg_superedge (); if (cfg_sedge.true_value_p ()) - return meaning (VERB_branch, PROPERTY_true); + return meaning (verb::branch, property::true_); else if (cfg_sedge.false_value_p ()) - return meaning (VERB_branch, PROPERTY_false); + return meaning (verb::branch, property::false_); else return meaning (); } @@ -710,7 +746,7 @@ start_cfg_edge_event::maybe_describe_condition (bool can_colorize) const lhs, op, rhs); } } - return label_text::borrow (NULL); + return label_text::borrow (nullptr); } /* Subroutine of maybe_describe_condition above. @@ -747,9 +783,9 @@ start_cfg_edge_event::maybe_describe_condition (bool can_colorize, /* Only attempt to generate text for sufficiently simple expressions. */ if (!should_print_expr_p (lhs)) - return label_text::borrow (NULL); + return label_text::borrow (nullptr); if (!should_print_expr_p (rhs)) - return label_text::borrow (NULL); + return label_text::borrow (nullptr); /* Special cases for pointer comparisons against NULL. */ if (POINTER_TYPE_P (TREE_TYPE (lhs)) @@ -846,7 +882,7 @@ call_event::print_desc (pretty_printer &pp) const diagnostic_event::meaning call_event::get_meaning () const { - return meaning (VERB_call, NOUN_function); + return meaning (verb::call, noun::function); } /* Override of checker_event::is_call_p for calls. */ @@ -869,6 +905,14 @@ call_event::get_callee_fndecl () const return m_dest_snode->m_fun->decl; } +const program_state * +call_event::get_program_state () const +{ + /* Use the state at the source (at the caller), + rather than the one at the dest, which has a frame for the callee. */ + return &m_eedge.m_src->get_state (); +} + /* class return_event : public superedge_event. */ /* return_event's ctor. */ @@ -922,7 +966,7 @@ return_event::print_desc (pretty_printer &pp) const diagnostic_event::meaning return_event::get_meaning () const { - return meaning (VERB_return, NOUN_function); + return meaning (verb::return_, noun::function); } /* Override of checker_event::is_return_p for returns. */ @@ -949,8 +993,8 @@ start_consolidated_cfg_edges_event::print_desc (pretty_printer &pp) const diagnostic_event::meaning start_consolidated_cfg_edges_event::get_meaning () const { - return meaning (VERB_branch, - (m_edge_sense ? PROPERTY_true : PROPERTY_false)); + return meaning (verb::branch, + (m_edge_sense ? property::true_ : property::false_)); } /* class inlined_call_event : public checker_event. */ @@ -970,7 +1014,7 @@ inlined_call_event::print_desc (pretty_printer &pp) const diagnostic_event::meaning inlined_call_event::get_meaning () const { - return meaning (VERB_call, NOUN_function); + return meaning (verb::call, noun::function); } /* class setjmp_event : public checker_event. */ @@ -1210,7 +1254,16 @@ warning_event::print_desc (pretty_printer &pp) const diagnostic_event::meaning warning_event::get_meaning () const { - return meaning (VERB_danger, NOUN_unknown); + return meaning (verb::danger, noun::unknown); +} + +const program_state * +warning_event::get_program_state () const +{ + if (m_program_state) + return m_program_state.get (); + else + return &m_enode->get_state (); } } // namespace ana diff --git a/gcc/analyzer/checker-event.h b/gcc/analyzer/checker-event.h index 2f26b8daaa6a..cf24e777e29a 100644 --- a/gcc/analyzer/checker-event.h +++ b/gcc/analyzer/checker-event.h @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-logical-location.h" #include "analyzer/program-state.h" #include "analyzer/event-loc-info.h" +#include "diagnostic-digraphs.h" namespace ana { @@ -116,6 +117,7 @@ class checker_event : public diagnostic_event sarif_object &thread_flow_loc_obj) const override; /* Additional functionality. */ + enum event_kind get_kind () const { return m_kind; } tree get_fndecl () const { return m_effective_fndecl; } int get_original_stack_depth () const { return m_original_depth; } @@ -127,6 +129,12 @@ class checker_event : public diagnostic_event virtual bool is_function_entry_p () const { return false; } virtual bool is_return_p () const { return false; } + std::unique_ptr<diagnostics::digraphs::digraph> + maybe_make_diagnostic_state_graph (bool debug) const final override; + + virtual const program_state * + get_program_state () const { return nullptr; } + /* For use with %@. */ const diagnostic_event_id_t *get_id_ptr () const { @@ -142,7 +150,8 @@ class checker_event : public diagnostic_event checker_event (enum event_kind kind, const event_loc_info &loc_info); - public: + private: + const checker_path *m_path; const enum event_kind m_kind; protected: location_t m_loc; @@ -224,6 +233,12 @@ class statement_event : public checker_event void print_desc (pretty_printer &) const final override; + const program_state * + get_program_state () const final override + { + return &m_dst_state; + } + const gimple * const m_stmt; const program_state m_dst_state; }; @@ -334,17 +349,29 @@ class region_creation_event_debug : public region_creation_event class function_entry_event : public checker_event { public: - function_entry_event (const event_loc_info &loc_info) - : checker_event (event_kind::function_entry, loc_info) + function_entry_event (const event_loc_info &loc_info, + const program_state &state) + : checker_event (event_kind::function_entry, loc_info), + m_state (state) { } - function_entry_event (const program_point &dst_point); + function_entry_event (const program_point &dst_point, + const program_state &state); void print_desc (pretty_printer &pp) const override; meaning get_meaning () const override; bool is_function_entry_p () const final override { return true; } + + const program_state * + get_program_state () const final override + { + return &m_state; + } + +private: + const program_state &m_state; }; /* Subclass of checker_event describing a state change. */ @@ -365,6 +392,12 @@ class state_change_event : public checker_event void print_desc (pretty_printer &pp) const final override; meaning get_meaning () const override; + const program_state * + get_program_state () const final override + { + return &m_dst_state; + } + const function *get_dest_function () const { return m_dst_state.get_current_function (); @@ -407,6 +440,9 @@ class superedge_event : public checker_event bool should_filter_p (int verbosity) const; + const program_state * + get_program_state () const override; + protected: superedge_event (enum event_kind kind, const exploded_edge &eedge, const event_loc_info &loc_info); @@ -517,6 +553,9 @@ class call_event : public superedge_event bool is_call_p () const final override; + const program_state * + get_program_state () const final override; + protected: tree get_caller_fndecl () const; tree get_callee_fndecl () const; @@ -791,16 +830,22 @@ class warning_event : public checker_event warning_event (const event_loc_info &loc_info, const exploded_node *enode, const state_machine *sm, - tree var, state_machine::state_t state) + tree var, state_machine::state_t state, + const program_state *program_state_ = nullptr) : checker_event (event_kind::warning, loc_info), m_enode (enode), m_sm (sm), m_var (var), m_state (state) { + if (program_state_) + m_program_state = std::make_unique<program_state> (*program_state_); } void print_desc (pretty_printer &pp) const final override; meaning get_meaning () const override; + const program_state * + get_program_state () const final override; + const exploded_node *get_exploded_node () const { return m_enode; } private: @@ -808,6 +853,9 @@ class warning_event : public checker_event const state_machine *m_sm; tree m_var; state_machine::state_t m_state; + /* Optional copy of program state, for when this is different from + m_enode's state: */ + std::unique_ptr<program_state> m_program_state; }; } // namespace ana diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc index 9bde6f2f8351..45593e0abe37 100644 --- a/gcc/analyzer/checker-path.cc +++ b/gcc/analyzer/checker-path.cc @@ -89,7 +89,7 @@ checker_path::maybe_log (logger *logger, const char *desc) const { logger->start_log_line (); logger->log_partial ("%s[%i]: %s ", desc, i, - event_kind_to_string (m_events[i]->m_kind)); + event_kind_to_string (m_events[i]->get_kind ())); m_events[i]->dump (logger->get_printer ()); logger->end_log_line (); } @@ -103,7 +103,7 @@ checker_path::add_event (std::unique_ptr<checker_event> event) m_logger->start_log_line (); m_logger->log_partial ("added event[%i]: %s ", m_events.length (), - event_kind_to_string (event.get ()->m_kind)); + event_kind_to_string (event.get ()->get_kind ())); event.get ()->dump (m_logger->get_printer ()); m_logger->end_log_line (); } @@ -123,7 +123,7 @@ checker_path::debug () const fprintf (stderr, "[%i]: %s \"%s\"\n", i, - event_kind_to_string (m_events[i]->m_kind), + event_kind_to_string (m_events[i]->get_kind ()), event_desc.get ()); } } @@ -167,8 +167,8 @@ checker_path::cfg_edge_pair_at_p (unsigned idx) const { if (m_events.length () < idx + 1) return false; - return (m_events[idx]->m_kind == event_kind::start_cfg_edge - && m_events[idx + 1]->m_kind == event_kind::end_cfg_edge); + return (m_events[idx]->get_kind () == event_kind::start_cfg_edge + && m_events[idx + 1]->get_kind () == event_kind::end_cfg_edge); } /* Consider a call from "outer" to "middle" which calls "inner", @@ -254,7 +254,7 @@ checker_path::inject_any_inlined_call_events (logger *logger) { logger->start_log_line (); logger->log_partial ("event[%i]: %s ", ev_idx, - event_kind_to_string (curr_event->m_kind)); + event_kind_to_string (curr_event->get_kind ())); curr_event->dump (logger->get_printer ()); logger->end_log_line (); for (inlining_iterator iter (curr_event->get_location ()); diff --git a/gcc/analyzer/checker-path.h b/gcc/analyzer/checker-path.h index 80c975c6a745..3c174bf8dd18 100644 --- a/gcc/analyzer/checker-path.h +++ b/gcc/analyzer/checker-path.h @@ -32,8 +32,10 @@ class checker_path : public diagnostic_path { public: checker_path (const logical_location_manager &logical_loc_mgr, + const extrinsic_state &ext_state, logger *logger) : diagnostic_path (logical_loc_mgr), + m_ext_state (ext_state), m_thread ("main"), m_logger (logger) {} @@ -59,6 +61,8 @@ class checker_path : public diagnostic_path return m_thread; } + const extrinsic_state &get_ext_state () const { return m_ext_state; } + checker_event *get_checker_event (int idx) { return m_events[idx]; @@ -140,6 +144,8 @@ class checker_path : public diagnostic_path private: DISABLE_COPY_AND_ASSIGN(checker_path); + const extrinsic_state &m_ext_state; + simple_diagnostic_thread m_thread; /* The events that have occurred along this path. */ diff --git a/gcc/analyzer/common.h b/gcc/analyzer/common.h index cb030043d8ad..148bfddb7114 100644 --- a/gcc/analyzer/common.h +++ b/gcc/analyzer/common.h @@ -22,6 +22,8 @@ along with GCC; see the file COPYING3. If not see #define GCC_ANALYZER_COMMON_H #include "config.h" +#define INCLUDE_MAP +#define INCLUDE_STRING #define INCLUDE_VECTOR #include "system.h" #include "coretypes.h" @@ -207,14 +209,14 @@ class region_offset { public: region_offset () - : m_base_region (NULL), m_offset (0), m_sym_offset (NULL) + : m_base_region (nullptr), m_offset (0), m_sym_offset (nullptr) { } static region_offset make_concrete (const region *base_region, bit_offset_t offset) { - return region_offset (base_region, offset, NULL); + return region_offset (base_region, offset, nullptr); } static region_offset make_symbolic (const region *base_region, const svalue *sym_offset) @@ -226,8 +228,8 @@ class region_offset const region *get_base_region () const { return m_base_region; } - bool concrete_p () const { return m_sym_offset == NULL; } - bool symbolic_p () const { return m_sym_offset != NULL; } + bool concrete_p () const { return m_sym_offset == nullptr; } + bool symbolic_p () const { return m_sym_offset != nullptr; } bit_offset_t get_bit_offset () const { @@ -304,7 +306,7 @@ class known_function } virtual const builtin_known_function * - dyn_cast_builtin_kf () const { return NULL; } + dyn_cast_builtin_kf () const { return nullptr; } }; /* Subclass of known_function for builtin functions. */ @@ -565,13 +567,13 @@ class consolidation_map delete (*iter).second; } - /* Get the instance of T for K if one exists, or NULL. */ + /* Get the instance of T for K if one exists, or nullptr. */ T *get (const key_t &k) const { if (instance_t **slot = const_cast<inner_map_t &> (m_inner_map).get (k)) return *slot; - return NULL; + return nullptr; } /* Take ownership of INSTANCE. */ diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc index 869e437d7c51..58c60feae369 100644 --- a/gcc/analyzer/constraint-manager.cc +++ b/gcc/analyzer/constraint-manager.cc @@ -609,7 +609,7 @@ bounded_ranges::canonicalize () { bounded_range *prev = &m_ranges[i - 1]; const bounded_range *next = &m_ranges[i]; - if (prev->intersects_p (*next, NULL) + if (prev->intersects_p (*next, nullptr) || (can_plus_one_p (prev->m_upper) && tree_int_cst_equal (plus_one (prev->m_upper), next->m_lower))) @@ -1058,7 +1058,7 @@ bounded_ranges_manager::log_stats (logger *logger, bool show_objs) const /* equiv_class's default ctor. */ equiv_class::equiv_class () -: m_constant (NULL_TREE), m_cst_sval (NULL), m_vars () +: m_constant (NULL_TREE), m_cst_sval (nullptr), m_vars () { } @@ -3024,7 +3024,7 @@ on_liveness_change (const svalue_set &live_svalues, const region_model *model) { dead_svalue_purger p (live_svalues, model); - purge (p, NULL); + purge (p, nullptr); } class svalue_purger @@ -3047,7 +3047,7 @@ void constraint_manager::purge_state_involving (const svalue *sval) { svalue_purger p (sval); - purge (p, NULL); + purge (p, nullptr); } /* Comparator for use by constraint_manager::canonicalize. @@ -3191,7 +3191,7 @@ class merger_fact_visitor : public fact_visitor { /* Special-case for widening. */ if (lhs->get_kind () == SK_WIDENING) - if (!m_cm_b->get_equiv_class_by_svalue (lhs, NULL)) + if (!m_cm_b->get_equiv_class_by_svalue (lhs, nullptr)) { /* LHS isn't constrained within m_cm_b. */ bool sat = m_out->add_constraint (lhs, code, rhs); @@ -3515,7 +3515,7 @@ test_constraint_conditions () ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, x); ADD_SAT_CONSTRAINT (model, int_42, EQ_EXPR, int_42); /* ...even when done directly via svalues: */ - const svalue *sval_int_42 = model.get_rvalue (int_42, NULL); + const svalue *sval_int_42 = model.get_rvalue (int_42, nullptr); bool sat = model.get_constraints ()->add_constraint (sval_int_42, EQ_EXPR, sval_int_42); @@ -4304,8 +4304,8 @@ test_purging (void) ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 1); /* Purge state for "a". */ - const svalue *sval_a = model.get_rvalue (a, NULL); - model.purge_state_involving (sval_a, NULL); + const svalue *sval_a = model.get_rvalue (a, nullptr); + model.purge_state_involving (sval_a, nullptr); model.canonicalize (); /* We should have an empty constraint_manager. */ ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 0); @@ -4322,8 +4322,8 @@ test_purging (void) ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 2); /* Purge state for "a". */ - const svalue *sval_a = model.get_rvalue (a, NULL); - model.purge_state_involving (sval_a, NULL); + const svalue *sval_a = model.get_rvalue (a, nullptr); + model.purge_state_involving (sval_a, nullptr); model.canonicalize (); /* We should just have the constraint/ECs involving b != 0. */ ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 2); @@ -4341,8 +4341,8 @@ test_purging (void) ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 1); /* Purge state for "a". */ - const svalue *sval_a = model.get_rvalue (a, NULL); - model.purge_state_involving (sval_a, NULL); + const svalue *sval_a = model.get_rvalue (a, nullptr); + model.purge_state_involving (sval_a, nullptr); model.canonicalize (); /* We should just have the EC involving b == 0. */ ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 1); @@ -4359,8 +4359,8 @@ test_purging (void) ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 0); /* Purge state for "a". */ - const svalue *sval_a = model.get_rvalue (a, NULL); - model.purge_state_involving (sval_a, NULL); + const svalue *sval_a = model.get_rvalue (a, nullptr); + model.purge_state_involving (sval_a, nullptr); model.canonicalize (); /* We should have an empty constraint_manager. */ ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 0); @@ -4377,8 +4377,8 @@ test_purging (void) ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 1); /* Purge state for "a". */ - const svalue *sval_a = model.get_rvalue (a, NULL); - model.purge_state_involving (sval_a, NULL); + const svalue *sval_a = model.get_rvalue (a, nullptr); + model.purge_state_involving (sval_a, nullptr); model.canonicalize (); /* We should just have the constraint/ECs involving b != 0. */ ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 2); @@ -4396,8 +4396,8 @@ test_purging (void) ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 0); /* Purge state for "a". */ - const svalue *sval_a = model.get_rvalue (a, NULL); - model.purge_state_involving (sval_a, NULL); + const svalue *sval_a = model.get_rvalue (a, nullptr); + model.purge_state_involving (sval_a, nullptr); model.canonicalize (); /* We should just have the EC involving b == 0. */ ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 1); @@ -4459,8 +4459,8 @@ test_bounded_range () bounded_range br_u8_64_128 (u8_64, u8_128); ASSERT_DUMP_BOUNDED_RANGE_EQ (br_u8_64_128, "[64, 128]"); - ASSERT_FALSE (br_u8_0.intersects_p (br_u8_64_128, NULL)); - ASSERT_FALSE (br_u8_64_128.intersects_p (br_u8_0, NULL)); + ASSERT_FALSE (br_u8_0.intersects_p (br_u8_64_128, nullptr)); + ASSERT_FALSE (br_u8_64_128.intersects_p (br_u8_0, nullptr)); bounded_range br_u8_128_255 (u8_128, u8_255); ASSERT_DUMP_BOUNDED_RANGE_EQ (br_u8_128_255, "[128, 255]"); diff --git a/gcc/analyzer/constraint-manager.h b/gcc/analyzer/constraint-manager.h index a26b48ddef44..4339ea665d84 100644 --- a/gcc/analyzer/constraint-manager.h +++ b/gcc/analyzer/constraint-manager.h @@ -226,8 +226,8 @@ class bounded_ranges_manager { return k->get_hash (); } - static inline bool is_empty (key_type k) { return k == NULL; } - static inline void mark_empty (key_type &k) { k = NULL; } + static inline bool is_empty (key_type k) { return k == nullptr; } + static inline void mark_empty (key_type &k) { k = nullptr; } static inline bool is_deleted (key_type k) { return k == reinterpret_cast<key_type> (1); diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc index e5d1a2571a04..c083b8c21be4 100644 --- a/gcc/analyzer/diagnostic-manager.cc +++ b/gcc/analyzer/diagnostic-manager.cc @@ -63,7 +63,7 @@ class epath_finder public: epath_finder (const exploded_graph &eg) : m_eg (eg), - m_sep (NULL) + m_sep (nullptr) { /* This is shared by all diagnostics, but only needed if !flag_analyzer_feasibility. */ @@ -125,7 +125,7 @@ class epath_finder within ENODE. Ideally we want to report the shortest feasible path. - Return NULL if we could not find a feasible path + Return nullptr if we could not find a feasible path (when flag_analyzer_feasibility is true). If flag_analyzer_feasibility is false, then simply return the @@ -177,7 +177,7 @@ epath_finder::get_best_epath (const exploded_node *enode, logger->log ("rejecting %qs at EN: %i, SN: %i (sd: %i)" " due to not finding feasible path", desc, enode->m_index, snode_idx, diag_idx); - return NULL; + return nullptr; } } else @@ -221,7 +221,7 @@ class feasible_worklist { public: feasible_worklist (const shortest_paths<eg_traits, exploded_path> &sep) - : m_queue (key_t (*this, NULL)), + : m_queue (key_t (*this, nullptr)), m_sep (sep) { } @@ -416,7 +416,7 @@ epath_finder::explore_feasible_paths (const exploded_node *target_enode, a limit. */ /* Set this if we find a feasible path to TARGET_ENODE. */ - std::unique_ptr<exploded_path> best_path = NULL; + std::unique_ptr<exploded_path> best_path = nullptr; { auto_checking_feasibility sentinel (mgr); @@ -508,7 +508,7 @@ process_worklist_item (feasible_worklist *worklist, std::unique_ptr<rejected_constraint> rc; if (succ_state.maybe_update_for_edge (logger, succ_eedge, nullptr, &rc)) { - gcc_assert (rc == NULL); + gcc_assert (rc == nullptr); feasible_node *succ_fnode = fg->add_node (succ_eedge->m_dest, succ_state, @@ -612,7 +612,7 @@ dump_trimmed_graph (const exploded_node *target_enode, pp_printf (&pp, "%s.%s.%i.to-en%i.tg.dot", dump_base_name, desc, diag_idx, target_enode->m_index); char *filename = xstrdup (pp_formatted_text (&pp)); - tg.dump_dot (filename, NULL, args); + tg.dump_dot (filename, nullptr, args); free (filename); } @@ -630,7 +630,7 @@ epath_finder::dump_feasible_graph (const exploded_node *target_enode, pp_printf (&pp, "%s.%s.%i.to-en%i.fg.dot", dump_base_name, desc, diag_idx, target_enode->m_index); char *filename = xstrdup (pp_formatted_text (&pp)); - fg.dump_dot (filename, NULL, args); + fg.dump_dot (filename, nullptr, args); free (filename); } @@ -687,6 +687,11 @@ saved_diagnostic::operator== (const saved_diagnostic &other) const for (unsigned i = 0; i < m_notes.length (); i++) if (!m_notes[i]->equal_p (*other.m_notes[i])) return false; + + // Don't deduplicate dump_path_diagnostic instances + if (!strcmp (m_d->get_kind (), "dump_path_diagnostic")) + return this == &other; + return (m_sm == other.m_sm /* We don't compare m_enode. */ && m_snode == other.m_snode @@ -822,7 +827,7 @@ saved_diagnostic::dump_as_dot_node (pretty_printer *pp) const /* Use PF to find the best exploded_path for this saved_diagnostic, and store it in m_best_epath. - If we don't have a specific location in m_loc and m_stmt is still NULL, + If we don't have a specific location in m_loc and m_stmt is still nullptr, use m_stmt_finder on the epath to populate m_stmt. Return true if a best path was found. */ @@ -831,20 +836,20 @@ saved_diagnostic::calc_best_epath (epath_finder *pf) { logger *logger = pf->get_logger (); LOG_SCOPE (logger); - m_problem = NULL; + m_problem = nullptr; m_best_epath = pf->get_best_epath (m_enode, m_stmt, *m_d, m_d->get_kind (), m_idx, &m_problem); /* Handle failure to find a feasible path. */ - if (m_best_epath == NULL) + if (m_best_epath == nullptr) return false; gcc_assert (m_best_epath); if (m_loc == UNKNOWN_LOCATION) { - if (m_stmt == NULL) + if (m_stmt == nullptr) { gcc_assert (m_stmt_finder); m_stmt = m_stmt_finder->find_stmt (*m_best_epath); @@ -1193,7 +1198,7 @@ diagnostic_manager::add_diagnostic (const pending_location &ploc, std::unique_ptr<pending_diagnostic> d) { gcc_assert (ploc.m_enode); - return add_diagnostic (NULL, ploc, NULL_TREE, NULL, 0, std::move (d)); + return add_diagnostic (nullptr, ploc, NULL_TREE, nullptr, 0, std::move (d)); } /* Add PN to the most recent saved_diagnostic. */ @@ -1338,7 +1343,7 @@ class dedupe_hash_map_traits template <typename T> static inline void mark_empty (T &entry) { - entry.m_key = NULL; + entry.m_key = nullptr; } template <typename T> static inline bool is_deleted (const T &entry) @@ -1348,7 +1353,7 @@ class dedupe_hash_map_traits template <typename T> static inline bool is_empty (const T &entry) { - return entry.m_key == NULL; + return entry.m_key == nullptr; } static const bool empty_zero_p = true; }; @@ -1581,6 +1586,7 @@ diagnostic_manager::emit_saved_diagnostic (const exploded_graph &eg, /* This is the diagnostic_path subclass that will be built for the diagnostic. */ checker_path emission_path (get_logical_location_manager (), + eg.get_ext_state (), get_logger ()); /* Populate emission_path with a full description of EPATH. */ @@ -1614,7 +1620,7 @@ diagnostic_manager::emit_saved_diagnostic (const exploded_graph &eg, trailing eedge stashed, add any events for it. This is for use in handling longjmp, to show where a longjmp is rewinding to. */ if (sd.m_trailing_eedge) - add_events_for_eedge (pb, *sd.m_trailing_eedge, &emission_path, NULL); + add_events_for_eedge (pb, *sd.m_trailing_eedge, &emission_path, nullptr); emission_path.inject_any_inlined_call_events (get_logger ()); @@ -1698,7 +1704,7 @@ diagnostic_manager::build_emission_path (const path_builder &pb, { emission_path->add_region_creation_events (pb.get_pending_diagnostic (), - reg, NULL, + reg, nullptr, event_loc_info (DECL_SOURCE_LOCATION (decl), NULL_TREE, 0), @@ -1757,7 +1763,7 @@ diagnostic_manager::add_event_on_final_node (const path_builder &pb, = src_model->get_dynamic_extents (base_reg); const svalue *new_extents = dst_model->get_dynamic_extents (base_reg); - if (old_extents == NULL && new_extents != NULL) + if (old_extents == nullptr && new_extents != nullptr) switch (base_reg->get_kind ()) { default: @@ -1970,7 +1976,7 @@ struct null_assignment_sm_context : public sm_context tree var) final override { const svalue *var_old_sval - = m_old_state->m_region_model->get_rvalue (var, NULL); + = m_old_state->m_region_model->get_rvalue (var, nullptr); const sm_state_map *old_smap = m_old_state->m_checker_states[m_sm_idx]; state_machine::state_t current @@ -1999,7 +2005,7 @@ struct null_assignment_sm_context : public sm_context return; const svalue *var_new_sval - = m_new_state->m_region_model->get_rvalue (var, NULL); + = m_new_state->m_region_model->get_rvalue (var, nullptr); const supernode *supernode = m_point->get_supernode (); int stack_depth = m_point->get_stack_depth (); @@ -2086,7 +2092,7 @@ struct null_assignment_sm_context : public sm_context if (!assign_stmt) return NULL_TREE; if (const svalue *sval - = m_new_state->m_region_model->get_gassign_result (assign_stmt, NULL)) + = m_new_state->m_region_model->get_gassign_result (assign_stmt, nullptr)) if (tree cst = sval->maybe_get_constant ()) if (::zerop(cst)) return gimple_assign_lhs (assign_stmt); @@ -2247,7 +2253,7 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb, { const extrinsic_state &ext_state = pb.get_ext_state (); program_state old_state (iter_state); - iter_state.m_region_model->on_assignment (assign, NULL); + iter_state.m_region_model->on_assignment (assign, nullptr); for (unsigned i = 0; i < ext_state.get_num_checkers (); i++) { const state_machine &sm = ext_state.get_sm (i); @@ -2293,7 +2299,7 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb, = src_model->get_dynamic_extents (base_reg); const svalue *new_extents = dst_model->get_dynamic_extents (base_reg); - if (old_extents == NULL && new_extents != NULL) + if (old_extents == nullptr && new_extents != nullptr) switch (base_reg->get_kind ()) { default: @@ -2599,19 +2605,19 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path, { label_text sval_desc = sval->get_desc (); log ("considering event %i (%s), with sval: %qs, state: %qs", - idx, event_kind_to_string (base_event->m_kind), + idx, event_kind_to_string (base_event->get_kind ()), sval_desc.get (), state->get_name ()); } else log ("considering event %i (%s), with global state: %qs", - idx, event_kind_to_string (base_event->m_kind), + idx, event_kind_to_string (base_event->get_kind ()), state->get_name ()); } else log ("considering event %i", idx); } - switch (base_event->m_kind) + switch (base_event->get_kind ()) { default: gcc_unreachable (); @@ -2718,7 +2724,7 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path, log ("filtering events %i and %i: CFG edge", idx, idx + 1); path->delete_event (idx); /* Also delete the corresponding event_kind::end_cfg_edge. */ - gcc_assert (path->get_checker_event (idx)->m_kind + gcc_assert (path->get_checker_event (idx)->get_kind () == event_kind::end_cfg_edge); path->delete_event (idx); } @@ -3038,7 +3044,7 @@ same_line_as_p (const expanded_location &ref_exp_loc, const checker_event *ev = path->get_checker_event (idx); expanded_location idx_exp_loc = expand_location (ev->get_location ()); gcc_assert (ref_exp_loc.file); - if (idx_exp_loc.file == NULL) + if (idx_exp_loc.file == nullptr) return false; if (strcmp (ref_exp_loc.file, idx_exp_loc.file)) return false; @@ -3103,13 +3109,13 @@ diagnostic_manager::consolidate_conditions (checker_path *path) const = path->get_checker_event (start_idx); expanded_location start_exp_loc = expand_location (old_start_ev->get_location ()); - if (start_exp_loc.file == NULL) + if (start_exp_loc.file == nullptr) continue; if (!same_line_as_p (start_exp_loc, path, start_idx + 1)) continue; /* Are we looking for a run of all TRUE edges, or all FALSE edges? */ - gcc_assert (old_start_ev->m_kind == event_kind::start_cfg_edge); + gcc_assert (old_start_ev->get_kind () == event_kind::start_cfg_edge); const start_cfg_edge_event *old_start_cfg_ev = (const start_cfg_edge_event *)old_start_ev; const cfg_superedge& first_cfg_sedge @@ -3132,7 +3138,7 @@ diagnostic_manager::consolidate_conditions (checker_path *path) const { const checker_event *iter_ev = path->get_checker_event (next_idx); - gcc_assert (iter_ev->m_kind == event_kind::start_cfg_edge); + gcc_assert (iter_ev->get_kind () == event_kind::start_cfg_edge); const start_cfg_edge_event *iter_cfg_ev = (const start_cfg_edge_event *)iter_ev; const cfg_superedge& iter_cfg_sedge @@ -3190,11 +3196,13 @@ diagnostic_manager::consolidate_unwind_events (checker_path *path) const start_idx++) { /* Find a run of consecutive unwind_event instances. */ - if (path->get_checker_event (start_idx)->m_kind != event_kind::unwind) + if (path->get_checker_event (start_idx)->get_kind () + != event_kind::unwind) continue; int iter_idx = start_idx + 1; while (iter_idx < (int)path->num_events ()) - if (path->get_checker_event (iter_idx)->m_kind == event_kind::unwind) + if (path->get_checker_event (iter_idx)->get_kind () + == event_kind::unwind) ++iter_idx; else break; @@ -3232,7 +3240,7 @@ diagnostic_manager::finish_pruning (checker_path *path) const while (idx >= 0 && idx < (signed)path->num_events ()) { checker_event *base_event = path->get_checker_event (idx); - if (base_event->m_kind == event_kind::function_entry) + if (base_event->get_kind () == event_kind::function_entry) { log ("filtering event %i:" " function entry for purely intraprocedural path", idx); diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index c3e4800f70ad..745ef7e52c83 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -95,14 +95,14 @@ impl_region_model_context (program_state *state, const extrinsic_state &ext_state, uncertainty_t *uncertainty, logger *logger) -: m_eg (NULL), m_logger (logger), m_enode_for_diag (NULL), - m_old_state (NULL), +: m_eg (nullptr), m_logger (logger), m_enode_for_diag (nullptr), + m_old_state (nullptr), m_new_state (state), - m_stmt (NULL), - m_stmt_finder (NULL), + m_stmt (nullptr), + m_stmt_finder (nullptr), m_ext_state (ext_state), m_uncertainty (uncertainty), - m_path_ctxt (NULL), + m_path_ctxt (nullptr), m_out_could_have_done_work (nullptr) { } @@ -113,7 +113,7 @@ impl_region_model_context::warn (std::unique_ptr<pending_diagnostic> d, { LOG_FUNC (get_logger ()); auto curr_stmt_finder = custom_finder ? custom_finder : m_stmt_finder; - if (m_stmt == NULL && curr_stmt_finder == NULL) + if (m_stmt == nullptr && curr_stmt_finder == nullptr) { if (get_logger ()) get_logger ()->log ("rejecting diagnostic: no stmt"); @@ -296,7 +296,7 @@ class impl_sm_context : public sm_context const sm_state_map *old_smap, sm_state_map *new_smap, path_context *path_ctxt, - const stmt_finder *stmt_finder = NULL, + const stmt_finder *stmt_finder = nullptr, bool unknown_side_effects = false) : sm_context (sm_idx, sm), m_logger (eg.get_logger ()), @@ -314,8 +314,8 @@ class impl_sm_context : public sm_context tree get_fndecl_for_call (const gcall &call) final override { impl_region_model_context old_ctxt - (m_eg, m_enode_for_diag, NULL, NULL, NULL/*m_enode->get_state ()*/, - NULL, &call); + (m_eg, m_enode_for_diag, nullptr, nullptr, nullptr/*m_enode->get_state ()*/, + nullptr, &call); region_model *model = m_new_state->m_region_model; return model->get_fndecl_for_call (call, &old_ctxt); } @@ -325,10 +325,10 @@ class impl_sm_context : public sm_context { logger * const logger = get_logger (); LOG_FUNC (logger); - /* Use NULL ctxt on this get_rvalue call to avoid triggering + /* Use nullptr ctxt on this get_rvalue call to avoid triggering uninitialized value warnings. */ const svalue *var_old_sval - = m_old_state->m_region_model->get_rvalue (var, NULL); + = m_old_state->m_region_model->get_rvalue (var, nullptr); state_machine::state_t current = m_old_smap->get_state (var_old_sval, m_eg.get_ext_state ()); @@ -353,9 +353,9 @@ class impl_sm_context : public sm_context logger * const logger = get_logger (); LOG_FUNC (logger); const svalue *var_new_sval - = m_new_state->m_region_model->get_rvalue (var, NULL); + = m_new_state->m_region_model->get_rvalue (var, nullptr); const svalue *origin_new_sval - = m_new_state->m_region_model->get_rvalue (origin, NULL); + = m_new_state->m_region_model->get_rvalue (origin, nullptr); /* We use the new sval here to avoid issues with uninitialized values. */ state_machine::state_t current @@ -378,11 +378,11 @@ class impl_sm_context : public sm_context logger * const logger = get_logger (); LOG_FUNC (logger); impl_region_model_context old_ctxt - (m_eg, m_enode_for_diag, NULL, NULL, NULL/*m_enode->get_state ()*/, - NULL, stmt); + (m_eg, m_enode_for_diag, nullptr, nullptr, nullptr/*m_enode->get_state ()*/, + nullptr, stmt); const svalue *origin_new_sval - = m_new_state->m_region_model->get_rvalue (origin, NULL); + = m_new_state->m_region_model->get_rvalue (origin, nullptr); state_machine::state_t current = m_old_smap->get_state (sval, m_eg.get_ext_state ()); @@ -408,7 +408,7 @@ class impl_sm_context : public sm_context LOG_FUNC (get_logger ()); gcc_assert (d); const svalue *var_old_sval - = m_old_state->m_region_model->get_rvalue (var, NULL); + = m_old_state->m_region_model->get_rvalue (var, nullptr); state_machine::state_t current = (var ? m_old_smap->get_state (var_old_sval, m_eg.get_ext_state ()) @@ -461,7 +461,7 @@ class impl_sm_context : public sm_context return expr; gcc_assert (m_new_state); - const svalue *sval = m_new_state->m_region_model->get_rvalue (expr, NULL); + const svalue *sval = m_new_state->m_region_model->get_rvalue (expr, nullptr); /* Find trees for all regions storing the value. */ if (tree t = m_new_state->m_region_model->get_representative_tree (sval)) return t; @@ -502,7 +502,7 @@ class impl_sm_context : public sm_context if (!assign_stmt) return NULL_TREE; impl_region_model_context old_ctxt - (m_eg, m_enode_for_diag, m_old_state, m_new_state, NULL, NULL, stmt); + (m_eg, m_enode_for_diag, m_old_state, m_new_state, nullptr, nullptr, stmt); if (const svalue *sval = m_new_state->m_region_model->get_gassign_result (assign_stmt, &old_ctxt)) @@ -666,7 +666,7 @@ class leak_stmt_finder : public stmt_finder } gcc_unreachable (); - return NULL; + return nullptr; } void update_event_loc_info (event_loc_info &) final override @@ -925,7 +925,9 @@ impl_region_model_context::on_state_leak (const state_machine &sm, } tree leaked_tree_for_diag = fixup_tree_for_diagnostic (leaked_tree); - std::unique_ptr<pending_diagnostic> pd = sm.on_leak (leaked_tree_for_diag); + std::unique_ptr<pending_diagnostic> pd = sm.on_leak (leaked_tree_for_diag, + m_old_state, + m_new_state); if (pd) { pending_location ploc (m_enode_for_diag, @@ -960,7 +962,7 @@ impl_region_model_context::on_condition (const svalue *lhs, sm.on_condition (sm_ctxt, (m_enode_for_diag ? m_enode_for_diag->get_supernode () - : NULL), + : nullptr), m_stmt, lhs, op, rhs); } @@ -987,7 +989,7 @@ impl_region_model_context::on_bounded_ranges (const svalue &sval, sm.on_bounded_ranges (sm_ctxt, (m_enode_for_diag ? m_enode_for_diag->get_supernode () - : NULL), + : nullptr), m_stmt, sval, ranges); } } @@ -1538,7 +1540,7 @@ exploded_node::on_stmt (exploded_graph &eg, = old_state.m_checker_states[sm_idx]; sm_state_map *new_smap = state->m_checker_states[sm_idx]; impl_sm_context sm_ctxt (eg, sm_idx, sm, this, &old_state, state, - old_smap, new_smap, path_ctxt, NULL, + old_smap, new_smap, path_ctxt, nullptr, unknown_side_effects); /* Allow the state_machine to handle the stmt. */ @@ -1578,6 +1580,16 @@ exploded_node::on_stmt_pre (exploded_graph &eg, state->dump (eg.get_ext_state (), true); return; } + else if (is_special_named_call_p (call, "__analyzer_dump_sarif", 0)) + { + state->dump_sarif (eg.get_ext_state ()); + return; + } + else if (is_special_named_call_p (call, "__analyzer_dump_dot", 0)) + { + state->dump_dot (eg.get_ext_state ()); + return; + } else if (is_special_named_call_p (call, "__analyzer_dump_state", 2)) { state->impl_call_analyzer_dump_state (call, eg.get_ext_state (), @@ -1839,7 +1851,7 @@ class stale_jmp_buf : public pending_diagnostic_subclass<stale_jmp_buf> stale_jmp_buf (const gcall &setjmp_call, const gcall &longjmp_call, const program_point &setjmp_point) : m_setjmp_call (setjmp_call), m_longjmp_call (longjmp_call), - m_setjmp_point (setjmp_point), m_stack_pop_event (NULL) + m_setjmp_point (setjmp_point), m_stack_pop_event (nullptr) {} int get_controlling_option () const final override @@ -1981,7 +1993,7 @@ exploded_node::on_longjmp (exploded_graph &eg, setjmp_point.get_stack_depth (), ctxt); /* Detect leaks in the new state relative to the old state. */ - program_state::detect_leaks (get_state (), *new_state, NULL, + program_state::detect_leaks (get_state (), *new_state, nullptr, eg.get_ext_state (), ctxt); program_point next_point @@ -1995,7 +2007,7 @@ exploded_node::on_longjmp (exploded_graph &eg, if (next) { exploded_edge *eedge - = eg.add_edge (const_cast<exploded_node *> (this), next, NULL, true, + = eg.add_edge (const_cast<exploded_node *> (this), next, nullptr, true, std::make_unique<rewind_info_t> (tmp_setjmp_record, longjmp_call)); @@ -2226,7 +2238,7 @@ exploded_graph::unwind_from_exception (exploded_node &thrown_enode, if (!next_enode) return; - add_edge (iter_enode, next_enode, NULL, false, nullptr); + add_edge (iter_enode, next_enode, nullptr, false, nullptr); return; } else @@ -2254,7 +2266,7 @@ exploded_graph::unwind_from_exception (exploded_node &thrown_enode, throw_stmt); program_state::detect_leaks (iter_enode->get_state (), unwound_state, - NULL, + nullptr, get_ext_state (), &ctxt); } const call_string &cs = iter_enode->get_point ().get_call_string (); @@ -2284,7 +2296,7 @@ exploded_graph::unwind_from_exception (exploded_node &thrown_enode, if (!after_unwind_enode) return; - add_edge (iter_enode, after_unwind_enode, NULL, true, + add_edge (iter_enode, after_unwind_enode, nullptr, true, std::move (unwind_edge_info)); iter_enode = after_unwind_enode; } @@ -2339,7 +2351,7 @@ exploded_node::on_throw (exploded_graph &eg, return; /* Create custom exploded_edge for a throw. */ - eg.add_edge (this, after_throw_enode, NULL, true, + eg.add_edge (this, after_throw_enode, nullptr, true, std::move (throw_edge_info)); eg.unwind_from_exception (*after_throw_enode, &throw_call, ctxt); @@ -2392,10 +2404,10 @@ exploded_node::detect_leaks (exploded_graph &eg) uncertainty_t uncertainty; impl_region_model_context ctxt (eg, this, - &old_state, &new_state, &uncertainty, NULL, + &old_state, &new_state, &uncertainty, nullptr, get_stmt ()); - const svalue *result = NULL; - new_state.m_region_model->pop_frame (NULL, &result, &ctxt, nullptr); + const svalue *result = nullptr; + new_state.m_region_model->pop_frame (nullptr, &result, &ctxt, nullptr); program_state::detect_leaks (old_state, new_state, result, eg.get_ext_state (), &ctxt); } @@ -2502,7 +2514,7 @@ rewind_info_t::update_model (region_model *model, model->on_longjmp (get_longjmp_call (), get_setjmp_call (), - setjmp_point.get_stack_depth (), NULL); + setjmp_point.get_stack_depth (), nullptr); return true; } @@ -2817,7 +2829,7 @@ strongly_connected_components::strong_connect (unsigned index) worklist::worklist (const exploded_graph &eg, const analysis_plan &plan) : m_scc (eg.get_supergraph (), eg.get_logger ()), m_plan (plan), - m_queue (key_t (*this, NULL)) + m_queue (key_t (*this, nullptr)) { } @@ -2879,8 +2891,8 @@ worklist::key_t::cmp (const worklist::key_t &ka, const worklist::key_t &kb) if (flag_analyzer_call_summaries && call_string_a.empty_p () && call_string_b.empty_p () - && point_a.get_function () != NULL - && point_b.get_function () != NULL + && point_a.get_function () != nullptr + && point_b.get_function () != nullptr && point_a.get_function () != point_b.get_function ()) { if (int cmp = ka.m_worklist.m_plan.cmp_function (point_a.get_function (), @@ -2916,19 +2928,19 @@ worklist::key_t::cmp (const worklist::key_t &ka, const worklist::key_t &kb) ordering). */ const supernode *snode_a = ka.m_enode->get_supernode (); const supernode *snode_b = kb.m_enode->get_supernode (); - if (snode_a == NULL) + if (snode_a == nullptr) { - if (snode_b != NULL) - /* One is NULL. */ + if (snode_b != nullptr) + /* One is nullptr. */ return -1; else - /* Both are NULL. */ + /* Both are nullptr. */ return 0; } - if (snode_b == NULL) - /* One is NULL. */ + if (snode_b == nullptr) + /* One is nullptr. */ return 1; - /* Neither are NULL. */ + /* Neither are nullptr. */ gcc_assert (snode_a && snode_b); if (snode_a->m_index != snode_b->m_index) return snode_a->m_index - snode_b->m_index; @@ -3002,7 +3014,7 @@ exploded_graph::exploded_graph (const supergraph &sg, logger *logger, { m_origin = get_or_create_node (program_point::origin (*ext_state.get_model_manager ()), - program_state (ext_state), NULL); + program_state (ext_state), nullptr); for (int i = 0; i < m_sg.num_nodes (); i++) m_PK_AFTER_SUPERNODE_per_snode.quick_push (i); } @@ -3054,10 +3066,10 @@ mark_params_as_tainted (program_state *state, tree fndecl, tree param = iter_parm; if (tree parm_default_ssa = ssa_default_def (fun, iter_parm)) param = parm_default_ssa; - const region *param_reg = state->m_region_model->get_lvalue (param, NULL); + const region *param_reg = state->m_region_model->get_lvalue (param, nullptr); const svalue *init_sval = mgr->get_or_create_initial_value (param_reg); smap->set_state (state->m_region_model, init_sval, - tainted, NULL /*origin_new_sval*/, ext_state); + tainted, nullptr /*origin_new_sval*/, ext_state); if (POINTER_TYPE_P (TREE_TYPE (param))) { const region *pointee_reg = mgr->get_symbolic_region (init_sval); @@ -3065,7 +3077,7 @@ mark_params_as_tainted (program_state *state, tree fndecl, const svalue *init_pointee_sval = mgr->get_or_create_initial_value (pointee_reg); smap->set_state (state->m_region_model, init_pointee_sval, - tainted, NULL /*origin_new_sval*/, ext_state); + tainted, nullptr /*origin_new_sval*/, ext_state); } } @@ -3151,7 +3163,7 @@ exploded_graph::add_function_entry (const function &fun) logger * const logger = get_logger (); if (logger) logger->log ("entrypoint for %qE already exists", fun.decl); - return NULL; + return nullptr; } program_point point @@ -3160,7 +3172,7 @@ exploded_graph::add_function_entry (const function &fun) program_state state (m_ext_state); state.push_frame (m_ext_state, fun); - std::unique_ptr<custom_edge_info> edge_info = NULL; + std::unique_ptr<custom_edge_info> edge_info = nullptr; if (lookup_attribute ("tainted_args", DECL_ATTRIBUTES (fun.decl))) { @@ -3169,13 +3181,13 @@ exploded_graph::add_function_entry (const function &fun) } if (!state.m_valid) - return NULL; + return nullptr; - exploded_node *enode = get_or_create_node (point, state, NULL); + exploded_node *enode = get_or_create_node (point, state, nullptr); if (!enode) - return NULL; + return nullptr; - add_edge (m_origin, enode, NULL, false, std::move (edge_info)); + add_edge (m_origin, enode, nullptr, false, std::move (edge_info)); m_functions_with_enodes.add (key); @@ -3218,7 +3230,7 @@ exploded_graph::get_or_create_node (const program_point &point, { if (logger) logger->log ("invalid state; not creating node"); - return NULL; + return nullptr; } auto_cfun sentinel (point.get_function ()); @@ -3332,7 +3344,7 @@ exploded_graph::get_or_create_node (const program_point &point, "terminating analysis for this program point: %s", pp_formatted_text (&pp)); per_point_data->m_excess_enodes++; - return NULL; + return nullptr; } ps.validate (m_ext_state); @@ -3412,7 +3424,7 @@ get_or_create_per_program_point_data (const program_point &point) } /* Get this graph's per-program-point-data for POINT if there is any, - otherwise NULL. */ + otherwise nullptr. */ per_program_point_data * exploded_graph::get_per_program_point_data (const program_point &point) const @@ -3421,7 +3433,7 @@ exploded_graph::get_per_program_point_data (const program_point &point) const = const_cast <point_map_t &> (m_per_point_data).get (&point)) return *slot; - return NULL; + return nullptr; } /* Ensure that this graph has per-call_string-data for CS; @@ -3454,7 +3466,7 @@ exploded_graph::get_or_create_per_function_data (function *fun) } /* Get this graph's per-function-data for FUN if there is any, - otherwise NULL. */ + otherwise nullptr. */ per_function_data * exploded_graph::get_per_function_data (function *fun) const @@ -3463,7 +3475,7 @@ exploded_graph::get_per_function_data (function *fun) const = const_cast <per_function_data_t &> (m_per_function_data).get (fun)) return *slot; - return NULL; + return nullptr; } /* Return true if FUN should be traversed directly, rather than only as @@ -3626,7 +3638,7 @@ add_tainted_args_callback (exploded_graph *eg, tree field, tree fndecl, if (!state.m_valid) return; - exploded_node *enode = eg->get_or_create_node (point, state, NULL); + exploded_node *enode = eg->get_or_create_node (point, state, nullptr); if (logger) { if (enode) @@ -3640,7 +3652,7 @@ add_tainted_args_callback (exploded_graph *eg, tree field, tree fndecl, } } - eg->add_edge (eg->get_origin (), enode, NULL, false, + eg->add_edge (eg->get_origin (), enode, nullptr, false, std::make_unique<tainted_args_call_info> (field, fndecl, loc)); } @@ -3714,7 +3726,7 @@ exploded_graph::build_initial_worklist () tree init = DECL_INITIAL (decl); if (!init) continue; - walk_tree (&init, add_any_callbacks, this, NULL); + walk_tree (&init, add_any_callbacks, this, nullptr); } } @@ -3795,7 +3807,7 @@ exploded_graph::process_worklist () if (merged_state == state) { /* Then merge node_2 into node by adding an edge. */ - add_edge (node_2, node, NULL, false); + add_edge (node_2, node, nullptr, false); /* Remove node_2 from the worklist. */ m_worklist.take_next (); @@ -3808,7 +3820,7 @@ exploded_graph::process_worklist () /* Then merge node into node_2, and leave node_2 in the worklist, to be processed on the next iteration. */ - add_edge (node, node_2, NULL, false); + add_edge (node, node_2, nullptr, false); node->set_status (exploded_node::status::merger); continue; } @@ -3825,7 +3837,7 @@ exploded_graph::process_worklist () exploded_node *merged_enode = get_or_create_node (node->get_point (), merged_state, node); - if (merged_enode == NULL) + if (merged_enode == nullptr) continue; if (logger) @@ -3853,7 +3865,7 @@ exploded_graph::process_worklist () m_worklist.add_node (merged_enode); else { - add_edge (node, merged_enode, NULL, false); + add_edge (node, merged_enode, nullptr, false); node->set_status (exploded_node::status::merger); } @@ -3861,7 +3873,7 @@ exploded_graph::process_worklist () m_worklist.add_node (merged_enode); else { - add_edge (node_2, merged_enode, NULL, false); + add_edge (node_2, merged_enode, nullptr, false); node_2->set_status (exploded_node::status::merger); } @@ -4016,7 +4028,7 @@ maybe_process_run_of_before_supernode_enodes (exploded_node *enode) uncertainty_t uncertainty; impl_region_model_context ctxt (*this, iter_enode, &state, next_state, - &uncertainty, NULL, NULL); + &uncertainty, nullptr, nullptr); const cfg_superedge *last_cfg_superedge = iter_sedge->dyn_cast_cfg_superedge (); if (last_cfg_superedge) @@ -4079,7 +4091,7 @@ maybe_process_run_of_before_supernode_enodes (exploded_node *enode) = first_item_for_each_merged_state[i]->m_input_enode; exploded_node *next = get_or_create_node (next_point, *merged_state, src_enode); - /* "next" could be NULL; we handle that when adding the edges below. */ + /* "next" could be nullptr; we handle that when adding the edges below. */ next_enodes.quick_push (next); if (logger) { @@ -4096,7 +4108,7 @@ maybe_process_run_of_before_supernode_enodes (exploded_node *enode) { exploded_node *next = next_enodes[it->m_merger_idx]; if (next) - add_edge (it->m_input_enode, next, NULL, + add_edge (it->m_input_enode, next, nullptr, false); /* no "work" is done during merger. */ it->m_input_enode->set_status (exploded_node::status::bulk_merged); } @@ -4207,7 +4219,7 @@ exploded_graph::maybe_create_dynamic_call (const gcall &call, program_point new_point = program_point::before_supernode (sn_entry, - NULL, + nullptr, this_point->get_call_string ()); new_point.push_to_call_stack (sn_exit, @@ -4240,7 +4252,7 @@ exploded_graph::maybe_create_dynamic_call (const gcall &call, next_state, node); if (enode) - add_edge (node,enode, NULL, + add_edge (node,enode, nullptr, false, /* No work is done by the call itself. */ std::make_unique<dynamic_call_info_t> (call)); return true; @@ -4420,7 +4432,7 @@ exploded_graph::process_node (exploded_node *node) { impl_region_model_context ctxt (*this, node, &state, &next_state, - &uncertainty, NULL, NULL); + &uncertainty, nullptr, nullptr); const cfg_superedge *last_cfg_superedge = point.get_from_edge ()->dyn_cast_cfg_superedge (); if (last_cfg_superedge) @@ -4428,14 +4440,14 @@ exploded_graph::process_node (exploded_node *node) (node->get_supernode (), last_cfg_superedge, &ctxt); - program_state::detect_leaks (state, next_state, NULL, + program_state::detect_leaks (state, next_state, nullptr, get_ext_state (), &ctxt); } program_point next_point (point.get_next ()); exploded_node *next = get_or_create_node (next_point, next_state, node); if (next) - add_edge (node, next, NULL, + add_edge (node, next, nullptr, false); /* Assume no work is done at phi nodes. */ } break; @@ -4468,7 +4480,7 @@ exploded_graph::process_node (exploded_node *node) uncertainty_t uncertainty; const supernode *snode = point.get_supernode (); unsigned stmt_idx; - const gimple *prev_stmt = NULL; + const gimple *prev_stmt = nullptr; for (stmt_idx = point.get_stmt_idx (); stmt_idx < snode->m_stmts.length (); stmt_idx++) @@ -4500,8 +4512,8 @@ exploded_graph::process_node (exploded_node *node) { impl_region_model_context ctxt (*this, node, &old_state, &next_state, - &uncertainty, NULL, stmt); - program_state::detect_leaks (old_state, next_state, NULL, + &uncertainty, nullptr, stmt); + program_state::detect_leaks (old_state, next_state, nullptr, get_ext_state (), &ctxt); } @@ -4545,7 +4557,7 @@ exploded_graph::process_node (exploded_node *node) node->m_num_processed_stmts--; if (logger) logger->log ("creating edge to split_enode"); - add_edge (node, split_enode, NULL, could_have_done_work); + add_edge (node, split_enode, nullptr, could_have_done_work); return; } else @@ -4572,7 +4584,7 @@ exploded_graph::process_node (exploded_node *node) exploded_node *next = get_or_create_node (next_point, next_state, node); if (next) - add_edge (node, next, NULL, could_have_done_work); + add_edge (node, next, nullptr, could_have_done_work); } /* If we have custom edge infos, "bifurcate" the state @@ -4600,11 +4612,11 @@ exploded_graph::process_node (exploded_node *node) node, // enode_for_diag &path_ctxt.get_state_at_bifurcation (), &bifurcated_new_state, - NULL, // uncertainty_t *uncertainty - NULL, // path_context *path_ctxt + nullptr, // uncertainty_t *uncertainty + nullptr, // path_context *path_ctxt stmt); if (edge_info->update_state (&bifurcated_new_state, - NULL, /* no exploded_edge yet. */ + nullptr, /* no exploded_edge yet. */ &bifurcation_ctxt)) { if (exploded_node *next2 @@ -4615,7 +4627,7 @@ exploded_graph::process_node (exploded_node *node) node, &bifurcation_ctxt)) { - add_edge (node, next2, NULL, + add_edge (node, next2, nullptr, true /* assume that work could be done */, std::move (edge_info)); } @@ -4696,7 +4708,7 @@ exploded_graph::process_node (exploded_node *node) &state, &next_state, &uncertainty, - NULL, + nullptr, point.get_stmt()); region_model *model = state.m_region_model; @@ -4712,7 +4724,7 @@ exploded_graph::process_node (exploded_node *node) logger); if (!call_discovered) { - /* Check for jump through NULL. */ + /* Check for jump through nullptr. */ if (tree fn_ptr = gimple_call_fn (&call)) { const svalue *fn_ptr_sval @@ -4779,7 +4791,7 @@ exploded_graph::process_node (exploded_node *node) const call_string &cs = point.get_call_string (); program_point next_point = program_point::before_supernode (cs.get_caller_node (), - NULL, + nullptr, cs); program_state next_state (state); uncertainty_t uncertainty; @@ -4797,7 +4809,7 @@ exploded_graph::process_node (exploded_node *node) next_state, node); if (enode) - add_edge (node, enode, NULL, false, + add_edge (node, enode, nullptr, false, std::make_unique<dynamic_call_info_t> (*call, true)); } } @@ -4807,7 +4819,7 @@ exploded_graph::process_node (exploded_node *node) } /* Ensure that this graph has a stats instance for FN, return it. - FN can be NULL, in which case a stats instances is returned covering + FN can be nullptr, in which case a stats instances is returned covering "functionless" parts of the graph (the origin node). */ stats * @@ -5389,16 +5401,16 @@ void feasibility_state::update_for_stmt (const gimple *stmt) { if (const gassign *assign = dyn_cast <const gassign *> (stmt)) - m_model.on_assignment (assign, NULL); + m_model.on_assignment (assign, nullptr); else if (const gasm *asm_stmt = dyn_cast <const gasm *> (stmt)) - m_model.on_asm_stmt (asm_stmt, NULL); + m_model.on_asm_stmt (asm_stmt, nullptr); else if (const gcall *call = dyn_cast <const gcall *> (stmt)) { - bool unknown_side_effects = m_model.on_call_pre (*call, NULL); - m_model.on_call_post (*call, unknown_side_effects, NULL); + bool unknown_side_effects = m_model.on_call_pre (*call, nullptr); + m_model.on_call_post (*call, unknown_side_effects, nullptr); } else if (const greturn *return_ = dyn_cast <const greturn *> (stmt)) - m_model.on_return (return_, NULL); + m_model.on_return (return_, nullptr); } /* Dump this object to PP. */ @@ -5613,7 +5625,7 @@ template <> inline void pod_hash_traits<function_call_string>::mark_empty (value_type &v) { - v.m_fun = NULL; + v.m_fun = nullptr; } template <> inline bool @@ -5625,7 +5637,7 @@ template <> inline bool pod_hash_traits<function_call_string>::is_empty (value_type v) { - return v.m_fun == NULL; + return v.m_fun == nullptr; } namespace ana { @@ -5781,7 +5793,7 @@ exploded_graph::dump_exploded_nodes () const { auto_timevar tv (TV_ANALYZER_DUMP); char *filename - = concat (dump_base_name, ".eg.txt", NULL); + = concat (dump_base_name, ".eg.txt", nullptr); FILE *outf = fopen (filename, "w"); if (!outf) error_at (UNKNOWN_LOCATION, "unable to open %qs for writing", filename); @@ -6208,7 +6220,7 @@ dump_callgraph (const supergraph &sg, const char *filename, // TODO viz_callgraph vcg (sg); - vcg.dump_dot (filename, NULL, viz_callgraph_traits::dump_args_t (eg)); + vcg.dump_dot (filename, nullptr, viz_callgraph_traits::dump_args_t (eg)); fclose (outf); } @@ -6219,7 +6231,7 @@ static void dump_callgraph (const supergraph &sg, const exploded_graph *eg) { auto_timevar tv (TV_ANALYZER_DUMP); - char *filename = concat (dump_base_name, ".callgraph.dot", NULL); + char *filename = concat (dump_base_name, ".callgraph.dot", nullptr); dump_callgraph (sg, filename, eg); free (filename); } @@ -6445,7 +6457,7 @@ dump_analyzer_json (const supergraph &sg, const exploded_graph &eg) { auto_timevar tv (TV_ANALYZER_DUMP); - char *filename = concat (dump_base_name, ".analyzer.json.gz", NULL); + char *filename = concat (dump_base_name, ".analyzer.json.gz", nullptr); gzFile output = gzopen (filename, "w"); if (!output) { @@ -6532,7 +6544,7 @@ impl_run_checkers (logger *logger) engine eng (&sg, logger); - state_purge_map *purge_map = NULL; + state_purge_map *purge_map = nullptr; if (flag_analyzer_state_purge) purge_map = new state_purge_map (sg, eng.get_model_manager (), logger); @@ -6541,8 +6553,8 @@ impl_run_checkers (logger *logger) { /* Dump supergraph pre-analysis. */ auto_timevar tv (TV_ANALYZER_DUMP); - char *filename = concat (dump_base_name, ".supergraph.dot", NULL); - supergraph::dump_args_t args ((enum supergraph_dot_flags)0, NULL); + char *filename = concat (dump_base_name, ".supergraph.dot", nullptr); + supergraph::dump_args_t args ((enum supergraph_dot_flags)0, nullptr); sg.dump_dot (filename, args); free (filename); } @@ -6551,7 +6563,7 @@ impl_run_checkers (logger *logger) { auto_timevar tv (TV_ANALYZER_DUMP); state_purge_annotator a (purge_map); - char *filename = concat (dump_base_name, ".state-purge.dot", NULL); + char *filename = concat (dump_base_name, ".state-purge.dot", nullptr); supergraph::dump_args_t args ((enum supergraph_dot_flags)0, &a); sg.dump_dot (filename, args); free (filename); @@ -6596,7 +6608,7 @@ impl_run_checkers (logger *logger) { auto_timevar tv (TV_ANALYZER_DUMP); char *filename - = concat (dump_base_name, ".eg.dot", NULL); + = concat (dump_base_name, ".eg.dot", nullptr); exploded_graph::dump_args_t args (eg); root_cluster c; eg.dump_dot (filename, &c, args); @@ -6617,7 +6629,7 @@ impl_run_checkers (logger *logger) { /* Dump post-analysis form of supergraph. */ auto_timevar tv (TV_ANALYZER_DUMP); - char *filename = concat (dump_base_name, ".supergraph-eg.dot", NULL); + char *filename = concat (dump_base_name, ".supergraph-eg.dot", nullptr); exploded_graph_annotator a (eg); supergraph::dump_args_t args ((enum supergraph_dot_flags)0, &a); sg.dump_dot (filename, args); @@ -6641,7 +6653,7 @@ impl_run_checkers (logger *logger) } /* Handle -fdump-analyzer and -fdump-analyzer-stderr. */ -static FILE *dump_fout = NULL; +static FILE *dump_fout = nullptr; /* Track if we're responsible for closing dump_fout. */ static bool owns_dump_fout = false; @@ -6658,7 +6670,7 @@ get_or_create_any_logfile () dump_fout = stderr; else if (flag_dump_analyzer) { - char *dump_filename = concat (dump_base_name, ".analyzer.txt", NULL); + char *dump_filename = concat (dump_base_name, ".analyzer.txt", nullptr); dump_fout = fopen (dump_filename, "w"); free (dump_filename); if (dump_fout) @@ -6678,7 +6690,7 @@ run_checkers () location_t saved_input_location = input_location; { - log_user the_logger (NULL); + log_user the_logger (nullptr); get_or_create_any_logfile (); if (dump_fout) the_logger.set_logger (new logger (dump_fout, 0, 0, @@ -6695,7 +6707,7 @@ run_checkers () { fclose (dump_fout); owns_dump_fout = false; - dump_fout = NULL; + dump_fout = nullptr; } /* Restore input_location. Subsequent passes may assume that input_location diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h index 23e344d87e4a..1d31097ec9c1 100644 --- a/gcc/analyzer/exploded-graph.h +++ b/gcc/analyzer/exploded-graph.h @@ -49,17 +49,17 @@ class impl_region_model_context : public region_model_context path_context *path_ctxt, const gimple *stmt, - stmt_finder *stmt_finder = NULL, + stmt_finder *stmt_finder = nullptr, bool *out_could_have_done_work = nullptr); impl_region_model_context (program_state *state, const extrinsic_state &ext_state, uncertainty_t *uncertainty, - logger *logger = NULL); + logger *logger = nullptr); bool warn (std::unique_ptr<pending_diagnostic> d, - const stmt_finder *custom_finder = NULL) final override; + const stmt_finder *custom_finder = nullptr) final override; void add_note (std::unique_ptr<pending_note> pn) final override; void add_event (std::unique_ptr<checker_event> event) final override; void on_svalue_leak (const svalue *) override; @@ -112,6 +112,8 @@ class impl_region_model_context : public region_model_context const gimple *get_stmt () const override { return m_stmt; } const exploded_graph *get_eg () const override { return m_eg; } + const program_state *get_state () const override { return m_new_state; } + void maybe_did_work () override; bool checking_for_infinite_loop_p () const override { return false; } void on_unusable_in_infinite_loop () override {} @@ -405,7 +407,7 @@ class exploded_edge : public dedge<eg_traits> //private: const superedge *const m_sedge; - /* NULL for most edges; will be non-NULL for special cases + /* nullptr for most edges; will be non-NULL for special cases such as an unwind from a longjmp to a setjmp, or when a signal is delivered to a signal-handler. */ std::unique_ptr<custom_edge_info> m_custom_info; @@ -546,14 +548,14 @@ struct eg_hash_map_traits static inline hashval_t hash (const key_type &k) { - gcc_assert (k != NULL); + gcc_assert (k != nullptr); gcc_assert (k != reinterpret_cast<key_type> (1)); return k->hash (); } static inline bool equal_keys (const key_type &k1, const key_type &k2) { - gcc_assert (k1 != NULL); - gcc_assert (k2 != NULL); + gcc_assert (k1 != nullptr); + gcc_assert (k2 != nullptr); gcc_assert (k1 != reinterpret_cast<key_type> (1)); gcc_assert (k2 != reinterpret_cast<key_type> (1)); if (k1 && k2) @@ -575,7 +577,7 @@ struct eg_hash_map_traits template <typename T> static inline void mark_empty (T &entry) { - entry.m_key = NULL; + entry.m_key = nullptr; } template <typename T> static inline bool is_deleted (const T &entry) @@ -585,7 +587,7 @@ struct eg_hash_map_traits template <typename T> static inline bool is_empty (const T &entry) { - return entry.m_key == NULL; + return entry.m_key == nullptr; } static const bool empty_zero_p = false; }; @@ -616,14 +618,14 @@ struct eg_point_hash_map_traits static inline hashval_t hash (const key_type &k) { - gcc_assert (k != NULL); + gcc_assert (k != nullptr); gcc_assert (k != reinterpret_cast<key_type> (1)); return k->hash (); } static inline bool equal_keys (const key_type &k1, const key_type &k2) { - gcc_assert (k1 != NULL); - gcc_assert (k2 != NULL); + gcc_assert (k1 != nullptr); + gcc_assert (k2 != nullptr); gcc_assert (k1 != reinterpret_cast<key_type> (1)); gcc_assert (k2 != reinterpret_cast<key_type> (1)); if (k1 && k2) @@ -645,7 +647,7 @@ struct eg_point_hash_map_traits template <typename T> static inline void mark_empty (T &entry) { - entry.m_key = NULL; + entry.m_key = nullptr; } template <typename T> static inline bool is_deleted (const T &entry) @@ -655,7 +657,7 @@ struct eg_point_hash_map_traits template <typename T> static inline bool is_empty (const T &entry) { - return entry.m_key == NULL; + return entry.m_key == nullptr; } static const bool empty_zero_p = false; }; @@ -776,7 +778,7 @@ class worklist int get_scc_id (const exploded_node *enode) const { const supernode *snode = enode->get_supernode (); - if (snode == NULL) + if (snode == nullptr) return 0; return m_worklist.m_scc.get_scc_id (snode->m_index); } @@ -844,7 +846,7 @@ class exploded_graph : public digraph<eg_traits> bool add_to_worklist = true); exploded_edge *add_edge (exploded_node *src, exploded_node *dest, const superedge *sedge, bool could_do_work, - std::unique_ptr<custom_edge_info> custom = NULL); + std::unique_ptr<custom_edge_info> custom = nullptr); per_program_point_data * get_or_create_per_program_point_data (const program_point &); @@ -977,7 +979,7 @@ class exploded_path void dump_to_pp (pretty_printer *pp, const extrinsic_state *ext_state) const; void dump (FILE *fp, const extrinsic_state *ext_state) const; - void dump (const extrinsic_state *ext_state = NULL) const; + void dump (const extrinsic_state *ext_state = nullptr) const; void dump_to_file (const char *filename, const extrinsic_state &ext_state) const; @@ -1042,7 +1044,7 @@ class feasibility_state typedef shortest_paths<eg_traits, exploded_path> shortest_exploded_paths; -/* Abstract base class for use when passing NULL as the stmt for +/* Abstract base class for use when passing nullptr as the stmt for a possible warning, allowing the choice of stmt to be deferred until after we have an emission path (and know we're emitting a warning). */ diff --git a/gcc/analyzer/function-set.cc b/gcc/analyzer/function-set.cc index 817a51249bcc..530e0adaa503 100644 --- a/gcc/analyzer/function-set.cc +++ b/gcc/analyzer/function-set.cc @@ -95,7 +95,7 @@ namespace selftest { static void test_empty () { - function_set fs (NULL, 0); + function_set fs (nullptr, 0); fs.assert_sorted (); fs.assert_sane (); ASSERT_FALSE (fs.contains_name_p ("")); diff --git a/gcc/analyzer/infinite-recursion.cc b/gcc/analyzer/infinite-recursion.cc index 064111769b0f..b80b94a0c5b7 100644 --- a/gcc/analyzer/infinite-recursion.cc +++ b/gcc/analyzer/infinite-recursion.cc @@ -55,7 +55,7 @@ class infinite_recursion_diagnostic : m_prev_entry_enode (prev_entry_enode), m_new_entry_enode (new_entry_enode), m_callee_fndecl (callee_fndecl), - m_prev_entry_event (NULL) + m_prev_entry_event (nullptr) {} const char *get_kind () const final override @@ -108,9 +108,10 @@ class infinite_recursion_diagnostic { public: recursive_function_entry_event (const program_point &dst_point, + const program_state &dst_state, const infinite_recursion_diagnostic &pd, bool topmost) - : function_entry_event (dst_point), + : function_entry_event (dst_point, dst_state), m_pd (pd), m_topmost (topmost) { @@ -146,17 +147,19 @@ class infinite_recursion_diagnostic const program_point &dst_point = dst_node->get_point (); if (eedge.m_dest == m_prev_entry_enode) { - gcc_assert (m_prev_entry_event == NULL); + gcc_assert (m_prev_entry_event == nullptr); std::unique_ptr<checker_event> prev_entry_event - = std::make_unique <recursive_function_entry_event> (dst_point, - *this, false); + = std::make_unique <recursive_function_entry_event> + (dst_point, + dst_node->get_state (), + *this, false); m_prev_entry_event = prev_entry_event.get (); emission_path->add_event (std::move (prev_entry_event)); } else if (eedge.m_dest == m_new_entry_enode) emission_path->add_event (std::make_unique<recursive_function_entry_event> - (dst_point, *this, true)); + (dst_point, dst_node->get_state (), *this, true)); else pending_diagnostic::add_function_entry_event (eedge, emission_path); } @@ -288,7 +291,7 @@ class infinite_recursion_diagnostic bool m_found_conjured_svalues; }; - const svalue *sval = model.get_rvalue (expr, NULL); + const svalue *sval = model.get_rvalue (expr, nullptr); conjured_svalue_finder v; sval->accept (&v); return v.m_found_conjured_svalues; @@ -348,7 +351,7 @@ exploded_graph::find_previous_entry_to (function *top_of_stack_fun, } /* Not found. */ - return NULL; + return nullptr; } /* Given BASE_REG within ENCLOSING_FRAME (such as a function parameter), @@ -382,7 +385,7 @@ remap_enclosing_frame (const region *base_reg, const decl_region *decl_reg = (const decl_region *)base_reg; return equiv_prev_frame->get_region_for_local (mgr, decl_reg->get_decl (), - NULL); + nullptr); } } } @@ -424,7 +427,7 @@ sufficiently_different_region_binding_p (exploded_node *new_entry_enode, /* Get the value within the new frame. */ const svalue *new_sval - = new_model.get_store_value (base_reg, NULL); + = new_model.get_store_value (base_reg, nullptr); /* If any part of the value is UNKNOWN (e.g. due to hitting complexity limits) assume that it differs from the previous @@ -444,7 +447,7 @@ sufficiently_different_region_binding_p (exploded_node *new_entry_enode, to the recursion. */ const int old_stack_depth = prev_entry_enode->get_stack_depth (); if (enclosing_frame->get_stack_depth () < old_stack_depth) - prev_sval = prev_model.get_store_value (base_reg, NULL); + prev_sval = prev_model.get_store_value (base_reg, nullptr); else { /* Ignore bindings within frames below the new entry node. */ @@ -466,11 +469,11 @@ sufficiently_different_region_binding_p (exploded_node *new_entry_enode, equiv_prev_frame, new_model.get_manager ()); prev_sval - = prev_model.get_store_value (equiv_prev_base_reg, NULL); + = prev_model.get_store_value (equiv_prev_base_reg, nullptr); } } else - prev_sval = prev_model.get_store_value (base_reg, NULL); + prev_sval = prev_model.get_store_value (base_reg, nullptr); /* If the prev_sval contains UNKNOWN (e.g. due to hitting complexity limits) assume that it will differ from any new value. */ diff --git a/gcc/analyzer/inlining-iterator.h b/gcc/analyzer/inlining-iterator.h index ac1463d44745..20d1d2b5e815 100644 --- a/gcc/analyzer/inlining-iterator.h +++ b/gcc/analyzer/inlining-iterator.h @@ -46,7 +46,7 @@ class inlining_iterator public: inlining_iterator (location_t loc) : m_abstract_origin (LOCATION_BLOCK (loc)), - m_callsite (UNKNOWN_LOCATION), m_fndecl (NULL), + m_callsite (UNKNOWN_LOCATION), m_fndecl (NULL_TREE), m_next_abstract_origin (NULL) { prepare_iteration (); @@ -71,7 +71,7 @@ class inlining_iterator return; tree block = m_abstract_origin; m_callsite = BLOCK_SOURCE_LOCATION (block); - m_fndecl = NULL; + m_fndecl = NULL_TREE; block = BLOCK_SUPERCONTEXT (block); while (block && TREE_CODE (block) == BLOCK && BLOCK_ABSTRACT_ORIGIN (block)) diff --git a/gcc/analyzer/kf-analyzer.cc b/gcc/analyzer/kf-analyzer.cc index 3e671e5edadb..13476defcafb 100644 --- a/gcc/analyzer/kf-analyzer.cc +++ b/gcc/analyzer/kf-analyzer.cc @@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "analyzer/region-model.h" #include "analyzer/pending-diagnostic.h" #include "analyzer/call-details.h" +#include "analyzer/program-state.h" #if ENABLE_ANALYZER @@ -260,6 +261,11 @@ class dump_path_diagnostic : public pending_diagnostic_subclass<dump_path_diagnostic> { public: + dump_path_diagnostic (const program_state &state) + : m_state (state) + { + } + int get_controlling_option () const final override { return 0; @@ -280,6 +286,15 @@ class dump_path_diagnostic { return true; } + + const program_state * + get_final_state () const final override + { + return &m_state; + } + +private: + program_state m_state; }; /* Handle calls to "__analyzer_dump_path" by queuing a diagnostic at this @@ -297,7 +312,8 @@ class kf_analyzer_dump_path : public known_function region_model_context *ctxt = cd.get_ctxt (); if (!ctxt) return; - ctxt->warn (std::make_unique<dump_path_diagnostic> ()); + if (const program_state *state = ctxt->get_state ()) + ctxt->warn (std::make_unique<dump_path_diagnostic> (*state)); } }; diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc index 75b627902f8c..fe25520fde6f 100644 --- a/gcc/analyzer/kf.cc +++ b/gcc/analyzer/kf.cc @@ -1053,11 +1053,11 @@ kf_realloc::impl_call_post (const call_details &cd) const const svalue *copied_size_sval = get_copied_size (model, old_size_sval, new_size_sval); const region *copied_old_reg - = mgr->get_sized_region (freed_reg, NULL, copied_size_sval); + = mgr->get_sized_region (freed_reg, nullptr, copied_size_sval); const svalue *buffer_content_sval = model->get_store_value (copied_old_reg, cd.get_ctxt ()); const region *copied_new_reg - = mgr->get_sized_region (new_reg, NULL, copied_size_sval); + = mgr->get_sized_region (new_reg, nullptr, copied_size_sval); model->set_value (copied_new_reg, buffer_content_sval, cd.get_ctxt ()); } @@ -1636,7 +1636,7 @@ kf_strncpy::impl_call_post (const call_details &cd) const } private: /* (strlen + 1) of the source string if it has a terminator, - or NULL for the case where UB would happen before + or nullptr for the case where UB would happen before finding any terminator. */ const svalue *m_num_bytes_with_terminator_sval; @@ -1691,8 +1691,8 @@ class kf_strndup : public builtin_known_function region_model_manager *mgr = cd.get_manager (); /* Ideally we'd get the size here, and simulate copying the bytes. */ const region *new_reg - = model->get_or_create_region_for_heap_alloc (NULL, cd.get_ctxt ()); - model->mark_region_as_unknown (new_reg, NULL); + = model->get_or_create_region_for_heap_alloc (nullptr, cd.get_ctxt ()); + model->mark_region_as_unknown (new_reg, nullptr); if (cd.get_lhs_type ()) { const svalue *ptr_sval diff --git a/gcc/analyzer/known-function-manager.cc b/gcc/analyzer/known-function-manager.cc index 1a2930edcb0f..3b645a8c90f8 100644 --- a/gcc/analyzer/known-function-manager.cc +++ b/gcc/analyzer/known-function-manager.cc @@ -92,7 +92,7 @@ known_function_manager::add (enum internal_fn ifn, The call must match all assumptions made by the known_function (such as e.g. "argument 1's type must be a pointer type"). - Return NULL if no known_function is found, or it does not match the + Return nullptr if no known_function is found, or it does not match the assumption(s). */ const known_function * @@ -122,16 +122,16 @@ known_function_manager::get_match (tree fndecl, const call_details &cd) const if (DECL_CONTEXT (fndecl) && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL) - return NULL; + return nullptr; if (tree identifier = DECL_NAME (fndecl)) if (const known_function *candidate = get_by_identifier (identifier)) if (candidate->matches_call_types_p (cd)) return candidate; - return NULL; + return nullptr; } -/* Get any known_function for IFN, or NULL. */ +/* Get any known_function for IFN, or nullptr. */ const known_function * known_function_manager::get_internal_fn (enum internal_fn ifn) const @@ -141,7 +141,7 @@ known_function_manager::get_internal_fn (enum internal_fn ifn) const } /* Get any known_function for NAME, without type-checking. - Return NULL if there isn't one. */ + Return nullptr if there isn't one. */ const known_function * known_function_manager::get_normal_builtin (enum built_in_function name) const @@ -160,7 +160,7 @@ get_normal_builtin (const builtin_known_function *builtin_kf) const } /* Get any known_function matching IDENTIFIER, without type-checking. - Return NULL if there isn't one. */ + Return nullptr if there isn't one. */ const known_function * known_function_manager::get_by_identifier (tree identifier) const @@ -170,7 +170,7 @@ known_function_manager::get_by_identifier (tree identifier) const if (slot) return *slot; else - return NULL; + return nullptr; } /* Get any known_function in C++ std:: namespace matching IDENTIFIER, without diff --git a/gcc/analyzer/pending-diagnostic.cc b/gcc/analyzer/pending-diagnostic.cc index 70dc8154d62f..5e95edd689be 100644 --- a/gcc/analyzer/pending-diagnostic.cc +++ b/gcc/analyzer/pending-diagnostic.cc @@ -171,7 +171,7 @@ pending_diagnostic::fixup_location (location_t loc, bool) const const line_map_macro *macro_map = linemap_check_macro (map); if (fixup_location_in_macro_p (macro_map->macro)) loc = linemap_resolve_location (line_table, loc, - LRK_MACRO_EXPANSION_POINT, NULL); + LRK_MACRO_EXPANSION_POINT, nullptr); } return loc; } @@ -185,7 +185,10 @@ pending_diagnostic::add_function_entry_event (const exploded_edge &eedge, { const exploded_node *dst_node = eedge.m_dest; const program_point &dst_point = dst_node->get_point (); - emission_path->add_event (std::make_unique<function_entry_event> (dst_point)); + const program_state &dst_state = dst_node->get_state (); + emission_path->add_event + (std::make_unique<function_entry_event> (dst_point, + dst_state)); } /* Base implementation of pending_diagnostic::add_call_event. @@ -241,7 +244,8 @@ pending_diagnostic::add_final_event (const state_machine *sm, (std::make_unique<warning_event> (loc_info, enode, - sm, var, state)); + sm, var, state, + get_final_state ())); } } // namespace ana diff --git a/gcc/analyzer/pending-diagnostic.h b/gcc/analyzer/pending-diagnostic.h index 6a0289e705ba..469513c726bd 100644 --- a/gcc/analyzer/pending-diagnostic.h +++ b/gcc/analyzer/pending-diagnostic.h @@ -364,6 +364,12 @@ class pending_diagnostic tree var, state_machine::state_t state, checker_path *emission_path); + virtual const program_state * + get_final_state () const + { + return nullptr; + } + /* Vfunc for determining that this pending_diagnostic supercedes OTHER, and that OTHER should therefore not be emitted. They have already been tested for being at the same stmt. */ diff --git a/gcc/analyzer/program-point.cc b/gcc/analyzer/program-point.cc index c95f8635e530..1f82559a9a7e 100644 --- a/gcc/analyzer/program-point.cc +++ b/gcc/analyzer/program-point.cc @@ -171,7 +171,7 @@ function_point::get_function () const if (m_supernode) return m_supernode->m_fun; else - return NULL; + return nullptr; } /* Get the gimple stmt for this function_point, if any. */ @@ -184,7 +184,7 @@ function_point::get_stmt () const else if (m_kind == PK_AFTER_SUPERNODE) return m_supernode->get_last_stmt (); else - return NULL; + return nullptr; } /* Get a location for this function_point, if any. */ @@ -219,18 +219,18 @@ function_point::final_stmt_p () const function_point function_point::from_function_entry (const supergraph &sg, const function &fun) { - return before_supernode (sg.get_node_for_function_entry (fun), NULL); + return before_supernode (sg.get_node_for_function_entry (fun), nullptr); } /* Create a function_point representing entering supernode SUPERNODE, - having reached it via FROM_EDGE (which could be NULL). */ + having reached it via FROM_EDGE (which could be nullptr). */ function_point function_point::before_supernode (const supernode *supernode, const superedge *from_edge) { if (from_edge && from_edge->get_kind () != SUPEREDGE_CFG_EDGE) - from_edge = NULL; + from_edge = nullptr; return function_point (supernode, from_edge, 0, PK_BEFORE_SUPERNODE); } @@ -673,7 +673,7 @@ function_point::get_next () const program_point program_point::origin (const region_model_manager &mgr) { - return program_point (function_point (NULL, NULL, + return program_point (function_point (nullptr, nullptr, 0, PK_ORIGIN), mgr.get_empty_call_string ()); } @@ -766,11 +766,11 @@ namespace selftest { static void test_function_point_equality () { - const supernode *snode = NULL; + const supernode *snode = nullptr; - function_point a = function_point (snode, NULL, 0, + function_point a = function_point (snode, nullptr, 0, PK_BEFORE_SUPERNODE); - function_point b = function_point::before_supernode (snode, NULL); + function_point b = function_point::before_supernode (snode, nullptr); ASSERT_EQ (a, b); } @@ -779,12 +779,12 @@ test_function_point_equality () static void test_function_point_ordering () { - const supernode *snode = NULL; + const supernode *snode = nullptr; /* Populate an array with various points within the same snode, in order. */ auto_vec<function_point> points; - points.safe_push (function_point::before_supernode (snode, NULL)); + points.safe_push (function_point::before_supernode (snode, nullptr)); points.safe_push (function_point::before_stmt (snode, 0)); points.safe_push (function_point::before_stmt (snode, 1)); points.safe_push (function_point::after_supernode (snode)); @@ -816,14 +816,14 @@ test_program_point_equality () { region_model_manager mgr; - const supernode *snode = NULL; + const supernode *snode = nullptr; const call_string &cs = mgr.get_empty_call_string (); - program_point a = program_point::before_supernode (snode, NULL, + program_point a = program_point::before_supernode (snode, nullptr, cs); - program_point b = program_point::before_supernode (snode, NULL, + program_point b = program_point::before_supernode (snode, nullptr, cs); ASSERT_EQ (a, b); diff --git a/gcc/analyzer/program-point.h b/gcc/analyzer/program-point.h index 38d831975f43..fc543c01a73c 100644 --- a/gcc/analyzer/program-point.h +++ b/gcc/analyzer/program-point.h @@ -120,23 +120,23 @@ class function_point static function_point before_stmt (const supernode *supernode, unsigned stmt_idx) { - return function_point (supernode, NULL, stmt_idx, PK_BEFORE_STMT); + return function_point (supernode, nullptr, stmt_idx, PK_BEFORE_STMT); } static function_point after_supernode (const supernode *supernode) { - return function_point (supernode, NULL, 0, PK_AFTER_SUPERNODE); + return function_point (supernode, nullptr, 0, PK_AFTER_SUPERNODE); } /* Support for hash_map. */ static function_point empty () { - return function_point (NULL, NULL, 0, PK_EMPTY); + return function_point (nullptr, nullptr, 0, PK_EMPTY); } static function_point deleted () { - return function_point (NULL, NULL, 0, PK_DELETED); + return function_point (nullptr, nullptr, 0, PK_DELETED); } static int cmp_within_supernode_1 (const function_point &point_a, @@ -305,7 +305,7 @@ class program_point private: program_point (const function_point &fn_point) : m_function_point (fn_point), - m_call_string (NULL) + m_call_string (nullptr) { } diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc index 21f78e5b5c3c..85cbe759ee91 100644 --- a/gcc/analyzer/program-state.cc +++ b/gcc/analyzer/program-state.cc @@ -28,6 +28,8 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "digraph.h" #include "diagnostic-event-id.h" +#include "diagnostic-state-graphs.h" +#include "graphviz.h" #include "text-art/tree-widget.h" #include "text-art/dump.h" @@ -48,6 +50,7 @@ along with GCC; see the file COPYING3. If not see #include "analyzer/state-purge.h" #include "analyzer/call-summary.h" #include "analyzer/analyzer-selftests.h" +#include "analyzer/ana-state-to-diagnostic-state.h" #if ENABLE_ANALYZER @@ -112,7 +115,7 @@ extrinsic_state::get_model_manager () const if (m_engine) return m_engine->get_model_manager (); else - return NULL; /* for selftests. */ + return nullptr; /* for selftests. */ } /* Try to find a state machine named NAME. @@ -255,7 +258,7 @@ DEBUG_FUNCTION void sm_state_map::dump (bool simple) const { tree_dump_pretty_printer pp (stderr); - print (NULL, simple, true, &pp); + print (nullptr, simple, true, &pp); pp_newline (&pp); } @@ -417,7 +420,7 @@ sm_state_map::operator== (const sm_state_map &other) const const svalue *sval = (*iter).first; entry_t e = (*iter).second; entry_t *other_slot = const_cast <map_t &> (other.m_map).get (sval); - if (other_slot == NULL) + if (other_slot == nullptr) return false; if (e != *other_slot) return false; @@ -498,7 +501,7 @@ sm_state_map::get_origin (const svalue *sval, if (slot) return slot->m_origin; else - return NULL; + return nullptr; } /* Set the state of SID within MODEL to STATE, recording that @@ -511,7 +514,7 @@ sm_state_map::set_state (region_model *model, const svalue *origin, const extrinsic_state &ext_state) { - if (model == NULL) + if (model == nullptr) return; /* Reject attempts to set state on UNKNOWN/POISONED. */ @@ -768,7 +771,7 @@ sm_state_map::on_unknown_change (const svalue *sval, for (svalue_set::iterator iter = svals_to_unset.begin (); iter != svals_to_unset.end (); ++iter) - impl_set_state (*iter, (state_machine::state_t)0, NULL, ext_state); + impl_set_state (*iter, (state_machine::state_t)0, nullptr, ext_state); } /* Purge state for things involving SVAL. @@ -799,7 +802,7 @@ sm_state_map::purge_state_involving (const svalue *sval, for (svalue_set::iterator iter = svals_to_unset.begin (); iter != svals_to_unset.end (); ++iter) - impl_set_state (*iter, (state_machine::state_t)0, NULL, ext_state); + impl_set_state (*iter, (state_machine::state_t)0, nullptr, ext_state); } /* Comparator for imposing an order on sm_state_map instances. */ @@ -909,7 +912,7 @@ sm_state_map::can_merge_with_p (const sm_state_map &other, state_machine::state_t other_state = other.get_state (sval, ext_state); if (state_machine::state_t merged_state = sm.maybe_get_merged_state (this_state, other_state)) - (*out)->impl_set_state (sval, merged_state, NULL, ext_state); + (*out)->impl_set_state (sval, merged_state, nullptr, ext_state); else return false; } @@ -923,7 +926,7 @@ sm_state_map::can_merge_with_p (const sm_state_map &other, /* program_state's ctor. */ program_state::program_state (const extrinsic_state &ext_state) -: m_region_model (NULL), +: m_region_model (nullptr), m_checker_states (ext_state.get_num_checkers ()), m_valid (true) { @@ -957,8 +960,8 @@ sm_state_map::replay_call_summary (call_summary_replay &r, const svalue *caller_origin = (summary_origin ? r.convert_svalue_from_summary (summary_origin) - : NULL); - // caller_origin can be NULL. + : nullptr); + // caller_origin can be nullptr. m_map.put (caller_sval, entry_t (kv.second.m_state, caller_origin)); } m_global_state = summary.m_global_state; @@ -1006,7 +1009,7 @@ program_state::program_state (program_state &&other) : m_region_model (other.m_region_model), m_checker_states (other.m_checker_states.length ()) { - other.m_region_model = NULL; + other.m_region_model = nullptr; int i; sm_state_map *smap; @@ -1224,6 +1227,24 @@ program_state::make_dump_widget (const text_art::dump_widget_info &dwi) const return state_widget; } +void +program_state::dump_dot (const extrinsic_state &ext_state) const +{ + auto state_graph = make_diagnostic_state_graph (ext_state); + + gcc_assert (global_dc); + auto logical_loc_mgr = global_dc->get_logical_location_manager (); + gcc_assert (logical_loc_mgr); + + auto graph = diagnostics::state_graphs::make_dot_graph (*state_graph, + *logical_loc_mgr); + + pretty_printer pp; + dot::writer w (pp); + graph->print (w); + pp_flush (&pp); +} + /* Update this program_state to reflect a top-level call to FUN. The params will have initial_svalues. */ @@ -1322,7 +1343,7 @@ program_state::on_edge (exploded_graph &eg, return false; program_state::detect_leaks (enode->get_state (), *this, - NULL, eg.get_ext_state (), + nullptr, eg.get_ext_state (), &ctxt); return true; @@ -1346,7 +1367,7 @@ program_state::push_call (exploded_graph &eg, &enode->get_state (), this, uncertainty, - NULL, + nullptr, last_stmt); m_region_model->update_for_gcall (call_stmt, &ctxt); } @@ -1369,7 +1390,7 @@ program_state::returning_call (exploded_graph &eg, &enode->get_state (), this, uncertainty, - NULL, + nullptr, last_stmt); m_region_model->update_for_return_gcall (call_stmt, &ctxt); } @@ -1427,7 +1448,7 @@ program_state::prune_for_point (exploded_graph &eg, temporaries keep the value reachable until the frame is popped. */ const svalue *sval - = new_state.m_region_model->get_store_value (reg, NULL); + = new_state.m_region_model->get_store_value (reg, nullptr); if (!new_state.can_purge_p (eg.get_ext_state (), sval) && SSA_NAME_VAR (ssa_name)) { @@ -1486,9 +1507,9 @@ program_state::prune_for_point (exploded_graph &eg, impl_region_model_context ctxt (eg, enode_for_diag, this, &new_state, - uncertainty, NULL, + uncertainty, nullptr, point.get_stmt ()); - detect_leaks (*this, new_state, NULL, eg.get_ext_state (), &ctxt); + detect_leaks (*this, new_state, nullptr, eg.get_ext_state (), &ctxt); } } @@ -1660,7 +1681,7 @@ program_state::detect_leaks (const program_state &src_state, *might* still be reachable in dst_state. */ svalue_set known_src_svalues; src_state.m_region_model->get_reachable_svalues (&known_src_svalues, - NULL, NULL); + nullptr, nullptr); svalue_set maybe_dest_svalues; dest_state.m_region_model->get_reachable_svalues (&maybe_dest_svalues, extra_sval, uncertainty); @@ -1778,7 +1799,7 @@ test_sm_state_map () tree y = build_global_decl ("y", integer_type_node); tree z = build_global_decl ("z", integer_type_node); - std::unique_ptr<state_machine> sm = make_malloc_state_machine (NULL); + std::unique_ptr<state_machine> sm = make_malloc_state_machine (nullptr); state_machine::state_t start = sm->get_start_state (); std::vector<std::unique_ptr<state_machine>> checkers; const state_machine &borrowed_sm = *sm.get (); @@ -1792,9 +1813,9 @@ test_sm_state_map () const state_machine::state_t TEST_STATE_42 = &test_state_42; region_model_manager mgr; region_model model (&mgr); - const svalue *x_sval = model.get_rvalue (x, NULL); - const svalue *y_sval = model.get_rvalue (y, NULL); - const svalue *z_sval = model.get_rvalue (z, NULL); + const svalue *x_sval = model.get_rvalue (x, nullptr); + const svalue *y_sval = model.get_rvalue (y, nullptr); + const svalue *z_sval = model.get_rvalue (z, nullptr); sm_state_map map (borrowed_sm); ASSERT_TRUE (map.is_empty_p ()); @@ -1821,16 +1842,16 @@ test_sm_state_map () { region_model_manager mgr; region_model model (&mgr); - const svalue *x_sval = model.get_rvalue (x, NULL); - const svalue *y_sval = model.get_rvalue (y, NULL); - const svalue *z_sval = model.get_rvalue (z, NULL); + const svalue *x_sval = model.get_rvalue (x, nullptr); + const svalue *y_sval = model.get_rvalue (y, nullptr); + const svalue *z_sval = model.get_rvalue (z, nullptr); sm_state_map map (borrowed_sm); ASSERT_TRUE (map.is_empty_p ()); ASSERT_EQ (map.get_state (x_sval, ext_state), start); ASSERT_EQ (map.get_state (y_sval, ext_state), start); - model.add_constraint (x, EQ_EXPR, y, NULL); + model.add_constraint (x, EQ_EXPR, y, nullptr); /* Setting x to a state should also update y, as they are in the same equivalence class. */ @@ -1845,8 +1866,8 @@ test_sm_state_map () { region_model_manager mgr; region_model model (&mgr); - const svalue *y_sval = model.get_rvalue (y, NULL); - const svalue *z_sval = model.get_rvalue (z, NULL); + const svalue *y_sval = model.get_rvalue (y, nullptr); + const svalue *z_sval = model.get_rvalue (z, nullptr); sm_state_map map0 (borrowed_sm); sm_state_map map1 (borrowed_sm); @@ -1880,17 +1901,17 @@ test_sm_state_map () region_model_manager mgr; region_model model (&mgr); - const svalue *x_sval = model.get_rvalue (x, NULL); - const svalue *y_sval = model.get_rvalue (y, NULL); - const svalue *z_sval = model.get_rvalue (z, NULL); + const svalue *x_sval = model.get_rvalue (x, nullptr); + const svalue *y_sval = model.get_rvalue (y, nullptr); + const svalue *z_sval = model.get_rvalue (z, nullptr); - map1.impl_set_state (x_sval, TEST_STATE_2, NULL, ext_state); - map1.impl_set_state (y_sval, TEST_STATE_3, NULL, ext_state); - map1.impl_set_state (z_sval, TEST_STATE_2, NULL, ext_state); + map1.impl_set_state (x_sval, TEST_STATE_2, nullptr, ext_state); + map1.impl_set_state (y_sval, TEST_STATE_3, nullptr, ext_state); + map1.impl_set_state (z_sval, TEST_STATE_2, nullptr, ext_state); - map2.impl_set_state (z_sval, TEST_STATE_2, NULL, ext_state); - map2.impl_set_state (y_sval, TEST_STATE_3, NULL, ext_state); - map2.impl_set_state (x_sval, TEST_STATE_2, NULL, ext_state); + map2.impl_set_state (z_sval, TEST_STATE_2, nullptr, ext_state); + map2.impl_set_state (y_sval, TEST_STATE_3, nullptr, ext_state); + map2.impl_set_state (x_sval, TEST_STATE_2, nullptr, ext_state); ASSERT_EQ (map1.hash (), map2.hash ()); ASSERT_EQ (map1, map2); @@ -1908,7 +1929,7 @@ test_program_state_1 () malloc sm-state, pointing to a region on the heap. */ tree p = build_global_decl ("p", ptr_type_node); - std::unique_ptr<state_machine> sm = make_malloc_state_machine (NULL); + std::unique_ptr<state_machine> sm = make_malloc_state_machine (nullptr); const state_machine::state_t UNCHECKED_STATE = sm->get_state_by_name ("unchecked"); @@ -1920,13 +1941,13 @@ test_program_state_1 () const svalue *size_in_bytes = mgr->get_or_create_unknown_svalue (size_type_node); const region *new_reg - = model->get_or_create_region_for_heap_alloc (size_in_bytes, NULL); + = model->get_or_create_region_for_heap_alloc (size_in_bytes, nullptr); const svalue *ptr_sval = mgr->get_ptr_svalue (ptr_type_node, new_reg); - model->set_value (model->get_lvalue (p, NULL), - ptr_sval, NULL); + model->set_value (model->get_lvalue (p, nullptr), + ptr_sval, nullptr); sm_state_map *smap = s.m_checker_states[0]; - smap->impl_set_state (ptr_sval, UNCHECKED_STATE, NULL, ext_state); + smap->impl_set_state (ptr_sval, UNCHECKED_STATE, nullptr, ext_state); ASSERT_EQ (smap->get_state (ptr_sval, ext_state), UNCHECKED_STATE); } @@ -1947,9 +1968,9 @@ test_program_state_2 () program_state s (ext_state); region_model *model = s.m_region_model; - const region *p_reg = model->get_lvalue (p, NULL); - const svalue *str_sval = model->get_rvalue (string_cst_ptr, NULL); - model->set_value (p_reg, str_sval, NULL); + const region *p_reg = model->get_lvalue (p, nullptr); + const svalue *str_sval = model->get_rvalue (string_cst_ptr, nullptr); + model->set_value (p_reg, str_sval, nullptr); } /* Verify that program_states with identical sm-state can be merged, @@ -1965,7 +1986,7 @@ test_program_state_merging () engine eng; region_model_manager *mgr = eng.get_model_manager (); program_point point (program_point::origin (*mgr)); - extrinsic_state ext_state (make_malloc_state_machine (NULL), + extrinsic_state ext_state (make_malloc_state_machine (nullptr), &eng); program_state s0 (ext_state); @@ -1976,20 +1997,20 @@ test_program_state_merging () const svalue *size_in_bytes = mgr->get_or_create_unknown_svalue (size_type_node); const region *new_reg - = model0->get_or_create_region_for_heap_alloc (size_in_bytes, NULL); + = model0->get_or_create_region_for_heap_alloc (size_in_bytes, nullptr); const svalue *ptr_sval = mgr->get_ptr_svalue (ptr_type_node, new_reg); model0->set_value (model0->get_lvalue (p, &ctxt), ptr_sval, &ctxt); sm_state_map *smap = s0.m_checker_states[0]; const state_machine::state test_state ("test state", 0); const state_machine::state_t TEST_STATE = &test_state; - smap->impl_set_state (ptr_sval, TEST_STATE, NULL, ext_state); + smap->impl_set_state (ptr_sval, TEST_STATE, nullptr, ext_state); ASSERT_EQ (smap->get_state (ptr_sval, ext_state), TEST_STATE); model0->canonicalize (); /* Verify that canonicalization preserves sm-state. */ - ASSERT_EQ (smap->get_state (model0->get_rvalue (p, NULL), ext_state), + ASSERT_EQ (smap->get_state (model0->get_rvalue (p, nullptr), ext_state), TEST_STATE); /* Make a copy of the program_state. */ @@ -2006,7 +2027,7 @@ test_program_state_merging () /* Verify that the merged state has the sm-state for "p". */ region_model *merged_model = merged.m_region_model; sm_state_map *merged_smap = merged.m_checker_states[0]; - ASSERT_EQ (merged_smap->get_state (merged_model->get_rvalue (p, NULL), + ASSERT_EQ (merged_smap->get_state (merged_model->get_rvalue (p, nullptr), ext_state), TEST_STATE); @@ -2015,7 +2036,7 @@ test_program_state_merging () merged.validate (ext_state); /* Verify that the merged state still has the sm-state for "p". */ - ASSERT_EQ (merged_smap->get_state (merged_model->get_rvalue (p, NULL), + ASSERT_EQ (merged_smap->get_state (merged_model->get_rvalue (p, nullptr), ext_state), TEST_STATE); @@ -2032,7 +2053,7 @@ test_program_state_merging_2 () engine eng; region_model_manager *mgr = eng.get_model_manager (); program_point point (program_point::origin (*mgr)); - extrinsic_state ext_state (make_signal_state_machine (NULL), &eng); + extrinsic_state ext_state (make_signal_state_machine (nullptr), &eng); const state_machine::state test_state_0 ("test state 0", 0); const state_machine::state test_state_1 ("test state 1", 1); diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h index 269ffde9ee6c..4278237adc80 100644 --- a/gcc/analyzer/program-state.h +++ b/gcc/analyzer/program-state.h @@ -22,6 +22,9 @@ along with GCC; see the file COPYING3. If not see #define GCC_ANALYZER_PROGRAM_STATE_H #include "text-art/widget.h" +#include "text-art/tree-widget.h" + +#include "analyzer/store.h" namespace ana { @@ -32,7 +35,7 @@ class extrinsic_state public: extrinsic_state (std::vector<std::unique_ptr<state_machine>> &&checkers, engine *eng, - logger *logger = NULL) + logger *logger = nullptr) : m_checkers (std::move (checkers)), m_logger (logger), m_engine (eng) @@ -42,7 +45,7 @@ class extrinsic_state // For use in selftests that use just one state machine extrinsic_state (std::unique_ptr<state_machine> sm, engine *eng, - logger *logger = NULL) + logger *logger = nullptr) : m_logger (logger), m_engine (eng) { @@ -93,7 +96,7 @@ class sm_state_map { /* Default ctor needed by hash_map::empty. */ entry_t () - : m_state (0), m_origin (NULL) + : m_state (0), m_origin (nullptr) { } @@ -243,6 +246,15 @@ class program_state void dump (const extrinsic_state &ext_state, bool simple) const; void dump () const; + std::unique_ptr<diagnostics::digraphs::digraph> + make_diagnostic_state_graph (const extrinsic_state &ext_state) const; + + void + dump_sarif (const extrinsic_state &ext_state) const; + + void + dump_dot (const extrinsic_state &ext_state) const; + std::unique_ptr<json::object> to_json (const extrinsic_state &ext_state) const; diff --git a/gcc/analyzer/record-layout.cc b/gcc/analyzer/record-layout.cc index aaf8ccd6f969..344653673227 100644 --- a/gcc/analyzer/record-layout.cc +++ b/gcc/analyzer/record-layout.cc @@ -30,7 +30,7 @@ namespace ana { /* class record_layout. */ -record_layout::record_layout (tree record_type) +record_layout::record_layout (const_tree record_type) { gcc_assert (TREE_CODE (record_type) == RECORD_TYPE); @@ -86,7 +86,7 @@ record_layout::get_item_at (bit_offset_t offset) const FOR_EACH_VEC_ELT (m_items, i, it) if (it->contains_p (offset)) return it; - return NULL; + return nullptr; } /* Subroutine of ctor. Add padding item to NEXT_OFFSET if necessary. */ diff --git a/gcc/analyzer/record-layout.h b/gcc/analyzer/record-layout.h index c1c41890dcd1..8649d1d601cd 100644 --- a/gcc/analyzer/record-layout.h +++ b/gcc/analyzer/record-layout.h @@ -36,7 +36,7 @@ class record_layout { public: item (const bit_range &br, - tree field, + const_tree field, bool is_padding) : m_bit_range (br), m_field (field), @@ -69,17 +69,20 @@ class record_layout } bit_range m_bit_range; - tree m_field; + const_tree m_field; bool m_is_padding; }; - record_layout (tree record_type); + record_layout (const_tree record_type); void dump_to_pp (pretty_printer *pp) const; DEBUG_FUNCTION void dump () const; const record_layout::item *get_item_at (bit_offset_t offset) const; + auto begin () const { return m_items.begin (); } + auto end () const { return m_items.end (); } + private: void maybe_pad_to (bit_offset_t next_offset); diff --git a/gcc/analyzer/region-model-asm.cc b/gcc/analyzer/region-model-asm.cc index 7d7e3b9258d5..fe704901a978 100644 --- a/gcc/analyzer/region-model-asm.cc +++ b/gcc/analyzer/region-model-asm.cc @@ -119,7 +119,7 @@ deterministic_p (const gasm *asm_stmt) void region_model::on_asm_stmt (const gasm *stmt, region_model_context *ctxt) { - logger *logger = ctxt ? ctxt->get_logger () : NULL; + logger *logger = ctxt ? ctxt->get_logger () : nullptr; LOG_SCOPE (logger); const unsigned noutputs = gimple_asm_noutputs (stmt); @@ -171,7 +171,8 @@ region_model::on_asm_stmt (const gasm *stmt, region_model_context *ctxt) no point in going further. */ constraint = constraints[i]; if (!parse_output_constraint (&constraint, i, ninputs, noutputs, - &allows_mem, &allows_reg, &is_inout)) + &allows_mem, &allows_reg, &is_inout, + nullptr)) { if (logger) logger->log ("error parsing constraint for output %i: %qs", @@ -204,8 +205,8 @@ region_model::on_asm_stmt (const gasm *stmt, region_model_context *ctxt) const char *constraint = constraints[i + noutputs]; bool allows_reg, allows_mem; if (! parse_input_constraint (&constraint, i, ninputs, noutputs, 0, - constraints.address (), - &allows_mem, &allows_reg)) + constraints.address (), &allows_mem, + &allows_reg, nullptr)) { if (logger) logger->log ("error parsing constraint for input %i: %qs", @@ -216,7 +217,7 @@ region_model::on_asm_stmt (const gasm *stmt, region_model_context *ctxt) tree src_expr = input_tvec[i]; const svalue *src_sval = get_rvalue (src_expr, ctxt); - check_for_poison (src_sval, src_expr, NULL, ctxt); + check_for_poison (src_sval, src_expr, nullptr, ctxt); input_svals.quick_push (src_sval); reachable_regs.handle_sval (src_sval); diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index df92503770b3..872b1d6a8528 100644 --- a/gcc/analyzer/region-model-manager.cc +++ b/gcc/analyzer/region-model-manager.cc @@ -49,7 +49,7 @@ region_model_manager::region_model_manager (logger *logger) m_root_region (alloc_symbol_id ()), m_stack_region (alloc_symbol_id (), &m_root_region), m_heap_region (alloc_symbol_id (), &m_root_region), - m_unknown_NULL (NULL), + m_unknown_NULL (nullptr), m_checking_feasibility (false), m_max_complexity (0, 0), m_code_region (alloc_symbol_id (), &m_root_region), @@ -259,7 +259,7 @@ region_model_manager::get_or_create_null_ptr (tree pointer_type) return get_or_create_int_cst (pointer_type, 0); } -/* Return the svalue * for a unknown_svalue for TYPE (which can be NULL), +/* Return the svalue * for a unknown_svalue for TYPE (which can be NULL_TREE), creating it if necessary. The unknown_svalue instances are reused, based on pointer equality of the types */ @@ -407,7 +407,7 @@ region_model_manager::get_ptr_svalue (tree ptr_type, const region *pointee) /* Subroutine of region_model_manager::get_or_create_unaryop. Attempt to fold the inputs and return a simpler svalue *. - Otherwise, return NULL. */ + Otherwise, return nullptr. */ const svalue * region_model_manager::maybe_fold_unaryop (tree type, enum tree_code op, @@ -516,7 +516,7 @@ region_model_manager::maybe_fold_unaryop (tree type, enum tree_code op, } } - return NULL; + return nullptr; } /* Return the svalue * for an unary operation OP on ARG with a result of @@ -594,7 +594,7 @@ region_model_manager::get_or_create_cast (tree type, const svalue *arg) If COMPOUND_SVAL has a value for the appropriate bits, return it, shifted accordingly. - Otherwise return NULL. */ + Otherwise return nullptr. */ const svalue * region_model_manager:: @@ -606,7 +606,7 @@ maybe_undo_optimize_bit_field_compare (tree type, if (!type) return nullptr; if (!INTEGRAL_TYPE_P (type)) - return NULL; + return nullptr; const binding_map &map = compound_sval->get_map (); unsigned HOST_WIDE_INT mask = TREE_INT_CST_LOW (cst); @@ -614,7 +614,7 @@ maybe_undo_optimize_bit_field_compare (tree type, compound_sval has a value for those bits. */ bit_range bits (0, 0); if (!bit_range::from_mask (mask, &bits)) - return NULL; + return nullptr; bit_range bound_bits (bits); if (BYTES_BIG_ENDIAN) @@ -624,7 +624,7 @@ maybe_undo_optimize_bit_field_compare (tree type, = get_store_manager ()->get_concrete_binding (bound_bits); const svalue *sval = map.get (conc); if (!sval) - return NULL; + return nullptr; /* We have a value; shift it by the correct number of bits. */ @@ -641,7 +641,7 @@ maybe_undo_optimize_bit_field_compare (tree type, /* Subroutine of region_model_manager::get_or_create_binop. Attempt to fold the inputs and return a simpler svalue *. - Otherwise, return NULL. */ + Otherwise, return nullptr. */ const svalue * region_model_manager::maybe_fold_binop (tree type, enum tree_code op, @@ -669,7 +669,7 @@ region_model_manager::maybe_fold_binop (tree type, enum tree_code op, if ((type && FLOAT_TYPE_P (type)) || (arg0->get_type () && FLOAT_TYPE_P (arg0->get_type ())) || (arg1->get_type () && FLOAT_TYPE_P (arg1->get_type ()))) - return NULL; + return nullptr; switch (op) { @@ -898,7 +898,7 @@ region_model_manager::maybe_fold_binop (tree type, enum tree_code op, /* etc. */ - return NULL; + return nullptr; } /* Return the svalue * for an binary operation OP on ARG0 and ARG1 @@ -933,7 +933,7 @@ region_model_manager::get_or_create_binop (tree type, enum tree_code op, } /* Subroutine of region_model_manager::get_or_create_sub_svalue. - Return a folded svalue, or NULL. */ + Return a folded svalue, or nullptr. */ const svalue * region_model_manager::maybe_fold_sub_svalue (tree type, @@ -1020,7 +1020,7 @@ region_model_manager::maybe_fold_sub_svalue (tree type, if (type) return get_or_create_cast (type, repeated_sval->get_inner_svalue ()); - return NULL; + return nullptr; } /* Return the svalue * for extracting a subvalue of type TYPE from @@ -1046,7 +1046,7 @@ region_model_manager::get_or_create_sub_svalue (tree type, } /* Subroutine of region_model_manager::get_or_create_repeated_svalue. - Return a folded svalue, or NULL. */ + Return a folded svalue, or nullptr. */ const svalue * region_model_manager::maybe_fold_repeated_svalue (tree type, @@ -1080,7 +1080,7 @@ region_model_manager::maybe_fold_repeated_svalue (tree type, if (zerop (cst) && type) return get_or_create_cast (type, inner_svalue); - return NULL; + return nullptr; } /* Return the svalue * of type TYPE in which INNER_SVALUE is repeated @@ -1274,7 +1274,7 @@ region_model_manager::maybe_fold_bits_within_svalue (tree type, } break; } - return NULL; + return nullptr; } /* Return the svalue * of type TYPE for extracting BITS from INNER_SVALUE, @@ -1401,7 +1401,7 @@ region_model_manager::get_or_create_conjured_svalue (tree type, } /* Subroutine of region_model_manager::get_or_create_asm_output_svalue. - Return a folded svalue, or NULL. */ + Return a folded svalue, or nullptr. */ const svalue * region_model_manager:: @@ -1413,7 +1413,7 @@ maybe_fold_asm_output_svalue (tree type, if (iter->get_kind () == SK_UNKNOWN) return get_or_create_unknown_svalue (type); - return NULL; + return nullptr; } /* Return the svalue * of type TYPE for OUTPUT_IDX of the deterministic @@ -1501,7 +1501,7 @@ get_or_create_const_fn_result_svalue (tree type, /* Given DATA_CST (a STRING_CST or RAW_DATA_CST) and BYTE_OFFSET_CST a constant, attempt to get the character at that offset, returning either - the svalue for the character constant, or NULL if unsuccessful. */ + the svalue for the character constant, or nullptr if unsuccessful. */ const svalue * region_model_manager::maybe_get_char_from_cst (tree data_cst, @@ -1533,7 +1533,7 @@ get_string_cst_size (const_tree string_cst) /* Given STRING_CST, a STRING_CST and BYTE_OFFSET_CST a constant, attempt to get the character at that offset, returning either - the svalue for the character constant, or NULL if unsuccessful. */ + the svalue for the character constant, or nullptr if unsuccessful. */ const svalue * region_model_manager::maybe_get_char_from_string_cst (tree string_cst, @@ -1552,7 +1552,7 @@ region_model_manager::maybe_get_char_from_string_cst (tree string_cst, if (compare_constants (byte_offset_cst, GE_EXPR, get_string_cst_size (string_cst)).is_true ()) - return NULL; + return nullptr; int char_val; if (compare_tree_int (byte_offset_cst, @@ -1567,12 +1567,12 @@ region_model_manager::maybe_get_char_from_string_cst (tree string_cst, = build_int_cst_type (TREE_TYPE (TREE_TYPE (string_cst)), char_val); return get_or_create_constant_svalue (char_cst); } - return NULL; + return nullptr; } /* Given RAW_DATA_CST, a RAW_DATA_CST and BYTE_OFFSET_CST a constant, attempt to get the character at that offset, returning either - the svalue for the character constant, or NULL if unsuccessful. */ + the svalue for the character constant, or nullptr if unsuccessful. */ const svalue * region_model_manager::maybe_get_char_from_raw_data_cst (tree raw_data_cst, @@ -1801,7 +1801,7 @@ region_model_manager::get_cast_region (const region *original_region, } /* Return the frame_region for call to FUN from CALLING_FRAME, creating it - if necessary. CALLING_FRAME may be NULL. */ + if necessary. CALLING_FRAME may be nullptr. */ const frame_region * region_model_manager::get_frame_region (const frame_region *calling_frame, diff --git a/gcc/analyzer/region-model-manager.h b/gcc/analyzer/region-model-manager.h index c3f0a645a201..865bedfb8624 100644 --- a/gcc/analyzer/region-model-manager.h +++ b/gcc/analyzer/region-model-manager.h @@ -31,7 +31,7 @@ namespace ana { class region_model_manager { public: - region_model_manager (logger *logger = NULL); + region_model_manager (logger *logger = nullptr); ~region_model_manager (); unsigned get_num_symbols () const { return m_next_symbol_id; } diff --git a/gcc/analyzer/region-model-reachability.cc b/gcc/analyzer/region-model-reachability.cc index d3bfeb7066c1..0fe324d001fb 100644 --- a/gcc/analyzer/region-model-reachability.cc +++ b/gcc/analyzer/region-model-reachability.cc @@ -68,7 +68,7 @@ reachable_regions::init_cluster (const region *base_reg) if (const symbolic_region *sym_reg = base_reg->dyn_cast_symbolic_region ()) { const svalue *ptr = sym_reg->get_pointer (); - if (ptr->implicitly_live_p (NULL, m_model)) + if (ptr->implicitly_live_p (nullptr, m_model)) add (base_reg, true); switch (ptr->get_kind ()) { @@ -84,7 +84,7 @@ reachable_regions::init_cluster (const region *base_reg) const region *other_base_reg = init_sval_reg->get_base_region (); const binding_cluster *other_cluster = m_store->get_cluster (other_base_reg); - if (other_cluster == NULL + if (other_cluster == nullptr || !other_cluster->touched_p ()) add (base_reg, true); } @@ -131,7 +131,7 @@ reachable_regions::add (const region *reg, bool is_mutable) if (binding_cluster *bind_cluster = m_store->get_cluster (base_reg)) bind_cluster->for_each_value (handle_sval_cb, this); else - handle_sval (m_model->get_store_value (reg, NULL)); + handle_sval (m_model->get_store_value (reg, nullptr)); } void diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 1ee882c98ea5..6df38429313f 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -159,7 +159,7 @@ region_to_value_map::operator== (const region_to_value_map &other) const const region *reg = iter.first; const svalue *sval = iter.second; const svalue * const *other_slot = other.get (reg); - if (other_slot == NULL) + if (other_slot == nullptr) return false; if (sval != *other_slot) return false; @@ -403,7 +403,7 @@ exception_node::add_to_reachable_regions (reachable_regions ®s) const /* Ctor for region_model: construct an "empty" model. */ region_model::region_model (region_model_manager *mgr) -: m_mgr (mgr), m_store (), m_current_frame (NULL), +: m_mgr (mgr), m_store (), m_current_frame (nullptr), m_thrown_exceptions_stack (), m_caught_exceptions_stack (), m_dynamic_extents () @@ -895,7 +895,7 @@ class poisoned_value_diagnostic /* Couldn't get state; accept this diagnostic. */ return true; - const svalue *fsval = emission_model.get_rvalue (m_check_expr, NULL); + const svalue *fsval = emission_model.get_rvalue (m_check_expr, nullptr); /* Check to see if the expr is also poisoned in FNODE (and in the same way). */ const poisoned_svalue * fspval = fsval->dyn_cast_poisoned_svalue (); @@ -1173,7 +1173,7 @@ check_for_invalid_ptrdiff (const gassign *assign, /* If ASSIGN is a stmt that can be modelled via set_value (lhs_reg, SVALUE, CTXT) for some SVALUE, get the SVALUE. - Otherwise return NULL. */ + Otherwise return nullptr. */ const svalue * region_model::get_gassign_result (const gassign *assign, @@ -1196,7 +1196,7 @@ region_model::get_gassign_result (const gassign *assign, switch (op) { default: - return NULL; + return nullptr; case POINTER_PLUS_EXPR: { @@ -1461,8 +1461,8 @@ within_short_circuited_stmt_p (const region_model *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); + /* Use a nullptr ctxt here to avoid generating warnings. */ + const svalue *other_arg_sval = model->get_rvalue (other_arg, nullptr); tree other_arg_cst = other_arg_sval->maybe_get_constant (); if (!other_arg_cst) return false; @@ -1529,7 +1529,7 @@ due_to_ifn_deferred_init_p (const gassign *assign_stmt) /* 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. - SRC_REGION is a hint about where SVAL came from, and can be NULL. */ + SRC_REGION is a hint about where SVAL came from, and can be nullptr. */ const svalue * region_model::check_for_poison (const svalue *sval, @@ -1572,7 +1572,7 @@ region_model::check_for_poison (const svalue *sval, the tree other than via the def stmts, using fixup_tree_for_diagnostic. */ tree diag_arg = fixup_tree_for_diagnostic (expr); - if (src_region == NULL && pkind == poison_kind::uninit) + if (src_region == nullptr && pkind == poison_kind::uninit) src_region = get_region_for_poisoned_expr (expr); /* Can we reliably get the poisoned value from "expr"? @@ -1581,11 +1581,11 @@ region_model::check_for_poison (const svalue *sval, Hence we only query its value now, and only use it if we get the poisoned value back again. */ tree check_expr = expr; - const svalue *foo_sval = get_rvalue (expr, NULL); + const svalue *foo_sval = get_rvalue (expr, nullptr); if (foo_sval == sval) check_expr = expr; else - check_expr = NULL; + check_expr = nullptr; if (ctxt->warn (std::make_unique<poisoned_value_diagnostic> (diag_arg, pkind, @@ -1606,7 +1606,7 @@ region_model::check_for_poison (const svalue *sval, /* Attempt to get a region for describing EXPR, the source of region of a poisoned_svalue for use in a poisoned_value_diagnostic. - Return NULL if there is no good region to use. */ + Return nullptr if there is no good region to use. */ const region * region_model::get_region_for_poisoned_expr (tree expr) const @@ -1617,9 +1617,9 @@ region_model::get_region_for_poisoned_expr (tree expr) const if (decl && DECL_P (decl)) expr = decl; else - return NULL; + return nullptr; } - return get_lvalue (expr, NULL); + return get_lvalue (expr, nullptr); } /* Update this model for the ASSIGN stmt, using CTXT to report any @@ -1648,7 +1648,7 @@ region_model::on_assignment (const gassign *assign, region_model_context *ctxt) if (const svalue *sval = get_gassign_result (assign, ctxt)) { tree expr = get_diagnostic_tree_for_gassign (assign); - check_for_poison (sval, expr, NULL, ctxt); + check_for_poison (sval, expr, nullptr, ctxt); set_value (lhs_reg, sval, ctxt); return; } @@ -1708,7 +1708,7 @@ region_model::on_assignment (const gassign *assign, region_model_context *ctxt) /* e.g. "struct s2 x = {{'A', 'B', 'C', 'D'}};". */ const svalue *rhs_sval = get_rvalue (rhs1, ctxt); m_store.set_value (m_mgr->get_store_manager(), lhs_reg, rhs_sval, - ctxt ? ctxt->get_uncertainty () : NULL); + ctxt ? ctxt->get_uncertainty () : nullptr); } break; } @@ -1939,7 +1939,7 @@ region_model::update_for_nonzero_return (const call_details &cd) to set an upper bound on the size of a copy_to_user. Attempt to simplify such sizes by trying to get the upper bound as a constant. - Return the simplified svalue if possible, or NULL otherwise. */ + Return the simplified svalue if possible, or nullptr otherwise. */ static const svalue * maybe_simplify_upper_bound (const svalue *num_bytes_sval, @@ -1957,7 +1957,7 @@ maybe_simplify_upper_bound (const svalue *num_bytes_sval, when recording the diagnostic, or note that we're using the upper bound. */ } - return NULL; + return nullptr; } /* Attempt to get an upper bound for the size of a copy when simulating a @@ -1968,7 +1968,7 @@ maybe_simplify_upper_bound (const svalue *num_bytes_sval, that, use the size of SRC_REG if constant. Return a symbolic value for an upper limit on the number of bytes - copied, or NULL if no such value could be determined. */ + copied, or nullptr if no such value could be determined. */ const svalue * region_model::maybe_get_copy_bounds (const region *src_reg, @@ -1994,7 +1994,7 @@ region_model::maybe_get_copy_bounds (const region *src_reg, return num_bytes_sval; /* Non-constant: give up. */ - return NULL; + return nullptr; } /* Get any known_function for FNDECL for call CD. @@ -2002,7 +2002,7 @@ region_model::maybe_get_copy_bounds (const region *src_reg, The call must match all assumptions made by the known_function (such as e.g. "argument 1's type must be a pointer type"). - Return NULL if no known_function is found, or it does not match the + Return nullptr if no known_function is found, or it does not match the assumption(s). */ const known_function * @@ -2012,7 +2012,7 @@ region_model::get_known_function (tree fndecl, const call_details &cd) const return known_fn_mgr->get_match (fndecl, cd); } -/* Get any known_function for IFN, or NULL. */ +/* Get any known_function for IFN, or nullptr. */ const known_function * region_model::get_known_function (enum internal_fn ifn) const @@ -2022,12 +2022,12 @@ region_model::get_known_function (enum internal_fn ifn) const } /* Get any builtin_known_function for CALL and emit any warning to CTXT - if not NULL. + if not nullptr. The call must match all assumptions made by the known_function (such as e.g. "argument 1's type must be a pointer type"). - Return NULL if no builtin_known_function is found, or it does + Return nullptr if no builtin_known_function is found, or it does not match the assumption(s). Internally calls get_known_function to find a known_function and cast it @@ -2063,18 +2063,18 @@ region_model::get_known_function (enum internal_fn ifn) const const builtin_known_function * region_model::get_builtin_kf (const gcall &call, - region_model_context *ctxt /* = NULL */) const + region_model_context *ctxt /* = nullptr */) const { region_model *mut_this = const_cast <region_model *> (this); tree callee_fndecl = mut_this->get_fndecl_for_call (call, ctxt); if (! callee_fndecl) - return NULL; + return nullptr; call_details cd (call, mut_this, ctxt); if (const known_function *kf = get_known_function (callee_fndecl, cd)) return kf->dyn_cast_builtin_kf (); - return NULL; + return nullptr; } /* Subclass of custom_edge_info for use by exploded_edges that represent @@ -2090,7 +2090,7 @@ class exception_thrown_from_unrecognized_call : public custom_edge_info { } - void print (pretty_printer *pp) const + void print (pretty_printer *pp) const final override { if (m_fndecl) pp_printf (pp, "if %qD throws an exception...", m_fndecl); @@ -2677,7 +2677,7 @@ region_model::handle_unrecognized_call (const gcall &call, } } - uncertainty_t *uncertainty = ctxt ? ctxt->get_uncertainty () : NULL; + uncertainty_t *uncertainty = ctxt ? ctxt->get_uncertainty () : nullptr; /* Purge sm-state for the svalues that were reachable, both in non-mutable and mutable form. */ @@ -2839,7 +2839,7 @@ region_model::on_longjmp (const gcall &longjmp_call, const gcall &setjmp_call, setjmp was called. */ gcc_assert (get_stack_depth () >= setjmp_stack_depth); while (get_stack_depth () > setjmp_stack_depth) - pop_frame (NULL, NULL, ctxt, nullptr, false); + pop_frame (nullptr, nullptr, ctxt, nullptr, false); gcc_assert (get_stack_depth () == setjmp_stack_depth); @@ -3040,7 +3040,7 @@ const region * region_model::get_lvalue (path_var pv, region_model_context *ctxt) const { if (pv.m_tree == NULL_TREE) - return NULL; + return nullptr; const region *result_reg = get_lvalue_1 (pv, ctxt); assert_compat_types (result_reg->get_type (), TREE_TYPE (pv.m_tree)); @@ -3185,13 +3185,13 @@ const svalue * region_model::get_rvalue (path_var pv, region_model_context *ctxt) const { if (pv.m_tree == NULL_TREE) - return NULL; + return nullptr; const svalue *result_sval = get_rvalue_1 (pv, ctxt); assert_compat_types (result_sval->get_type (), TREE_TYPE (pv.m_tree)); - result_sval = check_for_poison (result_sval, pv.m_tree, NULL, ctxt); + result_sval = check_for_poison (result_sval, pv.m_tree, nullptr, ctxt); return result_sval; } @@ -3579,7 +3579,7 @@ void region_model::check_for_writable_region (const region* dest_reg, region_model_context *ctxt) const { - /* Fail gracefully if CTXT is NULL. */ + /* Fail gracefully if CTXT is nullptr. */ if (!ctxt) return; @@ -3644,13 +3644,13 @@ region_model::get_capacity (const region *reg) const { tree type = TREE_TYPE (decl); tree size = TYPE_SIZE (type); - return get_rvalue (size, NULL); + return get_rvalue (size, nullptr); } else { tree size = decl_init_size (decl, false); if (size) - return get_rvalue (size, NULL); + return get_rvalue (size, nullptr); } } break; @@ -3727,7 +3727,7 @@ bool region_model::check_region_for_read (const region *src_reg, region_model_context *ctxt) const { - return check_region_access (src_reg, access_direction::read, NULL, ctxt); + return check_region_access (src_reg, access_direction::read, nullptr, ctxt); } /* Concrete subclass for casts of pointers that lead to trailing bytes. */ @@ -4115,7 +4115,7 @@ void region_model::check_region_size (const region *lhs_reg, const svalue *rhs_sval, region_model_context *ctxt) const { - if (!ctxt || ctxt->get_stmt () == NULL) + if (!ctxt || ctxt->get_stmt () == nullptr) return; /* Only report warnings on assignments that actually change the type. */ if (!is_any_cast_p (ctxt->get_stmt ())) @@ -4208,7 +4208,7 @@ region_model::set_value (const region *lhs_reg, const svalue *rhs_sval, check_region_for_write (lhs_reg, rhs_sval, ctxt); m_store.set_value (m_mgr->get_store_manager(), lhs_reg, rhs_sval, - ctxt ? ctxt->get_uncertainty () : NULL); + ctxt ? ctxt->get_uncertainty () : nullptr); } /* Set the value of the region given by LHS to the value given by RHS. */ @@ -4845,7 +4845,7 @@ region_model::scan_for_null_terminator (const region *reg, Simulate scanning through the buffer, reading until we find a 0 byte (equivalent to calling strlen). - Complain and return NULL if: + Complain and return nullptr if: - the buffer pointed to isn't null-terminated - the buffer pointed to has any uninitalized bytes before any 0-terminator - any of the reads aren't within the bounds of the underlying base region @@ -4873,7 +4873,7 @@ region_model::check_for_null_terminated_string_arg (const call_details &cd, Simulate scanning through the buffer, reading until we find a 0 byte (equivalent to calling strlen). - Complain and return NULL if: + Complain and return nullptr if: - the buffer pointed to isn't null-terminated - the buffer pointed to has any uninitalized bytes before any 0-terminator - any of the reads aren't within the bounds of the underlying base region @@ -4882,7 +4882,7 @@ region_model::check_for_null_terminated_string_arg (const call_details &cd, (including the null terminator) if INCLUDE_TERMINATOR is true, or strlen of the buffer (not including the null terminator) if it is false. - Also, when returning an svalue, if OUT_SVAL is non-NULL, write to + Also, when returning an svalue, if OUT_SVAL is non-nullptr, write to *OUT_SVAL with an svalue representing the content of the buffer up to and including the terminator. @@ -5845,7 +5845,7 @@ region_model::get_representative_path_var (const svalue *sval, svalue_set *visited, logger *logger) const { - if (sval == NULL) + if (sval == nullptr) return path_var (NULL_TREE, 0); LOG_SCOPE (logger); @@ -6204,7 +6204,7 @@ region_model::maybe_update_for_edge (const superedge &edge, break; } - if (last_stmt == NULL) + if (last_stmt == nullptr) return true; /* Apply any constraints for conditionals/switch/computed-goto statements. */ @@ -6285,7 +6285,7 @@ region_model::update_for_return_gcall (const gcall &call_stmt, so that pop_frame can determine the region with respect to the *caller* frame. */ tree lhs = gimple_call_lhs (&call_stmt); - pop_frame (lhs, NULL, ctxt, &call_stmt); + pop_frame (lhs, nullptr, ctxt, &call_stmt); } /* Extract calling information from the superedge and update the model for the @@ -6361,7 +6361,7 @@ apply_constraints_for_gcond (const cfg_superedge &sedge, std::unique_ptr<rejected_constraint> *out) { ::edge cfg_edge = sedge.get_cfg_edge (); - gcc_assert (cfg_edge != NULL); + gcc_assert (cfg_edge != nullptr); gcc_assert (cfg_edge->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)); enum tree_code op = gimple_cond_code (cond_stmt); @@ -6379,7 +6379,7 @@ static bool has_nondefault_case_for_value_p (const gswitch *switch_stmt, tree int_cst) { /* We expect the initial label to be the default; skip it. */ - gcc_assert (CASE_LOW (gimple_switch_label (switch_stmt, 0)) == NULL); + gcc_assert (CASE_LOW (gimple_switch_label (switch_stmt, 0)) == NULL_TREE); unsigned min_idx = 1; unsigned max_idx = gimple_switch_num_labels (switch_stmt) - 1; @@ -6981,7 +6981,7 @@ region_model::pop_frame (tree result_lvalue, /* Evaluate the result, within the callee frame. */ tree fndecl = m_current_frame->get_function ().decl; tree result = DECL_RESULT (fndecl); - const svalue *retval = NULL; + const svalue *retval = nullptr; if (result && TREE_TYPE (result) != void_type_node && eval_return_svalue) @@ -7312,7 +7312,7 @@ class float_as_size_arg : public imprecise_floating_point_arithmetic class contains_floating_point_visitor : public visitor { public: - contains_floating_point_visitor (const svalue *root_sval) : m_result (NULL) + contains_floating_point_visitor (const svalue *root_sval) : m_result (nullptr) { root_sval->accept (this); } @@ -7476,7 +7476,7 @@ region_model::set_dynamic_extents (const region *reg, m_dynamic_extents.put (reg, size_in_bytes); } -/* Get the recording of REG in bytes, or NULL if no dynamic size was +/* Get the recording of REG in bytes, or nullptr if no dynamic size was recorded. */ const svalue * @@ -7484,7 +7484,7 @@ region_model::get_dynamic_extents (const region *reg) const { if (const svalue * const *slot = m_dynamic_extents.get (reg)) return *slot; - return NULL; + return nullptr; } /* Unset any recorded dynamic size of REG. */ @@ -7798,7 +7798,7 @@ class exposure_through_uninit_copy static void complain_about_fully_uninit_item (const record_layout::item &item) { - tree field = item.m_field; + const_tree field = item.m_field; bit_size_t num_bits = item.m_bit_range.m_size_in_bits; if (item.m_is_padding) { @@ -7859,7 +7859,7 @@ class exposure_through_uninit_copy static void complain_about_partially_uninit_item (const record_layout::item &item) { - tree field = item.m_field; + const_tree field = item.m_field; if (item.m_is_padding) inform (DECL_SOURCE_LOCATION (field), "padding after field %qD is partially uninitialized", @@ -7930,7 +7930,7 @@ contains_uninit_p (const svalue *sval) Check that COPIED_SVAL is fully initialized. If not, complain about an infoleak to CTXT. - SRC_REG can be NULL; if non-NULL it is used as a hint in the diagnostic + SRC_REG can be nullptr; if non-NULL it is used as a hint in the diagnostic as to where COPIED_SVAL came from. */ void @@ -8083,8 +8083,8 @@ void rejected_op_constraint::dump_to_pp (pretty_printer *pp) const { region_model m (m_model); - const svalue *lhs_sval = m.get_rvalue (m_lhs, NULL); - const svalue *rhs_sval = m.get_rvalue (m_rhs, NULL); + const svalue *lhs_sval = m.get_rvalue (m_lhs, nullptr); + const svalue *rhs_sval = m.get_rvalue (m_rhs, nullptr); lhs_sval->dump_to_pp (pp, true); pp_printf (pp, " %s ", op_symbol_code (m_op)); rhs_sval->dump_to_pp (pp, true); @@ -8104,7 +8104,7 @@ void rejected_ranges_constraint::dump_to_pp (pretty_printer *pp) const { region_model m (m_model); - const svalue *sval = m.get_rvalue (m_expr, NULL); + const svalue *sval = m.get_rvalue (m_expr, nullptr); sval->dump_to_pp (pp, true); pp_string (pp, " in "); m_ranges->dump_to_pp (pp, true); @@ -8205,7 +8205,7 @@ assert_condition (const location &loc, tree lhs, tree_code op, tree rhs, tristate expected) { - tristate actual = model.eval_condition (lhs, op, rhs, NULL); + tristate actual = model.eval_condition (lhs, op, rhs, nullptr); ASSERT_EQ_AT (loc, actual, expected); } @@ -8294,7 +8294,7 @@ make_test_compound_type (const char *name, bool is_struct, TYPE_NAME (t) = get_identifier (name); TYPE_SIZE (t) = 0; - tree fieldlist = NULL; + tree fieldlist = NULL_TREE; int i; tree field; FOR_EACH_VEC_ELT (*fields, i, field) @@ -8349,22 +8349,22 @@ test_struct () region_model_manager mgr; region_model model (&mgr); - model.set_value (c_x, int_17, NULL); - model.set_value (c_y, int_m3, NULL); + model.set_value (c_x, int_17, nullptr); + model.set_value (c_y, int_m3, nullptr); /* Verify get_offset for "c.x". */ { - const region *c_x_reg = model.get_lvalue (c_x, NULL); + const region *c_x_reg = model.get_lvalue (c_x, nullptr); region_offset offset = c_x_reg->get_offset (&mgr); - ASSERT_EQ (offset.get_base_region (), model.get_lvalue (c, NULL)); + ASSERT_EQ (offset.get_base_region (), model.get_lvalue (c, nullptr)); ASSERT_EQ (offset.get_bit_offset (), 0); } /* Verify get_offset for "c.y". */ { - const region *c_y_reg = model.get_lvalue (c_y, NULL); + const region *c_y_reg = model.get_lvalue (c_y, nullptr); region_offset offset = c_y_reg->get_offset (&mgr); - ASSERT_EQ (offset.get_base_region (), model.get_lvalue (c, NULL)); + ASSERT_EQ (offset.get_base_region (), model.get_lvalue (c, nullptr)); ASSERT_EQ (offset.get_bit_offset (), INT_TYPE_SIZE); } } @@ -8385,7 +8385,7 @@ test_array_1 () tree a_0 = build4 (ARRAY_REF, char_type_node, a, int_0, NULL_TREE, NULL_TREE); tree char_A = build_int_cst (char_type_node, 'A'); - model.set_value (a_0, char_A, NULL); + model.set_value (a_0, char_A, nullptr); } /* Verify that region_model::get_representative_tree works as expected. */ @@ -8399,7 +8399,7 @@ test_get_representative_tree () { tree string_cst = build_string (4, "foo"); region_model m (&mgr); - const svalue *str_sval = m.get_rvalue (string_cst, NULL); + const svalue *str_sval = m.get_rvalue (string_cst, nullptr); tree rep = m.get_representative_tree (str_sval); ASSERT_EQ (rep, string_cst); } @@ -8408,7 +8408,7 @@ test_get_representative_tree () { tree string_cst_ptr = build_string_literal (4, "foo"); region_model m (&mgr); - const svalue *str_sval = m.get_rvalue (string_cst_ptr, NULL); + const svalue *str_sval = m.get_rvalue (string_cst_ptr, nullptr); tree rep = m.get_representative_tree (str_sval); ASSERT_DUMP_TREE_EQ (rep, "&\"foo\"[0]"); } @@ -8533,12 +8533,12 @@ test_unique_unknowns () /* Different types (or the NULL type) should have different unknown_svalues. */ - const svalue *unknown_NULL_type = mgr.get_or_create_unknown_svalue (NULL); + const svalue *unknown_NULL_type = mgr.get_or_create_unknown_svalue (nullptr); ASSERT_NE (unknown_NULL_type, unknown_int); /* Repeated calls with NULL for the type should get the same "unknown" svalue. */ - const svalue *unknown_NULL_type_2 = mgr.get_or_create_unknown_svalue (NULL); + const svalue *unknown_NULL_type_2 = mgr.get_or_create_unknown_svalue (nullptr); ASSERT_EQ (unknown_NULL_type, unknown_NULL_type_2); } @@ -8882,9 +8882,9 @@ test_assignment () region_model model (&mgr); ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0); ASSERT_CONDITION_UNKNOWN (model, y, EQ_EXPR, int_0); - model.set_value (model.get_lvalue (y, NULL), - model.get_rvalue (int_0, NULL), - NULL); + model.set_value (model.get_lvalue (y, nullptr), + model.get_rvalue (int_0, nullptr), + nullptr); ASSERT_CONDITION_TRUE (model, y, EQ_EXPR, int_0); ASSERT_CONDITION_TRUE (model, y, EQ_EXPR, x); } @@ -8912,16 +8912,16 @@ test_compound_assignment () region_model_manager mgr; region_model model (&mgr); - model.set_value (c_x, int_17, NULL); - model.set_value (c_y, int_m3, NULL); + model.set_value (c_x, int_17, nullptr); + model.set_value (c_y, int_m3, nullptr); /* Copy c to d. */ - const svalue *sval = model.get_rvalue (c, NULL); - model.set_value (model.get_lvalue (d, NULL), sval, NULL); + const svalue *sval = model.get_rvalue (c, nullptr); + model.set_value (model.get_lvalue (d, nullptr), sval, nullptr); /* Check that the fields have the same svalues. */ - ASSERT_EQ (model.get_rvalue (c_x, NULL), model.get_rvalue (d_x, NULL)); - ASSERT_EQ (model.get_rvalue (c_y, NULL), model.get_rvalue (d_y, NULL)); + ASSERT_EQ (model.get_rvalue (c_x, nullptr), model.get_rvalue (d_x, nullptr)); + ASSERT_EQ (model.get_rvalue (c_y, nullptr), model.get_rvalue (d_y, nullptr)); } /* Verify the details of pushing and popping stack frames. */ @@ -9011,7 +9011,7 @@ test_stack_frames () model.set_value (p_in_globals_reg, mgr.get_ptr_svalue (ptr_type_node, x_in_child_reg), &ctxt); - ASSERT_EQ (p_in_globals_reg->maybe_get_frame_region (), NULL); + ASSERT_EQ (p_in_globals_reg->maybe_get_frame_region (), nullptr); /* Point another global pointer at p: q = &p. */ const region *q_in_globals_reg = model.get_lvalue (q, &ctxt); @@ -9025,13 +9025,13 @@ test_stack_frames () ASSERT_FALSE (a_in_parent_reg->descendent_of_p (child_frame_reg)); /* Pop the "child_fn" frame from the stack. */ - model.pop_frame (NULL, NULL, &ctxt, nullptr); + model.pop_frame (nullptr, nullptr, &ctxt, nullptr); ASSERT_FALSE (model.region_exists_p (child_frame_reg)); ASSERT_TRUE (model.region_exists_p (parent_frame_reg)); /* Verify that p (which was pointing at the local "x" in the popped frame) has been poisoned. */ - const svalue *new_p_sval = model.get_rvalue (p, NULL); + const svalue *new_p_sval = model.get_rvalue (p, nullptr); ASSERT_EQ (new_p_sval->get_kind (), SK_POISONED); ASSERT_EQ (new_p_sval->dyn_cast_poisoned_svalue ()->get_poison_kind (), poison_kind::popped_stack); @@ -9109,7 +9109,7 @@ test_get_representative_path_var () } /* ...and that we can lookup lvalues for locals for all frames, not just the top. */ - ASSERT_EQ (model.get_lvalue (path_var (n, depth), NULL), + ASSERT_EQ (model.get_lvalue (path_var (n, depth), nullptr), parm_regs[depth]); /* ...and that we can locate the svalues. */ { @@ -9138,22 +9138,22 @@ test_equality_1 () /* Verify that setting state in model1 makes the models non-equal. */ tree x = build_global_decl ("x", integer_type_node); - model0.set_value (x, int_42, NULL); - ASSERT_EQ (model0.get_rvalue (x, NULL)->maybe_get_constant (), int_42); + model0.set_value (x, int_42, nullptr); + ASSERT_EQ (model0.get_rvalue (x, nullptr)->maybe_get_constant (), int_42); ASSERT_NE (model0, model1); /* Verify the copy-ctor. */ region_model model2 (model0); ASSERT_EQ (model0, model2); - ASSERT_EQ (model2.get_rvalue (x, NULL)->maybe_get_constant (), int_42); + ASSERT_EQ (model2.get_rvalue (x, nullptr)->maybe_get_constant (), int_42); ASSERT_NE (model1, model2); /* Verify that models obtained from copy-ctor are independently editable w/o affecting the original model. */ - model2.set_value (x, int_17, NULL); + model2.set_value (x, int_17, nullptr); ASSERT_NE (model0, model2); - ASSERT_EQ (model2.get_rvalue (x, NULL)->maybe_get_constant (), int_17); - ASSERT_EQ (model0.get_rvalue (x, NULL)->maybe_get_constant (), int_42); + ASSERT_EQ (model2.get_rvalue (x, nullptr)->maybe_get_constant (), int_17); + ASSERT_EQ (model0.get_rvalue (x, nullptr)->maybe_get_constant (), int_42); } /* Verify that region models for @@ -9172,20 +9172,20 @@ test_canonicalization_2 () region_model_manager mgr; region_model model0 (&mgr); - model0.set_value (model0.get_lvalue (x, NULL), - model0.get_rvalue (int_42, NULL), - NULL); - model0.set_value (model0.get_lvalue (y, NULL), - model0.get_rvalue (int_113, NULL), - NULL); + model0.set_value (model0.get_lvalue (x, nullptr), + model0.get_rvalue (int_42, nullptr), + nullptr); + model0.set_value (model0.get_lvalue (y, nullptr), + model0.get_rvalue (int_113, nullptr), + nullptr); region_model model1 (&mgr); - model1.set_value (model1.get_lvalue (y, NULL), - model1.get_rvalue (int_113, NULL), - NULL); - model1.set_value (model1.get_lvalue (x, NULL), - model1.get_rvalue (int_42, NULL), - NULL); + model1.set_value (model1.get_lvalue (y, nullptr), + model1.get_rvalue (int_113, nullptr), + nullptr); + model1.set_value (model1.get_lvalue (x, nullptr), + model1.get_rvalue (int_42, nullptr), + nullptr); ASSERT_EQ (model0, model1); } @@ -9206,12 +9206,12 @@ test_canonicalization_3 () region_model_manager mgr; region_model model0 (&mgr); - model0.add_constraint (x, GT_EXPR, int_3, NULL); - model0.add_constraint (y, GT_EXPR, int_42, NULL); + model0.add_constraint (x, GT_EXPR, int_3, nullptr); + model0.add_constraint (y, GT_EXPR, int_42, nullptr); region_model model1 (&mgr); - model1.add_constraint (y, GT_EXPR, int_42, NULL); - model1.add_constraint (x, GT_EXPR, int_3, NULL); + model1.add_constraint (y, GT_EXPR, int_42, nullptr); + model1.add_constraint (x, GT_EXPR, int_3, nullptr); model0.canonicalize (); model1.canonicalize (); @@ -9231,7 +9231,7 @@ test_canonicalization_4 () region_model model (&mgr); for (tree cst : csts) - model.get_rvalue (cst, NULL); + model.get_rvalue (cst, nullptr); model.canonicalize (); } @@ -9240,7 +9240,7 @@ test_canonicalization_4 () with values VAL_A and VAL_B for EXPR that they are mergable. Write the merged model to *OUT_MERGED_MODEL, and the merged svalue ptr to *OUT_MERGED_SVALUE. - If VAL_A or VAL_B are NULL_TREE, don't populate EXPR + If VAL_A or VAL_B are nullptr_TREE, don't populate EXPR for that region_model. */ static void @@ -9431,8 +9431,8 @@ test_state_merging () region_model model0 (&mgr); model0.push_frame (*DECL_STRUCT_FUNCTION (test_fndecl), nullptr, nullptr, nullptr); - model0.set_value (model0.get_lvalue (p, NULL), - model0.get_rvalue (addr_of_a, NULL), NULL); + model0.set_value (model0.get_lvalue (p, nullptr), + model0.get_rvalue (addr_of_a, nullptr), nullptr); region_model model1 (model0); ASSERT_EQ (model0, model1); @@ -9456,7 +9456,7 @@ test_state_merging () const region_svalue *merged_p_ptr = merged_p_sval->dyn_cast_region_svalue (); const region *merged_p_star_reg = merged_p_ptr->get_pointee (); - ASSERT_EQ (merged_p_star_reg, merged.get_lvalue (y, NULL)); + ASSERT_EQ (merged_p_star_reg, merged.get_lvalue (y, nullptr)); } /* Pointers: non-NULL ptrs to different globals: should be unknown. */ @@ -9571,7 +9571,7 @@ test_state_merging () region_model model0 (&mgr); model0.push_frame (*DECL_STRUCT_FUNCTION (test_fndecl), nullptr, nullptr, nullptr); - const region *q_in_first_frame = model0.get_lvalue (q, NULL); + const region *q_in_first_frame = model0.get_lvalue (q, nullptr); /* Push a second frame. */ const region *reg_2nd_frame @@ -9580,8 +9580,8 @@ test_state_merging () /* Have a pointer in the older frame point to a local in the more recent frame. */ - const svalue *sval_ptr = model0.get_rvalue (addr_of_a, NULL); - model0.set_value (q_in_first_frame, sval_ptr, NULL); + const svalue *sval_ptr = model0.get_rvalue (addr_of_a, nullptr); + model0.set_value (q_in_first_frame, sval_ptr, nullptr); /* Verify that it's pointing at the newer frame. */ const region *reg_pointee = sval_ptr->maybe_get_region (); @@ -9605,8 +9605,8 @@ test_state_merging () region_model model0 (&mgr); model0.push_frame (*DECL_STRUCT_FUNCTION (test_fndecl), nullptr, nullptr, nullptr); - model0.set_value (model0.get_lvalue (q, NULL), - model0.get_rvalue (addr_of_y, NULL), NULL); + model0.set_value (model0.get_lvalue (q, nullptr), + model0.get_rvalue (addr_of_y, nullptr), nullptr); region_model model1 (model0); ASSERT_EQ (model0, model1); @@ -9638,14 +9638,14 @@ test_constraint_merging () /* model0: 0 <= (x == y) < n. */ region_model model0 (&mgr); model0.add_constraint (x, EQ_EXPR, y, &ctxt); - model0.add_constraint (x, GE_EXPR, int_0, NULL); - model0.add_constraint (x, LT_EXPR, n, NULL); + model0.add_constraint (x, GE_EXPR, int_0, nullptr); + model0.add_constraint (x, LT_EXPR, n, nullptr); /* model1: z != 5 && (0 <= x < n). */ region_model model1 (&mgr); - model1.add_constraint (z, NE_EXPR, int_5, NULL); - model1.add_constraint (x, GE_EXPR, int_0, NULL); - model1.add_constraint (x, LT_EXPR, n, NULL); + model1.add_constraint (z, NE_EXPR, int_5, nullptr); + model1.add_constraint (x, GE_EXPR, int_0, nullptr); + model1.add_constraint (x, LT_EXPR, n, nullptr); /* They should be mergeable; the merged constraints should be: (0 <= x < n). */ @@ -9870,17 +9870,17 @@ test_malloc_constraints () const svalue *size_in_bytes = mgr.get_or_create_unknown_svalue (size_type_node); const region *reg - = model.get_or_create_region_for_heap_alloc (size_in_bytes, NULL); + = model.get_or_create_region_for_heap_alloc (size_in_bytes, nullptr); const svalue *sval = mgr.get_ptr_svalue (ptr_type_node, reg); - model.set_value (model.get_lvalue (p, NULL), sval, NULL); - model.set_value (q, p, NULL); + model.set_value (model.get_lvalue (p, nullptr), sval, nullptr); + model.set_value (q, p, nullptr); ASSERT_CONDITION_UNKNOWN (model, p, NE_EXPR, null_ptr); ASSERT_CONDITION_UNKNOWN (model, p, EQ_EXPR, null_ptr); ASSERT_CONDITION_UNKNOWN (model, q, NE_EXPR, null_ptr); ASSERT_CONDITION_UNKNOWN (model, q, EQ_EXPR, null_ptr); - model.add_constraint (p, NE_EXPR, null_ptr, NULL); + model.add_constraint (p, NE_EXPR, null_ptr, nullptr); ASSERT_CONDITION_TRUE (model, p, NE_EXPR, null_ptr); ASSERT_CONDITION_FALSE (model, p, EQ_EXPR, null_ptr); @@ -9902,25 +9902,25 @@ test_var () region_model_manager mgr; region_model model (&mgr); - const region *i_reg = model.get_lvalue (i, NULL); + const region *i_reg = model.get_lvalue (i, nullptr); ASSERT_EQ (i_reg->get_kind (), RK_DECL); /* Reading "i" should give a symbolic "initial value". */ - const svalue *sval_init = model.get_rvalue (i, NULL); + const svalue *sval_init = model.get_rvalue (i, nullptr); ASSERT_EQ (sval_init->get_kind (), SK_INITIAL); ASSERT_EQ (sval_init->dyn_cast_initial_svalue ()->get_region (), i_reg); /* ..and doing it again should give the same "initial value". */ - ASSERT_EQ (model.get_rvalue (i, NULL), sval_init); + ASSERT_EQ (model.get_rvalue (i, nullptr), sval_init); /* "i = 17;". */ - model.set_value (i, int_17, NULL); - ASSERT_EQ (model.get_rvalue (i, NULL), - model.get_rvalue (int_17, NULL)); + model.set_value (i, int_17, nullptr); + ASSERT_EQ (model.get_rvalue (i, nullptr), + model.get_rvalue (int_17, nullptr)); /* "i = -3;". */ - model.set_value (i, int_m3, NULL); - ASSERT_EQ (model.get_rvalue (i, NULL), - model.get_rvalue (int_m3, NULL)); + model.set_value (i, int_m3, nullptr); + ASSERT_EQ (model.get_rvalue (i, nullptr), + model.get_rvalue (int_m3, nullptr)); /* Verify get_offset for "i". */ { @@ -9959,38 +9959,41 @@ test_array_2 () region_model_manager mgr; region_model model (&mgr); /* "arr[0] = 17;". */ - model.set_value (arr_0, int_17, NULL); + model.set_value (arr_0, int_17, nullptr); /* "arr[1] = -3;". */ - model.set_value (arr_1, int_m3, NULL); + model.set_value (arr_1, int_m3, nullptr); - ASSERT_EQ (model.get_rvalue (arr_0, NULL), model.get_rvalue (int_17, NULL)); - ASSERT_EQ (model.get_rvalue (arr_1, NULL), model.get_rvalue (int_m3, NULL)); + ASSERT_EQ (model.get_rvalue (arr_0, nullptr), + model.get_rvalue (int_17, nullptr)); + ASSERT_EQ (model.get_rvalue (arr_1, nullptr), + model.get_rvalue (int_m3, nullptr)); /* Overwrite a pre-existing binding: "arr[1] = 42;". */ - model.set_value (arr_1, int_42, NULL); - ASSERT_EQ (model.get_rvalue (arr_1, NULL), model.get_rvalue (int_42, NULL)); + model.set_value (arr_1, int_42, nullptr); + ASSERT_EQ (model.get_rvalue (arr_1, nullptr), + model.get_rvalue (int_42, nullptr)); /* Verify get_offset for "arr[0]". */ { - const region *arr_0_reg = model.get_lvalue (arr_0, NULL); + const region *arr_0_reg = model.get_lvalue (arr_0, nullptr); region_offset offset = arr_0_reg->get_offset (&mgr); - ASSERT_EQ (offset.get_base_region (), model.get_lvalue (arr, NULL)); + ASSERT_EQ (offset.get_base_region (), model.get_lvalue (arr, nullptr)); ASSERT_EQ (offset.get_bit_offset (), 0); } /* Verify get_offset for "arr[1]". */ { - const region *arr_1_reg = model.get_lvalue (arr_1, NULL); + const region *arr_1_reg = model.get_lvalue (arr_1, nullptr); region_offset offset = arr_1_reg->get_offset (&mgr); - ASSERT_EQ (offset.get_base_region (), model.get_lvalue (arr, NULL)); + ASSERT_EQ (offset.get_base_region (), model.get_lvalue (arr, nullptr)); ASSERT_EQ (offset.get_bit_offset (), INT_TYPE_SIZE); } /* Verify get_offset for "arr[i]". */ { - const region *arr_i_reg = model.get_lvalue (arr_i, NULL); + const region *arr_i_reg = model.get_lvalue (arr_i, nullptr); region_offset offset = arr_i_reg->get_offset (&mgr); - ASSERT_EQ (offset.get_base_region (), model.get_lvalue (arr, NULL)); + ASSERT_EQ (offset.get_base_region (), model.get_lvalue (arr, nullptr)); const svalue *offset_sval = offset.get_symbolic_byte_offset (); if (const svalue *cast = offset_sval->maybe_undo_cast ()) offset_sval = cast; @@ -9998,14 +10001,15 @@ test_array_2 () } /* "arr[i] = i;" - this should remove the earlier bindings. */ - model.set_value (arr_i, i, NULL); - ASSERT_EQ (model.get_rvalue (arr_i, NULL), model.get_rvalue (i, NULL)); - ASSERT_EQ (model.get_rvalue (arr_0, NULL)->get_kind (), SK_UNKNOWN); + model.set_value (arr_i, i, nullptr); + ASSERT_EQ (model.get_rvalue (arr_i, nullptr), model.get_rvalue (i, nullptr)); + ASSERT_EQ (model.get_rvalue (arr_0, nullptr)->get_kind (), SK_UNKNOWN); /* "arr[0] = 17;" - this should remove the arr[i] binding. */ - model.set_value (arr_0, int_17, NULL); - ASSERT_EQ (model.get_rvalue (arr_0, NULL), model.get_rvalue (int_17, NULL)); - ASSERT_EQ (model.get_rvalue (arr_i, NULL)->get_kind (), SK_UNKNOWN); + model.set_value (arr_0, int_17, nullptr); + ASSERT_EQ (model.get_rvalue (arr_0, nullptr), + model.get_rvalue (int_17, nullptr)); + ASSERT_EQ (model.get_rvalue (arr_i, nullptr)->get_kind (), SK_UNKNOWN); } /* Smoketest of dereferencing a pointer via MEM_REF. */ @@ -10032,12 +10036,12 @@ test_mem_ref () region_model model (&mgr); /* "x = 17;". */ - model.set_value (x, int_17, NULL); + model.set_value (x, int_17, nullptr); /* "p = &x;". */ - model.set_value (p, addr_of_x, NULL); + model.set_value (p, addr_of_x, nullptr); - const svalue *sval = model.get_rvalue (star_p, NULL); + const svalue *sval = model.get_rvalue (star_p, nullptr); ASSERT_EQ (sval->maybe_get_constant (), int_17); } @@ -10083,8 +10087,8 @@ test_POINTER_PLUS_EXPR_then_MEM_REF () region_model m (&mgr); tree int_42 = build_int_cst (integer_type_node, 42); - m.set_value (mem_ref, int_42, NULL); - ASSERT_EQ (m.get_rvalue (mem_ref, NULL)->maybe_get_constant (), int_42); + m.set_value (mem_ref, int_42, nullptr); + ASSERT_EQ (m.get_rvalue (mem_ref, nullptr)->maybe_get_constant (), int_42); } /* Verify that malloc works. */ @@ -10147,8 +10151,8 @@ test_alloca () /* Verify that the pointers to the alloca region are replaced by poisoned values when the frame is popped. */ - model.pop_frame (NULL, NULL, &ctxt, nullptr); - ASSERT_EQ (model.get_rvalue (p, NULL)->get_kind (), SK_POISONED); + model.pop_frame (nullptr, nullptr, &ctxt, nullptr); + ASSERT_EQ (model.get_rvalue (p, nullptr)->get_kind (), SK_POISONED); } /* Verify that svalue::involves_p works. */ diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index 2c7f73795e24..6271ea27cd8f 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -385,11 +385,11 @@ class region_model std::unique_ptr<rejected_constraint> *out); void update_for_gcall (const gcall &call_stmt, - region_model_context *ctxt, - function *callee = NULL); + region_model_context *ctxt, + function *callee = nullptr); void update_for_return_gcall (const gcall &call_stmt, - region_model_context *ctxt); + region_model_context *ctxt); const region *push_frame (const function &fun, const gcall *call_stmt, @@ -517,9 +517,9 @@ class region_model bool can_merge_with_p (const region_model &other_model, const program_point &point, region_model *out_model, - const extrinsic_state *ext_state = NULL, - const program_state *state_a = NULL, - const program_state *state_b = NULL) const; + const extrinsic_state *ext_state = nullptr, + const program_state *state_a = nullptr, + const program_state *state_b = nullptr) const; tree get_fndecl_for_call (const gcall &call, region_model_context *ctxt); @@ -600,7 +600,7 @@ class region_model const builtin_known_function * get_builtin_kf (const gcall &call, - region_model_context *ctxt = NULL) const; + region_model_context *ctxt = nullptr) const; static void register_pop_frame_callback (const pop_frame_callback &callback) @@ -818,7 +818,7 @@ class region_model_context Return true if the diagnostic was stored, or false if it was deleted. Optionally provide a custom stmt_finder. */ virtual bool warn (std::unique_ptr<pending_diagnostic> d, - const stmt_finder *custom_finder = NULL) = 0; + const stmt_finder *custom_finder = nullptr) = 0; /* Hook for clients to add a note to the last previously stored pending diagnostic. */ @@ -912,13 +912,15 @@ class region_model_context const state_machine **out_sm, unsigned *out_sm_idx) { - return get_state_map_by_name ("malloc", out_smap, out_sm, out_sm_idx, NULL); + return get_state_map_by_name ("malloc", out_smap, out_sm, out_sm_idx, + nullptr); } bool get_taint_map (sm_state_map **out_smap, const state_machine **out_sm, unsigned *out_sm_idx) { - return get_state_map_by_name ("taint", out_smap, out_sm, out_sm_idx, NULL); + return get_state_map_by_name ("taint", out_smap, out_sm, out_sm_idx, + nullptr); } bool possibly_tainted_p (const svalue *sval); @@ -928,6 +930,8 @@ class region_model_context virtual const exploded_graph *get_eg () const = 0; + virtual const program_state *get_state () const = 0; + /* Hooks for detecting infinite loops. */ virtual void maybe_did_work () = 0; virtual bool checking_for_infinite_loop_p () const = 0; @@ -946,7 +950,7 @@ class noop_region_model_context : public region_model_context void on_svalue_leak (const svalue *) override {} void on_liveness_change (const svalue_set &, const region_model *) override {} - logger *get_logger () override { return NULL; } + logger *get_logger () override { return nullptr; } void on_condition (const svalue *lhs ATTRIBUTE_UNUSED, enum tree_code op ATTRIBUTE_UNUSED, const svalue *rhs ATTRIBUTE_UNUSED) override @@ -969,14 +973,14 @@ class noop_region_model_context : public region_model_context void on_escaped_function (tree) override {} - uncertainty_t *get_uncertainty () override { return NULL; } + uncertainty_t *get_uncertainty () override { return nullptr; } void purge_state_involving (const svalue *sval ATTRIBUTE_UNUSED) override {} void bifurcate (std::unique_ptr<custom_edge_info> info) override; void terminate_path () override; - const extrinsic_state *get_ext_state () const override { return NULL; } + const extrinsic_state *get_ext_state () const override { return nullptr; } bool get_state_map_by_name (const char *, sm_state_map **, @@ -987,8 +991,10 @@ class noop_region_model_context : public region_model_context return false; } - const gimple *get_stmt () const override { return NULL; } - const exploded_graph *get_eg () const override { return NULL; } + const gimple *get_stmt () const override { return nullptr; } + const exploded_graph *get_eg () const override { return nullptr; } + const program_state *get_state () const override { return nullptr; } + void maybe_did_work () override {} bool checking_for_infinite_loop_p () const override { return false; } void on_unusable_in_infinite_loop () override {} @@ -1167,6 +1173,14 @@ class region_model_context_decorator : public region_model_context return nullptr; } + const program_state *get_state () const override + { + if (m_inner) + return m_inner->get_state (); + else + return nullptr; + } + void maybe_did_work () override { if (m_inner) @@ -1337,7 +1351,7 @@ class rejected_ranges_constraint : public rejected_constraint class engine { public: - engine (const supergraph *sg = NULL, logger *logger = NULL); + engine (const supergraph *sg = nullptr, logger *logger = nullptr); const supergraph *get_supergraph () { return m_sg; } region_model_manager *get_model_manager () { return &m_mgr; } known_function_manager *get_known_function_manager () @@ -1396,7 +1410,7 @@ class test_region_model_context : public noop_region_model_context #define ADD_SAT_CONSTRAINT(MODEL, LHS, OP, RHS) \ SELFTEST_BEGIN_STMT \ - bool sat = (MODEL).add_constraint (LHS, OP, RHS, NULL); \ + bool sat = (MODEL).add_constraint (LHS, OP, RHS, nullptr); \ ASSERT_TRUE (sat); \ SELFTEST_END_STMT @@ -1405,7 +1419,7 @@ class test_region_model_context : public noop_region_model_context #define ADD_UNSAT_CONSTRAINT(MODEL, LHS, OP, RHS) \ SELFTEST_BEGIN_STMT \ - bool sat = (MODEL).add_constraint (LHS, OP, RHS, NULL); \ + bool sat = (MODEL).add_constraint (LHS, OP, RHS, nullptr); \ ASSERT_FALSE (sat); \ SELFTEST_END_STMT diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc index efbbca03c7fc..e27fc6e720b0 100644 --- a/gcc/analyzer/region.cc +++ b/gcc/analyzer/region.cc @@ -124,7 +124,7 @@ region_offset::dump (bool simple) const } /* An svalue that matches the pattern (BASE * FACTOR) + OFFSET - where FACTOR or OFFSET could be the identity (represented as NULL). */ + where FACTOR or OFFSET could be the identity (represented as nullptr). */ struct linear_op { @@ -231,7 +231,7 @@ struct linear_op { *out = linear_op (binop_sval.get_arg0 (), binop_sval.get_arg1 (), - NULL); + nullptr); return true; } else if (binop_sval.get_op () == PLUS_EXPR) @@ -250,7 +250,7 @@ struct linear_op } *out = linear_op (binop_sval.get_arg0 (), - NULL, + nullptr, binop_sval.get_arg1 ()); return true; } @@ -276,8 +276,8 @@ operator< (const region_offset &a, const region_offset &b) const svalue &a_sval = *a.get_symbolic_byte_offset (); const svalue &b_sval = *b.get_symbolic_byte_offset (); - linear_op op_a (NULL, NULL, NULL); - linear_op op_b (NULL, NULL, NULL); + linear_op op_a (nullptr, nullptr, nullptr); + linear_op op_b (nullptr, nullptr, nullptr); if (linear_op::from_svalue (a_sval, &op_a) && linear_op::from_svalue (b_sval, &op_b)) { @@ -318,8 +318,8 @@ operator<= (const region_offset &a, const region_offset &b) const svalue &a_sval = *a.get_symbolic_byte_offset (); const svalue &b_sval = *b.get_symbolic_byte_offset (); - linear_op op_a (NULL, NULL, NULL); - linear_op op_b (NULL, NULL, NULL); + linear_op op_a (nullptr, nullptr, nullptr); + linear_op op_b (nullptr, nullptr, nullptr); if (linear_op::from_svalue (a_sval, &op_a) && linear_op::from_svalue (b_sval, &op_b)) { @@ -448,7 +448,7 @@ region::descendent_of_p (const region *elder) const } /* If this region is a frame_region, or a descendent of one, return it. - Otherwise return NULL. */ + Otherwise return nullptr. */ const frame_region * region::maybe_get_frame_region () const @@ -460,7 +460,7 @@ region::maybe_get_frame_region () const return frame_reg; iter = iter->get_parent_region (); } - return NULL; + return nullptr; } /* Get the memory space of this region. */ @@ -609,7 +609,7 @@ region::calc_initial_value_at_main (region_model_manager *mgr) const } /* If this region is a decl_region, return the decl. - Otherwise return NULL. */ + Otherwise return NULL_TREE. */ tree region::maybe_get_decl () const @@ -769,7 +769,7 @@ get_field_at_bit_offset (tree record_type, bit_offset_t bit_offset) { gcc_assert (TREE_CODE (record_type) == RECORD_TYPE); if (bit_offset < 0) - return NULL; + return nullptr; /* Find the first field that has an offset > BIT_OFFSET, then return the one preceding it. @@ -879,7 +879,7 @@ region::calc_offset (region_model_manager *mgr) const { const region *iter_region = this; bit_offset_t accum_bit_offset = 0; - const svalue *accum_byte_sval = NULL; + const svalue *accum_byte_sval = nullptr; while (iter_region) { @@ -1155,7 +1155,7 @@ region::is_named_decl_p (const char *decl_name) const region::region (complexity c, symbol::id_t id, const region *parent, tree type) : symbol (c, id), m_parent (parent), m_type (type), - m_cached_offset (NULL), m_cached_init_sval_at_main (NULL) + m_cached_offset (nullptr), m_cached_init_sval_at_main (nullptr) { gcc_assert (type == NULL_TREE || TYPE_P (type)); } @@ -1548,7 +1548,7 @@ heap_region::print_dump_widget_label (pretty_printer *pp) const /* root_region's ctor. */ root_region::root_region (symbol::id_t id) -: region (complexity (1, 1), id, NULL, NULL_TREE) +: region (complexity (1, 1), id, nullptr, NULL_TREE) { } @@ -1680,7 +1680,7 @@ decl_region::print_dump_widget_label (pretty_printer *pp) const int decl_region::get_stack_depth () const { - if (get_parent_region () == NULL) + if (get_parent_region () == nullptr) return 0; if (const frame_region *frame_reg = get_parent_region ()->dyn_cast_frame_region ()) @@ -1690,7 +1690,7 @@ decl_region::get_stack_depth () const /* If the underlying decl is in the global constant pool, return an svalue representing the constant value. - Otherwise return NULL. */ + Otherwise return nullptr. */ const svalue * decl_region::maybe_get_constant_value (region_model_manager *mgr) const @@ -1700,7 +1700,7 @@ decl_region::maybe_get_constant_value (region_model_manager *mgr) const && DECL_INITIAL (m_decl) && TREE_CODE (DECL_INITIAL (m_decl)) == CONSTRUCTOR) return get_svalue_for_constructor (DECL_INITIAL (m_decl), mgr); - return NULL; + return nullptr; } /* Implementation of decl_region::get_svalue_for_constructor @@ -1742,7 +1742,7 @@ decl_region::get_svalue_for_constructor (tree ctor, "main" (either based on DECL_INITIAL, or implicit initialization to zero. - Return NULL if there is a problem. */ + Return nullptr if there is a problem. */ const svalue * decl_region::get_svalue_for_initializer (region_model_manager *mgr) const @@ -1753,10 +1753,10 @@ decl_region::get_svalue_for_initializer (region_model_manager *mgr) const /* If we have an "extern" decl then there may be an initializer in another TU. */ if (DECL_EXTERNAL (m_decl)) - return NULL; + return nullptr; if (empty_p ()) - return NULL; + return nullptr; /* Implicit initialization to zero; use a compound_svalue for it. Doing so requires that we have a concrete binding for this region, @@ -1765,12 +1765,12 @@ decl_region::get_svalue_for_initializer (region_model_manager *mgr) const const binding_key *binding = binding_key::make (mgr->get_store_manager (), this); if (binding->symbolic_p ()) - return NULL; + return nullptr; /* If we don't care about tracking the content of this region, then it's unused, and the value doesn't matter. */ if (!tracked_p ()) - return NULL; + return nullptr; binding_cluster c (this); c.zero_fill_region (mgr->get_store_manager (), this); @@ -1781,14 +1781,14 @@ decl_region::get_svalue_for_initializer (region_model_manager *mgr) const /* LTO can write out error_mark_node as the DECL_INITIAL for simple scalar values (to avoid writing out an extra section). */ if (init == error_mark_node) - return NULL; + return nullptr; if (TREE_CODE (init) == CONSTRUCTOR) return get_svalue_for_constructor (init, mgr); /* Reuse the get_rvalue logic from region_model. */ region_model m (mgr); - return m.get_rvalue (path_var (init, 0), NULL); + return m.get_rvalue (path_var (init, 0), nullptr); } /* Subroutine of symnode_requires_tracking_p; return true if REF @@ -1802,7 +1802,7 @@ ipa_ref_requires_tracking (ipa_ref *ref) if (ref->use != IPA_REF_ADDR) return true; - if (ref->stmt == NULL) + if (ref->stmt == nullptr) return true; switch (ref->stmt->code) @@ -1812,12 +1812,12 @@ ipa_ref_requires_tracking (ipa_ref *ref) case GIMPLE_CALL: { cgraph_node *caller_cnode = dyn_cast <cgraph_node *> (ref->referring); - if (caller_cnode == NULL) + if (caller_cnode == nullptr) return true; cgraph_edge *edge = caller_cnode->get_edge (ref->stmt); if (!edge) return true; - if (edge->callee == NULL) + if (edge->callee == nullptr) return true; /* e.g. call through function ptr. */ if (edge->callee->definition) return true; @@ -1852,7 +1852,7 @@ symnode_requires_tracking_p (symtab_node *symnode) if (symnode->externally_visible) return true; tree context_fndecl = DECL_CONTEXT (symnode->decl); - if (context_fndecl == NULL) + if (context_fndecl == nullptr) return true; if (TREE_CODE (context_fndecl) != FUNCTION_DECL) return true; diff --git a/gcc/analyzer/region.h b/gcc/analyzer/region.h index 801a8d32e18d..e01a2e2ba853 100644 --- a/gcc/analyzer/region.h +++ b/gcc/analyzer/region.h @@ -129,29 +129,29 @@ class region : public symbol virtual enum region_kind get_kind () const = 0; virtual const frame_region * - dyn_cast_frame_region () const { return NULL; } + dyn_cast_frame_region () const { return nullptr; } virtual const function_region * - dyn_cast_function_region () const { return NULL; } + dyn_cast_function_region () const { return nullptr; } virtual const symbolic_region * - dyn_cast_symbolic_region () const { return NULL; } + dyn_cast_symbolic_region () const { return nullptr; } virtual const decl_region * - dyn_cast_decl_region () const { return NULL; } + dyn_cast_decl_region () const { return nullptr; } virtual const field_region * - dyn_cast_field_region () const { return NULL; } + dyn_cast_field_region () const { return nullptr; } virtual const element_region * - dyn_cast_element_region () const { return NULL; } + dyn_cast_element_region () const { return nullptr; } virtual const offset_region * - dyn_cast_offset_region () const { return NULL; } + dyn_cast_offset_region () const { return nullptr; } virtual const sized_region * - dyn_cast_sized_region () const { return NULL; } + dyn_cast_sized_region () const { return nullptr; } virtual const cast_region * - dyn_cast_cast_region () const { return NULL; } + dyn_cast_cast_region () const { return nullptr; } virtual const string_region * - dyn_cast_string_region () const { return NULL; } + dyn_cast_string_region () const { return nullptr; } virtual const bit_range_region * - dyn_cast_bit_range_region () const { return NULL; } + dyn_cast_bit_range_region () const { return nullptr; } virtual const var_arg_region * - dyn_cast_var_arg_region () const { return NULL; } + dyn_cast_var_arg_region () const { return nullptr; } virtual void accept (visitor *v) const; @@ -324,7 +324,7 @@ class frame_region : public space_region key_t (const frame_region *calling_frame, const function &fun) : m_calling_frame (calling_frame), m_fun (&fun) { - /* calling_frame can be NULL. */ + /* calling_frame can be nullptr. */ } hashval_t hash () const @@ -342,12 +342,12 @@ class frame_region : public space_region } void mark_deleted () { m_fun = reinterpret_cast<function *> (1); } - void mark_empty () { m_fun = NULL; } + void mark_empty () { m_fun = nullptr; } bool is_deleted () const { return m_fun == reinterpret_cast<function *> (1); } - bool is_empty () const { return m_fun == NULL; } + bool is_empty () const { return m_fun == nullptr; } const frame_region *m_calling_frame; const function *m_fun; @@ -685,12 +685,12 @@ class symbolic_region : public region } void mark_deleted () { m_sval_ptr = reinterpret_cast<const svalue *> (1); } - void mark_empty () { m_sval_ptr = NULL; } + void mark_empty () { m_sval_ptr = nullptr; } bool is_deleted () const { return m_sval_ptr == reinterpret_cast<const svalue *> (1); } - bool is_empty () const { return m_sval_ptr == NULL; } + bool is_empty () const { return m_sval_ptr == nullptr; } const region *m_parent; const svalue *m_sval_ptr; @@ -744,7 +744,7 @@ class decl_region : public region decl_region (symbol::id_t id, const region *parent, tree decl) : region (complexity (parent), id, parent, TREE_TYPE (decl)), m_decl (decl), m_tracked (calc_tracked_p (decl)), - m_ctor_svalue (NULL) + m_ctor_svalue (nullptr) {} enum region_kind get_kind () const final override { return RK_DECL; } @@ -904,12 +904,12 @@ class element_region : public region } void mark_deleted () { m_index = reinterpret_cast<const svalue *> (1); } - void mark_empty () { m_index = NULL; } + void mark_empty () { m_index = nullptr; } bool is_deleted () const { return m_index == reinterpret_cast<const svalue *> (1); } - bool is_empty () const { return m_index == NULL; } + bool is_empty () const { return m_index == nullptr; } const region *m_parent; tree m_element_type; @@ -998,12 +998,12 @@ class offset_region : public region } void mark_deleted () { m_byte_offset = reinterpret_cast<const svalue *> (1); } - void mark_empty () { m_byte_offset = NULL; } + void mark_empty () { m_byte_offset = nullptr; } bool is_deleted () const { return m_byte_offset == reinterpret_cast<const svalue *> (1); } - bool is_empty () const { return m_byte_offset == NULL; } + bool is_empty () const { return m_byte_offset == nullptr; } const region *m_parent; tree m_element_type; @@ -1094,12 +1094,12 @@ class sized_region : public region } void mark_deleted () { m_byte_size_sval = reinterpret_cast<const svalue *> (1); } - void mark_empty () { m_byte_size_sval = NULL; } + void mark_empty () { m_byte_size_sval = nullptr; } bool is_deleted () const { return m_byte_size_sval == reinterpret_cast<const svalue *> (1); } - bool is_empty () const { return m_byte_size_sval == NULL; } + bool is_empty () const { return m_byte_size_sval == nullptr; } const region *m_parent; tree m_element_type; @@ -1342,12 +1342,12 @@ class bit_range_region : public region } void mark_deleted () { m_parent = reinterpret_cast<const region *> (1); } - void mark_empty () { m_parent = NULL; } + void mark_empty () { m_parent = nullptr; } bool is_deleted () const { return m_parent == reinterpret_cast<const region *> (1); } - bool is_empty () const { return m_parent == NULL; } + bool is_empty () const { return m_parent == nullptr; } const region *m_parent; tree m_type; @@ -1432,12 +1432,12 @@ class var_arg_region : public region { m_parent = reinterpret_cast<const frame_region *> (1); } - void mark_empty () { m_parent = NULL; } + void mark_empty () { m_parent = nullptr; } bool is_deleted () const { return m_parent == reinterpret_cast<const frame_region *> (1); } - bool is_empty () const { return m_parent == NULL; } + bool is_empty () const { return m_parent == nullptr; } const frame_region *m_parent; unsigned m_idx; diff --git a/gcc/analyzer/sm-fd.cc b/gcc/analyzer/sm-fd.cc index cee8d2d7670c..370d7a00ba4b 100644 --- a/gcc/analyzer/sm-fd.cc +++ b/gcc/analyzer/sm-fd.cc @@ -116,7 +116,11 @@ class fd_state_machine : public state_machine const svalue *rhs) const final override; bool can_purge_p (state_t s) const final override; - std::unique_ptr<pending_diagnostic> on_leak (tree var) const final override; + + std::unique_ptr<pending_diagnostic> + on_leak (tree var, + const program_state *old_state, + const program_state *new_state) const final override; bool is_unchecked_fd_p (state_t s) const; bool is_valid_fd_p (state_t s) const; @@ -210,7 +214,7 @@ class fd_state_machine : public state_machine /* State for a file descriptor that we do not want to track anymore . */ state_t m_stop; - /* Stashed constant values from the frontend. These could be NULL. */ + /* Stashed constant values from the frontend. These could be NULL_TREE. */ tree m_O_ACCMODE; tree m_O_RDONLY; tree m_O_WRONLY; @@ -257,7 +261,7 @@ class fd_state_machine : public state_machine const svalue *fd_sval, const supernode *node, state_t old_state, - bool *complained = NULL) const; + bool *complained = nullptr) const; bool check_for_new_socket_fd (const call_details &cd, bool successful, sm_context &sm_ctxt, @@ -397,11 +401,11 @@ class fd_diagnostic : public pending_diagnostic || change.m_new_state == m_sm.m_new_datagram_socket || change.m_new_state == m_sm.m_new_stream_socket || change.m_new_state == m_sm.m_new_unknown_socket)) - return diagnostic_event::meaning (diagnostic_event::VERB_acquire, - diagnostic_event::NOUN_resource); + return diagnostic_event::meaning (diagnostic_event::verb::acquire, + diagnostic_event::noun::resource); if (change.m_new_state == m_sm.m_closed) - return diagnostic_event::meaning (diagnostic_event::VERB_release, - diagnostic_event::NOUN_resource); + return diagnostic_event::meaning (diagnostic_event::verb::release, + diagnostic_event::noun::resource); return diagnostic_event::meaning (); } @@ -422,7 +426,7 @@ class fd_param_diagnostic : public fd_diagnostic fd_param_diagnostic (const fd_state_machine &sm, tree arg, tree callee_fndecl) : fd_diagnostic (sm, arg), m_callee_fndecl (callee_fndecl), - m_attr_name (NULL), m_arg_idx (-1) + m_attr_name (nullptr), m_arg_idx (-1) { } @@ -477,7 +481,14 @@ class fd_param_diagnostic : public fd_diagnostic class fd_leak : public fd_diagnostic { public: - fd_leak (const fd_state_machine &sm, tree arg) : fd_diagnostic (sm, arg) {} + fd_leak (const fd_state_machine &sm, tree arg, + const program_state *final_state) + : fd_diagnostic (sm, arg), + m_final_state () + { + if (final_state) + m_final_state = std::make_unique<program_state> (*final_state); + } const char * get_kind () const final override @@ -543,8 +554,15 @@ class fd_leak : public fd_diagnostic return true; } + const program_state * + get_final_state () const final override + { + return m_final_state.get (); + } + private: diagnostic_event_id_t m_open_event; + std::unique_ptr<program_state> m_final_state; }; class fd_access_mode_mismatch : public fd_param_diagnostic @@ -1296,7 +1314,7 @@ fd_state_machine::valid_to_unchecked_state (state_t state) const return m_unchecked_read_only; else gcc_unreachable (); - return NULL; + return nullptr; } void @@ -1305,7 +1323,7 @@ fd_state_machine::mark_as_valid_fd (region_model *model, const svalue *fd_sval, const extrinsic_state &ext_state) const { - smap->set_state (model, fd_sval, m_valid_read_write, NULL, ext_state); + smap->set_state (model, fd_sval, m_valid_read_write, nullptr, ext_state); } bool @@ -1528,7 +1546,7 @@ fd_state_machine::on_open (sm_context &sm_ctxt, const supernode *node, else { sm_ctxt.warn (node, stmt, NULL_TREE, - std::make_unique<fd_leak> (*this, NULL_TREE)); + std::make_unique<fd_leak> (*this, NULL_TREE, nullptr)); } } @@ -1541,7 +1559,7 @@ fd_state_machine::on_creat (sm_context &sm_ctxt, const supernode *node, sm_ctxt.on_transition (node, stmt, lhs, m_start, m_unchecked_write_only); else sm_ctxt.warn (node, stmt, NULL_TREE, - std::make_unique<fd_leak> (*this, NULL_TREE)); + std::make_unique<fd_leak> (*this, NULL_TREE, nullptr)); } void @@ -1792,7 +1810,7 @@ fd_state_machine::on_socket (const call_details &cd, } else sm_ctxt.warn (node, &call, NULL_TREE, - std::make_unique<fd_leak> (*this, NULL_TREE)); + std::make_unique<fd_leak> (*this, NULL_TREE, nullptr)); } else { @@ -1967,7 +1985,7 @@ fd_state_machine::on_bind (const call_details &cd, if (successful) { - state_t next_state = NULL; + state_t next_state = nullptr; if (old_state == m_new_stream_socket) next_state = m_bound_stream_socket; else if (old_state == m_new_datagram_socket) @@ -2185,7 +2203,7 @@ fd_state_machine::on_accept (const call_details &cd, } else sm_ctxt.warn (node, &call, NULL_TREE, - std::make_unique<fd_leak> (*this, NULL_TREE)); + std::make_unique<fd_leak> (*this, NULL_TREE, nullptr)); } else { @@ -2223,7 +2241,7 @@ fd_state_machine::on_connect (const call_details &cd, if (successful) { model->update_for_zero_return (cd, true); - state_t next_state = NULL; + state_t next_state = nullptr; if (old_state == m_new_stream_socket) next_state = m_connected_stream_socket; else if (old_state == m_new_datagram_socket) @@ -2321,9 +2339,11 @@ fd_state_machine::can_purge_p (state_t s) const } std::unique_ptr<pending_diagnostic> -fd_state_machine::on_leak (tree var) const +fd_state_machine::on_leak (tree var, + const program_state *, + const program_state *new_state) const { - return std::make_unique<fd_leak> (*this, var); + return std::make_unique<fd_leak> (*this, var, new_state); } } // namespace @@ -2361,7 +2381,7 @@ region_model::mark_as_valid_fd (const svalue *sval, region_model_context *ctxt) { sm_state_map *smap; const fd_state_machine *fd_sm; - if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, NULL)) + if (!get_fd_state (ctxt, &smap, &fd_sm, nullptr, nullptr)) return; const extrinsic_state *ext_state = ctxt->get_ext_state (); if (!ext_state) @@ -2390,7 +2410,7 @@ class kf_socket : public known_function sm_state_map *smap; const fd_state_machine *fd_sm; std::unique_ptr<sm_context> sm_ctxt; - if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt)) + if (!get_fd_state (ctxt, &smap, &fd_sm, nullptr, &sm_ctxt)) { cd.set_any_lhs_with_defaults (); return true; @@ -2445,7 +2465,7 @@ class kf_bind : public known_function sm_state_map *smap; const fd_state_machine *fd_sm; std::unique_ptr<sm_context> sm_ctxt; - if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt)) + if (!get_fd_state (ctxt, &smap, &fd_sm, nullptr, &sm_ctxt)) { cd.set_any_lhs_with_defaults (); return true; @@ -2498,7 +2518,7 @@ class kf_listen : public known_function sm_state_map *smap; const fd_state_machine *fd_sm; std::unique_ptr<sm_context> sm_ctxt; - if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt)) + if (!get_fd_state (ctxt, &smap, &fd_sm, nullptr, &sm_ctxt)) { cd.set_any_lhs_with_defaults (); return true; @@ -2552,7 +2572,7 @@ class kf_accept : public known_function sm_state_map *smap; const fd_state_machine *fd_sm; std::unique_ptr<sm_context> sm_ctxt; - if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt)) + if (!get_fd_state (ctxt, &smap, &fd_sm, nullptr, &sm_ctxt)) { cd.set_any_lhs_with_defaults (); return true; @@ -2609,7 +2629,7 @@ class kf_connect : public known_function sm_state_map *smap; const fd_state_machine *fd_sm; std::unique_ptr<sm_context> sm_ctxt; - if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt)) + if (!get_fd_state (ctxt, &smap, &fd_sm, nullptr, &sm_ctxt)) { cd.set_any_lhs_with_defaults (); return true; @@ -2687,7 +2707,7 @@ class kf_isatty : public known_function sm_state_map *smap; const fd_state_machine *fd_sm; std::unique_ptr<sm_context> sm_ctxt; - if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt)) + if (!get_fd_state (ctxt, &smap, &fd_sm, nullptr, &sm_ctxt)) return true; const extrinsic_state *ext_state = ctxt->get_ext_state (); if (!ext_state) diff --git a/gcc/analyzer/sm-file.cc b/gcc/analyzer/sm-file.cc index d7dbe2fe7b6e..4b1fc7788763 100644 --- a/gcc/analyzer/sm-file.cc +++ b/gcc/analyzer/sm-file.cc @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "analyzer/analyzer-selftests.h" #include "analyzer/call-string.h" #include "analyzer/program-point.h" +#include "analyzer/program-state.h" #include "analyzer/store.h" #include "analyzer/region-model.h" #include "analyzer/call-details.h" @@ -72,7 +73,11 @@ class fileptr_state_machine : public state_machine const svalue *rhs) const final override; bool can_purge_p (state_t s) const final override; - std::unique_ptr<pending_diagnostic> on_leak (tree var) const final override; + + std::unique_ptr<pending_diagnostic> + on_leak (tree var, + const program_state *old_state, + const program_state *new_state) const final override; /* State for a FILE * returned from fopen that hasn't been checked for NULL. @@ -156,11 +161,11 @@ class file_diagnostic : public pending_diagnostic { if (change.m_old_state == m_sm.get_start_state () && change.m_new_state == m_sm.m_unchecked) - return diagnostic_event::meaning (diagnostic_event::VERB_acquire, - diagnostic_event::NOUN_resource); + return diagnostic_event::meaning (diagnostic_event::verb::acquire, + diagnostic_event::noun::resource); if (change.m_new_state == m_sm.m_closed) - return diagnostic_event::meaning (diagnostic_event::VERB_release, - diagnostic_event::NOUN_resource); + return diagnostic_event::meaning (diagnostic_event::verb::release, + diagnostic_event::noun::resource); return diagnostic_event::meaning (); } @@ -226,9 +231,14 @@ class double_fclose : public file_diagnostic class file_leak : public file_diagnostic { public: - file_leak (const fileptr_state_machine &sm, tree arg) - : file_diagnostic (sm, arg) - {} + file_leak (const fileptr_state_machine &sm, tree arg, + const program_state *final_state) + : file_diagnostic (sm, arg), + m_final_state () + { + if (final_state) + m_final_state = std::make_unique<program_state> (*final_state); + } const char *get_kind () const final override { return "file_leak"; } @@ -286,8 +296,15 @@ class file_leak : public file_diagnostic return true; } + const program_state * + get_final_state () const final override + { + return m_final_state.get (); + } + private: diagnostic_event_id_t m_fopen_event; + std::unique_ptr<program_state> m_final_state; }; /* fileptr_state_machine's ctor. */ @@ -492,9 +509,11 @@ fileptr_state_machine::can_purge_p (state_t s) const state 'unchecked' and 'nonnull'. */ std::unique_ptr<pending_diagnostic> -fileptr_state_machine::on_leak (tree var) const +fileptr_state_machine::on_leak (tree var, + const program_state *, + const program_state *new_state) const { - return std::make_unique<file_leak> (*this, var); + return std::make_unique<file_leak> (*this, var, new_state); } } // anonymous namespace diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc index 333dfea47d34..2a218d0688be 100644 --- a/gcc/analyzer/sm-malloc.cc +++ b/gcc/analyzer/sm-malloc.cc @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-event-id.h" #include "stringpool.h" #include "attribs.h" +#include "xml-printer.h" #include "analyzer/analyzer-logging.h" #include "analyzer/sm.h" @@ -37,6 +38,7 @@ along with GCC; see the file COPYING3. If not see #include "analyzer/checker-event.h" #include "analyzer/exploded-graph.h" #include "analyzer/inlining-iterator.h" +#include "analyzer/ana-state-to-diagnostic-state.h" #if ENABLE_ANALYZER @@ -139,7 +141,7 @@ struct assumed_non_null_state : public allocation_state assumed_non_null_state (const char *name, unsigned id, const frame_region *frame) : allocation_state (name, id, RS_ASSUMED_NON_NULL, - NULL, NULL), + nullptr, nullptr), m_frame (frame) { gcc_assert (m_frame); @@ -290,7 +292,7 @@ struct deallocator_set_map_traits static inline hashval_t hash (const key_type &k) { - gcc_assert (k != NULL); + gcc_assert (k != nullptr); gcc_assert (k != reinterpret_cast<key_type> (1)); hashval_t result = 0; @@ -324,7 +326,7 @@ struct deallocator_set_map_traits template <typename T> static inline void mark_empty (T &entry) { - entry.m_key = NULL; + entry.m_key = nullptr; } template <typename T> static inline bool is_deleted (const T &entry) @@ -334,7 +336,7 @@ struct deallocator_set_map_traits template <typename T> static inline bool is_empty (const T &entry) { - return entry.m_key == NULL; + return entry.m_key == nullptr; } static const bool empty_zero_p = false; }; @@ -403,7 +405,11 @@ class malloc_state_machine : public state_machine const frame_region *) const final override; bool can_purge_p (state_t s) const final override; - std::unique_ptr<pending_diagnostic> on_leak (tree var) const final override; + + std::unique_ptr<pending_diagnostic> + on_leak (tree var, + const program_state *old_state, + const program_state *new_state) const final override; bool reset_when_passed_to_unknown_fn_p (state_t s, bool is_mutable) const final override; @@ -429,6 +435,11 @@ class malloc_state_machine : public state_machine const svalue *new_ptr_sval, const extrinsic_state &ext_state) const; + void + add_state_to_state_graph (analyzer_state_graph &out_state_graph, + const svalue &sval, + state_machine::state_t state) const final override; + standard_deallocator_set m_free; standard_deallocator_set m_scalar_delete; standard_deallocator_set m_vector_delete; @@ -524,7 +535,7 @@ deallocator::deallocator (malloc_state_machine *sm, enum wording wording) : m_name (name), m_wording (wording), - m_freed (sm->add_state ("freed", RS_FREED, NULL, this)) + m_freed (sm->add_state ("freed", RS_FREED, nullptr, this)) { } @@ -568,8 +579,8 @@ standard_deallocator::standard_deallocator (malloc_state_machine *sm, deallocator_set::deallocator_set (malloc_state_machine *sm, enum wording wording) : m_wording (wording), - m_unchecked (sm->add_state ("unchecked", RS_UNCHECKED, this, NULL)), - m_nonnull (sm->add_state ("nonnull", RS_NONNULL, this, NULL)) + m_unchecked (sm->add_state ("unchecked", RS_UNCHECKED, this, nullptr)), + m_nonnull (sm->add_state ("nonnull", RS_NONNULL, this, nullptr)) { } @@ -614,7 +625,7 @@ custom_deallocator_set::maybe_get_single () const { if (m_deallocator_vec.length () == 1) return m_deallocator_vec[0]; - return NULL; + return nullptr; } void @@ -662,14 +673,15 @@ standard_deallocator_set::dump_to_pp (pretty_printer *pp) const pp_character (pp, '}'); } -/* Return STATE cast to the custom state subclass, or NULL for the start state. +/* Return STATE cast to the custom state subclass, or nullptr for the + start state. Everything should be an allocation_state apart from the start state. */ static const allocation_state * dyn_cast_allocation_state (state_machine::state_t state) { if (state->get_id () == 0) - return NULL; + return nullptr; return static_cast <const allocation_state *> (state); } @@ -808,11 +820,11 @@ class malloc_diagnostic : public pending_diagnostic { if (change.m_old_state == m_sm.get_start_state () && unchecked_p (change.m_new_state)) - return diagnostic_event::meaning (diagnostic_event::VERB_acquire, - diagnostic_event::NOUN_memory); + return diagnostic_event::meaning (diagnostic_event::verb::acquire, + diagnostic_event::noun::memory); if (freed_p (change.m_new_state)) - return diagnostic_event::meaning (diagnostic_event::VERB_release, - diagnostic_event::NOUN_memory); + return diagnostic_event::meaning (diagnostic_event::verb::release, + diagnostic_event::noun::memory); return diagnostic_event::meaning (); } @@ -1414,8 +1426,14 @@ class use_after_free : public malloc_diagnostic class malloc_leak : public malloc_diagnostic { public: - malloc_leak (const malloc_state_machine &sm, tree arg) - : malloc_diagnostic (sm, arg) {} + malloc_leak (const malloc_state_machine &sm, tree arg, + const program_state *final_state) + : malloc_diagnostic (sm, arg), + m_final_state () + { + if (final_state) + m_final_state = std::make_unique<program_state> (*final_state); + } const char *get_kind () const final override { return "malloc_leak"; } @@ -1475,8 +1493,15 @@ class malloc_leak : public malloc_diagnostic return true; } + const program_state * + get_final_state () const final override + { + return m_final_state.get (); + } + private: diagnostic_event_id_t m_alloc_event; + std::unique_ptr<program_state> m_final_state; }; class free_of_non_heap : public malloc_diagnostic @@ -1571,9 +1596,9 @@ class deref_before_check : public malloc_diagnostic public: deref_before_check (const malloc_state_machine &sm, tree arg) : malloc_diagnostic (sm, arg), - m_deref_enode (NULL), - m_deref_expr (NULL), - m_check_enode (NULL) + m_deref_enode (nullptr), + m_deref_expr (nullptr), + m_check_enode (nullptr) { gcc_assert (arg); } @@ -1798,9 +1823,9 @@ malloc_state_machine::malloc_state_machine (logger *logger) m_realloc (this, "realloc", WORDING_REALLOCATED) { gcc_assert (m_start->get_id () == 0); - m_null = add_state ("null", RS_FREED, NULL, NULL); - m_non_heap = add_state ("non-heap", RS_NON_HEAP, NULL, NULL); - m_stop = add_state ("stop", RS_STOP, NULL, NULL); + m_null = add_state ("null", RS_FREED, nullptr, nullptr); + m_non_heap = add_state ("non-heap", RS_NON_HEAP, nullptr, nullptr); + m_stop = add_state ("stop", RS_STOP, nullptr, nullptr); } malloc_state_machine::~malloc_state_machine () @@ -1828,7 +1853,7 @@ malloc_state_machine::add_state (const char *name, enum resource_state rs, return a custom_deallocator_set for them, consolidating them to ensure uniqueness of the sets. - Return NULL if it has no such attributes. */ + Return nullptr if it has no such attributes. */ const custom_deallocator_set * malloc_state_machine:: @@ -1837,7 +1862,7 @@ get_or_create_custom_deallocator_set (tree allocator_fndecl) /* Early rejection of decls without attributes. */ tree attrs = DECL_ATTRIBUTES (allocator_fndecl); if (!attrs) - return NULL; + return nullptr; /* Otherwise, call maybe_create_custom_deallocator_set, memoizing the result. */ @@ -1855,7 +1880,7 @@ get_or_create_custom_deallocator_set (tree allocator_fndecl) custom_deallocator_set for them, consolidating them to ensure uniqueness of the sets. - Return NULL if it has no such attributes. + Return nullptr if it has no such attributes. Subroutine of get_or_create_custom_deallocator_set which memoizes the result. */ @@ -1886,7 +1911,7 @@ maybe_create_custom_deallocator_set (tree allocator_fndecl) /* If there weren't any deallocators, bail. */ if (deallocator_vec.length () == 0) - return NULL; + return nullptr; /* Consolidate, so that we reuse existing deallocator_set instances. */ @@ -1991,7 +2016,7 @@ malloc_state_machine::maybe_assume_non_null (sm_context &sm_ctxt, tree null_ptr_cst = build_int_cst (TREE_TYPE (ptr), 0); tristate known_non_null - = old_model->eval_condition (ptr, NE_EXPR, null_ptr_cst, NULL); + = old_model->eval_condition (ptr, NE_EXPR, null_ptr_cst, nullptr); if (known_non_null.is_unknown ()) { /* Cast away const-ness for cache-like operations. */ @@ -2172,19 +2197,27 @@ malloc_state_machine::on_stmt (sm_context &sm_ctxt, unsigned int idx = TREE_INT_CST_LOW (TREE_VALUE (args)) - 1; unsigned int idx2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args))) - 1; + unsigned int idx3 = idx2; + if (tree chain2 = TREE_CHAIN (TREE_CHAIN (args))) + idx3 = TREE_INT_CST_LOW (TREE_VALUE (chain2)) - 1; if (idx < gimple_call_num_args (stmt) - && idx2 < gimple_call_num_args (stmt)) + && idx2 < gimple_call_num_args (stmt) + && idx3 < gimple_call_num_args (stmt)) { tree arg = gimple_call_arg (stmt, idx); tree arg2 = gimple_call_arg (stmt, idx2); + tree arg3 = gimple_call_arg (stmt, idx3); if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE || !INTEGRAL_TYPE_P (TREE_TYPE (arg2)) - || integer_zerop (arg2)) + || !INTEGRAL_TYPE_P (TREE_TYPE (arg3)) + || integer_zerop (arg2) + || integer_zerop (arg3)) continue; - if (integer_nonzerop (arg2)) + if (integer_nonzerop (arg2) && integer_nonzerop (arg3)) ; else - /* FIXME: Use ranger here to query arg2 range? */ + /* FIXME: Use ranger here to query arg2 and arg3 + ranges? */ continue; handle_nonnull (sm_ctxt, node, stmt, fndecl, arg, idx); } @@ -2376,12 +2409,12 @@ malloc_state_machine::handle_free_of_non_heap (sm_context &sm_ctxt, const deallocator *d) const { tree diag_arg = sm_ctxt.get_diagnostic_tree (arg); - const region *freed_reg = NULL; + const region *freed_reg = nullptr; if (const program_state *old_state = sm_ctxt.get_old_program_state ()) { const region_model *old_model = old_state->m_region_model; - const svalue *ptr_sval = old_model->get_rvalue (arg, NULL); - freed_reg = old_model->deref_rvalue (ptr_sval, arg, NULL); + const svalue *ptr_sval = old_model->get_rvalue (arg, nullptr); + freed_reg = old_model->deref_rvalue (ptr_sval, arg, nullptr); } sm_ctxt.warn (node, &call, arg, std::make_unique<free_of_non_heap> @@ -2589,9 +2622,11 @@ malloc_state_machine::can_purge_p (state_t s) const 'nonnull'). */ std::unique_ptr<pending_diagnostic> -malloc_state_machine::on_leak (tree var) const +malloc_state_machine::on_leak (tree var, + const program_state *, + const program_state *new_state) const { - return std::make_unique<malloc_leak> (*this, var); + return std::make_unique<malloc_leak> (*this, var, new_state); } /* Implementation of state_machine::reset_when_passed_to_unknown_fn_p vfunc @@ -2624,7 +2659,7 @@ malloc_state_machine::maybe_get_merged_states_nonequal (state_t state_a, return m_start; if (state_a == m_start && assumed_non_null_p (state_b)) return m_start; - return NULL; + return nullptr; } /* Return true if calls to FNDECL are known to not affect this sm-state. */ @@ -2682,11 +2717,11 @@ on_realloc_with_move (region_model *model, { smap->set_state (model, old_ptr_sval, m_free.m_deallocator.m_freed, - NULL, ext_state); + nullptr, ext_state); smap->set_state (model, new_ptr_sval, m_free.m_nonnull, - NULL, ext_state); + nullptr, ext_state); } /* Hook for get_or_create_region_for_heap_alloc for the case when we want @@ -2697,7 +2732,61 @@ malloc_state_machine::transition_ptr_sval_non_null (region_model *model, const svalue *new_ptr_sval, const extrinsic_state &ext_state) const { - smap->set_state (model, new_ptr_sval, m_free.m_nonnull, NULL, ext_state); + smap->set_state (model, new_ptr_sval, m_free.m_nonnull, nullptr, ext_state); +} + +static enum diagnostics::state_graphs::node_dynalloc_state +get_dynalloc_state_for_state (enum resource_state rs) +{ + switch (rs) + { + default: + gcc_unreachable (); + case RS_START: + case RS_NULL: + case RS_NON_HEAP: + case RS_STOP: + return diagnostics::state_graphs::node_dynalloc_state::unknown; + + case RS_ASSUMED_NON_NULL: + return diagnostics::state_graphs::node_dynalloc_state::nonnull; + + case RS_UNCHECKED: + return diagnostics::state_graphs::node_dynalloc_state::unchecked; + case RS_NONNULL: + return diagnostics::state_graphs::node_dynalloc_state::nonnull; + case RS_FREED: + return diagnostics::state_graphs::node_dynalloc_state::freed; + } +} + +void +malloc_state_machine:: +add_state_to_state_graph (analyzer_state_graph &out_state_graph, + const svalue &sval, + state_machine::state_t state) const +{ + if (const region *reg = sval.maybe_get_region ()) + { + auto reg_node = out_state_graph.get_or_create_state_node (*reg); + auto alloc_state = as_a_allocation_state (state); + gcc_assert (alloc_state); + + reg_node.set_dynalloc_state + (get_dynalloc_state_for_state (alloc_state->m_rs)); + if (alloc_state->m_deallocators) + { + pretty_printer pp; + alloc_state->m_deallocators->dump_to_pp (&pp); + reg_node.m_node.set_attr (STATE_NODE_PREFIX, + "expected-deallocators", + pp_formatted_text (&pp)); + } + if (alloc_state->m_deallocator) + reg_node.m_node.set_attr (STATE_NODE_PREFIX, + "deallocator", + alloc_state->m_deallocator->m_name); + } } } // anonymous namespace diff --git a/gcc/analyzer/sm-pattern-test.cc b/gcc/analyzer/sm-pattern-test.cc index f05ffe024514..02b32ac19a21 100644 --- a/gcc/analyzer/sm-pattern-test.cc +++ b/gcc/analyzer/sm-pattern-test.cc @@ -122,7 +122,7 @@ pattern_test_state_machine::on_condition (sm_context &sm_ctxt, enum tree_code op, const svalue *rhs) const { - if (stmt == NULL) + if (stmt == nullptr) return; tree rhs_cst = rhs->maybe_get_constant (); diff --git a/gcc/analyzer/sm-sensitive.cc b/gcc/analyzer/sm-sensitive.cc index 7bd5ef68103f..f8fcdede8d8e 100644 --- a/gcc/analyzer/sm-sensitive.cc +++ b/gcc/analyzer/sm-sensitive.cc @@ -111,8 +111,8 @@ class exposure_through_output_file const final override { if (change.m_new_state == m_sm.m_sensitive) - return diagnostic_event::meaning (diagnostic_event::VERB_acquire, - diagnostic_event::NOUN_sensitive); + return diagnostic_event::meaning (diagnostic_event::verb::acquire, + diagnostic_event::noun::sensitive); return diagnostic_event::meaning (); } bool diff --git a/gcc/analyzer/sm-signal.cc b/gcc/analyzer/sm-signal.cc index 83f2808708e8..5a4b384648f9 100644 --- a/gcc/analyzer/sm-signal.cc +++ b/gcc/analyzer/sm-signal.cc @@ -173,7 +173,7 @@ class signal_unsafe_call if (id_equal ("exit", DECL_NAME (m_unsafe_fndecl))) return "_exit"; - return NULL; + return nullptr; } }; @@ -269,7 +269,7 @@ class register_signal_handler : public custom_transition state_entering_handler, src_enode); if (dst_enode) - eg->add_edge (src_enode, dst_enode, NULL, /*state_change (),*/ + eg->add_edge (src_enode, dst_enode, nullptr, /*state_change (),*/ true, /* assume does work */ std::make_unique<signal_delivery_edge_info_t> ()); } diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc index e782081ac2d7..5c8cc7ed205f 100644 --- a/gcc/analyzer/sm-taint.cc +++ b/gcc/analyzer/sm-taint.cc @@ -214,8 +214,8 @@ class taint_diagnostic : public pending_diagnostic const final override { if (change.m_new_state == m_sm.m_tainted) - return diagnostic_event::meaning (diagnostic_event::VERB_acquire, - diagnostic_event::NOUN_taint); + return diagnostic_event::meaning (diagnostic_event::verb::acquire, + diagnostic_event::noun::taint); return diagnostic_event::meaning (); } @@ -934,7 +934,7 @@ class tainted_assertion : public taint_diagnostic macro when we're describing them. */ return linemap_resolve_location (line_table, loc, LRK_SPELLING_LOCATION, - NULL); + nullptr); else return pending_diagnostic::fixup_location (loc, primary); } @@ -1060,12 +1060,12 @@ taint_state_machine::alt_get_inherited_state (const sm_state_map &map, case BIT_AND_EXPR: case RSHIFT_EXPR: - return NULL; + return nullptr; } } break; } - return NULL; + return nullptr; } /* Return true iff FNDECL should be considered to be an assertion failure @@ -1175,7 +1175,7 @@ taint_state_machine::check_control_flow_arg_for_taint (sm_context &sm_ctxt, tree expr) const { const region_model *old_model = sm_ctxt.get_old_region_model (); - const svalue *sval = old_model->get_rvalue (expr, NULL); + const svalue *sval = old_model->get_rvalue (expr, nullptr); state_t state = sm_ctxt.get_state (stmt, sval); enum bounds b; if (get_taint (state, TREE_TYPE (expr), &b)) @@ -1194,7 +1194,7 @@ taint_state_machine::on_condition (sm_context &sm_ctxt, enum tree_code op, const svalue *rhs) const { - if (stmt == NULL) + if (stmt == nullptr) return; if (lhs->get_kind () == SK_UNKNOWN @@ -1492,7 +1492,7 @@ taint_state_machine::check_for_tainted_divisor (sm_context &sm_ctxt, if (!INTEGRAL_TYPE_P (TREE_TYPE (divisor_expr))) return; - const svalue *divisor_sval = old_model->get_rvalue (divisor_expr, NULL); + const svalue *divisor_sval = old_model->get_rvalue (divisor_expr, nullptr); state_t state = sm_ctxt.get_state (assign, divisor_sval); enum bounds b; @@ -1793,7 +1793,7 @@ region_model::mark_as_tainted (const svalue *sval, if (!ext_state) return; - smap->set_state (this, sval, taint_sm.m_tainted, NULL, *ext_state); + smap->set_state (this, sval, taint_sm.m_tainted, nullptr, *ext_state); } /* Return true if SVAL could possibly be attacker-controlled. */ diff --git a/gcc/analyzer/sm.cc b/gcc/analyzer/sm.cc index 0abbdd69adf1..c93e9c2b67b5 100644 --- a/gcc/analyzer/sm.cc +++ b/gcc/analyzer/sm.cc @@ -116,9 +116,11 @@ state_machine::get_state_by_name (const char *name) const /* Base implementation of state_machine::on_leak. */ std::unique_ptr<pending_diagnostic> -state_machine::on_leak (tree var ATTRIBUTE_UNUSED) const +state_machine::on_leak (tree var ATTRIBUTE_UNUSED, + const program_state *old_state ATTRIBUTE_UNUSED, + const program_state *new_state ATTRIBUTE_UNUSED) const { - return NULL; + return nullptr; } /* Dump a multiline representation of this state machine to PP. */ @@ -158,6 +160,21 @@ state_machine::to_json () const return sm_obj; } +void +state_machine::add_state_to_state_graph (analyzer_state_graph &out_state_graph, + const svalue &sval, + state_machine::state_t state) const +{ + // no-op +} + +void +state_machine::add_global_state_to_state_graph (analyzer_state_graph &out_state_graph, + state_machine::state_t state) const +{ + // no-op +} + /* class sm_context. */ const region_model * @@ -166,7 +183,7 @@ sm_context::get_old_region_model () const if (const program_state *old_state = get_old_program_state ()) return old_state->m_region_model; else - return NULL; + return nullptr; } /* Create instances of the various state machines, each using LOGGER, diff --git a/gcc/analyzer/sm.h b/gcc/analyzer/sm.h index a932765131b6..4633facac3a2 100644 --- a/gcc/analyzer/sm.h +++ b/gcc/analyzer/sm.h @@ -28,6 +28,7 @@ namespace ana { class state_machine; class sm_context; class pending_diagnostic; +class analyzer_state_graph; extern bool any_pointer_p (tree expr); extern bool any_pointer_p (const svalue *sval); @@ -75,7 +76,7 @@ class state_machine : public log_user const svalue *, const extrinsic_state &) const { - return NULL; + return nullptr; } virtual bool @@ -136,7 +137,9 @@ class state_machine : public log_user /* Called when VAR leaks (and !can_purge_p). */ virtual std::unique_ptr<pending_diagnostic> - on_leak (tree var ATTRIBUTE_UNUSED) const; + on_leak (tree var ATTRIBUTE_UNUSED, + const program_state *old_state, + const program_state *new_state) const; /* Return true if S should be reset to "start" for values passed (or reachable from) calls to unknown functions. IS_MUTABLE is true for pointers as @@ -152,7 +155,7 @@ class state_machine : public log_user } /* Attempt to get a state for the merger of STATE_A and STATE_B, - or return NULL if merging shouldn't occur, so that differences + or return nullptr if merging shouldn't occur, so that differences between sm-state will lead to separate exploded nodes. Most state machines will only merge equal states, but can @@ -173,7 +176,7 @@ class state_machine : public log_user state_t state_b ATTRIBUTE_UNUSED) const { /* By default, non-equal sm states should inhibit merger of enodes. */ - return NULL; + return nullptr; } void validate (state_t s) const; @@ -184,6 +187,15 @@ class state_machine : public log_user state_t get_start_state () const { return m_start; } + virtual void + add_state_to_state_graph (analyzer_state_graph &out_state_graph, + const svalue &sval, + state_machine::state_t state) const; + + virtual void + add_global_state_to_state_graph (analyzer_state_graph &out_state_graph, + state_machine::state_t state) const; + protected: state_t add_state (const char *name); state_t add_custom_state (state *s) @@ -318,7 +330,7 @@ class sm_context virtual path_context *get_path_context () const { - return NULL; + return nullptr; } /* Are we handling an external function with unknown side effects? */ diff --git a/gcc/analyzer/state-purge.cc b/gcc/analyzer/state-purge.cc index 7a93ceee9a1d..1371db904aae 100644 --- a/gcc/analyzer/state-purge.cc +++ b/gcc/analyzer/state-purge.cc @@ -659,7 +659,7 @@ state_purge_per_ssa_name::process_point (const function_point &point, if (snode->entry_p ()) { add_to_worklist - (function_point::before_supernode (snode, NULL), + (function_point::before_supernode (snode, nullptr), worklist, logger); } } @@ -841,8 +841,8 @@ fully_overwrites_p (const gimple *stmt, tree decl, We can't just check for equality; consider the case of "s.field = EXPR;" where the stmt writes to the only field of "s", and there's no padding. */ - const region *lhs_reg = model.get_lvalue (lhs, NULL); - const region *decl_reg = model.get_lvalue (decl, NULL); + const region *lhs_reg = model.get_lvalue (lhs, nullptr); + const region *decl_reg = model.get_lvalue (decl, nullptr); if (same_binding_p (lhs_reg, decl_reg, model.get_manager ()->get_store_manager ())) return true; @@ -1074,7 +1074,7 @@ state_purge_annotator::add_node_annotations (graphviz_out *gv, const supernode &n, bool within_table) const { - if (m_map == NULL) + if (m_map == nullptr) return false; if (within_table) @@ -1091,7 +1091,7 @@ state_purge_annotator::add_node_annotations (graphviz_out *gv, Determine which points to dump. */ auto_vec<function_point> points; if (n.entry_p () || n.m_returning_call) - points.safe_push (function_point::before_supernode (&n, NULL)); + points.safe_push (function_point::before_supernode (&n, nullptr)); else for (auto inedge : n.m_preds) points.safe_push (function_point::before_supernode (&n, inedge)); @@ -1153,7 +1153,7 @@ state_purge_annotator::add_stmt_annotations (graphviz_out *gv, if (within_row) return; - if (m_map == NULL) + if (m_map == nullptr) return; if (stmt->code == GIMPLE_PHI) diff --git a/gcc/analyzer/state-purge.h b/gcc/analyzer/state-purge.h index bbe78a593f4a..2bac564175ce 100644 --- a/gcc/analyzer/state-purge.h +++ b/gcc/analyzer/state-purge.h @@ -109,7 +109,7 @@ class state_purge_map : public log_user = const_cast <decl_map_t&> (m_decl_map).get (decl)) return *slot; else - return NULL; + return nullptr; } state_purge_per_decl & diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc index e6723c7ffc94..942c9455e588 100644 --- a/gcc/analyzer/store.cc +++ b/gcc/analyzer/store.cc @@ -658,7 +658,7 @@ binding_map::operator== (const binding_map &other) const const svalue *sval = (*iter).second; const svalue **other_slot = const_cast <map_t &> (other.m_map).get (key); - if (other_slot == NULL) + if (other_slot == nullptr) return false; if (sval != *other_slot) return false; @@ -922,7 +922,7 @@ get_svalue_for_ctor_val (tree val, region_model_manager *mgr) { /* Reuse the get_rvalue logic from region_model. */ region_model m (mgr); - return m.get_rvalue (path_var (val, 0), NULL); + return m.get_rvalue (path_var (val, 0), nullptr); } /* Bind values from CONSTRUCTOR to this map, relative to @@ -1564,7 +1564,7 @@ binding_cluster::bind_compound_sval (store_manager *mgr, void binding_cluster::clobber_region (store_manager *mgr, const region *reg) { - remove_overlapping_bindings (mgr, reg, NULL, NULL); + remove_overlapping_bindings (mgr, reg, nullptr, nullptr); } /* Remove any bindings for REG within this cluster. */ @@ -1684,7 +1684,7 @@ binding_cluster::get_binding (store_manager *mgr, const region *reg) const { if (reg->empty_p ()) - return NULL; + return nullptr; const binding_key *reg_binding = binding_key::make (mgr, reg); const svalue *sval = m_map.get (reg_binding); if (sval) @@ -1752,7 +1752,7 @@ binding_cluster::get_binding_recursive (store_manager *mgr, return rmm_mgr->get_or_create_sub_svalue (reg->get_type (), parent_sval, reg); } - return NULL; + return nullptr; } /* Get any value bound for REG within this cluster. */ @@ -1800,7 +1800,7 @@ binding_cluster::get_any_binding (store_manager *mgr, return compound_sval; /* Otherwise, the initial value, or uninitialized. */ - return NULL; + return nullptr; } /* Attempt to get a compound_svalue for the bindings within the cluster @@ -1812,7 +1812,7 @@ binding_cluster::get_any_binding (store_manager *mgr, For example, REG could be one element within an array of structs. - Return the resulting compound_svalue, or NULL if there's a problem. */ + Return the resulting compound_svalue, or nullptr if there's a problem. */ const svalue * binding_cluster::maybe_get_compound_binding (store_manager *mgr, @@ -1821,13 +1821,13 @@ binding_cluster::maybe_get_compound_binding (store_manager *mgr, region_offset cluster_offset = m_base_region->get_offset (mgr->get_svalue_manager ()); if (cluster_offset.symbolic_p ()) - return NULL; + return nullptr; region_offset reg_offset = reg->get_offset (mgr->get_svalue_manager ()); if (reg_offset.symbolic_p ()) - return NULL; + return nullptr; if (reg->empty_p ()) - return NULL; + return nullptr; region_model_manager *sval_mgr = mgr->get_svalue_manager (); @@ -1880,7 +1880,7 @@ binding_cluster::maybe_get_compound_binding (store_manager *mgr, bit_size_t reg_bit_size; if (!reg->get_bit_size (®_bit_size)) - return NULL; + return nullptr; bit_range reg_range (reg_offset.get_bit_offset (), reg_bit_size); @@ -1909,7 +1909,7 @@ binding_cluster::maybe_get_compound_binding (store_manager *mgr, it overlaps with offset_concrete_key. */ default_map.remove_overlapping_bindings (mgr, offset_concrete_key, - NULL, NULL, false); + nullptr, nullptr, false); } else if (bound_range.contains_p (reg_range, &subrange)) { @@ -1943,16 +1943,16 @@ binding_cluster::maybe_get_compound_binding (store_manager *mgr, it overlaps with overlap_concrete_key. */ default_map.remove_overlapping_bindings (mgr, overlap_concrete_key, - NULL, NULL, false); + nullptr, nullptr, false); } } else /* Can't handle symbolic bindings. */ - return NULL; + return nullptr; } if (result_map.elements () == 0) - return NULL; + return nullptr; /* Merge any bindings from default_map into result_map. */ for (auto iter : default_map) @@ -2030,23 +2030,23 @@ binding_cluster::can_merge_p (const binding_cluster *cluster_a, /* At least one of CLUSTER_A and CLUSTER_B are non-NULL, but either could be NULL. Handle these cases. */ - if (cluster_a == NULL) + if (cluster_a == nullptr) { - gcc_assert (cluster_b != NULL); + gcc_assert (cluster_b != nullptr); gcc_assert (cluster_b->m_base_region == out_cluster->m_base_region); out_cluster->make_unknown_relative_to (cluster_b, out_store, mgr); return true; } - if (cluster_b == NULL) + if (cluster_b == nullptr) { - gcc_assert (cluster_a != NULL); + gcc_assert (cluster_a != nullptr); gcc_assert (cluster_a->m_base_region == out_cluster->m_base_region); out_cluster->make_unknown_relative_to (cluster_a, out_store, mgr); return true; } /* The "both inputs are non-NULL" case. */ - gcc_assert (cluster_a != NULL && cluster_b != NULL); + gcc_assert (cluster_a != nullptr && cluster_b != nullptr); gcc_assert (cluster_a->m_base_region == out_cluster->m_base_region); gcc_assert (cluster_b->m_base_region == out_cluster->m_base_region); @@ -2319,7 +2319,7 @@ binding_cluster::get_representative_path_vars (const region_model *model, } } -/* Get any svalue bound to KEY, or NULL. */ +/* Get any svalue bound to KEY, or nullptr. */ const svalue * binding_cluster::get_any_value (const binding_key *key) const @@ -2334,16 +2334,16 @@ binding_cluster::get_any_value (const binding_key *key) const const svalue * binding_cluster::maybe_get_simple_value (store_manager *mgr) const { - /* Fail gracefully if MGR is NULL to make it easier to dump store + /* Fail gracefully if MGR is nullptr to make it easier to dump store instances in the debugger. */ - if (mgr == NULL) - return NULL; + if (mgr == nullptr) + return nullptr; if (m_map.elements () != 1) - return NULL; + return nullptr; if (m_base_region->empty_p ()) - return NULL; + return nullptr; const binding_key *key = binding_key::make (mgr, m_base_region); return get_any_value (key); @@ -2467,7 +2467,7 @@ store::operator== (const store &other) const binding_cluster *c = (*iter).second; binding_cluster **other_slot = const_cast <cluster_map_t &> (other.m_cluster_map).get (reg); - if (other_slot == NULL) + if (other_slot == nullptr) return false; if (*c != **other_slot) return false; @@ -2520,7 +2520,7 @@ get_sorted_parent_regions (auto_vec<const region *> *out, /* Dump a representation of this store to PP, using SIMPLE to control how svalues and regions are printed. - MGR is used for simplifying dumps if non-NULL, but can also be NULL + MGR is used for simplifying dumps if non-NULL, but can also be nullptr (to make it easier to use from the debugger). */ void @@ -2629,7 +2629,7 @@ DEBUG_FUNCTION void store::dump (bool simple) const { tree_dump_pretty_printer pp (stderr); - dump_to_pp (&pp, simple, true, NULL); + dump_to_pp (&pp, simple, true, nullptr); pp_newline (&pp); } @@ -2761,7 +2761,7 @@ store::make_dump_widget (const text_art::dump_widget_info &dwi, return store_widget; } -/* Get any svalue bound to REG, or NULL. */ +/* Get any svalue bound to REG, or nullptr. */ const svalue * store::get_any_binding (store_manager *mgr, const region *reg) const @@ -2770,7 +2770,7 @@ store::get_any_binding (store_manager *mgr, const region *reg) const binding_cluster **cluster_slot = const_cast <cluster_map_t &> (m_cluster_map).get (base_reg); if (!cluster_slot) - return NULL; + return nullptr; return (*cluster_slot)->get_any_binding (mgr, reg); } @@ -2796,7 +2796,7 @@ store::set_value (store_manager *mgr, const region *lhs_reg, { /* Reject attempting to bind values into a symbolic region for an unknown ptr; merely invalidate values below. */ - lhs_cluster = NULL; + lhs_cluster = nullptr; /* The LHS of the write is *UNKNOWN. If the RHS is a pointer, then treat the region being pointed to as having escaped. */ @@ -2818,7 +2818,7 @@ store::set_value (store_manager *mgr, const region *lhs_reg, { /* Reject attempting to bind values into an untracked region; merely invalidate values below. */ - lhs_cluster = NULL; + lhs_cluster = nullptr; } /* Bindings to a cluster can affect other clusters if a symbolic @@ -2838,7 +2838,7 @@ store::set_value (store_manager *mgr, const region *lhs_reg, const region *iter_base_reg = (*iter).first; binding_cluster *iter_cluster = (*iter).second; if (iter_base_reg != lhs_base_reg - && (lhs_cluster == NULL + && (lhs_cluster == nullptr || lhs_cluster->symbolic_p () || iter_cluster->symbolic_p ())) { @@ -3097,7 +3097,7 @@ store::purge_state_involving (const svalue *sval, purge_cluster (iter); } -/* Get the cluster for BASE_REG, or NULL (const version). */ +/* Get the cluster for BASE_REG, or nullptr (const version). */ const binding_cluster * store::get_cluster (const region *base_reg) const @@ -3108,10 +3108,10 @@ store::get_cluster (const region *base_reg) const = const_cast <cluster_map_t &> (m_cluster_map).get (base_reg)) return *slot; else - return NULL; + return nullptr; } -/* Get the cluster for BASE_REG, or NULL (non-const version). */ +/* Get the cluster for BASE_REG, or nullptr (non-const version). */ binding_cluster * store::get_cluster (const region *base_reg) @@ -3121,7 +3121,7 @@ store::get_cluster (const region *base_reg) if (binding_cluster **slot = m_cluster_map.get (base_reg)) return *slot; else - return NULL; + return nullptr; } /* Get the cluster for BASE_REG, creating it if doesn't already exist. */ @@ -3321,9 +3321,9 @@ store::remove_overlapping_bindings (store_manager *mgr, const region *reg, delete cluster; return; } - /* Pass NULL for the maybe_live_values here, as we don't want to + /* Pass nullptr for the maybe_live_values here, as we don't want to record the old svalues as being maybe-bound. */ - cluster->remove_overlapping_bindings (mgr, reg, uncertainty, NULL); + cluster->remove_overlapping_bindings (mgr, reg, uncertainty, nullptr); } } @@ -3566,7 +3566,7 @@ store::replay_call_summary_cluster (call_summary_replay &r, caller_sval = reg_mgr->get_or_create_unknown_svalue (summary_sval->get_type ()); set_value (mgr, caller_dest_reg, - caller_sval, NULL /* uncertainty_t * */); + caller_sval, nullptr /* uncertainty_t * */); } break; @@ -3591,7 +3591,7 @@ store::replay_call_summary_cluster (call_summary_replay &r, caller_sval = reg_mgr->get_or_create_unknown_svalue (summary_sval->get_type ()); set_value (mgr, caller_dest_reg, - caller_sval, NULL /* uncertainty_t * */); + caller_sval, nullptr /* uncertainty_t * */); } break; @@ -3786,7 +3786,7 @@ assert_disjoint (const location &loc, static void test_binding_key_overlap () { - store_manager mgr (NULL); + store_manager mgr (nullptr); /* Various 8-bit bindings. */ const concrete_binding *cb_0_7 = mgr.get_concrete_binding (0, 8); diff --git a/gcc/analyzer/store.h b/gcc/analyzer/store.h index 171324c13d34..95d38e30924f 100644 --- a/gcc/analyzer/store.h +++ b/gcc/analyzer/store.h @@ -222,9 +222,9 @@ class binding_key static int cmp (const binding_key *, const binding_key *); virtual const concrete_binding *dyn_cast_concrete_binding () const - { return NULL; } + { return nullptr; } virtual const symbolic_binding *dyn_cast_symbolic_binding () const - { return NULL; } + { return nullptr; } }; /* A concrete range of bits. */ @@ -299,6 +299,16 @@ struct bit_range bool as_byte_range (byte_range *out) const; + bool + operator< (const bit_range &other) const + { + if (m_start_bit_offset < other.m_start_bit_offset) + return true; + if (m_start_bit_offset > other.m_start_bit_offset) + return false; + return (m_size_in_bits < other.m_size_in_bits); + } + bit_offset_t m_start_bit_offset; bit_size_t m_size_in_bits; }; @@ -482,10 +492,10 @@ class symbolic_binding : public binding_key static int cmp_ptr_ptr (const void *, const void *); void mark_deleted () { m_region = reinterpret_cast<const region *> (1); } - void mark_empty () { m_region = NULL; } + void mark_empty () { m_region = nullptr; } bool is_deleted () const { return m_region == reinterpret_cast<const region *> (1); } - bool is_empty () const { return m_region == NULL; } + bool is_empty () const { return m_region == nullptr; } private: const region *m_region; @@ -528,7 +538,7 @@ class binding_map if (slot) return *slot; else - return NULL; + return nullptr; } bool put (const binding_key *k, const svalue *v) { diff --git a/gcc/analyzer/supergraph.cc b/gcc/analyzer/supergraph.cc index de2c330a258c..8592db78395c 100644 --- a/gcc/analyzer/supergraph.cc +++ b/gcc/analyzer/supergraph.cc @@ -48,7 +48,7 @@ get_ultimate_function_for_cgraph_edge (cgraph_edge *edge) { cgraph_node *ultimate_node = edge->callee->ultimate_alias_target (); if (!ultimate_node) - return NULL; + return nullptr; return ultimate_node->get_fun (); } @@ -59,15 +59,15 @@ supergraph_call_edge (function *fun, const gimple *stmt) { const gcall *call = dyn_cast<const gcall *> (stmt); if (!call) - return NULL; + return nullptr; cgraph_edge *edge = cgraph_node::get (fun->decl)->get_edge (const_cast <gimple *> (stmt)); if (!edge) - return NULL; + return nullptr; if (!edge->callee) - return NULL; /* e.g. for a function pointer. */ + return nullptr; /* e.g. for a function pointer. */ if (!get_ultimate_function_for_cgraph_edge (edge)) - return NULL; + return nullptr; return edge; } @@ -146,7 +146,8 @@ supergraph::supergraph (logger *logger) FOR_ALL_BB_FN (bb, fun) { /* The initial supernode for the BB gets the phi nodes (if any). */ - supernode *node_for_stmts = add_node (fun, bb, NULL, phi_nodes (bb)); + supernode *node_for_stmts + = add_node (fun, bb, nullptr, phi_nodes (bb)); m_bb_to_initial_node.put (bb, node_for_stmts); for (gphi_iterator gpi = gsi_start_phis (bb); !gsi_end_p (gpi); gsi_next (&gpi)) @@ -171,12 +172,12 @@ supergraph::supergraph (logger *logger) m_stmt_to_node_t.put (stmt, node_for_stmts); m_stmt_uids.make_uid_unique (stmt); if (cgraph_edge *edge = supergraph_call_edge (fun, stmt)) - { - m_cgraph_edge_to_caller_prev_node.put(edge, node_for_stmts); - node_for_stmts = add_node (fun, bb, as_a <gcall *> (stmt), - NULL); - m_cgraph_edge_to_caller_next_node.put (edge, node_for_stmts); - } + { + m_cgraph_edge_to_caller_prev_node.put(edge, node_for_stmts); + node_for_stmts = add_node (fun, bb, as_a <gcall *> (stmt), + nullptr); + m_cgraph_edge_to_caller_next_node.put (edge, node_for_stmts); + } else { // maybe call is via a function pointer @@ -187,13 +188,13 @@ supergraph::supergraph (logger *logger) if (!edge || !edge->callee) { supernode *old_node_for_stmts = node_for_stmts; - node_for_stmts = add_node (fun, bb, call, NULL); + node_for_stmts = add_node (fun, bb, call, nullptr); superedge *sedge = new callgraph_superedge (old_node_for_stmts, node_for_stmts, SUPEREDGE_INTRAPROCEDURAL_CALL, - NULL); + nullptr); add_edge (sedge); } } @@ -984,25 +985,25 @@ superedge::to_json () const } /* If this is an intraprocedural superedge, return the associated - CFG edge. Otherwise, return NULL. */ + CFG edge. Otherwise, return nullptr. */ ::edge superedge::get_any_cfg_edge () const { if (const cfg_superedge *sub = dyn_cast_cfg_superedge ()) return sub->get_cfg_edge (); - return NULL; + return nullptr; } /* If this is an interprocedural superedge, return the associated - cgraph_edge *. Otherwise, return NULL. */ + cgraph_edge *. Otherwise, return nullptr. */ cgraph_edge * superedge::get_any_callgraph_edge () const { if (const callgraph_superedge *sub = dyn_cast_callgraph_superedge ()) return sub->m_cedge; - return NULL; + return nullptr; } /* Build a description of this superedge (e.g. "true" for the true diff --git a/gcc/analyzer/supergraph.h b/gcc/analyzer/supergraph.h index 8796ab77e29b..f64a2f4b5d7e 100644 --- a/gcc/analyzer/supergraph.h +++ b/gcc/analyzer/supergraph.h @@ -274,7 +274,7 @@ class supernode : public dnode<supergraph_traits> i.ptr = gimple_seq_first (*pseq); i.seq = pseq; - i.bb = i.ptr ? gimple_bb (i.ptr) : NULL; + i.bb = i.ptr ? gimple_bb (i.ptr) : nullptr; return i; } @@ -287,15 +287,15 @@ class supernode : public dnode<supergraph_traits> gimple *get_last_stmt () const { if (m_stmts.length () == 0) - return NULL; + return nullptr; return m_stmts[m_stmts.length () - 1]; } gcall *get_final_call () const { gimple *stmt = get_last_stmt (); - if (stmt == NULL) - return NULL; + if (stmt == nullptr) + return nullptr; return dyn_cast<gcall *> (stmt); } @@ -331,18 +331,18 @@ class superedge : public dedge<supergraph_traits> enum edge_kind get_kind () const { return m_kind; } - virtual cfg_superedge *dyn_cast_cfg_superedge () { return NULL; } - virtual const cfg_superedge *dyn_cast_cfg_superedge () const { return NULL; } - virtual const switch_cfg_superedge *dyn_cast_switch_cfg_superedge () const { return NULL; } + virtual cfg_superedge *dyn_cast_cfg_superedge () { return nullptr; } + virtual const cfg_superedge *dyn_cast_cfg_superedge () const { return nullptr; } + virtual const switch_cfg_superedge *dyn_cast_switch_cfg_superedge () const { return nullptr; } virtual const eh_dispatch_cfg_superedge *dyn_cast_eh_dispatch_cfg_superedge () const { return nullptr; } virtual const eh_dispatch_try_cfg_superedge *dyn_cast_eh_dispatch_try_cfg_superedge () const { return nullptr; } virtual const eh_dispatch_allowed_cfg_superedge *dyn_cast_eh_dispatch_allowed_cfg_superedge () const { return nullptr; } - virtual callgraph_superedge *dyn_cast_callgraph_superedge () { return NULL; } - virtual const callgraph_superedge *dyn_cast_callgraph_superedge () const { return NULL; } - virtual call_superedge *dyn_cast_call_superedge () { return NULL; } - virtual const call_superedge *dyn_cast_call_superedge () const { return NULL; } - virtual return_superedge *dyn_cast_return_superedge () { return NULL; } - virtual const return_superedge *dyn_cast_return_superedge () const { return NULL; } + virtual callgraph_superedge *dyn_cast_callgraph_superedge () { return nullptr; } + virtual const callgraph_superedge *dyn_cast_callgraph_superedge () const { return nullptr; } + virtual call_superedge *dyn_cast_call_superedge () { return nullptr; } + virtual const call_superedge *dyn_cast_call_superedge () const { return nullptr; } + virtual return_superedge *dyn_cast_return_superedge () { return nullptr; } + virtual const return_superedge *dyn_cast_return_superedge () const { return nullptr; } ::edge get_any_cfg_edge () const; cgraph_edge *get_any_callgraph_edge () const; @@ -594,7 +594,7 @@ template <> inline bool is_a_helper <const switch_cfg_superedge *>::test (const superedge *sedge) { - return sedge->dyn_cast_switch_cfg_superedge () != NULL; + return sedge->dyn_cast_switch_cfg_superedge () != nullptr; } namespace ana { @@ -653,7 +653,7 @@ template <> inline bool is_a_helper <const eh_dispatch_cfg_superedge *>::test (const superedge *sedge) { - return sedge->dyn_cast_eh_dispatch_cfg_superedge () != NULL; + return sedge->dyn_cast_eh_dispatch_cfg_superedge () != nullptr; } namespace ana { @@ -703,7 +703,7 @@ template <> inline bool is_a_helper <const eh_dispatch_try_cfg_superedge *>::test (const superedge *sedge) { - return sedge->dyn_cast_eh_dispatch_try_cfg_superedge () != NULL; + return sedge->dyn_cast_eh_dispatch_try_cfg_superedge () != nullptr; } namespace ana { @@ -753,7 +753,7 @@ template <> inline bool is_a_helper <const eh_dispatch_allowed_cfg_superedge *>::test (const superedge *sedge) { - return sedge->dyn_cast_eh_dispatch_allowed_cfg_superedge () != NULL; + return sedge->dyn_cast_eh_dispatch_allowed_cfg_superedge () != nullptr; } namespace ana { diff --git a/gcc/analyzer/svalue.cc b/gcc/analyzer/svalue.cc index f3f80d1dc4e6..fbbd1d2c1768 100644 --- a/gcc/analyzer/svalue.cc +++ b/gcc/analyzer/svalue.cc @@ -247,7 +247,7 @@ svalue::maybe_get_constant () const } /* If this svalue is a region_svalue, return the region it points to. - Otherwise return NULL. */ + Otherwise return nullptr. */ const region * svalue::maybe_get_region () const @@ -255,12 +255,12 @@ svalue::maybe_get_region () const if (const region_svalue *region_sval = dyn_cast_region_svalue ()) return region_sval->get_pointee (); else - return NULL; + return nullptr; } /* If this svalue is a cast (i.e a unaryop NOP_EXPR or VIEW_CONVERT_EXPR), return the underlying svalue. - Otherwise return NULL. */ + Otherwise return nullptr. */ const svalue * svalue::maybe_undo_cast () const @@ -271,7 +271,7 @@ svalue::maybe_undo_cast () const if (op == NOP_EXPR || op == VIEW_CONVERT_EXPR) return unaryop_sval->get_arg (); } - return NULL; + return nullptr; } /* If this svalue is an unmergeable decorator around another svalue, return @@ -287,7 +287,7 @@ svalue::unwrap_any_unmergeable () const } /* Attempt to merge THIS with OTHER, returning the merged svalue. - Return NULL if not mergeable. */ + Return nullptr if not mergeable. */ const svalue * svalue::can_merge_p (const svalue *other, @@ -295,22 +295,22 @@ svalue::can_merge_p (const svalue *other, model_merger *merger) const { if (!(get_type () && other->get_type ())) - return NULL; + return nullptr; if (!types_compatible_p (get_type (), other->get_type ())) - return NULL; + return nullptr; /* Reject attempts to merge unmergeable svalues. */ if ((get_kind () == SK_UNMERGEABLE) || (other->get_kind () == SK_UNMERGEABLE)) - return NULL; + return nullptr; /* Reject attempts to merge poisoned svalues with other svalues (either non-poisoned, or other kinds of poison), so that e.g. we identify paths in which a variable is conditionally uninitialized. */ if (get_kind () == SK_POISONED || other->get_kind () == SK_POISONED) - return NULL; + return nullptr; /* Reject attempts to merge NULL pointers with not-NULL-pointers. */ if (POINTER_TYPE_P (get_type ())) @@ -324,16 +324,16 @@ svalue::can_merge_p (const svalue *other, if (zerop (cst1)) null1 = true; if (null0 != null1) - return NULL; + return nullptr; } /* Reject merging svalues that have non-purgable sm-state, to avoid falsely reporting memory leaks by merging them with something else. */ if (!merger->mergeable_svalue_p (this)) - return NULL; + return nullptr; if (!merger->mergeable_svalue_p (other)) - return NULL; + return nullptr; /* Widening. */ /* Merge: (new_cst, existing_cst) -> widen (existing, new). */ @@ -410,7 +410,7 @@ svalue::can_merge_p (const svalue *other, /* Determine if this svalue is either within LIVE_SVALUES, or is implicitly live with respect to LIVE_SVALUES and MODEL. - LIVE_SVALUES can be NULL, in which case determine if this svalue is + LIVE_SVALUES can be nullptr, in which case determine if this svalue is intrinsically live. */ bool @@ -806,7 +806,7 @@ svalue::maybe_fold_bits_within (tree, region_model_manager *) const { /* By default, don't fold. */ - return NULL; + return nullptr; } /* Base implementation of svalue::all_zeroes_p. @@ -819,7 +819,7 @@ svalue::all_zeroes_p () const } /* If this svalue is a pointer, attempt to determine the base region it points - to. Return NULL on any problems. */ + to. Return nullptr on any problems. */ const region * svalue::maybe_get_deref_base_region () const @@ -830,7 +830,7 @@ svalue::maybe_get_deref_base_region () const switch (iter->get_kind ()) { default: - return NULL; + return nullptr; case SK_REGION: { @@ -852,9 +852,9 @@ svalue::maybe_get_deref_base_region () const continue; default: - return NULL; + return nullptr; } - return NULL; + return nullptr; } } } @@ -1147,7 +1147,7 @@ constant_svalue::maybe_fold_bits_within (tree type, } /* Otherwise, don't fold. */ - return NULL; + return nullptr; } /* Implementation of svalue::all_zeroes_p for constant_svalue. */ @@ -1374,7 +1374,7 @@ initial_svalue::implicitly_live_p (const svalue_set *, a popped stack frame. */ if (model->region_exists_p (m_reg)) { - const svalue *reg_sval = model->get_store_value (m_reg, NULL); + const svalue *reg_sval = model->get_store_value (m_reg, nullptr); if (reg_sval == this) return true; } @@ -1384,7 +1384,7 @@ initial_svalue::implicitly_live_p (const svalue_set *, live in the external caller. */ if (initial_value_of_param_p ()) if (const frame_region *frame_reg = m_reg->maybe_get_frame_region ()) - if (frame_reg->get_calling_frame () == NULL) + if (frame_reg->get_calling_frame () == nullptr) return true; return false; @@ -1508,7 +1508,7 @@ unaryop_svalue::maybe_fold_bits_within (tree type, break; } /* Otherwise, don't fold. */ - return NULL; + return nullptr; } /* class binop_svalue : public svalue. */ @@ -1837,7 +1837,7 @@ repeated_svalue::maybe_fold_bits_within (tree type, } } - return NULL; + return nullptr; } /* class bits_within_svalue : public svalue. */ @@ -2393,7 +2393,7 @@ compound_svalue::maybe_fold_bits_within (tree type, } else /* If we have any symbolic keys we can't get it as bits. */ - return NULL; + return nullptr; } return mgr->get_or_create_compound_svalue (type, result_map); } diff --git a/gcc/analyzer/svalue.h b/gcc/analyzer/svalue.h index 7a27cb66b247..0ccb5ce4bd6a 100644 --- a/gcc/analyzer/svalue.h +++ b/gcc/analyzer/svalue.h @@ -112,37 +112,37 @@ class svalue : public symbol const char *prefix = nullptr) const; virtual const region_svalue * - dyn_cast_region_svalue () const { return NULL; } + dyn_cast_region_svalue () const { return nullptr; } virtual const constant_svalue * - dyn_cast_constant_svalue () const { return NULL; } + dyn_cast_constant_svalue () const { return nullptr; } virtual const poisoned_svalue * - dyn_cast_poisoned_svalue () const { return NULL; } + dyn_cast_poisoned_svalue () const { return nullptr; } virtual const setjmp_svalue * - dyn_cast_setjmp_svalue () const { return NULL; } + dyn_cast_setjmp_svalue () const { return nullptr; } virtual const initial_svalue * - dyn_cast_initial_svalue () const { return NULL; } + dyn_cast_initial_svalue () const { return nullptr; } virtual const unaryop_svalue * - dyn_cast_unaryop_svalue () const { return NULL; } + dyn_cast_unaryop_svalue () const { return nullptr; } virtual const binop_svalue * - dyn_cast_binop_svalue () const { return NULL; } + dyn_cast_binop_svalue () const { return nullptr; } virtual const sub_svalue * - dyn_cast_sub_svalue () const { return NULL; } + dyn_cast_sub_svalue () const { return nullptr; } virtual const repeated_svalue * - dyn_cast_repeated_svalue () const { return NULL; } + dyn_cast_repeated_svalue () const { return nullptr; } virtual const bits_within_svalue * - dyn_cast_bits_within_svalue () const { return NULL; } + dyn_cast_bits_within_svalue () const { return nullptr; } virtual const unmergeable_svalue * - dyn_cast_unmergeable_svalue () const { return NULL; } + dyn_cast_unmergeable_svalue () const { return nullptr; } virtual const widening_svalue * - dyn_cast_widening_svalue () const { return NULL; } + dyn_cast_widening_svalue () const { return nullptr; } virtual const compound_svalue * - dyn_cast_compound_svalue () const { return NULL; } + dyn_cast_compound_svalue () const { return nullptr; } virtual const conjured_svalue * - dyn_cast_conjured_svalue () const { return NULL; } + dyn_cast_conjured_svalue () const { return nullptr; } virtual const asm_output_svalue * - dyn_cast_asm_output_svalue () const { return NULL; } + dyn_cast_asm_output_svalue () const { return nullptr; } virtual const const_fn_result_svalue * - dyn_cast_const_fn_result_svalue () const { return NULL; } + dyn_cast_const_fn_result_svalue () const { return nullptr; } tree maybe_get_constant () const; const region *maybe_get_region () const; @@ -246,7 +246,7 @@ class region_svalue : public svalue : svalue (complexity (reg), id, type), m_reg (reg) { - gcc_assert (m_reg != NULL); + gcc_assert (m_reg != nullptr); } enum svalue_kind get_kind () const final override { return SK_REGION; } @@ -650,7 +650,7 @@ class initial_svalue : public svalue initial_svalue (symbol::id_t id, tree type, const region *reg) : svalue (complexity (reg), id, type), m_reg (reg) { - gcc_assert (m_reg != NULL); + gcc_assert (m_reg != nullptr); } enum svalue_kind get_kind () const final override { return SK_INITIAL; } @@ -1547,15 +1547,15 @@ class conjured_svalue : public svalue && m_idx == other.m_idx); } - /* Use m_stmt to mark empty/deleted, as m_type can be NULL for + /* Use m_stmt to mark empty/deleted, as m_type can be NULL_TREE for legitimate instances. */ void mark_deleted () { m_stmt = reinterpret_cast<const gimple *> (1); } - void mark_empty () { m_stmt = NULL; } + void mark_empty () { m_stmt = nullptr; } bool is_deleted () const { return m_stmt == reinterpret_cast<const gimple *> (1); } - bool is_empty () const { return m_stmt == NULL; } + bool is_empty () const { return m_stmt == nullptr; } tree m_type; const gimple *m_stmt; @@ -1568,7 +1568,7 @@ class conjured_svalue : public svalue : svalue (complexity (id_reg), id, type), m_stmt (stmt), m_id_reg (id_reg), m_idx (idx) { - gcc_assert (m_stmt != NULL); + gcc_assert (m_stmt != nullptr); } enum svalue_kind get_kind () const final override { return SK_CONJURED; } @@ -1668,15 +1668,15 @@ class asm_output_svalue : public svalue return true; } - /* Use m_asm_string to mark empty/deleted, as m_type can be NULL for + /* Use m_asm_string to mark empty/deleted, as m_type can be NULL_TREE for legitimate instances. */ void mark_deleted () { m_asm_string = reinterpret_cast<const char *> (1); } - void mark_empty () { m_asm_string = NULL; } + void mark_empty () { m_asm_string = nullptr; } bool is_deleted () const { return m_asm_string == reinterpret_cast<const char *> (1); } - bool is_empty () const { return m_asm_string == NULL; } + bool is_empty () const { return m_asm_string == nullptr; } tree m_type; const char *m_asm_string; @@ -1813,12 +1813,12 @@ class const_fn_result_svalue : public svalue /* Use m_fndecl to mark empty/deleted. */ void mark_deleted () { m_fndecl = reinterpret_cast<tree> (1); } - void mark_empty () { m_fndecl = NULL; } + void mark_empty () { m_fndecl = NULL_TREE; } bool is_deleted () const { return m_fndecl == reinterpret_cast<tree> (1); } - bool is_empty () const { return m_fndecl == NULL; } + bool is_empty () const { return m_fndecl == NULL_TREE; } tree m_type; tree m_fndecl; diff --git a/gcc/analyzer/varargs.cc b/gcc/analyzer/varargs.cc index 6ea0d29d1314..494727149171 100644 --- a/gcc/analyzer/varargs.cc +++ b/gcc/analyzer/varargs.cc @@ -205,7 +205,11 @@ class va_list_state_machine : public state_machine { return s != m_started; } - std::unique_ptr<pending_diagnostic> on_leak (tree var) const final override; + + std::unique_ptr<pending_diagnostic> + on_leak (tree var, + const program_state *old_state, + const program_state *new_state) const final override; /* State for a va_list that is the result of a va_start or va_copy. */ state_t m_started; @@ -294,15 +298,15 @@ get_stateful_arg (sm_context &sm_ctxt, const gcall &call, unsigned arg_idx) if (const program_state *new_state = sm_ctxt.get_new_program_state ()) { const region_model *new_model = new_state->m_region_model; - const svalue *ptr_sval = new_model->get_rvalue (ap, NULL); - const region *reg = new_model->deref_rvalue (ptr_sval, ap, NULL); - const svalue *impl_sval = new_model->get_store_value (reg, NULL); + const svalue *ptr_sval = new_model->get_rvalue (ap, nullptr); + const region *reg = new_model->deref_rvalue (ptr_sval, ap, nullptr); + const svalue *impl_sval = new_model->get_store_value (reg, nullptr); if (const svalue *cast = impl_sval->maybe_undo_cast ()) impl_sval = cast; return impl_sval; } } - return NULL; + return nullptr; } /* Abstract class for diagnostics relating to va_list_state_machine. */ @@ -335,11 +339,11 @@ class va_list_sm_diagnostic : public pending_diagnostic const final override { if (change.m_new_state == m_sm.m_started) - return diagnostic_event::meaning (diagnostic_event::VERB_acquire, - diagnostic_event::NOUN_resource); + return diagnostic_event::meaning (diagnostic_event::verb::acquire, + diagnostic_event::noun::resource); if (change.m_new_state == m_sm.m_ended) - return diagnostic_event::meaning (diagnostic_event::VERB_release, - diagnostic_event::NOUN_resource); + return diagnostic_event::meaning (diagnostic_event::verb::release, + diagnostic_event::noun::resource); return diagnostic_event::meaning (); } @@ -366,7 +370,7 @@ class va_list_sm_diagnostic : public pending_diagnostic return "va_end"; } } - return NULL; + return nullptr; } const va_list_state_machine &m_sm; @@ -460,10 +464,14 @@ class va_list_leak : public va_list_sm_diagnostic { public: va_list_leak (const va_list_state_machine &sm, - const svalue *ap_sval, tree ap_tree) + const svalue *ap_sval, tree ap_tree, + const program_state *final_state) : va_list_sm_diagnostic (sm, ap_sval, ap_tree), - m_start_event_fnname (NULL) + m_start_event_fnname (nullptr), + m_final_state () { + if (final_state) + m_final_state = std::make_unique<program_state> (*final_state); } int get_controlling_option () const final override @@ -524,9 +532,16 @@ class va_list_leak : public va_list_sm_diagnostic return true; } + const program_state * + get_final_state () const final override + { + return m_final_state.get (); + } + private: diagnostic_event_id_t m_start_event; const char *m_start_event_fnname; + std::unique_ptr<program_state> m_final_state; }; /* Update state machine for a "va_start" call. */ @@ -562,7 +577,7 @@ va_list_state_machine::check_for_ended_va_list (sm_context &sm_ctxt, /* Get the svalue with associated va_list_state_machine state for ARG_IDX of CALL to va_copy, if SM_CTXT supports this, - or NULL otherwise. */ + or nullptr otherwise. */ static const svalue * get_stateful_va_copy_arg (sm_context &sm_ctxt, @@ -572,10 +587,10 @@ get_stateful_va_copy_arg (sm_context &sm_ctxt, if (const program_state *new_state = sm_ctxt.get_new_program_state ()) { const region_model *new_model = new_state->m_region_model; - const svalue *arg = get_va_copy_arg (new_model, NULL, call, arg_idx); + const svalue *arg = get_va_copy_arg (new_model, nullptr, call, arg_idx); return arg; } - return NULL; + return nullptr; } /* Update state machine for a "va_copy" call. */ @@ -633,9 +648,11 @@ va_list_state_machine::on_va_end (sm_context &sm_ctxt, (for complaining about leaks of values in state 'started'). */ std::unique_ptr<pending_diagnostic> -va_list_state_machine::on_leak (tree var) const +va_list_state_machine::on_leak (tree var, + const program_state *, + const program_state *new_state) const { - return std::make_unique<va_list_leak> (*this, nullptr, var); + return std::make_unique<va_list_leak> (*this, nullptr, var, new_state); } } // anonymous namespace @@ -723,7 +740,7 @@ kf_va_copy::impl_call_pre (const call_details &cd) const in_va_list = model->check_for_poison (in_va_list, get_va_list_diag_arg (cd.get_arg_tree (1)), - NULL, + nullptr, cd.get_ctxt ()); const region *out_dst_reg @@ -1003,14 +1020,14 @@ va_arg_compatible_types_p (tree lhs_type, tree arg_type, const svalue &arg_sval) } /* If AP_SVAL is a pointer to a var_arg_region, return that var_arg_region. - Otherwise return NULL. */ + Otherwise return nullptr. */ static const var_arg_region * maybe_get_var_arg_region (const svalue *ap_sval) { if (const region *reg = ap_sval->maybe_get_region ()) return reg->dyn_cast_var_arg_region (); - return NULL; + return nullptr; } /* Handler for "__builtin_va_arg". */ diff --git a/gcc/attribs.cc b/gcc/attribs.cc index 56dd18c2fa8e..3fce9d625256 100644 --- a/gcc/attribs.cc +++ b/gcc/attribs.cc @@ -1076,21 +1076,15 @@ apply_tm_attr (tree fndecl, tree attr) it to CHAIN. */ tree -make_attribute (const char *name, const char *arg_name, tree chain) +make_attribute (string_slice name, string_slice arg_name, tree chain) { - tree attr_name; - tree attr_arg_name; - tree attr_args; - tree attr; - - attr_name = get_identifier (name); - attr_arg_name = build_string (strlen (arg_name), arg_name); - attr_args = tree_cons (NULL_TREE, attr_arg_name, NULL_TREE); - attr = tree_cons (attr_name, attr_args, chain); + tree attr_name = get_identifier_with_length (name.begin (), name.size ()); + tree attr_arg_name = build_string (arg_name.size (), arg_name.begin ()); + tree attr_args = tree_cons (NULL_TREE, attr_arg_name, NULL_TREE); + tree attr = tree_cons (attr_name, attr_args, chain); return attr; } - /* Common functions used for target clone support. */ /* Comparator function to be used in qsort routine to sort attribute @@ -1279,18 +1273,31 @@ make_dispatcher_decl (const tree decl) return func_decl; } -/* Returns true if DECL is multi-versioned using the target attribute, and this - is the default version. This function can only be used for targets that do - not support the "target_version" attribute. */ +/* Returns true if DECL a multiversioned default. + With the target attribute semantics, returns true if the function is marked + as default with the target version. + With the target_version attribute semantics, returns true if the function + is either not annotated, or annotated as default. */ bool is_function_default_version (const tree decl) { - if (TREE_CODE (decl) != FUNCTION_DECL - || !DECL_FUNCTION_VERSIONED (decl)) + tree attr; + if (TREE_CODE (decl) != FUNCTION_DECL) return false; - tree attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl)); - gcc_assert (attr); + if (TARGET_HAS_FMV_TARGET_ATTRIBUTE) + { + if (!DECL_FUNCTION_VERSIONED (decl)) + return false; + attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl)); + gcc_assert (attr); + } + else + { + attr = lookup_attribute ("target_version", DECL_ATTRIBUTES (decl)); + if (!attr) + return true; + } attr = TREE_VALUE (TREE_VALUE (attr)); return (TREE_CODE (attr) == STRING_CST && strcmp (TREE_STRING_POINTER (attr), "default") == 0); diff --git a/gcc/attribs.h b/gcc/attribs.h index 4b946390f76b..b8b6838599cc 100644 --- a/gcc/attribs.h +++ b/gcc/attribs.h @@ -45,7 +45,7 @@ extern bool cxx11_attribute_p (const_tree); extern tree get_attribute_name (const_tree); extern tree get_attribute_namespace (const_tree); extern void apply_tm_attr (tree, tree); -extern tree make_attribute (const char *, const char *, tree); +extern tree make_attribute (string_slice, string_slice, tree); extern bool attribute_ignored_p (tree); extern bool attribute_ignored_p (const attribute_spec *const); extern bool any_nonignored_attribute_p (tree); diff --git a/gcc/auto-obstack.h b/gcc/auto-obstack.h new file mode 100644 index 000000000000..fe16dbd1068a --- /dev/null +++ b/gcc/auto-obstack.h @@ -0,0 +1,58 @@ +/* RAII wrapper around obstack. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + Contributed by David Malcolm <dmalcolm@redhat.com>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_AUTO_OBSTACK_H +#define GCC_AUTO_OBSTACK_H + +/* RAII wrapper around obstack. */ + +struct auto_obstack +{ + auto_obstack () + { + obstack_init (&m_obstack); + } + + ~auto_obstack () + { + obstack_free (&m_obstack, NULL); + } + + operator obstack & () { return m_obstack; } + + void grow (const void *src, size_t length) + { + obstack_grow (&m_obstack, src, length); + } + + void *object_base () const + { + return m_obstack.object_base; + } + + size_t object_size () const + { + return obstack_object_size (&m_obstack); + } + + obstack m_obstack; +}; + +#endif /* GCC_AUTO_OBSTACK_H */ diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc index 91cc8db2c832..d1954b4fad69 100644 --- a/gcc/auto-profile.cc +++ b/gcc/auto-profile.cc @@ -35,6 +35,8 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-core.h" #include "profile.h" #include "langhooks.h" +#include "context.h" +#include "pass_manager.h" #include "cfgloop.h" #include "tree-cfg.h" #include "tree-cfgcleanup.h" @@ -51,6 +53,7 @@ along with GCC; see the file COPYING3. If not see #include "auto-profile.h" #include "tree-pretty-print.h" #include "gimple-pretty-print.h" +#include "output.h" /* The following routines implements AutoFDO optimization. @@ -59,7 +62,8 @@ along with GCC; see the file COPYING3. If not see There are three phases in AutoFDO: - Phase 1: Read profile from the profile data file. + Phase 1: At startup. + Read profile from the profile data file. The following info is read from the profile datafile: * string_table: a map between function name and its index. * autofdo_source_profile: a map from function_instance name to @@ -74,23 +78,44 @@ along with GCC; see the file COPYING3. If not see standalone symbol, or a clone of a function that is inlined into another function. - Phase 2: Early inline + value profile transformation. - Early inline uses autofdo_source_profile to find if a callsite is: + Phase 2: In afdo_offline pass. + Remove function instances from other translation units + and offline all cross-translation unit inlining done during train + run compilation. This is necessary to not lose profiles with + LTO train run. + + Phase 3: During early optimization. + AFDO inline + value profile transformation. + This happens during early optimization. + During early inlning AFDO inliner is executed which + uses autofdo_source_profile to find if a callsite is: * inlined in the profiled binary. * callee body is hot in the profiling run. If both condition satisfies, early inline will inline the callsite regardless of the code growth. - Phase 2 is an iterative process. During each iteration, we also check - if an indirect callsite is promoted and inlined in the profiling run. - If yes, vpt will happen to force promote it and in the next iteration, - einline will inline the promoted callsite in the next iteration. - Phase 3: Annotate control flow graph. - AutoFDO uses a separate pass to: + Performing this early has benefit of doing early optimizations + before read IPA passe and getting more "context sensitivity" of + the profile read. Profile of inlined functions may differ + significantly form one inline instance to another and from the + offline version. + + This is controlled by -fauto-profile-inlinig and is independent + of -fearly-inlining. + + Phase 4: In AFDO pass. + Offline all functions that has been inlined in the + train run but were not inlined in early inlining nor AFDO + inline. + + Phase 5: In AFDO pass. + Annotate control flow graph. * Annotate basic block count * Estimate branch probability + * Use earlier static profile to fill in the gaps + if AFDO profile is ambigous - After the above 3 phases, all profile is readily annotated on the GCC IR. + After the above 5 phases, all profile is readily annotated on the GCC IR. AutoFDO tries to reuse all FDO infrastructure as much as possible to make use of the profile. E.g. it uses existing mechanism to calculate the basic block/edge frequency, as well as the cgraph node/edge count. @@ -99,6 +124,18 @@ along with GCC; see the file COPYING3. If not see #define DEFAULT_AUTO_PROFILE_FILE "fbdata.afdo" #define AUTO_PROFILE_VERSION 2 +/* profile counts determined by AFDO smaller than afdo_hot_bb_threshold are + considered cols. */ +gcov_type afdo_hot_bb_threshod = -1; + +/* Return ture if COUNT is possiby hot. */ +bool +maybe_hot_afdo_count_p (profile_count count) +{ + gcc_checking_assert (count.ipa ().initialized_p ()); + return count.ipa ().to_gcov_type () >= afdo_hot_bb_threshod; +} + namespace autofdo { @@ -120,10 +157,17 @@ class edge_info }; /* Represent a source location: (function_decl, lineno). */ -typedef std::pair<tree, unsigned> decl_lineno; +struct decl_lineno +{ + tree decl; + /* Relative locations stored in auto-profile. */ + unsigned int afdo_loc; + /* Actual location afdo_loc was computed from used to output diagnostics. */ + location_t location; +}; /* Represent an inline stack. vector[0] is the leaf node. */ -typedef auto_vec<decl_lineno> inline_stack; +typedef auto_vec<decl_lineno, 20> inline_stack; /* String array that stores function names. */ typedef auto_vec<char *> string_vector; @@ -136,6 +180,10 @@ typedef std::map<unsigned, gcov_type> icall_target_map; to direct call. */ typedef std::set<gimple *> stmt_set; +/* Set and map used to translate name indexes. */ +typedef hash_set<int_hash <int, -1, -2>> name_index_set; +typedef hash_map<int_hash <int, -1, -2>, int> name_index_map; + /* Represent count info of an inline stack. */ class count_info { @@ -183,6 +231,17 @@ class string_table /* Read profile, return TRUE on success. */ bool read (); + /* Return number of entries. */ + size_t num_entries () + { + return vector_.length (); + } + + /* Add new name and return its index. */ + int add_name (char *); + + /* Return cgraph node corresponding to given name index. */ + cgraph_node *get_cgraph_node (int); private: typedef std::map<const char *, unsigned, string_compare> string_index_map; string_vector vector_; @@ -217,11 +276,18 @@ class function_instance { return name_; } + int + set_name (int index) + { + return name_ = index; + } gcov_type total_count () const { return total_count_; } + + /* Return head count or -1 if unknown. */ gcov_type head_count () const { @@ -229,25 +295,158 @@ class function_instance } /* Traverse callsites of the current function_instance to find one at the - location of LINENO and callee name represented in DECL. */ + location of LINENO and callee name represented in DECL. + LOCATION should match LINENO and is used to output diagnostics. */ function_instance *get_function_instance_by_decl (unsigned lineno, - tree decl) const; + tree decl, + location_t location) const; /* Merge profile of clones. Note that cloning hasnt been performed when we annotate the CFG (at this stage). */ - void merge (function_instance *other); + void merge (function_instance *other, + vec <function_instance *> &new_functions); + + /* Look for inline instancs that was not realized and + remove them while possibly merging them to offline variants. */ + void offline_if_not_realized (vec <function_instance *> &new_functions); + + /* Match function instance with gimple body. */ + bool match (cgraph_node *node, vec <function_instance *> &new_functions, + name_index_map &to_symbol_name); + + /* Offline all inlined functions with name in SEEN. + If new toplevel functions are created, add them to NEW_FUNCTIONS. */ + void offline_if_in_set (name_index_set &seen, + vec <function_instance *> &new_functions); + + /* Walk inlined functions and if their name is not in SEEN + remove it. */ + + void remove_external_functions (name_index_set &seen, + name_index_map &to_symbol_name, + vec <function_instance *> &new_functions); /* Store the profile info for LOC in INFO. Return TRUE if profile info is found. */ bool get_count_info (location_t loc, count_info *info) const; - /* Read the inlined indirect call target profile for STMT and store it in - MAP, return the total count for all inlined indirect calls. */ - gcov_type find_icall_target_map (gcall *stmt, icall_target_map *map) const; + /* Read the inlined indirect call target profile for STMT in FN and store it + in MAP, return the total count for all inlined indirect calls. */ + gcov_type find_icall_target_map (tree fn, gcall *stmt, + icall_target_map *map) const; + + /* Remove inlined indirect call target profile for STMT in FN. */ + void remove_icall_target (tree fn, gcall *stmt); /* Mark LOC as annotated. */ void mark_annotated (location_t loc); + void dump (FILE *f, int indent = 0, bool nested = false) const; + + void dump_inline_stack (FILE *f) const; + + DEBUG_FUNCTION void debug () const; + + /* Mark function as removed from indir target list. */ + void + remove_icall_target () + { + removed_icall_target_ = true; + } + + /* Reutrn true if function is removed from indir target list. */ + bool + removed_icall_target () + { + return removed_icall_target_; + } + + /* Set inlined_to pointer. */ + void + set_inlined_to (function_instance *inlined_to) + { + gcc_checking_assert (inlined_to != this); + inlined_to_ = inlined_to; + } + + /* Return pointer to the function instance this function is inlined + to or NULL if it is outer instance. */ + function_instance * + inlined_to () const + { + return inlined_to_; + } + + /* Mark function as realized. */ + void + set_realized () + { + realized_ = true; + } + + /* Return true if function is realized. */ + bool + realized_p () + { + return realized_; + } + + /* Mark function as in_worklist. */ + void + set_in_worklist () + { + gcc_checking_assert (!inlined_to_ && !in_worklist_p ()); + in_worklist_ = true; + } + + void + clear_in_worklist () + { + gcc_checking_assert (!inlined_to_ && in_worklist_p ()); + in_worklist_ = false; + } + + + /* Return true if function is in_worklist. */ + bool + in_worklist_p () + { + return in_worklist_; + } + + /* Return corresponding cgraph node. */ + cgraph_node *get_cgraph_node (); + + void + set_location (location_t l) + { + gcc_checking_assert (location_ == UNKNOWN_LOCATION); + location_= l; + } + + location_t + get_location () + { + return location_; + } + + void + set_call_location (location_t l) + { + gcc_checking_assert (call_location_ == UNKNOWN_LOCATION + && l != UNKNOWN_LOCATION); + call_location_= l; + } + + location_t + get_call_location () + { + return call_location_; + } + + /* Lookup count and warn about duplicates. */ + count_info *lookup_count (location_t loc, inline_stack &stack, + cgraph_node *node); private: /* Callsite, represented as (decl_lineno, callee_function_name_index). */ typedef std::pair<unsigned, unsigned> callsite; @@ -256,7 +455,10 @@ class function_instance typedef std::map<callsite, function_instance *> callsite_map; function_instance (unsigned name, gcov_type head_count) - : name_ (name), total_count_ (0), head_count_ (head_count) + : name_ (name), total_count_ (0), head_count_ (head_count), + removed_icall_target_ (false), realized_ (false), + in_worklist_ (false), inlined_to_ (NULL), + location_ (UNKNOWN_LOCATION), call_location_ (UNKNOWN_LOCATION) { } @@ -277,6 +479,28 @@ class function_instance /* Map from source location to count_info. */ position_count_map pos_counts; + + /* True if function was removed from indir target list. */ + bool removed_icall_target_; + + /* True if function exists in IL. I.e. for toplevel instance we + have corresponding symbol and for inline instance we inlined + to it. */ + bool realized_; + + /* Ture if function is in worklist for merging/offlining. */ + bool in_worklist_; + + /* Pointer to outer function instance or NULL if this + is a toplevel one. */ + function_instance *inlined_to_; + + /* Location of function and its call (in case it is inlined). */ + location_t location_, call_location_; + + /* Turn inline instance to offline. */ + static bool offline (function_instance *fn, + vec <function_instance *> &new_functions); }; /* Profile for all functions. */ @@ -299,21 +523,37 @@ class autofdo_source_profile /* For a given DECL, returns the top-level function_instance. */ function_instance *get_function_instance_by_decl (tree decl) const; + /* For a given name index, returns the top-level function_instance. */ + function_instance *get_function_instance_by_name_index (int) const; + + void add_function_instance (function_instance *); + /* Find count_info for a given gimple STMT. If found, store the count_info - in INFO and return true; otherwise return false. */ - bool get_count_info (gimple *stmt, count_info *info) const; + in INFO and return true; otherwise return false. + NODE can be used to specify particular inline clone. */ + bool get_count_info (gimple *stmt, count_info *info, + cgraph_node *node = NULL) const; /* Find count_info for a given gimple location GIMPLE_LOC. If found, - store the count_info in INFO and return true; otherwise return false. */ - bool get_count_info (location_t gimple_loc, count_info *info) const; + store the count_info in INFO and return true; otherwise return false. + NODE can be used to specify particular inline clone. */ + bool get_count_info (location_t gimple_loc, count_info *info, + cgraph_node *node = NULL) const; /* Find total count of the callee of EDGE. */ gcov_type get_callsite_total_count (struct cgraph_edge *edge) const; - /* Update value profile INFO for STMT from the inlined indirect callsite. - Return true if INFO is updated. */ - bool update_inlined_ind_target (gcall *stmt, count_info *info); + /* Update value profile INFO for STMT within NODE from the inlined indirect + callsite. Return true if INFO is updated. */ + bool update_inlined_ind_target (gcall *stmt, count_info *info, + cgraph_node *node); + + void remove_icall_target (cgraph_edge *e); + /* Offline all functions not defined in the current translation unit. */ + void offline_external_functions (); + + void offline_unrealized_inlines (); private: /* Map from function_instance name index (in string_table) to function_instance. */ @@ -330,6 +570,8 @@ class autofdo_source_profile get_function_instance_by_inline_stack (const inline_stack &stack) const; name_function_instance_map map_; + + auto_vec <function_instance *> duplicate_functions_; }; /* Store the strings read from the profile data file. */ @@ -341,18 +583,61 @@ static autofdo_source_profile *afdo_source_profile; /* gcov_summary structure to store the profile_info. */ static gcov_summary *afdo_profile_info; +/* Scaling factor for afdo data. Compared to normal profile + AFDO profile counts are much lower, depending on sampling + frequency. We scale data up to reudce effects of roundoff + errors. */ + +static gcov_type afdo_count_scale = 1; + /* Helper functions. */ + /* Return the original name of NAME: strip the suffix that starts - with '.' Caller is responsible for freeing RET. */ + with '.' for names that are generetad after auto-profile pass. + This is to match profiled names with the names in the IR at this stage. + Note that we only have to strip sufix and not in the middle. + Caller is responsible for freeing RET. */ static char * -get_original_name (const char *name) +get_original_name (const char *name, bool alloc = true) { - char *ret = xstrdup (name); - char *find = strchr (ret, '.'); - if (find != NULL) - *find = 0; + char *ret = alloc ? xstrdup (name) : const_cast<char *> (name); + char *last_dot = strrchr (ret, '.'); + if (last_dot == NULL) + return ret; + bool only_digits = true; + char *ptr = last_dot; + while (*(++ptr) != 0) + if (*ptr < '0' || *ptr > '9') + { + only_digits = false; + break; + } + if (only_digits) + *last_dot = 0; + char *next_dot = strrchr (ret, '.'); + /* if nested function such as foo.0, return foo.0 */ + if (next_dot == NULL) + { + *last_dot = '.'; + return ret; + } + /* Suffixes of clones that compiler generates after auto-profile. */ + const char *suffixes[] = {"isra", "constprop", "lto_priv", "part", "cold"}; + for (unsigned i = 0; i < sizeof (suffixes) / sizeof (const char *); ++i) + { + int len = strlen (suffixes[i]); + if (len == last_dot - next_dot - 1 + && strncmp (next_dot + 1, suffixes[i], strlen (suffixes[i])) == 0) + { + *next_dot = 0; + return get_original_name (ret, false); + } + } + /* Otherwise, it is for clones such as .omp_fn.N that was done before + auto-profile and should be kept as it is. */ + *last_dot = '.'; return ret; } @@ -363,10 +648,21 @@ get_original_name (const char *name) static unsigned get_combined_location (location_t loc, tree decl) { + bool warned = false; /* TODO: allow more bits for line and less bits for discriminator. */ - if (LOCATION_LINE (loc) - DECL_SOURCE_LINE (decl) >= (1<<16)) - warning_at (loc, OPT_Woverflow, "offset exceeds 16 bytes"); - return ((LOCATION_LINE (loc) - DECL_SOURCE_LINE (decl)) << 16) + if ((LOCATION_LINE (loc) - DECL_SOURCE_LINE (decl)) >= (1<<15) + || (LOCATION_LINE (loc) - DECL_SOURCE_LINE (decl)) <= -(1<<15)) + warned = warning_at (loc, OPT_Wauto_profile, + "auto-profile cannot encode offset %i " + "that exceeds 16 bytes", + LOCATION_LINE (loc) - DECL_SOURCE_LINE (decl)); + if (warned) + inform (DECL_SOURCE_LOCATION (decl), "location offset is related to"); + if ((unsigned)get_discriminator_from_loc (loc) >= (1u << 16)) + warning_at (loc, OPT_Wauto_profile, + "auto-profile cannot encode discriminators " + "that exceeds 16 bytes"); + return ((unsigned)(LOCATION_LINE (loc) - DECL_SOURCE_LINE (decl)) << 16) | get_discriminator_from_loc (loc); } @@ -381,10 +677,59 @@ get_function_decl_from_block (tree block) return BLOCK_ABSTRACT_ORIGIN (block); } +/* Dump LOC to F. */ + +static void +dump_afdo_loc (FILE *f, unsigned loc) +{ + if (loc & 65535) + fprintf (f, "%i.%i", loc >> 16, loc & 65535); + else + fprintf (f, "%i", loc >> 16); +} + +/* Return assembler name as in symbol table and DW_AT_linkage_name. */ + +static const char * +raw_symbol_name (const char *asmname) +{ + /* If we start supporting user_label_prefixes, add_linkage_attr will also + need to be fixed. */ + if (strlen (user_label_prefix)) + sorry ("auto-profile is not supported for targets with user label prefix"); + return asmname + (asmname[0] == '*'); +} + +/* Convenience wrapper that looks up assembler name. */ + +static const char * +raw_symbol_name (tree decl) +{ + return raw_symbol_name (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); +} + +/* Dump STACK to F. */ + +static void +dump_inline_stack (FILE *f, inline_stack *stack) +{ + bool first = true; + for (decl_lineno &p : *stack) + { + fprintf (f, "%s%s:", + first ? "" : "; ", + raw_symbol_name (p.decl)); + dump_afdo_loc (f, p.afdo_loc); + first = false; + } + fprintf (f, "\n"); +} + /* Store inline stack for STMT in STACK. */ static void -get_inline_stack (location_t locus, inline_stack *stack) +get_inline_stack (location_t locus, inline_stack *stack, + tree fn = current_function_decl) { if (LOCATION_LOCUS (locus) == UNKNOWN_LOCATION) return; @@ -402,50 +747,65 @@ get_inline_stack (location_t locus, inline_stack *stack) tree decl = get_function_decl_from_block (block); stack->safe_push ( - std::make_pair (decl, get_combined_location (locus, decl))); + {decl, get_combined_location (locus, decl), locus}); locus = tmp_locus; } } - stack->safe_push ( - std::make_pair (current_function_decl, - get_combined_location (locus, current_function_decl))); + stack->safe_push ({fn, get_combined_location (locus, fn), locus}); } -/* Return STMT's combined location, which is a 32bit integer in which - higher 16 bits stores the line offset of LOC to the start lineno - of DECL, The lower 16 bits stores the discriminator. */ +/* Same as get_inline_stack for a given node which may be + an inline clone. If NODE is NULL, assume current_function_decl. */ +static void +get_inline_stack_in_node (location_t locus, inline_stack *stack, + cgraph_node *node) +{ + if (!node) + return get_inline_stack (locus, stack); + do + { + get_inline_stack (locus, stack, node->decl); + /* If caller is inlined, continue building stack. */ + if (!node->inlined_to) + node = NULL; + else + { + locus = gimple_location (node->callers->call_stmt); + node = node->callers->caller; + } + } + while (node); +} + +/* Return combined location of LOCUS within BLOCK that is in + function FN. + + This is a 32bit integer in which higher 16 bits stores the line offset of + LOC to the start lineno of DECL, The lower 16 bits stores the + discriminator. */ static unsigned -get_relative_location_for_stmt (gimple *stmt) +get_relative_location_for_locus (tree fn, tree block, location_t locus) { - location_t locus = gimple_location (stmt); if (LOCATION_LOCUS (locus) == UNKNOWN_LOCATION) - return UNKNOWN_LOCATION; + return -1; - for (tree block = gimple_block (stmt); block && (TREE_CODE (block) == BLOCK); + for (; block && (TREE_CODE (block) == BLOCK); block = BLOCK_SUPERCONTEXT (block)) - if (LOCATION_LOCUS (BLOCK_SOURCE_LOCATION (block)) != UNKNOWN_LOCATION) + if (inlined_function_outer_scope_p (block)) return get_combined_location (locus, - get_function_decl_from_block (block)); - return get_combined_location (locus, current_function_decl); + get_function_decl_from_block (block)); + return get_combined_location (locus, fn); } -/* Return true if BB contains indirect call. */ +/* Return combined location of STMT in function FN. */ -static bool -has_indirect_call (basic_block bb) +static unsigned +get_relative_location_for_stmt (tree fn, gimple *stmt) { - gimple_stmt_iterator gsi; - - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple *stmt = gsi_stmt (gsi); - if (gimple_code (stmt) == GIMPLE_CALL && !gimple_call_internal_p (stmt) - && (gimple_call_fn (stmt) == NULL - || TREE_CODE (gimple_call_fn (stmt)) != FUNCTION_DECL)) - return true; - } - return false; + return get_relative_location_for_locus + (fn, LOCATION_BLOCK (gimple_location (stmt)), + gimple_location (stmt)); } /* Member functions for string_table. */ @@ -480,13 +840,8 @@ string_table::get_index (const char *name) const int string_table::get_index_by_decl (tree decl) const { - char *name - = get_original_name (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); + const char *name = raw_symbol_name (decl); int ret = get_index (name); - free (name); - if (ret != -1) - return ret; - ret = get_index (lang_hooks.dwarf_name (decl, 0)); if (ret != -1) return ret; if (DECL_FROM_INLINE (decl)) @@ -504,6 +859,16 @@ string_table::get_name (int index) const return vector_[index]; } +/* Add new name SRRING and return its index. */ + +int +string_table::add_name (char *string) +{ + vector_.safe_push (string); + map_[vector_.last ()] = vector_.length () - 1; + return vector_.length () - 1; +} + /* Read the string table. Return TRUE if reading is successful. */ bool @@ -515,18 +880,43 @@ string_table::read () gcov_read_unsigned (); /* Read in the file name table. */ unsigned string_num = gcov_read_unsigned (); + vector_.reserve (string_num); for (unsigned i = 0; i < string_num; i++) { - vector_.safe_push (get_original_name (gcov_read_string ())); + vector_.quick_push (xstrdup (gcov_read_string ())); map_[vector_.last ()] = i; } return true; } +/* Return cgraph node corresponding to given NAME_INDEX, + NULL if unavailable. */ +cgraph_node * +string_table::get_cgraph_node (int name_index) +{ + const char *sname = get_name (name_index); + + symtab_node *n = cgraph_node::get_for_asmname (get_identifier (sname)); + for (;n; n = n->next_sharing_asm_name) + if (cgraph_node *cn = dyn_cast <cgraph_node *> (n)) + if (cn->definition && cn->has_gimple_body_p ()) + return cn; + return NULL; +} + +/* Return corresponding cgraph node. */ + +cgraph_node * +function_instance::get_cgraph_node () +{ + return afdo_string_table->get_cgraph_node (name ()); +} + /* Member functions for function_instance. */ function_instance::~function_instance () { + gcc_assert (!in_worklist_p ()); for (callsite_map::iterator iter = callsites.begin (); iter != callsites.end (); ++iter) delete iter->second; @@ -537,7 +927,8 @@ function_instance::~function_instance () function_instance * function_instance::get_function_instance_by_decl (unsigned lineno, - tree decl) const + tree decl, + location_t location) const { int func_name_idx = afdo_string_table->get_index_by_decl (decl); if (func_name_idx != -1) @@ -547,91 +938,1364 @@ function_instance::get_function_instance_by_decl (unsigned lineno, if (ret != callsites.end ()) return ret->second; } - func_name_idx - = afdo_string_table->get_index (lang_hooks.dwarf_name (decl, 0)); - if (func_name_idx != -1) + if (DECL_FROM_INLINE (decl)) { - callsite_map::const_iterator ret - = callsites.find (std::make_pair (lineno, func_name_idx)); - if (ret != callsites.end ()) - return ret->second; + function_instance + *ret = get_function_instance_by_decl (lineno, + DECL_ABSTRACT_ORIGIN (decl), + location); + return ret; + } + if (dump_enabled_p ()) + { + for (auto const &iter : callsites) + if (iter.first.first == lineno) + dump_printf_loc (MSG_NOTE | MSG_PRIORITY_INTERNALS, + dump_user_location_t::from_location_t (location), + "auto-profile has mismatched function name %s" + " insteed of %s at loc %i:%i", + afdo_string_table->get_name (iter.first.second), + raw_symbol_name (decl), + lineno >> 16, + lineno & 65535); } - if (DECL_FROM_INLINE (decl)) - return get_function_instance_by_decl (lineno, DECL_ABSTRACT_ORIGIN (decl)); return NULL; } -/* Merge profile of clones. Note that cloning hasnt been performed when +/* Merge profile of OTHER to THIS. Note that cloning hasnt been performed when we annotate the CFG (at this stage). */ -void function_instance::merge (function_instance *other) +void +function_instance::merge (function_instance *other, + vec <function_instance *> &new_functions) { + /* Do not merge to itself and only merge functions of same name. */ + gcc_checking_assert (other != this && other->name () == name ()); total_count_ += other->total_count_; - head_count_ += other->head_count_; + if (other->total_count () && total_count () && other->head_count () == -1) + head_count_ = -1; + else if (head_count_ != -1) + head_count_ += other->head_count_; + bool changed = true; + + while (changed) + { + changed = false; + /* If both function instances agree on particular inlined function, + merge profiles. Otherwise offline the instance. */ + for (callsite_map::const_iterator iter = other->callsites.begin (); + iter != other->callsites.end ();) + if (callsites.count (iter->first) == 0) + { + function_instance *f = iter->second; + if (dump_file) + { + fprintf (dump_file, " Mismatch in inlined functions;" + " offlining in merge source:"); + f->dump_inline_stack (dump_file); + fprintf (dump_file, "\n"); + } + /* We already merged outer part of the function acounting + the inlined calll; compensate. */ + for (function_instance *s = this; s; s = s->inlined_to ()) + { + s->total_count_ -= f->total_count (); + gcc_checking_assert (s->total_count_ >= 0); + } + other->callsites.erase (iter); + function_instance::offline (f, new_functions); + /* Start from begining as merging might have offlined + some functions in the case of recursive inlining. */ + iter = other->callsites.begin (); + } + else + ++iter; + for (callsite_map::const_iterator iter = callsites.begin (); + iter != callsites.end ();) + if (other->callsites.count (iter->first) == 0) + { + function_instance *f = iter->second; + if (dump_file) + { + fprintf (dump_file, " Mismatch in inlined functions;" + " offlining in merge destination:"); + f->dump_inline_stack (dump_file); + fprintf (dump_file, "\n"); + } + callsites.erase (iter); + function_instance::offline (f, new_functions); + iter = callsites.begin (); + changed = true; + } + else + ++iter; + } for (callsite_map::const_iterator iter = other->callsites.begin (); iter != other->callsites.end (); ++iter) - if (callsites.count (iter->first) == 0) - callsites[iter->first] = iter->second; + { + if (dump_file) + { + fprintf (dump_file, " Merging profile for inlined function\n" + " from: "); + iter->second->dump_inline_stack (dump_file); + fprintf (dump_file, " total:%" PRIu64 "\n to : ", + (int64_t)iter->second->total_count ()); + callsites[iter->first]->dump_inline_stack (dump_file); + fprintf (dump_file, " total:%" PRIu64 "\n", + (int64_t)callsites[iter->first]->total_count ()); + } - for (position_count_map::const_iterator iter = pos_counts.begin (); - iter != pos_counts.end (); ++iter) + callsites[iter->first]->merge (iter->second, new_functions); + } + + for (position_count_map::const_iterator iter = other->pos_counts.begin (); + iter != other->pos_counts.end (); ++iter) if (pos_counts.count (iter->first) == 0) pos_counts[iter->first] = iter->second; else - pos_counts[iter->first].count += iter->second.count; + { + pos_counts[iter->first].count += iter->second.count; + for (icall_target_map::const_iterator titer + = iter->second.targets.begin (); + titer != iter->second.targets.end (); ++titer) + if (pos_counts[iter->first].targets.count (titer->first) == 0) + pos_counts[iter->first].targets[titer->first] + = titer->second; + else + pos_counts[iter->first].targets[titer->first] + += titer->second; + } } -/* Store the profile info for LOC in INFO. Return TRUE if profile info - is found. */ +/* Make inline function FN offline. + If tolevel function of same name already exists, then merge profiles. + Otherwise turn FN toplevel. Return true if new toplevel function + was introduced. + If new toplevel functions are created and NEW_FUNCTIONS != NULL, + add them to NEW_FUNCTIONS. + + TODO: When offlining indirect call we lose information about the + call target. It should be possible to add it into + targets histogram. */ bool -function_instance::get_count_info (location_t loc, count_info *info) const +function_instance::offline (function_instance *fn, + vec <function_instance *> &new_functions) { - position_count_map::const_iterator iter = pos_counts.find (loc); - if (iter == pos_counts.end ()) - return false; - *info = iter->second; + gcc_checking_assert (fn->inlined_to ()); + for (function_instance *s = fn->inlined_to (); s; s = s->inlined_to ()) + { + s->total_count_ -= fn->total_count (); + gcc_checking_assert (s->total_count_ >= 0); + } + function_instance *to + = afdo_source_profile->get_function_instance_by_name_index (fn->name ()); + fn->set_inlined_to (NULL); + /* If there is offline function of same name, we need to merge profile. + Delay this by adding function to a worklist so we do not run into + problem with recursive inlining. */ + if (to) + { + if (fn->in_worklist_p ()) + return false; + fn->set_in_worklist (); + new_functions.safe_push (fn); + if (dump_file) + { + fprintf (dump_file, " Recoding duplicate: "); + to->dump_inline_stack (dump_file); + fprintf (dump_file, "\n"); + } + return true; + } + if (dump_file) + { + fprintf (dump_file, " Added as offline instance: "); + fn->dump_inline_stack (dump_file); + fprintf (dump_file, "\n"); + } + if (fn->total_count ()) + fn->head_count_ = -1; + afdo_source_profile->add_function_instance (fn); + fn->set_in_worklist (); + new_functions.safe_push (fn); return true; } -/* Read the inlined indirect call target profile for STMT and store it in - MAP, return the total count for all inlined indirect calls. */ +/* Offline all inlined functions with name in SEEN. + If new toplevel functions are created, add them to NEW_FUNCTIONS. */ -gcov_type -function_instance::find_icall_target_map (gcall *stmt, - icall_target_map *map) const +void +function_instance::offline_if_in_set (name_index_set &seen, + vec <function_instance *> &new_functions) { - gcov_type ret = 0; - unsigned stmt_offset = get_relative_location_for_stmt (stmt); - for (callsite_map::const_iterator iter = callsites.begin (); - iter != callsites.end (); ++iter) + iter != callsites.end ();) + if (seen.contains (iter->first.second)) + { + function_instance *f = iter->second; + if (dump_file) + { + fprintf (dump_file, "Offlining function inlined to other module: "); + f->dump_inline_stack (dump_file); + fprintf (dump_file, "\n"); + } + iter = callsites.erase (iter); + function_instance::offline (f, new_functions); + /* Start from begining as merging might have offlined + some functions in the case of recursive inlining. */ + iter = callsites.begin (); + } + else + { + iter->second->offline_if_in_set (seen, new_functions); + ++iter; + } +} + +/* Try to check if inlined_fn can correspond to a call of function N. + Return non-zero if it correspons and 2 if renaming was done. */ + +static int +match_with_target (cgraph_node *n, + gimple *stmt, + function_instance *inlined_fn, + cgraph_node *orig_callee) +{ + cgraph_node *callee = orig_callee->ultimate_alias_target (); + const char *symbol_name = raw_symbol_name (callee->decl); + const char *name = afdo_string_table->get_name (inlined_fn->name ()); + if (strcmp (name, symbol_name)) { - unsigned callee = iter->second->name (); - /* Check if callsite location match the stmt. */ - if (iter->first.first != stmt_offset) - continue; - struct cgraph_node *node = cgraph_node::get_for_asmname ( - get_identifier (afdo_string_table->get_name (callee))); - if (node == NULL) - continue; - (*map)[callee] = iter->second->total_count (); - ret += iter->second->total_count (); + int i; + bool in_suffix = false; + for (i = 0; i; i++) + { + if (name[i] != symbol_name[i]) + break; + if (name[i] == '.') + in_suffix = true; + } + /* Accept dwarf names and stripped suffixes. */ + if (!strcmp (lang_hooks.dwarf_name (callee->decl, 0), + afdo_string_table->get_name (inlined_fn->name ())) + || (!name[i] && symbol_name[i] == '.') + || in_suffix) + { + int index = afdo_string_table->get_index (symbol_name); + if (index == -1) + index = afdo_string_table->add_name (xstrdup (symbol_name)); + if (dump_file) + fprintf (dump_file, + " Renaming inlined call target %s to %s\n", + name, symbol_name); + inlined_fn->set_name (index); + return 2; + } + /* Only warn about declarations. It is possible that the function + is declared as alias in other module and we inlined cross-module. */ + if (callee->definition + && warning (OPT_Wauto_profile, + "auto-profile of %q+F contains inlined " + "function with symbol name %s instead of symbol name %s", + n->decl, name, symbol_name)) + inform (gimple_location (stmt), "corresponding call"); + return 0; } - return ret; + return 1; } -/* Read the profile and create a function_instance with head count as - HEAD_COUNT. Recursively read callsites to create nested function_instances - too. STACK is used to track the recursive creation process. */ +static void +dump_stmt (gimple *stmt, count_info *info, function_instance *inlined_fn, + inline_stack &stack) +{ + if (dump_file) + { + fprintf (dump_file, " "); + if (!stack.length ()) + fprintf (dump_file, " "); + else + { + gcc_checking_assert (stack.length () == 1); + fprintf (dump_file, "%5i", stack[0].afdo_loc >> 16); + if (stack[0].afdo_loc & 65535) + fprintf (dump_file, ".%-5i", stack[0].afdo_loc & 65535); + else + fprintf (dump_file, " "); + if (info) + fprintf (dump_file, "%9" PRIu64 " ", (int64_t)info->count); + else if (inlined_fn) + fprintf (dump_file, " inlined "); + else + fprintf (dump_file, " no info "); + } + print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + } +} -/* function instance profile format: +/* Lookup count and warn about duplicates. */ +count_info * +function_instance::lookup_count (location_t loc, inline_stack &stack, + cgraph_node *node) +{ + gcc_checking_assert (stack.length () < 2); + if (stack.length ()) + { + int c = pos_counts.count (stack[0].afdo_loc); + if (c > 1 + && warning (OPT_Wauto_profile, + "duplicated count information" + " in auto-profile of %q+F" + " with relative location %i discriminator %i", + node->decl, stack[0].afdo_loc >> 16, + stack[0].afdo_loc & 65535)) + inform (loc, "corresponding source location"); + if (c) + return &pos_counts[stack[0].afdo_loc]; + } + return NULL; +} - ENTRY_COUNT: 8 bytes - NAME_INDEX: 4 bytes - NUM_POS_COUNTS: 4 bytes +/* Mark expr locations as used. */ +void +mark_expr_locations (function_instance *f, tree t, cgraph_node *node, + hash_set<const count_info *> &counts) +{ + inline_stack stack; + return; + if (!t) + return; + do + { + get_inline_stack_in_node (EXPR_LOCATION (t), &stack, node); + /* FIXME: EXPR_LOCATION does not always originate from current + function. */ + if (stack.length () > 1) + break; + count_info *info = f->lookup_count (EXPR_LOCATION (t), stack, node); + if (info) + counts.add (info); + if (handled_component_p (t)) + t = TREE_OPERAND (t, 0); + else + break; + } + while (true); +} + +/* Match function instance with gimple body. + Report mismatches, attempt to fix them if possible and remove data we will + not use. + + Set location and call_location so we can output diagnostics and know what + functions was already matched. */ + +bool +function_instance::match (cgraph_node *node, + vec <function_instance *> &new_functions, + name_index_map &to_symbol_name) +{ + if (get_location () != UNKNOWN_LOCATION) + return false; + set_location (DECL_SOURCE_LOCATION (node->decl)); + if (dump_file) + { + fprintf (dump_file, + "\nMatching gimple function %s with auto profile: ", + node->dump_name ()); + dump_inline_stack (dump_file); + fprintf (dump_file, "\n"); + } + basic_block bb; + /* Sets used to track if entires in auto-profile are useful. */ + hash_set<const count_info *> counts; + hash_set<const count_info *> targets; + hash_set<const function_instance *> functions; + hash_set<const function_instance *> functions_to_offline; + + /* We try to fill in lost disciminator if there is unique call + with given line number. This map is used to record them. */ + hash_map<int_hash <int, -1, -2>,auto_vec <gcall *>> lineno_to_call; + bool lineno_to_call_computed = false; + + for (tree arg = DECL_ARGUMENTS (node->decl); arg; arg = DECL_CHAIN (arg)) + { + inline_stack stack; + + get_inline_stack_in_node (DECL_SOURCE_LOCATION (arg), &stack, node); + count_info *info = lookup_count (DECL_SOURCE_LOCATION (arg), stack, node); + if (stack.length () && dump_file) + { + gcc_checking_assert (stack.length () == 1); + fprintf (dump_file, "%5i", stack[0].afdo_loc >> 16); + if (stack[0].afdo_loc & 65535) + fprintf (dump_file, " .%-5i arg", stack[0].afdo_loc & 65535); + else + fprintf (dump_file, " arg "); + print_generic_expr (dump_file, arg); + fprintf (dump_file, "\n"); + } + if (info) + counts.add (info); + } + FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl)) + { + if (dump_file) + fprintf (dump_file, " basic block %i\n", bb->index); + for (gphi_iterator gpi = gsi_start_phis (bb); + !gsi_end_p (gpi); + gsi_next (&gpi)) + { + gphi *phi = gpi.phi (); + inline_stack stack; + + get_inline_stack_in_node (gimple_location (phi), &stack, node); + count_info *info = lookup_count (gimple_location (phi), stack, node); + if (info) + counts.add (info); + dump_stmt (phi, info, NULL, stack); + counts.add (info); + for (edge e : bb->succs) + { + location_t phi_loc + = gimple_phi_arg_location_from_edge (phi, e); + inline_stack stack; + get_inline_stack_in_node (phi_loc, &stack, node); + count_info *info = lookup_count (phi_loc, stack, node); + if (info) + counts.add (info); + gcc_checking_assert (stack.length () < 2); + mark_expr_locations (this, + gimple_phi_arg_def_from_edge (phi, e), + node, counts); + } + } + /* TODO: goto locuses are not used for BB annotation. */ + for (edge e : bb->succs) + { + inline_stack stack; + get_inline_stack_in_node (e->goto_locus, &stack, node); + count_info *info = lookup_count (e->goto_locus, stack, node); + if (info) + counts.add (info); + } + for (gimple_stmt_iterator gsi = gsi_start_bb (bb); + !gsi_end_p (gsi); gsi_next (&gsi)) + { + inline_stack stack; + gimple *stmt = gsi_stmt (gsi); + get_inline_stack_in_node (gimple_location (stmt), &stack, node); + + count_info *info = lookup_count (gimple_location (stmt), stack, node); + if (info) + counts.add (info); + for (unsigned int op = 0; op < gimple_num_ops (stmt); op++) + mark_expr_locations (this, gimple_op (stmt, op), node, counts); + if (gimple_code (stmt) == GIMPLE_CALL) + { + function_instance *inlined_fn = NULL; + function_instance *inlined_fn_nodisc = NULL; + /* Lookup callsite. */ + if (stack.length ()) + { + int c = 0; + int cnodis = 0; + for (auto const &iter : callsites) + if (iter.first.first == stack[0].afdo_loc) + { + if (!c) + inlined_fn = iter.second; + c++; + } + /* Discriminators are sometimes lost; try to find the + call without discriminator info. */ + else if (iter.first.first == (stack[0].afdo_loc & ~65535)) + { + if (!cnodis) + inlined_fn_nodisc = iter.second; + cnodis++; + } + if ((c > 1 || (!c && cnodis > 1)) + && warning (OPT_Wauto_profile, + "duplicated callsite in auto-profile of %q+F" + " with relative location %i," + " discriminator %i", + node->decl, stack[0].afdo_loc >> 16, + stack[0].afdo_loc & 65535)) + inform (gimple_location (stmt), "corresponding call"); + if (inlined_fn && info && info->targets.size () + && warning (OPT_Wauto_profile, + "both call targets and inline callsite" + " information is present in auto-profile" + " of function %q+F with relative location" + " %i, discriminator %i", + node->decl, stack[0].afdo_loc >> 16, + stack[0].afdo_loc & 65535)) + inform (gimple_location (stmt), "corresponding call"); + tree callee = gimple_call_fndecl (stmt); + cgraph_node *callee_node; + unsigned int loc = stack[0].afdo_loc; + bool lost_discriminator = false; + if (!inlined_fn && inlined_fn_nodisc) + { + if (!lineno_to_call_computed) + { + basic_block bb2; + FOR_EACH_BB_FN (bb2, + DECL_STRUCT_FUNCTION (node->decl)) + for (gimple_stmt_iterator gsi2 + = gsi_start_bb (bb2); + !gsi_end_p (gsi2); gsi_next (&gsi2)) + if (gcall *call + = dyn_cast <gcall *> (gsi_stmt (gsi2))) + { + inline_stack stack2; + get_inline_stack_in_node + (gimple_location (call), + &stack2, node); + if (stack2.length ()) + lineno_to_call.get_or_insert + (stack2[0].afdo_loc >> 16).safe_push (call); + } + lineno_to_call_computed = true; + } + /* If we can determine lost discriminator uniquely, + use it. */ + if (lineno_to_call.get + (stack[0].afdo_loc >> 16)->length () == 1) + { + if (warning (OPT_Wauto_profile, + "auto-profile of %q+F seem to contain" + " lost discriminator %i for" + " call of %s at relative location %i", + node->decl, + loc & 65535, + afdo_string_table->get_name + (inlined_fn_nodisc->name ()), + loc >> 16)) + inform (gimple_location (stmt), + "corresponding call"); + inlined_fn = inlined_fn_nodisc; + if (dump_file) + fprintf (dump_file, " Lost discriminator %i\n", + loc & 65535); + loc = loc & ~65535; + } + lost_discriminator = true; + } + if (callee && (callee_node = cgraph_node::get (callee))) + { + if (inlined_fn) + { + int old_name = inlined_fn->name (); + int r = match_with_target (node, stmt, inlined_fn, + callee_node); + if (r == 2) + { + auto iter = callsites.find ({loc, old_name}); + gcc_checking_assert (old_name + != inlined_fn->name () + && iter != callsites.end () + && iter->second + == inlined_fn); + callsite key2 = {stack[0].afdo_loc, + inlined_fn->name ()}; + callsites.erase (iter); + callsites[key2] = inlined_fn; + } + if (r) + functions.add (inlined_fn); + else + functions_to_offline.add (inlined_fn); + } + + if (info && info->targets.size () > 1) + warning_at (gimple_location (stmt), OPT_Wauto_profile, + "auto-profile of %q+F contains multiple" + " targets for a direct call with relative" + " location %i, discriminator %i", + node->decl, stack[0].afdo_loc >> 16, + stack[0].afdo_loc & 65535); + /* We do not need target profile for direct calls. */ + if (info) + info->targets.clear (); + } + else + { + if (inlined_fn + && inlined_fn->get_call_location () + != UNKNOWN_LOCATION) + { + if (warning (OPT_Wauto_profile, + "function contains two calls of the same" + " relative location +%i," + " discrimnator %i," + " that leads to lost auto-profile", + loc >> 16, + loc & 65535)) + { + inform (gimple_location (stmt), + "location of the first call"); + inform (inlined_fn->get_call_location (), + "location of the second call"); + } + if (dump_file) + fprintf (dump_file, + " Duplicated call location\n"); + inlined_fn = NULL; + } + if (inlined_fn) + { + inlined_fn->set_call_location + (gimple_location (stmt)); + /* Do renaming if needed so we can look up + cgraph node and recurse into inlined function. */ + int *newn = to_symbol_name.get (inlined_fn->name ()); + gcc_checking_assert + (!newn || *newn != inlined_fn->name ()); + if (newn || lost_discriminator) + { + auto iter = callsites.find + ({loc, inlined_fn->name ()}); + gcc_checking_assert (iter != callsites.end () + && iter->second + == inlined_fn); + callsite key2 = {stack[0].afdo_loc, + newn ? *newn + : inlined_fn->name ()}; + callsites.erase (iter); + callsites[key2] = inlined_fn; + inlined_fn->set_name (newn ? *newn + : inlined_fn->name ()); + } + functions.add (inlined_fn); + } + if (info) + targets.add (info); + } + } + dump_stmt (stmt, info, inlined_fn, stack); + } + else + dump_stmt (stmt, info, NULL, stack); + } + } + bool warned = false; + for (auto &iter : pos_counts) + if (iter.second.targets.size () + && counts.contains (&iter.second) + && !targets.contains (&iter.second)) + { + if (!warned) + warned = warning_at + (DECL_SOURCE_LOCATION (node->decl), + OPT_Wauto_profile, + "auto-profile of %q+F contains indirect call targets" + " not associated with an indirect call statement", + node->decl); + if (warned) + inform (DECL_SOURCE_LOCATION (node->decl), + "count %" PRIu64 + " with relative location +%i, discriminator %i", + iter.second.count, iter.first >> 16, iter.first & 65535); + if (dump_file) + { + fprintf (dump_file, "Removing targets of "); + dump_afdo_loc (dump_file, iter.first); + fprintf (dump_file, "\n"); + } + iter.second.targets.clear (); + } + warned = false; + /* Profile sometimes contains extra location for start or end of function + (prologue, epilogue). + TODO: If present, perhaps it can be used to determine entry block + and exit block counts. */ + unsigned int end_location = get_combined_location + (DECL_STRUCT_FUNCTION (node->decl)->function_end_locus, node->decl); + unsigned int start_location = get_combined_location + (DECL_STRUCT_FUNCTION (node->decl)->function_start_locus, node->decl); + /* When outputting code to builtins location we use line number 0. + craeate_gcov is stupid and hapilly computes offsets across files. + Silently ignore it. */ + unsigned int zero_location + = ((unsigned)(1-DECL_SOURCE_LINE (node->decl))) << 16; + for (position_count_map::const_iterator iter = pos_counts.begin (); + iter != pos_counts.end ();) + if (!counts.contains (&iter->second)) + { + if (iter->first != end_location + && iter->first != start_location + && (iter->first & 65535) != zero_location + && iter->first) + { + if (!warned) + warned = warning_at (DECL_SOURCE_LOCATION (node->decl), + OPT_Wauto_profile, + "auto-profile of %q+F contains extra statements", + node->decl); + if (warned) + inform (DECL_SOURCE_LOCATION (node->decl), + "count %" PRIu64 " with relative location +%i," + " discriminator %i", + iter->second.count, iter->first >> 16, + iter->first & 65535); + if ((iter->first >> 16) > (end_location >> 16) && warned) + inform (DECL_SOURCE_LOCATION (node->decl), + "location is after end of function"); + } + if (dump_file) + { + fprintf (dump_file, "Removing unmatched count "); + dump_afdo_loc (dump_file, iter->first); + fprintf (dump_file, ":%" PRIu64, iter->second.count); + for (auto &titer : iter->second.targets) + fprintf (dump_file, " %s:%" PRIu64, + afdo_string_table->get_name (titer.first), + (int64_t)titer.second); + fprintf (dump_file, "\n"); + } + iter = pos_counts.erase (iter); + } + else + iter++; + warned = false; + for (callsite_map::const_iterator iter = callsites.begin (); + iter != callsites.end ();) + if (!functions.contains (iter->second)) + { + function_instance *f = iter->second; + /* If we did not see the corresponding statement, warn. */ + if (!functions_to_offline.contains (iter->second)) + { + if (!warned) + warned = warning_at (DECL_SOURCE_LOCATION (node->decl), + OPT_Wauto_profile, + "auto-profile of %q+F contains" + " extra callsites", + node->decl); + if (warned) + inform (DECL_SOURCE_LOCATION (node->decl), + "call of %s with total count %" PRId64 + ", relative location +%i, discriminator %i", + afdo_string_table->get_name (iter->first.second), + iter->second->total_count (), + iter->first.first >> 16, iter->first.first & 65535); + if ((iter->first.first >> 16) > (end_location >> 16) && warned) + inform (DECL_SOURCE_LOCATION (node->decl), + "location is after end of function"); + if (dump_file) + { + fprintf (dump_file, + "Offlining inline with no corresponding gimple stmt "); + f->dump_inline_stack (dump_file); + fprintf (dump_file, "\n"); + } + } + else if (dump_file) + { + fprintf (dump_file, + "Offlining mismatched inline "); + f->dump_inline_stack (dump_file); + fprintf (dump_file, "\n"); + } + callsites.erase (iter); + offline (f, new_functions); + iter = callsites.begin (); + } + else + iter++; + for (auto &iter : callsites) + if (cgraph_node *n = iter.second->get_cgraph_node ()) + iter.second->match (n, new_functions, to_symbol_name); + return true; +} + +/* Walk inlined functions and if their name is not in SEEN + remove it. Also rename function names as given by + to_symbol_name map. */ + +void +function_instance::remove_external_functions + (name_index_set &seen, + name_index_map &to_symbol_name, + vec <function_instance *> &new_functions) +{ + auto_vec <callsite, 20> to_rename; + + for (callsite_map::const_iterator iter = callsites.begin (); + iter != callsites.end ();) + if (!seen.contains (iter->first.second)) + { + function_instance *f = iter->second; + if (dump_file) + { + fprintf (dump_file, " Removing external inline: "); + f->dump_inline_stack (dump_file); + fprintf (dump_file, "\n"); + } + iter = callsites.erase (iter); + f->set_inlined_to (NULL); + f->offline_if_in_set (seen, new_functions); + delete f; + } + else + { + gcc_checking_assert ((int)iter->first.second + == iter->second->name ()); + int *newn = iter->second->get_call_location () == UNKNOWN_LOCATION + ? to_symbol_name.get (iter->first.second) + : NULL; + if (newn) + { + gcc_checking_assert (iter->second->inlined_to ()); + to_rename.safe_push (iter->first); + } + iter->second->remove_external_functions + (seen, to_symbol_name, new_functions); + ++iter; + } + for (auto &key : to_rename) + { + auto iter = callsites.find (key); + callsite key2 = key; + key2.second = *to_symbol_name.get (key.second); + iter->second->set_name (key2.second); + callsites.erase (iter); + callsites[key2] = iter->second; + } + auto_vec <int, 20> target_to_rename; + for (auto &iter : pos_counts) + { + for (auto const &titer : iter.second.targets) + { + int *ren = to_symbol_name.get (titer.first); + if (ren) + target_to_rename.safe_push (titer.first); + } + while (target_to_rename.length ()) + { + int key = target_to_rename.pop (); + int key2 = *to_symbol_name.get (key); + auto i = iter.second.targets.find (key); + if (iter.second.targets.count (key2) == 0) + iter.second.targets[key2] = i->second; + else + iter.second.targets[key2] += i->second; + iter.second.targets.erase (i); + } + } +} + +/* Look for inline instances that was not realized and + remove them while possibly merging them to offline variants. */ + +void +function_instance::offline_if_not_realized + (vec <function_instance *> &new_functions) +{ + for (callsite_map::const_iterator iter = callsites.begin (); + iter != callsites.end ();) + if (!iter->second->realized_p ()) + { + function_instance *f = iter->second; + if (dump_file) + { + fprintf (dump_file, "Offlining unrealized inline "); + f->dump_inline_stack (dump_file); + fprintf (dump_file, "\n"); + } + iter = callsites.erase (iter); + offline (f, new_functions); + } + else + { + iter->second->offline_if_not_realized (new_functions); + ++iter; + } +} + +/* Dump instance to F indented by INDENT. */ + +void +function_instance::dump (FILE *f, int indent, bool nested) const +{ + if (!nested) + fprintf (f, "%*s%s total:%" PRIu64 " head:%" PRId64 "\n", + indent, "", afdo_string_table->get_name (name ()), + (int64_t)total_count (), (int64_t)head_count ()); + else + fprintf (f, " total:%" PRIu64 "\n", (int64_t)total_count ()); + for (auto const &iter : pos_counts) + { + fprintf (f, "%*s", indent + 2, ""); + dump_afdo_loc (f, iter.first); + fprintf (f, ": %" PRIu64, (int64_t)iter.second.count); + + for (auto const &titer : iter.second.targets) + fprintf (f, " %s:%" PRIu64, + afdo_string_table->get_name (titer.first), + (int64_t)titer.second); + fprintf (f,"\n"); + } + for (auto const &iter : callsites) + { + fprintf (f, "%*s", indent + 2, ""); + dump_afdo_loc (f, iter.first.first); + fprintf (f, ": %s", afdo_string_table->get_name (iter.first.second)); + iter.second->dump (f, indent + 2, true); + gcc_checking_assert ((int)iter.first.second == iter.second->name ()); + } +} + +/* Dump inline path. */ + +void +function_instance::dump_inline_stack (FILE *f) const +{ + auto_vec <callsite, 20> stack; + const function_instance *p = this, *s = inlined_to (); + while (s) + { + bool found = false; + for (callsite_map::const_iterator iter = s->callsites.begin (); + iter != s->callsites.end (); ++iter) + if (iter->second == p) + { + gcc_checking_assert (!found + && (int)iter->first.second == p->name ()); + stack.safe_push ({iter->first.first, s->name ()}); + found = true; + } + gcc_checking_assert (found); + p = s; + s = s->inlined_to (); + } + for (callsite &s: stack) + { + fprintf (f, "%s:", afdo_string_table->get_name (s.second)); + dump_afdo_loc (f, s.first); + fprintf (f, " "); + } + fprintf (f, "%s", afdo_string_table->get_name (name ())); +} + +/* Dump instance to stderr. */ + +void +function_instance::debug () const +{ + dump (stderr); +} + +/* Return profile info for LOC in INFO. */ + +bool +function_instance::get_count_info (location_t loc, count_info *info) const +{ + position_count_map::const_iterator iter = pos_counts.find (loc); + if (iter == pos_counts.end ()) + return false; + *info = iter->second; + return true; +} + +/* Read the inlined indirect call target profile for STMT and store it in + MAP, return the total count for all inlined indirect calls. */ + +gcov_type +function_instance::find_icall_target_map (tree fn, gcall *stmt, + icall_target_map *map) const +{ + gcov_type ret = 0; + unsigned stmt_offset = get_relative_location_for_stmt (fn, stmt); + + for (callsite_map::const_iterator iter = callsites.begin (); + iter != callsites.end (); ++iter) + { + unsigned callee = iter->second->name (); + /* Check if callsite location match the stmt. */ + if (iter->first.first != stmt_offset + || iter->second->removed_icall_target ()) + continue; + struct cgraph_node *node = cgraph_node::get_for_asmname ( + get_identifier (afdo_string_table->get_name (callee))); + if (node == NULL) + continue; + (*map)[callee] = iter->second->total_count () * afdo_count_scale; + ret += iter->second->total_count () * afdo_count_scale; + } + return ret; +} + +/* Remove the inlined indirect call target profile for STMT. */ + +void +function_instance::remove_icall_target (tree fn, gcall *stmt) +{ + unsigned stmt_offset = get_relative_location_for_stmt (fn, stmt); + int n = 0; + + for (auto iter : callsites) + if (iter.first.first == stmt_offset) + { + iter.second->remove_icall_target (); + n++; + } + /* TODO: If we add support for multiple targets, we may want to + remove only those we succesfully inlined. */ + gcc_assert (n); +} + +/* Offline all functions not defined in the current unit. + We will not be able to early inline them. + Doint so early will get VPT decisions more realistic. */ + +void +autofdo_source_profile::offline_external_functions () +{ + /* First check all available definitions and mark their names as + visible. */ + cgraph_node *node; + name_index_set seen; + name_index_map to_symbol_name; + size_t last_name; + + /* Add renames erasing suffixes produced by late clones, such as + .isra, .ipcp. */ + for (size_t i = 1; i < afdo_string_table->num_entries (); i++) + { + const char *n1 = afdo_string_table->get_name (i); + char *n2 = get_original_name (n1); + if (!strcmp (n1, n2)) + { + free (n2); + /* Watch for duplicate entries. + This seems to happen in practice and may be useful to distingush + multiple static symbols of the same name, but we do not realy + have a way to differentiate them in get_name lookup. */ + int index = afdo_string_table->get_index (n1); + if (index != (int)i) + { + if (dump_file) + fprintf (dump_file, + "string table in auto-profile contains" + " duplicated name %s\n", n1); + to_symbol_name.put (i, index); + } + continue; + } + if (dump_file) + fprintf (dump_file, "Adding rename removing clone suffxes %s -> %s\n", + n1, n2); + int index = afdo_string_table->get_index (n2); + if (index != -1) + free (n2); + else + index = afdo_string_table->add_name (n2); + to_symbol_name.put (i, index); + } + last_name = afdo_string_table->num_entries (); + FOR_EACH_DEFINED_FUNCTION (node) + { + const char *name = raw_symbol_name (node->decl); + const char *dwarf_name = lang_hooks.dwarf_name (node->decl, 0); + int index = afdo_string_table->get_index (name); + + /* Inline function may be identified by its dwarf names; + rename them to symbol names. With LTO dwarf names are + lost in free_lange_data. */ + if (strcmp (name, dwarf_name)) + { + int index2 = afdo_string_table->get_index (dwarf_name); + if (index2 != -1) + { + if (index == -1) + index = afdo_string_table->add_name (xstrdup (name)); + if (dump_file) + { + fprintf (dump_file, "Adding dwarf->symbol rename %s -> %s\n", + afdo_string_table->get_name (index2), name); + if (to_symbol_name.get (index2)) + fprintf (dump_file, "Dwarf name is not unique"); + } + to_symbol_name.put (index2, index); + seen.add (index2); + } + } + if (index != -1) + { + if (dump_file) + fprintf (dump_file, "%s is defined in node %s\n", + afdo_string_table->get_name (index), + node->dump_name ()); + seen.add (index); + } + else + { + if (dump_file) + { + if (dwarf_name && strcmp (dwarf_name, name)) + fprintf (dump_file, + "Node %s not in auto profile (%s neither %s)\n", + node->dump_name (), + name, + dwarf_name); + else + fprintf (dump_file, + "Node %s (symbol %s) not in auto profile\n", + node->dump_name (), + name); + } + } + } + + for (auto iter : to_symbol_name) + { + /* In case dwarf name was duplicated and later renamed, + handle both. No more than one hop shold be needed. */ + int *newn = to_symbol_name.get (iter.second); + if (newn) + iter.second = *newn; + gcc_checking_assert (!to_symbol_name.get (iter.second)); + if (seen.contains (iter.second)) + seen.add (iter.first); + } + + /* Now process all tolevel (offline) function instances. + + If instance has no definition in this translation unit, + first offline all inlined functions which are defined here + (so we do not lose porfile due to cross-module inlining + done by link-time optimizers). + + If instance has a definition, look into all inlined functions + and remove external ones (result of cross-module inlining). + + TODO: after early-inlining we ought to offline all functions + that were not inlined. */ + vec <function_instance *>&fns = duplicate_functions_; + auto_vec <function_instance *, 20>fns2; + /* Poppulate worklist with all functions to process. Processing + may introduce new functions by offlining. */ + for (auto const &iter : map_) + { + iter.second->set_in_worklist (); + fns.safe_push (iter.second); + } + + /* There are two worklists. First all functions needs to be matched + with gimple body and only then we want to do merging, since matching + should be done on unmodified profile and merging works better if + mismatches are already resolved both in source and destination. */ + while (fns.length () || fns2.length ()) + { + /* In case renaming introduced new name, keep seen up to date. */ + for (; last_name < afdo_string_table->num_entries (); last_name++) + { + const char *name = afdo_string_table->get_name (last_name); + symtab_node *n + = afdo_string_table->get_cgraph_node (last_name); + if (dump_file) + fprintf (dump_file, "New name %s %s\n", name, + n ? "wth corresponding definition" + : "with no corresponding definition"); + if (n) + seen.add (last_name); + } + if (fns.length ()) + { + function_instance *f = fns.pop (); + if (f->get_location () == UNKNOWN_LOCATION) + { + int index = f->name (); + int *newn = to_symbol_name.get (index); + if (newn) + { + f->set_name (*newn); + if (map_.count (index) + && map_[index] == f) + map_.erase (index); + if (!map_.count (*newn)) + map_[*newn] = f; + } + if (cgraph_node *n = f->get_cgraph_node ()) + { + gcc_checking_assert (seen.contains (f->name ())); + f->match (n, fns, to_symbol_name); + } + } + fns2.safe_push (f); + } + else + { + function_instance *f = fns2.pop (); + int index = f->name (); + gcc_checking_assert (f->in_worklist_p ()); + + /* If map has different function_instance of same name, then + this is a duplicated entry which needs to be merged. */ + if (map_.count (index) && map_[index] != f) + { + if (dump_file) + { + fprintf (dump_file, "Merging duplicate instance: "); + f->dump_inline_stack (dump_file); + fprintf (dump_file, "\n"); + } + map_[index]->merge (f, fns); + gcc_checking_assert (!f->inlined_to ()); + f->clear_in_worklist (); + delete f; + } + /* If name was not seen in the symbol table, remove it. */ + else if (!seen.contains (index)) + { + f->offline_if_in_set (seen, fns); + f->clear_in_worklist (); + if (dump_file) + fprintf (dump_file, "Removing external %s\n", + afdo_string_table->get_name (f->name ())); + if (map_.count (index) && map_[index] == f) + map_.erase (f->name ()); + delete f; + } + /* If this is offline function instance seen in this + translation unit offline external inlines and possibly + rename from dwarf name. */ + else + { + f->remove_external_functions (seen, to_symbol_name, fns); + f->clear_in_worklist (); + } + } + } + if (dump_file) + for (auto const &iter : map_) + { + seen.contains (iter.second->name ()); + iter.second->dump (dump_file); + } +} + +/* Walk scope block BLOCK and mark all inlined functions as realized. */ + +static void +walk_block (tree fn, function_instance *s, tree block) +{ + if (inlined_function_outer_scope_p (block)) + { + unsigned loc = get_relative_location_for_locus + (fn, BLOCK_SUPERCONTEXT (block), + BLOCK_SOURCE_LOCATION (block)); + function_instance *ns + = s->get_function_instance_by_decl + (loc, BLOCK_ABSTRACT_ORIGIN (block), + BLOCK_SOURCE_LOCATION (block)); + if (!ns) + { + if (dump_file) + { + fprintf (dump_file, " Failed to find inlined instance:"); + s->dump_inline_stack (dump_file); + fprintf (dump_file, ":"); + dump_afdo_loc (dump_file, loc); + fprintf (dump_file, " %s\n", + raw_symbol_name (BLOCK_ABSTRACT_ORIGIN (block))); + } + return; + } + s = ns; + if (dump_file) + { + fprintf (dump_file, " Marking realized inline: "); + s->dump_inline_stack (dump_file); + fprintf (dump_file, "\n"); + } + s->set_realized (); + } + for (tree t = BLOCK_SUBBLOCKS (block); t ; t = BLOCK_CHAIN (t)) + walk_block (fn, s, t); +} + +/* Offline all inline functions that are not marked as realized. + This will merge their profile into offline versions where available. + Also remove all functions we will no longer use. */ + +void +autofdo_source_profile::offline_unrealized_inlines () +{ + auto_vec <function_instance *>fns; + /* Poppulate worklist with all functions to process. Processing + may introduce new functions by offlining. */ + for (auto const &iter : map_) + { + fns.safe_push (iter.second); + iter.second->set_in_worklist (); + } + while (fns.length ()) + { + function_instance *f = fns.pop (); + int index = f->name (); + bool in_map = map_.count (index); + if (in_map) + if (cgraph_node *n = f->get_cgraph_node ()) + { + if (dump_file) + fprintf (dump_file, "Marking realized %s\n", + afdo_string_table->get_name (index)); + f->set_realized (); + if (DECL_INITIAL (n->decl) + && DECL_INITIAL (n->decl) != error_mark_node) + walk_block (n->decl, f, DECL_INITIAL (n->decl)); + } + f->offline_if_not_realized (fns); + gcc_checking_assert ((in_map || !f->realized_p ()) + && f->in_worklist_p ()); + + /* If this is duplicated instance, merge it into one in map. */ + if (in_map && map_[index] != f) + { + if (dump_file) + { + fprintf (dump_file, "Merging duplicate instance: "); + f->dump_inline_stack (dump_file); + fprintf (dump_file, "\n"); + } + map_[index]->merge (f, fns); + f->clear_in_worklist (); + gcc_checking_assert (!f->inlined_to ()); + delete f; + } + /* If function is not in symbol table, remove it. */ + else if (!f->realized_p ()) + { + if (dump_file) + fprintf (dump_file, "Removing optimized out function %s\n", + afdo_string_table->get_name (f->name ())); + map_.erase (index); + f->clear_in_worklist (); + delete f; + } + else + f->clear_in_worklist (); + } + if (dump_file) + for (auto const &iter : map_) + iter.second->dump (dump_file); +} + +/* Read the profile and create a function_instance with head count as + HEAD_COUNT. Recursively read callsites to create nested function_instances + too. STACK is used to track the recursive creation process. */ + +/* function instance profile format: + + ENTRY_COUNT: 8 bytes + NAME_INDEX: 4 bytes + NUM_POS_COUNTS: 4 bytes NUM_CALLSITES: 4 byte POS_COUNT_1: POS_1_OFFSET: 4 bytes @@ -656,12 +2320,14 @@ function_instance::find_icall_target_map (gcall *stmt, function_instance * function_instance::read_function_instance (function_instance_stack *stack, - gcov_type head_count) + gcov_type head_count) { unsigned name = gcov_read_unsigned (); unsigned num_pos_counts = gcov_read_unsigned (); unsigned num_callsites = gcov_read_unsigned (); function_instance *s = new function_instance (name, head_count); + if (!stack->is_empty ()) + s->set_inlined_to (stack->last ()); stack->safe_push (s); for (unsigned i = 0; i < num_pos_counts; i++) @@ -670,21 +2336,24 @@ function_instance::read_function_instance (function_instance_stack *stack, unsigned num_targets = gcov_read_unsigned (); gcov_type count = gcov_read_counter (); s->pos_counts[offset].count = count; + afdo_profile_info->sum_max = std::max (afdo_profile_info->sum_max, + count); + for (unsigned j = 0; j < stack->length (); j++) (*stack)[j]->total_count_ += count; for (unsigned j = 0; j < num_targets; j++) { - /* Only indirect call target histogram is supported now. */ - gcov_read_unsigned (); - gcov_type target_idx = gcov_read_counter (); - s->pos_counts[offset].targets[target_idx] = gcov_read_counter (); + /* Only indirect call target histogram is supported now. */ + gcov_read_unsigned (); + gcov_type target_idx = gcov_read_counter (); + s->pos_counts[offset].targets[target_idx] = gcov_read_counter (); } } for (unsigned i = 0; i < num_callsites; i++) { unsigned offset = gcov_read_unsigned (); function_instance *callee_function_instance - = read_function_instance (stack, 0); + = read_function_instance (stack, -1); s->callsites[std::make_pair (offset, callee_function_instance->name ())] = callee_function_instance; } @@ -713,30 +2382,52 @@ autofdo_source_profile::get_function_instance_by_decl (tree decl) const return ret == map_.end () ? NULL : ret->second; } +/* For a given NAME_INDEX, returns the top-level function_instance. */ + +function_instance * +autofdo_source_profile::get_function_instance_by_name_index (int name_index) + const +{ + name_function_instance_map::const_iterator ret = map_.find (name_index); + return ret == map_.end () ? NULL : ret->second; +} + +/* Add function instance FN. */ + +void +autofdo_source_profile::add_function_instance (function_instance *fn) +{ + int index = fn->name (); + gcc_checking_assert (map_.count (index) == 0); + map_[index] = fn; +} + /* Find count_info for a given gimple STMT. If found, store the count_info in INFO and return true; otherwise return false. */ bool -autofdo_source_profile::get_count_info (gimple *stmt, count_info *info) const +autofdo_source_profile::get_count_info (gimple *stmt, count_info *info, + cgraph_node *node) const { - return get_count_info (gimple_location (stmt), info); + return get_count_info (gimple_location (stmt), info, node); } bool autofdo_source_profile::get_count_info (location_t gimple_loc, - count_info *info) const + count_info *info, + cgraph_node *node) const { if (LOCATION_LOCUS (gimple_loc) == cfun->function_end_locus) return false; inline_stack stack; - get_inline_stack (gimple_loc, &stack); + get_inline_stack_in_node (gimple_loc, &stack, node); if (stack.length () == 0) return false; function_instance *s = get_function_instance_by_inline_stack (stack); if (s == NULL) return false; - return s->get_count_info (stack[0].second, info); + return s->get_count_info (stack[0].afdo_loc, info); } /* Update value profile INFO for STMT from the inlined indirect callsite. @@ -744,7 +2435,8 @@ autofdo_source_profile::get_count_info (location_t gimple_loc, bool autofdo_source_profile::update_inlined_ind_target (gcall *stmt, - count_info *info) + count_info *info, + cgraph_node *node) { if (dump_file) { @@ -755,16 +2447,17 @@ autofdo_source_profile::update_inlined_ind_target (gcall *stmt, if (LOCATION_LOCUS (gimple_location (stmt)) == cfun->function_end_locus) { if (dump_file) - fprintf (dump_file, " good locus\n"); + fprintf (dump_file, " bad locus (funciton end)\n"); return false; } count_info old_info; - get_count_info (stmt, &old_info); + get_count_info (stmt, &old_info, node); gcov_type total = 0; for (icall_target_map::const_iterator iter = old_info.targets.begin (); iter != old_info.targets.end (); ++iter) total += iter->second; + total *= afdo_count_scale; /* Program behavior changed, original promoted (and inlined) target is not hot any more. Will avoid promote the original target. @@ -783,7 +2476,7 @@ autofdo_source_profile::update_inlined_ind_target (gcall *stmt, } inline_stack stack; - get_inline_stack (gimple_location (stmt), &stack); + get_inline_stack_in_node (gimple_location (stmt), &stack, node); if (stack.length () == 0) { if (dump_file) @@ -794,24 +2487,46 @@ autofdo_source_profile::update_inlined_ind_target (gcall *stmt, if (s == NULL) { if (dump_file) - fprintf (dump_file, " function not found in inline stack\n"); + { + fprintf (dump_file, " function not found in inline stack:"); + dump_inline_stack (dump_file, &stack); + } return false; } icall_target_map map; - if (s->find_icall_target_map (stmt, &map) == 0) + if (s->find_icall_target_map (node ? node->decl + : current_function_decl, + stmt, &map) == 0) { if (dump_file) - fprintf (dump_file, " no target map\n"); + { + fprintf (dump_file, " no target map for stack: "); + dump_inline_stack (dump_file, &stack); + } return false; } for (icall_target_map::const_iterator iter = map.begin (); iter != map.end (); ++iter) info->targets[iter->first] = iter->second; if (dump_file) - fprintf (dump_file, " looks good\n"); + { + fprintf (dump_file, " looks good; stack:"); + dump_inline_stack (dump_file, &stack); + } return true; } +void +autofdo_source_profile::remove_icall_target (cgraph_edge *e) +{ + autofdo::inline_stack stack; + autofdo::get_inline_stack_in_node (gimple_location (e->call_stmt), + &stack, e->caller); + autofdo::function_instance *s + = get_function_instance_by_inline_stack (stack); + s->remove_icall_target (e->caller->decl, e->call_stmt); +} + /* Find total count of the callee of EDGE. */ gcov_type @@ -819,16 +2534,39 @@ autofdo_source_profile::get_callsite_total_count ( struct cgraph_edge *edge) const { inline_stack stack; - stack.safe_push (std::make_pair (edge->callee->decl, 0)); - get_inline_stack (gimple_location (edge->call_stmt), &stack); + stack.safe_push ({edge->callee->decl, 0, UNKNOWN_LOCATION}); + + get_inline_stack_in_node (gimple_location (edge->call_stmt), &stack, + edge->caller); + if (dump_file) + { + if (!edge->caller->inlined_to) + fprintf (dump_file, "Looking up afdo profile for call %s -> %s stack:", + edge->caller->dump_name (), edge->callee->dump_name ()); + else + fprintf (dump_file, "Looking up afdo profile for call %s -> %s transitively %s stack:", + edge->caller->dump_name (), edge->callee->dump_name (), + edge->caller->inlined_to->dump_name ()); + dump_inline_stack (dump_file, &stack); + } function_instance *s = get_function_instance_by_inline_stack (stack); - if (s == NULL - ||(afdo_string_table->get_index_by_decl (edge->callee->decl) - != s->name())) - return 0; + if (s == NULL) + { + if (dump_file) + fprintf (dump_file, "No function instance found\n"); + return 0; + } + if (afdo_string_table->get_index_by_decl (edge->callee->decl) != s->name ()) + { + if (dump_file) + fprintf (dump_file, "Mismatched name of callee %s and profile %s\n", + raw_symbol_name (edge->callee->decl), + afdo_string_table->get_name (s->name ())); + return 0; + } - return s->total_count (); + return s->total_count () * afdo_count_scale; } /* Read AutoFDO profile and returns TRUE on success. */ @@ -852,6 +2590,9 @@ autofdo_source_profile::read () return false; } + gcc_checking_assert (!afdo_source_profile); + afdo_source_profile = this; + /* Skip the length of the section. */ gcov_read_unsigned (); @@ -863,15 +2604,41 @@ autofdo_source_profile::read () function_instance::function_instance_stack stack; function_instance *s = function_instance::read_function_instance ( &stack, gcov_read_counter ()); - int fun_id = afdo_string_table->get_index - (afdo_string_table->get_name (s->name ())); + int fun_id = s->name (); /* If function_instace with get_original_name (without the clone suffix) exixts, merge the function instances. */ if (map_.count (fun_id) == 0) map_[fun_id] = s; else - map_[fun_id]->merge (s); + fatal_error (UNKNOWN_LOCATION, + "auto-profile contains duplicated function instance %s", + afdo_string_table->get_name (s->name ())); } + int hot_frac = param_hot_bb_count_fraction; + /* Scale up the profile, but leave some bits in case some counts gets + bigger than sum_max eventually. */ + if (afdo_profile_info->sum_max) + afdo_count_scale + = MAX (((gcov_type)1 << (profile_count::n_bits / 2)) + / afdo_profile_info->sum_max, 1); + afdo_profile_info->cutoff *= afdo_count_scale; + afdo_hot_bb_threshod + = hot_frac + ? afdo_profile_info->sum_max * afdo_count_scale / hot_frac + : (gcov_type)profile_count::max_count; + set_hot_bb_threshold (afdo_hot_bb_threshod); + if (dump_file) + fprintf (dump_file, "Max count in profile %" PRIu64 "\n" + "Setting scale %" PRIu64 "\n" + "Scaled max count %" PRIu64 "\n" + "Cutoff %" PRIu64 "\n" + "Hot count threshold %" PRIu64 "\n\n", + (int64_t)afdo_profile_info->sum_max, + (int64_t)afdo_count_scale, + (int64_t)(afdo_profile_info->sum_max * afdo_count_scale), + (int64_t)afdo_profile_info->cutoff, + (int64_t)afdo_hot_bb_threshod); + afdo_profile_info->sum_max *= afdo_count_scale; return true; } @@ -883,16 +2650,38 @@ autofdo_source_profile::get_function_instance_by_inline_stack ( const inline_stack &stack) const { name_function_instance_map::const_iterator iter = map_.find ( - afdo_string_table->get_index_by_decl (stack[stack.length () - 1].first)); - if (iter == map_.end()) - return NULL; + afdo_string_table->get_index_by_decl (stack[stack.length () - 1].decl)); + if (iter == map_.end ()) + { + if (dump_file) + fprintf (dump_file, "No offline instance for %s\n", + raw_symbol_name (stack[stack.length () - 1].decl)); + return NULL; + } function_instance *s = iter->second; - for (unsigned i = stack.length() - 1; i > 0; i--) + for (unsigned i = stack.length () - 1; i > 0; i--) { - s = s->get_function_instance_by_decl ( - stack[i].second, stack[i - 1].first); + s = s->get_function_instance_by_decl (stack[i].afdo_loc, + stack[i - 1].decl, + stack[i].location); if (s == NULL) - return NULL; + { + /* afdo inliner extends the stack by last entry with unknown + location while chekcing if function was inlined during train run. + We do not want to print diagnostics about every function + which is not inlined. */ + if (s && dump_enabled_p () && stack[i].location != UNKNOWN_LOCATION) + dump_printf_loc (MSG_NOTE | MSG_PRIORITY_INTERNALS, + dump_user_location_t::from_location_t + (stack[i].location), + "auto-profile has no inlined function instance " + "for inlined call of %s at relative " + " locaction +%i, discriminator %i\n", + raw_symbol_name (stack[i - 1].decl), + stack[i].afdo_loc >> 16, + stack[i].afdo_loc & 65535); + return NULL; + } } return s; } @@ -944,7 +2733,7 @@ read_profile (void) /* string_table. */ afdo_string_table = new string_table (); - if (!afdo_string_table->read()) + if (!afdo_string_table->read ()) { error ("cannot read string table from %s", auto_profile_file); return; @@ -971,19 +2760,35 @@ read_profile (void) decide if it needs to promote and inline. */ static bool -afdo_indirect_call (gimple_stmt_iterator *gsi, const icall_target_map &map, - bool transform) +afdo_indirect_call (gcall *stmt, const icall_target_map &map, + bool transform, cgraph_edge *indirect_edge) { - gimple *gs = gsi_stmt (*gsi); tree callee; if (map.size () == 0) - return false; - gcall *stmt = dyn_cast <gcall *> (gs); - if (!stmt - || gimple_call_internal_p (stmt) - || gimple_call_fndecl (stmt) != NULL_TREE) - return false; + { + if (dump_file) + fprintf (dump_file, "No targets found\n"); + return false; + } + if (!stmt) + { + if (dump_file) + fprintf (dump_file, "No call statement\n"); + return false; + } + if (gimple_call_internal_p (stmt)) + { + if (dump_file) + fprintf (dump_file, "Internal call\n"); + return false; + } + if (gimple_call_fndecl (stmt) != NULL_TREE) + { + if (dump_file) + fprintf (dump_file, "Call is already direct\n"); + return false; + } gcov_type total = 0; icall_target_map::const_iterator max_iter = map.end (); @@ -995,40 +2800,50 @@ afdo_indirect_call (gimple_stmt_iterator *gsi, const icall_target_map &map, if (max_iter == map.end () || max_iter->second < iter->second) max_iter = iter; } + total *= afdo_count_scale; struct cgraph_node *direct_call = cgraph_node::get_for_asmname ( get_identifier (afdo_string_table->get_name (max_iter->first))); - if (direct_call == NULL || !direct_call->profile_id) - return false; + if (direct_call == NULL) + { + if (dump_file) + fprintf (dump_file, "Failed to find cgraph node for %s\n", + afdo_string_table->get_name (max_iter->first)); + return false; + } callee = gimple_call_fn (stmt); - histogram_value hist = gimple_alloc_histogram_value ( - cfun, HIST_TYPE_INDIR_CALL, stmt, callee); - hist->n_counters = 4; - hist->hvalue.counters = XNEWVEC (gcov_type, hist->n_counters); - gimple_add_histogram_value (cfun, stmt, hist); - - /* Total counter */ - hist->hvalue.counters[0] = total; - /* Number of value/counter pairs */ - hist->hvalue.counters[1] = 1; - /* Value */ - hist->hvalue.counters[2] = direct_call->profile_id; - /* Counter */ - hist->hvalue.counters[3] = max_iter->second; - if (!transform) - return false; - - cgraph_node* current_function_node = cgraph_node::get (current_function_decl); - - /* If the direct call is a recursive call, don't promote it since - we are not set up to inline recursive calls at this stage. */ - if (direct_call == current_function_node) - return false; - - struct cgraph_edge *indirect_edge - = current_function_node->get_edge (stmt); + { + if (!direct_call->profile_id) + { + if (dump_file) + fprintf (dump_file, "No profile id\n"); + return false; + } + histogram_value hist = gimple_alloc_histogram_value ( + cfun, HIST_TYPE_INDIR_CALL, stmt, callee); + hist->n_counters = 4; + hist->hvalue.counters = XNEWVEC (gcov_type, hist->n_counters); + gimple_add_histogram_value (cfun, stmt, hist); + + /* Total counter */ + hist->hvalue.counters[0] = total; + /* Number of value/counter pairs */ + hist->hvalue.counters[1] = 1; + /* Value */ + hist->hvalue.counters[2] = direct_call->profile_id; + /* Counter */ + hist->hvalue.counters[3] = max_iter->second * afdo_count_scale; + + if (!direct_call->profile_id) + { + if (dump_file) + fprintf (dump_file, "Histogram attached\n"); + return false; + } + return false; + } if (dump_file) { @@ -1038,16 +2853,10 @@ afdo_indirect_call (gimple_stmt_iterator *gsi, const icall_target_map &map, print_generic_expr (dump_file, direct_call->decl, TDF_SLIM); } - if (direct_call == NULL) - { - if (dump_file) - fprintf (dump_file, " not transforming\n"); - return false; - } - if (DECL_STRUCT_FUNCTION (direct_call->decl) == NULL) + if (!direct_call->definition) { if (dump_file) - fprintf (dump_file, " no declaration\n"); + fprintf (dump_file, " no definition available\n"); return false; } @@ -1058,13 +2867,9 @@ afdo_indirect_call (gimple_stmt_iterator *gsi, const icall_target_map &map, fprintf (dump_file, "\n"); } - /* FIXME: Count should be initialized. */ - struct cgraph_edge *new_edge - = indirect_edge->make_speculative (direct_call, - profile_count::uninitialized ()); - cgraph_edge::redirect_call_stmt_to_callee (new_edge); - gimple_remove_histogram_value (cfun, stmt, hist); - inline_call (new_edge, true, NULL, NULL, false); + indirect_edge->make_speculative + (direct_call, + gimple_bb (stmt)->count.apply_scale (99, 100)); return true; } @@ -1072,29 +2877,38 @@ afdo_indirect_call (gimple_stmt_iterator *gsi, const icall_target_map &map, histograms and adds them to list VALUES. */ static bool -afdo_vpt (gimple_stmt_iterator *gsi, const icall_target_map &map, - bool transform) +afdo_vpt (gcall *gs, const icall_target_map &map, + bool transform, cgraph_edge *indirect_edge) { - return afdo_indirect_call (gsi, map, transform); + return afdo_indirect_call (gs, map, transform, indirect_edge); } typedef std::set<basic_block> bb_set; -typedef std::set<edge> edge_set; static bool is_bb_annotated (const basic_block bb, const bb_set &annotated) { - return annotated.find (bb) != annotated.end (); + if (annotated.find (bb) != annotated.end ()) + { + gcc_checking_assert (bb->count.quality () == AFDO + || !bb->count.nonzero_p ()); + return true; + } + gcc_checking_assert (bb->count.quality () != AFDO + || !bb->count.nonzero_p ()); + return false; } static void set_bb_annotated (basic_block bb, bb_set *annotated) { + gcc_checking_assert (bb->count.quality () == AFDO + || !bb->count.nonzero_p ()); annotated->insert (bb); } -/* Update profile_count by known autofdo count. */ -void +/* Update COUNT by known autofdo count C. */ +static void update_count_by_afdo_count (profile_count *count, gcov_type c) { if (c) @@ -1102,16 +2916,30 @@ update_count_by_afdo_count (profile_count *count, gcov_type c) /* In case we have guessed profile which is already zero, preserve quality info. */ else if (count->nonzero_p () - || count->quality () == GUESSED) + || count->quality () == GUESSED + || count->quality () == GUESSED_LOCAL) *count = profile_count::zero ().afdo (); } +/* Update COUNT by known autofdo count C. */ +static void +update_count_by_afdo_count (profile_count *count, profile_count c) +{ + if (c.nonzero_p ()) + *count = c; + /* In case we have guessed profile which is already zero, preserve + quality info. */ + else if (count->nonzero_p () + || count->quality () < c.quality ()) + *count = c; +} + /* For a given BB, set its execution count. Attach value profile if a stmt is not in PROMOTED, because we only want to promote an indirect call once. Return TRUE if BB is annotated. */ static bool -afdo_set_bb_count (basic_block bb, const stmt_set &promoted) +afdo_set_bb_count (basic_block bb, hash_set <basic_block> &zero_bbs) { gimple_stmt_iterator gsi; gcov_type max_count = 0; @@ -1123,23 +2951,27 @@ afdo_set_bb_count (basic_block bb, const stmt_set &promoted) { count_info info; gimple *stmt = gsi_stmt (gsi); - if (gimple_clobber_p (stmt) || is_gimple_debug (stmt)) - continue; + if (gimple_clobber_p (stmt)) + continue; if (afdo_source_profile->get_count_info (stmt, &info)) - { - if (info.count > max_count) - max_count = info.count; - if (dump_file && info.count) + { + if (info.count > max_count) + max_count = info.count; + if (dump_file) { fprintf (dump_file, " count %" PRIu64 " in stmt: ", (int64_t)info.count); print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); } - has_annotated = true; - if (info.targets.size () > 0 - && promoted.find (stmt) == promoted.end ()) - afdo_vpt (&gsi, info.targets, false); - } + has_annotated = true; + gcall *call = dyn_cast <gcall *> (gsi_stmt (gsi)); + /* TODO; if inlined early and indirect call was not optimized out, + we will end up speculating again. Early inliner should remove + all targets for edges it speculated into safely. */ + if (call + && info.targets.size () > 0) + afdo_vpt (call, info.targets, false, NULL); + } } if (!has_annotated) @@ -1183,13 +3015,23 @@ afdo_set_bb_count (basic_block bb, const stmt_set &promoted) if (max_count) { - update_count_by_afdo_count (&bb->count, max_count); + update_count_by_afdo_count (&bb->count, max_count * afdo_count_scale); if (dump_file) fprintf (dump_file, - " Annotated bb %i with count %" PRId64 "\n", - bb->index, (int64_t)max_count); + " Annotated bb %i with count %" PRId64 + ", scaled to %" PRId64 "\n", + bb->index, (int64_t)max_count, + (int64_t)(max_count * afdo_count_scale)); + return true; } - return true; + else + { + if (dump_file) + fprintf (dump_file, + " bb %i has statements with 0 count\n", bb->index); + zero_bbs.add (bb); + } + return false; } /* BB1 and BB2 are in an equivalent class iff: @@ -1207,7 +3049,7 @@ afdo_find_equiv_class (bb_set *annotated_bb) basic_block bb; FOR_ALL_BB_FN (bb, cfun) - bb->aux = NULL; + bb->aux = NULL; FOR_ALL_BB_FN (bb, cfun) { @@ -1219,7 +3061,9 @@ afdo_find_equiv_class (bb_set *annotated_bb) && bb1->loop_father == bb->loop_father) { bb1->aux = bb; - if (bb1->count > bb->count && is_bb_annotated (bb1, *annotated_bb)) + if (is_bb_annotated (bb1, *annotated_bb) + && (!is_bb_annotated (bb, *annotated_bb) + || bb1->count > bb->count)) { if (dump_file) { @@ -1228,8 +3072,9 @@ afdo_find_equiv_class (bb_set *annotated_bb) bb1->index, bb->index); bb1->count.dump (dump_file); + fprintf (dump_file, "\n"); } - bb->count = bb1->count; + update_count_by_afdo_count (&bb->count, bb1->count); set_bb_annotated (bb, annotated_bb); } } @@ -1239,7 +3084,9 @@ afdo_find_equiv_class (bb_set *annotated_bb) && bb1->loop_father == bb->loop_father) { bb1->aux = bb; - if (bb1->count > bb->count && is_bb_annotated (bb1, *annotated_bb)) + if (is_bb_annotated (bb1, *annotated_bb) + && (!is_bb_annotated (bb, *annotated_bb) + || bb1->count > bb->count)) { if (dump_file) { @@ -1248,8 +3095,9 @@ afdo_find_equiv_class (bb_set *annotated_bb) bb1->index, bb->index); bb1->count.dump (dump_file); + fprintf (dump_file, "\n"); } - bb->count = bb1->count; + update_count_by_afdo_count (&bb->count, bb1->count); set_bb_annotated (bb, annotated_bb); } } @@ -1275,50 +3123,125 @@ afdo_propagate_edge (bool is_succ, bb_set *annotated_bb) { edge e, unknown_edge = NULL; edge_iterator ei; - int num_unknown_edge = 0; - int num_edge = 0; + int num_unknown_edges = 0; + int num_edges = 0; profile_count total_known_count = profile_count::zero ().afdo (); FOR_EACH_EDGE (e, ei, is_succ ? bb->succs : bb->preds) { gcc_assert (AFDO_EINFO (e) != NULL); if (! AFDO_EINFO (e)->is_annotated ()) - num_unknown_edge++, unknown_edge = e; + num_unknown_edges++, unknown_edge = e; else total_known_count += AFDO_EINFO (e)->get_count (); - num_edge++; + num_edges++; + } + if (dump_file) + { + fprintf (dump_file, "bb %i %s propagating %s edges %i, " + "unknown edges %i, known count ", + bb->index, + is_bb_annotated (bb, *annotated_bb) ? "(annotated)" : "", + is_succ ? "succesors" : "predecessors", num_edges, + num_unknown_edges); + total_known_count.dump (dump_file); + fprintf (dump_file, " bb count "); + bb->count.dump (dump_file); + fprintf (dump_file, "\n"); } /* Be careful not to annotate block with no successor in special cases. */ - if (num_unknown_edge == 0 && total_known_count > bb->count) + if (num_unknown_edges == 0 && num_edges + && !is_bb_annotated (bb, *annotated_bb)) + { + if (dump_file) + { + fprintf (dump_file, " Annotating bb %i with count ", bb->index); + total_known_count.dump (dump_file); + fprintf (dump_file, "\n"); + } + update_count_by_afdo_count (&bb->count, total_known_count); + set_bb_annotated (bb, annotated_bb); + changed = true; + } + else if (is_bb_annotated (bb, *annotated_bb) + && bb->count < total_known_count) { + if (dump_file) + { + fprintf (dump_file, " Increasing bb %i count from ", + bb->index); + bb->count.dump (dump_file); + fprintf (dump_file, " to "); + total_known_count.dump (dump_file); + fprintf (dump_file, " hoping to mitigate afdo inconsistency\n"); + } bb->count = total_known_count; - if (!is_bb_annotated (bb, *annotated_bb)) - set_bb_annotated (bb, annotated_bb); changed = true; } - else if (num_unknown_edge == 1 && is_bb_annotated (bb, *annotated_bb)) + else if (num_unknown_edges == 1 && is_bb_annotated (bb, *annotated_bb)) { if (bb->count > total_known_count) { - profile_count new_count = bb->count - total_known_count; - AFDO_EINFO(unknown_edge)->set_count(new_count); - if (num_edge == 1) - { - basic_block succ_or_pred_bb = is_succ ? unknown_edge->dest : unknown_edge->src; - if (new_count > succ_or_pred_bb->count) - { - succ_or_pred_bb->count = new_count; - if (!is_bb_annotated (succ_or_pred_bb, *annotated_bb)) - set_bb_annotated (succ_or_pred_bb, annotated_bb); - } - } - } + profile_count new_count = bb->count - total_known_count; + AFDO_EINFO (unknown_edge)->set_count (new_count); + } else - AFDO_EINFO (unknown_edge)->set_count (profile_count::zero().afdo ()); + AFDO_EINFO (unknown_edge)->set_count + (profile_count::zero ().afdo ()); + if (dump_file) + { + fprintf (dump_file, " Annotated edge %i->%i with count ", + unknown_edge->src->index, unknown_edge->dest->index); + AFDO_EINFO (unknown_edge)->get_count ().dump (dump_file); + fprintf (dump_file, "\n"); + } AFDO_EINFO (unknown_edge)->set_annotated (); changed = true; } + else if (num_unknown_edges > 1 + && is_bb_annotated (bb, *annotated_bb) + && (total_known_count >= bb->count || !bb->count.nonzero_p ())) + { + FOR_EACH_EDGE (e, ei, is_succ ? bb->succs : bb->preds) + { + gcc_assert (AFDO_EINFO (e) != NULL); + if (! AFDO_EINFO (e)->is_annotated ()) + { + AFDO_EINFO (e)->set_count + (profile_count::zero ().afdo ()); + AFDO_EINFO (e)->set_annotated (); + if (dump_file) + { + fprintf (dump_file, " Annotated edge %i->%i with count ", + e->src->index, e->dest->index); + AFDO_EINFO (unknown_edge)->get_count ().dump (dump_file); + fprintf (dump_file, "\n"); + } + } + } + } + else if (num_unknown_edges == 0 + && is_bb_annotated (bb, *annotated_bb) + && (is_succ ? single_succ_p (bb) : single_pred_p (bb))) + { + edge e = is_succ ? single_succ_edge (bb) : single_pred_edge (bb); + if (AFDO_EINFO (e)->is_annotated () + && AFDO_EINFO (e)->get_count () < bb->count) + { + if (dump_file) + { + fprintf (dump_file, " Increasing edge %i->%i count from ", + e->src->index, e->dest->index); + AFDO_EINFO (e)->get_count ().dump (dump_file); + fprintf (dump_file, " to "); + bb->count.dump (dump_file); + fprintf (dump_file, " hoping to mitigate afdo inconsistency\n"); + } + AFDO_EINFO (e)->set_count (bb->count); + changed = true; + } + } } return changed; } @@ -1431,18 +3354,28 @@ afdo_propagate_circuit (const bb_set &annotated_bb) static void afdo_propagate (bb_set *annotated_bb) { - basic_block bb; bool changed = true; int i = 0; + basic_block bb; FOR_ALL_BB_FN (bb, cfun) - { - bb->count = ((basic_block)bb->aux)->count; - if (is_bb_annotated ((basic_block)bb->aux, *annotated_bb)) - set_bb_annotated (bb, annotated_bb); - } + if (!is_bb_annotated (bb, *annotated_bb) + && is_bb_annotated ((basic_block)bb->aux, *annotated_bb)) + { + update_count_by_afdo_count (&bb->count, ((basic_block)bb->aux)->count); + set_bb_annotated (bb, annotated_bb); + if (dump_file) + { + fprintf (dump_file, + " Copying count of bb %i to bb %i; count is:", + ((basic_block)bb->aux)->index, + bb->index); + bb->count.dump (dump_file); + fprintf (dump_file, "\n"); + } + } - while (changed && i++ < 10) + while (changed && i++ < 100) { changed = false; @@ -1452,6 +3385,340 @@ afdo_propagate (bb_set *annotated_bb) changed = true; afdo_propagate_circuit (*annotated_bb); } + if (dump_file) + fprintf (dump_file, "Propagation took %i iterations %s\n", + i, changed ? "; iteration limit reached\n" : ""); +} + +/* qsort comparator of sreals. */ +static int +cmp (const void *a, const void *b) +{ + if (*(const sreal *)a < *(const sreal *)b) + return 1; + if (*(const sreal *)a > *(const sreal *)b) + return -1; + return 0; +} + +/* To scalle a connected component of graph we collect desired scales of + basic blocks on the boundary and then compute a robust average. */ + +struct scale +{ + /* Scale descired. */ + sreal scale; + /* Weight for averaging computed from execution count of the edge + scale originates from. */ + uint64_t weight; +}; + +/* Add scale ORIG/ANNOTATED to SCALES. */ + +static void +add_scale (vec <scale> *scales, profile_count annotated, profile_count orig) +{ + if (dump_file) + { + orig.dump (dump_file); + fprintf (dump_file, " should be "); + annotated.dump (dump_file); + fprintf (dump_file, "\n"); + } + if (orig.force_nonzero () == orig) + { + sreal scale + = annotated.guessed_local () + .to_sreal_scale (orig); + if (dump_file) + fprintf (dump_file, " adding scale %.16f, weight %" PRId64 "\n", + scale.to_double (), annotated.value () + 1); + scales->safe_push ({scale, annotated.value () + 1}); + } +} + +/* Scale counts of all basic blocks in BBS by SCALE and convert them to + IPA quality. */ + +static void +scale_bbs (const vec <basic_block> &bbs, sreal scale) +{ + if (dump_file) + fprintf (dump_file, " Scaling by %.16f\n", scale.to_double ()); + for (basic_block b : bbs) + if (!(b->count == profile_count::zero ()) + && b->count.initialized_p ()) + { + profile_count o = b->count; + b->count = b->count.force_guessed () * scale; + + /* If we scaled to 0, make it auto-fdo since that is treated + less agressively. */ + if (!b->count.nonzero_p () && o.nonzero_p ()) + b->count = profile_count::zero ().afdo (); + if (dump_file) + { + fprintf (dump_file, " bb %i count updated ", b->index); + o.dump (dump_file); + fprintf (dump_file, " -> "); + b->count.dump (dump_file); + fprintf (dump_file, "\n"); + } + } +} + +/* In case given basic block was fully optimized out, AutoFDO + will have no data about it. In this case try to preserve static profile. + Identify connected components (in undirected form of CFG) which has + no annotations at all. Look at thir boundaries and try to determine + scaling factor and scale. */ + +void +afdo_adjust_guessed_profile (bb_set *annotated_bb) +{ + /* Basic blocks of connected component currently processed. */ + auto_vec <basic_block, 20> bbs (n_basic_blocks_for_fn (cfun)); + /* Scale factors found. */ + auto_vec <scale, 20> scales; + auto_vec <basic_block, 20> stack (n_basic_blocks_for_fn (cfun)); + + basic_block seed_bb; + unsigned int component_id = 1; + + /* Map from basic block to its component. + 0 is used for univisited BBs, + 1 means that BB is annotated, + >=2 is an id of the component BB belongs to. */ + auto_vec <unsigned int, 20> component; + component.safe_grow (last_basic_block_for_fn (cfun)); + profile_count max_count_in_fn = profile_count::zero (); + FOR_ALL_BB_FN (seed_bb, cfun) + if (is_bb_annotated (seed_bb, *annotated_bb)) + { + component[seed_bb->index] = 1; + max_count_in_fn = max_count_in_fn.max (seed_bb->count); + } + else + component[seed_bb->index] = 0; + FOR_ALL_BB_FN (seed_bb, cfun) + if (!component[seed_bb->index]) + { + stack.quick_push (seed_bb); + component_id++; + bbs.truncate (0); + scales.truncate (0); + component[seed_bb->index] = component_id; + profile_count max_count = profile_count::zero (); + + /* Identify connected component starting in BB. */ + if (dump_file) + fprintf (dump_file, "Starting connected component in bb %i\n", + seed_bb->index); + do + { + basic_block b = stack.pop (); + + bbs.quick_push (b); + max_count = max_count.max (b->count); + + for (edge e: b->preds) + if (!component[e->src->index]) + { + stack.quick_push (e->src); + component[e->src->index] = component_id; + } + for (edge e: b->succs) + if (!component[e->dest->index]) + { + stack.quick_push (e->dest); + component[e->dest->index] = component_id; + } + } + while (!stack.is_empty ()); + + /* If all blocks in components has 0 count, we do not need + to scale, only we must convert to IPA quality. */ + if (!max_count.nonzero_p ()) + { + if (dump_file) + fprintf (dump_file, " All counts are 0; scale = 1\n"); + scale_bbs (bbs, 1); + continue; + } + + /* Now visit the component and try to figure out its desired + frequency. */ + for (basic_block b : bbs) + { + if (dump_file) + { + fprintf (dump_file, " visiting bb %i with count ", b->index); + b->count.dump (dump_file); + fprintf (dump_file, "\n"); + } + if (!b->count.nonzero_p ()) + continue; + /* Sum of counts of annotated edges into B. */ + profile_count annotated_count = profile_count::zero (); + /* Sum of counts of edges into B with source in current + component. */ + profile_count current_component_count = profile_count::zero (); + bool boundary = false; + + for (edge e: b->preds) + if (AFDO_EINFO (e)->is_annotated ()) + { + if (dump_file) + { + fprintf (dump_file, " Annotated pred edge to %i " + "with count ", e->src->index); + AFDO_EINFO (e)->get_count ().dump (dump_file); + fprintf (dump_file, "\n"); + } + boundary = true; + annotated_count += AFDO_EINFO (e)->get_count (); + } + /* If source is anotated, combine with static + probability prediction. + TODO: We can do better in case some of edges out are + annotated and distribute only remaining count out of BB. */ + else if (is_bb_annotated (e->src, *annotated_bb)) + { + boundary = true; + if (dump_file) + { + fprintf (dump_file, " Annotated predecesor %i " + "with count ", e->src->index); + e->src->count.dump (dump_file); + fprintf (dump_file, " edge count using static profile "); + e->count ().dump (dump_file); + fprintf (dump_file, "\n"); + } + annotated_count += e->count (); + } + else + { + current_component_count += e->count (); + gcc_checking_assert (component[e->src->index] == component_id); + } + if (boundary && current_component_count.initialized_p ()) + { + if (dump_file) + fprintf (dump_file, " bb %i in count ", b->index); + add_scale (&scales, + annotated_count, + b->count - current_component_count); + } + for (edge e: b->succs) + if (AFDO_EINFO (e)->is_annotated ()) + { + if (dump_file) + fprintf (dump_file, " edge %i->%i count ", + b->index, e->dest->index); + add_scale (&scales, AFDO_EINFO (e)->get_count (), e->count ()); + } + else if (is_bb_annotated (e->dest, *annotated_bb)) + { + profile_count annotated_count = e->dest->count; + profile_count out_count = profile_count::zero (); + bool ok = true; + + for (edge e2: e->dest->preds) + if (AFDO_EINFO (e2)->is_annotated ()) + annotated_count -= AFDO_EINFO (e2)->get_count (); + else if (component[e2->src->index] == component_id) + out_count += e2->count (); + else if (is_bb_annotated (e2->src, *annotated_bb)) + annotated_count -= e2->count (); + else if (e2->probability.nonzero_p ()) + { + ok = false; + break; + } + if (!ok) + continue; + if (dump_file) + fprintf (dump_file, + " edge %i->%i has annotated sucessor; count ", + b->index, e->dest->index); + add_scale (&scales, annotated_count, e->count ()); + } + + } + + /* If we failed to find annotated entry or exit edge, + look for exit edges and scale profile so the dest + BB get all flow it needs. This is inprecise because + the edge is not annotated and thus BB has more than + one such predecessor. */ + if (!scales.length ()) + for (basic_block b : bbs) + if (b->count.nonzero_p ()) + for (edge e: b->succs) + if (is_bb_annotated (e->dest, *annotated_bb)) + { + profile_count annotated_count = e->dest->count; + for (edge e2: e->dest->preds) + if (AFDO_EINFO (e2)->is_annotated ()) + annotated_count -= AFDO_EINFO (e2)->get_count (); + if (dump_file) + fprintf (dump_file, + " edge %i->%i has annotated sucessor;" + " upper bound count ", + b->index, e->dest->index); + add_scale (&scales, annotated_count, e->count ()); + } + if (!scales.length ()) + { + if (dump_file) + fprintf (dump_file, + " Can not determine count from the boundary; giving up"); + continue; + } + gcc_checking_assert (scales.length ()); + scales.qsort (cmp); + + uint64_t overall_weight = 0; + for (scale &e : scales) + overall_weight += e.weight; + + uint64_t cummulated = 0, weight_sum = 0; + sreal scale_sum = 0; + for (scale &e : scales) + { + uint64_t prev = cummulated; + cummulated += e.weight; + if (cummulated >= overall_weight / 4 + && prev <= 3 * overall_weight / 4) + { + scale_sum += e.scale * e.weight; + weight_sum += e.weight; + if (dump_file) + fprintf (dump_file, " accounting scale %.16f, weight %" PRId64 "\n", + e.scale.to_double (), e.weight); + } + else if (dump_file) + fprintf (dump_file, " ignoring scale %.16f, weight %" PRId64 "\n", + e.scale.to_double (), e.weight); + } + sreal scale = scale_sum / (sreal)weight_sum; + + /* Avoid scaled regions to have very large counts. + Otherwise they may dominate ipa-profile's histogram computing cutoff + of hot basic blocks. */ + if (max_count * scale > max_count_in_fn.guessed_local ()) + { + if (dump_file) + { + fprintf (dump_file, "Scaling by %.16f produces max count ", + scale.to_double ()); + (max_count * scale).dump (dump_file); + fprintf (dump_file, " that exceeds max count in fn; capping\n"); + } + scale = max_count_in_fn.guessed_local ().to_sreal_scale (max_count); + } + scale_bbs (bbs, scale); + } } /* Propagate counts on control flow graph and calculate branch @@ -1464,10 +3731,6 @@ afdo_calculate_branch_prob (bb_set *annotated_bb) edge_iterator ei; basic_block bb; - calculate_dominance_info (CDI_POST_DOMINATORS); - calculate_dominance_info (CDI_DOMINATORS); - loop_optimizer_init (0); - FOR_ALL_BB_FN (bb, cfun) { gcc_assert (bb->aux == NULL); @@ -1482,25 +3745,50 @@ afdo_calculate_branch_prob (bb_set *annotated_bb) afdo_propagate (annotated_bb); FOR_EACH_BB_FN (bb, cfun) - { - int num_unknown_succ = 0; - profile_count total_count = profile_count::zero ().afdo (); - - FOR_EACH_EDGE (e, ei, bb->succs) - { - gcc_assert (AFDO_EINFO (e) != NULL); - if (! AFDO_EINFO (e)->is_annotated ()) - num_unknown_succ++; - else - total_count += AFDO_EINFO (e)->get_count (); - } - if (num_unknown_succ == 0 && total_count.nonzero_p ()) + if (is_bb_annotated (bb, *annotated_bb)) { + bool all_known = true; + profile_count total_count = profile_count::zero ().afdo (); + FOR_EACH_EDGE (e, ei, bb->succs) - e->probability - = AFDO_EINFO (e)->get_count ().probability_in (total_count); + { + gcc_assert (AFDO_EINFO (e) != NULL); + if (! AFDO_EINFO (e)->is_annotated ()) + { + /* If by static profile this edge never happens, + still propagate the rest. */ + if (e->probability.nonzero_p ()) + { + all_known = false; + break; + } + } + else + total_count += AFDO_EINFO (e)->get_count (); + } + if (!all_known || !total_count.nonzero_p ()) + continue; + + FOR_EACH_EDGE (e, ei, bb->succs) + if (AFDO_EINFO (e)->is_annotated ()) + { + /* If probability is 1, preserve reliable static prediction + (This is, for example the case of single fallthru edge + or single fallthru plus unlikely EH edge.) */ + if (AFDO_EINFO (e)->get_count () == total_count + && e->probability == profile_probability::always ()) + ; + else if (AFDO_EINFO (e)->get_count ().nonzero_p ()) + e->probability + = AFDO_EINFO (e)->get_count ().probability_in (total_count); + /* If probability is zero, preserve reliable static + prediction. */ + else if (e->probability.nonzero_p () + || e->probability.quality () == GUESSED) + e->probability = profile_probability::never ().afdo (); + } } - } + afdo_adjust_guessed_profile (annotated_bb); FOR_ALL_BB_FN (bb, cfun) { bb->aux = NULL; @@ -1511,82 +3799,12 @@ afdo_calculate_branch_prob (bb_set *annotated_bb) e->aux = NULL; } } - - loop_optimizer_finalize (); - free_dominance_info (CDI_DOMINATORS); - free_dominance_info (CDI_POST_DOMINATORS); -} - -/* Perform value profile transformation using AutoFDO profile. Add the - promoted stmts to PROMOTED_STMTS. Return TRUE if there is any - indirect call promoted. */ - -static bool -afdo_vpt_for_early_inline (stmt_set *promoted_stmts) -{ - basic_block bb; - if (afdo_source_profile->get_function_instance_by_decl ( - current_function_decl) == NULL) - return false; - - compute_fn_summary (cgraph_node::get (current_function_decl), true); - - bool has_vpt = false; - FOR_EACH_BB_FN (bb, cfun) - { - if (!has_indirect_call (bb)) - continue; - gimple_stmt_iterator gsi; - - gcov_type bb_count = 0; - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - count_info info; - gimple *stmt = gsi_stmt (gsi); - if (afdo_source_profile->get_count_info (stmt, &info)) - bb_count = MAX (bb_count, info.count); - } - - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gcall *stmt = dyn_cast <gcall *> (gsi_stmt (gsi)); - /* IC_promotion and early_inline_2 is done in multiple iterations. - No need to promoted the stmt if its in promoted_stmts (means - it is already been promoted in the previous iterations). */ - if ((!stmt) || gimple_call_fn (stmt) == NULL - || TREE_CODE (gimple_call_fn (stmt)) == FUNCTION_DECL - || promoted_stmts->find (stmt) != promoted_stmts->end ()) - continue; - - count_info info; - afdo_source_profile->get_count_info (stmt, &info); - info.count = bb_count; - if (afdo_source_profile->update_inlined_ind_target (stmt, &info)) - { - /* Promote the indirect call and update the promoted_stmts. */ - promoted_stmts->insert (stmt); - if (afdo_vpt (&gsi, info.targets, true)) - has_vpt = true; - } - } - } - - if (has_vpt) - { - unsigned todo = optimize_inline_calls (current_function_decl); - if (todo & TODO_update_ssa_any) - update_ssa (TODO_update_ssa); - return true; - } - - return false; } -/* Annotate auto profile to the control flow graph. Do not annotate value - profile for stmts in PROMOTED_STMTS. */ +/* Annotate auto profile to the control flow graph. */ static void -afdo_annotate_cfg (const stmt_set &promoted_stmts) +afdo_annotate_cfg (void) { basic_block bb; bb_set annotated_bb; @@ -1597,21 +3815,41 @@ afdo_annotate_cfg (const stmt_set &promoted_stmts) if (s == NULL) { if (dump_file) - fprintf (dump_file, "No afdo profile for %s", + fprintf (dump_file, "No afdo profile for %s\n", cgraph_node::get (current_function_decl)->dump_name ()); + /* create_gcov only dumps symbols with some samples in them. + This means that we get nonempty zero_bbs only if some + nonzero counts in profile were not matched with statements. */ + if (!flag_profile_partial_training) + { + FOR_ALL_BB_FN (bb, cfun) + if (bb->count.quality () == GUESSED_LOCAL) + bb->count = bb->count.global0afdo (); + update_max_bb_count (); + } return; } + calculate_dominance_info (CDI_POST_DOMINATORS); + calculate_dominance_info (CDI_DOMINATORS); + loop_optimizer_init (0); + if (dump_file) - fprintf (dump_file, "\n\nAnnotating BB profile of %s\n", - cgraph_node::get (current_function_decl)->dump_name ()); + { + fprintf (dump_file, "\n\nAnnotating BB profile of %s\n", + cgraph_node::get (current_function_decl)->dump_name ()); + fprintf (dump_file, "\n"); + s->dump (dump_file); + fprintf (dump_file, "\n"); + } /* In the first pass only store non-zero counts. */ - gcov_type head_count = s->head_count (); + gcov_type head_count = s->head_count () * autofdo::afdo_count_scale; bool profile_found = head_count > 0; + hash_set <basic_block> zero_bbs; FOR_EACH_BB_FN (bb, cfun) { - if (afdo_set_bb_count (bb, promoted_stmts)) + if (afdo_set_bb_count (bb, zero_bbs)) { if (bb->count.quality () == AFDO) { @@ -1621,49 +3859,108 @@ afdo_annotate_cfg (const stmt_set &promoted_stmts) set_bb_annotated (bb, &annotated_bb); } } + /* We try to preserve static profile for BBs with 0 + afdo samples, but if even static profile agrees with 0, + consider it final so propagation works better. */ + for (basic_block bb : zero_bbs) + if (!bb->count.nonzero_p ()) + { + update_count_by_afdo_count (&bb->count, 0); + set_bb_annotated (bb, &annotated_bb); + if (dump_file) + { + fprintf (dump_file, " Annotating bb %i with count ", bb->index); + bb->count.dump (dump_file); + fprintf (dump_file, + " (has 0 count in both static and afdo profile)\n"); + } + } /* Exit without clobbering static profile if there was no - non-zero count. - ??? Instead of keeping guessed profile we can introduce - GUESSED_GLOBAL0_AFDO. */ + non-zero count. */ if (!profile_found) { - if (dump_file) - fprintf (dump_file, "No afdo samples found; keeping original profile"); + /* create_gcov only dumps symbols with some samples in them. + This means that we get nonempty zero_bbs only if some + nonzero counts in profile were not matched with statements. + ??? We can adjust create_gcov to also recordinfo + about function with no samples. Then we can distinguish + between lost profiles which should be kept local and + real functions with 0 samples during train run. */ + if (zero_bbs.is_empty ()) + { + if (dump_file) + fprintf (dump_file, "No afdo samples found" + "; Setting global count to afdo0\n"); + } + else + { + if (dump_file) + fprintf (dump_file, "Setting global count to afdo0\n"); + } + if (!flag_profile_partial_training) + { + FOR_ALL_BB_FN (bb, cfun) + if (bb->count.quality () == GUESSED_LOCAL) + bb->count = bb->count.global0afdo (); + update_max_bb_count (); + } + + loop_optimizer_finalize (); + free_dominance_info (CDI_DOMINATORS); + free_dominance_info (CDI_POST_DOMINATORS); return; } /* Update profile. */ - update_count_by_afdo_count (&ENTRY_BLOCK_PTR_FOR_FN (cfun)->count, - head_count); - update_count_by_afdo_count (&EXIT_BLOCK_PTR_FOR_FN (cfun)->count, 0); - profile_count max_count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count; - - FOR_EACH_BB_FN (bb, cfun) - if (bb->count.quality () != AFDO) - update_count_by_afdo_count (&bb->count, 0); - else - max_count = max_count.max (bb->count); + if (head_count > 0) + { + update_count_by_afdo_count (&ENTRY_BLOCK_PTR_FOR_FN (cfun)->count, + head_count); + set_bb_annotated (ENTRY_BLOCK_PTR_FOR_FN (cfun), &annotated_bb); + if (!is_bb_annotated (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb, annotated_bb) + || ENTRY_BLOCK_PTR_FOR_FN (cfun)->count + > ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb->count) + { + ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb->count + = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count; + set_bb_annotated (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb, + &annotated_bb); + } + if (!is_bb_annotated (EXIT_BLOCK_PTR_FOR_FN (cfun), annotated_bb) + || ENTRY_BLOCK_PTR_FOR_FN (cfun)->count + > EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb->count) + { + EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb->count + = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count; + set_bb_annotated (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb, &annotated_bb); + } + } - if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count - > ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb->count) - { - ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb->count - = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count; - set_bb_annotated (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb, &annotated_bb); - } - if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count - > EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb->count) - { - EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb->count - = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count; - set_bb_annotated (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb, &annotated_bb); - } - gcc_assert (max_count.nonzero_p ()); /* Calculate, propagate count and probability information on CFG. */ afdo_calculate_branch_prob (&annotated_bb); - cgraph_node::get(current_function_decl)->count - = ENTRY_BLOCK_PTR_FOR_FN(cfun)->count; + /* If we failed to turn some of original guessed profile to global, + set basic blocks uninitialized. */ + FOR_ALL_BB_FN (bb, cfun) + if (!bb->count.ipa_p ()) + { + /* We skip annotating entry profile if it is 0 + in hope to be able to determine it better from the + static profile. + + Now we know we can not derive it from other info, + so set it since it is better than UNKNOWN. */ + if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)) + bb->count = profile_count::zero ().afdo (); + else + bb->count = profile_count::uninitialized (); + if (dump_file) + fprintf (dump_file, " Unknown count of bb %i\n", bb->index); + cfun->cfg->full_profile = false; + } + + cgraph_node::get (current_function_decl)->count + = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count; update_max_bb_count (); profile_status_for_fn (cfun) = PROFILE_READ; if (flag_value_profile_transformations) @@ -1673,18 +3970,10 @@ afdo_annotate_cfg (const stmt_set &promoted_stmts) free_dominance_info (CDI_POST_DOMINATORS); update_ssa (TODO_update_ssa); } -} -/* Wrapper function to invoke early inliner. */ - -static unsigned int -early_inline () -{ - compute_fn_summary (cgraph_node::get (current_function_decl), true); - unsigned int todo = early_inliner (cfun); - if (todo & TODO_update_ssa_any) - update_ssa (TODO_update_ssa); - return todo; + loop_optimizer_finalize (); + free_dominance_info (CDI_DOMINATORS); + free_dominance_info (CDI_POST_DOMINATORS); } /* Use AutoFDO profile to annoate the control flow graph. @@ -1695,11 +3984,12 @@ auto_profile (void) { struct cgraph_node *node; - if (symtab->state == FINISHED) + if (symtab->state == FINISHED || !afdo_source_profile) return 0; init_node_map (true); profile_info = autofdo::afdo_profile_info; + afdo_source_profile->offline_unrealized_inlines (); FOR_EACH_FUNCTION (node) { @@ -1712,56 +4002,12 @@ auto_profile (void) push_cfun (DECL_STRUCT_FUNCTION (node->decl)); - /* First do indirect call promotion and early inline to make the - IR match the profiled binary before actual annotation. - - This is needed because an indirect call might have been promoted - and inlined in the profiled binary. If we do not promote and - inline these indirect calls before annotation, the profile for - these promoted functions will be lost. - - e.g. foo() --indirect_call--> bar() - In profiled binary, the callsite is promoted and inlined, making - the profile look like: - - foo: { - loc_foo_1: count_1 - bar@loc_foo_2: { - loc_bar_1: count_2 - loc_bar_2: count_3 - } - } - - Before AutoFDO pass, loc_foo_2 is not promoted thus not inlined. - If we perform annotation on it, the profile inside bar@loc_foo2 - will be wasted. - - To avoid this, we promote loc_foo_2 and inline the promoted bar - function before annotation, so the profile inside bar@loc_foo2 - will be useful. */ - autofdo::stmt_set promoted_stmts; - unsigned int todo = 0; - for (int i = 0; i < 10; i++) - { - if (!flag_value_profile_transformations - || !autofdo::afdo_vpt_for_early_inline (&promoted_stmts)) - break; - todo |= early_inline (); - } - - todo |= early_inline (); - autofdo::afdo_annotate_cfg (promoted_stmts); + autofdo::afdo_annotate_cfg (); compute_function_frequency (); - /* Local pure-const may imply need to fixup the cfg. */ - todo |= execute_fixup_cfg (); - if (todo & TODO_cleanup_cfg) - cleanup_tree_cfg (); - free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); cgraph_edge::rebuild_edges (); - compute_fn_summary (cgraph_node::get (current_function_decl), true); pop_cfun (); } @@ -1780,6 +4026,7 @@ read_autofdo_file (void) autofdo::afdo_profile_info = XNEW (gcov_summary); autofdo::afdo_profile_info->runs = 1; autofdo::afdo_profile_info->sum_max = 0; + autofdo::afdo_profile_info->cutoff = 1; /* Read the profile from the profile file. */ autofdo::read_profile (); @@ -1807,18 +4054,93 @@ afdo_callsite_hot_enough_for_early_inline (struct cgraph_edge *edge) { bool is_hot; profile_count pcount = profile_count::from_gcov_type (count).afdo (); - gcov_summary *saved_profile_info = profile_info; - /* At early inline stage, profile_info is not set yet. We need to - temporarily set it to afdo_profile_info to calculate hotness. */ - profile_info = autofdo::afdo_profile_info; - is_hot = maybe_hot_count_p (NULL, pcount); - profile_info = saved_profile_info; + is_hot = maybe_hot_afdo_count_p (pcount); + if (dump_file) + { + fprintf (dump_file, "Call %s -> %s has %s afdo profile count ", + edge->caller->dump_name (), edge->callee->dump_name (), + is_hot ? "hot" : "cold"); + pcount.dump (dump_file); + fprintf (dump_file, "\n"); + } return is_hot; } return false; } +/* Do indirect call promotion during early inlining to make the + IR match the profiled binary before actual annotation. + + This is needed because an indirect call might have been promoted + and inlined in the profiled binary. If we do not promote and + inline these indirect calls before annotation, the profile for + these promoted functions will be lost. + + e.g. foo() --indirect_call--> bar() + In profiled binary, the callsite is promoted and inlined, making + the profile look like: + + foo: { + loc_foo_1: count_1 + bar@loc_foo_2: { + loc_bar_1: count_2 + loc_bar_2: count_3 + } + } + + Before AutoFDO pass, loc_foo_2 is not promoted thus not inlined. + If we perform annotation on it, the profile inside bar@loc_foo2 + will be wasted. + + To avoid this, we promote loc_foo_2 and inline the promoted bar + function before annotation, so the profile inside bar@loc_foo2 + will be useful. */ + +bool +afdo_vpt_for_early_inline (cgraph_node *node) +{ + if (!node->indirect_calls) + return false; + bool changed = false; + cgraph_node *outer = node->inlined_to ? node->inlined_to : node; + if (autofdo::afdo_source_profile->get_function_instance_by_decl + (outer->decl) == NULL) + return false; + for (cgraph_edge *e = node->indirect_calls; e; e = e->next_callee) + { + gcov_type bb_count = 0; + autofdo::count_info info; + basic_block bb = gimple_bb (e->call_stmt); + + /* TODO: This is quadratic; cache the value. */ + for (gimple_stmt_iterator gsi = gsi_start_bb (bb); + !gsi_end_p (gsi); gsi_next (&gsi)) + { + autofdo::count_info info; + gimple *stmt = gsi_stmt (gsi); + if (autofdo::afdo_source_profile->get_count_info (stmt, &info, node)) + bb_count = MAX (bb_count, info.count); + } + autofdo::afdo_source_profile->get_count_info (e->call_stmt, &info, node); + info.count = bb_count; + if (!autofdo::afdo_source_profile->update_inlined_ind_target + (e->call_stmt, &info, node)) + continue; + changed |= autofdo::afdo_vpt (e->call_stmt, info.targets, true, e); + } + return changed; +} + +/* If speculation used during early inline, remove the target + so we do not speculate the indirect edge again during afdo pass. */ + +void +remove_afdo_speculative_target (cgraph_edge *e) +{ + autofdo::afdo_source_profile->remove_icall_target (e); +} + namespace { @@ -1861,3 +4183,49 @@ make_pass_ipa_auto_profile (gcc::context *ctxt) { return new pass_ipa_auto_profile (ctxt); } + +namespace +{ + +const pass_data pass_data_ipa_auto_profile_offline = { + SIMPLE_IPA_PASS, "afdo_offline", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + TV_IPA_AUTOFDO_OFFLINE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_ipa_auto_profile_offline : public simple_ipa_opt_pass +{ +public: + pass_ipa_auto_profile_offline (gcc::context *ctxt) + : simple_ipa_opt_pass (pass_data_ipa_auto_profile_offline, ctxt) + { + } + + /* opt_pass methods: */ + bool + gate (function *) final override + { + return flag_auto_profile; + } + unsigned int + execute (function *) final override + { + read_autofdo_file (); + if (autofdo::afdo_source_profile) + autofdo::afdo_source_profile->offline_external_functions (); + return 0; + } +}; // class pass_ipa_auto_profile + +} // anon namespace + +simple_ipa_opt_pass * +make_pass_ipa_auto_profile_offline (gcc::context *ctxt) +{ + return new pass_ipa_auto_profile_offline (ctxt); +} diff --git a/gcc/auto-profile.h b/gcc/auto-profile.h index 83d523cee3c3..639e263ef7a9 100644 --- a/gcc/auto-profile.h +++ b/gcc/auto-profile.h @@ -28,4 +28,18 @@ extern void end_auto_profile (void); /* Returns TRUE if EDGE is hot enough to be inlined early. */ extern bool afdo_callsite_hot_enough_for_early_inline (struct cgraph_edge *); +/* Try to turn indirect calls into speculative calls for early inlining. */ +extern bool afdo_vpt_for_early_inline (cgraph_node *node); + +/* If speculation was early inlined, remove it from profile data so we + do not repeat it later. */ +extern void remove_afdo_speculative_target (cgraph_edge *); + +/* profile counts determined by AFDO smaller than afdo_hot_bb_threshold are + considered cols. */ +extern gcov_type afdo_hot_bb_threshold; + +/* Return ture if COUNT is possiby hot. */ +extern bool maybe_hot_afdo_count_p (profile_count count); + #endif /* AUTO_PROFILE_H */ diff --git a/gcc/avoid-store-forwarding.cc b/gcc/avoid-store-forwarding.cc index 6825d0426ecc..785efd22606f 100644 --- a/gcc/avoid-store-forwarding.cc +++ b/gcc/avoid-store-forwarding.cc @@ -80,12 +80,12 @@ class pass_rtl_avoid_store_forwarding : public rtl_opt_pass {} /* opt_pass methods: */ - virtual bool gate (function *) + virtual bool gate (function *) final override { return flag_avoid_store_forwarding && optimize >= 1; } - virtual unsigned int execute (function *) override; + virtual unsigned int execute (function *) final override; }; // class pass_rtl_avoid_store_forwarding /* Handler for finding and avoiding store forwardings. */ @@ -119,17 +119,6 @@ generate_bit_insert_sequence (store_fwd_info *store_info, rtx dest) unsigned HOST_WIDE_INT bitsize = store_size * BITS_PER_UNIT; unsigned HOST_WIDE_INT start = store_info->offset * BITS_PER_UNIT; - /* Adjust START for machines with BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN. - Given that the bytes will be reversed in this case, we need to - calculate the starting position from the end of the destination - register. */ - if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN) - { - unsigned HOST_WIDE_INT load_mode_bitsize - = (GET_MODE_BITSIZE (GET_MODE (dest))).to_constant (); - start = load_mode_bitsize - bitsize - start; - } - rtx mov_reg = store_info->mov_reg; store_bit_field (dest, bitsize, start, 0, 0, GET_MODE (mov_reg), mov_reg, false, false); @@ -248,11 +237,14 @@ process_store_forwarding (vec<store_fwd_info> &stores, rtx_insn *load_insn, { it->mov_reg = gen_reg_rtx (GET_MODE (it->store_mem)); rtx_insn *insns = NULL; - const bool has_zero_offset = it->offset == 0; + const bool has_base_offset + = known_eq (poly_uint64 (it->offset), + subreg_size_lowpart_offset (MEM_SIZE (it->store_mem), + load_size)); /* If we're eliminating the load then find the store with zero offset and use it as the base register to avoid a bit insert if possible. */ - if (load_elim && has_zero_offset) + if (load_elim && has_base_offset) { start_sequence (); diff --git a/gcc/builtin-attrs.def b/gcc/builtin-attrs.def index 850efea11ca0..2b82fc2326e0 100644 --- a/gcc/builtin-attrs.def +++ b/gcc/builtin-attrs.def @@ -90,6 +90,14 @@ DEF_LIST_INT_INT (5,0) DEF_LIST_INT_INT (5,6) #undef DEF_LIST_INT_INT +/* Construct a tree for a list of three integers. */ +#define DEF_LIST_INT_INT_INT(VALUE1, VALUE2, VALUE3) \ + DEF_ATTR_TREE_LIST (ATTR_LIST_##VALUE1##_##VALUE2##_##VALUE3, \ + ATTR_NULL, ATTR_##VALUE1, \ + ATTR_LIST_##VALUE2##_##VALUE3) +DEF_LIST_INT_INT_INT (1,2,3) +#undef DEF_LIST_INT_INT_INT + /* Construct trees for identifiers used in built-in function attributes. The construction contributes to startup costs so only attributes that are used to define built-ins should be defined here. */ @@ -209,6 +217,12 @@ DEF_ATTR_TREE_LIST (ATTR_NONNULL_1, ATTR_NONNULL, ATTR_LIST_1, ATTR_NULL) DEF_ATTR_TREE_LIST (ATTR_NONNULL_2, ATTR_NONNULL, ATTR_LIST_2, ATTR_NULL) /* Functions whose third parameter is a nonnull pointer. */ DEF_ATTR_TREE_LIST (ATTR_NONNULL_3, ATTR_NONNULL, ATTR_LIST_3, ATTR_NULL) +/* Functions whose selected pointer parameter(s) are conditionally + nonnull. */ +DEF_ATTR_TREE_LIST (ATTR_NONNULL_IF123_LIST, ATTR_NONNULL_IF_NONZERO, \ + ATTR_LIST_1_2_3, ATTR_NULL) +DEF_ATTR_TREE_LIST (ATTR_NONNULL_4_IF123_LIST, ATTR_NONNULL, \ + ATTR_LIST_4, ATTR_NONNULL_IF123_LIST) /* Nothrow functions with the sentinel(1) attribute. */ DEF_ATTR_TREE_LIST (ATTR_NOTHROW_SENTINEL_1, ATTR_SENTINEL, ATTR_LIST_1, \ ATTR_NOTHROW_LIST) diff --git a/gcc/builtins.cc b/gcc/builtins.cc index e818e819f7c8..7f580a3145ff 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -1158,12 +1158,18 @@ validate_arglist (const_tree callexpr, ...) unsigned int idx = TREE_INT_CST_LOW (TREE_VALUE (args)) - 1; unsigned int idx2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args))) - 1; + unsigned int idx3 = idx2; + if (tree chain2 = TREE_CHAIN (TREE_CHAIN (args))) + idx3 = TREE_INT_CST_LOW (TREE_VALUE (chain2)) - 1; if (idx < (unsigned) call_expr_nargs (callexpr) && idx2 < (unsigned) call_expr_nargs (callexpr) + && idx3 < (unsigned) call_expr_nargs (callexpr) && POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (callexpr, idx))) && integer_zerop (CALL_EXPR_ARG (callexpr, idx)) && INTEGRAL_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (callexpr, idx2))) - && integer_nonzerop (CALL_EXPR_ARG (callexpr, idx2))) + && integer_nonzerop (CALL_EXPR_ARG (callexpr, idx2)) + && INTEGRAL_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (callexpr, idx3))) + && integer_nonzerop (CALL_EXPR_ARG (callexpr, idx3))) return false; } @@ -3529,7 +3535,8 @@ expand_builtin_strnlen (tree exp, rtx target, machine_mode target_mode) wide_int min, max; int_range_max r; - get_global_range_query ()->range_of_expr (r, bound); + get_range_query (cfun)->range_of_expr (r, bound, + currently_expanding_gimple_stmt); if (r.varying_p () || r.undefined_p ()) return NULL_RTX; min = r.lower_bound (); @@ -3604,7 +3611,8 @@ determine_block_size (tree len, rtx len_rtx, { int_range_max r; tree tmin, tmax; - get_global_range_query ()->range_of_expr (r, len); + gimple *cg = currently_expanding_gimple_stmt; + get_range_query (cfun)->range_of_expr (r, len, cg); range_type = get_legacy_range (r, tmin, tmax); if (range_type != VR_UNDEFINED) { @@ -7791,11 +7799,17 @@ expand_builtin_crc_table_based (internal_fn fn, scalar_mode crc_mode, rtx op1 = expand_normal (rhs1); rtx op2 = expand_normal (rhs2); - gcc_assert (TREE_CODE (rhs3) == INTEGER_CST); - rtx op3 = gen_int_mode (TREE_INT_CST_LOW (rhs3), crc_mode); + rtx op3; + if (TREE_CODE (rhs3) != INTEGER_CST) + { + error ("third argument to %<crc%> builtins must be a constant"); + op3 = const0_rtx; + } + else + op3 = convert_to_mode (crc_mode, expand_normal (rhs3), 0); if (CONST_INT_P (op2)) - op2 = gen_int_mode (INTVAL (op2), crc_mode); + op2 = convert_to_mode (crc_mode, op2, 0); if (fn == IFN_CRC) expand_crc_table_based (target, op1, op2, op3, data_mode); diff --git a/gcc/builtins.def b/gcc/builtins.def index fdcad54a5d75..d7b2894bcfa0 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -217,6 +217,8 @@ along with GCC; see the file COPYING3. If not see DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ false, true, true, ATTRS, false, \ flag_openacc) +/* Set NONANSI_P = false to enable the builtins also with -fno-nonansi-builtins, + esp. as -std=c++../c.. imply that flag and -fopenacc should be othogonal. */ #undef DEF_GOACC_BUILTIN_COMPILER #define DEF_GOACC_BUILTIN_COMPILER(ENUM, NAME, TYPE, ATTRS) \ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ @@ -232,10 +234,12 @@ along with GCC; see the file COPYING3. If not see (flag_openacc \ || flag_openmp \ || flag_tree_parallelize_loops > 1)) +/* Set NONANSI_P = false to enable the builtins also with -fno-nonansi-builtins, + esp. as -std=c++../c.. imply that flag and -fopenmp should be othogonal. */ #undef DEF_GOMP_BUILTIN_COMPILER #define DEF_GOMP_BUILTIN_COMPILER(ENUM, NAME, TYPE, ATTRS) \ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ - flag_openmp, true, true, ATTRS, false, flag_openmp) + flag_openmp, true, false, ATTRS, false, flag_openmp) /* Builtin used by the implementation of GNU TM. These functions are mapped to the actual implementation of the STM library. */ @@ -920,8 +924,8 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTC_UNLOCKED, "fputc_unlocked", BT_FN_INT_INT DEF_LIB_BUILTIN (BUILT_IN_FPUTS, "fputs", BT_FN_INT_CONST_STRING_FILEPTR, ATTR_NONNULL_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTS_UNLOCKED, "fputs_unlocked", BT_FN_INT_CONST_STRING_FILEPTR, ATTR_NONNULL_LIST) DEF_LIB_BUILTIN (BUILT_IN_FSCANF, "fscanf", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_SCANF_2_3) -DEF_LIB_BUILTIN (BUILT_IN_FWRITE, "fwrite", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, ATTR_NONNULL_LIST) -DEF_EXT_LIB_BUILTIN (BUILT_IN_FWRITE_UNLOCKED, "fwrite_unlocked", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, ATTR_NONNULL_LIST) +DEF_LIB_BUILTIN (BUILT_IN_FWRITE, "fwrite", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, ATTR_NONNULL_4_IF123_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FWRITE_UNLOCKED, "fwrite_unlocked", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, ATTR_NONNULL_4_IF123_LIST) DEF_LIB_BUILTIN (BUILT_IN_PRINTF, "printf", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_1_2) DEF_EXT_LIB_BUILTIN (BUILT_IN_PRINTF_UNLOCKED, "printf_unlocked", BT_FN_INT_CONST_STRING_VAR, ATTR_NONNULL_1_FORMAT_PRINTF_1_2) DEF_LIB_BUILTIN (BUILT_IN_PUTCHAR, "putchar", BT_FN_INT_INT, ATTR_NULL) diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index cd96e825890d..fb40698bd30e 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,159 @@ +2025-07-16 Kwok Cheung Yeung <kcyeung@baylibre.com> + + * c-omp.cc (c_finish_omp_depobj): Use OMP_ITERATOR_DECL_P. + +2025-07-16 Alfie Richards <alfie.richards@arm.com> + + * c-attribs.cc (handle_target_clones_attribute): Change to use + get_clone_versions. + +2025-07-16 Alfie Richards <alfie.richards@arm.com> + + * c-format.cc (local_string_slice_node): New node type. + (asm_fprintf_char_table): New entry. + (init_dynamic_diag_info): Add support for string_slice. + * c-format.h (T_STRING_SLICE): New node type. + +2025-07-15 Jakub Jelinek <jakub@redhat.com> + Jason Merrill <jason@redhat.com> + + PR c/44677 + * c-opts.cc (c_common_post_options): Change + warn_unused_but_set_parameter and warn_unused_but_set_variable + from 1 to 3 if they were set only implicitly. + * c-attribs.cc (build_attr_access_from_parms): Remove unused + but set variable nelts. + +2025-07-11 Jakub Jelinek <jakub@redhat.com> + + PR c++/119064 + * c.opt (Wc++26-compat): New option. + * c.opt.urls: Regenerate. + * c-opts.cc (c_common_post_options): Clear warn_cxx26_compat for + C++26 or later. + * c-cppbuiltin.cc (c_cpp_builtins): For C++26 predefine + __cpp_trivial_relocatability=202502L. + +2025-07-10 Jakub Jelinek <jakub@redhat.com> + + PR c++/117785 + * c-cppbuiltin.cc (c_cpp_builtins): Predefine + __cpp_constexpr_exceptions=202411L for C++26. + +2025-07-10 Qing Zhao <qing.zhao@oracle.com> + + * c-ubsan.cc (get_bound_from_access_with_size): Adjust the position + of the arguments per the new design. + +2025-07-07 Qing Zhao <qing.zhao@oracle.com> + + Revert: + 2025-07-01 Qing Zhao <qing.zhao@oracle.com> + + * c-attribs.cc (handle_counted_by_attribute): Accept counted_by + attribute for pointer fields. + +2025-07-07 Qing Zhao <qing.zhao@oracle.com> + + Revert: + 2025-07-01 Qing Zhao <qing.zhao@oracle.com> + + * c-gimplify.cc (is_address_with_access_with_size): New function. + (ubsan_walk_array_refs_r): Instrument an INDIRECT_REF whose base + address is .ACCESS_WITH_SIZE or an address computation whose base + address is .ACCESS_WITH_SIZE. + * c-ubsan.cc (ubsan_instrument_bounds_pointer_address): New function. + (struct factor_t): New structure. + (get_factors_from_mul_expr): New function. + (get_index_from_offset): New function. + (get_index_from_pointer_addr_expr): New function. + (is_instrumentable_pointer_array_address): New function. + (ubsan_array_ref_instrumented_p): Change prototype. + Handle MEM_REF in addtional to ARRAY_REF. + (ubsan_maybe_instrument_array_ref): Handle MEM_REF in addtional + to ARRAY_REF. + +2025-07-07 Jason Merrill <jason@redhat.com> + + PR c++/120917 + * c.opt: Add -Wno-abbreviated-auto-in-template-arg. + * c.opt.urls: Regenerate. + +2025-07-04 Jakub Jelinek <jakub@redhat.com> + + PR c/120837 + * c-common.cc (pointer_int_sum): Rewrite the intop PLUS_EXPR or + MINUS_EXPR optimization into extension of both intop operands, + their separate multiplication and then addition/subtraction followed + by rest of pointer_int_sum handling after the multiplication. + +2025-07-01 Qing Zhao <qing.zhao@oracle.com> + + * c-gimplify.cc (is_address_with_access_with_size): New function. + (ubsan_walk_array_refs_r): Instrument an INDIRECT_REF whose base + address is .ACCESS_WITH_SIZE or an address computation whose base + address is .ACCESS_WITH_SIZE. + * c-ubsan.cc (ubsan_instrument_bounds_pointer_address): New function. + (struct factor_t): New structure. + (get_factors_from_mul_expr): New function. + (get_index_from_offset): New function. + (get_index_from_pointer_addr_expr): New function. + (is_instrumentable_pointer_array_address): New function. + (ubsan_array_ref_instrumented_p): Change prototype. + Handle MEM_REF in addtional to ARRAY_REF. + (ubsan_maybe_instrument_array_ref): Handle MEM_REF in addtional + to ARRAY_REF. + +2025-07-01 Qing Zhao <qing.zhao@oracle.com> + + * c-attribs.cc (handle_counted_by_attribute): Accept counted_by + attribute for pointer fields. + +2025-06-30 Jakub Jelinek <jakub@redhat.com> + + PR c/120520 + PR c/117023 + * c-attribs.cc (c_common_gnu_attributes): Allow 2 or 3 arguments for + nonnull_if_nonzero attribute instead of only 2. + (handle_nonnull_if_nonzero_attribute): Handle 3 argument + nonnull_if_nonzero. + * c-common.cc (struct nonnull_arg_ctx): Rename other member to other1, + add other2 member. + (check_function_nonnull): Clear a if nonnull attribute has an + argument. Adjust for nonnull_arg_ctx changes. Handle 3 argument + nonnull_if_nonzero attribute. + (check_nonnull_arg): Adjust for nonnull_arg_ctx changes, emit different + diagnostics for 3 argument nonnull_if_nonzero attributes. + (check_function_arguments): Adjust ctx var initialization. + +2025-06-27 Jakub Jelinek <jakub@redhat.com> + + PR c++/120777 + * c-cppbuiltin.cc (c_cpp_builtins): Predefine + __cpp_constexpr_virtual_inheritance=202506L for C++26. + +2025-06-26 David Malcolm <dmalcolm@redhat.com> + + * c-opts.cc (c_common_diagnostics_set_defaults): Use + diagnostic_context::set_permissive_option. + +2025-06-23 Tobias Burnus <tburnus@baylibre.com> + + * c-omp.cc (c_finish_oacc_wait): Handle if clause. + +2025-06-16 Jason Merrill <jason@redhat.com> + + * c.opt: Add -Wsfinae-incomplete. + * c.opt.urls: Regenerate. + +2025-06-12 Gwenole Beauchesne <gb.devel@gmail.com> + Andrew Pinski <quic_apinski@quicinc.com> + + PR c++/41201 + PR c++/48026 + * c-pragma.cc (init_pragma): Use c_register_pragma_with_early_handler + instead of c_register_pragma for `#pragma GCC optimize`. + 2025-06-03 Martin Uecker <uecker@tugraz.at> PR c/120078 diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc index 5a0e3d328ba7..1f4a0df12051 100644 --- a/gcc/c-family/c-attribs.cc +++ b/gcc/c-family/c-attribs.cc @@ -489,7 +489,7 @@ const struct attribute_spec c_common_gnu_attributes[] = handle_tls_model_attribute, NULL }, { "nonnull", 0, -1, false, true, true, false, handle_nonnull_attribute, NULL }, - { "nonnull_if_nonzero", 2, 2, false, true, true, false, + { "nonnull_if_nonzero", 2, 3, false, true, true, false, handle_nonnull_if_nonzero_attribute, NULL }, { "nonstring", 0, 0, true, false, false, false, handle_nonstring_attribute, NULL }, @@ -5034,12 +5034,21 @@ handle_nonnull_if_nonzero_attribute (tree *node, tree name, tree type = *node; tree pos = TREE_VALUE (args); tree pos2 = TREE_VALUE (TREE_CHAIN (args)); + tree chain2 = TREE_CHAIN (TREE_CHAIN (args)); + tree pos3 = NULL_TREE; + if (chain2) + pos3 = TREE_VALUE (chain2); tree val = positional_argument (type, name, pos, POINTER_TYPE, 1); tree val2 = positional_argument (type, name, pos2, INTEGER_TYPE, 2); - if (val && val2) + tree val3 = NULL_TREE; + if (chain2) + val3 = positional_argument (type, name, pos3, INTEGER_TYPE, 3); + if (val && val2 && (!chain2 || val3)) { TREE_VALUE (args) = val; TREE_VALUE (TREE_CHAIN (args)) = val2; + if (chain2) + TREE_VALUE (chain2) = val3; } else *no_add_attrs = true; @@ -5849,8 +5858,7 @@ build_attr_access_from_parms (tree parms, bool skip_voidptr) order. */ vblist = tree_cons (NULL_TREE, argvbs, vblist); - unsigned nelts = 0; - for (tree vb = argvbs; vb; vb = TREE_CHAIN (vb), ++nelts) + for (tree vb = argvbs; vb; vb = TREE_CHAIN (vb)) { tree bound = TREE_VALUE (vb); if (const unsigned *psizpos = arg2pos.get (bound)) @@ -6132,7 +6140,9 @@ handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args), } } - if (get_target_clone_attr_len (args) == -1) + auto_vec<string_slice> versions = get_clone_attr_versions (args, NULL); + + if (versions.length () == 1) { warning (OPT_Wattributes, "single %<target_clones%> attribute is ignored"); diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index f71cb2652d5a..362dc506f785 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -3438,20 +3438,41 @@ pointer_int_sum (location_t loc, enum tree_code resultcode, an overflow error if the constant is negative but INTOP is not. */ && (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (intop)) || (TYPE_PRECISION (TREE_TYPE (intop)) - == TYPE_PRECISION (TREE_TYPE (ptrop))))) - { - enum tree_code subcode = resultcode; - tree int_type = TREE_TYPE (intop); - if (TREE_CODE (intop) == MINUS_EXPR) - subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR); - /* Convert both subexpression types to the type of intop, - because weird cases involving pointer arithmetic - can result in a sum or difference with different type args. */ - ptrop = build_binary_op (EXPR_LOCATION (TREE_OPERAND (intop, 1)), - subcode, ptrop, - convert (int_type, TREE_OPERAND (intop, 1)), - true); - intop = convert (int_type, TREE_OPERAND (intop, 0)); + == TYPE_PRECISION (TREE_TYPE (ptrop)))) + && TYPE_PRECISION (TREE_TYPE (intop)) <= TYPE_PRECISION (sizetype)) + { + tree intop0 = TREE_OPERAND (intop, 0); + tree intop1 = TREE_OPERAND (intop, 1); + if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype) + || TYPE_UNSIGNED (TREE_TYPE (intop)) != TYPE_UNSIGNED (sizetype)) + { + tree optype = c_common_type_for_size (TYPE_PRECISION (sizetype), + TYPE_UNSIGNED (sizetype)); + intop0 = convert (optype, intop0); + intop1 = convert (optype, intop1); + } + tree t = fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (intop0), intop0, + convert (TREE_TYPE (intop0), size_exp)); + intop0 = convert (sizetype, t); + if (TREE_OVERFLOW_P (intop0) && !TREE_OVERFLOW (t)) + intop0 = wide_int_to_tree (TREE_TYPE (intop0), wi::to_wide (intop0)); + t = fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (intop1), intop1, + convert (TREE_TYPE (intop1), size_exp)); + intop1 = convert (sizetype, t); + if (TREE_OVERFLOW_P (intop1) && !TREE_OVERFLOW (t)) + intop1 = wide_int_to_tree (TREE_TYPE (intop1), wi::to_wide (intop1)); + intop = build_binary_op (EXPR_LOCATION (intop), TREE_CODE (intop), + intop0, intop1, true); + + /* Create the sum or difference. */ + if (resultcode == MINUS_EXPR) + intop = fold_build1_loc (loc, NEGATE_EXPR, sizetype, intop); + + ret = fold_build_pointer_plus_loc (loc, ptrop, intop); + + fold_undefer_and_ignore_overflow_warnings (); + + return ret; } /* Convert the integer argument to a type the same size as sizetype @@ -5749,8 +5770,8 @@ struct nonnull_arg_ctx /* The function whose arguments are being checked and its type (used for calls through function pointers). */ const_tree fndecl, fntype; - /* For nonnull_if_nonzero, index of the other argument. */ - unsigned HOST_WIDE_INT other; + /* For nonnull_if_nonzero, index of the other arguments. */ + unsigned HOST_WIDE_INT other1, other2; /* True if a warning has been issued. */ bool warned_p; }; @@ -5818,6 +5839,7 @@ check_function_nonnull (nonnull_arg_ctx &ctx, int nargs, tree *argarray) check_function_arguments_recurse (check_nonnull_arg, &ctx, argarray[i], i + 1, OPT_Wnonnull); + a = NULL_TREE; } } if (a == NULL_TREE) @@ -5829,17 +5851,25 @@ check_function_nonnull (nonnull_arg_ctx &ctx, int nargs, tree *argarray) unsigned int idx = TREE_INT_CST_LOW (TREE_VALUE (args)) - 1; unsigned int idx2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args))) - 1; + unsigned int idx3 = idx2; + if (tree chain2 = TREE_CHAIN (TREE_CHAIN (args))) + idx3 = TREE_INT_CST_LOW (TREE_VALUE (chain2)) - 1; if (idx < (unsigned) nargs - firstarg && idx2 < (unsigned) nargs - firstarg + && idx3 < (unsigned) nargs - firstarg && INTEGRAL_TYPE_P (TREE_TYPE (argarray[firstarg + idx2])) - && integer_nonzerop (argarray[firstarg + idx2])) + && integer_nonzerop (argarray[firstarg + idx2]) + && INTEGRAL_TYPE_P (TREE_TYPE (argarray[firstarg + idx3])) + && integer_nonzerop (argarray[firstarg + idx3])) { - ctx.other = firstarg + idx2 + 1; + ctx.other1 = firstarg + idx2 + 1; + ctx.other2 = firstarg + idx3 + 1; check_function_arguments_recurse (check_nonnull_arg, &ctx, argarray[firstarg + idx], firstarg + idx + 1, OPT_Wnonnull); - ctx.other = 0; + ctx.other1 = 0; + ctx.other2 = 0; } } return ctx.warned_p; @@ -6023,14 +6053,25 @@ check_nonnull_arg (void *ctx, tree param, unsigned HOST_WIDE_INT param_num) } else { - if (pctx->other) + if (pctx->other1 && pctx->other2 != pctx->other1) + warned = warning_at (loc, OPT_Wnonnull, + "argument %u null where non-null expected " + "because arguments %u and %u are nonzero", + (unsigned) param_num, + TREE_CODE (pctx->fntype) == METHOD_TYPE + ? (unsigned) pctx->other1 - 1 + : (unsigned) pctx->other1, + TREE_CODE (pctx->fntype) == METHOD_TYPE + ? (unsigned) pctx->other2 - 1 + : (unsigned) pctx->other2); + else if (pctx->other1) warned = warning_at (loc, OPT_Wnonnull, "argument %u null where non-null expected " "because argument %u is nonzero", (unsigned) param_num, TREE_CODE (pctx->fntype) == METHOD_TYPE - ? (unsigned) pctx->other - 1 - : (unsigned) pctx->other); + ? (unsigned) pctx->other1 - 1 + : (unsigned) pctx->other1); else warned = warning_at (loc, OPT_Wnonnull, "argument %u null where non-null expected", @@ -6039,7 +6080,7 @@ check_nonnull_arg (void *ctx, tree param, unsigned HOST_WIDE_INT param_num) inform (DECL_SOURCE_LOCATION (pctx->fndecl), "in a call to function %qD declared %qs", pctx->fndecl, - pctx->other ? "nonnull_if_nonzero" : "nonnull"); + pctx->other1 ? "nonnull_if_nonzero" : "nonnull"); } if (warned) @@ -6295,7 +6336,7 @@ check_function_arguments (location_t loc, const_tree fndecl, const_tree fntype, to do this if format checking is enabled. */ if (warn_nonnull) { - nonnull_arg_ctx ctx = { loc, fndecl, fntype, 0, false }; + nonnull_arg_ctx ctx = { loc, fndecl, fntype, 0, 0, false }; warned_p = check_function_nonnull (ctx, nargs, argarray); } diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc index 4589ee4a3a62..2f86b1fe0228 100644 --- a/gcc/c-family/c-cppbuiltin.cc +++ b/gcc/c-family/c-cppbuiltin.cc @@ -1087,6 +1087,7 @@ c_cpp_builtins (cpp_reader *pfile) { /* Set feature test macros for C++26. */ cpp_define (pfile, "__cpp_constexpr=202406L"); + cpp_define (pfile, "__cpp_constexpr_exceptions=202411L"); cpp_define (pfile, "__cpp_static_assert=202306L"); cpp_define (pfile, "__cpp_placeholder_variables=202306L"); cpp_define (pfile, "__cpp_structured_bindings=202403L"); @@ -1094,6 +1095,8 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__cpp_variadic_friend=202403L"); cpp_define (pfile, "__cpp_pack_indexing=202311L"); cpp_define (pfile, "__cpp_pp_embed=202502L"); + cpp_define (pfile, "__cpp_constexpr_virtual_inheritance=202506L"); + cpp_define (pfile, "__cpp_trivial_relocatability=202502L"); } if (flag_concepts && cxx_dialect > cxx14) cpp_define (pfile, "__cpp_concepts=202002L"); diff --git a/gcc/c-family/c-format.cc b/gcc/c-family/c-format.cc index a44249a02227..80430e9a8f7c 100644 --- a/gcc/c-family/c-format.cc +++ b/gcc/c-family/c-format.cc @@ -70,6 +70,7 @@ static GTY(()) tree local_event_ptr_node; static GTY(()) tree local_pp_element_ptr_node; static GTY(()) tree local_gimple_ptr_node; static GTY(()) tree local_cgraph_node_ptr_node; +static GTY(()) tree local_string_slice_node; static GTY(()) tree locus; static bool decode_format_attr (const_tree, tree, tree, function_format_info *, @@ -770,6 +771,7 @@ static const format_char_info asm_fprintf_char_table[] = { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, \ { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "//cR", NULL }, \ { "@", 1, STD_C89, { T_EVENT_PTR, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, \ + { "B", 1, STD_C89, { T_STRING_SLICE, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \ { "e", 1, STD_C89, { T_PP_ELEMENT_PTR, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, \ { "<", 0, STD_C89, NOARGUMENTS, "", "<", NULL }, \ { ">", 0, STD_C89, NOARGUMENTS, "", ">", NULL }, \ @@ -5211,6 +5213,11 @@ init_dynamic_diag_info (void) || local_cgraph_node_ptr_node == void_type_node) local_cgraph_node_ptr_node = get_named_type ("cgraph_node"); + /* Similar to the above but for string_slice*. */ + if (!local_string_slice_node + || local_string_slice_node == void_type_node) + local_string_slice_node = get_named_type ("string_slice"); + /* Similar to the above but for diagnostic_event_id_t*. */ if (!local_event_ptr_node || local_event_ptr_node == void_type_node) diff --git a/gcc/c-family/c-format.h b/gcc/c-family/c-format.h index 323338cb8e7f..d44d3862d830 100644 --- a/gcc/c-family/c-format.h +++ b/gcc/c-family/c-format.h @@ -317,6 +317,7 @@ struct format_kind_info #define T89_G { STD_C89, NULL, &local_gimple_ptr_node } #define T_CGRAPH_NODE { STD_C89, NULL, &local_cgraph_node_ptr_node } #define T_EVENT_PTR { STD_C89, NULL, &local_event_ptr_node } +#define T_STRING_SLICE { STD_C89, NULL, &local_string_slice_node } #define T_PP_ELEMENT_PTR { STD_C89, NULL, &local_pp_element_ptr_node } #define T89_T { STD_C89, NULL, &local_tree_type_node } #define T89_V { STD_C89, NULL, T_V } diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc index 13de2fe48f96..fe272888c51e 100644 --- a/gcc/c-family/c-omp.cc +++ b/gcc/c-family/c-omp.cc @@ -52,8 +52,8 @@ c_finish_oacc_wait (location_t loc, tree parms, tree clauses) vec_alloc (args, nparms + 2); stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT); - if (omp_find_clause (clauses, OMP_CLAUSE_ASYNC)) - t = OMP_CLAUSE_ASYNC_EXPR (clauses); + if ((t = omp_find_clause (clauses, OMP_CLAUSE_ASYNC))) + t = OMP_CLAUSE_ASYNC_EXPR (t); else t = build_int_cst (integer_type_node, GOMP_ASYNC_SYNC); @@ -71,6 +71,11 @@ c_finish_oacc_wait (location_t loc, tree parms, tree clauses) stmt = build_call_expr_loc_vec (loc, stmt, args); + t = omp_find_clause (clauses, OMP_CLAUSE_IF); + if (t) + stmt = build3_loc (input_location, COND_EXPR, void_type_node, + OMP_CLAUSE_IF_EXPR (t), stmt, NULL_TREE); + vec_free (args); return stmt; @@ -764,9 +769,7 @@ c_finish_omp_depobj (location_t loc, tree depobj, kind = OMP_CLAUSE_DEPEND_KIND (clause); t = OMP_CLAUSE_DECL (clause); gcc_assert (t); - if (TREE_CODE (t) == TREE_LIST - && TREE_PURPOSE (t) - && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) + if (OMP_ITERATOR_DECL_P (t)) { error_at (OMP_CLAUSE_LOCATION (clause), "%<iterator%> modifier may not be specified on " diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc index 697518637df3..795f5a355af6 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -192,7 +192,7 @@ void c_common_diagnostics_set_defaults (diagnostic_context *context) { diagnostic_text_finalizer (context) = c_diagnostic_text_finalizer; - context->m_opt_permissive = OPT_fpermissive; + context->set_permissive_option (OPT_fpermissive); } /* Input charset configuration for diagnostics. */ @@ -1165,6 +1165,9 @@ c_common_post_options (const char **pfilename) warn_cxx20_compat = 0; cpp_opts->cpp_warn_cxx20_compat = 0; } + if (cxx_dialect >= cxx26) + /* Don't warn about C++26 compatibility changes in C++26 or later. */ + warn_cxx26_compat = 0; /* C++17 has stricter evaluation order requirements; let's use some of them for earlier C++ as well, so chaining works as expected. */ @@ -1223,6 +1226,17 @@ c_common_post_options (const char **pfilename) SET_OPTION_IF_UNSET (&global_options, &global_options_set, flag_range_for_ext_temps, cxx_dialect >= cxx23); + /* EnabledBy unfortunately can't specify value to use if set and + LangEnabledBy can't specify multiple options with &&. For -Wunused + or -Wunused -Wextra we want these to default to 3 unless user specified + some other level explicitly. */ + if (warn_unused_but_set_parameter == 1) + SET_OPTION_IF_UNSET (&global_options, &global_options_set, + warn_unused_but_set_parameter, 3); + if (warn_unused_but_set_variable == 1) + SET_OPTION_IF_UNSET (&global_options, &global_options_set, + warn_unused_but_set_variable, 3); + /* -fimmediate-escalation has no effect when immediate functions are not supported. */ if (flag_immediate_escalation && cxx_dialect < cxx20) diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc index 8b5cdcc56ea8..137b83bf5b15 100644 --- a/gcc/c-family/c-pragma.cc +++ b/gcc/c-family/c-pragma.cc @@ -1847,7 +1847,9 @@ init_pragma (void) c_register_pragma_with_early_handler ("GCC", "target", handle_pragma_target, handle_pragma_target); - c_register_pragma ("GCC", "optimize", handle_pragma_optimize); + c_register_pragma_with_early_handler ("GCC", "optimize", + handle_pragma_optimize, + handle_pragma_optimize); c_register_pragma_with_early_handler ("GCC", "push_options", handle_pragma_push_options, handle_pragma_push_options); diff --git a/gcc/c-family/c-ubsan.cc b/gcc/c-family/c-ubsan.cc index 78b786854699..a4dc31066afb 100644 --- a/gcc/c-family/c-ubsan.cc +++ b/gcc/c-family/c-ubsan.cc @@ -397,8 +397,7 @@ get_bound_from_access_with_size (tree call) return NULL_TREE; tree ref_to_size = CALL_EXPR_ARG (call, 1); - unsigned int class_of_size = TREE_INT_CST_LOW (CALL_EXPR_ARG (call, 2)); - tree type = TREE_TYPE (CALL_EXPR_ARG (call, 3)); + tree type = TREE_TYPE (TREE_TYPE (CALL_EXPR_ARG (call, 2))); tree size = fold_build2 (MEM_REF, type, unshare_expr (ref_to_size), build_int_cst (ptr_type_node, 0)); /* If size is negative value, treat it as zero. */ @@ -410,12 +409,7 @@ get_bound_from_access_with_size (tree call) build_zero_cst (type), size); } - /* Only when class_of_size is 1, i.e, the number of the elements of - the object type, return the size. */ - if (class_of_size != 1) - return NULL_TREE; - else - size = fold_convert (sizetype, size); + size = fold_convert (sizetype, size); return size; } diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 50ba856fedba..12877eb0e175 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -397,6 +397,10 @@ Wassign-intercept ObjC ObjC++ Var(warn_assign_intercept) Warning Warn whenever an Objective-C assignment is being intercepted by the garbage collector. +Wabbreviated-auto-in-template-arg +C++ ObjC++ Warning Var(warn_abbev_auto_targ) Init(1) +Diagnose a placeholder type in a template argument in a function parameter type. + Wbad-function-cast C ObjC Var(warn_bad_function_cast) Warning Warn about casting functions to incompatible types. @@ -493,6 +497,10 @@ Wc++20-compat C++ ObjC++ Var(warn_cxx20_compat) Warning LangEnabledBy(C++ ObjC++,Wall) Init(0) CPP(cpp_warn_cxx20_compat) CppReason(CPP_W_CXX20_COMPAT) Warn about C++ constructs whose meaning differs between ISO C++ 2017 and ISO C++ 2020. +Wc++26-compat +C++ ObjC++ Var(warn_cxx26_compat) Warning LangEnabledBy(C++ ObjC++,Wall) Init(0) +Warn about C++ constructs whose meaning differs between ISO C++ 2023 and ISO C++ 2026. + Wc++11-extensions C++ ObjC++ Var(warn_cxx11_extensions) Warning Init(1) Warn about C++11 constructs in code compiled with an older standard. @@ -1319,6 +1327,14 @@ Wsequence-point C ObjC C++ ObjC++ Var(warn_sequence_point) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Warn about possible violations of sequence point rules. +Wsfinae-incomplete= +C++ ObjC++ Var(warn_sfinae_incomplete) Warning Init(1) Joined RejectNegative UInteger IntegerRange(0, 2) +Warn about an incomplete type affecting semantics in a non-error context. + +Wsfinae-incomplete +C++ ObjC++ Warning Alias(Wsfinae-incomplete=, 1, 0) +Warn about an incomplete type affecting semantics in a non-error context. + Wshadow-ivar ObjC ObjC++ Var(warn_shadow_ivar) EnabledBy(Wshadow) Init(1) Warning Warn if a local declaration hides an instance variable. diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls index ad6d8a0b3873..5c97593d703b 100644 --- a/gcc/c-family/c.opt.urls +++ b/gcc/c-family/c.opt.urls @@ -139,6 +139,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Warray-parameter) Wassign-intercept UrlSuffix(gcc/Objective-C-and-Objective-C_002b_002b-Dialect-Options.html#index-Wassign-intercept) +Wabbreviated-auto-in-template-arg +UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wabbreviated-auto-in-template-arg) + Wbad-function-cast UrlSuffix(gcc/Warning-Options.html#index-Wbad-function-cast) @@ -187,6 +190,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Wc_002b_002b17-compat) Wc++20-compat UrlSuffix(gcc/Warning-Options.html#index-Wc_002b_002b20-compat) +Wc++26-compat +UrlSuffix(gcc/Warning-Options.html#index-Wc_002b_002b26-compat) + Wc++11-extensions UrlSuffix(gcc/Warning-Options.html#index-Wc_002b_002b11-extensions) @@ -756,6 +762,12 @@ UrlSuffix(gcc/Warning-Options.html#index-Wno-self-move) Wsequence-point UrlSuffix(gcc/Warning-Options.html#index-Wno-sequence-point) +Wsfinae-incomplete= +UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wno-sfinae-incomplete) + +Wsfinae-incomplete +UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wno-sfinae-incomplete) + Wshadow-ivar UrlSuffix(gcc/Warning-Options.html#index-Wno-shadow-ivar) diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 7f5b0b8df900..a6dffa1714e5 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,133 @@ +2025-07-21 Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org> + + * c-typeck.cc (build_asm_expr): Pass null pointer to + parse_{input,output}_constraint(). + +2025-07-16 Kwok Cheung Yeung <kcyeung@baylibre.com> + + * c-typeck.cc (handle_omp_array_sections): Use OMP_ITERATOR_DECL_P. + (c_finish_omp_clauses): Likewise. + +2025-07-15 Jakub Jelinek <jakub@redhat.com> + Jason Merrill <jason@redhat.com> + + PR c/44677 + * c-parser.cc (c_parser_unary_expression): Clear DECL_READ_P + after default_function_array_read_conversion for + -Wunused-but-set-{parameter,variable}={2,3} on + PRE{IN,DE}CREMENT_EXPR argument. + (c_parser_postfix_expression_after_primary): Similarly for + POST{IN,DE}CREMENT_EXPR. + * c-decl.cc (pop_scope): Use OPT_Wunused_but_set_variable_ + instead of OPT_Wunused_but_set_variable. + (finish_function): Use OPT_Wunused_but_set_parameter_ + instead of OPT_Wunused_but_set_parameter. + * c-typeck.cc (mark_exp_read): Handle {PRE,POST}{IN,DE}CREMENT_EXPR + and don't handle it when cast to void. + (build_modify_expr): Clear DECL_READ_P after build_binary_op + for -Wunused-but-set-{parameter,variable}=3. + +2025-07-10 Qing Zhao <qing.zhao@oracle.com> + + * c-typeck.cc (build_access_with_size_for_counted_by): Update comments. + Adjust the arguments per the new design. + +2025-07-10 Qing Zhao <qing.zhao@oracle.com> + + PR middle-end/121000 + * c-typeck.cc (build_access_with_size_for_counted_by): Update comments. + Pass TYPE_SIZE_UNIT of the element as the 6th argument. + +2025-07-07 Qing Zhao <qing.zhao@oracle.com> + + Revert: + 2025-07-07 Qing Zhao <qing.zhao@oracle.com> + + * c-decl.cc (verify_counted_by_attribute): Change the 2nd argument + to a vector of fields with counted_by attribute. Verify all fields + in this vector. + (finish_struct): Collect all the fields with counted_by attribute + to a vector and pass this vector to verify_counted_by_attribute. + * c-typeck.cc (build_counted_by_ref): Handle pointers with counted_by. + Add one more argument, issue error when the pointee type is a structure + or union including a flexible array member. + (build_access_with_size_for_counted_by): Handle pointers with counted_by. + (handle_counted_by_for_component_ref): Call build_counted_by_ref + with the new prototype. + +2025-07-01 Qing Zhao <qing.zhao@oracle.com> + + * c-decl.cc (verify_counted_by_attribute): Change the 2nd argument + to a vector of fields with counted_by attribute. Verify all fields + in this vector. + (finish_struct): Collect all the fields with counted_by attribute + to a vector and pass this vector to verify_counted_by_attribute. + * c-typeck.cc (build_counted_by_ref): Handle pointers with counted_by. + Add one more argument, issue error when the pointee type is a structure + or union including a flexible array member. + (build_access_with_size_for_counted_by): Handle pointers with counted_by. + (handle_counted_by_for_component_ref): Call build_counted_by_ref + with the new prototype. + +2025-06-23 Tobias Burnus <tburnus@baylibre.com> + + * c-parser.cc (OACC_WAIT_CLAUSE_MASK): Add if clause. + +2025-06-12 Jakub Jelinek <jakub@redhat.com> + + * c-lang.h (union lang_type::maybe_objc_info): New type. + (struct lang_type): Use union maybe_objc_info info member + instead of tree objc_info. + * c-decl.cc (finish_struct): Allocate struct lang_type using + ggc_internal_cleared_alloc instead of ggc_cleared_alloc, + and use sizeof (struct lang_type) for ObjC and otherwise + offsetof (struct lang_type, info) as size. + (finish_enum): Likewise. + +2025-06-11 Martin Uecker <uecker@tugraz.at> + + PR c/120510 + * c-typeck.cc (composite_type_internal): Activate checking + assertions for all types and also inputs. + (comptypes_for_composite_check): New helper function. + (function_types_compatible_p): Add exception. + +2025-06-11 Martin Uecker <uecker@tugraz.at> + + * c-typeck.cc (function_types_compatible_p): Remove unused + variables and return true/false instead of 1/0. + (type_lists_compatible_p): Return false instead of 0. + +2025-06-11 Martin Uecker <uecker@tugraz.at> + + PR c/120303 + * c-parser.cc (c_parser_generic_selection): Handle error + condition. + +2025-06-09 Martin Uecker <uecker@tugraz.at> + + PR c/120510 + * c-typeck.cc (remove_qualifiers): New function. + (composite_type_internal): Use it. + (comp_target_types): Use it. + (type_lists_compatible_p): Use it. + (find_anonymous_field_with_type): Use it. + (convert_to_anonymous_field): Use it. + (convert_for_assignment): Use it. + +2025-06-09 Martin Uecker <uecker@tugraz.at> + + PR c/120510 + * c-typeck.cc (composite_type_internal): Activate checking + assertion for arrays. + (common_pointer_type): Remove qualifiers also from arrays. + +2025-06-09 Martin Uecker <uecker@tugraz.at> + + PR c/120510 + * c-typeck.cc (composite_types_internal): Handle arrays + declared with atomic for function arguments. + 2025-06-03 Martin Uecker <uecker@tugraz.at> * c-typeck.cc (composite_type_internal,composite_type): Move diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 2b0bd663ba91..acbe2b88e674 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -1363,7 +1363,7 @@ pop_scope (void) case VAR_DECL: /* Warnings for unused variables. */ if ((!TREE_USED (p) || !DECL_READ_P (p)) - && !warning_suppressed_p (p, OPT_Wunused_but_set_variable) + && !warning_suppressed_p (p, OPT_Wunused_but_set_variable_) && !DECL_IN_SYSTEM_HEADER (p) && DECL_NAME (p) && !DECL_ARTIFICIAL (p) @@ -1377,7 +1377,7 @@ pop_scope (void) } else if (DECL_CONTEXT (p) == current_function_decl) warning_at (DECL_SOURCE_LOCATION (p), - OPT_Wunused_but_set_variable, + OPT_Wunused_but_set_variable_, "variable %qD set but not used", p); } @@ -9790,12 +9790,17 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, len += list_length (x); /* Use the same allocation policy here that make_node uses, to - ensure that this lives as long as the rest of the struct decl. - All decls in an inline function need to be saved. */ - - space = ggc_cleared_alloc<struct lang_type> (); - space2 = (sorted_fields_type *) ggc_internal_alloc - (sizeof (struct sorted_fields_type) + len * sizeof (tree)); + ensure that this lives as long as the rest of the struct decl. + All decls in an inline function need to be saved. */ + + space = ((struct lang_type *) + ggc_internal_cleared_alloc (c_dialect_objc () + ? sizeof (struct lang_type) + : offsetof (struct lang_type, + info))); + space2 = ((sorted_fields_type *) + ggc_internal_alloc (sizeof (struct sorted_fields_type) + + len * sizeof (tree))); len = 0; space->s = space2; @@ -10269,7 +10274,10 @@ finish_enum (tree enumtype, tree values, tree attributes) /* Record the min/max values so that we can warn about bit-field enumerations that are too small for the values. */ - lt = ggc_cleared_alloc<struct lang_type> (); + lt = ((struct lang_type *) + ggc_internal_cleared_alloc (c_dialect_objc () + ? sizeof (struct lang_type) + : offsetof (struct lang_type, info))); lt->enum_min = minnode; lt->enum_max = maxnode; TYPE_LANG_SPECIFIC (enumtype) = lt; @@ -11457,9 +11465,9 @@ finish_function (location_t end_loc) && !DECL_READ_P (decl) && DECL_NAME (decl) && !DECL_ARTIFICIAL (decl) - && !warning_suppressed_p (decl, OPT_Wunused_but_set_parameter)) + && !warning_suppressed_p (decl, OPT_Wunused_but_set_parameter_)) warning_at (DECL_SOURCE_LOCATION (decl), - OPT_Wunused_but_set_parameter, + OPT_Wunused_but_set_parameter_, "parameter %qD set but not used", decl); } diff --git a/gcc/c/c-lang.h b/gcc/c/c-lang.h index 4b93d184dbca..2e99b4d86176 100644 --- a/gcc/c/c-lang.h +++ b/gcc/c/c-lang.h @@ -35,10 +35,14 @@ struct GTY(()) lang_type { /* In an ENUMERAL_TYPE, the min and max values. */ tree enum_min; tree enum_max; - /* In a RECORD_TYPE, information specific to Objective-C, such - as a list of adopted protocols or a pointer to a corresponding - @interface. See objc/objc-act.h for details. */ - tree objc_info; + union maybe_objc_info { + /* If not c_dialect_objc, this part is not even allocated. */ + char GTY((tag ("0"))) non_objc; + /* In a RECORD_TYPE, information specific to Objective-C, such + as a list of adopted protocols or a pointer to a corresponding + @interface. See objc/objc-act.h for details. */ + tree GTY((tag ("1"))) objc_info; + } GTY ((desc ("c_dialect_objc ()"))) info; }; struct GTY(()) lang_decl { diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 85580c57abfe..5119841a5895 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -10547,15 +10547,31 @@ c_parser_unary_expression (c_parser *parser) c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); - - op = default_function_array_read_conversion (exp_loc, op); + if ((VAR_P (op.value) || TREE_CODE (op.value) == PARM_DECL) + && !DECL_READ_P (op.value) + && (VAR_P (op.value) ? warn_unused_but_set_variable + : warn_unused_but_set_parameter) > 1) + { + op = default_function_array_read_conversion (exp_loc, op); + DECL_READ_P (op.value) = 0; + } + else + op = default_function_array_read_conversion (exp_loc, op); return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op); case CPP_MINUS_MINUS: c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); - - op = default_function_array_read_conversion (exp_loc, op); + if ((VAR_P (op.value) || TREE_CODE (op.value) == PARM_DECL) + && !DECL_READ_P (op.value) + && (VAR_P (op.value) ? warn_unused_but_set_variable + : warn_unused_but_set_parameter) > 1) + { + op = default_function_array_read_conversion (exp_loc, op); + DECL_READ_P (op.value) = 0; + } + else + op = default_function_array_read_conversion (exp_loc, op); return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op); case CPP_AND: c_parser_consume_token (parser); @@ -11146,8 +11162,14 @@ c_parser_generic_selection (c_parser *parser) "ISO C does not support use of type name as %<_Generic%> " "controlling operand before C2Y"); struct c_type_name *type = c_parser_type_name (parser); - selector_type = groktypename (type, NULL, NULL); + if (type) + selector_type = groktypename (type, NULL, NULL); c_inhibit_evaluation_warnings--; + if (!type) + { + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); + return error_expr; + } } else { @@ -13927,7 +13949,17 @@ c_parser_postfix_expression_after_primary (c_parser *parser, start = expr.get_start (); finish = c_parser_peek_token (parser)->get_finish (); c_parser_consume_token (parser); - expr = default_function_array_read_conversion (expr_loc, expr); + if ((VAR_P (expr.value) || TREE_CODE (expr.value) == PARM_DECL) + && !DECL_READ_P (expr.value) + && (VAR_P (expr.value) ? warn_unused_but_set_variable + : warn_unused_but_set_parameter) > 1 + && TREE_CODE (TREE_TYPE (expr.value)) != ARRAY_TYPE) + { + expr = default_function_array_read_conversion (expr_loc, expr); + DECL_READ_P (expr.value) = 0; + } + else + expr = default_function_array_read_conversion (expr_loc, expr); expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR, expr.value, false); set_c_expr_source_range (&expr, start, finish); @@ -13939,7 +13971,17 @@ c_parser_postfix_expression_after_primary (c_parser *parser, start = expr.get_start (); finish = c_parser_peek_token (parser)->get_finish (); c_parser_consume_token (parser); - expr = default_function_array_read_conversion (expr_loc, expr); + if ((VAR_P (expr.value) || TREE_CODE (expr.value) == PARM_DECL) + && !DECL_READ_P (expr.value) + && (VAR_P (expr.value) ? warn_unused_but_set_variable + : warn_unused_but_set_parameter) > 1 + && TREE_CODE (TREE_TYPE (expr.value)) != ARRAY_TYPE) + { + expr = default_function_array_read_conversion (expr_loc, expr); + DECL_READ_P (expr.value) = 0; + } + else + expr = default_function_array_read_conversion (expr_loc, expr); expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR, expr.value, false); set_c_expr_source_range (&expr, start, finish); @@ -22495,7 +22537,8 @@ c_parser_oacc_update (c_parser *parser) */ #define OACC_WAIT_CLAUSE_MASK \ - ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) ) + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) ) static tree c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name) diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index b59b5c8a8bb1..e022e61c6b19 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -136,6 +136,7 @@ static int lvalue_or_else (location_t, const_tree, enum lvalue_use); static void record_maybe_used_decl (tree); static bool comptypes_internal (const_tree, const_tree, struct comptypes_data *data); +static bool comptypes_check_for_composite (tree t1, tree t2); /* Return true if EXP is a null pointer constant, false otherwise. */ @@ -613,6 +614,17 @@ c_type_tag (const_tree t) return name; } +/* Remove qualifiers but not atomic. For arrays remove qualifiers + on the element type but also do not remove atomic. */ +static tree +remove_qualifiers (tree t) +{ + if (!t || t == error_mark_node) + return t; + return TYPE_ATOMIC (strip_array_types (t)) + ? c_build_qualified_type (TYPE_MAIN_VARIANT (t), TYPE_QUAL_ATOMIC) + : TYPE_MAIN_VARIANT (t); +} /* Return the composite type of two compatible types. @@ -910,15 +922,8 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache) for (; p1 && p1 != void_list_node; p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n)) { - tree mv1 = TREE_VALUE (p1); - if (mv1 && mv1 != error_mark_node - && TREE_CODE (mv1) != ARRAY_TYPE) - mv1 = TYPE_MAIN_VARIANT (mv1); - - tree mv2 = TREE_VALUE (p2); - if (mv2 && mv2 != error_mark_node - && TREE_CODE (mv2) != ARRAY_TYPE) - mv2 = TYPE_MAIN_VARIANT (mv2); + tree mv1 = remove_qualifiers (TREE_VALUE (p1)); + tree mv2 = remove_qualifiers (TREE_VALUE (p2)); /* A null type means arg type is not specified. Take whatever the other function type has. */ @@ -998,15 +1003,13 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache) tree composite_type (tree t1, tree t2) { + gcc_checking_assert (comptypes_check_for_composite (t1, t2)); + struct composite_cache cache = { }; tree n = composite_type_internal (t1, t2, &cache); - /* For function and arrays there are some cases where qualifiers do - not match. See PR120510. */ - if (FUNCTION_TYPE != TREE_CODE (n) && ARRAY_TYPE != TREE_CODE (n)) - { - gcc_checking_assert (comptypes (n, t1)); - gcc_checking_assert (comptypes (n, t2)); - } + + gcc_checking_assert (comptypes_check_for_composite (n, t1)); + gcc_checking_assert (comptypes_check_for_composite (n, t2)); return n; } @@ -1020,9 +1023,6 @@ static tree common_pointer_type (tree t1, tree t2) { tree attributes; - tree pointed_to_1, mv1; - tree pointed_to_2, mv2; - tree target; unsigned target_quals; addr_space_t as1, as2, as_common; int quals1, quals2; @@ -1044,15 +1044,11 @@ common_pointer_type (tree t1, tree t2) attributes = targetm.merge_type_attributes (t1, t2); /* Find the composite type of the target types, and combine the - qualifiers of the two types' targets. Do not lose qualifiers on - array element types by taking the TYPE_MAIN_VARIANT. */ - mv1 = pointed_to_1 = TREE_TYPE (t1); - mv2 = pointed_to_2 = TREE_TYPE (t2); - if (TREE_CODE (mv1) != ARRAY_TYPE) - mv1 = TYPE_MAIN_VARIANT (pointed_to_1); - if (TREE_CODE (mv2) != ARRAY_TYPE) - mv2 = TYPE_MAIN_VARIANT (pointed_to_2); - target = composite_type (mv1, mv2); + qualifiers of the two types' targets. */ + tree pointed_to_1 = TREE_TYPE (t1); + tree pointed_to_2 = TREE_TYPE (t2); + tree target = composite_type (TYPE_MAIN_VARIANT (pointed_to_1), + TYPE_MAIN_VARIANT (pointed_to_2)); /* Strip array types to get correct qualifier for pointers to arrays */ quals1 = TYPE_QUALS_NO_ADDR_SPACE (strip_array_types (pointed_to_1)); @@ -1457,16 +1453,39 @@ comptypes_verify (tree type1, tree type2) } struct comptypes_data { + + /* output */ bool enum_and_int_p; bool different_types_p; bool warning_needed; + + /* context */ bool anon_field; bool pointedto; + + /* configuration */ bool equiv; + bool ignore_promoting_args; const struct tagged_tu_seen_cache* cache; }; + +/* Helper function for composite_type. This function ignores when the + function type of an old-style declaration is incompatible with a type + of a declaration with prototype because some are arguments are not + self-promoting. This is ignored only for function types but not + ignored in a nested context. */ + +static bool +comptypes_check_for_composite (tree t1, tree t2) +{ + struct comptypes_data data = { }; + data.ignore_promoting_args = FUNCTION_TYPE == TREE_CODE (t1); + return comptypes_internal (t1, t2, &data); +} + + /* C implementation of compatible_types_for_indirection_note_p. */ bool @@ -1596,6 +1615,10 @@ comptypes_equiv_p (tree type1, tree type2) permitted in C11 typedef redeclarations, then this sets 'different_types_p' in DATA to true; it is never set to false, but may or may not be set if the types are incompatible. + If two functions types are not compatible only because one is + an old-style definition that does not have self-promoting arguments, + then this can be ignored by setting 'ignore_promoting_args_p'. + For 'equiv' we can compute equivalency classes (see above). This differs from comptypes, in that we don't free the seen types. */ @@ -1794,15 +1817,9 @@ comp_target_types (location_t location, tree ttl, tree ttr) val_ped = comptypes (mvl, mvr); /* Qualifiers on element types of array types that are - pointer targets are lost by taking their TYPE_MAIN_VARIANT. */ - - mvl = (TYPE_ATOMIC (strip_array_types (mvl)) - ? c_build_qualified_type (TYPE_MAIN_VARIANT (mvl), TYPE_QUAL_ATOMIC) - : TYPE_MAIN_VARIANT (mvl)); - - mvr = (TYPE_ATOMIC (strip_array_types (mvr)) - ? c_build_qualified_type (TYPE_MAIN_VARIANT (mvr), TYPE_QUAL_ATOMIC) - : TYPE_MAIN_VARIANT (mvr)); + pointer targets are also removed. */ + mvl = remove_qualifiers (mvl); + mvr = remove_qualifiers (mvr); enum_and_int_p = false; val = comptypes_check_enum_int (mvl, mvr, &enum_and_int_p); @@ -2025,14 +2042,8 @@ static bool function_types_compatible_p (const_tree f1, const_tree f2, struct comptypes_data *data) { - tree args1, args2; - /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - int val = 1; - int val1; - tree ret1, ret2; - - ret1 = TREE_TYPE (f1); - ret2 = TREE_TYPE (f2); + tree ret1 = TREE_TYPE (f1); + tree ret2 = TREE_TYPE (f2); /* 'volatile' qualifiers on a function's return type used to mean the function is noreturn. */ @@ -2044,12 +2055,17 @@ function_types_compatible_p (const_tree f1, const_tree f2, if (TYPE_VOLATILE (ret2)) ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2), TYPE_QUALS (ret2) & ~TYPE_QUAL_VOLATILE); - val = comptypes_internal (ret1, ret2, data); - if (val == 0) - return 0; - args1 = TYPE_ARG_TYPES (f1); - args2 = TYPE_ARG_TYPES (f2); + bool ignore_pargs = data->ignore_promoting_args; + data->ignore_promoting_args = false; + + if (!comptypes_internal (ret1, ret2, data)) + return false; + + data->ignore_promoting_args = ignore_pargs; + + tree args1 = TYPE_ARG_TYPES (f1); + tree args2 = TYPE_ARG_TYPES (f2); if ((args1 == NULL_TREE) != (args2 == NULL_TREE)) data->different_types_p = true; @@ -2060,40 +2076,33 @@ function_types_compatible_p (const_tree f1, const_tree f2, if (args1 == NULL_TREE) { if (TYPE_NO_NAMED_ARGS_STDARG_P (f1) != TYPE_NO_NAMED_ARGS_STDARG_P (f2)) - return 0; - if (!self_promoting_args_p (args2)) - return 0; + return false; + if (!(data->ignore_promoting_args || self_promoting_args_p (args2))) + return false; + data->ignore_promoting_args = false; /* If one of these types comes from a non-prototype fn definition, compare that with the other type's arglist. If they don't match, ask for a warning (but no error). */ if (TYPE_ACTUAL_ARG_TYPES (f1) - && type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1), - data) != 1) - { - val = 1; - data->warning_needed = true; - } - return val; + && !type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1), data)) + data->warning_needed = true; + return true; } if (args2 == NULL_TREE) { if (TYPE_NO_NAMED_ARGS_STDARG_P (f1) != TYPE_NO_NAMED_ARGS_STDARG_P (f2)) - return 0; - if (!self_promoting_args_p (args1)) - return 0; + return false; + if (!(data->ignore_promoting_args || self_promoting_args_p (args1))) + return false; + data->ignore_promoting_args = false; if (TYPE_ACTUAL_ARG_TYPES (f2) - && type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2), - data) != 1) - { - val = 1; - data->warning_needed = true; - } - return val; + && !type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2), data)) + data->warning_needed = true; + return true; } /* Both types have argument lists: compare them and propagate results. */ - val1 = type_lists_compatible_p (args1, args2, data); - return val1; + return type_lists_compatible_p (args1, args2, data); } /* Check two lists of types for compatibility, returning false for @@ -2105,25 +2114,16 @@ type_lists_compatible_p (const_tree args1, const_tree args2, { while (1) { - tree a1, mv1, a2, mv2; if (args1 == NULL_TREE && args2 == NULL_TREE) return true; /* If one list is shorter than the other, they fail to match. */ if (args1 == NULL_TREE || args2 == NULL_TREE) - return 0; - mv1 = a1 = TREE_VALUE (args1); - mv2 = a2 = TREE_VALUE (args2); - if (mv1 && mv1 != error_mark_node && TREE_CODE (mv1) != ARRAY_TYPE) - mv1 = (TYPE_ATOMIC (mv1) - ? c_build_qualified_type (TYPE_MAIN_VARIANT (mv1), - TYPE_QUAL_ATOMIC) - : TYPE_MAIN_VARIANT (mv1)); - if (mv2 && mv2 != error_mark_node && TREE_CODE (mv2) != ARRAY_TYPE) - mv2 = (TYPE_ATOMIC (mv2) - ? c_build_qualified_type (TYPE_MAIN_VARIANT (mv2), - TYPE_QUAL_ATOMIC) - : TYPE_MAIN_VARIANT (mv2)); + return false; + tree a1 = TREE_VALUE (args1); + tree a2 = TREE_VALUE (args2); + tree mv1 = remove_qualifiers (a1); + tree mv2 = remove_qualifiers (a2); /* A null pointer instead of a type means there is supposed to be an argument but nothing is specified about what type it has. @@ -2133,12 +2133,12 @@ type_lists_compatible_p (const_tree args1, const_tree args2, if (a1 == NULL_TREE) { if (c_type_promotes_to (a2) != a2) - return 0; + return false; } else if (a2 == NULL_TREE) { if (c_type_promotes_to (a1) != a1) - return 0; + return false; } /* If one of the lists has an error marker, ignore this arg. */ else if (TREE_CODE (a1) == ERROR_MARK @@ -2160,18 +2160,12 @@ type_lists_compatible_p (const_tree args1, const_tree args2, for (memb = TYPE_FIELDS (a1); memb; memb = DECL_CHAIN (memb)) { - tree mv3 = TREE_TYPE (memb); - if (mv3 && mv3 != error_mark_node - && TREE_CODE (mv3) != ARRAY_TYPE) - mv3 = (TYPE_ATOMIC (mv3) - ? c_build_qualified_type (TYPE_MAIN_VARIANT (mv3), - TYPE_QUAL_ATOMIC) - : TYPE_MAIN_VARIANT (mv3)); + tree mv3 = remove_qualifiers (TREE_TYPE (memb)); if (comptypes_internal (mv3, mv2, data)) break; } if (memb == NULL_TREE) - return 0; + return false; } else if (TREE_CODE (a2) == UNION_TYPE && (TYPE_NAME (a2) == NULL_TREE @@ -2184,21 +2178,15 @@ type_lists_compatible_p (const_tree args1, const_tree args2, for (memb = TYPE_FIELDS (a2); memb; memb = DECL_CHAIN (memb)) { - tree mv3 = TREE_TYPE (memb); - if (mv3 && mv3 != error_mark_node - && TREE_CODE (mv3) != ARRAY_TYPE) - mv3 = (TYPE_ATOMIC (mv3) - ? c_build_qualified_type (TYPE_MAIN_VARIANT (mv3), - TYPE_QUAL_ATOMIC) - : TYPE_MAIN_VARIANT (mv3)); + tree mv3 = remove_qualifiers (TREE_TYPE (memb)); if (comptypes_internal (mv3, mv1, data)) break; } if (memb == NULL_TREE) - return 0; + return false; } else - return 0; + return false; } args1 = TREE_CHAIN (args1); @@ -2322,14 +2310,30 @@ mark_exp_read (tree exp) case PARM_DECL: DECL_READ_P (exp) = 1; break; + CASE_CONVERT: + if (VOID_TYPE_P (TREE_TYPE (exp))) + switch (TREE_CODE (TREE_OPERAND (exp, 0))) + { + case PREINCREMENT_EXPR: + case PREDECREMENT_EXPR: + case POSTINCREMENT_EXPR: + case POSTDECREMENT_EXPR: + return; + default: + break; + } + /* FALLTHRU */ case ARRAY_REF: case COMPONENT_REF: case MODIFY_EXPR: case REALPART_EXPR: case IMAGPART_EXPR: - CASE_CONVERT: case ADDR_EXPR: case VIEW_CONVERT_EXPR: + case PREINCREMENT_EXPR: + case PREDECREMENT_EXPR: + case POSTINCREMENT_EXPR: + case POSTDECREMENT_EXPR: mark_exp_read (TREE_OPERAND (exp, 0)); break; case COMPOUND_EXPR: @@ -2994,8 +2998,8 @@ build_counted_by_ref (tree datum, tree subdatum, tree *counted_by_type) to: - (*.ACCESS_WITH_SIZE (REF, COUNTED_BY_REF, 1, (TYPE_OF_SIZE)0, -1, - (TYPE_OF_ARRAY *)0)) + (*.ACCESS_WITH_SIZE (REF, COUNTED_BY_REF, (* TYPE_OF_SIZE)0, + TYPE_SIZE_UNIT for element) NOTE: The return type of this function is the POINTER type pointing to the original flexible array type. @@ -3004,11 +3008,11 @@ build_counted_by_ref (tree datum, tree subdatum, tree *counted_by_type) The type of the first argument of this function is a POINTER type to the original flexible array type. - The 4th argument of the call is a constant 0 with the TYPE of the - object pointed by COUNTED_BY_REF. + The 3rd argument of the call is a constant 0 with the pointer TYPE whose + pointee type is the TYPE of the object pointed by COUNTED_BY_REF. - The 6th argument of the call is a constant 0 with the pointer TYPE - to the original flexible array type. + The 4th argument of the call is the TYPE_SIZE_UNIT of the element TYPE + of the array. */ static tree @@ -3019,20 +3023,22 @@ build_access_with_size_for_counted_by (location_t loc, tree ref, gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref))); /* The result type of the call is a pointer to the flexible array type. */ tree result_type = c_build_pointer_type (TREE_TYPE (ref)); + tree element_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ref))); + tree first_param = c_fully_fold (array_to_pointer_conversion (loc, ref), false, NULL); tree second_param = c_fully_fold (counted_by_ref, false, NULL); + tree third_param = build_int_cst (build_pointer_type (counted_by_type), 0); tree call = build_call_expr_internal_loc (loc, IFN_ACCESS_WITH_SIZE, - result_type, 6, + result_type, 4, first_param, second_param, - build_int_cst (integer_type_node, 1), - build_int_cst (counted_by_type, 0), - build_int_cst (integer_type_node, -1), - build_int_cst (result_type, 0)); + third_param, + element_size); + /* Wrap the call with an INDIRECT_REF with the flexible array type. */ call = build1 (INDIRECT_REF, TREE_TYPE (ref), call); SET_EXPR_LOCATION (call, loc); @@ -7318,8 +7324,21 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype, newrhs = build1 (EXCESS_PRECISION_EXPR, TREE_TYPE (rhs), newrhs); } + bool clear_decl_read = false; + if ((VAR_P (lhs) || TREE_CODE (lhs) == PARM_DECL) + && !DECL_READ_P (lhs) + && (VAR_P (lhs) ? warn_unused_but_set_variable + : warn_unused_but_set_parameter) > 2) + { + mark_exp_read (newrhs); + if (!DECL_READ_P (lhs)) + clear_decl_read = true; + } + newrhs = build_binary_op (location, modifycode, lhs, newrhs, true); + if (clear_decl_read) + DECL_READ_P (lhs) = 0; /* The original type of the right hand side is no longer meaningful. */ @@ -7482,10 +7501,7 @@ find_anonymous_field_with_type (tree struct_type, tree type) field != NULL_TREE; field = TREE_CHAIN (field)) { - tree fieldtype = (TYPE_ATOMIC (TREE_TYPE (field)) - ? c_build_qualified_type (TREE_TYPE (field), - TYPE_QUAL_ATOMIC) - : TYPE_MAIN_VARIANT (TREE_TYPE (field))); + tree fieldtype = remove_qualifiers (TREE_TYPE (field)); if (DECL_NAME (field) == NULL && comptypes (type, fieldtype)) { @@ -7523,10 +7539,7 @@ convert_to_anonymous_field (location_t location, tree type, tree rhs) gcc_assert (RECORD_OR_UNION_TYPE_P (rhs_struct_type)); gcc_assert (POINTER_TYPE_P (type)); - lhs_main_type = (TYPE_ATOMIC (TREE_TYPE (type)) - ? c_build_qualified_type (TREE_TYPE (type), - TYPE_QUAL_ATOMIC) - : TYPE_MAIN_VARIANT (TREE_TYPE (type))); + lhs_main_type = remove_qualifiers (TREE_TYPE (type)); found_field = NULL_TREE; found_sub_field = false; @@ -7537,10 +7550,7 @@ convert_to_anonymous_field (location_t location, tree type, tree rhs) if (DECL_NAME (field) != NULL_TREE || !RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))) continue; - tree fieldtype = (TYPE_ATOMIC (TREE_TYPE (field)) - ? c_build_qualified_type (TREE_TYPE (field), - TYPE_QUAL_ATOMIC) - : TYPE_MAIN_VARIANT (TREE_TYPE (field))); + tree fieldtype = remove_qualifiers (TREE_TYPE (field)); if (comptypes (lhs_main_type, fieldtype)) { if (found_field != NULL_TREE) @@ -8297,23 +8307,14 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, tree ttl = TREE_TYPE (type); tree ttr = TREE_TYPE (rhstype); - tree mvl = ttl; - tree mvr = ttr; bool is_opaque_pointer; bool target_cmp = false; /* Cache comp_target_types () result. */ addr_space_t asl; addr_space_t asr; - if (TREE_CODE (mvl) != ARRAY_TYPE) - mvl = (TYPE_ATOMIC (mvl) - ? c_build_qualified_type (TYPE_MAIN_VARIANT (mvl), - TYPE_QUAL_ATOMIC) - : TYPE_MAIN_VARIANT (mvl)); - if (TREE_CODE (mvr) != ARRAY_TYPE) - mvr = (TYPE_ATOMIC (mvr) - ? c_build_qualified_type (TYPE_MAIN_VARIANT (mvr), - TYPE_QUAL_ATOMIC) - : TYPE_MAIN_VARIANT (mvr)); + tree mvl = remove_qualifiers (ttl); + tree mvr = remove_qualifiers (ttr); + /* Opaque pointers are treated like void pointers. */ is_opaque_pointer = vector_targets_convertible_p (ttl, ttr); @@ -12645,7 +12646,8 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs, oconstraints[i] = constraint; if (parse_output_constraint (&constraint, i, ninputs, noutputs, - &allows_mem, &allows_reg, &is_inout)) + &allows_mem, &allows_reg, &is_inout, + nullptr)) { /* If the operand is going to end up in memory, mark it addressable. */ @@ -12706,7 +12708,8 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs, input = TREE_VALUE (tail); if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0, - oconstraints, &allows_mem, &allows_reg)) + oconstraints, &allows_mem, &allows_reg, + nullptr)) { /* If the operand is going to end up in memory, mark it addressable. */ @@ -15636,9 +15639,7 @@ handle_omp_array_sections (tree &c, enum c_omp_region_type ort) tree *tp = &OMP_CLAUSE_DECL (c); if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY) - && TREE_CODE (*tp) == TREE_LIST - && TREE_PURPOSE (*tp) - && TREE_CODE (TREE_PURPOSE (*tp)) == TREE_VEC) + && OMP_ITERATOR_DECL_P (*tp)) tp = &TREE_VALUE (*tp); tree first = handle_omp_array_sections_1 (c, *tp, types, maybe_zero_len, first_non_one, @@ -16835,9 +16836,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) /* FALLTHRU */ case OMP_CLAUSE_AFFINITY: t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) == TREE_LIST - && TREE_PURPOSE (t) - && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) + if (OMP_ITERATOR_DECL_P (t)) { if (TREE_PURPOSE (t) != last_iterators) last_iterators_remove @@ -16937,10 +16936,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) break; } } - if (TREE_CODE (OMP_CLAUSE_DECL (c)) == TREE_LIST - && TREE_PURPOSE (OMP_CLAUSE_DECL (c)) - && (TREE_CODE (TREE_PURPOSE (OMP_CLAUSE_DECL (c))) - == TREE_VEC)) + if (OMP_ITERATOR_DECL_P (OMP_CLAUSE_DECL (c))) TREE_VALUE (OMP_CLAUSE_DECL (c)) = t; else OMP_CLAUSE_DECL (c) = t; diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc index 8919cc33539b..8950294abb60 100644 --- a/gcc/cfgexpand.cc +++ b/gcc/cfgexpand.cc @@ -74,6 +74,8 @@ along with GCC; see the file COPYING3. If not see #include "output.h" #include "builtins.h" #include "opts.h" +#include "gimple-range.h" +#include "rtl-iter.h" /* Some systems use __main in a way incompatible with its use in gcc, in these cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to @@ -2771,6 +2773,10 @@ maybe_dump_rtl_for_gimple_stmt (gimple *stmt, rtx_insn *since) } } +/* Temporary storage for BB_HEAD and BB_END of bbs until they are converted + to BB_RTL. */ +static vec<std::pair <rtx_insn *, rtx_insn *>> head_end_for_bb; + /* Maps the blocks that do not contain tree labels to rtx labels. */ static hash_map<basic_block, rtx_code_label *> *lab_rtx_for_bb; @@ -2778,11 +2784,23 @@ static hash_map<basic_block, rtx_code_label *> *lab_rtx_for_bb; /* Returns the label_rtx expression for a label starting basic block BB. */ static rtx_code_label * -label_rtx_for_bb (basic_block bb ATTRIBUTE_UNUSED) +label_rtx_for_bb (basic_block bb) { if (bb->flags & BB_RTL) return block_label (bb); + if ((unsigned) bb->index < head_end_for_bb.length () + && head_end_for_bb[bb->index].first) + { + if (!LABEL_P (head_end_for_bb[bb->index].first)) + { + head_end_for_bb[bb->index].first + = emit_label_before (gen_label_rtx (), + head_end_for_bb[bb->index].first); + } + return as_a <rtx_code_label *> (head_end_for_bb[bb->index].first); + } + rtx_code_label **elt = lab_rtx_for_bb->get (bb); if (elt) return *elt; @@ -2801,6 +2819,44 @@ label_rtx_for_bb (basic_block bb ATTRIBUTE_UNUSED) } +/* Wrapper around remove_edge during expansion. */ + +void +expand_remove_edge (edge e) +{ + if (current_ir_type () != IR_GIMPLE + && (e->dest->flags & BB_RTL) == 0 + && !gimple_seq_empty_p (phi_nodes (e->dest))) + remove_phi_args (e); + remove_edge (e); +} + +/* Split edge E during expansion and instead of creating a new + bb on that edge, add there BB. FLAGS should be flags on the + new edge from BB to former E->dest. */ + +static void +expand_split_edge (edge e, basic_block bb, int flags) +{ + unsigned int dest_idx = e->dest_idx; + basic_block dest = e->dest; + redirect_edge_succ (e, bb); + e = make_single_succ_edge (bb, dest, flags); + if ((dest->flags & BB_RTL) == 0 + && phi_nodes (dest) + && e->dest_idx != dest_idx) + { + /* If there are any PHI nodes on dest, swap the new succ edge + with the one moved into false_edge's former position, so that + PHI arguments don't need adjustment. */ + edge e2 = EDGE_PRED (dest, dest_idx); + std::swap (e->dest_idx, e2->dest_idx); + std::swap (EDGE_PRED (dest, e->dest_idx), + EDGE_PRED (dest, e2->dest_idx)); + } +} + + /* A subroutine of expand_gimple_cond. Given E, a fallthrough edge of a basic block where we just expanded the conditional at the end, possibly clean up the CFG and instruction sequence. LAST is the @@ -2823,7 +2879,7 @@ maybe_cleanup_end_of_block (edge e, rtx_insn *last) if (BARRIER_P (get_last_insn ())) { rtx_insn *insn; - remove_edge (e); + expand_remove_edge (e); /* Now, we have a single successor block, if we have insns to insert on the remaining edge we potentially will insert it at the end of this block (if the dest block isn't feasible) @@ -2942,10 +2998,6 @@ expand_gimple_cond (basic_block bb, gcond *stmt) extract_true_false_edges_from_block (bb, &true_edge, &false_edge); set_curr_insn_location (gimple_location (stmt)); - /* These flags have no purpose in RTL land. */ - true_edge->flags &= ~EDGE_TRUE_VALUE; - false_edge->flags &= ~EDGE_FALSE_VALUE; - /* We can either have a pure conditional jump with one fallthru edge or two-way jump that needs to be decomposed into two basic blocks. */ if (false_edge->dest == bb->next_bb) @@ -2978,14 +3030,16 @@ expand_gimple_cond (basic_block bb, gcond *stmt) set_curr_insn_location (false_edge->goto_locus); emit_jump (label_rtx_for_bb (false_edge->dest)); - BB_END (bb) = last; - if (BARRIER_P (BB_END (bb))) - BB_END (bb) = PREV_INSN (BB_END (bb)); - update_bb_for_insn (bb); + head_end_for_bb[bb->index].second = last; + if (BARRIER_P (head_end_for_bb[bb->index].second)) + head_end_for_bb[bb->index].second + = PREV_INSN (head_end_for_bb[bb->index].second); + update_bb_for_insn_chain (head_end_for_bb[bb->index].first, + head_end_for_bb[bb->index].second, bb); new_bb = create_basic_block (NEXT_INSN (last), get_last_insn (), bb); dest = false_edge->dest; - redirect_edge_succ (false_edge, new_bb); + expand_split_edge (false_edge, new_bb, 0); false_edge->flags |= EDGE_FALLTHRU; new_bb->count = false_edge->count (); loop_p loop = find_common_loop (bb->loop_father, dest->loop_father); @@ -2993,7 +3047,6 @@ expand_gimple_cond (basic_block bb, gcond *stmt) if (loop->latch == bb && loop->header == dest) loop->latch = new_bb; - make_single_succ_edge (new_bb, dest, 0); if (BARRIER_P (BB_END (new_bb))) BB_END (new_bb) = PREV_INSN (BB_END (new_bb)); update_bb_for_insn (new_bb); @@ -3222,44 +3275,6 @@ expand_asm_loc (tree string, int vol, location_t locus) emit_insn (body); } -/* Return the number of times character C occurs in string S. */ -static int -n_occurrences (int c, const char *s) -{ - int n = 0; - while (*s) - n += (*s++ == c); - return n; -} - -/* A subroutine of expand_asm_operands. Check that all operands have - the same number of alternatives. Return true if so. */ - -static bool -check_operand_nalternatives (const vec<const char *> &constraints) -{ - unsigned len = constraints.length(); - if (len > 0) - { - int nalternatives = n_occurrences (',', constraints[0]); - - if (nalternatives + 1 > MAX_RECOG_ALTERNATIVES) - { - error ("too many alternatives in %<asm%>"); - return false; - } - - for (unsigned i = 1; i < len; ++i) - if (n_occurrences (',', constraints[i]) != nalternatives) - { - error ("operand constraints for %<asm%> differ " - "in number of alternatives"); - return false; - } - } - return true; -} - /* Check for overlap between registers marked in CLOBBERED_REGS and anything inappropriate in T. Emit error and return the register variable definition for error, NULL_TREE for ok. */ @@ -3425,10 +3440,6 @@ expand_asm_stmt (gasm *stmt) = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))); } - /* ??? Diagnose during gimplification? */ - if (! check_operand_nalternatives (constraints)) - return; - /* Count the number of meaningful clobbered registers, ignoring what we would ignore later. */ auto_vec<rtx> clobber_rvec; @@ -3502,7 +3513,8 @@ expand_asm_stmt (gasm *stmt) no point in going further. */ constraint = constraints[i]; if (!parse_output_constraint (&constraint, i, ninputs, noutputs, - &allows_mem, &allows_reg, &is_inout)) + &allows_mem, &allows_reg, &is_inout, + nullptr)) return; /* If the output is a hard register, verify it doesn't conflict with @@ -3580,8 +3592,8 @@ expand_asm_stmt (gasm *stmt) constraint = constraints[i + noutputs]; if (! parse_input_constraint (&constraint, i, ninputs, noutputs, 0, - constraints.address (), - &allows_mem, &allows_reg)) + constraints.address (), &allows_mem, + &allows_reg, nullptr)) return; if (! allows_reg && allows_mem) @@ -3611,7 +3623,7 @@ expand_asm_stmt (gasm *stmt) ok = parse_output_constraint (&constraints[i], i, ninputs, noutputs, &allows_mem, &allows_reg, - &is_inout); + &is_inout, nullptr); gcc_assert (ok); /* If an output operand is not a decl or indirect ref and our constraint @@ -3716,7 +3728,7 @@ expand_asm_stmt (gasm *stmt) constraint = constraints[i + noutputs]; ok = parse_input_constraint (&constraint, i, ninputs, noutputs, 0, constraints.address (), - &allows_mem, &allows_reg); + &allows_mem, &allows_reg, nullptr); gcc_assert (ok); /* EXPAND_INITIALIZER will not generate code for valid initializer @@ -4406,9 +4418,10 @@ expand_gimple_stmt (gimple *stmt) tailcall) and the normal result happens via a sqrt instruction. */ static basic_block -expand_gimple_tailcall (basic_block bb, gcall *stmt, bool *can_fallthru) +expand_gimple_tailcall (basic_block bb, gcall *stmt, bool *can_fallthru, + rtx_insn *asan_epilog_seq) { - rtx_insn *last2, *last; + rtx_insn *last2, *last, *first = get_last_insn (); edge e; edge_iterator ei; profile_probability probability; @@ -4425,6 +4438,58 @@ expand_gimple_tailcall (basic_block bb, gcall *stmt, bool *can_fallthru) return NULL; found: + + if (asan_epilog_seq) + { + /* We need to emit a copy of the asan_epilog_seq before + the insns emitted by expand_gimple_stmt above. The sequence + can contain labels, which need to be remapped. */ + hash_map<rtx, rtx> label_map; + start_sequence (); + emit_note (NOTE_INSN_DELETED); + for (rtx_insn *insn = asan_epilog_seq; insn; insn = NEXT_INSN (insn)) + switch (GET_CODE (insn)) + { + case INSN: + case CALL_INSN: + case JUMP_INSN: + emit_copy_of_insn_after (insn, get_last_insn ()); + break; + case CODE_LABEL: + label_map.put ((rtx) insn, (rtx) emit_label (gen_label_rtx ())); + break; + case BARRIER: + emit_barrier (); + break; + default: + gcc_unreachable (); + } + for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn)) + if (JUMP_P (insn)) + { + subrtx_ptr_iterator::array_type array; + FOR_EACH_SUBRTX_PTR (iter, array, &PATTERN (insn), ALL) + { + rtx *loc = *iter; + if (LABEL_REF_P (*loc)) + { + rtx *lab = label_map.get ((rtx) label_ref_label (*loc)); + gcc_assert (lab); + set_label_ref_label (*loc, as_a <rtx_insn *> (*lab)); + } + } + if (JUMP_LABEL (insn)) + { + rtx *lab = label_map.get (JUMP_LABEL (insn)); + gcc_assert (lab); + JUMP_LABEL (insn) = *lab; + } + } + asan_epilog_seq = NEXT_INSN (get_insns ()); + end_sequence (); + emit_insn_before (asan_epilog_seq, NEXT_INSN (first)); + } + /* ??? Wouldn't it be better to just reset any pending stack adjust? Any instructions emitted here are about to be deleted. */ do_pending_stack_adjust (); @@ -4445,7 +4510,7 @@ expand_gimple_tailcall (basic_block bb, gcall *stmt, bool *can_fallthru) if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)) e->dest->count -= e->count (); probability += e->probability; - remove_edge (e); + expand_remove_edge (e); } else ei_next (&ei); @@ -4473,8 +4538,9 @@ expand_gimple_tailcall (basic_block bb, gcall *stmt, bool *can_fallthru) e = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_ABNORMAL | EDGE_SIBCALL); e->probability = probability; - BB_END (bb) = last; - update_bb_for_insn (bb); + head_end_for_bb[bb->index].second = last; + update_bb_for_insn_chain (head_end_for_bb[bb->index].first, + head_end_for_bb[bb->index].second, bb); if (NEXT_INSN (last)) { @@ -5251,6 +5317,9 @@ expand_debug_expr (tree exp) return simplify_gen_binary (MULT, mode, op0, op1); case RDIV_EXPR: + gcc_assert (FLOAT_MODE_P (mode) + || ALL_FIXED_POINT_MODE_P (mode)); + /* Fall through. */ case TRUNC_DIV_EXPR: case EXACT_DIV_EXPR: if (unsignedp) @@ -6089,10 +6158,9 @@ reorder_operands (basic_block bb) /* Expand basic block BB from GIMPLE trees to RTL. */ static basic_block -expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) +expand_gimple_basic_block (basic_block bb, rtx_insn *asan_epilog_seq) { gimple_stmt_iterator gsi; - gimple_seq stmts; gimple *stmt = NULL; rtx_note *note = NULL; rtx_insn *last; @@ -6110,18 +6178,12 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) access the BB sequence directly. */ if (optimize) reorder_operands (bb); - stmts = bb_seq (bb); - bb->il.gimple.seq = NULL; - bb->il.gimple.phi_nodes = NULL; rtl_profile_for_bb (bb); - init_rtl_bb_info (bb); - bb->flags |= BB_RTL; /* Remove the RETURN_EXPR if we may fall though to the exit instead. */ - gsi = gsi_last (stmts); - if (!gsi_end_p (gsi) - && gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN) + gsi = gsi_last_bb (bb); + if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN) { greturn *ret_stmt = as_a <greturn *> (gsi_stmt (gsi)); @@ -6136,7 +6198,7 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) } } - gsi = gsi_start (stmts); + gsi = gsi_start_bb (bb); if (!gsi_end_p (gsi)) { stmt = gsi_stmt (gsi); @@ -6145,6 +6207,8 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) } rtx_code_label **elt = lab_rtx_for_bb->get (bb); + if ((unsigned) bb->index >= head_end_for_bb.length ()) + head_end_for_bb.safe_grow_cleared (bb->index + 1); if (stmt || elt) { @@ -6160,16 +6224,18 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) if (elt) emit_label (*elt); - BB_HEAD (bb) = NEXT_INSN (last); - if (NOTE_P (BB_HEAD (bb))) - BB_HEAD (bb) = NEXT_INSN (BB_HEAD (bb)); - gcc_assert (LABEL_P (BB_HEAD (bb))); - note = emit_note_after (NOTE_INSN_BASIC_BLOCK, BB_HEAD (bb)); + head_end_for_bb[bb->index].first = NEXT_INSN (last); + if (NOTE_P (head_end_for_bb[bb->index].first)) + head_end_for_bb[bb->index].first + = NEXT_INSN (head_end_for_bb[bb->index].first); + gcc_assert (LABEL_P (head_end_for_bb[bb->index].first)); + note = emit_note_after (NOTE_INSN_BASIC_BLOCK, + head_end_for_bb[bb->index].first); maybe_dump_rtl_for_gimple_stmt (stmt, last); } else - BB_HEAD (bb) = note = emit_note (NOTE_INSN_BASIC_BLOCK); + head_end_for_bb[bb->index].first = note = emit_note (NOTE_INSN_BASIC_BLOCK); if (note) NOTE_BASIC_BLOCK (note) = bb; @@ -6397,14 +6463,16 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) { gcall *call_stmt = dyn_cast <gcall *> (stmt); if (call_stmt + && asan_epilog_seq && gimple_call_tail_p (call_stmt) - && disable_tail_calls) + && !gimple_call_must_tail_p (call_stmt)) gimple_call_set_tail (call_stmt, false); if (call_stmt && gimple_call_tail_p (call_stmt)) { bool can_fallthru; - new_bb = expand_gimple_tailcall (bb, call_stmt, &can_fallthru); + new_bb = expand_gimple_tailcall (bb, call_stmt, &can_fallthru, + asan_epilog_seq); if (new_bb) { if (can_fallthru) @@ -6485,9 +6553,10 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) last = PREV_INSN (PREV_INSN (last)); if (BARRIER_P (last)) last = PREV_INSN (last); - BB_END (bb) = last; + head_end_for_bb[bb->index].second = last; - update_bb_for_insn (bb); + update_bb_for_insn_chain (head_end_for_bb[bb->index].first, + head_end_for_bb[bb->index].second, bb); return bb; } @@ -6498,7 +6567,7 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) static basic_block construct_init_block (void) { - basic_block init_block, first_block; + basic_block init_block; edge e = NULL; int flags; @@ -6529,11 +6598,7 @@ construct_init_block (void) init_block->count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count; add_bb_to_loop (init_block, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father); if (e) - { - first_block = e->dest; - redirect_edge_succ (e, init_block); - make_single_succ_edge (init_block, first_block, flags); - } + expand_split_edge (e, init_block, flags); else make_single_succ_edge (init_block, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FALLTHRU); @@ -7175,10 +7240,35 @@ pass_expand::execute (function *fun) >= param_max_debug_marker_count) cfun->debug_nonbind_markers = false; + enable_ranger (fun); lab_rtx_for_bb = new hash_map<basic_block, rtx_code_label *>; + head_end_for_bb.create (last_basic_block_for_fn (fun)); + FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR_FOR_FN (fun), + next_bb) + bb = expand_gimple_basic_block (bb, var_ret_seq); + disable_ranger (fun); FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR_FOR_FN (fun), next_bb) - bb = expand_gimple_basic_block (bb, var_ret_seq != NULL_RTX); + { + if ((bb->flags & BB_RTL) == 0) + { + bb->il.gimple.seq = NULL; + bb->il.gimple.phi_nodes = NULL; + init_rtl_bb_info (bb); + bb->flags |= BB_RTL; + BB_HEAD (bb) = head_end_for_bb[bb->index].first; + BB_END (bb) = head_end_for_bb[bb->index].second; + } + /* These flags have no purpose in RTL land. */ + if (EDGE_COUNT (bb->succs) == 2) + { + EDGE_SUCC (bb, 0)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE); + EDGE_SUCC (bb, 1)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE); + } + else if (single_succ_p (bb)) + single_succ_edge (bb)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE); + } + head_end_for_bb.release (); if (MAY_HAVE_DEBUG_BIND_INSNS) expand_debug_locations (); diff --git a/gcc/cfgexpand.h b/gcc/cfgexpand.h index b738059b1858..81ed273a7662 100644 --- a/gcc/cfgexpand.h +++ b/gcc/cfgexpand.h @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see extern tree gimple_assign_rhs_to_tree (gimple *); extern HOST_WIDE_INT estimated_stack_frame_size (struct cgraph_node *); +extern void expand_remove_edge (edge); extern void set_parm_rtl (tree, rtx); diff --git a/gcc/cfgrtl.cc b/gcc/cfgrtl.cc index 9add2533e743..1b4f78aa4b82 100644 --- a/gcc/cfgrtl.cc +++ b/gcc/cfgrtl.cc @@ -538,7 +538,7 @@ emit_insn_at_entry (rtx insn) The insn chain range is inclusive (i.e. both BEGIN and END will be updated. */ -static void +void update_bb_for_insn_chain (rtx_insn *begin, rtx_insn *end, basic_block bb) { rtx_insn *insn; diff --git a/gcc/cfgrtl.h b/gcc/cfgrtl.h index cf12bbb16c06..ab3bb9631a3e 100644 --- a/gcc/cfgrtl.h +++ b/gcc/cfgrtl.h @@ -28,6 +28,7 @@ extern basic_block create_basic_block_structure (rtx_insn *, rtx_insn *, extern void compute_bb_for_insn (void); extern void free_bb_for_insn (void); extern rtx_insn *entry_of_function (void); +extern void update_bb_for_insn_chain (rtx_insn *, rtx_insn *, basic_block); extern void update_bb_for_insn (basic_block); extern bool contains_no_active_insn_p (const_basic_block); extern bool forwarder_block_p (const_basic_block); diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc index 3f95ca1fa85c..32071a84bacc 100644 --- a/gcc/cgraph.cc +++ b/gcc/cgraph.cc @@ -179,6 +179,141 @@ cgraph_node::function_version (void) return cgraph_fnver_htab->find (&key); } +/* If profile is IPA, turn it into local one. */ +void +cgraph_node::make_profile_local () +{ + if (!count.ipa ().initialized_p ()) + return; + if (!(count == profile_count::zero ())) + count = count.guessed_local (); + for (cgraph_edge *e = callees; e; e = e->next_callee) + { + if (!e->inline_failed) + e->callee->make_profile_local (); + if (!(e->count == profile_count::zero ())) + e->count = e->count.guessed_local (); + } + for (cgraph_edge *e = indirect_calls; e; e = e->next_callee) + if (!(e->count == profile_count::zero ())) + e->count = e->count.guessed_local (); +} + +/* Turn profile to global0. Walk into inlined functions. + QUALITY must be GUESSED_GLOBAL0, GUESSED_GLOBAL0_ADJUSTED + or GUESSED_GLOBAL0_AFDO */ +void +cgraph_node::make_profile_global0 (profile_quality quality) +{ + if (count == profile_count::zero ()) + ; + else if (quality == GUESSED_GLOBAL0) + { + if (count.quality () == GUESSED_GLOBAL0) + return; + count = count.global0 (); + } + else if (quality == GUESSED_GLOBAL0_ADJUSTED) + { + if (count.quality () == GUESSED_GLOBAL0 + || count.quality () == GUESSED_GLOBAL0_ADJUSTED) + return; + count = count.global0adjusted (); + } + else if (quality == GUESSED_GLOBAL0_AFDO) + { + if (count.quality () == GUESSED_GLOBAL0 + || count.quality () == GUESSED_GLOBAL0_ADJUSTED + || count.quality () == GUESSED_GLOBAL0_AFDO) + return; + count = count.global0afdo (); + } + else + gcc_unreachable (); + for (cgraph_edge *e = callees; e; e = e->next_callee) + { + if (!e->inline_failed) + e->callee->make_profile_global0 (quality); + if (e->count == profile_count::zero ()) + ; + else if (quality == GUESSED_GLOBAL0) + e->count = e->count.global0 (); + else if (quality == GUESSED_GLOBAL0_ADJUSTED) + e->count = e->count.global0adjusted (); + else if (quality == GUESSED_GLOBAL0_AFDO) + e->count = e->count.global0afdo (); + else + gcc_unreachable (); + } + for (cgraph_edge *e = indirect_calls; e; e = e->next_callee) + if (e->count == profile_count::zero ()) + ; + else if (quality == GUESSED_GLOBAL0) + e->count = e->count.global0 (); + else if (quality == GUESSED_GLOBAL0_ADJUSTED) + e->count = e->count.global0adjusted (); + else if (quality == GUESSED_GLOBAL0_AFDO) + e->count = e->count.global0afdo (); + else + gcc_unreachable (); +} + +/* Scale profile by NUM/DEN. Walk into inlined functions. */ + +void +cgraph_node::apply_scale (profile_count num, profile_count den) +{ + if (num == den && !(num == profile_count::zero ())) + return; + + for (cgraph_edge *e = callees; e; e = e->next_callee) + { + if (!e->inline_failed) + e->callee->apply_scale (num, den); + e->count = e->count.apply_scale (num, den); + } + for (cgraph_edge *e = indirect_calls; e; e = e->next_callee) + e->count = e->count.apply_scale (num, den); + count = count.apply_scale (num, den); +} + +/* Scale profile to given IPA_COUNT. + IPA_COUNT should pass ipa_p () with a single exception. + It can be also GUESSED_LOCAL in case we want to + drop any IPA info about the profile. */ + +void +cgraph_node::scale_profile_to (profile_count ipa_count) +{ + /* If we do not know the adjustment, it is better to keep profile + as it is. */ + if (!ipa_count.initialized_p () + || ipa_count == count) + return; + /* ipa-cp converts value to guessed-local in case it believes + that we lost track of IPA profile. */ + if (ipa_count.quality () == GUESSED_LOCAL) + { + make_profile_local (); + return; + } + if (ipa_count == profile_count::zero ()) + { + make_profile_global0 (GUESSED_GLOBAL0); + return; + } + if (ipa_count == profile_count::adjusted_zero ()) + { + make_profile_global0 (GUESSED_GLOBAL0_ADJUSTED); + return; + } + gcc_assert (ipa_count.ipa () == ipa_count + && !inlined_to); + profile_count num = count.combine_with_ipa_count (ipa_count); + profile_count den = count; + profile_count::adjust_for_ipa_scaling (&num, &den); +} + /* Insert a new cgraph_function_version_info node into cgraph_fnver_htab corresponding to cgraph_node NODE. */ cgraph_function_version_info * @@ -231,45 +366,60 @@ cgraph_node::delete_function_version_by_decl (tree decl) decl_node->remove (); } -/* Record that DECL1 and DECL2 are semantically identical function +/* Add decl to the structure of semantically identical function versions. + The node is inserted at the point maintaining the priority ordering on the versions. */ void -cgraph_node::record_function_versions (tree decl1, tree decl2) +cgraph_node::add_function_version (cgraph_function_version_info *fn_v, + tree decl) { - cgraph_node *decl1_node = cgraph_node::get_create (decl1); - cgraph_node *decl2_node = cgraph_node::get_create (decl2); - cgraph_function_version_info *decl1_v = NULL; - cgraph_function_version_info *decl2_v = NULL; - cgraph_function_version_info *before; - cgraph_function_version_info *after; + cgraph_node *decl_node = cgraph_node::get_create (decl); + cgraph_function_version_info *decl_v = NULL; - gcc_assert (decl1_node != NULL && decl2_node != NULL); - decl1_v = decl1_node->function_version (); - decl2_v = decl2_node->function_version (); + gcc_assert (decl_node != NULL); - if (decl1_v != NULL && decl2_v != NULL) - return; - - if (decl1_v == NULL) - decl1_v = decl1_node->insert_new_function_version (); - - if (decl2_v == NULL) - decl2_v = decl2_node->insert_new_function_version (); + decl_v = decl_node->function_version (); - /* Chain decl2_v and decl1_v. All semantically identical versions - will be chained together. */ - - before = decl1_v; - after = decl2_v; + /* If the nodes are already linked, skip. */ + if (decl_v != NULL && (decl_v->next || decl_v->prev)) + return; - while (before->next != NULL) - before = before->next; + if (decl_v == NULL) + decl_v = decl_node->insert_new_function_version (); + + gcc_assert (decl_v); + gcc_assert (fn_v); + + /* Go to start of the FMV structure. */ + while (fn_v->prev) + fn_v = fn_v->prev; + + cgraph_function_version_info *insert_point_before = NULL; + cgraph_function_version_info *insert_point_after = fn_v; + + /* Find the insertion point for the new version to maintain ordering. + The default node must always go at the beginning. */ + if (!is_function_default_version (decl)) + while (insert_point_after + && (targetm.compare_version_priority + (decl, insert_point_after->this_node->decl) > 0 + || is_function_default_version + (insert_point_after->this_node->decl) + || lookup_attribute + ("target_clones", + DECL_ATTRIBUTES (insert_point_after->this_node->decl)))) + { + insert_point_before = insert_point_after; + insert_point_after = insert_point_after->next; + } - while (after->prev != NULL) - after= after->prev; + decl_v->prev = insert_point_before; + decl_v->next= insert_point_after; - before->next = after; - after->prev = before; + if (insert_point_before) + insert_point_before->next = decl_v; + if (insert_point_after) + insert_point_after->prev = decl_v; } /* Initialize callgraph dump file. */ @@ -1640,6 +1790,19 @@ cgraph_update_edges_for_call_stmt_node (cgraph_node *node, if (e) { + /* If call was devirtualized during cloning, mark edge + as resolved. */ + if (e->speculative) + { + if (new_stmt && is_gimple_call (new_stmt)) + { + tree decl = gimple_call_fndecl (new_stmt); + if (decl) + e = cgraph_edge::resolve_speculation (e, decl); + } + else + e = cgraph_edge::resolve_speculation (e, NULL); + } /* Keep calls marked as dead dead. */ if (new_stmt && is_gimple_call (new_stmt) && e->callee && fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE, @@ -3626,6 +3789,13 @@ cgraph_node::verify_node (void) count.debug (); error_found = true; } + if (inlined_to && !e->count.compatible_p (inlined_to->count)) + { + error ("edge count is not compatible with inlined to function count"); + e->count.debug (); + count.debug (); + error_found = true; + } if (!e->indirect_unknown_callee || !e->indirect_info) { diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 8dbe36eac09d..deca564a8e37 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -1256,6 +1256,21 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node it is not used in any other non-standard way. */ bool only_called_directly_p (void); + /* Turn profile to global0. Walk into inlined functions. */ + void make_profile_local (); + + /* Turn profile to global0. Walk into inlined functions. */ + void make_profile_global0 (profile_quality quality); + + /* Scale profile by NUM/DEN. Walk into inlined funtion. */ + void apply_scale (profile_count num, profile_count den); + + /* Scale profile to given IPA_COUNT. + IPA_COUNT should pass ipa_p () with a single exception. + It can be also GUESSED_LOCAL in case we want to + drop any IPA info about the profile. */ + void scale_profile_to (profile_count ipa_count); + /* Return true when function is only called directly or it has alias. i.e. it is not externally visible, address was not taken and it is not used in any other non-standard way. */ @@ -1324,9 +1339,9 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node return m_summary_id; } - /* Record that DECL1 and DECL2 are semantically identical function - versions. */ - static void record_function_versions (tree decl1, tree decl2); + /* Adds DECL to the FN_V structure of semantically identical functions. */ + static void add_function_version (cgraph_function_version_info *fn_v, + tree decl); /* Remove the cgraph_function_version_info and cgraph_node for DECL. This DECL is a duplicate declaration. */ diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc index fa54a59d02b8..8e8d85562b03 100644 --- a/gcc/cgraphunit.cc +++ b/gcc/cgraphunit.cc @@ -63,7 +63,7 @@ along with GCC; see the file COPYING3. If not see final assembler is generated. This is done in the following way. Note that with link time optimization the process is split into three stages (compile time, linktime analysis and parallel linktime as - indicated bellow). + indicated below). Compile time: diff --git a/gcc/cobol/ChangeLog b/gcc/cobol/ChangeLog index 03243e934d0a..e5072528ce74 100644 --- a/gcc/cobol/ChangeLog +++ b/gcc/cobol/ChangeLog @@ -1,3 +1,1004 @@ +2025-07-21 Robert Dubner <rdubner@symas.com> + James K. Lowden <jklowden@cobolworx.com> + + PR cobol/120402 + * Make-lang.in: Elminate commented-out scripting. + * cbldiag.h (_CBLDIAG_H): Change #if 0 to #if GCOBOL_GETENV + (warn_msg): Add printf attributes. + (location_dump): Add debugging message. + * cdf.y: Improved linemap tracking. + * genapi.cc (treeplet_fill_source): const attribute for formal parameter. + (insert_nop): Created to consolidate var_decl_nop writes. + (build_main_that_calls_something): Move generation to the end of executable. + (level_88_helper): Formatting. + (parser_call_targets_dump): Formatting. + (function_pointer_from_name): const attribute for formal parameter. + (parser_initialize_programs): const attribute for formal parameter. + (parser_statement_begin): Improved linemap handling. + (section_label): Improved linemap handling. + (paragraph_label): Improved linemap handling. + (pseudo_return_pop): Improved linemap handling. + (leave_procedure): Formatting. + (parser_enter_section): Improved linemap handling. + (parser_enter_paragraph): Improved linemap handling. + (parser_perform): Formatting. + (parser_leave_file): Move creation of main() to this routine. + (parser_enter_program): Move creation of main from here to leave_file. + (parser_accept): Formatting. const attribute for formal parameter. + (parser_accept_command_line): const attribute for formal parameter. + (parser_accept_command_line_count): const attribute for formal parameter. + (parser_accept_envar): Likewise. + (parser_set_envar): Likewise. + (parser_display): Likewise. + (get_exhibit_name): Implement EXHIBIT verb. + (parser_exhibit): Likewise. + (parser_sleep): const attribute for formal parameter. + (parser_division): Improved linemap handling. + (parser_classify): const attribute for formal parameter. + (create_iline_address_pairs): Improved linemap handling. + (parser_perform_start): Likewise. + (perform_inline_until): Likewise. + (perform_inline_testbefore_varying): Likewise. + (parser_perform_until): Likewise. + (parser_perform_inline_times): Likewise. + (parser_intrinsic_subst): const attribute for formal parameter. + (parser_file_merge): Formatting. + (create_and_call): Improved linemap handling. + (mh_identical): const attribute for formal parameter. + (mh_numeric_display): const attribute for formal parameter. + (mh_little_endian): Likewise. + (mh_source_is_group): Likewise. + (psa_FldLiteralA): Formatting. + * genapi.h (parser_accept): const attribute for formal parameter. + (parser_accept_envar): Likewise. + (parser_set_envar): Likewise. + (parser_accept_command_line): Likewise. + (parser_accept_command_line_count): Likewise. + (parser_add): Likewise. + (parser_classify): Likewise. + (parser_sleep): Likewise. + (parser_exhibit): Likewise. + (parser_display): Likewise. + (parser_initialize_programs): Likewise. + (parser_intrinsic_subst): Likewise. + * gengen.cc (gg_assign): Improved linemap handling. + (gg_add_field_to_structure): Likewise. + (gg_define_from_declaration): Likewise. + (gg_build_relational_expression): Likewise. + (gg_goto_label_decl): Likewise. + (gg_goto): Likewise. + (gg_printf): Likewise. + (gg_fprintf): Likewise. + (gg_memset): Likewise. + (gg_memchr): Likewise. + (gg_memcpy): Likewise. + (gg_memmove): Likewise. + (gg_strcpy): Likewise. + (gg_strcmp): Likewise. + (gg_strncmp): Likewise. + (gg_return): Likewise. + (chain_parameter_to_function): Likewise. + (gg_define_function): Likewise. + (gg_get_function_decl): Likewise. + (gg_call_expr): Likewise. + (gg_call): Likewise. + (gg_call_expr_list): Likewise. + (gg_exit): Likewise. + (gg_abort): Likewise. + (gg_strlen): Likewise. + (gg_strdup): Likewise. + (gg_malloc): Likewise. + (gg_realloc): Likewise. + (gg_free): Likewise. + (gg_set_current_line_number): Likewise. + (gg_get_current_line_number): Likewise. + (gg_insert_into_assembler): Likewise. + (token_location_override): Likewise. + (gg_token_location): Likewise. + * gengen.h (location_from_lineno): Likewise. + (gg_set_current_line_number): Likewise. + (gg_get_current_line_number): Likewise. + (gg_token_location): Likewise. + (current_token_location): Likewise. + (current_location_minus_one): Likewise. + (current_location_minus_one_clear): Likewise. + (token_location_override): Likewise. + * genmath.cc (fast_divide): const attribute for formal parameter. + * genutil.cc (get_and_check_refstart_and_reflen): Likewise. + (get_data_offset): Likewise. + (refer_refmod_length): Likewise. + (refer_offset): Likewise. + (refer_size): Likewise. + (refer_size_dest): Likewise. + (refer_size_source): Likewise. + (qualified_data_location): Likewise. + * genutil.h (refer_offset): Likewise. + (refer_size_source): Likewise. + (refer_size_dest): Likewise. + (qualified_data_location): Likewise. + * parse.y: EVALUATE token; Implement EXHIBIT verb; + Improved linemap handling. + * parse_ante.h (input_file_status_notify): Improved linemap handling. + (location_set): Likewise. + * scan.l: PICTURE string validation. + * scan_ante.h (class picture_t): PICTURE string validation. + (validate_picture): Likewise. + * symbols.cc (symbol_currency): Revised default currency handling. + * symbols.h (symbol_currency): Likewise. + * util.cc (location_from_lineno): Improved linemap handling. + (current_token_location): Improved linemap handling. + (current_location_minus_one): Improved linemap handling. + (current_location_minus_one_clear): Improved linemap handling. + (gcc_location_set_impl): Improved linemap handling. + (warn_msg): Improved linemap handling. + * util.h (cobol_lineno): Improved linemap handling. + +2025-07-15 Jakub Jelinek <jakub@redhat.com> + Jason Merrill <jason@redhat.com> + + PR c/44677 + * gcobolspec.cc (lang_specific_driver): Remove unused but set variable + n_cobol_files. + +2025-07-14 Robert Dubner <rdubner@symas.com> + + * cobol1.cc (cobol_langhook_handle_option): Eliminate cppcheck warnings. + * dts.h: Likewise. + * except.cc (cbl_enabled_exceptions_t::dump): Likewise. + * gcobolspec.cc (lang_specific_driver): Likewise. + * genapi.cc (parser_file_merge): Likewise. + * gengen.cc (gg_unique_in_function): Likewise. + (gg_declare_variable): Likewise. + (gg_peek_fn_decl): Likewise. + (gg_define_function): Likewise. + * genmath.cc (set_up_on_exception_label): Likewise. + (set_up_compute_error_label): Likewise. + (arithmetic_operation): Likewise. + (fast_divide): Likewise. + * genutil.cc (get_and_check_refstart_and_reflen): Likewise. + (get_depending_on_value_from_odo): Likewise. + (get_data_offset): Likewise. + (get_binary_value): Likewise. + (process_this_exception): Likewise. + (copy_little_endian_into_place): Likewise. + (refer_is_clean): Likewise. + (refer_fill_depends): Likewise. + * genutil.h (process_this_exception): Likewise. + (copy_little_endian_into_place): Likewise. + (refer_is_clean): Likewise. + * lexio.cc (check_push_pop_directive): Likewise. + (check_source_format_directive): Likewise. + (location_in): Likewise. + (lexer_input): Likewise. + (cdftext::lex_open): Likewise. + (lexio_dialect_mf): Likewise. + (valid_sequence_area): Likewise. + (cdftext::free_form_reference_format): Likewise. + (cdftext::segment_line): Likewise. + * lexio.h (struct span_t): Likewise. + * scan_ante.h (trim_location): Likewise. + * symbols.cc (symbol_elem_cmp): Likewise. + (symbol_alphabet): Likewise. + (end_of_group): Likewise. + (cbl_field_t::attr_str): Likewise. + (symbols_update): Likewise. + (symbol_typedef_add): Likewise. + (symbol_field_add): Likewise. + (new_temporary_impl): Likewise. + (symbol_label_section_exists): Likewise. + (symbol_program_callables): Likewise. + (file_status_status_of): Likewise. + * symfind.cc (is_data_field): Likewise. + (finalize_symbol_map2): Likewise. + (class in_scope): Likewise. + (symbol_match2): Likewise. + * util.cc (get_current_dir_name): Likewise. + (gb4): Likewise. + (class cdf_directives_t): Likewise. + (cbl_field_t::report_invalid_initial_value): Likewise. + (literal_subscript_oob): Likewise. + (cbl_refer_t::str): Likewise. + (date_time_fmt): Likewise. + (class unique_stack): Likewise. + (cobol_set_pp_option): Likewise. + (cobol_filename): Likewise. + (cobol_filename_restore): Likewise. + (gcc_location_set_impl): Likewise. + (ydferror): Likewise. + (error_msg_direct): Likewise. + (yyerror): Likewise. + (cbl_unimplemented_at): Likewise. + +2025-07-13 Robert Dubner <rdubner@symas.com> + + * Make-lang.in: Eliminate the .cc.o override. + * genapi.cc (level_88_helper): Eliminate cppcheck warning. + (get_level_88_domain): Likewise. + (get_class_condition_string): Likewise. + (parser_call_targets_dump): Likewise. + (parser_compile_ecs): Likewise. + (initialize_variable_internal): Likewise. + (move_tree): Likewise. + (combined_name): Likewise. + (assembler_label): Likewise. + (find_procedure): Likewise. + (parser_perform): Likewise. + (parser_perform_times): Likewise. + (internal_perform_through): Likewise. + (internal_perform_through_times): Likewise. + (psa_FldLiteralN): Likewise. + (psa_FldBlob): Likewise. + (parser_accept): Likewise. + (parser_accept_exception): Likewise. + (parser_accept_exception_end): Likewise. + (parser_accept_command_line): Likewise. + (parser_accept_envar): Likewise. + (parser_display_internal): Likewise. + (parser_display): Likewise. + (parser_assign): Likewise. + (parser_initialize_table): Likewise. + (parser_arith_error): Likewise. + (parser_arith_error_end): Likewise. + (parser_division): Likewise. + (label_fetch): Likewise. + (parser_label_label): Likewise. + (parser_label_goto): Likewise. + (parser_perform_start): Likewise. + (parser_perform_conditional): Likewise. + (parser_perform_conditional_end): Likewise. + (parser_perform_until): Likewise. + (parser_file_delete): Likewise. + (parser_intrinsic_subst): Likewise. + (create_lsearch_address_pairs): Likewise. + (parser_bsearch_start): Likewise. + (is_ascending_key): Likewise. + (parser_sort): Likewise. + (parser_file_sort): Likewise. + (parser_return_start): Likewise. + (parser_file_merge): Likewise. + (parser_string_overflow): Likewise. + (parser_unstring): Likewise. + (parser_string): Likewise. + (parser_call_exception): Likewise. + (create_and_call): Likewise. + (mh_identical): Likewise. + (move_helper): Likewise. + (binary_initial_from_float128): Likewise. + (initial_from_initial): Likewise. + (psa_FldLiteralA): Likewise. + (parser_local_add): Likewise. + (parser_symbol_add): Likewise. + * genapi.h (parser_display): Likewise. + * gengen.cc (gg_call_expr): Explict check for NULL_TREE. + (gg_call): Likewise. + * show_parse.h (SHOW_PARSE_LABEL_OK): Likewise. + (TRACE1_FIELD_VALUE): Likewise. + (CHECK_FIELD): Likewise. + (CHECK_FIELD2): Likewise. + (CHECK_LABEL): Likewise. + * util.cc (cbl_internal_error): Apply [[noreturn]] attribute. + * util.h (cbl_internal_error): Likewise. + +2025-07-11 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + PR cobol/120621 + * lexio.cc (parse_replace_pairs): Cast mfile.lineno() to fmt_size_t. + * parse.y (intrinsic): Print ptrdiff_t using %ld, cast arg to long. + * scan_ante.h (numstr_of): Print nx using %ld, cast arg to long. + * util.cc (cbl_field_t::report_invalid_initial_value): Print + ptrdiff_t using %ld, cast arg to long. + +2025-07-10 James K. Lowden <jklowden@cobolworx.com> + + PR cobol/120765 + * cdf.y: Extend grammar for new CDF syntax, relocate dictionary. + * cdfval.h (cdf_dictionary): Use new CDF dictionary. + * dts.h: Remove useless assignment, note incorrect behavior. + * except.cc: Remove obsolete EC state. + * gcobol.1: Document CDF in its own section. + * genapi.cc (parser_statement_begin): Use new EC state function. + (parser_file_merge): Same. + (parser_check_fatal_exception): Same. + * genutil.cc (get_and_check_refstart_and_reflen): Same. + (get_depending_on_value_from_odo): Same. + (get_data_offset): Same. + (process_this_exception): Same. + * lexio.cc (check_push_pop_directive): New function. + (check_source_format_directive): Restrict regex search to 1 line. + (cdftext::free_form_reference_format): Use new function. + * parse.y: Define new CDF tokens, use new CDF state. + * parse_ante.h (cdf_tokens): Use new CDF state. + (redefined_token): Same. + (class prog_descr_t): Remove obsolete CDF state. + (class program_stack_t): Same. + (current_call_convention): Same. + * scan.l: Recognize new CDF tokens. + * scan_post.h (is_cdf_token): Same. + * symbols.h (cdf_current_tokens): Change current_call_convention to return void. + * token_names.h: Regenerate. + * udf/stored-char-length.cbl: Use new PUSH/POP CDF functionality. + * util.cc (class cdf_directives_t): Define cdf_directives_t. + (current_call_convention): Same. + (cdf_current_tokens): Same. + (cdf_dictionary): Same. + (cdf_enabled_exceptions): Same. + (cdf_push): Same. + (cdf_push_call_convention): Same. + (cdf_push_current_tokens): Same. + (cdf_push_dictionary): Same. + (cdf_push_enabled_exceptions): Same. + (cdf_push_source_format): Same. + (cdf_pop): Same. + (cdf_pop_call_convention): Same. + (cdf_pop_current_tokens): Same. + (cdf_pop_dictionary): Same. + (cdf_pop_enabled_exceptions): Same. + (cdf_pop_source_format): Same. + * util.h (cdf_push): Declare cdf_directives_t. + (cdf_push_call_convention): Same. + (cdf_push_current_tokens): Same. + (cdf_push_dictionary): Same. + (cdf_push_enabled_exceptions): Same. + (cdf_push_source_format): Same. + (cdf_pop): Same. + (cdf_pop_call_convention): Same. + (cdf_pop_current_tokens): Same. + (cdf_pop_dictionary): Same. + (cdf_pop_source_format): Same. + (cdf_pop_enabled_exceptions): Same. + +2025-07-09 Robert Dubner <rdubner@symas.com> + James K. Lowden <jklowden@cobolworx.com> + + PR cobol/120765 + PR cobol/119337 + PR cobol/120794 + * Make-lang.in: Take control of the .cc.o rule. + * cbldiag.h (error_msg_direct): New declaration. + (gcc_location_dump): Forward declaration. + (location_dump): Use gcc_location_dump. + * cdf.y: Change some tokens. + * gcobc: Change dialect handling. + * genapi.cc (parser_call_targets_dump): Temporarily remove from service. + (parser_compile_dcls): Combine temporary arrays. + (get_binary_value_from_float): Apply const to one parameter. + (depending_on_value): Localize a boolean variable. + (normal_normal_compare): Likewise. + (cobol_compare): Eliminate cppcheck warning. + (combined_name): Apply const to an input parameter. + (parser_perform): Apply const to a variable. + (parser_accept): Improve handling of special_name_t parameter and + the exception conditions. + (parser_display): Improve handling of speciat_name_t parameter; use the + os_filename[] string when appropriate. + (program_end_stuff): Rename shadowing variable. + (parser_division): Consolidate temporary char[] arrays. + (parser_file_start): Apply const to a parameter. + (inspect_replacing): Likewise. + (parser_program_hierarchy): Rename shadowing variable. + (mh_identical): Apply const to parameters. + (float_type_of): Likewise. + (picky_memcpy): Likewise. + (mh_numeric_display): Likewise. + (mh_little_endian): Likewise. + (mh_source_is_group): Apply static to a variable it. + (move_helper): Quiet a cppcheck warning. + * genapi.h (parser_accept): Add exceptions to declaration. + (parser_accept_under_discussion): Add declaration. + (parser_display): Change to std::vector; add exceptions to declaration. + * lexio.cc (cdf_source_format): Improve source code location handling. + (source_format_t::infer): Likewise. + (is_fixed_format): Likewise. + (is_reference_format): Likewise. + (left_margin): Likewise. + (right_margin): Likewise. + (cobol_set_indicator_column): Likewise. + (include_debug): Likewise. + (continues_at): Likewise. + (indicated): Likewise. + (check_source_format_directive): Likewise. + (cdftext::free_form_reference_format): Likewise. + * parse.y: Tokens; program and function names; DISPLAY and ACCEPT + handling. + * parse_ante.h (class tokenset_t): Removed. + (class current_tokens_t): Removed. + (field_of): Removed. + * scan.l: Token handling. + * scan_ante.h (level_found): Comment. + * scan_post.h (start_condition_str): Remove cast author_state:. + * symbols.cc (symbols_update): Change error message. + (symbol_table_init): Correct and reorder entries. + (symbol_unresolved_file_key): New function definition. + (cbl_file_key_t::deforward): Change error message. + * symbols.h (symbol_unresolved_file_key): New declaration. + (keyword_tok): New function. + (redefined_token): New function. + (class current_tokens_t): New class. + * symfind.cc (symbol_match): Revise error message. + * token_names.h: Reorder and change numbers in comments. + * util.cc (class cdf_directives_t): New class. + (cobol_set_indicator_column): New function. + (cdf_source_format): New function. + (gcc_location_set_impl): Improve column handling in token_location. + (gcc_location_dump): New function. + (class temp_loc_t): Modify constructor. + (error_msg_direct): New function. + * util.h (class source_format_t): New class. + +2025-07-01 James K. Lowden <jklowden@cobolworx.com> + + * Make-lang.in: Use && instead of semicolon between commands. + +2025-07-01 Robert Dubner <rdubner@symas.com> + + * parse.y: printf() of size_t is %zu, not %ld. + +2025-06-30 James K. Lowden <jklowden@cobolworx.com> + + PR cobol/120772 + PR cobol/120779 + PR cobol/120790 + PR cobol/120791 + PR cobol/120794 + * gcobc: Supply -fPIC for shared objects. + * genapi.cc (linemap_add): Delete empty macro. + (parser_enter_file): Do not call linemap_add. + (parser_leave_file): Same. + * gengen.cc (location_from_lineno): Remove function. + * lexio.cc (parse_replacing_term): Allow empty term. + (cdftext::process_file): Always append to output. + (cdftext::segment_line): Output #line directives. + * lexio.h (struct span_t): Count lines in span. + * parse.y: Revamp REPOSITORY, and minor syntax extensions. + * parse_ante.h (input_file_status_notify): Update linemap filename before location. + (intrinsic_token_of): Declare. + (parser_move_carefully): Support MOVE pointer. + * parse_util.h (intrinsic_token_of): New function. + * scan.l: New EOF logic, accept NOT=, own yylloc and yylineno. + * scan_ante.h (class enter_leave_t): Do not store newline count. + (cdf_location_set): Remove declaration. + (ydfltype_of): New function. + (update_location): Accept location parameter. + (reset_location): New function. + (YY_USER_ACTION): Use update_location(). + (YY_USER_INIT): Update CDF location. + (verify_ws): New function. + (wait_for_the_child): Removed. + * symbols.h (cobol_fileline_set): return line number. + * util.cc (valid_move): Use range-based for loop. + (struct input_file_t): Remove line_map pointer. + (class unique_stack): New peek() member function. + (cobol_lineno_save): Rename to overload cobol_lineno(). + (cobol_lineno): Replaces cobol_lineno_save(). + (cobol_filename): Return void. + (location_from_lineno): New function used by genapi.cc. + (cdf_location_set): Remove. + (matched_length): No change. + (cobol_fileline_set): Return line number. + (fisspace): Remove extra semicolon. + (fisprint): Same. + * util.h (cobol_filename_restore): Return void. + (cobol_lineno_save): Remove declaration. + (cobol_lineno): Declare. + +2025-06-29 Robert Dubner <rdubner@symas.com> + + * Make-lang.in: Incorporate gcobol.clean. + * except.cc (cbl_enabled_exceptions_t::dump): Update debug message. + * genapi.cc (gg_attribute_bit_get): Formatting. + (file_static_variable): Formatting. + (trace1_init): Formatting. + (build_main_that_calls_something): Normalize function_decl use. + (parser_call_target): Likewise. + (set_call_convention): Likewise. + (parser_call_target_convention): Likewise. + (parser_call_targets_dump): Likewise. + (function_handle_from_name): Likewise. + (function_pointer_from_name): Likewise. + (parser_initialize_programs): Likewise. + (parser_statement_begin): Formatting. + (parser_leave_file): Use function_decl FIFO. + (enter_program_common): Normalize function_decl use. + (parser_enter_program): Normalize function_decl use. + (tree_type_from_field_type): Normalize function_decl use. + (is_valuable): Comment. + (pe_stuff): Change name to program_end_stuff. + (program_end_stuff): Likewise. + (parser_exit): Likewise. + (parser_division): Normalize function_decl use. + (create_and_call): Normalize function_decl use. + (parser_call): Normalize function_decl use. + (parser_set_pointers): Normalize function_decl use. + (parser_program_hierarchy): Normalize function_decl use. + (psa_FldLiteralA): Defeat attempt to re-use literals. (Fails on some aarch64). + (parser_symbol_add): Error message formatting. + * genapi.h: Formatting. + * gengen.cc (struct cbl_translation_unit_t): Add function_decl FIFO. + (show_type): Rename to gg_show_type. + (gg_show_type): Correct an error message. + (gg_assign): Formatting; change error handling. + (gg_modify_function_type): Normalize function_decl use. + (gg_define_function_with_no_parameters): Fold into gg_defint_function(). + (function_decl_key): Normalize function_decl use. + (gg_peek_fn_decl): Normalize function_decl use. + (gg_build_fn_decl): Normalize function_decl use. + (gg_define_function): Normalize function_decl use. + (gg_tack_on_function_parameters): Remove. + (gg_finalize_function): Normalize function_decl use. + (gg_leaving_the_source_code_file): Normalize function_decl use. + (gg_call_expr_list): Normalize function_decl use. + (gg_trans_unit_var_decl): Normalize function_decl use. + (gg_insert_into_assemblerf): New function; formatting. + * gengen.h (struct gg_function_t): Eliminate "is_truly_nested" flag. + (gg_assign): Incorporate return value. + (gg_define_function): Normalize function_decl use. + (gg_define_function_with_no_parameters): Eliminate. + (gg_build_fn_decl): Normalize function_decl use. + (gg_peek_fn_decl): Normalize function_decl use. + (gg_modify_function_type): Normalize function_decl use. + (gg_call_expr_list): Normalize function_decl use. + (gg_get_function_decl): Normalize function_decl use. + (location_from_lineno): Prefix with "extern". + (gg_open): Likewise. + (gg_close): Likewise. + (gg_get_indirect_reference): Likewise. + (gg_insert_into_assembler): Likewise. + (gg_insert_into_assemblerf): Likewise. + (gg_show_type): New declaration. + (gg_leaving_the_source_code_file): New declaration. + * parse.y: Format debugging message. + * parse_ante.h: Normalize function_decl use. + +2025-06-20 James K. Lowden <jklowden@cobolworx.com> + + PR cobol/120621 + * genapi.cc (parser_compile_ecs): Cast argument to unsigned long. + (parser_compile_dcls): Same. + (parser_division): RAII. + (inspect_tally): Cast argument to unsigned long. + * lexio.cc (cdftext::lex_open): Cast pid_t to long. + * parse.y: hard-code values for old versions of Bison, and message format. + * scan_ante.h (wait_for_the_child): Cast pid_t to long. + +2025-06-18 James K. Lowden <jklowden@cobolworx.com> + + PR cobol/120621 + * cbldiag.h (yyerror): Add diagnostic attributes. + (yywarn): Same. + (error_msg): Same. + (yyerrorvl): Same. + (cbl_unimplementedw): Same. + (cbl_unimplemented): Same. + (cbl_unimplemented_at): Same. + * cdf-copy.cc (copybook_elem_t::open_file): Supply string argument. + * cdf.y: Use %<%>. + * cobol-system.h (if): Check GCC_VERSION. + (ATTRIBUTE_GCOBOL_DIAG): Define. + * except.cc (cbl_enabled_exception_t::dump): Remove extra %s. + * genapi.cc (get_class_condition_string): Use acceptable message. + (get_bytes_needed): Same. + (move_tree): Same. + (get_string_from): Same. + (internal_perform_through): Same. + (tree_type_from_field_type): Same. + (is_valuable): Same. + (parser_logop): Same. + (parser_relop): Same. + (parser_relop_long): Same. + (parser_if): Same. + (parser_setop): Same. + (parser_perform_conditional): Same. + (parser_file_add): Same. + (parser_file_open): Same. + (parser_file_close): Same. + (parser_file_read): Same. + (parser_file_write): Same. + (inspect_replacing): Same. + (parser_sort): Same. + (parser_file_sort): Same. + (parser_file_merge): Same. + (create_and_call): Same. + (parser_bitop): Same. + (parser_bitwise_op): Same. + (hijack_for_development): Same. + (mh_source_is_literalN): Same. + (mh_dest_is_float): Same. + (parser_symbol_add): Same. + * gengen.cc (show_type): Use acceptable message. + (gg_find_field_in_struct): Same. + (gg_declare_variable): Same. + (gg_printf): Same. + (gg_fprintf): Same. + (gg_tack_on_function_parameters): Same. + (gg_define_function): Same. + (gg_get_function_decl): Same. + (gg_finalize_function): Same. + (gg_call_expr): Same. + (gg_call): Same. + (gg_insert_into_assembler): Define new function. + (gg_insert_into_assemblerf): Use gg_insert_into_assembler(). + * gengen.h (gg_insert_into_assembler): Simpler function declaration. + (gg_insert_into_assemblerf): Declare new function. + * genmath.cc (parser_op): Use acceptable message. + * genutil.cc (get_binary_value): Use acceptable message. + * lexio.cc (parse_replacing_pair): Correct diagnostic arguments. + (preprocess_filter_add): Same. + (cdftext::open_input): Same. + * parse.y: Use acceptable messages. + * parse_ante.h (struct evaluate_elem_t): Use %<%>. + (is_callable): Same. + * parse_util.h (intrinsic_invalid_parameter): Use %qs. + * scan.l: Use dialect_error(). + * scan_ante.h (numstr_of): Use %qs. + (scanner_token): Quote COBOL tokens in messages. + (scanner_parsing): Correct diagnostic message. + (scanner_parsing_toggle): Quote COBOL tokens in messages. + (scanner_parsing_pop): Same. + (typed_name): Use %qs. + * scan_post.h (prelex): Quote COBOL tokens in message. + * show_parse.h (CHECK_FIELD): Use acceptable message format. + (CHECK_LABEL): Same. + * symbols.cc (symbol_field_same_as): Remove extra spaces. + (cbl_alphabet_t::assign): Use %<%>. + (cbl_field_t::internalize): Quote library name in message. + * symbols.h (struct os_locale_t): Constify codeset. + (class temporaries_t): Add copy constructor. + (struct cbl_alphabet_t): Use acceptable message. + * util.cc (symbol_type_str): Use cbl_internal_error. + (cbl_field_type_str): Same. + (is_elementary): Same. + (cbl_field_t::report_invalid_initial_value): Use %qs. + (class unique_stack): Avoid %m. + (ydferror): Declare function with attributes. + (error_msg): Same. + (cobol_fileline_set): Use %<%>. + (os_locale_t): Remove use of xstrdup. + (cobol_parse_files): Quote C names in message. + (dialect_error): Use %<%>. + * util.h (cbl_message): Add attributes. + (cbl_internal_error): Same. + (cbl_err): Same. + (cbl_errx): Same. + +2025-06-16 James K. Lowden <jklowden@cobolworx.com> + + PR cobol/120621 + * Make-lang.in: Use STRICT_WARN. + * cbldiag.h (location_dump): suppress shadowVariable. + * cdf-copy.cc (esc): Fix shadowVariable. + (copybook_elem_t::open_file): Do not use %m. + * cdf.y: suppress invalidPrintfArgType for target format. + * cdfval.h (struct cdfval_t): Suppress noExplicitConstructor. + * cobol1.cc (cobol_name_mangler): Use C++ cast. + * copybook.h (class copybook_elem_t): Same. + * dts.h: Fixes and suppressions due to cppcheck. + * except.cc (cbl_enabled_exceptions_t::status): Suppress useStlAlgorithm. + (cbl_enabled_exceptions_t::turn_on_off): Const parameter. + (class choose_declarative): Removed. + * genapi.cc (struct called_tree_t): Explicit constructor. + (parser_compile_ecs): Cast to void * for %p. + (parser_compile_dcls): Same. + (parser_statement_begin): Same. + (initialize_variable_internal): Use std::vector for subscripts. + (parser_initialize): Constification. + (get_string_from): Same. + (combined_name): Same. + (parser_perform): Same. + (psa_FldLiteralN): Same. + (is_figconst): Const parameter. + (is_figconst_t): Same. + (parser_exit): Same. + (parser_division): Const pointer. + (parser_perform_conditional): Whitespace. + (parser_set_conditional88): Const parameter. + (inspect_tally): Use std::vector. + (inspect_replacing): Same. + (parser_inspect): Same. + (parser_intrinsic_subst): Use std::vector (constuct elements). + (parser_intrinsic_call_1): Use std::vector for subscripts. + (is_ascending_key): Const pointer. + (parser_sort): Use std::vector. + (parser_file_sort): Same. + (parser_file_merge): Same. + (parser_unstring): Same. + (parser_string): Same. + (parser_call): Const pointer. + (parser_program_hierarchy): Use std::vector. + (conditional_abs): Const paraemeter. + (float_type_of): Same. + (initial_from_initial): Set value, quoted or not. + (parser_symbol_add): Remove redundant nested test. + * genapi.h (parser_add): Const parameters. + (parser_subtract): Same. + (parser_multiply): Same. + (parser_divide): Same. + (parser_perform): Same. + (parser_exit): Same. + (parser_initialize): Same. + (parser_set_conditional88): Same. + (parser_sort): Same. + (parser_file_sort): Same. + (parser_file_merge): Same. + (parser_string): Same. + (is_ascending_key): Same. + * genmath.cc (arithmetic_operation): Use std::vector. + (is_somebody_float): Const parameter. + (all_results_binary): Const parameter. + (fast_multiply): Remove redundant nested test. + (parser_add): Const parameter. + (parser_multiply): Remove redundant nested test. + (parser_divide): Const parameter. + (parser_subtract): Same. + * genutil.cc (get_depending_on_value): Use std::vector. + (get_data_offset): Same. + (tree_type_from_field): Const parameter. + (refer_has_depends): Const pointers. + (get_literal_string): RAII. + (refer_is_clean): Use std::vector. + (get_time_nanoseconds): Newline at EOF. + * genutil.h (tree_type_from_field): Remove declaration. + * inspect.h (struct cbx_inspect_qual_t): Use std::vector. + (struct cbl_inspect_qual_t): Same. + (struct cbx_inspect_match_t): Same. + (class cbl_inspect_match_t): Same. + (struct cbx_inspect_replace_t): Same. + (struct cbl_inspect_replace_t): Same. + (struct cbx_inspect_oper_t): Same. + (struct cbl_inspect_oper_t): Same. + (struct cbx_inspect_t): Same. + (struct cbl_inspect_t): Same. + (parser_inspect): Same. + * lexio.cc (indicated): Const pointer. + (remove_inline_comment): Scope reduction. + (maybe_add_space): Const pointer. + (recognize_replacements): C++ cast. + (check_source_format_directive): Same. + (struct replacing_term_t): Explicit constructor. + (parse_replace_pairs): Const reference. + (location_in): Const reference. + (parse_copy_directive): C++ cast. + (parse_replace_last_off): Const parameter. + (parse_replace_text): Const reference. + (parse_replace_directive): C++ cast. + (cdftext::lex_open): Const reference. + (cdftext::open_output): Scope reduction. + (cdftext::free_form_reference_format): Remove unused variable. + (cdftext::process_file): Simplify. + * lexio.h (struct bytespan_t): Use nullptr. + (struct filespan_t): Initialize icol in constructor. + (struct span_t): Suppress confused operatorEqRetRefThis. + (struct replace_t): Eliminate single-value constructor. + * parse.y: Many const cppcheck reports, and portable bit-shift. + * parse_ante.h (reject_refmod): Const parameter. + (require_pointer): Same. + (require_integer): Same. + (struct evaluate_elem_t): Explicit constructor. + (struct arith_t): Use std::vector. + (class eval_subject_t): Const parameter. + (dump_inspect_match): Declare. + (struct perform_t): Explicit constructor. + (list_add): Const parameter. + (class tokenset_t): Avoid negative array index. + (struct file_list_t): Explicit constructor. + (struct field_list_t): Same. + (struct refer_list_t): Same. + (struct refer_marked_list_t): Const parameter. + (struct refer_collection_t): Explicit constructor. + (struct ast_inspect_oper_t): Remove class. + (ast_inspect_oper_t): Same. + (struct ast_inspect_t): Same. + (struct ast_inspect_list_t): Same. + (ast_inspect): Add location. + (struct elem_list_t): Explicit constructor. + (struct unstring_tgt_t): Same. + (struct unstring_tgt_list_t): Same. + (struct unstring_into_t): Same. + (struct ffi_args_t): Same. + (struct file_sort_io_t): Same. + (merge_t): Same. + (struct vargs_t): Same. + (class prog_descr_t): Eliminate single-value constructor. + (class program_stack_t): Suppress useStlAlgorithm. + (struct rel_part_t): Eliminate single-value constructor. + (class log_expr_t): Explicit constructor. + (add_debugging_declarative): Rename local variable. + (intrinsic_call_2): Const parameter. + (invalid_key): Use std::find_if. + (parser_add2): Const parameter. + (parser_subtract2): Same. + (stringify): Same. + (unstringify): Same. + (anybody_redefines): Same. + (ast_call): Same. + * parse_util.h (class cname_cmp): Explicit constructor. + (intrinsic_inconsistent_parameter): Same. + * scan_ante.h (struct cdf_status_t): Eliminate single-value constructor. + (class enter_leave_t): Explicit constructor. + (update_location): Const pointer, explicit constructor. + (symbol_function_token): Const pointer. + (typed_name): Same. + * scan_post.h (datetime_format_of): Scope reduction. + * show_parse.h (class ANALYZE): Use std::vector, explicit consstructor. + * symbols.cc (symbol_table_extend): Scope reduction. + (cbl_ffi_arg_t::cbl_ffi_arg_t): Define default constructor. + (end_of_group): Const pointer. + (symbol_find_odo): Const parameter. + (rename_not_ok): Same. + (field_str): Use %u instead of %d. + (struct capacity_of): Const pointer. + (symbols_update): Same. + (symbol_field_parent_set): Same. + (symbol_file_add): Same. + (symbol_typedef_add): Same. + (symbol_field_add): Use new operator=(). + (symbol_field): Suppress CastIntegerToAddressAtReturn. + (symbol_register): Same. + (symbol_file): Suppress knownConditionTrueFalse. + (next_program): Const parameter. + (symbol_file_record): Same. + (class is_section): Explicit constructor. + (cbl_file_t::no_key): Remove. + (cbl_prog_hier_t::cbl_prog_hier_t): Use std::vector. + (symbol_label_add): Assert pointer is not NULL. + (symbol_label_section_exists): Const reference in lambda. + (expand_picture): Use C++ cast. + (symbol_program_callables): Const pointer. + (symbol_currency_add): Suppress nullPointerRedundantCheck. + (cbl_key_t): Use std::vector. + (cbl_occurs_t::field_add): Const parameter. + (cbl_occurs_t::index_add): Explicit constructor. + (class is_field_at): Same. + (cbl_file_key_t::deforward): Scope reduction. + (cbl_file_t::keys_str): Use allocated memory only. + (file_status_status_of): Const pointer. + (is_register_field): Const parameter. + * symbols.h (struct cbl_field_data_t): Eliminate single-value constructor. + (struct cbl_occurs_bounds_t): Same. + (struct cbl_refer_t): Use std::vector. + (valid_move): Const parameter. + (is_register_field): Same. + (struct cbl_key_t): Use std::vector. + (struct cbl_substitute_t): Eliminate single-value constructor. + (refer_of): Return const reference + (struct cbl_ffi_arg_t): Eliminate single-value constructor. + (class temporaries_t): Same. + (struct cbl_file_key_t): Define default constructor. + (struct cbl_file_lock_t): Define copy constructor and operator=(). + (struct cbl_file_t): Complete default constructor. + (struct symbol_elem_t): Explicit constructor. + (symbol_elem_of): Suppress cstyleCast. + (symbol_redefines): Const parameter. + (struct cbl_field_t): Same. + (cbl_section_of): Test for NULL pointer. + (cbl_field_of): Same. + (cbl_label_of): Same. + (cbl_special_name_of): Same. + (cbl_alphabet_of): Same. + (cbl_file_of): Same. + (is_figconst): Delete extra "struct" keyword. + (is_figconst_low): Same. + (is_figconst_zero): Same. + (is_figconst_space): Same. + (is_figconst_quote): Same. + (is_figconst_high): Same. + (is_space_value): Same. + (is_quoted): Same. + (symbol_index): Const parameter. + (struct cbl_prog_hier_t): Suppress noExplicitConstructor. + (struct cbl_perform_vary_t): Eliminate single-value constructor. + (is_signable): Const parameter. + (is_temporary): Same. + (rename_not_ok): Same. + (field_at): Test for NULL pointer. + (class procref_base_t): Eliminate single-value constructor. + * symfind.cc (is_data_field): Const pointer. + (finalize_symbol_map2): Same. + (class in_scope): Same. + (symbol_match2): Same. + * token_names.h: Suppress useInitializationList. + * util.cc (normalize_picture): Whitespace and remove extra "continue". + (redefine_field): Const pointer. + (cbl_field_t::report_invalid_initial_value): Same. + (literal_subscript_oob): Rename shadow variable. + (cbl_refer_t::subscripts_set): Use std::vector. + (cbl_refer_t::str): Same. + (cbl_refer_t::deref_str): Same. + (locally_unique): Use explicit constructor. + (ambiguous_reference): Same. + (class unique_stack): Use const reference. + (cobol_filename): Const pointer. + (verify_format): Scope reduction. + (class temp_loc_t): Do not derive from YYLTYPE. + (cobol_parse_files): Const pointer. + * util.h (as_voidp): Define convenient converter. + +2025-06-10 James K. Lowden <jklowden@cobolworx.com> + + * Make-lang.in: cobol.clean does not remove libgcobol files. + * cdf.y: Suppress 1 cppcheck false positive. + * cdfval.h (scanner_parsing): Partial via cppcheck for PR119324. + * gcobol.1: Fix groff errors. + * gcobolspec.cc (append_arg): Const parameter. + * parse_ante.h (intrinsic_call_2): Avoid NULL dereference. + +2025-06-06 Robert Dubner <rdubner@symas.com> + James K. Lowden <jklowden@cobolworx.com> + + PR cobol/120328 + PR cobol/119695 + * Make-lang.in: Success with non-English locale. + * cbldiag.h (cbl_unimplemented_at): Comment: + * cdf-copy.cc (copybook_elem_t::open_file): Indentation. + * cdf.y: YYABORT on certain errors. + * cdfval.h (cdf_value): Const parameter. + * copybook.h (class copybook_elem_t): Initialization. + (class uppername_t): Explicit constructor. + * except.cc (ec_type_descr): Remove %04s. + (cbl_enabled_exceptions_t::dump): Remove %zu. + * exceptg.h (class exception_turn_t): Explicit constructor. + * genapi.cc (parser_perform_conditional): Remove %zu. + (set_exception_environment): Formatting. + (parser_statement_begin): Exception overhead. + (parser_perform_conditional): Formatting: + (parser_perform_conditional_end): Eliminate size_t. + (parser_check_fatal_exception): Exception overhead. + (parser_perform_conditional_end): Remove %zu. + * inspect.h (struct cbx_inspect_match_t): Const reference. + (struct cbx_inspect_t): Const parameter. + * lexio.cc (cdftext::process_file): Remove %zu. + * lexio.h (struct YYLTYPE): Remove unneeded struct. + (YYLTYPE_IS_DECLARED): Likewise. + (YYLTYPE_IS_TRIVIAL): Likewise. + * parse.y: Comment; change DOT. + * scan.l: Scan function names without swallowing whitespace. + * scan_ante.h (scanner_parsing): Remove %zu. + (scanner_parsing_pop): Remove %zu. + (binary_integer_usage): Remove %zu. + * scan_post.h (prelex): Correct post-CDF resumption. + (yylex): Clearer message. + * symbols.cc (symbol_table_extend): Explicit constructor. + (elementize): Const parameter. + (is_variable_length): Correct always-false. + (symbols_update): Remove unnecessary shadow variable. + (struct symbol_elem_t): Const parameter. + (symbol_alphabet_add): Const parameter. + (new_literal_add): Initialization. + * symbols.h (class cbl_domain_elem_t): Correct assignment. + (struct cbl_span_t): Improve constructor. + (struct cbl_refer_t): Initialization. + (struct cbl_alphabet_t): Rename shadow variable. + (struct cbl_file_key_t): Remove unused constructor. + (struct symbol_elem_t): Initialization. + (struct cbl_until_addresses_t): Use unsigned int, for messages. + (struct cbl_prog_hier_t): Initialization. + (struct cbl_perform_tgt_t): Repair constructor. + (struct cbl_label_t): Const parameter. + (symbol_typedef_add): Const parameter. + (symbol_field_add): Explicit constructor. + (symbol_label_add): Explicit constructor. + (symbol_program_add): Remove C-style "struct" use. + (symbol_special_add): Remove C-style "struct" use. + (symbol_alphabet_add): Const parameter. + (symbol_file_add): Remove C-style "struct" use. + (symbol_section_add): Remove C-style "struct" use. + * symfind.cc: Const parameter. + * util.cc (gb4): New function. + * util.h (gb4): New function. + * TODO: New file. + +2025-06-05 Robert Dubner <rdubner@symas.com> + + PR cobol/119975 + * genapi.cc (parser_intrinsic_call_0): Use get_time_nanoseconds(). + * genutil.cc (get_time_64): Rename to get_time_nanoseconds(). + (get_time_nanoseconds): Likewise. + * genutil.h (get_time_64): Likewise. + (get_time_nanoseconds): Likewise. + * util.cc (class cbl_timespec): Timing routine uses + get_time_nanoseconds(). + (operator-): Likewise. + (parse_file): Likewise. + 2025-06-02 Robert Dubner <rdubner@symas.com> PR cobol/119975 diff --git a/gcc/cobol/Make-lang.in b/gcc/cobol/Make-lang.in index a474123d741b..0e2a773d4dfb 100644 --- a/gcc/cobol/Make-lang.in +++ b/gcc/cobol/Make-lang.in @@ -34,6 +34,9 @@ # - the compiler proper (eg: cc1plus) # - define the names for selecting the language in LANGUAGES. +# Use strict warnings for this front end. +cobol-warn = $(STRICT_WARN) + GCOBOL_INSTALL_NAME := $(shell echo gcobol|sed '$(program_transform_name)') GCOBOLIO_INSTALL_NAME := $(shell echo gcobol-io|sed '$(program_transform_name)') GCOBOL_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gcobol|sed '$(program_transform_name)') @@ -159,8 +162,7 @@ FLEX_WARNING = warning, dangerous trailing context cobol/scan.cc: cobol/scan.l $(FLEX) -o$@ $(LFLAGS) $< 2>$@~ || { cat $@~ >&1; exit 1; } awk '! /$(FLEX_WARNING)/ {print > "/dev/stderr"; nerr++} \ - END {print "$(FLEX):", NR, "messages" > "/dev/stderr"; \ - exit nerr}' $@~ + END {print "$(FLEX):", NR, "messages" > "/dev/stderr"}' $@~ @rm $@~ @@ -285,7 +287,7 @@ cobol.install-common: installdirs rm -f $(DESTDIR)$(bindir)/$(GCOBOL_TARGET_INSTALL_NAME)$(exeext); \ rm -f $(DESTDIR)$(bindir)/$(GCOBC_TARGET_INSTALL_NAME)$(exeext); \ ( cd $(DESTDIR)$(bindir) && \ - $(LN) $(GCOBOL_INSTALL_NAME)$(exeext) $(GCOBOL_TARGET_INSTALL_NAME)$(exeext) ); \ + $(LN) $(GCOBOL_INSTALL_NAME)$(exeext) $(GCOBOL_TARGET_INSTALL_NAME)$(exeext) && \ $(LN) $(GCOBC_INSTALL_NAME)$(exeext) $(GCOBC_TARGET_INSTALL_NAME)$(exeext) ); \ fi; \ fi @@ -351,10 +353,16 @@ cobol.srcman: cobol.mostlyclean: -cobol.clean: +gcobol.clean: +# This is intended for non-general use. It is a last-ditch effort to flush +# out all oject files and executable code for gcobol and libgcobol, causing +# a complete rebuild of all executable code. rm -fr gcobol cobol1 cobol/* \ ../*/libgcobol/* +cobol.clean: + rm -fr gcobol cobol1 cobol/* + cobol.distclean: cobol.maintainer-clean: @@ -376,3 +384,4 @@ cobol.stagefeedback: stagefeedback-start selftest-cobol: lang_checks += check-cobol + diff --git a/gcc/cobol/TODO b/gcc/cobol/TODO new file mode 100644 index 000000000000..02ee0e2a4e79 --- /dev/null +++ b/gcc/cobol/TODO @@ -0,0 +1,33 @@ +Below is listed work to be done, hopefully all of it in 2025 for +GCC 16. They are vaguely in priority order, in that addressing more +technical issues may illuminate ways to attack more amorphous ones. + +Portability: + - host/target, for cross-compilation + - OS portability, BSD, macOS, Solaris + - 64-bit portability, LE + - 64-bit portability, BE + - 2025 goal: Compile & run on primary & secondary GCC 15 platforms + https://www.gnu.org/software/gcc/gcc-15/criteria.html + +Correctness: + - LTO ODR, PR 119215 + - cppcheck + - valgrind + - -static produces dynamic + +Efficiency: + - Code size for MOVE 'a' TO FOO(1,1) + - EC checking + +COBOL Features: + - XML, JSON + - MF system functions + - National characters (and Unicode, for IBM) + - GLOBAL and PERFORM declaratives + - dialect feature names (to enable and enumerate) + +GCC features: + - make check-nist + - -Werror, -Wno-<foo> + - -fEC-ALL, -fno-EC-I-O diff --git a/gcc/cobol/cbldiag.h b/gcc/cobol/cbldiag.h index 3cb54e74c75d..39f13690bec9 100644 --- a/gcc/cobol/cbldiag.h +++ b/gcc/cobol/cbldiag.h @@ -33,7 +33,7 @@ #else #define _CBLDIAG_H -#if 0 +#if GCOBOL_GETENV #define gcobol_getenv(x) getenv(x) #else #define gcobol_getenv(x) ((char *)nullptr) @@ -45,8 +45,8 @@ const char * cobol_filename(); * These are user-facing messages. They go through the gcc * diagnostic framework and use text that can be localized. */ -void yyerror( const char fmt[], ... ); -bool yywarn( const char fmt[], ... ); +void yyerror( const char fmt[], ... ) ATTRIBUTE_GCOBOL_DIAG(1, 2); +bool yywarn( const char fmt[], ... ) ATTRIBUTE_GCOBOL_DIAG(1, 2); /* Location type. Borrowed from parse.h as generated by Bison. */ #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED @@ -78,39 +78,58 @@ struct YDFLTYPE #endif +// Diagnostic format specifiers are documented in gcc/pretty-print.cc // an error at a location, called from the parser for semantic errors -void error_msg( const YYLTYPE& loc, const char gmsgid[], ... ); +void error_msg( const YYLTYPE& loc, const char gmsgid[], ... ) + ATTRIBUTE_GCOBOL_DIAG(2, 3); + +bool +warn_msg( const YYLTYPE& loc, const char gmsgid[], ... ) + ATTRIBUTE_GCOBOL_DIAG(2, 3); + +// an error that uses token_location, not yylloc +void error_msg_direct( const char gmsgid[], ... ) + ATTRIBUTE_GCOBOL_DIAG(1, 2); void dialect_error( const YYLTYPE& loc, const char term[], const char dialect[] ); // for CDF and other warnings that refer back to an earlier line // (not in diagnostic framework yet) -void yyerrorvl( int line, const char *filename, const char fmt[], ... ); +void yyerrorvl( int line, const char *filename, const char fmt[], ... ) + ATTRIBUTE_PRINTF_3; -void cbl_unimplementedw(const char *gmsgid, ...); // warning -void cbl_unimplemented(const char *gmsgid, ...); // error -void cbl_unimplemented_at( const YYLTYPE& loc, const char *gmsgid, ... ); +void cbl_unimplementedw(const char *gmsgid, ...) ATTRIBUTE_GCOBOL_DIAG(1, 2); // warning +void cbl_unimplemented(const char *gmsgid, ...) ATTRIBUTE_GCOBOL_DIAG(1, 2); // error +void cbl_unimplemented_at( const YYLTYPE& loc, const char *gmsgid, ... ) + ATTRIBUTE_GCOBOL_DIAG(2, 3); /* - * dbgmsg produce messages not intended for the user. They cannot - * be localized and fwrite directly to standard out. dbgmsg is activated by - * -fflex-debug or -fyacc-debug. + * dbgmsg produce messages not intended for the user. They cannot be localized + * and fwrite directly to standard error. dbgmsg is activated by -fflex-debug + * or -fyacc-debug. */ void dbgmsg( const char fmt[], ... ) ATTRIBUTE_PRINTF_1; void gcc_location_set( const YYLTYPE& loc ); +void gcc_location_dump(); + // tree.h defines yy_flex_debug as a macro because options.h #if ! defined(yy_flex_debug) template <typename LOC> static void location_dump( const char func[], int line, const char tag[], const LOC& loc) { - extern int yy_flex_debug; - if( yy_flex_debug && gcobol_getenv("update_location") ) - fprintf(stderr, "%s:%d: %s location (%d,%d) to (%d,%d)\n", - func, line, tag, - loc.first_line, loc.first_column, loc.last_line, loc.last_column); + extern int yy_flex_debug; // cppcheck-suppress shadowVariable + if( yy_flex_debug ) { + const char *detail = gcobol_getenv("update_location"); + if( detail ) { + fprintf(stderr, "%s:%d: %s location (%d,%d) to (%d,%d)\n", + func, line, tag, + loc.first_line, loc.first_column, loc.last_line, loc.last_column); + if( *detail == '2' ) gcc_location_dump(); + } + } } #endif // defined(yy_flex_debug) diff --git a/gcc/cobol/cdf-copy.cc b/gcc/cobol/cdf-copy.cc index 99f5866ae86f..11be9b818efa 100644 --- a/gcc/cobol/cdf-copy.cc +++ b/gcc/cobol/cdf-copy.cc @@ -124,13 +124,13 @@ verify_bounds( size_t pos, size_t size, const char input[] ) { */ const char * esc( size_t len, const char input[] ) { - static char spaces[] = "([,;]?[[:space:]])+"; - static char spaceD[] = "(\n {6}D" "|" "[,;]?[[:space:]])+"; + static const char space[] = "([,;]?[[:space:]])+"; + static const char spaceD[] = "(\n {6}D" "|" "[,;]?[[:space:]])+"; static char buffer[64 * 1024]; char *p = buffer; const char *eoinput = input + len; - const char *spacex = is_reference_format()? spaceD : spaces; + const char *spacex = is_reference_format()? spaceD : space; for( const char *s=input; *s && s < eoinput; s++ ) { *p = '\0'; @@ -279,7 +279,7 @@ copybook_elem_t::open_file( const char directory[], bool literally ) { dbgmsg("copybook_elem_t::open_file: trying %s", path); if( (this->fd = open(path, O_RDONLY)) == -1 ) { - dbgmsg("could not open %s: %m", path); + dbgmsg("could not open %s: %s", path, xstrerror(errno)); return fd; } this->source.name = path; @@ -304,9 +304,10 @@ copybook_elem_t::open_file( const char directory[], bool literally ) { dbgmsg("found copybook file %s", filename); this->source.name = xstrdup(filename); if( ! cobol_filename(this->source.name, inode_of(fd)) ) { - error_msg(source.loc, "recursive copybook: '%s' includes itself", this->source); - (void)! close(fd); - fd = -1; + error_msg(source.loc, "recursive copybook: '%s' includes itself", + this->source.name); + (void)! close(fd); + fd = -1; } dbgmsg("%s: opened %s as fd %d", __func__, source.name, fd); return fd; diff --git a/gcc/cobol/cdf.y b/gcc/cobol/cdf.y index 7680f48585bd..53fea5d894ce 100644 --- a/gcc/cobol/cdf.y +++ b/gcc/cobol/cdf.y @@ -95,7 +95,7 @@ void input_file_status_notify(); } \ location_dump("cdf.c", __LINE__, "current", (Current)); \ input_file_status_notify(); \ - gcc_location_set( location_set(Current) ); \ + location_set(Current); \ } while (0) %} @@ -105,14 +105,14 @@ void input_file_status_notify(); using std::map; - static map<std::string, cdfval_t> dictionary; - #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" static bool cdfval_add( const char name[], const cdfval_t& value, bool override = false ) { + cdf_values_t& dictionary( cdf_dictionary() ); + if( scanner_parsing() ) { if( ! override ) { if( dictionary.find(name) != dictionary.end() ) return false; @@ -123,6 +123,8 @@ void input_file_status_notify(); } static void cdfval_off( const char name[] ) { + cdf_values_t& dictionary( cdf_dictionary() ); + if( scanner_parsing() ) { auto p = dictionary.find(name); if( p == dictionary.end() ) { @@ -159,6 +161,8 @@ exception_turn_t exception_turn; bool apply_cdf_turn( const exception_turn_t& turn ) { + cbl_enabled_exceptions_t& enabled_exceptions( cdf_enabled_exceptions() ); + for( auto elem : turn.exception_files() ) { std::set<size_t> files(elem.second.begin(), elem.second.end()); enabled_exceptions.turn_on_off(turn.enabled, @@ -185,6 +189,7 @@ apply_cdf_turn( const exception_turn_t& turn ) { %printer { fprintf(yyo, "%s '%s'", keyword_str($$.token), $$.string? $$.string : "<nil>" ); } <cdfarg> +/* cppcheck-suppress invalidPrintfArgType_sint */ %printer { fprintf(yyo, HOST_SIZE_T_PRINT_DEC " '%s'", (fmt_size_t)$$.number, $$.string? $$.string : "" ); } <cdfval> @@ -203,15 +208,17 @@ apply_cdf_turn( const exception_turn_t& turn ) { %type <file> filename %type <files> filenames -%token BY 478 +%type <number> cdf_stackable + +%token BY 486 %token COPY 362 %token CDF_DISPLAY 384 ">>DISPLAY" -%token IN 597 +%token IN 605 %token NAME 286 %token NUMSTR 305 "numeric literal" -%token OF 678 -%token PSEUDOTEXT 713 -%token REPLACING 735 +%token OF 686 +%token PSEUDOTEXT 721 +%token REPLACING 743 %token LITERAL 298 %token SUPPRESS 376 @@ -226,25 +233,32 @@ apply_cdf_turn( const exception_turn_t& turn ) { %token CDF_WHEN 389 ">>WHEN" %token CDF_END_EVALUATE 390 ">>END-EVALUATE" -%token AS 460 CONSTANT 361 DEFINED 363 +%token ALL 450 +%token CALL_CONVENTION 391 ">>CALL-CONVENTION" +%token COBOL_WORDS 380 ">>COBOL-WORDS" +%token CDF_PUSH 394 ">>PUSH" +%token CDF_POP 395 ">>POP" +%token SOURCE_FORMAT 396 ">>SOURCE FORMAT" + +%token AS 468 CONSTANT 361 DEFINED 363 %type <boolean> DEFINED -%token OTHER 690 PARAMETER_kw 368 "PARAMETER" -%token OFF 679 OVERRIDE 369 -%token THRU 931 -%token TRUE_kw 805 "True" +%token OTHER 698 PARAMETER_kw 368 "PARAMETER" +%token OFF 687 OVERRIDE 369 +%token THRU 939 +%token TRUE_kw 813 "True" -%token CALL_COBOL 391 "CALL" -%token CALL_VERBATIM 392 "CALL (as C)" +%token CALL_COBOL 392 "CALL" +%token CALL_VERBATIM 393 "CALL (as C)" -%token TURN 807 CHECKING 488 LOCATION 641 ON 681 WITH 833 +%token TURN 815 CHECKING 496 LOCATION 649 ON 689 WITH 841 -%left OR 932 -%left AND 933 -%right NOT 934 -%left '<' '>' '=' NE 935 LE 936 GE 937 +%left OR 940 +%left AND 941 +%right NOT 942 +%left '<' '>' '=' NE 943 LE 944 GE 945 %left '-' '+' %left '*' '/' -%right NEG 939 +%right NEG 947 %define api.prefix {ydf} %define api.token.prefix{YDF_} @@ -262,8 +276,8 @@ top: partials { YYACCEPT; } YYACCEPT; } | copy error { - error_msg(@error, "COPY directive must end in a '.'"); - YYACCEPT; + error_msg(@error, "COPY directive must end in a %<.%>"); + YYABORT; } | completes { YYACCEPT; } ; @@ -276,6 +290,8 @@ complete: cdf_define | cdf_display | cdf_turn | cdf_call_convention + | cdf_push + | cdf_pop ; /* @@ -327,6 +343,7 @@ cdf_define: CDF_DEFINE cdf_constant NAME as cdf_expr[value] override } if( !cdfval_add( $NAME, cdfval_t($value), $override) ) { error_msg(@NAME, "name already in dictionary: %s", $NAME); + cdf_values_t& dictionary( cdf_dictionary() ); const cdfval_t& entry = dictionary[$NAME]; if( entry.filename ) { error_msg(@NAME, "%s previously defined in %s:%d", @@ -356,7 +373,7 @@ cdf_define: CDF_DEFINE cdf_constant NAME as cdf_expr[value] override * available regardless. */ { - if( 0 == dictionary.count($NAME) ) { + if( 0 == cdf_dictionary().count($NAME) ) { yywarn("CDF: '%s' is defined AS PARAMETER " "but was not defined", $NAME); } @@ -364,13 +381,15 @@ cdf_define: CDF_DEFINE cdf_constant NAME as cdf_expr[value] override | CDF_DEFINE FEATURE as ON { auto feature = cbl_gcobol_feature_t($2); if( ! cobol_gcobol_feature_set(feature, true) ) { - error_msg(@FEATURE, ">>DEFINE %EBCDIC-MODE is invalid within program body"); + error_msg(@FEATURE, + "%<>>DEFINE %%EBCDIC-MODE%> is invalid within program body"); } } | CDF_DEFINE FEATURE as OFF { auto feature = cbl_gcobol_feature_t($2); if( ! cobol_gcobol_feature_set(feature, false) ) { - error_msg(@FEATURE, ">>DEFINE %EBCDIC-MODE is invalid within program body"); + error_msg(@FEATURE, + "%<>>DEFINE %%EBCDIC-MODE%> is invalid within program body"); } } ; @@ -397,6 +416,35 @@ cdf_call_convention: } ; +cdf_push: CDF_PUSH cdf_stackable { + switch( $cdf_stackable ) { + case YDF_ALL: cdf_push(); break; + case YDF_CALL_CONVENTION: cdf_push_call_convention(); break; + case YDF_CDF_DEFINE: cdf_push_dictionary(); break; + case YDF_COBOL_WORDS: cdf_push_current_tokens(); break; + case YDF_SOURCE_FORMAT: cdf_push_source_format(); break; + default: gcc_unreachable(); + } + } + ; +cdf_pop: CDF_POP cdf_stackable { + switch( $cdf_stackable ) { + case YDF_ALL: cdf_pop(); break; + case YDF_CALL_CONVENTION: cdf_pop_call_convention(); break; + case YDF_CDF_DEFINE: cdf_pop_dictionary(); break; + case YDF_COBOL_WORDS: cdf_pop_current_tokens(); break; + case YDF_SOURCE_FORMAT: cdf_pop_source_format(); break; + default: gcc_unreachable(); + } + } + ; + +cdf_stackable: ALL { $$ = YDF_ALL; } + | CALL_CONVENTION { $$ = YDF_CALL_CONVENTION; } + | COBOL_WORDS { $$ = YDF_COBOL_WORDS; } + | CDF_DEFINE { $$ = YDF_CDF_DEFINE; } + | SOURCE_FORMAT { $$ = YDF_SOURCE_FORMAT; } + ; except_names: except_name | except_names except_name @@ -429,7 +477,7 @@ filenames: filename { auto inserted = $$->insert(symbol_index(symbol_elem_of($2))); if( ! inserted.second ) { error_msg(@2, "%s: No file-name shall be specified more than " - " once for one exception condition", $filename->name); + "once for one exception condition", $filename->name); } } ; @@ -468,6 +516,7 @@ cdf_eval_obj: cdf_cond_expr cdf_cond_expr: BOOL | NAME DEFINED { + cdf_values_t& dictionary( cdf_dictionary() ); auto p = dictionary.find($1); bool found = p != dictionary.end(); if( !$DEFINED ) found = ! found; @@ -516,7 +565,7 @@ cdf_relexpr: cdf_relexpr '<' cdf_expr { $$ = $1(@1) < $3(@3); } const char *msg = $1.string? "incommensurate comparison is FALSE: '%s' = %ld" : "incommensurate comparison is FALSE: %ld = '%s'" ; - error_msg(@1, msg); + error_msg(@1, "%s", msg); } } | cdf_relexpr NE cdf_expr @@ -530,7 +579,7 @@ cdf_relexpr: cdf_relexpr '<' cdf_expr { $$ = $1(@1) < $3(@3); } const char *msg = $1.string? "incommensurate comparison is FALSE: '%s' = %ld" : "incommensurate comparison is FALSE: %ld = '%s'" ; - error_msg(@1, msg); + error_msg(@1, "%s", msg); } } | cdf_relexpr GE cdf_expr { $$ = $1(@1) >= $3(@3); } @@ -549,6 +598,7 @@ cdf_expr: cdf_expr '+' cdf_expr { $$ = $1(@1) + $3(@3); } ; cdf_factor: NAME { + cdf_values_t& dictionary( cdf_dictionary() ); auto that = dictionary.find($1); if( that != dictionary.end() ) { $$ = that->second; @@ -566,7 +616,7 @@ cdf_factor: NAME { | NUMSTR { auto value = integer_literal($NUMSTR); if( !value.second ) { - error_msg(@1, "CDF error: parsed %s as %ld", + error_msg(@1, "CDF error: parsed %qs as %lld", $NUMSTR, value.first); YYERROR; } @@ -584,7 +634,7 @@ copybook_name: COPY name_one[src] if( -1 == copybook.open(@src, $src.string) ) { error_msg(@src, "could not open copybook file " "for '%s'", $src.string); - YYERROR; + YYABORT; } } | COPY name_one[src] IN name_one[lib] @@ -592,8 +642,8 @@ copybook_name: COPY name_one[src] copybook.library(@lib, $lib.string); if( -1 == copybook.open(@src, $src.string) ) { error_msg(@src, "could not open copybook file " - "for '%s' in '%'s'", $src.string, $lib.string); - YYERROR; + "for %<%s%> in %<%s%>", $src.string, $lib.string); + YYABORT; } } ; @@ -648,6 +698,7 @@ name_any: namelit name_one: NAME { + cdf_values_t& dictionary( cdf_dictionary() ); cdf_arg_t arg = { YDF_NAME, $1 }; auto p = dictionary.find($1); @@ -662,6 +713,7 @@ name_one: NAME namelit: name { + cdf_values_t& dictionary( cdf_dictionary() ); cdf_arg_t arg = { YDF_NAME, $1 }; auto p = dictionary.find($1); @@ -742,6 +794,7 @@ location_set( const YYLTYPE& loc ) { bool // used by cobol1.cc defined_cmd( const char arg[] ) { + cdf_values_t& dictionary( cdf_dictionary() ); cdfval_t value(1); char *name = xstrdup(arg); @@ -864,7 +917,8 @@ static int ydflex(void) { } bool -cdf_value( const char name[], cdfval_t value ) { +cdf_value( const char name[], const cdfval_t& value ) { + cdf_values_t& dictionary( cdf_dictionary() ); auto p = dictionary.find(name); if( p != dictionary.end() ) return false; @@ -875,6 +929,7 @@ cdf_value( const char name[], cdfval_t value ) { const cdfval_t * cdf_value( const char name[] ) { + cdf_values_t& dictionary( cdf_dictionary() ); auto p = dictionary.find(name); if( p == dictionary.end() ) return NULL; @@ -894,5 +949,6 @@ verify_integer( const YDFLTYPE& loc, const cdfval_base_t& val ) { const cdfval_base_t& cdfval_base_t::operator()( const YDFLTYPE& loc ) { static cdfval_t zero(0); + // cppcheck-suppress returnTempReference return verify_integer(loc, *this) ? *this : zero; } diff --git a/gcc/cobol/cdfval.h b/gcc/cobol/cdfval.h index 76ed7dae0fdf..cc474a22a482 100644 --- a/gcc/cobol/cdfval.h +++ b/gcc/cobol/cdfval.h @@ -38,6 +38,14 @@ bool scanner_parsing(); +/* cdfval_base_t has no constructor because otherwise: + * cobol/cdf.h:172:7: note: ‘YDFSTYPE::YDFSTYPE()’ is implicitly deleted + * because the default definition would be ill-formed: + * 172 | union YDFSTYPE + * + * We use the derived type cdfval_t, which can be properly constructed and + * operated on, but tell Bison only about its POD base class. + */ struct YDFLTYPE; struct cdfval_base_t { bool off; @@ -65,28 +73,28 @@ struct cdfval_t : public cdfval_base_t { cdfval_base_t::string = NULL; cdfval_base_t::number = 0; } - cdfval_t( const char value[] ) + cdfval_t( const char value[] ) // cppcheck-suppress noExplicitConstructor : lineno(yylineno), filename(cobol_filename()) { cdfval_base_t::off = false; cdfval_base_t::string = value; cdfval_base_t::number = 0; } - cdfval_t( long long value ) + cdfval_t( long long value ) // cppcheck-suppress noExplicitConstructor : lineno(yylineno), filename(cobol_filename()) { cdfval_base_t::off = false; cdfval_base_t::string = NULL; cdfval_base_t::number = value; } - cdfval_t( long value ) + cdfval_t( long value ) // cppcheck-suppress noExplicitConstructor : lineno(yylineno), filename(cobol_filename()) { cdfval_base_t::off = false; cdfval_base_t::string = NULL; cdfval_base_t::number = value; } - cdfval_t( int value ) + cdfval_t( int value ) // cppcheck-suppress noExplicitConstructor : lineno(yylineno), filename(cobol_filename()) { cdfval_base_t::off = false; @@ -101,7 +109,7 @@ struct cdfval_t : public cdfval_base_t { HOST_WIDE_INT value = real_to_integer(&r); cdfval_base_t::number = value; } - cdfval_t( const cdfval_base_t& value ) + cdfval_t( const cdfval_base_t& value ) // cppcheck-suppress noExplicitConstructor : lineno(yylineno), filename(cobol_filename()) { cdfval_base_t *self(this); @@ -116,6 +124,10 @@ const cdfval_t * cdf_value( const char name[] ); bool -cdf_value( const char name[], cdfval_t value ); +cdf_value( const char name[], const cdfval_t& value ); + +typedef std::map<std::string, cdfval_t> cdf_values_t; + +cdf_values_t& cdf_dictionary(); #endif diff --git a/gcc/cobol/cobol-system.h b/gcc/cobol/cobol-system.h index ff9583530e25..828f4f53ec8b 100644 --- a/gcc/cobol/cobol-system.h +++ b/gcc/cobol/cobol-system.h @@ -60,4 +60,10 @@ // The following "local" #include is part of the GCC core code #include "system.h" +#if (CHECKING_P && GCC_VERSION >= 4001) || GCC_VERSION == BUILDING_GCC_VERSION +#define ATTRIBUTE_GCOBOL_DIAG(m, n) __attribute__ ((__format__ (__gcc_tdiag__, m, n))) ATTRIBUTE_NONNULL(m) +#else +#define ATTRIBUTE_GCOBOL_DIAG(m, n) ATTRIBUTE_NONNULL(m) +#endif + #endif diff --git a/gcc/cobol/cobol1.cc b/gcc/cobol/cobol1.cc index 63f2b37816d1..3146da578998 100644 --- a/gcc/cobol/cobol1.cc +++ b/gcc/cobol/cobol1.cc @@ -357,7 +357,7 @@ cobol_langhook_handle_option (size_t scode, return true; case OPT_M: - cobol_set_pp_option('M'); + cobol_set_pp_option('M'); return true; case OPT_fstatic_call: @@ -368,16 +368,18 @@ cobol_langhook_handle_option (size_t scode, wsclear(cobol_default_byte); return true; - case OPT_fflex_debug: + case OPT_fflex_debug: // cppcheck-suppress syntaxError // The need for this is a mystery yy_flex_debug = 1; cobol_set_debugging( true, yy_debug == 1, cobol_trace_debug == 1 ); return true; + case OPT_fyacc_debug: yy_debug = 1; cobol_set_debugging(yy_flex_debug == 1, true, cobol_trace_debug == 1 ); return true; + case OPT_ftrace_debug: cobol_set_debugging( yy_flex_debug == 1, yy_debug == 1, true ); return true; @@ -406,11 +408,13 @@ cobol_langhook_handle_option (size_t scode, case OPT_fsyntax_only: mode_syntax_only(identification_div_e); break; + case OPT_preprocess: if( ! preprocess_filter_add(arg) ) { cbl_errx( "could not execute preprocessor %s", arg); } return true; + case OPT_include: if( ! include_file_add(arg) ) { cbl_errx( "could not include %s", arg); @@ -571,7 +575,7 @@ cobol_name_mangler(const char *cobol_name_) } // Allocate enough space for a prepended underscore and a final '\0' - char *cobol_name = (char *)xmalloc(strlen(cobol_name_)+2); + char *cobol_name = static_cast<char *>(xmalloc(strlen(cobol_name_)+2)); size_t n = 0; if( cobol_name_[0] >= '0' && cobol_name_[0] <= '9' ) { diff --git a/gcc/cobol/copybook.h b/gcc/cobol/copybook.h index a4b1117f9565..ff8c6d0ca276 100644 --- a/gcc/cobol/copybook.h +++ b/gcc/cobol/copybook.h @@ -62,7 +62,7 @@ class copybook_elem_t { struct copybook_loc_t { YYLTYPE loc; const char *name; - copybook_loc_t() : name(NULL) {} + copybook_loc_t() : loc(), name(NULL) {} } source, library; bool suppress; static std::list<const char *> suffixes; @@ -74,12 +74,11 @@ class copybook_elem_t { copybook_elem_t() : suppress(false) + , literally() , fd(-1) , nsubexpr(0) , regex_text(NULL) - { - literally = {}; - } + {} void clear() { suppress = false; @@ -101,7 +100,7 @@ class copybook_elem_t { } static char * dequote( const char orig[] ) { gcc_assert(quoted(orig)); - auto name = (char*)xcalloc(1, strlen(orig)); + auto name = static_cast<char*>(xcalloc(1, strlen(orig))); gcc_assert(name); char *tgt = name; @@ -130,7 +129,7 @@ class copybook_elem_t { class uppername_t { std::string upper; public: - uppername_t( const std::string input ) : upper(input) { + explicit uppername_t( const std::string& input ) : upper(input) { std::transform(input.begin(), input.end(), upper.begin(), []( char ch ) { return TOUPPER(ch); } ); } diff --git a/gcc/cobol/dts.h b/gcc/cobol/dts.h index dfd7c4c24f71..c900c4515a78 100644 --- a/gcc/cobol/dts.h +++ b/gcc/cobol/dts.h @@ -35,13 +35,13 @@ namespace dts { { static regmatch_t empty; empty.rm_so = empty.rm_eo = -1; - regmatch_t& self(*this); + regmatch_t& self(*this); // cppcheck-suppress constVariableReference self = empty; } csub_match( const char input[], const regmatch_t& m ) : input(input) { - regmatch_t& self(*this); + regmatch_t& self(*this); // cppcheck-suppress constVariableReference self = m; matched = rm_so != -1; first = rm_so == -1? NULL : input + rm_so; @@ -68,7 +68,6 @@ namespace dts { #if __cpp_exceptions throw std::logic_error(msg); #else - pattern = NULL; cbl_errx("%s", msg); #endif } @@ -78,7 +77,7 @@ namespace dts { size_t size() const { return nsubexpr; } bool ready() const { return pattern != NULL; } private: - regex( const regex& ) {} + regex( const regex& ) = default; }; inline bool regex_search( const char input[], const char *eoinput, @@ -87,24 +86,30 @@ namespace dts { #if __cpp_exceptions static const char msg[] = "input not NUL-terminated"; throw std::domain_error( msg ); -#else - eoinput = strchr(input, '\0'); #endif } - if( eoinput == NULL ) eoinput = strchr(input, '\0'); auto ncm = re.size(); cm.resize(ncm); std::vector <regmatch_t> cms(ncm); - int erc = regexec( &re, input, ncm, cms.data(), 0 ); if( erc != 0 ) return false; +#if __cpp_exceptions + // This is not correct at all, but current use depends on current behavior. + // The following line is excluded from the GCC build, which is compiled + // without __cpp_exceptions. parse_copy_directive (for one) depends on + // regex_search returning true even if the match is beyond eoinput. + if( eoinput < cm[0].second ) return false; + // Correct behavior would return match only between input and eoinput. + // Because regex(3) uses a NUL terminator, it may match text between + // eoinput and the NUL. +#endif std::transform( cms.begin(), cms.end(), cm.begin(), [input]( const regmatch_t& m ) { return csub_match( input, m ); } ); return true; } -}; +} diff --git a/gcc/cobol/except.cc b/gcc/cobol/except.cc index d477139a1e1a..df1c7dfb1d1a 100644 --- a/gcc/cobol/except.cc +++ b/gcc/cobol/except.cc @@ -51,7 +51,7 @@ static const ec_descr_t * ec_type_descr( ec_type_t type ) { auto p = std::find( __gg__exception_table, __gg__exception_table_end, type ); if( p == __gg__exception_table_end ) { - cbl_internal_error("no such exception: 0x%04x", type); + cbl_internal_error("no such exception: 0x%x", type); } return p; } @@ -77,15 +77,13 @@ ec_level( ec_type_t ec ) { void cbl_enabled_exception_t::dump( int i ) const { - cbl_message(2, "cbl_enabled_exception_t: %2d {%s, %s, %s, %zu}", + cbl_message(2, "cbl_enabled_exception_t: %2d {%s, %s, %zu}", i, location? "location" : " none", ec_type_str(ec), file ); } -cbl_enabled_exceptions_t enabled_exceptions; - void cbl_enabled_exceptions_t::dump() const { extern int yydebug; @@ -98,24 +96,26 @@ cbl_enabled_exceptions_t::dump() const { return; } int i = 1; - for( auto& elem : *this ) { - dbgmsg("cbl_enabled_exceptions_t: %2d {%s, %s, %zu}", + for( auto& elem : *this ) { // cppcheck-suppress constVariableReference + dbgmsg("cbl_enabled_exceptions_t: %2d {%s, %s, %lu}", i++, elem.location? "with location" : " no location", ec_type_str(elem.ec), - elem.file ); + gb4(elem.file) ); } std::swap(debug, yydebug); } +// cppcheck-suppress-begin [useStlAlgorithm] because why? uint32_t cbl_enabled_exceptions_t::status() const { uint32_t status_word = 0; for( const auto& ena : *this ) { status_word |= (EC_ALL_E & ena.ec ); - } + } return status_word; } +// cppcheck-suppress-end useStlAlgorithm std::vector<uint64_t> cbl_enabled_exceptions_t::encode() const { @@ -133,13 +133,13 @@ void cbl_enabled_exceptions_t::turn_on_off( bool enabled, bool location, ec_type_t type, - std::set<size_t> files ) + const std::set<size_t>& files ) { // Update current enabled ECs tree on leaving this function. class update_parser_t { const cbl_enabled_exceptions_t& ecs; public: - update_parser_t(const cbl_enabled_exceptions_t& ecs) : ecs(ecs) {} + explicit update_parser_t(const cbl_enabled_exceptions_t& ecs) : ecs(ecs) {} ~update_parser_t() { tree ena = parser_compile_ecs(ecs.encode()); current_enabled_ecs(ena); @@ -244,16 +244,6 @@ cbl_enabled_exceptions_t::match( ec_type_t type, size_t file ) const { return output != end()? &*output : NULL; } -class choose_declarative { - size_t program; - public: - choose_declarative( size_t program ) : program(program) {} - - bool operator()( const cbl_declarative_t& dcl ) { - return dcl.global || program == symbol_at(dcl.section)->program; - } -}; - bool sort_supers_last( const cbl_declarative_t& a, const cbl_declarative_t& b ) { if( symbol_at(a.section)->program == symbol_at(b.section)->program ) { diff --git a/gcc/cobol/exceptg.h b/gcc/cobol/exceptg.h index e29e056dbf14..f90cc28ebc50 100644 --- a/gcc/cobol/exceptg.h +++ b/gcc/cobol/exceptg.h @@ -58,8 +58,8 @@ class exception_turn_t { exception_turn_t() : enabled(false), location(false) {}; - exception_turn_t( ec_type_t ec, bool enabled = true ) - : enabled(enabled) + explicit exception_turn_t( ec_type_t ec, bool enabled = true ) + : enabled(enabled), location(false) { add_exception(ec); } @@ -74,7 +74,7 @@ class exception_turn_t { const ec_filemap_t& exception_files() const { return exceptions; } - bool add_exception( ec_type_t type, const filelist_t files = filelist_t() ) { + bool add_exception( ec_type_t type, const filelist_t& files = filelist_t() ) { ec_disposition_t disposition = ec_type_disposition(type); if( disposition != ec_implemented(disposition) ) { cbl_unimplementedw("CDF: exception '%s'", ec_type_str(type)); diff --git a/gcc/cobol/gcobc b/gcc/cobol/gcobc index 8c2245f5f82c..fa9f6095d327 100755 --- a/gcc/cobol/gcobc +++ b/gcc/cobol/gcobc @@ -35,6 +35,10 @@ ## output set the mode variable. Everything else is appended to the ## opts variable. ## +## - -fPIC is added to the command line if $mode is "-shared". That +## option applies only to "certain machines", per the gcc info +## manual. For this script to be portable across machines, -fPIC +## would have to be set more judiciously. if [ "$COBCPY" ] then @@ -121,25 +125,24 @@ $0 recognizes the following GnuCOBOL cobc compilation options: -std=mvs -std=mvs-strict -std=mf -std=mf-strict -std=cobol85 -std=cobol2002 -std=cobol2014 - Options that are the same in gcobol and cobc are passed through verbatim. - Options that have no analog in gcobol produce a warning message. - To produce this message, use -HELP. +Options that are the same in gcobol and cobc are passed through verbatim. +Options that have no analog in gcobol produce a warning message. +To produce this message, use -HELP. To see the constructed cobc command-line, use -echo. To override the default cobc, set the "cobc" environment variable. By default, gcobc invokes the gcobol the same directory the gcobc resides. To override, set the gcobol environment variable. - EOF - } +EOF +} -dialect="gnu" +dialect="mf gnu" out_set="" first="" - # - # Simply iterate over the command-line tokens. We can't use getopts - # here because it's not designed for single-dash words (e.g. -shared). # - +# Iterate over the command-line tokens. We can't use getopts here +# because it's not designed for single-dash words (e.g. -shared). +# for opt in "$@" do if [ "$skip_arg" ] @@ -437,11 +440,13 @@ do -std=mvs | -std=mvs-strict | -std=ibm | -std=ibm-strict) dialect=ibm ;; -std=mf | -std=mf-strict) dialect=mf - ;; - -std=default) dialect=gnu # that's GnuCOBOL's default and GCC's dialect for GnuCOBOL - ;; - -std=cobol*) dialect="" # GCC COBOL targets COBOL2024 "mostly backward to COBOL85" - ;; + ;; + # GnuCOBOL's default and GCC's dialect for GnuCOBOL + -std=default) dialect=gnu + ;; + # GCC COBOL targets COBOL2024 "mostly backward to COBOL85" + -std=cobol*) dialect="" + ;; -std=*) dialect="" warn "$opt (unkown dialect)" @@ -476,14 +481,16 @@ do opts="$opts /dev/stdin" ;; - *) if [ -z "$output_name" ] # first non-option argument is source file name + # First file name argument is default output filename. + *) if [ -z "$output_name" -a -e "$opt" ] then - output_name=$(basename ${opt%.*}) + output_name=$(basename "${opt%.*}") case $mode in -c) output_name="$output_name".o ;; -shared) output_name="$output_name".so + opts="$opts -fPIC" ;; esac opts="$opts -o $output_name" @@ -507,6 +514,11 @@ fi # To override the default gcobol, set the "gcobol" environment variable. gcobol="${gcobol:-${0%/*}/gcobol}" +if [ "$dialect" ] +then + dialect=$(echo $dialect | sed -E 's/[[:alnum:]]+/-dialect &/g') +fi + if [ "$echo" ] then echo $gcobol $mode $opts @@ -518,4 +530,4 @@ then set -x fi -exec $gcobol $mode $opts +exec $gcobol $mode $dialect $opts diff --git a/gcc/cobol/gcobol.1 b/gcc/cobol/gcobol.1 index 0ce890e97229..ebb833c793bd 100644 --- a/gcc/cobol/gcobol.1 +++ b/gcc/cobol/gcobol.1 @@ -39,7 +39,7 @@ compiles \*[lang] source code to object code, and optionally produces an executable binary or shared object. As a GCC component, it accepts all options that affect code-generation and linking. Options specific to \*[lang] are listed below. -.Bl -tag -width \0\0debug +.Bl -tag -width "\0\0debug" .It Fl main Ar filename .Nm will generate a @@ -197,14 +197,12 @@ Otherwise, columns 1-6 are examined. If those characters are all digits or blanks, the file is assumed to be in .Em "fixed-form reference format", also with the indicator in column 7. - If not auto-detected as .Em "fixed-form reference format" or .Em "extended source format", the file is assumed to be in .Em "free-form reference format". - .Pp . .It Fl fcobol-exceptions Ar exception Op Ns , Ns Ar exception Ns ... @@ -589,6 +587,21 @@ statement, regardless of compile-time constants. .. . .Ss Implemented Exception Conditions +By default, per ISO, no EC is enabled. Implemented ECs may be enabled +on the command line or via the +.Sy TURN +directive. Any attempt to enable an EC that is not implemented is +treated as an error. +.Pp +An enabled EC not handled by a +.Sy DECLARATIVE +is written to the system log and to standard error. (The authors +intend to make that an option.) A fatal EC not handled with +.Sy RESUME +ends with a call to +.Xr abort 3 +and process termination. +.Pp Not all Exception Conditions are implemented. Any attempt to enable an EC that that is not implemented produces a warning message. The following are implemented: @@ -915,11 +928,90 @@ or has no effect; the two are interchangeable. .. . -.Ss Compiler-Directing Facility (CDF) +.Sh COMPILER-DIRECTING FACILITY The CDF should be used with caution because no comprehensive test -suite has been identified. +suite has been identified. . -.Ss Conditional Compilation +.Ss CDF Text Manipulation +.Bl -tag -width >>DEFINE +.It Sy COPY Ar copybook Li Oo OF|BY Ar library Oc Oo Sy REPLACING ... Oc +If +.Ar copybook +is a literal, it treated a literal filename, which either does or does not exist. If +.Ar copybook +is a \*[lang] word, +.Nm +looks first for an environment variable named +.Va copybook +and, if found, uses the contents of that variable as the name of the +copybook file. If that file does not exist, it continues looking for +a file named one of: +.sp +.Bl -bullet -compact -offset 5n +.It +.Pa copybook +(literally) +.It +.Pa copybook.cpy +.It +.Pa copybook.CPY +.It +.Pa copybook.cbl +.It +.Pa copybook.CBL +.It +.Pa copybook.cob +.It +.Pa copybook.COB +.El +.sp +in that order. It looks first in the same directory as the source +code file, and then in any +.Ar copybook-path +named with the +.Fl I +option. +. +.\" FIXME: need escape mechanism for directories with ':' in the name. +.Ar copybook-path +may (like the shell's +.Ev PATH +variable) be a colon-separated list. +The +.Fl I +option may occur multiple times on the command line. Each successive +.Ar copybook-path +is concatenated to previous ones. +Relative paths (having no leading +.Ql / Ns +\&) +are searched relative to the compiler's current working directory. +.Pp +For example, +.D1 \& +.D1 Fl I Li /usr/local/include:include +.D1 \& +searches first the directory where the \*[lang] program is found, next in +.Pa /usr/local/include , +and finally in an +.Pa include +subdirectory of the directory from which +.Nm +was invoked. +.Pp +For the +.Sy REPLACING +phrase, both the modern pseudo-text and the \*[lang]/85 forms are +recognized. (The older forms are used in the NIST CCVS/85 test suite.) +.It Sy REPLACE ... +.Nm +supports the full ISO +.Sy REPLACE +syntax. +.El +. +.Ss CDF Directives +.\"Bl -tag -width >>PROPAGATE .Bl -tag -width >>DEFINE .It >> Ns Sy DEFINE Ar name Sy AS Bro Ar expression Li | Sy PARAMETER Brc Op Sy OVERRIDE Define @@ -961,10 +1053,6 @@ is supported. Boolean literals are not supported. . .It >> Ns Sy EVALUATE Not implemented. -.El -. -.Ss Other CDF Directives -.Bl -tag -width >>PROPAGATE .It >> Ns Sy CALL-CONVENTION Ar convention .Ar convention may be one of: @@ -1038,6 +1126,24 @@ Not implemented. Not implemented. .It >> Ns Sy PROPAGATE Not implemented. +.It >> Ns Sy PUSH Ar directive +.It >> Ns Sy POP Ar directive +With +.Sy PUSH , +push CDF state onto a stack. +With +.Sy POP , +return to the prior pushed state. +.Ar directive +may be one of +.Bl -tag -compact +.It Sy CALL-CONVENTION +.It Sy COBOL-WORDS +.It Sy DEFINE +.It Sy SOURCE FORMAT +.It Sy TURN +.El +. .It >> Ns Sy TURN Oo .Ar ec Oo Ar file Li ... Oc ... .Oc Sy CHECKING Bro Oo Sy ON Oc Oo Oo Sy WITH Oc Sy LOCATION Oc | Sy OFF Brc @@ -1088,76 +1194,6 @@ the directive must appear before .Pp To test a feature-set variable, use .Dl >>IF Ar feature Li DEFINED -.. -.Ss Copybooks -.Nm -supports the CDF -.Sy COPY -statement, with or without its -.Sy REPLACING -component. For any statement -.sp -.D1 COPY Ar copybook -.sp -.Nm -looks first for an environment variable named -.Va copybook -and, if found, uses the contents of that variable as the name of the -copybook file. If that file does not exist, it continues looking for -a file named one of: -.sp -.Bl -bullet -compact -offset 5n -.It -.Pa copybook -(literally) -.It -.Pa copybook.cpy -.It -.Pa copybook.CPY -.It -.Pa copybook.cbl -.It -.Pa copybook.CBL -.It -.Pa copybook.cob -.It -.Pa copybook.COB -.El -.sp -in that order. It looks first in the same directory as the source -code file, and then in any -.Ar copybook-path -named with the -.Fl I -option. -. -.\" FIXME: need escape mechanism for directories with ':' in the name. -.Ar copybook-path -may (like the shell's -.Ev PATH -variable) be a colon-separated list. -. -The -.Fl I -option may occur multiple times on the command line. Each successive -.Ar copybook-path -is concatenated to previous ones. -Relative paths (having no leading -.Ql / Ns -\&) -are searched relative to the compiler's current working directory. -.Pp -For example, -.D1 \& -.D1 Fl I Li /usr/local/include:include -.D1 \& -searches first the directory where the \*[lang] program is found, next in -.Pa /usr/local/include , -and finally in an -.Pa include -subdirectory of the directory from which -.Nm -was invoked. . .Ss Intrinsic functions .Nm @@ -1294,7 +1330,7 @@ stores and converts numbers. Converting the floating-point value to the numeric display value 0055110 is done by multiplying 55.109999...\& by 1,000 and then truncating the result to an integer. And it turns out that even -though 55.11 can’t be represented in floating-point as an exact value, +though 55.11 can't be represented in floating-point as an exact value, the product of the multiplication, 55110, is an exact value. .Pp In cases where it is important for conversions to have predictable @@ -1325,7 +1361,7 @@ specified for a calculation, then the intermediate result becomes a . .Ss A warning about binary floating point comparison The cardinal rule when doing comparisons involving floating-point -values: Never, ever, test for equality. It’s just not worth the hassle. +values: Never, ever, test for equality. It's just not worth the hassle. .Pp For example: .Bd -literal @@ -1361,7 +1397,7 @@ and you really test the code. And then avoid it anyway. .Pp Finally, it is observably the case that the .Nm -implementations of floating-point conversions and comparisons don’t +implementations of floating-point conversions and comparisons don't precisely match the behavior of other \*[lang] compilers. .Pp You have been warned. diff --git a/gcc/cobol/gcobolspec.cc b/gcc/cobol/gcobolspec.cc index d1ffc97f8ca5..038aaec13469 100644 --- a/gcc/cobol/gcobolspec.cc +++ b/gcc/cobol/gcobolspec.cc @@ -82,7 +82,7 @@ static bool need_libgcobol = true; // #define NOISY 1 static void -append_arg(const struct cl_decoded_option arg) +append_arg(const cl_decoded_option& arg) { #ifdef NOISY static int counter = 1; @@ -142,9 +142,6 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, int n_infiles = 0; int n_outfiles = 0; - // The number of input files when the language is "none" or "cobol" - int n_cobol_files = 0; - // saw_OPT_no_main means "don't expect -main" bool saw_OPT_no_main = false; @@ -234,11 +231,6 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, case OPT_SPECIAL_input_file: no_files_error = false; n_infiles += 1; - if( strcmp(language, "none") == 0 - || strcmp(language, "cobol") == 0 ) - { - n_cobol_files += 1; - } if( strstr(decoded_options[i].orig_option_with_args_text, "libgcobol.a") ) { // We have been given an explicit libgcobol.a. We need to note that. @@ -529,7 +521,8 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, // cl_decoded_option size_t new_option_count = new_opt.size(); - struct cl_decoded_option *new_options = XNEWVEC (struct cl_decoded_option, new_option_count); + struct cl_decoded_option *new_options = XNEWVEC (struct cl_decoded_option, + new_option_count); for(size_t i=0; i<new_option_count; i++) { @@ -539,7 +532,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, #ifdef NOISY verbose = true; #endif - if( verbose && new_options != original_options ) + if( verbose && new_options != original_options ) // cppcheck-suppress knownConditionTrueFalse { fprintf(stderr, _("Driving: (" HOST_SIZE_T_PRINT_DEC ")\n"), (fmt_size_t)new_option_count); diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index 5e983ab503c2..52e75e583556 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -27,6 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include "cobol-system.h" #include "coretypes.h" @@ -60,7 +61,8 @@ extern int yylineno; #define TSI_BACK (tsi_last(current_function->statement_list_stack.back())) extern char *cobol_name_mangler(const char *cobol_name); -static tree gg_attribute_bit_get(struct cbl_field_t *var, cbl_field_attr_t bits); +static tree gg_attribute_bit_get( struct cbl_field_t *var, + cbl_field_attr_t bits); static tree label_list_out_goto; static tree label_list_out_label; @@ -116,7 +118,7 @@ typedef struct TREEPLET static void -treeplet_fill_source(TREEPLET &treeplet, cbl_refer_t &refer) +treeplet_fill_source(TREEPLET &treeplet, const cbl_refer_t &refer) { treeplet.pfield = gg_get_address_of(refer.field->var_decl_node); treeplet.offset = refer_offset(refer); @@ -125,8 +127,8 @@ treeplet_fill_source(TREEPLET &treeplet, cbl_refer_t &refer) tree file_static_variable(tree type, const char *v) { - // This routine returns a reference to an already-defined file_static variable - // You need to know the type that was used for the definition. + // This routine returns a reference to an already-defined file_static + // variable. You need to know the type that was used for the definition. return gg_declare_variable(type, v, NULL, vs_file_static); } @@ -142,9 +144,9 @@ static void move_helper(tree size_error, // INT // set using -f-trace-debug, defined in lang.opt int f_trace_debug; -// When doing WRITE statements, the IBM Language Reference and the ISO/IEC_2014 -// standard specify that when the ADVANCING clause is omitted, the default is -// AFTER ADVANCING 1 LINE. +// When doing WRITE statements, the IBM Language Reference and the +// ISO/IEC_2014 standard specify that when the ADVANCING clause is omitted, the +// default isAFTER ADVANCING 1 LINE. // // MicroFocus and GnuCOBOL state that the default is BEFORE ADVANCING 1 LINE // @@ -189,6 +191,9 @@ const char *gv_trace_switch = NULL; char const *bTRACE1 = NULL; tree trace_handle; tree trace_indent; + +// This variable is set to true when the output cursor is known to be at the +// start-of-line. bool cursor_at_sol = true; static void @@ -201,7 +206,7 @@ trace1_init() trace_handle = gg_define_variable(INT, "trace_handle", vs_static); trace_indent = gg_define_variable(INT, "trace_indent", vs_static); - bTRACE1 = getenv("GCOBOL_TRACE") ? getenv("GCOBOL_TRACE") : gv_trace_switch; + bTRACE1 = getenv("GCOBOL_TRACE") ? getenv("GCOBOL_TRACE") :gv_trace_switch; if( bTRACE1 && strcmp(bTRACE1, "0") != 0 ) { @@ -228,6 +233,13 @@ trace1_init() } } +static +void +insert_nop(int n) + { + gg_assign(var_decl_nop, build_int_cst_type(INT, n)); + } + static void create_cblc_string_variable(const char *var_name, const char *var_contents) { @@ -265,13 +277,22 @@ build_main_that_calls_something(const char *something) SHOW_PARSE_END } - gg_set_current_line_number(DEFAULT_LINE_NUMBER); + tree function_decl = gg_define_function( INT, + "main", + "main", + INT, "argc", + build_pointer_type(CHAR_P), "argv", + NULL_TREE); - gg_define_function( INT, - "main", - INT, "argc", - build_pointer_type(CHAR_P), "argv", - NULL_TREE); + // Modify the default settings for main(), as empirically determined from + // examining C/C+_+ compilations. (See the comment for gg_build_fn_decl()). + TREE_ADDRESSABLE(function_decl) = 0; + TREE_USED(function_decl) = 0; + TREE_NOTHROW(function_decl) = 0; + TREE_STATIC(function_decl) = 1; + DECL_EXTERNAL (function_decl) = 0; + TREE_PUBLIC (function_decl) = 1; + DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(function_decl) = 1; // Pick up pointers to the input parameters: // First is the INT which is the number of argv[] entries @@ -309,7 +330,6 @@ build_main_that_calls_something(const char *something) argc, argv, NULL_TREE))); - strncpy(ach_cobol_entry_point, psz, sizeof(ach_cobol_entry_point)-1); free(psz); gg_finalize_function(); } @@ -349,8 +369,11 @@ level_88_helper(size_t parent_capacity, size_t &returned_size) { // We return a MALLOCed return value, which the caller must free. - char *retval = (char *)xmalloc(parent_capacity + 64); - char *builder = (char *)xmalloc(parent_capacity + 64); + char *retval = static_cast<char *>(xmalloc(parent_capacity + 64)); + gcc_assert(retval); + char *builder = static_cast<char *>(xmalloc(parent_capacity + 64)); + gcc_assert(builder); + size_t nbuild = 0; cbl_figconst_t figconst = cbl_figconst_of( elem.name()); @@ -391,7 +414,8 @@ level_88_helper(size_t parent_capacity, // Pick up the string size_t first_name_length = elem.size(); - char *first_name = (char *)xmalloc(first_name_length + 1); + char *first_name = static_cast<char *>(xmalloc(first_name_length + 1)); + gcc_assert(first_name); memcpy(first_name, elem.name(), first_name_length); first_name[first_name_length] = '\0'; @@ -468,7 +492,7 @@ get_level_88_domain(size_t parent_capacity, cbl_field_t *var, size_t &returned_s // Numerics are converted to strings, and handled as above size_t retval_capacity = 64; - char *retval = (char *)xmalloc(retval_capacity); + char *retval = static_cast<char *>(xmalloc(retval_capacity)); size_t output_index = 0; // Loop through the provided domains: @@ -485,8 +509,9 @@ get_level_88_domain(size_t parent_capacity, cbl_field_t *var, size_t &returned_s if( output_index + stream_len > retval_capacity ) { retval_capacity *= 2; - retval = (char *)xrealloc(retval, retval_capacity); + retval = static_cast<char *>(xrealloc(retval, retval_capacity)); } + gcc_assert(retval); memcpy(retval + output_index, stream, stream_len); output_index += stream_len; returned_size += stream_len; @@ -497,8 +522,9 @@ get_level_88_domain(size_t parent_capacity, cbl_field_t *var, size_t &returned_s if( output_index + stream_len > retval_capacity ) { retval_capacity *= 2; - retval = (char *)xrealloc(retval, retval_capacity); + retval = static_cast<char *>(xrealloc(retval, retval_capacity)); } + gcc_assert(retval); memcpy(retval + output_index, stream, stream_len); output_index += stream_len; returned_size += stream_len; @@ -571,7 +597,7 @@ get_class_condition_string(cbl_field_t *var) { if( strlen(ach) > sizeof(ach) - 1000 ) { - cbl_internal_error("Nice try, but you can't fire me. I quit!"); + cbl_internal_error("Nice try, but you cannot fire me."); } // We are working with unquoted strings that contain the values 1 through @@ -596,13 +622,8 @@ get_class_condition_string(cbl_field_t *var) // Since the first.name is a single character, we can do this as // a single-character pair. - // Keep in mind that the single character might be a two-byte UTF-8 - // codepoint - uint8_t ch1 = domain->first.name()[0]; - uint8_t ch2 = domain->last.name()[0]; - - gcc_assert(first_name_length <= 2); - gcc_assert(last_name_length <= 2); + uint8_t ch1; + uint8_t ch2; char *p2; size_t one; @@ -694,30 +715,42 @@ struct called_tree_t { tree node; public: - match_tree( tree node ) : node(node) {} + explicit match_tree( tree node ) : node(node) {} bool operator()( const called_tree_t& that ) const { return this->node == that.node; } }; }; -static std::map<program_reference_t, std::list<called_tree_t> > call_targets; +static std::map<program_reference_t, std::list<tree> > call_targets; static std::map<tree, cbl_call_convention_t> called_targets; -static void -parser_call_target( tree func ) +static +void +set_call_convention(tree function_decl, cbl_call_convention_t convention) { - cbl_call_convention_t convention = current_call_convention(); - const char *name = IDENTIFIER_POINTER( DECL_NAME(func) ); - program_reference_t key(current_program_index(), name); - - // Each func is unique and inserted only once. - assert( called_targets.find(func) == called_targets.end() ); - called_targets[func] = convention; + called_targets[function_decl] = convention; + } - called_tree_t value(func, convention); - auto& p = call_targets[key]; - p.push_back(value); +static +void +parser_call_target( const char *name, tree call_expr ) + { + /* This routine gets called when parser_call() has been invoked with a + literal target. That target is a COBOL name like "prog_2". However, + there is the case when "prog_2" is a forward reference to a contained + program nested inside "prog_1". In that case, the actual definition + of "prog_2" will end up with a name like "prog_2.62", and eventually + the target of the call will have to be modified from "prog_2" to + "prog_2.62". + + We save the call expression for this call, and then we update it later, + after we know whether or not it was a forward reference to a local + function. */ + + program_reference_t key(current_program_index(), name); + auto& p = call_targets[key]; + p.push_back(call_expr); } /* @@ -729,17 +762,23 @@ parser_call_target( tree func ) cbl_call_convention_t parser_call_target_convention( tree func ) { - auto p = called_targets.find(func); - if( p != called_targets.end() ) return p->second; + auto p = called_targets.find(func); + if( p != called_targets.end() ) + { + // This was found in our list of call targets + return p->second; + } - return cbl_call_cobol_e; + return cbl_call_cobol_e; } void parser_call_targets_dump() { - dbgmsg( "call targets for #" HOST_SIZE_T_PRINT_UNSIGNED, + dbgmsg( "call targets for #" HOST_SIZE_T_PRINT_UNSIGNED " NOT dumping", (fmt_size_t)current_program_index() ); +#if 0 // A change to call_targets rendered this routine useless. Until we get + // around to repairing it, this code is left for reference. for( const auto& elem : call_targets ) { const auto& k = elem.first; const auto& v = elem.second; @@ -748,11 +787,12 @@ parser_call_targets_dump() k.called); char ch = '['; for( auto func : v ) { - fprintf( stderr, "%c %s", ch, IDENTIFIER_POINTER(DECL_NAME(func.node)) ); + fprintf( stderr, "%c %s", ch, IDENTIFIER_POINTER(DECL_NAME(func)) ); ch = ','; } fprintf(stderr, " ]\n"); } +#endif } size_t @@ -760,21 +800,28 @@ parser_call_target_update( size_t caller, const char plain_name[], const char mangled_name[] ) { - auto key = program_reference_t(caller, plain_name); - auto p = call_targets.find(key); - if( p == call_targets.end() ) return 0; + auto key = program_reference_t(caller, plain_name); + auto p = call_targets.find(key); + if( p == call_targets.end() ) return 0; - for( auto func : p->second ) - { - func.convention = cbl_call_verbatim_e; - DECL_NAME(func.node) = get_identifier(mangled_name); - } - return p->second.size(); + for( auto call_expr : p->second ) + { + tree fndecl_type = build_varargs_function_type_array( COBOL_FUNCTION_RETURN_TYPE, + 0, // No parameters yet + NULL); // And, hence, no types + + // Fetch the FUNCTION_DECL for that FUNCTION_TYPE + tree function_decl = gg_build_fn_decl(mangled_name, fndecl_type); + tree function_address = gg_get_address_of(function_decl); + + TREE_OPERAND(call_expr, 1) = function_address; + } + return p->second.size(); } static tree -function_handle_from_name(cbl_refer_t &name, - tree function_return_type) +function_pointer_from_name(const cbl_refer_t &name, + tree function_return_type) { Analyze(); @@ -782,74 +829,76 @@ function_handle_from_name(cbl_refer_t &name, function_return_type, 0, NULL); - tree function_pointer = build_pointer_type(function_type); - tree function_handle = gg_define_variable(function_pointer, "..function_handle.1", vs_stack); - + tree function_pointer_type = build_pointer_type(function_type); + tree function_pointer = gg_define_variable(function_pointer_type, + "..function_pointer.1", + vs_stack); if( name.field->type == FldPointer ) { // If the parameter is a pointer, just pick up the value and head for the // exit if( refer_is_clean(name) ) { - gg_memcpy(gg_get_address_of(function_handle), + gg_memcpy(gg_get_address_of(function_pointer), member(name.field->var_decl_node, "data"), sizeof_pointer); } else { - gg_memcpy(gg_get_address_of(function_handle), + gg_memcpy(gg_get_address_of(function_pointer), qualified_data_location(name), sizeof_pointer); } - return function_handle; + return function_pointer; } else if( use_static_call() && is_literal(name.field) ) { - // It's a literal, and we are using static calls. Generate the CALL, and - // pass the address expression to parser_call_target(). That will cause - // parser_call_target_update() to replace any nested CALL "foo" with the - // local "foo.60" name. + tree fndecl_type = build_varargs_function_type_array( function_return_type, + 0, // No parameters yet + NULL); // And, hence, no types - // We create a reference to it, which is later resolved by the linker. - tree addr_expr = gg_get_function_address( function_return_type, - name.field->data.initial); - gg_assign(function_handle, addr_expr); - - tree func = TREE_OPERAND(addr_expr, 0); - parser_call_target(func); // add function to list of call targets + // Fetch the FUNCTION_DECL for that FUNCTION_TYPE + tree function_decl = gg_build_fn_decl(name.field->data.initial, + fndecl_type); + // Take the address of the function decl: + tree address_of_function = gg_get_address_of(function_decl); + gg_assign(function_pointer, address_of_function); } else { - // This is not a literal or static + // We are not using static calls. if( name.field->type == FldLiteralA ) { - gg_assign(function_handle, + gg_assign(function_pointer, gg_cast(build_pointer_type(function_type), - gg_call_expr(VOID_P, - "__gg__function_handle_from_literal", - build_int_cst_type(INT, current_function->our_symbol_table_index), - gg_string_literal(name.field->data.initial), - NULL_TREE))); + gg_call_expr( VOID_P, + "__gg__function_handle_from_literal", + build_int_cst_type(INT, + current_function->our_symbol_table_index), + gg_string_literal(name.field->data.initial), + NULL_TREE))); } else { - gg_assign(function_handle, + gg_assign(function_pointer, gg_cast(build_pointer_type(function_type), gg_call_expr( VOID_P, - "__gg__function_handle_from_name", - build_int_cst_type(INT, current_function->our_symbol_table_index), - gg_get_address_of(name.field->var_decl_node), - refer_offset(name), - refer_size_source( name), - NULL_TREE))); + "__gg__function_handle_from_name", + build_int_cst_type(INT, + current_function->our_symbol_table_index), + gg_get_address_of(name.field->var_decl_node), + refer_offset(name), + refer_size_source( name), + NULL_TREE))); } } - return function_handle; + return function_pointer; } void -parser_initialize_programs(size_t nprogs, struct cbl_refer_t *progs) +parser_initialize_programs( size_t nprogs, + const struct cbl_refer_t *progs) { Analyze(); SHOW_PARSE @@ -879,11 +928,11 @@ parser_initialize_programs(size_t nprogs, struct cbl_refer_t *progs) for( size_t i=0; i<nprogs; i++ ) { - tree function_handle = function_handle_from_name( progs[i], - COBOL_FUNCTION_RETURN_TYPE); + tree function_pointer = function_pointer_from_name( progs[i], + COBOL_FUNCTION_RETURN_TYPE); gg_call(VOID, "__gg__to_be_canceled", - gg_cast(SIZE_T, function_handle), + gg_cast(SIZE_T, function_pointer), NULL_TREE); } } @@ -949,23 +998,23 @@ parser_compile_ecs( const std::vector<uint64_t>& ecs ) return NULL_TREE; } - char ach[32]; + char ach[64]; static int counter = 1; sprintf(ach, "_ecs_table_%d", counter++); tree retval = array_of_long_long(ach, ecs); SHOW_IF_PARSE(nullptr) { SHOW_PARSE_HEADER - char ach[64]; - snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", ecs.size(), retval); + snprintf(ach, sizeof(ach), " Size is %lu; retval is %p", + gb4(ecs.size()), as_voidp(retval)); SHOW_PARSE_TEXT(ach) SHOW_PARSE_END } TRACE1 { TRACE1_HEADER - char ach[64]; - snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", ecs.size(), retval); + snprintf(ach, sizeof(ach), " Size is %lu; retval is %p", + gb4(ecs.size()), as_voidp(retval)); TRACE1_TEXT_ABC("", ach, ""); TRACE1_END } @@ -996,33 +1045,86 @@ parser_compile_dcls( const std::vector<uint64_t>& dcls ) return NULL_TREE; } - char ach[32]; + char ach[64]; static int counter = 1; sprintf(ach, "_dcls_table_%d", counter++); tree retval = array_of_long_long(ach, dcls); SHOW_IF_PARSE(nullptr) { SHOW_PARSE_HEADER - char ach[64]; - snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", dcls.size(), retval); + snprintf(ach, sizeof(ach), " Size is %lu; retval is %p", + gb4(dcls.size()), as_voidp(retval)); SHOW_PARSE_TEXT(ach); SHOW_PARSE_END } TRACE1 { TRACE1_HEADER - char ach[64]; - snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", dcls.size(), retval); + snprintf(ach, sizeof(ach), " Size is %lu; retval is %p", + gb4(dcls.size()), as_voidp(retval)); TRACE1_TEXT_ABC("", ach, ""); TRACE1_END } return retval; } -static void store_location_stuff(const cbl_name_t statement_name); +static void +store_location_stuff(const cbl_name_t statement_name) + { + if( exception_location_active && !current_declarative_section_name() ) + { + // We need to establish some stuff for EXCEPTION- function processing + + gg_assign(var_decl_exception_program_id, + gg_string_literal(current_function->our_unmangled_name)); + + if( strstr(current_function->current_section->label->name, "_implicit") + != current_function->current_section->label->name ) + { + gg_assign(var_decl_exception_section, + gg_string_literal(current_function->current_section->label->name)); + } + else + { + gg_assign(var_decl_exception_section, + gg_cast(build_pointer_type(CHAR_P),null_pointer_node)); + } + + if( strstr(current_function->current_paragraph->label->name, "_implicit") + != current_function->current_paragraph->label->name ) + { + gg_assign(var_decl_exception_paragraph, + gg_string_literal(current_function->current_paragraph->label->name)); + } + else + { + gg_assign(var_decl_exception_paragraph, + gg_cast(build_pointer_type(CHAR_P), null_pointer_node)); + } + + gg_assign(var_decl_exception_source_file, + gg_string_literal(current_filename.back().c_str())); + gg_assign(var_decl_exception_line_number, build_int_cst_type(INT, + CURRENT_LINE_NUMBER)); + gg_assign(var_decl_exception_statement, gg_string_literal(statement_name)); + } + } + +static +void +set_exception_environment( tree ecs, tree dcls ) + { + gg_call(VOID, + "__gg__set_exception_environment", + ecs ? gg_get_address_of(ecs) : null_pointer_node, + dcls ? gg_get_address_of(dcls) : null_pointer_node, + NULL_TREE); + } void -parser_statement_begin( const cbl_name_t statement_name, tree ecs, tree dcls ) +parser_statement_begin( const cbl_name_t statement_name, + tree ecs, + tree dcls ) { SHOW_PARSE { @@ -1038,7 +1140,7 @@ parser_statement_begin( const cbl_name_t statement_name, tree ecs, tree dcls ) { SHOW_PARSE_INDENT snprintf( ach, sizeof(ach), - "Sending ecs/dcls %p / %p", ecs, dcls); + "Sending ecs/dcls %p / %p", as_voidp(ecs), as_voidp(dcls)); SHOW_PARSE_TEXT(ach); } SHOW_PARSE_END @@ -1047,40 +1149,53 @@ parser_statement_begin( const cbl_name_t statement_name, tree ecs, tree dcls ) { TRACE1_HEADER char ach[64]; - snprintf(ach, sizeof(ach), " ecs/dcls %p / %p", ecs, dcls); + snprintf(ach, sizeof(ach), " ecs/dcls %p / %p", as_voidp(ecs), as_voidp(dcls)); TRACE1_TEXT_ABC("", ach, ""); TRACE1_END } - if( gg_get_current_line_number() == DEFAULT_LINE_NUMBER ) + gcc_assert( gg_trans_unit.function_stack.size() ); + + // In the cases where enabled_exceptions.size() is non-zero, or when + // there is a possibility of an EC-I-O exception because this is a file + // operation, we need to store the location information and do the exception + // overhead: + + static const std::set<std::string> file_ops = + { + "OPEN", + "CLOSE", + "READ", + "WRITE", + "DELETE", + "REWRITE", + "START", + }; + + // Performance note: By doing exception processing only when necessary + // the execution time of a program doing two-billion simple adds in an inner + // loop dropped from 3.8 seconds to 0.175 seconds. + + bool exception_processing = cdf_enabled_exceptions().size() ; + + if( !exception_processing ) { - // This code is intended to prevert GDB anomalies when the first line of a - // program is a PERFORM <proc> ... TEST AFTER ... UNTIL ... - gg_set_current_line_number(CURRENT_LINE_NUMBER-1); - gg_assign(var_decl_nop, build_int_cst_type(INT, 106)); + exception_processing = file_ops.find(statement_name) != file_ops.end(); } // At this point, if any exception is enabled, we store the location stuff. // Each file I-O routine calls store_location_stuff explicitly, because // those exceptions can't be defeated. - if( enabled_exceptions.size() ) + if( exception_processing ) { store_location_stuff(statement_name); } - gg_set_current_line_number(CURRENT_LINE_NUMBER); - - // if( ecs || dcls || sv_is_i_o ) + if( exception_processing ) { - gg_call(VOID, - "__gg__set_exception_environment", - ecs ? gg_get_address_of(ecs) : null_pointer_node, - dcls ? gg_get_address_of(dcls) : null_pointer_node, - NULL_TREE); + set_exception_environment(ecs, dcls); } - - gcc_assert( gg_trans_unit.function_stack.size() ); sv_is_i_o = false; } @@ -1094,10 +1209,9 @@ initialize_variable_internal( cbl_refer_t refer, // gg_string_literal(refer.field->name), // NULL_TREE); cbl_field_t *parsed_var = refer.field; - - if( parsed_var->type == FldLiteralA ) + if( !parsed_var ) { - return; + cbl_internal_error("%s should not be null", "parsed_var"); } if( parsed_var->is_key_name() ) @@ -1113,7 +1227,7 @@ initialize_variable_internal( cbl_refer_t refer, return; } - if( parsed_var && parsed_var->type == FldBlob ) + if( parsed_var->type == FldBlob ) { return; } @@ -1231,15 +1345,13 @@ initialize_variable_internal( cbl_refer_t refer, SHOW_PARSE_END } - CHECK_FIELD(parsed_var); - // When initializing a variable, we have to ignore any DEPENDING ON clause // that might otherwise apply suppress_dest_depends = true; bool is_redefined = false; - cbl_field_t *family_tree = parsed_var; + const cbl_field_t *family_tree = parsed_var; while(family_tree) { if( symbol_redefines(family_tree) ) @@ -1260,7 +1372,7 @@ initialize_variable_internal( cbl_refer_t refer, if( parsed_var->data.initial ) { bool a_parent_initialized = false; - cbl_field_t *parent = parent_of(parsed_var); + const cbl_field_t *parent = parent_of(parsed_var); while( parent ) { if( parent->attr & has_value_e ) @@ -1290,7 +1402,7 @@ initialize_variable_internal( cbl_refer_t refer, flag_bits |= wsclear() ? DEFAULTBYTE_BIT + (*wsclear() & DEFAULT_BYTE_MASK) : 0; - flag_bits |= (refer.nsubscript << NSUBSCRIPT_SHIFT) & NSUBSCRIPT_MASK; + flag_bits |= (refer.nsubscript() << NSUBSCRIPT_SHIFT) & NSUBSCRIPT_MASK; flag_bits |= just_once ? JUST_ONCE_BIT : 0 ; suppress_dest_depends = false; // Set this to false so that refer_is_clean is valid @@ -1455,7 +1567,7 @@ initialize_variable_internal( cbl_refer_t refer, // } void -parser_initialize(cbl_refer_t refer, bool like_parser_symbol_add) +parser_initialize(const cbl_refer_t& refer, bool like_parser_symbol_add) { //gg_printf("parser_initialize %s\n", gg_string_literal(refer.field->name), NULL_TREE); if( like_parser_symbol_add ) @@ -1472,7 +1584,7 @@ parser_initialize(cbl_refer_t refer, bool like_parser_symbol_add) static void get_binary_value_from_float(tree value, - cbl_refer_t &dest, + const cbl_refer_t &dest, cbl_field_t *source, tree source_offset ) @@ -1566,6 +1678,7 @@ depending_on_value(tree depending_on, cbl_field_t *current_sizer) // gg_assign(occurs_lower, build_int_cst_type(LONG, current_sizer->occurs.bounds.lower)); // gg_assign(occurs_upper, build_int_cst_type(LONG, current_sizer->occurs.bounds.upper)); + gcc_assert(current_sizer); if( current_sizer->occurs.depending_on ) { get_depending_on_value_from_odo(depending_on, current_sizer); @@ -1676,7 +1789,7 @@ get_bytes_needed(cbl_field_t *field) } default: - cbl_internal_error("%s(): Knows not the variable type %s for %s", + cbl_internal_error("%s: Knows not the variable type %s for %s", __func__, cbl_field_type_str(field->type), field->name ); @@ -1709,16 +1822,12 @@ normal_normal_compare(bool debugging, NULL_TREE); } - bool needs_adjusting; if( !left_intermediate && !right_intermediate ) { // Yay! Both sides have fixed rdigit values. - // Flag needs_adjusting as false, because we are going to do it here: - needs_adjusting = false; int adjust = get_scaled_rdigits(left_side_ref->field) - get_scaled_rdigits(right_side_ref->field); - if( adjust > 0 ) { // We need to make right_side bigger to match the scale of left_side @@ -1733,6 +1842,7 @@ normal_normal_compare(bool debugging, else { // At least one side is right_intermediate + bool needs_adjusting; tree adjust; if( !left_intermediate && right_intermediate ) @@ -2241,7 +2351,7 @@ cobol_compare( tree return_int, build_int_cst_type(INT, rightflags), integer_zero_node, NULL_TREE)); - compared = true; + // compared = true; // Commented out to quiet cppcheck } // gg_printf(" result is %d\n", return_int, NULL_TREE); @@ -2261,6 +2371,8 @@ move_tree( cbl_field_t *dest, SHOW_PARSE_END } + CHECK_FIELD(dest); + bool moved = true; tree source_length = gg_define_size_t(); @@ -2344,7 +2456,7 @@ move_tree( cbl_field_t *dest, psz_source, min_length, member(dest->var_decl_node, "picture"), - NULL); + NULL_TREE); break; } @@ -2365,10 +2477,10 @@ move_tree( cbl_field_t *dest, if( !moved ) { - dbgmsg("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ ); - cbl_internal_error( "I don't know how to MOVE an alphabetical string to %s(%s) \n", - cbl_field_type_str(dest->type), - dest->name + dbgmsg("%10s in %s:%d", __func__, __FILE__, __LINE__ ); + cbl_internal_error( "I don%'t know how to MOVE an alphabetical string to %s(%s)", + cbl_field_type_str(dest->type), + dest->name ); return; } @@ -2399,7 +2511,7 @@ get_string_from(cbl_field_t *field) gg_cast(CHAR_P, gg_malloc(build_int_cst_type(SIZE_T, field->data.capacity+1)))); - char *litstring = get_literal_string(field); + const char *litstring = get_literal_string(field); gg_memcpy(psz, gg_string_literal(litstring), build_int_cst_type(SIZE_T, field->data.capacity+1)); @@ -2434,7 +2546,7 @@ get_string_from(cbl_field_t *field) default: cbl_internal_error( - "%s(): field->type %s must be literal or alphanumeric", + "%s: %<field->type%> %s must be literal or alphanumeric", __func__, cbl_field_type_str(field->type)); break; } @@ -2447,12 +2559,12 @@ get_string_from(cbl_field_t *field) } static char * -combined_name(cbl_label_t *label) +combined_name(const cbl_label_t *label) { // This routine returns a pointer to a static, so make sure you use the result // before calling the routine again - char *para_name = nullptr; - char *sect_name = nullptr; + const char *para_name = nullptr; + const char *sect_name = nullptr; const char *program_name = current_function->our_unmangled_name; if( label->type == LblParagraph ) @@ -2462,7 +2574,7 @@ combined_name(cbl_label_t *label) if( label->parent ) { // It's possible for implicit - cbl_label_t *section_label = cbl_label_of(symbol_at(label->parent)); + const cbl_label_t *section_label = cbl_label_of(symbol_at(label->parent)); sect_name = section_label->name; } } @@ -2472,10 +2584,10 @@ combined_name(cbl_label_t *label) } static size_t retval_size = 256; - static char *retval= (char *)xmalloc(retval_size); + static char *retval= static_cast<char *>(xmalloc(retval_size)); char *paragraph = cobol_name_mangler(para_name); - char *section = cobol_name_mangler(sect_name); + char *section = cobol_name_mangler(sect_name); char *mangled_program_name = cobol_name_mangler(program_name); while( retval_size < (paragraph ? strlen(paragraph) : 0 ) @@ -2484,8 +2596,9 @@ combined_name(cbl_label_t *label) + 24 ) { retval_size *= 2; - retval = (char *)xrealloc(retval, retval_size); + retval = static_cast<char *>(xrealloc(retval, retval_size)); } + gcc_assert(retval); *retval = '\0'; char ach[24]; @@ -2532,8 +2645,9 @@ assembler_label(const char *label) { length = strlen(label) + strlen(local_text) + 1; free(build); - build = (char *)xmalloc(length); + build = static_cast<char *>(xmalloc(length)); } + gcc_assert(build); strcpy(build, label); strcat(build, local_text); @@ -2547,8 +2661,6 @@ section_label(struct cbl_proc_t *procedure) // With nested programs, you can have multiple program/section pairs with the // the same names; we use a deconflictor to avoid collisions - gg_set_current_line_number(CURRENT_LINE_NUMBER); - size_t deconflictor = symbol_label_id(procedure->label); cbl_label_t *label = procedure->label; @@ -2573,7 +2685,7 @@ section_label(struct cbl_proc_t *procedure) } assembler_label(psz2); free(psz2); - gg_assign(var_decl_nop, build_int_cst_type(INT, 108)); + insert_nop(108); } static void @@ -2588,8 +2700,6 @@ paragraph_label(struct cbl_proc_t *procedure) // are not referenced by the program. We provide a deconflictor to // separate such labels. - gg_set_current_line_number(CURRENT_LINE_NUMBER); - cbl_label_t *paragraph = procedure->label; cbl_label_t *section = nullptr; @@ -2611,6 +2721,9 @@ paragraph_label(struct cbl_proc_t *procedure) section_name ? section_name: "(null)" , current_function->our_unmangled_name ? current_function->our_unmangled_name: "" , (fmt_size_t)deconflictor ); + + // (0) is wrong, so back up one + gg_insert_into_assembler(psz1); SHOW_PARSE @@ -2627,7 +2740,25 @@ paragraph_label(struct cbl_proc_t *procedure) combined_name(procedure->label)); assembler_label(psz2); free(psz2); - gg_assign(var_decl_nop, build_int_cst_type(INT, 109)); + + // We are inserting a NOP after having created a label for the procedure. + // This means that when using GDC_COBOL to step into a procedure, the + // execution will stop there and show "123 para-name." at the stopped point. + // + // Note that because there is no user-specified executable code at that point + // the user can't set a working breakpoint with "break 123". But because + // GDB will pick up the psz2 text and set a breakpoint there (which is the + // location of the NOP) "break para-name" will actually stop and show line + // 123. + // + // This really only makes sense when you look at the assembly language. Keep + // in mind as you read it that issuing a "break 123" causes GDB to set a + // breakpoint at the first executable machine language code following the + // first ".loc 123" directive. + // + // Yes, trying to understand this causes headaches for many people who read + // this. Take an aspirin. + insert_nop(109); } static void @@ -2671,6 +2802,7 @@ pseudo_return_pop(cbl_proc_t *procedure) NULL_TREE); } + token_location_override(current_location_minus_one()); IF( var_decl_exit_address, eq_op, procedure->exit.addr ) { TRACE1 @@ -2680,11 +2812,13 @@ pseudo_return_pop(cbl_proc_t *procedure) // The top of the stack is us! // Pick up the return address from the pseudo_return stack: + token_location_override(current_location_minus_one()); gg_assign(current_function->void_star_temp, gg_call_expr( VOID_P, "__gg__pseudo_return_pop", NULL_TREE)); // And do the return: + token_location_override(current_location_minus_one()); gg_goto(current_function->void_star_temp); } ELSE @@ -2718,6 +2852,7 @@ leave_procedure(struct cbl_proc_t *procedure, bool /*section*/) // procedure->bottom.label); // Procedure can be null, for example at the beginning of a // new program, or after somebody else has cleared it out. + gg_append_statement(procedure->exit.label); char *psz; @@ -2835,7 +2970,9 @@ find_procedure(cbl_label_t *label) static int counter=1; // This is a new section or paragraph; we need to create its values: - retval = (struct cbl_proc_t *)xmalloc(sizeof(struct cbl_proc_t)); + retval = static_cast<struct cbl_proc_t *> + (xmalloc(sizeof(struct cbl_proc_t))); + gcc_assert(retval); retval->label = label; gg_create_goto_pair(&retval->top.go_to, @@ -2891,6 +3028,8 @@ parser_enter_section(cbl_label_t *label) { SHOW_PARSE_HEADER SHOW_PARSE_LABEL(" ", label) + SHOW_PARSE_INDENT + linemap_dump_location( line_table, current_token_location(), stderr ); SHOW_PARSE_END } @@ -2898,8 +3037,7 @@ parser_enter_section(cbl_label_t *label) // This NOP is needed to give GDB a line number for the entry point of // paragraphs - gg_set_current_line_number(CURRENT_LINE_NUMBER); - gg_assign(var_decl_nop, build_int_cst_type(INT, 101)); + insert_nop(101); struct cbl_proc_t *procedure = find_procedure(label); gg_append_statement(procedure->top.label); @@ -2926,6 +3064,8 @@ parser_enter_paragraph(cbl_label_t *label) { SHOW_PARSE_HEADER SHOW_PARSE_LABEL(" ", label) + SHOW_PARSE_INDENT + linemap_dump_location( line_table, current_token_location(), stderr ); SHOW_PARSE_END } @@ -3141,16 +3281,20 @@ parser_goto( cbl_refer_t value_ref, size_t narg, cbl_label_t * const labels[] ) void parser_perform(cbl_label_t *label, bool suppress_nexting) { - label->used = yylineno; Analyze(); SHOW_PARSE { SHOW_PARSE_HEADER SHOW_PARSE_LABEL(" ", label) char ach[32]; - sprintf(ach, " label is at %p", (void*)label); + sprintf(ach, " label is at %p", static_cast<void*>(label)); SHOW_PARSE_TEXT(ach) - sprintf(ach, " label->proc is %p", (void*)label->structs.proc); + if( label ) + { + sprintf(ach, + " label->proc is %p", + static_cast<void*>(label->structs.proc)); + } SHOW_PARSE_TEXT(ach) SHOW_PARSE_END } @@ -3163,6 +3307,7 @@ parser_perform(cbl_label_t *label, bool suppress_nexting) } CHECK_LABEL(label); + label->used = yylineno; struct cbl_proc_t *procedure = find_procedure(label); @@ -3191,17 +3336,17 @@ parser_perform(cbl_label_t *label, bool suppress_nexting) // pairs were created, the locations of the goto instruction and the label // were not known. - char *para_name = nullptr; - char *sect_name = nullptr; + const char *para_name = nullptr; + const char *sect_name = nullptr; const char *program_name = current_function->our_unmangled_name; size_t deconflictor = symbol_label_id(label); char ach[256]; if( label->type == LblParagraph ) { - cbl_label_t *section_label = cbl_label_of(symbol_at(label->parent)); + const cbl_label_t *sec_label = cbl_label_of(symbol_at(label->parent)); para_name = label->name; - sect_name = section_label->name; + sect_name = sec_label->name; sprintf(ach, "%s PERFORM %s of %s of %s (" HOST_SIZE_T_PRINT_DEC ")", ASM_COMMENT_START, @@ -3261,9 +3406,9 @@ parser_perform_times( cbl_label_t *proc_1, cbl_refer_t count ) SHOW_PARSE_REF(" ", count) SHOW_PARSE_TEXT(" TIMES") char ach[32]; - sprintf(ach, " proc_1 is at %p", (void*)proc_1); + sprintf(ach, " proc_1 is at %p", static_cast<void*>(proc_1)); SHOW_PARSE_TEXT(ach) - sprintf(ach, " proc_1->proc is %p", (void*)proc_1->structs.proc); + sprintf(ach, " proc_1->proc is %p", static_cast<void*>(proc_1->structs.proc)); SHOW_PARSE_TEXT(ach) SHOW_PARSE_END } @@ -3314,17 +3459,22 @@ internal_perform_through( cbl_label_t *proc_1, SHOW_PARSE_HEADER SHOW_PARSE_LABEL(" ", proc_1); char ach[32]; - sprintf(ach, " proc_1 is at %p", (void*)proc_1); + sprintf(ach, " proc_1 is at %p", static_cast<void*>(proc_1)); SHOW_PARSE_TEXT(ach) - sprintf(ach, " proc_1->proc is %p", (void*)proc_1->structs.proc); + if( proc_1 ) + { + sprintf(ach, + " proc_1->proc is %p", + static_cast<void*>(proc_1->structs.proc)); + } SHOW_PARSE_TEXT(ach) if( proc_2 ) { SHOW_PARSE_INDENT - SHOW_PARSE_LABEL("", proc_2); - sprintf(ach, " proc_2 is at %p", (void*)proc_2); + SHOW_PARSE_LABEL_OK("", proc_2); + sprintf(ach, " proc_2 is at %p", static_cast<void*>(proc_2)); SHOW_PARSE_TEXT(ach) - sprintf(ach, " proc_2->proc is %p", (void*)proc_2->structs.proc); + sprintf(ach, " proc_2->proc is %p", static_cast<void*>(proc_2->structs.proc)); SHOW_PARSE_TEXT(ach) } SHOW_PARSE_END @@ -3337,14 +3487,12 @@ internal_perform_through( cbl_label_t *proc_1, CHECK_LABEL(proc_1); - if(!proc_2) + if( !proc_2 ) { parser_perform(proc_1, suppress_nexting); return; } - CHECK_LABEL(proc_2); - struct cbl_proc_t *proc1 = find_procedure(proc_1); struct cbl_proc_t *proc2 = find_procedure(proc_2); @@ -3369,7 +3517,7 @@ internal_perform_through( cbl_label_t *proc_1, pseudo_return_push(proc2, return_addr); // Create the code that will launch the first procedure - gg_insert_into_assembler("%s PERFORM %s THROUGH %s", + gg_insert_into_assemblerf("%s PERFORM %s THROUGH %s", ASM_COMMENT_START, proc_1->name, proc_2->name); if( !suppress_nexting ) @@ -3399,17 +3547,22 @@ internal_perform_through_times( cbl_label_t *proc_1, SHOW_PARSE_HEADER SHOW_PARSE_LABEL(" ", proc_1); char ach[32]; - sprintf(ach, " proc_1 is at %p", (void*)proc_1); + sprintf(ach, " proc_1 is at %p", static_cast<void*>(proc_1)); SHOW_PARSE_TEXT(ach) - sprintf(ach, " proc_1->proc is %p", (void*)proc_1->structs.proc); + if( proc_1 ) + { + sprintf(ach, + " proc_1->proc is %p", + static_cast<void*>(proc_1->structs.proc)); + } SHOW_PARSE_TEXT(ach) if( proc_2 ) { SHOW_PARSE_INDENT - SHOW_PARSE_LABEL("", proc_2); - sprintf(ach, " proc_2 is at %p", (void*)proc_2); + SHOW_PARSE_LABEL_OK("", proc_2); + sprintf(ach, " proc_2 is at %p", static_cast<void*>(proc_2)); SHOW_PARSE_TEXT(ach) - sprintf(ach, " proc_2->proc is %p", (void*)proc_2->structs.proc); + sprintf(ach, " proc_2->proc is %p", static_cast<void*>(proc_2->structs.proc)); SHOW_PARSE_TEXT(ach) } SHOW_PARSE_REF(" ", count); @@ -3519,8 +3672,6 @@ parser_first_statement( int lineno ) } } -#define linemap_add(...) - void parser_enter_file(const char *filename) { @@ -3552,9 +3703,6 @@ parser_enter_file(const char *filename) } } - // Let the linemap routine know we are working on a new file: - linemap_add(line_table, LC_ENTER, 0, filename, 1); - if( file_level == 0 ) { // Build a translation_unit_decl: @@ -3627,16 +3775,38 @@ parser_leave_file() { SHOW_PARSE_HEADER char ach[256]; - sprintf(ach, "leaving level:%d %s", file_level, current_filename.back().c_str()); + sprintf(ach, + "leaving level:%d %s", + file_level, + current_filename.back().c_str()); SHOW_PARSE_TEXT(ach) SHOW_PARSE_END } - if( file_level > 0) - { - linemap_add(line_table, LC_LEAVE, false, NULL, 0); - } file_level -= 1; current_filename.pop_back(); + + if( file_level == 0 ) + { + // We are leaving the top-level file, which means this compilation is + // done, done, done. + + // There is, however, one thing left to do. If the command line says + // that this module needs a main entry point, then this is where + // we create a main() function. We build it at the end, so that all of + // the .loc directives associated with it appear at the end of the + // source code. We used to create the main() entry point at the beginning, + // but that created confusion for GDB when trying to debug the generated + // executable. + if( main_entry_point ) + { + next_program_is_main = false; + build_main_that_calls_something(main_entry_point); + free(main_entry_point); + main_entry_point = NULL; + } + + gg_leaving_the_source_code_file(); + } } void @@ -3651,15 +3821,16 @@ enter_program_common(const char *funcname, const char *funcname_) // have no parameters. We'll chain the parameters on in parser_division(), // when we process PROCEDURE DIVISION USING... - gg_define_function_with_no_parameters( COBOL_FUNCTION_RETURN_TYPE, - funcname, - funcname_); + gg_define_function(COBOL_FUNCTION_RETURN_TYPE, + funcname, + funcname_, + NULL_TREE); current_function->first_time_through = - gg_define_variable(INT, - "_first_time_through", - vs_static, - integer_one_node); + gg_define_variable(INT, + "_first_time_through", + vs_static, + integer_one_node); gg_create_goto_pair(¤t_function->skip_init_goto, ¤t_function->skip_init_label); @@ -3684,8 +3855,6 @@ enter_program_common(const char *funcname, const char *funcname_) current_function->current_section = NULL; current_function->current_paragraph = NULL; - current_function->is_truly_nested = false; - // Text conversion must be initialized before the code generated by // parser_symbol_add runs. @@ -3745,20 +3914,22 @@ parser_enter_program( const char *funcname_, // The first thing we have to do is mangle this name. This is safe even // though the end result will be mangled again, because the mangler doesn't // change a mangled name. + char *mangled_name = cobol_name_mangler(funcname_); size_t parent_index = current_program_index(); - char funcname[128]; + char *funcname; if( parent_index ) { // This is a nested function. Tack on the parent_index to the end of it. - sprintf(funcname, "%s." HOST_SIZE_T_PRINT_DEC, mangled_name, - (fmt_size_t)parent_index); + funcname = xasprintf( "%s." HOST_SIZE_T_PRINT_DEC, + mangled_name, + (fmt_size_t)parent_index); } else { // This is a top-level function; just use the straight mangled name - strcpy(funcname, mangled_name); + funcname = xstrdup(mangled_name); } free(mangled_name); @@ -3772,28 +3943,25 @@ parser_enter_program( const char *funcname_, if( !is_function && !parent_index ) { - // This is a top_level program, and not a function + // This is a top_level program-id, and not a function if( next_program_is_main ) { + // This is the first top-level program-id. next_program_is_main = false; - if(main_entry_point) - { - build_main_that_calls_something(main_entry_point); - free(main_entry_point); - main_entry_point = NULL; - } - else + if( !main_entry_point ) { - build_main_that_calls_something(funcname); + // Because no explicit main_entry_point was specified, this program-id, + // the first in the file, becomes the target of the main() function + // that will be created at parser_leave_file time. + main_entry_point = xstrdup(funcname); + + char *psz = cobol_name_mangler(main_entry_point); + strncpy(ach_cobol_entry_point, psz, sizeof(ach_cobol_entry_point)-1); + free(psz); } } } - // Call this after build_main_that_calls_something, because it manipulates - // the current line number to DEFAULT_LINE_NUMBER. We have to manipulate it - // back afterward. - gg_set_current_line_number(CURRENT_LINE_NUMBER); - if( strcmp(funcname_, "main") == 0 && this_module_has_main ) { // setting 'retval' to 1 let's the caller know that we are being told @@ -3824,6 +3992,8 @@ parser_enter_program( const char *funcname_, TRACE1_TEXT("\"") TRACE1_END } + + free(funcname); } void @@ -3981,6 +4151,8 @@ psa_FldLiteralN(struct cbl_field_t *field ) // We are constructing a completely static constant structure, based on the // text string in .initial + CHECK_FIELD(field); + FIXED_WIDE_INT(128) value = 0; do @@ -4019,7 +4191,7 @@ psa_FldLiteralN(struct cbl_field_t *field ) int rdigit_delta = 0; int exponent = 0; - char *exp = strchr(p, 'E'); + const char *exp = strchr(p, 'E'); if( !exp ) { exp = strchr(p, 'e'); @@ -4173,6 +4345,8 @@ psa_FldBlob(struct cbl_field_t *var ) SHOW_PARSE_END } + CHECK_FIELD(var); + // We are constructing a completely static constant structure. We know the // capacity. We'll create it from the data.initial. The var_decl_node will // be a pointer to the data @@ -4210,67 +4384,182 @@ psa_FldBlob(struct cbl_field_t *var ) } void -parser_accept( struct cbl_refer_t refer, - enum special_name_t special_e ) +parser_accept(const struct cbl_refer_t &tgt, + special_name_t special_e, + cbl_label_t *error, + cbl_label_t *not_error ) { - Analyze(); SHOW_PARSE { SHOW_PARSE_HEADER - SHOW_PARSE_REF(" ", refer); + if( error ) + { + SHOW_PARSE_LABEL(" error ", error) + } + if( not_error ) + { + SHOW_PARSE_LABEL(" not_error ", not_error) + } SHOW_PARSE_END } - TRACE1 - { - TRACE1_HEADER - TRACE1_END - } - - /* - enum special_name_t - { - SYSIN_e, - SYSIPT_e, - SYSOUT_e, - SYSLIST_e, - SYSLST_e, - SYSPUNCH_e, - SYSPCH_e, - CONSOLE_e, - C01_e, C02_e, C03_e, C04_e, C05_e, C06_e, - C07_e, C08_e, C09_e, C10_e, C11_e, C12_e, - CSP_e, - S01_e, S02_e, S03_e, S04_e, S05_e, - AFP_5A_e, - }; - */ // The ISO spec describes the valid special names for ACCEPT as implementation // dependent. We are following IBM's lead. tree environment = build_int_cst_type(INT, special_e); - switch( special_e ) + const char *function_to_call = NULL; + + switch(special_e) { + case STDIN_e: case CONSOLE_e: case SYSIPT_e: case SYSIN_e: - break; - default: - dbgmsg("%s(): We don't know what to do with special_name_t %d,", __func__, special_e); - dbgmsg("%s(): so we are ignoring it.", __func__); - yywarn("unrecognized SPECIAL NAME ignored"); + // This is ordinary input from from the stdin: + gg_call(VOID, + "__gg__accept", + environment, + gg_get_address_of(tgt.field->var_decl_node), + refer_offset(tgt), + refer_size_dest(tgt), + NULL_TREE); return; break; - } - gg_call(VOID, - "__gg__accept", - environment, - gg_get_address_of(refer.field->var_decl_node), - refer_offset(refer), - refer_size_dest(refer), - NULL_TREE); + case C01_e: + case C02_e: + case C03_e: + case C04_e: + case C05_e: + case C06_e: + case C07_e: + case C08_e: + case C09_e: + case C10_e: + case C11_e: + case C12_e: + case CSP_e: + case S01_e: + case S02_e: + case S03_e: + case S04_e: + case S05_e: + case AFP_5A_e: + case STDOUT_e: + case SYSOUT_e: + case SYSLIST_e: + case SYSLST_e: + case STDERR_e: + case SYSPUNCH_e: + case SYSPCH_e: + case SYSERR_e: + cbl_internal_error("Not valid for ACCEPT statement."); + break; + + case ARG_NUM_e: + // This ACCEPT statement wants the number of argv values: + gg_call(VOID, + "__gg__get_argc", + gg_get_address_of(tgt.field->var_decl_node), + refer_offset(tgt), + refer_size_source(tgt), + NULL_TREE); + return; + break; + + case ENV_NAME_e: + // This fetches the environment name set by DISPLAY... UPON ENV_NAME_e + gg_call(VOID, + "__gg__get_env_name", + gg_get_address_of(tgt.field->var_decl_node), + refer_offset(tgt), + refer_size_source(tgt), + NULL_TREE); + return; + break; + + case ENV_VALUE_e: + // This fetches the environment value associated with the previously + // esablished name + function_to_call = "__gg__get_env_value"; + break; + + case ARG_VALUE_e: + // We are fetching the variable whose index was established by a prior + // DISPLAY UPON ARGUMENT-NUMBER. After the fetch, the value will be + // incremented by one. + function_to_call = "__gg__accept_arg_value"; + break; + } + if( function_to_call ) + { + tree erf = gg_define_int(); + gg_assign(erf, + gg_call_expr( INT, + function_to_call, + gg_get_address_of(tgt.field->var_decl_node), + refer_offset(tgt), + refer_size_dest(tgt), + NULL_TREE)); + if( error ) + { + // There is an ON EXCEPTION phrase: + IF( erf, ne_op, integer_zero_node ) + { + SHOW_PARSE + { + SHOW_PARSE_INDENT + SHOW_PARSE_TEXT("Laying down GOTO error->INTO for_argv") + SHOW_PARSE_LABEL_OK(" ", error) + } + gg_append_statement( error->structs.arith_error->into.go_to ); + } + ELSE + { + } + ENDIF + } + if( not_error ) + { + // There is an NOT ON EXCEPTION phrase: + IF( erf, eq_op, integer_zero_node ) + { + SHOW_PARSE + { + SHOW_PARSE_INDENT + SHOW_PARSE_TEXT("Laying down GOTO not_error->INTO for_argv") + SHOW_PARSE_LABEL_OK(" ", not_error) + } + gg_append_statement( not_error->structs.arith_error->into.go_to ); + } + ELSE + { + } + ENDIF + } + if( error ) + { + SHOW_PARSE + { + SHOW_PARSE_INDENT + SHOW_PARSE_TEXT("Laying down LABEL error->bottom") + SHOW_PARSE_LABEL_OK(" ", error) + } + gg_append_statement( error->structs.arith_error->bottom.label ); + } + if( not_error ) + { + SHOW_PARSE + { + SHOW_PARSE_INDENT + SHOW_PARSE_TEXT("Laying down LABEL not_error->bottom") + SHOW_PARSE_LABEL_OK(" ", not_error) + SHOW_PARSE_END + } + gg_append_statement( not_error->structs.arith_error->bottom.label ); + } + } } // TODO: update documentation. @@ -4282,7 +4571,6 @@ parser_accept_exception( cbl_label_t *accept_label ) // We are entering either SIZE ERROR or NOT SIZE ERROR code RETURN_IF_PARSE_ONLY; - set_up_on_exception_label(accept_label); SHOW_PARSE { @@ -4295,6 +4583,9 @@ parser_accept_exception( cbl_label_t *accept_label ) SHOW_PARSE_END } + CHECK_LABEL(accept_label); + set_up_on_exception_label(accept_label); + // Jump over the [NOT] ON EXCEPTION code that is about to be laid down gg_append_statement( accept_label->structs.arith_error->over.go_to ); // Create the label that allows the following code to be executed at @@ -4321,6 +4612,8 @@ parser_accept_exception_end( cbl_label_t *accept_label ) SHOW_PARSE_END } + CHECK_LABEL(accept_label); + // Jump to the end of the arithmetic code: gg_append_statement( accept_label->structs.arith_error->bottom.go_to ); // Lay down the label that allows the ERROR/NOT ERROR instructions @@ -4330,8 +4623,8 @@ parser_accept_exception_end( cbl_label_t *accept_label ) } void -parser_accept_command_line( cbl_refer_t tgt, - cbl_refer_t source, +parser_accept_command_line( const cbl_refer_t &tgt, + const cbl_refer_t &source, cbl_label_t *error, cbl_label_t *not_error ) { @@ -4371,7 +4664,7 @@ parser_accept_command_line( cbl_refer_t tgt, { SHOW_PARSE_INDENT SHOW_PARSE_TEXT("Laying down GOTO error->INTO for_command_line") - SHOW_PARSE_LABEL(" ", error) + SHOW_PARSE_LABEL_OK(" ", error) } gg_append_statement( error->structs.arith_error->into.go_to ); } @@ -4389,7 +4682,7 @@ parser_accept_command_line( cbl_refer_t tgt, { SHOW_PARSE_INDENT SHOW_PARSE_TEXT("Laying down GOTO not_error->INTO for command_line") - SHOW_PARSE_LABEL(" ", not_error) + SHOW_PARSE_LABEL_OK(" ", not_error) } gg_append_statement( not_error->structs.arith_error->into.go_to ); } @@ -4421,7 +4714,7 @@ parser_accept_command_line( cbl_refer_t tgt, { SHOW_PARSE_INDENT SHOW_PARSE_TEXT("Laying down GOTO error->INTO for_argv") - SHOW_PARSE_LABEL(" ", error) + SHOW_PARSE_LABEL_OK(" ", error) } gg_append_statement( error->structs.arith_error->into.go_to ); } @@ -4439,7 +4732,7 @@ parser_accept_command_line( cbl_refer_t tgt, { SHOW_PARSE_INDENT SHOW_PARSE_TEXT("Laying down GOTO not_error->INTO for_argv") - SHOW_PARSE_LABEL(" ", not_error) + SHOW_PARSE_LABEL_OK(" ", not_error) } gg_append_statement( not_error->structs.arith_error->into.go_to ); } @@ -4455,7 +4748,7 @@ parser_accept_command_line( cbl_refer_t tgt, { SHOW_PARSE_INDENT SHOW_PARSE_TEXT("Laying down LABEL error->bottom") - SHOW_PARSE_LABEL(" ", error) + SHOW_PARSE_LABEL_OK(" ", error) } gg_append_statement( error->structs.arith_error->bottom.label ); } @@ -4465,7 +4758,7 @@ parser_accept_command_line( cbl_refer_t tgt, { SHOW_PARSE_INDENT SHOW_PARSE_TEXT("Laying down LABEL not_error->bottom") - SHOW_PARSE_LABEL(" ", not_error) + SHOW_PARSE_LABEL_OK(" ", not_error) SHOW_PARSE_END } gg_append_statement( not_error->structs.arith_error->bottom.label ); @@ -4473,7 +4766,7 @@ parser_accept_command_line( cbl_refer_t tgt, } void -parser_accept_command_line_count( cbl_refer_t tgt ) +parser_accept_command_line_count( const cbl_refer_t &tgt ) { Analyze(); SHOW_PARSE @@ -4495,10 +4788,10 @@ parser_accept_command_line_count( cbl_refer_t tgt ) } void -parser_accept_envar(struct cbl_refer_t tgt, - struct cbl_refer_t envar, - cbl_label_t *error, - cbl_label_t *not_error ) +parser_accept_envar(const struct cbl_refer_t &tgt, + const struct cbl_refer_t &envar, + cbl_label_t *error, + cbl_label_t *not_error ) { Analyze(); @@ -4563,7 +4856,7 @@ parser_accept_envar(struct cbl_refer_t tgt, { SHOW_PARSE_INDENT SHOW_PARSE_TEXT("Laying down LABEL error->bottom") - SHOW_PARSE_LABEL(" ", error) + SHOW_PARSE_LABEL_OK(" ", error) } gg_append_statement( error->structs.arith_error->bottom.label ); } @@ -4573,7 +4866,7 @@ parser_accept_envar(struct cbl_refer_t tgt, { SHOW_PARSE_INDENT SHOW_PARSE_TEXT("Laying down LABEL not_error->bottom") - SHOW_PARSE_LABEL(" ", not_error) + SHOW_PARSE_LABEL_OK(" ", not_error) SHOW_PARSE_END } gg_append_statement( not_error->structs.arith_error->bottom.label ); @@ -4581,7 +4874,8 @@ parser_accept_envar(struct cbl_refer_t tgt, } void -parser_set_envar( struct cbl_refer_t name, struct cbl_refer_t value ) +parser_set_envar( const struct cbl_refer_t &name, + const struct cbl_refer_t &value ) { Analyze(); SHOW_PARSE @@ -4983,7 +5277,6 @@ parser_display_internal(tree file_descriptor, build_int_cst_type(SIZE_T, refer.field->data.capacity), advance ? integer_one_node : integer_zero_node, NULL_TREE ); - cursor_at_sol = advance; } else if( refer.field->type == FldLiteralN ) { @@ -5021,50 +5314,50 @@ parser_display_internal(tree file_descriptor, *p = 'E'; if( exp < 0 && exp >= -9 ) { - p[1] = '-'; - p[2] = '0'; - p[3] = '0' - exp; - p[4] = '\0'; + p[1] = '-'; + p[2] = '0'; + p[3] = '0' - exp; + p[4] = '\0'; } else if( exp >= 0 && exp <= 9 ) { - p[1] = '+'; - p[2] = '0'; - p[3] = '0' + exp; - p[4] = '\0'; + p[1] = '+'; + p[2] = '0'; + p[3] = '0' + exp; + p[4] = '\0'; } } else if (exp == 0) { - p[-1] = '\0'; + p[-1] = '\0'; } else if (exp < 0) { - p[-1] = '\0'; - char *q = strchr (ach, '.'); - char dig = q[-1]; - q[-1] = '\0'; - char tem[132]; - snprintf (tem, 132, "%s0.%0*u%c%s", ach, -exp - 1, 0, dig, q + 1); - strcpy (ach, tem); + p[-1] = '\0'; + char *q = strchr (ach, '.'); + char dig = q[-1]; + q[-1] = '\0'; + char tem[132]; + snprintf (tem, 132, "%s0.%0*d%c%s", ach, -exp - 1, 0, dig, q + 1); + strcpy (ach, tem); } - else if (exp > 0) + else // if (exp > 0) { - p[-1] = '\0'; - char *q = strchr (ach, '.'); - for (int i = 0; i != exp; ++i) - q[i] = q[i + 1]; - q[exp] = '.'; + p[-1] = '\0'; + char *q = strchr (ach, '.'); + for (int i = 0; i != exp; ++i) + q[i] = q[i + 1]; + q[exp] = '.'; } __gg__remove_trailing_zeroes(ach); } if( symbol_decimal_point() == ',' ) { - char *p = strchr(ach, '.' ); - if( p ) + char *pdot = strchr(ach, '.' ); + if( pdot ) { - *p = symbol_decimal_point(); + *pdot = symbol_decimal_point(); } } @@ -5121,22 +5414,29 @@ parser_display_field(cbl_field_t *field) DISPLAY_NO_ADVANCE); } -/* - * The first parameter to parser_display is the "device" upon which to display - * the data. Besides normal devices, these may include elements that define the - * Unix command line and environment: - * 1. ARG_NUM_e, the ARGUMENT-NUMBER - * 2. ARG_VALUE_e, the ARGUMENT-VALUE - * 3. ENV_NAME_e, the ENVIRONMENT-NAME - * 4. ENV_VALUE_e, the ENVIRONMENT-VALUE - * that need special care and feeding. - */ void parser_display( const struct cbl_special_name_t *upon, - struct cbl_refer_t refs[], - size_t n, - bool advance ) + const std::vector<cbl_refer_t> &refs, + bool advance, + const cbl_label_t *not_error, + const cbl_label_t *error ) { + const size_t n = refs.size(); + /* + * The first parameter to parser_display is the "device" upon which to display + * the data. Besides normal devices, these may include elements that define the + * Unix command line and environment: + * 1. ARG_NUM_e, the ARGUMENT-NUMBER + * 2. ARG_VALUE_e, the ARGUMENT-VALUE + * 3. ENV_NAME_e, the ENVIRONMENT-NAME + * 4. ENV_VALUE_e, the ENVIRONMENT-VALUE + * that need special care and feeding. + */ + + // At the present time, I am not sure what not_error and error are for + gcc_assert(!not_error); + gcc_assert(!error); + Analyze(); SHOW_PARSE { @@ -5145,7 +5445,7 @@ parser_display( const struct cbl_special_name_t *upon, for(size_t i=0; i<n; i++) { SHOW_PARSE_INDENT - SHOW_PARSE_REF("", refs[i]); + SHOW_PARSE_REF("", refs.at(i)); } if( advance ) { @@ -5177,45 +5477,100 @@ parser_display( const struct cbl_special_name_t *upon, { switch(upon->id) { + // See table 5 in the IBM Cobol For Linux x86 1.2 document. + + case STDIN_e: + case SYSIN_e: + case SYSIPT_e: + cbl_internal_error("Attempting to send to an input device."); + break; + + case C01_e: + case C02_e: + case C03_e: + case C04_e: + case C05_e: + case C06_e: + case C07_e: + case C08_e: + case C09_e: + case C10_e: + case C11_e: + case C12_e: + case CSP_e: + case S01_e: + case S02_e: + case S03_e: + case S04_e: + case S05_e: + case AFP_5A_e: + case ARG_VALUE_e: + cbl_internal_error("Not valid for DISPLAY statement."); + break; + case STDOUT_e: - case SYSOUT_e: - case SYSLIST_e: - case SYSLST_e: case CONSOLE_e: + // These are inarguably stdout gg_assign(file_descriptor, integer_one_node); break; case STDERR_e: + case SYSERR_e: + // These are inarguably stderr + gg_assign(file_descriptor, integer_two_node); + break; + + case SYSOUT_e: + case SYSLIST_e: + case SYSLST_e: case SYSPUNCH_e: case SYSPCH_e: - gg_assign(file_descriptor, integer_two_node); + // In the 21st century, when there are no longer valid assumptions to + // be made about the existence of line printers, and where things + // formerly-ubiquitous card punches no longer exist, there is a need + // for the possibility of assigning these "devices" to externally- + // determined Unix gadgetry in /dev: + gg_assign(file_descriptor, + gg_call_expr( INT, + "__gg__get_file_descriptor", + gg_string_literal(upon->os_filename), + NULL_TREE)); + needs_closing = true; break; - case ENV_NAME_e: - // This Part I of the slightly absurd method of using DISPLAY...UPON - // to fetch, or set, environment variables. + case ARG_NUM_e: + // Set the index number for a subsequent ACCEPT FROM ARG_VALUE_e + gg_call(VOID, + "__gg__set_arg_num", + gg_get_address_of(refs[0].field->var_decl_node), + refer_offset(refs[0]), + refer_size_source(refs[0]), + NULL_TREE); + return; + break; + + case ENV_NAME_e: + // Establish the name of an environment variable for later use with + // in either DISPLAY UPON or ACCEPT FROM + gg_call(VOID, + "__gg__set_env_name", + gg_get_address_of(refs[0].field->var_decl_node), + refer_offset(refs[0]), + refer_size_source(refs[0]), + NULL_TREE); + return; + break; + + case ENV_VALUE_e: + // Set the contents of the environment variable named with ENV_NAME_e gg_call(VOID, - "__gg__set_env_name", + "__gg__set_env_value", gg_get_address_of(refs[0].field->var_decl_node), refer_offset(refs[0]), refer_size_source(refs[0]), NULL_TREE); return; break; - - default: - if( upon->os_filename[0] ) - { - tree topen = gg_open( gg_string_literal(upon->os_filename), - build_int_cst_type(INT, O_APPEND|O_WRONLY)); - gg_assign(file_descriptor, topen); - needs_closing = true; - } - else - { - fprintf(stderr, "We don't know what to do in parser_display\n"); - gcc_unreachable(); - } } } else @@ -5230,17 +5585,114 @@ parser_display( const struct cbl_special_name_t *upon, } CHECK_FIELD(refs[n-1].field); parser_display_internal(file_descriptor, refs[n-1], advance ? DISPLAY_ADVANCE : DISPLAY_NO_ADVANCE); - if( needs_closing ) { - tree tclose = gg_close(file_descriptor); - // We are ignoring the close() return value - gg_append_statement(tclose); + gg_close(file_descriptor); } cursor_at_sol = advance; } +static +bool // Returns false for literals; true for named variables +get_exhibit_name(tree file_descriptor, const cbl_refer_t &arg) + { + bool retval; + if( is_literal(arg.field) ) + { + // If something is a literal, we just display the literal value + parser_display_internal(file_descriptor, + arg, + DISPLAY_NO_ADVANCE); + retval = false; + } + else + { + // It's not a literal, so we show its name, and the names or literal + // values) of any qualifier subscripts or refmods + gg_write( file_descriptor, + gg_string_literal(arg.field->name), + build_int_cst_type(SIZE_T, strlen(arg.field->name)) ); + + if( arg.subscripts.size() ) + { + // This refer has subscripts: + gg_write( file_descriptor, + gg_string_literal("("), + integer_one_node ); + for(size_t i=0; i<arg.subscripts.size(); i++) + { + if( i > 0 ) + { + gg_write( file_descriptor, + gg_string_literal(","), + integer_one_node ); + } + get_exhibit_name(file_descriptor, arg.subscripts[i]); + } + gg_write( file_descriptor, + gg_string_literal(")"), + integer_one_node ); + } + if( arg.refmod.from || arg.refmod.len ) + { + gg_write( file_descriptor, + gg_string_literal("("), + integer_one_node ); + if( arg.refmod.from ) + { + get_exhibit_name(file_descriptor, *(arg.refmod.from)); + } + gg_write( file_descriptor, + gg_string_literal(":"), + integer_one_node ); + if( arg.refmod.len ) + { + get_exhibit_name(file_descriptor, *(arg.refmod.len)); + } + gg_write( file_descriptor, + gg_string_literal(")"), + integer_one_node ); + } + retval = true; + } + return retval; + } + +void +parser_exhibit( bool /*changed*/, bool /*named*/, + const std::vector<cbl_refer_t> &args ) + { + tree file_descriptor = gg_define_int(); + gg_assign(file_descriptor, integer_one_node); // stdout is file descriptor 1. + + for(size_t i=0; i<args.size(); i++) + { + CHECK_FIELD(args[i].field); + if(i > 0) + { + // When there more than one argument, the second through Nth get a space + // in front of them. + gg_write( file_descriptor, + gg_string_literal(" "), + integer_one_node); + } + if( get_exhibit_name(file_descriptor, args[i]) ) + { + gg_write( file_descriptor, + gg_string_literal("="), + integer_one_node); + parser_display_internal(file_descriptor, + args[i], + DISPLAY_NO_ADVANCE); + } + } + gg_write( file_descriptor, + gg_string_literal("\n"), + integer_one_node); + cursor_at_sol = true; + } + static tree get_literalN_value(cbl_field_t *var) { @@ -5513,12 +5965,12 @@ parser_assign( size_t nC, cbl_num_result_t *C, { SHOW_PARSE_INDENT SHOW_PARSE_TEXT(" Laying down on_error GOTO into") - SHOW_PARSE_LABEL(" ", on_error) + SHOW_PARSE_LABEL_OK(" ", on_error) } IF( gg_bitwise_or(error_flag, compute_error->structs.compute_error->compute_error_code), - ne_op, - integer_zero_node ) + ne_op, + integer_zero_node ) { gg_append_statement( on_error->structs.arith_error->into.go_to ); } @@ -5544,7 +5996,7 @@ parser_assign( size_t nC, cbl_num_result_t *C, { SHOW_PARSE_INDENT SHOW_PARSE_TEXT(" Laying down not_error GOTO into") - SHOW_PARSE_LABEL(" ", not_error) + SHOW_PARSE_LABEL_OK(" ", not_error) } IF( compute_error->structs.compute_error->compute_error_code, eq_op, integer_zero_node ) { @@ -5560,7 +6012,7 @@ parser_assign( size_t nC, cbl_num_result_t *C, { SHOW_PARSE_INDENT SHOW_PARSE_TEXT(" Laying down on_error LABEL BOTTOM:") - SHOW_PARSE_LABEL(" ", on_error) + SHOW_PARSE_LABEL_OK(" ", on_error) } gg_append_statement( on_error->structs.arith_error->bottom.label ); } @@ -5571,7 +6023,7 @@ parser_assign( size_t nC, cbl_num_result_t *C, { SHOW_PARSE_INDENT SHOW_PARSE_TEXT(" Laying down not_error LABEL BOTTOM:") - SHOW_PARSE_LABEL(" ", not_error) + SHOW_PARSE_LABEL_OK(" ", not_error) } gg_append_statement( not_error->structs.arith_error->bottom.label ); } @@ -5583,16 +6035,16 @@ parser_assign( size_t nC, cbl_num_result_t *C, } static cbl_figconst_t -is_figconst(cbl_field_t *field) +is_figconst_t(const cbl_field_t *field) { cbl_figconst_t figconst = (cbl_figconst_t)(field->attr & FIGCONST_MASK); return figconst; } static cbl_figconst_t -is_figconst(cbl_refer_t &sourceref) +is_figconst(const cbl_refer_t &sourceref) { - return is_figconst(sourceref.field); + return is_figconst_t(sourceref.field); } void @@ -5846,10 +6298,18 @@ parser_initialize_table(size_t nelem, } typedef size_t span_t[2]; static_assert(sizeof(spans[0]) == sizeof(span_t), "pair size wrong"); - static tree tspans = gg_define_variable(SIZE_T_P, "..pit_v1", vs_file_static); - static tree ttbls = gg_define_variable(SIZE_T_P, "..pit_v2", vs_file_static); - gg_assign(tspans, build_array_of_size_t(2*nspan, (const size_t *)spans)); - gg_assign(ttbls, build_array_of_size_t(2*ntbl, (const size_t *)tbls)); + static tree tspans = gg_define_variable(SIZE_T_P, + "..pit_v1", + vs_file_static); + static tree ttbls = gg_define_variable(SIZE_T_P, + "..pit_v2", +vs_file_static); + gg_assign(tspans, + build_array_of_size_t(2*nspan, + reinterpret_cast<const size_t *>(spans))); + gg_assign(ttbls, + build_array_of_size_t(2*ntbl, + reinterpret_cast<const size_t *>(tbls))); gg_call(VOID, "__gg__mirror_range", @@ -5893,7 +6353,7 @@ tree_type_from_field_type(cbl_field_t *field, size_t &nbytes) case FldNumericDisplay: case FldNumericBinary: case FldPacked: - if( field->data.digits > 18 ) + if( field->data.digits > 18 ) { retval = UINT128; nbytes = 16; @@ -5946,19 +6406,19 @@ tree_type_from_field_type(cbl_field_t *field, size_t &nbytes) break; default: - cbl_internal_error( "%s(): Invalid field type %s:", + cbl_internal_error( "%s: Invalid field type %s:", __func__, cbl_field_type_str(field->type)); break; } - } - if( retval == SIZE_T && field->attr & signable_e ) - { - retval = SSIZE_T; - } - if( retval == UINT128 && field->attr & signable_e ) - { - retval = INT128; + if( retval == SIZE_T && field->attr & signable_e ) + { + retval = SSIZE_T; + } + if( retval == UINT128 && field->attr & signable_e ) + { + retval = INT128; + } } return retval; } @@ -5974,12 +6434,13 @@ restore_local_variables() static inline bool is_valuable( cbl_field_type_t type ) { + /* The name of this routine is a play on words, in English. It doesn't + mean "Is worth a lot". It means "Can be converted to a value." */ switch ( type ) { case FldInvalid: case FldGroup: case FldAlphanumeric: case FldNumericEdited: - case FldAlphaEdited: case FldLiteralA: case FldClass: case FldConditional: @@ -5992,6 +6453,7 @@ is_valuable( cbl_field_type_t type ) { // COBOL form to a little-endian binary representation so that they // can be conveyed BY CONTENT/BY VALUE in a CALL or user-defined // function activation. + case FldAlphaEdited: case FldNumericDisplay: case FldNumericBinary: case FldFloat: @@ -6002,11 +6464,11 @@ is_valuable( cbl_field_type_t type ) { case FldPointer: return true; } - cbl_internal_error( "%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type ); + cbl_internal_error( "%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type ); return false; } -void parser_sleep(cbl_refer_t seconds) +void parser_sleep(const cbl_refer_t &seconds) { if( seconds.field ) { @@ -6026,7 +6488,7 @@ void parser_sleep(cbl_refer_t seconds) // This is a naked place-holding CONTINUE. Generate some do-nothing // code that will stick some .LOC information into the assembly language, // so that GDB-COBOL can display the CONTINUE statement. - gg_assign(var_decl_nop, build_int_cst_type(INT, 103)); + insert_nop(103); } } @@ -6046,7 +6508,7 @@ parser_exit_program(void) // exits back to COBOL only, else continue static void -pe_stuff(cbl_refer_t refer, ec_type_t ec) +program_end_stuff(cbl_refer_t refer, ec_type_t ec) { // This is the moral equivalent of a C "return xyz;". @@ -6069,9 +6531,6 @@ pe_stuff(cbl_refer_t refer, ec_type_t ec) gg_assign(retval, gg_cast(return_type, integer_zero_node)); - gg_modify_function_type(current_function->function_decl, - return_type); - if( is_valuable( field_type ) ) { // The field being returned is numeric. @@ -6112,12 +6571,12 @@ pe_stuff(cbl_refer_t refer, ec_type_t ec) tree array_type = build_array_type_nelts(UCHAR, returner->data.capacity); - tree retval = gg_define_variable(array_type, vs_static); - gg_memcpy(gg_get_address_of(retval), + tree array = gg_define_variable(array_type, vs_static); + gg_memcpy(gg_get_address_of(array), member(returner->var_decl_node, "data"), member(returner->var_decl_node, "capacity")); - tree actual = gg_cast(COBOL_FUNCTION_RETURN_TYPE, gg_get_address_of(retval)); + tree actual = gg_cast(COBOL_FUNCTION_RETURN_TYPE, gg_get_address_of(array)); restore_local_variables(); gg_return(actual); @@ -6137,7 +6596,7 @@ pe_stuff(cbl_refer_t refer, ec_type_t ec) } void -parser_exit( cbl_refer_t refer, ec_type_t ec ) +parser_exit( const cbl_refer_t& refer, ec_type_t ec ) { Analyze(); SHOW_PARSE @@ -6174,7 +6633,7 @@ parser_exit( cbl_refer_t refer, ec_type_t ec ) IF( current_function->called_by_main_counter, eq_op, integer_zero_node ) { // This function wasn't called by main, so we treat it like a GOBACK - pe_stuff(refer, ec); + program_end_stuff(refer, ec); } ELSE { @@ -6185,7 +6644,7 @@ parser_exit( cbl_refer_t refer, ec_type_t ec ) // This was a recursive call into the function originally called by // main. Because we are under the control of a calling program, we // treat this like a GOBACK - pe_stuff(refer, ec); + program_end_stuff(refer, ec); } ELSE { @@ -6210,7 +6669,7 @@ parser_exit( cbl_refer_t refer, ec_type_t ec ) { } ENDIF - pe_stuff(refer, ec); + program_end_stuff(refer, ec); } } @@ -6373,7 +6832,6 @@ parser_arith_error(cbl_label_t *arithmetic_label) // We are entering either SIZE ERROR or NOT SIZE ERROR code RETURN_IF_PARSE_ONLY; - set_up_on_exception_label(arithmetic_label); SHOW_PARSE { @@ -6386,6 +6844,10 @@ parser_arith_error(cbl_label_t *arithmetic_label) SHOW_PARSE_END } + CHECK_LABEL(arithmetic_label); + + set_up_on_exception_label(arithmetic_label); + // Jump over the [NOT] ON EXCEPTION code that is about to be laid down gg_append_statement( arithmetic_label->structs.arith_error->over.go_to ); // Create the label that allows the following code to be executed at @@ -6412,6 +6874,8 @@ parser_arith_error_end(cbl_label_t *arithmetic_label) SHOW_PARSE_END } + CHECK_LABEL(arithmetic_label); + // Jump to the end of the arithmetic code: gg_append_statement( arithmetic_label->structs.arith_error->bottom.go_to ); // Lay down the label that allows the ERROR/NOT ERROR instructions @@ -6595,8 +7059,6 @@ parser_division(cbl_division_t division, SHOW_PARSE_END } - gg_set_current_line_number(CURRENT_LINE_NUMBER); - if( division == data_div_e ) { Analyze(); @@ -6701,7 +7163,7 @@ parser_division(cbl_division_t division, // gg_printf("Somebody wants to cancel %s\n", // gg_string_literal(current_function->our_unmangled_name), // NULL_TREE); - cbl_label_t *prog = cbl_label_of(symbol_at(current_program_index())); + const cbl_label_t *prog = cbl_label_of(symbol_at(current_program_index())); size_t initializer_index = prog->initial_section; cbl_label_t *initializer = cbl_label_of(symbol_at(initializer_index)); parser_perform(initializer, true); // true means suppress nexting @@ -6722,6 +7184,10 @@ parser_division(cbl_division_t division, { parser_local_add(returning); current_function->returning = returning; + + size_t nbytes = 0; + tree returning_type = tree_type_from_field_type(returning, nbytes); + gg_modify_function_type(current_function->function_decl, returning_type); } // Stash the returning variables for use during parser_return() @@ -6744,7 +7210,6 @@ parser_division(cbl_division_t division, // expected formal parameter and tacks it onto the end of the // function's arguments chain. - char ach[2*sizeof(cbl_name_t)]; sprintf(ach, "_p_%s", args[i].refer.field->name); size_t nbytes = 0; @@ -6764,14 +7229,13 @@ parser_division(cbl_division_t division, chain_parameter_to_function(current_function->function_decl, par_type, ach); } - bool check_for_parameter_count = false; - if( nusing ) { // During the call, we saved the parameter_count and an array of variable // lengths. We need to look at those values if, and only if, one or more // of our USING arguments has an OPTIONAL flag or if one of our targets is // marked as VARYING. + bool check_for_parameter_count = false; for(size_t i=0; i<nusing; i++) { if( args[i].optional ) @@ -6818,7 +7282,7 @@ parser_division(cbl_division_t division, // There are 'nusing' elements in the PROCEDURE DIVISION USING list. - tree parameter; + tree parameter = NULL_TREE; tree rt_i = gg_define_int(); for(size_t i=0; i<nusing; i++) { @@ -6967,7 +7431,6 @@ parser_division(cbl_division_t division, // If so, we have to give var2::data_pointer the same value as // var1::data_pointer // - cbl_field_t *next_var; size_t our_index = symbol_index(symbol_elem_of(new_var)); size_t next_index = our_index + 1; // Look ahead in the symbol table for the next LEVEL01/77 @@ -6978,7 +7441,7 @@ parser_division(cbl_division_t division, { break; } - next_var = cbl_field_of(e); + cbl_field_t *next_var = cbl_field_of(e); if( !next_var ) { break; @@ -7053,6 +7516,11 @@ parser_division(cbl_division_t division, ENDIF } ENDIF + // The first token_location that the parser establishes is caused by the + // parser scanning all of the lines in the source code. This messes up the + // logic for backing up one line, which is needed to correctly step through + // COBOL code with GDB-COBOL. So, we clear it here. + current_location_minus_one_clear(); } } @@ -7148,20 +7616,20 @@ parser_logop( struct cbl_field_t *tgt, if( tgt->type != FldConditional ) { - cbl_internal_error("parser_logop() was called with variable %s on line %d" - ", which is not a FldConditional\n", + cbl_internal_error("%<parser_logop()%> was called with variable %s on line %d" + ", which is not a FldConditional", tgt->name, cobol_location().first_line); } if( a && a->type != FldConditional ) { - cbl_internal_error("parser_logop() was called with variable %s on line %d" - ", which is not a FldConditional\n", + cbl_internal_error("%<parser_logop()%> was called with variable %s on line %d" + ", which is not a FldConditional", a->name, cobol_location().first_line); } if( b && b->type != FldConditional ) { - cbl_internal_error("parser_logop() was called with variable %s on line %d" - ", which is not a FldConditional\n", + cbl_internal_error("%<parser_logop()%> was called with variable %s on line %d" + ", which is not a FldConditional", b->name, cobol_location().first_line); } @@ -7267,9 +7735,9 @@ parser_relop( cbl_field_t *tgt, if( tgt->type != FldConditional ) { - cbl_internal_error("parser_relop() was called with variable %s, " - "which is not a FldConditional\n", - tgt->name); + cbl_internal_error("%<parser_relop%> was called with variable %qs, " + "which is not a FldConditional", + tgt->name); } static tree comp_res = gg_define_variable(INT, "..pr_comp_res", vs_file_static); @@ -7331,8 +7799,8 @@ parser_relop_long(cbl_field_t *tgt, if( tgt->type != FldConditional ) { - cbl_internal_error("parser_relop() was called with variable %s, " - "which is not a FldConditional\n", + cbl_internal_error("%<parser_relop()%> was called with variable %s, " + "which is not a FldConditional", tgt->name); } @@ -7377,8 +7845,8 @@ parser_if( struct cbl_field_t *conditional ) if( conditional->type != FldConditional ) { - cbl_internal_error("parser_if() was called with variable %s, " - "which is not a FldConditional\n", + cbl_internal_error("%<parser_if()%> was called with variable %s, " + "which is not a FldConditional", conditional->name); } @@ -7497,7 +7965,9 @@ label_fetch(struct cbl_label_t *label) if( !label->structs.goto_trees ) { label->structs.goto_trees - = (cbl_label_addresses_t *)xmalloc(sizeof(struct cbl_label_addresses_t) ); + = static_cast<cbl_label_addresses_t *> + (xmalloc(sizeof(struct cbl_label_addresses_t))); + gcc_assert(label->structs.goto_trees); gg_create_goto_pair(&label->structs.goto_trees->go_to, &label->structs.goto_trees->label); @@ -7515,15 +7985,18 @@ parser_label_label(struct cbl_label_t *label) SHOW_PARSE_HEADER SHOW_PARSE_LABEL("", label) char ach[32]; - sprintf(ach, " label is at %p", (void*)label); + sprintf(ach, " label is at %p", static_cast<void*>(label)); SHOW_PARSE_TEXT(ach) - sprintf(ach, " label->proc is %p", (void*)label->structs.proc); + if( label ) + { + sprintf(ach, + " label->proc is %p", + static_cast<void*>(label->structs.proc)); + } SHOW_PARSE_TEXT(ach) SHOW_PARSE_END } - CHECK_LABEL(label); - TRACE1 { TRACE1_HEADER @@ -7531,6 +8004,8 @@ parser_label_label(struct cbl_label_t *label) TRACE1_END } + CHECK_LABEL(label); + if(strcmp(label->name, "_end_declaratives") == 0 ) { suppress_cobol_entry_point = false; @@ -7542,21 +8017,25 @@ void parser_label_goto(struct cbl_label_t *label) { label->used = yylineno; + Analyze(); SHOW_PARSE { SHOW_PARSE_HEADER SHOW_PARSE_LABEL(" ", label) char ach[32]; - sprintf(ach, " label is at %p", (void*)label); + sprintf(ach, " label is at %p", static_cast<void*>(label)); SHOW_PARSE_TEXT(ach) - sprintf(ach, " label->proc is %p", (void*)label->structs.proc); + if( label ) + { + sprintf(ach, + " label->proc is %p", + static_cast<void*>(label->structs.proc)); + } SHOW_PARSE_TEXT(ach) SHOW_PARSE_END } - CHECK_LABEL(label); - TRACE1 { TRACE1_HEADER @@ -7564,7 +8043,9 @@ parser_label_goto(struct cbl_label_t *label) TRACE1_END } - if(strcmp(label->name, "_end_declaratives") == 0 ) + CHECK_LABEL(label); + + if( strcmp(label->name, "_end_declaratives") == 0 ) { suppress_cobol_entry_point = true; } @@ -7628,20 +8109,19 @@ parser_setop( struct cbl_field_t *tgt, integer_zero_node)); break; default: - dbgmsg("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ ); - cbl_internal_error( - "###### candidate %s has unimplemented CVT_type %d(%s)\n", - candidate->name, - candidate->type, - cbl_field_type_str(candidate->type)); + dbgmsg("%10s in %s:%d", __func__, __FILE__, __LINE__ ); + cbl_internal_error("candidate %s has unimplemented %<CVT_type%> %d(%s)", + candidate->name, + candidate->type, + cbl_field_type_str(candidate->type)); gcc_unreachable(); break; } break; default: - dbgmsg("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ ); - cbl_internal_error("###### unknown setop_t code %d\n", op); + dbgmsg("%10s in %s:%d", __func__, __FILE__, __LINE__ ); + cbl_internal_error("unknown %<setop_t%> code %d", op); gcc_unreachable(); break; } @@ -7649,7 +8129,7 @@ parser_setop( struct cbl_field_t *tgt, void parser_classify( cbl_field_t *tgt, - cbl_refer_t candidate, + const cbl_refer_t &candidate, enum classify_t type ) { Analyze(); @@ -7694,9 +8174,9 @@ parser_classify( cbl_field_t *tgt, } void -parser_perform(struct cbl_perform_tgt_t *tgt, struct cbl_refer_t how_many) +parser_perform(const cbl_perform_tgt_t *tgt, cbl_refer_t how_many) { - cbl_field_t *N = how_many.field; + const cbl_field_t *N = how_many.field; // No SHOW_PARSE here; we want to fall through: if( !tgt->to() ) { @@ -7746,14 +8226,6 @@ create_iline_address_pairs(struct cbl_perform_tgt_t *tgt) gg_create_goto_pair(&tgt->addresses.setup.go_to, &tgt->addresses.setup.label); - - // Even in -O0 compilations, the compiler does some elementary optimizations - // around JMP instructions. We have the SETUP code for in-line performats - // in an island at the end of the loop code. With this intervention, NEXTing - // through the code shows you the final statement of the loop before the - // loop actually starts. - - tgt->addresses.line_number_of_setup_code = gg_get_current_line_number(); } void @@ -7767,7 +8239,7 @@ parser_perform_start( struct cbl_perform_tgt_t *tgt ) { SHOW_PARSE_TEXT(" cbl_perform_tgt_t is at") char ach[32]; - sprintf(ach, " %p", (void*)tgt); + sprintf(ach, " %p", static_cast<void*>(tgt)); SHOW_PARSE_TEXT(ach); SHOW_PARSE_LABEL(" ", tgt->from()) if( tgt->to() ) @@ -7816,7 +8288,7 @@ parser_perform_start( struct cbl_perform_tgt_t *tgt ) // Give GDB-COBOL something to chew on when NEXTing. This instruction will // get the line number of the PERFORM N TIMES code. gg_append_statement(tgt->addresses.top.label); - gg_assign(var_decl_nop, build_int_cst_type(INT, 104)); + insert_nop(104); } void @@ -7828,17 +8300,18 @@ parser_perform_conditional( struct cbl_perform_tgt_t *tgt ) SHOW_PARSE_HEADER SHOW_PARSE_TEXT(" cbl_perform_tgt_t is at") char ach[32]; - sprintf(ach, " %p", (void*)tgt); + sprintf(ach, " %p", static_cast<void*>(tgt)); SHOW_PARSE_TEXT(ach); SHOW_PARSE_END } - size_t i = tgt->addresses.number_of_conditionals; + unsigned int i = tgt->addresses.number_of_conditionals; if( !(i < MAXIMUM_UNTILS) ) { - cbl_internal_error("%s:%d: %zu exceeds MAXIMUM_UNTILS of %d, line %d", - __func__, __LINE__, i, MAXIMUM_UNTILS, CURRENT_LINE_NUMBER); + cbl_internal_error("%s:%d: %u exceeds %<MAXIMUM_UNTILS%> of %d, line %d", + __func__, __LINE__, + i, MAXIMUM_UNTILS, CURRENT_LINE_NUMBER); } gcc_assert(i < MAXIMUM_UNTILS); @@ -7877,12 +8350,12 @@ parser_perform_conditional_end( struct cbl_perform_tgt_t *tgt ) SHOW_PARSE_HEADER SHOW_PARSE_TEXT(" cbl_perform_tgt_t is at") char ach[32]; - sprintf(ach, " %p", (void*)tgt); + sprintf(ach, " %p", static_cast<void*>(tgt)); SHOW_PARSE_TEXT(ach); SHOW_PARSE_END } - size_t i = tgt->addresses.number_of_conditionals; + unsigned int i = tgt->addresses.number_of_conditionals; gcc_assert(i); // We need to cap off the prior conditional in this chain of conditionals @@ -8372,8 +8845,6 @@ perform_inline_until( struct cbl_perform_tgt_t *tgt, GOTO TOP EXIT: */ - gg_set_current_line_number(cobol_location().last_line); - gg_append_statement(tgt->addresses.test.label); // Go to where the conditional is recalculated.... @@ -8488,8 +8959,6 @@ perform_inline_testbefore_varying( struct cbl_perform_tgt_t *tgt, parser_move(varys[i].varying, varys[i].from); } - gg_set_current_line_number(cobol_location().last_line); - // Lay down the testing cycle: for(size_t i=0; i<N; i++) { @@ -8801,7 +9270,7 @@ parser_perform_until( struct cbl_perform_tgt_t *tgt, SHOW_PARSE_HEADER SHOW_PARSE_TEXT(" cbl_perform_tgt_t is at") char ach[32]; - sprintf(ach, " %p", (void*)tgt); + sprintf(ach, " %p", static_cast<void*>(tgt)); SHOW_PARSE_TEXT(ach); SHOW_PARSE_LABEL(" ", tgt->from()) if( tgt->to() ) @@ -8811,9 +9280,6 @@ parser_perform_until( struct cbl_perform_tgt_t *tgt, SHOW_PARSE_END } - gg_set_current_line_number(cobol_location().last_line); - gg_assign(var_decl_nop, build_int_cst_type(INT, 105)); - if( tgt->from()->type != LblLoop ) { perform_outofline( tgt, test_before, N, varys); @@ -8880,10 +9346,6 @@ parser_perform_inline_times(struct cbl_perform_tgt_t *tgt, gg_append_statement( tgt->addresses.testA.label ); gg_append_statement( tgt->addresses.test.label ); - // AT this point, we want to set the line_number to the location of the - // END-PERFORM statement. - gg_set_current_line_number(cobol_location().last_line); - gg_decrement(counter); // Do the test: IF( counter, gt_op, gg_cast(LONG, integer_zero_node) ) @@ -8914,8 +9376,6 @@ parser_perform_inline_times(struct cbl_perform_tgt_t *tgt, SHOW_PARSE_END } - int stash = gg_get_current_line_number(); - gg_set_current_line_number(tgt->addresses.line_number_of_setup_code); gg_append_statement( tgt->addresses.setup.label ); // Get the count: @@ -8946,8 +9406,6 @@ parser_perform_inline_times(struct cbl_perform_tgt_t *tgt, gg_append_statement( tgt->addresses.exit.go_to ); ENDIF - gg_set_current_line_number(stash); - SHOW_PARSE { SHOW_PARSE_INDENT @@ -8958,7 +9416,7 @@ parser_perform_inline_times(struct cbl_perform_tgt_t *tgt, } void -parser_set_conditional88( struct cbl_refer_t refer, bool which_way ) +parser_set_conditional88( const cbl_refer_t& refer, bool which_way ) { Analyze(); struct cbl_field_t *tgt = refer.field; @@ -9070,7 +9528,7 @@ parser_file_add(struct cbl_file_t *file) if( !file ) { - cbl_internal_error("%s(): called with NULL *file", __func__); + cbl_internal_error("%s: called with NULL *file", __func__); gcc_assert(file); } @@ -9195,7 +9653,7 @@ parser_file_add(struct cbl_file_t *file) if(file->access == file_inaccessible_e) { cbl_internal_error( - "%s:%d file %s access mode is 'file_inaccessible_e' in %s", + "%s:%d file %s access mode is %<file_inaccessible_e%> in %s", current_filename.back().c_str(), CURRENT_LINE_NUMBER, file->name, @@ -9269,12 +9727,13 @@ parser_file_open( struct cbl_file_t *file, int mode_char ) if( !file ) { - cbl_internal_error("parser_file_open called with NULL *file"); + cbl_internal_error("%<parser_file_open%> called with NULL *file"); } if( !file->var_decl_node ) { - cbl_internal_error("parser_file_open for %s called with NULL var_decl_node", file->name); + cbl_internal_error("%<parser_file_open%> for %s called with NULL " + "%<var_decl_node%>", file->name); } if( mode_char == 'a' && (file->access != file_access_seq_e) ) @@ -9348,12 +9807,13 @@ parser_file_close( struct cbl_file_t *file, file_close_how_t how ) if( !file ) { - cbl_internal_error("parser_file_close called with NULL *file"); + cbl_internal_error("%<parser_file_close%> called with NULL *file"); } if( !file->var_decl_node ) { - cbl_internal_error("parser_file_close for %s called with NULL file->var_decl_node", file->name); + cbl_internal_error("%<parser_file_close%> for %s called with " + "NULL %<file->var_decl_node%>", file->name); } TRACE1 @@ -9417,27 +9877,29 @@ parser_file_read( struct cbl_file_t *file, if( !file ) { - cbl_internal_error("parser_file_read called with NULL *file"); + cbl_internal_error("%<parser_file_read%> called with NULL *file"); } if( !file->var_decl_node ) { - cbl_internal_error("parser_file_read for %s called with NULL file->var_decl_node", file->name); + cbl_internal_error("%<parser_file_read%> for %s called with " + "NULL %<file->var_decl_node%>", file->name); } if( !file ) { - cbl_internal_error("parser_file_read called with NULL *field"); + cbl_internal_error("%<parser_file_read%> called with NULL *field"); } if( !file->var_decl_node ) { - cbl_internal_error("parser_file_read for %s called with NULL field->var_decl_node", file->name); + cbl_internal_error("%<parser_file_read%> for %s called with " + "NULL %<field->var_decl_node%>", file->name); } if( file->access == file_access_seq_e && where >= 0) { - cbl_internal_error("%s:%d file %s is RELATIVE/SEQUENTIAL, but 'where' >= 0", + cbl_internal_error("%s:%d file %s is RELATIVE/SEQUENTIAL, but %<where >= 0%>", current_filename.back().c_str(), CURRENT_LINE_NUMBER, file->name); @@ -9446,7 +9908,7 @@ parser_file_read( struct cbl_file_t *file, if( file->access == file_access_rnd_e && where < 0) { - cbl_internal_error("%s:%d file %s is RELATIVE/RANDOM, but 'where' < 0", + cbl_internal_error("%s:%d file %s is RELATIVE/RANDOM, but %<where < 0%>", current_filename.back().c_str(), CURRENT_LINE_NUMBER, file->name); @@ -9534,23 +9996,23 @@ parser_file_write( cbl_file_t *file, if( !file ) { - cbl_internal_error("%s(): called with NULL *file", __func__); + cbl_internal_error("%s: called with NULL *file", __func__); } if( !file->var_decl_node ) { - cbl_internal_error("%s(): for %s called with NULL file->var_decl_node", + cbl_internal_error("%s: for %s called with NULL %<file->var_decl_node%>", __func__, file->name); } if( !file ) { - cbl_internal_error("%s(): called with NULL *field", __func__); + cbl_internal_error("%s: called with NULL *field", __func__); } if( !file->var_decl_node ) { - cbl_internal_error( "%s(): for %s called with NULL field->var_decl_node", + cbl_internal_error( "%s: for %s called with NULL %<field->var_decl_node%>", __func__, file->name); } @@ -9632,13 +10094,19 @@ void parser_file_delete( struct cbl_file_t *file, bool /*sequentially*/ ) { Analyze(); + + if( !file ) + { + cbl_internal_error("The file pointer should not be null"); + abort(); // Because cppcheck doesn't recognize [[noerror]] + } + bool sequentially = file->access == file_access_seq_e || file->org == file_sequential_e || file->org == file_line_sequential_e; SHOW_PARSE { SHOW_PARSE_HEADER - if(file) { SHOW_PARSE_TEXT(" "); SHOW_PARSE_TEXT(file->name); @@ -9651,10 +10119,6 @@ parser_file_delete( struct cbl_file_t *file, bool /*sequentially*/ ) SHOW_PARSE_TEXT(" sequentially") } } - else - { - SHOW_PARSE_TEXT(" *file is NULL") - } SHOW_PARSE_END } @@ -9811,8 +10275,8 @@ parser_file_start(struct cbl_file_t *file, // A key has a number of fields for(size_t ifield=0; ifield<file->keys[key_number].nfield; ifield++) { - size_t field_index = file->keys[key_number].fields[ifield]; - cbl_field_t *field = cbl_field_of(symbol_at(field_index)); + size_t nfield = file->keys[key_number].fields[ifield]; + cbl_field_t *field = cbl_field_of(symbol_at(nfield)); combined_length += field->data.capacity; } gg_assign(length, build_int_cst_type(SIZE_T, combined_length)); @@ -9839,15 +10303,53 @@ parser_file_start(struct cbl_file_t *file, static void inspect_tally(bool backward, - cbl_refer_t identifier_1, - unsigned long n_identifier_2, - cbx_inspect_t<cbl_refer_t>* identifier_2) + const cbl_refer_t &identifier_1, + cbl_inspect_opers_t& identifier_2) { Analyze(); // This is an INSPECT FORMAT 1 SHOW_PARSE { SHOW_PARSE_HEADER + char ach[128]; + sprintf(ach, "There are %lu identifier_2", gb4(identifier_2.size())); + SHOW_PARSE_TEXT(ach); + for(size_t i=0; i<identifier_2.size(); i++) + { + SHOW_PARSE_INDENT + sprintf(ach, "%lu: bounds: %lu", gb4(i), gb4(identifier_2[i].nbound())); + SHOW_PARSE_TEXT(ach); + for(size_t j=0; j<identifier_2[i].nbound(); j++) + { + SHOW_PARSE_INDENT + sprintf(ach, " %lu: matches: %lu", + gb4(j), gb4(identifier_2[i][j].matches.size())); + SHOW_PARSE_TEXT(ach); + + SHOW_PARSE_INDENT + if( identifier_2[i][j].bound == bound_characters_e ) + { + SHOW_PARSE_TEXT(" bound_characters"); + } + else + { + SHOW_PARSE_TEXT(" bound_leading/all"); + } + + if( identifier_2[i][j].matches.size() ) + { + SHOW_PARSE_INDENT + sprintf(ach, " before %p", + as_voidp(identifier_2.at(i).at(j).matches.at(0).before.identifier_4.field)); + SHOW_PARSE_TEXT(ach); + SHOW_PARSE_INDENT + sprintf(ach, " after %p", + as_voidp(identifier_2.at(i).at(j).matches.at(0).after.identifier_4.field)); + SHOW_PARSE_TEXT(ach); + } + } + } + SHOW_PARSE_END } @@ -9857,6 +10359,7 @@ inspect_tally(bool backward, size_t int_index = 0; size_t pcbl_index = 0; + unsigned long n_identifier_2 = identifier_2.size(); // The first integer is the all-important controlling count: int_index++; @@ -9870,12 +10373,11 @@ inspect_tally(bool backward, pcbl_index++; // For each FOR there is a count of the loops after the FOR int_index++; - for(size_t j=0; j<identifier_2[i].nbound; j++) + for(size_t j=0; j<identifier_2[i].nbound(); j++) { - // After each identifier-2, there is a cbl_inspect_bound_t value: int_index++; - if( identifier_2[i].opers[j].bound == bound_characters_e) + if( identifier_2[i][j].bound == bound_characters_e) { // This is a FOR CHARACTERS PHRASE1, so we will need before/after // for each: @@ -9886,7 +10388,7 @@ inspect_tally(bool backward, { // This is ALL or LEADING. Each has some number of identifier-3 int_index++; - for(size_t k=0; k<identifier_2[i].opers[j].n_identifier_3; k++) + for(size_t k=0; k<identifier_2[i][j].n_identifier_3(); k++) { // Put identifier-3 into the array: pcbl_index++; @@ -9922,8 +10424,8 @@ inspect_tally(bool backward, } ENDIF - size_t n_resolveds = pcbl_index; - cbl_refer_t *pcbl_refers = (cbl_refer_t *)xmalloc(n_resolveds * sizeof(cbl_refer_t)); + const size_t n_resolveds = pcbl_index; + std::vector<cbl_refer_t> pcbl_refers(n_resolveds); // Now we make a second pass, populating those arrays: int_index = 0; @@ -9942,34 +10444,42 @@ inspect_tally(bool backward, pcbl_refers[pcbl_index++] = identifier_2[i].tally; // For each FOR there is a count of the loops after the FOR gg_assign( gg_array_value(integers, int_index++), - build_int_cst_type(SIZE_T, identifier_2[i].nbound) ); - for(size_t j=0; j<identifier_2[i].nbound; j++) + build_int_cst_type(SIZE_T, identifier_2[i].nbound()) ); + for(size_t j=0; j<identifier_2[i].nbound(); j++) { // After each identifier-2, there is a cbl_inspect_bound_t value: gg_assign( gg_array_value(integers, int_index++), - build_int_cst_type(SIZE_T, identifier_2[i].opers[j].bound)); - if( identifier_2[i].opers[j].bound == bound_characters_e) + build_int_cst_type(SIZE_T, identifier_2[i][j].bound)); + if( identifier_2[i][j].bound == bound_characters_e) { // This is a FOR CHARACTERS PHRASE1, so we will need before/after // for each: - pcbl_refers[pcbl_index++] = identifier_2[i].opers[j].matches[0].before.identifier_4; - pcbl_refers[pcbl_index++] = identifier_2[i].opers[j].matches[0].after.identifier_4; + const auto& m( identifier_2[i][j].matches ); + if( m.empty() ) + { + pcbl_index += 2; + } + else + { + pcbl_refers[pcbl_index++] = m[0].before.identifier_4; + pcbl_refers[pcbl_index++] = m[0].after.identifier_4; + } } else { // This is ALL or LEADING. Each has some number of identifier-3 gg_assign( gg_array_value(integers, int_index++), - build_int_cst_type(SIZE_T, identifier_2[i].opers[j].n_identifier_3)); - for(size_t k=0; k<identifier_2[i].opers[j].n_identifier_3; k++) + build_int_cst_type(SIZE_T, identifier_2[i][j].n_identifier_3())); + for(size_t k=0; k<identifier_2[i][j].n_identifier_3(); k++) { // Put identifier-3 into the array: - pcbl_refers[pcbl_index++] = identifier_2[i].opers[j].matches[k].matching; + pcbl_refers[pcbl_index++] = identifier_2[i][j].matches[k].matching(); // We need the PHRASE1 for that identifier-3 - pcbl_refers[pcbl_index++] = identifier_2[i].opers[j].matches[k].before.identifier_4; + pcbl_refers[pcbl_index++] = identifier_2[i][j].matches[k].before.identifier_4; - pcbl_refers[pcbl_index++] = identifier_2[i].opers[j].matches[k].after.identifier_4; + pcbl_refers[pcbl_index++] = identifier_2[i][j].matches[k].after.identifier_4; } } } @@ -9981,7 +10491,7 @@ inspect_tally(bool backward, gcc_assert(pcbl_index == n_resolveds); // We have built up an array of integers, and an array of cbl_refer_t. - build_array_of_treeplets(1, pcbl_index, pcbl_refers); + build_array_of_treeplets(1, pcbl_index, pcbl_refers.data()); // Do the actual call: gg_call(VOID, @@ -9989,16 +10499,12 @@ inspect_tally(bool backward, backward ? integer_one_node : integer_zero_node, integers, NULL_TREE); - - // And free up the memory we allocated - free(pcbl_refers); } static void inspect_replacing(int backward, - cbl_refer_t identifier_1, - unsigned long n_ops, - cbx_inspect_t<cbl_refer_t>* operations) + const cbl_refer_t &identifier_1, + cbl_inspect_opers_t &operations) { Analyze(); // This is an INSPECT FORMAT 2 @@ -10009,6 +10515,7 @@ inspect_replacing(int backward, } // For REPLACING, unlike TALLY, there can be but one operation + unsigned long n_ops = operations.size(); gcc_assert(n_ops == 1); size_t n_id_3 = 0; @@ -10019,9 +10526,9 @@ inspect_replacing(int backward, // Make one pass through the inputs to count up the sizes of the arrays // we will be passing to the library routines: - for( size_t j=0; j<operations[0].nbound; j++) + for( size_t j=0; j<operations[0].nbound(); j++) { - if( operations[0].opers[j].bound == bound_characters_e) + if( operations[0][j].bound == bound_characters_e) { // This is a FOR CHARACTERS phrase @@ -10040,13 +10547,13 @@ inspect_replacing(int backward, // The n_identifier-3 values will go into the resolved values; we have to // leave room for them - n_id_3 += operations[0].opers[j].n_identifier_3; + n_id_3 += operations[0][j].n_identifier_3(); // Likewise identifier-5 values: - n_id_5 += operations[0].opers[j].n_identifier_3; + n_id_5 += operations[0][j].n_identifier_3(); // And each identifier-3 / identifier-5 pair has BEFORE and AFTER phrases: - n_id_4 += 2 * operations[0].opers[j].n_identifier_3; + n_id_4 += 2 * operations[0][j].n_identifier_3(); } } @@ -10054,8 +10561,8 @@ inspect_replacing(int backward, // all the integers and cbl_inspect_bound_t values, in a strict sequence so // that the library routine can peel them off. - size_t n_integers = 1 // Room for operations[0].nbound - + operations[0].nbound // Room for all the cbl_inspect_bound_t values + size_t n_integers = 1 // Room for operations[0].nbound() + + operations[0].nbound() // Room for all the cbl_inspect_bound_t values + n_all_leading_first; // Room for all of the n_identifier_3 counts static tree int_size = gg_define_variable(INT, "..pir_size", vs_file_static, 0); @@ -10075,12 +10582,12 @@ inspect_replacing(int backward, } ENDIF - size_t n_resolveds = 1 // Room for identifier-1 + const size_t n_resolveds = 1 // Room for identifier-1 + n_id_3 // Room for the identifier-3 variables + n_id_4 // Room for the identifier-4 variables + n_id_5; // Room for the identifier-5 variables - cbl_refer_t *pcbl_refers = (cbl_refer_t *)xmalloc(n_resolveds * sizeof(cbl_refer_t)); + std::vector<cbl_refer_t> pcbl_refers(n_resolveds); // Now we make a second pass, populating those arrays: size_t int_index = 0; @@ -10088,28 +10595,28 @@ inspect_replacing(int backward, // The first integer is the all-important controlling count: gg_assign( gg_array_value(integers, int_index++), - build_int_cst_type(SIZE_T, operations[0].nbound) ); + build_int_cst_type(SIZE_T, operations[0].nbound()) ); // The first refer is for identifier-1 pcbl_refers[pcbl_index++] = identifier_1; - for( size_t j=0; j<operations[0].nbound; j++) + for( size_t j=0; j<operations[0].nbound(); j++) { // For each FOR there is a count of the loops after the FOR // For each operation, there is a cbl_inspect_bound_t value: gg_assign( gg_array_value(integers, int_index++), - build_int_cst_type(SIZE_T, operations[0].opers[j].bound)); - if( operations[0].opers[j].bound == bound_characters_e) + build_int_cst_type(SIZE_T, operations[0][j].bound)); + if( operations[0][j].bound == bound_characters_e) { // This is a FOR CHARACTERS PHRASE1 // Put in the identifier-5 replacement value: - pcbl_refers[pcbl_index++] = operations[0].opers[j].replaces[0].replacement; + pcbl_refers[pcbl_index++] = operations[0][j].replaces[0].replacement; // Each identifier-5 gets a PHRASE1: - pcbl_refers[pcbl_index++] = operations[0].opers[j].replaces[0].before.identifier_4; - pcbl_refers[pcbl_index++] = operations[0].opers[j].replaces[0].after.identifier_4; + pcbl_refers[pcbl_index++] = operations[0][j].replaces[0].before.identifier_4; + pcbl_refers[pcbl_index++] = operations[0][j].replaces[0].after.identifier_4; SHOW_PARSE { @@ -10117,14 +10624,14 @@ inspect_replacing(int backward, { SHOW_PARSE_INDENT } - SHOW_PARSE_FIELD("ID-5 ", operations[0].opers[j].replaces[0].replacement.field) - if(operations[0].opers[j].replaces[0].before.identifier_4.field) + SHOW_PARSE_FIELD("ID-5 ", operations[0][j].replaces[0].replacement.field) + if(operations[0][j].replaces[0].before.identifier_4.field) { - SHOW_PARSE_FIELD(" before ", operations[0].opers[j].replaces[0].before.identifier_4.field) + SHOW_PARSE_FIELD(" before ", operations[0][j].replaces[0].before.identifier_4.field) } - if(operations[0].opers[j].replaces[0].after.identifier_4.field) + if(operations[0][j].replaces[0].after.identifier_4.field) { - SHOW_PARSE_FIELD(" after ", operations[0].opers[j].replaces[0].after.identifier_4.field) + SHOW_PARSE_FIELD(" after ", operations[0][j].replaces[0].after.identifier_4.field) } SHOW_PARSE_END } @@ -10133,19 +10640,19 @@ inspect_replacing(int backward, { // This is ALL or LEADING. Each has some number of identifier-3/identifier-5 pairs gg_assign( gg_array_value(integers, int_index++), - build_int_cst_type(SIZE_T, operations[0].opers[j].n_identifier_3)); - for(size_t k=0; k<operations[0].opers[j].n_identifier_3; k++) + build_int_cst_type(SIZE_T, operations[0][j].n_identifier_3())); + for(size_t k=0; k<operations[0][j].n_identifier_3(); k++) { // Put identifier-3 into the array: - pcbl_refers[pcbl_index++] = operations[0].opers[j].replaces[k].matching; + pcbl_refers[pcbl_index++] = operations[0][j].replaces[k].matching(); // Put in the identifier-5 replacement value: - pcbl_refers[pcbl_index++] = operations[0].opers[j].replaces[k].replacement; + pcbl_refers[pcbl_index++] = operations[0][j].replaces[k].replacement; // We need the PHRASE1 for that identifier-3/identifier-5 pair: - pcbl_refers[pcbl_index++] = operations[0].opers[j].replaces[k].before.identifier_4; + pcbl_refers[pcbl_index++] = operations[0][j].replaces[k].before.identifier_4; - pcbl_refers[pcbl_index++] = operations[0].opers[j].replaces[k].after.identifier_4; + pcbl_refers[pcbl_index++] = operations[0][j].replaces[k].after.identifier_4; SHOW_PARSE { @@ -10153,15 +10660,15 @@ inspect_replacing(int backward, { SHOW_PARSE_INDENT } - SHOW_PARSE_FIELD("ID-3 ", operations[0].opers[j].replaces[k].matching.field) - SHOW_PARSE_FIELD(" ID-5 ", operations[0].opers[j].replaces[k].replacement.field) - if( operations[0].opers[j].replaces[k].before.identifier_4.field ) + SHOW_PARSE_FIELD("ID-3 ", operations[0][j].replaces[k].matching().field) + SHOW_PARSE_FIELD(" ID-5 ", operations[0][j].replaces[k].replacement.field) + if( operations[0][j].replaces[k].before.identifier_4.field ) { - SHOW_PARSE_FIELD("before ", operations[0].opers[j].replaces[k].before.identifier_4.field) + SHOW_PARSE_FIELD("before ", operations[0][j].replaces[k].before.identifier_4.field) } - if(operations[0].opers[j].replaces[k].after.identifier_4.field) + if(operations[0][j].replaces[k].after.identifier_4.field) { - SHOW_PARSE_FIELD("after ", operations[0].opers[j].replaces[k].after.identifier_4.field) + SHOW_PARSE_FIELD("after ", operations[0][j].replaces[k].after.identifier_4.field) } SHOW_PARSE_END } @@ -10169,9 +10676,9 @@ inspect_replacing(int backward, } } - //fprintf(stderr, "%s(): %ld %ld\n", __func__, int_index, n_integers); + //fprintf(stderr, "%s: %ld %ld\n", __func__, int_index, n_integers); gcc_assert(int_index == n_integers); - //fprintf(stderr, "%s(): %ld %ld\n", __func__, pcbl_index, n_resolveds); + //fprintf(stderr, "%s: %ld %ld\n", __func__, pcbl_index, n_resolveds); gcc_assert(pcbl_index == n_resolveds); // We have built up an array of integers, and an array of cbl_refer_t. @@ -10186,7 +10693,7 @@ inspect_replacing(int backward, } } - build_array_of_treeplets(1, pcbl_index, pcbl_refers); + build_array_of_treeplets(1, pcbl_index, pcbl_refers.data()); // Do the actual call: gg_call(VOID, @@ -10197,13 +10704,12 @@ inspect_replacing(int backward, } void -parser_inspect(cbl_refer_t identifier_1, +parser_inspect(const cbl_refer_t& identifier_1, bool backward, - size_t n_operations, - cbx_inspect_t<cbl_refer_t>* operations) + cbl_inspect_opers_t& operations) { Analyze(); - gcc_assert(n_operations); + gcc_assert(! operations.empty()); /* Operating philosophy: We are going to minimize the amount of GENERIC tag creation here at compile time, mainly by eliminating @@ -10213,12 +10719,12 @@ parser_inspect(cbl_refer_t identifier_1, if( operations[0].tally.field ) { // This is a FORMAT 1 "TALLYING" - inspect_tally(backward, identifier_1, n_operations, operations); + inspect_tally(backward, identifier_1, operations); } else { // This is a FORMAT 2 "REPLACING" - inspect_replacing(backward, identifier_1, n_operations, operations); + inspect_replacing(backward, identifier_1, operations); } } @@ -10338,7 +10844,7 @@ parser_intrinsic_numval_c( cbl_field_t *f, void parser_intrinsic_subst( cbl_field_t *f, - cbl_refer_t& ref1, + const cbl_refer_t& ref1, size_t argc, cbl_substitute_t * argv ) { @@ -10363,9 +10869,11 @@ parser_intrinsic_subst( cbl_field_t *f, sv_is_i_o = true; store_location_stuff("SUBSTITUTE"); - unsigned char *control_bytes = (unsigned char *)xmalloc(argc * sizeof(unsigned char)); - cbl_refer_t *arg1 = (cbl_refer_t *)xmalloc(argc * sizeof(cbl_refer_t)); - cbl_refer_t *arg2 = (cbl_refer_t *)xmalloc(argc * sizeof(cbl_refer_t)); + unsigned char *control_bytes = + static_cast<unsigned char *>(xmalloc(argc * sizeof(unsigned char))); + gcc_assert(control_bytes); + std::vector<cbl_refer_t> arg1(argc); + std::vector<cbl_refer_t> arg2(argc); for(size_t i=0; i<argc; i++) { @@ -10381,8 +10889,8 @@ parser_intrinsic_subst( cbl_field_t *f, tree control = gg_array_of_bytes(argc, control_bytes); - build_array_of_treeplets(1, argc, arg1); - build_array_of_treeplets(2, argc, arg2); + build_array_of_treeplets(1, argc, arg1.data()); + build_array_of_treeplets(2, argc, arg2.data()); gg_call(VOID, "__gg__substitute", @@ -10396,8 +10904,6 @@ parser_intrinsic_subst( cbl_field_t *f, gg_free(control); - free(arg2); - free(arg1); free(control_bytes); } @@ -10491,7 +10997,7 @@ parser_intrinsic_call_0(cbl_field_t *tgt, { // Pass __gg__when_compiled() the time from right now. struct timespec tp; - uint64_t now = get_time_64(); + uint64_t now = get_time_nanoseconds(); tp.tv_sec = now / 1000000000; tp.tv_nsec = now % 1000000000; @@ -10548,12 +11054,12 @@ parser_intrinsic_call_1( cbl_field_t *tgt, } size_t upper = ref1.field->occurs.bounds.upper ? ref1.field->occurs.bounds.upper : 1; - if( ref1.nsubscript ) + if( ref1.nsubscript() ) { upper = 1; } - if( is_table(ref1.field) && !ref1.nsubscript ) + if( is_table(ref1.field) && !ref1.nsubscript() ) { static tree depending_on = gg_define_variable(LONG, "..pic1_dep"); depending_on_value(depending_on, ref1.field); @@ -10802,7 +11308,9 @@ static void create_lsearch_address_pairs(struct cbl_label_t *name) { // Create the lsearch structure - name->structs.lsearch = (cbl_lsearch_t *)xmalloc(sizeof(cbl_lsearch_t)); + name->structs.lsearch = + static_cast<cbl_lsearch_t *>(xmalloc(sizeof(cbl_lsearch_t))); + gcc_assert(name->structs.lsearch); cbl_lsearch_t *lsearch = name->structs.lsearch; gg_create_goto_pair(&lsearch->addresses.at_exit.go_to, @@ -11052,7 +11560,9 @@ parser_bsearch_start( cbl_label_t* name, } // We need a cbl_bsearch_t structure: - name->structs.bsearch = (cbl_bsearch_t *)xmalloc(sizeof(cbl_bsearch_t)); + name->structs.bsearch = + static_cast<cbl_bsearch_t *>(xmalloc(sizeof(cbl_bsearch_t))); + gcc_assert(name->structs.bsearch); cbl_bsearch_t *bsearch = name->structs.bsearch; // Create the address/label pairs we need @@ -11085,6 +11595,8 @@ parser_bsearch_start( cbl_label_t* name, current = parent_of(current); } + CHECK_FIELD(current); + // There are a number of things we learn from the field "current" // We get the index: @@ -11192,12 +11704,11 @@ parser_bsearch_conditional( cbl_label_t* name ) } bool -is_ascending_key(cbl_refer_t key) +is_ascending_key(const cbl_refer_t& key) { bool retval = true; cbl_field_t *family_tree = key.field; - gcc_assert(family_tree); while( family_tree ) { if( family_tree->occurs.nkey ) @@ -11206,14 +11717,17 @@ is_ascending_key(cbl_refer_t key) } family_tree = parent_of(family_tree); } + + CHECK_FIELD(family_tree); gcc_assert(family_tree->occurs.nkey); + for(size_t i=0; i<family_tree->occurs.nkey; i++) { for(size_t j=0; j<family_tree->occurs.keys[i].field_list.nfield; j++) { size_t index_of_field = family_tree->occurs.keys[i].field_list.fields[j]; - cbl_field_t *key_field = cbl_field_of(symbol_at(index_of_field)); + const cbl_field_t *key_field = cbl_field_of(symbol_at(index_of_field)); if( strcmp( key_field->name, key.field->name ) == 0 ) @@ -11339,8 +11853,7 @@ void parser_sort(cbl_refer_t tableref, bool duplicates, cbl_alphabet_t *alphabet, - size_t nkeys, - cbl_key_t *keys ) + const std::vector<cbl_key_t>& keys ) { Analyze(); SHOW_PARSE @@ -11358,22 +11871,26 @@ parser_sort(cbl_refer_t tableref, gcc_assert(table->var_decl_node); if( !is_table(table) ) { - cbl_internal_error( "%s(): asked to sort %s, but it's not a table", + cbl_internal_error( "%s: asked to sort %s, which is not a table", __func__, tableref.field->name); } - size_t total_keys = 0; - for( size_t i=0; i<nkeys; i++ ) - { - total_keys += keys[i].nfield; - } - cbl_field_t **flattened_fields = (cbl_field_t **)xmalloc(total_keys * sizeof(cbl_field_t *)); - size_t *flattened_ascending = (size_t *)xmalloc(total_keys * sizeof(size_t)); + size_t total_keys = std::accumulate( keys.begin(), keys.end(), 0, + [](size_t n, const cbl_key_t& key ) { + return n + key.fields.size(); + } ); + typedef const cbl_field_t * const_field_t; + const_field_t *flattened_fields = + static_cast<const_field_t *>(xmalloc(total_keys * sizeof(cbl_field_t *))); + gcc_assert(flattened_fields); + size_t *flattened_ascending = + static_cast<size_t *>(xmalloc(total_keys * sizeof(size_t))); + gcc_assert(flattened_ascending); size_t key_index = 0; - for( size_t i=0; i<nkeys; i++ ) + for( size_t i=0; i<keys.size(); i++ ) { - for( size_t j=0; j<keys[i].nfield; j++ ) + for( size_t j=0; j<keys[i].fields.size(); j++ ) { flattened_fields[key_index] = keys[i].fields[j]; flattened_ascending[key_index] = keys[i].ascending ? 1 : 0; @@ -11382,7 +11899,8 @@ parser_sort(cbl_refer_t tableref, } // Create the array of cbl_field_t pointers for the keys - tree all_keys = gg_array_of_field_pointers( total_keys, flattened_fields); + tree all_keys = gg_array_of_field_pointers( total_keys, + const_cast<cbl_field_t**>(flattened_fields)); // Create the array of integers that are the flags for ASCENDING: tree ascending = gg_array_of_size_t( total_keys, flattened_ascending ); @@ -11421,8 +11939,7 @@ void parser_file_sort( cbl_file_t *workfile, bool duplicates, cbl_alphabet_t *alphabet, - size_t nkeys, - cbl_key_t *keys, + const std::vector<cbl_key_t>& keys, size_t ninput, cbl_file_t **inputs, size_t noutput, @@ -11486,7 +12003,7 @@ parser_file_sort( cbl_file_t *workfile, else { // Having both or neither violates SORT syntax - cbl_internal_error("%s(): syntax error -- both (or neither) USING " + cbl_internal_error("%s: syntax error: both (or neither) USING " "and input-proc are specified", __func__); } @@ -11499,18 +12016,22 @@ parser_file_sort( cbl_file_t *workfile, // clone of the code for handling multiple keys, each of which can have // multiple fields. - size_t total_keys = 0; - for( size_t i=0; i<nkeys; i++ ) - { - total_keys += keys[i].nfield; - } - cbl_field_t **flattened_fields = (cbl_field_t **)xmalloc(total_keys * sizeof(cbl_field_t *)); - size_t *flattened_ascending = (size_t *) xmalloc(total_keys * sizeof(size_t)); + size_t total_keys = std::accumulate( keys.begin(), keys.end(), 0, + []( size_t n, const cbl_key_t& key ) { + return n + key.fields.size(); + } ); + typedef const cbl_field_t * const_field_t; + auto flattened_fields + = static_cast<const_field_t *>(xmalloc(total_keys * sizeof(cbl_field_t *))); + gcc_assert(flattened_fields); + size_t *flattened_ascending = + static_cast<size_t *>(xmalloc(total_keys * sizeof(size_t))); + gcc_assert(flattened_ascending); size_t key_index = 0; - for( size_t i=0; i<nkeys; i++ ) + for( size_t i=0; i<keys.size(); i++ ) { - for( size_t j=0; j<keys[i].nfield; j++ ) + for( size_t j=0; j<keys[i].fields.size(); j++ ) { flattened_fields[key_index] = keys[i].fields[j]; flattened_ascending[key_index] = keys[i].ascending ? 1 : 0; @@ -11519,7 +12040,8 @@ parser_file_sort( cbl_file_t *workfile, } // Create the array of cbl_field_t pointers for the keys - tree all_keys = gg_array_of_field_pointers( total_keys, flattened_fields); + tree all_keys = gg_array_of_field_pointers( total_keys, + const_cast<cbl_field_t**>(flattened_fields)); // Create the array of integers that are the flags for ASCENDING: tree ascending = gg_array_of_size_t( total_keys, flattened_ascending ); @@ -11615,7 +12137,7 @@ parser_file_sort( cbl_file_t *workfile, } else { - cbl_internal_error("%s(): syntax error -- both (or neither) GIVING " + cbl_internal_error("%s: syntax error: both (or neither) GIVING " "and output-proc are specified", __func__); } } @@ -11663,7 +12185,9 @@ parser_return_start( cbl_file_t *workfile, cbl_refer_t into ) // We assume that workfile is open. - workfile->addresses = (cbl_sortreturn_t *)xmalloc(sizeof(cbl_sortreturn_t)); + workfile->addresses = static_cast<cbl_sortreturn_t *> + (xmalloc(sizeof(cbl_sortreturn_t))); + gcc_assert(workfile->addresses); gg_create_goto_pair(&workfile->addresses->at_end.go_to, &workfile->addresses->at_end.label); gg_create_goto_pair(&workfile->addresses->not_at_end.go_to, @@ -11821,8 +12345,7 @@ gg_array_of_file_pointers( size_t N, void parser_file_merge( cbl_file_t *workfile, cbl_alphabet_t *alphabet, - size_t nkeys, - cbl_key_t *keys, + const std::vector<cbl_key_t>& keys, size_t ninputs, cbl_file_t **inputs, size_t noutputs, @@ -11845,20 +12368,23 @@ parser_file_merge( cbl_file_t *workfile, build_int_cst_type(INT, file_sequential_e)); } - size_t total_keys = 0; - for( size_t i=0; i<nkeys; i++ ) - { - total_keys += keys[i].nfield; - } - cbl_field_t **flattened_fields - = (cbl_field_t **)xmalloc(total_keys * sizeof(cbl_field_t *)); + size_t total_keys = std::accumulate( keys.begin(), keys.end(), 0, + []( size_t i, const cbl_key_t& key ) { + return i + key.fields.size(); + } ); + typedef const cbl_field_t * const_field_t; + const_field_t *flattened_fields + = static_cast<const_field_t *> + (xmalloc(total_keys * sizeof(cbl_field_t *))); + gcc_assert(flattened_fields); size_t *flattened_ascending - = (size_t *)xmalloc(total_keys * sizeof(size_t)); + = static_cast<size_t *>(xmalloc(total_keys * sizeof(size_t))); + gcc_assert(flattened_ascending); size_t key_index = 0; - for( size_t i=0; i<nkeys; i++ ) + for( size_t i=0; i<keys.size(); i++ ) { - for( size_t j=0; j<keys[i].nfield; j++ ) + for( size_t j=0; j<keys[i].fields.size(); j++ ) { flattened_fields[key_index] = keys[i].fields[j]; flattened_ascending[key_index] = keys[i].ascending ? 1 : 0; @@ -11867,7 +12393,9 @@ parser_file_merge( cbl_file_t *workfile, } // Create the array of cbl_field_t pointers for the keys - tree all_keys = gg_array_of_field_pointers(total_keys, flattened_fields); + tree all_keys = gg_array_of_field_pointers( + total_keys, + const_cast<cbl_field_t**>(flattened_fields)); // Create the array of integers that are the flags for ASCENDING: tree ascending = gg_array_of_size_t(total_keys, flattened_ascending); @@ -11891,6 +12419,9 @@ parser_file_merge( cbl_file_t *workfile, ELSE ENDIF + const cbl_enabled_exceptions_t& + enabled_exceptions( cdf_enabled_exceptions() ); + for(size_t i=0; i<ninputs; i++) { if( process_this_exception(ec_sort_merge_file_open_e) ) @@ -11934,7 +12465,7 @@ parser_file_merge( cbl_file_t *workfile, gg_call(VOID, "__gg__merge_files", gg_get_address_of(workfile->var_decl_node), - build_int_cst_type(SIZE_T, nkeys), + build_int_cst_type(SIZE_T, keys.size()), all_keys, ascending, build_int_cst_type(SIZE_T, ninputs), @@ -12028,7 +12559,7 @@ parser_file_merge( cbl_file_t *workfile, } else { - cbl_internal_error("%s(): syntax error -- both (or neither) " + cbl_internal_error("%s: syntax error: both (or neither) " "files and output-proc are specified", __func__); } } @@ -12048,7 +12579,8 @@ parser_string_overflow( cbl_label_t *name ) */ name->structs.unstring - = (cbl_unstring_t *)xmalloc(sizeof(struct cbl_unstring_t) ); + = static_cast<cbl_unstring_t *>(xmalloc(sizeof(struct cbl_unstring_t))); + gcc_assert(name->structs.unstring); // Set up the address pairs for this clause gg_create_goto_pair(&name->structs.unstring->over.go_to, @@ -12106,9 +12638,9 @@ parser_unstring(cbl_refer_t src, gg_append_statement(not_overflow->structs.unstring->over.label); } - cbl_refer_t *delims = (cbl_refer_t *)xmalloc(ndelimited * sizeof(cbl_refer_t)); - char *alls = (char *)xmalloc(ndelimited+1); - + std::vector<cbl_refer_t> delims(ndelimited); + char *alls = static_cast<char *>(xmalloc(ndelimited+1)); + gcc_assert(alls); for(size_t i=0; i<ndelimited; i++) { delims[i] = delimiteds[i]; @@ -12118,7 +12650,7 @@ parser_unstring(cbl_refer_t src, tree t_alls = build_string_literal(ndelimited+1, alls); - build_array_of_treeplets(1, ndelimited, delims); + build_array_of_treeplets(1, ndelimited, delims.data()); build_array_of_treeplets(2, noutputs, outputs); build_array_of_treeplets(3, noutputs, delimiters); build_array_of_treeplets(4, noutputs, counts); @@ -12142,7 +12674,6 @@ parser_unstring(cbl_refer_t src, NULL_TREE) ); free(alls); - free(delims); if( overflow ) { @@ -12178,12 +12709,12 @@ parser_unstring(cbl_refer_t src, } void -parser_string( cbl_refer_t tgt, - cbl_refer_t pointer, - size_t nsource, - cbl_string_src_t *sources, - cbl_label_t *overflow, - cbl_label_t *not_overflow ) +parser_string(const cbl_refer_t& tgt, + const cbl_refer_t& pointer, + size_t nsource, + cbl_string_src_t *sources, + cbl_label_t *overflow, + cbl_label_t *not_overflow ) { SHOW_PARSE { @@ -12200,7 +12731,8 @@ parser_string( cbl_refer_t tgt, } // We need an array of nsource+1 integers: - size_t *integers = (size_t *)xmalloc((nsource+1)*sizeof(size_t)); + size_t *integers = static_cast<size_t *>(xmalloc((nsource+1)*sizeof(size_t))); + gcc_assert(integers); // Count up how many treeplets we are going to need: size_t cblc_count = 2; // tgt and pointer @@ -12209,7 +12741,7 @@ parser_string( cbl_refer_t tgt, cblc_count += 1 + sources[i].ninput; // 1 for identifier_2 + ninput identifier_1 values; } - cbl_refer_t *refers = (cbl_refer_t *)xmalloc(cblc_count * sizeof(cbl_refer_t)); + std::vector<cbl_refer_t> refers(cblc_count); size_t index_int = 0; size_t index_cblc = 0; @@ -12234,7 +12766,7 @@ parser_string( cbl_refer_t tgt, tree pintegers = build_array_of_size_t( index_int, integers); - build_array_of_treeplets(1, index_cblc, refers); + build_array_of_treeplets(1, index_cblc, refers.data()); tree t_overflow = gg_define_int(); gg_assign(t_overflow, gg_call_expr( INT, @@ -12244,7 +12776,6 @@ parser_string( cbl_refer_t tgt, gg_free(pintegers); free(integers); - free(refers); if( overflow ) { @@ -12292,8 +12823,9 @@ parser_call_exception( cbl_label_t *name ) } name->structs.call_exception - = (cbl_call_exception_t *)xmalloc(sizeof(struct cbl_call_exception_t) ); - + = static_cast<cbl_call_exception_t *> + (xmalloc(sizeof(struct cbl_call_exception_t))); + gcc_assert(name->structs.call_exception); // Set up the address pairs for this clause gg_create_goto_pair(&name->structs.call_exception->over.go_to, &name->structs.call_exception->over.label); @@ -12341,11 +12873,11 @@ static void create_and_call(size_t narg, cbl_ffi_arg_t args[], - tree function_handle, + tree function_pointer, + const char *funcname, tree returned_value_type, cbl_refer_t returned, - cbl_label_t *not_except - ) + cbl_label_t *not_except) { // We have a good function handle, so we are going to create a call tree *arguments = NULL; @@ -12353,8 +12885,10 @@ create_and_call(size_t narg, if(narg) { - arguments = (tree *)xmalloc(2*narg * sizeof(tree)); - allocated = (int * )xmalloc(narg * sizeof(int)); + arguments = static_cast<tree *>(xmalloc(2*narg * sizeof(tree))); + gcc_assert(arguments); + allocated = static_cast<int *>(xmalloc(narg * sizeof(int))); + gcc_assert(allocated); } // Put the arguments onto the "stack" of calling parameters: @@ -12566,28 +13100,67 @@ create_and_call(size_t narg, gg_assign(var_decl_call_parameter_count, build_int_cst_type(INT, narg)); - gg_assign(var_decl_call_parameter_signature, - gg_cast(CHAR_P, function_handle)); + tree call_expr = NULL_TREE; + if( function_pointer ) + { + gg_assign(var_decl_call_parameter_signature, + gg_cast(CHAR_P, function_pointer)); + + call_expr = gg_call_expr_list(returned_value_type, + function_pointer, + narg, + arguments ); + } + else + { + tree fndecl_type = build_varargs_function_type_array( returned_value_type, + 0, // No parameters yet + NULL); // And, hence, no types + + // Fetch the FUNCTION_DECL for that FUNCTION_TYPE + tree function_decl = gg_build_fn_decl(funcname, fndecl_type); + set_call_convention(function_decl, current_call_convention()); + + // Take the address of the function decl: + tree address_of_function = gg_get_address_of(function_decl); - tree call_expr = gg_call_expr_list( returned_value_type, - function_handle, + // Stash that address as the called program's signature: + tree address_as_char_p = gg_cast(CHAR_P, address_of_function); + tree assigment = gg_assign( var_decl_call_parameter_signature, + address_as_char_p); + // The source of the assigment is the second element of a MODIFY_EXPR + parser_call_target( funcname, assigment ); + + // Create the call_expr from that address + call_expr = build_call_array_loc( gg_token_location(), + returned_value_type, + address_of_function, narg, - arguments ); + arguments); + // Among other possibilities, this might be a forward reference to a + // contained function. The name here is "prog2", and ultimately will need + // to be replaced with a call to "prog2.62". So, this call expr goes into + // a list of call expressions whose function_decl targets will be replaced. + parser_call_target( funcname, call_expr ); + } + tree returned_value; + if( returned.field ) { - returned_value = gg_define_variable(returned_value_type); + // Because the CALL had a RETURNING clause, RETURN-CODE doesn't return a + // value. So, we make sure it is zero + //// gg_assign(var_decl_return_code, build_int_cst_type(SHORT, 0)); + + // We expect the return value to be a 64-bit or 128-bit integer. How + // we treat that returned value depends on the target. - // We are expecting a return value of type CHAR_P, SSIZE_T, SIZE_T, - // UINT128 or INT128 + // Pick up that value: + returned_value = gg_define_variable(returned_value_type); push_program_state(); gg_assign(returned_value, gg_cast(returned_value_type, call_expr)); pop_program_state(); - // Because the CALL had a RETURNING clause, RETURN-CODE doesn't return a - // value. So, we make sure it is zero -//// gg_assign(var_decl_return_code, build_int_cst_type(SHORT, 0)); - if( returned_value_type == CHAR_P ) { tree returned_location = gg_define_uchar_star(); @@ -12681,7 +13254,7 @@ create_and_call(size_t narg, else { cbl_internal_error( - "%s(): What in the name of Nero's fiddle are we doing here?", + "%s: What in the name of Nero are we doing here?", __func__); } } @@ -12736,7 +13309,7 @@ parser_call( cbl_refer_t name, SHOW_PARSE_TEXT(" (") for(size_t i=0; i<narg; i++) { - cbl_field_t *p = args[i].refer.field; + const cbl_field_t *p = args[i].refer.field; SHOW_PARSE_FIELD( " ", p) } SHOW_PARSE_TEXT(" )") @@ -12797,39 +13370,49 @@ parser_call( cbl_refer_t name, // We are getting close to establishing the function_type. To do that, // we want to establish the function's return type. -// gg_push_context(); size_t nbytes; tree returned_value_type = tree_type_from_field_type(returned.field, nbytes); - tree function_handle = function_handle_from_name( name, - returned_value_type); - if( (use_static_call() && is_literal(name.field)) - || (name.field && name.field->type == FldPointer) ) + if( use_static_call() && is_literal(name.field) ) { - // If these conditions are true, then we know we have a good - // function_handle, and we don't need to check + // name is a literal create_and_call(narg, args, - function_handle, + NULL_TREE, + name.field->data.initial, returned_value_type, returned, - not_except - ); + not_except); + } + else if( name.field && name.field->type == FldPointer ) + { + tree function_pointer = function_pointer_from_name( name, + returned_value_type); + // This is call-by-pointer; we know function_pointer is good: + create_and_call(narg, + args, + function_pointer, + nullptr, + returned_value_type, + returned, + not_except); } else { + tree function_pointer = function_pointer_from_name( name, + returned_value_type); // We might not have a good handle, so we have to check: - IF( function_handle, + IF( function_pointer, ne_op, - gg_cast(TREE_TYPE(function_handle), null_pointer_node) ) + gg_cast(TREE_TYPE(function_pointer), null_pointer_node) ) { - create_and_call(narg, - args, - function_handle, - returned_value_type, - returned, - not_except - ); + create_and_call(narg, + args, + function_pointer, + nullptr, + returned_value_type, + returned, + not_except); } ELSE { @@ -12877,8 +13460,6 @@ parser_call( cbl_refer_t name, gg_append_statement( not_except->structs.call_exception->bottom.label ); free( not_except->structs.call_exception ); } -// gg_pop_context(); - } // Set global variable to use alternative ENTRY point. @@ -12921,7 +13502,7 @@ parser_bitop( struct cbl_field_t *tgt, // tgt has to be a FldConditional if(tgt && tgt->type != FldConditional) { fprintf(stderr, - "%s(): The target %s has to be a FldConditional, not %s\n", + "%s: The target %s has to be a FldConditional, not %s\n", __func__, tgt->name, cbl_field_type_str(tgt->type)); @@ -12958,7 +13539,7 @@ parser_bitop( struct cbl_field_t *tgt, // tgt has to be a FldConditional case bit_or_op: case bit_xor_op: fprintf(stderr, - "%s(): The %s operation is not valid\n", + "%s: The %s operation is not valid\n", __func__, ops[op]); gcc_unreachable(); @@ -13005,7 +13586,7 @@ parser_bitwise_op(struct cbl_field_t *tgt, if( tgt && !is_valuable(tgt->type) && tgt->type != FldLiteralN) { fprintf(stderr, - "%s(): The target %s has to be is_valuable, not %s\n", + "%s: The target %s has to be is_valuable, not %s\n", __func__, tgt->name, cbl_field_type_str(tgt->type)); @@ -13019,7 +13600,7 @@ parser_bitwise_op(struct cbl_field_t *tgt, case bit_on_op: case bit_off_op: fprintf(stderr, - "%s(): The %s operation is not valid\n", + "%s: The %s operation is not valid\n", __func__, ops[op]); gcc_unreachable(); @@ -13074,10 +13655,10 @@ parser_set_pointers( size_t ntgt, cbl_refer_t *tgts, cbl_refer_t source ) || source.field->type == FldLiteralA)) { // This is something like SET varp TO ENTRY "ref". - tree function_handle = function_handle_from_name(source, + tree function_pointer = function_pointer_from_name(source, COBOL_FUNCTION_RETURN_TYPE); gg_memcpy(qualified_data_location(tgts[i]), - gg_get_address_of(function_handle), + gg_get_address_of(function_pointer), sizeof_pointer); } else @@ -13126,7 +13707,8 @@ typedef struct hier_node hier_node() : our_index(0), common(false), - parent_node(NULL) + parent_node(nullptr), + name(nullptr) {} } hier_node; @@ -13170,7 +13752,7 @@ find_uncles(const hier_node *node, std::vector<const hier_node *> &uncles) } void -parser_program_hierarchy( const struct cbl_prog_hier_t& hier ) +parser_program_hierarchy( const cbl_prog_hier_t& hier ) { Analyze(); /* This routine gets called near the end of every program-id. It keeps @@ -13188,7 +13770,7 @@ parser_program_hierarchy( const struct cbl_prog_hier_t& hier ) } else { - for( size_t i=0; i<hier.nlabel; i++ ) + for( size_t i=0; i<hier.labels.size(); i++ ) { if( i ) { @@ -13243,9 +13825,9 @@ parser_program_hierarchy( const struct cbl_prog_hier_t& hier ) node_map[0] = nodes.back(); // Pass 1: Create a node for every program: - for( size_t i=0; i<hier.nlabel; i++ ) + for( size_t i=0; i<hier.labels.size(); i++ ) { - hier_node *existing_node = find_hier_node(node_map, hier.labels[i].ordinal); + const hier_node *existing_node = find_hier_node(node_map, hier.labels[i].ordinal); gcc_assert( existing_node == NULL ); hier_node *new_node = new hier_node; @@ -13257,7 +13839,7 @@ parser_program_hierarchy( const struct cbl_prog_hier_t& hier ) } // Pass 2: populate each node with their parent and children: - for( size_t i=0; i<hier.nlabel; i++ ) + for( size_t i=0; i<hier.labels.size(); i++ ) { hier_node *child_node = find_hier_node(node_map, hier.labels[i].ordinal); gcc_assert(child_node); @@ -13289,9 +13871,9 @@ parser_program_hierarchy( const struct cbl_prog_hier_t& hier ) // are also accessible by us. Go find them. std::vector<const hier_node *>uncles; find_uncles(nodes[i], uncles); - for( size_t i=0; i<uncles.size(); i++ ) + for( size_t j=0; j<uncles.size(); j++ ) { - const hier_node *uncle = uncles[i]; + const hier_node *uncle = uncles[j]; if( map_of_sets[caller].find(uncle->name) == map_of_sets[caller].end() ) { // We have a COMMON uncle or sibling we haven't seen before. @@ -13329,9 +13911,8 @@ parser_program_hierarchy( const struct cbl_prog_hier_t& hier ) if( callers.find(caller) == callers.end() ) { // We haven't seen this caller before - callers.insert(caller); - char ach[2*sizeof(cbl_name_t)]; + char ach[3*sizeof(cbl_name_t)]; tree names_table_type = build_array_type_nelts(CHAR_P, mol->second.size()+1); sprintf(ach, "..our_accessible_functions_" HOST_SIZE_T_PRINT_DEC, (fmt_size_t)caller); @@ -13358,7 +13939,9 @@ parser_program_hierarchy( const struct cbl_prog_hier_t& hier ) callee != mol->second.end(); callee++ ) { - sprintf(ach, "%s." HOST_SIZE_T_PRINT_DEC, (*callee)->name, + sprintf(ach, + "%s." HOST_SIZE_T_PRINT_DEC, + (*callee)->name, (fmt_size_t)(*callee)->parent_node->our_index); CONSTRUCTOR_APPEND_ELT( CONSTRUCTOR_ELTS(constr_names), @@ -13394,6 +13977,8 @@ parser_program_hierarchy( const struct cbl_prog_hier_t& hier ) (fmt_size_t)caller); tree accessible_programs_decl = gg_trans_unit_var_decl(ach); gg_assign( accessible_programs_decl, gg_get_address_of(the_constructed_table) ); + + callers.insert(caller); } } } @@ -13427,48 +14012,6 @@ parser_set_numeric(struct cbl_field_t *tgt, ssize_t value) NULL_TREE ); } -static void -store_location_stuff(const cbl_name_t statement_name) - { - if( exception_location_active && !current_declarative_section_name() ) - { - // We need to establish some stuff for EXCEPTION- function processing - - gg_assign(var_decl_exception_program_id, - gg_string_literal(current_function->our_unmangled_name)); - - if( strstr(current_function->current_section->label->name, "_implicit") - != current_function->current_section->label->name ) - { - gg_assign(var_decl_exception_section, - gg_string_literal(current_function->current_section->label->name)); - } - else - { - gg_assign(var_decl_exception_section, - gg_cast(build_pointer_type(CHAR_P),null_pointer_node)); - } - - if( strstr(current_function->current_paragraph->label->name, "_implicit") - != current_function->current_paragraph->label->name ) - { - gg_assign(var_decl_exception_paragraph, - gg_string_literal(current_function->current_paragraph->label->name)); - } - else - { - gg_assign(var_decl_exception_paragraph, - gg_cast(build_pointer_type(CHAR_P), null_pointer_node)); - } - - gg_assign(var_decl_exception_source_file, - gg_string_literal(current_filename.back().c_str())); - gg_assign(var_decl_exception_line_number, build_int_cst_type(INT, - CURRENT_LINE_NUMBER)); - gg_assign(var_decl_exception_statement, gg_string_literal(statement_name)); - } - } - void parser_exception_clear() { @@ -13548,9 +14091,17 @@ parser_check_fatal_exception() TRACE1_END } + // Performance note: + // A simple program that does two billion additions of 32-bit binary numbers + // in its innermost loop had an execution time of 19.5 seconds. By putting in + // the if() statement, that was reduced to 3.8 seconds. + + if( cdf_enabled_exceptions().size() || sv_is_i_o ) + { gg_call(VOID, "__gg__check_fatal_exception", NULL_TREE); + } } void @@ -13665,7 +14216,7 @@ hijack_for_development(const char *funcname) // Assume that funcname is lowercase with no hyphens enter_program_common(funcname, funcname); parser_display_literal("You have been hijacked by a program named \"dubner\""); - gg_insert_into_assembler("%s HIJACKED DUBNER CODE START", ASM_COMMENT_START); + gg_insert_into_assemblerf("%s HIJACKED DUBNER CODE START", ASM_COMMENT_START); for(int i=0; i<10; i++) { @@ -13678,12 +14229,12 @@ hijack_for_development(const char *funcname) NULL_TREE); } - gg_insert_into_assembler("%s HIJACKED DUBNER CODE END", ASM_COMMENT_START); + gg_insert_into_assemblerf("%s HIJACKED DUBNER CODE END", ASM_COMMENT_START); gg_return(0); } static void -conditional_abs(tree source, cbl_field_t *field) +conditional_abs(tree source, const cbl_field_t *field) { Analyze(); if( !(field->attr & signable_e) ) @@ -13693,9 +14244,9 @@ conditional_abs(tree source, cbl_field_t *field) } static bool -mh_identical(cbl_refer_t &destref, - cbl_refer_t &sourceref, - TREEPLET &tsource) +mh_identical(const cbl_refer_t &destref, + const cbl_refer_t &sourceref, + const TREEPLET &tsource) { // Check to see if the two variables are identical types, thus allowing // for a simple byte-for-byte copy of the data areas: @@ -13717,7 +14268,7 @@ mh_identical(cbl_refer_t &destref, ) { // The source and destination are identical in type - if( (sourceref.field->attr & intermediate_e) || !symbol_find_odo(sourceref.field) ) + if( !symbol_find_odo(sourceref.field) ) { Analyze(); // Source doesn't have a depending_on clause @@ -13999,8 +14550,8 @@ mh_source_is_literalN(cbl_refer_t &destref, default: cbl_internal_error( - "In parser_move(%s to %s), the move of FldLiteralN to %s " - "hasn't been implemented", + "In %<parser_move(%s to %s)%>, the move of FldLiteralN to %s " + "is unimplemented", sourceref.field->name, destref.field->name, cbl_field_type_str(destref.field->type)); @@ -14028,14 +14579,14 @@ tree float_type_of(int n) } static tree -float_type_of(cbl_field_t *field) +float_type_of(const cbl_field_t *field) { gcc_assert(field->type == FldFloat); return float_type_of(field->data.capacity); } static tree -float_type_of(cbl_refer_t *refer) +float_type_of(const cbl_refer_t *refer) { return float_type_of(refer->field); } @@ -14235,8 +14786,8 @@ mh_dest_is_float( cbl_refer_t &destref, } default: - cbl_internal_error("In mh_dest_is_float(%s to %s), the " - "move of %s to %s hasn't been implemented", + cbl_internal_error("In %<mh_dest_is_float%>(%s to %s), the " + "move of %s to %s is unimplemented", sourceref.field->name, destref.field->name, cbl_field_type_str(sourceref.field->type), @@ -14267,7 +14818,7 @@ picky_memset(tree &dest_p, unsigned char value, size_t length) } static void -picky_memcpy(tree &dest_p, tree &source_p, size_t length) +picky_memcpy(tree &dest_p, const tree &source_p, size_t length) { if( length ) { @@ -14286,10 +14837,10 @@ picky_memcpy(tree &dest_p, tree &source_p, size_t length) } static bool -mh_numeric_display( cbl_refer_t &destref, - cbl_refer_t &sourceref, - TREEPLET &tsource, - tree size_error) +mh_numeric_display( const cbl_refer_t &destref, + const cbl_refer_t &sourceref, + const TREEPLET &tsource, + tree size_error) { bool moved = false; @@ -14775,11 +15326,11 @@ mh_numeric_display( cbl_refer_t &destref, } static bool -mh_little_endian( cbl_refer_t &destref, - cbl_refer_t &sourceref, - TREEPLET &tsource, - bool check_for_error, - tree size_error) +mh_little_endian( const cbl_refer_t &destref, + const cbl_refer_t &sourceref, + const TREEPLET &tsource, + bool check_for_error, + tree size_error) { bool moved = false; @@ -14847,9 +15398,9 @@ mh_little_endian( cbl_refer_t &destref, } static bool -mh_source_is_group( cbl_refer_t &destref, - cbl_refer_t &sourceref, - TREEPLET &tsrc) +mh_source_is_group( const cbl_refer_t &destref, + const cbl_refer_t &sourceref, + const TREEPLET &tsrc) { bool retval = false; if( sourceref.field->type == FldGroup && !(destref.field->attr & rjust_e) ) @@ -14914,7 +15465,7 @@ move_helper(tree size_error, // This is an INT { // We are creating a copy of the original destination in case we clobber it // and have to restore it because of a computational error. - bool first_time = true; + static bool first_time = true; static size_t stash_size = 1024; if( first_time ) { @@ -14939,7 +15490,7 @@ move_helper(tree size_error, // This is an INT //goto dont_be_clever; this will go through to the default. } - if( !moved ) + // if( !moved ) // commented out to quiet cppcheck { moved = mh_source_is_group(destref, sourceref, tsource); } @@ -15008,8 +15559,9 @@ move_helper(tree size_error, // This is an INT if( buffer_size < source_length ) { buffer_size = source_length; - buffer = (char *)xrealloc(buffer, buffer_size); + buffer = static_cast<char *>(xrealloc(buffer, buffer_size)); } + gcc_assert(buffer); if( figconst ) { @@ -15152,7 +15704,7 @@ move_helper(tree size_error, // This is an INT gg_attribute_bit_clear(destref.field, refmod_e); } - moved = true; + // moved = true; // commented out to quiet cppcheck } if( restore_on_error ) @@ -15283,7 +15835,8 @@ binary_initial_from_float128(cbl_field_t *field, int rdigits, FIXED_WIDE_INT(128) i = FIXED_WIDE_INT(128)::from (real_to_integer (&value, &fail, 128), SIGNED); - retval = (char *)xmalloc(field->data.capacity); + retval = static_cast<char *>(xmalloc(field->data.capacity)); + gcc_assert(retval); switch(field->data.capacity) { tree type; @@ -15294,7 +15847,7 @@ binary_initial_from_float128(cbl_field_t *field, int rdigits, case 16: type = build_nonstandard_integer_type ( field->data.capacity * BITS_PER_UNIT, 0); - native_encode_wide_int (type, i, (unsigned char *)retval, + native_encode_wide_int (type, i, PTRCAST(unsigned char, retval), field->data.capacity); break; default: @@ -15424,7 +15977,8 @@ initial_from_initial(cbl_field_t *field) } if( set_return ) { - retval = (char *)xmalloc(field->data.capacity+1); + retval = static_cast<char *>(xmalloc(field->data.capacity+1)); + gcc_assert(retval); memset(retval, const_char, field->data.capacity); retval[field->data.capacity] = '\0'; return retval; @@ -15494,7 +16048,8 @@ initial_from_initial(cbl_field_t *field) case FldNumericDisplay: { - retval = (char *)xmalloc(field->data.capacity); + retval = static_cast<char *>(xmalloc(field->data.capacity)); + gcc_assert(retval); char *pretval = retval; char ach[128]; @@ -15511,7 +16066,7 @@ initial_from_initial(cbl_field_t *field) digits_from_float128(ach, field, field->data.digits, rdigits, value); - char *digits = ach; + const char *digits = ach; if( (field->attr & signable_e) && (field->attr & separate_e) && (field->attr & leading_e ) ) @@ -15574,7 +16129,8 @@ initial_from_initial(cbl_field_t *field) case FldPacked: { - retval = (char *)xmalloc(field->data.capacity); + retval = static_cast<char *>(xmalloc(field->data.capacity)); + gcc_assert(retval); char *pretval = retval; char ach[128]; @@ -15600,7 +16156,7 @@ initial_from_initial(cbl_field_t *field) : field->data.capacity * 2 - 1; digits_from_float128(ach, field, ndigits, rdigits, value); - char *digits = ach; + const char *digits = ach; for(size_t i=0; i<ndigits; i++) { if( !(i & 0x01) ) @@ -15641,7 +16197,8 @@ initial_from_initial(cbl_field_t *field) { if( field->data.initial ) { - retval = (char *)xmalloc(field->data.capacity+1); + retval = static_cast<char *>(xmalloc(field->data.capacity+1)); + gcc_assert(retval); if( field->attr & hex_encoded_e) { memcpy(retval, field->data.initial, field->data.capacity); @@ -15649,7 +16206,7 @@ initial_from_initial(cbl_field_t *field) else { size_t buffer_size = 0; - size_t length = (size_t)field->data.capacity; + size_t length = field->data.capacity; memset(retval, internal_space, length); raw_to_internal(&retval, &buffer_size, field->data.initial, length); if( strlen(field->data.initial) < length ) @@ -15665,25 +16222,23 @@ initial_from_initial(cbl_field_t *field) case FldNumericEdited: { - retval = (char *)xmalloc(field->data.capacity+1); + retval = static_cast<char *>(xmalloc(field->data.capacity+1)); + gcc_assert(retval); if( field->data.initial && field->attr & quoted_e ) { - if( field->attr & quoted_e ) + // What the programmer says the value is, the value becomes, no + // matter how wrong it might be. + size_t length = std::min( (size_t)field->data.capacity, + strlen(field->data.initial)); + for(size_t i=0; i<length; i++) { - // What the programmer says the value is, the value becomes, no - // matter how wrong it might be. - size_t length = std::min( (size_t)field->data.capacity, - strlen(field->data.initial)); - for(size_t i=0; i<length; i++) - { - retval[i] = ascii_to_internal(field->data.initial[i]); - } - if( length < (size_t)field->data.capacity ) - { - memset( retval+length, - internal_space, - (size_t)field->data.capacity - length); - } + retval[i] = ascii_to_internal(field->data.initial[i]); + } + if( length < (size_t)field->data.capacity ) + { + memset( retval+length, + internal_space, + (size_t)field->data.capacity - length); } } else @@ -15703,7 +16258,6 @@ initial_from_initial(cbl_field_t *field) char ach[128]; memset(ach, 0, sizeof(ach)); memset(retval, 0, field->data.capacity); - size_t ndigits = field->data.capacity; if( (field->attr & blank_zero_e) && real_iszero (&value) ) { @@ -15711,6 +16265,7 @@ initial_from_initial(cbl_field_t *field) } else { + size_t ndigits = field->data.capacity; digits_from_float128(ach, field, ndigits, rdigits, value); /* ??? This resides in libgcobol valconv.cc. */ __gg__string_to_numeric_edited( retval, @@ -15725,23 +16280,24 @@ initial_from_initial(cbl_field_t *field) case FldFloat: { - retval = (char *)xmalloc(field->data.capacity); + retval = static_cast<char *>(xmalloc(field->data.capacity)); + gcc_assert(retval); switch( field->data.capacity ) { case 4: value = real_value_truncate (TYPE_MODE (FLOAT), value); native_encode_real (SCALAR_FLOAT_TYPE_MODE (FLOAT), &value, - (unsigned char *)retval, 4, 0); + PTRCAST(unsigned char, retval), 4, 0); break; case 8: value = real_value_truncate (TYPE_MODE (DOUBLE), value); native_encode_real (SCALAR_FLOAT_TYPE_MODE (DOUBLE), &value, - (unsigned char *)retval, 8, 0); + PTRCAST(unsigned char, retval), 8, 0); break; case 16: value = real_value_truncate (TYPE_MODE (FLOAT128), value); native_encode_real (SCALAR_FLOAT_TYPE_MODE (FLOAT128), &value, - (unsigned char *)retval, 16, 0); + PTRCAST(unsigned char, retval), 16, 0); break; } break; @@ -16127,12 +16683,13 @@ psa_FldLiteralA(struct cbl_field_t *field ) // First make room static size_t buffer_size = 1024; - static char *buffer = (char *)xmalloc(buffer_size); + static char *buffer = static_cast<char *>(xmalloc(buffer_size)); if( buffer_size < field->data.capacity+1 ) { buffer_size = field->data.capacity+1; - buffer = (char *)xrealloc(buffer, buffer_size); + buffer = static_cast<char *>(xrealloc(buffer, buffer_size)); } + gcc_assert(buffer); cbl_figconst_t figconst = cbl_figconst_of( field->data.initial ); gcc_assert(figconst == normal_value_e); @@ -16153,14 +16710,28 @@ psa_FldLiteralA(struct cbl_field_t *field ) // We have the original nul-terminated text at data.initial. We have a // copy of it in buffer[] in the internal codeset. + static const char name_base[] = "_literal_a_"; + // We will reuse a single static structure for each string static std::unordered_map<std::string, int> seen_before; + std::string field_string(buffer); + +#if 0 + /* This code is suppoed to re-use literals, and seems to work just fine in + x86_64-linux and on an Apple aarch64 M1 Macbook Pro. But on an M1 + mini, using -Os optimization, attempts were made in the generated + assembly language to define _literal_a_1 more than once. + + I didn't know how to try to track this one down, so I decided simply to + punt by removing the code. + + I am leaving the code here because of a conviction that it someday should + be tracked down. */ + std::unordered_map<std::string, int>::const_iterator it = seen_before.find(field_string); - static const char name_base[] = "_literal_a_"; - if( it != seen_before.end() ) { // We've seen that string before. @@ -16173,9 +16744,11 @@ psa_FldLiteralA(struct cbl_field_t *field ) vs_file_static); } else +#endif { // We have not seen that string before - static int nvar = 1; + static int nvar = 0; + nvar += 1; seen_before[field_string] = nvar; char ach[32]; @@ -16195,7 +16768,6 @@ psa_FldLiteralA(struct cbl_field_t *field ) TREE_USED(field->var_decl_node) = 1; TREE_STATIC(field->var_decl_node) = 1; DECL_PRESERVE_P (field->var_decl_node) = 1; - nvar += 1; } // TRACE1 // { @@ -16216,6 +16788,8 @@ parser_local_add(struct cbl_field_t *new_var ) SHOW_PARSE_END } + CHECK_FIELD(new_var); + IF( member(new_var->var_decl_node, "data"), ne_op, gg_cast(UCHAR_P, null_pointer_node) ) @@ -16268,12 +16842,12 @@ parser_symbol_add(struct cbl_field_t *new_var ) { do { - fprintf(stderr, "( %d ) %s():", CURRENT_LINE_NUMBER, __func__); + fprintf(stderr, "( %d ) %s:", CURRENT_LINE_NUMBER, __func__); } while(0); - fprintf(stderr, " %2.2d %s<%s> off:" HOST_SIZE_T_PRINT_DEC " " - "msiz:%d cap:%d dig:%d rdig:%d attr:0x" HOST_SIZE_T_PRINT_HEX_PURE " loc:%p", + fprintf(stderr, " %2.2u %s<%s> off:" HOST_SIZE_T_PRINT_UNSIGNED " " + "msiz:%u cap:%u dig:%u rdig:%d attr:0x" HOST_SIZE_T_PRINT_HEX_PURE " loc:%p", new_var->level, new_var->name, cbl_field_type_str(new_var->type), @@ -16283,14 +16857,14 @@ parser_symbol_add(struct cbl_field_t *new_var ) new_var->data.digits, new_var->data.rdigits, (fmt_size_t)new_var->attr, - (void*)new_var); + static_cast<void*>(new_var)); if( is_table(new_var) ) { fprintf(stderr," OCCURS:" HOST_SIZE_T_PRINT_DEC, (fmt_size_t)new_var->occurs.ntimes()); } - cbl_field_t *parent = parent_of(new_var); + const cbl_field_t *parent = parent_of(new_var); if( parent ) { fprintf(stderr, @@ -16304,7 +16878,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) size_t parent_index = new_var->parent; if( parent_index ) { - symbol_elem_t *e = symbol_at(parent_index); + const symbol_elem_t *e = symbol_at(parent_index); if( e->type == SymFile ) { fprintf(stderr, @@ -16323,7 +16897,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) { fprintf(stderr, " redefines:(%p)%s", - (void*)symbol_redefines(new_var), + static_cast<void*>(symbol_redefines(new_var)), symbol_redefines(new_var)->name); } @@ -16406,7 +16980,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) // Make sure we have a new variable to work with. if( !new_var ) { - cbl_internal_error("parser_symbol_add() was called with a NULL new_var\n"); + cbl_internal_error("%<parser_symbol_add()%> was called with a NULL %<new_var%>"); } TRACE1 @@ -16423,10 +16997,12 @@ parser_symbol_add(struct cbl_field_t *new_var ) TRACE1_TEXT_ABC(" (", cbl_field_type_str(new_var->type) ,")") if( new_var->type == FldLiteralN) { + const void *p1 = (new_var->data.initial); + const long *pldata = static_cast<const long *>(p1); + long ldata = *pldata; gg_fprintf( trace_handle, 1, " [%ld]", - build_int_cst_type(LONG, - *(const long *)new_var->data.initial)); + build_int_cst_type(LONG, ldata)); } TRACE1_END } @@ -16434,7 +17010,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) if( is_table(new_var) && new_var->data.capacity == 0) { cbl_internal_error( - "%s(): %2.2d %s is a table, but it improperly has a capacity of zero", + "%s: %d %s is a table, but it improperly has a capacity of zero", __func__, new_var->level, new_var->name); @@ -16474,23 +17050,20 @@ parser_symbol_add(struct cbl_field_t *new_var ) if( ancestor == new_var ) { - cbl_internal_error("parser_symbol_add(): %s is its own ancestor", - new_var->name); + cbl_internal_error("%s: %s is its own ancestor", __func__, new_var->name); } if( !ancestor && (new_var->level > LEVEL01 && new_var->level <= LEVEL49 ) ) { - cbl_internal_error("parser_symbol_add(): %2.2d %s has null ancestor", - new_var->level, - new_var->name); + cbl_internal_error("%s: %d %qs has NULL ancestor", __func__, + new_var->level, new_var->name); } // new_var's var_decl_node should be NULL at this point if( new_var->var_decl_node ) { - cbl_internal_error( "parser_symbol_add( %s ) improperly has a non-null " - "var_decl_node\n", - new_var->name); + cbl_internal_error( "%s(%s) improperly has a non-null " + "%<var_decl_node%>", __func__, new_var->name); } switch( new_var->type ) @@ -16684,7 +17257,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) && new_var->type != FldLiteralN && new_var->type != FldLiteralA ) { - cbl_internal_error( "%s(): %2.2d %s<%s> improperly has a data.capacity of zero", + cbl_internal_error( "%s: %d %s<%s> improperly has a data.capacity of zero", __func__, new_var->level, new_var->name, @@ -16704,10 +17277,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) if( *external_record_base ) { char achDataName[256]; - if( *external_record_base ) - { - sprintf(achDataName, "__%s_vardata", external_record_base); - } + sprintf(achDataName, "__%s_vardata", external_record_base); tree array_type = build_array_type_nelts(UCHAR, new_var->data.capacity); new_var->data_decl_node = gg_define_variable( array_type, @@ -16754,12 +17324,10 @@ parser_symbol_add(struct cbl_field_t *new_var ) if( !bytes_to_allocate ) { - fprintf(stderr, - "bytes_to_allocate is zero for %s (symbol number " - HOST_SIZE_T_PRINT_DEC ")\n", - new_var->name, - (fmt_size_t)new_var->our_index); - gcc_assert(bytes_to_allocate); + cbl_internal_error( "%<bytes_to_allocate%> is zero for %s (symbol number " + HOST_SIZE_T_PRINT_DEC ")", + new_var->name, + (fmt_size_t)new_var->our_index); } if( new_var->type == FldIndex && new_var->level == 0 ) diff --git a/gcc/cobol/genapi.h b/gcc/cobol/genapi.h index 26944572d629..b41b906aa697 100644 --- a/gcc/cobol/genapi.h +++ b/gcc/cobol/genapi.h @@ -7,7 +7,7 @@ * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above + * * Redistributions in binary form must reproduce the above` * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. @@ -52,17 +52,26 @@ void parser_division( cbl_division_t division, void parser_enter_program(const char *funcname, bool is_function, int *retval); void parser_leave_program(); -void parser_accept( cbl_refer_t refer, special_name_t special_e); +void parser_accept( const cbl_refer_t &refer, + special_name_t special_e, + cbl_label_t *error, + cbl_label_t *not_error ); void parser_accept_exception( cbl_label_t *name ); void parser_accept_exception_end( cbl_label_t *name ); -void parser_accept_envar( cbl_refer_t refer, cbl_refer_t envar, - cbl_label_t *error, cbl_label_t *not_error ); -void parser_set_envar( cbl_refer_t envar, cbl_refer_t refer ); +void parser_accept_under_discussion(struct cbl_refer_t tgt, special_name_t special, + cbl_label_t *error, cbl_label_t *not_error ); +void parser_accept_envar( const cbl_refer_t &refer, + const cbl_refer_t &envar, + cbl_label_t *error, + cbl_label_t *not_error ); +void parser_set_envar( const cbl_refer_t &envar, const cbl_refer_t &refer ); -void parser_accept_command_line( cbl_refer_t tgt, cbl_refer_t src, - cbl_label_t *error, cbl_label_t *not_error ); -void parser_accept_command_line_count( cbl_refer_t tgt ); +void parser_accept_command_line(const cbl_refer_t &tgt, + const cbl_refer_t &src, + cbl_label_t *error, + cbl_label_t *not_error ); +void parser_accept_command_line_count( const cbl_refer_t &tgt ); void parser_accept_date_yymmdd( cbl_field_t *tgt ); void parser_accept_date_yyyymmdd( cbl_field_t *tgt ); @@ -86,8 +95,7 @@ parser_add( size_t nC, cbl_num_result_t *C, size_t nA, cbl_refer_t *A, cbl_arith_format_t format, cbl_label_t *error, - cbl_label_t *not_error, - void *compute_error = NULL); // This has to be cast to a tree pointer to int + cbl_label_t *not_error, void *compute_error = NULL); // This has to be cast to a tree pointer to int void parser_arith_error( cbl_label_t *name ); void parser_arith_error_end( cbl_label_t *name ); @@ -119,26 +127,26 @@ parser_divide(size_t nC, cbl_num_result_t *C, void *compute_error = NULL); // This has to be cast to a tree pointer to int void -parser_add( struct cbl_refer_t tgt, - struct cbl_refer_t a, struct cbl_refer_t b, +parser_add( const cbl_refer_t& tgt, + const cbl_refer_t& a, const cbl_refer_t& b, enum cbl_round_t = truncation_e ); void -parser_subtract( struct cbl_refer_t tgt, - struct cbl_refer_t a, struct cbl_refer_t b, +parser_subtract( const cbl_refer_t& tgt, + const cbl_refer_t& a, const cbl_refer_t& b, enum cbl_round_t = truncation_e ); void -parser_multiply( struct cbl_refer_t tgt, - struct cbl_refer_t a, struct cbl_refer_t b, +parser_multiply( const cbl_refer_t& tgt, + const cbl_refer_t& a, const cbl_refer_t& b, enum cbl_round_t = truncation_e ); void -parser_divide( struct cbl_refer_t quotient, - struct cbl_refer_t divisor, - struct cbl_refer_t dividend, +parser_divide( const cbl_refer_t& quotient, + const cbl_refer_t& divisor, + const cbl_refer_t& dividend, enum cbl_round_t = truncation_e, - struct cbl_refer_t remainder = cbl_refer_t()); + const cbl_refer_t& remainder = cbl_refer_t()); // void // parser_exponentiation( cbl_refer_t cref, @@ -174,7 +182,8 @@ parser_bitwise_op(struct cbl_field_t *tgt, void parser_classify( struct cbl_field_t *tgt, - struct cbl_refer_t srca, enum classify_t type ); + const struct cbl_refer_t &srca, + enum classify_t type ); void parser_op( struct cbl_refer_t cref, @@ -225,7 +234,7 @@ parser_perform_conditional_end( struct cbl_perform_tgt_t *tgt ); * For an in-line loop body, tgt->from.type == LblLoop, and tgt->to is NULL. */ void -parser_perform( struct cbl_perform_tgt_t *tgt, struct cbl_refer_t N ); +parser_perform( const cbl_perform_tgt_t *tgt, cbl_refer_t N ); /* * A simple UNTIL loop uses 1 varys element. For VARY loops, the @@ -253,18 +262,23 @@ parser_program_hierarchy( const struct cbl_prog_hier_t& hier ); void parser_end_program(const char *name=NULL); -void parser_sleep(cbl_refer_t seconds); +void parser_sleep(const cbl_refer_t &seconds); -void parser_exit( cbl_refer_t refer, ec_type_t = ec_none_e ); +void parser_exit( const cbl_refer_t& refer, ec_type_t = ec_none_e ); void parser_exit_section(void); void parser_exit_paragraph(void); void parser_exit_perform( struct cbl_perform_tgt_t *tgt, bool cycle ); void parser_exit_program(void); // exits back to COBOL only, else continue +void +parser_exhibit( bool changed, bool named, + const std::vector<cbl_refer_t> &args ); void parser_display( const struct cbl_special_name_t *upon, - struct cbl_refer_t args[], size_t n, - bool advance = DISPLAY_ADVANCE ); + const std::vector<cbl_refer_t> &args, + bool advance = DISPLAY_ADVANCE, + const cbl_label_t *not_error = nullptr, + const cbl_label_t *compute_error = nullptr ); void parser_display_field(cbl_field_t *fld); @@ -297,10 +311,10 @@ void parser_symbol_add(struct cbl_field_t *field); void -parser_initialize(struct cbl_refer_t refer, bool like_parser_symbol_add=false); +parser_initialize(const cbl_refer_t& refer, bool like_parser_symbol_add=false); void -parser_initialize_programs(size_t nprog, struct cbl_refer_t *progs); +parser_initialize_programs(size_t nprog, const struct cbl_refer_t *progs); void parser_label_label( struct cbl_label_t *label ); @@ -315,7 +329,7 @@ void parser_alter( cbl_perform_tgt_t *tgt ); void -parser_set_conditional88( struct cbl_refer_t tgt, bool which_way ); +parser_set_conditional88( const cbl_refer_t& tgt, bool which_way ); void parser_set_numeric(struct cbl_field_t *tgt, ssize_t value); @@ -406,14 +420,12 @@ void parser_sort(cbl_refer_t table, bool duplicates, cbl_alphabet_t *alphabet, - size_t nkey, - cbl_key_t *keys ); + const std::vector<cbl_key_t>& keys ); void parser_file_sort( cbl_file_t *file, bool duplicates, cbl_alphabet_t *alphabet, - size_t nkey, - cbl_key_t *keys, + const std::vector<cbl_key_t>& keys, size_t ninput, cbl_file_t **inputs, size_t noutput, @@ -423,8 +435,7 @@ parser_file_sort( cbl_file_t *file, void parser_file_merge( cbl_file_t *file, cbl_alphabet_t *alphabet, - size_t nkey, - cbl_key_t *keys, + const std::vector<cbl_key_t>& keys, size_t ninput, cbl_file_t **inputs, size_t noutput, @@ -450,7 +461,7 @@ parser_intrinsic_numval_c( cbl_field_t *f, void parser_intrinsic_subst( cbl_field_t *f, - cbl_refer_t& ref1, + const cbl_refer_t& ref1, size_t argc, cbl_substitute_t * argv ); @@ -492,12 +503,12 @@ void parser_string_overflow_end( cbl_label_t *name ); void -parser_string( cbl_refer_t tgt, - cbl_refer_t pointer, - size_t nsource, - cbl_string_src_t *sources, - cbl_label_t *overflow, - cbl_label_t *not_overflow ); +parser_string(const cbl_refer_t& tgt, + const cbl_refer_t& pointer, + size_t nsource, + cbl_string_src_t *sources, + cbl_label_t *overflow, + cbl_label_t *not_overflow ); void parser_unstring( cbl_refer_t src, @@ -552,7 +563,7 @@ void parser_entry_activate( size_t iprog, const cbl_label_t *declarative ); void parser_entry( cbl_field_t *name, size_t narg = 0, cbl_ffi_arg_t args[] = NULL); -bool is_ascending_key(cbl_refer_t key); +bool is_ascending_key(const cbl_refer_t& key); void register_main_switch(const char *main_string); diff --git a/gcc/cobol/gengen.cc b/gcc/cobol/gengen.cc index a5f143cf2342..3ad33442119c 100644 --- a/gcc/cobol/gengen.cc +++ b/gcc/cobol/gengen.cc @@ -107,8 +107,6 @@ // Don't like it? Cry me a river. static const int ARG_LIMIT = 512; -static int sv_current_line_number; - // These are globally useful constants tree char_nodes[256]; @@ -136,6 +134,14 @@ tree bool_false_node; struct cbl_translation_unit_t gg_trans_unit; +// This set is used to prevent duplicated top-level program names from breaking +// the compiler when a source code module makes that mistake. +static std::unordered_set<std::string> names_we_have_seen; + +// This vector is used to process the function_decls at the point we leave +// the file. +static std::vector<tree> finalized_function_decls; + void gg_build_translation_unit(const char *filename) { @@ -257,14 +263,6 @@ gg_append_var_decl(tree var_decl) } } -location_t -location_from_lineno() - { - location_t loc; - loc = linemap_line_start(line_table, sv_current_line_number, 0); - return loc; - } - void gg_append_statement(tree stmt) { @@ -354,13 +352,12 @@ adjust_for_type(tree type) return retval; } -static char * -show_type(tree type) +gg_show_type(tree type) { if( !type ) { - cbl_internal_error("The given type is not NULL, and that's just not fair"); + cbl_internal_error("The given type is NULL, and that is just not fair"); } if( DECL_P(type) ) @@ -369,14 +366,17 @@ show_type(tree type) } if( !TYPE_P(type) ) { - cbl_internal_error("The given type is not a DECL or a TYPE"); + cbl_internal_error("The given type is not a declaration or a TYPE"); } - static char ach[1024]; + static char ach[1100]; + static char ach2[1024]; + static char ach3[1024]; switch( TREE_CODE(type) ) { case POINTER_TYPE: - sprintf(ach, "POINTER"); + strcpy(ach2, gg_show_type(TREE_TYPE(type))); + sprintf(ach, "POINTER to %s", ach2); break; case VOID_TYPE: @@ -405,11 +405,8 @@ show_type(tree type) break; case FUNCTION_TYPE: - sprintf(ach, "FUNCTION"); -// sprintf(ach, -// "%3ld-bit %s INT", -// TREE_INT_CST_LOW(TYPE_SIZE(type)), -// (TYPE_UNSIGNED(type) ? "unsigned" : " signed")); + strcpy(ach3, gg_show_type(TREE_TYPE(type))); + sprintf(ach, "FUNCTION returning %s", ach3); break; default: @@ -419,7 +416,7 @@ show_type(tree type) return ach; } -void +tree gg_assign(tree dest, const tree source) { // This does the equivalent of a C/C++ "dest = source". When X1 is set, it @@ -430,6 +427,7 @@ gg_assign(tree dest, const tree source) // This routine also provides for the possibility that the assignment is // for a source that is a function invocation, as in // "dest = function_call()" + tree stmt = NULL_TREE; saw_pointer = false; tree dest_type = adjust_for_type(TREE_TYPE(dest)); @@ -452,11 +450,11 @@ gg_assign(tree dest, const tree source) if( okay ) { - tree stmt = build2_loc( location_from_lineno(), - MODIFY_EXPR, - TREE_TYPE(dest), - dest, - source); + stmt = build2_loc(gg_token_location(), + MODIFY_EXPR, + TREE_TYPE(dest), + dest, + source); gg_append_statement(stmt); } else @@ -465,20 +463,25 @@ gg_assign(tree dest, const tree source) // the same. This is a compilation-time error, since we want the caller to // have sorted the types out explicitly. If we don't throw an error here, // the gimple reduction will do so. Better to do it here, when we know - // where we are. - dbgmsg("Inefficient assignment"); - if(DECL_P(dest) && DECL_NAME(dest)) - { - dbgmsg(" Destination is %s", IDENTIFIER_POINTER(DECL_NAME(dest))); - } - dbgmsg(" dest type is %s%s", show_type(dest_type), p2 ? "_P" : ""); - if(DECL_P(source) && DECL_NAME(source)) + // where we are.S + static const int debugging = 1; + if( debugging ) { - dbgmsg(" Source is %s", IDENTIFIER_POINTER(DECL_NAME(source))); + fprintf(stderr, "Inefficient assignment\n"); + if(DECL_P(dest) && DECL_NAME(dest)) + { + fprintf(stderr, " Destination is %s\n", IDENTIFIER_POINTER(DECL_NAME(dest))); + } + fprintf(stderr, " dest type is %s%s\n", gg_show_type(dest_type), p2 ? "_P" : ""); + if(DECL_P(source) && DECL_NAME(source)) + { + fprintf(stderr, " Source is %s\n", IDENTIFIER_POINTER(DECL_NAME(source))); + } + fprintf(stderr, " source type is %s%s\n", gg_show_type(source_type), p2 ? "_P" : ""); } - dbgmsg(" source type is %s%s", show_type(source_type), p2 ? "_P" : ""); - gcc_unreachable(); + cbl_internal_error("Attempting an assignment of differing types."); } + return stmt; } tree @@ -520,8 +523,7 @@ gg_find_field_in_struct(const tree base, const char *field_name) if( !field_decl ) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### Somebody asked for the field %s.%s, which doesn't exist", + yywarn("Somebody asked for the field %s.%s, which does not exist", IDENTIFIER_POINTER(DECL_NAME(base)), field_name); gcc_unreachable(); @@ -612,7 +614,7 @@ gg_add_field_to_structure(const tree type_of_field, const char *name_of_field, t tree id_of_field = get_identifier (name_of_field); // Create the new field: - tree new_field_decl = build_decl( location_from_lineno(), + tree new_field_decl = build_decl( gg_token_location(), FIELD_DECL, id_of_field, type_of_field); @@ -889,7 +891,7 @@ gg_create_assembler_name(const char *cobol_name) static char * gg_unique_in_function(const char *var_name, gg_variable_scope_t vs_scope) { - char *retval = (char *)xmalloc(strlen(var_name)+32); + char *retval = static_cast<char *>(xmalloc(strlen(var_name)+32)); if( (vs_scope == vs_stack || vs_scope == vs_static) ) { sprintf(retval, "%s." HOST_SIZE_T_PRINT_DEC, var_name, @@ -933,7 +935,7 @@ gg_declare_variable(tree type_decl, // causes the storage to be allocated. // It is routine to let the compiler assign names to stack variables. The - // assembly code doesn't use names for variables on the stack; they are + // assembly code does not use names for variables on the stack; they are // referenced by offsets to the base pointer. But static variables have to // have names, and there are places in my code generation -- Lord only knows // why -- where I didn't give the variables explicit names. We remedy that @@ -1024,10 +1026,7 @@ gg_declare_variable(tree type_decl, break; } DECL_INITIAL(var_decl) = initial_value; - if( unique_name ) - { - free(unique_name); - } + free(unique_name); return var_decl; } @@ -1042,7 +1041,7 @@ gg_define_from_declaration(tree var_decl) { // Having made sure the chain of variable declarations is nicely started, // it's time to actually define the storage with a decl_expression: - tree stmt = build1_loc (location_from_lineno(), + tree stmt = build1_loc (gg_token_location(), DECL_EXPR, TREE_TYPE(var_decl), var_decl); @@ -1773,7 +1772,7 @@ gg_build_relational_expression(tree operand_a, compare = LE_EXPR; break; } - tree relational_expression = build2_loc(location_from_lineno(), + tree relational_expression = build2_loc(gg_token_location(), compare, boolean_type_node, operand_a, @@ -1890,7 +1889,7 @@ gg_create_goto_pair(tree *goto_expr, void gg_goto_label_decl(tree label_decl) { - tree goto_expr = build1_loc( location_from_lineno(), + tree goto_expr = build1_loc( gg_token_location(), GOTO_EXPR, void_type_node, label_decl); @@ -1937,7 +1936,7 @@ gg_create_goto_pair(tree *goto_expr, tree *label_expr, const char *name) void gg_goto(tree var_decl_pointer) { - tree go_to = build1_loc(location_from_lineno(), + tree go_to = build1_loc(gg_token_location(), GOTO_EXPR, void_type_node, var_decl_pointer); @@ -2161,8 +2160,7 @@ gg_printf(const char *format_string, ...) { if(nargs >= ARG_LIMIT) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### You *must* be joking!"); + yywarn("You *must* be joking"); gcc_unreachable(); } @@ -2170,10 +2168,8 @@ gg_printf(const char *format_string, ...) { // Warning: This test is not completely reliable, because a garbage // byte could have a valid TREE_CODE. But it does help. - yywarn("You nitwit!"); - yywarn("You forgot to put a NULL_TREE at the end of a " - "gg_printf() again!"); - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); + yywarn("You forgot to put a %<NULL_TREE%> at the end of a " + "%<gg_printf()%> again"); gcc_unreachable(); } @@ -2188,7 +2184,7 @@ gg_printf(const char *format_string, ...) function = gg_get_function_address(INT, "__gg__fprintf_stderr"); } - tree stmt = build_call_array_loc (location_from_lineno(), + tree stmt = build_call_array_loc (gg_token_location(), INT, function, nargs, @@ -2219,8 +2215,7 @@ gg_fprintf(tree fd, int nargs, const char *format_string, ...) { if(argc >= ARG_LIMIT) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### You *must* be joking!"); + yywarn("You *must* be joking"); gcc_unreachable(); } @@ -2236,7 +2231,7 @@ gg_fprintf(tree fd, int nargs, const char *format_string, ...) function = gg_get_function_address(INT, "sprintf"); } - tree stmt = build_call_array_loc (location_from_lineno(), + tree stmt = build_call_array_loc (gg_token_location(), INT, function, argc, @@ -2283,7 +2278,7 @@ void gg_memset(tree dest, const tree value, tree size) { tree the_call = - build_call_expr_loc(location_from_lineno(), + build_call_expr_loc(gg_token_location(), builtin_decl_explicit (BUILT_IN_MEMSET), 3, dest, @@ -2297,7 +2292,7 @@ gg_memchr(tree buf, tree ch, tree length) { tree the_call = fold_convert( pvoid_type_node, - build_call_expr_loc(location_from_lineno(), + build_call_expr_loc(gg_token_location(), builtin_decl_explicit (BUILT_IN_MEMCHR), 3, buf, @@ -2312,7 +2307,7 @@ void gg_memcpy(tree dest, const tree src, tree size) { tree the_call = build_call_expr_loc( - location_from_lineno(), + gg_token_location(), builtin_decl_explicit (BUILT_IN_MEMCPY), 3, dest, @@ -2327,7 +2322,7 @@ void gg_memmove(tree dest, const tree src, tree size) { tree the_call = build_call_expr_loc( - location_from_lineno(), + gg_token_location(), builtin_decl_explicit (BUILT_IN_MEMMOVE), 3, dest, @@ -2360,7 +2355,7 @@ void gg_strcpy(tree dest, tree src) { tree the_call = - build_call_expr_loc(location_from_lineno(), + build_call_expr_loc(gg_token_location(), builtin_decl_explicit (BUILT_IN_STRCPY), 2, dest, @@ -2373,7 +2368,7 @@ gg_strcmp(tree A, tree B) { tree the_call = fold_convert( integer_type_node, - build_call_expr_loc(location_from_lineno(), + build_call_expr_loc(gg_token_location(), builtin_decl_explicit (BUILT_IN_STRCMP), 2, A, @@ -2405,7 +2400,7 @@ gg_strncmp(tree char_star_A, tree char_star_B, tree size_t_N) { tree the_call = fold_convert( integer_type_node, - build_call_expr_loc(location_from_lineno(), + build_call_expr_loc(gg_token_location(), builtin_decl_explicit (BUILT_IN_STRNCMP), 3, char_star_A, @@ -2436,7 +2431,7 @@ gg_return(tree operand) { // When there is no operand, or if the function result is void, then // we just generate a return_expr. - stmt = build1_loc(location_from_lineno(), RETURN_EXPR, void_type_node, NULL_TREE); + stmt = build1_loc(gg_token_location(), RETURN_EXPR, void_type_node, NULL_TREE); } else { @@ -2446,7 +2441,7 @@ gg_return(tree operand) function_type, DECL_RESULT(current_function->function_decl), gg_cast(function_type, operand)); - stmt = build1_loc(location_from_lineno(), RETURN_EXPR, void_type_node, modify); + stmt = build1_loc(gg_token_location(), RETURN_EXPR, void_type_node, modify); } gg_append_statement(stmt); } @@ -2454,7 +2449,7 @@ gg_return(tree operand) void chain_parameter_to_function(tree function_decl, const tree param_type, const char *name) { - tree parm = build_decl (location_from_lineno(), + tree parm = build_decl (gg_token_location(), PARM_DECL, get_identifier (name), param_type); @@ -2472,171 +2467,113 @@ chain_parameter_to_function(tree function_decl, const tree param_type, const ch } } -void -gg_modify_function_type(tree function_decl, tree return_type) - { - tree fndecl_type = build_varargs_function_type_array( return_type, - 0, // No parameters yet - NULL); // And, hence, no types - TREE_TYPE(function_decl) = fndecl_type; - tree resdecl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, return_type); - DECL_CONTEXT (resdecl) = function_decl; - DECL_RESULT (function_decl) = resdecl; - } +/* There are five ways that we use function_decls: -tree -gg_define_function_with_no_parameters(tree return_type, - const char *funcname, - const char *unmangled_name) - { - // This routine builds a function_decl, puts it on the stack, and - // gives it a context. + 1, We define a main() entry point. + 2. We call a function that turns out to be a static "t" function local to the source code module. + 3. We define an global "T" function, and possibly call it later. + 4. We call a function that we define later in the source code module. + 5. We call a function that ends up being an extern that is not defined in the source code module. - // At this time we don't know how many parameters this function expects, so - // we set things up and we'll tack on the parameters later. + Cases 3. and 4. turn out to require the same flags. Here are the combinations of + flags that are required for each flavor of function_decl. This was empirically + determind by compiling a C++ program with sample code for each type. - // Create the FUNCTION_TYPE for that array: - // int nparams = 1; - // tree types[1] = {VOID_P}; - // const char *names[1] = {"_p1"}; + | addressable | used | nothrow | static | external | public | no_instrument +main | | | | X | | X | X +local | X | X | X | X | | | X +external defined inside | X | X | X | X | | X | X +external defined elsewhere | X | X | | | X | X | - // tree fndecl_type = build_varargs_function_type_array( return_type, - // nparams, - // types); +*/ - tree fndecl_type = build_varargs_function_type_array( return_type, - 0, // No parameters yet - NULL); // And, hence, no types - // Create the FUNCTION_DECL for that FUNCTION_TYPE - tree function_decl = build_fn_decl (funcname, fndecl_type); +static std::unordered_map<std::string, tree> map_of_function_decls; - // Some of this stuff is magical, and is based on compiling C programs - // and just mimicking the results. - TREE_ADDRESSABLE(function_decl) = 1; - TREE_STATIC(function_decl) = 1; - DECL_EXTERNAL (function_decl) = 0; - DECL_PRESERVE_P (function_decl) = 0; - DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(function_decl) = 1; - DECL_ARTIFICIAL(function_decl) = 0; - TREE_NOTHROW(function_decl) = 0; - TREE_USED(function_decl) = 1; - - // This code makes COBOL nested programs actual visible on the - // source code "trans_unit_decl" level, but with non-public "static" - // visibility. - if( gg_trans_unit.function_stack.size() == 0 ) - { - // gg_trans_unit.function_stack is empty, so our context is - // the compilation module, and we need to be public: - DECL_CONTEXT (function_decl) = gg_trans_unit.trans_unit_decl; - TREE_PUBLIC(function_decl) = 1; - } - else - { - // The stack has something in it, so we are building a nested function. - // Make the current function our context - DECL_CONTEXT (function_decl) = gg_trans_unit.trans_unit_decl; - TREE_PUBLIC(function_decl) = 0; +static +std::string function_decl_key(const char *funcname, tree fndecl_type) + { + std::string retval; + retval += funcname; + retval += gg_show_type(TREE_TYPE(fndecl_type)); + return retval; + } - // This function is file static, but nobody calls it, so without - // intervention -O1+ optimizations will discard it. - DECL_PRESERVE_P (function_decl) = 1; +tree +gg_peek_fn_decl(const char *funcname, tree fndecl_type) + { + // When funcname is found in map_of_function_decls, this routine returns + // the type of the return value of that function decl. - // Append this function to the list of functions and variables - // associated with the computation module. - gg_append_var_decl(function_decl); + tree retval = NULL_TREE; + std::string key = function_decl_key(funcname, fndecl_type); + std::unordered_map<std::string, tree>::const_iterator it = + map_of_function_decls.find(key); + if( it != map_of_function_decls.end() ) + { + // This function_decl has already been defined. + retval = TREE_TYPE(TREE_TYPE(it->second)); } - - // Establish the RESULT_DECL for the function: - tree resdecl = build_decl (location_from_lineno(), RESULT_DECL, NULL_TREE, return_type); - DECL_CONTEXT (resdecl) = function_decl; - DECL_RESULT (function_decl) = resdecl; - - // The function_decl has a .function member, a pointer to struct_function. - // This is quietly, almost invisibly, extremely important. You need to - // call this routine after DECL_RESULT has been established: - - allocate_struct_function(function_decl, false); - - struct gg_function_t new_function = {}; - new_function.context_count = 0; - new_function.function_decl = function_decl; - new_function.our_name = IDENTIFIER_POINTER(DECL_NAME(function_decl)); - new_function.our_unmangled_name = xstrdup(unmangled_name); - new_function.function_address = gg_get_function_address(VOID, new_function.our_name); - - // Each program on the stack gets a unique identifier. This is used, for - // example, to make sure that static variables have unique names. - static size_t program_id = 0; - new_function.program_id_number = program_id++; - - // With everything established, put this function_decl on the stack - gg_trans_unit.function_stack.push_back(new_function); - - // All we need is a context, and we are ready to go: - gg_push_context(); - return function_decl; + return retval; } -void -gg_tack_on_function_parameters(tree function_decl, ...) +tree +gg_build_fn_decl(const char *funcname, tree fndecl_type) { - int nparams = 0; - - tree types[ARG_LIMIT]; - const char *names[ARG_LIMIT]; + tree function_decl; - va_list params; - va_start(params, function_decl); - for(;;) + std::string key = function_decl_key(funcname, fndecl_type); + std::unordered_map<std::string, tree>::const_iterator it = + map_of_function_decls.find(key); + if( it != map_of_function_decls.end() ) { - tree var_type = va_arg(params, tree); - if( !var_type ) - { - break; - } - - if( TREE_CODE(var_type) >= NUM_TREE_CODES) - { - // Warning: This test is not completely reliable, because a garbage - // byte could have a valid TREE_CODE. But it does help. - yywarn("You nitwit!"); - yywarn("You forgot to put a NULL_TREE at the end of a " - "gg_define_function() again!"); - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - gcc_unreachable(); - } + // This function_decl has already been defined. Just return it; the caller + // is responsible for modifying it, if necessary. + function_decl = it->second; + } + else + { + // When creating a never-seen function_decl, we default to the type used + // for calling a function defined elsewhere. It's up to our caller to + // modify the flags, for example if this is part of creating a function. - const char *name = va_arg(params, const char *); + function_decl = build_fn_decl(funcname, fndecl_type); - types[nparams] = var_type; - names[nparams] = name; - nparams += 1; - if(nparams > ARG_LIMIT) - { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### %d parameters? Really? Are you insane?",ARG_LIMIT+1); - gcc_unreachable(); - } - } - va_end(params); + // These are the bits shown in the table in the comment up above + TREE_ADDRESSABLE(function_decl) = 1; + TREE_USED(function_decl) = 1; + TREE_NOTHROW(function_decl) = 0; + TREE_STATIC(function_decl) = 0; + DECL_EXTERNAL (function_decl) = 1; + TREE_PUBLIC (function_decl) = 1; + DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(function_decl) = 0; - // Chain the names onto the variables list: - for(int i=0; i<nparams; i++) - { - chain_parameter_to_function(function_decl, types[i], names[i]); + DECL_PRESERVE_P (function_decl) = 0; + DECL_ARTIFICIAL(function_decl) = 0; + map_of_function_decls[key] = function_decl; } + return function_decl; } -void -gg_define_function(tree return_type, const char *funcname, ...) +tree +gg_define_function( tree return_type, + const char *funcname, + const char *unmangled_name, + ...) { // This routine builds a function_decl, puts it on the stack, and // gives it a context. - // After the funcname, we expect the formal parameters: pairs of types/names - // terminated by a NULL_TREE + // At this time we don't know how many parameters this function expects, so + // we set things up and we'll tack on the parameters later. + + /* There is some bookkeeping we need to do to avoid crashing. + + It's possible for the source code to have two top-level functions with + the same name. This is a compile-time error, but the GCC processing gets + upset when it happens. We'll prevent it from happening here: + + */ int nparams = 0; @@ -2644,7 +2581,7 @@ gg_define_function(tree return_type, const char *funcname, ...) const char *names[ARG_LIMIT]; va_list params; - va_start(params,funcname); + va_start(params, unmangled_name); for(;;) { tree var_type = va_arg(params, tree); @@ -2657,10 +2594,8 @@ gg_define_function(tree return_type, const char *funcname, ...) { // Warning: This test is not completely reliable, because a garbage // byte could have a valid TREE_CODE. But it does help. - yywarn("You nitwit!"); - yywarn("You forgot to put a NULL_TREE at the end of a " - "gg_define_function() again!"); - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); + yywarn("You forgot to put a %<NULL_TREE%> at the end of a " + "%<gg_define_function()%> again"); gcc_unreachable(); } @@ -2671,32 +2606,33 @@ gg_define_function(tree return_type, const char *funcname, ...) nparams += 1; if(nparams > ARG_LIMIT) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### %d parameters? Really? Are you insane?", - ARG_LIMIT+1); + yywarn("%d parameters? Really? Are you insane?", ARG_LIMIT+1); gcc_unreachable(); } } va_end(params); - // Create the FUNCTION_TYPE for that array: + char ach[32]; + std::unordered_set<std::string>::const_iterator it = + names_we_have_seen.find(funcname); + if( it != names_we_have_seen.end() ) + { + static int bum_counter = 1; + // We have seen this name before. Replace it with something unique: + sprintf(ach, "..no_dupes.%d", bum_counter++); + funcname = ach; + } + else + { + names_we_have_seen.insert(funcname); + } + tree fndecl_type = build_varargs_function_type_array( return_type, nparams, types); // Create the FUNCTION_DECL for that FUNCTION_TYPE - tree function_decl = build_fn_decl (funcname, fndecl_type); - - // Some of this stuff is magical, and is based on compiling C programs - // and just mimicking the results. - TREE_ADDRESSABLE(function_decl) = 1; - TREE_STATIC(function_decl) = 1; - DECL_EXTERNAL (function_decl) = 0; - DECL_PRESERVE_P (function_decl) = 0; - DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(function_decl) = 1; - DECL_ARTIFICIAL(function_decl) = 0; - TREE_NOTHROW(function_decl) = 0; - TREE_USED(function_decl) = 1; + tree function_decl = gg_build_fn_decl (funcname, fndecl_type); // This code makes COBOL nested programs actual visible on the // source code "trans_unit_decl" level, but with non-public "static" @@ -2704,22 +2640,40 @@ gg_define_function(tree return_type, const char *funcname, ...) if( gg_trans_unit.function_stack.size() == 0 ) { // gg_trans_unit.function_stack is empty, so our context is - // the compilation module, and we need to be public: + // the compilation module, and we need to be public because this is a + // top-level function with global scope: + + // These are the bits shown in the table for gg_build_fn_decl() + TREE_ADDRESSABLE(function_decl) = 1; + TREE_USED(function_decl) = 1; + TREE_NOTHROW(function_decl) = 1; + TREE_STATIC(function_decl) = 1; + DECL_EXTERNAL (function_decl) = 0; + TREE_PUBLIC (function_decl) = 1; + DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(function_decl) = 1; DECL_CONTEXT (function_decl) = gg_trans_unit.trans_unit_decl; - TREE_PUBLIC(function_decl) = 1; } else { - // The stack has something in it, so we are building a nested function. - // Make the current function our context + // The stack has something in it, so we are building a contained + // program-id. Such function are implemented local static functions. + // + // It's not necessarily true that a static call to such a function will be + // part of the source code (the call can be through a variable), and so + // optimization routines can decide the function isn't used and can + // therefore be optimized away. The preserve flag prevents that. + + // These are the bits shown in the table for gg_build_fn_decl() + TREE_ADDRESSABLE(function_decl) = 1; + TREE_USED(function_decl) = 1; + TREE_NOTHROW(function_decl) = 1; + TREE_STATIC(function_decl) = 1; + DECL_EXTERNAL (function_decl) = 0; + TREE_PUBLIC (function_decl) = 0; + DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(function_decl) = 1; DECL_CONTEXT (function_decl) = gg_trans_unit.trans_unit_decl; - - // We need to make it public, because otherwise COBOL CALL "func" - // won't be able to find it, because dlopen/dlsym won't find it. - TREE_PUBLIC(function_decl) = 0; - - // Append this function to the list of functions and variables - // associated with the computation module. + DECL_CONTEXT(function_decl) = gg_trans_unit.trans_unit_decl; + DECL_PRESERVE_P (function_decl) = 1; gg_append_var_decl(function_decl); } @@ -2730,7 +2684,7 @@ gg_define_function(tree return_type, const char *funcname, ...) } // Establish the RESULT_DECL for the function: - tree resdecl = build_decl (location_from_lineno(), RESULT_DECL, NULL_TREE, return_type); + tree resdecl = build_decl (gg_token_location(), RESULT_DECL, NULL_TREE, return_type); DECL_CONTEXT (resdecl) = function_decl; DECL_RESULT (function_decl) = resdecl; @@ -2743,6 +2697,9 @@ gg_define_function(tree return_type, const char *funcname, ...) struct gg_function_t new_function = {}; new_function.context_count = 0; new_function.function_decl = function_decl; + new_function.our_name = IDENTIFIER_POINTER(DECL_NAME(function_decl)); + new_function.our_unmangled_name = xstrdup(unmangled_name); + new_function.function_address = gg_get_address_of(function_decl); // Each program on the stack gets a unique identifier. This is used, for // example, to make sure that static variables have unique names. @@ -2754,6 +2711,19 @@ gg_define_function(tree return_type, const char *funcname, ...) // All we need is a context, and we are ready to go: gg_push_context(); + return function_decl; + } + +void +gg_modify_function_type(tree function_decl, tree return_type) + { + tree fndecl_type = build_varargs_function_type_array( return_type, + 0, // No parameters yet + NULL); // And, hence, no types + TREE_TYPE(function_decl) = fndecl_type; + tree resdecl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, return_type); + DECL_CONTEXT (resdecl) = function_decl; + DECL_RESULT (function_decl) = resdecl; } tree @@ -2785,10 +2755,8 @@ gg_get_function_decl(tree return_type, const char *funcname, ...) { // Warning: This test is not completely reliable, because a garbage // byte could have a valid TREE_CODE. But it does help. - yywarn("You nitwit!"); - yywarn("You forgot to put a NULL_TREE at the end of a " - "gg_define_function() again!"); - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); + yywarn("You forgot to put a %<NULL_TREE%> at the end of a " + "%<gg_define_function()%> again"); gcc_unreachable(); } @@ -2799,8 +2767,7 @@ gg_get_function_decl(tree return_type, const char *funcname, ...) nparams += 1; if(nparams > ARG_LIMIT) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### %d parameters? Really? Are you insane?", + yywarn("%d parameters? Really? Are you insane?", ARG_LIMIT+1); gcc_unreachable(); } @@ -2849,7 +2816,7 @@ gg_get_function_decl(tree return_type, const char *funcname, ...) } // Establish the RESULT_DECL for the function: - tree resdecl = build_decl (location_from_lineno(), RESULT_DECL, NULL_TREE, return_type); + tree resdecl = build_decl (gg_token_location(), RESULT_DECL, NULL_TREE, return_type); DECL_CONTEXT (resdecl) = function_decl; DECL_RESULT (function_decl) = resdecl; @@ -2875,62 +2842,72 @@ gg_finalize_function() // Finish off the context gg_pop_context(); - if( gg_trans_unit.function_stack.back().is_truly_nested ) - { - // This code is for true nested functions. - - ///////// DANGER, WILL ROBINSON! - ///////// This is all well and good. It does not, however, work. - ///////// I tried to implement it because I had a Brilliant Idea for - ///////// building COBOL paragraphs in a way that would easily allow - ///////// the GDB "NEXT" command to step over a PERFORM <paragraph>. - ///////// But, alas, I realized that it was just not going to work. - ///////// - ///////// Pity. - ///////// - ///////// But at that point, I was here, and I am leaving this uncooked - ///////// code in case I someday want to return to it. If it becomes - ///////// your job, rather than mine, I encourage you to write a C - ///////// program that uses the GNU extensions that allow true nested - ///////// functions, and reverse engineer the "finish_function" - ///////// function, and get it working. - ///////// - ///////// Good luck. Bob Dubner, 2022-08-13 - - // Because this is a nested function, let's make sure that it actually - // has a function that it is nested within - gcc_assert(gg_trans_unit.function_stack.size() > 1 ); - - /* Genericize before inlining. Delay genericizing nested functions - until their parent function is genericized. Since finalizing - requires GENERIC, delay that as well. */ - - // This is the comment in gcc/c/c-decl.c: - - /* Register this function with cgraph just far enough to get it - added to our parent's nested function list. Handy, since the - C front end doesn't have such a list. */ - - static cgraph_node *node = cgraph_node::get_create (current_function->function_decl); - gcc_assert(node); - - } - else - { - // This makes the function visible on the source code module level. - cgraph_node::finalize_function (current_function->function_decl, true); - } + /* Because COBOL functions can be misleadingly referenced before they + defined, and because our compiler is single pass, we need to defer + actually passing the function_decls to the middle end until we are + done with the entire compilation unit. + + An actual example: + + IDENTIFICATION DIVISION. + PROGRAM-ID. A. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 CWD PIC X(100). + 01 LEN_OF_CWD PIC 999 VALUE 100. + PROCEDURE DIVISION. + CALL "getcwd" USING BY REFERENCE CWD BY VALUE LEN_OF_CWD + DISPLAY CWD + goback. + END PROGRAM A. + IDENTIFICATION DIVISION. + PROGRAM-ID. B. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 CWD PIC X(100). + 01 RETURNED-CWD PIC X(100). + 01 LEN_OF_CWD PIC 999 VALUE 100. + PROCEDURE DIVISION. + CALL "getcwd" USING BY REFERENCE CWD BY VALUE LEN_OF_CWD RETURNING RETURNED-CWD + DISPLAY RETURNED-CWD + goback. + END PROGRAM B. + + When we encounter the first call to getcwd, we have no clue as to the + type of the return value, so we assume it is COBOL_FUNCTION_RETURN_TYPE + + When we encounter the second call, we learn that it returns CHAR_P. But + an attempt to change the return type of the function_decl will result + in problems if the function_decl of A is processed by the middle end + before we get a chance to change the getcwd functiona_decl. + + Hence the need for finalized_function_decls, which gets processed + at the end of the file. */ + + finalized_function_decls.push_back(current_function->function_decl); dump_function (TDI_original, current_function->function_decl); if( gg_trans_unit.function_stack.back().context_count ) { - cbl_internal_error("Residual context count!"); + cbl_internal_error("Residual context count"); } gg_trans_unit.function_stack.pop_back(); } +void +gg_leaving_the_source_code_file() + { + for( std::vector<tree>::const_iterator it=finalized_function_decls.begin(); + it != finalized_function_decls.end(); + it++ ) + { + //This makes the function visible on the source code module level. + cgraph_node::finalize_function(*it, true); + } + } + void gg_push_context() { @@ -3070,14 +3047,13 @@ gg_call_expr(tree return_type, const char *function_name, ...) { if(nargs >= ARG_LIMIT) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### You *must* be joking!"); + yywarn("You *must* be joking"); gcc_unreachable(); } tree arg = va_arg(ap, tree); - if( !arg ) + if( arg == NULL_TREE ) { break; } @@ -3098,7 +3074,7 @@ gg_call_expr(tree return_type, const char *function_name, ...) tree the_func_addr = build1(ADDR_EXPR, build_pointer_type (TREE_TYPE(function_decl)), function_decl); - tree the_call = build_call_array_loc(location_from_lineno(), + tree the_call = build_call_array_loc(gg_token_location(), return_type, the_func_addr, nargs, @@ -3127,14 +3103,13 @@ gg_call(tree return_type, const char *function_name, ...) { if(nargs >= ARG_LIMIT) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### You *must* be joking!"); + yywarn("You *must* be joking"); gcc_unreachable(); } tree arg = va_arg(ap, tree); - if( !arg ) + if( arg == NULL_TREE ) { break; } @@ -3155,7 +3130,7 @@ gg_call(tree return_type, const char *function_name, ...) tree the_func_addr = build1(ADDR_EXPR, build_pointer_type (TREE_TYPE(function_decl)), function_decl); - tree the_call = build_call_array_loc(location_from_lineno(), + tree the_call = build_call_array_loc(gg_token_location(), return_type, the_func_addr, nargs, @@ -3165,7 +3140,7 @@ gg_call(tree return_type, const char *function_name, ...) } tree -gg_call_expr_list(tree return_type, tree function_name, int param_count, tree args[]) +gg_call_expr_list(tree return_type, tree function_pointer, int param_count, tree args[]) { // Generalized caller. param_count is the count of params in the arg[]] @@ -3180,9 +3155,9 @@ gg_call_expr_list(tree return_type, tree function_name, int param_count, tree ar // Avoid that with something like // gg_assign( dest, gg_call_expr_list(...) ); - tree the_call = build_call_array_loc(location_from_lineno(), + tree the_call = build_call_array_loc(gg_token_location(), return_type, - function_name, + function_pointer, param_count, args); // This routine returns the call_expr; the caller will have to deal with it @@ -3215,7 +3190,7 @@ void gg_exit(tree exit_code) { tree the_call = - build_call_expr_loc(location_from_lineno(), + build_call_expr_loc(gg_token_location(), builtin_decl_explicit (BUILT_IN_EXIT), 1, exit_code); @@ -3226,7 +3201,7 @@ void gg_abort() { tree the_call = - build_call_expr_loc(location_from_lineno(), + build_call_expr_loc(gg_token_location(), builtin_decl_explicit (BUILT_IN_ABORT), 0); gg_append_statement(the_call); @@ -3237,7 +3212,7 @@ gg_strlen(tree psz) { tree the_call = fold_convert( size_type_node, - build_call_expr_loc(location_from_lineno(), + build_call_expr_loc(gg_token_location(), builtin_decl_explicit (BUILT_IN_STRLEN), 1, psz)); @@ -3249,7 +3224,7 @@ gg_strdup(tree psz) { tree the_call = fold_convert( build_pointer_type(char_type_node), - build_call_expr_loc(location_from_lineno(), + build_call_expr_loc(gg_token_location(), builtin_decl_explicit (BUILT_IN_STRDUP), 1, psz)); @@ -3263,7 +3238,7 @@ gg_malloc(tree size) { tree the_call = fold_convert( pvoid_type_node, - build_call_expr_loc(location_from_lineno(), + build_call_expr_loc(gg_token_location(), builtin_decl_explicit (BUILT_IN_MALLOC), 1, size)); @@ -3275,7 +3250,7 @@ gg_realloc(tree base, tree size) { tree the_call = fold_convert( pvoid_type_node, - build_call_expr_loc(location_from_lineno(), + build_call_expr_loc(gg_token_location(), builtin_decl_explicit (BUILT_IN_REALLOC), 2, base, @@ -3299,7 +3274,7 @@ void gg_free(tree pointer) { tree the_call = - build_call_expr_loc(location_from_lineno(), + build_call_expr_loc(gg_token_location(), builtin_decl_explicit (BUILT_IN_FREE), 1, pointer); @@ -3400,18 +3375,6 @@ gg_string_literal(const char *string) return build_string_literal(strlen(string)+1, string); } -void -gg_set_current_line_number(int line_number) - { - sv_current_line_number = line_number; - } - -int -gg_get_current_line_number() - { - return sv_current_line_number; - } - tree gg_trans_unit_var_decl(const char *var_name) { @@ -3424,8 +3387,31 @@ gg_trans_unit_var_decl(const char *var_name) return NULL_TREE; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsuggest-attribute=format" + void -gg_insert_into_assembler(const char *format, ...) +gg_insert_into_assembler(const char ach[]) + { + if( !optimize ) + { + // Create the required generic tag + tree asm_expr = build5_loc( gg_token_location(), + ASM_EXPR, + VOID, + build_string(strlen(ach), ach), + NULL_TREE, + NULL_TREE, + NULL_TREE, + NULL_TREE); + + // And insert it as a statement + gg_append_statement(asm_expr); + } + } + +void +gg_insert_into_assemblerf(const char *format, ...) { // Temporarily defeat all ASM_EXPR for optimized code per PR119214 // The correct solution using LABEL_DECL is forthcoming @@ -3444,18 +3430,31 @@ gg_insert_into_assembler(const char *format, ...) vsnprintf(ach, sizeof(ach), format, ap); va_end(ap); - // Create the required generic tag - tree asm_expr = build5_loc( location_from_lineno(), - ASM_EXPR, - VOID, - build_string(strlen(ach), ach), - NULL_TREE, - NULL_TREE, - NULL_TREE, - NULL_TREE); - //SET_EXPR_LOCATION (asm_expr, UNKNOWN_LOCATION); + gg_insert_into_assembler(ach); + } + } +#pragma GCC diagnostic pop - // And insert it as a statement - gg_append_statement(asm_expr); +static location_t sv_token_location_override = 0; + +void +token_location_override(location_t loc) + { + sv_token_location_override = loc; + } + +location_t +gg_token_location() + { + location_t retval; + if( sv_token_location_override ) + { + retval = sv_token_location_override; + sv_token_location_override = 0; } + else + { + retval = current_token_location(); + } + return retval; } diff --git a/gcc/cobol/gengen.h b/gcc/cobol/gengen.h index 8c1bc8daef63..96e69dd3ac70 100644 --- a/gcc/cobol/gengen.h +++ b/gcc/cobol/gengen.h @@ -206,11 +206,6 @@ struct gg_function_t // logical way: All programs are siblings, with the context being the source // code module. The nested aspect is not reflected in the GENERIC tree. - // Truly nested functions are implemented within the generic tree; the - // nested function is completely inside the outer function. This was - // implemented to support paragraphs as callable entities. - bool is_truly_nested; - // This variable, which appears on the stack, contains the exit_address // for the terminating proc of a PERFORM A or PERFORM A THROUGH B tree perform_exit_address; @@ -300,7 +295,7 @@ extern tree gg_trunc(tree integer_type, tree float_var); extern tree gg_cast(tree type, tree var); // Assignment, that is to say, A = B -extern void gg_assign(tree dest, const tree source); +extern tree gg_assign(tree dest, const tree source); // struct creation and field access // Create struct, and access a field in a struct @@ -456,13 +451,16 @@ extern tree gg_strncmp(tree char_star_A, tree char_star_B, tree size_t_N); extern void gg_return(tree operand = NULL_TREE); // These routines are the preample and postamble that bracket everything else -extern void gg_define_function(tree return_type, const char *funcname, ...); -extern tree gg_define_function_with_no_parameters(tree return_type, - const char *funcname, - const char *unmangled_name); +extern tree gg_build_fn_decl(const char *funcname, tree fndecl_type); +extern tree gg_peek_fn_decl(const char *funcname); +extern tree gg_define_function( tree return_type, + const char *funcname, + const char *unmangled_name, + ...); extern void chain_parameter_to_function( tree function_decl, const tree param_type, const char *name); +extern void gg_modify_function_type(tree function_decl, tree return_type); extern void gg_finalize_function(); extern void gg_push_context(); @@ -471,7 +469,9 @@ extern void gg_pop_context(); // These are a generalized call constructor. The first for when you just want // the function called, because you don't care about the return value. The others // are for when you do need the return value. -extern tree gg_call_expr_list(tree return_type, tree function_name, int param_count, tree[]); +extern tree gg_call_expr_list(tree return_type, + tree function_pointer, + int param_count, tree[]); // The following is a garden-variety call, with known return type and known // but in the case where the return value is unimportant. @@ -505,9 +505,6 @@ void gg_goto(tree pointer); void gg_record_statement_list_start(); tree gg_record_statement_list_finish(); -// These routines are in support of PERFORM PARAGRAPH -extern tree gg_get_function_decl(tree return_type, const char *funcname, ...); - // Used to call system exit() extern void gg_exit(tree exit_code); extern void gg_abort(); @@ -528,17 +525,21 @@ extern tree gg_indirect(tree pointer, tree byte_offset = NULL_TREE); extern tree gg_string_literal(const char *string); #define CURRENT_LINE_NUMBER (cobol_location().first_line) -location_t location_from_lineno(); - -// When set to true, use UNKNOWN_LOCATION instead of CURRENT_LINE_NUMBER -extern void gg_set_current_line_number(int line_number); -extern int gg_get_current_line_number(); +extern location_t gg_token_location(); +extern location_t current_token_location(); +extern location_t current_location_minus_one(); +extern void current_location_minus_one_clear(); +extern void token_location_override(location_t loc); extern tree gg_trans_unit_var_decl(const char *var_name); -tree gg_open(tree char_star_A, tree int_B); -tree gg_close(tree int_A); -tree gg_get_indirect_reference(tree pointer, tree offset); -void gg_insert_into_assembler(const char *format, ...); -void gg_modify_function_type(tree function_decl, tree return_type); +extern tree gg_open(tree char_star_A, tree int_B); +extern tree gg_close(tree int_A); +extern tree gg_get_indirect_reference(tree pointer, tree offset); + +extern void gg_insert_into_assembler(const char ach[]); +extern void gg_insert_into_assemblerf(const char *format, ...) ATTRIBUTE_PRINTF_1; + +extern char *gg_show_type(tree type); +extern void gg_leaving_the_source_code_file(); #endif diff --git a/gcc/cobol/genmath.cc b/gcc/cobol/genmath.cc index edf3f22f68eb..e7eb971d1acb 100644 --- a/gcc/cobol/genmath.cc +++ b/gcc/cobol/genmath.cc @@ -52,7 +52,8 @@ set_up_on_exception_label(cbl_label_t *arithmetic_label) if( !arithmetic_label->structs.arith_error ) { arithmetic_label->structs.arith_error - = (cbl_arith_error_t *)xmalloc(sizeof(struct cbl_arith_error_t) ); + = static_cast<cbl_arith_error_t *> + (xmalloc(sizeof(struct cbl_arith_error_t))); // Set up the address pairs for this clause gg_create_goto_pair(&arithmetic_label->structs.arith_error->over.go_to, &arithmetic_label->structs.arith_error->over.label); @@ -72,8 +73,8 @@ set_up_compute_error_label(cbl_label_t *compute_label) if( !compute_label->structs.compute_error ) { compute_label->structs.compute_error - = (cbl_compute_error_t *) - xmalloc(sizeof(struct cbl_compute_error_t) ); + = static_cast<cbl_compute_error_t *> + (xmalloc(sizeof(struct cbl_compute_error_t))); compute_label->structs.compute_error->compute_error_code = gg_define_int(0); } @@ -95,8 +96,8 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C, size_t nA, cbl_refer_t *A, size_t nB, cbl_refer_t *B, cbl_arith_format_t format, - cbl_label_t *error, - cbl_label_t *not_error, + const cbl_label_t *error, + const cbl_label_t *not_error, tree compute_error, // Pointer to int const char *operation, cbl_refer_t *remainder = NULL) @@ -112,7 +113,6 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C, { TRACE1_HEADER TRACE1_TEXT_ABC("calling ", operation, "") - TRACE1_END for(size_t ii=0; ii<nA; ii++) { TRACE1_INDENT @@ -129,7 +129,6 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C, build_int_cst_type(SIZE_T, ii)); TRACE1_REFER("", B[ii], ""); } - TRACE1_END } // We need to split up cbl_num_result_t into two arrays, one for the refer_t @@ -137,7 +136,7 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C, // Allocate nC+1 in case this is a divide with a REMAINDER - cbl_refer_t *results = (cbl_refer_t *)xmalloc((nC+1) * sizeof( cbl_refer_t )); + std::vector<cbl_refer_t> results(nC + 1); int ncount = 0; if( nC+1 <= MIN_FIELD_BLOCK_SIZE ) @@ -207,7 +206,7 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C, build_array_of_treeplets(1, nA, A); build_array_of_treeplets(2, nB, B); - build_array_of_treeplets(3, ncount, results); + build_array_of_treeplets(3, ncount, results.data()); gg_call(VOID, operation, @@ -223,7 +222,6 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C, { for(size_t ii=0; ii<nC; ii++) { - break; // Breaks on ADD 1 SUB2 GIVING SUB4 both PIC S9(3) COMP TRACE1_INDENT gg_fprintf( trace_handle, 1, "result: C[%ld]: ", @@ -253,9 +251,6 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C, { SHOW_PARSE_END } - - // We need to release all of the refers we allocated: - free(results); } static void @@ -307,7 +302,7 @@ arithmetic_error_handler( cbl_label_t *error, } static bool -is_somebody_float(size_t nA, cbl_refer_t *A) +is_somebody_float(size_t nA, const cbl_refer_t *A) { bool retval = false; for(size_t i=0; i<nA; i++) @@ -322,7 +317,7 @@ is_somebody_float(size_t nA, cbl_refer_t *A) } static bool -is_somebody_float(size_t nC, cbl_num_result_t *C) +is_somebody_float(size_t nC, const cbl_num_result_t *C) { bool retval = false; for(size_t i=0; i<nC; i++) @@ -337,7 +332,7 @@ is_somebody_float(size_t nC, cbl_num_result_t *C) } static bool -all_results_binary(size_t nC, cbl_num_result_t *C) +all_results_binary(size_t nC, const cbl_num_result_t *C) { bool retval = true; @@ -581,10 +576,6 @@ fast_multiply(size_t nC, cbl_num_result_t *C, { // This is a MULTIPLY Format 2 get_binary_value(valB, NULL, B[0].field, refer_offset(B[0])); - } - - if(nB) - { gg_assign(valA, gg_multiply(valA, valB)); } @@ -619,7 +610,7 @@ static bool fast_divide(size_t nC, cbl_num_result_t *C, size_t nA, cbl_refer_t *A, size_t nB, cbl_refer_t *B, - cbl_refer_t remainder) + const cbl_refer_t &remainder) { bool retval = false; if( all_results_binary(nC, C) ) @@ -670,8 +661,10 @@ fast_divide(size_t nC, cbl_num_result_t *C, // We now either divide into C[n] or assign dividend/divisor to C[n]: for(size_t i=0; i<nC; i++ ) { - tree dest_type = tree_type_from_size(C[i].refer.field->data.capacity, 0); - tree dest_addr = gg_add(member(C[i].refer.field->var_decl_node, "data"), + tree dest_type = + tree_type_from_size(C[i].refer.field->data.capacity, 0); + tree dest_addr = gg_add(member( C[i].refer.field->var_decl_node, + "data"), refer_offset(C[i].refer)); tree ptr = gg_cast(build_pointer_type(dest_type), dest_addr); if( nB ) @@ -687,16 +680,15 @@ fast_divide(size_t nC, cbl_num_result_t *C, } // This is where we handle any remainder, keeping in mind that for - // nB != 0, the actual dividend is in the value we have named "divisor". - // - // And, yes, I hate comments like that, too. + // nB != 0, the actual dividend is in the value we have named + // "divisor". // We calculate the remainder by calculating // dividend minus quotient * divisor if( remainder.field ) { - tree dest_addr = gg_add(member(remainder.field->var_decl_node, "data"), - refer_offset(remainder)); + dest_addr = gg_add( member(remainder.field->var_decl_node, "data"), + refer_offset(remainder)); dest_type = tree_type_from_size(remainder.field->data.capacity, 0); ptr = gg_cast(build_pointer_type(dest_type), dest_addr); @@ -993,9 +985,9 @@ parser_add( size_t nC, cbl_num_result_t *C, } void -parser_add( cbl_refer_t cref, - cbl_refer_t aref, - cbl_refer_t bref, +parser_add( const cbl_refer_t& cref, + const cbl_refer_t& aref, + const cbl_refer_t& bref, cbl_round_t rounded) { // This is the simple and innocent C = A + B @@ -1215,9 +1207,9 @@ parser_divide( size_t nC, cbl_num_result_t *C, // C = A / B } void -parser_multiply(cbl_refer_t cref, - cbl_refer_t aref, - cbl_refer_t bref, +parser_multiply(const cbl_refer_t& cref, + const cbl_refer_t& aref, + const cbl_refer_t& bref, cbl_round_t rounded ) { cbl_num_result_t C[1]; @@ -1238,11 +1230,11 @@ parser_multiply(cbl_refer_t cref, } void -parser_divide( cbl_refer_t cref, - cbl_refer_t aref, - cbl_refer_t bref, +parser_divide( const cbl_refer_t& cref, + const cbl_refer_t& aref, + const cbl_refer_t& bref, cbl_round_t rounded, - cbl_refer_t remainder_ref ) + const cbl_refer_t& remainder_ref ) { cbl_num_result_t C[1]; C[0].rounded = rounded; @@ -1390,12 +1382,12 @@ parser_op( struct cbl_refer_t cref, break; } default: - cbl_internal_error( "parser_op() doesn't know how to " - "evaluate \"%s = %s %c %s\"\n", - cref.field->name, - aref.field->name, - op, - bref.field->name); + cbl_internal_error( "%<parser_op()%> doesn%'t know how to " + "evaluate %<%s = %s %c %s%>", + cref.field->name, + aref.field->name, + op, + bref.field->name); break; } } @@ -1704,9 +1696,9 @@ parser_subtract(size_t nC, cbl_num_result_t *C, // C = B - A } void -parser_subtract(cbl_refer_t cref, // cref = aref - bref - cbl_refer_t aref, - cbl_refer_t bref, +parser_subtract(const cbl_refer_t& cref, // cref = aref - bref + const cbl_refer_t& aref, + const cbl_refer_t& bref, cbl_round_t rounded ) { cbl_num_result_t C[1]; diff --git a/gcc/cobol/genutil.cc b/gcc/cobol/genutil.cc index e971043164c7..7895ea8d71ec 100644 --- a/gcc/cobol/genutil.cc +++ b/gcc/cobol/genutil.cc @@ -305,8 +305,11 @@ static void get_and_check_refstart_and_reflen( tree refstart,// LONG returned value tree reflen, // LONG returned value - cbl_refer_t &refer) + const cbl_refer_t &refer) { + const cbl_enabled_exceptions_t& + enabled_exceptions( cdf_enabled_exceptions() ); + if( !enabled_exceptions.match(ec_bound_ref_mod_e) ) { // This is normal operation -- no exception checking. Thus, we won't @@ -458,6 +461,8 @@ get_depending_on_value_from_odo(tree retval, cbl_field_t *odo) declarative with a RESUME NEXT STATEMENT, or before the default_condition processing can do a controlled exit. */ + const cbl_enabled_exceptions_t& + enabled_exceptions( cdf_enabled_exceptions() ); cbl_field_t *depending_on; depending_on = cbl_field_of(symbol_at(odo->occurs.depending_on)); @@ -471,8 +476,8 @@ get_depending_on_value_from_odo(tree retval, cbl_field_t *odo) return; } - // Bounds checking is enabled, so we test the DEPENDING ON value to be between - // the lower and upper OCCURS limits: + // Bounds checking is enabled, so we test the DEPENDING ON value to be + // between the lower and upper OCCURS limits: get_integer_value(retval, depending_on, NULL, @@ -482,23 +487,28 @@ get_depending_on_value_from_odo(tree retval, cbl_field_t *odo) { // This needs to evaluate to an integer set_exception_code(ec_bound_odo_e); - gg_assign(retval, build_int_cst_type(TREE_TYPE(retval), odo->occurs.bounds.lower)); + gg_assign(retval, build_int_cst_type( TREE_TYPE(retval), + odo->occurs.bounds.lower)); gg_assign(var_decl_rdigits, integer_zero_node); } ELSE ENDIF - IF( retval, gt_op, build_int_cst_type(TREE_TYPE(retval), odo->occurs.bounds.upper) ) + IF( retval, gt_op, build_int_cst_type(TREE_TYPE(retval), + odo->occurs.bounds.upper) ) { set_exception_code(ec_bound_odo_e); - gg_assign(retval, build_int_cst_type(TREE_TYPE(retval), odo->occurs.bounds.lower)); + gg_assign(retval, build_int_cst_type( TREE_TYPE(retval), + odo->occurs.bounds.lower)); } ELSE { - IF( retval, lt_op, build_int_cst_type(TREE_TYPE(retval), odo->occurs.bounds.lower) ) + IF( retval, lt_op, build_int_cst_type(TREE_TYPE(retval), + odo->occurs.bounds.lower) ) { set_exception_code(ec_bound_odo_e); - gg_assign(retval, build_int_cst_type(TREE_TYPE(retval), odo->occurs.bounds.lower)); + gg_assign(retval, build_int_cst_type( TREE_TYPE(retval), + odo->occurs.bounds.lower)); } ELSE ENDIF @@ -515,7 +525,7 @@ get_depending_on_value_from_odo(tree retval, cbl_field_t *odo) static void -get_depending_on_value(tree retval, cbl_refer_t &refer) +get_depending_on_value(tree retval, const cbl_refer_t &refer) { /* This routine, called only when we know there is an OCCURS DEPENDING ON clause, returns the current value of the DEPENDING ON variable. When @@ -532,8 +542,8 @@ get_depending_on_value(tree retval, cbl_refer_t &refer) static tree -get_data_offset(cbl_refer_t &refer, - int *pflags = NULL) +get_data_offset(const cbl_refer_t &refer, + int *pflags = NULL) { Analyze(); // This routine returns a tree which is the size_t offset to the data in the @@ -548,9 +558,8 @@ get_data_offset(cbl_refer_t &refer, // We have a refer. // At the very least, we have an constant offset int all_flags = 0; - int all_flag_bit = 1; - if( refer.nsubscript ) + if( refer.nsubscript() ) { REFER("subscript"); // We have at least one subscript: @@ -568,8 +577,9 @@ get_data_offset(cbl_refer_t &refer, // Establish the field_t pointer for walking up through our ancestors: cbl_field_t *parent = refer.field; + int all_flag_bit = 1; // Note the backwards test, because refer->nsubscript is an unsigned value - for(size_t i=refer.nsubscript-1; i<refer.nsubscript; i-- ) + for(size_t i=refer.nsubscript()-1; i<refer.nsubscript(); i-- ) { // We need to search upward for an ancestor with occurs_max: while(parent) @@ -601,6 +611,8 @@ get_data_offset(cbl_refer_t &refer, } else { + const cbl_enabled_exceptions_t& + enabled_exceptions( cdf_enabled_exceptions() ); if( !enabled_exceptions.match(ec_bound_subscript_e) ) { // With no exception testing, just pick up the value @@ -625,21 +637,25 @@ get_data_offset(cbl_refer_t &refer, } ELSE { - IF( subscript, lt_op, gg_cast(TREE_TYPE(subscript), integer_one_node) ) + IF( subscript, lt_op, gg_cast(TREE_TYPE(subscript), + integer_one_node) ) { // The subscript is too small set_exception_code(ec_bound_subscript_e); - gg_assign(subscript, build_int_cst_type(TREE_TYPE(subscript), 1)); + gg_assign(subscript, build_int_cst_type(TREE_TYPE(subscript), + 1)); } ELSE { IF( subscript, ge_op, - build_int_cst_type(TREE_TYPE(subscript), parent->occurs.ntimes()) ) + build_int_cst_type( TREE_TYPE(subscript), + parent->occurs.ntimes()) ) { // The subscript is too large set_exception_code(ec_bound_subscript_e); - gg_assign(subscript, build_int_cst_type(TREE_TYPE(subscript), 1)); + gg_assign(subscript, build_int_cst_type(TREE_TYPE(subscript), + 1)); } ELSE { @@ -654,14 +670,19 @@ get_data_offset(cbl_refer_t &refer, all_flag_bit <<= 1; - // Although we strictly don't need to look at the ODO value at this point, - // we do want it checked for the purposes of ec-bound-odo + // Although we strictly don't need to look at the ODO value at this + // point, we do want it checked for the purposes of ec-bound-odo + + const cbl_enabled_exceptions_t& + enabled_exceptions( cdf_enabled_exceptions() ); if( enabled_exceptions.match(ec_bound_odo_e) ) { if( parent->occurs.depending_on ) { - static tree value64 = gg_define_variable(LONG, ".._gdos_value64", vs_file_static); + static tree value64 = gg_define_variable( LONG, + ".._gdos_value64", + vs_file_static); cbl_field_t *odo = symbol_find_odo(parent); get_depending_on_value_from_odo(value64, odo); } @@ -698,6 +719,8 @@ get_data_offset(cbl_refer_t &refer, return retval; } +static tree tree_type_from_field(const cbl_field_t *field); + void get_binary_value( tree value, tree rdigits, @@ -735,7 +758,7 @@ get_binary_value( tree value, { if( SCALAR_FLOAT_TYPE_P(value) ) { - cbl_internal_error("Can't get float value from %s", field->name); + cbl_internal_error("cannot get %<float%> value from %s", field->name); } else { @@ -1236,20 +1259,15 @@ get_binary_value( tree value, break; } - case FldAlphanumeric: - { - - } - - default: { - fprintf(stderr, "%s(): We know not how to" - " get a binary value from %s\n", - __func__, - cbl_field_type_str(field->type) ); + char *err = xasprintf("%s(): We know not how to" + " get a binary value from %s\n", + __func__, + cbl_field_type_str(field->type) ); + cbl_internal_error("%s", err); abort(); - break; + // break; // break not needed after abort(); } } @@ -1265,8 +1283,8 @@ get_binary_value( tree value, } } -tree -tree_type_from_field(cbl_field_t *field) +static tree +tree_type_from_field(const cbl_field_t *field) { gcc_assert(field); return tree_type_from_size(field->data.capacity, field->attr & signable_e); @@ -1559,7 +1577,7 @@ tree_type_from_size(size_t bytes, int signable) static bool -refer_has_depends(cbl_refer_t &refer, refer_type_t refer_type) +refer_has_depends(const cbl_refer_t &refer, refer_type_t refer_type) { if( suppress_dest_depends ) { @@ -1577,7 +1595,7 @@ refer_has_depends(cbl_refer_t &refer, refer_type_t refer_type) // Check if there there is an occurs with a depending_on in the hierarchy bool proceed = false; - cbl_field_t *odo = symbol_find_odo(refer.field); + const cbl_field_t *odo = symbol_find_odo(refer.field); cbl_field_t *depending_on; if( odo && odo != refer.field ) { @@ -1603,7 +1621,7 @@ refer_has_depends(cbl_refer_t &refer, refer_type_t refer_type) { parent1 = p; } - cbl_field_t *parent2 = depending_on; + const cbl_field_t *parent2 = depending_on; while( (p = parent_of(parent2)) ) { parent2 = p; @@ -1665,8 +1683,9 @@ set_exception_code_func(ec_type_t ec, int /*line*/, int from_raise_statement) } bool -process_this_exception(ec_type_t ec) +process_this_exception(const ec_type_t ec) { + const cbl_enabled_exceptions_t& enabled_exceptions( cdf_enabled_exceptions() ); bool retval; if( enabled_exceptions.match(ec) || !skip_exception_processing ) { @@ -1698,7 +1717,7 @@ copy_little_endian_into_place(cbl_field_t *dest, tree value, int rhs_rdigits, bool check_for_error, - tree &size_error) + const tree &size_error) { if( check_for_error ) { @@ -1912,23 +1931,19 @@ char * get_literal_string(cbl_field_t *field) { assert(field->type == FldLiteralA); - char *buffer = NULL; - size_t buffer_length = 0; - if( buffer_length < field->data.capacity+1 ) - { - buffer_length = field->data.capacity+1; - buffer = (char *)xrealloc(buffer, buffer_length); - } + size_t buffer_length = field->data.capacity+1; + char *buffer = static_cast<char *>(xcalloc(1, buffer_length)); + for(size_t i=0; i<field->data.capacity; i++) { buffer[i] = ascii_to_internal(field->data.initial[i]); } - buffer[field->data.capacity] = '\0'; + return buffer; } bool -refer_is_clean(cbl_refer_t &refer) +refer_is_clean(const cbl_refer_t &refer) { if( !refer.field || refer.field->type == FldLiteralN ) { @@ -1943,7 +1958,7 @@ refer_is_clean(cbl_refer_t &refer) return !refer.all && !refer.addr_of - && !refer.nsubscript + && !refer.nsubscript() && !refer.refmod.from && !refer.refmod.len && !refer_has_depends(refer, refer_source) @@ -1959,7 +1974,7 @@ refer_is_clean(cbl_refer_t &refer) */ static tree // size_t -refer_refmod_length(cbl_refer_t &refer) +refer_refmod_length(const cbl_refer_t &refer) { Analyze(); REFER("refstart and reflen"); @@ -1975,7 +1990,7 @@ refer_refmod_length(cbl_refer_t &refer) static tree // size_t -refer_fill_depends(cbl_refer_t &refer) +refer_fill_depends(const cbl_refer_t &refer) { REFER(""); // This returns a positive number which is the amount a depends-limited @@ -2002,8 +2017,8 @@ refer_fill_depends(cbl_refer_t &refer) } tree // size_t -refer_offset(cbl_refer_t &refer, - int *pflags) +refer_offset(const cbl_refer_t &refer, + int *pflags) { // This routine calculates the effect of a refer offset on the // refer.field->data location. When there are subscripts, the data location @@ -2030,7 +2045,7 @@ refer_offset(cbl_refer_t &refer, static tree // size_t -refer_size(cbl_refer_t &refer, refer_type_t refer_type) +refer_size(const cbl_refer_t &refer, refer_type_t refer_type) { Analyze(); static tree retval = gg_define_variable(SIZE_T, "..rs_retval", vs_file_static); @@ -2071,13 +2086,13 @@ refer_size(cbl_refer_t &refer, refer_type_t refer_type) } tree // size_t -refer_size_dest(cbl_refer_t &refer) +refer_size_dest(const cbl_refer_t &refer) { return refer_size(refer, refer_dest); } tree // size_t -refer_size_source(cbl_refer_t &refer) +refer_size_source(const cbl_refer_t &refer) { /* There are oddities involved with refer_size_source and refer_size_dest. See the comments in refer_has_depends for some explanation. There are @@ -2114,14 +2129,14 @@ refer_size_source(cbl_refer_t &refer) } tree -qualified_data_location(cbl_refer_t &refer) +qualified_data_location(const cbl_refer_t &refer) { return gg_add(member(refer.field->var_decl_node, "data"), refer_offset(refer)); } uint64_t -get_time_64() +get_time_nanoseconds() { // This code was unabashedly stolen from gcc/timevar.cc. // It returns the Unix epoch with nine decimal places. @@ -2141,4 +2156,4 @@ get_time_64() return retval; #endif return retval; -} \ No newline at end of file +} diff --git a/gcc/cobol/genutil.h b/gcc/cobol/genutil.h index 43102d7cc544..f12124ecc5b9 100644 --- a/gcc/cobol/genutil.h +++ b/gcc/cobol/genutil.h @@ -92,7 +92,7 @@ int get_scaled_rdigits(cbl_field_t *field); int get_scaled_digits(cbl_field_t *field); tree tree_type_from_digits(size_t digits, int signable); tree tree_type_from_size(size_t bytes, int signable); -tree tree_type_from_field(cbl_field_t *field); + void get_binary_value( tree value, tree rdigits, cbl_field_t *field, @@ -118,7 +118,7 @@ void set_exception_code_func(ec_type_t ec, int line, int from_raise_statement=0); #define set_exception_code(ec) set_exception_code_func(ec, __LINE__) -bool process_this_exception(ec_type_t ec); +bool process_this_exception(const ec_type_t ec); #define CHECK_FOR_FRACTIONAL_DIGITS true void get_integer_value(tree value, // This is always a LONG cbl_field_t *field, @@ -130,7 +130,7 @@ void copy_little_endian_into_place(cbl_field_t *dest, tree value, int rhs_rdigits, bool check_for_error, - tree &size_error); + const tree &size_error); tree build_array_of_size_t( size_t N, const size_t *values); void parser_display_internal_field(tree file_descriptor, @@ -138,14 +138,14 @@ void parser_display_internal_field(tree file_descriptor, bool advance=DISPLAY_NO_ADVANCE); char *get_literal_string(cbl_field_t *field); -bool refer_is_clean(cbl_refer_t &refer); +bool refer_is_clean(const cbl_refer_t &refer); -tree refer_offset(cbl_refer_t &refer, +tree refer_offset(const cbl_refer_t &refer, int *pflags=NULL); -tree refer_size_source(cbl_refer_t &refer); -tree refer_size_dest(cbl_refer_t &refer); +tree refer_size_source(const cbl_refer_t &refer); +tree refer_size_dest(const cbl_refer_t &refer); -tree qualified_data_location(cbl_refer_t &refer); +tree qualified_data_location(const cbl_refer_t &refer); void build_array_of_treeplets( int ngroup, size_t N, @@ -155,7 +155,7 @@ void build_array_of_fourplets( int ngroup, size_t N, cbl_refer_t *refers); void get_depending_on_value_from_odo(tree retval, cbl_field_t *odo); -uint64_t get_time_64(); +uint64_t get_time_nanoseconds(); #endif diff --git a/gcc/cobol/inspect.h b/gcc/cobol/inspect.h index 9e86a0bd1a7e..96399f5dc010 100644 --- a/gcc/cobol/inspect.h +++ b/gcc/cobol/inspect.h @@ -53,181 +53,162 @@ static inline bool is_active( const cbl_refer_t& refer ) { return NULL != refer.field; } -template <typename DATA> -struct cbx_inspect_qual_t { +struct cbl_inspect_qual_t { bool initial; - DATA identifier_4; + cbl_refer_t identifier_4; - cbx_inspect_qual_t() : initial(false), identifier_4(DATA()) {} - cbx_inspect_qual_t( bool initial, const DATA& identifier_4 ) + cbl_inspect_qual_t() : initial(false), identifier_4(cbl_refer_t()) {} + cbl_inspect_qual_t( bool initial, const cbl_refer_t& identifier_4 ) : initial(initial), identifier_4(identifier_4) - { - //if( identifier_4.field ) yywarn("%s:qualifying field is '%s'", __func__, identifier_4.field->name); - } - cbx_inspect_qual_t( const cbx_inspect_qual_t& that ) + {} + cbl_inspect_qual_t( const cbl_inspect_qual_t& that ) : initial(that.initial) , identifier_4(that.identifier_4) - { - //if( identifier_4.field ) yywarn("%s:qualifying field is '%s'", __func__, identifier_4.field->name); - } + {} - cbx_inspect_qual_t& operator=( const cbx_inspect_qual_t& that ) { + cbl_inspect_qual_t& operator=( const cbl_inspect_qual_t& that ) { initial = that.initial; identifier_4 = that.identifier_4; - //if( identifier_4.field ) yywarn("%s:qualifying field is '%s'", __func__, identifier_4.field->name); return *this; } bool active() const { return is_active(identifier_4); } - - void clear() { - initial = false; - identifier_4.clear(); - } }; -typedef cbx_inspect_qual_t<cbl_refer_t> cbl_inspect_qual_t; - /* * Data for INSPECT X TALLYING Y FOR. Captures information for operands of * CHARACTERS/ALL/LEADING. The CHARACTERS/ALL/LEADING control is kept at the * next higher level, and may be repeated for each tally. * - * cbx_inspect_match_t::matching is not used with CHARACTERS + * cbl_inspect_match_t::matching is not used with CHARACTERS */ -template <typename DATA> -struct cbx_inspect_match_t { - DATA matching; // identifier-3/5 or literal-1/3 - cbx_inspect_qual_t<DATA> before, after; // phrase 1 - - cbx_inspect_match_t( - const DATA& matching = DATA(), - cbx_inspect_qual_t<DATA> before = cbx_inspect_qual_t<DATA>(), - cbx_inspect_qual_t<DATA> after = cbx_inspect_qual_t<DATA>() - ) - : matching(matching) + +class cbl_inspect_match_t { + friend void dump_inspect_match( const cbl_inspect_match_t& M ); + cbl_refer_t match; // identifier-3/5 or literal-1/3 + cbl_refer_t tally; // collected too soon, belongs to next phrase + public: + cbl_inspect_qual_t before, after; // phrase 1 + + cbl_inspect_match_t() {} + explicit + cbl_inspect_match_t( const cbl_refer_t& matching, + const cbl_inspect_qual_t& before = cbl_inspect_qual_t(), + const cbl_inspect_qual_t& after = cbl_inspect_qual_t() ) + : match(matching) , before(before) , after(after) {} // match all characters bool match_any() const { return !(before.active() || after.active()); } -}; -typedef cbx_inspect_match_t<cbl_refer_t> cbl_inspect_match_t; + void save_premature_tally( const cbl_refer_t& tally ) { + this->tally = tally; // put it here temporarily + } + cbl_refer_t premature_tally() { + if( !tally.field ) { std::swap(match, tally); } + return tally; + } + + const cbl_refer_t& matching( const cbl_refer_t& match ) { + return this->match = match; + } + const cbl_refer_t& matching() const { return match; } + + bool empty() const { + return !is_active(match) && !before.active() && !after.active(); + } +}; /* * Data for INSPECT X REPLACING. The CHARACTERS/ALL/LEADING/FIRST control is * kept at the next higher level, and may be repeated. */ -template <typename DATA> -struct cbx_inspect_replace_t : public cbx_inspect_match_t<DATA> { - DATA replacement; - - cbx_inspect_replace_t( const DATA& matching = DATA(), - const DATA& replacement = DATA() ) - : cbx_inspect_match_t<DATA>(matching) - , replacement(replacement) - {} - cbx_inspect_replace_t( const DATA& matching, - const DATA& replacement, - const cbx_inspect_qual_t<DATA>& before, - const cbx_inspect_qual_t<DATA>& after ) - : cbx_inspect_match_t<DATA>(matching, before, after) +struct cbl_inspect_replace_t : public cbl_inspect_match_t { + cbl_refer_t replacement; + + cbl_inspect_replace_t() {} + cbl_inspect_replace_t( const cbl_refer_t& matching, + const cbl_refer_t& replacement, + const cbl_inspect_qual_t& before, + const cbl_inspect_qual_t& after ) + : cbl_inspect_match_t(matching, before, after) , replacement(replacement) {} }; -typedef cbx_inspect_replace_t<cbl_refer_t> cbl_inspect_replace_t; - // One partial tally or substitution. -template <typename DATA> -struct cbx_inspect_oper_t { +struct cbl_inspect_oper_t { cbl_inspect_bound_t bound; // CHARACTERS/ALL/LEADING/FIRST - size_t n_identifier_3; // N matches/replaces - // either tallies or replaces is NULL - cbx_inspect_match_t<DATA> *matches; - cbx_inspect_replace_t<DATA> *replaces; + // either tallies or replaces is empty + std::vector<cbl_inspect_match_t> matches; + std::vector<cbl_inspect_replace_t> replaces; - cbx_inspect_oper_t( cbl_inspect_bound_t bound, - std::list<cbx_inspect_match_t<DATA>> matches ) + cbl_inspect_oper_t() : bound(bound_characters_e) {} + + explicit cbl_inspect_oper_t( const cbl_inspect_match_t& match, + cbl_inspect_bound_t bound = bound_characters_e ) : bound(bound) - , n_identifier_3( matches.size()) - , matches(NULL) - , replaces(NULL) - { - this->matches = new cbx_inspect_match_t<DATA>[n_identifier_3]; - std::copy( matches.begin(), matches.end(), this->matches ); - } - - cbx_inspect_oper_t( cbl_inspect_bound_t bound, - std::list<cbx_inspect_replace_t<DATA>> replaces ) + { + matches.push_back(match); + } + explicit cbl_inspect_oper_t( const cbl_inspect_replace_t& replace, + cbl_inspect_bound_t bound = bound_characters_e ) : bound(bound) - , n_identifier_3( replaces.size() ) - , matches(NULL) - , replaces(NULL) - { - this->replaces = new cbx_inspect_replace_t<DATA>[n_identifier_3]; - std::copy( replaces.begin(), replaces.end(), this->replaces ); - } - - cbx_inspect_oper_t() - : bound(bound_characters_e) - , n_identifier_3(0) - , matches(NULL) - , replaces(NULL) - { - assert( is_valid() ); - } - - bool is_valid() const { - if( matches && replaces ) return false; - if( matches || replaces ) return n_identifier_3 > 0; - return n_identifier_3 == 0; + { + replaces.push_back(replace); } -}; -typedef cbx_inspect_oper_t<cbl_refer_t> cbl_inspect_oper_t; + cbl_inspect_oper_t( cbl_inspect_bound_t bound, + const std::vector<cbl_inspect_match_t>& matches ) + : bound(bound) + , matches(matches) + {} -// One whole tally or substitution. For REPLACING, nbound == 1 -template <typename DATA> -struct cbx_inspect_t { - DATA tally; // identifier-2: NULL without a tally - size_t nbound; // Each FOR or REPLACING operation starts with a cbl_inspect_bound_t - cbx_inspect_oper_t<DATA> *opers; - - cbx_inspect_t( const DATA& tally = DATA() ) - : tally(tally) - , nbound(0) - , opers(NULL) + cbl_inspect_oper_t( cbl_inspect_bound_t bound, + const std::vector<cbl_inspect_replace_t>& replaces ) + : bound(bound) + , replaces(replaces) {} - cbx_inspect_t( const DATA& tally, cbx_inspect_oper_t<DATA> oper ) - : tally(tally) - , nbound(1) - , opers(NULL) - { - this->opers = new cbx_inspect_oper_t<DATA>[1]; - this->opers[0] = oper; - } - cbx_inspect_t( const DATA& tally, - const std::list<cbx_inspect_oper_t<DATA>>& opers ) - : tally(tally) - , nbound( opers.size() ) - , opers(NULL) - { - this->opers = new cbx_inspect_oper_t<DATA>[nbound]; - std::copy( opers.begin(), opers.end(), this->opers ); - } + + // N matches/replaces + size_t n_identifier_3() const { + return std::max( matches.size(), replaces.size() ); + } + + bool is_valid() const { // only one or the other, never both + bool invalid = !matches.empty() && !replaces.empty(); + return ! invalid; + } }; -typedef cbx_inspect_t<cbl_refer_t> cbl_inspect_t; +// One whole tally or substitution. For REPLACING, nbound == 1 +// FOR and REPLACING start with a cbl_inspect_bound_t +struct cbl_inspect_t : public std::vector<cbl_inspect_oper_t> { + cbl_refer_t tally; // field is NULL for REPLACING + cbl_inspect_t() {} + cbl_inspect_t( size_t n, const cbl_inspect_oper_t& oper ) + : std::vector<cbl_inspect_oper_t>(n, oper) + {} + cbl_inspect_t( const cbl_refer_t& tally, + const std::vector<cbl_inspect_oper_t>& opers ) + : std::vector<cbl_inspect_oper_t>(opers) + , tally(tally) + {} + + size_t nbound() const { return size(); } +}; +typedef std::vector<cbl_inspect_t> cbl_inspect_opers_t; /* * Runtime */ -void parser_inspect( cbl_refer_t input, bool backward, - size_t ninspect, cbl_inspect_t *inspects ); +void parser_inspect( const cbl_refer_t& input, + bool backward, + cbl_inspect_opers_t& inspects ); + void parser_inspect_conv( cbl_refer_t input, bool backward, cbl_refer_t original, cbl_refer_t replacement, diff --git a/gcc/cobol/lexio.cc b/gcc/cobol/lexio.cc index 6b2d1fbf957e..52d1affee810 100644 --- a/gcc/cobol/lexio.cc +++ b/gcc/cobol/lexio.cc @@ -38,29 +38,24 @@ extern int yy_flex_debug; -static struct { - bool first_file, explicitly; - int column, right_margin; - bool inference_pending() { - bool tf = first_file && !explicitly; - first_file = false; - return tf; - } - inline bool is_fixed() const { return column == 7; } - inline bool is_reffmt() const { return is_fixed() && right_margin == 73; } - inline bool is_free() const { return ! is_fixed(); } - - const char * description() const { - if( is_reffmt() ) return "REFERENCE"; - if( is_fixed() ) return "FIXED"; - if( is_free() ) return "FREE"; - gcc_unreachable(); - } -} indicator = { true, false, 0, 0 }; +source_format_t& cdf_source_format(); + +void +source_format_t::infer( const char *bol, bool want_reference_format ) { + if( bol ) { + left = 7; + if( want_reference_format ) { + right = 73; + } + } + dbgmsg("%s:%d: %s format detected", __func__, __LINE__, + description()); +} + // public source format test functions -bool is_fixed_format() { return indicator.is_fixed(); } -bool is_reference_format() { return indicator.is_reffmt(); } +bool is_fixed_format() { return cdf_source_format().is_fixed(); } +bool is_reference_format() { return cdf_source_format().is_reffmt(); } static bool debug_mode = false; @@ -76,11 +71,10 @@ static bool debug_mode = false; */ static inline int left_margin() { - return indicator.column == 0? indicator.column : indicator.column - 1; + return cdf_source_format().left_margin(); } static inline int right_margin() { - return indicator.right_margin == 0? - indicator.right_margin : indicator.right_margin - 1; + return cdf_source_format().right_margin(); } /* @@ -89,18 +83,9 @@ static inline int right_margin() { * When setting back to 0 (free), the right margin is also reset to 0. */ void -cobol_set_indicator_column( int column ) -{ - indicator.explicitly = true; - if( column == 0 ) indicator.right_margin = 0; - if( column < 0 ) { - column = -column; - indicator.right_margin = 73; - } - indicator.column = column; -} +cobol_set_indicator_column( int column ); -bool include_debug() { return indicator.column == 7 && debug_mode; } +bool include_debug() { return is_fixed_format() && debug_mode; } bool set_debug( bool tf ) { return debug_mode = tf && is_fixed_format(); } static bool nonblank( const char ch ) { return !isblank(ch); } @@ -114,7 +99,7 @@ start_of_line( char *bol, char *eol ) { static inline char * continues_at( char *bol, char *eol ) { - if( indicator.column == 0 ) return NULL; // cannot continue in free format + if( cdf_source_format().is_free() ) return NULL; // cannot continue in free format bol += left_margin(); if( *bol != '-' ) return NULL; // not a continuation line return start_of_line(++bol, eol); @@ -123,8 +108,8 @@ continues_at( char *bol, char *eol ) { // Return pointer to indicator column. Test ch if provided. // NULL means no indicator column or tested value not present. static inline char * -indicated( char *bol, char *eol, char ch = '\0' ) { - if( indicator.column == 0 && *bol != '*' ) { +indicated( char *bol, const char *eol, char ch = '\0' ) { + if( cdf_source_format().left_margin() == 0 && *bol != '*' ) { return NULL; // no indicator column in free format, except for comments } gcc_assert(bol != NULL); @@ -140,10 +125,10 @@ indicated( char *bol, char *eol, char ch = '\0' ) { static char * remove_inline_comment( char *bol, char *eol ) { - static char ends = '\0'; char *nl = std::find(bol, eol, '\n'); if( bol < nl ) { + static char ends = '\0'; std::swap(*nl, ends); char *comment = strstr(bol, "*>"); if( comment ) { @@ -208,10 +193,10 @@ maybe_add_space(const span_t& pattern, replace_t& recognized) { } if( befter[0] == blank || befter[1] == blank ) { - char *s = xasprintf( "%s%.*s%s", - befter[0], - recognized.after.size(), recognized.after.p, - befter[1] ); + const char *s = xasprintf( "%s%.*s%s", + befter[0], + recognized.after.size(), recognized.after.p, + befter[1] ); recognized.after = span_t(s, s + strlen(s)); } } @@ -266,7 +251,9 @@ recognize_replacements( filespan_t mfile, std::list<replace_t>& pending_replacem span_t found(mfile.eodata, mfile.eodata); - if( regex_search( mfile.ccur(), (const char *)mfile.eodata, cm, re) ) { + if( regex_search( mfile.ccur(), + const_cast<const char *>(mfile.eodata), + cm, re) ) { gcc_assert(cm[1].matched); found = span_t( cm[1].first, cm[1].second ); if( yy_flex_debug ) { @@ -301,7 +288,8 @@ recognize_replacements( filespan_t mfile, std::list<replace_t>& pending_replacem bol = next.found.pend; if( yy_flex_debug ) { - size_t n = std::count((const char *)mfile.data, recognized.before.p, '\n'); + size_t n = std::count(const_cast<const char *>(mfile.data), + recognized.before.p, '\n'); dbgmsg( "%s:%d: line " HOST_SIZE_T_PRINT_UNSIGNED " @ " HOST_SIZE_T_PRINT_UNSIGNED ": '%s'\n/%.*s/%.*s/", __func__, __LINE__, @@ -317,10 +305,11 @@ recognize_replacements( filespan_t mfile, std::list<replace_t>& pending_replacem next.found = span_t(mfile.eodata, mfile.eodata); regex re(next.directive.before.p, extended_icase); - if( regex_search(bol, (const char *)mfile.eodata, cm, re) ) { + if( regex_search(bol, const_cast<const char *>(mfile.eodata), cm, re) ) { gcc_assert(cm[1].matched); next.found = span_t( cm[1].first, cm[1].second ); - size_t n = std::count((const char *)mfile.data, next.found.p, '\n'); + size_t n = std::count(const_cast<const char *>(mfile.data), + next.found.p, '\n'); if( false ) dbgmsg("%s:%d next '%.*s' will be on line " HOST_SIZE_T_PRINT_UNSIGNED " (offset " HOST_SIZE_T_PRINT_UNSIGNED ")", __func__, __LINE__, @@ -331,8 +320,70 @@ recognize_replacements( filespan_t mfile, std::list<replace_t>& pending_replacem } } +static void +check_push_pop_directive( filespan_t& mfile ) { + char eol = '\0'; + const char *p = std::find(mfile.cur, mfile.eol, '>'); + if( ! (p < mfile.eol && p[1] == *p ) ) return; + + const char pattern[] = + ">>[[:blank:]]*(push|pop)[[:blank:]]+" + "(" + "all|" + "call-convention|" + "cobol-words|" + "define|" + "source[[:blank:]]+format|" + "turn" + ")"; + static regex re(pattern, extended_icase); + + // show contents of marked subexpressions within each match + cmatch cm; + + std::swap(*mfile.eol, eol); // see implementation for excuses + bool ok = regex_search(p, const_cast<const char *>(mfile.eol), cm, re); + std::swap(*mfile.eol, eol); + + if( ok ) { + gcc_assert(cm.size() > 1); + bool push = TOUPPER(cm[1].first[1]) == 'U'; + switch( TOUPPER(cm[2].first[0]) ) { + case 'A': // ALL + push? cdf_push() : cdf_pop(); + break; + case 'C': + switch( TOUPPER(cm[2].first[1]) ) { + case 'A': // CALL-CONVENTION + push? cdf_push_call_convention() : cdf_pop_call_convention(); + break; + case 'O': // COBOL-WORDS + push? cdf_push_current_tokens() : cdf_pop_current_tokens(); + break; + default: + gcc_unreachable(); + } + break; + case 'D': // DEFINE + push? cdf_push_dictionary() : cdf_pop_dictionary(); + break; + case 'S': // SOURCE FORMAT + push? cdf_push_source_format() : cdf_pop_source_format(); + break; + case 'T': // TURN + push? cdf_push_enabled_exceptions() : cdf_pop_enabled_exceptions(); + break; + default: + gcc_unreachable(); + } + erase_line(const_cast<char*>(cm[0].first), + const_cast<char*>(cm[0].second)); + } +} + static void check_source_format_directive( filespan_t& mfile ) { + char eol = '\0'; const char *p = std::find(mfile.cur, mfile.eol, '>'); if( ! (p < mfile.eol && p[1] == *p ) ) return; @@ -345,7 +396,12 @@ check_source_format_directive( filespan_t& mfile ) { // show contents of marked subexpressions within each match cmatch cm; - if( regex_search(p, (const char *)mfile.eol, cm, re) ) { + + std::swap(*mfile.eol, eol); // see implementation for excuses + bool ok = regex_search(p, const_cast<const char *>(mfile.eol), cm, re); + std::swap(*mfile.eol, eol); + + if( ok ) { gcc_assert(cm.size() > 1); switch( cm[3].length() ) { case 4: @@ -361,11 +417,11 @@ check_source_format_directive( filespan_t& mfile ) { dbgmsg( "%s:%d: %s format set, on line " HOST_SIZE_T_PRINT_UNSIGNED, __func__, __LINE__, - indicator.column == 7? "FIXED" : "FREE", + cdf_source_format().description(), (fmt_size_t)mfile.lineno() ); - char *bol = indicator.is_fixed()? mfile.cur : const_cast<char*>(cm[0].first); + char *bol = cdf_source_format().is_fixed()? mfile.cur : const_cast<char*>(cm[0].first); + gcc_assert(cm[0].second <= mfile.eol); erase_line(bol, const_cast<char*>(cm[0].second)); - mfile.cur = const_cast<char*>(cm[0].second); } } @@ -459,9 +515,9 @@ struct replacing_term_t { bool matched, done; span_t leading_trailing, term, stmt; - replacing_term_t(const char input[]) : matched(false), done(false) { - stmt = span_t(input, input); - } + explicit replacing_term_t(const char input[]) + : matched(false), done(false), stmt(span_t(input, input)) + {} }; extern YYLTYPE yylloc; @@ -531,7 +587,7 @@ update_yylloc( const csub_match& stmt, const csub_match& term ) { static replacing_term_t parse_replacing_term( const char *stmt, const char *estmt ) { - gcc_assert(stmt); gcc_assert(estmt); gcc_assert(stmt < estmt); + gcc_assert(stmt); gcc_assert(estmt); gcc_assert(stmt <= estmt); replacing_term_t output(stmt); static const char pattern[] = @@ -741,7 +797,7 @@ parse_replacing_pair( const char *stmt, const char *estmt ) { } } if( pair.stmt.p ) { - yywarn("CDF syntax error '%*s'", (int)pair.stmt.size(), pair.stmt.p); + yywarn("CDF syntax error '%.*s'", (int)pair.stmt.size(), pair.stmt.p); } else { // This eliminated a compiler warning about "format-overflow" @@ -809,7 +865,7 @@ parse_replace_pairs( const char *stmt, const char *estmt, bool is_copy_stmt ) { } span_t& before(parsed.replace.before); - span_t& after(parsed.replace.after); + const span_t& after(parsed.replace.after); const char *befter[2] = { nonword_ch, nonword_ch }; gcc_assert(before.p < before.pend); @@ -877,7 +933,7 @@ struct copy_descr_t { }; static YYLTYPE -location_in( const filespan_t& mfile, const csub_match cm ) { +location_in( const filespan_t& mfile, const csub_match& cm ) { YYLTYPE loc { int(mfile.lineno() + 1), int(mfile.colno() + 1), int(mfile.lineno() + 1), int(mfile.colno() + 1) @@ -885,7 +941,7 @@ location_in( const filespan_t& mfile, const csub_match cm ) { gcc_assert(mfile.cur <= cm.first && cm.second <= mfile.eodata); auto nline = std::count(cm.first, cm.second, '\n'); if( nline ) { - gcc_assert(loc.first_line < nline); + gcc_assert(nline < loc.first_line); loc.first_line -= nline; auto p = static_cast<const char*>(memrchr(cm.first, '\n', cm.length())); loc.last_column = (cm.second) - p; @@ -928,7 +984,7 @@ parse_copy_directive( filespan_t& mfile ) { copy_stmt.p = mfile.eodata; if( regex_search(mfile.ccur(), - (const char *)mfile.eodata, cm, re) ) { + const_cast<const char *>(mfile.eodata), cm, re) ) { copy_stmt = span_t( cm[0].first, cm[0].second ); if( yy_flex_debug ) { size_t nnl = 1 + count_newlines(mfile.data, copy_stmt.p); @@ -981,7 +1037,7 @@ parse_copy_directive( filespan_t& mfile ) { std::pair<std::list<replace_t>, char*> result = parse_replace_pairs( cm[0].second, mfile.eodata, true ); - std::list<replace_t>& replacements(result.first); + const std::list<replace_t>& replacements(result.first); outcome.parsed = (outcome.nreplace = replacements.size()) > 0; if( outcome.parsed ) { replace_directives.push(replacements); @@ -1008,7 +1064,7 @@ parse_copy_directive( filespan_t& mfile ) { } static char * -parse_replace_last_off( filespan_t& mfile ) { +parse_replace_last_off( const filespan_t& mfile ) { static const char pattern[] = "REPLACE" "[[:space:]]+" "(LAST[[:space:]]+)?OFF[[:space:]]*[.]" @@ -1018,7 +1074,7 @@ parse_replace_last_off( filespan_t& mfile ) { // REPLACE [LAST] OFF? bool found = regex_search(mfile.ccur(), - (const char *)mfile.eodata, cm, re); + const_cast<const char *>(mfile.eodata), cm, re); gcc_assert(found); // caller ensures gcc_assert(cm.size() == 2); @@ -1073,7 +1129,7 @@ parse_replace_text( filespan_t& mfile ) { (fmt_size_t)current_lineno, len, mfile.cur); } - if( ! regex_search(mfile.ccur(), (const char *)mfile.eodata, cm, re) ) { + if( ! regex_search(mfile.ccur(), mfile.eodata, cm, re) ) { dbgmsg( "%s:%d: line " HOST_SIZE_T_PRINT_UNSIGNED ": not a REPLACE statement:\n'%.*s'", __func__, __LINE__, (fmt_size_t)current_lineno, @@ -1109,7 +1165,7 @@ parse_replace_text( filespan_t& mfile ) { std::pair<std::list<replace_t>, char*> result = parse_replace_pairs(replace_stmt.p, replace_stmt.pend, false); - std::list<replace_t>& replacements(result.first); + const std::list<replace_t>& replacements(result.first); replace_directives.push( replacements ); if( yy_flex_debug ) { @@ -1147,7 +1203,7 @@ parse_replace_directive( filespan_t& mfile ) { next_directive = mfile.eodata; if( regex_search(mfile.ccur(), - (const char *)mfile.eodata, cm, re) ) { + const_cast<const char *>(mfile.eodata), cm, re) ) { gcc_assert(cm[1].matched); next_directive = cm[0].first; @@ -1323,13 +1379,13 @@ lexer_input( char buf[], int max_size, FILE *input ) { for( auto p = mfile.cur; p < next; *output.pos++ = *p++ ) { static bool at_bol = false; if( at_bol ) { - auto nonblank = std::find_if( p, next, + auto nonblank_l = std::find_if( p, next, []( char ch ) { return !isblank(ch); } ); - if( nonblank + 1 < next ) { - if( *nonblank == '\r' ) nonblank++; // Windows - if( *nonblank == '\n' ) { - p = nonblank; + if( nonblank_l + 1 < next ) { + if( *nonblank_l == '\r' ) nonblank_l++; // Windows + if( *nonblank_l == '\n' ) { + p = nonblank_l; continue; } } @@ -1409,7 +1465,7 @@ preprocess_filter_add( const char input[] ) { auto filename = find_filter(filter.c_str()); if( !filename ) { - yywarn("preprocessor '%s/%s' not found", getcwd(NULL, 0), filter); + yywarn("preprocessor '%s/%s' not found", getcwd(NULL, 0), filter.c_str()); return false; } preprocessor_filters.push_back( std::make_pair(xstrdup(filename), options) ); @@ -1457,7 +1513,6 @@ cdftext::lex_open( const char filename[] ) { // Process any files supplied by the -include command-line option. for( auto name : included_files ) { - int input; if( -1 == (input = open(name, O_RDONLY)) ) { yyerrorvl(1, "", "cannot open -include file %s", name); continue; @@ -1491,7 +1546,7 @@ cdftext::lex_open( const char filename[] ) { argv[0] = filter; auto last_argv = std::transform( options.begin(), options.end(), argv.begin() + 1, - []( std::string& opt ) { + []( const std::string& opt ) { return xstrdup(opt.c_str()); } ); *last_argv = NULL; @@ -1520,11 +1575,11 @@ cdftext::lex_open( const char filename[] ) { int status; auto kid = wait(&status); gcc_assert(pid == kid); - if( kid == -1 ) cbl_err( "failed waiting for pid %d", pid); + if( kid == -1 ) cbl_err( "failed waiting for pid %ld", static_cast<long>(pid)); if( WIFSIGNALED(status) ) { - cbl_errx( "%s pid %d terminated by %s", - filter, kid, strsignal(WTERMSIG(status)) ); + cbl_errx( "%s pid %ld terminated by %s", + filter, static_cast<long>(kid), strsignal(WTERMSIG(status)) ); } if( WIFEXITED(status) ) { if( (status = WEXITSTATUS(status)) != 0 ) { @@ -1542,7 +1597,7 @@ int cdftext::open_input( const char filename[] ) { int fd = open(filename, O_RDONLY); if( fd == -1 ) { - dbgmsg( "could not open '%s': %m", filename ); + dbgmsg( "could not open '%s': %s", filename, xstrerror(errno) ); } verbose_file_reader = NULL != getenv("GCOBOL_TEMPDIR"); @@ -1556,9 +1611,9 @@ cdftext::open_input( const char filename[] ) { int cdftext::open_output() { char *name = getenv("GCOBOL_TEMPDIR"); - int fd; if( name && 0 != strcmp(name, "/") ) { + int fd; char * stem = xasprintf("%sXXXXXX", name); if( -1 == (fd = mkstemp(stem)) ) { cbl_err( "could not open temporary file '%s' (%s)", @@ -1630,7 +1685,7 @@ bool lexio_dialect_mf(); */ static const char * valid_sequence_area( const char *data, const char *eodata ) { - + for( const char *p = data; (p = std::find_if(p, eodata, is_p)) != eodata; p++ ) @@ -1653,7 +1708,7 @@ valid_sequence_area( const char *data, const char *eodata ) { } } } - return nullptr; + return nullptr; } /* @@ -1685,26 +1740,21 @@ cdftext::free_form_reference_format( int input ) { size_t lineno; bytespan_t line; // construct with length zero - current_line_t( char data[] ) : lineno(0), line(data, data) {} + explicit current_line_t( char data[] ) : lineno(0), line(data, data) {} } current( mfile.data ); /* - * Infer source code format. + * Infer source code format. */ - if( indicator.inference_pending() ) { + if( cdf_source_format().inference_pending() ) { const char *bol = valid_sequence_area(mfile.data, mfile.eodata); if( bol ) { - indicator.column = 7; - if( infer_reference_format(bol, mfile.eodata) ) { - indicator.right_margin = 73; - } + cdf_source_format().infer( bol, infer_reference_format(bol, mfile.eodata) ); } - - dbgmsg("%s:%d: %s format detected", __func__, __LINE__, - indicator.description()); } while( mfile.next_line() ) { + check_push_pop_directive(mfile); check_source_format_directive(mfile); remove_inline_comment(mfile.cur, mfile.eol); @@ -1825,9 +1875,8 @@ cdftext::free_form_reference_format( int input ) { void cdftext::process_file( filespan_t mfile, int output, bool second_pass ) { static size_t nfiles = 0; - std::list<replace_t> replacements; - __gnu_cxx::stdio_filebuf<char> outbuf(fdopen(output, "w"), std::ios::out); + __gnu_cxx::stdio_filebuf<char> outbuf(fdopen(output, "a"), std::ios::out); std::ostream out(&outbuf); std::ostream_iterator<char> ofs(out); @@ -1854,7 +1903,7 @@ cdftext::process_file( filespan_t mfile, int output, bool second_pass ) { []( char ch ) { return ch == '\n'; } ); struct { int in, out; filespan_t mfile; } copy; dbgmsg("%s:%d: line " HOST_SIZE_T_PRINT_UNSIGNED ", opening %s on fd %d", - __func__, __LINE__,mfile.lineno(), + __func__, __LINE__, (fmt_size_t)mfile.lineno(), copybook.source(), copybook.current()->fd); copy.in = copybook.current()->fd; copy.mfile = free_form_reference_format( copy.in ); @@ -1890,31 +1939,12 @@ cdftext::process_file( filespan_t mfile, int output, bool second_pass ) { continue; // No active REPLACE directive. } - std::list<span_t> segments = segment_line(mfile); // no replace yields - // // 1 segment + std::list<span_t> segments = segment_line(mfile); for( const auto& segment : segments ) { std::copy(segment.p, segment.pend, ofs); } - if( segments.size() == 2 ) { - struct { - size_t before, after; - int delta() const { return before - after; } } nlines; - nlines.before = std::count(segments.front().p, - segments.front().pend, '\n'); - nlines.after = std::count(segments.back().p, segments.back().pend, '\n'); - if( nlines.delta() < 0 ) { - yywarn("line %zu: REPLACED %zu lines with %zu lines, " - "line count off by %d", mfile.lineno(), - nlines.before, nlines.after, nlines.delta()); - } - int nnl = nlines.delta(); - while( nnl-- > 0 ) { - static const char nl[] = "\n"; - std::copy(nl, nl + 1, ofs); - } - } out.flush(); } // end of file @@ -1938,12 +1968,30 @@ cdftext::segment_line( filespan_t& mfile ) { return output; } + /* + * If the replacement changes the number of lines in the replaced text, we + * need to reset the line number, because the next statement is on a + * different line in the manipulated text than in the original. Before each + * replacement, set the original line number. After each replacement, set + * the line number after the elided text on the next line. + */ for( const replace_t& segment : pending ) { gcc_assert(mfile.cur <= segment.before.p); gcc_assert(segment.before.pend <= mfile.eodata); + struct { unsigned long ante, post; } lineno = { + gb4(mfile.lineno()), gb4(mfile.lineno() + segment.after.nlines()) + }; + const char *directive = lineno.ante == lineno.post? + nullptr : xasprintf("\n#line %lu \"%s\"\n", + lineno.ante, cobol_filename()); + + if( directive ) + output.push_back( span_t(strlen(directive), directive) ); output.push_back( span_t(mfile.cur, segment.before.p) ); output.push_back( span_t(segment.after.p, segment.after.pend ) ); + if( directive ) + output.push_back( span_t(strlen(directive), directive) ); mfile.cur = const_cast<char*>(segment.before.pend); } @@ -1959,5 +2007,3 @@ cdftext::segment_line( filespan_t& mfile ) { return output; } - -//////// End of the cdf_text.h file diff --git a/gcc/cobol/lexio.h b/gcc/cobol/lexio.h index ed642afbf16a..ba4ef0adb8e6 100644 --- a/gcc/cobol/lexio.h +++ b/gcc/cobol/lexio.h @@ -69,7 +69,9 @@ erase_source( char *src, char *esrc ) { struct bytespan_t { char *data, *eodata; - bytespan_t( char *data = NULL, char *eodata = NULL ) + bytespan_t() : data( nullptr), eodata(nullptr) {} + + bytespan_t( char *data, char *eodata ) : data(data), eodata(eodata) { if( eodata < data ) { @@ -110,19 +112,7 @@ struct bytespan_t { } }; -/* Location type. Borrowed from parse.h as generated by Bison. */ -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE YYLTYPE; -struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -}; -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif +// YYLTYPE supplied by cbldiag.h. Borrowed from parse.h as generated by Bison. struct filespan_t : public bytespan_t { char *cur, *eol, *quote; @@ -136,7 +126,7 @@ struct filespan_t : public bytespan_t { {} filespan_t(void *p, size_t len) : bytespan_t( static_cast<char*>(p), static_cast<char*>(p) + len ) - , cur(data), eol(data), quote(NULL), iline(0), line_quote72(0) + , cur(data), eol(data), quote(NULL), iline(0), icol(0), line_quote72(0) {} size_t lineno() const { return iline; } @@ -236,6 +226,7 @@ struct span_t { span_t( const char *data, const char *eodata ) : p(data), pend(eodata) { verify(); } + // cppcheck-suppress operatorEqRetRefThis span_t& operator=( const csub_match& cm ) { p = cm.first; pend = cm.second; @@ -244,6 +235,8 @@ struct span_t { int size() const { return pend - p; } + size_t nlines() const { return p && pend? std::count(p, pend, '\n') : 0; } + span_t dup() const { auto output = new char[size() + 1]; auto eout = std::copy(p, pend, output); @@ -251,15 +244,22 @@ struct span_t { return span_t(output, eout); } const char * has_nul() const { - auto p = std::find(this->p, pend, '\0'); - return p != pend? p : NULL; + auto p_l = std::find(this->p, pend, '\0'); + return p_l != pend? p_l : NULL; + } + + bool at_eol() const { + return p < pend && '\n' == pend[-1]; + } + const char * optional_eol() const { + return at_eol() ? "" : "\n"; } }; struct replace_t { struct span_t before, after; - replace_t( span_t before = span_t(), - span_t after = span_t() ) + replace_t() : before(span_t()), after(span_t()) {} + replace_t( span_t before, span_t after ) : before(before), after(after) {} replace_t& reset() { diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y index a3195fead4d9..59cc64ddeca4 100644 --- a/gcc/cobol/parse.y +++ b/gcc/cobol/parse.y @@ -45,6 +45,7 @@ }; enum accept_func_t { + accept_e, accept_done_e, accept_command_line_e, accept_envar_e, @@ -188,14 +189,14 @@ data_category_t category; category_map_t replacement; - init_statement_t( category_map_t replacement ) + explicit init_statement_t( const category_map_t& replacement ) : to_value(false) , category(data_category_none) , replacement(replacement) {} - init_statement_t( bool to_value = false ) + explicit init_statement_t( bool to_value = false ) : to_value(to_value) , category(data_category_none) , replacement(category_map_t()) @@ -242,7 +243,7 @@ struct Elem_list_t { std::list<E> elems; Elem_list_t() {} - Elem_list_t( E elem ) { + explicit Elem_list_t( E elem ) { elems.push_back(elem); } Elem_list_t * push_back( E elem ) { @@ -349,7 +350,7 @@ %token <string> SECTION %token <number> STANDARD_ALPHABET "STANDARD ALPHABET" %token <string> SWITCH -%token <string> UPSI +%token <string> UPSI %token <number> ZERO /* environment names */ @@ -385,7 +386,10 @@ CDF_EVALUATE ">>EVALUATE" CDF_WHEN ">>WHEN" CDF_END_EVALUATE ">>END-EVALUATE" + CALL_CONVENTION ">>CALL-CONVENTION" CALL_COBOL "CALL" CALL_VERBATIM "CALL (as C)" + CDF_PUSH ">>PUSH" CDF_POP ">>POP" + SOURCE_FORMAT ">>SOURCE FORMAT" IF THEN ELSE SENTENCE @@ -399,7 +403,10 @@ STRING_kw "STRING" STOP SUBTRACT START UNSTRING WRITE WHEN - ABS ACCESS ACOS ACTUAL ADVANCING AFTER ALL + ARGUMENT_NUMBER ARGUMENT_VALUE + ENVIRONMENT_NAME ENVIRONMENT_VALUE + + ABS ACCESS ACOS ACTUAL ADVANCING AFTER ALL ALLOCATE ALPHABET ALPHABETIC ALPHABETIC_LOWER "ALPHABETIC-LOWER" ALPHABETIC_UPPER "ALPHABETIC-UPPER" @@ -692,7 +699,7 @@ %type <string> fd_name picture_sym name66 paragraph_name %type <literal> literalism %type <number> bound advance_when org_clause1 read_next -%type <number> access_mode multiple lock_how lock_mode +%type <number> access_mode multiple lock_how lock_mode org_is %type <select_clauses> select_clauses %type <select_clause> select_clause access_clause alt_key_clause assign_clause collate_clause status_clause @@ -732,7 +739,7 @@ %type <refer> inspected %type <insp_qual> insp_qual -%type <insp_match> insp_quals insp_mtquals tally_match +%type <insp_match> insp_quals insp_mtqual tally_match %type <insp_replace> x_by_y %type <insp_oper> replace_oper x_by_ys %type <insp_oper> tally_forth tally_matches @@ -793,6 +800,8 @@ %type <error_clauses> io_invalids read_eofs write_eops %type <boolean> io_invalid read_eof write_eop global is_global anycase backward + end_display + exh_changed exh_named %type <number> mistake globally first_last %type <io_mode> io_mode @@ -831,6 +840,9 @@ %type <opt_arith> opt_arith_type %type <module_type> module_type +%type <nameloc> repo_func_name +%type <namelocs> repo_func_names + %union { bool boolean; int number; @@ -840,10 +852,12 @@ cbl_field_attr_t field_attr; ec_type_t ec_type; ec_list_t* ec_list; + cbl_nameloc_t *nameloc; + cbl_namelocs_t *namelocs; declarative_list_t* dcl_list_t; isym_list_t* isym_list; struct { radix_t radix; char *string; } numstr; - struct { int token; literal_t name; } prog_end; + struct { YYLTYPE loc; int token; literal_t name; } prog_end; struct { int token; special_name_t id; } special_type; struct { cbl_field_type_t type; uint32_t capacity; bool signable; } computational; @@ -880,9 +894,9 @@ struct arith_t *arith; struct { size_t ntgt; cbl_num_result_t *tgts; cbl_refer_t *expr; } compute_body_t; - struct ast_inspect_t *insp_one; - struct ast_inspect_list_t *insp_all; - struct ast_inspect_oper_t *insp_oper; + struct cbl_inspect_t *insp_one; + cbl_inspect_opers_t *insp_all; + struct cbl_inspect_oper_t *insp_oper; struct { bool before; cbl_inspect_qual_t *qual; } insp_qual; cbl_inspect_t *inspect; cbl_inspect_match_t *insp_match; @@ -897,7 +911,7 @@ struct refer_pair_t { cbl_refer_t *first, *second; } refer2; struct { refer_collection_t *inputs; refer_pair_t into; } str_body; - struct { accept_func_t func; cbl_refer_t *into, *from; } accept_func; + struct { accept_func_t func; cbl_refer_t *into, *from; special_name_t special;} accept_func; struct unstring_into_t *uns_into; struct unstring_tgt_list_t *uns_tgts; struct unstring_tgt_t *uns_tgt; @@ -999,7 +1013,9 @@ %right IF THEN ELSE SENTENCE ACCEPT ADD ALTER CALL CANCEL CLOSE COMPUTE CONTINUE - DELETE DISPLAY DIVIDE EVALUATE END EOP EXIT FILLER_kw + DELETE DISPLAY DIVIDE + EVALUATE END EOP EXIT + FILLER_kw GOBACK GOTO INITIALIZE INSPECT MERGE MOVE MULTIPLY OPEN OVERFLOW_kw PARAGRAPH PERFORM @@ -1320,7 +1336,7 @@ return ok; } - static void initialize_allocated( cbl_refer_t input ); + static void initialize_allocated( const cbl_refer_t& input ); static void initialize_statement( std::list<cbl_num_result_t>& tgts, bool with_filler, @@ -1453,21 +1469,22 @@ id_div: cdf_words IDENTIFICATION_DIV '.' program_id cdf_words: %empty | cobol_words + /* | error { error_msg(@1, "not a COBOL-WORD"); } */ ; cobol_words: cobol_words1 | cobol_words cobol_words1 ; cobol_words1: COBOL_WORDS EQUATE NAME[keyword] WITH NAME[name] { - if( ! tokens.equate(@keyword, $keyword, $name) ) { YYERROR; } + if( ! cdf_tokens.equate(@keyword, $keyword, $name) ) { YYERROR; } } | COBOL_WORDS UNDEFINE NAME[keyword] { - if( ! tokens.undefine(@keyword, $keyword) ) { YYERROR; } + if( ! cdf_tokens.undefine(@keyword, $keyword) ) { YYERROR; } } | COBOL_WORDS SUBSTITUTE NAME[keyword] BY NAME[name] { - if( ! tokens.substitute(@keyword, $keyword, $name) ) { YYERROR; } + if( ! cdf_tokens.substitute(@keyword, $keyword, $name) ) { YYERROR; } } | COBOL_WORDS RESERVE NAME[name] { - if( ! tokens.reserve(@name, $name) ) { YYERROR; } + if( ! cdf_tokens.reserve(@name, $name) ) { YYERROR; } } ; @@ -1481,7 +1498,7 @@ program_id: PROGRAM_ID dot namestr[name] program_as program_attrs[attr] dot const char *name = string_of($name); parser_enter_program( name, false, &main_error ); if( main_error ) { - error_msg(@name, "PROGRAM-ID 'main' is invalid with -main option"); + error_msg(@name, "PROGRAM-ID 'main' is invalid with %<-main%> option"); YYERROR; } @@ -1507,7 +1524,7 @@ program_as: %empty { static const literal_t empty {}; $$ = empty; } | AS LITERAL { $$ = $2; } ; -function_id: FUNCTION '.' NAME program_as program_attrs[attr] '.' +function_id: FUNCTION NAME program_as program_attrs[attr] '.' { internal_ebcdic_lock(); current_division = identification_div_e; @@ -1517,7 +1534,8 @@ function_id: FUNCTION '.' NAME program_as program_attrs[attr] '.' int main_error = 0; parser_enter_program( $NAME, true, &main_error ); if( main_error ) { - error_msg(@NAME, "FUNCTION-ID 'main' is invalid with -main option"); + error_msg(@NAME, "FUNCTION-ID %<main%> is invalid " + "with %<-main%> option"); YYERROR; } if( symbols_begin() == symbols_end() ) { @@ -1540,7 +1558,7 @@ function_id: FUNCTION '.' NAME program_as program_attrs[attr] '.' current.udf_add(current_program_index()); if( nparse_error > 0 ) YYABORT; } - | FUNCTION '.' NAME program_as is PROTOTYPE '.' + | FUNCTION NAME program_as is PROTOTYPE '.' { cbl_unimplemented("FUNCTION PROTOTYPE"); } @@ -1588,7 +1606,7 @@ opt_binary: FLOAT_BINARY default_kw is HIGH_ORDER_LEFT { cbl_unimplementedw("HIGH-ORDER-LEFT was ignored"); if( ! current.option_binary(cbl_options_t::high_order_left_e) ) { - error_msg(@3, "unable to set HIGH_ORDER_LEFT"); + error_msg(@3, "unable to set %<HIGH_ORDER_LEFT%>"); } } | FLOAT_BINARY default_kw is HIGH_ORDER_RIGHT[opt] @@ -1831,7 +1849,7 @@ select: SELECT optional NAME[name] select_clauses[clauses] '.' cbl_file_t *file = $clauses.file; file->optional = $optional; - file->line = yylineno; + file->line = @name.first_line; if( !namcpy(@clauses, file->name, $name) ) YYERROR; if( ! ($clauses.clauses & assign_clause_e) ) { @@ -1904,7 +1922,7 @@ select: SELECT optional NAME[name] select_clauses[clauses] '.' cbl_file_t file = protofile; file.optional = $optional; - file.line = yylineno; + file.line = @name.first_line; if( !namcpy(@name, file.name, $name) ) YYERROR; if( file_add(@name, &file) == NULL ) YYERROR; @@ -1948,7 +1966,7 @@ select_clauses: select_clause { $$.clauses = $1.clause; $$.file = $1.file; } if( $$.file->nkey++ == 0 ) { // If no key yet exists, create room for it and the // present alternate. - assert($$.file->keys == &cbl_file_t::no_key); + assert($$.file->keys == nullptr); $$.file->keys = new cbl_file_key_t[++$$.file->nkey]; } { @@ -1960,8 +1978,7 @@ select_clauses: select_clause { $$.clauses = $1.clause; $$.file = $1.file; } // Assign the alternate key to the last element, // and update the pointer. *alt = $part.file->keys[0]; - delete[] $$.file->keys; - $$.file->keys = keys; + $$.file->keys_update(keys); } break; case assign_clause_e: @@ -2030,11 +2047,11 @@ select_clauses: select_clause { $$.clauses = $1.clause; $$.file = $1.file; } YYERROR; } if( $$.file->nkey == 0 ) { + assert( 1 == $part.file->nkey ); $$.file->nkey = $part.file->nkey; - $$.file->keys = $part.file->keys; - } else { - $$.file->keys[0] = $part.file->keys[0]; - } + $$.file->keys = new cbl_file_key_t[1]; + } + $$.file->keys[0] = $part.file->keys[0]; break; /* case password_clause_e: */ case file_status_clause_e: @@ -2192,14 +2209,28 @@ org_clause: org_clause1[org] $$.file->org = static_cast<cbl_file_org_t>($org); } ; -org_is: %empty - | ORGANIZATION is +org_is: %empty { $$ = 0; } + | ORGANIZATION is { $$ = 0; } + | ORGANIZATION is RECORD { $$ = RECORD; } + | RECORD { $$ = RECORD; } ; // file_sequential is the proper default -org_clause1: org_is SEQUENTIAL { $$ = file_sequential_e; } - | org_is LINE SEQUENTIAL { $$ = file_line_sequential_e; } - | org_is RELATIVE { $$ = file_relative_e; } - | org_is INDEXED { $$ = file_indexed_e; } +org_clause1: org_is SEQUENTIAL { + $$ = $1 == RECORD? file_line_sequential_e : file_sequential_e; + } + | org_is LINE SEQUENTIAL + { + if( $1 ) error_msg(@2, "syntax error: invalid %<RECORD%>"); + $$ = file_line_sequential_e; + } + | org_is RELATIVE { + if( $1 ) error_msg(@2, "syntax error: invalid %<RECORD%>"); + $$ = file_relative_e; + } + | org_is INDEXED { + if( $1 ) error_msg(@2, "syntax error: invalid %<RECORD%>"); + $$ = file_indexed_e; + } ; /* @@ -2298,8 +2329,8 @@ config_paragraph: } } } - | REPOSITORY '.' - | REPOSITORY '.' repo_members '.' + | REPOSITORY dot + | REPOSITORY dot repo_members '.' ; repo_members: repo_member @@ -2327,38 +2358,61 @@ repo_expands: %empty repo_interface: INTERFACE NAME repo_as repo_expands ; -repo_func: FUNCTION repo_func_names INTRINSIC - { - auto namelocs( name_queue.pop() ); - for( const auto& nameloc : namelocs ) { - current.repository_add(nameloc.name); +repo_func: FUNCTION repo_func_names[namelocs] INTRINSIC { + for( const auto& nameloc : *$namelocs ) { + if( 0 == intrinsic_token_of(nameloc.name) ) { + error_msg(nameloc.loc, + "no such intrinsic function: %qs", + nameloc.name); + continue; + } + current.repository_add(nameloc.name); } } | FUNCTION ALL INTRINSIC { current.repository_add_all(); } - | FUNCTION repo_func_names - ; -repo_func_names: - repo_func_name - | repo_func_names repo_func_name - ; -repo_func_name: NAME { - if( ! current.repository_add($NAME) ) { // add intrinsic by name - auto token = current.udf_in($NAME); + | FUNCTION repo_func_names[namelocs] { + // We allow multiple names because GnuCOBOL does. ISO says 1. + for( const auto& nameloc : *$namelocs ) { + if( 0 != intrinsic_token_of(nameloc.name) ) { + error_msg(nameloc.loc, + "intrinsic function %qs requires INTRINSIC", + nameloc.name); + continue; + } + auto token = current.udf_in(nameloc.name); if( !token ) { - error_msg(@NAME, "%s is not defined here as a user-defined function", - $NAME); - current.udf_dump(); - YYERROR; + error_msg(nameloc.loc, + "%s is not defined here as a user-defined function", + nameloc.name); + continue; } - auto e = symbol_function(0, $NAME); + auto e = symbol_function(0, nameloc.name); assert(e); current.repository_add(symbol_index(e)); // add UDF to repository } } ; +repo_func_names: + repo_func_name[name] { + $$ = new cbl_namelocs_t(1, *$name); + delete $name; + } + | repo_func_names repo_func_name[name] { + $$ = $1; + $$->push_back(*$name); + delete $name; + } + ; +repo_func_name: NAME repo_as { + if( ! $repo_as.empty() ) { + cbl_unimplemented_at(@repo_as, "%qs", $repo_as.data); + } + $$ = new cbl_nameloc_t(@NAME, $NAME); + } + ; repo_program: PROGRAM_kw NAME repo_as { @@ -2390,7 +2444,7 @@ repo_program: PROGRAM_kw NAME repo_as assert(program); prog.data.initial = program->name; } - auto e = symbol_field_add(PROGRAM, &prog); + const auto e = symbol_field_add(PROGRAM, &prog); symbol_field_location(symbol_index(e), @NAME); } ; @@ -2430,7 +2484,7 @@ special_name: dev_mnemonic | CLASS NAME is domains { struct cbl_field_t field = { 0, - FldClass, FldInvalid, 0, 0, 0, 0, nonarray, yylineno, "", + FldClass, FldInvalid, 0, 0, 0, 0, nonarray, @NAME.first_line, "", 0, cbl_field_t::linkage_t(), {}, NULL }; if( !namcpy(@NAME, field.name, $2) ) YYERROR; @@ -2520,7 +2574,7 @@ dev_mnemonic: device_name is NAME { auto p = cmd_or_env_special_of($device); if( !p ) { - error_msg(@device, "%s is not a device name"); + error_msg(@device, "%s is not a device name", $device); YYERROR; } @@ -2561,6 +2615,10 @@ device_name: SYSIN { $$.token = SYSIN; $$.id = SYSIN_e; } | STDIN { $$.token = STDIN; $$.id = STDIN_e; } | STDOUT { $$.token = STDOUT; $$.id = STDOUT_e; } | STDERR { $$.token = STDERR; $$.id = STDERR_e; } + /* These cannot be both ctx_name and here. * + /* ARGUMENT_NUMBER { $$.token=0; $$.id = ARG_NUM_e; } */ + /* ENVIRONMENT_NAME { $$.token=0; $$.id = ENV_NAME_e; } */ + /* ENVIRONMENT_VALUE { $$.token=0; $$.id = ENV_VALUE_e; } */ ; alphabet_name: STANDARD_ALPHABET { $$ = alphabet_add(@1, ASCII_e); } @@ -2592,7 +2650,8 @@ alphabet_seqs: alphabet_seq[seq] YYERROR; } $$->add_sequence(@seq, $seq.low); - size_t len = $seq.low == nul_string()? 1 : strlen((const char*)$seq.low); + size_t len = $seq.low == nul_string()? + 1 : strlen((const char*)$seq.low); assert(len > 0); $$->add_interval(@seq, $seq.low[--len], $seq.high[0]); $$->add_sequence(@seq, $seq.high); @@ -2645,17 +2704,19 @@ alphabet_seq: alphabet_lit[low] alphabet_etc: alphabet_lit { if( $1.len > 1 ) { - error_msg(@1, "'%c' can be only a single letter", $1.data); + error_msg(@1, "%qs can be only a single letter", $1.data); YYERROR; } $$ = (unsigned char)$1.data[0]; } | spaces_etc { - // For figurative constants, pass the synmbol table index, + // For figurative constants, pass the symbol table index, // marked with the high bit. static const auto bits = sizeof($$) * 8 - 1; - $$ = 1; - $$ = $$ << bits; + unsigned int high_bit = 1L << bits; + static_assert(sizeof($$) == sizeof(high_bit), + "adjust high_bit to match size of nonterminal target"); + memcpy(&$$, &high_bit, sizeof($$)); $$ |= constant_index($1); } ; @@ -2829,7 +2890,7 @@ domain: all LITERAL[a] if( ! string_of($value) ) { yywarn("'%s' has embedded NUL", $value.data); } - char *dom = $value.data; + const char *dom = $value.data; $$ = new cbl_domain_t(@value, false, $value.len, dom); } | when_set_to FALSE_kw is reserved_value @@ -2909,7 +2970,7 @@ fd_clause: record_desc f->varying_size.explicitly = f->varies(); if( f->varying_size.max != 0 ) { if( !(f->varying_size.min <= f->varying_size.max) ) { - error_msg(@1, "%zu must be <= %zu", + error_msg(@1, "%zu must be less than or equal to %zu", f->varying_size.min, f->varying_size.max); YYERROR; } @@ -2950,7 +3011,7 @@ fd_clause: record_desc f->attr |= external_e; cbl_unimplemented("AS LITERAL"); } - | fd_linage + | fd_linage { cbl_unimplemented("LINAGE"); } | fd_report { cbl_unimplemented("REPORT WRITER"); YYERROR; @@ -2985,7 +3046,7 @@ rec_contains: NUMSTR[min] { } $$.max = n; if( !($$.min < $$.max) ) { - error_msg(@max, "FROM (%xz) must be less than TO (%zu)", + error_msg(@max, "FROM (%zu) must be less than TO (%zu)", $$.min, $$.max); YYERROR; } @@ -3118,7 +3179,7 @@ depending: %empty assert(e->type == SymField); odo = symbol_index(e); } else { - e = symbol_field_forward_add(PROGRAM, 0, $NAME, yylineno); + e = symbol_field_forward_add(PROGRAM, 0, $NAME, @NAME.first_line); if( !e ) YYERROR; symbol_field_location( symbol_index(e), @NAME ); odo = field_index(cbl_field_of(e)); @@ -3181,7 +3242,7 @@ field: cdf } initial = string_of(field.data.value_of()); if( !initial ) { - error_msg(@1, xstrerror(errno)); + error_msg(@1, "could not convert value to string"); YYERROR; } char decimal = symbol_decimal_point(); @@ -3289,9 +3350,9 @@ index_field1: ctx_name[name] auto symbol = symbol_field(PROGRAM, field.parent, $name); if( symbol ) { - auto field( cbl_field_of(symbol) ); + auto f( cbl_field_of(symbol) ); error_msg(@name, "'%s' already defined on line %d", - field->name, field->line ); + f->name, f->line ); YYERROR; } @@ -3318,7 +3379,7 @@ level_name: LEVEL ctx_name } struct cbl_field_t field = { 0, FldInvalid, FldInvalid, 0, 0, 0, capacity_cast($1), - nonarray, yylineno, "", + nonarray, @ctx_name.first_line, "", 0, cbl_field_t::linkage_t(), {}, NULL }; if( !namcpy(@ctx_name, field.name, $2) ) YYERROR; @@ -3343,7 +3404,7 @@ level_name: LEVEL ctx_name } struct cbl_field_t field = { 0, FldInvalid, FldInvalid, 0, 0, 0, capacity_cast($1), - nonarray, yylineno, "", + nonarray, @LEVEL.first_line, "", 0, {}, {}, NULL }; $$ = field_add(@1, &field); @@ -3384,7 +3445,7 @@ value78: literalism } | reserved_value[value] { - auto field = constant_of(constant_index($value)); + const auto field = constant_of(constant_index($value)); $$ = new cbl_field_data_t(field->data); } @@ -3481,7 +3542,7 @@ data_descr1: level_name } struct cbl_field_t field = { 0, FldLiteralA, FldInvalid, constant_e, 0, 0, 78, nonarray, - yylineno, "", 0, {}, *$data, NULL }; + @name.first_line, "", 0, {}, *$data, NULL }; if( !namcpy(@name, field.name, $name) ) YYERROR; if( field.data.initial ) { field.attr |= quoted_e; @@ -3504,7 +3565,7 @@ data_descr1: level_name | LEVEL88 NAME /* VALUE */ NULLPTR { struct cbl_field_t field = { 0, - FldClass, FldInvalid, 0, 0, 0, 88, nonarray, yylineno, "", + FldClass, FldInvalid, 0, 0, 0, 88, nonarray, @NAME.first_line, "", 0, cbl_field_t::linkage_t(), {}, NULL }; if( !namcpy(@NAME, field.name, $2) ) YYERROR; @@ -3530,7 +3591,7 @@ data_descr1: level_name | LEVEL88 NAME VALUE domains { struct cbl_field_t field = { 0, - FldClass, FldInvalid, 0, 0, 0, 88, nonarray, yylineno, "", + FldClass, FldInvalid, 0, 0, 0, 88, nonarray, @NAME.first_line, "", 0, cbl_field_t::linkage_t(), {}, NULL }; if( !namcpy(@NAME, field.name, $2) ) YYERROR; @@ -3635,7 +3696,7 @@ data_descr1: level_name } if( field_index($thru) <= field_index($orig) ) { error_msg(@orig, "cannot RENAME %s %s THRU %s %s " - "because they're in the wrong order", + "because they are in the wrong order", $orig->level_str(), name_of($orig), $thru->level_str(), name_of($thru)); YYERROR; @@ -3677,7 +3738,7 @@ data_descr1: level_name case FldNumericEdited: if( $field->has_attr(signable_e) ) { error_msg(@2, "%s has 'S' in PICTURE, cannot be BLANK WHEN ZERO", - $field->name, cbl_field_type_str($field->type) ); + $field->name ); } break; default: @@ -3755,7 +3816,7 @@ data_descr1: level_name $field->report_invalid_initial_value(@data_clauses); // verify REDEFINES - auto parent = parent_of($field); + const auto parent = parent_of($field); if( parent && $field->level == parent->level ) { valid_redefine(@field, $field, parent); // calls yyerror } @@ -3888,10 +3949,10 @@ data_clauses: data_clause auto redefined = symbol_redefines(field); if( redefined && redefined->type == FldPointer ) { if( yydebug ) { - yywarn("expanding %s size from %u bytes to %zu " - "because it redefines %s with USAGE POINTER", + yywarn("expanding %s size from %u bytes to %wd " + "because it redefines %s with %<USAGE POINTER%>", field->name, field->size(), - (size_t)int_size_in_bytes(ptr_type_node), + int_size_in_bytes(ptr_type_node), redefined->name); } field->embiggen(); @@ -3982,7 +4043,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft] field->data.capacity = type_capacity(field->type, $4); field->data.digits = $4; if( long(field->data.digits) != $4 ) { - error_msg(@2, "indicated size would be %ld bytes, " + error_msg(@2, "indicated size would be %d bytes, " "maximum data item size is %u", $4, UINT32_MAX); } @@ -4052,7 +4113,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft] (dialect_gnu() || dialect_mf()) ) { // PIC X COMP-X or COMP-9 if( ! field->has_attr(all_x_e) ) { - error_msg(@2, "COMP PICTURE requires all X's or all 9's"); + error_msg(@2, "COMP PICTURE requires all X%'s or all 9%'s"); YYERROR; } } else { @@ -4087,7 +4148,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft] } ERROR_IF_CAPACITY(@PIC, field); if( !is_numeric_edited($picture) ) { - error_msg(@picture, numed_message); + error_msg(@picture, "%s", numed_message); YYERROR; } field->data.picture = $picture; @@ -4166,7 +4227,7 @@ alphanum_part: ALNUM[picture] count $$.nbyte += count; // AX9(3) has count 5 } if( count < 0 ) { - error_msg(@2, "PICTURE count '(%d)' is negative", count ); + error_msg(@2, "PICTURE count %<(%d)%> is negative", count ); YYERROR; } } @@ -4185,7 +4246,7 @@ nine: %empty { $$ = 0; } { $$ = $1; if( $$ == 0 ) { - error_msg(@1, "'(0)' invalid in PICTURE (ISO 2023 13.18.40.3)"); + error_msg(@1, "%<(0)%> invalid in PICTURE (ISO 2023 13.18.40.3)"); } } ; @@ -4199,14 +4260,14 @@ count: %empty { $$ = 0; } REAL_VALUE_TYPE rn = numstr2i($NUMSTR.string, $NUMSTR.radix); $$ = real_to_integer (&rn); if( $$ == 0 ) { - error_msg(@2, "'(0)' invalid in PICTURE (ISO 2023 13.18.40.3)"); + error_msg(@2, "%<0%> invalid in PICTURE (ISO 2023 13.18.40.3)"); } } | '(' NAME ')' { auto value = cdf_value($NAME); if( ! (value && value->is_numeric()) ) { - error_msg(@NAME, "PICTURE '(%s)' requires a CONSTANT value", $NAME ); + error_msg(@NAME, "PICTURE %qs requires a CONSTANT value", $NAME ); YYERROR; } int nmsg = 0; @@ -4219,13 +4280,13 @@ count: %empty { $$ = 0; } if( !real_identical (TREE_REAL_CST_PTR (field->data.value_of()), &vi) ) { nmsg++; - error_msg(@NAME, "invalid PICTURE count '(%s)'", + error_msg(@NAME, "invalid PICTURE count %<(%s)%>", field->data.initial ); } } $$ = value->as_number(); if( $$ <= 0 && !nmsg) { - error_msg(@NAME, "invalid PICTURE count '(%s)'", $NAME ); + error_msg(@NAME, "invalid PICTURE count %<(%s)%>", $NAME ); } } ; @@ -4560,7 +4621,7 @@ justified_clause: is JUSTIFIED redefines_clause: REDEFINES NAME[orig] { - struct symbol_elem_t *e = field_of($orig); + struct symbol_elem_t *e = symbol_field(PROGRAM, 0, $orig); if( !e ) { error_msg(@2, "REDEFINES target not defined"); YYERROR; @@ -4696,7 +4757,7 @@ same_clause: SAME AS name YYERROR; } - auto e = symbol_field_same_as( field, other ); + const auto e = symbol_field_same_as( field, other ); symbol_field_location( symbol_index(e), @name ); } ; @@ -4745,7 +4806,7 @@ type_clause: TYPE to typename { cbl_field_t *field = current_field(); if( $typename ) { - auto e = symbol_field_same_as(field, $typename); + const auto e = symbol_field_same_as(field, $typename); symbol_field_location( symbol_index(e), @typename ); } } @@ -4757,7 +4818,7 @@ type_clause: TYPE to typename } cbl_field_t *field = current_field(); if( $typename ) { - auto e = symbol_field_same_as(field, $typename); + const auto e = symbol_field_same_as(field, $typename); symbol_field_location( symbol_index(e), @typename ); } } @@ -4860,6 +4921,7 @@ by_value_arg: scalar declaratives: %empty | DECLARATIVES '.' <label>{ + cbl_enabled_exceptions_t& enabled_exceptions( cdf_enabled_exceptions() ); current.enabled_exception_cache = enabled_exceptions; enabled_exceptions.clear(); current.doing_declaratives(true); @@ -4878,6 +4940,7 @@ declaratives: %empty * forward reference, because we haven't yet begun to parse * nondeclarative procedures. */ + cbl_enabled_exceptions_t& enabled_exceptions( cdf_enabled_exceptions() ); parser_label_label($label); enabled_exceptions = current.enabled_exception_cache; current.enabled_exception_cache.clear(); @@ -4970,12 +5033,11 @@ statements: statement { $$ = $1; } statement: error { if( current.declarative_section_name() ) { - error_msg(@1, "missing END DECLARATIVES or SECTION name", - nparse_error); + error_msg(@1, "missing END DECLARATIVES or SECTION name"); YYABORT; } if( max_errors_exceeded(nparse_error) ) { - error_msg(@1, "max errors %d reached", nparse_error); + error_msg(@1, "max errors %zu reached", nparse_error); YYABORT; } } @@ -4993,6 +5055,7 @@ statement: error { | divide { $$ = DIVIDE; } | entry { $$ = ENTRY; } | evaluate { $$ = EVALUATE; } + | exhibit_stmt { $$ = EXHIBIT; } | exit { $$ = EXIT; } | free { $$ = FREE; } | go_to { $$ = GOTO; } @@ -5023,9 +5086,8 @@ statement: error { /* * ISO defines ON EXCEPTION only for Format 3 (screen). We - * implement extensions defined by MF and Fujitsu (and us) to - * use ACCEPT to interact with the command line and the - * environment. + * implement extensions defined by MF and Fujitsu to use ACCEPT + * to interact with the command line and the environment. * * ISO ACCEPT and some others are implemented in accept_body, * before the parser sees any ON EXCEPTION. In those cases @@ -5040,6 +5102,9 @@ accept: accept_body end_accept { switch( $accept_body.func ) { case accept_done_e: break; + case accept_e: + parser_accept(*$1.into, $1.special, nullptr, nullptr); + break; case accept_command_line_e: if( $1.from->field == NULL ) { // take next command-line arg parser_accept_command_line(*$1.into, argi, NULL, NULL); @@ -5063,6 +5128,9 @@ accept: accept_body end_accept { error_msg(@ec, "ON EXCEPTION valid only " "with ENVIRONMENT or COMMAND-LINE(n)"); break; + case accept_e: + parser_accept(*$1.into, $1.special, $ec.on_error, $ec.not_error); + break; case accept_command_line_e: if( $1.from->field == NULL ) { // take next command-line arg parser_accept_command_line(*$1.into, argi, @@ -5094,7 +5162,7 @@ end_accept: %empty %prec ACCEPT accept_body: accept_refer { $$.func = accept_done_e; - parser_accept(*$1, CONSOLE_e); + parser_accept(*$1, CONSOLE_e, nullptr, nullptr); } | accept_refer FROM DATE { @@ -5153,29 +5221,15 @@ accept_body: accept_refer } | accept_refer FROM acceptable { - cbl_field_t *argc = register_find("_ARGI"); - switch( $acceptable->id ) { - case ARG_NUM_e: - $$.func = accept_command_line_e; - $$.into = $1; - $$.from = new_reference(argc); - break; - case ARG_VALUE_e: - $$.func = accept_command_line_e; - $$.into = $1; - $$.from = cbl_refer_t::empty(); - break; - default: - $$.func = accept_done_e; - parser_accept( *$1, $acceptable->id ); - } + $$.func = accept_e; + $$.into = $1; + $$.special = $acceptable->id; } | accept_refer FROM ENVIRONMENT envar { $$.func = accept_envar_e; $$.into = $1; $$.from = $envar; - //// parser_accept_envar( *$1, *$envar ); } | accept_refer FROM COMMAND_LINE { @@ -5187,7 +5241,6 @@ accept_body: accept_refer $$.func = accept_command_line_e; $$.into = $1; $$.from = $expr; - //// parser_accept_command_line(*$1, $expr->field ); } | accept_refer FROM COMMAND_LINE_COUNT { $$.func = accept_done_e; @@ -5240,7 +5293,7 @@ accept_except: EXCEPTION { $$.not_error = NULL; $$.on_error = label_add(LblArith, - uniq_label("accept"), yylineno); + uniq_label("accept"), @1.first_line); if( !$$.on_error ) YYERROR; parser_accept_exception( $$.on_error ); @@ -5275,15 +5328,54 @@ acceptable: device_name error_msg(@NAME, "no such special name '%s'", $NAME); YYERROR; } + if( ENV_NAME_e == *special_type ) { + error_msg(@NAME, "cannot ACCEPT FROM %qs", $NAME); + YYERROR; + } // Add the name now, as a convenience. - cbl_special_name_t special = { 0, *special_type }; + int token = 0; + switch(*special_type) { + case ARG_NUM_e: token = ARGUMENT_NUMBER; break; + case ARG_VALUE_e: token = ARGUMENT_VALUE; break; + case ENV_VALUE_e: token = ENVIRONMENT_VALUE; break; + + case ENV_NAME_e: + default: + error_msg(@NAME, "cannot ACCEPT FROM %qs", $NAME); + YYERROR; + break; + } + cbl_special_name_t special = { token, *special_type }; namcpy(@NAME, special.name, $NAME); symbol_elem_t *e = symbol_special_add(PROGRAM, &special); $$ = cbl_special_name_of(e); + cbl_special_name_t& unused(*$$); + assert(unused.id); } assert($$); } + | ENVIRONMENT_VALUE { + // Add the name now, as a convenience. + cbl_special_name_t special = + { ENVIRONMENT_VALUE, ENV_VALUE_e, "ENVIRONMENT-VALUE" }; + symbol_elem_t *e = symbol_special_add(PROGRAM, &special); + $$ = cbl_special_name_of(e); + } + | ARGUMENT_NUMBER { + // Add the name now, as a convenience. + cbl_special_name_t special = + { ARGUMENT_NUMBER, ARG_NUM_e, "ARGUMENT-NUMBER" }; + symbol_elem_t *e = symbol_special_add(PROGRAM, &special); + $$ = cbl_special_name_of(e); + } + | ARGUMENT_VALUE { + // Add the name now, as a convenience. + cbl_special_name_t special = + { ARGUMENT_VALUE, ARG_VALUE_e, "ARGUMENT-VALUE" }; + symbol_elem_t *e = symbol_special_add(PROGRAM, &special); + $$ = cbl_special_name_of(e); + } ; add: add_impl end_add { ast_add($1); } @@ -5399,16 +5491,13 @@ name88: NAME88 { scalar88: name88 subscripts[subs] refmod[ref] { - size_t n = $subs->size(); - auto subscripts = new cbl_refer_t[n]; - $subs->use_list(subscripts); if( $ref.from->is_reference() || $ref.len->is_reference() ) { error_msg(@subs, "subscripts on start:len refmod " "parameters are unsupported"); YYERROR; } cbl_span_t span( $ref.from, $ref.len ); - $$ = new cbl_refer_t($1, n, subscripts, span); + $$ = new cbl_refer_t($1, $subs->vectorize(), span); } | name88 refmod[ref] { @@ -5437,7 +5526,7 @@ allocate: ALLOCATE expr[size] CHARACTERS initialized RETURNING scalar[retu { statement_begin(@1, ALLOCATE); if( $size->field->type == FldLiteralN ) { - auto size = TREE_REAL_CST_PTR ($size->field->data.value_of()); + const auto size = TREE_REAL_CST_PTR ($size->field->data.value_of()); if( real_isneg(size) || real_iszero(size) ) { error_msg(@size, "size must be greater than 0"); YYERROR; @@ -5516,46 +5605,18 @@ compute_expr: '=' { } ; -display: disp_body end_display - { - std::vector <cbl_refer_t> args($1.vargs->args.size()); - std::copy( $1.vargs->args.begin(), $1.vargs->args.end(), args.begin() ); - if( $1.special && $1.special->id == ARG_NUM_e ) { - if( $1.vargs->args.size() != 1 ) { - error_msg(@1, "ARGUMENT-NUMBER can be set to only one value"); - } - cbl_refer_t& src( $1.vargs->args.front() ); - cbl_field_t *dst = register_find("_ARGI"); - parser_move( dst, src ); - } else { - parser_display($1.special, - args.empty()? NULL : args.data(), args.size(), - DISPLAY_ADVANCE); - } - current.declaratives_evaluate(); - } - | disp_body NO ADVANCING end_display +display: disp_body end_display[advance] { - std::vector <cbl_refer_t> args($1.vargs->args.size()); - std::copy( $1.vargs->args.begin(), $1.vargs->args.end(), args.begin() ); - - if( $1.special && $1.special->id == ARG_NUM_e ) { - if( $1.vargs->args.size() != 1 ) { - error_msg(@1, "ARGUMENT-NUMBER can be set to only one value"); - } - cbl_refer_t& src( $1.vargs->args.front() ); - cbl_field_t *dst = register_find("_ARGI"); - parser_move( dst, src ); - } else { - parser_display($1.special, - args.empty()? NULL : args.data(), args.size(), - DISPLAY_NO_ADVANCE); - } + std::vector <cbl_refer_t> args($1.vargs->args.begin(), + $1.vargs->args.end()); + parser_display($1.special, args, $advance); current.declaratives_evaluate(); } ; -end_display: %empty - | END_DISPLAY +end_display: %empty { $$ = DISPLAY_ADVANCE; } + | END_DISPLAY { $$ = DISPLAY_ADVANCE; } + | NO ADVANCING { $$ = DISPLAY_NO_ADVANCE; } + | NO ADVANCING END_DISPLAY { $$ = DISPLAY_NO_ADVANCE; } ; disp_body: disp_vargs[vargs] { @@ -5586,14 +5647,62 @@ disp_upon: device_name { error_msg(@NAME, "no such special name '%s'", $NAME); YYERROR; } - // Add the name now, as a convenience. - cbl_special_name_t special = { 0, *special_type }; + // Add the name now, as a convenience. + // These may come through as a NAME, depending on how scanned. + int token = 0; + switch(*special_type) { + case ARG_NUM_e: token = ARGUMENT_NUMBER; break; + case ENV_NAME_e: token = ENVIRONMENT_NAME; break; + case ENV_VALUE_e: token = ENVIRONMENT_VALUE; break; + + case ARG_VALUE_e: + default: + error_msg(@NAME, "cannot DISPLAY UPON %qs", $NAME); + YYERROR; + break; + } + cbl_special_name_t special = { token, *special_type }; namcpy(@NAME, special.name, $NAME); e = symbol_special_add(PROGRAM, &special); } $$ = cbl_special_name_of(e); } + | ARGUMENT_NUMBER { + // Add the name now, as a convenience. + cbl_special_name_t special = + { ARGUMENT_NUMBER, ARG_NUM_e, "ARGUMENT-NUMBER" }; + symbol_elem_t *e = symbol_special_add(PROGRAM, &special); + $$ = cbl_special_name_of(e); + } + | ENVIRONMENT_NAME { + // Add the name now, as a convenience. + cbl_special_name_t special = + { ENVIRONMENT_NAME, ENV_NAME_e, "ENVIRONMENT-NAME" }; + symbol_elem_t *e = symbol_special_add(PROGRAM, &special); + $$ = cbl_special_name_of(e); + } + | ENVIRONMENT_VALUE { + // Add the name now, as a convenience. + cbl_special_name_t special = + { ENVIRONMENT_VALUE, ENV_VALUE_e, "ENVIRONMENT-VALUE" }; + symbol_elem_t *e = symbol_special_add(PROGRAM, &special); + $$ = cbl_special_name_of(e); + } + ; + +exhibit_stmt: EXHIBIT exh_changed exh_named vargs { + statement_begin(@1, EXHIBIT); + std::vector<cbl_refer_t> args( $vargs->args.begin(), + $vargs->args.end() ); + parser_exhibit( $exh_changed, $exh_named, args ); + } + ; +exh_changed: %empty { $$ = false; } + | CHANGED { $$ = true; } + ; +exh_named: %empty { $$ = false; } + | NAMED { $$ = true; } ; divide: divide_impl end_divide { ast_divide($1); } @@ -5691,19 +5800,20 @@ end_program: end_program1[end] '.' gcc_unreachable(); } if( !matches ) { - error_msg(@end, "END %s %s' does not match IDENTIFICATION DIVISION '%s'", + error_msg($end.loc, "END %s %s does not match " + "%<IDENTIFICATION DIVISION %s%>", token_name, name, prog->name); YYERROR; } if( 0 != strcasecmp(prog->name, name) ) { - error_msg(@end, "END PROGRAM '%s' does not match PROGRAM-ID '%s'", + error_msg($end.loc, "END PROGRAM '%s' does not match PROGRAM-ID '%s'", name, prog->name); YYERROR; } std::set<std::string> externals = current.end_program(); if( !externals.empty() ) { - for( auto name : externals ) { + for( const auto& name : externals ) { yywarn("%s calls external symbol '%s'", prog->name, name.c_str()); } YYERROR; @@ -5722,28 +5832,32 @@ end_program: end_program1[end] '.' token_name = "FUNCTION"; break; default: - cbl_internal_error( "END token invalid"); + cbl_internal_error( "%<END%> token invalid"); } - error_msg(@end, "END %s requires NAME before '.'", token_name); + error_msg(@end, "%<END%> %s requires %<NAME%> before %<.%>", token_name); YYERROR; } ; end_program1: END_PROGRAM namestr[name] { + $$.loc = @name; $$.token = END_PROGRAM; $$.name = $name; } | END_FUNCTION namestr[name] { + $$.loc = @name; $$.token = END_FUNCTION; $$.name = $name; } | END_PROGRAM '.' // error { + $$.loc = @1; $$.token = END_PROGRAM; } | END_FUNCTION '.' // error { + $$.loc = @1; $$.token = END_FUNCTION; } ; @@ -5798,7 +5912,7 @@ exit_with: %empty static cbl_refer_t status(rt); $$ = &status; } - auto prog = cbl_label_of(symbol_at(current_program_index())); + const auto prog = cbl_label_of(symbol_at(current_program_index())); if( prog->returning ) { $$ = new cbl_refer_t( cbl_field_of(symbol_at(prog->returning)) ); } @@ -6382,17 +6496,17 @@ eval_abbrs: rel_term[a] { auto& ev( eval_stack.current() ); auto subj( ev.subject() ); if( !subj ) { - error_msg(@1, "WHEN %s phrase exceeds " + error_msg(@1, "WHEN %qs phrase exceeds " "subject set count of %zu", - $a.term->name(), ev.subject_count()); + nice_name_of($a.term->field), ev.subject_count()); YYERROR; } if( ! ev.compatible($a.term->field) ) { auto obj($a.term->field); error_msg(@1, "subject %s, type %s, " - "cannot be compared %s, type %s", - subj->name, 3 + cbl_field_type_str(subj->type), - obj->name, 3 + cbl_field_type_str(obj->type) ); + "cannot be compared %s, type %s", + subj->name, 3 + cbl_field_type_str(subj->type), + obj->name, 3 + cbl_field_type_str(obj->type) ); } auto result = ev.compare(*$a.term); if( ! result ) YYERROR; @@ -6487,7 +6601,7 @@ true_false: TRUE_kw { $$ = TRUE_kw; } scalar: tableref { // Check for missing subscript; others already checked. - if( $1->nsubscript == 0 && 0 < dimensions($1->field) ) { + if( $1->nsubscript() == 0 && 0 < dimensions($1->field) ) { subscript_dimension_error(@1, 0, $$); } } @@ -6498,8 +6612,8 @@ tableref: tableish { $$ = $1; $$->loc = @1; if( $$->is_table_reference() ) { - if( $$->nsubscript != dimensions($$->field) ) { - subscript_dimension_error(@1, $$->nsubscript, $$); + if( $$->nsubscript() != dimensions($$->field) ) { + subscript_dimension_error(@1, $$->nsubscript(), $$); YYERROR; } } @@ -6579,7 +6693,7 @@ name: qname auto name = names.front(); names.pop_front(); auto e = symbol_field_forward_add(PROGRAM, parent, - name, yylineno); + name, @1.first_line); if( !e ) YYERROR; symbol_field_location( symbol_index(e), @qname ); parent = symbol_index(e); @@ -6609,6 +6723,10 @@ ctx_name: NAME context_word: APPLY { static char s[] ="APPLY"; $$ = s; } // screen description entry + | ARGUMENT_NUMBER { static char s[] ="ARGUMENT-NUMBER"; + $$ = s; } // Display Upon / Accept From + | ARGUMENT_VALUE { static char s[] ="ARGUMENT-VALUE"; + $$ = s; } // Accept From | ARITHMETIC { static char s[] ="ARITHMETIC"; $$ = s; } // OPTIONS paragraph | ATTRIBUTE { static char s[] ="ATTRIBUTE"; @@ -6645,6 +6763,10 @@ context_word: APPLY { static char s[] ="APPLY"; $$ = s; } // ERASE clause in a screen description entry | ENTRY_CONVENTION { static char s[] ="ENTRY-CONVENTION"; $$ = s; } // OPTIONS paragraph + | ENVIRONMENT_NAME { static char s[] ="ENVIRONMENT-NAME"; + $$ = s; } // Display Upon + | ENVIRONMENT_VALUE { static char s[] ="ENVIRONMENT-VALUE"; + $$ = s; } // Display Upon / Accept From | ERASE { static char s[] ="ERASE"; $$ = s; } // screen description entry | EXPANDS { static char s[] ="EXPANDS"; @@ -6775,7 +6897,7 @@ move: MOVE scalar TO move_tgts[tgts] { statement_begin(@1, MOVE); if( $scalar->field->type == FldIndex ) { - error_msg(@1, "'%s' cannot be MOVEd because it's an INDEX", + error_msg(@1, "%qs cannot be MOVEd because it is an %<INDEX%>", name_of($scalar->field) ); YYERROR; } @@ -6993,9 +7115,9 @@ arith_err: SIZE_ERROR *ptgt = $1 == NOT? current.compute_not_error() : current.compute_on_error(); } else { - *ptgt = label_add(LblArith, uniq_label("arith"), yylineno); + *ptgt = label_add(LblArith, uniq_label("arith"), @1.first_line); } - (*ptgt)->lain = yylineno; + (*ptgt)->lain = @1.first_line; parser_arith_error( *ptgt ); } ; @@ -7167,20 +7289,20 @@ section_kw: SECTION { if( $1 ) { if( *$1 == '-' ) { - error_msg(@1, "SECTION segment %<%s%> is negative", $1); + error_msg(@1, "SECTION segment %qs is negative", $1); } else { if( dialect_ibm() ) { int sectno; - sscanf($1, "%u", §no); + sscanf($1, "%d", §no); if( ! (0 <= sectno && sectno <= 99) ) { - error_msg(@1, "SECTION segment %<%s%> must be 0-99", $1); + error_msg(@1, "SECTION segment %qs must be 0-99", $1); } else { if(false) { // stand-in for warning, someday. - yywarn("SECTION segment %<%s%> was ignored", $1); + yywarn("SECTION segment %qs was ignored", $1); } } } else { - cbl_unimplemented("SECTION segment %<%s%> is not ISO syntax", $1); + cbl_unimplemented("SECTION segment %qs is not ISO syntax", $1); } } } @@ -7532,6 +7654,7 @@ perform_cond: UNTIL { parser_perform_conditional( &perform_current()->tgt); } perform_inline: perform_start statements END_PERFORM { location_set(@END_PERFORM); + parser_sleep(*cbl_refer_t::empty()); $$ = perform_current(); if( $perform_start == LOCATION ) { error_msg(@1, "LOCATION not valid with PERFORM Format 2"); @@ -7540,6 +7663,7 @@ perform_inline: perform_start statements END_PERFORM | perform_start END_PERFORM { location_set(@END_PERFORM); + parser_sleep(*cbl_refer_t::empty()); $$ = perform_current(); if( $perform_start == LOCATION ) { error_msg(@1, "LOCATION not valid with PERFORM Format 2"); @@ -7591,7 +7715,7 @@ perform_when1: WHEN perform_ec { std::transform( $perform_ec->elems.begin(), $perform_ec->elems.end(), std::back_inserter(perf->dcls), - []( cbl_declarative_t *p ) { + []( const cbl_declarative_t *p ) { return *p; } ); ast_enter_paragraph(when); @@ -7681,12 +7805,12 @@ except_files: except_name[ec] FILE_KW filenames { perform_ec_other: %empty %prec WHEN { - auto& ec_labels( perform_current()->ec_labels ); + const auto& ec_labels( perform_current()->ec_labels ); ast_enter_paragraph(ec_labels.other); parser_exit_paragraph(); } | WHEN OTHER { - auto& ec_labels( perform_current()->ec_labels ); + const auto& ec_labels( perform_current()->ec_labels ); ast_enter_paragraph(ec_labels.other); } exception statements %prec WHEN { @@ -7695,12 +7819,12 @@ perform_ec_other: ; perform_ec_common: %empty { - auto& ec_labels( perform_current()->ec_labels ); + const auto& ec_labels( perform_current()->ec_labels ); ast_enter_paragraph(ec_labels.common); parser_exit_paragraph(); } | WHEN COMMON { - auto& ec_labels( perform_current()->ec_labels ); + const auto& ec_labels( perform_current()->ec_labels ); ast_enter_paragraph(ec_labels.common); } exception statements { @@ -7709,18 +7833,18 @@ perform_ec_common: ; perform_ec_finally: %empty { - auto& ec_labels( perform_current()->ec_labels ); + const auto& ec_labels( perform_current()->ec_labels ); ast_enter_paragraph(ec_labels.finally); parser_exit_paragraph(); parser_label_goto(ec_labels.fini); } | FINALLY { - auto& ec_labels( perform_current()->ec_labels ); + const auto& ec_labels( perform_current()->ec_labels ); ast_enter_paragraph(ec_labels.finally); } exception statements { parser_exit_paragraph(); - auto& ec_labels( perform_current()->ec_labels ); + const auto& ec_labels( perform_current()->ec_labels ); parser_label_goto(ec_labels.fini); } ; @@ -7931,7 +8055,7 @@ raise: RAISE EXCEPTION NAME "EXCEPTION CONDITION: %s", $NAME); YYERROR; } - cbl_unimplemented("RAISE <EXCEPTION OBJECT>"); + cbl_unimplemented("RAISE %<EXCEPTION OBJECT%>"); YYERROR; } ; @@ -7998,10 +8122,6 @@ read_body: NAME read_next read_into read_key error_msg(@1, "syntax error? invalid file record name"); YYERROR; } - if( 0 && $$->access == file_access_dyn_e && $read_next >= 0 ) { - error_msg(@1, "sequential DYNAMIC access requires NEXT RECORD"); - YYERROR; - } if( $read_key->field && is_sequential($$) ) { error_msg(@1, "SEQUENTIAL file %s has no KEY", $$->name); YYERROR; @@ -8012,7 +8132,7 @@ read_body: NAME read_next read_into read_key YYERROR; } if( $read_key->field && $read_next < 0 ) { - error_msg(@1, "cannot read NEXT with KEY", $$->name); + error_msg(@1, "cannot read NEXT with KEY %qs", $$->name); YYERROR; } @@ -8449,8 +8569,8 @@ merge: MERGE { statement_begin(@1, MERGE); } USING filenames[inputs] sort_output { std::vector <cbl_key_t> keys($sort_keys->key_list.size()); - std::copy( $sort_keys->key_list.begin(), - $sort_keys->key_list.end(), keys.begin() ); + std::copy( $sort_keys->key_list.begin(), + $sort_keys->key_list.end(), keys.begin() ); size_t ninput = $inputs->files.size(); size_t noutput = $sort_output->nfile(); @@ -8469,8 +8589,7 @@ merge: MERGE { statement_begin(@1, MERGE); } out_proc = &$sort_output->tgt; } - parser_file_merge( $file, $sort_seq, - keys.size(), keys.empty()? NULL : keys.data(), + parser_file_merge( $file, $sort_seq, keys, ninput, inputs, noutput, outputs, out_proc ); @@ -8636,7 +8755,7 @@ set: SET set_tgts[tgts] TO set_operand[src] class set_conditional { bool tf; public: - set_conditional( int token ) : tf(token == TRUE_kw) {} + explicit set_conditional( int token ) : tf(token == TRUE_kw) {} void operator()(cbl_refer_t& refer) { if( refer.field->data.false_value_of() == NULL && !tf ) { auto loc = symbol_field_location(field_index(refer.field)); @@ -8661,7 +8780,7 @@ set_switches: switches TO on_off { struct switcheroo { bitop_t op; - switcheroo( bool tf ) : op( tf? bit_set_op : bit_clear_op ) {} + explicit switcheroo( bool tf ) : op( tf? bit_set_op : bit_clear_op ) {} switcheroo& operator()(cbl_field_t* sw) { assert(sw->type == FldSwitch); assert(sw->data.initial); // not a switch condition @@ -8716,12 +8835,12 @@ search_1_body: name[table] search_varying[varying] cbl_name_t label_name; auto len = snprintf(label_name, sizeof(label_name), - "linear_search_%d", yylineno); + "linear_search_%d", @1.first_line); if( ! (0 < len && len < int(sizeof(label_name))) ) { gcc_unreachable(); } cbl_label_t *name = label_add( LblSearch, - label_name, yylineno ); + label_name, @1.first_line ); auto varying($varying); if( index == varying ) varying = NULL; parser_lsearch_start( name, $table, index, varying ); @@ -8774,9 +8893,9 @@ search_binary: SEARCH ALL search_2_body search_2_cases search_2_body: name[table] { statement_begin(@$, SEARCH); - char *label_name = xasprintf("binary_search_%d", yylineno); + char *label_name = xasprintf("binary_search_%d", @1.first_line); cbl_label_t *name = label_add( LblSearch, - label_name, yylineno ); + label_name, @1.first_line ); parser_bsearch_start( name, $table ); search_alloc(name); } @@ -8801,14 +8920,14 @@ search_terms: search_term ; search_term: scalar[key] '=' search_expr[sarg] { - if( $key->nsubscript == 0 ) { + if( $key->nsubscript() == 0 ) { error_msg(@1, "no index for key"); YYERROR; } - if( dimensions($key->field) < $key->nsubscript ) { + if( dimensions($key->field) < $key->nsubscript() ) { error_msg(@1, "too many subscripts: " - "%zu for table of %zu dimensions", - $key->nsubscript, dimensions($key->field) ); + "%u for table of %zu dimensions", + $key->nsubscript(), dimensions($key->field) ); YYERROR; } @@ -8847,8 +8966,7 @@ sort_table: SORT tableref[table] sort_keys sort_dup sort_seq { keys.at(i++) = cbl_key_t(k); } - parser_sort( *$table, $sort_dup, $sort_seq, - keys.size(), keys.empty()? NULL : keys.data() ); + parser_sort( *$table, $sort_dup, $sort_seq, keys ); } | SORT tableref[table] sort_dup sort_seq { statement_begin(@1, SORT); @@ -8858,9 +8976,10 @@ sort_table: SORT tableref[table] sort_keys sort_dup sort_seq { cbl_key_t key = cbl_key_t($table->field->occurs.keys[0]), guess(1, &$table->field); - ; - if( key.nfield == 0 ) key = guess; - parser_sort( *$table, $sort_dup, $sort_seq, 1, &key ); + + if( key.fields.empty() ) key = guess; + std::vector<cbl_key_t> keys(1, key); + parser_sort( *$table, $sort_dup, $sort_seq, keys ); } ; @@ -8901,7 +9020,7 @@ sort_file: SORT FILENAME[file] sort_keys sort_dup sort_seq parser_file_sort( file, $sort_dup, $sort_seq, - keys.size(), keys.empty()? NULL : keys.data(), + keys, ninput, inputs, noutput, outputs, in_proc, out_proc ); @@ -9093,7 +9212,7 @@ backward: %empty { $$ = false; } inspect: INSPECT backward inspected TALLYING tallies { statement_begin(@1, INSPECT); - ast_inspect( *$inspected, $backward, *$tallies ); + ast_inspect( @$, *$inspected, $backward, *$tallies ); } | INSPECT backward inspected TALLYING tallies REPLACING replacements { @@ -9105,8 +9224,8 @@ inspect: INSPECT backward inspected TALLYING tallies } statement_begin(@1, INSPECT); // All tallying is done before any replacing - ast_inspect( *$inspected, $backward, *$tallies ); - ast_inspect( *$inspected, $backward, *$replacements ); + ast_inspect( @$, *$inspected, $backward, *$tallies ); + ast_inspect( @$, *$inspected, $backward, *$replacements ); } | INSPECT backward inspected REPLACING replacements { @@ -9117,11 +9236,11 @@ inspect: INSPECT backward inspected TALLYING tallies YYERROR; } statement_begin(@1, INSPECT); - ast_inspect( *$inspected, $backward, *$replacements ); + ast_inspect( @$, *$inspected, $backward, *$replacements ); } | INSPECT backward inspected CONVERTING alpha_val[match] TO all alpha_val[replace_oper] - insp_mtquals[qual] + insp_mtqual[qual] { if( $all ) { $replace_oper->all = true; @@ -9141,7 +9260,7 @@ inspect: INSPECT backward inspected TALLYING tallies if( is_literal(match) && is_literal(replace) ) { if( !$match->all && !$replace_oper->all) { if( match->data.capacity != replace->data.capacity ) { - error_msg(@match, "'%s', size %u NOT EQUAL '%s', size %u", + error_msg(@match, "%qs, size %u NOT EQUAL %qs, size %u", nice_name_of(match), match->data.capacity, nice_name_of(replace), replace->data.capacity); YYERROR; @@ -9167,7 +9286,7 @@ inspect: INSPECT backward inspected TALLYING tallies tallies: { need_nume_set(); } tally { - $$ = new ast_inspect_list_t( *$tally ); + $$ = new cbl_inspect_opers_t( 1, *$tally ); } | tallies { need_nume_set(); } tally { @@ -9177,12 +9296,17 @@ tallies: { need_nume_set(); } tally if( !next.tally.field ) { // prior tally swallowed one too many cbl_inspect_t& prior = $$->back(); - assert(prior.nbound > 0); - assert(prior.opers); - cbl_inspect_oper_t& prior_op = prior.opers[prior.nbound - 1]; - - assert(prior_op.n_identifier_3 > 0 ); - next.tally = prior_op.matches[--prior_op.n_identifier_3].matching; + assert(prior.nbound() > 0); + cbl_inspect_oper_t& prior_op = prior.back(); + assert(! prior_op.matches.empty() ); + assert(prior_op.n_identifier_3() > 0 ); + cbl_inspect_match_t wrong_match = prior_op.matches.back(); + dbgmsg("moving overeager tally to next clause"); + dump_inspect_match(wrong_match); + next.tally = wrong_match.premature_tally(); + if( wrong_match.empty() ) { + prior_op.matches.pop_back(); + } } if( !next.tally.field ) { error_msg(@$, "missing summation field before FOR"); @@ -9194,44 +9318,37 @@ tallies: { need_nume_set(); } tally /* * numref might be "empty" only because it was consumed by a - * prior insp_mtquals, which can end in a scalar. If that + * prior insp_mtqual, which can end in a scalar. If that * happens, the tallies target, above, takes back the borrowed * scalar and assigns it to be the tally total, as the user * intended. */ tally: numeref[total] FOR tally_fors[fors] - { // reduce ast_inspect_t to cbl_inspect_t + { if( yydebug && !$total ) { - error_msg(@FOR, "caution: missing summation field before FOR"); + dbgmsg("tally: caution: missing summation field before FOR"); } - cbl_refer_t total( $total? *$total : cbl_refer_t() ); - $$ = new cbl_inspect_t( total, $fors->opers() ); + $$ = $fors; + if( $total ) $$->tally = *$total; } ; -tally_fors: tally_forth - { // reduce ast_inspect_oper_t to cbl_inspect_oper_t - cbl_inspect_oper_t oper( $1->bound, $1->matches ); - $$ = new ast_inspect_t; - $$ ->push_back(oper); - } - | tally_fors tally_forth - { - cbl_inspect_oper_t oper( $2->bound, $2->matches ); - $1 ->push_back(oper); - } +tally_fors: tally_forth { $$ = new cbl_inspect_t(1, *$1); } + | tally_fors tally_forth { $$->push_back(*$2); $$ = $1; } ; -tally_forth: CHARACTERS insp_mtquals[q] scalar[next_tally] +tally_forth: CHARACTERS insp_mtqual[q] scalar[next_tally] { // Add ensuing scalar as if it were an argument to CHARACTERS. // It will be moved to the succeeding FOR as its tally. - $q->matching = *$next_tally; - $$ = new ast_inspect_oper_t(*$q); + dbgmsg("saving overeager tally for next clause"); + $q->save_premature_tally(*$next_tally); + $$ = new cbl_inspect_oper_t(*$q); + dump_inspect_match($$->matches.back()); } - | CHARACTERS insp_mtquals[q] + | CHARACTERS insp_mtqual[q] { - $$ = new ast_inspect_oper_t(*$q); + $$ = new cbl_inspect_oper_t(*$q); } | ALL tally_matches[q] { $q->bound = bound_all_e; @@ -9250,26 +9367,23 @@ tally_forth: CHARACTERS insp_mtquals[q] scalar[next_tally] } ; -tally_matches: tally_match { $$ = new ast_inspect_oper_t(*$1); } +tally_matches: tally_match { $$ = new cbl_inspect_oper_t(*$1); } | tally_matches tally_match { // add to the list of matches for an operand $1->matches.push_back(*$2); } ; -tally_match: alpha_val[matching] insp_mtquals[q] +tally_match: alpha_val[matching] insp_mtqual[q] { // include the matching field with the qualifiers $$ = $q; - $$->matching = *$matching; + $$->matching(*$matching); } ; numeref: %empty { $$ = NULL; need_nume_set(false); } | nume[name] subscripts[subs] { - size_t n = $subs->size(); - auto offsets = new cbl_refer_t[n]; - std::copy( $subs->begin(), $subs->end(), offsets ); - $$ = new cbl_refer_t($name, n, offsets); + $$ = new cbl_refer_t($name, $subs->vectorize()); } | nume { $$ = new cbl_refer_t($nume); } ; @@ -9299,13 +9413,13 @@ qnume: NUME { name_queue.qualify(@1, $1); } replacements: replacement { - cbl_inspect_t inspect( cbl_refer_t(), $1->opers() ); - $$ = new ast_inspect_list_t(inspect); + cbl_inspect_t inspect( cbl_refer_t(), *$1 ); + $$ = new cbl_inspect_opers_t(1, inspect); } ; replacement: replace_oper { - $$ = new ast_inspect_t; + $$ = new cbl_inspect_t; $$->push_back( cbl_inspect_oper_t($1->bound, $1->replaces) ); } | replacement replace_oper @@ -9313,9 +9427,9 @@ replacement: replace_oper $$->push_back( cbl_inspect_oper_t($2->bound, $2->replaces) ); } ; -replace_oper: CHARACTERS BY alpha_val[replace] insp_mtquals[q] +replace_oper: CHARACTERS BY alpha_val[replace] insp_mtqual[q] { - $$ = new ast_inspect_oper_t( cbl_inspect_replace_t(NULL, + $$ = new cbl_inspect_oper_t( cbl_inspect_replace_t(NULL, *$replace, $q->before, $q->after) ); @@ -9329,21 +9443,22 @@ replace_oper: CHARACTERS BY alpha_val[replace] insp_mtquals[q] x_by_ys: x_by_y { - $$ = new ast_inspect_oper_t(*$1); + $$ = new cbl_inspect_oper_t(*$1); } | x_by_ys x_by_y { $$->replaces.push_back(*$2); } ; -x_by_y: alpha_val[matching] BY alpha_val[replace] insp_mtquals[q] +x_by_y: alpha_val[matching] BY alpha_val[replace] insp_mtqual[q] { $$ = new cbl_inspect_replace_t(*$matching, *$replace, $q->before, $q->after); } ; -insp_mtquals: %empty { $$ = new cbl_inspect_match_t; } + /* mt may be "empty": match may have no qualifiers */ +insp_mtqual: %empty { $$ = new cbl_inspect_match_t; } | insp_quals ; insp_quals: insp_qual { @@ -9353,6 +9468,7 @@ insp_quals: insp_qual { } else { $$->after = *$insp_qual.qual; } + dump_inspect_match(*$$); } | insp_quals insp_qual { @@ -9724,7 +9840,7 @@ call_except: EXCEPTION { $$.not_error = NULL; $$.on_error = label_add(LblArith, - uniq_label("call"), yylineno); + uniq_label("call"), @1.first_line); if( !$$.on_error ) YYERROR; parser_call_exception( $$.on_error ); @@ -9737,7 +9853,7 @@ call_except: EXCEPTION { $$.not_error = NULL; $$.on_error = label_add(LblArith, - uniq_label("call"), yylineno); + uniq_label("call"), @1.first_line); if( !$$.on_error ) YYERROR; parser_call_exception( $$.on_error ); @@ -9772,7 +9888,7 @@ alter_tgt: label_1[old] alter_to label_1[new] cbl_perform_tgt_t tgt( $old, $new ); parser_alter(&tgt); - auto prog = cbl_label_of( symbol_at(symbol_elem_of($old)->program)); + const auto prog = cbl_label_of( symbol_at(symbol_elem_of($old)->program)); if( prog->initial ) { cbl_unimplemented("ALTER %s", $old->name); } @@ -9793,7 +9909,7 @@ go_to: GOTO labels[args] } for( auto& label : $args->elems ) { - label->used = yylineno; + label->used = @2.first_line; } cbl_label_t *arg = $args->elems.front(); parser_goto( cbl_refer_t(), 1, &arg ); @@ -9805,7 +9921,7 @@ go_to: GOTO labels[args] std::vector <cbl_label_t *> args($args->elems.size()); std::copy($args->elems.begin(), $args->elems.end(), args.begin()); for( auto& label : $args->elems ) { - label->used = yylineno; + label->used = @2.first_line; } parser_goto( *$value, args.size(), args.data() ); } @@ -9825,7 +9941,7 @@ resume: RESUME NEXT STATEMENT { statement_begin(@1, RESUME); parser_clear_exception(); - $tgt->used = yylineno; + $tgt->used = @1.first_line; parser_goto( cbl_refer_t(), 1, &$tgt ); } ; @@ -10000,7 +10116,7 @@ on_overflow: OVERFLOW_kw { $$.not_error = NULL; $$.on_error = label_add(LblString, - uniq_label("string"), yylineno); + uniq_label("string"), @1.first_line); if( !$$.on_error ) YYERROR; parser_string_overflow( $$.on_error ); @@ -10170,7 +10286,7 @@ function_udf: FUNCTION_UDF '(' arg_list[args] ')' { size_t i = 0; // Pass parameters as defined by the function. std::transform( $args->refers.begin(), $args->refers.end(), args.begin(), - [params, &i]( cbl_refer_t& arg ) { + [params, &i]( const cbl_refer_t& arg ) { function_descr_arg_t param = params.at(i++); auto ar = new cbl_refer_t(arg); cbl_ffi_arg_t actual(param.crv, ar); @@ -10219,9 +10335,9 @@ intrinsic: function_udf args.data()); if( p != NULL ) { auto loc = symbol_field_location(field_index(p->field)); - error_msg(loc, "FUNCTION %s has " - "inconsistent parameter type %zu ('%s')", - keyword_str($1), p - args.data(), name_of(p->field) ); + error_msg(loc, "FUNCTION %qs has " + "inconsistent parameter type %ld (%qs)", + keyword_str($1), (long)(p - args.data()), name_of(p->field) ); YYERROR; } $$ = is_numeric(args[0].field)? @@ -10297,7 +10413,7 @@ intrinsic: function_udf location_set(@1); $$ = new_alphanumeric("FIND-STRING"); /* auto r1 = new_reference(new_literal(strlen($r1), $r1, quoted_e)); */ - cbl_unimplemented("FIND_STRING"); + cbl_unimplemented("%<FIND_STRING%>"); /* if( ! intrinsic_call_4($$, FIND_STRING, r1, $r2) ) YYERROR; */ } @@ -10764,7 +10880,7 @@ numval_locale: %empty { $$.arg2 = cbl_refer_t::empty(); } | LOCALE NAME { $$.is_locale = true; $$.arg2 = NULL; - cbl_unimplemented("NUMVAL_C LOCALE"); YYERROR; + cbl_unimplemented("%<NUMVAL_C LOCALE%>"); YYERROR; } | varg { $$.is_locale = false; $$.arg2 = $1; } ; @@ -11313,7 +11429,7 @@ first_line_of( YYLTYPE loc ) { return loc; } -void ast_call( const YYLTYPE& loc, cbl_refer_t name, cbl_refer_t returning, +void ast_call( const YYLTYPE& loc, cbl_refer_t name, const cbl_refer_t& returning, size_t narg, cbl_ffi_arg_t args[], cbl_label_t *except, cbl_label_t *not_except, @@ -11342,6 +11458,7 @@ void ast_call( const YYLTYPE& loc, cbl_refer_t name, cbl_refer_t returning, */ static bool possible_ec() { + cbl_enabled_exceptions_t& enabled_exceptions( cdf_enabled_exceptions() ); bool format_1 = current.declaratives.has_format_1(); bool enabled = 0xFF < (current.declaratives.status() @@ -11364,6 +11481,7 @@ possible_ec() { */ static void statement_epilog( int token ) { + cbl_enabled_exceptions_t& enabled_exceptions( cdf_enabled_exceptions() ); if( possible_ec() && token != CONTINUE ) { if( enabled_exceptions.size() ) { current.declaratives_evaluate(); @@ -11405,7 +11523,7 @@ statement_begin( const YYLTYPE& loc, int token ) { struct string_match { const char *name; - string_match( const char name[] ) : name(name) {} + explicit string_match( const char name[] ) : name(name) {} bool operator()( const char input[] ) const { return strlen(name) == strlen(input) && 0 == strcasecmp(name, input); } @@ -11413,18 +11531,24 @@ struct string_match { const char * keyword_str( int token ) { - if( token == YYEOF ) return "YYEOF"; - if( token == YYEMPTY ) return "YYEMPTY"; - + switch( token ) { + case YYEOF: return "YYEOF"; + case YYEMPTY: return "YYEMPTY"; + case 256: return "YYerror"; + case 257: return "invalid token"; // YYUNDEF + } + if( token < 256 ) { static char ascii[2]; ascii[0] = token; return ascii; } - return tokens.name_of(token); + return cdf_tokens.name_of(token); } +bool iso_cobol_word( const std::string& name, bool include_context ); + /* * Return the token for the Cobol name, unless it is a function name. The * lexer uses keyword_tok to determine if what appears to be a NAME is in fact @@ -11435,15 +11559,14 @@ keyword_str( int token ) { */ // tokens.h is generated as needed from parse.h with tokens.h.gen -tokenset_t::tokenset_t() { +current_tokens_t::tokenset_t::tokenset_t() { #include "token_names.h" } -bool iso_cobol_word( const std::string& name, bool include_context ); // Look up the lowercase form of a keyword, excluding some CDF names. int -tokenset_t::find( const cbl_name_t name, bool include_intrinsics ) { +current_tokens_t::tokenset_t::find( const cbl_name_t name, bool include_intrinsics ) { static const cbl_name_t non_names[] = { // including CDF NAMES, and "SWITCH" "CHECKING", "LIST", "LOCATION", "MAP", "SWITCH", }, * const eonames = non_names + COUNT_OF(non_names); @@ -11459,9 +11582,9 @@ tokenset_t::find( const cbl_name_t name, bool include_intrinsics ) { if( dialect_ibm() ) { static const cbl_name_t ibm_non_names[] = { "RESUME", - }, * const eonames = ibm_non_names + COUNT_OF(ibm_non_names); + }, * const eoibm = ibm_non_names + COUNT_OF(ibm_non_names); - if( std::any_of(ibm_non_names, eonames, + if( std::any_of(ibm_non_names, eoibm, [candidate=name](const cbl_name_t non_name) { return 0 == strcasecmp(non_name, candidate) && strlen(non_name) == strlen(candidate); @@ -11493,12 +11616,12 @@ tokenset_t::find( const cbl_name_t name, bool include_intrinsics ) { int keyword_tok( const char * text, bool include_intrinsics ) { - return tokens.find(text, include_intrinsics); + return cdf_tokens.find(text, include_intrinsics); } static inline size_t verify_figconst( enum cbl_figconst_t figconst , size_t pos ) { - cbl_field_t *f = cbl_field_of(symbol_at(pos)); + const cbl_field_t *f = cbl_field_of(symbol_at(pos)); assert((f->attr & FIGCONST_MASK) == figconst); return pos; } @@ -11544,7 +11667,7 @@ relop_invert(relop_t op) { case ge_op: return lt_op; case gt_op: return le_op; } - cbl_errx( "%s:%d: invalid relop_t %d", __func__, __LINE__, op); + cbl_internal_error("%s:%d: invalid %<relop_t%> %d", __func__, __LINE__, op); return relop_t(0); // not reached } @@ -11685,7 +11808,7 @@ label_add( const YYLTYPE& loc, name, cbl_label_of(p)->name, cbl_label_of(p)->line); } } - struct cbl_label_t label = { type, parent, loc.last_line }; + struct cbl_label_t label = { type, parent, loc.first_line }; if( !namcpy(loc, label.name, name) ) return NULL; auto p = symbol_label_add(PROGRAM, &label); @@ -11790,7 +11913,7 @@ current_t::udf_update( const ffi_args_t *ffi_args ) { if( ! ffi_args ) return; assert(ffi_args->elems.size() < sizeof(function_descr_t::types)); - auto returning = cbl_field_of(symbol_at(L->returning)); + const auto returning = cbl_field_of(symbol_at(L->returning)); auto key = function_descr_t::init(L->name); auto func = udfs.find(key); assert(func != udfs.end()); @@ -11832,12 +11955,12 @@ current_t::udf_args_valid( const cbl_label_t *L, } size_t i = 0; - for( cbl_refer_t arg : args ) { + for( const cbl_refer_t& arg : args ) { if( arg.field ) { // else omitted auto tgt = cbl_field_of(symbol_at(udf.linkage_fields.at(i).isym)); if( ! valid_move(tgt, arg.field) ) { auto loc = symbol_field_location(field_index(arg.field)); - error_msg(loc, "FUNCTION %s arg %zu, '%s' cannot be passed to %s, type %s", + error_msg(loc, "FUNCTION %s argument %zu, '%s' cannot be passed to %s, type %s", L->name, i, arg.field->pretty_name(), tgt->pretty_name(), 3 + cbl_field_type_str(tgt->type) ); return false; @@ -11853,7 +11976,10 @@ current_t::repository_add( const char name[]) { assert( !programs.empty() ); function_descr_t arg = function_descr_t::init(name); auto parg = std::find( function_descrs, function_descrs_end, arg ); - if( parg == function_descrs_end ) return false; + if( parg == function_descrs_end ) { + dbgmsg("%s:%d: no intrinsic %s found", __func__, __LINE__, name); + return false; + } auto p = programs.top().function_repository.insert(*parg); if( yydebug ) { for( auto descr : programs.top().function_repository ) { @@ -11889,7 +12015,7 @@ function_descr_t function_descr_t::init( int isym ) { function_descr_t descr = { FUNCTION_UDF_0 }; descr.ret_type = FldInvalid; - auto L = cbl_label_of(symbol_at(isym)); + const auto L = cbl_label_of(symbol_at(isym)); bool ok = namcpy(YYLTYPE(), descr.name, L->name); gcc_assert(ok); return descr; @@ -11903,16 +12029,16 @@ arith_t::arith_t( cbl_arith_format_t format, refer_list_t * refers ) delete refers; } - -cbl_key_t::cbl_key_t( const sort_key_t& that ) +cbl_key_t::cbl_key_t( sort_key_t that ) : ascending(that.ascending) - , nfield(that.fields.size()) - , fields(NULL) -{ - if( nfield > 0 ) { - fields = new cbl_field_t* [nfield]; - std::copy(that.fields.begin(), that.fields.end(), fields); - } + , fields( that.fields.begin(), that.fields.end() ) +{} + +cbl_key_t& +cbl_key_t::operator=( const sort_key_t& that ) { + ascending = that.ascending; + fields = that.as_vector(); + return *this; } static cbl_refer_t * @@ -12018,10 +12144,10 @@ ast_divide( arith_t *arith ) { * the convenience of the parser. */ struct stringify_src_t : public cbl_string_src_t { - stringify_src_t( const refer_marked_list_t& marked = refer_marked_list_t() ) - : cbl_string_src_t( marked.marker? *marked.marker : null_reference, - marked.refers.size(), - new cbl_refer_t[marked.refers.size()] ) + stringify_src_t( const refer_marked_list_t& marked = refer_marked_list_t() ) + : cbl_string_src_t( marked.marker? *marked.marker : null_reference, + marked.refers.size(), + new cbl_refer_t[marked.refers.size()] ) { std::copy( marked.refers.begin(), marked.refers.end(), inputs ); } @@ -12035,13 +12161,13 @@ struct stringify_src_t : public cbl_string_src_t { protected: static void dump_input( const cbl_refer_t& refer ) { - yywarn( "%s:\t%s", __func__, field_str(refer.field) ); + yywarn( "%s: %s", __func__, field_str(refer.field) ); } }; void stringify( refer_collection_t *inputs, - cbl_refer_t into, cbl_refer_t pointer, + const cbl_refer_t& into, const cbl_refer_t& pointer, cbl_label_t *on_error, cbl_label_t *not_error ) { @@ -12056,7 +12182,7 @@ stringify( refer_collection_t *inputs, } void -unstringify( cbl_refer_t& src, +unstringify( const cbl_refer_t& src, refer_list_t *delimited, unstring_into_t * into, cbl_label_t *on_error, @@ -12064,6 +12190,7 @@ unstringify( cbl_refer_t& src, { size_t ndelimited = delimited? delimited->size() : 0; cbl_refer_t *pdelimited = NULL; + // cppcheck-suppress [variableScope] pdelimited points to delimiteds.data() std::vector <cbl_refer_t> delimiteds(ndelimited); if( ndelimited > 0 ) { pdelimited = use_any( delimited->refers, delimiteds ); @@ -12175,15 +12302,19 @@ lang_check_failed (const char* file, int line, const char* function) {} #pragma GCC diagnostic pop -void ast_inspect( cbl_refer_t& input, bool backward, ast_inspect_list_t& inspects ) { +void +ast_inspect( YYLTYPE loc, cbl_refer_t& input, bool backward, + cbl_inspect_opers_t& inspects ) +{ if( yydebug ) { - dbgmsg("%s:%d: INSPECT " HOST_SIZE_T_PRINT_UNSIGNED " operations on %s, line %d", - __func__, __LINE__, (fmt_size_t)inspects.size(), input.field->name, yylineno); + dbgmsg("%s:%d: INSPECT " HOST_SIZE_T_PRINT_UNSIGNED " operations on %s, " + "lines %d:%d - %d:%d", + __func__, __LINE__, + (fmt_size_t)inspects.size(), input.field->name, + loc.first_line, loc.first_column, loc.last_line, loc.last_column ); } std::for_each(inspects.begin(), inspects.end(), dump_inspect); - auto array = inspects.as_array(); - parser_inspect( input, backward, inspects.size(), array ); - delete[] array; + parser_inspect( input, backward, inspects ); } static const char * @@ -12195,28 +12326,29 @@ cbl_refer_str( char output[], const cbl_refer_t& R ) { return output; } -static void +void dump_inspect_match( const cbl_inspect_match_t& M ) { - static char fields[3][4 * 64]; - cbl_refer_str(fields[0], M.matching); - cbl_refer_str(fields[1], M.before.identifier_4); - cbl_refer_str(fields[2], M.after.identifier_4); - - yywarn( "matching %s \n\t\tbefore %s%s \n\t\tafter %s%s", - fields[0], - M.before.initial? "initial " : "", fields[1], - M.after.initial? "initial " : "", fields[2] ); + static char fields[4][4 * 64]; + cbl_refer_str(fields[0], M.match); + cbl_refer_str(fields[1], M.tally); + cbl_refer_str(fields[2], M.before.identifier_4); + cbl_refer_str(fields[3], M.after.identifier_4); + + dbgmsg( "matching %s [tally %s]\n\t\tbefore %s%s \n\t\tafter %s%s", + fields[0], fields[1], + M.before.initial? "initial " : "", fields[2], + M.after.initial? "initial " : "", fields[3] ); } static void dump_inspect_replace( const cbl_inspect_replace_t& R ) { static char fields[4][4 * 64]; - cbl_refer_str(fields[0], R.matching); + cbl_refer_str(fields[0], R.matching()); cbl_refer_str(fields[1], R.before.identifier_4); cbl_refer_str(fields[2], R.after.identifier_4); cbl_refer_str(fields[3], R.replacement); - yywarn( "matching %s \n\treplacement %s\n\t\tbefore %s%s \n\t\tafter %s%s", + dbgmsg( "matching %s \n\treplacement %s\n\t\tbefore %s%s \n\t\tafter %s%s", fields[0], fields[3], R.before.initial? "initial " : "", fields[1], R.after.initial? "initial " : "", fields[2] ); @@ -12332,13 +12464,13 @@ numstr2i( const char input[], radix_t radix ) { break; case hexadecimal_e: erc = sscanf(input, "%" GCC_PRISZ "x", &integerf); - integer = integer; + integer = integerf; real_from_integer (&output, VOIDmode, integer, UNSIGNED); break; case boolean_e: for( const char *p = input; *p != '\0'; p++ ) { if( ssize_t(8 * sizeof(integer) - 1) < p - input ) { - yywarn("'%s' was accepted as %d", input, integer); + yywarn("'%s' was accepted as %zu", input, integer); break; } switch(*p) { @@ -12348,7 +12480,7 @@ numstr2i( const char input[], radix_t radix ) { integer |= ((*p) == '0' ? 0 : 1); break; default: - yywarn("'%s' was accepted as %d", input, integer); + yywarn("'%s' was accepted as %zu", input, integer); break; } } @@ -12356,7 +12488,7 @@ numstr2i( const char input[], radix_t radix ) { return output; } if( erc == -1 ) { - yywarn("'%s' was accepted as %lld", input, output); + yywarn("'%s' was accepted as %zu", input, integer); } return output; } @@ -12382,7 +12514,7 @@ new_literal( const char initial[], enum radix_t radix ) { class is_elementary_type { // for INITIALIZE purposes bool with_filler; public: - is_elementary_type( bool with_filler ) : with_filler(with_filler) {} + explicit is_elementary_type( bool with_filler ) : with_filler(with_filler) {} bool operator()( const symbol_elem_t& elem ) const { if( elem.type != SymField ) return false; @@ -12396,7 +12528,7 @@ public: size_t end_of_group( size_t igroup ); static std::list<cbl_refer_t> -symbol_group_data_members( cbl_refer_t refer, bool with_filler ) { +symbol_group_data_members( const cbl_refer_t& refer, bool with_filler ) { std::list<cbl_refer_t> refers; refers.push_front( refer ); @@ -12404,7 +12536,7 @@ symbol_group_data_members( cbl_refer_t refer, bool with_filler ) { class refer_of : public cbl_refer_t { public: - refer_of( const cbl_refer_t& refer ) : cbl_refer_t(refer) {} + explicit refer_of( const cbl_refer_t& refer ) : cbl_refer_t(refer) {} cbl_refer_t operator()( symbol_elem_t& elem ) { this->field = cbl_field_of(&elem); // preserve subscript/refmod return *this; @@ -12428,7 +12560,7 @@ struct expand_group : public std::list<cbl_refer_t> { return cbl_refer_t(field); } bool with_filler; - expand_group( bool with_filler ) : with_filler(with_filler) {} + explicit expand_group( bool with_filler ) : with_filler(with_filler) {} void operator()( const cbl_refer_t& refer ) { assert(refer.field); @@ -12454,7 +12586,7 @@ wsclear( char ch ) { } static void -initialize_allocated( cbl_refer_t input ) { +initialize_allocated( const cbl_refer_t& input ) { cbl_num_result_t result = { truncation_e, input }; std::list<cbl_num_result_t> results; results.push_back(result); @@ -12463,13 +12595,14 @@ initialize_allocated( cbl_refer_t input ) { } static int -initialize_with( cbl_refer_t tgt ) { +initialize_with( const cbl_refer_t& tgt ) { if( tgt.field->type == FldPointer ) return ZERO; if( tgt.is_refmod_reference() ) return SPACES; return is_numeric(tgt.field)? ZERO : SPACES; } static bool +// cppcheck-suppress [passedByValue] target.refer.field is modified initialize_one( cbl_num_result_t target, bool with_filler, data_category_t value_category, const category_map_t& replacements, @@ -12539,11 +12672,11 @@ typedef std::pair<size_t, size_t> cbl_bytespan_t; * After the 1st record is initialized, copy it to the others. */ static bool -initialize_table( cbl_num_result_t target, +initialize_table( const cbl_num_result_t& target, size_t nspan, const cbl_bytespan_t spans[], const std::list<cbl_subtable_t>& subtables ) { - assert( target.refer.nsubscript == dimensions(target.refer.field) ); + assert( target.refer.nsubscript() == dimensions(target.refer.field) ); const cbl_refer_t& src( target.refer ); size_t n( src.field->occurs.ntimes()); assert( 0 < n ); @@ -12559,17 +12692,17 @@ static cbl_refer_t synthesize_table_refer( cbl_refer_t tgt ) { // For a table, use supplied subscripts or start with 1. auto ndim( dimensions(tgt.field) ); - if( tgt.nsubscript < ndim ) { // it's an incomplete table + if( tgt.nsubscript() < ndim ) { // it's an incomplete table std::vector <cbl_refer_t> subscripts(ndim); for( size_t i=0; i < ndim; i++ ) { - if( i < tgt.nsubscript ) { + if( i < tgt.nsubscript() ) { subscripts[i] = tgt.subscripts[i]; continue; } subscripts[i].field = new_tempnumeric(); parser_set_numeric(subscripts[i].field, 1); } - return cbl_refer_t( tgt.field, subscripts.size(), subscripts.data() ); + return cbl_refer_t( tgt.field, subscripts ); } return tgt; } @@ -12579,7 +12712,7 @@ group_offset( const cbl_field_t *field ) { if( field->parent ) { auto e = symbol_at(field->parent); if( e->type == SymField ) { - auto parent = cbl_field_of(e); + const auto parent = cbl_field_of(e); return field->offset - parent->offset; } } @@ -12593,7 +12726,7 @@ initialize_statement( const cbl_num_result_t& target, bool with_filler, size_t depth = 0 ) { const cbl_refer_t& tgt( target.refer ); - assert(dimensions(tgt.field) == tgt.nsubscript || 0 < depth); + assert(dimensions(tgt.field) == tgt.nsubscript() || 0 < depth); assert(!is_literal(tgt.field)); if( tgt.field->type == FldGroup ) { @@ -12630,7 +12763,7 @@ initialize_statement( const cbl_num_result_t& target, bool with_filler, if( fOK && is_table(tgt.field) ) { cbl_num_result_t output = { target.rounded, synthesize_table_refer(tgt) }; - if( tgt.nsubscript < output.refer.nsubscript ) { // tgt is whole table + if( tgt.nsubscript() < output.refer.nsubscript() ) { // tgt is whole table std::list<field_span_t> field_spans; static const field_span_t empty_span = { NULL, NULL }; field_span_t span = empty_span; @@ -12741,17 +12874,7 @@ static void initialize_statement( std::list<cbl_num_result_t>& tgts, bool with_filler, data_category_t value_category, const category_map_t& replacements) { - - bool is_refmod = std::any_of( tgts.begin(), tgts.end(), - []( const auto& tgt ) { - return tgt.refer.is_refmod_reference(); - } ); - if( false && is_refmod ) { // refmod seems valid per ISO - dbgmsg("INITIALIZE cannot initialize a refmod"); - return; - } - - for( auto tgt : tgts ) { + for( const auto& tgt : tgts ) { initialize_statement( tgt, with_filler, value_category, replacements ); } @@ -12762,13 +12885,11 @@ static void dump_inspect_oper( const cbl_inspect_oper_t& op ) { dbgmsg("\t%s: " HOST_SIZE_T_PRINT_UNSIGNED " \"matches\", " HOST_SIZE_T_PRINT_UNSIGNED " \"replaces\"", - bound_str(op.bound), - op.matches? (fmt_size_t)op.n_identifier_3 : 0, - op.replaces? (fmt_size_t)op.n_identifier_3 : 0); - if( op.matches ) - std::for_each(op.matches, op.matches + op.n_identifier_3, dump_inspect_match); - if( op.replaces ) - std::for_each(op.replaces, op.replaces + op.n_identifier_3, dump_inspect_replace); + bound_str(op.bound), + (fmt_size_t)op.matches.size(), + (fmt_size_t)op.replaces.size()); + std::for_each(op.matches.begin(), op.matches.end(), dump_inspect_match); + std::for_each(op.replaces.begin(), op.replaces.end(), dump_inspect_replace); } #pragma GCC diagnostic push @@ -12785,14 +12906,14 @@ dump_inspect( const cbl_inspect_t& I ) { } else { fprintf( stderr, "\tREPLACING:\n" ); } - std::for_each( I.opers, I.opers + I.nbound, dump_inspect_oper ); + std::for_each( I.begin(), I.end(), dump_inspect_oper ); } #pragma GCC diagnostic pop #include <iterator> struct declarative_file_list_t : protected cbl_declarative_t { - declarative_file_list_t( const cbl_declarative_t& d ) + explicit declarative_file_list_t( const cbl_declarative_t& d ) : cbl_declarative_t(d) { if( nfile > 0 ) @@ -12817,7 +12938,7 @@ operator<<( std::ostream& os, const declarative_file_list_t& dcl ) { static declarative_file_list_t file_list_of( const cbl_declarative_t& dcl ) { - return dcl; + return declarative_file_list_t(dcl); } std::ostream& @@ -12889,7 +13010,7 @@ cbl_file_t::validate_key( const cbl_file_key_t& key ) const { bool cbl_file_t::validate() const { - size_t members[] = { user_status, vsam_status, record_length }; + const size_t members[] = { user_status, vsam_status, record_length }; bool tf = true; for( auto isym : members ) { @@ -12990,7 +13111,7 @@ literal_attr( const char prefix[] ) { } // must be [BN]X - cbl_internal_error("'%s': invalid literal prefix", prefix); + cbl_internal_error("invalid literal prefix: %qs", prefix); gcc_unreachable(); return none_e; } @@ -13037,7 +13158,7 @@ cobol_dialect_set( cbl_dialect_t dialect ) { break; case dialect_gnu_e: if( 0 == (cbl_dialects & dialect) ) { // first time - tokens.equate(YYLTYPE(), "BINARY-DOUBLE", "BINARY-C-LONG"); + cdf_tokens.equate(YYLTYPE(), "BINARY-DOUBLE", "BINARY-C-LONG"); } break; } @@ -13100,7 +13221,7 @@ literal_refmod_valid( YYLTYPE loc, const cbl_refer_t& r ) { if( --edge < r.field->data.capacity ) return true; } // len < 0 or not: 0 < from + len <= capacity - auto loc = symbol_field_location(field_index(r.field)); + loc = symbol_field_location(field_index(r.field)); error_msg(loc, "%s(%zu:%zu) out of bounds, " "size is %u", r.field->name, @@ -13123,19 +13244,22 @@ literal_subscript_oob( const cbl_refer_t& r, size_t& isub ); static bool literal_subscripts_valid( YYLTYPE loc, const cbl_refer_t& name ) { - static char subs[ 7 * 32 ], *esub = subs + sizeof(subs); - char *p = subs; size_t isub; - // Find subscript in the supplied refer + // Report any out-of-bound subscript. const cbl_field_t *oob = literal_subscript_oob(name, isub); if( oob ) { - const char *sep = ""; - for( auto r = name.subscripts; r < name.subscripts + name.nsubscript; r++ ) { - snprintf( p, esub - p, "%s%s", sep, nice_name_of(r->field) ); - sep = " "; - } - + std::string sep(""); + std::string subscript_names = + std::accumulate( name.subscripts.begin(), + name.subscripts.end(), + std::string(), + [&sep]( std::string acc, const auto& sub ) { + acc += sep; + sep = " "; + return acc + nice_name_of(sub.field); + } ); + const char *upper_phrase = ""; if( ! oob->occurs.bounds.fixed_size() ) { static char ub[32] = "boo"; @@ -13146,8 +13270,8 @@ literal_subscripts_valid( YYLTYPE loc, const cbl_refer_t& name ) { // X(0): subscript 1 of for out of range for 02 X OCCURS 4 to 6 error_msg(loc, "%s(%s): subscript %zu out of range " - "for %s %s OCCURS %lu%s", - oob->name, subs, 1 + isub, + "for %s %s OCCURS %zu%s", + oob->name, subscript_names.c_str(), 1 + isub, oob->level_str(), oob->name, oob->occurs.bounds.lower, upper_phrase ); return false; @@ -13169,14 +13293,14 @@ subscript_dimension_error( YYLTYPE loc, size_t nsub, const cbl_refer_t *scalar ) } static void -reject_refmod( YYLTYPE loc, cbl_refer_t scalar ) { +reject_refmod( YYLTYPE loc, const cbl_refer_t& scalar ) { if( scalar.is_refmod_reference() ) { error_msg(loc, "%s cannot be reference-modified here", scalar.name()); } } static bool -require_pointer( YYLTYPE loc, cbl_refer_t scalar ) { +require_pointer( YYLTYPE loc, const cbl_refer_t& scalar ) { if( scalar.field->type != FldPointer ) { error_msg(loc, "%s must have USAGE POINTER", scalar.name()); return false; @@ -13185,7 +13309,7 @@ require_pointer( YYLTYPE loc, cbl_refer_t scalar ) { } static bool -require_numeric( YYLTYPE loc, cbl_refer_t scalar ) { +require_numeric( YYLTYPE loc, const cbl_refer_t& scalar ) { if( ! is_numeric(scalar.field) ) { error_msg(loc, "%s must have numeric USAGE", scalar.name()); return false; @@ -13194,7 +13318,7 @@ require_numeric( YYLTYPE loc, cbl_refer_t scalar ) { } static bool -require_integer( YYLTYPE loc, cbl_refer_t scalar ) { +require_integer( YYLTYPE loc, const cbl_refer_t& scalar ) { if( is_literal(scalar.field) ) { if( ! is_integer_literal(scalar.field) ) { error_msg(loc, "numeric literal '%s' must be an integer", diff --git a/gcc/cobol/parse_ante.h b/gcc/cobol/parse_ante.h index f62a2f1a534b..03cb0a0492e7 100644 --- a/gcc/cobol/parse_ante.h +++ b/gcc/cobol/parse_ante.h @@ -102,8 +102,8 @@ void input_file_status_notify(); (Current).last_column = YYRHSLOC (Rhs, 0).last_column; \ } \ location_dump("parse.c", __LINE__, "current", (Current)); \ - gcc_location_set( location_set(Current) ); \ input_file_status_notify(); \ + location_set(Current); \ } while (0) int yylex(void); @@ -210,6 +210,9 @@ in_file_section(void) { return current_data_section == file_datasect_e; } static cbl_refer_t * intrinsic_inconsistent_parameter( size_t n, cbl_refer_t *args ); +static int +intrinsic_token_of( const char name[] ); + static inline bool namcpy(const YYLTYPE& loc, cbl_name_t tgt, const char *src ) { // snprintf(3): writes at most size bytes (including the terminating NUL byte) @@ -244,9 +247,9 @@ new_reference_like( const cbl_field_t& skel ) { return new cbl_refer_t( new_temporary_like(skel) ); } -static void reject_refmod( YYLTYPE loc, cbl_refer_t ); -static bool require_pointer( YYLTYPE loc, cbl_refer_t ); -static bool require_integer( YYLTYPE loc, cbl_refer_t ); +static void reject_refmod( YYLTYPE loc, const cbl_refer_t& ); +static bool require_pointer( YYLTYPE loc, const cbl_refer_t& ); +static bool require_integer( YYLTYPE loc, const cbl_refer_t& ); struct cbl_field_t * constant_of( size_t isym ); @@ -289,7 +292,7 @@ struct evaluate_elem_t { relop_t oper; public: cbl_field_t *subject, *object, *cond; - case_t( cbl_field_t * subject ) + explicit case_t( cbl_field_t * subject ) : oper(eq_op) , subject(subject) , object(NULL) @@ -328,15 +331,14 @@ struct evaluate_elem_t { explicit evaluate_elem_t( const char skel[] ) : nother(0) + , label{LblEvaluate} , result( keep_temporary(FldConditional) ) , pcase( cases.end() ) { - static const cbl_label_t protolabel = { LblEvaluate }; - label = protolabel; label.line = yylineno; if( -1 == snprintf(label.name, sizeof(label.name), "%.*s_%d", (int)sizeof(label.name)-6, skel, yylineno) ) { - yyerror("could not create unique label '%s_%d' because it is too long", + yyerror("could not create unique label %<%s_%d%> because it is too long", skel, yylineno); } } @@ -367,13 +369,14 @@ struct evaluate_elem_t { static class file_delete_args_t { cbl_file_t *file; public: + file_delete_args_t() : file(nullptr) {} void init( cbl_file_t *file ) { this->file = file; } - bool ready() const { return file != NULL; } + bool ready() const { return file != nullptr; } void call_parser_file_delete( bool sequentially ) { parser_file_delete(file, sequentially); - file = NULL; + file = nullptr; } } file_delete_args; @@ -389,7 +392,7 @@ static struct file_read_args_t { void init( struct cbl_file_t *file, - cbl_refer_t record, + const cbl_refer_t& record, cbl_refer_t *read_into, int where ) { this->file = file; @@ -438,7 +441,7 @@ static class file_return_args_t { this->file = file; } bool ready() const { return file != NULL; } - void call_parser_return_start(cbl_refer_t into = cbl_refer_t() ) { + void call_parser_return_start(const cbl_refer_t& into = cbl_refer_t() ) { parser_return_start(file, into); file = NULL; } @@ -448,17 +451,18 @@ static class file_rewrite_args_t { cbl_file_t *file; cbl_field_t *record; public: + file_rewrite_args_t() : file(nullptr), record(nullptr) {} void init( cbl_file_t *file, cbl_field_t *record ) { this->file = file; this->record = record; } - bool ready() const { return file != NULL; } + bool ready() const { return file != nullptr; } void call_parser_file_rewrite( bool sequentially ) { sequentially = sequentially || file->access == file_access_seq_e; if( file->access == file_access_rnd_e ) sequentially = false; parser_file_rewrite(file, record, sequentially); - file = NULL; - record = NULL; + file = nullptr; + record = nullptr; } } file_rewrite_args; @@ -487,21 +491,22 @@ static class file_write_args_t { cbl_refer_t *advance; public: file_write_args_t() - : file(NULL) + : file(nullptr) + , data_source(nullptr) , after(false) - , advance(NULL) + , advance(nullptr) {} cbl_file_t * init( cbl_file_t *file, cbl_field_t *data_source, bool after, - cbl_refer_t *advance ) { + const cbl_refer_t *advance ) { this->file = file; this->data_source = data_source; this->after = after; this->advance = new cbl_refer_t(*advance); return this->file; } - bool ready() const { return file != NULL; } + bool ready() const { return file != nullptr; } void call_parser_file_write( bool sequentially ) { sequentially = sequentially || file->access == file_access_seq_e; parser_file_write(file, data_source, after, *advance, sequentially); @@ -535,7 +540,7 @@ struct arith_t { cbl_refer_t remainder; cbl_label_t *on_error, *not_error; - arith_t( cbl_arith_format_t format ) + explicit arith_t( cbl_arith_format_t format ) : format(format), on_error(NULL), not_error(NULL) {} arith_t( cbl_arith_format_t format, refer_list_t * refers ); @@ -619,7 +624,7 @@ class eval_subject_t { void new_object_labels(); public: eval_subject_t(); - void append( cbl_refer_t field ) { + void append( const cbl_refer_t& field ) { columns.push_back(field); pcol = columns.begin(); } @@ -750,6 +755,7 @@ class evaluate_t : private std::stack<eval_subject_t> { static void dump_inspect( const cbl_inspect_t& i ); +void dump_inspect_match( const cbl_inspect_match_t& M ); struct perform_t { struct cbl_perform_tgt_t tgt; @@ -789,11 +795,10 @@ struct perform_t { cbl_refer_t table; } search; - perform_t( cbl_label_t *from, cbl_label_t *to = NULL ) + explicit perform_t( cbl_label_t *from, cbl_label_t *to = NULL ) : tgt( from, to ), before(true) - { - search = {}; - } + , search() + {} ~perform_t() { varys.clear(); } cbl_field_t * until() { assert(!varys.empty()); @@ -892,7 +897,7 @@ static struct cbl_label_t * paragraph_reference( const char name[], size_t section ); static inline void -list_add( list<cbl_num_result_t>& list, cbl_refer_t refer, int round ) { +list_add( list<cbl_num_result_t>& list, const cbl_refer_t& refer, int round ) { struct cbl_num_result_t arg = { static_cast<cbl_round_t>(round), refer }; list.push_back(arg); } @@ -930,171 +935,17 @@ teed_up_names() { return name_queue_t::namelist_of( name_queue.peek() ); } -class tokenset_t { - // token_names is initialized from a generated header file. - std::vector<const char *>token_names; // position indicates token value - std::map <std::string, int> tokens; // aliases - std::set<std::string> cobol_words; // Anything in COBOL-WORDS may appear only once. - public: - static std::string - lowercase( const cbl_name_t name ) { - cbl_name_t lname; - std::transform(name, name + strlen(name) + 1, lname, ftolower); - return lname; - } - static std::string - uppercase( const cbl_name_t name ) { - cbl_name_t uname; - std::transform(name, name + strlen(name) + 1, uname, ftoupper); - return uname; - } - - public: - tokenset_t(); - int find( const cbl_name_t name, bool include_intrinsics ); - - bool equate( const YYLTYPE& loc, int token, - const cbl_name_t name, const cbl_name_t verb = "EQUATE") { - auto lname( lowercase(name) ); - auto cw = cobol_words.insert(lname); - if( ! cw.second ) { - error_msg(loc, "COBOL-WORDS %s: %s may appear but once", verb, name); - return false; - } - auto p = tokens.find(lowercase(name)); - bool fOK = p == tokens.end(); - if( fOK ) { // name not already in use - tokens[lname] = token; - dbgmsg("%s:%d: %d has alias %s", __func__, __LINE__, token, name); - } else { - error_msg(loc, "%s: %s already defined as a token", verb, name); - } - return fOK; - } - bool undefine( const YYLTYPE& loc, - const cbl_name_t name, const cbl_name_t verb = "UNDEFINE" ) { - auto lname( lowercase(name) ); - auto cw = cobol_words.insert(lname); - if( ! cw.second ) { - error_msg(loc, "COBOL-WORDS %s: %s may appear but once", verb, name); - return false; - } - - // Do not erase generic, multi-type tokens COMPUTATIONAL and BINARY_INTEGER. - if( binary_integer_usage_of(name) ) { - dbgmsg("%s:%d: generic %s remains valid as a token", __func__, __LINE__, name); - return true; - } - - auto p = tokens.find(lname); - bool fOK = p != tokens.end(); - if( fOK ) { // name in use - tokens.erase(p); - } else { - error_msg(loc, "%s: %s not defined as a token", verb, name); - } - dbgmsg("%s:%d: %s removed as a valid token name", __func__, __LINE__, name); - return fOK; - } - - bool substitute( const YYLTYPE& loc, - const cbl_name_t extant, int token, const cbl_name_t name ) { - return - equate( loc, token, name, "SUBSTITUTE" ) - && - undefine( loc, extant, "SUBSTITUTE" ); - } - bool reserve( const YYLTYPE& loc, const cbl_name_t name ) { - auto lname( lowercase(name) ); - auto cw = cobol_words.insert(lname); - if( ! cw.second ) { - error_msg(loc, "COBOL-WORDS RESERVE: %s may appear but once", name); - return false; - } - tokens[lname] = -42; - return true; - } - int redefined_as( const cbl_name_t name ) { - auto lname( lowercase(name) ); - if( cobol_words.find(lname) != cobol_words.end() ) { - auto p = tokens.find(lname); - if( p != tokens.end() ) { - return p->second; - } - } - return 0; - } - const char * name_of( int tok ) const { - tok -= (255 + 3); - gcc_assert(0 <= tok && size_t(tok) < token_names.size()); - return token_names[tok]; - } -}; - -class current_tokens_t { - tokenset_t tokens; - public: - current_tokens_t() {} - int find( const cbl_name_t name, bool include_intrinsics ) { - return tokens.find(name, include_intrinsics); - } - bool equate( const YYLTYPE& loc, const cbl_name_t keyword, const cbl_name_t alias ) { - int token; - if( 0 == (token = binary_integer_usage_of(keyword)) ) { - if( 0 == (token = keyword_tok(keyword)) ) { - error_msg(loc, "EQUATE %s: not a valid token", keyword); - return false; - } - } - auto name = keyword_alias_add(tokens.uppercase(keyword), - tokens.uppercase(alias)); - if( name != keyword ) { - error_msg(loc, "EQUATE: %s is already an alias for %s", alias, name.c_str()); - return false; - } - return tokens.equate(loc, token, alias); - } - bool undefine( const YYLTYPE& loc, cbl_name_t keyword ) { - return tokens.undefine(loc, keyword); - } - bool substitute( const YYLTYPE& loc, const cbl_name_t keyword, const cbl_name_t alias ) { - int token; - if( 0 == (token = binary_integer_usage_of(keyword)) ) { - if( 0 == (token = keyword_tok(keyword)) ) { - error_msg(loc, "SUBSTITUTE %s: not a valid token", keyword); - return false; - } - } - auto name = keyword_alias_add(tokens.uppercase(keyword), - tokens.uppercase(alias)); - if( name != keyword ) { - error_msg(loc, "SUBSTITUTE: %s is already an alias for %s", alias, name.c_str()); - return false; - } - - dbgmsg("%s:%d: %s (%d) will have alias %s", __func__, __LINE__, keyword, token, alias); - return tokens.substitute(loc, keyword, token, alias); - } - bool reserve( const YYLTYPE& loc, const cbl_name_t name ) { - return tokens.reserve(loc, name); - } - int redefined_as( const cbl_name_t name ) { - return tokens.redefined_as(name); - } - const char * name_of( int tok ) const { - return tokens.name_of(tok); - } -} tokens; +#define cdf_tokens cdf_current_tokens() int redefined_token( const cbl_name_t name ) { - return tokens.redefined_as(name); + return cdf_tokens.redefined_as(name); } struct file_list_t { list<cbl_file_t*> files; file_list_t() {} - file_list_t( cbl_file_t* file ) { + explicit file_list_t( cbl_file_t* file ) { files.push_back(file); } file_list_t( file_list_t& that ) : files(that.files.size()) { @@ -1108,10 +959,15 @@ struct file_list_t { struct field_list_t { list<cbl_field_t*> fields; - field_list_t( cbl_field_t *field ) { + field_list_t() {} + explicit field_list_t( cbl_field_t *field ) { fields.push_back(field); } - explicit field_list_t() {} + std::vector<const cbl_field_t*> + as_vector() const { + std::vector<const cbl_field_t*> output( fields.begin(), fields.end() ); + return output; + } }; cbl_field_t ** @@ -1138,7 +994,7 @@ cbl_file_t ** struct refer_list_t { list<cbl_refer_t> refers; - refer_list_t( cbl_refer_t *refer ) { + explicit refer_list_t( cbl_refer_t *refer ) { if( refer ) { refers.push_back(*refer); delete refer; @@ -1160,13 +1016,20 @@ struct refer_list_t { refers.clear(); return tgt; } + std::vector<cbl_refer_t> + vectorize() { + std::vector<cbl_refer_t> tgt(refers.size()); + std::copy(refers.begin(), refers.end(), tgt.begin()); + refers.clear(); + return tgt; + } }; struct refer_marked_list_t : public refer_list_t { cbl_refer_t *marker; refer_marked_list_t() : refer_list_t(NULL), marker(NULL) {} - refer_marked_list_t( cbl_refer_t *marker, refer_list_t *refers ) + refer_marked_list_t( cbl_refer_t *marker, const refer_list_t *refers ) : refer_list_t(*refers), marker(marker) {} refer_marked_list_t( cbl_refer_t *marker, cbl_refer_t *input ) : refer_list_t(input) @@ -1186,7 +1049,7 @@ struct refer_marked_list_t : public refer_list_t { struct refer_collection_t { list<refer_marked_list_t> lists; - refer_collection_t( const refer_marked_list_t& marked_list ) + explicit refer_collection_t( const refer_marked_list_t& marked_list ) { lists.push_back( marked_list ); } @@ -1212,48 +1075,13 @@ struct refer_collection_t { } }; -struct ast_inspect_oper_t { - cbl_inspect_bound_t bound; // CHARACTERS/ALL/LEADING/FIRST - std::list<cbl_inspect_match_t> matches; - std::list<cbl_inspect_replace_t> replaces; - -ast_inspect_oper_t( const cbl_inspect_match_t& match, - cbl_inspect_bound_t bound = bound_characters_e ) - : bound(bound) - { - matches.push_back(match); - } - ast_inspect_oper_t( const cbl_inspect_replace_t& replace, - cbl_inspect_bound_t bound = bound_characters_e ) - : bound(bound) - { - replaces.push_back(replace); - } -}; - -struct ast_inspect_t : public std::list<cbl_inspect_oper_t> { - cbl_refer_t tally; // field is NULL for REPLACING - const std::list<cbl_inspect_oper_t>& opers() const { return *this; } -}; - -struct ast_inspect_list_t : public std::list<cbl_inspect_t> { - ast_inspect_list_t( const cbl_inspect_t& insp ) { - push_back(insp); - } - - cbl_inspect_t * as_array() { - cbl_inspect_t *output = new cbl_inspect_t[ size() ]; - std::copy( begin(), end(), output ); - return output; - } -}; - -void ast_inspect( cbl_refer_t& input, bool backward, ast_inspect_list_t& inspects ); +void ast_inspect( YYLTYPE loc, cbl_refer_t& input, bool backward, + cbl_inspect_opers_t& inspects ); template <typename E> struct elem_list_t { list<E*> elems; - elem_list_t( E *elem ) { + explicit elem_list_t( E *elem ) { elems.push_back(elem); } void clear() { @@ -1278,7 +1106,7 @@ template <typename L, typename E> struct unstring_tgt_t { cbl_refer_t *tgt, *delimiter, *count; - unstring_tgt_t( cbl_refer_t *tgt, + explicit unstring_tgt_t( cbl_refer_t *tgt, cbl_refer_t *delimiter = NULL, cbl_refer_t *count = NULL ) : tgt(tgt), delimiter(delimiter), count(count) @@ -1302,7 +1130,7 @@ struct unstring_tgt_t { struct unstring_tgt_list_t { list<unstring_tgt_t> unstring_tgts; - unstring_tgt_list_t( unstring_tgt_t *unstring_tgt ) { + explicit unstring_tgt_list_t( unstring_tgt_t *unstring_tgt ) { unstring_tgts.push_back(*unstring_tgt); delete unstring_tgt; } @@ -1324,7 +1152,7 @@ struct unstring_tgt_list_t { struct unstring_into_t : public unstring_tgt_list_t { cbl_refer_t pointer, tally; - unstring_into_t( unstring_tgt_list_t *tgt_list, + explicit unstring_into_t( unstring_tgt_list_t *tgt_list, cbl_refer_t *pointer = NULL, cbl_refer_t *tally = NULL ) : unstring_tgt_list_t(*tgt_list) @@ -1340,7 +1168,7 @@ struct unstring_into_t : public unstring_tgt_list_t { struct ffi_args_t { list<cbl_ffi_arg_t> elems; - ffi_args_t( cbl_ffi_arg_t *arg ) { + explicit ffi_args_t( cbl_ffi_arg_t *arg ) { this->push_back(arg); } @@ -1416,8 +1244,8 @@ struct file_sort_io_t { file_list_t file_list; cbl_perform_tgt_t tgt; - file_sort_io_t( file_list_t& files ) : file_list(files) {} - file_sort_io_t( cbl_perform_tgt_t& tgt ) : tgt(tgt.from(), tgt.to()) {} + explicit file_sort_io_t( file_list_t& files ) : file_list(files) {} + explicit file_sort_io_t( cbl_perform_tgt_t& tgt ) : tgt(tgt.from(), tgt.to()) {} size_t nfile() const { return file_list.files.size(); } }; @@ -1432,14 +1260,14 @@ struct merge_t { cbl_perform_tgt_t tgt; list<cbl_file_t*> outputs; - merge_t( cbl_file_t *input ) : master(input), type(output_unknown_e) {} + explicit merge_t( cbl_file_t *input ) : master(input), type(output_unknown_e) {} }; static list<merge_t> merges; static inline merge_t& merge_alloc( cbl_file_t *file ) { - merges.push_back(file); + merges.push_back(merge_t(file)); return merges.back(); } @@ -1460,7 +1288,7 @@ static list<cbl_refer_t> lhs; struct vargs_t { std::list<cbl_refer_t> args; vargs_t() {} - vargs_t( struct cbl_refer_t *p ) { args.push_back(*p); delete p; } + explicit vargs_t( struct cbl_refer_t *p ) { args.push_back(*p); delete p; } void push_back( cbl_refer_t *p ) { args.push_back(*p); delete p; } }; @@ -1484,7 +1312,8 @@ class prog_descr_t { const char *collating_sequence; struct locale_t { cbl_name_t name; const char *os_name; - locale_t(const cbl_name_t name = NULL, const char *os_name = NULL) + locale_t() : name(""), os_name(nullptr) {} + locale_t(const cbl_name_t name, const char *os_name) : name(""), os_name(os_name) { if( name ) { bool ok = namcpy(YYLTYPE(), this->name, name); @@ -1492,18 +1321,15 @@ class prog_descr_t { } } } locale; - cbl_call_convention_t call_convention; cbl_options_t options; - prog_descr_t( size_t isymbol ) + explicit prog_descr_t( size_t isymbol ) : program_index(isymbol) , declaratives_eval(NULL) , paragraph(NULL) , section(NULL) , collating_sequence(NULL) - { - call_convention = current_call_convention(); - } + {} std::set<std::string> external_targets() { std::set<std::string> externals; @@ -1592,24 +1418,13 @@ static cbl_label_t * implicit_section(); class program_stack_t : protected std::stack<prog_descr_t> { struct pending_t { - cbl_call_convention_t call_convention; bool initial; - pending_t() - : call_convention(cbl_call_convention_t(0)) - , initial(false) - {} + pending_t() : initial(false) {} } pending; public: - cbl_call_convention_t - pending_call_convention( cbl_call_convention_t convention ) { - return pending.call_convention = convention; - } bool pending_initial() { return pending.initial = true; } void push( prog_descr_t descr ) { - cbl_call_convention_t current_call_convention = cbl_call_cobol_e; - if( !empty() ) current_call_convention = top().call_convention; - descr.call_convention = current_call_convention; std::stack<prog_descr_t>& me(*this); me.push(descr); } @@ -1635,9 +1450,6 @@ class program_stack_t : protected std::stack<prog_descr_t> { } void apply_pending() { - if( size() == 1 && 0 != pending.call_convention ) { - top().call_convention = pending.call_convention; - } if( pending.initial ) { auto e = symbol_at(top().program_index); auto prog(cbl_label_of(e)); @@ -1645,11 +1457,12 @@ class program_stack_t : protected std::stack<prog_descr_t> { } } + // cppcheck-suppress-begin useStlAlgorithm cbl_label_t *first_declarative() { auto eval = top().declaratives_eval; if( eval ) return eval; // scan stack container for declaratives - for( auto& prog : c ) { + for( const auto& prog : c ) { if( prog.declaratives_eval ) { eval = prog.declaratives_eval; break; @@ -1657,6 +1470,7 @@ class program_stack_t : protected std::stack<prog_descr_t> { } return eval; } + // cppcheck-suppress-end useStlAlgorithm }; struct rel_part_t { @@ -1664,9 +1478,13 @@ struct rel_part_t { bool has_relop, invert; relop_t relop; - rel_part_t( cbl_refer_t *operand = NULL, - relop_t relop = relop_t(-1), - bool invert = false ) + rel_part_t() + : operand(nullptr), + has_relop(false), + invert(false), + relop(relop_t(-1)) + {} + rel_part_t( cbl_refer_t *operand, relop_t relop, bool invert ) : operand(operand), has_relop(relop != -1), invert(invert), @@ -1700,7 +1518,7 @@ struct rel_part_t { class log_expr_t { cbl_field_t *orable, *andable; public: - log_expr_t( cbl_field_t *init ) : orable(NULL), andable(init) { + explicit log_expr_t( cbl_field_t *init ) : orable(NULL), andable(init) { if( ! is_conditional(init) ) { dbgmsg("%s:%d: logic error: %s is not a truth value", __func__, __LINE__, name_of(init)); @@ -1859,6 +1677,10 @@ static class current_t { class declaratives_t : protected declaratives_list_t { struct file_exception_t { ec_type_t type; uint32_t file; + file_exception_t() : type(ec_none_e), file(0) {} + file_exception_t(ec_type_t type, uint32_t file) + : type(type), file(file) + {} bool operator<( const file_exception_t& that ) const { if( type == that.type ) return file < that.file; return type < that.type; @@ -1866,9 +1688,11 @@ static class current_t { }; std::set<file_exception_t> file_exceptions; public: + declaratives_t() {} // current compiled data for enabled ECs and Declaratives, used by library. struct runtime_t { tree ena, dcl; + runtime_t() : ena(nullptr), dcl(nullptr) {} } runtime; bool empty() const { @@ -1888,7 +1712,7 @@ static class current_t { } for( auto f = declarative.files; f && f < declarative.files + declarative.nfile; f++ ) { - file_exception_t ex = { declarative.type, *f }; + file_exception_t ex( declarative.type, *f ); auto result = file_exceptions.insert(ex); if( ! result.second ) { yyerror("%s defined twice for %s", @@ -1901,6 +1725,7 @@ static class current_t { return true; } + // cppcheck-suppress-begin useStlAlgorithm uint32_t status() const { uint32_t status_word = 0; for( auto dcl : *this ) { @@ -1908,6 +1733,7 @@ static class current_t { } return status_word; } + // cppcheck-suppress-end useStlAlgorithm bool has_format_1() const { return std::any_of( begin(), end(), @@ -1947,7 +1773,6 @@ static class current_t { const cbl_field_t * has_typedef( const cbl_field_t *field ) { auto found = typedefs.find(field); return found == typedefs.end()? NULL : *found; - return found == typedefs.end()? NULL : *found; } void udf_add( size_t isym ) { @@ -2003,12 +1828,12 @@ static class current_t { std::list<std::string>& debugging_declaratives(bool all) const { const char *para = programs.top().paragraph->name; - auto declaratives = debugging_clients.find(all? ":all:" : para); - if( declaratives == debugging_clients.end() ) { + auto client = debugging_clients.find(all? ":all:" : para); + if( client == debugging_clients.end() ) { static std::list<std::string> empty; return empty; } - return declaratives->second; + return client->second; } bool @@ -2031,19 +1856,6 @@ static class current_t { return programs.top().options.default_round = mode; } - cbl_call_convention_t - call_convention() { - return programs.empty()? cbl_call_cobol_e : programs.top().call_convention; - } - cbl_call_convention_t - call_convention( cbl_call_convention_t convention) { - if( programs.empty() ) { - return programs.pending_call_convention(convention); - } - auto& prog( programs.top() ); - return prog.call_convention = convention; - } - const char * locale() { return programs.empty()? NULL : programs.top().locale.os_name; @@ -2079,7 +1891,7 @@ static class current_t { const cbl_label_t *L; if( (L = symbol_program_add(parent, &label)) == NULL ) return false; - programs.push( symbol_index(symbol_elem_of(L))); + programs.push( prog_descr_t(symbol_index(symbol_elem_of(L))) ); programs.apply_pending(); bool fOK = symbol_at(programs.top().program_index) + 1 == symbols_end(); @@ -2123,7 +1935,7 @@ static class current_t { if( ! dialect_ibm() ) { error_msg(loc, "Per ISO a program with DECLARATIVES must begin with a SECTION, " - "requires -dialect ibm"); + "requires %<-dialect ibm%>"); } } } @@ -2141,13 +1953,14 @@ static class current_t { * ISO, in new_program. */ std::set<std::string> end_program() { + cbl_enabled_exceptions_t& enabled_exceptions( cdf_enabled_exceptions() ); if( enabled_exceptions.size() ) { declaratives_evaluate(); } assert(!programs.empty()); - procref_t *ref = ambiguous_reference(program_index()); + const procref_t *ref = ambiguous_reference(program_index()); std::set<std::string> externals = programs.top().external_targets(); /* @@ -2158,9 +1971,19 @@ static class current_t { * subprograms, and whether or not they are COMMON. PROGRAM may be * the caller, or a subprogram could call COMMON sibling. */ + + static std::unordered_set<size_t> callers_we_have_seen; if( programs.size() == 1 ) { if( yydebug ) parser_call_targets_dump(); for( size_t caller : symbol_program_programs() ) { + // We are running through the entire growing list of called programs + // at the point of each END PROGRAM. This confuses the name changing + // routines, so we use a std::set to avoid doing callers more than + // once. + if( callers_we_have_seen.find(caller) != callers_we_have_seen.end() ) + { + continue; + } const char *caller_name = cbl_label_of(symbol_at(caller))->name; for( auto callable : symbol_program_callables(caller) ) { auto called = cbl_label_of(symbol_at(callable)); @@ -2168,13 +1991,16 @@ static class current_t { called->mangled_name? called->mangled_name : called->name; size_t n = - parser_call_target_update(caller, called->name, mangled_name); + parser_call_target_update(caller, + called->name, + mangled_name); // Zero is not an error dbgmsg("updated " HOST_SIZE_T_PRINT_UNSIGNED " calls from #%-3" GCC_PRISZ "u (%s) s/%s/%s/", (fmt_size_t)n, (fmt_size_t)caller, caller_name, called->name, mangled_name); } + callers_we_have_seen.insert(caller); } if( yydebug ) parser_call_targets_dump(); } @@ -2371,11 +2197,12 @@ void current_enabled_ecs( tree ena ) { static void add_debugging_declarative( const cbl_label_t * label ) { + // cppcheck-suppress [unreadVariable] obviously not true const char *section = current.declarative_section_name(); if( section ) { debugging_clients[label->name].push_back(section); } -}; +} cbl_options_t current_options() { return current.options_paragraph; @@ -2417,15 +2244,6 @@ current_rounded_mode( cbl_round_t rounded) { #endif static cbl_round_t current_rounded_mode( int token ); -cbl_call_convention_t -current_call_convention() { - return current.call_convention(); -} -cbl_call_convention_t -current_call_convention( cbl_call_convention_t convention) { - return current.call_convention(convention); -} - size_t program_level() { return current.program_level(); } static size_t constant_index( int token ); @@ -2564,7 +2382,8 @@ is_callable( const cbl_field_t *field ) { case FldPointer: return true; } - cbl_internal_error( "%s:%d: invalid symbol_type_t %d", __func__, __LINE__, field->type ); + cbl_internal_error( "%s:%d: invalid %<symbol_type_t%> %d", + __func__, __LINE__, field->type ); return false; } @@ -2611,8 +2430,8 @@ intrinsic_call_1( cbl_field_t *output, int token, } static bool -intrinsic_call_2( cbl_field_t *tgt, int token, cbl_refer_t *r1, cbl_refer_t *r2 ) { - std::vector<cbl_refer_t> args { *r1, *r2 }; +intrinsic_call_2( cbl_field_t *tgt, int token, const cbl_refer_t *r1, cbl_refer_t *r2 ) { + std::vector<cbl_refer_t> args { *r1, r2? *r2 : cbl_refer_t() }; size_t n = intrinsic_invalid_parameter(token, args); if( n < args.size() ) { error_msg(args[n].loc, "invalid parameter '%s'", args[n].field->name); @@ -2689,18 +2508,14 @@ table_primary_index( cbl_field_t *table ) { NULL : cbl_field_of(symbol_at(table->occurs.indexes.fields[0])); } -static inline const cbl_refer_t // & // Removed the '&' to stop a weird compiler error +static inline const cbl_refer_t // return copy, not element reference invalid_key( const cbl_refer_t& ref ) { assert(ref.field); - - if( ref.nsubscript == 0 ) return ref; - - for( size_t i=0; i < ref.nsubscript; i++ ) { - if( ref.subscripts[i].field->parent != ref.field->parent ) { - return ref.subscripts[i]; - } - } - return NULL; + auto p = std::find_if( ref.subscripts.begin(), ref.subscripts.end(), + [parent = ref.field->parent]( const auto &sub ) { + return sub.field->parent == parent; + } ); + return p != ref.subscripts.end() ? *p : nullptr; } static inline symbol_elem_t * @@ -2902,17 +2717,6 @@ group_attr( const cbl_field_t * field ) { return p->attr; } -static struct symbol_elem_t * -field_of( const char F[], int L, const char name[] ) { - struct symbol_elem_t *e = symbol_field(PROGRAM, 0, name); - if( !e ) { - cbl_internal_error("%s:%d: no symbol '%s' found", F, L, name); - } - assert( procedure_div_e != current_division ); - return e; -} -#define field_of( F ) field_of(__func__, __LINE__, (F)) - static struct cbl_field_t * field_add( const YYLTYPE& loc, cbl_field_t *field ) { switch(current_data_section) { @@ -3186,14 +2990,14 @@ cmd_or_env_special_of( std::string name ) { } static inline void -parser_add2( struct cbl_num_result_t& to, - struct cbl_refer_t from ) { +parser_add2( const cbl_num_result_t& to, + const cbl_refer_t& from ) { parser_add(to.refer, to.refer, from, to.rounded); } static inline void -parser_subtract2( struct cbl_num_result_t to, - struct cbl_refer_t from ) { +parser_subtract2( const cbl_num_result_t& to, + const cbl_refer_t& from ) { parser_subtract(to.refer, to.refer, from, to.rounded); } @@ -3216,6 +3020,11 @@ parser_move_carefully( const char */*F*/, int /*L*/, } } else { if( ! valid_move( tgt.field, src.field ) ) { + if( src.field->type == FldPointer && + tgt.field->type == FldPointer ) { + if( dialect_mf() || dialect_gnu() ) return true; + dialect_error(src.loc, "MOVE POINTER", "mf"); + } if( ! is_index ) { char ach[16]; char stype[32]; @@ -3241,7 +3050,6 @@ parser_move_carefully( const char */*F*/, int /*L*/, sprintf(ach, ".%d", tgt.field->data.rdigits); strcat(dtype, ach); } - error_msg(src.loc, "cannot MOVE '%s' (%s) to '%s' (%s)", name_of(src.field), stype, name_of(tgt.field), dtype); @@ -3277,11 +3085,11 @@ ast_set_pointers( const list<cbl_num_result_t>& tgts, cbl_refer_t src ) { void stringify( refer_collection_t *inputs, - cbl_refer_t into, cbl_refer_t pointer, + const cbl_refer_t& into, const cbl_refer_t& pointer, cbl_label_t *on_error = NULL, cbl_label_t *not_error = NULL); -void unstringify( cbl_refer_t& src, refer_list_t *delimited, +void unstringify( const cbl_refer_t& src, refer_list_t *delimited, unstring_into_t * into, cbl_label_t *on_error = NULL, cbl_label_t *not_error = NULL ); @@ -3306,6 +3114,7 @@ implicit_section() } static void +// cppcheck-suppress constParameterPointer ast_enter_exit_section( cbl_label_t * section ) { auto implicit = section? implicit_paragraph() : NULL; @@ -3385,7 +3194,7 @@ data_division_ready() { static bool -anybody_redefines(cbl_field_t *tree) +anybody_redefines( const cbl_field_t *tree ) { bool retval = false; while(tree) @@ -3395,7 +3204,8 @@ anybody_redefines(cbl_field_t *tree) retval = true; break; } - tree = parent_of(tree); + // cppcheck-suppress [unreadVariable] obviously not true + tree = parent_of(tree); } return retval; } @@ -3615,14 +3425,14 @@ file_section_parent_set( cbl_field_t *field ) { field->data.capacity); field->file = file_section_fd; - auto redefined = symbol_redefines(record_area); + const auto redefined = symbol_redefines(record_area); field->parent = redefined? record_area->parent : file->default_record; } return file_section_fd > 0; } void ast_call(const YYLTYPE& loc, cbl_refer_t name, - cbl_refer_t returning, + const cbl_refer_t& returning, size_t narg, cbl_ffi_arg_t args[], cbl_label_t *except, cbl_label_t *not_except, @@ -3683,18 +3493,18 @@ goodnight_gracie() { // false after USE statement, to enter Declarative with EC intact. static bool statement_cleanup = true; +static YYLTYPE current_location; static void statement_epilog( int token ); const char * keyword_str( int token ); -static YYLTYPE current_location; - const YYLTYPE& cobol_location() { return current_location; } -static inline YYLTYPE +static inline void location_set( const YYLTYPE& loc ) { - return current_location = loc; + current_location = loc; + gcc_location_set(loc); } static void statement_begin( const YYLTYPE& loc, int token ); diff --git a/gcc/cobol/parse_util.h b/gcc/cobol/parse_util.h index e504f46ee405..20847e3ef469 100644 --- a/gcc/cobol/parse_util.h +++ b/gcc/cobol/parse_util.h @@ -271,7 +271,7 @@ function_descr_t *function_descrs_end = function_descrs + COUNT_OF(function_desc class cname_cmp { const char *cname; public: - cname_cmp( const char *cname ) : cname(cname) {} + explicit cname_cmp( const char *cname ) : cname(cname) {} bool operator()( const function_descr_t& descr ) { return strlen(cname) == strlen(descr.cname) && @@ -283,6 +283,15 @@ class cname_cmp { } }; +static int +intrinsic_token_of( const char name[] ) { + auto pdescr = std::find_if( function_descrs, function_descrs_end, + [name]( const function_descr_t& descr ) { + return 0 == strcmp(name, descr.name); + } ); + return pdescr == function_descrs_end? 0 : pdescr->token; +} + /* * For variadic intrinsic functions, ensure all parameters are commensurate. * Return pointer in 1st inconsistent parameter type. @@ -293,8 +302,8 @@ intrinsic_inconsistent_parameter( size_t n, cbl_refer_t *args ) { class commensurate_type { cbl_refer_t first; public: - commensurate_type( const cbl_refer_t& first ) : first(first) {} - bool operator()( cbl_refer_t& arg ) const { + explicit commensurate_type( const cbl_refer_t& first ) : first(first) {} + bool operator()( const cbl_refer_t& arg ) const { return is_numeric(first.field) == is_numeric(arg.field); } }; @@ -348,7 +357,7 @@ intrinsic_invalid_parameter( int token, return token == descr.token; } ); if( p == function_descrs_end ) { - cbl_internal_error( "%s: intrinsic function %s not found", + cbl_internal_error( "%s: intrinsic function %qs not found", __func__, keyword_str(token) ); } diff --git a/gcc/cobol/scan.l b/gcc/cobol/scan.l index c11f66ef960a..2da38d82a2e7 100644 --- a/gcc/cobol/scan.l +++ b/gcc/cobol/scan.l @@ -79,14 +79,19 @@ nonseq (([''][[:alnum:]]+][''])|([""][[:alnum:]]+[""])) INTEGER 0*[1-9][[:digit:]]* INTEGERZ [[:digit:]]+ +NONWORD [^[:alnum:]$_-]+ + SPC [[:space:]]+ OSPC [[:space:]]* +BLANK [[:blank:]]+ +OBLANK [[:blank:]]* EOL \r?\n BLANK_EOL [[:blank:]]*{EOL} BLANK_OEOL [[:blank:]]*{EOL}? +PICTURE [^[:space:]]+ -DOTSEP [.][[:space:]] +DOTSEP [.]+[[:space:]] DOTEOL [[:blank:]]*[.]{BLANK_EOL} SKIP [[:blank:]]*SKIP[123][[:blank:]]*[.]?{BLANK_EOL} @@ -158,7 +163,7 @@ COMMA [,;][[:blank:]]* ISNT (IS{SPC})?NOT -COMMENTARY DATE-COMPILED|DATE-WRITTEN|INSTALLATION|SECURITY +COMMENTARY AUTHOR|DATE-COMPILED|DATE-WRITTEN|INSTALLATION|SECURITY SORT_MERGE SORT(-MERGE)? @@ -172,15 +177,15 @@ SIZE_ERROR (ON[[[:space:]]+)?SIZE[[:space:]]+ERROR VARTYPE NUMERIC|ALPHABETIC|ALPHABETIC_LOWER|ALPHABETIC_UPPER|DBCS|KANJI NAMTYP {NAME}|{VARTYPE} -NL [[:blank:]]*\r?\n[[:blank:]]* +NL [[:blank:]]*{EOL}[[:blank:]]* PUSH_FILE \f?[#]FILE{SPC}PUSH{SPC}[^\f]+\f POP_FILE \f?[#]FILE{SPC}POP\f -LINE_DIRECTIVE [#]line{SPC}[[:alnum:]]+{SPC}[""''].+\n +LINE_DIRECTIVE ^[#]line{SPC}[[:alnum:]]+{SPC}[""''].+\n %x procedure_div ident_state addr_of function classify %x program_id_state comment_entries -%x author_state date_state field_level field_state dot_state +%x date_state field_level field_state dot_state %x numeric_state name_state %x quoted1 quoted2 quoteq %x picture picture_count integer_count @@ -236,30 +241,23 @@ WORKING-STORAGE{SPC}SECTION { yy_push_state(field_state); return WORKING_STORAGE_SECT; } LOCAL-STORAGE{SPC}SECTION { - yy_push_state(field_state); - return LOCAL_STORAGE_SECT; } -WORKING-STORAGE { - return WORKING_STORAGE; } -LOCAL-STORAGE { - return LOCAL_STORAGE; } -SCREEN { - return SCREEN; } + yy_push_state(field_state); + return LOCAL_STORAGE_SECT; } +WORKING-STORAGE { return WORKING_STORAGE; } +LOCAL-STORAGE { return LOCAL_STORAGE; } +SCREEN { return SCREEN; } LINKAGE{SPC}SECTION { yy_push_state(field_state); return LINKAGE_SECT; } -FUNCTION-ID { yy_push_state(ident_state); - yy_push_state(program_id_state); - yy_push_state(name_state); return FUNCTION; } - -PROGRAM-ID { yy_push_state(ident_state); - yy_push_state(program_id_state); - yy_push_state(name_state); return PROGRAM_ID; } +FUNCTION-ID{OSPC}{DOTSEP}? { yy_push_state(ident_state); + yy_push_state(program_id_state); + yy_push_state(name_state); return FUNCTION; } -PROGRAM-ID/{DOTEOL} { yy_push_state(ident_state); - yy_push_state(name_state); - yy_push_state(dot_state); return PROGRAM_ID; } +PROGRAM-ID{OSPC}{DOTSEP}? { yy_push_state(ident_state); + yy_push_state(program_id_state); + yy_push_state(name_state); return PROGRAM_ID; } PROCEDURE{SPC}DIVISION { yy_push_state(procedure_div); return PROCEDURE_DIV; } @@ -270,29 +268,18 @@ PROCEDURE{SPC}DIVISION { yy_push_state(procedure_div); } <ident_state>{ + {BLANK_OEOL} + ID(ENTIFICATION)?{SPC}DIVISION { myless(0); yy_pop_state(); } + (ENVIRONMENT|DATA|PROCEDURE){SPC}DIVISION { + myless(0); yy_pop_state(); } + OPTIONS { myless(0); yy_pop_state(); } + AS{SPC}[""] { yy_push_state(quoted2); return AS; } AS{SPC}[''] { yy_push_state(quoted1); return AS; } IS { pop_return IS; } - OPTIONS { yy_pop_state(); myless(0); } - [[:blank:]]*(ENVIRONMENT|DATA|PROCEDURE){SPC}DIVISION/[[:space:].] { - yy_pop_state(); myless(0); } - [[:blank:]]*AUTHOR[[:blank:].]+{EOL}? { - // Might not have an EOL, but stop on one. - yy_push_state(author_state); } - - {DOTEOL} - {COMMENTARY} { BEGIN(comment_entries); } } -<author_state>{ - [[:blank:]]+ - ^{BLANK_EOL} - [^\r\n]+ { yy_pop_state(); - yylval.string = xstrdup(yytext); - } -} - <INITIAL>{ COBOL { return COBOL; } @@ -304,6 +291,15 @@ PROCEDURE{SPC}DIVISION { yy_push_state(procedure_div); yy_push_state(field_state); yy_set_bol(1); myless(0); } + + END{SPC}PROGRAM { yy_push_state(name_state); + return program_level() > 1? + END_SUBPROGRAM : END_PROGRAM; } + + END{SPC}FUNCTION { yy_push_state(name_state); + return program_level() > 1? + END_SUBPROGRAM /*invalid*/ : + END_FUNCTION; } } <INITIAL,procedure_div,cdf_state>{ @@ -326,6 +322,15 @@ CENTER { return typed_name(yytext); } + /* figurative constants that are otherwise matched as names */ + +ZEROE?S?/{OSPC}{DOTSEP} { return ZERO; } +SPACES?/{OSPC}{DOTSEP} { yylval.string = NULL; return SPACES; } +QUOTES?/{OSPC}{DOTSEP} { return QUOTES; } +NULLS?/{OSPC}{DOTSEP} { return NULLS; } +LOW-VALUES?/{OSPC}{DOTSEP} { return LOW_VALUES; } +HIGH-VALUES?/{OSPC}{DOTSEP} { return HIGH_VALUES; } + BINARY { return BINARY; } CLASSIFICATION { return CLASSIFICATION; } CYCLE { return CYCLE; } @@ -432,6 +437,11 @@ STDOUT { return STDOUT; } STDERR { return STDERR; } SYSERR { return STDERR; } +ARGUMENT-NUMBER { return ARGUMENT_NUMBER; } +ARGUMENT-VALUE { return ARGUMENT_VALUE; } +ENVIRONMENT-NAME { return ENVIRONMENT_NAME; } +ENVIRONMENT-VALUE { return ENVIRONMENT_VALUE; } + CANCEL { return CANCEL; } COMMIT { return COMMIT; } COMMON { return COMMON; } @@ -529,7 +539,7 @@ SECTION{SPC}[+-]?{INTEGERZ}/{OSPC}{DOTSEP} { auto eotext = yytext + yyleng; auto p = std::find_if(yytext, eotext, fisspace); p = std::find_if(p, eotext, nonspace); - yylval.string = p; + yylval.string = xstrdup(p); return SECTION; } @@ -856,8 +866,9 @@ ANUM { return ANUM; } ALTERNATE { return ALTERNATE; } ALTER { return ALTER; } ALSO { return ALSO; } -ALPHABET { return ALPHABET; } -ALPHABETIC { return ALPHABETIC; } + +ALPHABET { return ALPHABET; } +ALPHABETIC { return ALPHABETIC; } ALPHABETIC-LOWER { return ALPHABETIC_LOWER; } ALPHABETIC-UPPER { return ALPHABETIC_UPPER; } ALPHANUMERIC { return ALPHANUMERIC; } @@ -955,7 +966,9 @@ USE({SPC}FOR)? { return USE; } return NUMSTR; } - PIC(TURE)?({SPC}IS)?[[:space:]]{BLANK_OEOL} { + PIC(TURE)?({SPC}IS)?{SPC}{PICTURE} { + auto pos = validate_picture(); + myless(pos); yy_push_state(picture); return PIC; } ANY { return ANY; } @@ -980,7 +993,7 @@ USE({SPC}FOR)? { return USE; } BINARY-LONG { return bcomputable(FldNumericBin5, 4); } BINARY-DOUBLE { return bcomputable(FldNumericBin5, 8); } BINARY-LONG-LONG { if( ! dialect_mf() ) { - error_msg(yylloc, "%s requires -dialect mf", yytext); + dialect_error(yylloc, yytext, "mf"); } return bcomputable(FldNumericBin5, 8); } @@ -991,7 +1004,7 @@ USE({SPC}FOR)? { return USE; } FLOAT-BINARY-32 { return ucomputable(FldFloat, 4); } FLOAT-BINARY-64 { return ucomputable(FldFloat, 8); } FLOAT-BINARY-128 { return ucomputable(FldFloat, 16); } - FLOAT-DECIMAL-(16|34) { not_implemented("USAGE type: FLOAT_DECIMAL"); + FLOAT-DECIMAL-(16|34) { not_implemented("USAGE type: %<FLOAT_DECIMAL%>"); return FLOAT_DECIMAL; // causes syntax error } /* 21) The representation and length of a data item described with USAGE @@ -1017,7 +1030,7 @@ USE({SPC}FOR)? { return USE; } POINTER { yylval.field_attr = none_e; return POINTER; } PROCEDURE-POINTER { if( dialect_gcc() ) { - error_msg(yylloc, "%s requires -dialect ibm or mf", yytext); + dialect_error(yylloc, yytext, "ibm or mf"); } yylval.field_attr = prog_ptr_e; return POINTER; // return it anyway @@ -1137,7 +1150,7 @@ USE({SPC}FOR)? { return USE; } yy_push_state(hex_state); } N?X{nonseq} { dbgmsg("invalid hexadecimal value: %s", yytext); return NO_CONDITION; } - [[:blank:]]*\r?\n {} + [[:blank:]]*{EOL} {} WORKING-STORAGE{SPC}SECTION { return WORKING_STORAGE_SECT; } LOCAL-STORAGE{SPC}SECTION { return LOCAL_STORAGE_SECT; } @@ -1207,7 +1220,7 @@ USE({SPC}FOR)? { return USE; } {NP}V?/[,.]? { yylval.number = ndigit(yyleng); return picset(PIC_P); } {N9}*V/{N9}* { yylval.number = ndigit(yyleng - 1); return picset(NINEV); } {N9}/{N9}*[,.]? { yylval.number = ndigit(yyleng); return picset(NINES); } - P+/[,.]?\r?\n { yylval.number = yyleng; return picset(PIC_P); } + P+/[,.]?{EOL} { yylval.number = yyleng; return picset(PIC_P); } 1{1,31}/({COUNT}|[(]{NAME}[)]) { yy_push_state(picture_count); @@ -1306,7 +1319,7 @@ USE({SPC}FOR)? { return USE; } [""]{SPC}[&]{SPC}[""''] { if( yytext[yyleng - 1] == '\'' ) BEGIN(quoted1); } - [""]-{OSPC}(\r?\n{OSPC})+[""] /* continue ... */ + [""]-{OSPC}({EOL}{OSPC})+[""] /* continue ... */ [""] { char *s = xstrdup(tmpstring? tmpstring : "\0"); yylval.literal.set_data(strlen(s), s); @@ -1323,7 +1336,7 @@ USE({SPC}FOR)? { return USE; } ['']{SPC}[&]{SPC}[""''] { if( yytext[yyleng - 1] == '"' ) BEGIN(quoted2); } - ['']-{OSPC}(\r?\n{OSPC})+[''] /* continue ... */ + ['']-{OSPC}({EOL}{OSPC})+[''] /* continue ... */ [''] { char *s = xstrdup(tmpstring? tmpstring : "\0"); yylval.literal.set_data(strlen(s), s); @@ -1371,46 +1384,36 @@ USE({SPC}FOR)? { return USE; } } <program_id_state>{ - ^[[:blank:]]+ - ^{BLANK_EOL} + {BLANK_OEOL} (IS)?[[:space:]] + AS/{SPC} { myless(0); yy_pop_state(); } /* => ident_state */ - COMMON/[.]|{SPC}[[:alnum:].] { return COMMON; } - INITIAL/[.]|{SPC}[[:alnum:].] { return INITIAL_kw; } - RECURSIVE { return RECURSIVE; } - PROGRAM/[.]|{SPC}[[:alnum:].] { return PROGRAM_kw; } - - INITIAL { pop_return INITIAL_kw; } - COMMON { pop_return COMMON; } - PROGRAM { pop_return PROGRAM; } + INITIAL { return INITIAL_kw; } + COMMON { return COMMON; } + RECURSIVE { return RECURSIVE; } + PROGRAM { return PROGRAM_kw; } - AS/{SPC} { myless(0); yy_pop_state(); } /* => ident_state */ - [[:blank:]]*{DOTSEP}[[:blank:].]+{EOL} { pop_return '.'; } - {DOTEOL} { pop_return '.'; } + {DOTSEP} { pop_return '.'; } } -<name_state>{ - ^[[:blank:]]+ - ^{BLANK_EOL} - {NAME}/{OSPC}[.] { yy_pop_state(); - yylval.string = xstrdup(yytext); return NAME; } - {NAME} { yy_pop_state(); - yylval.string = xstrdup(yytext); return NAME; } +<name_state>{ /* Either pop from here, or let the quoted state pop */ + {BLANK_OEOL} + {NAME} { yy_pop_state(); + yylval.string = xstrdup(yytext); + return NAME; + } Z?[''] { yylval.literal.set_prefix(yytext, yyleng-1); - yy_push_state(quoted1); } + BEGIN(quoted1); } Z?[""] { yylval.literal.set_prefix(yytext, yyleng-1); - yy_push_state(quoted2); } - - [.]/[[:blank:]]+. { return *yytext; } + BEGIN(quoted2); } - [[:blank:]]*{DOTSEP}[[:blank:].]+{EOL} { - yy_pop_state(); myless(0); } - {DOTEOL} { yy_pop_state(); myless(0); } + . { myless(0); yy_pop_state(); + /* Should not happen for valid inputs. */ } } <dot_state>{ [[:blank:]]*[.][[:blank:].]+{EOL} { pop_return '.'; } - [[:blank:]]*[.] { pop_return '.'; } + [[:blank:]]*[.]+ { pop_return '.'; } } <date_state>{ @@ -1499,11 +1502,11 @@ USE({SPC}FOR)? { return USE; } {GREATER_THAN}{SPC}{OR_EQUAL}/[[:space:]] { return GE; } {GREATER_THAN} { return '>'; } - {ISNT}{SPC}">=" { return '<'; } - {ISNT}{SPC}">" { return LE; } - {ISNT}{SPC}"=" { return NE; } - {ISNT}{SPC}"<" { return GE; } - {ISNT}{SPC}"<=" { return '>'; } + {ISNT}{OSPC}">=" { verify_ws(yytext[yyleng - 3]); return '<'; } + {ISNT}{OSPC}">" { verify_ws(yytext[yyleng - 2]); return LE; } + {ISNT}{OSPC}"=" { verify_ws(yytext[yyleng - 2]); return NE; } + {ISNT}{OSPC}"<" { verify_ws(yytext[yyleng - 2]); return GE; } + {ISNT}{OSPC}"<=" { verify_ws(yytext[yyleng - 3]); return '>'; } {ISNT}{SPC}GREATER{SPC}(THAN)?{SPC}{OR_EQUAL}/[[:space:]] { return '<'; } {ISNT}{SPC}GREATER{SPC}(THAN)? { return LE; } @@ -1511,13 +1514,35 @@ USE({SPC}FOR)? { return USE; } {ISNT}{SPC}LESS{SPC}(THAN)? { return GE; } {ISNT}{SPC}LESS{SPC}(THAN)?{SPC}{OR_EQUAL}/[[:space:]] { return '>'; } - [*]{2}{SPC}[+] { return POW; } - "**" { return POW; } + [*]{2} { return POW; } + + /* + * "A boolean operator specifies the type of boolean operation to be performed + * on one or two operands, for a unary operator or binary operator, + * respectively." + * Binary boolean operators + * B-AND B-OR B-XOR + * Unary boolean operator + * B-NOT + * Boolean shift operators + * B-SHIFT-L B-SHIFT-LC B-SHIFT-R B-SHIFT-RC + */ + +B-AND +B-OR +B-XOR +B-NOT +B-SHIFT-L +B-SHIFT-LC +B-SHIFT-R +B-SHIFT-RC + } <procedure_div>{ (ID|IDENTIFICATION|ENVIRONMENT|DATA|PROCEDURE){SPC}DIVISION { - myless(0); yy_pop_state(); } + myless(0); BEGIN(INITIAL); } + PROGRAM-ID{OSPC}{DOTSEP} { myless(0); BEGIN(INITIAL); } EXIT{SPC}/(PROGRAM|SECTION|PARAGRAPH|PERFORM) { return EXIT; } @@ -1584,6 +1609,7 @@ USE({SPC}FOR)? { return USE; } DELIMITER { return DELIMITER; } ENVIRONMENT { return ENVIRONMENT; } + /* After name state, pop out of procedure_div state. */ END{SPC}PROGRAM { yy_push_state(name_state); return program_level() > 1? END_SUBPROGRAM : END_PROGRAM; } @@ -1610,24 +1636,10 @@ USE({SPC}FOR)? { return USE; } FUNCTION { yy_push_state(function); return FUNCTION; } - SECTION{OSPC}[.]{SPC}/USE[[:space:]] { yylval.string = NULL; return SECTION; } + SECTION{OSPC}[.]+{SPC}/USE[[:space:]] { yylval.string = NULL; return SECTION; } - {NAME}{OSPC}[.]({SPC}(EJECT|SKIP[123]))*{SPC}EXIT{OSPC}/{DOTSEP} { + [.]+({SPC}(EJECT|SKIP[123]))*{SPC}EXIT{OSPC}/{DOTSEP} { // EXIT format-1 is a "continue" statement - yylval.string = xstrdup(yytext); - auto p = strchr(yylval.string, '.'); - assert(p); - assert( ISSPACE(p[1]) ); - *p = '\0'; - while( p > yylval.string && ISSPACE(p[-1]) ) { - *--p = '\0'; - } - - int token; - if( 0 != (token = binary_integer_usage(yylval.string)) )return token; - if( 0 != (token = keyword_tok(yylval.string)) ) return token; - if( is_integer_token() ) return numstr_of(yylval.string); - return typed_name(yylval.string); } {NAME}/{OSPC}{DOTSEP} { assert(YY_START == procedure_div); @@ -1795,126 +1807,128 @@ USE({SPC}FOR)? { return USE; } } <function>{ - - - ABS{OSPC}/[(]? { pop_return ABS; } - ACOS{OSPC}/[(]? { pop_return ACOS; } - ANNUITY{OSPC}/[(]? { pop_return ANNUITY; } - ASIN{OSPC}/[(]? { pop_return ASIN; } - ATAN{OSPC}/[(]? { pop_return ATAN; } - BASECONVERT{OSPC}/[(]? { pop_return BASECONVERT; } - BIT-OF{OSPC}/[(]? { pop_return BIT_OF; } - BIT-TO-CHAR{OSPC}/[(]? { pop_return BIT_TO_CHAR; } - BOOLEAN-OF-INTEGER{OSPC}/[(]? { pop_return BOOLEAN_OF_INTEGER; } - BYTE-LENGTH{OSPC}/[(]? { pop_return BYTE_LENGTH; } - CHAR-NATIONAL{OSPC}/[(]? { pop_return CHAR_NATIONAL; } - CHAR{OSPC}/[(]? { pop_return CHAR; } - COMBINED-DATETIME{OSPC}/[(]? { pop_return COMBINED_DATETIME; } - CONCAT{OSPC}/[(]? { pop_return CONCAT; } - CONTENT-LENGTH{OSPC}/[(]? { pop_return NO_CONDITION; /* GNU only*/ } - CONTENT-OF{OSPC}/[(]? { pop_return NO_CONDITION; /* GNU only*/ } - CONVERT{OSPC}/[(]? { pop_return CONVERT; } - COS{OSPC}/[(]? { pop_return COS; } - CURRENCY-SYBOL{OSPC}/[(]? { pop_return NO_CONDITION; /* GNU only*/ } - CURRENT-DATE{OSPC}/[(]? { pop_return CURRENT_DATE; } - DATE-OF-INTEGER{OSPC}/[(]? { pop_return DATE_OF_INTEGER; } - DATE-TO-YYYYMMDD{OSPC}/[(]? { pop_return DATE_TO_YYYYMMDD; } - DAY-OF-INTEGER{OSPC}/[(]? { pop_return DAY_OF_INTEGER; } - DAY-TO-YYYYDDD{OSPC}/[(]? { pop_return DAY_TO_YYYYDDD; } - DISPLAY-OF{OSPC}/[(]? { pop_return DISPLAY_OF; } - E{OSPC}/[(]? { pop_return E; } - - EXCEPTION-FILE-N{OSPC}/[(]? { pop_return EXCEPTION_FILE_N; } - EXCEPTION-FILE{OSPC}/[(]? { pop_return EXCEPTION_FILE; } - EXCEPTION-LOCATION-N{OSPC}/[(]? { pop_return EXCEPTION_LOCATION_N; } - EXCEPTION-LOCATION{OSPC}/[(]? { pop_return EXCEPTION_LOCATION; } - EXCEPTION-STATEMENT{OSPC}/[(]? { pop_return EXCEPTION_STATEMENT; } - EXCEPTION-STATUS{OSPC}/[(]? { pop_return EXCEPTION_STATUS; } - - EXP{OSPC}/[(]? { pop_return EXP; } - EXP10{OSPC}/[(]? { pop_return EXP10; } - FACTORIAL{OSPC}/[(]? { pop_return FACTORIAL; } - FIND-STRING{OSPC}/[(]? { pop_return FIND_STRING; } - - FORMATTED-CURRENT-DATE{OSPC}/[(]? { BEGIN(datetime_fmt); return FORMATTED_CURRENT_DATE; } - FORMATTED-DATE{OSPC}/[(]? { BEGIN(datetime_fmt); return FORMATTED_DATE; } - FORMATTED-DATETIME{OSPC}/[(]? { BEGIN(datetime_fmt); return FORMATTED_DATETIME; } - FORMATTED-TIME{OSPC}/[(]? { BEGIN(datetime_fmt); return FORMATTED_TIME; } - FRACTION-PART{OSPC}/[(]? { pop_return FRACTION_PART; } - - HEX-OF{OSPC}/[(]? { pop_return HEX_OF; } - HEX-TO-CHAR{OSPC}/[(]? { pop_return HEX_TO_CHAR; } - HIGHEST-ALGEBRAIC{OSPC}/[(]? { pop_return HIGHEST_ALGEBRAIC; } - - INTEGER{OSPC}/[(]? { pop_return INTEGER; } - INTEGER-OF-BOOLEAN{OSPC}/[(]? { pop_return INTEGER_OF_BOOLEAN; } - INTEGER-OF-DATE{OSPC}/[(]? { pop_return INTEGER_OF_DATE; } - INTEGER-OF-DAY{OSPC}/[(]? { pop_return INTEGER_OF_DAY; } - INTEGER-OF-FORMATTED-DATE{OSPC}/[(]? { BEGIN(datetime_fmt); return INTEGER_OF_FORMATTED_DATE; } - INTEGER-PART{OSPC}/[(]? { pop_return INTEGER_PART; } - LENGTH{OSPC}/[(]? { pop_return LENGTH; } - LOCALE-COMPARE{OSPC}/[(]? { pop_return LOCALE_COMPARE; } - LOCALE-DATE{OSPC}/[(]? { pop_return LOCALE_DATE; } - LOCALE-TIME{OSPC}/[(]? { pop_return LOCALE_TIME; } - LOCALE-TIME-FROM-SECONDS{OSPC}/[(]? { pop_return LOCALE_TIME_FROM_SECONDS; } - LOG{OSPC}/[(]? { pop_return LOG; } - LOG10{OSPC}/[(]? { pop_return LOG10; } - LOWER-CASE{OSPC}/[(]? { pop_return LOWER_CASE; } - LOWEST-ALGEBRAIC{OSPC}/[(]? { pop_return LOWEST_ALGEBRAIC; } - MAX{OSPC}/[(]? { pop_return MAXX; } - MEAN{OSPC}/[(]? { pop_return MEAN; } - MEDIAN{OSPC}/[(]? { pop_return MEDIAN; } - MIDRANGE{OSPC}/[(]? { pop_return MIDRANGE; } - MIN{OSPC}/[(]? { pop_return MINN; } - MOD{OSPC}/[(]? { pop_return MOD; } - MODULE-NAME{OSPC}/[(]? { pop_return MODULE_NAME; } - NATIONAL-OF{OSPC}/[(]? { pop_return NATIONAL_OF; } - NUMVAL{OSPC}/[(]? { pop_return NUMVAL; } - NUMVAL-C{OSPC}/[(]? { pop_return NUMVAL_C; } - NUMVAL-F{OSPC}/[(]? { pop_return NUMVAL_F; } - ORD{OSPC}/[(]? { pop_return ORD; } - ORD-MAX{OSPC}/[(]? { pop_return ORD_MAX; } - ORD-MIN{OSPC}/[(]? { pop_return ORD_MIN; } - PI{OSPC}/[(]? { pop_return PI; } - PRESENT-VALUE{OSPC}/[(]? { pop_return PRESENT_VALUE; } + ABS/{NONWORD} { pop_return ABS; } + ACOS/{NONWORD} { pop_return ACOS; } + ANNUITY/{NONWORD} { pop_return ANNUITY; } + ASIN/{NONWORD} { pop_return ASIN; } + ATAN/{NONWORD} { pop_return ATAN; } + BASECONVERT/{NONWORD} { pop_return BASECONVERT; } + BIT-OF/{NONWORD} { pop_return BIT_OF; } + BIT-TO-CHAR/{NONWORD} { pop_return BIT_TO_CHAR; } + BOOLEAN-OF-INTEGER/{NONWORD} { pop_return BOOLEAN_OF_INTEGER; } + BYTE-LENGTH/{NONWORD} { pop_return BYTE_LENGTH; } + CHAR-NATIONAL/{NONWORD} { pop_return CHAR_NATIONAL; } + CHAR/{NONWORD} { pop_return CHAR; } + COMBINED-DATETIME/{NONWORD} { pop_return COMBINED_DATETIME; } + CONCAT/{NONWORD} { pop_return CONCAT; } + CONTENT-LENGTH/{NONWORD} { pop_return NO_CONDITION; /* GNU only*/ } + CONTENT-OF/{NONWORD} { pop_return NO_CONDITION; /* GNU only*/ } + CONVERT/{NONWORD} { pop_return CONVERT; } + COS/{NONWORD} { pop_return COS; } + CURRENCY-SYBOL/{NONWORD} { pop_return NO_CONDITION; /* GNU only*/ } + CURRENT-DATE/{NONWORD} { pop_return CURRENT_DATE; } + DATE-OF-INTEGER/{NONWORD} { pop_return DATE_OF_INTEGER; } + DATE-TO-YYYYMMDD/{NONWORD} { pop_return DATE_TO_YYYYMMDD; } + DAY-OF-INTEGER/{NONWORD} { pop_return DAY_OF_INTEGER; } + DAY-TO-YYYYDDD/{NONWORD} { pop_return DAY_TO_YYYYDDD; } + DISPLAY-OF/{NONWORD} { pop_return DISPLAY_OF; } + E/{NONWORD} { pop_return E; } + + EXCEPTION-FILE-N/{NONWORD} { pop_return EXCEPTION_FILE_N; } + EXCEPTION-FILE/{NONWORD} { pop_return EXCEPTION_FILE; } + EXCEPTION-LOCATION-N/{NONWORD} { pop_return EXCEPTION_LOCATION_N; } + EXCEPTION-LOCATION/{NONWORD} { pop_return EXCEPTION_LOCATION; } + EXCEPTION-STATEMENT/{NONWORD} { pop_return EXCEPTION_STATEMENT; } + EXCEPTION-STATUS/{NONWORD} { pop_return EXCEPTION_STATUS; } + + EXP/{NONWORD} { pop_return EXP; } + EXP10/{NONWORD} { pop_return EXP10; } + FACTORIAL/{NONWORD} { pop_return FACTORIAL; } + FIND-STRING/{NONWORD} { pop_return FIND_STRING; } + + FORMATTED-CURRENT-DATE/{NONWORD} { BEGIN(datetime_fmt); + return FORMATTED_CURRENT_DATE; } + FORMATTED-DATE/{NONWORD} { BEGIN(datetime_fmt); return FORMATTED_DATE; } + FORMATTED-DATETIME/{NONWORD} { BEGIN(datetime_fmt); return FORMATTED_DATETIME; } + FORMATTED-TIME/{NONWORD} { BEGIN(datetime_fmt); return FORMATTED_TIME; } + FRACTION-PART/{NONWORD} { pop_return FRACTION_PART; } + + HEX-OF/{NONWORD} { pop_return HEX_OF; } + HEX-TO-CHAR/{NONWORD} { pop_return HEX_TO_CHAR; } + HIGHEST-ALGEBRAIC/{NONWORD} { pop_return HIGHEST_ALGEBRAIC; } + + INTEGER/{NONWORD} { pop_return INTEGER; } + INTEGER-OF-BOOLEAN/{NONWORD} { pop_return INTEGER_OF_BOOLEAN; } + INTEGER-OF-DATE/{NONWORD} { pop_return INTEGER_OF_DATE; } + INTEGER-OF-DAY/{NONWORD} { pop_return INTEGER_OF_DAY; } + INTEGER-OF-FORMATTED-DATE/{NONWORD} { BEGIN(datetime_fmt); + return INTEGER_OF_FORMATTED_DATE; } + INTEGER-PART/{NONWORD} { pop_return INTEGER_PART; } + LENGTH/{NONWORD} { pop_return LENGTH; } + LOCALE-COMPARE/{NONWORD} { pop_return LOCALE_COMPARE; } + LOCALE-DATE/{NONWORD} { pop_return LOCALE_DATE; } + LOCALE-TIME/{NONWORD} { pop_return LOCALE_TIME; } + LOCALE-TIME-FROM-SECONDS/{NONWORD} { pop_return LOCALE_TIME_FROM_SECONDS; } + LOG/{NONWORD} { pop_return LOG; } + LOG10/{NONWORD} { pop_return LOG10; } + LOWER-CASE/{NONWORD} { pop_return LOWER_CASE; } + LOWEST-ALGEBRAIC/{NONWORD} { pop_return LOWEST_ALGEBRAIC; } + MAX/{NONWORD} { pop_return MAXX; } + MEAN/{NONWORD} { pop_return MEAN; } + MEDIAN/{NONWORD} { pop_return MEDIAN; } + MIDRANGE/{NONWORD} { pop_return MIDRANGE; } + MIN/{NONWORD} { pop_return MINN; } + MOD/{NONWORD} { pop_return MOD; } + MODULE-NAME/{NONWORD} { pop_return MODULE_NAME; } + NATIONAL-OF/{NONWORD} { pop_return NATIONAL_OF; } + NUMVAL/{NONWORD} { pop_return NUMVAL; } + NUMVAL-C/{NONWORD} { pop_return NUMVAL_C; } + NUMVAL-F/{NONWORD} { pop_return NUMVAL_F; } + ORD/{NONWORD} { pop_return ORD; } + ORD-MAX/{NONWORD} { pop_return ORD_MAX; } + ORD-MIN/{NONWORD} { pop_return ORD_MIN; } + PI/{NONWORD} { pop_return PI; } + PRESENT-VALUE/{NONWORD} { pop_return PRESENT_VALUE; } RANDOM{OSPC}{PARENS} { pop_return RANDOM; } RANDOM{OSPC}[(] { pop_return RANDOM_SEED; } RANDOM { pop_return RANDOM; } - RANGE{OSPC}/[(]? { pop_return RANGE; } - REM{OSPC}/[(]? { pop_return REM; } - REVERSE{OSPC}/[(]? { pop_return REVERSE; } - SECONDS-FROM-FORMATTED-TIME{OSPC}/[(]? { BEGIN(datetime_fmt); + RANGE/{NONWORD} { pop_return RANGE; } + REM/{NONWORD} { pop_return REM; } + REVERSE/{NONWORD} { pop_return REVERSE; } + SECONDS-FROM-FORMATTED-TIME/{NONWORD} { BEGIN(datetime_fmt); return SECONDS_FROM_FORMATTED_TIME; } - SECONDS-PAST-MIDNIGHT{OSPC}/[(]? { pop_return SECONDS_PAST_MIDNIGHT; } - SIGN{OSPC}/[(]? { pop_return SIGN; } - SIN{OSPC}/[(]? { pop_return SIN; } - SMALLEST-ALGEBRAIC{OSPC}/[(]? { pop_return SMALLEST_ALGEBRAIC; } - SQRT{OSPC}/[(]? { pop_return SQRT; } - STANDARD-COMPARE{OSPC}/[(]? { pop_return STANDARD_COMPARE; } - STANDARD-DEVIATION{OSPC}/[(]? { pop_return STANDARD_DEVIATION; } - SUBSTITUTE{OSPC}/[(]? { pop_return SUBSTITUTE; } - SUM{OSPC}/[(]? { pop_return SUM; } - TAN{OSPC}/[(]? { pop_return TAN; } - TEST-DATE-YYYYMMDD{OSPC}/[(]? { pop_return TEST_DATE_YYYYMMDD; } - TEST-DAY-YYYYDDD{OSPC}/[(]? { pop_return TEST_DAY_YYYYDDD; } - TEST-FORMATTED-DATETIME{OSPC}/[(]? { BEGIN(datetime_fmt); return TEST_FORMATTED_DATETIME; } - TEST-NUMVAL{OSPC}/[(]? { pop_return TEST_NUMVAL; } - TEST-NUMVAL-C{OSPC}/[(]? { pop_return TEST_NUMVAL_C; } - TEST-NUMVAL-F{OSPC}/[(]? { pop_return TEST_NUMVAL_F; } - TRIM{OSPC}/[(]? { pop_return TRIM; } - ULENGTH{OSPC}/[(]? { pop_return ULENGTH; } - UPOS{OSPC}/[(]? { pop_return UPOS; } - UPPER-CASE{OSPC}/[(]? { pop_return UPPER_CASE; } - USUBSTR{OSPC}/[(]? { pop_return USUBSTR; } - USUPPLEMENTARY{OSPC}/[(]? { pop_return USUPPLEMENTARY; } - UUID4{OSPC}/[(]? { pop_return UUID4; } - UVALID{OSPC}/[(]? { pop_return UVALID; } - UWIDTH{OSPC}/[(]? { pop_return UWIDTH; } - VARIANCE{OSPC}/[(]? { pop_return VARIANCE; } - WHEN-COMPILED{OSPC}/[(]? { pop_return WHEN_COMPILED; } - YEAR-TO-YYYY{OSPC}/[(]? { pop_return YEAR_TO_YYYY; } + SECONDS-PAST-MIDNIGHT/{NONWORD} { pop_return SECONDS_PAST_MIDNIGHT; } + SIGN/{NONWORD} { pop_return SIGN; } + SIN/{NONWORD} { pop_return SIN; } + SMALLEST-ALGEBRAIC/{NONWORD} { pop_return SMALLEST_ALGEBRAIC; } + SQRT/{NONWORD} { pop_return SQRT; } + STANDARD-COMPARE/{NONWORD} { pop_return STANDARD_COMPARE; } + STANDARD-DEVIATION/{NONWORD} { pop_return STANDARD_DEVIATION; } + SUBSTITUTE/{NONWORD} { pop_return SUBSTITUTE; } + SUM/{NONWORD} { pop_return SUM; } + TAN/{NONWORD} { pop_return TAN; } + TEST-DATE-YYYYMMDD/{NONWORD} { pop_return TEST_DATE_YYYYMMDD; } + TEST-DAY-YYYYDDD/{NONWORD} { pop_return TEST_DAY_YYYYDDD; } + TEST-FORMATTED-DATETIME/{NONWORD} { BEGIN(datetime_fmt); return TEST_FORMATTED_DATETIME; } + TEST-NUMVAL/{NONWORD} { pop_return TEST_NUMVAL; } + TEST-NUMVAL-C/{NONWORD} { pop_return TEST_NUMVAL_C; } + TEST-NUMVAL-F/{NONWORD} { pop_return TEST_NUMVAL_F; } + TRIM/{NONWORD} { pop_return TRIM; } + ULENGTH/{NONWORD} { pop_return ULENGTH; } + UPOS/{NONWORD} { pop_return UPOS; } + UPPER-CASE/{NONWORD} { pop_return UPPER_CASE; } + USUBSTR/{NONWORD} { pop_return USUBSTR; } + USUPPLEMENTARY/{NONWORD} { pop_return USUPPLEMENTARY; } + UUID4/{NONWORD} { pop_return UUID4; } + UVALID/{NONWORD} { pop_return UVALID; } + UWIDTH/{NONWORD} { pop_return UWIDTH; } + VARIANCE/{NONWORD} { pop_return VARIANCE; } + WHEN-COMPILED/{NONWORD} { pop_return WHEN_COMPILED; } + YEAR-TO-YYYY/{NONWORD} { pop_return YEAR_TO_YYYY; } + + /* Matches above include NONWORD because the NAME tests below are otherwise longer, */ {NAME}{OSPC}/[(] { /* If /{OSPC}, "dangerous trailing context" "*/ auto name = null_trim(xstrdup(yytext)); @@ -2009,7 +2023,7 @@ BASIS { yy_push_state(basis); return BASIS; } } return token; } - [.][[:blank:].]+ { return '.'; } + [.]+[[:blank:].]+ { return '.'; } } <exception>{ @@ -2029,7 +2043,7 @@ BASIS { yy_push_state(basis); return BASIS; } return symbol_file(PROGRAM, yytext)? FILENAME : NAME; } [[:blank:]]+ - \r?\n { yy_pop_state(); } + {EOL} { yy_pop_state(); } } <raising>{ @@ -2050,49 +2064,62 @@ BASIS { yy_push_state(basis); return BASIS; } if( include_debug() ) myless(7); } } - ^[ ]*>>{OSPC}IF { yy_push_state(cdf_state); return CDF_IF; } - ^[ ]*>>{OSPC}ELSE { return CDF_ELSE; } - ^[ ]*>>{OSPC}END-IF { return CDF_END_IF; } + ^[ ]*>>{OBLANK}IF { yy_push_state(cdf_state); return CDF_IF; } + ^[ ]*>>{OBLANK}ELSE { return CDF_ELSE; } + ^[ ]*>>{OBLANK}END-IF { return CDF_END_IF; } - ^[ ]*[$]{OSPC}IF { if( ! dialect_mf() ) { + ^[ ]*[$]{OBLANK}IF { if( ! dialect_mf() ) { dialect_error(yylloc, yytext, "mf"); } yy_push_state(cdf_state); return CDF_IF; } - ^[ ]*[$]{OSPC}ELSE { if( ! dialect_mf() ) { + ^[ ]*[$]{OBLANK}ELSE { if( ! dialect_mf() ) { dialect_error(yylloc, yytext, "mf"); } return CDF_ELSE; } - ^[ ]*[$]{OSPC}END { if( ! dialect_mf() ) { + ^[ ]*[$]{OBLANK}END { if( ! dialect_mf() ) { dialect_error(yylloc, yytext, "mf"); } return CDF_END_IF; } - ^[ ]*[$]{OSPC}SET({SPC}CONSTANT)? { + ^[ ]*[$]{OBLANK}SET({SPC}CONSTANT)? { if( ! dialect_mf() ) dialect_error(yylloc, yytext, "mf"); yy_push_state(cdf_state); return CDF_DEFINE; } - ^[ ]*>>{OSPC}EVALUATE { return CDF_EVALUATE; } - ^[ ]*>>{OSPC}WHEN { return CDF_WHEN; } - ^[ ]*>>{OSPC}END-EVALUATE { return CDF_END_EVALUATE; } + ^[ ]*>>{OBLANK}EVALUATE { return CDF_EVALUATE; } + ^[ ]*>>{OBLANK}WHEN { return CDF_WHEN; } + ^[ ]*>>{OBLANK}END-EVALUATE { return CDF_END_EVALUATE; } - ^[ ]*>>{OSPC}CALL-CONVENTION{SPC}C { return CALL_VERBATIM; } - ^[ ]*>>{OSPC}CALL-CONVENTION{SPC}COBOL { return CALL_COBOL; } - ^[ ]*>>{OSPC}CALL-CONVENTION{SPC}VERBATIM { return CALL_VERBATIM; } + ^[ ]*>>{OBLANK}CALL-CONVENTION{BLANK}C { return CALL_VERBATIM; } + ^[ ]*>>{OBLANK}CALL-CONVENTION{BLANK}COBOL { return CALL_COBOL; } + ^[ ]*>>{OBLANK}CALL-CONVENTION{BLANK}VERBATIM { return CALL_VERBATIM; } - ^[ ]*>>{OSPC}DEFINE { yy_push_state(cdf_state); return CDF_DEFINE; } - ^[ ]*>>{OSPC}DISPLAY { return CDF_DISPLAY; } - ^[ ]*>>{OSPC}TURN { yy_push_state(exception); return TURN; } - ^[ ]*>>{OSPC}COBOL-WORDS { yy_push_state(cobol_words); return COBOL_WORDS; } + ^[ ]*>>{OBLANK}DEFINE { yy_push_state(cdf_state); return CDF_DEFINE; } + ^[ ]*>>{OBLANK}DISPLAY { return CDF_DISPLAY; } + ^[ ]*>>{OBLANK}TURN { yy_push_state(exception); return TURN; } + ^[ ]*>>{OBLANK}COBOL-WORDS { yy_push_state(cobol_words); return COBOL_WORDS; } - ^[ ]*>>{OSPC}{NAME} { + ^[ ]*>>{OBLANK}SOURCE{BLANK}FORMAT { return SOURCE_FORMAT; } + + ^[ ]*>>{OBLANK}PUSH { return CDF_PUSH; } + ^[ ]*>>{OBLANK}POP { return CDF_POP; } + + ^[ ]*>>{OBLANK}{NAME} { error_msg(yylloc, "unknown CDF token: %s", yytext); } + OTHER { return OTHER; } OVERRIDE { return OVERRIDE; } PARAMETER { return PARAMETER_kw; } THRU { return THRU; } TRUE { return TRUE_kw; } + + ALL { return ALL; } + CALL-CONVENTION { return CALL_CONVENTION; } + COBOL-WORDS { return COBOL_WORDS; } + DEFINE { return CDF_DEFINE; } + SOURCE{BLANK}FORMAT { return SOURCE_FORMAT; } + } <cobol_words>{ @@ -2107,39 +2134,45 @@ BASIS { yy_push_state(basis); return BASIS; } } <*>{ - {PUSH_FILE} { - yy_set_bol(true); - auto top_file = cobol_lineno_save(); - if( top_file ) { - if( yy_flex_debug ) dbgmsg(" saving line %4d of %s", - yylineno, top_file); - } - // "\f#file push <name>": name starts at offset 13. - char *filename = xstrdup(yytext); - filename[yyleng - 1] = '\0'; // kill the trailing formfeed - filename += 12; - if( yytext[0] != '\f' ) { - dbgmsg("logic warning: filename was adjusted to %s", --filename); + {PUSH_FILE} { + yy_set_bol(true); + auto top_file = cobol_lineno(yylineno); + if( top_file ) { + if( yy_flex_debug ) dbgmsg(" saving line %4d of %s", + yylineno, top_file); + } + // "\f#file push <name>": name starts at offset 13. + char *filename = xstrdup(yytext); + filename[yyleng - 1] = '\0'; // kill the trailing formfeed + filename += 12; + if( yytext[0] != '\f' ) { + dbgmsg("logic warning: filename was adjusted to %s", + --filename); + } + input_file_status.enter(filename); + yylineno = 1; + reset_location(); + } + + {POP_FILE} { + yy_set_bol(true); + input_file_status.leave(); + yylineno = cobol_lineno(); } - input_file_status.enter(filename); - } - - {POP_FILE}{OSPC} { - yy_set_bol(true); - input_file_status.leave(); - } - {LINE_DIRECTIVE} { cobol_fileline_set(yytext); } + {LINE_DIRECTIVE} { + yylineno = cobol_fileline_set(yytext); + reset_location(); + } } <*>OR { return OR; } <*>AND { return AND; } -<*>{DOTSEP}[[:blank:].]+$ { return '.'; } -<*>[*/+-]{SPC}[+] { return *yytext; } +<*>{DOTSEP} { return '.'; } <*>[().=*/+&-] { return *yytext; } <*>[[:blank:]]+ -<*>\r?\n +<*>{EOL} <*>{ {COMMA} @@ -2150,48 +2183,48 @@ BASIS { yy_push_state(basis); return BASIS; } <*>{ ACCEPT { return ACCEPT; } ACCESS { return ACCESS; } - ADD { return ADD; } + ADD { return ADD; } ADDRESS { return ADDRESS; } ADVANCING { return ADVANCING; } - AFTER { return AFTER; } - ALL { return ALL; } + AFTER { return AFTER; } + ALL { return ALL; } ALLOCATE { return ALLOCATE; } ALPHABET { return ALPHABET; } ALPHABETIC { return ALPHABETIC; } ALPHABETIC-LOWER { return ALPHABETIC_LOWER; } ALPHABETIC-UPPER { return ALPHABETIC_UPPER; } - ALPHANUMERIC { return ALPHANUMERIC; } + ALPHANUMERIC { return ALPHANUMERIC; } ALPHANUMERIC-EDITED { return ALPHANUMERIC_EDITED; } - ALSO { return ALSO; } + ALSO { return ALSO; } ALTERNATE { return ALTERNATE; } - AND { return AND; } - ANY { return ANY; } + AND { return AND; } + ANY { return ANY; } ANYCASE { return ANYCASE; } - ARE { return ARE; } - AREA { return AREA; } - AREAS { return AREAS; } - AS { return AS; } + ARE { return ARE; } + AREA { return AREA; } + AREAS { return AREAS; } + AS { return AS; } ASCENDING { return ASCENDING; } - ASSIGN { return ASSIGN; } - AT { return AT; } - BASED { return BASED; } + ASSIGN { return ASSIGN; } + AT { return AT; } + BASED { return BASED; } BEFORE { return BEFORE; } BINARY { return BINARY; } - BIT { return BIT; } - BLANK { return BLANK; } - BLOCK { return BLOCK_kw; } + BIT { return BIT; } + BLANK { return BLANK; } + BLOCK { return BLOCK_kw; } BOTTOM { return BOTTOM; } - BY { return BY; } - CALL { return CALL; } + BY { return BY; } + CALL { return CALL; } CANCEL { return CANCEL; } - CF { return CF; } - CH { return CH; } + CF { return CF; } + CH { return CH; } CHARACTER { return CHARACTER; } CHARACTERS { return CHARACTERS; } - CLASS { return CLASS; } - CLOSE { return CLOSE; } - CODE { return CODE; } - COMMA { return COMMA; } + CLASS { return CLASS; } + CLOSE { return CLOSE; } + CODE { return CODE; } + COMMA { return COMMA; } COMMIT { return COMMIT; } COMMON { return COMMON; } CONDITION { return CONDITION; } @@ -2202,14 +2235,14 @@ BASIS { yy_push_state(basis); return BASIS; } CONTROL { return CONTROL; } CONTROLS { return CONTROLS; } CONVERTING { return CONVERTING; } - COPY { return COPY; } - COUNT { return COUNT; } + COPY { return COPY; } + COUNT { return COUNT; } CURRENCY { return CURRENCY; } - DATA { return DATA; } - DATE { return DATE; } - DAY { return DAY; } + DATA { return DATA; } + DATE { return DATE; } + DAY { return DAY; } DAY-OF-WEEK { return DAY_OF_WEEK; } - DE { return DE; } + DE { return DE; } DECIMAL-POINT { return DECIMAL_POINT; } DECLARATIVES { return DECLARATIVES; } DEFAULT { return DEFAULT; } @@ -2221,12 +2254,12 @@ BASIS { yy_push_state(basis); return BASIS; } DETAIL { return DETAIL; } DISPLAY { return DISPLAY; } DIVIDE { return DIVIDE; } - DOWN { return DOWN; } + DOWN { return DOWN; } DUPLICATES { return DUPLICATES; } DYNAMIC { return DYNAMIC; } - EC { return EC; } - ELSE { return ELSE; } - END { return END; } + EC { return EC; } + ELSE { return ELSE; } + END { return END; } END-ACCEPT { return END_ACCEPT; } END-ADD { return END_ADD; } END-CALL { return END_CALL; } @@ -2244,117 +2277,116 @@ BASIS { yy_push_state(basis); return BASIS; } END-SUBTRACT { return END_SUBTRACT; } END-WRITE { return END_WRITE; } ENVIRONMENT { return ENVIRONMENT; } - EQUAL { return EQUAL; } - ERROR { return ERROR; } + EQUAL { return EQUAL; } + ERROR { return ERROR; } EVALUATE { return EVALUATE; } EXCEPTION { return EXCEPTION; } - EXIT { return EXIT; } + EXIT { return EXIT; } EXTEND { return EXTEND; } EXTERNAL { return EXTERNAL; } - FD { return FD; } - FINAL { return FINAL; } + FD { return FD; } + FINAL { return FINAL; } FINALLY { return FINALLY; } - FIRST { return FIRST; } + FIRST { return FIRST; } FOOTING { return FOOTING; } - FOR { return FOR; } - FREE { return FREE; } - FROM { return FROM; } + FOR { return FOR; } + FREE { return FREE; } + FROM { return FROM; } FUNCTION { return FUNCTION; } GENERATE { return GENERATE; } GIVING { return GIVING; } GLOBAL { return GLOBAL; } - GO { return GO; } + GO { return GO; } GOBACK { return GOBACK; } - GROUP { return GROUP; } + GROUP { return GROUP; } HEADING { return HEADING; } - IDENTIFICATION { return IDENTIFICATION_DIV; } - IF { return IF; } - IN { return IN; } - INDEX { return INDEX; } + IF { return IF; } + IN { return IN; } + INDEX { return INDEX; } INDEXED { return INDEXED; } INDICATE { return INDICATE; } INITIAL { return INITIAL; } INITIALIZE { return INITIALIZE; } INITIATE { return INITIATE; } - INPUT { return INPUT; } + INPUT { return INPUT; } INSPECT { return INSPECT; } INTERFACE { return INTERFACE; } - INTO { return INTO; } + INTO { return INTO; } INVOKE { return INVOKE; } - IS { return IS; } - KEY { return KEY; } - LAST { return LAST; } + IS { return IS; } + KEY { return KEY; } + LAST { return LAST; } LEADING { return LEADING; } - LEFT { return LEFT; } + LEFT { return LEFT; } LENGTH { return LENGTH; } - LIMIT { return LIMIT; } + LIMIT { return LIMIT; } LIMITS { return LIMITS; } LINAGE { return LINAGE; } - LINE { return LINE; } + LINE { return LINE; } LINE-COUNTER { return LINE_COUNTER; } - LINES { return LINES; } + LINES { return LINES; } LINKAGE { return LINKAGE; } LOCAL-STORAGE { return LOCAL_STORAGE; } LOCALE { return LOCALE; } LOCATION { return LOCATION; } - LOCK { return LOCK; } - MERGE { return MERGE; } - MODE { return MODE; } - MOVE { return MOVE; } + LOCK { return LOCK; } + MERGE { return MERGE; } + MODE { return MODE; } + MOVE { return MOVE; } MULTIPLY { return MULTIPLY; } NATIONAL { return NATIONAL; } NATIONAL-EDITED { return NATIONAL_EDITED; } NATIVE { return NATIVE; } NEGATIVE { return NEGATIVE; } NESTED { return NESTED; } - NEXT { return NEXT; } - NO { return NO; } - NOT { return NOT; } + NEXT { return NEXT; } + NO { return NO; } + NOT { return NOT; } NUMBER { return NUMBER; } NUMERIC { return NUMERIC; } NUMERIC-EDITED { return NUMERIC_EDITED; } OCCURS { return OCCURS; } - OF { return OF; } - OFF { return OFF; } + OF { return OF; } + OFF { return OFF; } OMITTED { return OMITTED; } - ON { return ON; } - OPEN { return OPEN; } + ON { return ON; } + OPEN { return OPEN; } OPTIONAL { return OPTIONAL; } OPTIONS { return OPTIONS; } - OR { return OR; } - ORDER { return ORDER; } - ORGANIZATION { return ORGANIZATION; } - OTHER { return OTHER; } + OR { return OR; } + ORDER { return ORDER; } + ORGANI[SZ]ATION { return ORGANIZATION; } + OTHER { return OTHER; } OUTPUT { return OUTPUT; } OVERFLOW { return OVERFLOW_kw; } OVERRIDE { return OVERRIDE; } PACKED-DECIMAL { return PACKED_DECIMAL; } - PAGE { return PAGE; } + PAGE { return PAGE; } PAGE-COUNTER { return PAGE_COUNTER; } PERFORM { return PERFORM; } - PF { return PF; } - PH { return PH; } - PIC { return PIC; } + PF { return PF; } + PH { return PH; } + PIC { return PIC; } PICTURE { return PICTURE; } - PLUS { return PLUS; } + PLUS { return PLUS; } POINTER { return POINTER; } POSITIVE { return POSITIVE; } PROCEDURE { return PROCEDURE; } - PROGRAM { return PROGRAM; } + PROGRAM { return PROGRAM_kw; } PROGRAM-ID { return PROGRAM_ID; } PROPERTY { return PROPERTY; } PROTOTYPE { return PROTOTYPE; } QUOTES { return QUOTES; } - RAISE { return RAISE; } + RAISE { return RAISE; } RAISING { return RAISING; } RANDOM { return RANDOM; } - RD { return RD; } - READ { return READ; } + RD { return RD; } + READ { return READ; } RECORD { return RECORD; } RECORDS { return RECORDS; } REDEFINES { return REDEFINES; } - REEL { return REEL; } + REEL { return REEL; } REFERENCE { return REFERENCE; } RELATIVE { return RELATIVE; } RELEASE { return RELEASE; } @@ -2368,77 +2400,77 @@ BASIS { yy_push_state(basis); return BASIS; } REPORTS { return REPORTS; } REPOSITORY { return REPOSITORY; } RESERVE { return RESERVE; } - RESET { return RESET; } + RESET { return RESET; } RESUME { return RESUME; } RETURN { return RETURN; } RETURNING { return RETURNING; } REWIND { return REWIND; } REWRITE { return REWRITE; } - RF { return RF; } - RH { return RH; } - RIGHT { return RIGHT; } + RF { return RF; } + RH { return RH; } + RIGHT { return RIGHT; } ROUNDED { return ROUNDED; } - RUN { return RUN; } - SAME { return SAME; } + RUN { return RUN; } + SAME { return SAME; } SCREEN { return SCREEN; } - SD { return SD; } + SD { return SD; } SEARCH { return SEARCH; } - SECTION { return SECTION; } + SECTION { yylval.string = NULL; return SECTION; } SELECT { return SELECT; } SENTENCE { return SENTENCE; } SEPARATE { return SEPARATE; } SEQUENCE { return SEQUENCE; } SEQUENTIAL { return SEQUENTIAL; } - SET { return SET; } + SET { return SET; } SHARING { return SHARING; } - SIGN { return SIGN; } - SIZE { return SIZE; } - SORT { return SORT; } + SIGN { return SIGN; } + SIZE { return SIZE; } + SORT { return SORT; } SORT-MERGE { return SORT_MERGE; } SOURCE { return SOURCE; } - SPACE { return SPACE; } + SPACE { return SPACE; } SPACES { return SPACES; } SPECIAL-NAMES { return SPECIAL_NAMES; } STANDARD { return STANDARD; } STANDARD-1 { return STANDARD_1; } - START { return START; } + START { return START; } STATUS { return STATUS; } - STOP { return STOP; } + STOP { return STOP; } SUBTRACT { return SUBTRACT; } - SUM { return SUM; } + SUM { return SUM; } SUPPRESS { return SUPPRESS; } SYMBOLIC { return SYMBOLIC; } TALLYING { return TALLYING; } TERMINATE { return TERMINATE; } - TEST { return TEST; } - THAN { return THAN; } - THEN { return THEN; } - THRU { return THRU; } - TIME { return TIME; } - TIMES { return TIMES; } - TO { return TO; } - TOP { return TOP; } + TEST { return TEST; } + THAN { return THAN; } + THEN { return THEN; } + THRU { return THRU; } + TIME { return TIME; } + TIMES { return TIMES; } + TO { return TO; } + TOP { return TOP; } TRAILING { return TRAILING; } - TYPE { return TYPE; } + TYPE { return TYPE; } TYPEDEF { return TYPEDEF; } - UNIT { return UNIT; } - UNTIL { return UNTIL; } - UP { return UP; } - UPON { return UPON; } - USAGE { return USAGE; } - USE { return USE; } - USING { return USING; } - VALUE { return VALUE; } + UNIT { return UNIT; } + UNTIL { return UNTIL; } + UP { return UP; } + UPON { return UPON; } + USAGE { return USAGE; } + USE { return USE; } + USING { return USING; } + VALUE { return VALUE; } VARYING { return VARYING; } - WHEN { return WHEN; } - WITH { return WITH; } + WHEN { return WHEN; } + WITH { return WITH; } WORKING-STORAGE { return WORKING_STORAGE; } - WRITE { return WRITE; } + WRITE { return WRITE; } ZERO | ZEROES | - ZEROS { return ZERO; } + ZEROS { return ZERO; } } <*>{ @@ -2475,29 +2507,13 @@ BASIS { yy_push_state(basis); return BASIS; } return NO_CONDITION; } -<<EOF>> { - - if( YY_START == quoted1 || YY_START == quoted2 ) { - error_msg(yylloc, "syntax error: unterminated string '%s'", +<quoted1,quoted2>{ + <<EOF>> { + error_msg(yylloc, "syntax error: unterminated string %<%s%>", tmpstring); return NO_CONDITION; - cbl_internal_error(""); - } - yypop_buffer_state(); - - if ( !YY_CURRENT_BUFFER ) { - return 0; - } - - if( ! wait_for_the_child() ) { - yyterminate(); - } - cobol_filename_restore(); - parser_leave_file(); - - if( yydebug ) yywarn("resume parsing '%s'", cobol_filename()); - yy_set_bol(true); - } + } +} %% diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h index d2faf5a6d92e..19ceb2b4a08b 100644 --- a/gcc/cobol/scan_ante.h +++ b/gcc/cobol/scan_ante.h @@ -149,7 +149,7 @@ numstr_of( const char string[], radix_t radix = decimal_e ) { } auto nx = std::count_if(input, p, fisdigit); if( 36 < nx ) { - error_msg(yylloc, "significand of %s has more than 36 digits (%zu)", input, nx); + error_msg(yylloc, "significand of %s has more than 36 digits (%ld)", input, (long)nx); return NO_CONDITION; } @@ -159,11 +159,11 @@ numstr_of( const char string[], radix_t radix = decimal_e ) { // exponent is implementor-defined." (We allow 9999.) nx = std::count_if(p, eoinput, fisdigit); if( 4 < nx ) { - error_msg(yylloc, "exponent %s more than 4 digits", ++p); + error_msg(yylloc, "exponent %qs more than 4 digits", ++p); return NO_CONDITION; } if( eoinput != std::find(p, eoinput, symbol_decimal_point()) ) { - error_msg(yylloc, "exponent includes decimal point", ++p); + error_msg(yylloc, "exponent %qs includes decimal point", ++p); return NO_CONDITION; } @@ -187,7 +187,7 @@ numstr_of( const char string[], radix_t radix = decimal_e ) { } } if( 1 < std::count(input, eoinput, symbol_decimal_point()) ) { - error_msg(yylloc, "invalid numeric literal", ++p); + error_msg(yylloc, "invalid numeric literal %qs", ++p); return NO_CONDITION; } @@ -214,7 +214,11 @@ struct cdf_status_t { const char *filename; int token; bool parsing; - cdf_status_t( int token = 0, bool parsing = true ) + cdf_status_t() + : lineno(yylineno), filename(cobol_filename()) + , token(0), parsing(true) + {} + cdf_status_t( int token, bool parsing ) : lineno(yylineno), filename(cobol_filename()) , token(token), parsing(parsing) {} @@ -291,7 +295,7 @@ static class parsing_status_t : public std::stack<cdf_status_t> { void splat() const { int i=0; for( const auto& status : c ) { - yywarn( "%4d\t%s", ++i, status.str() ); + yywarn( "%d %s", ++i, status.str() ); } } } parsing; @@ -301,7 +305,7 @@ void field_done() { orig_picture[0] = '\0'; parsing.need_level(true); } static int scanner_token() { if( parsing.empty() ) { - error_msg(yylloc, ">>ELSE or >>END-IF without >>IF"); + error_msg(yylloc, "%<>>ELSE%> or %<>>END-IF%> without %<>>IF%>"); return NO_CONDITION; } return parsing.top().token; @@ -313,31 +317,32 @@ bool scanner_normal() { return parsing.normal(); } void scanner_parsing( int token, bool tf ) { parsing.push( cdf_status_t(token, tf) ); if( yydebug ) { - yywarn("%10s: parsing now %5s, depth %zu", + yywarn("%s: parsing now %s, depth %zu", keyword_str(token), boolalpha(parsing.on()), parsing.size()); parsing.splat(); } } void scanner_parsing_toggle() { if( parsing.empty() ) { - error_msg(yylloc, ">>ELSE without >>IF"); + error_msg(yylloc, "%<>>ELSE%> without %<>>IF%>"); return; } parsing.top().toggle(); if( yydebug ) { - yywarn("%10s: parsing now %5s", + yywarn("%s: parsing now %s", keyword_str(CDF_ELSE), boolalpha(parsing.on())); } } void scanner_parsing_pop() { if( parsing.empty() ) { - error_msg(yylloc, ">>END-IF without >>IF"); + error_msg(yylloc, "%<>>END-IF%> without %<>>IF%>"); return; } parsing.pop(); if( yydebug ) { - yywarn("%10s: parsing now %5s, depth %zu", - keyword_str(CDF_END_IF), boolalpha(parsing.on()), parsing.size()); + yywarn("%s: parsing now %s, depth %zu", + keyword_str(CDF_END_IF), boolalpha(parsing.on()), + parsing.size()); parsing.splat(); } } @@ -351,6 +356,10 @@ static void level_found() { if( scanner_normal() ) parsing.need_level(false); } +/* + * Trim the scanned location by the amount about to re-scanned. + * Must be a macro because it expands yyless. + */ #define myless(N) \ do { \ auto n(N); \ @@ -368,11 +377,12 @@ class enter_leave_t { public: enter_leave_t() : entering(NULL), leaving(NULL), filename(NULL) {} enter_leave_t( parser_enter_file_f *entering, const char *filename ) - : entering(entering), leaving(NULL), filename(filename) {} - enter_leave_t(parser_leave_file_f *leaving) + : entering(entering), leaving(NULL), filename(filename) + {} + explicit enter_leave_t(parser_leave_file_f *leaving) : entering(NULL), leaving(leaving), filename(NULL) {} - void notify( unsigned int newlines = 0 ) { + void notify() { if( entering ) { cobol_filename(filename, 0); if( yy_flex_debug ) dbgmsg("starting line %4d of %s", @@ -381,10 +391,9 @@ class enter_leave_t { gcc_assert(leaving == NULL); } if( leaving ) { - auto name = cobol_filename_restore(); - yylineno += newlines; + cobol_filename_restore(); if( yy_flex_debug ) dbgmsg("resuming line %4d of %s", - yylineno, name? name : "<none>"); + yylineno, cobol_filename()); leaving(); gcc_assert(entering == NULL); } @@ -393,22 +402,17 @@ class enter_leave_t { static class input_file_status_t { std::queue <enter_leave_t> inputs; - unsigned int trailing_newlines = 0; public: void enter(const char *filename) { inputs.push( enter_leave_t(parser_enter_file, filename) ); } void leave() { - // Add the number of newlines following the POP to yylineno when it's restored. - trailing_newlines = std::count(yytext, yytext + yyleng, '\n'); - if( trailing_newlines && yy_flex_debug ) - dbgmsg("adding %u lines after POP", trailing_newlines); - inputs.push( parser_leave_file ); + inputs.push( enter_leave_t(parser_leave_file) ); } void notify() { while( ! inputs.empty() ) { auto enter_leave = inputs.front(); - enter_leave.notify(trailing_newlines); + enter_leave.notify(); inputs.pop(); } } @@ -416,26 +420,60 @@ static class input_file_status_t { void input_file_status_notify() { input_file_status.notify(); } -void cdf_location_set(YYLTYPE loc); +/* + * parse.y and cdf.y each define a 4-integer struct to hold a token's location. + * parse.y uses YYLTYPE yylloc; + * cdf.y uses YDFLLTYPE ydflloc; + * + * The structs have identical definitions with different types and of course + * names. We define "conversion" between them for convenience. + * + * Each parser expects its location value to be updated whenever it calls + * yylex(). Therefore, here in the lexer we set both locations as each token + * is scanned, so that both parsers see the same location. + */ +static YDFLTYPE +ydfltype_of( const YYLTYPE& loc ) { + YDFLTYPE output { + loc.first_line, loc.first_column, + loc.last_line, loc.last_column }; + return output; +} +/* + * After the input filename and yylineno are set, update the location of the + * scanned token. + */ static void -update_location() { +update_location( const YYLTYPE *ploc = nullptr ) { YYLTYPE loc = { yylloc.last_line, yylloc.last_column, yylineno, yylloc.last_column + yyleng }; + if( ploc ) loc = *ploc; - auto nline = std::count(yytext, yytext + yyleng, '\n'); - if( nline ) { - char *p = static_cast<char*>(memrchr(yytext, '\n', yyleng)); + const char *p = static_cast<char*>(memrchr(yytext, '\n', yyleng)); + if( p ) { loc.last_column = (yytext + yyleng) - p; } yylloc = loc; - cdf_location_set(loc); - location_dump(__func__, __LINE__, "yylloc", yylloc); + ydflloc = ydfltype_of(yylloc); + + dbgmsg(" SC: %s location (%d,%d) to (%d,%d)", + start_condition_is(), + yylloc.first_line, yylloc.first_column, + yylloc.last_line, yylloc.last_column); } +static void +reset_location() { + static const YYLTYPE loc { yylineno, 1, yylineno, 1 }; + update_location(&loc); +} + +#define YY_USER_ACTION update_location(); + static void trim_location( int nkeep) { gcc_assert( 0 <= nkeep && nkeep <= yyleng ); @@ -452,7 +490,8 @@ trim_location( int nkeep) { (fmt_size_t)nline, (fmt_size_t)rescan.size()); if( nline ) { gcc_assert( yylloc.first_line + nline <= yylloc.last_line ); - yylloc.last_line =- int(nline); + yylloc.last_line -= int(nline); + gcc_assert( yylloc.first_line <= yylloc.last_line ); char *p = static_cast<char*>(memrchr(rescan.p, '\n', rescan.size())); yylloc.last_column = rescan.pend - ++p; return; @@ -480,7 +519,8 @@ update_location_col( const char str[], int correction = 0) { #define YY_USER_INIT do { \ static YYLTYPE ones = {1,1, 1,1}; \ - yylloc = ones; \ + yylloc = ones; \ + ydflloc = ydfltype_of(yylloc); \ } while(0) /* @@ -489,15 +529,11 @@ update_location_col( const char str[], int correction = 0) { * updates neither yylval nor yylloc. That job is left to the actions. * * The parser relies on yylex to set yylval and yylloc each time it is - * called. It apparently maintains a separate copy for each term, and uses + * called. It maintains a separate copy for each term, and uses * YYLLOC_DEFAULT() to update the location of nonterminals. */ #define YY_DECL int lexer(void) -#define YY_USER_ACTION \ - update_location(); \ - if( yy_flex_debug ) dbgmsg("SC: %s", start_condition_is() ); - # define YY_INPUT(buf, result, max_size) \ { \ if( 0 == (result = lexer_input(buf, max_size, yyin)) ) \ @@ -577,7 +613,8 @@ binary_integer_usage( const char name[]) { std::transform(name, name + strlen(name), uname, ftoupper); dbgmsg("%s:%d: checking %s in %zu keyword_aliases", - __func__, __LINE__, uname, keyword_aliases.size() ); + __func__, __LINE__, uname, + keyword_aliases.size() ); std::string key = uname; auto alias = keyword_aliases.find(key); @@ -594,6 +631,16 @@ binary_integer_usage( const char name[]) { return p->second.token; } +static void +verify_ws( const YYLTYPE& loc, const char input[], char ch ) { + if( ! fisspace(ch) ) { + if( ! (dialect_mf() || dialect_gnu()) ) { + dialect_error(loc, "separator space required in %qs", input); + } + } +} +#define verify_ws(C) verify_ws(yylloc, yytext, C) + int binary_integer_usage_of( const char name[] ) { cbl_name_t uname = {}; @@ -647,6 +694,387 @@ picset( int token ) { return token; } +/** +## Script and data to produce picture_t::followers. +## Based on ISO Table 10. +#! /usr/bin/awk -f + +BEGIN { + str = "B0/ , . + +- +- CR/DB cs cs Z* Z* + + cs cs 9 AX S V P P 1 N E" + split(str, cols) +} + +$1 ~ /CR|DB|cs/ { next } + +0 && !nlines++ { + for( i=0; i < length(cols); i++ ) { + print i, cols[i], "'" $i "'" + } +} + +$field == "x" { + if( ! nout++ ) { + printf "%2d: %5s: \"", field, cols[field - 1] + } + + gsub(/^ +| +$/, "", $1) + printf "%s", $1 +} + +END { + if( ! nout++ ) { + printf "%2d: %5s: \"", field, cols[field - 1] + } + print "\"" +} + +B x x x - x - - x - x x x x x x x x - x - x - x +0 x x x - x - - x - x x x x x x x x - x - x - x +/ x x x - x - - x - x x x x x x x x - x - x - x +, x x x - x - - x - x x x x x x x - - x - x +. x x - - x - - x - x - x - x - x ++ - - - - - - - - - - - - - - - - - - - - - - - x ++ +– ++ x x x - - - - x x x x - - x x x - - x x x +CR x x x - - - - x x x x - - x x x - - x x x +DB x x x - - - - x x x x - - x x x - - x x x +cs - - - - x +cs x x x - x - - - - x x - - - - x - - x x x + +Z x x - - x - - x - x +* x x - - x - - x - x +Z x x x - x - - x - x x - - - - - - - x - x +* x x x - x - - x - x x - - - - - - - x - x ++ x x - - - - - x - - - x +– x x - - - - - x - - - x ++ x x x - - - - x - - - x x - - - - - x +– x x x - - - - x - - - x x - - - - - x +cs x x - - x - - - - - - - - x +cs x x x - x - - - - - - - - x x - - - x + +9 x x x x x - - x - x - x - x - x x x x - x - - x +A x - - - - - - - - - - - - - - x x +X x - - - - - - - - - - - - - - x x +S +V x x - - x - - x - x - x - x - x - x - x +P x x - - x - - x - x - x - x - x - x - x +P - - - - x - - x - - - - - - - - - x x - x +1 - - - - - - - - - - - - - - - - - - - - - x +N x - - - - - - - - - - - - - - - - - - - - - x +E x x x - x - - - - - - - - - - x +**/ + +class picture_t { + static const char dot = '.', comma = ','; + + typedef std::vector<std::string> followings_t; + static const std::map <char, followings_t> followers; + + const char * const begin; + const char *p, *pend; + size_t pos; + struct exclusions_t { // Nonzero if set, > 1 is false. + // crdb means CR/DB or +/-. + // pluses means 2 or more consecutive '+'. + // minuses means 2 or more consecutive '-'. + // "21) The symbol 'Z' and the symbol '*' are mutually exclusive " + // stars means '*' or Z. + unsigned short int crdb, currency, dot, pluses, minuses, stars, zzz; + exclusions_t() + : crdb(0), currency(0), dot(0), pluses(0), minuses(0), stars(0) + {} + } exclusions; + YYLTYPE loc; + + bool is_crdb() const { // input must be uppercase for CR/DB + if( p[0] == 'C' || p[0] == 'D' ) { + char input[3] = { p[0], p[1] }; + return ( 0 == strcmp(input, "CR") || 0 == strcmp(input, "DB") ); + } + return false; + } + + const char * match_paren( const char *paren ) const { + gcc_assert(paren[0] == '('); // start with opening paren + paren = std::find_if( paren, pend, + []( char ch ) { + return ch == '(' || ch == ')'; + } ); + if( *paren == '(' ) return nullptr; // no nesting + if( paren == pend ) return nullptr; + return ++paren; + } + + const char * next_not( char ch ) const { + return std::find_if( p, pend, + [ch = TOUPPER(ch)]( char next ) { + return ch != next; + } ); + } + + const char * valid_next( const char *p, const std::string& valid ) const { + if( p == pend || p + 1 == pend ) return pend; + if( p[1] == '(' ) { + return match_paren(++p); + } + auto pv = std::find(valid.begin(), valid.end(), TOUPPER(p[1])); + return pv != valid.end()? ++p : nullptr; + } + const char * valid_next( const char *p, + bool first = true, char ch = '\0' ) const { + if( p == pend || p + 1 == pend ) return pend; + if( p[0] == '(' ) { + if( (p = match_paren(p)) == nullptr ) return nullptr; + } + if( p[0] == '(' ) return nullptr; // consecutive parentheses + + int index = first? 0 : 1; + if( !ch ) ch = *p; // use current character unless overridden + auto valid = followers.find(TOUPPER(ch)); + if( valid == followers.end() ) { + YYLTYPE loc(yylloc); + loc.first_column += int(p - begin); + error_msg( loc, "PICTURE: strange character %qc, giving up", ch ); + return nullptr; + } + return valid_next(p, valid->second[index]); + } + + const char * start() { // start modifies exclusions, but not p + auto pnext = p; + + switch(TOUPPER(p[0])) { + case comma: case dot: + // use decimal_is_comma() + // 4: .: "B0/,+Z*+-9E" + exclusions.dot++; + pnext = valid_next(p, "B0/,+Z*+-9E"); + break; + case '+': case '-': + // 6: +-: "B0/,.Z*Z*9VPPE" + exclusions.crdb++; + pnext = next_not(p[0]); + if( p + 1 < pnext ) { + exclusions.pluses++; + } + pnext = valid_next(--pnext, "B0/,.Z*Z*9VPPE"); + break; + case 'Z': case '*': + exclusions.stars++; + pnext = next_not(p[0]); + break; + case 'S': + // 19: S: "9VP" + pnext = valid_next(p, "9VP"); + break; + } + + /* + * "For fixed editing sign control, the currency symbol, when used, shall + * be either the leftmost symbol in character-string-1, optionally preceded + * by one of the symbols '+' or '-' " + */ + if( pnext ) { + if( p == pnext || p[0] == '+' || p[0] == '-' ) { + if( symbol_currency(*pnext) ) { + exclusions.currency++; + pnext = next_not(*pnext); + pnext = valid_next(--pnext, true, '$'); + } + } + } + + return pnext; + } + + const char * next() { // modify state; do not modify position + auto pnext = p; + auto loc(picture_t::loc); + loc.first_column += int(p - begin); + + if( is_crdb() ) { + if( exclusions.crdb++ ) { + error_msg( loc, "PICTURE: CR/DB and %c/%c may appear only once", '+', '-' ); + return nullptr; + } + if( p + 2 != pend ) { + error_msg( loc, "PICTURE: CR/DB must appear at the end" ); + return nullptr; + } + return pend; + } + + if( symbol_currency(p[0]) ) { + if( false && exclusions.currency++ ) { // not enforced + error_msg( loc, "PICTURE: CURRENCY SYMBOL sequence may appear at most once" ); + return nullptr; + } + return valid_next(p, ! exclusions.dot, '$'); + } + + switch(TOUPPER(p[0])) { + case '(': + return match_paren(p); + break; + case 'B': case '0': case '/': + pnext = valid_next(p); + break; + case comma: + if( decimal_is_comma() ) { + if( exclusions.dot++ ) { + error_msg( loc, "PICTURE: %qc: may appear at most once", p[0] ); + return nullptr; + } + pnext = valid_next(p, true, dot); + } else { + pnext = valid_next(p); + } + break; + case dot: + if( p + 1 == pend ) { + pnext = pend; + } else { + if( decimal_is_comma() ) { + pnext = valid_next(p, true, comma ); + } else { + if( exclusions.dot++ ) { + error_msg( loc, "PICTURE: %qc: may appear at most once", p[0] ); + return nullptr; + } + pnext = valid_next(p); + } + } + break; + + case '+': case '-': + // 7 is trailing sign; 13 & 14 are numeric. Leading sign handled by start(). + if( p + 1 == pend ) { + if( exclusions.crdb++ ) { + error_msg( loc, "PICTURE: %c/%c may appear at most once as a sign", '+', '-' ); + return nullptr; + } + pnext = pend; + } else { + pnext = next_not(p[0]); + if( p + 1 < pnext ) { + if( false && exclusions.pluses++ ) { // not enforced + error_msg( loc, "PICTURE: %qc: sequence may appear at most once", p[0] ); + return nullptr; + } + } + pnext = valid_next(pnext, ! exclusions.dot); + } + break; + + case 'Z': case '*': + if( false && exclusions.stars++ ) { // not enforced + error_msg( loc, "PICTURE: %qc: sequence may appear at most once", p[0] ); + return nullptr; + } + if( (pnext = next_not(p[0])) == nullptr ) return pnext; + pnext = valid_next(pnext, ! exclusions.dot); + break; + case 'P': + pnext = valid_next(pnext, ! exclusions.dot); + break; + case '9': + case 'A': case 'X': + case 'V': + case '1': + case 'N': + pnext = valid_next(p); + break; + case 'E': + pnext = valid_next(p, "+9"); + if( pnext && *pnext == '+' ) { + pnext = valid_next(p, "9"); + } + break; + default: + error_msg( loc, "PICTURE: %qc: invalid character", p[0] ); + return nullptr; + } + return pnext; + } + + public: + picture_t( const char *p, int len ) + : begin(p) + , p(p), pend(p + len) + , loc(yylloc) + { + assert(TOUPPER(*p) == 'P'); // as in PICTURE (or PICTURE IS) + // move p to start of picture string + while( (p = std::find_if(p, pend, fisspace)) != pend ) { + this->p = p = std::find_if(p, pend, + []( char ch ) { return ! fisspace(ch); } ); + } + assert(this->p != pend); + pos = this->p - begin; + } + + bool is_valid() { + if( !p ) return false; + if( (p = start()) == nullptr ) { + return false; + } + + while( p && p < pend) { + p = next(); + } + return p == pend; + } + + int starts_at() const { return pos; } +}; + +/* + * The Followers map gives 1 or 2 lists of valid characters following a + * character, the one in the key. If there are two lists, the correct one is + * determined by the caller based on the state of the picture string, i.e., + * what has been seen before. + */ +const std::map <char, picture_t::followings_t> picture_t::followers { + /* B0/ */ { 'B', {"B0/,.Z*+-9AXVPNE" } }, + /* B0/ */ { '0', {"B0/,.Z*+-9AXVPNE" } }, + /* B0/ */ { '/', {"B0/,.Z*+-9AXVPNE" } }, + /* , */ { ',', {"B0/,.Z*+-9VPE"} }, + /* . */ { '.', {"B0/,Z*+-9E"} }, + /* + { '+', "9" }, */ + /* +- */ { '+', {"B0/,.Z*9VPE", "" } }, + /* +- */ { '-', {"B0/,.Z*9VPE", "" } }, + /* CR/DB { 'C', "" }, */ + /* cs { 'c', "B0/,.Z*+-9VP" }, */ + /* cs { 'c', "+" }, */ + /* Z* */ { 'Z', {"B0/,.+Z*9VP", "B0/,+Z*"} }, + /* Z* */ { '*', {"B0/,.+Z*9VP", "B0/,+Z*"} }, + /* + */ { '+', {"B0/,.+-9VP", "B0/,+-"} }, + /* cs */ { '$', {"B0/,.+9VP", "B0/,+"} }, + /* 9 */ { '9', {"B0/,.+9AXVPE"} }, + /* AX */ { 'A', {"B0/9AX"} }, + /* AX */ { 'X', {"B0/9AX"} }, + /* S */ { 'S', {"9VP"} }, + /* V */ { 'V', {"B0/,+Z*+-9P"} }, + /* P */ { 'P', {"+VP", "B0/,+Z*9P"} }, + /* 1 */ { '1', {"1"} }, + /* N */ { 'N', {"B0/N"} }, + /* E */ { 'E', {"+9"} }, +}; + +/* + * Although picture_t::is_valid return a bool, it's not used. The validation + * routines emit messages where the error is detected. The entire string is + * subsequently parsed by the parser, which might otherwise accept an invalid + * string, but will usually emit a message of its own. + */ +static int +validate_picture() { + picture_t picture(yytext, yyleng); + picture.is_valid(); + return picture.starts_at(); +} + static inline bool is_integer_token( int *pvalue = NULL ) { int v, n = 0; @@ -663,7 +1091,7 @@ bool need_nume_set( bool tf ) { static int datetime_format_of( const char input[] ); static int symbol_function_token( const char name[] ) { - auto e = symbol_function( 0, name ); + const auto e = symbol_function( 0, name ); return e ? symbol_index(e) : 0; } @@ -751,7 +1179,7 @@ typed_name( const char name[] ) { __attribute__((fallthrough)); case FldLiteralN: { - auto f = cbl_field_of(e); + const auto f = cbl_field_of(e); if( type == FldLiteralN ) { yylval.numstr.radix = f->has_attr(hex_encoded_e)? hexadecimal_e : decimal_e; @@ -785,7 +1213,7 @@ typed_name( const char name[] ) { return cbl_field_of(e)->level == 88? NAME88 : CLASS_NAME; break; default: - yywarn("%s:%d: invalid symbol type %s for symbol \"%s\"", + yywarn("%s:%d: invalid symbol type %s for symbol %qs", __func__, __LINE__, cbl_field_type_str(type), name); return NAME; } @@ -807,32 +1235,6 @@ tmpstring_append( int len ) { #define pop_return yy_pop_state(); return -static bool -wait_for_the_child(void) { - pid_t pid; - int status; - - if( (pid = wait(&status)) == -1 ) { - yywarn("internal error: no pending child CDF parser process"); - return false; - } - - if( WIFSIGNALED(status) ) { - yywarn( "process %d terminated by %s", pid, strsignal(WTERMSIG(status)) ); - return false; - } - if( WIFEXITED(status) ) { - if( WEXITSTATUS(status) != 0 ) { - yywarn("process %d exited with status %d", pid, status); - return false; - } - } - if( yy_flex_debug ) { - yywarn("process %d exited with status %d", pid, status); - } - return true; -} - static bool is_not = false; static uint64_t diff --git a/gcc/cobol/scan_post.h b/gcc/cobol/scan_post.h index 85feac86be1a..7cf2b98cd372 100644 --- a/gcc/cobol/scan_post.h +++ b/gcc/cobol/scan_post.h @@ -34,7 +34,6 @@ start_condition_str( int sc ) { switch(sc) { case INITIAL: state = "INITIAL"; break; case addr_of: state = "addr_of"; break; - case author_state: state = "author_state"; break; case basis: state = "basis"; break; case bool_state: state = "bool_state"; break; case cdf_state: state = "cdf_state"; break; @@ -116,10 +115,10 @@ datetime_format_of( const char input[] ) { for( auto p = patterns; p < eopatterns; p++ ) { static const int cflags = REG_EXTENDED | REG_ICASE; - static char msg[80]; int erc; if( 0 != (erc = regcomp(&p->re, p->regex, cflags)) ) { + static char msg[80]; regerror(erc, &p->re, msg, sizeof(msg)); yywarn("%s:%d: %s: %s", __func__, __LINE__, keyword_str(p->token), msg); } @@ -159,6 +158,8 @@ is_cdf_token( int token ) { case CDF_DISPLAY: case CDF_IF: case CDF_ELSE: case CDF_END_IF: case CDF_EVALUATE: case CDF_WHEN: case CDF_END_EVALUATE: + case CDF_PUSH: + case CDF_POP: return true; case CALL_COBOL: case CALL_VERBATIM: @@ -260,13 +261,12 @@ prelex() { while( is_cdf_token(token) ) { if( ! run_cdf(token) ) { - dbgmsg( ">>CDF parser failed" ); - return NO_CONDITION; + dbgmsg( ">>CDF parser failed, ydfchar %d", ydfchar ); } // Return the CDF's discarded lookahead token, if extant. token = ydfchar > 0? ydfchar : next_token(); if( token == NO_CONDITION && parsing.at_eof() ) { - return token = YYEOF; + return YYEOF; } // Reenter cdf parser only if next token could affect parsing state. @@ -298,7 +298,7 @@ prelex() { token = LEVEL; break; case YDF_NUMBER: - if( yy_flex_debug ) yywarn("final token is YDF_NUMBER"); + if( yy_flex_debug ) yywarn("final token is %<YDF_NUMBER%>"); yylval.number = ydflval.number; token = LEVEL; break; @@ -375,7 +375,7 @@ yylex(void) { token = prelex(); if( yy_flex_debug ) { if( parsing.in_cdf() ) { - dbgmsg( "%s:%d: %s routing %s to CDF parser", __func__, __LINE__, + dbgmsg( "%s:%d: <%s> routing %s to CDF parser", __func__, __LINE__, start_condition_is(), keyword_str(token) ); } else if( !parsing.on() ) { dbgmsg( "eating %s because conditional compilation is FALSE", diff --git a/gcc/cobol/show_parse.h b/gcc/cobol/show_parse.h index f7ab98220a5a..bd0e16fe8332 100644 --- a/gcc/cobol/show_parse.h +++ b/gcc/cobol/show_parse.h @@ -147,10 +147,10 @@ extern bool cursor_at_sol; fprintf(stderr, "<%s>", cbl_field_type_str((b).field->type)); \ } \ } \ - if( (b).nsubscript) \ + if( (b).nsubscript()) \ { \ fprintf(stderr,"("); \ - for(size_t jjj=0; jjj<(b).nsubscript; jjj++) \ + for(size_t jjj=0; jjj<(b).nsubscript(); jjj++) \ { \ if(jjj) \ { \ @@ -176,11 +176,21 @@ extern bool cursor_at_sol; } \ else \ { \ - fprintf(stderr, " %p:%s (%s)", (void*)b, b->name, b->type_str()); \ + fprintf(stderr, " %p:%s (%s)", static_cast<void*>(b), b->name, b->type_str()); \ } \ show_parse_sol = false; \ } while(0); +// Use this version when b is known to be valid. This is necessary to quiet +// cppcheck nullPointerRedundantCheck warnings +#define SHOW_PARSE_LABEL_OK(a, b) \ + do \ + { \ + fprintf(stderr, "%s", a); \ + fprintf(stderr, " %p:%s (%s)", static_cast<void*>(b), b->name, b->type_str()); \ + show_parse_sol = false; \ + } while(0); + #define TRACE1 if(bTRACE1) #define TRACE1_HEADER do \ { \ @@ -211,6 +221,7 @@ extern bool cursor_at_sol; #define TRACE1_FIELD_VALUE(a, field, b) \ do \ { \ + gcc_assert(field); \ cursor_at_sol=false; \ if ( field->type == FldConditional ) \ { \ @@ -337,13 +348,13 @@ extern bool cursor_at_sol; else \ { \ gg_fprintf(trace_handle, 1, "%s", gg_string_literal( (b).field->name ? (b).field->name:"")); \ - if( b.nsubscript ) \ + if( b.nsubscript() ) \ { \ gg_fprintf(trace_handle, 0, "("); \ - for(unsigned int i=0; i<b.nsubscript; i++) \ + for(unsigned int i=0; i<b.nsubscript(); i++) \ { \ gg_fprintf(trace_handle, 1, "%s", gg_string_literal( b.subscripts[i].field->name ? b.subscripts[i].field->name : "" )); \ - if( i<b.nsubscript-1 ) \ + if( i<b.nsubscript()-1 ) \ { \ gg_fprintf(trace_handle, 0, " "); \ } \ @@ -423,31 +434,61 @@ extern bool cursor_at_sol; } while(0); // Use CHECK_FIELD when a should be non-null, and a->var_decl_node also should -// by non-null: -#define CHECK_FIELD(a) \ - do{ \ - if(!a) \ - { \ - yywarn("%s(): parameter " #a " is NULL", __func__); \ - gcc_unreachable(); \ - } \ - if( !a->var_decl_node && a->type != FldConditional && a->type != FldLiteralA) \ - { \ - yywarn("%s() parameter " #a " is variable %s<%s> with NULL var_decl_node", \ - __func__, \ - a->name, \ - cbl_field_type_str(a->type) ); \ - gcc_unreachable(); \ - } \ - }while(0); - -#define CHECK_LABEL(a) \ - do{ \ - if(!a) \ - { \ - yywarn("%s(): parameter " #a " is NULL", __func__); \ - gcc_unreachable(); \ - } \ +// by non-null. (The useless calls to abort() are because cppcheck doesn't +// understand that gcc_unreachable doesn't return); + +// Use this after doing any SHOW_PARSE stuff, to avoid cppcheck complaints +// about nullPointerRedundantCheck +#define CHECK_FIELD(a) \ + do { \ + if(!a) \ + { \ + yywarn("%s: parameter %<" #a "%> is NULL", __func__); \ + gcc_unreachable(); \ + abort(); \ + } \ + if( !a->var_decl_node ) \ + { \ + yywarn("%s: parameter %<" #a "%> is variable " \ + "%s<%s> with NULL %<var_decl_node%>", \ + __func__, \ + a->name, \ + cbl_field_type_str(a->type) ); \ + gcc_unreachable(); \ + abort(); \ + } \ + } while(0); + +// This version is a bit more lax, for special cases +#define CHECK_FIELD2(a) \ + do { \ + if(!a) \ + { \ + yywarn("%s: parameter %<" #a "%> is NULL", __func__); \ + gcc_unreachable(); \ + abort(); \ + } \ + if( !a->var_decl_node && a->type != FldConditional && a->type != FldLiteralA) \ + { \ + yywarn("%s: parameter %<" #a "%> is variable " \ + "%s<%s> with NULL %<var_decl_node%>", \ + __func__, \ + a->name, \ + cbl_field_type_str(a->type) ); \ + gcc_unreachable(); \ + abort(); \ + } \ + } while(0); + + +#define CHECK_LABEL(a) \ + do{ \ + if(!a) \ + { \ + yywarn("%s: parameter %<" #a "%> is NULL", __func__); \ + gcc_unreachable(); \ + abort(); \ + } \ }while(0); #ifdef INCORPORATE_ANALYZER @@ -503,10 +544,11 @@ class ANALYZE } }; #else +// cppcheck-suppress ctuOneDefinitionRuleViolation class ANALYZE { public: - ANALYZE(const char *) + explicit ANALYZE(const char *) { } ~ANALYZE() diff --git a/gcc/cobol/symbols.cc b/gcc/cobol/symbols.cc index e540b40a92c5..7d6a9554bdde 100644 --- a/gcc/cobol/symbols.cc +++ b/gcc/cobol/symbols.cc @@ -56,7 +56,7 @@ class symbol_pair_t { const symbol_elem_t *first, *last; public: - symbol_pair_t( const symbol_elem_t * first, const symbol_elem_t * end = NULL ) + explicit symbol_pair_t( const symbol_elem_t * first, const symbol_elem_t * end = NULL ) : first(first), last(end) {} @@ -136,11 +136,9 @@ static struct symbol_table_t { static symbol_table_t& symbol_table_extend() { - static FILE *mapped; if( symbols.nelem == 0 ) { // first time: create file & set initial capacity - assert(mapped == NULL && symbols.fd == -1); - + FILE *mapped; if( (mapped = tmpfile()) == NULL ) { cbl_err( "could not create temporary file for symbol table"); } @@ -160,8 +158,8 @@ symbol_table_extend() { off_t len = symbols.size(); if( 0 != ftruncate(symbols.fd, len) ) { - cbl_err( "%s:%d:could not extend symbol table to %zu elements", - __func__, __LINE__, symbols.capacity); + cbl_err( "%s:%d: could not extend symbol table to %lu elements", + __func__, __LINE__, gb4(symbols.capacity)); } /* @@ -229,6 +227,12 @@ cbl_span_t::from_field() { assert(from); return from->field; } cbl_field_t * cbl_span_t::len_field() { assert(len); return len->field; } +cbl_ffi_arg_t::cbl_ffi_arg_t() + : optional(false) + , crv(by_reference_e) + , attr(none_of_e) +{} + cbl_ffi_arg_t:: cbl_ffi_arg_t( cbl_refer_t* refer, cbl_ffi_arg_attr_t attr ) : optional(false) @@ -280,7 +284,7 @@ class group_size_t { enum { constq = constant_e | quoted_e }; static symbol_elem_t -elementize( cbl_field_t& field ) { +elementize( const cbl_field_t& field ) { symbol_elem_t sym (SymField); sym.elem.field = field; return sym; @@ -496,13 +500,13 @@ symbol_elem_cmp( const void *K, const void *E ) } return strcasecmp(key.name, elem.name); } - break; + // break; // This break not needed if all options do a return. case SymSpecial: return special_pair_cmp(k->elem.special, e->elem.special)? 0 : 1; - break; + // break; // This break not needed after return. case SymAlphabet: return strcasecmp(k->elem.alphabet.name, e->elem.alphabet.name); - break; + // break; // This break not needed after return. case SymFile: // If the key is global, so must be the found element. if( (cbl_file_of(k)->attr & global_e) == global_e && @@ -510,7 +514,7 @@ symbol_elem_cmp( const void *K, const void *E ) return 1; } return strcasecmp(k->elem.file.name, e->elem.file.name); - break; + // break; // This break not needed after return. } assert(k->type == SymField); @@ -668,7 +672,7 @@ symbol_special( size_t program, const char name[] ) struct symbol_elem_t * symbol_alphabet( size_t program, const char name[] ) { - cbl_alphabet_t alphabet(YYLTYPE(), custom_encoding_e); + cbl_alphabet_t alphabet(YYLTYPE(), custom_encoding_e); // cppcheck-suppress syntaxError assert(strlen(name) < sizeof alphabet.name); strcpy(alphabet.name, name); @@ -907,7 +911,7 @@ end_of_group( const cbl_field_t *group, const cbl_field_t *field ) { class eog_t { const cbl_field_t * group; public: - eog_t( const symbol_elem_t *e ) : group(cbl_field_of(e)) {} + explicit eog_t( const symbol_elem_t *e ) : group(cbl_field_of(e)) {} bool operator()( symbol_elem_t& e ) { return e.type == SymField && end_of_group(group, cbl_field_of(&e)); @@ -927,7 +931,7 @@ end_of_group( size_t igroup ) { if( e->program != group->program ) return isym; if( e->type == SymLabel ) return isym; // end of data division if( e->type == SymField ) { - auto f = cbl_field_of(e); + const cbl_field_t * f = cbl_field_of(e); if( f->level == LEVEL77 || f->level == 66 ) return isym; if( f->level == 1 && f->parent != igroup ) { return isym; @@ -938,7 +942,7 @@ end_of_group( size_t igroup ) { } eog_t eog(symbol_at(igroup)); - symbol_elem_t *e = std::find_if( symbols_begin(++igroup), symbols_end(), eog ); + const symbol_elem_t *e = std::find_if( symbols_begin(++igroup), symbols_end(), eog ); return e - symbols_begin(); } @@ -993,7 +997,7 @@ symbol_find_odo_debug( cbl_field_t * field ) { // Return OCCURS DEPENDING ON table subordinate to field, if any. struct cbl_field_t * -symbol_find_odo( cbl_field_t * field ) { +symbol_find_odo( const cbl_field_t * field ) { size_t bog = field_index(field), eog = end_of_group(bog); auto e = std::find_if( symbol_at(bog), symbol_at_impl(eog, true), has_odo ); return e == symbol_at_impl(eog, true)? NULL : cbl_field_of(e); @@ -1170,7 +1174,7 @@ static struct symbol_elem_t * // If an 01 record exists for the FD/SD, use its capacity as the // default_record capacity. if( p != symbols_end() ) { - auto record = cbl_field_of(p); + const cbl_field_t * record = cbl_field_of(p); assert(record->level == 1); e = calculate_capacity(p); auto record_size = std::max(record->data.memsize, @@ -1258,7 +1262,7 @@ static struct symbol_elem_t * // If group has a parent that is a record area, expand it, too. if( 0 < group->parent ) { - auto redefined = symbol_redefines(group); + redefined = symbol_redefines(group); if( redefined && is_record_area(redefined) ) { if( redefined->data.capacity < group->data.memsize ) { redefined->data.capacity = group->data.memsize; @@ -1339,19 +1343,18 @@ immediately_follows( const cbl_field_t *field ) { bool is_variable_length( const cbl_field_t *field ) { - bool odo = false; - std::find_if( symbol_at(field_index(field)) + 1, symbols_end(), - [&odo, field]( const auto& elem ) { - if( elem.type == SymField ) { - auto f = cbl_field_of(&elem); - if( f->level <= field->level ) return true; - if( f->occurs.depending_on ) { - odo = true; - return true; - } - } - return false; - } ); + // RENAMES may be included in end_of_group. + size_t isym = field_index(field), esym = end_of_group(isym); + bool odo = std::any_of( symbol_at(isym) + 1, symbol_at_impl(esym), + [field]( const auto& elem ) { + if( elem.type == SymField ) { + auto f = cbl_field_of(&elem); + if( field->level < f->level ) { // exclude RENAMES + return 0 < f->occurs.depending_on; + } + } + return false; + } ); return odo; } @@ -1363,7 +1366,7 @@ is_variable_length( const cbl_field_t *field ) { * occurs-depending table." */ cbl_field_t * -rename_not_ok( cbl_field_t *first, cbl_field_t *last) { +rename_not_ok( const cbl_field_t *first, const cbl_field_t *last) { symbol_elem_t *beg = symbol_at(field_index(first)), *end = symbol_at(field_index(last)); @@ -1431,11 +1434,11 @@ cbl_field_t::attr_str( const std::vector<cbl_field_attr_t>& attrs ) const const char *sep = ""; char *out = NULL; - for( auto attr : attrs ) { + for( auto attr_l : attrs ) { char *part = out; - if( has_attr(attr) ) { + if( has_attr(attr_l) ) { int erc = asprintf(&out, "%s%s%s", - part? part : "", sep, cbl_field_attr_str(attr)); + part? part : "", sep, cbl_field_attr_str(attr_l)); if( -1 == erc ) return part; free(part); sep = ", "; @@ -1464,7 +1467,7 @@ field_str( const cbl_field_t *field ) { } pend += snprintf(pend, string + sizeof(string) - pend, - "%02d %-20s ", field->level, name); + "%02u %-20s ", field->level, name); char offset[32] = ""; if( field->level > 1 ) { @@ -1575,7 +1578,7 @@ struct capacity_of { capacity_of operator()( symbol_elem_t& elem ) { if( elem.type == SymField ) { - cbl_field_t *f = cbl_field_of(&elem); + const cbl_field_t *f = cbl_field_of(&elem); if( is_elementary(f->type) ) { capacity += field_size(f); } @@ -1704,7 +1707,6 @@ symbols_update( size_t first, bool parsed_ok ) { case 1: pend = calculate_capacity(p); if( dialect_mf() && is_table(field) ) { - cbl_field_t *field = cbl_field_of(p); if( field->data.memsize < field->size() ) { field->data.memsize = field->size(); } @@ -1743,7 +1745,7 @@ symbols_update( size_t first, bool parsed_ok ) { bool size_invalid = field->data.memsize > 0 && symbol_redefines(field); if( size_invalid ) { // redefine of record area is ok - auto redefined = symbol_redefines(field); + const cbl_field_t * redefined = symbol_redefines(field); size_invalid = ! is_record_area(redefined); } if( !field->is_valid() || size_invalid ) @@ -1766,8 +1768,8 @@ symbols_update( size_t first, bool parsed_ok ) { if( e == symbols_end() ) { // no field redefines the file's default record auto file = cbl_file_of(symbol_at(field->parent)); - ERROR_FIELD(field, "line %d: %s lacks a file description", - file->line, file->name); + ERROR_FIELD(field, "%s lacks a file description", + file->name); return 0; } } @@ -1826,7 +1828,7 @@ symbols_update( size_t first, bool parsed_ok ) { } // Verify REDEFINing field has no ODO components - auto parent = symbol_redefines(field); + const cbl_field_t * parent = symbol_redefines(field); if( parent && !is_record_area(parent) && is_variable_length(field) ) { ERROR_FIELD(field, "line %d: REDEFINES field %s cannot be variable length", field->line, field->name); @@ -2016,15 +2018,15 @@ symbol_in_file( symbol_elem_t *e ) { } #endif -static struct cbl_field_t * -symbol_field_parent_set( struct cbl_field_t *field ) +static cbl_field_t * +symbol_field_parent_set( cbl_field_t *field ) { if( field->level == 01 ) return NULL; if( field->level == 77 ) return NULL; if( field->level == 78 ) return NULL; struct symbol_elem_t *e = symbols.elems + symbols.nelem - 1; - struct symbol_elem_t *first = symbols.elems + symbols.first_program; + const struct symbol_elem_t *first = symbols.elems + symbols.first_program; for( ; field->parent == 0 && e >= first; e-- ) { if( ! (e->type == SymField && cbl_field_of(e)->level > 0) ) { @@ -2102,7 +2104,7 @@ class parent_elem_set private: size_t parent_index; public: - parent_elem_set( size_t parent_index ) + explicit parent_elem_set( size_t parent_index ) : parent_index(parent_index) {} void operator()( struct symbol_elem_t& e ) { @@ -2178,14 +2180,22 @@ symbol_table_init(void) { } static symbol_elem_t environs[] = { + { symbol_elem_t{ 0, cbl_special_name_t{0, CONSOLE_e, "CONSOLE", 0, "/dev/stdout"}} }, // stdout in DISPLAY; stdin in ACCEPT + + { symbol_elem_t{ 0, cbl_special_name_t{0, STDIN_e, "STDIN", 0, "/dev/stdin"}} }, { symbol_elem_t{ 0, cbl_special_name_t{0, SYSIN_e, "SYSIN", 0, "/dev/stdin"}} }, - { symbol_elem_t{ 0, cbl_special_name_t{0, SYSIPT_e, "SYSIPT", 0, "/dev/stdout"}} }, + { symbol_elem_t{ 0, cbl_special_name_t{0, SYSIPT_e, "SYSIPT", 0, "/dev/stdin"}} }, + + { symbol_elem_t{ 0, cbl_special_name_t{0, STDOUT_e, "STDOUT", 0, "/dev/stdout"}} }, { symbol_elem_t{ 0, cbl_special_name_t{0, SYSOUT_e, "SYSOUT", 0, "/dev/stdout"}} }, { symbol_elem_t{ 0, cbl_special_name_t{0, SYSLIST_e, "SYSLIST", 0, "/dev/stdout"}} }, { symbol_elem_t{ 0, cbl_special_name_t{0, SYSLST_e, "SYSLST", 0, "/dev/stdout"}} }, + { symbol_elem_t{ 0, cbl_special_name_t{0, SYSPUNCH_e, "SYSPUNCH", 0, "/dev/stderr"}} }, { symbol_elem_t{ 0, cbl_special_name_t{0, SYSPCH_e, "SYSPCH", 0, "/dev/stderr"}} }, - { symbol_elem_t{ 0, cbl_special_name_t{0, CONSOLE_e, "CONSOLE", 0, "/dev/stdout"}} }, + { symbol_elem_t{ 0, cbl_special_name_t{0, STDERR_e, "STDERR", 0, "/dev/stderr"}} }, + { symbol_elem_t{ 0, cbl_special_name_t{0, SYSERR_e, "SYSERR", 0, "/dev/stderr"}} }, + { symbol_elem_t{ 0, cbl_special_name_t{0, C01_e, "C01", 0, "/dev/null"}} }, { symbol_elem_t{ 0, cbl_special_name_t{0, C02_e, "C02", 0, "/dev/null"}} }, { symbol_elem_t{ 0, cbl_special_name_t{0, C03_e, "C03", 0, "/dev/null"}} }, @@ -2205,10 +2215,6 @@ symbol_table_init(void) { { symbol_elem_t{ 0, cbl_special_name_t{0, S04_e, "S04", 0, "/dev/null"}} }, { symbol_elem_t{ 0, cbl_special_name_t{0, S05_e, "S05", 0, "/dev/null"}} }, { symbol_elem_t{ 0, cbl_special_name_t{0, AFP_5A_e, "AFP-5A", 0, "/dev/null"}} }, - { symbol_elem_t{ 0, cbl_special_name_t{0, STDIN_e, "STDIN", 0, "/dev/stdin"}} }, - { symbol_elem_t{ 0, cbl_special_name_t{0, STDOUT_e, "STDOUT", 0, "/dev/stdout"}} }, - { symbol_elem_t{ 0, cbl_special_name_t{0, STDERR_e, "STDERR", 0, "/dev/stderr"}} }, - { symbol_elem_t{ 0, cbl_special_name_t{0, SYSERR_e, "SYSERR", 0, "/dev/stderr"}} }, }; struct symbol_elem_t *p = table.elems + table.nelem; @@ -2406,7 +2412,7 @@ symbol_file_add( size_t program, cbl_file_t *file ) { return NULL; } - struct symbol_elem_t sym = { SymFile, program }; + symbol_elem_t sym{ SymFile, program }; sym.elem.file = *file; e = symbol_add(&sym); @@ -2419,9 +2425,9 @@ symbol_file_add( size_t program, cbl_file_t *file ) { return e; } -struct symbol_elem_t * -symbol_alphabet_add( size_t program, struct cbl_alphabet_t *alphabet ) { - struct symbol_elem_t sym{ SymAlphabet, program }; +symbol_elem_t * +symbol_alphabet_add( size_t program, const cbl_alphabet_t *alphabet ) { + symbol_elem_t sym{ SymAlphabet, program }; sym.elem.alphabet = *alphabet; return symbol_add(&sym); } @@ -2464,7 +2470,7 @@ symbol_typedef_add( size_t program, struct cbl_field_t *field ) { auto e = symbols_end() - 1; assert( symbols_begin() < e ); if( e->type == SymField ) { - auto f = cbl_field_of(e); + const cbl_field_t * f = cbl_field_of(e); if( f == field ) return e; } @@ -2502,7 +2508,7 @@ struct symbol_elem_t * symbol_field_add( size_t program, struct cbl_field_t *field ) { field->our_index = symbols.nelem; - cbl_field_t *parent = symbol_field_parent_set( field ); + const cbl_field_t *parent = symbol_field_parent_set( field ); if( parent && parent->type == FldGroup) { // Inherit effects of parent's USAGE, as though it appeared 1st in the // member's definition. @@ -2514,7 +2520,8 @@ symbol_field_add( size_t program, struct cbl_field_t *field ) if( is_numeric(parent->usage) && parent->data.capacity > 0 ) { field->type = parent->usage; field->data = parent->data; - field->data = 0.0; + field->data = 0; // cppcheck-suppress redundantAssignment + // // cppcheck doesn't understand multiple overloaded operator= field->data.initial = NULL; } } @@ -2633,6 +2640,7 @@ symbol_field( size_t program, size_t parent, const char name[] ) return p != end? &*p : NULL; } +// cppcheck-suppress-begin [CastIntegerToAddressAtReturn] obviously not true symbol_elem_t * symbol_register( const char name[] ) { @@ -2648,6 +2656,7 @@ symbol_register( const char name[] ) return p; } +// cppcheck-suppress-end [CastIntegerToAddressAtReturn] // Find current 01 record during Level 66 construction. const symbol_elem_t * @@ -2710,11 +2719,12 @@ symbol_literalA( size_t program, const char name[] ) struct symbol_elem_t * symbol_file( size_t program, const char name[] ) { size_t nelem = symbols.nelem; - struct symbol_elem_t key = { SymFile, program }, *e = &key; + symbol_elem_t key{ SymFile, program }, *e = &key; assert(strlen(name) < sizeof(key.elem.file.name)); strcpy(key.elem.file.name, name); + // cppcheck-suppress-begin [knownConditionTrueFalse] do { e = static_cast<struct symbol_elem_t *>(lfind( &key, symbols.elems, &nelem, sizeof(*e), @@ -2723,6 +2733,7 @@ symbol_file( size_t program, const char name[] ) { key.program = cbl_label_of(symbol_at(key.program))->parent; if( key.program == 0 ) break; // no file without a program } while( !e ); + // cppcheck-suppress-end [knownConditionTrueFalse] if( e ) { assert(e->type == SymFile); @@ -2830,7 +2841,7 @@ seek_parent( const symbol_elem_t *e, size_t level ) { struct symbol_elem_t * symbol_field_same_as( cbl_field_t *tgt, const cbl_field_t *src ) { if( target_in_src(tgt, src) ) { - ERROR_FIELD(tgt, "%s %s may not reference itself as part of %s %s", + ERROR_FIELD(tgt, "%s %s may not reference itself as part of %s %s", tgt->level_str(), tgt->name, src->level_str(), src->name); return NULL; } @@ -2916,7 +2927,7 @@ symbol_file_same_record_area( std::list<cbl_file_t*>& files ) { } static symbol_elem_t * -next_program( symbol_elem_t *elem ) { +next_program( const symbol_elem_t *elem ) { size_t start = elem? symbol_index(elem) : 0; symbol_elem_t * e = std::find_if( symbols_begin(start), symbols_end(), is_program ); @@ -2954,14 +2965,14 @@ is_numeric_constant( const char name[] ) { // get default record layout for a file struct cbl_field_t * -symbol_file_record( struct cbl_file_t *file ) { +symbol_file_record( const cbl_file_t *file ) { return cbl_field_of(symbol_at(file->default_record)); } class is_section { cbl_section_type_t section_type; public: - is_section( cbl_section_type_t sect ) : section_type(sect) {} + explicit is_section( cbl_section_type_t sect ) : section_type(sect) {} bool operator()( symbol_elem_t& e ) const { return e.type == SymDataSection && cbl_section_of(&e)->type == section_type; } @@ -2972,8 +2983,6 @@ static bool fd_record_size_cmp( const symbol_elem_t& a, const symbol_elem_t& b ) return cbl_field_of(&a)->data.capacity < cbl_field_of(&b)->data.capacity; } -cbl_file_key_t cbl_file_t::no_key; - /* * Find largest and smallest record defined for a file. The rule is: * cbl_file_t::varies() returns true if the record size varies, @@ -3084,7 +3093,7 @@ cbl_alphabet_t::assign( const YYLTYPE& loc, unsigned char ch, unsigned char high return true; } auto taken = alphabet[ch]; - error_msg(loc, "ALPHABET %s, character '%c' (X'%x') " + error_msg(loc, "ALPHABET %s, character %<%c%> (X%'%x%') " "in position %d already defined at position %d", name, ISPRINT(ch)? ch : '?', ch, @@ -3136,7 +3145,6 @@ static cbl_field_t * new_temporary_impl( enum cbl_field_type_t type, const cbl_name_t name = nullptr ) { extern int yylineno; - static int nstack, nliteral; static const struct cbl_field_t empty_alpha = { 0, FldAlphanumeric, FldInvalid, intermediate_e, 0, 0, 0, nonarray, 0, "", @@ -3205,8 +3213,10 @@ new_temporary_impl( enum cbl_field_type_t type, const cbl_name_t name = nullptr f->line = yylineno; if( is_literal(type) ) { + static int nliteral = 0; snprintf(f->name, sizeof(f->name), "_literal%d",++nliteral); } else { + static int nstack = 0; snprintf(f->name, sizeof(f->name), "_stack%d",++nstack); } @@ -3230,7 +3240,6 @@ parser_symbol_add2( cbl_field_t *field ) { static cbl_field_t * new_literal_add( const char initial[], uint32_t len, enum cbl_field_attr_t attr ) { - static char empty[2] = "\0"; cbl_field_t *field = NULL; if( !(attr & quoted_e) ) { @@ -3240,6 +3249,7 @@ new_literal_add( const char initial[], uint32_t len, enum cbl_field_attr_t attr } else { + static char empty[2] = "\0"; field = new_temporary_impl(FldLiteralA); field->attr |= attr; field->data.initial = len > 0? initial : empty; @@ -3489,7 +3499,7 @@ cbl_field_t::internalize() { static const size_t noconv = size_t(-1); if (cd == (iconv_t)-1) { - yywarn("failed iconv_open tocode = '%s' fromcode = %s", tocode, fromcode); + yywarn("failed %<iconv_open%> tocode = %<%s%> fromcode = %s", tocode, fromcode); } bool using_assumed = fromcode == os_locale.assumed; @@ -3606,12 +3616,9 @@ cbl_label_t::explicit_parent() const { } cbl_prog_hier_t::cbl_prog_hier_t() { - nlabel = std::count_if( symbols_begin(), symbols_end(), is_program ); - assert(nlabel >0); - labels = new cbl_prog_hier_t::program_label_t[nlabel]; - std::copy_if( symbols_begin(), symbols_end(), - labels, is_program ); + std::back_inserter(labels), is_program ); + assert(! labels.empty()); } /* @@ -3704,7 +3711,8 @@ symbol_label_add( size_t program, cbl_label_t *input ) if( (e = symbol_add(&elem)) == NULL ) { cbl_errx("%s:%d: could not add '%s'", __func__, __LINE__, label->name); } - + assert(e); + common_callables_update( symbol_index(e) ); // restore munged line number unless symbol_add returned an existing label @@ -3722,10 +3730,16 @@ symbol_label_add( size_t program, cbl_label_t *input ) bool symbol_label_section_exists( size_t eval_label_index ) { auto eval = symbols_begin(eval_label_index); + /* cppcheck warns that the following statement depends on the order of + evaluation of side effects. Since this isn't my code, and since I don't + think the warning can be eliminated without rewriting it, I am just + supprressing it. + -- Bob Dubner, 2025-07-14 */ + // cppcheck-suppress unknownEvaluationOrder bool has_section = std::any_of( ++eval, symbols_end(), [program = eval->program]( const auto& sym ) { if( program == sym.program && sym.type == SymLabel ) { - auto& L(sym.elem.label); + const auto& L(sym.elem.label); // true if the symbol is an explicit label. return L.type == LblSection && L.name[0] != '_'; } @@ -3877,7 +3891,7 @@ expand_picture(const char *picture) { assert(strlen(picture) < PICTURE_MAX); // guaranteed by picset() in scanner size_t retval_length = PICTURE_MAX; - char *retval = (char *)xmalloc(retval_length); + char *retval = static_cast<char *>(xmalloc(retval_length)); size_t index = 0; int ch; @@ -3906,7 +3920,7 @@ expand_picture(const char *picture) if( index + repeat >= retval_length ) { retval_length <<= 1; - retval = (char *)xrealloc(retval, retval_length); + retval = static_cast<char *>(xrealloc(retval, retval_length)); } while(repeat--) @@ -3919,7 +3933,7 @@ expand_picture(const char *picture) if( index >= retval_length ) { retval_length <<= 1; - retval = (char *)xrealloc(retval, retval_length); + retval = static_cast<char *>(xrealloc(retval, retval_length)); } retval[index++] = ch; } @@ -3928,7 +3942,7 @@ expand_picture(const char *picture) if( index >= retval_length ) { retval_length <<= 1; - retval = (char *)xrealloc(retval, retval_length); + retval = static_cast<char *>(xrealloc(retval, retval_length)); } retval[index++] = '\0'; @@ -3951,7 +3965,6 @@ expand_picture(const char *picture) { pcurrency[i] = 'B'; } - dest_length += sign_length; } } @@ -4182,7 +4195,7 @@ symbol_program_callables( size_t program ) { if( e->type != SymLabel ) continue; if( e->elem.label.type != LblProgram ) continue; - auto prog = cbl_label_of(e); + const cbl_label_t * prog = cbl_label_of(e); if( program == symbol_index(e) && !prog->recursive ) continue; if( (self->parent == prog->parent && prog->common) || @@ -4216,6 +4229,7 @@ symbol_program_local( const char tgt_name[] ) { */ std::map<char, const char *> currencies; +// cppcheck-suppress-begin [nullPointerRedundantCheck] bool symbol_currency_add( const char symbol[], const char sign[] ) { // In service of CURRENCY sign PICTURE SYMBOL symbol @@ -4227,6 +4241,7 @@ symbol_currency_add( const char symbol[], const char sign[] ) { currencies[*symbol] = sign; return true; } +// cppcheck-suppress-end [nullPointerRedundantCheck] const char * symbol_currency( char sign ) { @@ -4234,6 +4249,11 @@ symbol_currency( char sign ) { if( currencies.size() == 0 ) { currencies['$'] = "$"; } + if( sign == '\0' ) { // default + auto result = currencies.begin(); + gcc_assert(result != currencies.end()); + return result->second; + } auto result = currencies.find(sign); return result == currencies.end()? NULL : result->second; } @@ -4249,24 +4269,19 @@ bool decimal_is_comma() { return decimal_point == ','; } /* * A cbl_occurs_key_t is part of a field definition, and comprises * size_t symbol indexes. A cbl_key_t is a list of field pointers, - * and can be created ad hoc to describe a sort. We can construct a + * and can be created ad hoc to describe a sort. We construct a * cbl_key_t from cbl_occurs_key_t. */ cbl_key_t:: cbl_key_t( const cbl_occurs_key_t& that ) : ascending(that.ascending) { - if( that.field_list.nfield == 0 ) { - *this = cbl_key_t(); - return; - } - - nfield = that.field_list.nfield; - fields = static_cast<cbl_field_t**>( xcalloc(nfield, - sizeof(*fields)) ); - for( size_t i=0; i < that.field_list.nfield; i++ ) { - fields[i] = cbl_field_of(symbol_at(that.field_list.fields[i])); - } + std::transform( that.field_list.fields, + that.field_list.fields + that.field_list.nfield, + std::back_inserter(fields), + []( size_t isym ) { + return cbl_field_of(symbol_at(isym)); + } ); } void @@ -4279,7 +4294,7 @@ cbl_occurs_t::key_alloc( bool ascending ) { } void -cbl_occurs_t::field_add( cbl_field_list_t& field_list, cbl_field_t *field ) { +cbl_occurs_t::field_add( cbl_field_list_t& field_list, const cbl_field_t *field ) { cbl_field_list_t list = field_list; size_t ifield = field_index(field); auto nbytes = sizeof(list.fields[0]) * (list.nfield + 1); @@ -4297,14 +4312,14 @@ cbl_occurs_t::key_field_add( cbl_field_t *field ) { } void -cbl_occurs_t::index_add( cbl_field_t *field ) { +cbl_occurs_t::index_add( const cbl_field_t *field ) { field_add(indexes, field); } class is_field_at { cbl_field_t *field; public: - is_field_at( cbl_field_t *field ) : field(field) {} + explicit is_field_at( cbl_field_t *field ) : field(field) {} bool operator()( size_t isym ) const { return field == field_at(isym); } @@ -4347,6 +4362,26 @@ cbl_occurs_t::subscript_ok( const cbl_field_t *subscript ) const { return bounds.lower <= (size_t)sub && (size_t)sub <= bounds.upper; } +const cbl_field_t * +symbol_unresolved_file_key( const cbl_file_t * file, + const cbl_name_t key_field_name ) { + const symbol_elem_t *file_sym = symbol_elem_of(file); + size_t program = file_sym->program; + for( const symbol_elem_t *e = file_sym - 1; e->program == program; e-- ) { + if( e->type == SymFile ) break; + if( e->type == SymField ) { + auto f = cbl_field_of(e); + if( f->type == FldLiteralA ) break; + if( f->type == FldForward ) { + if( 0 == strcmp(key_field_name, f->name) ) { + return f; + } + } + } + } + return nullptr; +} + cbl_file_key_t:: cbl_file_key_t( cbl_name_t name, const std::list<cbl_field_t *>& fields, @@ -4472,11 +4507,11 @@ cbl_file_key_t::deforward( size_t ifile ) { const auto file = cbl_file_of(symbol_at(ifile)); std::transform( fields, fields + nfield, fields, [ifile, file]( size_t fwd ) { - static std::map<size_t, int> keys; auto ifield = symbol_forward_to(fwd); const auto field = cbl_field_of(symbol_at(ifield)); if( is_forward(field) && yydebug ) { + static std::map<size_t, int> keys; dbgmsg("%s:%d: key %d: #" HOST_SIZE_T_PRINT_UNSIGNED " %s of %s is %s", "deforward", __LINE__, keys[ifile]++, (fmt_size_t)ifield, field->name, file->name, @@ -4488,7 +4523,7 @@ cbl_file_key_t::deforward( size_t ifile ) { if( ifield == fwd ) { ERROR_FIELD(field, "line %d: %s of %s " "is not defined", - file->line, field->name, file->name); + field->line, field->name, file->name); return ifield; } @@ -4517,9 +4552,13 @@ cbl_file_key_t::deforward( size_t ifile ) { // looked-up field must have same file as parent if( ! (parent != NULL && symbol_index(symbol_elem_of(parent)) == ifile) ) { - ERROR_FIELD(field, "line %d: %s of %s " - "is not defined in file description", - file->line, field->name, file->name); + const cbl_field_t *undefined = + symbol_unresolved_file_key(file, field->name); + int lineno = undefined? undefined->line : file->line; + ERROR_FIELD(undefined? undefined : field, + "line %d: %s of %s " + "is not defined in file description", + lineno, field->name, file->name); } return ifield; } ); @@ -4563,27 +4602,12 @@ cbl_file_t::deforward() { char * cbl_file_t::keys_str() const { - std::vector <char *> ks(nkey); - std::transform(keys, keys + nkey, ks.begin(), - []( const cbl_file_key_t& key ) { - return key.str(); - } ); - size_t n = 4 * nkey + std::accumulate(ks.begin(), ks.end(), 0, - []( int n, const char *s ) { - return n + strlen(s); - } ); - char *output = static_cast<char*>( xcalloc(1, n) ), *p = output; - const char *sep = ""; - - *p++ = '['; - for( auto k : ks ) { - p = stpcpy(p, sep); - p = stpcpy(p, k); - sep = ", "; - free(k); + std::string names = "["; + for( cbl_file_key_t *p = keys; p < keys + nkey; p++ ) { + names += p->str(); + names += p + 1 < keys + nkey ? "," : "]"; } - *p++ = ']'; - return output; + return xasprintf("%s", names.c_str()); } /* @@ -4645,11 +4669,13 @@ cbl_file_status_cmp( const void *K, const void *E ) { static long file_status_status_of( file_status_t status ) { size_t n = COUNT_OF(file_status_fields); - file_status_field_t *fs, key { status }; - - fs = (file_status_field_t*)lfind( &key, file_status_fields, - &n, sizeof(*fs), cbl_file_status_cmp ); + const file_status_field_t *fs, key { status }; + fs = static_cast<file_status_field_t*>(lfind( &key, + file_status_fields, + &n, + sizeof(*fs), + cbl_file_status_cmp )); return fs? (long)fs->status : -1; } @@ -4675,7 +4701,7 @@ ast_file_status_between( file_status_t lower, file_status_t upper ) { } bool -is_register_field(cbl_field_t *field) +is_register_field(const cbl_field_t *field) { // TRUE when the field is an executable-level global variable of the type we // are calling a "register", like RETURN-CODE or UPSI or the like: diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h index 059d4aa5c7f7..c8ae32f2f605 100644 --- a/gcc/cobol/symbols.h +++ b/gcc/cobol/symbols.h @@ -131,13 +131,13 @@ is_numeric( cbl_field_type_t type ) { case FldIndex: return true; } - yywarn( "%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type ); + cbl_internal_error( "%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type ); return false; } struct os_locale_t { char assumed[16]; - char *codeset; + const char *codeset; }; const char * cbl_field_attr_str( cbl_field_attr_t attr ); @@ -173,7 +173,7 @@ class cbl_domain_elem_t { { if( value && ! is_numeric ) { auto s = consistent_encoding_check(loc, value); - if( s ) value = s; + if( s ) this->value = s; } } const char *name() const { return value; } @@ -264,7 +264,18 @@ struct cbl_field_data_t { explicit etc_t( tree v = build_zero_cst (float128_type_node)) : value(v) {} } etc; - cbl_field_data_t( uint32_t memsize=0, uint32_t capacity=0 ) + cbl_field_data_t() + : memsize(0) + , capacity(0) + , digits(0) + , rdigits(0) + , initial(0) + , picture(0) + , etc_type(value_e) + , etc() + {} + + cbl_field_data_t( uint32_t memsize, uint32_t capacity ) : memsize(memsize) , capacity(capacity) , digits(0) @@ -327,6 +338,10 @@ struct cbl_field_data_t { etc_type = value_e; return etc.value = v; } + tree& operator=(int i) { + etc_type = value_e; + return etc.value = build_int_cst_type(integer_type_node, i); + } void set_real_from_capacity( REAL_VALUE_TYPE *r ) const { real_from_integer (r, VOIDmode, capacity, SIGNED); @@ -412,8 +427,11 @@ struct cbl_occurs_bounds_t { // variable size table. lower can be zero. size_t lower, upper; - cbl_occurs_bounds_t(size_t lower=0, size_t upper=0) + cbl_occurs_bounds_t() + : lower(0), upper(0) {} + explicit cbl_occurs_bounds_t(size_t lower, size_t upper=0) : lower(lower), upper(upper) {} + size_t ntimes() const { return upper; } @@ -446,12 +464,12 @@ struct cbl_occurs_t { void key_alloc( bool ascending ); void key_field_add( cbl_field_t *field ); - void index_add( cbl_field_t *field ); + void index_add( const cbl_field_t *field ); cbl_occurs_key_t * key_of( cbl_field_t *field ); bool subscript_ok( const cbl_field_t *subscript ) const; protected: - void field_add( cbl_field_list_t& fields, cbl_field_t *field ); + void field_add( cbl_field_list_t& fields, const cbl_field_t *field ); }; /* @@ -641,7 +659,7 @@ struct cbl_refer_t; struct cbl_span_t { cbl_refer_t *from, *len; - cbl_span_t( cbl_refer_t *from, cbl_refer_t *len = NULL ) + explicit cbl_span_t( cbl_refer_t *from, cbl_refer_t *len = NULL ) : from(from), len(len) {}; bool is_active() const { return !( from == NULL && len == NULL ); } @@ -655,50 +673,64 @@ struct cbl_refer_t { cbl_field_t *field; cbl_label_t *prog_func; bool all, addr_of; - uint32_t nsubscript; - cbl_refer_t *subscripts; // indices + std::vector<cbl_refer_t> subscripts; // indices cbl_span_t refmod; // substring bounds cbl_refer_t() - : field(NULL), prog_func(NULL) + : loc(), field(NULL), prog_func(NULL) , all(NULL), addr_of(false) - , nsubscript(0), subscripts(NULL), refmod(NULL) + , refmod(NULL) {} + // cppcheck-suppress noExplicitConstructor cbl_refer_t( cbl_field_t *field, bool all = false ) - : field(field), prog_func(NULL) + : loc(), field(field), prog_func(NULL) , all(all), addr_of(false) - , nsubscript(0), subscripts(NULL), refmod(NULL) + , refmod(NULL) {} cbl_refer_t( const YYLTYPE& loc, cbl_field_t *field, bool all = false ) : loc(loc), field(field), prog_func(NULL) , all(all), addr_of(false) - , nsubscript(0), subscripts(NULL), refmod(NULL) + , refmod(NULL) {} cbl_refer_t( cbl_field_t *field, cbl_span_t& refmod ) - : field(field), prog_func(NULL) + : loc(), field(field), prog_func(NULL) , all(false), addr_of(false) - , nsubscript(0), subscripts(NULL), refmod(refmod) + , refmod(refmod) {} cbl_refer_t( cbl_field_t *field, - size_t nsubscript, cbl_refer_t *subscripts, + const std::vector<cbl_refer_t>& subscripts, cbl_span_t refmod = cbl_span_t(NULL) ) - : field(field), prog_func(NULL) + : loc(), field(field), prog_func(NULL) , all(false), addr_of(false) - , nsubscript(nsubscript) , subscripts( new cbl_refer_t[nsubscript] ) + , subscripts(subscripts) , refmod(refmod) - { - std::copy(subscripts, subscripts + nsubscript, this->subscripts); - } + {} explicit cbl_refer_t( cbl_label_t *prog_func, bool addr_of = true ) - : field(NULL), prog_func(prog_func) + : loc(), field(NULL), prog_func(prog_func) , all(false), addr_of(addr_of) - , nsubscript(0), subscripts(NULL), refmod(cbl_span_t(NULL)) + , refmod(cbl_span_t(NULL)) {} + cbl_refer_t( const cbl_refer_t& that ) = default; + + cbl_refer_t& operator=( const cbl_refer_t& that ) { + loc = that.loc; + field = that.field; + prog_func = that.prog_func; + all = that.all; + addr_of = that.addr_of; + subscripts = that.subscripts; + refmod = that.refmod; + return *this; + } + + cbl_refer_t duplicate() const { - return cbl_refer_t( field, nsubscript, subscripts, refmod ); + return cbl_refer_t( field, subscripts, refmod ); } + uint32_t nsubscript() const { return subscripts.size(); } + static cbl_refer_t *empty(); cbl_refer_t * name( const char name[] ) { @@ -709,8 +741,8 @@ struct cbl_refer_t { } bool is_pointer() const { return addr_of || field->type == FldPointer; } - bool is_reference() const { return nsubscript > 0 || refmod.is_active(); } - bool is_table_reference() const { return nsubscript > 0; } + bool is_reference() const { return nsubscript() > 0 || refmod.is_active(); } + bool is_table_reference() const { return nsubscript() > 0; } bool is_refmod_reference() const { return refmod.is_active(); } size_t subscripts_set( const std::list<cbl_refer_t>& subs ); @@ -775,7 +807,7 @@ struct field_key_t { } }; -bool valid_move( const struct cbl_field_t *tgt, const struct cbl_field_t *src ); +bool valid_move( const cbl_field_t *tgt, const cbl_field_t *src ); #define record_area_name_stem "_ra_" @@ -785,8 +817,7 @@ is_record_area( const cbl_field_t *field ) { return 0 == memcmp(field->name, stem, sizeof(stem)-1); } -bool -is_register_field(cbl_field_t *field); +bool is_register_field( const cbl_field_t *field ); static inline bool is_constant( const cbl_field_t *field ) { @@ -804,17 +835,20 @@ symbol_field_type_update( cbl_field_t *field, cbl_field_type_t type, bool is_usage ); struct sort_key_t; +struct sort_key_t; struct cbl_key_t { bool ascending; - size_t nfield; - cbl_field_t **fields; + std::vector<const cbl_field_t*> fields; - cbl_key_t() : ascending(false), nfield(0), fields(0) {} - cbl_key_t( size_t nfield, cbl_field_t **fields, bool ascending = true ) - : ascending(ascending), nfield(nfield), fields(fields) {} - cbl_key_t( const sort_key_t& src ); + cbl_key_t() : ascending(true) {} + explicit cbl_key_t( sort_key_t src ); explicit cbl_key_t( const cbl_occurs_key_t& that ); + cbl_key_t( size_t nfield, cbl_field_t **fields, bool ascending = true ) + : ascending(ascending) + , fields(fields, fields + nfield) + {} + cbl_key_t& operator=( const sort_key_t& that ); }; enum cbl_label_type_t { @@ -911,8 +945,12 @@ struct cbl_substitute_t { subst_fl_t first_last; cbl_refer_t orig, replacement; - cbl_substitute_t( bool anycase = false, char first_last = 0, - cbl_refer_t *orig = NULL, cbl_refer_t *replacement = NULL ) + cbl_substitute_t() + : anycase(false) + , first_last(subst_all_e) + {} + cbl_substitute_t( bool anycase, char first_last, + cbl_refer_t *orig, cbl_refer_t *replacement ) : anycase(anycase) , first_last(subst_fl_t(first_last)) , orig( orig? *orig : cbl_refer_t() ) @@ -945,7 +983,10 @@ struct cbl_num_result_t { enum cbl_round_t rounded; struct cbl_refer_t refer; - static cbl_refer_t refer_of( const cbl_num_result_t& res ) { return res.refer; } + static const cbl_refer_t& + refer_of( const cbl_num_result_t& res ) { + return res.refer; + } }; void parser_symbol_add( struct cbl_field_t *new_var ); @@ -957,8 +998,9 @@ struct cbl_ffi_arg_t { cbl_ffi_arg_attr_t attr; cbl_refer_t refer; // refer::field == NULL is OMITTED - cbl_ffi_arg_t( cbl_refer_t* refer = NULL, - cbl_ffi_arg_attr_t attr = none_of_e ); + cbl_ffi_arg_t(); + cbl_ffi_arg_t( cbl_refer_t* refer, + cbl_ffi_arg_attr_t attr ); cbl_ffi_arg_t( cbl_ffi_crv_t crv, cbl_refer_t* refer, cbl_ffi_arg_attr_t attr = none_of_e ); @@ -1171,8 +1213,11 @@ class temporaries_t { struct literal_an { bool is_quoted; std::string value; - literal_an( const char value[] = "???", bool is_quoted = false ) + literal_an() : is_quoted(false), value("???") {} + literal_an( const char value[], bool is_quoted ) : is_quoted(is_quoted), value(value) {} + literal_an( const literal_an& that ) + : is_quoted(that.is_quoted), value(that.value) {} literal_an& operator=( const literal_an& that ) { is_quoted = that.is_quoted; value = that.value; @@ -1419,10 +1464,10 @@ struct cbl_alphabet_t { add_sequence( const YYLTYPE& loc, const unsigned char seq[] ) { if( low_index == 0 ) low_index = seq[0]; - unsigned char high_value = last_index > 0? alphabet[last_index] + 1 : 0; + unsigned char last = last_index > 0? alphabet[last_index] + 1 : 0; for( const unsigned char *p = seq; !end_of_string(p); p++ ) { - assign(loc, *p, high_value++); + assign(loc, *p, last++); } } @@ -1430,10 +1475,10 @@ struct cbl_alphabet_t { add_interval( const YYLTYPE& loc, unsigned char low, unsigned char high ) { if( low_index == 0 ) low_index = low; - unsigned char high_value = alphabet[last_index]; + unsigned char last = alphabet[last_index]; for( unsigned char ch = low; ch < high; ch++ ) { - assign(loc, ch, high_value++); + assign(loc, ch, last++); } } @@ -1452,7 +1497,7 @@ struct cbl_alphabet_t { } void dump() const { - yywarn("'%s': %s, '%c' to '%c' (low 0x%02x, high 0x%02x)", + yywarn("%qs: %s, %<%c%> to %<%c%> (low 0x%x, high 0x%x)", name, encoding_str(encoding), low_index, last_index, low_index, high_index); if( encoding == custom_encoding_e ) { @@ -1513,9 +1558,19 @@ struct cbl_file_key_t { cbl_name_t name; size_t leftmost; // START or READ named leftmost field in key size_t nfield; - size_t *fields; + size_t *fields; // cppcheck-suppress unsafeClassCanLeak + + cbl_file_key_t() + : unique(true) + , leftmost(0) + , nfield(0) + , fields(nullptr) + { + memset(name, '\0', sizeof(name)); + } - cbl_file_key_t( size_t field = 0, bool unique = true ) + // Construct a key of length 1 having a single field. + explicit cbl_file_key_t( size_t field, bool unique = true ) : unique(unique) , leftmost(0) , nfield(1) @@ -1524,20 +1579,34 @@ struct cbl_file_key_t { fields[0] = field; memset(name, '\0', sizeof(name)); } - cbl_file_key_t( const cbl_file_key_t *that ) - : unique(that->unique) - , leftmost(that->leftmost) - , nfield(that->nfield) - { - memcpy(name, that->name, sizeof(name)); - fields = new size_t[nfield]; - std::copy( that->fields, that->fields + that->nfield, fields ); - } cbl_file_key_t( cbl_name_t name, const std::list<cbl_field_t *>& fields, bool is_unique ); + // The copy constructor and assignment operator exist to quell reports from + // cppcheck. When these objects are copied, the copy still points to the + // original data. + cbl_file_key_t( const cbl_file_key_t& that ) + : unique(that.unique) + , leftmost(that.leftmost) + , nfield(that.nfield) + // cppcheck-suppress copyCtorPointerCopying + , fields(that.fields) + { + strcpy(name, that.name); + } + ~cbl_file_key_t() {} + cbl_file_key_t& operator=( const cbl_file_key_t& that ) { + unique = that.unique; + leftmost = that.leftmost; + nfield = that.nfield; + // cppcheck-suppress copyCtorPointerCopying + fields = that.fields; + strcpy(name, that.name); + return *this; + } + uint32_t size(); void deforward( size_t ifile ); char * str() const; @@ -1551,12 +1620,12 @@ struct cbl_file_key_t { struct cbl_file_lock_t { bool multiple; enum lock_mode_t { unlocked_e, manual_e, record_e, automatic_e } mode; + cbl_file_lock_t() : multiple(false), mode(unlocked_e) {} bool mode_set( int token ); bool locked() const { return mode != unlocked_e; } }; struct cbl_file_t { - static cbl_file_key_t no_key; enum cbl_file_org_t org; enum file_entry_type_t entry_type; uint32_t attr; @@ -1583,15 +1652,32 @@ struct cbl_file_t { tree var_decl_node; // GENERIC tag for the run-time FIELD structure cbl_file_t() - : org(file_disorganized_e), - access(file_access_seq_e) + : org(file_disorganized_e) + , entry_type(fd_e) + , attr(0), reserve(0), same_record_as(0) + , padding('\0') + , optional(false) + , varying_size{ false, 0, 0 } + , access(file_access_seq_e) + , filename(0) + , default_record(0) + , nkey(0) + , keys(nullptr) + , password(0), user_status(0), vsam_status(0), record_length(0) + , line(0) + , addresses(nullptr) + , var_decl_node(nullptr) { - keys = &no_key; + memset(name, '\0', sizeof(name)); } bool varies() const { return varying_size.min != varying_size.max; } bool validate() const; void deforward(); + cbl_file_key_t * keys_update( cbl_file_key_t * keys ) { + if( this->keys ) delete[] this->keys; + return this->keys = keys; + } char * keys_str() const; int key_one( cbl_field_t *field ) const { auto ekey = keys + nkey, p = ekey; @@ -1636,13 +1722,11 @@ struct symbol_elem_t { cbl_alphabet_t alphabet; cbl_file_t file; cbl_section_t section; - symbol_elem_u() { - static const cbl_field_t empty = {}; - field = empty; - } + symbol_elem_u() : field() {} } elem; - symbol_elem_t( symbol_type_t type = SymField, size_t program = 0 ) + symbol_elem_t() : type(SymField), program(0) {} + explicit symbol_elem_t( symbol_type_t type, size_t program = 0 ) : type(type), program(program) {} @@ -1712,6 +1796,7 @@ static inline symbol_elem_t * symbol_elem_of( cbl_label_t *label ) { size_t n = offsetof(struct symbol_elem_t, elem.label); return + // cppcheck-suppress cstyleCast reinterpret_cast<struct symbol_elem_t *>((char*)label - n); } @@ -1719,6 +1804,7 @@ static inline const symbol_elem_t * symbol_elem_of( const cbl_label_t *label ) { size_t n = offsetof(symbol_elem_t, elem.label); return + // cppcheck-suppress cstyleCast reinterpret_cast<const symbol_elem_t *>((const char*)label - n); } @@ -1726,6 +1812,7 @@ static inline symbol_elem_t * symbol_elem_of( cbl_special_name_t *special ) { size_t n = offsetof(symbol_elem_t, elem.special); return + // cppcheck-suppress cstyleCast reinterpret_cast<symbol_elem_t *>((char*)special - n); } @@ -1733,6 +1820,7 @@ static inline symbol_elem_t * symbol_elem_of( cbl_alphabet_t *alphabet ) { size_t n = offsetof(symbol_elem_t, elem.alphabet); return + // cppcheck-suppress cstyleCast reinterpret_cast<symbol_elem_t *>((char*)alphabet - n); } @@ -1740,12 +1828,14 @@ static inline symbol_elem_t * symbol_elem_of( cbl_file_t *file ) { size_t n = offsetof(struct symbol_elem_t, elem.file); return + // cppcheck-suppress cstyleCast reinterpret_cast<struct symbol_elem_t *>((char*)file - n); } static inline const symbol_elem_t * symbol_elem_of( const cbl_file_t *file ) { size_t n = offsetof(symbol_elem_t, elem.file); return + // cppcheck-suppress cstyleCast reinterpret_cast<const symbol_elem_t *>((const char*)file - n); } @@ -1753,18 +1843,20 @@ static inline symbol_elem_t * symbol_elem_of( cbl_field_t *field ) { size_t n = offsetof(struct symbol_elem_t, elem.field); return + // cppcheck-suppress cstyleCast reinterpret_cast<struct symbol_elem_t *>((char*)field - n); } static inline const symbol_elem_t * symbol_elem_of( const cbl_field_t *field ) { size_t n = offsetof(symbol_elem_t, elem.field); return + // cppcheck-suppress cstyleCast reinterpret_cast<const symbol_elem_t *>((const char*)field - n); } symbol_elem_t * symbols_begin( size_t first = 0 ); symbol_elem_t * symbols_end(void); -cbl_field_t * symbol_redefines( const struct cbl_field_t *field ); +cbl_field_t * symbol_redefines( const cbl_field_t *field ); void build_symbol_map(); bool update_symbol_map( symbol_elem_t *e ); @@ -1780,7 +1872,7 @@ symbol_find( size_t program, std::list<const char *> names ); symbol_elem_t * symbol_find_of( size_t program, std::list<const char *> names, size_t group ); -struct cbl_field_t *symbol_find_odo( cbl_field_t * field ); +struct cbl_field_t *symbol_find_odo( const cbl_field_t * field ); size_t dimensions( const cbl_field_t *field ); const symbol_elem_t * symbol_field_current_record(); @@ -1802,56 +1894,60 @@ const cbl_label_t * symbol_program_local( const char called[] ); bool redefine_field( cbl_field_t *field ); +const cbl_field_t * +symbol_unresolved_file_key( const cbl_file_t * file, + const cbl_name_t key_field_name ); + static inline struct cbl_section_t * cbl_section_of( struct symbol_elem_t *e ) { - assert(e->type == SymDataSection); + assert(e && e->type == SymDataSection); return &e->elem.section; } static inline struct cbl_field_t * cbl_field_of( struct symbol_elem_t *e ) { - assert(e->type == SymField); + assert(e && e->type == SymField); return &e->elem.field; } -static inline const struct cbl_field_t * -cbl_field_of( const struct symbol_elem_t *e ) { - assert(e->type == SymField); +static inline const cbl_field_t * +cbl_field_of( const symbol_elem_t *e ) { + assert(e && e->type == SymField); return &e->elem.field; } static inline struct cbl_label_t * cbl_label_of( struct symbol_elem_t *e ) { - assert(e->type == SymLabel); + assert(e && e->type == SymLabel); return &e->elem.label; } -static inline const struct cbl_label_t * -cbl_label_of( const struct symbol_elem_t *e ) { - assert(e->type == SymLabel); +static inline const cbl_label_t * +cbl_label_of( const symbol_elem_t *e ) { + assert(e && e->type == SymLabel); return &e->elem.label; } static inline struct cbl_special_name_t * cbl_special_name_of( struct symbol_elem_t *e ) { - assert(e->type == SymSpecial); + assert(e && e->type == SymSpecial); return &e->elem.special; } static inline struct cbl_alphabet_t * cbl_alphabet_of( struct symbol_elem_t *e ) { - assert(e->type == SymAlphabet); + assert(e && e->type == SymAlphabet); return &e->elem.alphabet; } static inline struct cbl_file_t * cbl_file_of( struct symbol_elem_t *e ) { - assert(e->type == SymFile); + assert(e && e->type == SymFile); return &e->elem.file; } -static inline const struct cbl_file_t * -cbl_file_of( const struct symbol_elem_t *e ) { - assert(e->type == SymFile); +static inline const cbl_file_t * +cbl_file_of( const symbol_elem_t *e ) { + assert(e && e->type == SymFile); return &e->elem.file; } @@ -1870,43 +1966,43 @@ is_procedure( const symbol_elem_t& e ) { } static inline bool -is_figconst(const struct cbl_field_t *field ) { - return ((field->attr & FIGCONST_MASK) != 0 ); +is_figconst(const cbl_field_t *field ) { + return (field->attr & FIGCONST_MASK) != 0; } static inline bool -is_figconst_low( const struct cbl_field_t *field ) { - return ((field->attr & FIGCONST_MASK) == low_value_e ); +is_figconst_low( const cbl_field_t *field ) { + return (field->attr & FIGCONST_MASK) == low_value_e; } static inline bool -is_figconst_zero( const struct cbl_field_t *field ) { - return ((field->attr & FIGCONST_MASK) == zero_value_e ); +is_figconst_zero( const cbl_field_t *field ) { + return (field->attr & FIGCONST_MASK) == zero_value_e; } static inline bool -is_figconst_space( const struct cbl_field_t *field ) { - return ((field->attr & FIGCONST_MASK) == space_value_e ); +is_figconst_space( const cbl_field_t *field ) { + return (field->attr & FIGCONST_MASK) == space_value_e; } static inline bool -is_figconst_quote( const struct cbl_field_t *field ) { - return ((field->attr & FIGCONST_MASK) == quote_value_e ); +is_figconst_quote( const cbl_field_t *field ) { + return (field->attr & FIGCONST_MASK) == quote_value_e; } static inline bool -is_figconst_high( const struct cbl_field_t *field ) { - return ((field->attr & FIGCONST_MASK) == high_value_e ); +is_figconst_high( const cbl_field_t *field ) { + return (field->attr & FIGCONST_MASK) == high_value_e; } static inline bool -is_space_value( const struct cbl_field_t *field ) { - return( (strcmp(field->name, "SPACE") == 0) - || (strcmp(field->name, "SPACES") == 0) ); +is_space_value( const cbl_field_t *field ) { + return (strcmp(field->name, "SPACE") == 0) + || (strcmp(field->name, "SPACES") == 0); } static inline bool -is_quoted( const struct cbl_field_t *field ) { +is_quoted( const cbl_field_t *field ) { return field->has_attr(quoted_e); } @@ -1926,7 +2022,7 @@ struct cbl_until_addresses_t { struct cbl_label_addresses_t test; // The test at the bottom of the body struct cbl_label_addresses_t testA; // Starting point of a TEST_AFTER loop struct cbl_label_addresses_t setup; // The actual entry point - size_t number_of_conditionals; + unsigned int number_of_conditionals; struct cbl_label_addresses_t condover[MAXIMUM_UNTILS]; // Jumping over the conditional struct cbl_label_addresses_t condinto[MAXIMUM_UNTILS]; // Jumping into the conditional struct cbl_label_addresses_t condback[MAXIMUM_UNTILS]; // Jumping back from the conditional @@ -1934,7 +2030,7 @@ struct cbl_until_addresses_t { }; size_t symbol_index(); // nth after first program symbol -size_t symbol_index( const struct symbol_elem_t *e ); +size_t symbol_index( const symbol_elem_t *e ); struct symbol_elem_t * symbol_at( size_t index ); struct cbl_options_t { @@ -1986,17 +2082,20 @@ symbol_field_forward_add( size_t program, size_t parent, struct cbl_field_t * symbol_field_forward( size_t index ); struct cbl_prog_hier_t { - size_t nlabel; struct program_label_t { size_t ordinal; cbl_label_t label; - program_label_t() : ordinal(0) {} - program_label_t( const symbol_elem_t& e ) { + program_label_t() : ordinal(0), label() {} + // because std::copy_if: + // cppcheck-suppress noExplicitConstructor + program_label_t( const symbol_elem_t& e ) { + assert(is_program(e)); ordinal = symbol_index(&e); label = e.elem.label; } - } *labels; - + }; + std::vector<program_label_t> labels; + cbl_prog_hier_t(); }; @@ -2008,13 +2107,11 @@ struct cbl_prog_hier_t { struct cbl_perform_tgt_t { struct cbl_until_addresses_t addresses; - cbl_perform_tgt_t() : ifrom(0), ito(0) {} - cbl_perform_tgt_t( cbl_label_t * from, cbl_label_t *to = NULL ) - : ifrom( from? symbol_index(symbol_elem_of(from)) : 0 ) + cbl_perform_tgt_t() : addresses(), ifrom(0), ito(0) {} + explicit cbl_perform_tgt_t( cbl_label_t * from, cbl_label_t *to = NULL ) + : addresses(), ifrom( from? symbol_index(symbol_elem_of(from)) : 0 ) , ito( to? symbol_index(symbol_elem_of(to)) : 0 ) - { - addresses = {}; - } + {} cbl_label_t * from( cbl_label_t * label ) { ifrom = symbol_index(symbol_elem_of(label)); @@ -2052,10 +2149,11 @@ struct cbl_perform_vary_t { struct cbl_refer_t by; // numeric struct cbl_field_t *until; // FldConditional - cbl_perform_vary_t( const cbl_refer_t& varying = cbl_refer_t(), - const cbl_refer_t& from = cbl_refer_t(), - const cbl_refer_t& by = cbl_refer_t(), - cbl_field_t *until = NULL ) + cbl_perform_vary_t() : until(nullptr) {} + cbl_perform_vary_t( const cbl_refer_t& varying, + const cbl_refer_t& from, + const cbl_refer_t& by, + cbl_field_t *until ) : varying(varying) , from(from) , by(by) @@ -2077,12 +2175,12 @@ is_literal( const cbl_field_t *field ) { } static inline bool -is_signable( const struct cbl_field_t *field ) { +is_signable( const cbl_field_t *field ) { return field->attr & signable_e; } static inline bool -is_temporary( const struct cbl_field_t *field ) { +is_temporary( const cbl_field_t *field ) { return field->attr & intermediate_e; } @@ -2103,7 +2201,7 @@ is_numeric( const cbl_field_t *field ) { bool cobol_filename( const char *name ); const char * cobol_filename(); -const char * cobol_fileline_set( const char line[] ); +int cobol_fileline_set( const char line[] ); char *cobol_name_mangler(const char *cobol_name); @@ -2217,7 +2315,7 @@ struct symbol_elem_t * symbol_special( size_t program, const char name[] ); struct symbol_elem_t * symbol_alphabet( size_t program, const char name[] ); struct symbol_elem_t * symbol_file( size_t program, const char name[] ); -struct cbl_field_t * symbol_file_record( struct cbl_file_t *file ); +struct cbl_field_t * symbol_file_record( const cbl_file_t *file ); cbl_file_t::varying_t symbol_file_record_sizes( struct cbl_file_t *file ); struct cbl_section_t * symbol_section( size_t program, struct cbl_section_t *section ); @@ -2227,7 +2325,7 @@ size_t symbol_label_id( const cbl_label_t *label ); struct cbl_field_t * parent_of( const cbl_field_t *f ); const cbl_field_t * occurs_in( const cbl_field_t *f ); -cbl_field_t *rename_not_ok( cbl_field_t *first, cbl_field_t *last); +cbl_field_t *rename_not_ok( const cbl_field_t *first, const cbl_field_t *last); bool immediately_follows( const cbl_field_t *first ); bool is_variable_length( const cbl_field_t *field ); @@ -2240,7 +2338,7 @@ uint64_t numeric_group_attrs( const cbl_field_t *field ); static inline struct cbl_field_t * field_at( size_t index ) { struct symbol_elem_t *e = symbol_at(index); - assert(e->type == SymField); + assert(e && e->type == SymField); return &e->elem.field; } @@ -2252,21 +2350,21 @@ size_t symbols_update( size_t first, bool parsed_ok = true ); void symbol_table_init(void); void symbol_table_check(void); -struct symbol_elem_t * symbol_typedef_add( size_t program, - struct cbl_field_t *field ); -struct symbol_elem_t * symbol_field_add( size_t program, - struct cbl_field_t *field ); -struct cbl_label_t * symbol_label_add( size_t program, - struct cbl_label_t *label ); -struct cbl_label_t * symbol_program_add( size_t program, cbl_label_t *input ); -struct symbol_elem_t * symbol_special_add( size_t program, - struct cbl_special_name_t *special ); -struct symbol_elem_t * symbol_alphabet_add( size_t program, - struct cbl_alphabet_t *alphabet ); -struct symbol_elem_t * symbol_file_add( size_t program, - struct cbl_file_t *file ); -struct symbol_elem_t * symbol_section_add( size_t program, - struct cbl_section_t *section ); +symbol_elem_t * symbol_typedef_add( size_t program, + cbl_field_t *field ); +symbol_elem_t * symbol_field_add( size_t program, + cbl_field_t *field ); +cbl_label_t * symbol_label_add( size_t program, + cbl_label_t *label ); +cbl_label_t * symbol_program_add( size_t program, cbl_label_t *input ); +symbol_elem_t * symbol_special_add( size_t program, + cbl_special_name_t *special ); +symbol_elem_t * symbol_alphabet_add( size_t program, + const cbl_alphabet_t *alphabet ); +symbol_elem_t * symbol_file_add( size_t program, + cbl_file_t *file ); +symbol_elem_t * symbol_section_add( size_t program, + cbl_section_t *section ); void symbol_field_location( size_t ifield, const YYLTYPE& loc ); YYLTYPE symbol_field_location( size_t ifield ); @@ -2293,17 +2391,178 @@ enum cbl_call_convention_t { cbl_call_cobol_e = 'N', // native }; +int keyword_tok( const char * text, bool include_intrinsics = false ); +int redefined_token( const cbl_name_t name ); + +class current_tokens_t { + class tokenset_t { + // token_names is initialized from a generated header file. + std::vector<const char *>token_names; // position indicates token value + std::map <std::string, int> tokens; // aliases + std::set<std::string> cobol_words; // Anything in COBOL-WORDS may appear only once. + public: + static std::string + lowercase( const cbl_name_t name ) { + cbl_name_t lname; + std::transform(name, name + strlen(name) + 1, lname, ftolower); + return lname; + } + static std::string + uppercase( const cbl_name_t name ) { + cbl_name_t uname; + std::transform(name, name + strlen(name) + 1, uname, ftoupper); + return uname; + } + + public: + tokenset_t(); + int find( const cbl_name_t name, bool include_intrinsics ); + + bool equate( const YYLTYPE& loc, int token, + const cbl_name_t name, const cbl_name_t verb = "EQUATE") { + auto lname( lowercase(name) ); + auto cw = cobol_words.insert(lname); + if( ! cw.second ) { + error_msg(loc, "COBOL-WORDS %s: %s may appear but once", verb, name); + return false; + } + auto p = tokens.find(lowercase(name)); + bool fOK = p == tokens.end(); + if( fOK ) { // name not already in use + tokens[lname] = token; + dbgmsg("%s:%d: %d has alias %s", __func__, __LINE__, token, name); + } else { + error_msg(loc, "%s: %s already defined as a token", verb, name); + } + return fOK; + } + bool undefine( const YYLTYPE& loc, + const cbl_name_t name, const cbl_name_t verb = "UNDEFINE" ) { + auto lname( lowercase(name) ); + auto cw = cobol_words.insert(lname); + if( ! cw.second ) { + error_msg(loc, "COBOL-WORDS %s: %s may appear but once", verb, name); + return false; + } + + // Do not erase generic, multi-type tokens COMPUTATIONAL and BINARY_INTEGER. + if( binary_integer_usage_of(name) ) { + dbgmsg("%s:%d: generic %s remains valid as a token", __func__, __LINE__, name); + return true; + } + + auto p = tokens.find(lname); + bool fOK = p != tokens.end(); + if( fOK ) { // name in use + tokens.erase(p); + } else { + error_msg(loc, "%s: %s not defined as a token", verb, name); + } + dbgmsg("%s:%d: %s removed as a valid token name", __func__, __LINE__, name); + return fOK; + } + + bool substitute( const YYLTYPE& loc, + const cbl_name_t extant, int token, const cbl_name_t name ) { + return + equate( loc, token, name, "SUBSTITUTE" ) + && + undefine( loc, extant, "SUBSTITUTE" ); + } + bool reserve( const YYLTYPE& loc, const cbl_name_t name ) { + auto lname( lowercase(name) ); + auto cw = cobol_words.insert(lname); + if( ! cw.second ) { + error_msg(loc, "COBOL-WORDS RESERVE: %s may appear but once", name); + return false; + } + tokens[lname] = -42; + return true; + } + int redefined_as( const cbl_name_t name ) { + auto lname( lowercase(name) ); + if( cobol_words.find(lname) != cobol_words.end() ) { + auto p = tokens.find(lname); + if( p != tokens.end() ) { + return p->second; + } + } + return 0; + } + const char * name_of( int tok ) const { + tok -= (255 + 3); + gcc_assert(0 <= tok && size_t(tok) < token_names.size()); + return tok < 0? "???" : token_names[tok]; + } + }; + + tokenset_t tokens; + public: + current_tokens_t() {} + int find( const cbl_name_t name, bool include_intrinsics ) { + return tokens.find(name, include_intrinsics); + } + bool equate( const YYLTYPE& loc, const cbl_name_t keyword, const cbl_name_t alias ) { + int token; + if( 0 == (token = binary_integer_usage_of(keyword)) ) { + if( 0 == (token = keyword_tok(keyword)) ) { + error_msg(loc, "EQUATE %s: not a valid token", keyword); + return false; + } + } + auto name = keyword_alias_add(tokens.uppercase(keyword), + tokens.uppercase(alias)); + if( name != keyword ) { + error_msg(loc, "EQUATE: %s is already an alias for %s", alias, name.c_str()); + return false; + } + return tokens.equate(loc, token, alias); + } + bool undefine( const YYLTYPE& loc, cbl_name_t keyword ) { + return tokens.undefine(loc, keyword); + } + bool substitute( const YYLTYPE& loc, const cbl_name_t keyword, const cbl_name_t alias ) { + int token; + if( 0 == (token = binary_integer_usage_of(keyword)) ) { + if( 0 == (token = keyword_tok(keyword)) ) { + error_msg(loc, "SUBSTITUTE %s: not a valid token", keyword); + return false; + } + } + auto name = keyword_alias_add(tokens.uppercase(keyword), + tokens.uppercase(alias)); + if( name != keyword ) { + error_msg(loc, "SUBSTITUTE: %s is already an alias for %s", alias, name.c_str()); + return false; + } + + dbgmsg("%s:%d: %s (%d) will have alias %s", __func__, __LINE__, keyword, token, alias); + return tokens.substitute(loc, keyword, token, alias); + } + bool reserve( const YYLTYPE& loc, const cbl_name_t name ) { + return tokens.reserve(loc, name); + } + int redefined_as( const cbl_name_t name ) { + return tokens.redefined_as(name); + } + const char * name_of( int tok ) const { + return tokens.name_of(tok); + } +}; + cbl_call_convention_t current_call_convention(); +current_tokens_t& cdf_current_tokens(); -cbl_call_convention_t +void current_call_convention( cbl_call_convention_t convention); class procref_base_t { private: const char *section_name, *paragraph_name; public: - procref_base_t( const char *section_name = NULL, - const char *paragraph_name = NULL ) + procref_base_t() : section_name(nullptr) , paragraph_name(nullptr) {} + procref_base_t( const char *section_name, + const char *paragraph_name ) : section_name(section_name) , paragraph_name(paragraph_name) {} @@ -2338,9 +2597,6 @@ class procref_t : public procref_base_t { int line_number() const { return line; } }; -int keyword_tok( const char * text, bool include_intrinsics = false ); -int redefined_token( const cbl_name_t name ); - void procedure_definition_add( size_t program, const cbl_label_t *procedure ); void procedure_reference_add( const char *sect, const char *para, int line, size_t context ); @@ -2357,7 +2613,7 @@ symbol_field_same_as( cbl_field_t *tgt, const cbl_field_t *src ); size_t symbol_file_same_record_area( std::list<cbl_file_t*>& files ); bool symbol_currency_add( const char symbol[], const char sign[] = NULL ); -const char * symbol_currency( char symbol ); +const char * symbol_currency( char symbol = '\0' ); const char * symbol_type_str( enum symbol_type_t type ); const char * cbl_field_type_str( enum cbl_field_type_t type ); @@ -2370,7 +2626,7 @@ refer_type_str( const cbl_refer_t *r ) { enum cbl_field_type_t symbol_field_type( size_t program, const char name[] ); -struct symbol_elem_t * symbol_parent( const struct symbol_elem_t *e ); +struct symbol_elem_t * symbol_parent( const symbol_elem_t *e ); int length_of_picture(const char *picture); int rdigits_of_picture(const char *picture); diff --git a/gcc/cobol/symfind.cc b/gcc/cobol/symfind.cc index b4b1b3a1c3ba..8141b2206e6f 100644 --- a/gcc/cobol/symfind.cc +++ b/gcc/cobol/symfind.cc @@ -48,7 +48,7 @@ extern int yydebug; static bool is_data_field( symbol_elem_t& e ) { if( e.type != SymField ) return false; - auto f = cbl_field_of(&e); + const cbl_field_t *f = cbl_field_of(&e); if( f->name[0] == '\0' ) return false; if( is_filler(f) ) return false; @@ -129,7 +129,7 @@ finalize_symbol_map2() { for( auto& elem : symbol_map2 ) { auto& fields( elem.second ); fields.remove_if( []( auto isym ) { - auto f = cbl_field_of(symbol_at(isym)); + const cbl_field_t *f = cbl_field_of(symbol_at(isym)); return f->type == FldInvalid; } ); if( fields.empty() ) empties.insert(elem.first); @@ -275,8 +275,8 @@ update_symbol_map( symbol_elem_t *e ) { class is_name { const char *name; public: - is_name( const char *name ) : name(name) {} - bool operator()( symbol_map_t::value_type& elem ) { + explicit is_name( const char *name ) : name(name) {} + bool operator()( const symbol_map_t::value_type& elem ) { const bool tf = elem.first == name; return tf; } @@ -298,7 +298,7 @@ class reduce_ancestry { static symbol_map_t::mapped_type candidates_only( const symbol_map_t::value_type& elem ) { return elem.second; } public: - reduce_ancestry( const symbol_map_t& groups ) + explicit reduce_ancestry( const symbol_map_t& groups ) : candidates( groups.size() ) { std::transform( groups.begin(), groups.end(), candidates.begin(), @@ -316,9 +316,9 @@ class reduce_ancestry { if( p != item.second.end() ) { // Preserve symbol's index at front of ancestor list. symbol_map_t::mapped_type shorter(1 + ancestors->size()); - auto p = shorter.begin(); - *p = item.second.front(); - shorter.insert( ++p, ancestors->begin(), ancestors->end() ); + auto p_l = shorter.begin(); + *p_l = item.second.front(); + shorter.insert( ++p_l, ancestors->begin(), ancestors->end() ); return make_pair(item.first, shorter); } } @@ -331,7 +331,7 @@ class reduce_ancestry { class different_program { size_t program; public: - different_program( size_t program ) : program(program) {} + explicit different_program( size_t program ) : program(program) {} bool operator()( const symbol_map_t::value_type& item ) const { return ! item.first.same_program(program); } @@ -341,16 +341,16 @@ class in_scope { size_t program; static size_t prog_of( size_t program ) { - auto L = cbl_label_of(symbol_at(program)); + const cbl_label_t *L = cbl_label_of(symbol_at(program)); return L->parent; } public: - in_scope( size_t program ) : program(program) {} + explicit in_scope( size_t program ) : program(program) {} // A symbol is in scope if it's defined by this program or by an ancestor. bool operator()( const symbol_map_t::value_type& item ) const { - symbol_elem_t *e = symbol_at(item.second.front()); + const symbol_elem_t *e = symbol_at(item.second.front()); for( size_t prog = this->program; prog != 0; prog = prog_of(prog) ) { if( e->program == prog ) return true; } @@ -430,7 +430,7 @@ symbol_match2( size_t program, auto plist = symbol_map2.find(key); if( plist != symbol_map2.end() ) { for( auto candidate : plist->second ) { - auto e = symbol_at(candidate); + const symbol_elem_t *e = symbol_at(candidate); if( name_has_names( e, names, local ) ) { fields.push_back( symbol_index(e) ); } @@ -504,7 +504,7 @@ symbol_match( size_t program, const std::list<const char *>& names ) { } auto inserted = output.insert(*p); if( ! inserted.second ) { - yyerror("%s is not a unique reference", key.name); + error_msg_direct("%s is not a unique reference", key.name); } } return output; @@ -561,7 +561,7 @@ symbol_find( size_t program, std::list<const char *> names ) { class in_group { size_t group; public: - in_group( size_t group ) : group(group) {} + explicit in_group( size_t group ) : group(group) {} bool operator()( symbol_map_t::const_reference elem ) const { return 0 < std::count( elem.second.begin(), diff --git a/gcc/cobol/token_names.h b/gcc/cobol/token_names.h index 682d68df2dc3..ca51510fcb79 100644 --- a/gcc/cobol/token_names.h +++ b/gcc/cobol/token_names.h @@ -1,5 +1,5 @@ // generated by ./token_names.h.gen ../../build/gcc/cobol/parse.h -// Thu May 8 18:53:33 EDT 2025 +// Tue Jul 8 19:21:28 EDT 2025 tokens = { { "identification", IDENTIFICATION_DIV }, // 258 { "environment", ENVIRONMENT_DIV }, // 259 @@ -137,560 +137,569 @@ tokens = { { "cdf-evaluate", CDF_EVALUATE }, // 388 { "cdf-when", CDF_WHEN }, // 389 { "cdf-end-evaluate", CDF_END_EVALUATE }, // 390 - { "call-cobol", CALL_COBOL }, // 391 - { "call-verbatim", CALL_VERBATIM }, // 392 - { "if", IF }, // 393 - { "then", THEN }, // 394 - { "else", ELSE }, // 395 - { "sentence", SENTENCE }, // 396 - { "accept", ACCEPT }, // 397 - { "add", ADD }, // 398 - { "alter", ALTER }, // 399 - { "call", CALL }, // 400 - { "cancel", CANCEL }, // 401 - { "close", CLOSE }, // 402 - { "compute", COMPUTE }, // 403 - { "continue", CONTINUE }, // 404 - { "delete", DELETE }, // 405 - { "display", DISPLAY }, // 406 - { "divide", DIVIDE }, // 407 - { "evaluate", EVALUATE }, // 408 - { "exit", EXIT }, // 409 - { "filler", FILLER_kw }, // 410 - { "goback", GOBACK }, // 411 - { "goto", GOTO }, // 412 - { "initialize", INITIALIZE }, // 413 - { "inspect", INSPECT }, // 414 - { "merge", MERGE }, // 415 - { "move", MOVE }, // 416 - { "multiply", MULTIPLY }, // 417 - { "open", OPEN }, // 418 - { "paragraph", PARAGRAPH }, // 419 - { "read", READ }, // 420 - { "release", RELEASE }, // 421 - { "return", RETURN }, // 422 - { "rewrite", REWRITE }, // 423 - { "search", SEARCH }, // 424 - { "set", SET }, // 425 - { "select", SELECT }, // 426 - { "sort", SORT }, // 427 - { "sort-merge", SORT_MERGE }, // 428 - { "string", STRING_kw }, // 429 - { "stop", STOP }, // 430 - { "subtract", SUBTRACT }, // 431 - { "start", START }, // 432 - { "unstring", UNSTRING }, // 433 - { "write", WRITE }, // 434 - { "when", WHEN }, // 435 - { "abs", ABS }, // 436 - { "access", ACCESS }, // 437 - { "acos", ACOS }, // 438 - { "actual", ACTUAL }, // 439 - { "advancing", ADVANCING }, // 440 - { "after", AFTER }, // 441 - { "all", ALL }, // 442 - { "allocate", ALLOCATE }, // 443 - { "alphabet", ALPHABET }, // 444 - { "alphabetic", ALPHABETIC }, // 445 - { "alphabetic-lower", ALPHABETIC_LOWER }, // 446 - { "alphabetic-upper", ALPHABETIC_UPPER }, // 447 - { "alphanumeric", ALPHANUMERIC }, // 448 - { "alphanumeric-edited", ALPHANUMERIC_EDITED }, // 449 - { "also", ALSO }, // 450 - { "alternate", ALTERNATE }, // 451 - { "annuity", ANNUITY }, // 452 - { "anum", ANUM }, // 453 - { "any", ANY }, // 454 - { "anycase", ANYCASE }, // 455 - { "apply", APPLY }, // 456 - { "are", ARE }, // 457 - { "area", AREA }, // 458 - { "areas", AREAS }, // 459 - { "as", AS }, // 460 - { "ascending", ASCENDING }, // 461 - { "activating", ACTIVATING }, // 462 - { "asin", ASIN }, // 463 - { "assign", ASSIGN }, // 464 - { "at", AT }, // 465 - { "atan", ATAN }, // 466 - { "based", BASED }, // 467 - { "baseconvert", BASECONVERT }, // 468 - { "before", BEFORE }, // 469 - { "binary", BINARY }, // 470 - { "bit", BIT }, // 471 - { "bit-of", BIT_OF }, // 472 - { "bit-to-char", BIT_TO_CHAR }, // 473 - { "blank", BLANK }, // 474 - { "block", BLOCK_kw }, // 475 - { "boolean-of-integer", BOOLEAN_OF_INTEGER }, // 476 - { "bottom", BOTTOM }, // 477 - { "by", BY }, // 478 - { "byte", BYTE }, // 479 - { "byte-length", BYTE_LENGTH }, // 480 - { "cf", CF }, // 481 - { "ch", CH }, // 482 - { "changed", CHANGED }, // 483 - { "char", CHAR }, // 484 - { "char-national", CHAR_NATIONAL }, // 485 - { "character", CHARACTER }, // 486 - { "characters", CHARACTERS }, // 487 - { "checking", CHECKING }, // 488 - { "class", CLASS }, // 489 - { "cobol", COBOL }, // 490 - { "code", CODE }, // 491 - { "code-set", CODESET }, // 492 - { "collating", COLLATING }, // 493 - { "column", COLUMN }, // 494 - { "combined-datetime", COMBINED_DATETIME }, // 495 - { "comma", COMMA }, // 496 - { "command-line", COMMAND_LINE }, // 497 - { "command-line-count", COMMAND_LINE_COUNT }, // 498 - { "commit", COMMIT }, // 499 - { "common", COMMON }, // 500 - { "concat", CONCAT }, // 501 - { "condition", CONDITION }, // 502 - { "configuration", CONFIGURATION_SECT }, // 503 - { "contains", CONTAINS }, // 504 - { "content", CONTENT }, // 505 - { "control", CONTROL }, // 506 - { "controls", CONTROLS }, // 507 - { "convert", CONVERT }, // 508 - { "converting", CONVERTING }, // 509 - { "corresponding", CORRESPONDING }, // 510 - { "cos", COS }, // 511 - { "count", COUNT }, // 512 - { "currency", CURRENCY }, // 513 - { "current", CURRENT }, // 514 - { "current-date", CURRENT_DATE }, // 515 - { "data", DATA }, // 516 - { "date", DATE }, // 517 - { "date-compiled", DATE_COMPILED }, // 518 - { "date-of-integer", DATE_OF_INTEGER }, // 519 - { "date-to-yyyymmdd", DATE_TO_YYYYMMDD }, // 520 - { "date-written", DATE_WRITTEN }, // 521 - { "day", DAY }, // 522 - { "day-of-integer", DAY_OF_INTEGER }, // 523 - { "day-of-week", DAY_OF_WEEK }, // 524 - { "day-to-yyyyddd", DAY_TO_YYYYDDD }, // 525 - { "dbcs", DBCS }, // 526 - { "de", DE }, // 527 - { "debugging", DEBUGGING }, // 528 - { "decimal-point", DECIMAL_POINT }, // 529 - { "declaratives", DECLARATIVES }, // 530 - { "default", DEFAULT }, // 531 - { "delimited", DELIMITED }, // 532 - { "delimiter", DELIMITER }, // 533 - { "depending", DEPENDING }, // 534 - { "descending", DESCENDING }, // 535 - { "detail", DETAIL }, // 536 - { "direct", DIRECT }, // 537 - { "direct-access", DIRECT_ACCESS }, // 538 - { "down", DOWN }, // 539 - { "duplicates", DUPLICATES }, // 540 - { "dynamic", DYNAMIC }, // 541 - { "e", E }, // 542 - { "ebcdic", EBCDIC }, // 543 - { "ec", EC }, // 544 - { "egcs", EGCS }, // 545 - { "entry", ENTRY }, // 546 - { "environment", ENVIRONMENT }, // 547 - { "equal", EQUAL }, // 548 - { "every", EVERY }, // 549 - { "examine", EXAMINE }, // 550 - { "exhibit", EXHIBIT }, // 551 - { "exp", EXP }, // 552 - { "exp10", EXP10 }, // 553 - { "extend", EXTEND }, // 554 - { "external", EXTERNAL }, // 555 - { "exception-file", EXCEPTION_FILE }, // 556 - { "exception-file-n", EXCEPTION_FILE_N }, // 557 - { "exception-location", EXCEPTION_LOCATION }, // 558 - { "exception-location-n", EXCEPTION_LOCATION_N }, // 559 - { "exception-statement", EXCEPTION_STATEMENT }, // 560 - { "exception-status", EXCEPTION_STATUS }, // 561 - { "factorial", FACTORIAL }, // 562 - { "false", FALSE_kw }, // 563 - { "fd", FD }, // 564 - { "file-control", FILE_CONTROL }, // 565 - { "file", FILE_KW }, // 566 - { "file-limit", FILE_LIMIT }, // 567 - { "final", FINAL }, // 568 - { "finally", FINALLY }, // 569 - { "find-string", FIND_STRING }, // 570 - { "first", FIRST }, // 571 - { "fixed", FIXED }, // 572 - { "footing", FOOTING }, // 573 - { "for", FOR }, // 574 - { "formatted-current-date", FORMATTED_CURRENT_DATE }, // 575 - { "formatted-date", FORMATTED_DATE }, // 576 - { "formatted-datetime", FORMATTED_DATETIME }, // 577 - { "formatted-time", FORMATTED_TIME }, // 578 - { "form-overflow", FORM_OVERFLOW }, // 579 - { "free", FREE }, // 580 - { "fraction-part", FRACTION_PART }, // 581 - { "from", FROM }, // 582 - { "function", FUNCTION }, // 583 - { "generate", GENERATE }, // 584 - { "giving", GIVING }, // 585 - { "global", GLOBAL }, // 586 - { "go", GO }, // 587 - { "group", GROUP }, // 588 - { "heading", HEADING }, // 589 - { "hex", HEX }, // 590 - { "hex-of", HEX_OF }, // 591 - { "hex-to-char", HEX_TO_CHAR }, // 592 - { "high-values", HIGH_VALUES }, // 593 - { "highest-algebraic", HIGHEST_ALGEBRAIC }, // 594 - { "hold", HOLD }, // 595 - { "ibm-360", IBM_360 }, // 596 - { "in", IN }, // 597 - { "include", INCLUDE }, // 598 - { "index", INDEX }, // 599 - { "indexed", INDEXED }, // 600 - { "indicate", INDICATE }, // 601 - { "initial", INITIAL_kw }, // 602 - { "initiate", INITIATE }, // 603 - { "input", INPUT }, // 604 - { "installation", INSTALLATION }, // 605 - { "interface", INTERFACE }, // 606 - { "integer", INTEGER }, // 607 - { "integer-of-boolean", INTEGER_OF_BOOLEAN }, // 608 - { "integer-of-date", INTEGER_OF_DATE }, // 609 - { "integer-of-day", INTEGER_OF_DAY }, // 610 - { "integer-of-formatted-date", INTEGER_OF_FORMATTED_DATE }, // 611 - { "integer-part", INTEGER_PART }, // 612 - { "into", INTO }, // 613 - { "intrinsic", INTRINSIC }, // 614 - { "invoke", INVOKE }, // 615 - { "i-o", IO }, // 616 - { "i-o-control", IO_CONTROL }, // 617 - { "is", IS }, // 618 - { "isnt", ISNT }, // 619 - { "kanji", KANJI }, // 620 - { "key", KEY }, // 621 - { "label", LABEL }, // 622 - { "last", LAST }, // 623 - { "leading", LEADING }, // 624 - { "left", LEFT }, // 625 - { "length", LENGTH }, // 626 - { "length-of", LENGTH_OF }, // 627 - { "limit", LIMIT }, // 628 - { "limits", LIMITS }, // 629 - { "line", LINE }, // 630 - { "lines", LINES }, // 631 - { "line-counter", LINE_COUNTER }, // 632 - { "linage", LINAGE }, // 633 - { "linkage", LINKAGE }, // 634 - { "locale", LOCALE }, // 635 - { "locale-compare", LOCALE_COMPARE }, // 636 - { "locale-date", LOCALE_DATE }, // 637 - { "locale-time", LOCALE_TIME }, // 638 - { "locale-time-from-seconds", LOCALE_TIME_FROM_SECONDS }, // 639 - { "local-storage", LOCAL_STORAGE }, // 640 - { "location", LOCATION }, // 641 - { "lock", LOCK }, // 642 - { "lock-on", LOCK_ON }, // 643 - { "log", LOG }, // 644 - { "log10", LOG10 }, // 645 - { "lower-case", LOWER_CASE }, // 646 - { "low-values", LOW_VALUES }, // 647 - { "lowest-algebraic", LOWEST_ALGEBRAIC }, // 648 - { "lparen", LPAREN }, // 649 - { "manual", MANUAL }, // 650 - { "maxx", MAXX }, // 651 - { "mean", MEAN }, // 652 - { "median", MEDIAN }, // 653 - { "midrange", MIDRANGE }, // 654 - { "minn", MINN }, // 655 - { "multiple", MULTIPLE }, // 656 - { "mod", MOD }, // 657 - { "mode", MODE }, // 658 - { "module-name", MODULE_NAME }, // 659 - { "named", NAMED }, // 660 - { "nat", NAT }, // 661 - { "national", NATIONAL }, // 662 - { "national-edited", NATIONAL_EDITED }, // 663 - { "national-of", NATIONAL_OF }, // 664 - { "native", NATIVE }, // 665 - { "nested", NESTED }, // 666 - { "next", NEXT }, // 667 - { "no", NO }, // 668 - { "note", NOTE }, // 669 - { "nulls", NULLS }, // 670 - { "null", NULLS }, // 670 - { "nullptr", NULLPTR }, // 671 - { "numeric", NUMERIC }, // 672 - { "numeric-edited", NUMERIC_EDITED }, // 673 - { "numval", NUMVAL }, // 674 - { "numval-c", NUMVAL_C }, // 675 - { "numval-f", NUMVAL_F }, // 676 - { "occurs", OCCURS }, // 677 - { "of", OF }, // 678 - { "off", OFF }, // 679 - { "omitted", OMITTED }, // 680 - { "on", ON }, // 681 - { "only", ONLY }, // 682 - { "optional", OPTIONAL }, // 683 - { "options", OPTIONS }, // 684 - { "ord", ORD }, // 685 - { "order", ORDER }, // 686 - { "ord-max", ORD_MAX }, // 687 - { "ord-min", ORD_MIN }, // 688 - { "organization", ORGANIZATION }, // 689 - { "other", OTHER }, // 690 - { "otherwise", OTHERWISE }, // 691 - { "output", OUTPUT }, // 692 - { "packed-decimal", PACKED_DECIMAL }, // 693 - { "padding", PADDING }, // 694 - { "page", PAGE }, // 695 - { "page-counter", PAGE_COUNTER }, // 696 - { "pf", PF }, // 697 - { "ph", PH }, // 698 - { "pi", PI }, // 699 - { "pic", PIC }, // 700 - { "picture", PICTURE }, // 701 - { "plus", PLUS }, // 702 - { "present-value", PRESENT_VALUE }, // 703 - { "print-switch", PRINT_SWITCH }, // 704 - { "procedure", PROCEDURE }, // 705 - { "procedures", PROCEDURES }, // 706 - { "proceed", PROCEED }, // 707 - { "process", PROCESS }, // 708 - { "program-id", PROGRAM_ID }, // 709 - { "program", PROGRAM_kw }, // 710 - { "property", PROPERTY }, // 711 - { "prototype", PROTOTYPE }, // 712 - { "pseudotext", PSEUDOTEXT }, // 713 - { "quotes", QUOTES }, // 714 - { "quote", QUOTES }, // 714 - { "random", RANDOM }, // 715 - { "random-seed", RANDOM_SEED }, // 716 - { "range", RANGE }, // 717 - { "raise", RAISE }, // 718 - { "raising", RAISING }, // 719 - { "rd", RD }, // 720 - { "record", RECORD }, // 721 - { "recording", RECORDING }, // 722 - { "records", RECORDS }, // 723 - { "recursive", RECURSIVE }, // 724 - { "redefines", REDEFINES }, // 725 - { "reel", REEL }, // 726 - { "reference", REFERENCE }, // 727 - { "relative", RELATIVE }, // 728 - { "rem", REM }, // 729 - { "remainder", REMAINDER }, // 730 - { "remarks", REMARKS }, // 731 - { "removal", REMOVAL }, // 732 - { "renames", RENAMES }, // 733 - { "replace", REPLACE }, // 734 - { "replacing", REPLACING }, // 735 - { "report", REPORT }, // 736 - { "reporting", REPORTING }, // 737 - { "reports", REPORTS }, // 738 - { "repository", REPOSITORY }, // 739 - { "rerun", RERUN }, // 740 - { "reserve", RESERVE }, // 741 - { "restricted", RESTRICTED }, // 742 - { "resume", RESUME }, // 743 - { "reverse", REVERSE }, // 744 - { "reversed", REVERSED }, // 745 - { "rewind", REWIND }, // 746 - { "rf", RF }, // 747 - { "rh", RH }, // 748 - { "right", RIGHT }, // 749 - { "rounded", ROUNDED }, // 750 - { "run", RUN }, // 751 - { "same", SAME }, // 752 - { "screen", SCREEN }, // 753 - { "sd", SD }, // 754 - { "seconds-from-formatted-time", SECONDS_FROM_FORMATTED_TIME }, // 755 - { "seconds-past-midnight", SECONDS_PAST_MIDNIGHT }, // 756 - { "security", SECURITY }, // 757 - { "separate", SEPARATE }, // 758 - { "sequence", SEQUENCE }, // 759 - { "sequential", SEQUENTIAL }, // 760 - { "sharing", SHARING }, // 761 - { "simple-exit", SIMPLE_EXIT }, // 762 - { "sign", SIGN }, // 763 - { "sin", SIN }, // 764 - { "size", SIZE }, // 765 - { "smallest-algebraic", SMALLEST_ALGEBRAIC }, // 766 - { "source", SOURCE }, // 767 - { "source-computer", SOURCE_COMPUTER }, // 768 - { "special-names", SPECIAL_NAMES }, // 769 - { "sqrt", SQRT }, // 770 - { "stack", STACK }, // 771 - { "standard", STANDARD }, // 772 - { "standard-1", STANDARD_1 }, // 773 - { "standard-deviation", STANDARD_DEVIATION }, // 774 - { "standard-compare", STANDARD_COMPARE }, // 775 - { "status", STATUS }, // 776 - { "strong", STRONG }, // 777 - { "substitute", SUBSTITUTE }, // 778 - { "sum", SUM }, // 779 - { "symbol", SYMBOL }, // 780 - { "symbolic", SYMBOLIC }, // 781 - { "synchronized", SYNCHRONIZED }, // 782 - { "tally", TALLY }, // 783 - { "tallying", TALLYING }, // 784 - { "tan", TAN }, // 785 - { "terminate", TERMINATE }, // 786 - { "test", TEST }, // 787 - { "test-date-yyyymmdd", TEST_DATE_YYYYMMDD }, // 788 - { "test-day-yyyyddd", TEST_DAY_YYYYDDD }, // 789 - { "test-formatted-datetime", TEST_FORMATTED_DATETIME }, // 790 - { "test-numval", TEST_NUMVAL }, // 791 - { "test-numval-c", TEST_NUMVAL_C }, // 792 - { "test-numval-f", TEST_NUMVAL_F }, // 793 - { "than", THAN }, // 794 - { "time", TIME }, // 795 - { "times", TIMES }, // 796 - { "to", TO }, // 797 - { "top", TOP }, // 798 - { "top-level", TOP_LEVEL }, // 799 - { "tracks", TRACKS }, // 800 - { "track-area", TRACK_AREA }, // 801 - { "trailing", TRAILING }, // 802 - { "transform", TRANSFORM }, // 803 - { "trim", TRIM }, // 804 - { "true", TRUE_kw }, // 805 - { "try", TRY }, // 806 - { "turn", TURN }, // 807 - { "type", TYPE }, // 808 - { "typedef", TYPEDEF }, // 809 - { "ulength", ULENGTH }, // 810 - { "unbounded", UNBOUNDED }, // 811 - { "unit", UNIT }, // 812 - { "units", UNITS }, // 813 - { "unit-record", UNIT_RECORD }, // 814 - { "until", UNTIL }, // 815 - { "up", UP }, // 816 - { "upon", UPON }, // 817 - { "upos", UPOS }, // 818 - { "upper-case", UPPER_CASE }, // 819 - { "usage", USAGE }, // 820 - { "using", USING }, // 821 - { "usubstr", USUBSTR }, // 822 - { "usupplementary", USUPPLEMENTARY }, // 823 - { "utility", UTILITY }, // 824 - { "uuid4", UUID4 }, // 825 - { "uvalid", UVALID }, // 826 - { "uwidth", UWIDTH }, // 827 - { "value", VALUE }, // 828 - { "variance", VARIANCE }, // 829 - { "varying", VARYING }, // 830 - { "volatile", VOLATILE }, // 831 - { "when-compiled", WHEN_COMPILED }, // 832 - { "with", WITH }, // 833 - { "working-storage", WORKING_STORAGE }, // 834 - { "xml", XML }, // 835 - { "xmlgenerate", XMLGENERATE }, // 836 - { "xmlparse", XMLPARSE }, // 837 - { "year-to-yyyy", YEAR_TO_YYYY }, // 838 - { "yyyyddd", YYYYDDD }, // 839 - { "yyyymmdd", YYYYMMDD }, // 840 - { "arithmetic", ARITHMETIC }, // 841 - { "attribute", ATTRIBUTE }, // 842 - { "auto", AUTO }, // 843 - { "automatic", AUTOMATIC }, // 844 - { "away-from-zero", AWAY_FROM_ZERO }, // 845 - { "background-color", BACKGROUND_COLOR }, // 846 - { "bell", BELL }, // 847 - { "binary-encoding", BINARY_ENCODING }, // 848 - { "blink", BLINK }, // 849 - { "capacity", CAPACITY }, // 850 - { "center", CENTER }, // 851 - { "classification", CLASSIFICATION }, // 852 - { "cycle", CYCLE }, // 853 - { "decimal-encoding", DECIMAL_ENCODING }, // 854 - { "entry-convention", ENTRY_CONVENTION }, // 855 - { "eol", EOL }, // 856 - { "eos", EOS }, // 857 - { "erase", ERASE }, // 858 - { "expands", EXPANDS }, // 859 - { "float-binary", FLOAT_BINARY }, // 860 - { "float-decimal", FLOAT_DECIMAL }, // 861 - { "foreground-color", FOREGROUND_COLOR }, // 862 - { "forever", FOREVER }, // 863 - { "full", FULL }, // 864 - { "highlight", HIGHLIGHT }, // 865 - { "high-order-left", HIGH_ORDER_LEFT }, // 866 - { "high-order-right", HIGH_ORDER_RIGHT }, // 867 - { "ignoring", IGNORING }, // 868 - { "implements", IMPLEMENTS }, // 869 - { "initialized", INITIALIZED }, // 870 - { "intermediate", INTERMEDIATE }, // 871 - { "lc-all", LC_ALL_kw }, // 872 - { "lc-collate", LC_COLLATE_kw }, // 873 - { "lc-ctype", LC_CTYPE_kw }, // 874 - { "lc-messages", LC_MESSAGES_kw }, // 875 - { "lc-monetary", LC_MONETARY_kw }, // 876 - { "lc-numeric", LC_NUMERIC_kw }, // 877 - { "lc-time", LC_TIME_kw }, // 878 - { "lowlight", LOWLIGHT }, // 879 - { "nearest-away-from-zero", NEAREST_AWAY_FROM_ZERO }, // 880 - { "nearest-even", NEAREST_EVEN }, // 881 - { "nearest-toward-zero", NEAREST_TOWARD_ZERO }, // 882 - { "none", NONE }, // 883 - { "normal", NORMAL }, // 884 - { "numbers", NUMBERS }, // 885 - { "prefixed", PREFIXED }, // 886 - { "previous", PREVIOUS }, // 887 - { "prohibited", PROHIBITED }, // 888 - { "relation", RELATION }, // 889 - { "required", REQUIRED }, // 890 - { "reverse-video", REVERSE_VIDEO }, // 891 - { "rounding", ROUNDING }, // 892 - { "seconds", SECONDS }, // 893 - { "secure", SECURE }, // 894 - { "short", SHORT }, // 895 - { "signed", SIGNED_kw }, // 896 - { "standard-binary", STANDARD_BINARY }, // 897 - { "standard-decimal", STANDARD_DECIMAL }, // 898 - { "statement", STATEMENT }, // 899 - { "step", STEP }, // 900 - { "structure", STRUCTURE }, // 901 - { "toward-greater", TOWARD_GREATER }, // 902 - { "toward-lesser", TOWARD_LESSER }, // 903 - { "truncation", TRUNCATION }, // 904 - { "ucs-4", UCS_4 }, // 905 - { "underline", UNDERLINE }, // 906 - { "unsigned", UNSIGNED_kw }, // 907 - { "utf-16", UTF_16 }, // 908 - { "utf-8", UTF_8 }, // 909 - { "address", ADDRESS }, // 910 - { "end-accept", END_ACCEPT }, // 911 - { "end-add", END_ADD }, // 912 - { "end-call", END_CALL }, // 913 - { "end-compute", END_COMPUTE }, // 914 - { "end-delete", END_DELETE }, // 915 - { "end-display", END_DISPLAY }, // 916 - { "end-divide", END_DIVIDE }, // 917 - { "end-evaluate", END_EVALUATE }, // 918 - { "end-multiply", END_MULTIPLY }, // 919 - { "end-perform", END_PERFORM }, // 920 - { "end-read", END_READ }, // 921 - { "end-return", END_RETURN }, // 922 - { "end-rewrite", END_REWRITE }, // 923 - { "end-search", END_SEARCH }, // 924 - { "end-start", END_START }, // 925 - { "end-string", END_STRING }, // 926 - { "end-subtract", END_SUBTRACT }, // 927 - { "end-unstring", END_UNSTRING }, // 928 - { "end-write", END_WRITE }, // 929 - { "end-if", END_IF }, // 930 - { "thru", THRU }, // 931 - { "through", THRU }, // 931 - { "or", OR }, // 932 - { "and", AND }, // 933 - { "not", NOT }, // 934 - { "ne", NE }, // 935 - { "le", LE }, // 936 - { "ge", GE }, // 937 - { "pow", POW }, // 938 - { "neg", NEG }, // 939 + { "call-convention", CALL_CONVENTION }, // 391 + { "call-cobol", CALL_COBOL }, // 392 + { "call-verbatim", CALL_VERBATIM }, // 393 + { "cdf-push", CDF_PUSH }, // 394 + { "cdf-pop", CDF_POP }, // 395 + { "source-format", SOURCE_FORMAT }, // 396 + { "if", IF }, // 397 + { "then", THEN }, // 398 + { "else", ELSE }, // 399 + { "sentence", SENTENCE }, // 400 + { "accept", ACCEPT }, // 401 + { "add", ADD }, // 402 + { "alter", ALTER }, // 403 + { "call", CALL }, // 404 + { "cancel", CANCEL }, // 405 + { "close", CLOSE }, // 406 + { "compute", COMPUTE }, // 407 + { "continue", CONTINUE }, // 408 + { "delete", DELETE }, // 409 + { "display", DISPLAY }, // 410 + { "divide", DIVIDE }, // 411 + { "evaluate", EVALUATE }, // 412 + { "exit", EXIT }, // 413 + { "filler", FILLER_kw }, // 414 + { "goback", GOBACK }, // 415 + { "goto", GOTO }, // 416 + { "initialize", INITIALIZE }, // 417 + { "inspect", INSPECT }, // 418 + { "merge", MERGE }, // 419 + { "move", MOVE }, // 420 + { "multiply", MULTIPLY }, // 421 + { "open", OPEN }, // 422 + { "paragraph", PARAGRAPH }, // 423 + { "read", READ }, // 424 + { "release", RELEASE }, // 425 + { "return", RETURN }, // 426 + { "rewrite", REWRITE }, // 427 + { "search", SEARCH }, // 428 + { "set", SET }, // 429 + { "select", SELECT }, // 430 + { "sort", SORT }, // 431 + { "sort-merge", SORT_MERGE }, // 432 + { "string", STRING_kw }, // 433 + { "stop", STOP }, // 434 + { "subtract", SUBTRACT }, // 435 + { "start", START }, // 436 + { "unstring", UNSTRING }, // 437 + { "write", WRITE }, // 438 + { "when", WHEN }, // 439 + { "argument-number", ARGUMENT_NUMBER }, // 440 + { "argument-value", ARGUMENT_VALUE }, // 441 + { "environment-name", ENVIRONMENT_NAME }, // 442 + { "environment-value", ENVIRONMENT_VALUE }, // 443 + { "abs", ABS }, // 444 + { "access", ACCESS }, // 445 + { "acos", ACOS }, // 446 + { "actual", ACTUAL }, // 447 + { "advancing", ADVANCING }, // 448 + { "after", AFTER }, // 449 + { "all", ALL }, // 450 + { "allocate", ALLOCATE }, // 451 + { "alphabet", ALPHABET }, // 452 + { "alphabetic", ALPHABETIC }, // 453 + { "alphabetic-lower", ALPHABETIC_LOWER }, // 454 + { "alphabetic-upper", ALPHABETIC_UPPER }, // 455 + { "alphanumeric", ALPHANUMERIC }, // 456 + { "alphanumeric-edited", ALPHANUMERIC_EDITED }, // 457 + { "also", ALSO }, // 458 + { "alternate", ALTERNATE }, // 459 + { "annuity", ANNUITY }, // 460 + { "anum", ANUM }, // 461 + { "any", ANY }, // 462 + { "anycase", ANYCASE }, // 463 + { "apply", APPLY }, // 464 + { "are", ARE }, // 465 + { "area", AREA }, // 466 + { "areas", AREAS }, // 467 + { "as", AS }, // 468 + { "ascending", ASCENDING }, // 469 + { "activating", ACTIVATING }, // 470 + { "asin", ASIN }, // 471 + { "assign", ASSIGN }, // 472 + { "at", AT }, // 473 + { "atan", ATAN }, // 474 + { "based", BASED }, // 475 + { "baseconvert", BASECONVERT }, // 476 + { "before", BEFORE }, // 477 + { "binary", BINARY }, // 478 + { "bit", BIT }, // 479 + { "bit-of", BIT_OF }, // 480 + { "bit-to-char", BIT_TO_CHAR }, // 481 + { "blank", BLANK }, // 482 + { "block", BLOCK_kw }, // 483 + { "boolean-of-integer", BOOLEAN_OF_INTEGER }, // 484 + { "bottom", BOTTOM }, // 485 + { "by", BY }, // 486 + { "byte", BYTE }, // 487 + { "byte-length", BYTE_LENGTH }, // 488 + { "cf", CF }, // 489 + { "ch", CH }, // 490 + { "changed", CHANGED }, // 491 + { "char", CHAR }, // 492 + { "char-national", CHAR_NATIONAL }, // 493 + { "character", CHARACTER }, // 494 + { "characters", CHARACTERS }, // 495 + { "checking", CHECKING }, // 496 + { "class", CLASS }, // 497 + { "cobol", COBOL }, // 498 + { "code", CODE }, // 499 + { "code-set", CODESET }, // 500 + { "collating", COLLATING }, // 501 + { "column", COLUMN }, // 502 + { "combined-datetime", COMBINED_DATETIME }, // 503 + { "comma", COMMA }, // 504 + { "command-line", COMMAND_LINE }, // 505 + { "command-line-count", COMMAND_LINE_COUNT }, // 506 + { "commit", COMMIT }, // 507 + { "common", COMMON }, // 508 + { "concat", CONCAT }, // 509 + { "condition", CONDITION }, // 510 + { "configuration", CONFIGURATION_SECT }, // 511 + { "contains", CONTAINS }, // 512 + { "content", CONTENT }, // 513 + { "control", CONTROL }, // 514 + { "controls", CONTROLS }, // 515 + { "convert", CONVERT }, // 516 + { "converting", CONVERTING }, // 517 + { "corresponding", CORRESPONDING }, // 518 + { "cos", COS }, // 519 + { "count", COUNT }, // 520 + { "currency", CURRENCY }, // 521 + { "current", CURRENT }, // 522 + { "current-date", CURRENT_DATE }, // 523 + { "data", DATA }, // 524 + { "date", DATE }, // 525 + { "date-compiled", DATE_COMPILED }, // 526 + { "date-of-integer", DATE_OF_INTEGER }, // 527 + { "date-to-yyyymmdd", DATE_TO_YYYYMMDD }, // 528 + { "date-written", DATE_WRITTEN }, // 529 + { "day", DAY }, // 530 + { "day-of-integer", DAY_OF_INTEGER }, // 531 + { "day-of-week", DAY_OF_WEEK }, // 532 + { "day-to-yyyyddd", DAY_TO_YYYYDDD }, // 533 + { "dbcs", DBCS }, // 534 + { "de", DE }, // 535 + { "debugging", DEBUGGING }, // 536 + { "decimal-point", DECIMAL_POINT }, // 537 + { "declaratives", DECLARATIVES }, // 538 + { "default", DEFAULT }, // 539 + { "delimited", DELIMITED }, // 540 + { "delimiter", DELIMITER }, // 541 + { "depending", DEPENDING }, // 542 + { "descending", DESCENDING }, // 543 + { "detail", DETAIL }, // 544 + { "direct", DIRECT }, // 545 + { "direct-access", DIRECT_ACCESS }, // 546 + { "down", DOWN }, // 547 + { "duplicates", DUPLICATES }, // 548 + { "dynamic", DYNAMIC }, // 549 + { "e", E }, // 550 + { "ebcdic", EBCDIC }, // 551 + { "ec", EC }, // 552 + { "egcs", EGCS }, // 553 + { "entry", ENTRY }, // 554 + { "environment", ENVIRONMENT }, // 555 + { "equal", EQUAL }, // 556 + { "every", EVERY }, // 557 + { "examine", EXAMINE }, // 558 + { "exhibit", EXHIBIT }, // 559 + { "exp", EXP }, // 560 + { "exp10", EXP10 }, // 561 + { "extend", EXTEND }, // 562 + { "external", EXTERNAL }, // 563 + { "exception-file", EXCEPTION_FILE }, // 564 + { "exception-file-n", EXCEPTION_FILE_N }, // 565 + { "exception-location", EXCEPTION_LOCATION }, // 566 + { "exception-location-n", EXCEPTION_LOCATION_N }, // 567 + { "exception-statement", EXCEPTION_STATEMENT }, // 568 + { "exception-status", EXCEPTION_STATUS }, // 569 + { "factorial", FACTORIAL }, // 570 + { "false", FALSE_kw }, // 571 + { "fd", FD }, // 572 + { "file-control", FILE_CONTROL }, // 573 + { "file", FILE_KW }, // 574 + { "file-limit", FILE_LIMIT }, // 575 + { "final", FINAL }, // 576 + { "finally", FINALLY }, // 577 + { "find-string", FIND_STRING }, // 578 + { "first", FIRST }, // 579 + { "fixed", FIXED }, // 580 + { "footing", FOOTING }, // 581 + { "for", FOR }, // 582 + { "formatted-current-date", FORMATTED_CURRENT_DATE }, // 583 + { "formatted-date", FORMATTED_DATE }, // 584 + { "formatted-datetime", FORMATTED_DATETIME }, // 585 + { "formatted-time", FORMATTED_TIME }, // 586 + { "form-overflow", FORM_OVERFLOW }, // 587 + { "free", FREE }, // 588 + { "fraction-part", FRACTION_PART }, // 589 + { "from", FROM }, // 590 + { "function", FUNCTION }, // 591 + { "generate", GENERATE }, // 592 + { "giving", GIVING }, // 593 + { "global", GLOBAL }, // 594 + { "go", GO }, // 595 + { "group", GROUP }, // 596 + { "heading", HEADING }, // 597 + { "hex", HEX }, // 598 + { "hex-of", HEX_OF }, // 599 + { "hex-to-char", HEX_TO_CHAR }, // 600 + { "high-values", HIGH_VALUES }, // 601 + { "highest-algebraic", HIGHEST_ALGEBRAIC }, // 602 + { "hold", HOLD }, // 603 + { "ibm-360", IBM_360 }, // 604 + { "in", IN }, // 605 + { "include", INCLUDE }, // 606 + { "index", INDEX }, // 607 + { "indexed", INDEXED }, // 608 + { "indicate", INDICATE }, // 609 + { "initial", INITIAL_kw }, // 610 + { "initiate", INITIATE }, // 611 + { "input", INPUT }, // 612 + { "installation", INSTALLATION }, // 613 + { "interface", INTERFACE }, // 614 + { "integer", INTEGER }, // 615 + { "integer-of-boolean", INTEGER_OF_BOOLEAN }, // 616 + { "integer-of-date", INTEGER_OF_DATE }, // 617 + { "integer-of-day", INTEGER_OF_DAY }, // 618 + { "integer-of-formatted-date", INTEGER_OF_FORMATTED_DATE }, // 619 + { "integer-part", INTEGER_PART }, // 620 + { "into", INTO }, // 621 + { "intrinsic", INTRINSIC }, // 622 + { "invoke", INVOKE }, // 623 + { "i-o", IO }, // 624 + { "i-o-control", IO_CONTROL }, // 625 + { "is", IS }, // 626 + { "isnt", ISNT }, // 627 + { "kanji", KANJI }, // 628 + { "key", KEY }, // 629 + { "label", LABEL }, // 630 + { "last", LAST }, // 631 + { "leading", LEADING }, // 632 + { "left", LEFT }, // 633 + { "length", LENGTH }, // 634 + { "length-of", LENGTH_OF }, // 635 + { "limit", LIMIT }, // 636 + { "limits", LIMITS }, // 637 + { "line", LINE }, // 638 + { "lines", LINES }, // 639 + { "line-counter", LINE_COUNTER }, // 640 + { "linage", LINAGE }, // 641 + { "linkage", LINKAGE }, // 642 + { "locale", LOCALE }, // 643 + { "locale-compare", LOCALE_COMPARE }, // 644 + { "locale-date", LOCALE_DATE }, // 645 + { "locale-time", LOCALE_TIME }, // 646 + { "locale-time-from-seconds", LOCALE_TIME_FROM_SECONDS }, // 647 + { "local-storage", LOCAL_STORAGE }, // 648 + { "location", LOCATION }, // 649 + { "lock", LOCK }, // 650 + { "lock-on", LOCK_ON }, // 651 + { "log", LOG }, // 652 + { "log10", LOG10 }, // 653 + { "lower-case", LOWER_CASE }, // 654 + { "low-values", LOW_VALUES }, // 655 + { "lowest-algebraic", LOWEST_ALGEBRAIC }, // 656 + { "lparen", LPAREN }, // 657 + { "manual", MANUAL }, // 658 + { "maxx", MAXX }, // 659 + { "mean", MEAN }, // 660 + { "median", MEDIAN }, // 661 + { "midrange", MIDRANGE }, // 662 + { "minn", MINN }, // 663 + { "multiple", MULTIPLE }, // 664 + { "mod", MOD }, // 665 + { "mode", MODE }, // 666 + { "module-name", MODULE_NAME }, // 667 + { "named", NAMED }, // 668 + { "nat", NAT }, // 669 + { "national", NATIONAL }, // 670 + { "national-edited", NATIONAL_EDITED }, // 671 + { "national-of", NATIONAL_OF }, // 672 + { "native", NATIVE }, // 673 + { "nested", NESTED }, // 674 + { "next", NEXT }, // 675 + { "no", NO }, // 676 + { "note", NOTE }, // 677 + { "nulls", NULLS }, // 678 + { "null", NULLS }, // 678 + { "nullptr", NULLPTR }, // 679 + { "numeric", NUMERIC }, // 680 + { "numeric-edited", NUMERIC_EDITED }, // 681 + { "numval", NUMVAL }, // 682 + { "numval-c", NUMVAL_C }, // 683 + { "numval-f", NUMVAL_F }, // 684 + { "occurs", OCCURS }, // 685 + { "of", OF }, // 686 + { "off", OFF }, // 687 + { "omitted", OMITTED }, // 688 + { "on", ON }, // 689 + { "only", ONLY }, // 690 + { "optional", OPTIONAL }, // 691 + { "options", OPTIONS }, // 692 + { "ord", ORD }, // 693 + { "order", ORDER }, // 694 + { "ord-max", ORD_MAX }, // 695 + { "ord-min", ORD_MIN }, // 696 + { "organization", ORGANIZATION }, // 697 + { "other", OTHER }, // 698 + { "otherwise", OTHERWISE }, // 699 + { "output", OUTPUT }, // 700 + { "packed-decimal", PACKED_DECIMAL }, // 701 + { "padding", PADDING }, // 702 + { "page", PAGE }, // 703 + { "page-counter", PAGE_COUNTER }, // 704 + { "pf", PF }, // 705 + { "ph", PH }, // 706 + { "pi", PI }, // 707 + { "pic", PIC }, // 708 + { "picture", PICTURE }, // 709 + { "plus", PLUS }, // 710 + { "present-value", PRESENT_VALUE }, // 711 + { "print-switch", PRINT_SWITCH }, // 712 + { "procedure", PROCEDURE }, // 713 + { "procedures", PROCEDURES }, // 714 + { "proceed", PROCEED }, // 715 + { "process", PROCESS }, // 716 + { "program-id", PROGRAM_ID }, // 717 + { "program", PROGRAM_kw }, // 718 + { "property", PROPERTY }, // 719 + { "prototype", PROTOTYPE }, // 720 + { "pseudotext", PSEUDOTEXT }, // 721 + { "quotes", QUOTES }, // 722 + { "quote", QUOTES }, // 722 + { "random", RANDOM }, // 723 + { "random-seed", RANDOM_SEED }, // 724 + { "range", RANGE }, // 725 + { "raise", RAISE }, // 726 + { "raising", RAISING }, // 727 + { "rd", RD }, // 728 + { "record", RECORD }, // 729 + { "recording", RECORDING }, // 730 + { "records", RECORDS }, // 731 + { "recursive", RECURSIVE }, // 732 + { "redefines", REDEFINES }, // 733 + { "reel", REEL }, // 734 + { "reference", REFERENCE }, // 735 + { "relative", RELATIVE }, // 736 + { "rem", REM }, // 737 + { "remainder", REMAINDER }, // 738 + { "remarks", REMARKS }, // 739 + { "removal", REMOVAL }, // 740 + { "renames", RENAMES }, // 741 + { "replace", REPLACE }, // 742 + { "replacing", REPLACING }, // 743 + { "report", REPORT }, // 744 + { "reporting", REPORTING }, // 745 + { "reports", REPORTS }, // 746 + { "repository", REPOSITORY }, // 747 + { "rerun", RERUN }, // 748 + { "reserve", RESERVE }, // 749 + { "restricted", RESTRICTED }, // 750 + { "resume", RESUME }, // 751 + { "reverse", REVERSE }, // 752 + { "reversed", REVERSED }, // 753 + { "rewind", REWIND }, // 754 + { "rf", RF }, // 755 + { "rh", RH }, // 756 + { "right", RIGHT }, // 757 + { "rounded", ROUNDED }, // 758 + { "run", RUN }, // 759 + { "same", SAME }, // 760 + { "screen", SCREEN }, // 761 + { "sd", SD }, // 762 + { "seconds-from-formatted-time", SECONDS_FROM_FORMATTED_TIME }, // 763 + { "seconds-past-midnight", SECONDS_PAST_MIDNIGHT }, // 764 + { "security", SECURITY }, // 765 + { "separate", SEPARATE }, // 766 + { "sequence", SEQUENCE }, // 767 + { "sequential", SEQUENTIAL }, // 768 + { "sharing", SHARING }, // 769 + { "simple-exit", SIMPLE_EXIT }, // 770 + { "sign", SIGN }, // 771 + { "sin", SIN }, // 772 + { "size", SIZE }, // 773 + { "smallest-algebraic", SMALLEST_ALGEBRAIC }, // 774 + { "source", SOURCE }, // 775 + { "source-computer", SOURCE_COMPUTER }, // 776 + { "special-names", SPECIAL_NAMES }, // 777 + { "sqrt", SQRT }, // 778 + { "stack", STACK }, // 779 + { "standard", STANDARD }, // 780 + { "standard-1", STANDARD_1 }, // 781 + { "standard-deviation", STANDARD_DEVIATION }, // 782 + { "standard-compare", STANDARD_COMPARE }, // 783 + { "status", STATUS }, // 784 + { "strong", STRONG }, // 785 + { "substitute", SUBSTITUTE }, // 786 + { "sum", SUM }, // 787 + { "symbol", SYMBOL }, // 788 + { "symbolic", SYMBOLIC }, // 789 + { "synchronized", SYNCHRONIZED }, // 790 + { "tally", TALLY }, // 791 + { "tallying", TALLYING }, // 792 + { "tan", TAN }, // 793 + { "terminate", TERMINATE }, // 794 + { "test", TEST }, // 795 + { "test-date-yyyymmdd", TEST_DATE_YYYYMMDD }, // 796 + { "test-day-yyyyddd", TEST_DAY_YYYYDDD }, // 797 + { "test-formatted-datetime", TEST_FORMATTED_DATETIME }, // 798 + { "test-numval", TEST_NUMVAL }, // 799 + { "test-numval-c", TEST_NUMVAL_C }, // 800 + { "test-numval-f", TEST_NUMVAL_F }, // 801 + { "than", THAN }, // 802 + { "time", TIME }, // 803 + { "times", TIMES }, // 804 + { "to", TO }, // 805 + { "top", TOP }, // 806 + { "top-level", TOP_LEVEL }, // 807 + { "tracks", TRACKS }, // 808 + { "track-area", TRACK_AREA }, // 809 + { "trailing", TRAILING }, // 810 + { "transform", TRANSFORM }, // 811 + { "trim", TRIM }, // 812 + { "true", TRUE_kw }, // 813 + { "try", TRY }, // 814 + { "turn", TURN }, // 815 + { "type", TYPE }, // 816 + { "typedef", TYPEDEF }, // 817 + { "ulength", ULENGTH }, // 818 + { "unbounded", UNBOUNDED }, // 819 + { "unit", UNIT }, // 820 + { "units", UNITS }, // 821 + { "unit-record", UNIT_RECORD }, // 822 + { "until", UNTIL }, // 823 + { "up", UP }, // 824 + { "upon", UPON }, // 825 + { "upos", UPOS }, // 826 + { "upper-case", UPPER_CASE }, // 827 + { "usage", USAGE }, // 828 + { "using", USING }, // 829 + { "usubstr", USUBSTR }, // 830 + { "usupplementary", USUPPLEMENTARY }, // 831 + { "utility", UTILITY }, // 832 + { "uuid4", UUID4 }, // 833 + { "uvalid", UVALID }, // 834 + { "uwidth", UWIDTH }, // 835 + { "value", VALUE }, // 836 + { "variance", VARIANCE }, // 837 + { "varying", VARYING }, // 838 + { "volatile", VOLATILE }, // 839 + { "when-compiled", WHEN_COMPILED }, // 840 + { "with", WITH }, // 841 + { "working-storage", WORKING_STORAGE }, // 842 + { "xml", XML }, // 843 + { "xmlgenerate", XMLGENERATE }, // 844 + { "xmlparse", XMLPARSE }, // 845 + { "year-to-yyyy", YEAR_TO_YYYY }, // 846 + { "yyyyddd", YYYYDDD }, // 847 + { "yyyymmdd", YYYYMMDD }, // 848 + { "arithmetic", ARITHMETIC }, // 849 + { "attribute", ATTRIBUTE }, // 850 + { "auto", AUTO }, // 851 + { "automatic", AUTOMATIC }, // 852 + { "away-from-zero", AWAY_FROM_ZERO }, // 853 + { "background-color", BACKGROUND_COLOR }, // 854 + { "bell", BELL }, // 855 + { "binary-encoding", BINARY_ENCODING }, // 856 + { "blink", BLINK }, // 857 + { "capacity", CAPACITY }, // 858 + { "center", CENTER }, // 859 + { "classification", CLASSIFICATION }, // 860 + { "cycle", CYCLE }, // 861 + { "decimal-encoding", DECIMAL_ENCODING }, // 862 + { "entry-convention", ENTRY_CONVENTION }, // 863 + { "eol", EOL }, // 864 + { "eos", EOS }, // 865 + { "erase", ERASE }, // 866 + { "expands", EXPANDS }, // 867 + { "float-binary", FLOAT_BINARY }, // 868 + { "float-decimal", FLOAT_DECIMAL }, // 869 + { "foreground-color", FOREGROUND_COLOR }, // 870 + { "forever", FOREVER }, // 871 + { "full", FULL }, // 872 + { "highlight", HIGHLIGHT }, // 873 + { "high-order-left", HIGH_ORDER_LEFT }, // 874 + { "high-order-right", HIGH_ORDER_RIGHT }, // 875 + { "ignoring", IGNORING }, // 876 + { "implements", IMPLEMENTS }, // 877 + { "initialized", INITIALIZED }, // 878 + { "intermediate", INTERMEDIATE }, // 879 + { "lc-all", LC_ALL_kw }, // 880 + { "lc-collate", LC_COLLATE_kw }, // 881 + { "lc-ctype", LC_CTYPE_kw }, // 882 + { "lc-messages", LC_MESSAGES_kw }, // 883 + { "lc-monetary", LC_MONETARY_kw }, // 884 + { "lc-numeric", LC_NUMERIC_kw }, // 885 + { "lc-time", LC_TIME_kw }, // 886 + { "lowlight", LOWLIGHT }, // 887 + { "nearest-away-from-zero", NEAREST_AWAY_FROM_ZERO }, // 888 + { "nearest-even", NEAREST_EVEN }, // 889 + { "nearest-toward-zero", NEAREST_TOWARD_ZERO }, // 890 + { "none", NONE }, // 891 + { "normal", NORMAL }, // 892 + { "numbers", NUMBERS }, // 893 + { "prefixed", PREFIXED }, // 894 + { "previous", PREVIOUS }, // 895 + { "prohibited", PROHIBITED }, // 896 + { "relation", RELATION }, // 897 + { "required", REQUIRED }, // 898 + { "reverse-video", REVERSE_VIDEO }, // 899 + { "rounding", ROUNDING }, // 900 + { "seconds", SECONDS }, // 901 + { "secure", SECURE }, // 902 + { "short", SHORT }, // 903 + { "signed", SIGNED_kw }, // 904 + { "standard-binary", STANDARD_BINARY }, // 905 + { "standard-decimal", STANDARD_DECIMAL }, // 906 + { "statement", STATEMENT }, // 907 + { "step", STEP }, // 908 + { "structure", STRUCTURE }, // 909 + { "toward-greater", TOWARD_GREATER }, // 910 + { "toward-lesser", TOWARD_LESSER }, // 911 + { "truncation", TRUNCATION }, // 912 + { "ucs-4", UCS_4 }, // 913 + { "underline", UNDERLINE }, // 914 + { "unsigned", UNSIGNED_kw }, // 915 + { "utf-16", UTF_16 }, // 916 + { "utf-8", UTF_8 }, // 917 + { "address", ADDRESS }, // 918 + { "end-accept", END_ACCEPT }, // 919 + { "end-add", END_ADD }, // 920 + { "end-call", END_CALL }, // 921 + { "end-compute", END_COMPUTE }, // 922 + { "end-delete", END_DELETE }, // 923 + { "end-display", END_DISPLAY }, // 924 + { "end-divide", END_DIVIDE }, // 925 + { "end-evaluate", END_EVALUATE }, // 926 + { "end-multiply", END_MULTIPLY }, // 927 + { "end-perform", END_PERFORM }, // 928 + { "end-read", END_READ }, // 929 + { "end-return", END_RETURN }, // 930 + { "end-rewrite", END_REWRITE }, // 931 + { "end-search", END_SEARCH }, // 932 + { "end-start", END_START }, // 933 + { "end-string", END_STRING }, // 934 + { "end-subtract", END_SUBTRACT }, // 935 + { "end-unstring", END_UNSTRING }, // 936 + { "end-write", END_WRITE }, // 937 + { "end-if", END_IF }, // 938 + { "thru", THRU }, // 939 + { "through", THRU }, // 939 + { "or", OR }, // 940 + { "and", AND }, // 941 + { "not", NOT }, // 942 + { "ne", NE }, // 943 + { "le", LE }, // 944 + { "ge", GE }, // 945 + { "pow", POW }, // 946 + { "neg", NEG }, // 947 }; +// cppcheck-suppress useInitializationList token_names = { "IDENTIFICATION", // 0 (258) "ENVIRONMENT", // 1 (259) @@ -825,553 +834,561 @@ token_names = { "CDF-EVALUATE", // 130 (388) "CDF-WHEN", // 131 (389) "CDF-END-EVALUATE", // 132 (390) - "CALL-COBOL", // 133 (391) - "CALL-VERBATIM", // 134 (392) - "IF", // 135 (393) - "THEN", // 136 (394) - "ELSE", // 137 (395) - "SENTENCE", // 138 (396) - "ACCEPT", // 139 (397) - "ADD", // 140 (398) - "ALTER", // 141 (399) - "CALL", // 142 (400) - "CANCEL", // 143 (401) - "CLOSE", // 144 (402) - "COMPUTE", // 145 (403) - "CONTINUE", // 146 (404) - "DELETE", // 147 (405) - "DISPLAY", // 148 (406) - "DIVIDE", // 149 (407) - "EVALUATE", // 150 (408) - "EXIT", // 151 (409) - "FILLER", // 152 (410) - "GOBACK", // 153 (411) - "GOTO", // 154 (412) - "INITIALIZE", // 155 (413) - "INSPECT", // 156 (414) - "MERGE", // 157 (415) - "MOVE", // 158 (416) - "MULTIPLY", // 159 (417) - "OPEN", // 160 (418) - "PARAGRAPH", // 161 (419) - "READ", // 162 (420) - "RELEASE", // 163 (421) - "RETURN", // 164 (422) - "REWRITE", // 165 (423) - "SEARCH", // 166 (424) - "SET", // 167 (425) - "SELECT", // 168 (426) - "SORT", // 169 (427) - "SORT-MERGE", // 170 (428) - "STRING", // 171 (429) - "STOP", // 172 (430) - "SUBTRACT", // 173 (431) - "START", // 174 (432) - "UNSTRING", // 175 (433) - "WRITE", // 176 (434) - "WHEN", // 177 (435) - "ABS", // 178 (436) - "ACCESS", // 179 (437) - "ACOS", // 180 (438) - "ACTUAL", // 181 (439) - "ADVANCING", // 182 (440) - "AFTER", // 183 (441) - "ALL", // 184 (442) - "ALLOCATE", // 185 (443) - "ALPHABET", // 186 (444) - "ALPHABETIC", // 187 (445) - "ALPHABETIC-LOWER", // 188 (446) - "ALPHABETIC-UPPER", // 189 (447) - "ALPHANUMERIC", // 190 (448) - "ALPHANUMERIC-EDITED", // 191 (449) - "ALSO", // 192 (450) - "ALTERNATE", // 193 (451) - "ANNUITY", // 194 (452) - "ANUM", // 195 (453) - "ANY", // 196 (454) - "ANYCASE", // 197 (455) - "APPLY", // 198 (456) - "ARE", // 199 (457) - "AREA", // 200 (458) - "AREAS", // 201 (459) - "AS", // 202 (460) - "ASCENDING", // 203 (461) - "ACTIVATING", // 204 (462) - "ASIN", // 205 (463) - "ASSIGN", // 206 (464) - "AT", // 207 (465) - "ATAN", // 208 (466) - "BASED", // 209 (467) - "BASECONVERT", // 210 (468) - "BEFORE", // 211 (469) - "BINARY", // 212 (470) - "BIT", // 213 (471) - "BIT-OF", // 214 (472) - "BIT-TO-CHAR", // 215 (473) - "BLANK", // 216 (474) - "BLOCK", // 217 (475) - "BOOLEAN-OF-INTEGER", // 218 (476) - "BOTTOM", // 219 (477) - "BY", // 220 (478) - "BYTE", // 221 (479) - "BYTE-LENGTH", // 222 (480) - "CF", // 223 (481) - "CH", // 224 (482) - "CHANGED", // 225 (483) - "CHAR", // 226 (484) - "CHAR-NATIONAL", // 227 (485) - "CHARACTER", // 228 (486) - "CHARACTERS", // 229 (487) - "CHECKING", // 230 (488) - "CLASS", // 231 (489) - "COBOL", // 232 (490) - "CODE", // 233 (491) - "CODE-SET", // 234 (492) - "COLLATING", // 235 (493) - "COLUMN", // 236 (494) - "COMBINED-DATETIME", // 237 (495) - "COMMA", // 238 (496) - "COMMAND-LINE", // 239 (497) - "COMMAND-LINE-COUNT", // 240 (498) - "COMMIT", // 241 (499) - "COMMON", // 242 (500) - "CONCAT", // 243 (501) - "CONDITION", // 244 (502) - "CONFIGURATION", // 245 (503) - "CONTAINS", // 246 (504) - "CONTENT", // 247 (505) - "CONTROL", // 248 (506) - "CONTROLS", // 249 (507) - "CONVERT", // 250 (508) - "CONVERTING", // 251 (509) - "CORRESPONDING", // 252 (510) - "COS", // 253 (511) - "COUNT", // 254 (512) - "CURRENCY", // 255 (513) - "CURRENT", // 256 (514) - "CURRENT-DATE", // 257 (515) - "DATA", // 258 (516) - "DATE", // 259 (517) - "DATE-COMPILED", // 260 (518) - "DATE-OF-INTEGER", // 261 (519) - "DATE-TO-YYYYMMDD", // 262 (520) - "DATE-WRITTEN", // 263 (521) - "DAY", // 264 (522) - "DAY-OF-INTEGER", // 265 (523) - "DAY-OF-WEEK", // 266 (524) - "DAY-TO-YYYYDDD", // 267 (525) - "DBCS", // 268 (526) - "DE", // 269 (527) - "DEBUGGING", // 270 (528) - "DECIMAL-POINT", // 271 (529) - "DECLARATIVES", // 272 (530) - "DEFAULT", // 273 (531) - "DELIMITED", // 274 (532) - "DELIMITER", // 275 (533) - "DEPENDING", // 276 (534) - "DESCENDING", // 277 (535) - "DETAIL", // 278 (536) - "DIRECT", // 279 (537) - "DIRECT-ACCESS", // 280 (538) - "DOWN", // 281 (539) - "DUPLICATES", // 282 (540) - "DYNAMIC", // 283 (541) - "E", // 284 (542) - "EBCDIC", // 285 (543) - "EC", // 286 (544) - "EGCS", // 287 (545) - "ENTRY", // 288 (546) - "ENVIRONMENT", // 289 (547) - "EQUAL", // 290 (548) - "EVERY", // 291 (549) - "EXAMINE", // 292 (550) - "EXHIBIT", // 293 (551) - "EXP", // 294 (552) - "EXP10", // 295 (553) - "EXTEND", // 296 (554) - "EXTERNAL", // 297 (555) - "EXCEPTION-FILE", // 298 (556) - "EXCEPTION-FILE-N", // 299 (557) - "EXCEPTION-LOCATION", // 300 (558) - "EXCEPTION-LOCATION-N", // 301 (559) - "EXCEPTION-STATEMENT", // 302 (560) - "EXCEPTION-STATUS", // 303 (561) - "FACTORIAL", // 304 (562) - "FALSE", // 305 (563) - "FD", // 306 (564) - "FILE-CONTROL", // 307 (565) - "FILE", // 308 (566) - "FILE-LIMIT", // 309 (567) - "FINAL", // 310 (568) - "FINALLY", // 311 (569) - "FIND-STRING", // 312 (570) - "FIRST", // 313 (571) - "FIXED", // 314 (572) - "FOOTING", // 315 (573) - "FOR", // 316 (574) - "FORMATTED-CURRENT-DATE", // 317 (575) - "FORMATTED-DATE", // 318 (576) - "FORMATTED-DATETIME", // 319 (577) - "FORMATTED-TIME", // 320 (578) - "FORM-OVERFLOW", // 321 (579) - "FREE", // 322 (580) - "FRACTION-PART", // 323 (581) - "FROM", // 324 (582) - "FUNCTION", // 325 (583) - "GENERATE", // 326 (584) - "GIVING", // 327 (585) - "GLOBAL", // 328 (586) - "GO", // 329 (587) - "GROUP", // 330 (588) - "HEADING", // 331 (589) - "HEX", // 332 (590) - "HEX-OF", // 333 (591) - "HEX-TO-CHAR", // 334 (592) - "HIGH-VALUES", // 335 (593) - "HIGHEST-ALGEBRAIC", // 336 (594) - "HOLD", // 337 (595) - "IBM-360", // 338 (596) - "IN", // 339 (597) - "INCLUDE", // 340 (598) - "INDEX", // 341 (599) - "INDEXED", // 342 (600) - "INDICATE", // 343 (601) - "INITIAL", // 344 (602) - "INITIATE", // 345 (603) - "INPUT", // 346 (604) - "INSTALLATION", // 347 (605) - "INTERFACE", // 348 (606) - "INTEGER", // 349 (607) - "INTEGER-OF-BOOLEAN", // 350 (608) - "INTEGER-OF-DATE", // 351 (609) - "INTEGER-OF-DAY", // 352 (610) - "INTEGER-OF-FORMATTED-DATE", // 353 (611) - "INTEGER-PART", // 354 (612) - "INTO", // 355 (613) - "INTRINSIC", // 356 (614) - "INVOKE", // 357 (615) - "I-O", // 358 (616) - "I-O-CONTROL", // 359 (617) - "IS", // 360 (618) - "ISNT", // 361 (619) - "KANJI", // 362 (620) - "KEY", // 363 (621) - "LABEL", // 364 (622) - "LAST", // 365 (623) - "LEADING", // 366 (624) - "LEFT", // 367 (625) - "LENGTH", // 368 (626) - "LENGTH-OF", // 369 (627) - "LIMIT", // 370 (628) - "LIMITS", // 371 (629) - "LINE", // 372 (630) - "LINES", // 373 (631) - "LINE-COUNTER", // 374 (632) - "LINAGE", // 375 (633) - "LINKAGE", // 376 (634) - "LOCALE", // 377 (635) - "LOCALE-COMPARE", // 378 (636) - "LOCALE-DATE", // 379 (637) - "LOCALE-TIME", // 380 (638) - "LOCALE-TIME-FROM-SECONDS", // 381 (639) - "LOCAL-STORAGE", // 382 (640) - "LOCATION", // 383 (641) - "LOCK", // 384 (642) - "LOCK-ON", // 385 (643) - "LOG", // 386 (644) - "LOG10", // 387 (645) - "LOWER-CASE", // 388 (646) - "LOW-VALUES", // 389 (647) - "LOWEST-ALGEBRAIC", // 390 (648) - "LPAREN", // 391 (649) - "MANUAL", // 392 (650) - "MAXX", // 393 (651) - "MEAN", // 394 (652) - "MEDIAN", // 395 (653) - "MIDRANGE", // 396 (654) - "MINN", // 397 (655) - "MULTIPLE", // 398 (656) - "MOD", // 399 (657) - "MODE", // 400 (658) - "MODULE-NAME", // 401 (659) - "NAMED", // 402 (660) - "NAT", // 403 (661) - "NATIONAL", // 404 (662) - "NATIONAL-EDITED", // 405 (663) - "NATIONAL-OF", // 406 (664) - "NATIVE", // 407 (665) - "NESTED", // 408 (666) - "NEXT", // 409 (667) - "NO", // 410 (668) - "NOTE", // 411 (669) - "NULLS", // 412 (670) - "NULLPTR", // 413 (671) - "NUMERIC", // 414 (672) - "NUMERIC-EDITED", // 415 (673) - "NUMVAL", // 416 (674) - "NUMVAL-C", // 417 (675) - "NUMVAL-F", // 418 (676) - "OCCURS", // 419 (677) - "OF", // 420 (678) - "OFF", // 421 (679) - "OMITTED", // 422 (680) - "ON", // 423 (681) - "ONLY", // 424 (682) - "OPTIONAL", // 425 (683) - "OPTIONS", // 426 (684) - "ORD", // 427 (685) - "ORDER", // 428 (686) - "ORD-MAX", // 429 (687) - "ORD-MIN", // 430 (688) - "ORGANIZATION", // 431 (689) - "OTHER", // 432 (690) - "OTHERWISE", // 433 (691) - "OUTPUT", // 434 (692) - "PACKED-DECIMAL", // 435 (693) - "PADDING", // 436 (694) - "PAGE", // 437 (695) - "PAGE-COUNTER", // 438 (696) - "PF", // 439 (697) - "PH", // 440 (698) - "PI", // 441 (699) - "PIC", // 442 (700) - "PICTURE", // 443 (701) - "PLUS", // 444 (702) - "PRESENT-VALUE", // 445 (703) - "PRINT-SWITCH", // 446 (704) - "PROCEDURE", // 447 (705) - "PROCEDURES", // 448 (706) - "PROCEED", // 449 (707) - "PROCESS", // 450 (708) - "PROGRAM-ID", // 451 (709) - "PROGRAM", // 452 (710) - "PROPERTY", // 453 (711) - "PROTOTYPE", // 454 (712) - "PSEUDOTEXT", // 455 (713) - "QUOTES", // 456 (714) - "RANDOM", // 457 (715) - "RANDOM-SEED", // 458 (716) - "RANGE", // 459 (717) - "RAISE", // 460 (718) - "RAISING", // 461 (719) - "RD", // 462 (720) - "RECORD", // 463 (721) - "RECORDING", // 464 (722) - "RECORDS", // 465 (723) - "RECURSIVE", // 466 (724) - "REDEFINES", // 467 (725) - "REEL", // 468 (726) - "REFERENCE", // 469 (727) - "RELATIVE", // 470 (728) - "REM", // 471 (729) - "REMAINDER", // 472 (730) - "REMARKS", // 473 (731) - "REMOVAL", // 474 (732) - "RENAMES", // 475 (733) - "REPLACE", // 476 (734) - "REPLACING", // 477 (735) - "REPORT", // 478 (736) - "REPORTING", // 479 (737) - "REPORTS", // 480 (738) - "REPOSITORY", // 481 (739) - "RERUN", // 482 (740) - "RESERVE", // 483 (741) - "RESTRICTED", // 484 (742) - "RESUME", // 485 (743) - "REVERSE", // 486 (744) - "REVERSED", // 487 (745) - "REWIND", // 488 (746) - "RF", // 489 (747) - "RH", // 490 (748) - "RIGHT", // 491 (749) - "ROUNDED", // 492 (750) - "RUN", // 493 (751) - "SAME", // 494 (752) - "SCREEN", // 495 (753) - "SD", // 496 (754) - "SECONDS-FROM-FORMATTED-TIME", // 497 (755) - "SECONDS-PAST-MIDNIGHT", // 498 (756) - "SECURITY", // 499 (757) - "SEPARATE", // 500 (758) - "SEQUENCE", // 501 (759) - "SEQUENTIAL", // 502 (760) - "SHARING", // 503 (761) - "SIMPLE-EXIT", // 504 (762) - "SIGN", // 505 (763) - "SIN", // 506 (764) - "SIZE", // 507 (765) - "SMALLEST-ALGEBRAIC", // 508 (766) - "SOURCE", // 509 (767) - "SOURCE-COMPUTER", // 510 (768) - "SPECIAL-NAMES", // 511 (769) - "SQRT", // 512 (770) - "STACK", // 513 (771) - "STANDARD", // 514 (772) - "STANDARD-1", // 515 (773) - "STANDARD-DEVIATION", // 516 (774) - "STANDARD-COMPARE", // 517 (775) - "STATUS", // 518 (776) - "STRONG", // 519 (777) - "SUBSTITUTE", // 520 (778) - "SUM", // 521 (779) - "SYMBOL", // 522 (780) - "SYMBOLIC", // 523 (781) - "SYNCHRONIZED", // 524 (782) - "TALLY", // 525 (783) - "TALLYING", // 526 (784) - "TAN", // 527 (785) - "TERMINATE", // 528 (786) - "TEST", // 529 (787) - "TEST-DATE-YYYYMMDD", // 530 (788) - "TEST-DAY-YYYYDDD", // 531 (789) - "TEST-FORMATTED-DATETIME", // 532 (790) - "TEST-NUMVAL", // 533 (791) - "TEST-NUMVAL-C", // 534 (792) - "TEST-NUMVAL-F", // 535 (793) - "THAN", // 536 (794) - "TIME", // 537 (795) - "TIMES", // 538 (796) - "TO", // 539 (797) - "TOP", // 540 (798) - "TOP-LEVEL", // 541 (799) - "TRACKS", // 542 (800) - "TRACK-AREA", // 543 (801) - "TRAILING", // 544 (802) - "TRANSFORM", // 545 (803) - "TRIM", // 546 (804) - "TRUE", // 547 (805) - "TRY", // 548 (806) - "TURN", // 549 (807) - "TYPE", // 550 (808) - "TYPEDEF", // 551 (809) - "ULENGTH", // 552 (810) - "UNBOUNDED", // 553 (811) - "UNIT", // 554 (812) - "UNITS", // 555 (813) - "UNIT-RECORD", // 556 (814) - "UNTIL", // 557 (815) - "UP", // 558 (816) - "UPON", // 559 (817) - "UPOS", // 560 (818) - "UPPER-CASE", // 561 (819) - "USAGE", // 562 (820) - "USING", // 563 (821) - "USUBSTR", // 564 (822) - "USUPPLEMENTARY", // 565 (823) - "UTILITY", // 566 (824) - "UUID4", // 567 (825) - "UVALID", // 568 (826) - "UWIDTH", // 569 (827) - "VALUE", // 570 (828) - "VARIANCE", // 571 (829) - "VARYING", // 572 (830) - "VOLATILE", // 573 (831) - "WHEN-COMPILED", // 574 (832) - "WITH", // 575 (833) - "WORKING-STORAGE", // 576 (834) - "XML", // 577 (835) - "XMLGENERATE", // 578 (836) - "XMLPARSE", // 579 (837) - "YEAR-TO-YYYY", // 580 (838) - "YYYYDDD", // 581 (839) - "YYYYMMDD", // 582 (840) - "ARITHMETIC", // 583 (841) - "ATTRIBUTE", // 584 (842) - "AUTO", // 585 (843) - "AUTOMATIC", // 586 (844) - "AWAY-FROM-ZERO", // 587 (845) - "BACKGROUND-COLOR", // 588 (846) - "BELL", // 589 (847) - "BINARY-ENCODING", // 590 (848) - "BLINK", // 591 (849) - "CAPACITY", // 592 (850) - "CENTER", // 593 (851) - "CLASSIFICATION", // 594 (852) - "CYCLE", // 595 (853) - "DECIMAL-ENCODING", // 596 (854) - "ENTRY-CONVENTION", // 597 (855) - "EOL", // 598 (856) - "EOS", // 599 (857) - "ERASE", // 600 (858) - "EXPANDS", // 601 (859) - "FLOAT-BINARY", // 602 (860) - "FLOAT-DECIMAL", // 603 (861) - "FOREGROUND-COLOR", // 604 (862) - "FOREVER", // 605 (863) - "FULL", // 606 (864) - "HIGHLIGHT", // 607 (865) - "HIGH-ORDER-LEFT", // 608 (866) - "HIGH-ORDER-RIGHT", // 609 (867) - "IGNORING", // 610 (868) - "IMPLEMENTS", // 611 (869) - "INITIALIZED", // 612 (870) - "INTERMEDIATE", // 613 (871) - "LC-ALL", // 614 (872) - "LC-COLLATE", // 615 (873) - "LC-CTYPE", // 616 (874) - "LC-MESSAGES", // 617 (875) - "LC-MONETARY", // 618 (876) - "LC-NUMERIC", // 619 (877) - "LC-TIME", // 620 (878) - "LOWLIGHT", // 621 (879) - "NEAREST-AWAY-FROM-ZERO", // 622 (880) - "NEAREST-EVEN", // 623 (881) - "NEAREST-TOWARD-ZERO", // 624 (882) - "NONE", // 625 (883) - "NORMAL", // 626 (884) - "NUMBERS", // 627 (885) - "PREFIXED", // 628 (886) - "PREVIOUS", // 629 (887) - "PROHIBITED", // 630 (888) - "RELATION", // 631 (889) - "REQUIRED", // 632 (890) - "REVERSE-VIDEO", // 633 (891) - "ROUNDING", // 634 (892) - "SECONDS", // 635 (893) - "SECURE", // 636 (894) - "SHORT", // 637 (895) - "SIGNED", // 638 (896) - "STANDARD-BINARY", // 639 (897) - "STANDARD-DECIMAL", // 640 (898) - "STATEMENT", // 641 (899) - "STEP", // 642 (900) - "STRUCTURE", // 643 (901) - "TOWARD-GREATER", // 644 (902) - "TOWARD-LESSER", // 645 (903) - "TRUNCATION", // 646 (904) - "UCS-4", // 647 (905) - "UNDERLINE", // 648 (906) - "UNSIGNED", // 649 (907) - "UTF-16", // 650 (908) - "UTF-8", // 651 (909) - "ADDRESS", // 652 (910) - "END-ACCEPT", // 653 (911) - "END-ADD", // 654 (912) - "END-CALL", // 655 (913) - "END-COMPUTE", // 656 (914) - "END-DELETE", // 657 (915) - "END-DISPLAY", // 658 (916) - "END-DIVIDE", // 659 (917) - "END-EVALUATE", // 660 (918) - "END-MULTIPLY", // 661 (919) - "END-PERFORM", // 662 (920) - "END-READ", // 663 (921) - "END-RETURN", // 664 (922) - "END-REWRITE", // 665 (923) - "END-SEARCH", // 666 (924) - "END-START", // 667 (925) - "END-STRING", // 668 (926) - "END-SUBTRACT", // 669 (927) - "END-UNSTRING", // 670 (928) - "END-WRITE", // 671 (929) - "END-IF", // 672 (930) - "THRU", // 673 (931) - "OR", // 674 (932) - "AND", // 675 (933) - "NOT", // 676 (934) - "NE", // 677 (935) - "LE", // 678 (936) - "GE", // 679 (937) - "POW", // 680 (938) - "NEG", // 681 (939) + "CALL-CONVENTION", // 133 (391) + "CALL-COBOL", // 134 (392) + "CALL-VERBATIM", // 135 (393) + "CDF-PUSH", // 136 (394) + "CDF-POP", // 137 (395) + "SOURCE-FORMAT", // 138 (396) + "IF", // 139 (397) + "THEN", // 140 (398) + "ELSE", // 141 (399) + "SENTENCE", // 142 (400) + "ACCEPT", // 143 (401) + "ADD", // 144 (402) + "ALTER", // 145 (403) + "CALL", // 146 (404) + "CANCEL", // 147 (405) + "CLOSE", // 148 (406) + "COMPUTE", // 149 (407) + "CONTINUE", // 150 (408) + "DELETE", // 151 (409) + "DISPLAY", // 152 (410) + "DIVIDE", // 153 (411) + "EVALUATE", // 154 (412) + "EXIT", // 155 (413) + "FILLER", // 156 (414) + "GOBACK", // 157 (415) + "GOTO", // 158 (416) + "INITIALIZE", // 159 (417) + "INSPECT", // 160 (418) + "MERGE", // 161 (419) + "MOVE", // 162 (420) + "MULTIPLY", // 163 (421) + "OPEN", // 164 (422) + "PARAGRAPH", // 165 (423) + "READ", // 166 (424) + "RELEASE", // 167 (425) + "RETURN", // 168 (426) + "REWRITE", // 169 (427) + "SEARCH", // 170 (428) + "SET", // 171 (429) + "SELECT", // 172 (430) + "SORT", // 173 (431) + "SORT-MERGE", // 174 (432) + "STRING", // 175 (433) + "STOP", // 176 (434) + "SUBTRACT", // 177 (435) + "START", // 178 (436) + "UNSTRING", // 179 (437) + "WRITE", // 180 (438) + "WHEN", // 181 (439) + "ARGUMENT-NUMBER", // 182 (440) + "ARGUMENT-VALUE", // 183 (441) + "ENVIRONMENT-NAME", // 184 (442) + "ENVIRONMENT-VALUE", // 185 (443) + "ABS", // 186 (444) + "ACCESS", // 187 (445) + "ACOS", // 188 (446) + "ACTUAL", // 189 (447) + "ADVANCING", // 190 (448) + "AFTER", // 191 (449) + "ALL", // 192 (450) + "ALLOCATE", // 193 (451) + "ALPHABET", // 194 (452) + "ALPHABETIC", // 195 (453) + "ALPHABETIC-LOWER", // 196 (454) + "ALPHABETIC-UPPER", // 197 (455) + "ALPHANUMERIC", // 198 (456) + "ALPHANUMERIC-EDITED", // 199 (457) + "ALSO", // 200 (458) + "ALTERNATE", // 201 (459) + "ANNUITY", // 202 (460) + "ANUM", // 203 (461) + "ANY", // 204 (462) + "ANYCASE", // 205 (463) + "APPLY", // 206 (464) + "ARE", // 207 (465) + "AREA", // 208 (466) + "AREAS", // 209 (467) + "AS", // 210 (468) + "ASCENDING", // 211 (469) + "ACTIVATING", // 212 (470) + "ASIN", // 213 (471) + "ASSIGN", // 214 (472) + "AT", // 215 (473) + "ATAN", // 216 (474) + "BASED", // 217 (475) + "BASECONVERT", // 218 (476) + "BEFORE", // 219 (477) + "BINARY", // 220 (478) + "BIT", // 221 (479) + "BIT-OF", // 222 (480) + "BIT-TO-CHAR", // 223 (481) + "BLANK", // 224 (482) + "BLOCK", // 225 (483) + "BOOLEAN-OF-INTEGER", // 226 (484) + "BOTTOM", // 227 (485) + "BY", // 228 (486) + "BYTE", // 229 (487) + "BYTE-LENGTH", // 230 (488) + "CF", // 231 (489) + "CH", // 232 (490) + "CHANGED", // 233 (491) + "CHAR", // 234 (492) + "CHAR-NATIONAL", // 235 (493) + "CHARACTER", // 236 (494) + "CHARACTERS", // 237 (495) + "CHECKING", // 238 (496) + "CLASS", // 239 (497) + "COBOL", // 240 (498) + "CODE", // 241 (499) + "CODE-SET", // 242 (500) + "COLLATING", // 243 (501) + "COLUMN", // 244 (502) + "COMBINED-DATETIME", // 245 (503) + "COMMA", // 246 (504) + "COMMAND-LINE", // 247 (505) + "COMMAND-LINE-COUNT", // 248 (506) + "COMMIT", // 249 (507) + "COMMON", // 250 (508) + "CONCAT", // 251 (509) + "CONDITION", // 252 (510) + "CONFIGURATION", // 253 (511) + "CONTAINS", // 254 (512) + "CONTENT", // 255 (513) + "CONTROL", // 256 (514) + "CONTROLS", // 257 (515) + "CONVERT", // 258 (516) + "CONVERTING", // 259 (517) + "CORRESPONDING", // 260 (518) + "COS", // 261 (519) + "COUNT", // 262 (520) + "CURRENCY", // 263 (521) + "CURRENT", // 264 (522) + "CURRENT-DATE", // 265 (523) + "DATA", // 266 (524) + "DATE", // 267 (525) + "DATE-COMPILED", // 268 (526) + "DATE-OF-INTEGER", // 269 (527) + "DATE-TO-YYYYMMDD", // 270 (528) + "DATE-WRITTEN", // 271 (529) + "DAY", // 272 (530) + "DAY-OF-INTEGER", // 273 (531) + "DAY-OF-WEEK", // 274 (532) + "DAY-TO-YYYYDDD", // 275 (533) + "DBCS", // 276 (534) + "DE", // 277 (535) + "DEBUGGING", // 278 (536) + "DECIMAL-POINT", // 279 (537) + "DECLARATIVES", // 280 (538) + "DEFAULT", // 281 (539) + "DELIMITED", // 282 (540) + "DELIMITER", // 283 (541) + "DEPENDING", // 284 (542) + "DESCENDING", // 285 (543) + "DETAIL", // 286 (544) + "DIRECT", // 287 (545) + "DIRECT-ACCESS", // 288 (546) + "DOWN", // 289 (547) + "DUPLICATES", // 290 (548) + "DYNAMIC", // 291 (549) + "E", // 292 (550) + "EBCDIC", // 293 (551) + "EC", // 294 (552) + "EGCS", // 295 (553) + "ENTRY", // 296 (554) + "ENVIRONMENT", // 297 (555) + "EQUAL", // 298 (556) + "EVERY", // 299 (557) + "EXAMINE", // 300 (558) + "EXHIBIT", // 301 (559) + "EXP", // 302 (560) + "EXP10", // 303 (561) + "EXTEND", // 304 (562) + "EXTERNAL", // 305 (563) + "EXCEPTION-FILE", // 306 (564) + "EXCEPTION-FILE-N", // 307 (565) + "EXCEPTION-LOCATION", // 308 (566) + "EXCEPTION-LOCATION-N", // 309 (567) + "EXCEPTION-STATEMENT", // 310 (568) + "EXCEPTION-STATUS", // 311 (569) + "FACTORIAL", // 312 (570) + "FALSE", // 313 (571) + "FD", // 314 (572) + "FILE-CONTROL", // 315 (573) + "FILE", // 316 (574) + "FILE-LIMIT", // 317 (575) + "FINAL", // 318 (576) + "FINALLY", // 319 (577) + "FIND-STRING", // 320 (578) + "FIRST", // 321 (579) + "FIXED", // 322 (580) + "FOOTING", // 323 (581) + "FOR", // 324 (582) + "FORMATTED-CURRENT-DATE", // 325 (583) + "FORMATTED-DATE", // 326 (584) + "FORMATTED-DATETIME", // 327 (585) + "FORMATTED-TIME", // 328 (586) + "FORM-OVERFLOW", // 329 (587) + "FREE", // 330 (588) + "FRACTION-PART", // 331 (589) + "FROM", // 332 (590) + "FUNCTION", // 333 (591) + "GENERATE", // 334 (592) + "GIVING", // 335 (593) + "GLOBAL", // 336 (594) + "GO", // 337 (595) + "GROUP", // 338 (596) + "HEADING", // 339 (597) + "HEX", // 340 (598) + "HEX-OF", // 341 (599) + "HEX-TO-CHAR", // 342 (600) + "HIGH-VALUES", // 343 (601) + "HIGHEST-ALGEBRAIC", // 344 (602) + "HOLD", // 345 (603) + "IBM-360", // 346 (604) + "IN", // 347 (605) + "INCLUDE", // 348 (606) + "INDEX", // 349 (607) + "INDEXED", // 350 (608) + "INDICATE", // 351 (609) + "INITIAL", // 352 (610) + "INITIATE", // 353 (611) + "INPUT", // 354 (612) + "INSTALLATION", // 355 (613) + "INTERFACE", // 356 (614) + "INTEGER", // 357 (615) + "INTEGER-OF-BOOLEAN", // 358 (616) + "INTEGER-OF-DATE", // 359 (617) + "INTEGER-OF-DAY", // 360 (618) + "INTEGER-OF-FORMATTED-DATE", // 361 (619) + "INTEGER-PART", // 362 (620) + "INTO", // 363 (621) + "INTRINSIC", // 364 (622) + "INVOKE", // 365 (623) + "I-O", // 366 (624) + "I-O-CONTROL", // 367 (625) + "IS", // 368 (626) + "ISNT", // 369 (627) + "KANJI", // 370 (628) + "KEY", // 371 (629) + "LABEL", // 372 (630) + "LAST", // 373 (631) + "LEADING", // 374 (632) + "LEFT", // 375 (633) + "LENGTH", // 376 (634) + "LENGTH-OF", // 377 (635) + "LIMIT", // 378 (636) + "LIMITS", // 379 (637) + "LINE", // 380 (638) + "LINES", // 381 (639) + "LINE-COUNTER", // 382 (640) + "LINAGE", // 383 (641) + "LINKAGE", // 384 (642) + "LOCALE", // 385 (643) + "LOCALE-COMPARE", // 386 (644) + "LOCALE-DATE", // 387 (645) + "LOCALE-TIME", // 388 (646) + "LOCALE-TIME-FROM-SECONDS", // 389 (647) + "LOCAL-STORAGE", // 390 (648) + "LOCATION", // 391 (649) + "LOCK", // 392 (650) + "LOCK-ON", // 393 (651) + "LOG", // 394 (652) + "LOG10", // 395 (653) + "LOWER-CASE", // 396 (654) + "LOW-VALUES", // 397 (655) + "LOWEST-ALGEBRAIC", // 398 (656) + "LPAREN", // 399 (657) + "MANUAL", // 400 (658) + "MAXX", // 401 (659) + "MEAN", // 402 (660) + "MEDIAN", // 403 (661) + "MIDRANGE", // 404 (662) + "MINN", // 405 (663) + "MULTIPLE", // 406 (664) + "MOD", // 407 (665) + "MODE", // 408 (666) + "MODULE-NAME", // 409 (667) + "NAMED", // 410 (668) + "NAT", // 411 (669) + "NATIONAL", // 412 (670) + "NATIONAL-EDITED", // 413 (671) + "NATIONAL-OF", // 414 (672) + "NATIVE", // 415 (673) + "NESTED", // 416 (674) + "NEXT", // 417 (675) + "NO", // 418 (676) + "NOTE", // 419 (677) + "NULLS", // 420 (678) + "NULLPTR", // 421 (679) + "NUMERIC", // 422 (680) + "NUMERIC-EDITED", // 423 (681) + "NUMVAL", // 424 (682) + "NUMVAL-C", // 425 (683) + "NUMVAL-F", // 426 (684) + "OCCURS", // 427 (685) + "OF", // 428 (686) + "OFF", // 429 (687) + "OMITTED", // 430 (688) + "ON", // 431 (689) + "ONLY", // 432 (690) + "OPTIONAL", // 433 (691) + "OPTIONS", // 434 (692) + "ORD", // 435 (693) + "ORDER", // 436 (694) + "ORD-MAX", // 437 (695) + "ORD-MIN", // 438 (696) + "ORGANIZATION", // 439 (697) + "OTHER", // 440 (698) + "OTHERWISE", // 441 (699) + "OUTPUT", // 442 (700) + "PACKED-DECIMAL", // 443 (701) + "PADDING", // 444 (702) + "PAGE", // 445 (703) + "PAGE-COUNTER", // 446 (704) + "PF", // 447 (705) + "PH", // 448 (706) + "PI", // 449 (707) + "PIC", // 450 (708) + "PICTURE", // 451 (709) + "PLUS", // 452 (710) + "PRESENT-VALUE", // 453 (711) + "PRINT-SWITCH", // 454 (712) + "PROCEDURE", // 455 (713) + "PROCEDURES", // 456 (714) + "PROCEED", // 457 (715) + "PROCESS", // 458 (716) + "PROGRAM-ID", // 459 (717) + "PROGRAM", // 460 (718) + "PROPERTY", // 461 (719) + "PROTOTYPE", // 462 (720) + "PSEUDOTEXT", // 463 (721) + "QUOTES", // 464 (722) + "RANDOM", // 465 (723) + "RANDOM-SEED", // 466 (724) + "RANGE", // 467 (725) + "RAISE", // 468 (726) + "RAISING", // 469 (727) + "RD", // 470 (728) + "RECORD", // 471 (729) + "RECORDING", // 472 (730) + "RECORDS", // 473 (731) + "RECURSIVE", // 474 (732) + "REDEFINES", // 475 (733) + "REEL", // 476 (734) + "REFERENCE", // 477 (735) + "RELATIVE", // 478 (736) + "REM", // 479 (737) + "REMAINDER", // 480 (738) + "REMARKS", // 481 (739) + "REMOVAL", // 482 (740) + "RENAMES", // 483 (741) + "REPLACE", // 484 (742) + "REPLACING", // 485 (743) + "REPORT", // 486 (744) + "REPORTING", // 487 (745) + "REPORTS", // 488 (746) + "REPOSITORY", // 489 (747) + "RERUN", // 490 (748) + "RESERVE", // 491 (749) + "RESTRICTED", // 492 (750) + "RESUME", // 493 (751) + "REVERSE", // 494 (752) + "REVERSED", // 495 (753) + "REWIND", // 496 (754) + "RF", // 497 (755) + "RH", // 498 (756) + "RIGHT", // 499 (757) + "ROUNDED", // 500 (758) + "RUN", // 501 (759) + "SAME", // 502 (760) + "SCREEN", // 503 (761) + "SD", // 504 (762) + "SECONDS-FROM-FORMATTED-TIME", // 505 (763) + "SECONDS-PAST-MIDNIGHT", // 506 (764) + "SECURITY", // 507 (765) + "SEPARATE", // 508 (766) + "SEQUENCE", // 509 (767) + "SEQUENTIAL", // 510 (768) + "SHARING", // 511 (769) + "SIMPLE-EXIT", // 512 (770) + "SIGN", // 513 (771) + "SIN", // 514 (772) + "SIZE", // 515 (773) + "SMALLEST-ALGEBRAIC", // 516 (774) + "SOURCE", // 517 (775) + "SOURCE-COMPUTER", // 518 (776) + "SPECIAL-NAMES", // 519 (777) + "SQRT", // 520 (778) + "STACK", // 521 (779) + "STANDARD", // 522 (780) + "STANDARD-1", // 523 (781) + "STANDARD-DEVIATION", // 524 (782) + "STANDARD-COMPARE", // 525 (783) + "STATUS", // 526 (784) + "STRONG", // 527 (785) + "SUBSTITUTE", // 528 (786) + "SUM", // 529 (787) + "SYMBOL", // 530 (788) + "SYMBOLIC", // 531 (789) + "SYNCHRONIZED", // 532 (790) + "TALLY", // 533 (791) + "TALLYING", // 534 (792) + "TAN", // 535 (793) + "TERMINATE", // 536 (794) + "TEST", // 537 (795) + "TEST-DATE-YYYYMMDD", // 538 (796) + "TEST-DAY-YYYYDDD", // 539 (797) + "TEST-FORMATTED-DATETIME", // 540 (798) + "TEST-NUMVAL", // 541 (799) + "TEST-NUMVAL-C", // 542 (800) + "TEST-NUMVAL-F", // 543 (801) + "THAN", // 544 (802) + "TIME", // 545 (803) + "TIMES", // 546 (804) + "TO", // 547 (805) + "TOP", // 548 (806) + "TOP-LEVEL", // 549 (807) + "TRACKS", // 550 (808) + "TRACK-AREA", // 551 (809) + "TRAILING", // 552 (810) + "TRANSFORM", // 553 (811) + "TRIM", // 554 (812) + "TRUE", // 555 (813) + "TRY", // 556 (814) + "TURN", // 557 (815) + "TYPE", // 558 (816) + "TYPEDEF", // 559 (817) + "ULENGTH", // 560 (818) + "UNBOUNDED", // 561 (819) + "UNIT", // 562 (820) + "UNITS", // 563 (821) + "UNIT-RECORD", // 564 (822) + "UNTIL", // 565 (823) + "UP", // 566 (824) + "UPON", // 567 (825) + "UPOS", // 568 (826) + "UPPER-CASE", // 569 (827) + "USAGE", // 570 (828) + "USING", // 571 (829) + "USUBSTR", // 572 (830) + "USUPPLEMENTARY", // 573 (831) + "UTILITY", // 574 (832) + "UUID4", // 575 (833) + "UVALID", // 576 (834) + "UWIDTH", // 577 (835) + "VALUE", // 578 (836) + "VARIANCE", // 579 (837) + "VARYING", // 580 (838) + "VOLATILE", // 581 (839) + "WHEN-COMPILED", // 582 (840) + "WITH", // 583 (841) + "WORKING-STORAGE", // 584 (842) + "XML", // 585 (843) + "XMLGENERATE", // 586 (844) + "XMLPARSE", // 587 (845) + "YEAR-TO-YYYY", // 588 (846) + "YYYYDDD", // 589 (847) + "YYYYMMDD", // 590 (848) + "ARITHMETIC", // 591 (849) + "ATTRIBUTE", // 592 (850) + "AUTO", // 593 (851) + "AUTOMATIC", // 594 (852) + "AWAY-FROM-ZERO", // 595 (853) + "BACKGROUND-COLOR", // 596 (854) + "BELL", // 597 (855) + "BINARY-ENCODING", // 598 (856) + "BLINK", // 599 (857) + "CAPACITY", // 600 (858) + "CENTER", // 601 (859) + "CLASSIFICATION", // 602 (860) + "CYCLE", // 603 (861) + "DECIMAL-ENCODING", // 604 (862) + "ENTRY-CONVENTION", // 605 (863) + "EOL", // 606 (864) + "EOS", // 607 (865) + "ERASE", // 608 (866) + "EXPANDS", // 609 (867) + "FLOAT-BINARY", // 610 (868) + "FLOAT-DECIMAL", // 611 (869) + "FOREGROUND-COLOR", // 612 (870) + "FOREVER", // 613 (871) + "FULL", // 614 (872) + "HIGHLIGHT", // 615 (873) + "HIGH-ORDER-LEFT", // 616 (874) + "HIGH-ORDER-RIGHT", // 617 (875) + "IGNORING", // 618 (876) + "IMPLEMENTS", // 619 (877) + "INITIALIZED", // 620 (878) + "INTERMEDIATE", // 621 (879) + "LC-ALL", // 622 (880) + "LC-COLLATE", // 623 (881) + "LC-CTYPE", // 624 (882) + "LC-MESSAGES", // 625 (883) + "LC-MONETARY", // 626 (884) + "LC-NUMERIC", // 627 (885) + "LC-TIME", // 628 (886) + "LOWLIGHT", // 629 (887) + "NEAREST-AWAY-FROM-ZERO", // 630 (888) + "NEAREST-EVEN", // 631 (889) + "NEAREST-TOWARD-ZERO", // 632 (890) + "NONE", // 633 (891) + "NORMAL", // 634 (892) + "NUMBERS", // 635 (893) + "PREFIXED", // 636 (894) + "PREVIOUS", // 637 (895) + "PROHIBITED", // 638 (896) + "RELATION", // 639 (897) + "REQUIRED", // 640 (898) + "REVERSE-VIDEO", // 641 (899) + "ROUNDING", // 642 (900) + "SECONDS", // 643 (901) + "SECURE", // 644 (902) + "SHORT", // 645 (903) + "SIGNED", // 646 (904) + "STANDARD-BINARY", // 647 (905) + "STANDARD-DECIMAL", // 648 (906) + "STATEMENT", // 649 (907) + "STEP", // 650 (908) + "STRUCTURE", // 651 (909) + "TOWARD-GREATER", // 652 (910) + "TOWARD-LESSER", // 653 (911) + "TRUNCATION", // 654 (912) + "UCS-4", // 655 (913) + "UNDERLINE", // 656 (914) + "UNSIGNED", // 657 (915) + "UTF-16", // 658 (916) + "UTF-8", // 659 (917) + "ADDRESS", // 660 (918) + "END-ACCEPT", // 661 (919) + "END-ADD", // 662 (920) + "END-CALL", // 663 (921) + "END-COMPUTE", // 664 (922) + "END-DELETE", // 665 (923) + "END-DISPLAY", // 666 (924) + "END-DIVIDE", // 667 (925) + "END-EVALUATE", // 668 (926) + "END-MULTIPLY", // 669 (927) + "END-PERFORM", // 670 (928) + "END-READ", // 671 (929) + "END-RETURN", // 672 (930) + "END-REWRITE", // 673 (931) + "END-SEARCH", // 674 (932) + "END-START", // 675 (933) + "END-STRING", // 676 (934) + "END-SUBTRACT", // 677 (935) + "END-UNSTRING", // 678 (936) + "END-WRITE", // 679 (937) + "END-IF", // 680 (938) + "THRU", // 681 (939) + "OR", // 682 (940) + "AND", // 683 (941) + "NOT", // 684 (942) + "NE", // 685 (943) + "LE", // 686 (944) + "GE", // 687 (945) + "POW", // 688 (946) + "NEG", // 689 (947) }; diff --git a/gcc/cobol/udf/stored-char-length.cbl b/gcc/cobol/udf/stored-char-length.cbl index 9ab3b14eb465..66889d021e6d 100644 --- a/gcc/cobol/udf/stored-char-length.cbl +++ b/gcc/cobol/udf/stored-char-length.cbl @@ -1,3 +1,6 @@ + >> PUSH source format + >>SOURCE format is fixed + * This function is in public domain. * Contributed by James K. Lowden of Cobolworx in August 2024 @@ -13,3 +16,4 @@ to Output-Value. End Function STORED-CHAR-LENGTH. + >> pop source format \ No newline at end of file diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc index 75a0b26c0a91..69b758a01b3a 100644 --- a/gcc/cobol/util.cc +++ b/gcc/cobol/util.cc @@ -34,29 +34,32 @@ * header files. */ -#include "cobol-system.h" -#include "coretypes.h" -#include "tree.h" +#include <cobol-system.h> +#include <coretypes.h> +#include <tree.h> #undef yy_flex_debug #include <langinfo.h> -#include "coretypes.h" -#include "version.h" -#include "demangle.h" -#include "intl.h" -#include "backtrace.h" -#include "diagnostic.h" -#include "diagnostic-color.h" -#include "diagnostic-url.h" -#include "diagnostic-metadata.h" -#include "diagnostic-path.h" -#include "edit-context.h" -#include "selftest.h" -#include "selftest-diagnostic.h" -#include "opts.h" +#include <coretypes.h> +#include <version.h> +#include <demangle.h> +#include <intl.h> +#include <backtrace.h> +#include <diagnostic.h> +#include <diagnostic-color.h> +#include <diagnostic-url.h> +#include <diagnostic-metadata.h> +#include <diagnostic-path.h> +#include <edit-context.h> +#include <selftest.h> +#include <selftest-diagnostic.h> +#include <opts.h> + #include "util.h" + #include "cbldiag.h" +#include "cdfval.h" #include "lexio.h" #include "../../libgcobol/ec.h" @@ -65,6 +68,7 @@ #include "inspect.h" #include "../../libgcobol/io.h" #include "genapi.h" +#include "genutil.h" #pragma GCC diagnostic ignored "-Wunused-result" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" @@ -89,11 +93,179 @@ static inline char * get_current_dir_name () { /* Use libiberty's allocator here. */ - char *buf = (char *) xmalloc (PATH_MAX); + char *buf = static_cast<char *>(xmalloc (PATH_MAX)); return getcwd (buf, PATH_MAX); } #endif +/* + * For printing messages, usually the size of the thing is some kind of string + * length, and doesn't really need a size_t. For message formatting, use a + * simple unsigned long, and warn if that's no good. "gb4" here stands for + * "4 Gigabytes". + */ +unsigned long +gb4( size_t input ) { + if( input != static_cast<unsigned long>(input) ) { + yywarn("size too large to print: %lx:%lx", + (unsigned long)(input >> (4 * sizeof(unsigned long))), + static_cast<unsigned long>(input)); + } + return input; +} + +/* + * Most CDF Directives -- those that have state -- can be pushed and popped. + * This class maintains stacks of them, with each stack having a "default + * value" that may be updated, without push/pop, via a CDF directive or + * command-line option. A push to a stack pushes the default value onto it; a + * pop copies the top of the stack to the default value. + * + * Supported: + * CALL-CONVENTION + * COBOL-WORDS + * DEFINE + * DISPLAY + * IF + * POP + * PUSH + * SOURCE FORMAT + * TURN + * not supported + * EVALUATE + * FLAG-02 + * FLAG-14 + * LEAP-SECOND + * LISTING + * PAGE + * PROPAGATE + * REF-MOD-ZERO-LENGTH + * + * >>PUSH ALL calls the class's push() method. + * >>POP ALL calls the class's pop() method. + */ +class cdf_directives_t +{ + template <typename T> + class cdf_stack_t : private std::stack<T> { // cppcheck-suppress noConstructor + T default_value; + const T& top() const { return std::stack<T>::top(); } + bool empty() const { return std::stack<T>::empty(); } + public: + void value( const T& value ) { + T& output( empty()? default_value : std::stack<T>::top() ); // cppcheck-suppress constVariableReference + output = value; + dbgmsg("cdf_directives_t::%s: %s", __func__, str(output).c_str()); + } + T& value() { + return empty()? default_value : std::stack<T>::top(); + } + void push() { + std::stack<T>::push(value()); + dbgmsg("cdf_directives_t::%s: %s", __func__, str(top()).c_str()); + } + void pop() { + if( empty() ) { + error_msg(YYLTYPE(), "CDF stack empty"); // cppcheck-suppress syntaxError + return; + } + default_value = top(); + std::stack<T>::pop(); + dbgmsg("cdf_directives_t::%s: %s", __func__, str(default_value).c_str()); + } + protected: + static std::string str(cbl_call_convention_t arg) { + char output[2] = { static_cast<char>(arg) }; + return std::string("call-convention ") + output; + } + static std::string str(current_tokens_t) { + return "<cobol-words>"; + } + static std::string str(cdf_values_t) { + return "<dictionary>"; + } + static std::string str(source_format_t arg) { + return arg.description(); + } + static std::string str(cbl_enabled_exceptions_t) { + return "<enabled_exceptions>"; + } + }; + + public: + cdf_stack_t<cbl_call_convention_t> call_convention; + cdf_stack_t<current_tokens_t> cobol_words; + cdf_stack_t<cdf_values_t> dictionary; // DEFINE + cdf_stack_t<source_format_t> source_format; + cdf_stack_t<cbl_enabled_exceptions_t> enabled_exceptions; + + cdf_directives_t() { + call_convention.value() = cbl_call_cobol_e; + } + + void push() { + call_convention.push(); + cobol_words.push(); + dictionary.push(); + source_format.push(); + enabled_exceptions.push(); + } + void pop() { + call_convention.pop(); + cobol_words.pop(); + dictionary.pop(); + source_format.pop(); + enabled_exceptions.pop(); + } +}; +static cdf_directives_t cdf_directives; + +void +current_call_convention( cbl_call_convention_t convention) { + cdf_directives.call_convention.value(convention); +} +cbl_call_convention_t +current_call_convention() { + return cdf_directives.call_convention.value(); +} + +current_tokens_t& +cdf_current_tokens() { + return cdf_directives.cobol_words.value(); +} + +cdf_values_t& +cdf_dictionary() { + return cdf_directives.dictionary.value(); +} + +void +cobol_set_indicator_column( int column ) { + cdf_directives.source_format.value().indicator_column_set(column); +} +source_format_t& cdf_source_format() { + return cdf_directives.source_format.value(); +} + +cbl_enabled_exceptions_t& +cdf_enabled_exceptions() { + return cdf_directives.enabled_exceptions.value(); +} + +void cdf_push() { cdf_directives.push(); } +void cdf_push_call_convention() { cdf_directives.call_convention.push(); } +void cdf_push_current_tokens() { cdf_directives.cobol_words.push(); } +void cdf_push_dictionary() { cdf_directives.dictionary.push(); } +void cdf_push_enabled_exceptions() { cdf_directives.enabled_exceptions.push(); } +void cdf_push_source_format() { cdf_directives.source_format.push(); } + +void cdf_pop() { cdf_directives.pop(); } +void cdf_pop_call_convention() { cdf_directives.call_convention.pop(); } +void cdf_pop_current_tokens() { cdf_directives.cobol_words.pop(); } +void cdf_pop_dictionary() { cdf_directives.dictionary.pop(); } +void cdf_pop_enabled_exceptions() { cdf_directives.enabled_exceptions.pop(); } +void cdf_pop_source_format() { cdf_directives.source_format.pop(); } + const char * symbol_type_str( enum symbol_type_t type ) { @@ -113,7 +285,7 @@ symbol_type_str( enum symbol_type_t type ) case SymDataSection: return "SymDataSection"; } - dbgmsg("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type); + cbl_internal_error("%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type); return "???"; } @@ -162,7 +334,7 @@ cbl_field_type_str( enum cbl_field_type_t type ) case FldBlob: return "FldBlob"; } - dbgmsg("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type); + cbl_internal_error("%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type); return "???"; } @@ -348,51 +520,50 @@ normalize_picture( char picture[] ) regmatch_t pmatch[4]; if( (erc = regcomp(preg, regex, cflags)) != 0 ) { - regerror(erc, preg, regexmsg, sizeof(regexmsg)); - dbgmsg( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); - return picture; + regerror(erc, preg, regexmsg, sizeof(regexmsg)); + dbgmsg( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); + return picture; } while( (erc = regexec(preg, picture, COUNT_OF(pmatch), pmatch, 0)) == 0 ) { - assert(pmatch[1].rm_so != -1 && pmatch[1].rm_so < pmatch[1].rm_eo); - size_t len = pmatch[1].rm_eo - pmatch[1].rm_so; - assert(len == 1); - const char *start = picture + pmatch[1].rm_so; - - assert(pmatch[2].rm_so != -2 && pmatch[2].rm_so < pmatch[2].rm_eo); - len = pmatch[2].rm_eo - pmatch[2].rm_so; - assert(len > 0); - - /* - * Overwrite e.g. A(4) with AAAA. - */ - assert(pmatch[2].rm_so == pmatch[1].rm_eo + 1); // character paren number - p = picture + pmatch[2].rm_so; - len = 0; - fmt_size_t lenf = 0; - if( 1 != sscanf(p, "%" GCC_PRISZ "u", &lenf) ) { - dbgmsg("%s:%d: no number found in '%s'", __func__, __LINE__, p); - goto irregular; - } - len = lenf; - if( len == 0 ) { - dbgmsg("%s:%d: ZERO length found in '%s'", __func__, __LINE__, p); - goto irregular; - } + assert(pmatch[1].rm_so != -1 && pmatch[1].rm_so < pmatch[1].rm_eo); + size_t len = pmatch[1].rm_eo - pmatch[1].rm_so; + assert(len == 1); + const char *start = picture + pmatch[1].rm_so; + + assert(pmatch[2].rm_so != -2 && pmatch[2].rm_so < pmatch[2].rm_eo); + len = pmatch[2].rm_eo - pmatch[2].rm_so; + assert(len > 0); + + /* + * Overwrite e.g. A(4) with AAAA. + */ + assert(pmatch[2].rm_so == pmatch[1].rm_eo + 1); // character paren number + p = picture + pmatch[2].rm_so; + len = 0; + fmt_size_t lenf = 0; + if( 1 != sscanf(p, "%" GCC_PRISZ "u", &lenf) ) { + dbgmsg("%s:%d: no number found in '%s'", __func__, __LINE__, p); + goto irregular; + } + len = lenf; + if( len == 0 ) { + dbgmsg("%s:%d: ZERO length found in '%s'", __func__, __LINE__, p); + goto irregular; + } - std::vector <char> pic(len + 1, '\0'); - memset(pic.data(), *start, len); - const char *finish = picture + pmatch[2].rm_eo, - *eopicture = picture + strlen(picture); + std::vector <char> pic(len + 1, '\0'); + memset(pic.data(), *start, len); + const char *finish = picture + pmatch[2].rm_eo, + *eopicture = picture + strlen(picture); - p = xasprintf( "%*s%s%*s", - (int)(start - picture), picture, - pic.data(), - (int)(eopicture - finish), finish ); + p = xasprintf( "%*s%s%*s", + (int)(start - picture), picture, + pic.data(), + (int)(eopicture - finish), finish ); - free(picture); - picture = p; - continue; + free(picture); + picture = p; } assert(erc == REG_NOMATCH); @@ -463,7 +634,7 @@ is_elementary( enum cbl_field_type_t type ) case FldFloat: return true; // takes up space } - dbgmsg("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type); + cbl_internal_error("%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type); return false; } @@ -775,7 +946,7 @@ symbol_field_type_update( cbl_field_t *field, bool redefine_field( cbl_field_t *field ) { - cbl_field_t *primary = symbol_redefines(field); + const cbl_field_t *primary = symbol_redefines(field); bool fOK = true; if( !primary ) return false; @@ -823,7 +994,7 @@ cbl_field_t::report_invalid_initial_value(const YYLTYPE& loc) const { // 8 or more, we need do no further testing because we assume // everything fits. if( data.capacity < 8 ) { - auto p = strchr(data.initial, symbol_decimal_point()); + const char *p = strchr(data.initial, symbol_decimal_point()); if( p && atoll(p+1) != 0 ) { error_msg(loc, "integer type %s VALUE '%s' " "requires integer VALUE", @@ -886,8 +1057,8 @@ cbl_field_t::report_invalid_initial_value(const YYLTYPE& loc) const { return TOUPPER(ch) == 'E'; } ); if( !has_exponent && data.precision() < pend - p ) { - error_msg(loc, "%s cannot represent VALUE '%s' exactly (max .%zu)", - name, data.initial, pend - p); + error_msg(loc, "%s cannot represent VALUE %qs exactly (max %c%ld)", + name, data.initial, '.', (long)(pend - p)); } } } @@ -945,8 +1116,7 @@ const cbl_field_t * literal_subscript_oob( const cbl_refer_t& r, size_t& isub /* output */) { // Verify literal subscripts if dimensions are correct. size_t ndim(dimensions(r.field)); - if( ndim == 0 || ndim != r.nsubscript ) return NULL; - cbl_refer_t *esub = r.subscripts + r.nsubscript; + if( ndim == 0 || ndim != r.nsubscript() ) return NULL; std::vector<cbl_field_t *> dims( ndim, NULL ); auto pdim = dims.end(); @@ -964,33 +1134,31 @@ literal_subscript_oob( const cbl_refer_t& r, size_t& isub /* output */) { * for the corresponding dimension. Return the first subscript not * meeting those criteria, if any. */ - auto p = std::find_if( r.subscripts, esub, - [&pdim]( const cbl_refer_t& r ) { + auto psub = std::find_if( r.subscripts.begin(), r.subscripts.end(), + [pdim]( const cbl_refer_t& r ) mutable { const auto& occurs((*pdim)->occurs); pdim++; return ! occurs.subscript_ok(r.field); } ); - isub = p - r.subscripts; - return p == esub? NULL : dims[isub]; + isub = psub - r.subscripts.begin(); + return psub == r.subscripts.end()? NULL : dims[isub]; } size_t cbl_refer_t::subscripts_set( const std::list<cbl_refer_t>& subs ) { - nsubscript = subs.size(); - subscripts = new cbl_refer_t[nsubscript]; - std::copy( subs.begin(), subs.end(), subscripts ); - + subscripts.clear(); + std::copy( subs.begin(), subs.end(), std::back_inserter(subscripts) ); return dimensions(field); } const char * cbl_refer_t::str() const { - static char subscripts[64]; - sprintf(subscripts, "(%u of " HOST_SIZE_T_PRINT_UNSIGNED " dimensions)", - nsubscript, (fmt_size_t)dimensions(field)); + static char subscripts_l[64]; + sprintf(subscripts_l, "(%u of " HOST_SIZE_T_PRINT_UNSIGNED " dimensions)", + nsubscript(), (fmt_size_t)dimensions(field)); char *output = xasprintf("%s %s %s", field? field_str(field) : "(none)", - 0 < dimensions(field)? subscripts : "", + 0 < dimensions(field)? subscripts_l : "", is_refmod_reference()? "(refmod)" : "" ); return output; } @@ -1003,18 +1171,18 @@ cbl_refer_t::name() const { const char * cbl_refer_t::deref_str() const { - std::vector<char> dimstr(nsubscript * 16, '\0'); + std::vector<char> dimstr(nsubscript() * 16, '\0'); dimstr.at(0) = '('; auto p = dimstr.begin() + 1; if( !field ) return name(); - for( auto sub = subscripts; sub < subscripts + nsubscript; sub++ ) { - auto initial = sub->field->data.initial ? sub->field->data.initial : "?"; + for( const auto& sub : subscripts ) { + auto initial = sub.field->data.initial ? sub.field->data.initial : "?"; size_t len = dimstr.end() - p; p += snprintf( &*p, len, "%s ", initial ); } - if( 0 < nsubscript ) { + if( ! subscripts.empty() ) { *--p = ')'; } char *output = xasprintf("%s%s", field->name, dimstr.data()); @@ -1091,10 +1259,8 @@ valid_move( const struct cbl_field_t *tgt, const struct cbl_field_t *src ) static_assert(sizeof(matrix[0]) == COUNT_OF(matrix[0]), "matrix should be square"); - for( const cbl_field_t *args[] = {tgt, src}, **p=args; - p < args + COUNT_OF(args); p++ ) { - auto& f(**p); - switch(f.type) { + for( auto field : { src, tgt } ) { + switch(field->type) { case FldClass: case FldConditional: case FldIndex: @@ -1106,9 +1272,9 @@ valid_move( const struct cbl_field_t *tgt, const struct cbl_field_t *src ) case FldForward: case FldBlob: default: - if( sizeof(matrix[0]) < f.type ) { + if( sizeof(matrix[0]) < field->type ) { cbl_internal_error("logic error: MOVE %s %s invalid type:", - cbl_field_type_str(f.type), f.name); + cbl_field_type_str(field->type), field->name); } break; } @@ -1366,7 +1532,7 @@ class procdef_t : public procref_base_t { { assert(isym); } - procdef_t( const procref_base_t& ref ) + explicit procdef_t( const procref_base_t& ref ) : procref_base_t(ref) , isym(0) {} @@ -1375,13 +1541,6 @@ class procdef_t : public procref_base_t { return procref_base_t(*this) < procref_base_t(that); } - bool operator<( const procref_base_t& that ) const { - if( that.has_section() ) { - return procref_base_t(*this) < that; - } - return strcasecmp(paragraph(), that.paragraph()) < 0; - } - cbl_label_t * label_of() const { return isym == 0? NULL : cbl_label_of(symbol_at(isym)); } @@ -1412,7 +1571,7 @@ static procedures_t::iterator current_procedure = programs.end()->second.end(); class procedure_match { const procref_base_t& ref; public: - procedure_match( const procref_base_t& ref ) : ref(ref) {} + explicit procedure_match( const procref_base_t& ref ) : ref(ref) {} // Match a 2-name reference to section & paragraph, else to one or the other. bool operator()( procedures_t::const_reference elem ) { const procdef_t& key = elem.first; @@ -1440,7 +1599,7 @@ locally_unique( size_t program, const procdef_t& key, const procref_t& ref ) { const char *section_name = ref.has_section()? ref.section() : key.section(); procref_base_t full_ref(section_name, ref.paragraph()); - return 1 == procedures.count(full_ref); + return 1 == procedures.count(procdef_t(full_ref)); } // Add each section and paragraph to the map as it occurs in the Cobol text. @@ -1502,9 +1661,9 @@ ambiguous_reference( size_t program ) { if( proc.second.end() != ambiguous ) { if( yydebug ) { dbgmsg("%s: %s of '%s' has " HOST_SIZE_T_PRINT_UNSIGNED - "potential matches", __func__, - ambiguous->paragraph(), ambiguous->section(), - (fmt_size_t)procedures.count(*ambiguous)); + "potential matches", __func__, + ambiguous->paragraph(), ambiguous->section(), + (fmt_size_t)procedures.count(procdef_t(*ambiguous))); } return new procref_t(*ambiguous); } @@ -1531,7 +1690,7 @@ intradeclarative_reference() { class next_group { size_t isym; public: - next_group( symbol_elem_t *group ) : isym(symbol_index(group)) {} + explicit next_group( const symbol_elem_t *group ) : isym(symbol_index(group)) {} // return true if elem is not a member of the group bool operator()( const symbol_elem_t& elem ) { @@ -1578,7 +1737,7 @@ class find_corresponding { static bool any_redefines( const cbl_field_t& field, const symbol_elem_t *group ) { for( const cbl_field_t *f = &field; f && f->parent > 0; f = parent_of(f) ) { - symbol_elem_t *e = symbol_at(f->parent); + const symbol_elem_t *e = symbol_at(f->parent); if( e == group || e->type != SymField ) break; if( symbol_redefines(f) ) return true; } @@ -1701,12 +1860,13 @@ date_time_fmt( const char input[] ) { { regex_t(), 'd', "^(" DATE_FMT_B "|" DATE_FMT_E ")$" }, { regex_t(), 't', "^(" TIME_FMT_B "|" TIME_FMT_E ")$" }, }; - int erc, cflags = REG_EXTENDED | REG_ICASE, eflags=0; + int cflags = REG_EXTENDED | REG_ICASE, eflags=0; regmatch_t m[5]; char result = 0; if( ! compiled ) { for( auto& fmt : fmts ) { + int erc; if( (erc = regcomp(&fmt.reg, fmt.pattern, cflags)) != 0 ) { char msg[80]; regerror(erc, &fmt.reg, msg, sizeof(msg)); @@ -1739,11 +1899,10 @@ struct input_file_t { ino_t inode; int lineno; const char *name; - const line_map *lines; input_file_t( const char *name, ino_t inode, - int lineno=1, const line_map *lines = NULL ) - : inode(inode), lineno(lineno), name(name), lines(lines) + int lineno=1 ) + : inode(inode), lineno(lineno), name(name) { if( inode == 0 ) inode_set(); } @@ -1765,7 +1924,7 @@ class unique_stack : public std::stack<input_file_t> friend void cobol_set_pp_option(int opt); bool option_m; std::set<std::string> all_names; - + const char * no_wd( const char *wd, const char *name ) { int i; @@ -1776,10 +1935,10 @@ class unique_stack : public std::stack<input_file_t> public: unique_stack() : option_m(false) {} - + bool push( const value_type& value ) { auto ok = std::none_of( c.cbegin(), c.cend(), - [value]( auto& that ) { + [value]( const auto& that ) { return value == that; } ); if( ok ) { @@ -1799,13 +1958,19 @@ class unique_stack : public std::stack<input_file_t> (fmt_size_t)(c.size() - --n), v.lineno, no_wd(wd, v.name) ); } } else { - dbgmsg("unable to get current working directory: %m"); + dbgmsg("unable to get current working directory: %s", xstrerror(errno)); } free(wd); } return false; } - + + // Look down into the stack. peek(0) == top() + const input_file_t& peek( size_t n ) const { + gcc_assert( n < size() ); + return c.at(size() - ++n); + } + void option( int opt ) { // capture other preprocessor options eventually assert(opt == 'M'); option_m = true; @@ -1817,8 +1982,8 @@ class unique_stack : public std::stack<input_file_t> void print() const { std::string input( top().name ); printf( "%s: ", input.c_str() ); - for( auto name : all_names ) { - if( name != input ) + for( const auto& name : all_names ) { + if( name != input ) printf( "\\\n\t%s ", name.c_str() ); } printf("\n"); @@ -1835,7 +2000,7 @@ void cobol_set_pp_option(int opt) { assert(opt == 'M'); input_filenames.option_m = true; } - + /* * Maintain a stack of input filenames. Ensure the files are unique (by * inode), to prevent copybook cycles. Before pushing a new name, Record the @@ -1846,7 +2011,7 @@ void cobol_set_pp_option(int opt) { * to enforce uniqueness, and the scanner to maintain line numbers. */ bool cobol_filename( const char *name, ino_t inode ) { - line_map *lines = NULL; + //const line_map *lines = NULL; if( inode == 0 ) { auto p = old_filenames.find(name); if( p == old_filenames.end() ) { @@ -1856,30 +2021,49 @@ bool cobol_filename( const char *name, ino_t inode ) { } cbl_errx( "logic error: missing inode for %s", name); } - inode = p->second; - assert(inode != 0); + else { + inode = p->second; + assert(inode != 0); + } } linemap_add(line_table, LC_ENTER, sysp, name, 1); input_filename_vestige = name; - bool pushed = input_filenames.push( input_file_t(name, inode, 1, lines) ); - input_filenames.top().lineno = yylineno = 1; + bool pushed = input_filenames.push( input_file_t(name, inode, 1) ); return pushed; } const char * -cobol_lineno_save() { +cobol_lineno( int lineno ) { if( input_filenames.empty() ) return NULL; auto& input( input_filenames.top() ); - input.lineno = yylineno; + input.lineno = lineno; return input.name; } +/* + * This function is called from the scanner, usually when a copybook is on top + * of the input stack, before the parser retrieves the token and resets the + * current filename. For that reason, we normaly want to line number of the + * file that is about to become the current one, which is the one behind top(). + * + * If somehow we arrive here when there is nothing underneath, we return the + * current line nubmer, or zero if there's no input. The only consequence is + * that the reported line number might be wrong. + */ +int +cobol_lineno() { + if( input_filenames.empty() ) return 0; + size_t n = input_filenames.size() < 2? 0 : 1; + const auto& input( input_filenames.peek(n) ); + return input.lineno; +} + const char * cobol_filename() { return input_filenames.empty()? input_filename_vestige : input_filenames.top().name; } -const char * +void cobol_filename_restore() { assert(!input_filenames.empty()); const input_file_t& top( input_filenames.top() ); @@ -1887,23 +2071,52 @@ cobol_filename_restore() { input_filename_vestige = top.name; input_filenames.pop(); - if( input_filenames.empty() ) return NULL; + if( input_filenames.empty() ) return; - auto& input = input_filenames.top(); + const auto& input = input_filenames.top(); - input.lines = linemap_add(line_table, LC_LEAVE, sysp, NULL, 0); - - yylineno = input.lineno; - return input.name; + linemap_add(line_table, LC_LEAVE, sysp, NULL, 0); } -static location_t token_location; +static int first_line_minus_1 = 0; +static location_t token_location_minus_1 = 0; +static location_t token_location = 0; + +location_t current_token_location() { return token_location; } +location_t current_location_minus_one() { return token_location_minus_1; } +void current_location_minus_one_clear() + { + first_line_minus_1 = 0; + } template <typename LOC> static void gcc_location_set_impl( const LOC& loc ) { - token_location = linemap_line_start( line_table, loc.last_line, 80 ); + // Set the position to the first line & column in the location. + if( getenv("KILROY") ) + { + fprintf(stderr, "********** KILROY %d\n", loc.first_line); + } + + static location_t loc_m_1 = 0; + + token_location = linemap_line_start( line_table, loc.first_line, 80 ); token_location = linemap_position_for_column( line_table, loc.first_column); + + if( loc.first_line > first_line_minus_1 ) + { + // In order for GDB-COBOL to be able to step through COBOL code properly, + // it is sometimes necessary for the code at the beginning of a COBOL + // line to be using the location_t of the previous line. This is true, for + // example, when laying down the infrastructure code between the last + // statement of a paragraph and the code created at the beginning of the + // following paragragh. This code assumes that token_location values of + // interest are monotonic, and stores that prior value. + first_line_minus_1 = loc.first_line; + token_location_minus_1 = loc_m_1; + loc_m_1 = token_location; + } + location_dump(__func__, __LINE__, "parser", loc); } @@ -1926,11 +2139,9 @@ verify_format( const char gmsgid[] ) { static regex_t re; static int cflags = REG_EXTENDED; static int status = regcomp( &re, pattern, cflags ); - static char errbuf[80]; - - if( status != 0 ) { + static char errbuf[80]; int n = regerror(status, &re, errbuf, sizeof(errbuf)); gcc_assert(size_t(n) < sizeof(errbuf)); fprintf(stderr, "%s:%d: %s", __func__, __LINE__, errbuf); @@ -1949,6 +2160,13 @@ verify_format( const char gmsgid[] ) { static const diagnostic_option_id option_zero; size_t parse_error_inc(); +void gcc_location_dump() { + linemap_dump_location( line_table, token_location, stderr ); +} + + +void ydferror( const char gmsgid[], ... ) ATTRIBUTE_GCOBOL_DIAG(1, 2); + void ydferror( const char gmsgid[], ... ) { verify_format(gmsgid); @@ -1957,8 +2175,8 @@ ydferror( const char gmsgid[], ... ) { va_list ap; va_start (ap, gmsgid); rich_location richloc (line_table, token_location); - bool ret = global_dc->diagnostic_impl (&richloc, nullptr, option_zero, - gmsgid, &ap, DK_ERROR); + /*bool ret =*/ global_dc->diagnostic_impl (&richloc, nullptr, option_zero, + gmsgid, &ap, DK_ERROR); va_end (ap); } @@ -1971,7 +2189,7 @@ extern YYLTYPE yylloc; * the global token_location, which is passed to the diagnostic framework. The * original value is restored when the instantiated variable goes out of scope. */ -class temp_loc_t : protected YYLTYPE { +class temp_loc_t { location_t orig; public: temp_loc_t() : orig(token_location) { @@ -1979,14 +2197,11 @@ class temp_loc_t : protected YYLTYPE { gcc_location_set(yylloc); // use lookahead location } - temp_loc_t( const YYLTYPE& loc) : orig(token_location) { + explicit temp_loc_t( const YYLTYPE& loc) : orig(token_location) { gcc_location_set(loc); } - temp_loc_t( const YDFLTYPE& loc) : orig(token_location) { - YYLTYPE lloc = { - loc.first_line, loc.first_column, - loc.last_line, loc.last_column }; - gcc_location_set(lloc); + explicit temp_loc_t( const YDFLTYPE& loc) : orig(token_location) { + gcc_location_set(loc); } ~temp_loc_t() { if( orig != token_location ) { @@ -2025,18 +2240,36 @@ void error_msg( const YYLTYPE& loc, const char gmsgid[], ... ) { ERROR_MSG_BODY } +void error_msg( const YDFLTYPE& loc, const char gmsgid[], ... ) + ATTRIBUTE_GCOBOL_DIAG(2, 3); + void error_msg( const YDFLTYPE& loc, const char gmsgid[], ... ) { ERROR_MSG_BODY } -void -cdf_location_set(YYLTYPE loc) { - extern YDFLTYPE ydflloc; +bool +warn_msg( const YYLTYPE& loc, const char gmsgid[], ... ) { + temp_loc_t looker(loc); + verify_format(gmsgid); + auto_diagnostic_group d; + va_list ap; + va_start (ap, gmsgid); + rich_location richloc (line_table, token_location); + auto ret = emit_diagnostic_valist( DK_WARNING, token_location, + option_zero, gmsgid, &ap ); + va_end (ap); + return ret; +} - ydflloc.first_line = loc.first_line; - ydflloc.first_column = loc.first_column; - ydflloc.last_line = loc.last_line; - ydflloc.last_column = loc.last_column; +void error_msg_direct( const char gmsgid[], ... ) { + verify_format(gmsgid); + parse_error_inc(); + auto_diagnostic_group d; + va_list ap; + va_start (ap, gmsgid); + /*auto ret = */emit_diagnostic_valist( DK_ERROR, token_location, + option_zero, gmsgid, &ap ); + va_end (ap); } void @@ -2048,8 +2281,11 @@ yyerror( const char gmsgid[], ... ) { va_list ap; va_start (ap, gmsgid); rich_location richloc (line_table, token_location); - bool ret = global_dc->diagnostic_impl (&richloc, nullptr, option_zero, - gmsgid, &ap, DK_ERROR); + /*bool ret =*/ global_dc->diagnostic_impl ( &richloc, + nullptr, + option_zero, + gmsgid, + &ap, DK_ERROR); va_end (ap); global_dc->end_group(); } @@ -2092,7 +2328,7 @@ yyerrorvl( int line, const char *filename, const char fmt[], ... ) { static inline size_t matched_length( const regmatch_t& rm ) { return rm.rm_eo - rm.rm_so; } -const char * +int cobol_fileline_set( const char line[] ) { static const char pattern[] = "#line +([[:alnum:]]+) +[\"']([^\"']+). *\n"; static const int cflags = REG_EXTENDED | REG_ICASE; @@ -2105,7 +2341,7 @@ cobol_fileline_set( const char line[] ) { if( (erc = regcomp(&re, pattern, cflags)) != 0 ) { regerror(erc, &re, regexmsg, sizeof(regexmsg)); dbgmsg( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); - return line; + return 0; } preg = &re; } @@ -2113,10 +2349,10 @@ cobol_fileline_set( const char line[] ) { if( erc != REG_NOMATCH ) { regerror(erc, preg, regexmsg, sizeof(regexmsg)); dbgmsg( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); - return line; + return 0; } - error_msg(yylloc, "invalid #line directive: %s", line ); - return line; + error_msg(yylloc, "invalid %<#line%> directive: %s", line ); + return 0; } const char @@ -2125,38 +2361,39 @@ cobol_fileline_set( const char line[] ) { int fileline; if( 1 != sscanf(line_str, "%d", &fileline) ) - yywarn("could not parse line number %s from #line directive", line_str); + yywarn("could not parse line number %s from %<#line%> directive", line_str); input_file_t input_file( filename, ino_t(0), fileline ); // constructor sets inode if( input_filenames.empty() ) { - input_file.lines = linemap_add(line_table, LC_ENTER, sysp, filename, 1); input_filenames.push(input_file); } input_file_t& file = input_filenames.top(); file = input_file; - yylineno = file.lineno; - return file.name; + return file.lineno; } +//#define TIMING_PARSE +#ifdef TIMING_PARSE class cbl_timespec { - struct timespec now; + uint64_t now; // Nanoseconds public: cbl_timespec() { - clock_gettime(CLOCK_MONOTONIC, &now); + now = get_time_nanoseconds(); } double ns() const { - return now.tv_sec * 1000000000 + now.tv_nsec; + return now; } friend double operator-( const cbl_timespec& now, const cbl_timespec& then ); }; double -operator-( const cbl_timespec& then, const cbl_timespec& now ) { +operator-( const cbl_timespec& now, const cbl_timespec& then ) { return (now.ns() - then.ns()) / 1000000000; } +#endif static int parse_file( const char filename[] ) @@ -2172,15 +2409,20 @@ parse_file( const char filename[] ) return 0; } +#ifdef TIMING_PARSE cbl_timespec start; +#endif int erc = yyparse(); +#ifdef TIMING_PARSE cbl_timespec finish; double dt = finish - start; + printf("Overall parse & generate time is %.6f seconds\n", dt); +#endif + parser_leave_file(); - //printf("Overall parse & generate time is %.6f seconds\n", dt); fclose (yyin); @@ -2204,30 +2446,20 @@ cobol_set_debugging( bool flex, bool yacc, bool parser ) yy_flex_debug = flex? 1 : 0; ydfdebug = yydebug = yacc? 1 : 0; f_trace_debug = parser? 1 : 0; - - char *ind = getenv("INDICATOR_COLUMN"); - if( ind ) { - int col; - if( 1 != sscanf(ind, "%d", &col) ) { - yywarn("ignored non-integer value for INDICATOR_COLUMN=%s", ind); - } - cobol_set_indicator_column(col); - } } -os_locale_t os_locale = { "UTF-8", xstrdup("C.UTF-8") }; - +os_locale_t os_locale = { "UTF-8", "C.UTF-8" }; void cobol_parse_files (int nfile, const char **files) { - char * opaque = setlocale(LC_CTYPE, ""); + const char * opaque = setlocale(LC_CTYPE, ""); if( ! opaque ) { yywarn("setlocale: unable to initialize LOCALE"); } else { char *codeset = nl_langinfo(CODESET); if( ! codeset ) { - yywarn("nl_langinfo failed after setlocale succeeded"); + yywarn("%<nl_langinfo%> failed after %<setlocale()%> succeeded"); } else { os_locale.codeset = codeset; } @@ -2264,6 +2496,8 @@ cbl_internal_error(const char *gmsgid, ...) { va_start(ap, gmsgid); emit_diagnostic_valist( DK_ICE, token_location, option_zero, gmsgid, &ap ); va_end(ap); + abort(); // This unnecessary statement is needed so that [[noreturn]] + // // doesn't cause a warning. } void @@ -2297,8 +2531,8 @@ cbl_unimplemented_at( const YYLTYPE& loc, const char *gmsgid, ... ) { va_end(ap); } -/* - * analogs to err(3) and errx(3). +/* + * analogs to err(3) and errx(3). */ #pragma GCC diagnostic push @@ -2339,7 +2573,7 @@ dbgmsg(const char *msg, ...) { void dialect_error( const YYLTYPE& loc, const char term[], const char dialect[] ) { - error_msg(loc, "%s is not ISO syntax, requires -dialect %s", + error_msg(loc, "%s is not ISO syntax, requires %<-dialect %s%>", term, dialect); } @@ -2350,7 +2584,7 @@ bool fisdigit(int c) bool fisspace(int c) { return ISSPACE(c); - }; + } int ftolower(int c) { return TOLOWER(c); @@ -2362,7 +2596,7 @@ int ftoupper(int c) bool fisprint(int c) { return ISPRINT(c); - }; + } // 8.9 Reserved words static const std::set<std::string> reserved_words = { @@ -2433,7 +2667,7 @@ static const std::set<std::string> reserved_words = { "VOLATILE", "XML", "END-START", - + // ISO 2023 keywords "ACCEPT", "ACCESS", diff --git a/gcc/cobol/util.h b/gcc/cobol/util.h index 9a968ea16510..d478ea22731a 100644 --- a/gcc/cobol/util.h +++ b/gcc/cobol/util.h @@ -31,11 +31,13 @@ #ifndef _UTIL_H_ #define _UTIL_H_ -void cbl_message(int fd, const char *format_string, ...); -void cbl_internal_error(const char *format_string, ...); +void cbl_message(int fd, const char *format_string, ...) + ATTRIBUTE_PRINTF_2; +[[noreturn]] void cbl_internal_error(const char *format_string, ...) + ATTRIBUTE_GCOBOL_DIAG(1, 2); -void cbl_err(const char *format_string, ...); -void cbl_errx(const char *format_string, ...); +void cbl_err(const char *format_string, ...) ATTRIBUTE_GCOBOL_DIAG(1, 2); +void cbl_errx(const char *format_string, ...) ATTRIBUTE_GCOBOL_DIAG(1, 2); bool fisdigit(int c); bool fisspace(int c); @@ -45,8 +47,82 @@ bool fisprint(int c); void cobol_set_pp_option(int opt); -const char * cobol_filename_restore(); -const char * cobol_lineno_save(); +void cobol_filename_restore(); +const char * cobol_lineno( int ); +int cobol_lineno(void); +unsigned long gb4( size_t input ); + +template <typename P> +static inline const void * +as_voidp( P p ) { + return static_cast<const void *>(p); +} + +/* + * The default source format, whether free or fixed, is determined + * heuristically by examining the PROGRAM-ID line, if it exists, in the first + * input file. If that file does not have such a line, the default is free + * format. Else the format is set to fixed if anything appears on that line + * that would prohibit parsing it as free format, + */ +class source_format_t { + bool first_file, explicitly; + int left, right; +public: + source_format_t() + : first_file(true), explicitly(false), left(0), right(0) + {} + void indicator_column_set( int column ) { + explicitly = true; + if( column == 0 ) right = 0; + if( column < 0 ) { + column = -column; + right = 73; + } + left = column; + } + + bool inference_pending() { + bool tf = first_file && !explicitly; + first_file = false; + return tf; + } + + void infer( const char *bol, bool want_reference_format ); + + inline bool is_fixed() const { return left == 7; } + inline bool is_reffmt() const { return is_fixed() && right == 73; } + inline bool is_free() const { return ! is_fixed(); } + + const char * description() const { + if( is_reffmt() ) return "REFERENCE"; + if( is_fixed() ) return "FIXED"; + if( is_free() ) return "FREE"; + gcc_unreachable(); + } + + inline int left_margin() { + return left == 0? left : left - 1; + } + inline int right_margin() { + return right == 0? right : right - 1; + } +}; + + +void cdf_push(); +void cdf_push_call_convention(); +void cdf_push_current_tokens(); +void cdf_push_dictionary(); +void cdf_push_enabled_exceptions(); +void cdf_push_source_format(); + +void cdf_pop(); +void cdf_pop_call_convention(); +void cdf_pop_current_tokens(); +void cdf_pop_dictionary(); +void cdf_pop_source_format(); +void cdf_pop_enabled_exceptions(); #endif diff --git a/gcc/common.opt b/gcc/common.opt index 0e50305dde8e..d68d7d8d9148 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -545,6 +545,10 @@ Warray-bounds= Common Joined RejectNegative UInteger Var(warn_array_bounds) Warning IntegerRange(0, 2) Warn if an array is accessed out of bounds. +Wauto-profile +Common Var(warn_auto_profile) Warning +Warn about problems with auto-profile data. + Wuse-after-free Common Var(warn_use_after_free) Warning Warn for uses of pointers to deallocated storage. @@ -847,11 +851,17 @@ Common Var(warn_unused) Init(0) Warning Enable all -Wunused- warnings. Wunused-but-set-parameter -Common Var(warn_unused_but_set_parameter) Warning EnabledBy(Wunused && Wextra) +Common Alias(Wunused-but-set-parameter=,3,0) Warning + +Wunused-but-set-parameter= +Common Var(warn_unused_but_set_parameter) RejectNegative Joined UInteger Warning IntegerRange(0, 3) EnabledBy(Wunused && Wextra) Warn when a function parameter is only set, otherwise unused. Wunused-but-set-variable -Common Var(warn_unused_but_set_variable) Warning EnabledBy(Wunused) +Common Alias(Wunused-but-set-variable=,3,0) Warning + +Wunused-but-set-variable= +Common Var(warn_unused_but_set_variable) RejectNegative Joined UInteger Warning IntegerRange(0, 3) EnabledBy(Wunused) Warn when a variable is only set, otherwise unused. Wunused-function @@ -1187,6 +1197,10 @@ Common Joined RejectNegative Var(auto_profile_file) Use sample profile information for call graph node weights. The profile file is specified in the argument. +fauto-profile-inlining +Common Var(flag_auto_profile_inlining) Init(1) Optimization +Perform inlining using auto-profile. + ; -fcheck-bounds causes gcc to generate array bounds checks. ; For C, C++ and ObjC: defaults off. ; For Java: defaults to on. @@ -1481,7 +1495,7 @@ Common Joined RejectNegative UInteger fdiagnostics-format= Common Joined RejectNegative Enum(diagnostics_output_format) --fdiagnostics-format=[text|sarif-stderr|sarif-file|json|json-stderr|json-file] Select output format. +-fdiagnostics-format=[text|sarif-stderr|sarif-file] Select output format. fdiagnostics-add-output= Common Joined RejectNegative @@ -1523,15 +1537,6 @@ Name(diagnostics_output_format) Type(int) EnumValue Enum(diagnostics_output_format) String(text) Value(DIAGNOSTICS_OUTPUT_FORMAT_TEXT) -EnumValue -Enum(diagnostics_output_format) String(json) Value(DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR) - -EnumValue -Enum(diagnostics_output_format) String(json-stderr) Value(DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR) - -EnumValue -Enum(diagnostics_output_format) String(json-file) Value(DIAGNOSTICS_OUTPUT_FORMAT_JSON_FILE) - EnumValue Enum(diagnostics_output_format) String(sarif-stderr) Value(DIAGNOSTICS_OUTPUT_FORMAT_SARIF_STDERR) diff --git a/gcc/common.opt.urls b/gcc/common.opt.urls index c10856087357..38dd9d317598 100644 --- a/gcc/common.opt.urls +++ b/gcc/common.opt.urls @@ -64,6 +64,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Warray-bounds) Warray-bounds= UrlSuffix(gcc/Warning-Options.html#index-Warray-bounds) +Wauto-profile +UrlSuffix(gcc/Warning-Options.html#index-Wauto-profile) + Wuse-after-free UrlSuffix(gcc/Warning-Options.html#index-Wno-use-after-free) @@ -159,7 +162,7 @@ Wmissing-noreturn UrlSuffix(gcc/Warning-Options.html#index-Wmissing-noreturn) Wmusttail-local-addr -UrlSuffix(gcc/Warning-Options.html#index-Wno-musttail-local-addr) +UrlSuffix(gcc/Warning-Options.html#index-Wmusttail-local-addr) Wmaybe-musttail-local-addr UrlSuffix(gcc/Warning-Options.html#index-Wmaybe-musttail-local-addr) @@ -269,9 +272,15 @@ UrlSuffix(gcc/Warning-Options.html#index-Wno-unused) Wunused-but-set-parameter UrlSuffix(gcc/Warning-Options.html#index-Wno-unused-but-set-parameter) +Wunused-but-set-parameter= +UrlSuffix(gcc/Warning-Options.html#index-Wno-unused-but-set-parameter) + Wunused-but-set-variable UrlSuffix(gcc/Warning-Options.html#index-Wno-unused-but-set-variable) +Wunused-but-set-variable= +UrlSuffix(gcc/Warning-Options.html#index-Wno-unused-but-set-variable) + Wunused-function UrlSuffix(gcc/Warning-Options.html#index-Wno-unused-function) @@ -433,6 +442,9 @@ UrlSuffix(gcc/Optimize-Options.html#index-fauto-profile) fauto-profile= UrlSuffix(gcc/Optimize-Options.html#index-fauto-profile) +fauto-profile-inlining +UrlSuffix(gcc/Optimize-Options.html#index-fauto-profile-inlining) + fbounds-check LangUrlSuffix_D(gdc/Runtime-Options.html#index-fbounds-check) LangUrlSuffix_Fortran(gfortran/Code-Gen-Options.html#index-fbounds-check) diff --git a/gcc/common/config/aarch64/aarch64-common.cc b/gcc/common/config/aarch64/aarch64-common.cc index b9ed83642ade..1488697c6ce4 100644 --- a/gcc/common/config/aarch64/aarch64-common.cc +++ b/gcc/common/config/aarch64/aarch64-common.cc @@ -142,6 +142,10 @@ aarch64_handle_option (struct gcc_options *opts, opts->x_aarch64_flag_outline_atomics = val; return true; + case OPT_mmax_vectorization: + opts->x_flag_aarch64_max_vectorization = val; + return true; + default: return true; } diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc index 64908ce740a9..9e807e4b8f66 100644 --- a/gcc/common/config/i386/i386-common.cc +++ b/gcc/common/config/i386/i386-common.cc @@ -131,8 +131,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_AVX10_2_SET \ (OPTION_MASK_ISA2_AVX10_1_SET | OPTION_MASK_ISA2_AVX10_2) #define OPTION_MASK_ISA2_AMX_AVX512_SET \ - (OPTION_MASK_ISA2_AMX_TILE_SET | OPTION_MASK_ISA2_AVX10_2_SET \ - | OPTION_MASK_ISA2_AMX_AVX512) + (OPTION_MASK_ISA2_AMX_TILE_SET | OPTION_MASK_ISA2_AMX_AVX512) #define OPTION_MASK_ISA2_AMX_TF32_SET \ (OPTION_MASK_ISA2_AMX_TILE_SET | OPTION_MASK_ISA2_AMX_TF32) #define OPTION_MASK_ISA2_AMX_TRANSPOSE_SET \ @@ -328,8 +327,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_USER_MSR_UNSET OPTION_MASK_ISA2_USER_MSR #define OPTION_MASK_ISA2_AVX10_1_UNSET \ (OPTION_MASK_ISA2_AVX10_1 | OPTION_MASK_ISA2_AVX10_2_UNSET) -#define OPTION_MASK_ISA2_AVX10_2_UNSET \ - (OPTION_MASK_ISA2_AVX10_2 | OPTION_MASK_ISA2_AMX_AVX512_UNSET) +#define OPTION_MASK_ISA2_AVX10_2_UNSET OPTION_MASK_ISA2_AVX10_2 #define OPTION_MASK_ISA2_AMX_AVX512_UNSET OPTION_MASK_ISA2_AMX_AVX512 #define OPTION_MASK_ISA2_AMX_TF32_UNSET OPTION_MASK_ISA2_AMX_TF32 #define OPTION_MASK_ISA2_AMX_TRANSPOSE_UNSET OPTION_MASK_ISA2_AMX_TRANSPOSE @@ -379,7 +377,8 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_AVX512F_UNSET \ (OPTION_MASK_ISA2_AVX512BW_UNSET \ | OPTION_MASK_ISA2_AVX512VP2INTERSECT_UNSET \ - | OPTION_MASK_ISA2_AVX10_1_UNSET) + | OPTION_MASK_ISA2_AVX10_1_UNSET \ + | OPTION_MASK_ISA2_AMX_AVX512_UNSET) #define OPTION_MASK_ISA2_GENERAL_REGS_ONLY_UNSET \ OPTION_MASK_ISA2_SSE_UNSET #define OPTION_MASK_ISA2_AVX_UNSET \ @@ -1374,8 +1373,8 @@ ix86_handle_option (struct gcc_options *opts, { opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_AMX_AVX512_SET; opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AMX_AVX512_SET; - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX10_1_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX10_1_SET; + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX512F_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512F_SET; } else { @@ -2310,7 +2309,7 @@ const pta processor_alias_table[] = M_CPU_TYPE (INTEL_GRANDRIDGE), P_PROC_AVX2}, {"clearwaterforest", PROCESSOR_CLEARWATERFOREST, CPU_HASWELL, PTA_CLEARWATERFOREST, M_CPU_TYPE (INTEL_CLEARWATERFOREST), P_PROC_AVX2}, - {"intel", PROCESSOR_INTEL, CPU_SLM, PTA_NEHALEM, + {"intel", PROCESSOR_INTEL, CPU_HASWELL, PTA_HASWELL, M_VENDOR (VENDOR_INTEL), P_NONE}, {"geode", PROCESSOR_GEODE, CPU_GEODE, PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_PREFETCH_SSE, 0, P_NONE}, diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index a6d8763f032b..82037a334528 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -290,20 +290,36 @@ static const riscv_profiles riscv_profiles_table[] = /* RVA23 contains all mandatory base ISA for RVA22U64 and the new extension 'v,zihintntl,zvfhmin,zvbb,zvkt,zicond,zimop,zcmop,zfa,zawrs' as mandatory extensions. */ - {"rva23u64", "rv64imafdcv_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" + {"rva23u64", "rv64imafdcbv_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop" "_zicboz_zfhmin_zkt_zvfhmin_zvbb_zvkt_zihintntl_zicond_zimop_zcmop_zcb" - "_zfa_zawrs"}, + "_zfa_zawrs_supm"}, + + /* RVA23S contains all mandatory base ISA for RVA23U64 and the privileged + extensions as mandatory extensions. */ + {"rva23s64", "rv64imafdcbv_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" + "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop" + "_zicboz_zfhmin_zkt_zvfhmin_zvbb_zvkt_zihintntl_zicond_zimop_zcmop_zcb" + "_zfa_zawrs_svbare_svade_ssccptr_sstvecd_sstvala_sscounterenw_svpbmt" + "_svinval_svnapot_sstc_sscofpmf_ssnpm_ssu64xl_sha_supm" + }, /* RVB23 contains all mandatory base ISA for RVA22U64 and the new extension 'zihintntl,zicond,zimop,zcmop,zfa,zawrs' as mandatory extensions. */ - {"rvb23u64", "rv64imafdc_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" + {"rvb23u64", "rv64imafdcb_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop" "_zicboz_zfhmin_zkt_zihintntl_zicond_zimop_zcmop_zcb" "_zfa_zawrs"}, - /* Currently we do not define S/M mode Profiles in gcc part. */ + /* RVB23S contains all mandatory base ISA for RVB23U64 and the privileged + extensions as mandatory extensions. */ + {"rvb23s64", "rv64imafdcb_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" + "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop" + "_zicboz_zfhmin_zkt_zvfhmin_zvbb_zvkt_zihintntl_zicond_zimop_zcmop_zcb" + "_zfa_zawrs_svbare_svade_ssccptr_sstvecd_sstvala_sscounterenw_svpbmt" + "_svinval_svnapot_sstc_sscofpmf_ssu64xl_supm" + }, /* Terminate the list. */ {NULL, NULL} @@ -1129,8 +1145,10 @@ riscv_subset_list::check_implied_ext () void riscv_subset_list::handle_combine_ext () { - for (const auto &[ext_name, ext_info] : riscv_ext_infos) + for (const auto &pair : riscv_ext_infos) { + const std::string &ext_name = pair.first; + auto &ext_info = pair.second; bool is_combined = true; /* Skip if this extension don't need to combine. */ if (!ext_info.need_combine_p ()) @@ -1558,20 +1576,27 @@ riscv_set_arch_by_subset_list (riscv_subset_list *subset_list, if (opts) { /* Clean up target flags before we set. */ - for (const auto &[ext_name, ext_info] : riscv_ext_infos) - ext_info.clean_opts (opts); + for (const auto &pair : riscv_ext_infos) + { + auto &ext_info = pair.second; + ext_info.clean_opts (opts); + } if (subset_list->xlen () == 32) opts->x_riscv_isa_flags &= ~MASK_64BIT; else if (subset_list->xlen () == 64) opts->x_riscv_isa_flags |= MASK_64BIT; - for (const auto &[ext_name, ext_info] : riscv_ext_infos) - if (subset_list->lookup (ext_name.c_str ())) - { - /* Set the extension flag. */ - ext_info.set_opts (opts); - } + for (const auto &pair : riscv_ext_infos) + { + const std::string &ext_name = pair.first; + auto &ext_info = pair.second; + if (subset_list->lookup (ext_name.c_str ())) + { + /* Set the extension flag. */ + ext_info.set_opts (opts); + } + } } } diff --git a/gcc/config.gcc b/gcc/config.gcc index 1e386a469e0e..8ed111392bb4 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -351,7 +351,7 @@ aarch64*-*-*) c_target_objs="aarch64-c.o" cxx_target_objs="aarch64-c.o" d_target_objs="aarch64-d.o" - extra_objs="aarch64-builtins.o aarch-common.o aarch64-sve-builtins.o aarch64-sve-builtins-shapes.o aarch64-sve-builtins-base.o aarch64-sve-builtins-sve2.o aarch64-sve-builtins-sme.o cortex-a57-fma-steering.o aarch64-speculation.o aarch-bti-insert.o aarch64-cc-fusion.o aarch64-early-ra.o aarch64-ldp-fusion.o" + extra_objs="aarch64-builtins.o aarch-common.o aarch64-elf-metadata.o aarch64-sve-builtins.o aarch64-sve-builtins-shapes.o aarch64-sve-builtins-base.o aarch64-sve-builtins-sve2.o aarch64-sve-builtins-sme.o cortex-a57-fma-steering.o aarch64-speculation.o aarch-bti-insert.o aarch64-cc-fusion.o aarch64-early-ra.o aarch64-ldp-fusion.o" target_gtfiles="\$(srcdir)/config/aarch64/aarch64-protos.h \$(srcdir)/config/aarch64/aarch64-builtins.h \$(srcdir)/config/aarch64/aarch64-builtins.cc \$(srcdir)/config/aarch64/aarch64-sve-builtins.h \$(srcdir)/config/aarch64/aarch64-sve-builtins.cc" target_has_targetm_common=yes ;; @@ -1847,11 +1847,11 @@ moxie-*-moxiebox*) ;; h8300-*-elf*) tmake_file="h8300/t-h8300" - tm_file="h8300/h8300.h elfos.h newlib-stdint.h h8300/elf.h" + tm_file="elfos.h h8300/h8300.h newlib-stdint.h h8300/elf.h" ;; h8300-*-linux*) tmake_file="${tmake_file} h8300/t-h8300 h8300/t-linux" - tm_file="h8300/h8300.h elfos.h gnu-user.h linux.h glibc-stdint.h h8300/linux.h" + tm_file="elfos.h h8300/h8300.h gnu-user.h linux.h glibc-stdint.h h8300/linux.h" ;; hppa*64*-*-linux*) target_cpu_default="MASK_PA_11|MASK_PA_20" @@ -4611,15 +4611,13 @@ case "${target}" in for which in arch tune; do eval "val=\$with_$which" - case ${val} in - "" | gfx900 | gfx906 | gfx908 | gfx90a | gfx90c | gfx1030 | gfx1036 | gfx1100 | gfx1103) - # OK - ;; - *) + if test x"$val" != x \ + && ! grep -q "GCN_DEVICE($val," \ + "${srcdir}/config/gcn/gcn-devices.def"; + then echo "Unknown cpu used in --with-$which=$val." 1>&2 exit 1 - ;; - esac + fi done [ "x$with_arch" = x ] && with_arch=gfx900 @@ -5896,7 +5894,7 @@ esac # distinguish VxWorks variants such as VxWorks 7 or 64). case ${target} in -arm*-*-* | i[34567]86-*-* | mips*-*-* | powerpc*-*-* | sh*-*-* \ +aarch64*-*-* | arm*-*-* | i[34567]86-*-* | mips*-*-* | powerpc*-*-* | sh*-*-* \ | sparc*-*-* | x86_64-*-*) tm_file="vxworks-dummy.h ${tm_file}" ;; diff --git a/gcc/config.in b/gcc/config.in index a79c51adb2b3..353d1bc94078 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -318,6 +318,12 @@ #endif +/* Define to enable -mfentry by default on x86-64. */ +#ifndef USED_FOR_TARGET +#undef ENABLE_X86_64_MFENTRY +#endif + + /* Define to the name of a file containing a list of extra machine modes for this architecture. */ #ifndef USED_FOR_TARGET @@ -355,6 +361,12 @@ #endif +/* Define if your assembler supports AEABI build attributes. */ +#ifndef USED_FOR_TARGET +#undef HAVE_AS_AEABI_BUILD_ATTRIBUTES +#endif + + /* Define if your assembler supports architecture modifiers. */ #ifndef USED_FOR_TARGET #undef HAVE_AS_ARCHITECTURE_MODIFIERS diff --git a/gcc/config/aarch64/aarch64-builtin-pairs.def b/gcc/config/aarch64/aarch64-builtin-pairs.def new file mode 100644 index 000000000000..1757e19131fd --- /dev/null +++ b/gcc/config/aarch64/aarch64-builtin-pairs.def @@ -0,0 +1,73 @@ +/* Pairs of AArch64 builtins that can be folded into each other. + Copyright (C) 2025 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +/* Pairs of single and half integer modes. */ +#define LO_HI_PAIR_V_HSI(T, LO, HI) \ + LO_HI_PAIR (T##_##LO##v2si, T##_##HI##v4si) \ + LO_HI_PAIR (T##_##LO##v4hi, T##_##HI##v8hi) + +#define LO_HI_PAIR_V_US_HSI(T, LO, HI) \ + LO_HI_PAIR_V_HSI (T, s##LO, s##HI) \ + LO_HI_PAIR_V_HSI (T##U, u##LO, u##HI) + +/* Pairs of widenable integer modes. */ +#define LO_HI_PAIR_V_WI(T, LO, HI) \ + LO_HI_PAIR_V_HSI (T, LO, HI) \ + LO_HI_PAIR (T##_##LO##v8qi, T##_##HI##v16qi) + +#define LO_HI_PAIR_V_US_WI(T, LO, HI) \ + LO_HI_PAIR_V_WI (T, s##LO, s##HI) \ + LO_HI_PAIR_V_WI (T##U, u##LO, u##HI) + +#define UNOP_LONG_LH_PAIRS \ + LO_HI_PAIR (UNOP_sxtlv8hi, UNOP_vec_unpacks_hi_v16qi) \ + LO_HI_PAIR (UNOP_sxtlv4si, UNOP_vec_unpacks_hi_v8hi) \ + LO_HI_PAIR (UNOP_sxtlv2di, UNOP_vec_unpacks_hi_v4si) \ + LO_HI_PAIR (UNOPU_uxtlv8hi, UNOPU_vec_unpacku_hi_v16qi) \ + LO_HI_PAIR (UNOPU_uxtlv4si, UNOPU_vec_unpacku_hi_v8hi) \ + LO_HI_PAIR (UNOPU_uxtlv2di, UNOPU_vec_unpacku_hi_v4si) + +#define BINOP_LONG_LH_PAIRS \ + LO_HI_PAIR_V_US_WI (BINOP, addl, addl2) \ + LO_HI_PAIR_V_US_WI (BINOP, subl, subl2) \ + LO_HI_PAIR_V_US_WI (BINOP, abdl, abdl2) \ + LO_HI_PAIR_V_WI (BINOP, intrinsic_vec_smult_lo_, vec_widen_smult_hi_) \ + LO_HI_PAIR_V_WI (BINOPU, intrinsic_vec_umult_lo_, vec_widen_umult_hi_) \ + LO_HI_PAIR_V_HSI (BINOP, sqdmull, sqdmull2) \ + LO_HI_PAIR (BINOPP_pmullv8qi, BINOPP_pmull_hiv16qi) + +#define BINOP_LONG_N_LH_PAIRS \ + LO_HI_PAIR_V_US_HSI (BINOP, mull_n, mull_hi_n) \ + LO_HI_PAIR_V_HSI (BINOP, sqdmull_n, sqdmull2_n) + +#define BINOP_WIDE_LH_PAIRS \ + LO_HI_PAIR_V_US_WI (BINOP, subw, subw2) \ + LO_HI_PAIR_V_US_WI (BINOP, addw, addw2) + +#define TERNOP_LONG_LH_PAIRS \ + LO_HI_PAIR_V_US_WI (TERNOP, mlal, mlal_hi) \ + LO_HI_PAIR_V_US_WI (TERNOP, mlsl, mlsl_hi) \ + LO_HI_PAIR_V_US_WI (TERNOP, abal, abal2) \ + LO_HI_PAIR_V_HSI (TERNOP, sqdmlal, sqdmlal2) \ + LO_HI_PAIR_V_HSI (TERNOP, sqdmlsl, sqdmlsl2) + +#define TERNOP_LONG_N_LH_PAIRS \ + LO_HI_PAIR_V_US_HSI (TERNOP, mlal_n, mlal_hi_n) \ + LO_HI_PAIR_V_US_HSI (TERNOP, mlsl_n, mlsl_hi_n) \ + LO_HI_PAIR_V_HSI (TERNOP, sqdmlal_n, sqdmlal2_n) diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index 93f939a9c834..408099a50e8a 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc @@ -49,6 +49,8 @@ #include "attribs.h" #include "gimple-fold.h" #include "builtins.h" +#include "tree-pass.h" +#include "tree-vector-builder.h" #include "aarch64-builtins.h" using namespace aarch64; @@ -738,6 +740,16 @@ static aarch64_simd_builtin_datum aarch64_simd_builtin_data[] = { VGET_HIGH_BUILTIN(u64) \ VGET_HIGH_BUILTIN(bf16) +#include "aarch64-builtin-pairs.def" + +#define LO_HI_PAIRINGS \ + UNOP_LONG_LH_PAIRS \ + BINOP_LONG_LH_PAIRS \ + BINOP_LONG_N_LH_PAIRS \ + BINOP_WIDE_LH_PAIRS \ + TERNOP_LONG_LH_PAIRS \ + TERNOP_LONG_N_LH_PAIRS + typedef struct { const char *name; @@ -5004,6 +5016,167 @@ aarch64_gimple_fold_pragma_builtin } } +/* Return the fndecl of the builtin paired with FCODE_LO if one + exists (see aarch64-builtin-pairs.def), or NULL_TREE if not. */ +static inline tree +aarch64_get_highpart_builtin (unsigned int fcode_lo) +{ +#undef LO_HI_PAIR +#define LO_HI_PAIR(A, B) case AARCH64_SIMD_BUILTIN_##A: \ + return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_##B]; + + switch (fcode_lo) + { + LO_HI_PAIRINGS + default: + return NULL_TREE; + } +} + +/* If REF describes the high half of a 128-bit vector, return this + vector. Otherwise, return NULL_TREE. */ +static tree +aarch64_v128_highpart_ref (const_tree ref) +{ + if (TREE_CODE (ref) != SSA_NAME) + return NULL_TREE; + + gassign *stmt = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (ref)); + if (!stmt || gimple_assign_rhs_code (stmt) != BIT_FIELD_REF) + return NULL_TREE; + + /* Look for a BIT_FIELD_REF that denotes the most significant 64 + bits of a 128-bit vector. */ + tree bf_ref = gimple_assign_rhs1 (stmt); + unsigned int offset = BYTES_BIG_ENDIAN ? 0 : 64; + + if (maybe_ne (bit_field_size (bf_ref), 64u) + || maybe_ne (bit_field_offset (bf_ref), offset)) + return NULL_TREE; + + tree obj = TREE_OPERAND (bf_ref, 0); + tree type = TREE_TYPE (obj); + + if (VECTOR_TYPE_P (type) && tree_fits_uhwi_p (TYPE_SIZE (type)) + && tree_to_uhwi (TYPE_SIZE (type)) == 128) + return obj; + + return NULL_TREE; +} + +/* Build and return a new VECTOR_CST of type OUT_TY, using repeated + copies of the elements of VEC_IN. */ +static tree +aarch64_build_vector_cst (const_tree vec_in, tree out_ty) +{ + gcc_assert (TREE_CODE (vec_in) == VECTOR_CST + && VECTOR_TYPE_P (out_ty)); + unsigned HOST_WIDE_INT nelts + = VECTOR_CST_NELTS (vec_in).to_constant (); + + tree_vector_builder vec_out (out_ty, nelts, 1); + for (unsigned i = 0; i < nelts; i++) + vec_out.quick_push (VECTOR_CST_ELT (vec_in, i)); + + return vec_out.build (); +} + +/* Try to fold STMT, a call to to a lowpart-operating builtin, to + it's highpart-operating equivalent if doing so would save + unnecessary data movement instructions. + + Return the new call if so, otherwise nullptr. */ +static gcall * +aarch64_fold_lo_call_to_hi (unsigned int fcode, gcall *stmt, + gimple_stmt_iterator *gsi) +{ + /* Punt until as late as possible: + 1) By folding away BIT_FIELD_REFs we remove information about the + operands that may be useful to other optimizers. + + 2) For simplicity, we'd like the expression + + x = BIT_FIELD_REF<a, x, y> + + to imply that A is not a VECTOR_CST. This assumption is unlikely + to hold before constant prop/folding. */ + if (!(cfun->curr_properties & PROP_last_full_fold)) + return nullptr; + + tree builtin_hi = aarch64_get_highpart_builtin (fcode); + gcc_assert (builtin_hi != NULL_TREE); + + /* Prefer to use the highpart builtin when at least one vector + argument is a reference to the high half of a 128b vector, and + all others are VECTOR_CSTs that we can extend to 128b. */ + auto_vec<unsigned int, 2> vec_constants; + auto_vec<unsigned int, 2> vec_highparts; + /* The arguments and signature of the new call. */ + auto_vec<tree, 4> call_args; + auto_vec<tree, 4> call_types; + + /* The interesting args are those that differ between the lo/hi + builtins. Walk the function signatures to find these. */ + tree types_hi = TYPE_ARG_TYPES (TREE_TYPE (builtin_hi)); + tree types_lo = TYPE_ARG_TYPES (gimple_call_fntype (stmt)); + unsigned int argno = 0; + while (types_lo != void_list_node && types_hi != void_list_node) + { + tree type_lo = TREE_VALUE (types_lo); + tree type_hi = TREE_VALUE (types_hi); + tree arg = gimple_call_arg (stmt, argno); + if (!types_compatible_p (type_lo, type_hi)) + { + /* Check our assumptions about this pair. */ + gcc_assert (wi::to_widest (TYPE_SIZE (type_lo)) == 64 + && wi::to_widest (TYPE_SIZE (type_hi)) == 128); + + tree vq = aarch64_v128_highpart_ref (arg); + if (vq && is_gimple_reg (vq)) + { + vec_highparts.safe_push (argno); + arg = vq; + } + else if (TREE_CODE (arg) == VECTOR_CST) + vec_constants.safe_push (argno); + else + return nullptr; + } + call_args.safe_push (arg); + call_types.safe_push (type_hi); + + argno++; + types_hi = TREE_CHAIN (types_hi); + types_lo = TREE_CHAIN (types_lo); + } + gcc_assert (types_lo == void_list_node && types_hi == void_list_node); + + if (vec_highparts.is_empty ()) + return nullptr; + + /* Build and return a new call to BUILTIN_HI. */ + for (auto i : vec_constants) + call_args[i] = aarch64_build_vector_cst (call_args[i], call_types[i]); + + for (auto i : vec_highparts) + if (!types_compatible_p (TREE_TYPE (call_args[i]), call_types[i])) + { + tree vce_ssa = make_ssa_name (call_types[i]); + tree vce_expr = build1 (VIEW_CONVERT_EXPR, + call_types[i], call_args[i]); + gsi_insert_before (gsi, gimple_build_assign (vce_ssa, vce_expr), + GSI_SAME_STMT); + call_args[i] = vce_ssa; + } + + gcall *new_call = gimple_build_call_vec (builtin_hi, call_args); + gimple_call_set_lhs (new_call, gimple_call_lhs (stmt)); + return new_call; +} + +#undef LO_HI_PAIR +#define LO_HI_PAIR(A, B) case AARCH64_SIMD_BUILTIN_##A: + /* Try to fold STMT, given that it's a call to the built-in function with subcode FCODE. Return the new statement on success and null on failure. */ @@ -5190,6 +5363,9 @@ aarch64_general_gimple_fold_builtin (unsigned int fcode, gcall *stmt, } break; } + LO_HI_PAIRINGS + new_stmt = aarch64_fold_lo_call_to_hi (fcode, stmt, gsi); + break; case AARCH64_SIMD_BUILTIN_LANE_CHECK: if (aarch64_fold_builtin_lane_check (args[0], args[1], args[2])) { diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def index 24b7cd362aaf..8040409d2830 100644 --- a/gcc/config/aarch64/aarch64-cores.def +++ b/gcc/config/aarch64/aarch64-cores.def @@ -226,6 +226,9 @@ AARCH64_CORE("demeter", demeter, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, /* NVIDIA ('N') cores. */ AARCH64_CORE("olympus", olympus, cortexa57, V9_2A, (SVE2_BITPERM, RNG, LS64, MEMTAG, PROFILE, FAMINMAX, FP8FMA, FP8DOT2, FP8DOT4, LUT, SVE2_AES, SVE2_SHA3, SVE2_SM4), neoversev3, 0x4e, 0x10, -1) +/* Armv9-A big.LITTLE processors. */ +AARCH64_CORE("gb10", gb10, cortexa57, V9_2A, (SVE2_BITPERM, SVE2_AES, SVE2_SHA3, SVE2_SM4, MEMTAG, PROFILE), cortexx925, 0x41, AARCH64_BIG_LITTLE (0xd85, 0xd87), -1) + /* Generic Architecture Processors. */ AARCH64_CORE("generic", generic, cortexa53, V8A, (), generic, 0x0, 0x0, -1) AARCH64_CORE("generic-armv8-a", generic_armv8_a, cortexa53, V8A, (), generic_armv8_a, 0x0, 0x0, -1) diff --git a/gcc/config/aarch64/aarch64-cost-tables.h b/gcc/config/aarch64/aarch64-cost-tables.h index c49ff7f62ef2..e7926eb4a0e4 100644 --- a/gcc/config/aarch64/aarch64-cost-tables.h +++ b/gcc/config/aarch64/aarch64-cost-tables.h @@ -125,9 +125,9 @@ const struct cpu_cost_table qdf24xx_extra_costs = { COSTS_N_INSNS (1), /* alu. */ COSTS_N_INSNS (4), /* mult. */ - COSTS_N_INSNS (1), /* movi. */ - COSTS_N_INSNS (2), /* dup. */ - COSTS_N_INSNS (2) /* extract. */ + COSTS_N_INSNS (0), /* movi. */ + COSTS_N_INSNS (1), /* dup. */ + COSTS_N_INSNS (1) /* extract. */ } }; @@ -233,9 +233,9 @@ const struct cpu_cost_table thunderx_extra_costs = { COSTS_N_INSNS (1), /* Alu. */ COSTS_N_INSNS (4), /* mult. */ - COSTS_N_INSNS (1), /* movi. */ - COSTS_N_INSNS (2), /* dup. */ - COSTS_N_INSNS (2) /* extract. */ + COSTS_N_INSNS (0), /* movi. */ + COSTS_N_INSNS (1), /* dup. */ + COSTS_N_INSNS (1) /* extract. */ } }; @@ -340,9 +340,9 @@ const struct cpu_cost_table thunderx2t99_extra_costs = { COSTS_N_INSNS (1), /* Alu. */ COSTS_N_INSNS (4), /* Mult. */ - COSTS_N_INSNS (1), /* movi. */ - COSTS_N_INSNS (2), /* dup. */ - COSTS_N_INSNS (2) /* extract. */ + COSTS_N_INSNS (0), /* movi. */ + COSTS_N_INSNS (1), /* dup. */ + COSTS_N_INSNS (1) /* extract. */ } }; @@ -447,9 +447,9 @@ const struct cpu_cost_table thunderx3t110_extra_costs = { COSTS_N_INSNS (1), /* Alu. */ COSTS_N_INSNS (4), /* Mult. */ - COSTS_N_INSNS (1), /* movi. */ - COSTS_N_INSNS (2), /* dup. */ - COSTS_N_INSNS (2) /* extract. */ + COSTS_N_INSNS (0), /* movi. */ + COSTS_N_INSNS (1), /* dup. */ + COSTS_N_INSNS (1) /* extract. */ } }; @@ -555,9 +555,9 @@ const struct cpu_cost_table tsv110_extra_costs = { COSTS_N_INSNS (1), /* alu. */ COSTS_N_INSNS (4), /* mult. */ - COSTS_N_INSNS (1), /* movi. */ - COSTS_N_INSNS (2), /* dup. */ - COSTS_N_INSNS (2) /* extract. */ + COSTS_N_INSNS (0), /* movi. */ + COSTS_N_INSNS (1), /* dup. */ + COSTS_N_INSNS (1) /* extract. */ } }; @@ -662,9 +662,9 @@ const struct cpu_cost_table a64fx_extra_costs = { COSTS_N_INSNS (1), /* alu. */ COSTS_N_INSNS (4), /* mult. */ - COSTS_N_INSNS (1), /* movi. */ - COSTS_N_INSNS (2), /* dup. */ - COSTS_N_INSNS (2) /* extract. */ + COSTS_N_INSNS (0), /* movi. */ + COSTS_N_INSNS (1), /* dup. */ + COSTS_N_INSNS (1) /* extract. */ } }; @@ -769,9 +769,9 @@ const struct cpu_cost_table ampere1_extra_costs = { COSTS_N_INSNS (3), /* alu. */ COSTS_N_INSNS (3), /* mult. */ - COSTS_N_INSNS (2), /* movi. */ - COSTS_N_INSNS (2), /* dup. */ - COSTS_N_INSNS (2) /* extract. */ + COSTS_N_INSNS (1), /* movi. */ + COSTS_N_INSNS (1), /* dup. */ + COSTS_N_INSNS (1) /* extract. */ } }; @@ -876,9 +876,9 @@ const struct cpu_cost_table ampere1a_extra_costs = { COSTS_N_INSNS (3), /* alu. */ COSTS_N_INSNS (3), /* mult. */ - COSTS_N_INSNS (2), /* movi. */ - COSTS_N_INSNS (2), /* dup. */ - COSTS_N_INSNS (2) /* extract. */ + COSTS_N_INSNS (1), /* movi. */ + COSTS_N_INSNS (1), /* dup. */ + COSTS_N_INSNS (1) /* extract. */ } }; @@ -983,9 +983,9 @@ const struct cpu_cost_table ampere1b_extra_costs = { COSTS_N_INSNS (1), /* alu. */ COSTS_N_INSNS (2), /* mult. */ - COSTS_N_INSNS (1), /* movi. */ - COSTS_N_INSNS (1), /* dup. */ - COSTS_N_INSNS (1) /* extract. */ + COSTS_N_INSNS (0), /* movi. */ + COSTS_N_INSNS (0), /* dup. */ + COSTS_N_INSNS (0) /* extract. */ } }; diff --git a/gcc/config/aarch64/aarch64-elf-metadata.cc b/gcc/config/aarch64/aarch64-elf-metadata.cc new file mode 100644 index 000000000000..88fbb9347e85 --- /dev/null +++ b/gcc/config/aarch64/aarch64-elf-metadata.cc @@ -0,0 +1,145 @@ +/* ELF metadata for AArch64 architecture. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + Contributed by ARM Ltd. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#define INCLUDE_STRING +#define INCLUDE_ALGORITHM +#define INCLUDE_MEMORY +#define INCLUDE_VECTOR +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "backend.h" +#include "target.h" +#include "rtl.h" +#include "output.h" + +#include "aarch64-elf-metadata.h" + +/* Defined for convenience. */ +#define POINTER_BYTES (POINTER_SIZE / BITS_PER_UNIT) + +namespace aarch64 { + +constexpr unsigned GNU_PROPERTY_AARCH64_FEATURE_1_AND = 0xc0000000; +constexpr unsigned GNU_PROPERTY_AARCH64_FEATURE_1_BTI = (1U << 0); +constexpr unsigned GNU_PROPERTY_AARCH64_FEATURE_1_PAC = (1U << 1); +constexpr unsigned GNU_PROPERTY_AARCH64_FEATURE_1_GCS = (1U << 2); + +namespace { + +std::string +gnu_property_features_to_string (unsigned feature_1_and) +{ + struct flag_name + { + unsigned int mask; + const char *name; + }; + + static const flag_name flags[] = { + {GNU_PROPERTY_AARCH64_FEATURE_1_BTI, "BTI"}, + {GNU_PROPERTY_AARCH64_FEATURE_1_PAC, "PAC"}, + {GNU_PROPERTY_AARCH64_FEATURE_1_GCS, "GCS"}, + }; + + const char *separator = ""; + std::string s_features; + for (auto &flag : flags) + if (feature_1_and & flag.mask) + { + s_features.append (separator).append (flag.name); + separator = ", "; + } + return s_features; +}; + +} // namespace anonymous + +section_note_gnu_property::section_note_gnu_property () + : m_feature_1_and (0) {} + +void +section_note_gnu_property::bti_enabled () +{ + m_feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI; +} + +void +section_note_gnu_property::pac_enabled () +{ + m_feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC; +} + +void +section_note_gnu_property::gcs_enabled () +{ + m_feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_GCS; +} + +void +section_note_gnu_property::write () const +{ + if (m_feature_1_and) + { + /* Generate .note.gnu.property section. */ + switch_to_section ( + get_section (".note.gnu.property", SECTION_NOTYPE, NULL)); + + /* PT_NOTE header: namesz, descsz, type. + namesz = 4 ("GNU\0") + descsz = 16 (Size of the program property array) + [(12 + padding) * Number of array elements] + type = 5 (NT_GNU_PROPERTY_TYPE_0). */ + assemble_align (POINTER_SIZE); + assemble_integer (GEN_INT (4), 4, 32, 1); + assemble_integer (GEN_INT (ROUND_UP (12, POINTER_BYTES)), 4, 32, 1); + assemble_integer (GEN_INT (5), 4, 32, 1); + + /* PT_NOTE name. */ + assemble_string ("GNU", 4); + + /* PT_NOTE contents for NT_GNU_PROPERTY_TYPE_0: + type = GNU_PROPERTY_AARCH64_FEATURE_1_AND + datasz = 4 + data = feature_1_and. */ + fputs (integer_asm_op (4, true), asm_out_file); + fprint_whex (asm_out_file, GNU_PROPERTY_AARCH64_FEATURE_1_AND); + putc ('\n', asm_out_file); + assemble_integer (GEN_INT (4), 4, 32, 1); + + fputs (integer_asm_op (4, true), asm_out_file); + fprint_whex (asm_out_file, m_feature_1_and); + if (flag_debug_asm) + { + auto const &s_features + = gnu_property_features_to_string (m_feature_1_and); + asm_fprintf (asm_out_file, + "\t%s GNU_PROPERTY_AARCH64_FEATURE_1_AND (%s)\n", + ASM_COMMENT_START, s_features.c_str ()); + } + else + putc ('\n', asm_out_file); + + /* Pad the size of the note to the required alignment. */ + assemble_align (POINTER_SIZE); + } +} + +} // namespace aarch64 diff --git a/gcc/config/aarch64/aarch64-elf-metadata.h b/gcc/config/aarch64/aarch64-elf-metadata.h new file mode 100644 index 000000000000..e99f6df999d9 --- /dev/null +++ b/gcc/config/aarch64/aarch64-elf-metadata.h @@ -0,0 +1,253 @@ +/* ELF metadata for AArch64 architecture. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + Contributed by ARM Ltd. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#ifndef GCC_AARCH64_ELF_METADATA_H +#define GCC_AARCH64_ELF_METADATA_H + +#include "vec.h" + +namespace aarch64 { + +class section_note_gnu_property +{ + public: + section_note_gnu_property (); + + /* Add BTI flag to GNU properties. */ + void bti_enabled (); + /* Add GCS flag to GNU properties. */ + void gcs_enabled (); + /* Add PAC flag to GNU properties. */ + void pac_enabled (); + + /* Write the data to the assembly file. */ + void write () const; + + private: + unsigned m_feature_1_and; +}; + +enum subsection_optionality : uint8_t +{ + required = 0x0, + optional = 0x1, +}; + +enum subsection_val_type : uint8_t +{ + uleb128 = 0x0, + ntbs = 0x1, +}; + +enum BA_TagFeature_t : uint8_t +{ + Tag_Feature_BTI = 0, + Tag_Feature_PAC = 1, + Tag_Feature_GCS = 2, +}; + +template <typename T_tag, typename T_val> +struct aeabi_attribute +{ + T_tag tag; + T_val value; +}; + +template <typename T_tag, typename T_val> +aeabi_attribute<T_tag, T_val> +make_aeabi_attribute (T_tag tag, T_val val) +{ + return aeabi_attribute<T_tag, T_val>{tag, val}; +} + +namespace details { + +constexpr const char * +to_c_str (bool b) +{ + return b ? "true" : "false"; +} + +constexpr const char * +to_c_str (const char *s) +{ + return s; +} + +constexpr const char * +to_c_str (subsection_optionality v) +{ + return (v == optional ? "optional" + : v == required ? "required" + : nullptr); +} + +constexpr const char * +to_c_str (subsection_val_type v) +{ + return (v == uleb128 ? "ULEB128" + : v == ntbs ? "NTBS" + : nullptr); +} + +constexpr const char * +to_c_str (BA_TagFeature_t feature) +{ + return (feature == Tag_Feature_BTI ? "Tag_Feature_BTI" + : feature == Tag_Feature_PAC ? "Tag_Feature_PAC" + : feature == Tag_Feature_GCS ? "Tag_Feature_GCS" + : nullptr); +} + +template < + typename T, + typename = typename std::enable_if<std::is_unsigned<T>::value, T>::type +> +constexpr const char * +aeabi_attr_str_fmt (T) +{ + return "\t.aeabi_attribute %s, %u"; +} + +constexpr const char * +aeabi_attr_str_fmt (const char *) +{ + return "\t.aeabi_attribute %s, \"%s\""; +} + +template < + typename T, + typename = typename std::enable_if<std::is_unsigned<T>::value, T>::type +> +constexpr uint8_t +aeabi_attr_val_for_fmt (T value) +{ + return static_cast<uint8_t>(value); +} + +constexpr const char * +aeabi_attr_val_for_fmt (const char *s) +{ + return s; +} + +template <typename T_tag, typename T_val> +void +write (FILE *out_file, aeabi_attribute<T_tag, T_val> const &attr) +{ + asm_fprintf (out_file, aeabi_attr_str_fmt (T_val{}), + to_c_str (attr.tag), aeabi_attr_val_for_fmt (attr.value)); + if (flag_debug_asm) + asm_fprintf (out_file, "\t%s %s: %s", ASM_COMMENT_START, + to_c_str (attr.tag), to_c_str (attr.value)); + asm_fprintf (out_file, "\n"); +} + +template < + typename T, + typename = typename std::enable_if<std::is_unsigned<T>::value, T>::type +> +constexpr subsection_val_type +deduce_attr_av_type (T) +{ + return subsection_val_type::uleb128; +} + +constexpr subsection_val_type +deduce_attr_av_type (const char *) +{ + return subsection_val_type::ntbs; +} + +} // namespace details + +/* AEABI subsections can be public or private. A subsection is public if it is + prefixed with "aeabi", private otherwise. The header of an AEABI subsection + is composed of a name (usually a vendor name), an optionality status (optional + or required), and the expected type of its associated attributes (ULEB128 or + NTBS). Note: The attributes in the same subsection have all the same type. + An attribute is composed of a tag identifier (ULEB128), and its value (ULEB128 + or NTBS). + + Syntax: + .aeabi_subsection NameOfTheSubsection: string (=NTBS), + Optional: boolean (=ULEB128), + AttributeValueType: enum{ULEB128, NTBS} (=ULEB128) + [ + .aeabi_attribute TagIdentifier: ULEB128, + TagValue: Variant[ULEB128|NTBS] + ]* + + Example: + .aeabi_subsection .aeabi-feature-and-bits, optional, ULEB128 + .aeabi_attribute Tag_Feature_GCS, 1 // Tag_Feature_GCS: true + + Note: The textual representations of the tag and its value are emitted as a + comment along their numerical representations to annotate the assembler + output when the developer flag '-dA' is provided. */ +template < + typename T_tag, /* The type of a tag. */ + typename T_val, /* The type of a value. */ + size_t N = 0 /* The number of expected attributes if we know it. */ +> +class aeabi_subsection +{ + public: + aeabi_subsection (const char *name, bool optional) + : m_name (name), + m_optionality (optional + ? subsection_optionality::optional + : subsection_optionality::required), + m_avtype (details::deduce_attr_av_type (T_val{})) + {} + + /* Append an attribute to the subsection. */ + void append (aeabi_attribute<T_tag, T_val> &&attr) + { + m_attributes.quick_push (std::move (attr)); + } + + /* Write the data to the assembly file. */ + void write (FILE *out_file) const + { + asm_fprintf (out_file, "\n\t.aeabi_subsection %s, %s, %s\n", + m_name, details::to_c_str (m_optionality), + details::to_c_str (m_avtype)); + + for (auto const &attr : m_attributes) + details::write (out_file, attr); + } + + /* Indicate if the subsection is empty. */ + bool empty () const + { + return m_attributes.is_empty (); + } + + private: + const char *m_name; + subsection_optionality m_optionality; + subsection_val_type m_avtype; + auto_vec<aeabi_attribute<T_tag, T_val>, N> m_attributes; +}; + +} // namespace aarch64 + +#endif /* GCC_AARCH64_ELF_METADATA_H */ diff --git a/gcc/config/aarch64/aarch64-option-extensions.def b/gcc/config/aarch64/aarch64-option-extensions.def index dbbb021f05ac..1c3e69799f5a 100644 --- a/gcc/config/aarch64/aarch64-option-extensions.def +++ b/gcc/config/aarch64/aarch64-option-extensions.def @@ -249,6 +249,8 @@ AARCH64_OPT_EXTENSION("mops", MOPS, (), (), (), "mops") AARCH64_OPT_EXTENSION("cssc", CSSC, (), (), (), "cssc") +AARCH64_OPT_EXTENSION("cmpbr", CMPBR, (), (), (), "cmpbr") + AARCH64_OPT_EXTENSION("lse128", LSE128, (LSE), (), (), "lse128") AARCH64_OPT_EXTENSION("d128", D128, (LSE128), (), (), "d128") diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 8f37e56d440e..e946e8da11da 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -947,6 +947,7 @@ bool aarch64_parallel_select_half_p (machine_mode, rtx); bool aarch64_pars_overlap_p (rtx, rtx); bool aarch64_simd_scalar_immediate_valid_for_move (rtx, scalar_int_mode); bool aarch64_simd_shift_imm_p (rtx, machine_mode, bool); +bool aarch64_sve_valid_pred_p (rtx, machine_mode); bool aarch64_sve_ptrue_svpattern_p (rtx, struct simd_immediate_info *); bool aarch64_simd_valid_and_imm (rtx); bool aarch64_simd_valid_and_imm_fmov (rtx, unsigned int * = NULL); @@ -1028,6 +1029,8 @@ rtx aarch64_ptrue_reg (machine_mode, unsigned int); rtx aarch64_ptrue_reg (machine_mode, machine_mode); rtx aarch64_pfalse_reg (machine_mode); bool aarch64_sve_same_pred_for_ptest_p (rtx *, rtx *); +rtx aarch64_sve_packed_pred (machine_mode); +rtx aarch64_sve_fp_pred (machine_mode, rtx *); void aarch64_emit_load_store_through_mode (rtx, rtx, machine_mode); bool aarch64_expand_maskloadstore (rtx *, machine_mode); void aarch64_emit_sve_pred_move (rtx, rtx, rtx); @@ -1036,6 +1039,7 @@ bool aarch64_maybe_expand_sve_subreg_move (rtx, rtx); rtx aarch64_replace_reg_mode (rtx, machine_mode); void aarch64_split_sve_subreg_move (rtx, rtx, rtx); void aarch64_expand_prologue (void); +void aarch64_decompose_vec_struct_index (machine_mode, rtx *, rtx *, bool); void aarch64_expand_vector_init (rtx, rtx); void aarch64_sve_expand_vector_init_subvector (rtx, rtx); void aarch64_sve_expand_vector_init (rtx, rtx); @@ -1131,6 +1135,8 @@ bool aarch64_general_check_builtin_call (location_t, vec<location_t>, unsigned int, tree, unsigned int, tree *); +bool aarch64_cb_rhs (rtx_code op_code, rtx rhs); + namespace aarch64 { void report_non_ice (location_t, tree, unsigned int); void report_out_of_range (location_t, tree, unsigned int, HOST_WIDE_INT, @@ -1267,6 +1273,7 @@ void aarch64_expand_reversed_crc_using_pmull (scalar_mode, scalar_mode, rtx *); void aarch64_expand_fp_spaceship (rtx, rtx, rtx, rtx); +extern bool aarch64_pacret_enabled (); extern bool aarch64_gcs_enabled (); extern unsigned aarch64_data_alignment (const_tree exp, unsigned align); diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 6e30dc48934c..8b75c3d7f6d5 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -1190,13 +1190,16 @@ [(set_attr "type" "neon_ins<q>, neon_from_gp<q>, neon_load1_one_lane<q>")] ) +;; Inserting from the zero register into a vector lane is treated as an +;; expensive GP->FP move on all CPUs. Avoid it when optimizing for speed. (define_insn "aarch64_simd_vec_set_zero<mode>" [(set (match_operand:VALL_F16 0 "register_operand" "=w") (vec_merge:VALL_F16 (match_operand:VALL_F16 1 "register_operand" "0") (match_operand:VALL_F16 3 "aarch64_simd_imm_zero" "") (match_operand:SI 2 "immediate_operand" "i")))] - "TARGET_SIMD && aarch64_exact_log2_inverse (<nunits>, operands[2]) >= 0" + "TARGET_SIMD && aarch64_exact_log2_inverse (<nunits>, operands[2]) >= 0 + && optimize_function_for_size_p (cfun)" { int elt = ENDIAN_LANE_N (<nunits>, aarch64_exact_log2_inverse (<nunits>, @@ -1628,6 +1631,24 @@ } ) +(define_expand "vec_set<mode>" + [(match_operand:VSTRUCT_QD 0 "register_operand") + (match_operand:<VEL> 1 "aarch64_simd_nonimmediate_operand") + (match_operand:SI 2 "immediate_operand")] + "TARGET_SIMD" +{ + aarch64_decompose_vec_struct_index (<VSTRUCT_ELT>mode, &operands[0], + &operands[2], true); + /* For tuples of 64-bit modes, <vstruct_elt> is the 64-bit scalar mode. + Allow gen_vec_set<vstruct_elt> to cope with those cases too. */ + auto gen_vec_setdi ATTRIBUTE_UNUSED = [](rtx x0, rtx x1, rtx) + { + return gen_move_insn (x0, x1); + }; + auto gen_vec_setdf ATTRIBUTE_UNUSED = gen_vec_setdi; + emit_insn (gen_vec_set<vstruct_elt> (operands[0], operands[1], operands[2])); + DONE; +}) (define_insn "aarch64_mla<mode><vczle><vczbe>" [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w") @@ -3948,7 +3969,7 @@ rtx cc_reg = aarch64_gen_compare_reg (code, val, const0_rtx); rtx cmp_rtx = gen_rtx_fmt_ee (code, DImode, cc_reg, const0_rtx); - emit_jump_insn (gen_condjump (cmp_rtx, cc_reg, operands[3])); + emit_jump_insn (gen_aarch64_bcond (cmp_rtx, cc_reg, operands[3])); DONE; }) @@ -5028,6 +5049,36 @@ DONE; }) +;; convert (truncate)(~x >> imm) into (truncate)(((u16)-1 - x) >> imm) +;; because it will result in the 'not' being replaced with a constant load +;; which allows for better loop optimization. +;; We limit this to truncations that take the upper half and shift it to the +;; lower half as we use subhn (patterns that would have generated an shrn +;; otherwise). +;; On some implementations the use of subhn also result in better throughput. +(define_insn_and_split "*shrn_to_subhn_<mode>" + [(set (match_operand:<VNARROWQ> 0 "register_operand" "=&w") + (truncate:<VNARROWQ> + (lshiftrt:VQN + (not:VQN (match_operand:VQN 1 "register_operand" "w")) + (match_operand:VQN 2 "aarch64_simd_shift_imm_vec_exact_top"))))] + "TARGET_SIMD" + "#" + "&& true" + [(const_int 0)] +{ + rtx tmp; + if (can_create_pseudo_p ()) + tmp = gen_reg_rtx (<MODE>mode); + else + tmp = gen_rtx_REG (<MODE>mode, REGNO (operands[0])); + emit_move_insn (tmp, CONSTM1_RTX (<MODE>mode)); + emit_insn (gen_aarch64_subhn<mode>_insn (operands[0], tmp, + operands[1], operands[2])); + DONE; +}) + + ;; pmul. (define_insn "aarch64_pmul<mode>" @@ -8883,6 +8934,26 @@ DONE; }) +(define_expand "vec_extract<mode><Vel>" + [(match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand") + (match_operand:VSTRUCT_QD 1 "register_operand") + (match_operand:SI 2 "immediate_operand")] + "TARGET_SIMD" +{ + aarch64_decompose_vec_struct_index (<VSTRUCT_ELT>mode, &operands[1], + &operands[2], false); + /* For tuples of 64-bit modes, <vstruct_elt> is the 64-bit scalar mode. + Allow gen_vec_extract<vstruct_elt><Vel> to cope with those cases too. */ + auto gen_vec_extractdidi ATTRIBUTE_UNUSED = [](rtx x0, rtx x1, rtx) + { + return gen_move_insn (x0, x1); + }; + auto gen_vec_extractdfdf ATTRIBUTE_UNUSED = gen_vec_extractdidi; + emit_insn (gen_vec_extract<vstruct_elt><Vel> (operands[0], operands[1], + operands[2])); + DONE; +}) + ;; Extract a 64-bit vector from one half of a 128-bit vector. (define_expand "vec_extract<mode><Vhalf>" [(match_operand:<VHALF> 0 "register_operand") @@ -9112,12 +9183,12 @@ ;; sha3 (define_insn "eor3q<mode>4" - [(set (match_operand:VQ_I 0 "register_operand" "=w") - (xor:VQ_I - (xor:VQ_I - (match_operand:VQ_I 2 "register_operand" "w") - (match_operand:VQ_I 3 "register_operand" "w")) - (match_operand:VQ_I 1 "register_operand" "w")))] + [(set (match_operand:VDQ_I 0 "register_operand" "=w") + (xor:VDQ_I + (xor:VDQ_I + (match_operand:VDQ_I 2 "register_operand" "w") + (match_operand:VDQ_I 3 "register_operand" "w")) + (match_operand:VDQ_I 1 "register_operand" "w")))] "TARGET_SHA3" "eor3\\t%0.16b, %1.16b, %2.16b, %3.16b" [(set_attr "type" "crypto_sha3")] @@ -9173,17 +9244,46 @@ ) (define_insn "bcaxq<mode>4" - [(set (match_operand:VQ_I 0 "register_operand" "=w") - (xor:VQ_I - (and:VQ_I - (not:VQ_I (match_operand:VQ_I 3 "register_operand" "w")) - (match_operand:VQ_I 2 "register_operand" "w")) - (match_operand:VQ_I 1 "register_operand" "w")))] + [(set (match_operand:VDQ_I 0 "register_operand" "=w") + (xor:VDQ_I + (and:VDQ_I + (not:VDQ_I (match_operand:VDQ_I 3 "register_operand" "w")) + (match_operand:VDQ_I 2 "register_operand" "w")) + (match_operand:VDQ_I 1 "register_operand" "w")))] "TARGET_SHA3" "bcax\\t%0.16b, %1.16b, %2.16b, %3.16b" [(set_attr "type" "crypto_sha3")] ) +(define_insn_and_split "*bcaxqdi4" + [(set (match_operand:DI 0 "register_operand") + (xor:DI + (and:DI + (not:DI (match_operand:DI 3 "register_operand")) + (match_operand:DI 2 "register_operand")) + (match_operand:DI 1 "register_operand")))] + "TARGET_SHA3" + {@ [ cons: =0, 1, 2 , 3 ; attrs: type ] + [ w , w, w , w ; crypto_sha3 ] bcax\t%0.16b, %1.16b, %2.16b, %3.16b + [ &r , r, r0, r0 ; multiple ] # + } + "&& REG_P (operands[0]) && GP_REGNUM_P (REGNO (operands[0]))" + [(set (match_dup 4) + (and:DI (not:DI (match_dup 3)) + (match_dup 2))) + (set (match_dup 0) + (xor:DI (match_dup 4) + (match_dup 1)))] + { + if (reload_completed) + operands[4] = operands[0]; + else if (can_create_pseudo_p ()) + operands[4] = gen_reg_rtx (DImode); + else + FAIL; + } +) + ;; SM3 (define_insn "aarch64_sm3ss1qv4si" diff --git a/gcc/config/aarch64/aarch64-sme.md b/gcc/config/aarch64/aarch64-sme.md index c49affd0dd39..6b3f4390943a 100644 --- a/gcc/config/aarch64/aarch64-sme.md +++ b/gcc/config/aarch64/aarch64-sme.md @@ -38,6 +38,7 @@ ;; ---- Binary arithmetic on ZA tile ;; ---- Binary arithmetic on ZA slice ;; ---- Binary arithmetic, writing to ZA slice +;; ---- Absolute minimum/maximum ;; ;; == Ternary arithmetic ;; ---- [INT] Dot product @@ -373,6 +374,8 @@ (reg:DI SME_STATE_REGNUM) (reg:DI TPIDR2_SETUP_REGNUM) (reg:DI ZA_SAVED_REGNUM)] UNSPEC_RESTORE_ZA)) + (set (reg:DI SME_STATE_REGNUM) + (unspec:DI [(reg:DI SME_STATE_REGNUM)] UNSPEC_TPIDR2_RESTORE)) (clobber (reg:DI R0_REGNUM)) (clobber (reg:DI R14_REGNUM)) (clobber (reg:DI R15_REGNUM)) @@ -389,7 +392,7 @@ auto label = gen_label_rtx (); auto tpidr2 = gen_rtx_REG (DImode, R16_REGNUM); emit_insn (gen_aarch64_read_tpidr2 (tpidr2)); - auto jump = emit_likely_jump_insn (gen_aarch64_cbnedi1 (tpidr2, label)); + auto jump = emit_likely_jump_insn (gen_aarch64_cbznedi1 (tpidr2, label)); JUMP_LABEL (jump) = label; aarch64_restore_za (operands[0]); @@ -1262,6 +1265,23 @@ "<sme_int_op>\tza.<Vetype>[%w0, %1, vgx<vector_count>], %2, %3.<Vetype>" ) +;; ------------------------------------------------------------------------- +;; ---- Absolute minimum/maximum +;; ------------------------------------------------------------------------- +;; Includes: +;; - FAMIN (SME2+FAMINMAX) +;; - FAMAX (SME2+FAMINMAX) +;; ------------------------------------------------------------------------- + +(define_insn "@aarch64_sme_<faminmax_uns_op><mode>" + [(set (match_operand:SVE_Fx24 0 "register_operand" "=Uw<vector_count>") + (unspec:SVE_Fx24 [(match_operand:SVE_Fx24 1 "register_operand" "%0") + (match_operand:SVE_Fx24 2 "register_operand" "Uw<vector_count>")] + FAMINMAX_UNS))] + "TARGET_STREAMING_SME2 && TARGET_FAMINMAX" + "<faminmax_uns_op>\t%0, %1, %2" +) + ;; ========================================================================= ;; == Ternary arithmetic ;; ========================================================================= diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sme.def b/gcc/config/aarch64/aarch64-sve-builtins-sme.def index f75c0a5b8b13..8e6aadce7de9 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-sme.def +++ b/gcc/config/aarch64/aarch64-sve-builtins-sme.def @@ -92,6 +92,11 @@ DEF_SME_FUNCTION (svstr_zt, str_zt, none, none) DEF_SME_FUNCTION (svzero_zt, inherent_zt, none, none) #undef REQUIRED_EXTENSIONS +#define REQUIRED_EXTENSIONS streaming_only (AARCH64_FL_SME2 && AARCH64_FL_FAMINMAX) +DEF_SME_FUNCTION_GS (svamin, binary_opt_single_n, all_float, x24, none) +DEF_SME_FUNCTION_GS (svamax, binary_opt_single_n, all_float, x24, none) +#undef REQUIRED_EXTENSIONS + /* The d_za entries in this section just declare C _za64 overloads, which will then be resolved to either an integer function or a floating-point function. They are needed because the integer and diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc b/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc index d9922de7ca5a..73004a8fd5c5 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc @@ -316,7 +316,8 @@ class svld1q_gather_impl : public full_width_access expand (function_expander &e) const override { e.prepare_gather_address_operands (1, false); - return e.use_exact_insn (CODE_FOR_aarch64_gather_ld1q); + auto icode = code_for_aarch64_gather_ld1q (e.tuple_mode (0)); + return e.use_exact_insn (icode); } }; @@ -722,7 +723,7 @@ class svst1q_scatter_impl : public full_width_access expand (function_expander &e) const override { rtx data = e.args.last (); - e.args.last () = force_lowpart_subreg (VNx2DImode, data, GET_MODE (data)); + e.args.last () = aarch64_sve_reinterpret (VNx2DImode, data); e.prepare_gather_address_operands (1, false); return e.use_exact_insn (CODE_FOR_aarch64_scatter_st1q); } @@ -929,6 +930,44 @@ class svluti_lane_impl : public function_base unsigned int m_bits; }; +/* The same as cond_or_uncond_unspec_function but the intrinsics with vector + modes are SME2 extensions instead of SVE. */ +class faminmaximpl : public function_base +{ +public: + CONSTEXPR faminmaximpl (int cond_unspec, int uncond_unspec) + : m_cond_unspec (cond_unspec), m_uncond_unspec (uncond_unspec) + {} + + rtx + expand (function_expander &e) const override + { + if (e.group_suffix ().vectors_per_tuple > 1) + { + /* SME2+faminmax intrinsics. */ + gcc_assert (e.pred == PRED_none); + auto mode = e.tuple_mode (0); + auto icode = (code_for_aarch64_sme (m_uncond_unspec, mode)); + return e.use_exact_insn (icode); + } + /* SVE+faminmax intrinsics. */ + else if (e.pred == PRED_none) + { + auto mode = e.tuple_mode (0); + auto icode = (e.mode_suffix_id == MODE_single + ? code_for_aarch64_sve_single (m_uncond_unspec, mode) + : code_for_aarch64_sve (m_uncond_unspec, mode)); + return e.use_exact_insn (icode); + } + return e.map_to_unspecs (m_cond_unspec, m_cond_unspec, m_cond_unspec); + } + + /* The unspecs for the conditional and unconditional instructions, + respectively. */ + int m_cond_unspec; + int m_uncond_unspec; +}; + } /* end anonymous namespace */ namespace aarch64_sve { @@ -957,10 +996,8 @@ FUNCTION (svaesd, fixed_insn_function, (CODE_FOR_aarch64_sve2_aesd)) FUNCTION (svaese, fixed_insn_function, (CODE_FOR_aarch64_sve2_aese)) FUNCTION (svaesimc, fixed_insn_function, (CODE_FOR_aarch64_sve2_aesimc)) FUNCTION (svaesmc, fixed_insn_function, (CODE_FOR_aarch64_sve2_aesmc)) -FUNCTION (svamax, cond_or_uncond_unspec_function, - (UNSPEC_COND_FAMAX, UNSPEC_FAMAX)) -FUNCTION (svamin, cond_or_uncond_unspec_function, - (UNSPEC_COND_FAMIN, UNSPEC_FAMIN)) +FUNCTION (svamax, faminmaximpl, (UNSPEC_COND_FAMAX, UNSPEC_FAMAX)) +FUNCTION (svamin, faminmaximpl, (UNSPEC_COND_FAMIN, UNSPEC_FAMIN)) FUNCTION (svandqv, reduction, (UNSPEC_ANDQV, UNSPEC_ANDQV, -1)) FUNCTION (svbcax, CODE_FOR_MODE0 (aarch64_sve2_bcax),) FUNCTION (svbdep, unspec_based_function, (UNSPEC_BDEP, UNSPEC_BDEP, -1)) diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc index 36519262efd5..2b627a950602 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc @@ -47,6 +47,8 @@ #include "langhooks.h" #include "stringpool.h" #include "attribs.h" +#include "value-range.h" +#include "tree-ssanames.h" #include "aarch64-sve-builtins.h" #include "aarch64-sve-builtins-base.h" #include "aarch64-sve-builtins-sve2.h" @@ -3664,7 +3666,8 @@ gimple_folder::fold_pfalse () /* Convert the lhs and all non-boolean vector-type operands to TYPE. Pass the converted variables to the callback FP, and finally convert the result back to the original type. Add the necessary conversion statements. - Return the new call. */ + Return the new call. Note the tree argument to the callback FP, can only + be set once; it will always be a SSA_NAME. */ gimple * gimple_folder::convert_and_fold (tree type, gimple *(*fp) (gimple_folder &, @@ -3675,7 +3678,7 @@ gimple_folder::convert_and_fold (tree type, tree old_ty = TREE_TYPE (lhs); gimple_seq stmts = NULL; bool convert_lhs_p = !useless_type_conversion_p (type, old_ty); - tree lhs_conv = convert_lhs_p ? create_tmp_var (type) : lhs; + tree lhs_conv = convert_lhs_p ? make_ssa_name (type) : lhs; unsigned int num_args = gimple_call_num_args (call); auto_vec<tree, 16> args_conv; args_conv.safe_grow (num_args); diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index c5d3e8cd3b32..10aecf1f1901 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -154,8 +154,10 @@ ;; ---- [FP<-INT] Packs ;; ---- [FP<-INT] Unpacks ;; ---- [FP<-FP] Packs +;; ---- [FP<-FP] Truncating conversions ;; ---- [FP<-FP] Packs (bfloat16) ;; ---- [FP<-FP] Unpacks +;; ---- [FP<-FP] Extending conversions ;; ---- [PRED<-PRED] Packs ;; ---- [PRED<-PRED] Unpacks ;; @@ -1342,7 +1344,7 @@ "TARGET_SVE" { operands[2] = aarch64_ptrue_reg (<VPRED>mode); - operands[3] = CONST0_RTX (<MODE>mode); + operands[3] = CONST0_RTX (<VSINGLE>mode); } ) @@ -1352,7 +1354,7 @@ (unspec:SVE_STRUCT [(match_operand:<VPRED> 2 "register_operand" "Upl") (match_operand:SVE_STRUCT 1 "memory_operand" "m") - (match_operand 3 "aarch64_maskload_else_operand")] + (match_operand:<VSINGLE> 3 "aarch64_maskload_else_operand")] UNSPEC_LDN))] "TARGET_SVE" "ld<vector_count><Vesize>\t%0, %2/z, %1" @@ -3948,6 +3950,7 @@ ;; ------------------------------------------------------------------------- ;; Includes: ;; - NOT +;; - NOTS ;; ------------------------------------------------------------------------- ;; Unpredicated predicate inverse. @@ -3963,7 +3966,7 @@ ) ;; Predicated predicate inverse. -(define_insn "*one_cmpl<mode>3" +(define_insn "@aarch64_pred_one_cmpl<mode>_z" [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa") (and:PRED_ALL (not:PRED_ALL (match_operand:PRED_ALL 2 "register_operand" "Upa")) @@ -3972,6 +3975,42 @@ "not\t%0.b, %1/z, %2.b" ) +;; Predicated predicate inverse in which the flags are set in the same +;; way as a PTEST. +(define_insn "*one_cmpl<mode>3_cc" + [(set (reg:CC_NZC CC_REGNUM) + (unspec:CC_NZC + [(match_operand:VNx16BI 1 "register_operand" "Upa") + (match_operand 3) + (match_operand:SI 4 "aarch64_sve_ptrue_flag") + (and:PRED_ALL + (not:PRED_ALL + (match_operand:PRED_ALL 2 "register_operand" "Upa")) + (match_dup 3))] + UNSPEC_PTEST)) + (set (match_operand:PRED_ALL 0 "register_operand" "=Upa") + (and:PRED_ALL (not:PRED_ALL (match_dup 2)) (match_dup 3)))] + "TARGET_SVE" + "nots\t%0.b, %1/z, %2.b" +) + +;; Same, where only the flags result is interesting. +(define_insn "*one_cmpl<mode>3_ptest" + [(set (reg:CC_NZC CC_REGNUM) + (unspec:CC_NZC + [(match_operand:VNx16BI 1 "register_operand" "Upa") + (match_operand 3) + (match_operand:SI 4 "aarch64_sve_ptrue_flag") + (and:PRED_ALL + (not:PRED_ALL + (match_operand:PRED_ALL 2 "register_operand" "Upa")) + (match_dup 3))] + UNSPEC_PTEST)) + (clobber (match_scratch:PRED_ALL 0 "=Upa"))] + "TARGET_SVE" + "nots\t%0.b, %1/z, %2.b" +) + ;; ========================================================================= ;; == Binary arithmetic ;; ========================================================================= @@ -5456,27 +5495,27 @@ ;; Split a predicated instruction whose predicate is unused into an ;; unpredicated instruction. (define_split - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_operand:<VPRED> 1 "register_operand") (match_operand:SI 4 "aarch64_sve_gp_strictness") - (match_operand:SVE_FULL_F_BF 2 "register_operand") - (match_operand:SVE_FULL_F_BF 3 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 2 "register_operand") + (match_operand:SVE_FULL_F_B16B16 3 "register_operand")] <SVE_COND_FP>))] "TARGET_SVE && reload_completed && INTVAL (operands[4]) == SVE_RELAXED_GP" [(set (match_dup 0) - (SVE_UNPRED_FP_BINARY:SVE_FULL_F_BF (match_dup 2) (match_dup 3)))] + (SVE_UNPRED_FP_BINARY:SVE_FULL_F_B16B16 (match_dup 2) (match_dup 3)))] ) ;; Unpredicated floating-point binary operations (post-RA only). ;; These are generated by the split above. (define_insn "*post_ra_<sve_fp_op><mode>3" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand" "=w") - (SVE_UNPRED_FP_BINARY:SVE_FULL_F_BF - (match_operand:SVE_FULL_F_BF 1 "register_operand" "w") - (match_operand:SVE_FULL_F_BF 2 "register_operand" "w")))] + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand" "=w") + (SVE_UNPRED_FP_BINARY:SVE_FULL_F_B16B16 + (match_operand:SVE_FULL_F_B16B16 1 "register_operand" "w") + (match_operand:SVE_FULL_F_B16B16 2 "register_operand" "w")))] "TARGET_SVE && reload_completed" "<b><sve_fp_op>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>") @@ -5520,12 +5559,12 @@ ;; Unpredicated floating-point binary operations that need to be predicated ;; for SVE. (define_expand "<optab><mode>3" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_dup 3) (const_int SVE_RELAXED_GP) - (match_operand:SVE_FULL_F_BF 1 "<sve_pred_fp_rhs1_operand>") - (match_operand:SVE_FULL_F_BF 2 "<sve_pred_fp_rhs2_operand>")] + (match_operand:SVE_FULL_F_B16B16 1 "<sve_pred_fp_rhs1_operand>") + (match_operand:SVE_FULL_F_B16B16 2 "<sve_pred_fp_rhs2_operand>")] SVE_COND_FP_BINARY_OPTAB))] "TARGET_SVE && (<supports_bf16> || !<is_bf16>)" { @@ -5552,30 +5591,30 @@ ;; Predicated floating-point operations with merging. (define_expand "@cond_<optab><mode>" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_operand:<VPRED> 1 "register_operand") - (unspec:SVE_FULL_F_BF + (unspec:SVE_FULL_F_B16B16 [(match_dup 1) (const_int SVE_STRICT_GP) - (match_operand:SVE_FULL_F_BF 2 "<sve_pred_fp_rhs1_operand>") - (match_operand:SVE_FULL_F_BF 3 "<sve_pred_fp_rhs2_operand>")] + (match_operand:SVE_FULL_F_B16B16 2 "<sve_pred_fp_rhs1_operand>") + (match_operand:SVE_FULL_F_B16B16 3 "<sve_pred_fp_rhs2_operand>")] SVE_COND_FP_BINARY) - (match_operand:SVE_FULL_F_BF 4 "aarch64_simd_reg_or_zero")] + (match_operand:SVE_FULL_F_B16B16 4 "aarch64_simd_reg_or_zero")] UNSPEC_SEL))] "TARGET_SVE && (<supports_bf16> || !<is_bf16>)" ) ;; Predicated floating-point operations, merging with the first input. (define_insn_and_rewrite "*cond_<optab><mode>_2_relaxed" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_operand:<VPRED> 1 "register_operand") - (unspec:SVE_FULL_F_BF + (unspec:SVE_FULL_F_B16B16 [(match_operand 4) (const_int SVE_RELAXED_GP) - (match_operand:SVE_FULL_F_BF 2 "register_operand") - (match_operand:SVE_FULL_F_BF 3 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 2 "register_operand") + (match_operand:SVE_FULL_F_B16B16 3 "register_operand")] SVE_COND_FP_BINARY) (match_dup 2)] UNSPEC_SEL))] @@ -5591,14 +5630,14 @@ ) (define_insn "*cond_<optab><mode>_2_strict" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_operand:<VPRED> 1 "register_operand") - (unspec:SVE_FULL_F_BF + (unspec:SVE_FULL_F_B16B16 [(match_dup 1) (const_int SVE_STRICT_GP) - (match_operand:SVE_FULL_F_BF 2 "register_operand") - (match_operand:SVE_FULL_F_BF 3 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 2 "register_operand") + (match_operand:SVE_FULL_F_B16B16 3 "register_operand")] SVE_COND_FP_BINARY) (match_dup 2)] UNSPEC_SEL))] @@ -5654,14 +5693,14 @@ ;; Predicated floating-point operations, merging with the second input. (define_insn_and_rewrite "*cond_<optab><mode>_3_relaxed" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_operand:<VPRED> 1 "register_operand") - (unspec:SVE_FULL_F_BF + (unspec:SVE_FULL_F_B16B16 [(match_operand 4) (const_int SVE_RELAXED_GP) - (match_operand:SVE_FULL_F_BF 2 "register_operand") - (match_operand:SVE_FULL_F_BF 3 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 2 "register_operand") + (match_operand:SVE_FULL_F_B16B16 3 "register_operand")] SVE_COND_FP_BINARY) (match_dup 3)] UNSPEC_SEL))] @@ -5677,14 +5716,14 @@ ) (define_insn "*cond_<optab><mode>_3_strict" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_operand:<VPRED> 1 "register_operand") - (unspec:SVE_FULL_F_BF + (unspec:SVE_FULL_F_B16B16 [(match_dup 1) (const_int SVE_STRICT_GP) - (match_operand:SVE_FULL_F_BF 2 "register_operand") - (match_operand:SVE_FULL_F_BF 3 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 2 "register_operand") + (match_operand:SVE_FULL_F_B16B16 3 "register_operand")] SVE_COND_FP_BINARY) (match_dup 3)] UNSPEC_SEL))] @@ -5697,16 +5736,16 @@ ;; Predicated floating-point operations, merging with an independent value. (define_insn_and_rewrite "*cond_<optab><mode>_any_relaxed" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_operand:<VPRED> 1 "register_operand") - (unspec:SVE_FULL_F_BF + (unspec:SVE_FULL_F_B16B16 [(match_operand 5) (const_int SVE_RELAXED_GP) - (match_operand:SVE_FULL_F_BF 2 "register_operand") - (match_operand:SVE_FULL_F_BF 3 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 2 "register_operand") + (match_operand:SVE_FULL_F_B16B16 3 "register_operand")] SVE_COND_FP_BINARY) - (match_operand:SVE_FULL_F_BF 4 "aarch64_simd_reg_or_zero")] + (match_operand:SVE_FULL_F_B16B16 4 "aarch64_simd_reg_or_zero")] UNSPEC_SEL))] "TARGET_SVE && (<supports_bf16> || !<is_bf16>) @@ -5741,16 +5780,16 @@ ) (define_insn_and_rewrite "*cond_<optab><mode>_any_strict" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_operand:<VPRED> 1 "register_operand") - (unspec:SVE_FULL_F_BF + (unspec:SVE_FULL_F_B16B16 [(match_dup 1) (const_int SVE_STRICT_GP) - (match_operand:SVE_FULL_F_BF 2 "register_operand") - (match_operand:SVE_FULL_F_BF 3 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 2 "register_operand") + (match_operand:SVE_FULL_F_B16B16 3 "register_operand")] SVE_COND_FP_BINARY) - (match_operand:SVE_FULL_F_BF 4 "aarch64_simd_reg_or_zero")] + (match_operand:SVE_FULL_F_B16B16 4 "aarch64_simd_reg_or_zero")] UNSPEC_SEL))] "TARGET_SVE && (<supports_bf16> || !<is_bf16>) @@ -6614,13 +6653,13 @@ ;; Unpredicated multiplication by selected lanes. (define_insn "@aarch64_mul_lane_<mode>" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand" "=w") - (mult:SVE_FULL_F_BF - (unspec:SVE_FULL_F_BF - [(match_operand:SVE_FULL_F_BF 2 "register_operand" "<sve_lane_con>") + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand" "=w") + (mult:SVE_FULL_F_B16B16 + (unspec:SVE_FULL_F_B16B16 + [(match_operand:SVE_FULL_F_B16B16 2 "register_operand" "<sve_lane_con>") (match_operand:SI 3 "const_int_operand")] UNSPEC_SVE_LANE_SELECT) - (match_operand:SVE_FULL_F_BF 1 "register_operand" "w")))] + (match_operand:SVE_FULL_F_B16B16 1 "register_operand" "w")))] "TARGET_SVE" "<b>fmul\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>[%3]" ) @@ -6679,10 +6718,10 @@ ;; by providing this, but we need to use UNSPECs since rtx logical ops ;; aren't defined for floating-point modes. (define_insn "*<optab><mode>3" - [(set (match_operand:SVE_F 0 "register_operand" "=w") - (unspec:SVE_F - [(match_operand:SVE_F 1 "register_operand" "w") - (match_operand:SVE_F 2 "register_operand" "w")] + [(set (match_operand:SVE_F_BF 0 "register_operand" "=w") + (unspec:SVE_F_BF + [(match_operand:SVE_F_BF 1 "register_operand" "w") + (match_operand:SVE_F_BF 2 "register_operand" "w")] LOGICALF))] "TARGET_SVE" "<logicalf_op>\t%0.d, %1.d, %2.d" @@ -7542,13 +7581,13 @@ ;; Unpredicated floating-point ternary operations. (define_expand "<optab><mode>4" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_dup 4) (const_int SVE_RELAXED_GP) - (match_operand:SVE_FULL_F_BF 1 "register_operand") - (match_operand:SVE_FULL_F_BF 2 "register_operand") - (match_operand:SVE_FULL_F_BF 3 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 1 "register_operand") + (match_operand:SVE_FULL_F_B16B16 2 "register_operand") + (match_operand:SVE_FULL_F_B16B16 3 "register_operand")] SVE_COND_FP_TERNARY))] "TARGET_SVE && (<supports_bf16> || !<is_bf16>)" { @@ -7558,13 +7597,13 @@ ;; Predicated floating-point ternary operations. (define_insn "@aarch64_pred_<optab><mode>" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_operand:<VPRED> 1 "register_operand") (match_operand:SI 5 "aarch64_sve_gp_strictness") - (match_operand:SVE_FULL_F_BF 2 "register_operand") - (match_operand:SVE_FULL_F_BF 3 "register_operand") - (match_operand:SVE_FULL_F_BF 4 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 2 "register_operand") + (match_operand:SVE_FULL_F_B16B16 3 "register_operand") + (match_operand:SVE_FULL_F_B16B16 4 "register_operand")] SVE_COND_FP_TERNARY))] "TARGET_SVE && (<supports_bf16> || !<is_bf16>)" {@ [ cons: =0 , 1 , %2 , 3 , 4 ; attrs: movprfx , is_rev ] @@ -7578,17 +7617,17 @@ ;; Predicated floating-point ternary operations with merging. (define_expand "@cond_<optab><mode>" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_operand:<VPRED> 1 "register_operand") - (unspec:SVE_FULL_F_BF + (unspec:SVE_FULL_F_B16B16 [(match_dup 1) (const_int SVE_STRICT_GP) - (match_operand:SVE_FULL_F_BF 2 "register_operand") - (match_operand:SVE_FULL_F_BF 3 "register_operand") - (match_operand:SVE_FULL_F_BF 4 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 2 "register_operand") + (match_operand:SVE_FULL_F_B16B16 3 "register_operand") + (match_operand:SVE_FULL_F_B16B16 4 "register_operand")] SVE_COND_FP_TERNARY) - (match_operand:SVE_FULL_F_BF 5 "aarch64_simd_reg_or_zero")] + (match_operand:SVE_FULL_F_B16B16 5 "aarch64_simd_reg_or_zero")] UNSPEC_SEL))] "TARGET_SVE && (<supports_bf16> || !<is_bf16>)" { @@ -7647,15 +7686,15 @@ ;; Predicated floating-point ternary operations, merging with the ;; third input. (define_insn_and_rewrite "*cond_<optab><mode>_4_relaxed" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_operand:<VPRED> 1 "register_operand") - (unspec:SVE_FULL_F_BF + (unspec:SVE_FULL_F_B16B16 [(match_operand 5) (const_int SVE_RELAXED_GP) - (match_operand:SVE_FULL_F_BF 2 "register_operand") - (match_operand:SVE_FULL_F_BF 3 "register_operand") - (match_operand:SVE_FULL_F_BF 4 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 2 "register_operand") + (match_operand:SVE_FULL_F_B16B16 3 "register_operand") + (match_operand:SVE_FULL_F_B16B16 4 "register_operand")] SVE_COND_FP_TERNARY) (match_dup 4)] UNSPEC_SEL))] @@ -7671,15 +7710,15 @@ ) (define_insn "*cond_<optab><mode>_4_strict" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_operand:<VPRED> 1 "register_operand") - (unspec:SVE_FULL_F_BF + (unspec:SVE_FULL_F_B16B16 [(match_dup 1) (const_int SVE_STRICT_GP) - (match_operand:SVE_FULL_F_BF 2 "register_operand") - (match_operand:SVE_FULL_F_BF 3 "register_operand") - (match_operand:SVE_FULL_F_BF 4 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 2 "register_operand") + (match_operand:SVE_FULL_F_B16B16 3 "register_operand") + (match_operand:SVE_FULL_F_B16B16 4 "register_operand")] SVE_COND_FP_TERNARY) (match_dup 4)] UNSPEC_SEL))] @@ -7693,17 +7732,17 @@ ;; Predicated floating-point ternary operations, merging with an ;; independent value. (define_insn_and_rewrite "*cond_<optab><mode>_any_relaxed" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_operand:<VPRED> 1 "register_operand") - (unspec:SVE_FULL_F_BF + (unspec:SVE_FULL_F_B16B16 [(match_operand 6) (const_int SVE_RELAXED_GP) - (match_operand:SVE_FULL_F_BF 2 "register_operand") - (match_operand:SVE_FULL_F_BF 3 "register_operand") - (match_operand:SVE_FULL_F_BF 4 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 2 "register_operand") + (match_operand:SVE_FULL_F_B16B16 3 "register_operand") + (match_operand:SVE_FULL_F_B16B16 4 "register_operand")] SVE_COND_FP_TERNARY) - (match_operand:SVE_FULL_F_BF 5 "aarch64_simd_reg_or_zero")] + (match_operand:SVE_FULL_F_B16B16 5 "aarch64_simd_reg_or_zero")] UNSPEC_SEL))] "TARGET_SVE && (<supports_bf16> || !<is_bf16>) @@ -7739,17 +7778,17 @@ ) (define_insn_and_rewrite "*cond_<optab><mode>_any_strict" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 [(match_operand:<VPRED> 1 "register_operand") - (unspec:SVE_FULL_F_BF + (unspec:SVE_FULL_F_B16B16 [(match_dup 1) (const_int SVE_STRICT_GP) - (match_operand:SVE_FULL_F_BF 2 "register_operand") - (match_operand:SVE_FULL_F_BF 3 "register_operand") - (match_operand:SVE_FULL_F_BF 4 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 2 "register_operand") + (match_operand:SVE_FULL_F_B16B16 3 "register_operand") + (match_operand:SVE_FULL_F_B16B16 4 "register_operand")] SVE_COND_FP_TERNARY) - (match_operand:SVE_FULL_F_BF 5 "aarch64_simd_reg_or_zero")] + (match_operand:SVE_FULL_F_B16B16 5 "aarch64_simd_reg_or_zero")] UNSPEC_SEL))] "TARGET_SVE && (<supports_bf16> || !<is_bf16>) @@ -7780,14 +7819,14 @@ ;; Unpredicated FMLA and FMLS by selected lanes. It doesn't seem worth using ;; (fma ...) since target-independent code won't understand the indexing. (define_insn "@aarch64_<optab>_lane_<mode>" - [(set (match_operand:SVE_FULL_F_BF 0 "register_operand") - (unspec:SVE_FULL_F_BF - [(match_operand:SVE_FULL_F_BF 1 "register_operand") - (unspec:SVE_FULL_F_BF - [(match_operand:SVE_FULL_F_BF 2 "register_operand") + [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") + (unspec:SVE_FULL_F_B16B16 + [(match_operand:SVE_FULL_F_B16B16 1 "register_operand") + (unspec:SVE_FULL_F_B16B16 + [(match_operand:SVE_FULL_F_B16B16 2 "register_operand") (match_operand:SI 3 "const_int_operand")] UNSPEC_SVE_LANE_SELECT) - (match_operand:SVE_FULL_F_BF 4 "register_operand")] + (match_operand:SVE_FULL_F_B16B16 4 "register_operand")] SVE_FP_TERNARY_LANE))] "TARGET_SVE" {@ [ cons: =0 , 1 , 2 , 4 ; attrs: movprfx ] @@ -8598,8 +8637,8 @@ (define_expand "vec_cmp<mode><vpred>" [(set (match_operand:<VPRED> 0 "register_operand") (match_operator:<VPRED> 1 "comparison_operator" - [(match_operand:SVE_FULL_F 2 "register_operand") - (match_operand:SVE_FULL_F 3 "aarch64_simd_reg_or_zero")]))] + [(match_operand:SVE_F 2 "register_operand") + (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero")]))] "TARGET_SVE" { aarch64_expand_sve_vec_cmp_float (operands[0], GET_CODE (operands[1]), @@ -8612,10 +8651,10 @@ (define_insn "@aarch64_pred_fcm<cmp_op><mode>" [(set (match_operand:<VPRED> 0 "register_operand") (unspec:<VPRED> - [(match_operand:<VPRED> 1 "register_operand") + [(match_operand:<VPRED> 1 "aarch64_predicate_operand") (match_operand:SI 2 "aarch64_sve_ptrue_flag") - (match_operand:SVE_FULL_F 3 "register_operand") - (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero")] + (match_operand:SVE_F 3 "register_operand") + (match_operand:SVE_F 4 "aarch64_simd_reg_or_zero")] SVE_COND_FP_CMP_I0))] "TARGET_SVE" {@ [ cons: =0 , 1 , 3 , 4 ] @@ -8628,10 +8667,10 @@ (define_insn "@aarch64_pred_fcmuo<mode>" [(set (match_operand:<VPRED> 0 "register_operand" "=Upa") (unspec:<VPRED> - [(match_operand:<VPRED> 1 "register_operand" "Upl") + [(match_operand:<VPRED> 1 "aarch64_predicate_operand" "Upl") (match_operand:SI 2 "aarch64_sve_ptrue_flag") - (match_operand:SVE_FULL_F 3 "register_operand" "w") - (match_operand:SVE_FULL_F 4 "register_operand" "w")] + (match_operand:SVE_F 3 "register_operand" "w") + (match_operand:SVE_F 4 "register_operand" "w")] UNSPEC_COND_FCMUO))] "TARGET_SVE" "fcmuo\t%0.<Vetype>, %1/z, %3.<Vetype>, %4.<Vetype>" @@ -8651,8 +8690,8 @@ (unspec:<VPRED> [(match_operand:<VPRED> 1) (const_int SVE_KNOWN_PTRUE) - (match_operand:SVE_FULL_F 2 "register_operand" "w, w") - (match_operand:SVE_FULL_F 3 "aarch64_simd_reg_or_zero" "Dz, w")] + (match_operand:SVE_F 2 "register_operand" "w, w") + (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w")] SVE_COND_FP_CMP_I0) (match_operand:<VPRED> 4 "register_operand" "Upl, Upl")))] "TARGET_SVE" @@ -8674,8 +8713,8 @@ (unspec:<VPRED> [(match_operand:<VPRED> 1) (const_int SVE_KNOWN_PTRUE) - (match_operand:SVE_FULL_F 2 "register_operand" "w") - (match_operand:SVE_FULL_F 3 "register_operand" "w")] + (match_operand:SVE_F 2 "register_operand" "w") + (match_operand:SVE_F 3 "register_operand" "w")] UNSPEC_COND_FCMUO) (match_operand:<VPRED> 4 "register_operand" "Upl")))] "TARGET_SVE" @@ -8701,8 +8740,8 @@ (unspec:<VPRED> [(match_operand:<VPRED> 1) (const_int SVE_KNOWN_PTRUE) - (match_operand:SVE_FULL_F 2 "register_operand" "w") - (match_operand:SVE_FULL_F 3 "aarch64_simd_reg_or_zero" "wDz")] + (match_operand:SVE_F 2 "register_operand" "w") + (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "wDz")] SVE_COND_FP_CMP_I0)) (match_operand:<VPRED> 4 "register_operand" "Upa")) (match_dup:<VPRED> 1))) @@ -8738,8 +8777,8 @@ (unspec:<VPRED> [(match_operand:<VPRED> 1) (const_int SVE_KNOWN_PTRUE) - (match_operand:SVE_FULL_F 2 "register_operand" "w") - (match_operand:SVE_FULL_F 3 "aarch64_simd_reg_or_zero" "wDz")] + (match_operand:SVE_F 2 "register_operand" "w") + (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "wDz")] SVE_COND_FP_CMP_I0)) (not:<VPRED> (match_operand:<VPRED> 4 "register_operand" "Upa"))) @@ -8769,6 +8808,7 @@ } ) +;; Same for unordered comparisons. (define_insn_and_split "*fcmuo<mode>_bic_combine" [(set (match_operand:<VPRED> 0 "register_operand" "=Upa") (and:<VPRED> @@ -8777,8 +8817,8 @@ (unspec:<VPRED> [(match_operand:<VPRED> 1) (const_int SVE_KNOWN_PTRUE) - (match_operand:SVE_FULL_F 2 "register_operand" "w") - (match_operand:SVE_FULL_F 3 "register_operand" "w")] + (match_operand:SVE_F 2 "register_operand" "w") + (match_operand:SVE_F 3 "register_operand" "w")] UNSPEC_COND_FCMUO)) (match_operand:<VPRED> 4 "register_operand" "Upa")) (match_dup:<VPRED> 1))) @@ -8804,7 +8844,6 @@ } ) -;; Same for unordered comparisons. (define_insn_and_split "*fcmuo<mode>_nor_combine" [(set (match_operand:<VPRED> 0 "register_operand" "=Upa") (and:<VPRED> @@ -8813,8 +8852,8 @@ (unspec:<VPRED> [(match_operand:<VPRED> 1) (const_int SVE_KNOWN_PTRUE) - (match_operand:SVE_FULL_F 2 "register_operand" "w") - (match_operand:SVE_FULL_F 3 "register_operand" "w")] + (match_operand:SVE_F 2 "register_operand" "w") + (match_operand:SVE_F 3 "register_operand" "w")] UNSPEC_COND_FCMUO)) (not:<VPRED> (match_operand:<VPRED> 4 "register_operand" "Upa"))) @@ -9487,18 +9526,37 @@ ;; - FCVTZU ;; ------------------------------------------------------------------------- -;; Unpredicated conversion of floats to integers of the same size (HF to HI, -;; SF to SI or DF to DI). -(define_expand "<optab><mode><v_int_equiv>2" - [(set (match_operand:<V_INT_EQUIV> 0 "register_operand") - (unspec:<V_INT_EQUIV> +;; Unpredicated conversion of floats to integers of the same size or wider, +;; excluding conversions from DF (see below). +(define_expand "<optab><SVE_HSF:mode><SVE_HSDI:mode>2" + [(set (match_operand:SVE_HSDI 0 "register_operand") + (unspec:SVE_HSDI + [(match_dup 2) + (match_dup 3) + (match_operand:SVE_HSF 1 "register_operand")] + SVE_COND_FCVTI))] + "TARGET_SVE + && (~(<SVE_HSDI:self_mask> | <SVE_HSDI:narrower_mask>) & <SVE_HSF:self_mask>) == 0" + { + operands[2] = aarch64_sve_fp_pred (<SVE_HSDI:MODE>mode, &operands[3]); + } +) + +;; SI <- DF can't use SI <- trunc (DI <- DF) without -ffast-math, so this +;; truncating variant of FCVTZ{S,U} is useful for auto-vectorization. +;; +;; DF is the only source mode for which the mask used above doesn't apply, +;; we define a separate pattern for it here. +(define_expand "<optab><VNx2DF_ONLY:mode><SVE_2SDI:mode>2" + [(set (match_operand:SVE_2SDI 0 "register_operand") + (unspec:SVE_2SDI [(match_dup 2) (const_int SVE_RELAXED_GP) - (match_operand:SVE_FULL_F 1 "register_operand")] + (match_operand:VNx2DF_ONLY 1 "register_operand")] SVE_COND_FCVTI))] "TARGET_SVE" { - operands[2] = aarch64_ptrue_reg (<VPRED>mode); + operands[2] = aarch64_ptrue_reg (VNx2BImode); } ) @@ -9517,18 +9575,37 @@ } ) -;; Predicated narrowing float-to-integer conversion. -(define_insn "@aarch64_sve_<optab>_trunc<VNx2DF_ONLY:mode><VNx4SI_ONLY:mode>" - [(set (match_operand:VNx4SI_ONLY 0 "register_operand") - (unspec:VNx4SI_ONLY +;; As above, for pairs used by the auto-vectorizer only. +(define_insn "*aarch64_sve_<optab>_nontrunc<SVE_PARTIAL_F:mode><SVE_HSDI:mode>" + [(set (match_operand:SVE_HSDI 0 "register_operand") + (unspec:SVE_HSDI + [(match_operand:<SVE_HSDI:VPRED> 1 "aarch64_predicate_operand") + (match_operand:SI 3 "aarch64_sve_gp_strictness") + (match_operand:SVE_PARTIAL_F 2 "register_operand")] + SVE_COND_FCVTI))] + "TARGET_SVE + && (~(<SVE_HSDI:self_mask> | <SVE_HSDI:narrower_mask>) & <SVE_PARTIAL_F:self_mask>) == 0" + {@ [ cons: =0 , 1 , 2 ; attrs: movprfx ] + [ w , Upl , 0 ; * ] fcvtz<su>\t%0.<SVE_HSDI:Vetype>, %1/m, %2.<SVE_PARTIAL_F:Vetype> + [ ?&w , Upl , w ; yes ] movprfx\t%0, %2\;fcvtz<su>\t%0.<SVE_HSDI:Vetype>, %1/m, %2.<SVE_PARTIAL_F:Vetype> + } +) + +;; Predicated narrowing float-to-integer conversion. The VNx2DF->VNx4SI +;; variant is provided for the ACLE, where the zeroed odd-indexed lanes are +;; significant. The VNx2DF->VNx2SI variant is provided for auto-vectorization, +;; where the upper 32 bits of each container are ignored. +(define_insn "@aarch64_sve_<optab>_trunc<VNx2DF_ONLY:mode><SVE_SI:mode>" + [(set (match_operand:SVE_SI 0 "register_operand") + (unspec:SVE_SI [(match_operand:VNx2BI 1 "register_operand") (match_operand:SI 3 "aarch64_sve_gp_strictness") (match_operand:VNx2DF_ONLY 2 "register_operand")] SVE_COND_FCVTI))] "TARGET_SVE" {@ [ cons: =0 , 1 , 2 ; attrs: movprfx ] - [ w , Upl , 0 ; * ] fcvtz<su>\t%0.<VNx4SI_ONLY:Vetype>, %1/m, %2.<VNx2DF_ONLY:Vetype> - [ ?&w , Upl , w ; yes ] movprfx\t%0, %2\;fcvtz<su>\t%0.<VNx4SI_ONLY:Vetype>, %1/m, %2.<VNx2DF_ONLY:Vetype> + [ w , Upl , 0 ; * ] fcvtz<su>\t%0.<SVE_SI:Vetype>, %1/m, %2.<VNx2DF_ONLY:Vetype> + [ ?&w , Upl , w ; yes ] movprfx\t%0, %2\;fcvtz<su>\t%0.<SVE_SI:Vetype>, %1/m, %2.<VNx2DF_ONLY:Vetype> } ) @@ -9673,18 +9750,19 @@ ;; - UCVTF ;; ------------------------------------------------------------------------- -;; Unpredicated conversion of integers to floats of the same size -;; (HI to HF, SI to SF or DI to DF). -(define_expand "<optab><v_int_equiv><mode>2" - [(set (match_operand:SVE_FULL_F 0 "register_operand") - (unspec:SVE_FULL_F +;; Unpredicated conversion of integers to floats of the same size or +;; narrower. +(define_expand "<optab><SVE_HSDI:mode><SVE_F:mode>2" + [(set (match_operand:SVE_F 0 "register_operand") + (unspec:SVE_F [(match_dup 2) - (const_int SVE_RELAXED_GP) - (match_operand:<V_INT_EQUIV> 1 "register_operand")] + (match_dup 3) + (match_operand:SVE_HSDI 1 "register_operand")] SVE_COND_ICVTF))] - "TARGET_SVE" + "TARGET_SVE + && (~(<SVE_HSDI:self_mask> | <SVE_HSDI:narrower_mask>) & <SVE_F:self_mask>) == 0" { - operands[2] = aarch64_ptrue_reg (<VPRED>mode); + operands[2] = aarch64_sve_fp_pred (<SVE_HSDI:MODE>mode, &operands[3]); } ) @@ -9704,6 +9782,22 @@ } ) +;; As above, for pairs that are used by the auto-vectorizer only. +(define_insn "*aarch64_sve_<optab>_nonextend<SVE_HSDI:mode><SVE_PARTIAL_F:mode>" + [(set (match_operand:SVE_PARTIAL_F 0 "register_operand") + (unspec:SVE_PARTIAL_F + [(match_operand:<SVE_HSDI:VPRED> 1 "aarch64_predicate_operand") + (match_operand:SI 3 "aarch64_sve_gp_strictness") + (match_operand:SVE_HSDI 2 "register_operand")] + SVE_COND_ICVTF))] + "TARGET_SVE + && (~(<SVE_HSDI:self_mask> | <SVE_HSDI:narrower_mask>) & <SVE_PARTIAL_F:self_mask>) == 0" + {@ [ cons: =0 , 1 , 2 ; attrs: movprfx ] + [ w , Upl , 0 ; * ] <su>cvtf\t%0.<SVE_PARTIAL_F:Vetype>, %1/m, %2.<SVE_HSDI:Vetype> + [ ?&w , Upl , w ; yes ] movprfx\t%0, %2\;<su>cvtf\t%0.<SVE_PARTIAL_F:Vetype>, %1/m, %2.<SVE_HSDI:Vetype> + } +) + ;; Predicated widening integer-to-float conversion. (define_insn "@aarch64_sve_<optab>_extend<VNx4SI_ONLY:mode><VNx2DF_ONLY:mode>" [(set (match_operand:VNx2DF_ONLY 0 "register_operand") @@ -9887,6 +9981,27 @@ } ) +;; ------------------------------------------------------------------------- +;; ---- [FP<-FP] Truncating conversions +;; ------------------------------------------------------------------------- +;; Includes: +;; - FCVT +;; ------------------------------------------------------------------------- + +;; Unpredicated float-to-float truncation. +(define_expand "trunc<SVE_SDF:mode><SVE_PARTIAL_HSF:mode>2" + [(set (match_operand:SVE_PARTIAL_HSF 0 "register_operand") + (unspec:SVE_PARTIAL_HSF + [(match_dup 2) + (match_dup 3) + (match_operand:SVE_SDF 1 "register_operand")] + SVE_COND_FCVT))] + "TARGET_SVE && (~<SVE_SDF:narrower_mask> & <SVE_PARTIAL_HSF:self_mask>) == 0" + { + operands[2] = aarch64_sve_fp_pred (<SVE_SDF:MODE>mode, &operands[3]); + } +) + ;; Predicated float-to-float truncation. (define_insn "@aarch64_sve_<optab>_trunc<SVE_FULL_SDF:mode><SVE_FULL_HSF:mode>" [(set (match_operand:SVE_FULL_HSF 0 "register_operand") @@ -9902,6 +10017,21 @@ } ) +;; As above, for pairs that are used by the auto-vectorizer only. +(define_insn "*aarch64_sve_<optab>_trunc<SVE_SDF:mode><SVE_PARTIAL_HSF:mode>" + [(set (match_operand:SVE_PARTIAL_HSF 0 "register_operand") + (unspec:SVE_PARTIAL_HSF + [(match_operand:<SVE_SDF:VPRED> 1 "aarch64_predicate_operand") + (match_operand:SI 3 "aarch64_sve_gp_strictness") + (match_operand:SVE_SDF 2 "register_operand")] + SVE_COND_FCVT))] + "TARGET_SVE && (~<SVE_SDF:narrower_mask> & <SVE_PARTIAL_HSF:self_mask>) == 0" + {@ [ cons: =0 , 1 , 2 ; attrs: movprfx ] + [ w , Upl , 0 ; * ] fcvt\t%0.<SVE_PARTIAL_HSF:Vetype>, %1/m, %2.<SVE_SDF:Vetype> + [ ?&w , Upl , w ; yes ] movprfx\t%0, %2\;fcvt\t%0.<SVE_PARTIAL_HSF:Vetype>, %1/m, %2.<SVE_SDF:Vetype> + } +) + ;; Predicated float-to-float truncation with merging. (define_expand "@cond_<optab>_trunc<SVE_FULL_SDF:mode><SVE_FULL_HSF:mode>" [(set (match_operand:SVE_FULL_HSF 0 "register_operand") @@ -10044,6 +10174,27 @@ } ) +;; ------------------------------------------------------------------------- +;; ---- [FP<-FP] Extending conversions +;; ------------------------------------------------------------------------- +;; Includes: +;; - FCVT +;; ------------------------------------------------------------------------- + +;; Unpredicated float-to-float extension. +(define_expand "extend<SVE_PARTIAL_HSF:mode><SVE_SDF:mode>2" + [(set (match_operand:SVE_SDF 0 "register_operand") + (unspec:SVE_SDF + [(match_dup 2) + (match_dup 3) + (match_operand:SVE_PARTIAL_HSF 1 "register_operand")] + SVE_COND_FCVT))] + "TARGET_SVE && (~<SVE_SDF:narrower_mask> & <SVE_PARTIAL_HSF:self_mask>) == 0" + { + operands[2] = aarch64_sve_fp_pred (<SVE_SDF:MODE>mode, &operands[3]); + } +) + ;; Predicated float-to-float extension. (define_insn "@aarch64_sve_<optab>_nontrunc<SVE_FULL_HSF:mode><SVE_FULL_SDF:mode>" [(set (match_operand:SVE_FULL_SDF 0 "register_operand") @@ -10059,6 +10210,21 @@ } ) +;; As above, for pairs that are used by the auto-vectorizer only. +(define_insn "*aarch64_sve_<optab>_nontrunc<SVE_PARTIAL_HSF:mode><SVE_SDF:mode>" + [(set (match_operand:SVE_SDF 0 "register_operand") + (unspec:SVE_SDF + [(match_operand:<SVE_SDF:VPRED> 1 "aarch64_predicate_operand") + (match_operand:SI 3 "aarch64_sve_gp_strictness") + (match_operand:SVE_PARTIAL_HSF 2 "register_operand")] + SVE_COND_FCVT))] + "TARGET_SVE && (~<SVE_SDF:narrower_mask> & <SVE_PARTIAL_HSF:self_mask>) == 0" + {@ [ cons: =0 , 1 , 2 ; attrs: movprfx ] + [ w , Upl , 0 ; * ] fcvt\t%0.<SVE_SDF:Vetype>, %1/m, %2.<SVE_PARTIAL_HSF:Vetype> + [ ?&w , Upl , w ; yes ] movprfx\t%0, %2\;fcvt\t%0.<SVE_SDF:Vetype>, %1/m, %2.<SVE_PARTIAL_HSF:Vetype> + } +) + ;; Predicated float-to-float extension with merging. (define_expand "@cond_<optab>_nontrunc<SVE_FULL_HSF:mode><SVE_FULL_SDF:mode>" [(set (match_operand:SVE_FULL_SDF 0 "register_operand") @@ -11271,16 +11437,12 @@ (define_insn "@aarch64_sve_set_neonq_<mode>" [(set (match_operand:SVE_FULL 0 "register_operand" "=w") - (unspec:SVE_FULL - [(match_operand:SVE_FULL 1 "register_operand" "w") - (match_operand:<V128> 2 "register_operand" "w") - (match_operand:<VPRED> 3 "register_operand" "Upl")] - UNSPEC_SET_NEONQ))] + (unspec:SVE_FULL + [(match_operand:SVE_FULL 1 "register_operand" "w") + (match_operand:<V128> 2 "register_operand" "w") + (match_operand:<VPRED> 3 "register_operand" "Upl")] + UNSPEC_SET_NEONQ))] "TARGET_SVE && BYTES_BIG_ENDIAN" - { - operands[2] = lowpart_subreg (<MODE>mode, operands[2], - GET_MODE (operands[2])); - return "sel\t%0.<Vetype>, %3, %2.<Vetype>, %1.<Vetype>"; - } + "sel\t%0.<Vetype>, %3, %Z2.<Vetype>, %1.<Vetype>" ) diff --git a/gcc/config/aarch64/aarch64-sve2.md b/gcc/config/aarch64/aarch64-sve2.md index 62524f36de65..8c03e28cb084 100644 --- a/gcc/config/aarch64/aarch64-sve2.md +++ b/gcc/config/aarch64/aarch64-sve2.md @@ -334,12 +334,21 @@ ;; - LD1Q (SVE2p1) ;; ------------------------------------------------------------------------- -;; Model this as operating on the largest valid element size, which is DI. -;; This avoids having to define move patterns & more for VNx1TI, which would -;; be difficult without a non-gather form of LD1Q. -(define_insn "aarch64_gather_ld1q" - [(set (match_operand:VNx2DI 0 "register_operand") - (unspec:VNx2DI +;; For little-endian targets, it would be enough to use a single pattern, +;; with a subreg to bitcast the result to whatever mode is needed. +;; However, on big-endian targets, the bitcast would need to be an +;; aarch64_sve_reinterpret instruction. That would interact badly +;; with the "&" and "?" constraints in this pattern: if the result +;; of the reinterpret needs to be in the same register as the index, +;; the RA would tend to prefer to allocate a separate register for the +;; intermediate (uncast) result, even if the reinterpret prefers tying. +;; +;; The index is logically VNx1DI rather than VNx2DI, but introducing +;; and using VNx1DI would just create more bitcasting. The ACLE intrinsic +;; uses svuint64_t, which corresponds to VNx2DI. +(define_insn "@aarch64_gather_ld1q<mode>" + [(set (match_operand:SVE_FULL 0 "register_operand") + (unspec:SVE_FULL [(match_operand:VNx2BI 1 "register_operand") (match_operand:DI 2 "aarch64_reg_or_zero") (match_operand:VNx2DI 3 "register_operand") @@ -1628,7 +1637,7 @@ "TARGET_SVE2" {@ [ cons: =0 , %1 , 2 ; attrs: movprfx ] [ w , 0 , w ; * ] nbsl\t%0.d, %0.d, %2.d, %0.d - [ ?&w , w , w ; yes ] movprfx\t%0, %1\;nbsl\t%0.d, %0.d, %2.d, %0.d + [ ?&w , w , w ; yes ] movprfx\t%0, %1\;nbsl\t%0.d, %0.d, %2.d, %1.d } "&& !CONSTANT_P (operands[3])" { @@ -1636,6 +1645,20 @@ } ) +(define_insn "*aarch64_sve2_unpred_nor<mode>" + [(set (match_operand:VDQ_I 0 "register_operand") + (and:VDQ_I + (not:VDQ_I + (match_operand:VDQ_I 1 "register_operand")) + (not:VDQ_I + (match_operand:VDQ_I 2 "register_operand"))))] + "TARGET_SVE2" + {@ [ cons: =0 , %1 , 2 ; attrs: movprfx ] + [ w , 0 , w ; * ] nbsl\t%Z0.d, %Z0.d, %Z2.d, %Z0.d + [ ?&w , w , w ; yes ] movprfx\t%Z0, %Z1\;nbsl\t%Z0.d, %Z0.d, %Z2.d, %Z1.d + } +) + ;; Use NBSL for vector NAND. (define_insn_and_rewrite "*aarch64_sve2_nand<mode>" [(set (match_operand:SVE_FULL_I 0 "register_operand") @@ -1658,6 +1681,21 @@ } ) +;; Same as above but unpredicated and including Advanced SIMD modes. +(define_insn "*aarch64_sve2_nand_unpred<mode>" + [(set (match_operand:VDQ_I 0 "register_operand") + (ior:VDQ_I + (not:VDQ_I + (match_operand:VDQ_I 1 "register_operand")) + (not:VDQ_I + (match_operand:VDQ_I 2 "register_operand"))))] + "TARGET_SVE2" + {@ [ cons: =0 , %1 , 2 ; attrs: movprfx ] + [ w , 0 , w ; * ] nbsl\t%Z0.d, %Z0.d, %Z2.d, %Z2.d + [ ?&w , w , w ; yes ] movprfx\t%Z0, %Z1\;nbsl\t%Z0.d, %Z0.d, %Z2.d, %Z2.d + } +) + ;; Unpredicated bitwise select. ;; (op3 ? bsl_mov : bsl_dup) == (((bsl_mov ^ bsl_dup) & op3) ^ bsl_dup) (define_expand "@aarch64_sve2_bsl<mode>" @@ -1918,6 +1956,40 @@ } ) +;; Vector EON (~(x, y)) using BSL2N. +(define_insn_and_rewrite "*aarch64_sve2_bsl2n_eon<mode>" + [(set (match_operand:SVE_FULL_I 0 "register_operand") + (unspec:SVE_FULL_I + [(match_operand 3) + (not:SVE_FULL_I + (xor:SVE_FULL_I + (match_operand:SVE_FULL_I 1 "register_operand") + (match_operand:SVE_FULL_I 2 "register_operand")))] + UNSPEC_PRED_X))] + "TARGET_SVE2" + {@ [ cons: =0, 1, 2 ; attrs: movprfx ] + [ w , 0, w ; * ] bsl2n\t%0.d, %0.d, %0.d, %2.d + [ ?&w, w, w ; yes ] movprfx\t%0, %1\;bsl2n\t%0.d, %0.d, %1.d, %2.d + } + "&& !CONSTANT_P (operands[3])" + { + operands[3] = CONSTM1_RTX (<VPRED>mode); + } +) + +(define_insn "*aarch64_sve2_eon_bsl2n_unpred<mode>" + [(set (match_operand:VDQ_I 0 "register_operand") + (not:VDQ_I + (xor:VDQ_I + (match_operand:VDQ_I 1 "register_operand") + (match_operand:VDQ_I 2 "register_operand"))))] + "TARGET_SVE2" + {@ [ cons: =0, 1, 2 ; attrs: movprfx ] + [ w , 0, w ; * ] bsl2n\t%Z0.d, %Z0.d, %Z0.d, %Z2.d + [ ?&w, w, w ; yes ] movprfx\t%Z0, %Z1\;bsl2n\t%Z0.d, %Z0.d, %Z1.d, %Z2.d + } +) + ;; ------------------------------------------------------------------------- ;; ---- [INT] Shift-and-accumulate operations ;; ------------------------------------------------------------------------- diff --git a/gcc/config/aarch64/aarch64-sys-regs.def b/gcc/config/aarch64/aarch64-sys-regs.def index 39e6c5c646fb..d7ef6da4ee8a 100644 --- a/gcc/config/aarch64/aarch64-sys-regs.def +++ b/gcc/config/aarch64/aarch64-sys-regs.def @@ -572,12 +572,12 @@ SYSREG ("mdrar_el1", CPENC (2,0,1,0,0), F_REG_READ, AARCH64_NO_FEATURES) SYSREG ("mdscr_el1", CPENC (2,0,0,2,2), 0, AARCH64_NO_FEATURES) SYSREG ("mdselr_el1", CPENC (2,0,0,4,2), F_ARCHEXT, AARCH64_FEATURE (DEBUGv8p9)) - SYSREG ("mecid_a0_el2", CPENC (3,4,10,8,1), 0, AARCH64_NO_FEATURES) - SYSREG ("mecid_a1_el2", CPENC (3,4,10,8,3), 0, AARCH64_NO_FEATURES) - SYSREG ("mecid_p0_el2", CPENC (3,4,10,8,0), 0, AARCH64_NO_FEATURES) - SYSREG ("mecid_p1_el2", CPENC (3,4,10,8,2), 0, AARCH64_NO_FEATURES) - SYSREG ("mecid_rl_a_el3", CPENC (3,6,10,10,1), 0, AARCH64_NO_FEATURES) - SYSREG ("mecidr_el2", CPENC (3,4,10,8,7), F_REG_READ, AARCH64_NO_FEATURES) + SYSREG ("mecid_a0_el2", CPENC (3,4,10,8,1), F_ARCHEXT, AARCH64_FEATURE (V8_7A)) + SYSREG ("mecid_a1_el2", CPENC (3,4,10,8,3), F_ARCHEXT, AARCH64_FEATURE (V8_7A)) + SYSREG ("mecid_p0_el2", CPENC (3,4,10,8,0), F_ARCHEXT, AARCH64_FEATURE (V8_7A)) + SYSREG ("mecid_p1_el2", CPENC (3,4,10,8,2), F_ARCHEXT, AARCH64_FEATURE (V8_7A)) + SYSREG ("mecid_rl_a_el3", CPENC (3,6,10,10,1), F_ARCHEXT, AARCH64_FEATURE (V8_7A)) + SYSREG ("mecidr_el2", CPENC (3,4,10,8,7), F_REG_READ|F_ARCHEXT, AARCH64_FEATURE (V8_7A)) SYSREG ("mfar_el3", CPENC (3,6,6,0,5), 0, AARCH64_NO_FEATURES) SYSREG ("midr_el1", CPENC (3,0,0,0,0), F_REG_READ, AARCH64_NO_FEATURES) SYSREG ("mpam0_el1", CPENC (3,0,10,5,1), 0, AARCH64_NO_FEATURES) @@ -1145,8 +1145,8 @@ SYSREG ("vbar_el2", CPENC (3,4,12,0,0), 0, AARCH64_NO_FEATURES) SYSREG ("vbar_el3", CPENC (3,6,12,0,0), 0, AARCH64_NO_FEATURES) SYSREG ("vdisr_el2", CPENC (3,4,12,1,1), F_ARCHEXT, AARCH64_FEATURE (RAS)) - SYSREG ("vmecid_a_el2", CPENC (3,4,10,9,1), 0, AARCH64_NO_FEATURES) - SYSREG ("vmecid_p_el2", CPENC (3,4,10,9,0), 0, AARCH64_NO_FEATURES) + SYSREG ("vmecid_a_el2", CPENC (3,4,10,9,1), F_ARCHEXT, AARCH64_FEATURE (V8_7A)) + SYSREG ("vmecid_p_el2", CPENC (3,4,10,9,0), F_ARCHEXT, AARCH64_FEATURE (V8_7A)) SYSREG ("vmpidr_el2", CPENC (3,4,0,0,5), 0, AARCH64_NO_FEATURES) SYSREG ("vncr_el2", CPENC (3,4,2,2,0), F_ARCHEXT, AARCH64_FEATURE (V8_4A)) SYSREG ("vpidr_el2", CPENC (3,4,0,0,0), 0, AARCH64_NO_FEATURES) diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md index 982074c2c21e..40ff147d6f83 100644 --- a/gcc/config/aarch64/aarch64-tune.md +++ b/gcc/config/aarch64/aarch64-tune.md @@ -1,5 +1,5 @@ ;; -*- buffer-read-only: t -*- ;; Generated automatically by gentune.sh from aarch64-cores.def (define_attr "tune" - "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88,thunderxt88p1,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,fujitsu_monaka,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,oryon1,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexr82ae,applea12,applem1_0,applem1_1,applem1_2,applem1_3,applem2_0,applem2_1,applem2_2,applem2_3,applem3_0,cortexa510,cortexa520,cortexa520ae,cortexa710,cortexa715,cortexa720,cortexa720ae,cortexa725,cortexx2,cortexx3,cortexx4,cortexx925,neoversen2,cobalt100,neoversen3,neoversev2,grace,neoversev3,neoversev3ae,demeter,olympus,generic,generic_armv8_a,generic_armv9_a" + "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88,thunderxt88p1,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,fujitsu_monaka,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,oryon1,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexr82ae,applea12,applem1_0,applem1_1,applem1_2,applem1_3,applem2_0,applem2_1,applem2_2,applem2_3,applem3_0,cortexa510,cortexa520,cortexa520ae,cortexa710,cortexa715,cortexa720,cortexa720ae,cortexa725,cortexx2,cortexx3,cortexx4,cortexx925,neoversen2,cobalt100,neoversen3,neoversev2,grace,neoversev3,neoversev3ae,demeter,olympus,gb10,generic,generic_armv8_a,generic_armv9_a" (const (symbol_ref "((enum attr_tune) aarch64_tune)"))) diff --git a/gcc/config/aarch64/aarch64-tuning-flags.def b/gcc/config/aarch64/aarch64-tuning-flags.def index f2c916e9d770..dd91324e9c80 100644 --- a/gcc/config/aarch64/aarch64-tuning-flags.def +++ b/gcc/config/aarch64/aarch64-tuning-flags.def @@ -44,6 +44,8 @@ AARCH64_EXTRA_TUNING_OPTION ("avoid_cross_loop_fma", AVOID_CROSS_LOOP_FMA) AARCH64_EXTRA_TUNING_OPTION ("fully_pipelined_fma", FULLY_PIPELINED_FMA) +AARCH64_EXTRA_TUNING_OPTION ("avoid_ldapur", AVOID_LDAPUR) + /* Enable is the target prefers to use a fresh register for predicate outputs rather than re-use an input predicate register. */ AARCH64_EXTRA_TUNING_OPTION ("avoid_pred_rmw", AVOID_PRED_RMW) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 59ac08483f4d..72a691b8e2f2 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -83,6 +83,7 @@ #include "rtlanal.h" #include "tree-dfa.h" #include "asan.h" +#include "aarch64-elf-metadata.h" #include "aarch64-feature-deps.h" #include "config/arm/aarch-common.h" #include "config/arm/aarch-common-protos.h" @@ -108,6 +109,10 @@ and 1 MOVI/DUP (same size as a call). */ #define MAX_SET_SIZE(speed) (speed ? 256 : 96) +#ifndef HAVE_AS_AEABI_BUILD_ATTRIBUTES +#define HAVE_AS_AEABI_BUILD_ATTRIBUTES 0 +#endif + /* Flags that describe how a function shares certain architectural state with its callers. @@ -954,6 +959,39 @@ svpattern_token (enum aarch64_svpattern pattern) gcc_unreachable (); } +/* Return true if RHS is an operand suitable for a CB<cc> (immediate) + instruction. OP_CODE determines the type of the comparison. */ +bool +aarch64_cb_rhs (rtx_code op_code, rtx rhs) +{ + if (!CONST_INT_P (rhs)) + return REG_P (rhs); + + HOST_WIDE_INT rhs_val = INTVAL (rhs); + + switch (op_code) + { + case EQ: + case NE: + case GT: + case GTU: + case LT: + case LTU: + return IN_RANGE (rhs_val, 0, 63); + + case GE: /* CBGE: signed greater than or equal */ + case GEU: /* CBHS: unsigned greater than or equal */ + return IN_RANGE (rhs_val, 1, 64); + + case LE: /* CBLE: signed less than or equal */ + case LEU: /* CBLS: unsigned less than or equal */ + return IN_RANGE (rhs_val, -1, 62); + + default: + return false; + } +} + /* Return the location of a piece that is known to be passed or returned in registers. FIRST_ZR is the first unused vector argument register and FIRST_PR is the first unused predicate argument register. */ @@ -2879,10 +2917,10 @@ aarch64_gen_test_and_branch (rtx_code code, rtx x, int bitnum, emit_insn (gen_aarch64_and3nr_compare0 (mode, x, mask)); rtx cc_reg = gen_rtx_REG (CC_NZVmode, CC_REGNUM); rtx x = gen_rtx_fmt_ee (code, CC_NZVmode, cc_reg, const0_rtx); - return gen_condjump (x, cc_reg, label); + return gen_aarch64_bcond (x, cc_reg, label); } - return gen_aarch64_tb (code, mode, mode, - x, gen_int_mode (bitnum, mode), label); + return gen_aarch64_tbz (code, mode, mode, + x, gen_int_mode (bitnum, mode), label); } /* Consider the operation: @@ -3855,6 +3893,44 @@ aarch64_sve_same_pred_for_ptest_p (rtx *pred1, rtx *pred2) return (ptrue1_p && ptrue2_p) || rtx_equal_p (pred1[0], pred2[0]); } + +/* Generate a predicate to control partial SVE mode DATA_MODE as if it + were fully packed, enabling the defined elements only. */ +rtx +aarch64_sve_packed_pred (machine_mode data_mode) +{ + unsigned int container_bytes + = aarch64_sve_container_bits (data_mode) / BITS_PER_UNIT; + /* Enable the significand of each container only. */ + rtx ptrue = force_reg (VNx16BImode, aarch64_ptrue_all (container_bytes)); + /* Predicate at the element size. */ + machine_mode pmode + = aarch64_sve_pred_mode (GET_MODE_UNIT_SIZE (data_mode)).require (); + return gen_lowpart (pmode, ptrue); +} + +/* Generate a predicate and strictness value to govern a floating-point + operation with SVE mode DATA_MODE. + + If DATA_MODE is a partial vector mode, this pair prevents the operation + from interpreting undefined elements - unless we don't need to suppress + their trapping behavior. */ +rtx +aarch64_sve_fp_pred (machine_mode data_mode, rtx *strictness) +{ + unsigned int vec_flags = aarch64_classify_vector_mode (data_mode); + if (flag_trapping_math && (vec_flags & VEC_PARTIAL)) + { + if (strictness) + *strictness = gen_int_mode (SVE_STRICT_GP, SImode); + return aarch64_sve_packed_pred (data_mode); + } + if (strictness) + *strictness = gen_int_mode (SVE_RELAXED_GP, SImode); + /* Use the VPRED mode. */ + return aarch64_ptrue_reg (aarch64_sve_pred_mode (data_mode)); +} + /* Emit a comparison CMP between OP0 and OP1, both of which have mode DATA_MODE, and return the result in a predicate of mode PRED_MODE. Use TARGET as the target register if nonnull and convenient. */ @@ -8756,6 +8832,13 @@ aarch_bti_j_insn_p (rtx_insn *insn) return GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == UNSPECV_BTI_J; } +/* Return TRUE if Pointer Authentication for the return address is enabled. */ +bool +aarch64_pacret_enabled (void) +{ + return (aarch_ra_sign_scope != AARCH_FUNCTION_NONE); +} + /* Return TRUE if Guarded Control Stack is enabled. */ bool aarch64_gcs_enabled (void) @@ -15771,11 +15854,14 @@ aarch64_rtx_costs (rtx x, machine_mode mode, int outer ATTRIBUTE_UNUSED, break; case CONST_VECTOR: { - /* Load using MOVI/MVNI. */ - if (aarch64_simd_valid_mov_imm (x)) - *cost = extra_cost->vect.movi; - else /* Load using constant pool. */ - *cost = extra_cost->ldst.load; + if (speed) + { + /* Load using MOVI/MVNI. */ + if (aarch64_simd_valid_mov_imm (x)) + *cost += extra_cost->vect.movi; + else /* Load using constant pool. */ + *cost += extra_cost->ldst.load; + } break; } case VEC_CONCAT: @@ -15784,7 +15870,8 @@ aarch64_rtx_costs (rtx x, machine_mode mode, int outer ATTRIBUTE_UNUSED, break; case VEC_DUPLICATE: /* Load using a DUP. */ - *cost = extra_cost->vect.dup; + if (speed) + *cost += extra_cost->vect.dup; return false; case VEC_SELECT: { @@ -15792,13 +15879,16 @@ aarch64_rtx_costs (rtx x, machine_mode mode, int outer ATTRIBUTE_UNUSED, *cost = rtx_cost (op0, GET_MODE (op0), VEC_SELECT, 0, speed); /* cost subreg of 0 as free, otherwise as DUP */ - rtx op1 = XEXP (x, 1); - if (vec_series_lowpart_p (mode, GET_MODE (op1), op1)) - ; - else if (vec_series_highpart_p (mode, GET_MODE (op1), op1)) - *cost = extra_cost->vect.dup; - else - *cost = extra_cost->vect.extract; + if (speed) + { + rtx op1 = XEXP (x, 1); + if (vec_series_lowpart_p (mode, GET_MODE (op1), op1)) + ; + else if (vec_series_highpart_p (mode, GET_MODE (op1), op1)) + *cost += extra_cost->vect.dup; + else + *cost += extra_cost->vect.extract; + } return true; } default: @@ -17849,7 +17939,7 @@ aarch64_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind, /* Do one-time initialization based on the vinfo. */ loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo); - if (!m_analyzed_vinfo) + if (!m_analyzed_vinfo && !m_costing_for_scalar) { if (loop_vinfo) analyze_loop_vinfo (loop_vinfo); @@ -18710,6 +18800,8 @@ aarch64_adjust_generic_arch_tuning (struct tune_params ¤t_tune) if (TARGET_SVE2) current_tune.extra_tuning_flags &= ~AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS; + if (!AARCH64_HAVE_ISA(V8_8A)) + aarch64_tune_params.extra_tuning_flags |= AARCH64_EXTRA_TUNE_AVOID_LDAPUR; } static void @@ -18774,7 +18866,10 @@ aarch64_override_options_internal (struct gcc_options *opts) /* Make a copy of the tuning parameters attached to the core, which we may later overwrite. */ aarch64_tune_params = *(tune->tune); - if (tune->tune == &generic_tunings) + + if (tune->tune == &generic_tunings + || tune->tune == &generic_armv8_a_tunings + || tune->tune == &generic_armv9_a_tunings) aarch64_adjust_generic_arch_tuning (aarch64_tune_params); if (opts->x_aarch64_override_tune_string) @@ -18986,6 +19081,20 @@ aarch64_override_options_internal (struct gcc_options *opts) if (TARGET_SME && !TARGET_SVE2) sorry ("no support for %qs without %qs", "sme", "sve2"); + /* Set scalar costing to a high value such that we always pick + vectorization. Increase scalar costing by 10000%. */ + if (opts->x_flag_aarch64_max_vectorization) + SET_OPTION_IF_UNSET (opts, &global_options_set, + param_vect_scalar_cost_multiplier, 10000); + + /* Synchronize the -mautovec-preference and aarch64_autovec_preference using + whichever one is not default. If both are set then prefer the param flag + over the parameters. */ + if (opts->x_autovec_preference != AARCH64_AUTOVEC_DEFAULT) + SET_OPTION_IF_UNSET (opts, &global_options_set, + aarch64_autovec_preference, + opts->x_autovec_preference); + aarch64_override_options_after_change_1 (opts); } @@ -19736,6 +19845,8 @@ static const struct aarch64_attribute_info aarch64_attributes[] = OPT_msign_return_address_ }, { "outline-atomics", aarch64_attr_bool, true, NULL, OPT_moutline_atomics}, + { "max-vectorization", aarch64_attr_bool, false, NULL, + OPT_mmax_vectorization}, { NULL, aarch64_attr_custom, false, NULL, OPT____ } }; @@ -20862,7 +20973,6 @@ aarch64_get_function_versions_dispatcher (void *decl) struct cgraph_node *node = NULL; struct cgraph_node *default_node = NULL; struct cgraph_function_version_info *node_v = NULL; - struct cgraph_function_version_info *first_v = NULL; tree dispatch_decl = NULL; @@ -20879,37 +20989,16 @@ aarch64_get_function_versions_dispatcher (void *decl) if (node_v->dispatcher_resolver != NULL) return node_v->dispatcher_resolver; - /* Find the default version and make it the first node. */ - first_v = node_v; - /* Go to the beginning of the chain. */ - while (first_v->prev != NULL) - first_v = first_v->prev; - default_version_info = first_v; - while (default_version_info != NULL) - { - if (get_feature_mask_for_version - (default_version_info->this_node->decl) == 0ULL) - break; - default_version_info = default_version_info->next; - } + /* The default node is always the beginning of the chain. */ + default_version_info = node_v; + while (default_version_info->prev) + default_version_info = default_version_info->prev; + default_node = default_version_info->this_node; /* If there is no default node, just return NULL. */ - if (default_version_info == NULL) + if (!is_function_default_version (default_node->decl)) return NULL; - /* Make default info the first node. */ - if (first_v != default_version_info) - { - default_version_info->prev->next = default_version_info->next; - if (default_version_info->next) - default_version_info->next->prev = default_version_info->prev; - first_v->prev = default_version_info; - default_version_info->next = first_v; - default_version_info->prev = NULL; - } - - default_node = default_version_info->this_node; - if (targetm.has_ifunc_p ()) { struct cgraph_function_version_info *it_v = NULL; @@ -22997,6 +23086,58 @@ aarch64_sve_index_immediate_p (rtx base_or_step) && IN_RANGE (INTVAL (base_or_step), -16, 15)); } +/* Return true if SERIES is a constant vector that can be loaded using + an immediate SVE INDEX, considering both SVE and Advanced SIMD modes. + When returning true, store the base in *BASE_OUT and the step + in *STEP_OUT. */ + +static bool +aarch64_sve_index_series_p (rtx series, rtx *base_out, rtx *step_out) +{ + rtx base, step; + if (!const_vec_series_p (series, &base, &step) + || !CONST_INT_P (base) + || !CONST_INT_P (step)) + return false; + + auto mode = GET_MODE (series); + auto elt_mode = as_a<scalar_int_mode> (GET_MODE_INNER (mode)); + unsigned int vec_flags = aarch64_classify_vector_mode (mode); + if (BYTES_BIG_ENDIAN && (vec_flags & VEC_ADVSIMD)) + { + /* On big-endian targets, architectural lane 0 holds the last element + for Advanced SIMD and the first element for SVE; see the comment at + the head of aarch64-sve.md for details. This means that, from an SVE + point of view, an Advanced SIMD series goes from the last element to + the first. */ + auto i = GET_MODE_NUNITS (mode).to_constant () - 1; + base = gen_int_mode (UINTVAL (base) + i * UINTVAL (step), elt_mode); + step = gen_int_mode (-UINTVAL (step), elt_mode); + } + + if (!aarch64_sve_index_immediate_p (base) + || !aarch64_sve_index_immediate_p (step)) + return false; + + /* If the mode spans multiple registers, check that each subseries is + in range. */ + unsigned int nvectors = aarch64_ldn_stn_vectors (mode); + if (nvectors != 1) + { + unsigned int nunits; + if (!GET_MODE_NUNITS (mode).is_constant (&nunits)) + return false; + nunits /= nvectors; + for (unsigned int i = 1; i < nvectors; ++i) + if (!IN_RANGE (INTVAL (base) + i * nunits * INTVAL (step), -16, 15)) + return false; + } + + *base_out = base; + *step_out = step; + return true; +} + /* Return true if X is a valid immediate for the SVE ADD and SUB instructions when applied to mode MODE. Negate X first if NEGATE_P is true. */ @@ -23445,13 +23586,8 @@ aarch64_simd_valid_imm (rtx op, simd_immediate_info *info, n_elts = CONST_VECTOR_NPATTERNS (op); else if (which == AARCH64_CHECK_MOV && TARGET_SVE - && const_vec_series_p (op, &base, &step)) + && aarch64_sve_index_series_p (op, &base, &step)) { - gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT); - if (!aarch64_sve_index_immediate_p (base) - || !aarch64_sve_index_immediate_p (step)) - return false; - if (info) { /* Get the corresponding container mode. E.g. an INDEX on V2SI @@ -23563,6 +23699,8 @@ aarch64_simd_valid_imm (rtx op, simd_immediate_info *info, long int as_long_ints[2]; as_long_ints[0] = ival & 0xFFFFFFFF; as_long_ints[1] = (ival >> 32) & 0xFFFFFFFF; + if (imode == DImode && FLOAT_WORDS_BIG_ENDIAN) + std::swap (as_long_ints[0], as_long_ints[1]); REAL_VALUE_TYPE r; real_from_target (&r, as_long_ints, fmode); @@ -23707,6 +23845,19 @@ aarch64_simd_shift_imm_p (rtx x, machine_mode mode, bool left) return IN_RANGE (INTVAL (x), 1, bit_width); } + +/* Check whether X can control SVE mode MODE. */ +bool +aarch64_sve_valid_pred_p (rtx x, machine_mode mode) +{ + machine_mode pred_mode = GET_MODE (x); + if (!aarch64_sve_pred_mode_p (pred_mode)) + return false; + + return known_ge (GET_MODE_NUNITS (pred_mode), + GET_MODE_NUNITS (mode)); +} + /* Return the bitmask CONST_INT to select the bits required by a zero extract operation of width WIDTH at bit position POS. */ @@ -24680,6 +24831,28 @@ seq_cost_ignoring_scalar_moves (const rtx_insn *seq, bool speed) return cost; } +/* *VECTOR is an Advanced SIMD structure mode and *INDEX is a constant index + into it. Narrow *VECTOR and *INDEX so that they reference a single vector + of mode SUBVEC_MODE. IS_DEST is true if *VECTOR is a destination operand, + false if it is a source operand. */ + +void +aarch64_decompose_vec_struct_index (machine_mode subvec_mode, + rtx *vector, rtx *index, bool is_dest) +{ + auto elts_per_vector = GET_MODE_NUNITS (subvec_mode).to_constant (); + auto subvec = UINTVAL (*index) / elts_per_vector; + auto subelt = UINTVAL (*index) % elts_per_vector; + auto subvec_byte = subvec * GET_MODE_SIZE (subvec_mode); + if (is_dest) + *vector = simplify_gen_subreg (subvec_mode, *vector, GET_MODE (*vector), + subvec_byte); + else + *vector = force_subreg (subvec_mode, *vector, GET_MODE (*vector), + subvec_byte); + *index = gen_int_mode (subelt, SImode); +} + /* Expand a vector initialization sequence, such that TARGET is initialized to contain VALS. */ @@ -24718,6 +24891,13 @@ aarch64_expand_vector_init (rtx target, rtx vals) emit_insn (rec_seq); } + /* The two halves should (by induction) be individually endian-correct. + However, in the memory layout provided by VALS, the nth element of + HALVES[0] comes immediately before the nth element HALVES[1]. + This means that, on big-endian targets, the nth element of HALVES[0] + is more significant than the nth element HALVES[1]. */ + if (BYTES_BIG_ENDIAN) + std::swap (halves[0], halves[1]); rtvec v = gen_rtvec (2, halves[0], halves[1]); rtx_insn *zip1_insn = emit_set_insn (target, gen_rtx_UNSPEC (mode, v, UNSPEC_ZIP1)); @@ -25355,7 +25535,6 @@ aarch64_start_file (void) } /* Emit load exclusive. */ - static void aarch64_emit_load_exclusive (machine_mode mode, rtx rval, rtx mem, rtx model_rtx) @@ -26634,7 +26813,6 @@ aarch64_evpc_hvla (struct expand_vec_perm_d *d) machine_mode vmode = d->vmode; if (!TARGET_SVE2p1 || !TARGET_NON_STREAMING - || BYTES_BIG_ENDIAN || d->vec_flags != VEC_SVE_DATA || GET_MODE_UNIT_BITSIZE (vmode) > 64) return false; @@ -26794,12 +26972,23 @@ aarch64_evpc_tbl (struct expand_vec_perm_d *d) static bool aarch64_evpc_sve_tbl (struct expand_vec_perm_d *d) { - unsigned HOST_WIDE_INT nelt; + if (!d->one_vector_p) + { + /* aarch64_expand_sve_vec_perm does not yet handle variable-length + vectors. */ + if (!d->perm.length ().is_constant ()) + return false; - /* Permuting two variable-length vectors could overflow the - index range. */ - if (!d->one_vector_p && !d->perm.length ().is_constant (&nelt)) - return false; + /* This permutation reduces to the vec_perm optab if the elements are + large enough to hold all selector indices. Do not handle that case + here, since the general TBL+SUB+TBL+ORR sequence is too expensive to + be considered a "native" constant permutation. + + Not doing this would undermine code that queries can_vec_perm_const_p + with allow_variable_p set to false. See PR121027. */ + if (selector_fits_mode_p (d->vmode, d->perm)) + return false; + } if (d->testing_p) return true; @@ -27189,7 +27378,7 @@ aarch64_emit_sve_fp_cond (rtx target, rtx_code code, rtx pred, bool known_ptrue_p, rtx op0, rtx op1) { rtx flag = gen_int_mode (known_ptrue_p, SImode); - rtx unspec = gen_rtx_UNSPEC (GET_MODE (pred), + rtx unspec = gen_rtx_UNSPEC (GET_MODE (target), gen_rtvec (4, pred, flag, op0, op1), aarch64_unspec_cond_code (code)); emit_set_insn (target, unspec); @@ -27208,10 +27397,10 @@ static void aarch64_emit_sve_or_fp_conds (rtx target, rtx_code code1, rtx_code code2, rtx pred, bool known_ptrue_p, rtx op0, rtx op1) { - machine_mode pred_mode = GET_MODE (pred); - rtx tmp1 = gen_reg_rtx (pred_mode); + machine_mode target_mode = GET_MODE (target); + rtx tmp1 = gen_reg_rtx (target_mode); aarch64_emit_sve_fp_cond (tmp1, code1, pred, known_ptrue_p, op0, op1); - rtx tmp2 = gen_reg_rtx (pred_mode); + rtx tmp2 = gen_reg_rtx (target_mode); aarch64_emit_sve_fp_cond (tmp2, code2, pred, known_ptrue_p, op0, op1); aarch64_emit_binop (target, ior_optab, tmp1, tmp2); } @@ -27228,8 +27417,7 @@ static void aarch64_emit_sve_invert_fp_cond (rtx target, rtx_code code, rtx pred, bool known_ptrue_p, rtx op0, rtx op1) { - machine_mode pred_mode = GET_MODE (pred); - rtx tmp = gen_reg_rtx (pred_mode); + rtx tmp = gen_reg_rtx (GET_MODE (target)); aarch64_emit_sve_fp_cond (tmp, code, pred, known_ptrue_p, op0, op1); aarch64_emit_unop (target, one_cmpl_optab, tmp); } @@ -27241,10 +27429,25 @@ aarch64_emit_sve_invert_fp_cond (rtx target, rtx_code code, rtx pred, void aarch64_expand_sve_vec_cmp_float (rtx target, rtx_code code, rtx op0, rtx op1) { - machine_mode pred_mode = GET_MODE (target); machine_mode data_mode = GET_MODE (op0); + rtx pred = aarch64_sve_fp_pred (data_mode, nullptr); - rtx ptrue = aarch64_ptrue_reg (pred_mode); + /* The governing and destination modes. */ + machine_mode pred_mode = GET_MODE (pred); + machine_mode target_mode = GET_MODE (target); + + /* For partial vector modes, the choice of predicate mode depends + on whether we need to suppress exceptions for inactive elements. + If we do need to suppress exceptions, the predicate mode matches + the element size rather than the container size and the predicate + marks the upper bits in each container as inactive. The predicate + is then a ptrue wrt TARGET_MODE but not wrt PRED_MODE. It is the + latter which matters here. + + If we don't need to suppress exceptions, the predicate mode matches + the container size, PRED_MODE == TARGET_MODE, and the predicate is + thus a ptrue wrt both TARGET_MODE and PRED_MODE. */ + bool known_ptrue_p = pred_mode == target_mode; switch (code) { case UNORDERED: @@ -27258,12 +27461,13 @@ aarch64_expand_sve_vec_cmp_float (rtx target, rtx_code code, rtx op0, rtx op1) case EQ: case NE: /* There is native support for the comparison. */ - aarch64_emit_sve_fp_cond (target, code, ptrue, true, op0, op1); + aarch64_emit_sve_fp_cond (target, code, pred, known_ptrue_p, op0, op1); return; case LTGT: /* This is a trapping operation (LT or GT). */ - aarch64_emit_sve_or_fp_conds (target, LT, GT, ptrue, true, op0, op1); + aarch64_emit_sve_or_fp_conds (target, LT, GT, + pred, known_ptrue_p, op0, op1); return; case UNEQ: @@ -27272,7 +27476,7 @@ aarch64_expand_sve_vec_cmp_float (rtx target, rtx_code code, rtx op0, rtx op1) /* This would trap for signaling NaNs. */ op1 = force_reg (data_mode, op1); aarch64_emit_sve_or_fp_conds (target, UNORDERED, EQ, - ptrue, true, op0, op1); + pred, known_ptrue_p, op0, op1); return; } /* fall through */ @@ -27282,11 +27486,19 @@ aarch64_expand_sve_vec_cmp_float (rtx target, rtx_code code, rtx op0, rtx op1) case UNGE: if (flag_trapping_math) { - /* Work out which elements are ordered. */ - rtx ordered = gen_reg_rtx (pred_mode); op1 = force_reg (data_mode, op1); - aarch64_emit_sve_invert_fp_cond (ordered, UNORDERED, - ptrue, true, op0, op1); + + /* Work out which elements are unordered. */ + rtx uo_tmp = gen_reg_rtx (target_mode); + aarch64_emit_sve_fp_cond (uo_tmp, UNORDERED, + pred, known_ptrue_p, op0, op1); + + /* Invert the result. Governered by PRED so that we only + flip the active bits. */ + rtx ordered = gen_reg_rtx (pred_mode); + uo_tmp = gen_lowpart (pred_mode, uo_tmp); + emit_insn (gen_aarch64_pred_one_cmpl_z (pred_mode, ordered, + pred, uo_tmp)); /* Test the opposite condition for the ordered elements, then invert the result. */ @@ -27311,7 +27523,8 @@ aarch64_expand_sve_vec_cmp_float (rtx target, rtx_code code, rtx op0, rtx op1) /* There is native support for the inverse comparison. */ code = reverse_condition_maybe_unordered (code); - aarch64_emit_sve_invert_fp_cond (target, code, ptrue, true, op0, op1); + aarch64_emit_sve_invert_fp_cond (target, code, + pred, known_ptrue_p, op0, op1); } /* Return true if: @@ -29986,60 +30199,43 @@ aarch64_can_tag_addresses () /* Implement TARGET_ASM_FILE_END for AArch64. This adds the AArch64 GNU NOTE section at the end if needed. */ -#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 -#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0) -#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1) -#define GNU_PROPERTY_AARCH64_FEATURE_1_GCS (1U << 2) void aarch64_file_end_indicate_exec_stack () { file_end_indicate_exec_stack (); - unsigned feature_1_and = 0; - if (aarch_bti_enabled ()) - feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI; - - if (aarch_ra_sign_scope != AARCH_FUNCTION_NONE) - feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC; + /* Check whether the current assembler supports AEABI build attributes, if + not fallback to .note.gnu.property section. */ + if (HAVE_AS_AEABI_BUILD_ATTRIBUTES) + { + using namespace aarch64; + aeabi_subsection<BA_TagFeature_t, bool, 3> + aeabi_subsec ("aeabi_feature_and_bits", true); - if (aarch64_gcs_enabled ()) - feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_GCS; + aeabi_subsec.append ( + make_aeabi_attribute (Tag_Feature_BTI, aarch_bti_enabled ())); + aeabi_subsec.append ( + make_aeabi_attribute (Tag_Feature_PAC, aarch64_pacret_enabled ())); + aeabi_subsec.append ( + make_aeabi_attribute (Tag_Feature_GCS, aarch64_gcs_enabled ())); - if (feature_1_and) + if (!aeabi_subsec.empty ()) + aeabi_subsec.write (asm_out_file); + } + else { - /* Generate .note.gnu.property section. */ - switch_to_section (get_section (".note.gnu.property", - SECTION_NOTYPE, NULL)); + aarch64::section_note_gnu_property gnu_properties; - /* PT_NOTE header: namesz, descsz, type. - namesz = 4 ("GNU\0") - descsz = 16 (Size of the program property array) - [(12 + padding) * Number of array elements] - type = 5 (NT_GNU_PROPERTY_TYPE_0). */ - assemble_align (POINTER_SIZE); - assemble_integer (GEN_INT (4), 4, 32, 1); - assemble_integer (GEN_INT (ROUND_UP (12, POINTER_BYTES)), 4, 32, 1); - assemble_integer (GEN_INT (5), 4, 32, 1); - - /* PT_NOTE name. */ - assemble_string ("GNU", 4); - - /* PT_NOTE contents for NT_GNU_PROPERTY_TYPE_0: - type = GNU_PROPERTY_AARCH64_FEATURE_1_AND - datasz = 4 - data = feature_1_and. */ - assemble_integer (GEN_INT (GNU_PROPERTY_AARCH64_FEATURE_1_AND), 4, 32, 1); - assemble_integer (GEN_INT (4), 4, 32, 1); - assemble_integer (GEN_INT (feature_1_and), 4, 32, 1); - - /* Pad the size of the note to the required alignment. */ - assemble_align (POINTER_SIZE); + if (aarch_bti_enabled ()) + gnu_properties.bti_enabled (); + if (aarch64_pacret_enabled ()) + gnu_properties.pac_enabled (); + if (aarch64_gcs_enabled ()) + gnu_properties.gcs_enabled (); + + gnu_properties.write (); } } -#undef GNU_PROPERTY_AARCH64_FEATURE_1_GCS -#undef GNU_PROPERTY_AARCH64_FEATURE_1_PAC -#undef GNU_PROPERTY_AARCH64_FEATURE_1_BTI -#undef GNU_PROPERTY_AARCH64_FEATURE_1_AND /* Helper function for straight line speculation. Return what barrier should be emitted for straight line speculation diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index e8bd8c73c129..096c853af7ff 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -410,6 +410,9 @@ constexpr auto AARCH64_FL_DEFAULT_ISA_MODE ATTRIBUTE_UNUSED /* CSSC instructions are enabled through +cssc. */ #define TARGET_CSSC AARCH64_HAVE_ISA (CSSC) +/* CB<cc> instructions are enabled through +cmpbr. */ +#define TARGET_CMPBR AARCH64_HAVE_ISA (CMPBR) + /* Make sure this is always defined so we don't have to check for ifdefs but rather use normal ifs. */ #ifndef TARGET_FIX_ERR_A53_835769_DEFAULT @@ -490,6 +493,11 @@ constexpr auto AARCH64_FL_DEFAULT_ISA_MODE ATTRIBUTE_UNUSED (bool (aarch64_tune_params.extra_tuning_flags \ & AARCH64_EXTRA_TUNE_CHEAP_FPMR_WRITE)) +/* Enable folding address computation into LDAPUR when RCPC2 is available. */ +#define TARGET_ENABLE_LDAPUR (TARGET_RCPC2 \ + && !(aarch64_tune_params.extra_tuning_flags \ + & AARCH64_EXTRA_TUNE_AVOID_LDAPUR)) + /* Combinatorial tests. */ #define TARGET_SVE2_OR_SME2 \ diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 6dbc9faf7130..a4ae6859da01 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -136,6 +136,14 @@ ;; The actual value can sometimes vary, because it does not track ;; changes to PSTATE.ZA that happen during a lazy save and restore. ;; Those effects are instead tracked by ZA_SAVED_REGNUM. + ;; + ;; Sequences also write to this register if they synchronize the + ;; actual contents of ZA and PSTATE.ZA with the current function's + ;; ZA_REGNUM and SME_STATE_REGNUM. Conceptually, these extra writes + ;; do not change the value of SME_STATE_REGNUM. They simply act as + ;; sequencing points. They means that all direct accesses to ZA can + ;; depend only on ZA_REGNUM and SME_STATE_REGNUM, rather than also + ;; depending on ZA_SAVED_REGNUM etc. (SME_STATE_REGNUM 89) ;; Instructions write to this register if they set TPIDR2_EL0 to a @@ -474,6 +482,8 @@ ;; clobber for SVE predicates. (define_attr "pred_clobber" "any,no,yes" (const_string "any")) +(define_attr "enable_ldapur" "any,no,yes" (const_string "any")) + ;; [For compatibility with Arm in pipeline models] ;; Attribute that specifies whether or not the instruction touches fp ;; registers. @@ -498,7 +508,14 @@ (eq_attr "pred_clobber" "yes") (match_test "TARGET_SVE_PRED_CLOBBER")) (eq_attr "pred_clobber" "any")) - + (ior + (and + (eq_attr "enable_ldapur" "yes") + (match_test "TARGET_ENABLE_LDAPUR")) + (and + (eq_attr "enable_ldapur" "no") + (match_test "!TARGET_ENABLE_LDAPUR")) + (eq_attr "enable_ldapur" "any")) (ior (eq_attr "arch" "any") @@ -561,9 +578,7 @@ ;; Attribute that specifies whether we are dealing with a branch to a ;; label that is far away, i.e. further away than the maximum/minimum ;; representable in a signed 21-bits number. -;; 0 :=: no -;; 1 :=: yes -(define_attr "far_branch" "" (const_int 0)) +(define_attr "far_branch" "no,yes" (const_string "no")) ;; Attribute that specifies whether the alternative uses MOVPRFX. (define_attr "movprfx" "no,yes" (const_string "no")) @@ -674,6 +689,10 @@ "msrr\t%x0, %x1, %H1" ) +;; ------------------------------------------------------------------- +;; Unconditional jumps +;; ------------------------------------------------------------------- + (define_insn "indirect_jump" [(set (pc) (match_operand:DI 0 "register_operand" "r"))] "" @@ -692,18 +711,70 @@ [(set_attr "type" "branch")] ) -(define_expand "cbranch<mode>4" +;; Maximum PC-relative positive/negative displacements for various branching +;; instructions. +(define_constants + [ + ;; +/- 1MiB. Used by B.<cond>, CBZ, CBNZ. + (BRANCH_LEN_P_1MiB 1048572) + (BRANCH_LEN_N_1MiB -1048576) + + ;; +/- 32KiB. Used by TBZ, TBNZ. + (BRANCH_LEN_P_32KiB 32764) + (BRANCH_LEN_N_32KiB -32768) + + ;; +/- 1KiB. Used by CBB<cond>, CBH<cond>, CB<cond>. + (BRANCH_LEN_P_1Kib 1020) + (BRANCH_LEN_N_1Kib -1024) + ] +) + +;; ------------------------------------------------------------------- +;; Conditional jumps +;; ------------------------------------------------------------------- + +;; The order of the rules below is important. +;; Higher priority rules are preferred because they can express larger +;; displacements. +;; 1) EQ/NE comparisons against zero are handled by CBZ/CBNZ. +;; 2) LT/GE comparisons against zero are handled by TBZ/TBNZ. +;; 3) When the CMPBR extension is enabled: +;; a) Comparisons between two registers are handled by +;; CBB<cond>/CBH<cond>/CB<cond>. +;; b) Comparisons between a GP register and an in range immediate are +;; handled by CB<cond> (immediate). +;; 4) Otherwise, emit a CMP+B<cond> sequence. +;; ------------------------------------------------------------------- + +(define_expand "cbranch<GPI:mode>4" [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator" [(match_operand:GPI 1 "register_operand") (match_operand:GPI 2 "aarch64_plus_operand")]) - (label_ref (match_operand 3 "" "")) + (label_ref (match_operand 3)) (pc)))] "" - " - operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1], - operands[2]); - operands[2] = const0_rtx; - " + { + if (TARGET_CMPBR && aarch64_cb_rhs (GET_CODE (operands[0]), operands[2])) + { + /* The branch is supported natively. */ + } + else + { + operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), + operands[1], operands[2]); + operands[2] = const0_rtx; + } + } +) + +(define_expand "cbranch<SHORT:mode>4" + [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator" + [(match_operand:SHORT 1 "register_operand") + (match_operand:SHORT 2 "aarch64_reg_or_zero")]) + (label_ref (match_operand 3)) + (pc)))] + "TARGET_CMPBR" + "" ) (define_expand "cbranch<mode>4" @@ -711,25 +782,301 @@ (match_operator 0 "aarch64_comparison_operator" [(match_operand:GPF_F16 1 "register_operand") (match_operand:GPF_F16 2 "aarch64_fp_compare_operand")]) - (label_ref (match_operand 3 "" "")) + (label_ref (match_operand 3)) (pc)))] "" - " - operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1], - operands[2]); - operands[2] = const0_rtx; - " + { + operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1], + operands[2]); + operands[2] = const0_rtx; + } ) (define_expand "cbranchcc4" - [(set (pc) (if_then_else - (match_operator 0 "aarch64_comparison_operator" - [(match_operand 1 "cc_register") - (match_operand 2 "const0_operand")]) - (label_ref (match_operand 3 "" "")) - (pc)))] + [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator" + [(match_operand 1 "cc_register") + (match_operand 2 "const0_operand")]) + (label_ref (match_operand 3)) + (pc)))] "" - "") + "" +) + +;; For an EQ/NE comparison against zero, emit `CBZ`/`CBNZ` +(define_insn "aarch64_cbz<optab><mode>1" + [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r") + (const_int 0)) + (label_ref (match_operand 1)) + (pc)))] + "!aarch64_track_speculation" + { + if (get_attr_length (insn) == 8) + return aarch64_gen_far_branch (operands, 1, "Lcb", "<inv_cb>\\t%<w>0, "); + else + return "<cbz>\\t%<w>0, %l1"; + } + [(set_attr "type" "branch") + (set (attr "length") + (if_then_else (and (ge (minus (match_dup 1) (pc)) + (const_int BRANCH_LEN_N_1MiB)) + (lt (minus (match_dup 1) (pc)) + (const_int BRANCH_LEN_P_1MiB))) + (const_int 4) + (const_int 8))) + (set (attr "far_branch") + (if_then_else (and (ge (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_N_1MiB)) + (lt (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_P_1MiB))) + (const_string "no") + (const_string "yes")))] +) + +;; For an LT/GE comparison against zero, emit `TBZ`/`TBNZ` +(define_insn "*aarch64_tbz<optab><mode>1" + [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r") + (const_int 0)) + (label_ref (match_operand 1)) + (pc))) + (clobber (reg:CC CC_REGNUM))] + "!aarch64_track_speculation" + { + if (get_attr_length (insn) == 8) + { + if (get_attr_far_branch (insn) == FAR_BRANCH_YES) + return aarch64_gen_far_branch (operands, 1, "Ltb", + "<inv_tb>\\t%<w>0, <sizem1>, "); + else + { + char buf[64]; + uint64_t val = ((uint64_t) 1) + << (GET_MODE_SIZE (<MODE>mode) * BITS_PER_UNIT - 1); + sprintf (buf, "tst\t%%<w>0, %" PRId64, val); + output_asm_insn (buf, operands); + return "<bcond>\t%l1"; + } + } + else + return "<tbz>\t%<w>0, <sizem1>, %l1"; + } + [(set_attr "type" "branch") + (set (attr "length") + (if_then_else (and (ge (minus (match_dup 1) (pc)) + (const_int BRANCH_LEN_N_32KiB)) + (lt (minus (match_dup 1) (pc)) + (const_int BRANCH_LEN_P_32KiB))) + (const_int 4) + (const_int 8))) + (set (attr "far_branch") + (if_then_else (and (ge (minus (match_dup 1) (pc)) + (const_int BRANCH_LEN_N_1MiB)) + (lt (minus (match_dup 1) (pc)) + (const_int BRANCH_LEN_P_1MiB))) + (const_string "no") + (const_string "yes")))] +) + +;; Emit a `CB<cond> (register)` or `CB<cond> (immediate)` instruction. +;; The immediate range depends on the comparison code. +;; Comparisons against immediates outside this range fall back to +;; CMP + B<cond>. +(define_insn "aarch64_cb<INT_CMP:code><GPI:mode>" + [(set (pc) (if_then_else (INT_CMP + (match_operand:GPI 0 "register_operand" "r") + (match_operand:GPI 1 "nonmemory_operand" + "r<INT_CMP:cmpbr_imm_constraint>")) + (label_ref (match_operand 2)) + (pc)))] + "TARGET_CMPBR && aarch64_cb_rhs (<INT_CMP:CODE>, operands[1])" + { + return (get_attr_far_branch (insn) == FAR_BRANCH_NO) + ? "cb<INT_CMP:cmp_op>\\t%<w>0, %<w>1, %l2" + : aarch64_gen_far_branch (operands, 2, "L", + "cb<INT_CMP:inv_cmp_op>\\t%<w>0, %<w>1, "); + } + [(set_attr "type" "branch") + (set (attr "length") + (if_then_else (and (ge (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_N_1Kib)) + (lt (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_P_1Kib))) + (const_int 4) + (const_int 8))) + (set (attr "far_branch") + (if_then_else (and (ge (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_N_1Kib)) + (lt (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_P_1Kib))) + (const_string "no") + (const_string "yes")))] +) + +;; Emit a `CBB<cond> (register)` or `CBH<cond> (register)` instruction. +(define_insn "aarch64_cb<INT_CMP:code><SHORT:mode>" + [(set (pc) (if_then_else (INT_CMP + (match_operand:SHORT 0 "register_operand" "r") + (match_operand:SHORT 1 "aarch64_reg_or_zero" "rZ")) + (label_ref (match_operand 2)) + (pc)))] + "TARGET_CMPBR" + { + return (get_attr_far_branch (insn) == FAR_BRANCH_NO) + ? "cb<SHORT:cmpbr_suffix><INT_CMP:cmp_op>\\t%<w>0, %<w>1, %l2" + : aarch64_gen_far_branch (operands, 2, "L", + "cb<SHORT:cmpbr_suffix><INT_CMP:inv_cmp_op>\\t%<w>0, %<w>1, "); + } + [(set_attr "type" "branch") + (set (attr "length") + (if_then_else (and (ge (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_N_1Kib)) + (lt (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_P_1Kib))) + (const_int 4) + (const_int 8))) + (set (attr "far_branch") + (if_then_else (and (ge (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_N_1Kib)) + (lt (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_P_1Kib))) + (const_string "no") + (const_string "yes")))] +) + +;; Emit `B<cond>`, assuming that the condition is already in the CC register. +(define_insn "aarch64_bcond" + [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator" + [(match_operand 1 "cc_register") + (const_int 0)]) + (label_ref (match_operand 2)) + (pc)))] + "" + { + /* GCC's traditional style has been to use "beq" instead of "b.eq", etc., + but the "." is required for SVE conditions. */ + bool use_dot_p = GET_MODE (operands[1]) == CC_NZCmode; + if (get_attr_length (insn) == 8) + return aarch64_gen_far_branch (operands, 2, "Lbcond", + use_dot_p ? "b.%M0\\t" : "b%M0\\t"); + else + return use_dot_p ? "b.%m0\\t%l2" : "b%m0\\t%l2"; + } + [(set_attr "type" "branch") + (set (attr "length") + (if_then_else (and (ge (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_N_1MiB)) + (lt (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_P_1MiB))) + (const_int 4) + (const_int 8))) + (set (attr "far_branch") + (if_then_else (and (ge (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_N_1MiB)) + (lt (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_P_1MiB))) + (const_string "no") + (const_string "yes")))] +) + +;; For a 24-bit immediate CST we can optimize the compare for equality +;; and branch sequence from: +;; mov x0, #imm1 +;; movk x0, #imm2, lsl 16 /* x0 contains CST. */ +;; cmp x1, x0 +;; b<ne,eq> .Label +;; into the shorter: +;; sub x0, x1, #(CST & 0xfff000) +;; subs x0, x0, #(CST & 0x000fff) +;; b<ne,eq> .Label +(define_insn_and_split "*aarch64_bcond_wide_imm<GPI:mode>" + [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r") + (match_operand:GPI 1 "aarch64_imm24" "n")) + (label_ref:P (match_operand 2)) + (pc)))] + "!aarch64_move_imm (INTVAL (operands[1]), <GPI:MODE>mode) + && !aarch64_plus_operand (operands[1], <GPI:MODE>mode) + && !reload_completed" + "#" + "&& true" + [(const_int 0)] + { + HOST_WIDE_INT lo_imm = UINTVAL (operands[1]) & 0xfff; + HOST_WIDE_INT hi_imm = UINTVAL (operands[1]) & 0xfff000; + rtx tmp = gen_reg_rtx (<GPI:MODE>mode); + emit_insn (gen_add<GPI:mode>3 (tmp, operands[0], GEN_INT (-hi_imm))); + emit_insn (gen_add<GPI:mode>3_compare0 (tmp, tmp, GEN_INT (-lo_imm))); + rtx cc_reg = gen_rtx_REG (CC_NZmode, CC_REGNUM); + rtx cmp_rtx = gen_rtx_fmt_ee (<EQL:CMP>, <GPI:MODE>mode, + cc_reg, const0_rtx); + emit_jump_insn (gen_aarch64_bcond (cmp_rtx, cc_reg, operands[2])); + DONE; + } +) + +;; ------------------------------------------------------------------- +;; Test bit and branch +;; ------------------------------------------------------------------- + +(define_expand "tbranch_<code><mode>3" + [(set (pc) (if_then_else (EQL + (match_operand:SHORT 0 "register_operand") + (match_operand 1 "const0_operand")) + (label_ref (match_operand 2 "")) + (pc)))] + "" +{ + rtx bitvalue = gen_reg_rtx (<ZEROM>mode); + rtx reg = gen_lowpart (<ZEROM>mode, operands[0]); + rtx val = gen_int_mode (HOST_WIDE_INT_1U << UINTVAL (operands[1]), + <MODE>mode); + emit_insn (gen_and<zerom>3 (bitvalue, reg, val)); + operands[1] = const0_rtx; + operands[0] = aarch64_gen_compare_reg (<CODE>, bitvalue, + operands[1]); +}) + +(define_insn "@aarch64_tbz<optab><ALLI:mode><GPI:mode>" + [(set (pc) (if_then_else (EQL + (zero_extract:GPI + (match_operand:ALLI 0 "register_operand" "r") + (const_int 1) + (match_operand 1 "aarch64_simd_shift_imm_<ALLI:mode>" "n")) + (const_int 0)) + (label_ref (match_operand 2)) + (pc))) + (clobber (reg:CC CC_REGNUM))] + "!aarch64_track_speculation" + { + if (get_attr_length (insn) == 8) + { + if (get_attr_far_branch (insn) == 1) + return aarch64_gen_far_branch (operands, 2, "Ltb", + "<inv_tb>\\t%<ALLI:w>0, %1, "); + else + { + operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1])); + return "tst\t%<ALLI:w>0, %1\;<bcond>\t%l2"; + } + } + else + return "<tbz>\t%<ALLI:w>0, %1, %l2"; + } + [(set_attr "type" "branch") + (set (attr "length") + (if_then_else (and (ge (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_N_32KiB)) + (lt (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_P_32KiB))) + (const_int 4) + (const_int 8))) + (set (attr "far_branch") + (if_then_else (and (ge (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_N_1MiB)) + (lt (minus (match_dup 2) (pc)) + (const_int BRANCH_LEN_P_1MiB))) + (const_string "no") + (const_string "yes")))] + +) (define_insn "@ccmp<CC_ONLY:mode><GPI:mode>" [(set (match_operand:CC_ONLY 1 "cc_register") @@ -861,71 +1208,6 @@ } ) -(define_insn "condjump" - [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator" - [(match_operand 1 "cc_register" "") (const_int 0)]) - (label_ref (match_operand 2 "" "")) - (pc)))] - "" - { - /* GCC's traditional style has been to use "beq" instead of "b.eq", etc., - but the "." is required for SVE conditions. */ - bool use_dot_p = GET_MODE (operands[1]) == CC_NZCmode; - if (get_attr_length (insn) == 8) - return aarch64_gen_far_branch (operands, 2, "Lbcond", - use_dot_p ? "b.%M0\\t" : "b%M0\\t"); - else - return use_dot_p ? "b.%m0\\t%l2" : "b%m0\\t%l2"; - } - [(set_attr "type" "branch") - (set (attr "length") - (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576)) - (lt (minus (match_dup 2) (pc)) (const_int 1048572))) - (const_int 4) - (const_int 8))) - (set (attr "far_branch") - (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576)) - (lt (minus (match_dup 2) (pc)) (const_int 1048572))) - (const_int 0) - (const_int 1)))] -) - -;; For a 24-bit immediate CST we can optimize the compare for equality -;; and branch sequence from: -;; mov x0, #imm1 -;; movk x0, #imm2, lsl 16 /* x0 contains CST. */ -;; cmp x1, x0 -;; b<ne,eq> .Label -;; into the shorter: -;; sub x0, x1, #(CST & 0xfff000) -;; subs x0, x0, #(CST & 0x000fff) -;; b<ne,eq> .Label -(define_insn_and_split "*compare_condjump<GPI:mode>" - [(set (pc) (if_then_else (EQL - (match_operand:GPI 0 "register_operand" "r") - (match_operand:GPI 1 "aarch64_imm24" "n")) - (label_ref:P (match_operand 2 "" "")) - (pc)))] - "!aarch64_move_imm (INTVAL (operands[1]), <GPI:MODE>mode) - && !aarch64_plus_operand (operands[1], <GPI:MODE>mode) - && !reload_completed" - "#" - "&& true" - [(const_int 0)] - { - HOST_WIDE_INT lo_imm = UINTVAL (operands[1]) & 0xfff; - HOST_WIDE_INT hi_imm = UINTVAL (operands[1]) & 0xfff000; - rtx tmp = gen_reg_rtx (<GPI:MODE>mode); - emit_insn (gen_add<GPI:mode>3 (tmp, operands[0], GEN_INT (-hi_imm))); - emit_insn (gen_add<GPI:mode>3_compare0 (tmp, tmp, GEN_INT (-lo_imm))); - rtx cc_reg = gen_rtx_REG (CC_NZmode, CC_REGNUM); - rtx cmp_rtx = gen_rtx_fmt_ee (<EQL:CMP>, <GPI:MODE>mode, - cc_reg, const0_rtx); - emit_jump_insn (gen_condjump (cmp_rtx, cc_reg, operands[2])); - DONE; - } -) - (define_expand "casesi" [(match_operand:SI 0 "register_operand") ; Index (match_operand:SI 1 "const_int_operand") ; Lower bound @@ -1117,127 +1399,6 @@ (set_attr "sls_length" "retbr")] ) -(define_insn "aarch64_cb<optab><mode>1" - [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r") - (const_int 0)) - (label_ref (match_operand 1 "" "")) - (pc)))] - "!aarch64_track_speculation" - { - if (get_attr_length (insn) == 8) - return aarch64_gen_far_branch (operands, 1, "Lcb", "<inv_cb>\\t%<w>0, "); - else - return "<cbz>\\t%<w>0, %l1"; - } - [(set_attr "type" "branch") - (set (attr "length") - (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -1048576)) - (lt (minus (match_dup 1) (pc)) (const_int 1048572))) - (const_int 4) - (const_int 8))) - (set (attr "far_branch") - (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576)) - (lt (minus (match_dup 2) (pc)) (const_int 1048572))) - (const_int 0) - (const_int 1)))] -) - -(define_expand "tbranch_<code><mode>3" - [(set (pc) (if_then_else - (EQL (match_operand:SHORT 0 "register_operand") - (match_operand 1 "const0_operand")) - (label_ref (match_operand 2 "")) - (pc)))] - "" -{ - rtx bitvalue = gen_reg_rtx (<ZEROM>mode); - rtx reg = gen_lowpart (<ZEROM>mode, operands[0]); - rtx val = gen_int_mode (HOST_WIDE_INT_1U << UINTVAL (operands[1]), <MODE>mode); - emit_insn (gen_and<zerom>3 (bitvalue, reg, val)); - operands[1] = const0_rtx; - operands[0] = aarch64_gen_compare_reg (<CODE>, bitvalue, - operands[1]); -}) - -(define_insn "@aarch64_tb<optab><ALLI:mode><GPI:mode>" - [(set (pc) (if_then_else - (EQL (zero_extract:GPI (match_operand:ALLI 0 "register_operand" "r") - (const_int 1) - (match_operand 1 - "aarch64_simd_shift_imm_<ALLI:mode>" "n")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc))) - (clobber (reg:CC CC_REGNUM))] - "!aarch64_track_speculation" - { - if (get_attr_length (insn) == 8) - { - if (get_attr_far_branch (insn) == 1) - return aarch64_gen_far_branch (operands, 2, "Ltb", - "<inv_tb>\\t%<ALLI:w>0, %1, "); - else - { - operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1])); - return "tst\t%<ALLI:w>0, %1\;<bcond>\t%l2"; - } - } - else - return "<tbz>\t%<ALLI:w>0, %1, %l2"; - } - [(set_attr "type" "branch") - (set (attr "length") - (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768)) - (lt (minus (match_dup 2) (pc)) (const_int 32764))) - (const_int 4) - (const_int 8))) - (set (attr "far_branch") - (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576)) - (lt (minus (match_dup 2) (pc)) (const_int 1048572))) - (const_int 0) - (const_int 1)))] - -) - -(define_insn "*cb<optab><mode>1" - [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r") - (const_int 0)) - (label_ref (match_operand 1 "" "")) - (pc))) - (clobber (reg:CC CC_REGNUM))] - "!aarch64_track_speculation" - { - if (get_attr_length (insn) == 8) - { - if (get_attr_far_branch (insn) == 1) - return aarch64_gen_far_branch (operands, 1, "Ltb", - "<inv_tb>\\t%<w>0, <sizem1>, "); - else - { - char buf[64]; - uint64_t val = ((uint64_t) 1) - << (GET_MODE_SIZE (<MODE>mode) * BITS_PER_UNIT - 1); - sprintf (buf, "tst\t%%<w>0, %" PRId64, val); - output_asm_insn (buf, operands); - return "<bcond>\t%l1"; - } - } - else - return "<tbz>\t%<w>0, <sizem1>, %l1"; - } - [(set_attr "type" "branch") - (set (attr "length") - (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768)) - (lt (minus (match_dup 1) (pc)) (const_int 32764))) - (const_int 4) - (const_int 8))) - (set (attr "far_branch") - (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -1048576)) - (lt (minus (match_dup 1) (pc)) (const_int 1048572))) - (const_int 0) - (const_int 1)))] -) - (define_expand "save_stack_nonlocal" [(set (match_operand 0 "memory_operand") (match_operand 1 "register_operand"))] @@ -1308,13 +1469,13 @@ emit_insn (gen_subdi3_compare1 (gcs_now, gcs_old, gcs_now)); rtx cc_reg = gen_rtx_REG (CC_NZmode, CC_REGNUM); rtx cmp_rtx = gen_rtx_fmt_ee (EQ, DImode, cc_reg, const0_rtx); - emit_jump_insn (gen_condjump (cmp_rtx, cc_reg, done_label)); + emit_jump_insn (gen_aarch64_bcond (cmp_rtx, cc_reg, done_label)); emit_label (loop_label); emit_insn (gen_aarch64_gcspopm_xzr ()); emit_insn (gen_adddi3_compare0 (gcs_now, gcs_now, GEN_INT (-8))); cc_reg = gen_rtx_REG (CC_NZmode, CC_REGNUM); cmp_rtx = gen_rtx_fmt_ee (NE, DImode, cc_reg, const0_rtx); - emit_jump_insn (gen_condjump (cmp_rtx, cc_reg, loop_label)); + emit_jump_insn (gen_aarch64_bcond (cmp_rtx, cc_reg, loop_label)); emit_label (done_label); } DONE; @@ -5619,6 +5780,19 @@ (match_operand:TI 1 "register_operand")] "TARGET_SIMD && !TARGET_CSSC" { + /* For SVE we can do popcount on DImode chunks of the TImode argument + and then use a cheap ADDP reduction. The SVE CNT instruction requires + materializing a PTRUE so don't do this if optimizing for size. */ + if (TARGET_SVE && !optimize_function_for_size_p (cfun)) + { + rtx v = gen_reg_rtx (V2DImode); + rtx v1 = gen_reg_rtx (V2DImode); + emit_move_insn (v, gen_lowpart (V2DImode, operands[1])); + rtx p = aarch64_ptrue_reg (VNx2BImode, 16); + emit_insn (gen_aarch64_pred_popcountv2di (v1, p, v)); + emit_insn (gen_reduc_plus_scal_v2di (operands[0], v1)); + DONE; + } rtx v = gen_reg_rtx (V16QImode); rtx v1 = gen_reg_rtx (V16QImode); emit_move_insn (v, gen_lowpart (V16QImode, operands[1])); @@ -8082,8 +8256,8 @@ : gen_stack_protect_test_si) (operands[0], operands[1])); rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM); - emit_jump_insn (gen_condjump (gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx), - cc_reg, operands[2])); + emit_jump_insn (gen_aarch64_bcond (gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx), + cc_reg, operands[2])); DONE; }) diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt index f32d56d4ffae..9ca753e6a886 100644 --- a/gcc/config/aarch64/aarch64.opt +++ b/gcc/config/aarch64/aarch64.opt @@ -290,6 +290,17 @@ msve-vector-bits= Target RejectNegative Joined Enum(sve_vector_bits) Var(aarch64_sve_vector_bits) Init(SVE_SCALABLE) -msve-vector-bits=<number> Set the number of bits in an SVE vector register. +mautovec-preference= +Target RejectNegative Joined Var(autovec_preference) Enum(aarch64_autovec_preference) Init(AARCH64_AUTOVEC_DEFAULT) +-mautovec-preference=[default|asimd-only|sve-only|prefer-asimd|prefer-sve] +Force an ISA selection strategy for auto-vectorization. For best performance it +is highly recommended to use -mcpu or -mtune instead. This parameter should +only be used for code exploration. + +mmax-vectorization +Target Var(flag_aarch64_max_vectorization) Save +Override the scalar cost model such that vectorization is always profitable. + mverbose-cost-dump Target Undocumented Var(flag_aarch64_verbose_cost) Enables verbose cost model dumping in the debug dump files. @@ -356,8 +367,8 @@ The number of Newton iterations for calculating the reciprocal for double type. -param=aarch64-autovec-preference= Target Joined Var(aarch64_autovec_preference) Enum(aarch64_autovec_preference) Init(AARCH64_AUTOVEC_DEFAULT) Param ---param=aarch64-autovec-preference=[default|asimd-only|sve-only|prefer-asimd|prefer-sve] -Force an ISA selection strategy for auto-vectorization. +An old alias for -mautovec-preference. If both -mautovec-preference and +--param=aarch64-autovec-preference are passed, the --param value will be used. Enum Name(aarch64_autovec_preference) Type(enum aarch64_autovec_preference_enum) UnknownError(unknown autovec preference %qs) diff --git a/gcc/config/aarch64/atomics.md b/gcc/config/aarch64/atomics.md index 36b0dbd1f57f..ea4a9367fc88 100644 --- a/gcc/config/aarch64/atomics.md +++ b/gcc/config/aarch64/atomics.md @@ -679,13 +679,16 @@ ) (define_insn "aarch64_atomic_load<mode>_rcpc" - [(set (match_operand:ALLI 0 "register_operand" "=r") + [(set (match_operand:ALLI 0 "register_operand") (unspec_volatile:ALLI - [(match_operand:ALLI 1 "aarch64_sync_memory_operand" "Q") + [(match_operand:ALLI 1 "aarch64_rcpc_memory_operand") (match_operand:SI 2 "const_int_operand")] ;; model UNSPECV_LDAP))] "TARGET_RCPC" - "ldapr<atomic_sfx>\t%<w>0, %1" + {@ [ cons: =0 , 1 ; attrs: enable_ldapur ] + [ r , Q ; any ] ldapr<atomic_sfx>\t%<w>0, %1 + [ r , Ust ; yes ] ldapur<atomic_sfx>\t%<w>0, %1 + } ) (define_insn "aarch64_atomic_load<mode>" @@ -705,21 +708,24 @@ ) (define_insn "*aarch64_atomic_load<ALLX:mode>_rcpc_zext" - [(set (match_operand:SD_HSDI 0 "register_operand" "=r") + [(set (match_operand:SD_HSDI 0 "register_operand") (zero_extend:SD_HSDI (unspec_volatile:ALLX - [(match_operand:ALLX 1 "aarch64_sync_memory_operand" "Q") + [(match_operand:ALLX 1 "aarch64_rcpc_memory_operand") (match_operand:SI 2 "const_int_operand")] ;; model UNSPECV_LDAP)))] "TARGET_RCPC && (<SD_HSDI:sizen> > <ALLX:sizen>)" - "ldapr<ALLX:atomic_sfx>\t%w0, %1" + {@ [ cons: =0 , 1 ; attrs: enable_ldapur ] + [ r , Q ; any ] ldapr<ALLX:atomic_sfx>\t%w0, %1 + [ r , Ust ; yes ] ldapur<ALLX:atomic_sfx>\t%w0, %1 + } ) (define_insn "*aarch64_atomic_load<ALLX:mode>_rcpc_sext" [(set (match_operand:GPI 0 "register_operand" "=r") (sign_extend:GPI (unspec_volatile:ALLX - [(match_operand:ALLX 1 "aarch64_sync_memory_operand" "Q") + [(match_operand:ALLX 1 "aarch64_rcpc_memory_operand" "Ust") (match_operand:SI 2 "const_int_operand")] ;; model UNSPECV_LDAP)))] "TARGET_RCPC2 && (<GPI:sizen> > <ALLX:sizen>)" diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md index e9f69f823a6b..dc1925dfb6c3 100644 --- a/gcc/config/aarch64/constraints.md +++ b/gcc/config/aarch64/constraints.md @@ -304,6 +304,24 @@ (and (match_code "const_int") (match_test "(unsigned HOST_WIDE_INT) ival <= 7"))) +(define_constraint "Uc0" + "@internal + A constraint that matches the integers 0...63." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, 0, 63)"))) + +(define_constraint "Uc1" + "@internal + A constraint that matches the integers 1...64." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, 1, 64)"))) + +(define_constraint "Uc2" + "@internal + A constraint that matches the integers -1...62." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, -1, 62)"))) + (define_constraint "Up3" "@internal A constraint that matches the integers 2^(0...4)." diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 146453b05168..c59fcd679d72 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -479,13 +479,25 @@ ;; All fully-packed SVE integer and Advanced SIMD integer modes. (define_mode_iterator SVE_ASIMD_FULL_I [SVE_FULL_I VDQ_I]) -;; All fully-packed SVE floating-point vector modes. +;; Fully-packed SVE floating-point vector modes, excluding BF16. (define_mode_iterator SVE_FULL_F [VNx8HF VNx4SF VNx2DF]) +;; Partial SVE floating-point vector modes, excluding BF16. +(define_mode_iterator SVE_PARTIAL_F [VNx2HF VNx4HF VNx2SF]) + +;; SVE floating-point vector modes, excluding BF16. +(define_mode_iterator SVE_F [SVE_PARTIAL_F SVE_FULL_F]) + ;; Fully-packed SVE floating-point vector modes and their scalar equivalents. (define_mode_iterator SVE_FULL_F_SCALAR [SVE_FULL_F GPF_HF]) -(define_mode_iterator SVE_FULL_F_BF [(VNx8BF "TARGET_SSVE_B16B16") SVE_FULL_F]) +(define_mode_iterator SVE_FULL_F_B16B16 [(VNx8BF "TARGET_SSVE_B16B16") SVE_FULL_F]) + +(define_mode_iterator SVE_PARTIAL_F_B16B16 [(VNx2BF "TARGET_SSVE_B16B16") + (VNx4BF "TARGET_SSVE_B16B16") + SVE_PARTIAL_F]) + +(define_mode_iterator SVE_F_B16B16 [SVE_PARTIAL_F_B16B16 SVE_FULL_F_B16B16]) ;; Modes for which (B)FCLAMP is supported. (define_mode_iterator SVE_CLAMP_F [(VNx8BF "TARGET_SSVE_B16B16") @@ -529,6 +541,13 @@ ;; elements. (define_mode_iterator SVE_FULL_HSF [VNx8HF VNx4SF]) +;; Partial SVE floating-point vector modes that have 16-bit or 32-bit +;; elements. +(define_mode_iterator SVE_PARTIAL_HSF [VNx2HF VNx4HF VNx2SF]) + +;; SVE floating-point vector modes that have 16-bit or 32-bit elements. +(define_mode_iterator SVE_HSF [SVE_PARTIAL_HSF SVE_FULL_HSF]) + ;; Fully-packed SVE integer vector modes that have 16-bit or 64-bit elements. (define_mode_iterator SVE_FULL_HDI [VNx8HI VNx2DI]) @@ -553,6 +572,9 @@ (define_mode_iterator SVE_MATMULF [(VNx4SF "TARGET_SVE_F32MM") (VNx2DF "TARGET_SVE_F64MM")]) +;; SVE floating-point vector modes that have 32-bit or 64-bit elements. +(define_mode_iterator SVE_SDF [VNx2SF SVE_FULL_SDF]) + ;; Fully-packed SVE vector modes that have 32-bit or smaller elements. (define_mode_iterator SVE_FULL_BHS [VNx16QI VNx8HI VNx4SI VNx8BF VNx8HF VNx4SF]) @@ -580,14 +602,13 @@ VNx4SI VNx2SI VNx2DI]) +(define_mode_iterator SVE_BF [VNx2BF VNx4BF VNx8BF]) + ;; All SVE floating-point vector modes. -(define_mode_iterator SVE_F [VNx8HF VNx4HF VNx2HF - VNx8BF VNx4BF VNx2BF - VNx4SF VNx2SF - VNx2DF]) +(define_mode_iterator SVE_F_BF [SVE_F SVE_BF]) ;; All SVE vector modes. -(define_mode_iterator SVE_ALL [SVE_I SVE_F]) +(define_mode_iterator SVE_ALL [SVE_I SVE_F_BF]) ;; All SVE 2-vector modes. (define_mode_iterator SVE_FULLx2 [VNx32QI VNx16HI VNx8SI VNx4DI @@ -623,6 +644,9 @@ VNx4SI VNx2SI VNx2DI]) +;; SVE integer vector modes with 32-bit elements. +(define_mode_iterator SVE_SI [VNx2SI VNx4SI]) + (define_mode_iterator SVE_DIx24 [VNx4DI VNx8DI]) ;; SVE modes with 2 or 4 elements. @@ -638,6 +662,9 @@ (define_mode_iterator SVE_2 [VNx2QI VNx2HI VNx2HF VNx2BF VNx2SI VNx2SF VNx2DI VNx2DF]) +;; SVE SI and DI modes with 2 elements. +(define_mode_iterator SVE_2SDI [VNx2SI VNx2DI]) + ;; SVE integer modes with 2 elements, excluding the widest element. (define_mode_iterator SVE_2BHSI [VNx2QI VNx2HI VNx2SI]) @@ -1678,6 +1705,30 @@ (SI "SI") (HI "HI") (QI "QI") (V4BF "BF") (V8BF "BF") + (V2x8QI "QI") (V2x4HI "HI") + (V2x2SI "SI") (V2x1DI "DI") + (V2x4HF "HF") (V2x2SF "SF") + (V2x1DF "DF") (V2x4BF "BF") + (V3x8QI "QI") (V3x4HI "HI") + (V3x2SI "SI") (V3x1DI "DI") + (V3x4HF "HF") (V3x2SF "SF") + (V3x1DF "DF") (V3x4BF "BF") + (V4x8QI "QI") (V4x4HI "HI") + (V4x2SI "SI") (V4x1DI "DI") + (V4x4HF "HF") (V4x2SF "SF") + (V4x1DF "DF") (V4x4BF "BF") + (V2x16QI "QI") (V2x8HI "HI") + (V2x4SI "SI") (V2x2DI "DI") + (V2x8HF "HF") (V2x4SF "SF") + (V2x2DF "DF") (V2x8BF "BF") + (V3x16QI "QI") (V3x8HI "HI") + (V3x4SI "SI") (V3x2DI "DI") + (V3x8HF "HF") (V3x4SF "SF") + (V3x2DF "DF") (V3x8BF "BF") + (V4x16QI "QI") (V4x8HI "HI") + (V4x4SI "SI") (V4x2DI "DI") + (V4x8HF "HF") (V4x4SF "SF") + (V4x2DF "DF") (V4x8BF "BF") (VNx16QI "QI") (VNx8QI "QI") (VNx4QI "QI") (VNx2QI "QI") (VNx8HI "HI") (VNx4HI "HI") (VNx2HI "HI") (VNx8HF "HF") (VNx4HF "HF") (VNx2HF "HF") @@ -1699,6 +1750,30 @@ (DF "df") (SI "si") (HI "hi") (QI "qi") (V4BF "bf") (V8BF "bf") + (V2x8QI "qi") (V2x4HI "hi") + (V2x2SI "si") (V2x1DI "di") + (V2x4HF "hf") (V2x2SF "sf") + (V2x1DF "df") (V2x4BF "bf") + (V3x8QI "qi") (V3x4HI "hi") + (V3x2SI "si") (V3x1DI "di") + (V3x4HF "hf") (V3x2SF "sf") + (V3x1DF "df") (V3x4BF "bf") + (V4x8QI "qi") (V4x4HI "hi") + (V4x2SI "si") (V4x1DI "di") + (V4x4HF "hf") (V4x2SF "sf") + (V4x1DF "df") (V4x4BF "bf") + (V2x16QI "qi") (V2x8HI "hi") + (V2x4SI "si") (V2x2DI "di") + (V2x8HF "hf") (V2x4SF "sf") + (V2x2DF "df") (V2x8BF "bf") + (V3x16QI "qi") (V3x8HI "hi") + (V3x4SI "si") (V3x2DI "di") + (V3x8HF "hf") (V3x4SF "sf") + (V3x2DF "df") (V3x8BF "bf") + (V4x16QI "qi") (V4x8HI "hi") + (V4x4SI "si") (V4x2DI "di") + (V4x8HF "hf") (V4x4SF "sf") + (V4x2DF "df") (V4x8BF "bf") (VNx16QI "qi") (VNx8QI "qi") (VNx4QI "qi") (VNx2QI "qi") (VNx8HI "hi") (VNx4HI "hi") (VNx2HI "hi") (VNx8HF "hf") (VNx4HF "hf") (VNx2HF "hf") @@ -2445,7 +2520,9 @@ (VNx8DI "vnx2di") (VNx8DF "vnx2df")]) ;; The predicate mode associated with an SVE data mode. For structure modes -;; this is equivalent to the <VPRED> of the subvector mode. +;; this is equivalent to the <VPRED> of the subvector mode. For partial +;; vector modes, this is equivalent to the <VPRED> of a full SVE mode with +;; the same number of elements. (define_mode_attr VPRED [(VNx16QI "VNx16BI") (VNx8QI "VNx8BI") (VNx4QI "VNx4BI") (VNx2QI "VNx2BI") (VNx8HI "VNx8BI") (VNx4HI "VNx4BI") (VNx2HI "VNx2BI") @@ -2583,19 +2660,22 @@ (define_mode_attr data_bytes [(VNx16BI "1") (VNx8BI "2") (VNx4BI "4") (VNx2BI "8")]) -;; Two-nybble mask for partial vector modes: nunits, byte size. -(define_mode_attr self_mask [(VNx8QI "0x81") - (VNx4QI "0x41") - (VNx2QI "0x21") - (VNx4HI "0x42") - (VNx2HI "0x22") - (VNx2SI "0x24")]) - -;; For SVE_HSDI vector modes, the mask of narrower modes, encoded as above. -(define_mode_attr narrower_mask [(VNx8HI "0x81") (VNx4HI "0x41") - (VNx2HI "0x21") - (VNx4SI "0x43") (VNx2SI "0x23") - (VNx2DI "0x27")]) +;; Two-nybble mask for vector modes: nunits, byte size. +(define_mode_attr self_mask [(VNx2HI "0x22") (VNx2HF "0x22") + (VNx4HI "0x42") (VNx4HF "0x42") + (VNx8HI "0x82") (VNx8HF "0x82") + (VNx2SI "0x24") (VNx2SF "0x24") + (VNx4SI "0x44") (VNx4SF "0x44") + (VNx2DI "0x28") (VNx2DF "0x28") + (VNx8QI "0x81") (VNx4QI "0x41") (VNx2QI "0x21")]) + +;; The mask of narrower vector modes, encoded as above. +(define_mode_attr narrower_mask [(VNx8HI "0x81") (VNx8HF "0x81") + (VNx4HI "0x41") (VNx4HF "0x41") + (VNx2HI "0x21") (VNx2HF "0x21") + (VNx4SI "0x43") (VNx4SF "0x43") + (VNx2SI "0x23") (VNx2SF "0x23") + (VNx2DI "0x27") (VNx2DF "0x27")]) ;; The constraint to use for an SVE [SU]DOT, FMUL, FMLA or FMLS lane index. (define_mode_attr sve_lane_con [(VNx8HI "y") (VNx4SI "y") (VNx2DI "x") @@ -2611,13 +2691,15 @@ (V2DI "vec") (DI "offset")]) (define_mode_attr b [(V4BF "b") (V4HF "") (V8BF "b") (V8HF "") - (VNx8BF "b") (VNx8HF "") (VNx4SF "") (VNx2DF "") + (VNx2BF "b") (VNx2HF "") (VNx2SF "") + (VNx4BF "b") (VNx4HF "") (VNx4SF "") + (VNx8BF "b") (VNx8HF "") (VNx2DF "") (VNx16BF "b") (VNx16HF "") (VNx8SF "") (VNx4DF "") (VNx32BF "b") (VNx32HF "") (VNx16SF "") (VNx8DF "")]) -(define_mode_attr is_bf16 [(VNx8BF "true") - (VNx8HF "false") - (VNx4SF "false") +(define_mode_attr is_bf16 [(VNx2BF "true") (VNx4BF "true") (VNx8BF "true") + (VNx2HF "false") (VNx4HF "false") (VNx8HF "false") + (VNx2SF "false") (VNx4SF "false") (VNx2DF "false")]) (define_mode_attr aligned_operand [(VNx16QI "register_operand") @@ -2879,6 +2961,36 @@ (geu "hs") (gtu "hi")]) +(define_code_attr inv_cmp_op [(lt "ge") + (le "gt") + (eq "ne") + (ne "eq") + (ge "lt") + (gt "le") + (ltu "hs") + (leu "hi") + (geu "lo") + (gtu "ls")]) + +(define_mode_attr cmpbr_suffix [(QI "b") (HI "h")]) + +(define_code_iterator INT_CMP [lt le eq ne ge gt ltu leu geu gtu]) + +(define_code_attr cmpbr_imm_constraint [ + (eq "Uc0") + (ne "Uc0") + (gt "Uc0") + (gtu "Uc0") + (lt "Uc0") + (ltu "Uc0") + + (ge "Uc1") + (geu "Uc1") + + (le "Uc2") + (leu "Uc2") +]) + (define_code_attr fix_trunc_optab [(fix "fix_trunc") (unsigned_fix "fixuns_trunc")]) diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index 2c6af831eae1..32056daf3298 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -587,6 +587,11 @@ return aarch64_simd_shift_imm_p (op, mode, false); }) +(define_special_predicate "aarch64_predicate_operand" + (and (match_code "reg,subreg") + (match_test "register_operand (op, GET_MODE (op))") + (match_test "aarch64_sve_valid_pred_p (op, mode)"))) + (define_predicate "aarch64_simd_imm_zero" (and (match_code "const,const_vector") (match_test "op == CONST0_RTX (GET_MODE (op))"))) @@ -1071,5 +1076,5 @@ && !(INTVAL (op) & 0xf)"))) (define_predicate "aarch64_maskload_else_operand" - (and (match_code "const_int,const_vector") + (and (match_code "const_vector") (match_test "op == CONST0_RTX (GET_MODE (op))"))) diff --git a/gcc/config/aarch64/t-aarch64 b/gcc/config/aarch64/t-aarch64 index 59571948479c..38a8c0637255 100644 --- a/gcc/config/aarch64/t-aarch64 +++ b/gcc/config/aarch64/t-aarch64 @@ -140,6 +140,17 @@ aarch-common.o: $(srcdir)/config/arm/aarch-common.cc $(CONFIG_H) $(SYSTEM_H) \ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(srcdir)/config/arm/aarch-common.cc +aarch64-elf-metadata.o: $(srcdir)/config/aarch64/aarch64-elf-metadata.cc \ + $(CONFIG_H) \ + $(BACKEND_H) \ + $(RTL_H) \ + $(SYSTEM_H) \ + $(TARGET_H) \ + $(srcdir)/config/aarch64/aarch64-elf-metadata.h \ + output.h + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_SPPFLAGS) $(INCLUDES) \ + $(srcdir)/config/aarch64/aarch64-elf-metadata.cc + aarch64-c.o: $(srcdir)/config/aarch64/aarch64-c.cc $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H) $(TARGET_H) $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ diff --git a/gcc/config/aarch64/tuning_models/cortexx925.h b/gcc/config/aarch64/tuning_models/cortexx925.h index 7d0162eae54c..f448493b1bc5 100644 --- a/gcc/config/aarch64/tuning_models/cortexx925.h +++ b/gcc/config/aarch64/tuning_models/cortexx925.h @@ -222,7 +222,8 @@ static const struct tune_params cortexx925_tunings = (AARCH64_EXTRA_TUNE_BASE | AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT - | AARCH64_EXTRA_TUNE_AVOID_PRED_RMW), /* tune_flags. */ + | AARCH64_EXTRA_TUNE_AVOID_PRED_RMW + | AARCH64_EXTRA_TUNE_AVOID_LDAPUR), /* tune_flags. */ &generic_armv9a_prefetch_tune, AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */ diff --git a/gcc/config/aarch64/tuning_models/neoversev2.h b/gcc/config/aarch64/tuning_models/neoversev2.h index b000fb465709..266d8f190a25 100644 --- a/gcc/config/aarch64/tuning_models/neoversev2.h +++ b/gcc/config/aarch64/tuning_models/neoversev2.h @@ -220,7 +220,8 @@ static const struct tune_params neoversev2_tunings = (AARCH64_EXTRA_TUNE_BASE | AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT - | AARCH64_EXTRA_TUNE_AVOID_PRED_RMW), /* tune_flags. */ + | AARCH64_EXTRA_TUNE_AVOID_PRED_RMW + | AARCH64_EXTRA_TUNE_AVOID_LDAPUR), /* tune_flags. */ &generic_armv9a_prefetch_tune, AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */ diff --git a/gcc/config/aarch64/tuning_models/neoversev3.h b/gcc/config/aarch64/tuning_models/neoversev3.h index ad3cd222512d..f5566d270dac 100644 --- a/gcc/config/aarch64/tuning_models/neoversev3.h +++ b/gcc/config/aarch64/tuning_models/neoversev3.h @@ -220,7 +220,8 @@ static const struct tune_params neoversev3_tunings = (AARCH64_EXTRA_TUNE_BASE | AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT - | AARCH64_EXTRA_TUNE_AVOID_PRED_RMW), /* tune_flags. */ + | AARCH64_EXTRA_TUNE_AVOID_PRED_RMW + | AARCH64_EXTRA_TUNE_AVOID_LDAPUR), /* tune_flags. */ &generic_armv9a_prefetch_tune, AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */ diff --git a/gcc/config/aarch64/tuning_models/neoversev3ae.h b/gcc/config/aarch64/tuning_models/neoversev3ae.h index a0adef00824d..5796e52a2667 100644 --- a/gcc/config/aarch64/tuning_models/neoversev3ae.h +++ b/gcc/config/aarch64/tuning_models/neoversev3ae.h @@ -220,7 +220,8 @@ static const struct tune_params neoversev3ae_tunings = (AARCH64_EXTRA_TUNE_BASE | AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT - | AARCH64_EXTRA_TUNE_AVOID_PRED_RMW), /* tune_flags. */ + | AARCH64_EXTRA_TUNE_AVOID_PRED_RMW + | AARCH64_EXTRA_TUNE_AVOID_LDAPUR), /* tune_flags. */ &generic_armv9a_prefetch_tune, AARCH64_LDP_STP_POLICY_ALWAYS, /* ldp_policy_model. */ AARCH64_LDP_STP_POLICY_ALWAYS /* stp_policy_model. */ diff --git a/gcc/config/arc/arc-modes.def b/gcc/config/arc/arc-modes.def index cab46d7ce9c6..7c7dff9146a5 100644 --- a/gcc/config/arc/arc-modes.def +++ b/gcc/config/arc/arc-modes.def @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see CC_MODE (CC_ZN); CC_MODE (CC_Z); +CC_MODE (CC_V); CC_MODE (CC_C); CC_MODE (CC_FP_GT); CC_MODE (CC_FP_GE); diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h index cd82aa1ef5e5..2db643cea08c 100644 --- a/gcc/config/arc/arc-protos.h +++ b/gcc/config/arc/arc-protos.h @@ -55,6 +55,7 @@ extern bool arc_check_mov_const (HOST_WIDE_INT ); extern bool arc_split_mov_const (rtx *); extern bool arc_can_use_return_insn (void); extern bool arc_split_move_p (rtx *); +extern void arc_gen_unlikely_cbranch (enum rtx_code, machine_mode, rtx); #endif /* RTX_CODE */ diff --git a/gcc/config/arc/arc.cc b/gcc/config/arc/arc.cc index 78ba814d223a..bb5db977c800 100644 --- a/gcc/config/arc/arc.cc +++ b/gcc/config/arc/arc.cc @@ -1436,6 +1436,13 @@ get_arc_condition_code (rtx comparison) case GEU : return ARC_CC_NC; default : gcc_unreachable (); } + case E_CC_Vmode: + switch (GET_CODE (comparison)) + { + case EQ : return ARC_CC_NV; + case NE : return ARC_CC_V; + default : gcc_unreachable (); + } case E_CC_FP_GTmode: if (TARGET_ARGONAUT_SET && TARGET_SPFP) switch (GET_CODE (comparison)) @@ -1546,6 +1553,13 @@ arc_select_cc_mode (enum rtx_code op, rtx x, rtx y) machine_mode mode = GET_MODE (x); rtx x1; + /* Matches all instructions which can do .f and clobbers only Z flag. */ + if (GET_MODE_CLASS (mode) == MODE_INT + && y == const0_rtx + && GET_CODE (x) == MULT + && (op == EQ || op == NE)) + return CC_Zmode; + /* For an operation that sets the condition codes as a side-effect, the C and V flags is not set as for cmp, so we can only use comparisons where this doesn't matter. (For LT and GE we can use "mi" and "pl" @@ -11543,6 +11557,21 @@ arc_libm_function_max_error (unsigned cfn, machine_mode mode, return default_libm_function_max_error (cfn, mode, boundary_p); } +void +arc_gen_unlikely_cbranch (enum rtx_code cmp, machine_mode cc_mode, rtx label) +{ + rtx cc_reg, x; + + cc_reg = gen_rtx_REG (cc_mode, CC_REG); + label = gen_rtx_LABEL_REF (VOIDmode, label); + + x = gen_rtx_fmt_ee (cmp, VOIDmode, cc_reg, const0_rtx); + x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, label, pc_rtx); + + emit_unlikely_jump (gen_rtx_SET (pc_rtx, x)); +} + + #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index 1344d9c68b02..d119464176b8 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -842,6 +842,9 @@ archs4x, archs4xd" ; Optab prefix for sign/zero-extending operations (define_code_attr su_optab [(sign_extend "") (zero_extend "u")]) +;; Code iterator for sign/zero extension +(define_code_iterator ANY_EXTEND [sign_extend zero_extend]) + (define_insn "*<SEZ_prefix>xt<SQH_postfix>_cmp0_noout" [(set (match_operand 0 "cc_set_register" "") (compare:CC_ZN (SEZ:SI (match_operand:SQH 1 "register_operand" "r")) @@ -1068,11 +1071,67 @@ archs4x, archs4xd" (set_attr "cond" "set_zn") (set_attr "length" "*,4,4,4,8")]) -;; The next two patterns are for plos, ior, xor, and, and mult. +(define_expand "<su_optab>mulvsi4" + [(ANY_EXTEND:DI (match_operand:SI 0 "register_operand")) + (ANY_EXTEND:DI (match_operand:SI 1 "register_operand")) + (ANY_EXTEND:DI (match_operand:SI 2 "register_operand")) + (label_ref (match_operand 3 "" ""))] + "TARGET_MPY" + { + emit_insn (gen_<su_optab>mulsi3_Vcmp (operands[0], operands[1], + operands[2])); + arc_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); + DONE; + }) + +(define_insn "<su_optab>mulsi3_Vcmp" + [(parallel + [(set + (reg:CC_V CC_REG) + (compare:CC_V + (mult:DI + (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "%0,r,r,r")) + (ANY_EXTEND:DI (match_operand:SI 2 "nonmemory_operand" "I,L,r,C32"))) + (ANY_EXTEND:DI (mult:SI (match_dup 1) (match_dup 2))))) + (set (match_operand:SI 0 "register_operand" "=r,r,r,r") + (mult:SI (match_dup 1) (match_dup 2)))])] + "register_operand (operands[1], SImode) + || register_operand (operands[2], SImode)" + "mpy<su_optab>.f\\t%0,%1,%2" + [(set_attr "length" "4,4,4,8") + (set_attr "type" "multi")]) + +(define_insn "*mulsi3_cmp0" + [(set (reg:CC_Z CC_REG) + (compare:CC_Z + (mult:SI + (match_operand:SI 1 "register_operand" "%r,0,r") + (match_operand:SI 2 "nonmemory_operand" "rL,I,i")) + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=r,r,r") + (mult:SI (match_dup 1) (match_dup 2)))] + "TARGET_MPY" + "mpy%?.f\\t%0,%1,%2" + [(set_attr "length" "4,4,8") + (set_attr "type" "multi")]) + +(define_insn "*mulsi3_cmp0_noout" + [(set (reg:CC_Z CC_REG) + (compare:CC_Z + (mult:SI + (match_operand:SI 0 "register_operand" "%r,r,r") + (match_operand:SI 1 "nonmemory_operand" "rL,I,i")) + (const_int 0)))] + "TARGET_MPY" + "mpy%?.f\\t0,%0,%1" + [(set_attr "length" "4,4,8") + (set_attr "type" "multi")]) + +;; The next two patterns are for plus, ior, xor, and. (define_insn "*commutative_binary_cmp0_noout" [(set (match_operand 0 "cc_set_register" "") (match_operator 4 "zn_compare_operator" - [(match_operator:SI 3 "commutative_operator" + [(match_operator:SI 3 "commutative_operator_sans_mult" [(match_operand:SI 1 "register_operand" "%r,r") (match_operand:SI 2 "nonmemory_operand" "rL,Cal")]) (const_int 0)]))] @@ -1085,7 +1144,7 @@ archs4x, archs4xd" (define_insn "*commutative_binary_cmp0" [(set (match_operand 3 "cc_set_register" "") (match_operator 5 "zn_compare_operator" - [(match_operator:SI 4 "commutative_operator" + [(match_operator:SI 4 "commutative_operator_sans_mult" [(match_operand:SI 1 "register_operand" "%0, 0,r,r") (match_operand:SI 2 "nonmemory_operand" "rL,rI,r,Cal")]) (const_int 0)])) @@ -2734,6 +2793,56 @@ archs4x, archs4xd" } [(set_attr "length" "8")]) +(define_insn "addsi3_v" + [(set (match_operand:SI 0 "register_operand" "=r,r,r, r") + (plus:SI (match_operand:SI 1 "register_operand" "r,r,0, r") + (match_operand:SI 2 "nonmemory_operand" "r,L,I,C32"))) + (set (reg:CC_V CC_REG) + (compare:CC_V (sign_extend:DI (plus:SI (match_dup 1) + (match_dup 2))) + (plus:DI (sign_extend:DI (match_dup 1)) + (sign_extend:DI (match_dup 2)))))] + "" + "add.f\\t%0,%1,%2" + [(set_attr "cond" "set") + (set_attr "type" "compare") + (set_attr "length" "4,4,4,8")]) + +(define_expand "addvsi4" + [(match_operand:SI 0 "register_operand") + (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "nonmemory_operand") + (label_ref (match_operand 3 "" ""))] + "" + "emit_insn (gen_addsi3_v (operands[0], operands[1], operands[2])); + arc_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); + DONE;") + +(define_insn "addsi3_c" + [(set (match_operand:SI 0 "register_operand" "=r,r,r, r") + (plus:SI (match_operand:SI 1 "register_operand" "r,r,0, r") + (match_operand:SI 2 "nonmemory_operand" "r,L,I,C32"))) + (set (reg:CC_C CC_REG) + (compare:CC_C (plus:SI (match_dup 1) + (match_dup 2)) + (match_dup 1)))] + "" + "add.f\\t%0,%1,%2" + [(set_attr "cond" "set") + (set_attr "type" "compare") + (set_attr "length" "4,4,4,8")]) + +(define_expand "uaddvsi4" + [(match_operand:SI 0 "register_operand") + (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "nonmemory_operand") + (label_ref (match_operand 3 "" ""))] + "" + "emit_insn (gen_addsi3_c (operands[0], operands[1], operands[2])); + arc_gen_unlikely_cbranch (LTU, CC_Cmode, operands[3]); + DONE;") + + (define_insn "add_f" [(set (reg:CC_C CC_REG) (compare:CC_C @@ -2914,6 +3023,54 @@ archs4x, archs4xd" (set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*") ]) +(define_insn "subsi3_v" + [(set (match_operand:SI 0 "register_operand" "=r,r,r, r") + (minus:SI (match_operand:SI 1 "register_operand" "r,r,0, r") + (match_operand:SI 2 "nonmemory_operand" "r,L,I,C32"))) + (set (reg:CC_V CC_REG) + (compare:CC_V (sign_extend:DI (minus:SI (match_dup 1) + (match_dup 2))) + (minus:DI (sign_extend:DI (match_dup 1)) + (sign_extend:DI (match_dup 2)))))] + "" + "sub.f\\t%0,%1,%2" + [(set_attr "cond" "set") + (set_attr "type" "compare") + (set_attr "length" "4,4,4,8")]) + +(define_expand "subvsi4" + [(match_operand:SI 0 "register_operand") + (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "nonmemory_operand") + (label_ref (match_operand 3 "" ""))] + "" + "emit_insn (gen_subsi3_v (operands[0], operands[1], operands[2])); + arc_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); + DONE;") + +(define_insn "subsi3_c" + [(set (match_operand:SI 0 "register_operand" "=r,r,r, r") + (minus:SI (match_operand:SI 1 "register_operand" "r,r,0, r") + (match_operand:SI 2 "nonmemory_operand" "r,L,I,C32"))) + (set (reg:CC_C CC_REG) + (compare:CC_C (match_dup 1) + (match_dup 2)))] + "" + "sub.f\\t%0,%1,%2" + [(set_attr "cond" "set") + (set_attr "type" "compare") + (set_attr "length" "4,4,4,8")]) + +(define_expand "usubvsi4" + [(match_operand:SI 0 "register_operand") + (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "nonmemory_operand") + (label_ref (match_operand 3 "" ""))] + "" + "emit_insn (gen_subsi3_c (operands[0], operands[1], operands[2])); + arc_gen_unlikely_cbranch (LTU, CC_Cmode, operands[3]); + DONE;") + (define_expand "subdi3" [(set (match_operand:DI 0 "register_operand" "") (minus:DI (match_operand:DI 1 "register_operand" "") diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md index 209cda908054..f506cee8baf7 100644 --- a/gcc/config/arc/predicates.md +++ b/gcc/config/arc/predicates.md @@ -419,6 +419,8 @@ return code == EQ || code == NE; case E_CC_Cmode: return code == LTU || code == GEU; + case E_CC_Vmode: + return code == EQ || code == NE; case E_CC_FP_GTmode: return code == GT || code == UNLE; case E_CC_FP_GEmode: @@ -451,7 +453,12 @@ }) (define_predicate "equality_comparison_operator" - (match_code "eq, ne")) + (match_code "eq, ne") + { + machine_mode opmode = GET_MODE (XEXP (op, 0)); + return opmode != CC_Vmode; + } +) (define_predicate "ge_lt_comparison_operator" (match_code "ge, lt")) diff --git a/gcc/config/arm/aarch-cost-tables.h b/gcc/config/arm/aarch-cost-tables.h index c7a14b3750d8..0600e590089b 100644 --- a/gcc/config/arm/aarch-cost-tables.h +++ b/gcc/config/arm/aarch-cost-tables.h @@ -123,9 +123,9 @@ const struct cpu_cost_table generic_extra_costs = { COSTS_N_INSNS (1), /* alu. */ COSTS_N_INSNS (4), /* mult. */ - COSTS_N_INSNS (1), /* movi. */ - COSTS_N_INSNS (2), /* dup. */ - COSTS_N_INSNS (2) /* extract. */ + COSTS_N_INSNS (0), /* movi. */ + COSTS_N_INSNS (1), /* dup. */ + COSTS_N_INSNS (1) /* extract. */ } }; @@ -230,9 +230,9 @@ const struct cpu_cost_table cortexa53_extra_costs = { COSTS_N_INSNS (1), /* alu. */ COSTS_N_INSNS (4), /* mult. */ - COSTS_N_INSNS (1), /* movi. */ - COSTS_N_INSNS (2), /* dup. */ - COSTS_N_INSNS (2) /* extract. */ + COSTS_N_INSNS (0), /* movi. */ + COSTS_N_INSNS (1), /* dup. */ + COSTS_N_INSNS (1) /* extract. */ } }; @@ -337,9 +337,9 @@ const struct cpu_cost_table cortexa57_extra_costs = { COSTS_N_INSNS (1), /* alu. */ COSTS_N_INSNS (4), /* mult. */ - COSTS_N_INSNS (1), /* movi. */ - COSTS_N_INSNS (2), /* dup. */ - COSTS_N_INSNS (2) /* extract. */ + COSTS_N_INSNS (0), /* movi. */ + COSTS_N_INSNS (1), /* dup. */ + COSTS_N_INSNS (1) /* extract. */ } }; @@ -444,9 +444,9 @@ const struct cpu_cost_table cortexa76_extra_costs = { COSTS_N_INSNS (1), /* alu. */ COSTS_N_INSNS (4), /* mult. */ - COSTS_N_INSNS (1), /* movi. */ - COSTS_N_INSNS (2), /* dup. */ - COSTS_N_INSNS (2) /* extract. */ + COSTS_N_INSNS (0), /* movi. */ + COSTS_N_INSNS (1), /* dup. */ + COSTS_N_INSNS (1) /* extract. */ } }; @@ -551,9 +551,9 @@ const struct cpu_cost_table exynosm1_extra_costs = { COSTS_N_INSNS (0), /* alu. */ COSTS_N_INSNS (4), /* mult. */ - COSTS_N_INSNS (1), /* movi. */ - COSTS_N_INSNS (2), /* dup. */ - COSTS_N_INSNS (2) /* extract. */ + COSTS_N_INSNS (0), /* movi. */ + COSTS_N_INSNS (1), /* dup. */ + COSTS_N_INSNS (1) /* extract. */ } }; @@ -658,9 +658,9 @@ const struct cpu_cost_table xgene1_extra_costs = { COSTS_N_INSNS (2), /* alu. */ COSTS_N_INSNS (8), /* mult. */ - COSTS_N_INSNS (1), /* movi. */ - COSTS_N_INSNS (2), /* dup. */ - COSTS_N_INSNS (2) /* extract. */ + COSTS_N_INSNS (0), /* movi. */ + COSTS_N_INSNS (1), /* dup. */ + COSTS_N_INSNS (1) /* extract. */ } }; diff --git a/gcc/config/arm/arm_neon.h b/gcc/config/arm/arm_neon.h index cba50de07204..105385f7f5de 100644 --- a/gcc/config/arm/arm_neon.h +++ b/gcc/config/arm/arm_neon.h @@ -20938,11 +20938,6 @@ vbfdotq_lane_f32 (float32x4_t __r, bfloat16x8_t __a, bfloat16x4_t __b, return __builtin_neon_vbfdot_lanev4bfv4sf (__r, __a, __b, __index); } -#pragma GCC pop_options - -#pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+bf16") - typedef struct bfloat16x4x2_t { bfloat16x4_t val[2]; diff --git a/gcc/config/avr/avr-mcus.def b/gcc/config/avr/avr-mcus.def index ad640501541f..2e7c8ac736e8 100644 --- a/gcc/config/avr/avr-mcus.def +++ b/gcc/config/avr/avr-mcus.def @@ -313,6 +313,10 @@ AVR_MCU ("avr64da28", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR AVR_MCU ("avr64da32", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DA32__", 0x6000, 0x0, 0x10000, 0) AVR_MCU ("avr64da48", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DA48__", 0x6000, 0x0, 0x10000, 0) AVR_MCU ("avr64da64", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DA64__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64da28s", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DA28S__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64da32s", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DA32S__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64da48s", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DA48S__", 0x6000, 0x0, 0x10000, 0) +AVR_MCU ("avr64da64s", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DA64S__", 0x6000, 0x0, 0x10000, 0) AVR_MCU ("avr64db28", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DB28__", 0x6000, 0x0, 0x10000, 0) AVR_MCU ("avr64db32", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DB32__", 0x6000, 0x0, 0x10000, 0) AVR_MCU ("avr64db48", ARCH_AVRXMEGA2, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR64DB48__", 0x6000, 0x0, 0x10000, 0) @@ -389,6 +393,9 @@ AVR_MCU ("avr16du32", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR AVR_MCU ("avr32da28", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DA28__", 0x7000, 0x0, 0x8000, 0x8000) AVR_MCU ("avr32da32", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DA32__", 0x7000, 0x0, 0x8000, 0x8000) AVR_MCU ("avr32da48", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DA48__", 0x7000, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr32da28s", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DA28S__", 0x7000, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr32da32s", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DA32S__", 0x7000, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr32da48s", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DA48S__", 0x7000, 0x0, 0x8000, 0x8000) AVR_MCU ("avr32db28", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DB28__", 0x7000, 0x0, 0x8000, 0x8000) AVR_MCU ("avr32db32", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DB32__", 0x7000, 0x0, 0x8000, 0x8000) AVR_MCU ("avr32db48", ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32DB48__", 0x7000, 0x0, 0x8000, 0x8000) @@ -427,6 +434,10 @@ AVR_MCU ("avr128da28", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR AVR_MCU ("avr128da32", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DA32__", 0x4000, 0x0, 0x20000, 0) AVR_MCU ("avr128da48", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DA48__", 0x4000, 0x0, 0x20000, 0) AVR_MCU ("avr128da64", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DA64__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128da28s", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DA28S__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128da32s", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DA32S__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128da48s", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DA48S__", 0x4000, 0x0, 0x20000, 0) +AVR_MCU ("avr128da64s", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DA64S__", 0x4000, 0x0, 0x20000, 0) AVR_MCU ("avr128db28", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DB28__", 0x4000, 0x0, 0x20000, 0) AVR_MCU ("avr128db32", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DB32__", 0x4000, 0x0, 0x20000, 0) AVR_MCU ("avr128db48", ARCH_AVRXMEGA4, AVR_CVT | AVR_ISA_FLMAP, "__AVR_AVR128DB48__", 0x4000, 0x0, 0x20000, 0) diff --git a/gcc/config/avr/avr-passes.cc b/gcc/config/avr/avr-passes.cc index 284f49d14680..6a88a2740bc5 100644 --- a/gcc/config/avr/avr-passes.cc +++ b/gcc/config/avr/avr-passes.cc @@ -4120,9 +4120,8 @@ avr_optimize_casesi (rtx_insn *insns[5], rtx *xop) JUMP_LABEL (cbranch) = xop[4]; ++LABEL_NUSES (xop[4]); - rtx_insn *seq1 = get_insns (); rtx_insn *last1 = get_last_insn (); - end_sequence (); + rtx_insn *seq1 = end_sequence (); emit_insn_after (seq1, insns[2]); @@ -4141,9 +4140,8 @@ avr_optimize_casesi (rtx_insn *insns[5], rtx *xop) emit_insn (pat_4); - rtx_insn *seq2 = get_insns (); rtx_insn *last2 = get_last_insn (); - end_sequence (); + rtx_insn *seq2 = end_sequence (); emit_insn_after (seq2, insns[3]); diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index f651692536b1..c469297d6d09 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -14148,7 +14148,7 @@ avr_hard_regno_mode_ok (unsigned int regno, machine_mode mode) address registers is extreme stress test for reload. */ if (GET_MODE_SIZE (mode) >= 4 - && regno >= REG_X + && regno + GET_MODE_SIZE (mode) >= REG_30 // This problem only concerned the old reload. && ! avropt_lra_p) return false; diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 01b8e4bce4cf..f8bbdc766085 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -5273,6 +5273,41 @@ ;;<< << << << << << << << << << << << << << << << << << << << << << << << << << ;; arithmetic shift left +;; Work around PR120423: Transform left shift of a paradoxical subreg +;; into left shift of the zero-extended entity. +(define_split ; PR120423 + [(set (match_operand:HISI 0 "register_operand") + (ashift:HISI (subreg:HISI (match_operand:QIPSI 1 "nonimmediate_operand") + 0) + (match_operand:QI 2 "const_int_operand")))] + "!reload_completed + && !avropt_lra_p + && <HISI:SIZE> > <QIPSI:SIZE>" + [(set (match_dup 4) + (zero_extend:HISI (match_dup 5))) + (set (match_dup 0) + (ashift:HISI (match_dup 4) + (match_dup 2)))] + { + operands[4] = gen_reg_rtx (<HISI:MODE>mode); + operands[5] = force_reg (<QIPSI:MODE>mode, operands[1]); + }) + +;; Similar happens for PR116389. +(define_split ; PR116389 + [(set (match_operand:HISI 0 "register_operand") + (subreg:HISI (match_operand:QIPSI 1 "nonimmediate_operand") + 0))] + "!reload_completed + && !avropt_lra_p + && <HISI:SIZE> > <QIPSI:SIZE>" + [(set (match_dup 0) + (zero_extend:HISI (match_dup 2)))] + { + operands[2] = force_reg (<QIPSI:MODE>mode, operands[1]); + }) + + ;; "ashlqi3" ;; "ashlqq3" "ashluqq3" (define_expand "ashl<mode>3" diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt index fcd2bf68f2a8..988311927bda 100644 --- a/gcc/config/avr/avr.opt +++ b/gcc/config/avr/avr.opt @@ -19,8 +19,8 @@ ; <http://www.gnu.org/licenses/>. mlra -Target Var(avropt_lra_p) UInteger Init(0) Optimization Undocumented -Usa LRA for reload instead of the old reload framework. This option is experimental, and it may be removed in future versions of the compiler. +Target Var(avropt_lra_p) UInteger Init(1) Optimization Undocumented +Usa LRA for reload instead of the old reload framework. This option is experimental, on per default, and it may be removed in future versions of the compiler. mcall-prologues Target Mask(CALL_PROLOGUES) Optimization diff --git a/gcc/config/cris/cris.cc b/gcc/config/cris/cris.cc index a34c9e9743ce..4acdd1dee7d5 100644 --- a/gcc/config/cris/cris.cc +++ b/gcc/config/cris/cris.cc @@ -3711,9 +3711,11 @@ cris_md_asm_adjust (vec<rtx> &outputs, vec<rtx> &inputs, /* Determine if the source using MOF. If it is, automatically clobbering MOF would cause it to have impossible constraints. */ - /* Look for a use of the MOF constraint letter: h. */ + /* Look for a use of the MOF constraint letter h or a hard register + constraint. */ for (unsigned i = 0, n = constraints.length(); i < n; ++i) - if (strchr (constraints[i], 'h') != NULL) + if (strchr (constraints[i], 'h') != NULL + || strstr (constraints[i], "{mof}") != NULL) return NULL; /* Look for an output or an input that touches MOF. */ diff --git a/gcc/config/darwin-driver.cc b/gcc/config/darwin-driver.cc index 224e0a0de700..e83b7cdc0c95 100644 --- a/gcc/config/darwin-driver.cc +++ b/gcc/config/darwin-driver.cc @@ -64,7 +64,8 @@ validate_macosx_version_min (const char *version_str) major = strtoul (version_str, &end, 10); - /* macOS 10, 11, and 12 are known. clang accepts up to 99. */ + /* macOS 10, 11, 12, 13, 14, 15 and 26 are known. + clang accepts up to 99. */ if (major < 10 || major > 99) return NULL; @@ -159,15 +160,16 @@ darwin_find_version_from_kernel (void) if (*version_p++ != '.') goto parse_failed; - /* Darwin20 sees a transition to macOS 11. In this, it seems that the - mapping to macOS minor version and patch level is now always 0, 0 - (at least for macOS 11 and 12). */ - if (major_vers >= 20) - { - /* Apple clang doesn't include the minor version or the patch level - in the object file, nor does it pass it to ld */ - asprintf (&new_flag, "%d.00.00", major_vers - 9); - } + /* Darwin25 saw a transition to macOS 26. */ + if (major_vers >= 25) + /* Apple clang doesn't include the minor version or the patch level + in the object file, nor does it pass it to ld */ + asprintf (&new_flag, "%d.00.00", major_vers + 1); + /* Darwin20 saw a transition to macOS 11. */ + else if (major_vers >= 20) + /* Apple clang doesn't include the minor version or the patch level + in the object file, nor does it pass it to ld */ + asprintf (&new_flag, "%d.00.00", major_vers - 9); else if (major_vers - 4 <= 4) /* On 10.4 and earlier, the old linker is used which does not support three-component system versions. diff --git a/gcc/config/gcn/gcn-devices.def b/gcc/config/gcn/gcn-devices.def index af1420382e2f..426acf0cb7a5 100644 --- a/gcc/config/gcn/gcn-devices.def +++ b/gcc/config/gcn/gcn-devices.def @@ -171,6 +171,28 @@ GCN_DEVICE(gfx90c, GFX90C, 0x32, ISA_GCN5, /* Generic Name */ GFX9_GENERIC ) +GCN_DEVICE(gfx942, GFX942, 0x4c, ISA_CDNA3, + /* XNACK default */ HSACO_ATTR_ANY, + /* SRAM_ECC default */ HSACO_ATTR_ANY, + /* WAVE64 mode */ HSACO_ATTR_UNSUPPORTED, + /* CU mode */ HSACO_ATTR_UNSUPPORTED, + /* Max ISA VGPRs */ 512, + /* Generic code obj version */ 0, /* non-generic */ + /* Architecture Family */ GFX9, + /* Generic Name */ NONE + ) + +GCN_DEVICE(gfx950, GFX950, 0x4f, ISA_CDNA3, + /* XNACK default */ HSACO_ATTR_ANY, + /* SRAM_ECC default */ HSACO_ATTR_ANY, + /* WAVE64 mode */ HSACO_ATTR_UNSUPPORTED, + /* CU mode */ HSACO_ATTR_UNSUPPORTED, + /* Max ISA VGPRs */ 512, + /* Generic code obj version */ 0, /* non-generic */ + /* Architecture Family */ GFX9, + /* Generic Name */ NONE + ) + GCN_DEVICE(gfx9-generic, GFX9_GENERIC, 0x051, ISA_GCN5, /* XNACK default */ HSACO_ATTR_ANY, /* SRAM_ECC default */ HSACO_ATTR_UNSUPPORTED, @@ -182,6 +204,17 @@ GCN_DEVICE(gfx9-generic, GFX9_GENERIC, 0x051, ISA_GCN5, /* Generic Name */ NONE ) +GCN_DEVICE(gfx9-4-generic, GFX9_4_GENERIC, 0x05f, ISA_CDNA3, + /* XNACK default */ HSACO_ATTR_ANY, + /* SRAM_ECC default */ HSACO_ATTR_UNSUPPORTED, + /* WAVE64 mode */ HSACO_ATTR_UNSUPPORTED, + /* CU mode */ HSACO_ATTR_UNSUPPORTED, + /* Max ISA VGPRs */ 256, + /* Generic code obj version */ 1, + /* Architecture Family */ GFX9, + /* Generic Name */ NONE + ) + /* GCN GFX10.3 (RDNA 2) */ GCN_DEVICE(gfx1030, GFX1030, 0x36, ISA_RDNA2, diff --git a/gcc/config/gcn/gcn-opts.h b/gcc/config/gcn/gcn-opts.h index 88f562dfc1e1..0bfc7869eefe 100644 --- a/gcc/config/gcn/gcn-opts.h +++ b/gcc/config/gcn/gcn-opts.h @@ -33,7 +33,8 @@ extern enum gcn_isa { ISA_RDNA2, ISA_RDNA3, ISA_CDNA1, - ISA_CDNA2 + ISA_CDNA2, + ISA_CDNA3 } gcn_isa; #define TARGET_GCN5 (gcn_isa == ISA_GCN5) @@ -41,6 +42,8 @@ extern enum gcn_isa { #define TARGET_CDNA1_PLUS (gcn_isa >= ISA_CDNA1) #define TARGET_CDNA2 (gcn_isa == ISA_CDNA2) #define TARGET_CDNA2_PLUS (gcn_isa >= ISA_CDNA2) +#define TARGET_CDNA3 (gcn_isa == ISA_CDNA3) +#define TARGET_CDNA3_PLUS (gcn_isa >= ISA_CDNA3) #define TARGET_RDNA2 (gcn_isa == ISA_RDNA2) #define TARGET_RDNA2_PLUS (gcn_isa >= ISA_RDNA2 && gcn_isa < ISA_CDNA1) #define TARGET_RDNA3 (gcn_isa == ISA_RDNA3) @@ -81,18 +84,25 @@ enum hsaco_attr_type #define TARGET_DPP8 TARGET_RDNA2_PLUS /* Device requires CDNA1-style manually inserted wait states for AVGPRs. */ #define TARGET_AVGPR_CDNA1_NOPS TARGET_CDNA1 +/* Whether to use the 'globally coherent' (glc) or the 'scope' (sc0) flag + for non-scalar memory operations. The string starts on purpose with a space. + Note: for scalar memory operations (i.e. 's_...'), 'glc' is still used. + CDNA3 also uses 'nt' instead of 'slc' and 'sc1' instead of 'scc'; however, + there is no non-scalar user so far. */ +#define TARGET_GLC_NAME (TARGET_CDNA3 ? " sc0" : " glc") /* The metadata on different devices need different granularity. */ #define TARGET_VGPR_GRANULARITY \ (TARGET_RDNA3 ? 12 \ : TARGET_RDNA2_PLUS || TARGET_CDNA2_PLUS ? 8 \ : 4) /* This mostly affects the metadata. */ -#define TARGET_ARCHITECTED_FLAT_SCRATCH TARGET_RDNA3 +#define TARGET_ARCHITECTED_FLAT_SCRATCH (TARGET_RDNA3 || TARGET_CDNA3) /* Device has Sub-DWord Addressing instrucions. */ #define TARGET_SDWA (!TARGET_RDNA3) /* Different devices uses different cache control instructions. */ -#define TARGET_WBINVL1_CACHE (!TARGET_RDNA2_PLUS) +#define TARGET_WBINVL1_CACHE (!TARGET_RDNA2_PLUS && !TARGET_CDNA3) #define TARGET_GLn_CACHE TARGET_RDNA2_PLUS +#define TARGET_TARGET_SC_CACHE TARGET_CDNA3 /* Some devices have TGSPLIT, which needs at least metadata. */ #define TARGET_TGSPLIT TARGET_CDNA2_PLUS diff --git a/gcc/config/gcn/gcn-tables.opt b/gcc/config/gcn/gcn-tables.opt index 96ce9bd2df33..4a381b33b515 100644 --- a/gcc/config/gcn/gcn-tables.opt +++ b/gcc/config/gcn/gcn-tables.opt @@ -48,9 +48,18 @@ Enum(gpu_type) String(gfx90a) Value(PROCESSOR_GFX90A) EnumValue Enum(gpu_type) String(gfx90c) Value(PROCESSOR_GFX90C) +EnumValue +Enum(gpu_type) String(gfx942) Value(PROCESSOR_GFX942) + +EnumValue +Enum(gpu_type) String(gfx950) Value(PROCESSOR_GFX950) + EnumValue Enum(gpu_type) String(gfx9-generic) Value(PROCESSOR_GFX9_GENERIC) +EnumValue +Enum(gpu_type) String(gfx9-4-generic) Value(PROCESSOR_GFX9_4_GENERIC) + EnumValue Enum(gpu_type) String(gfx1030) Value(PROCESSOR_GFX1030) diff --git a/gcc/config/gcn/gcn-valu.md b/gcc/config/gcn/gcn-valu.md index 977ad886ef20..3899117f2719 100644 --- a/gcc/config/gcn/gcn-valu.md +++ b/gcc/config/gcn/gcn-valu.md @@ -1133,6 +1133,23 @@ DONE; }) +(define_expand "gather_load<mode><vndi>" + [(match_operand:V_MOV 0 "register_operand") + (match_operand:DI 1 "register_operand") + (match_operand:<VnDI> 2 "register_operand") + (match_operand 3 "immediate_operand") + (match_operand:SI 4 "gcn_alu_operand")] + "" + { + rtx addr = gcn_expand_scaled_offsets (DEFAULT_ADDR_SPACE, operands[1], + operands[2], operands[4], + INTVAL (operands[3]), NULL); + + emit_insn (gen_gather<mode>_insn_1offset (operands[0], addr, const0_rtx, + const0_rtx, const0_rtx)); + DONE; + }) + ; Allow any address expression (define_expand "gather<mode>_expr<exec>" [(set (match_operand:V_MOV 0 "register_operand") @@ -1161,7 +1178,7 @@ && (((unsigned HOST_WIDE_INT)INTVAL(operands[2]) + 0x1000) < 0x2000))" { addr_space_t as = INTVAL (operands[3]); - const char *glc = INTVAL (operands[4]) ? " glc" : ""; + const char *glc = INTVAL (operands[4]) ? TARGET_GLC_NAME : ""; static char buf[200]; if (AS_FLAT_P (as)) @@ -1221,7 +1238,7 @@ && (((unsigned HOST_WIDE_INT)INTVAL(operands[3]) + 0x1000) < 0x2000))" { addr_space_t as = INTVAL (operands[4]); - const char *glc = INTVAL (operands[5]) ? " glc" : ""; + const char *glc = INTVAL (operands[5]) ? TARGET_GLC_NAME : ""; static char buf[200]; if (AS_GLOBAL_P (as)) @@ -1259,6 +1276,23 @@ DONE; }) +(define_expand "scatter_store<mode><vndi>" + [(match_operand:DI 0 "register_operand") + (match_operand:<VnDI> 1 "register_operand") + (match_operand 2 "immediate_operand") + (match_operand:SI 3 "gcn_alu_operand") + (match_operand:V_MOV 4 "register_operand")] + "" + { + rtx addr = gcn_expand_scaled_offsets (DEFAULT_ADDR_SPACE, operands[0], + operands[1], operands[3], + INTVAL (operands[2]), NULL); + + emit_insn (gen_scatter<mode>_insn_1offset (addr, const0_rtx, operands[4], + const0_rtx, const0_rtx)); + DONE; + }) + ; Allow any address expression (define_expand "scatter<mode>_expr<exec_scatter>" [(set (mem:BLK (scratch)) @@ -1288,7 +1322,7 @@ && (((unsigned HOST_WIDE_INT)INTVAL(operands[1]) + 0x1000) < 0x2000))" { addr_space_t as = INTVAL (operands[3]); - const char *glc = INTVAL (operands[4]) ? " glc" : ""; + const char *glc = INTVAL (operands[4]) ? TARGET_GLC_NAME : ""; static char buf[200]; if (AS_FLAT_P (as)) @@ -1345,7 +1379,7 @@ && (((unsigned HOST_WIDE_INT)INTVAL(operands[2]) + 0x1000) < 0x2000))" { addr_space_t as = INTVAL (operands[4]); - const char *glc = INTVAL (operands[5]) ? " glc" : ""; + const char *glc = INTVAL (operands[5]) ? TARGET_GLC_NAME : ""; static char buf[200]; if (AS_GLOBAL_P (as)) @@ -1455,28 +1489,26 @@ ;; }}} ;; {{{ ALU special case: add/sub -(define_insn "add<mode>3<exec_clobber>" +(define_insn "add<mode>3<exec>" [(set (match_operand:V_INT_1REG 0 "register_operand") (plus:V_INT_1REG (match_operand:V_INT_1REG 1 "register_operand") - (match_operand:V_INT_1REG 2 "gcn_alu_operand"))) - (clobber (reg:DI VCC_REG))] + (match_operand:V_INT_1REG 2 "gcn_alu_operand")))] "" {@ [cons: =0, %1, 2; attrs: type, length] - [v,v,vSvA;vop2,4] v_add_co_u32\t%0, vcc, %2, %1 + [v,v,vSvA;vop2,4] {v_add_u32|v_add_nc_u32}\t%0, %2, %1 [v,v,vSvB;vop2,8] ^ }) -(define_insn "add<mode>3_dup<exec_clobber>" +(define_insn "add<mode>3_dup<exec>" [(set (match_operand:V_INT_1REG 0 "register_operand") (plus:V_INT_1REG (vec_duplicate:V_INT_1REG (match_operand:<SCALAR_MODE> 2 "gcn_alu_operand")) - (match_operand:V_INT_1REG 1 "register_operand"))) - (clobber (reg:DI VCC_REG))] + (match_operand:V_INT_1REG 1 "register_operand")))] "" {@ [cons: =0, 1, 2; attrs: type, length] - [v,v,SvA;vop2,4] v_add_co_u32\t%0, vcc, %2, %1 + [v,v,SvA;vop2,4] {v_add_u32|v_add_nc_u32}\t%0, %2, %1 [v,v,SvB;vop2,8] ^ }) @@ -1503,16 +1535,16 @@ (plus:V_SI (vec_duplicate:V_SI (match_operand:SI 1 "gcn_alu_operand")) - (match_operand:V_SI 2 "register_operand"))) + (match_operand:V_SI 2 "gcn_alu_operand"))) (set (match_operand:DI 3 "register_operand") - (ltu:DI (plus:V_SI (vec_duplicate:V_SI (match_dup 2)) - (match_dup 1)) - (vec_duplicate:V_SI (match_dup 2))))] + (ltu:DI (plus:V_SI (vec_duplicate:V_SI (match_dup 1)) + (match_dup 2)) + (match_dup 2)))] "" {@ [cons: =0, 1, 2, =3; attrs: type, length] - [v,SvA,v,cV;vop2 ,4] v_add_co_u32\t%0, %3, %1, %2 - [v,SvB,v,cV;vop2 ,8] ^ - [v,SvA,v,Sg;vop3b,8] ^ + [v,SvA,vA,cV;vop2 ,4] v_add_co_u32\t%0, %3, %1, %2 + [v,SvB,vA,cV;vop2 ,8] ^ + [v,SvA,vA,Sg;vop3b,8] ^ }) ; v_addc does not accept an SGPR because the VCC read already counts as an @@ -1551,16 +1583,15 @@ [(set_attr "type" "vop2,vop3b") (set_attr "length" "4,8")]) -(define_insn "sub<mode>3<exec_clobber>" +(define_insn "sub<mode>3<exec>" [(set (match_operand:V_INT_1REG 0 "register_operand" "= v, v") (minus:V_INT_1REG (match_operand:V_INT_1REG 1 "gcn_alu_operand" "vSvB, v") - (match_operand:V_INT_1REG 2 "gcn_alu_operand" " v,vSvB"))) - (clobber (reg:DI VCC_REG))] + (match_operand:V_INT_1REG 2 "gcn_alu_operand" " v,vSvB")))] "" "@ - v_sub_co_u32\t%0, vcc, %1, %2 - v_subrev_co_u32\t%0, vcc, %2, %1" + {v_sub_u32|v_sub_nc_u32}\t%0, %1, %2 + {v_subrev_u32|v_subrev_nc_u32}\t%0, %2, %1" [(set_attr "type" "vop2") (set_attr "length" "8,8")]) @@ -1648,6 +1679,39 @@ [(set_attr "type" "vmult") (set_attr "length" "8")]) +(define_insn_and_split "add<mode>3_dup" + [(set (match_operand:V_DI 0 "register_operand" "= v") + (plus:V_DI + (vec_duplicate:V_DI + (match_operand:DI 1 "register_operand" "SvB")) + (match_operand:V_DI 2 "gcn_alu_operand" "vDb"))) + (clobber (reg:DI VCC_REG)) + (clobber (match_scratch:<VnSI> 3 "=&v"))] + "" + "#" + "gcn_can_split_p (<MODE>mode, operands[0]) + && gcn_can_split_p (<MODE>mode, operands[1]) + && gcn_can_split_p (<MODE>mode, operands[2])" + [(const_int 0)] + { + rtx vcc = gen_rtx_REG (DImode, VCC_REG); + emit_insn (gen_add<vnsi>3_vcc_dup + (gcn_operand_part (<MODE>mode, operands[0], 0), + gcn_operand_part (DImode, operands[1], 0), + gcn_operand_part (<MODE>mode, operands[2], 0), + vcc)); + emit_insn (gen_vec_duplicate<vnsi> (operands[3], + gcn_operand_part (DImode, operands[1], 1))); + emit_insn (gen_addc<vnsi>3 + (gcn_operand_part (<MODE>mode, operands[0], 1), + operands[3], + gcn_operand_part (<MODE>mode, operands[2], 1), + vcc, vcc)); + DONE; + } + [(set_attr "type" "vmult") + (set_attr "length" "8")]) + (define_insn_and_split "add<mode>3_exec" [(set (match_operand:V_DI 0 "register_operand" "= v") (vec_merge:V_DI @@ -1685,6 +1749,49 @@ [(set_attr "type" "vmult") (set_attr "length" "8")]) +(define_insn_and_split "add<mode>3_dup_exec" + [(set (match_operand:V_DI 0 "register_operand" "= v") + (vec_merge:V_DI + (plus:V_DI + (vec_duplicate:V_DI + (match_operand:DI 1 "register_operand" "SvB")) + (match_operand:V_DI 2 "gcn_alu_operand" "vDb")) + (match_operand:V_DI 3 "gcn_register_or_unspec_operand" " U0") + (match_operand:DI 4 "gcn_exec_reg_operand" " e"))) + (clobber (reg:DI VCC_REG)) + (clobber (match_scratch:<VnSI> 5 "=&v"))] + "" + "#" + "gcn_can_split_p (<MODE>mode, operands[0]) + && gcn_can_split_p (<MODE>mode, operands[1]) + && gcn_can_split_p (<MODE>mode, operands[2]) + && gcn_can_split_p (<MODE>mode, operands[4])" + [(const_int 0)] + { + rtx vcc = gen_rtx_REG (DImode, VCC_REG); + emit_insn (gen_add<vnsi>3_vcc_dup_exec + (gcn_operand_part (<MODE>mode, operands[0], 0), + gcn_operand_part (DImode, operands[1], 0), + gcn_operand_part (<MODE>mode, operands[2], 0), + vcc, + gcn_operand_part (<MODE>mode, operands[3], 0), + operands[4])); + emit_insn (gen_vec_duplicate<vnsi>_exec (operands[5], + gcn_operand_part (DImode, operands[1], 1), + gcn_gen_undef (<VnSI>mode), + operands[4])); + emit_insn (gen_addc<vnsi>3_exec + (gcn_operand_part (<MODE>mode, operands[0], 1), + operands[5], + gcn_operand_part (<MODE>mode, operands[2], 1), + vcc, vcc, + gcn_operand_part (<MODE>mode, operands[3], 1), + operands[4])); + DONE; + } + [(set_attr "type" "vmult") + (set_attr "length" "8")]) + (define_insn_and_split "sub<mode>3" [(set (match_operand:V_DI 0 "register_operand" "= v, v") (minus:V_DI @@ -1827,7 +1934,7 @@ (ltu:DI (plus:V_DI (zero_extend:V_DI (vec_duplicate:<VnSI> (match_dup 1))) (match_dup 2)) - (match_dup 1)))] + (match_dup 2)))] "" {@ [cons: =0, 1, 2, =3] [v,ASv,v,&Sg] # @@ -1878,7 +1985,7 @@ (ltu:DI (plus:V_DI (zero_extend:V_DI (vec_duplicate:<VnSI> (match_dup 1))) (match_dup 2)) - (match_dup 1)) + (match_dup 2)) (match_dup 5)))] "" {@ [cons: =0, 1, 2, =3, 4, 5] @@ -1932,7 +2039,7 @@ (ltu:DI (plus:V_DI (zero_extend:V_DI (match_dup 1)) (vec_duplicate:V_DI (match_dup 2))) - (match_dup 1)))] + (vec_duplicate:V_DI (match_dup 2))))] "" {@ [cons: =0, 1, 2, =3] [v,v,DbSv,&cV] # @@ -1981,7 +2088,7 @@ (ltu:DI (plus:V_DI (zero_extend:V_DI (match_dup 1)) (vec_duplicate:V_DI (match_dup 2))) - (match_dup 1)) + (vec_duplicate:V_DI (match_dup 2))) (match_dup 5)))] "" {@ [cons: =0, 1, 2, =3, 4, 5] @@ -2190,6 +2297,22 @@ [(set_attr "type" "vop3a") (set_attr "length" "8")]) +(define_insn "<su>mul<mode>3_highpart_dup<exec>" + [(set (match_operand:V_SI 0 "register_operand" "= v") + (truncate:V_SI + (lshiftrt:<VnDI> + (mult:<VnDI> + (any_extend:<VnDI> + (vec_duplicate:V_SI + (match_operand:SI 1 "gcn_alu_operand" "SvA"))) + (any_extend:<VnDI> + (match_operand:V_SI 2 "gcn_alu_operand" " vA"))) + (const_int 32))))] + "" + "v_mul_hi<sgnsuffix>0\t%0, %2, %1" + [(set_attr "type" "vop3a") + (set_attr "length" "8")]) + (define_insn "mul<mode>3<exec>" [(set (match_operand:V_INT_1REG 0 "register_operand" "= v") (mult:V_INT_1REG @@ -2201,11 +2324,11 @@ (set_attr "length" "8")]) (define_insn "mul<mode>3_dup<exec>" - [(set (match_operand:V_INT_1REG 0 "register_operand" "= v") + [(set (match_operand:V_INT_1REG 0 "register_operand" "= v") (mult:V_INT_1REG - (match_operand:V_INT_1REG 1 "gcn_alu_operand" "%vSvA") (vec_duplicate:V_INT_1REG - (match_operand:<SCALAR_MODE> 2 "gcn_alu_operand" " SvA"))))] + (match_operand:<SCALAR_MODE> 1 "gcn_alu_operand" "SvA")) + (match_operand:V_INT_1REG 2 "gcn_alu_operand" " vA")))] "" "v_mul_lo_u32\t%0, %1, %2" [(set_attr "type" "vop3a") @@ -2241,6 +2364,37 @@ DONE; }) +(define_insn_and_split "mul<mode>3_dup" + [(set (match_operand:V_DI 0 "register_operand" "=&v") + (mult:V_DI + (vec_duplicate:V_DI + (match_operand:DI 1 "gcn_alu_operand" " Sv")) + (match_operand:V_DI 2 "gcn_alu_operand" "vDA"))) + (clobber (match_scratch:<VnSI> 3 "=&v"))] + "" + "#" + "reload_completed" + [(const_int 0)] + { + rtx out_lo = gcn_operand_part (<MODE>mode, operands[0], 0); + rtx out_hi = gcn_operand_part (<MODE>mode, operands[0], 1); + rtx left_lo = gcn_operand_part (DImode, operands[1], 0); + rtx left_hi = gcn_operand_part (DImode, operands[1], 1); + rtx right_lo = gcn_operand_part (<MODE>mode, operands[2], 0); + rtx right_hi = gcn_operand_part (<MODE>mode, operands[2], 1); + rtx tmp = operands[3]; + + emit_insn (gen_mul<vnsi>3_dup (out_lo, left_lo, right_lo)); + emit_insn (gen_umul<vnsi>3_highpart_dup (out_hi, left_lo, right_lo)); + emit_insn (gen_mul<vnsi>3_dup (tmp, left_hi, right_lo)); + emit_insn (gen_add<vnsi>3 (out_hi, out_hi, tmp)); + emit_insn (gen_mul<vnsi>3_dup (tmp, left_lo, right_hi)); + emit_insn (gen_add<vnsi>3 (out_hi, out_hi, tmp)); + emit_insn (gen_mul<vnsi>3_dup (tmp, left_hi, right_hi)); + emit_insn (gen_add<vnsi>3 (out_hi, out_hi, tmp)); + DONE; + }) + (define_insn_and_split "mul<mode>3_exec" [(set (match_operand:V_DI 0 "register_operand" "=&v") (vec_merge:V_DI @@ -2289,6 +2443,56 @@ DONE; }) +(define_insn_and_split "mul<mode>3_dup_exec" + [(set (match_operand:V_DI 0 "register_operand" "=&v") + (vec_merge:V_DI + (mult:V_DI + (vec_duplicate:V_DI + (match_operand:DI 1 "gcn_alu_operand" " Sv")) + (match_operand:V_DI 2 "gcn_alu_operand" "vDA")) + (match_operand:V_DI 3 "gcn_register_or_unspec_operand" " U0") + (match_operand:DI 4 "gcn_exec_reg_operand" " e"))) + (clobber (match_scratch:<VnSI> 5 "=&v"))] + "" + "#" + "reload_completed" + [(const_int 0)] + { + rtx out_lo = gcn_operand_part (<MODE>mode, operands[0], 0); + rtx out_hi = gcn_operand_part (<MODE>mode, operands[0], 1); + rtx left_lo = gcn_operand_part (DImode, operands[1], 0); + rtx left_hi = gcn_operand_part (DImode, operands[1], 1); + rtx right_lo = gcn_operand_part (<MODE>mode, operands[2], 0); + rtx right_hi = gcn_operand_part (<MODE>mode, operands[2], 1); + rtx exec = operands[4]; + rtx tmp = operands[5]; + + rtx old_lo, old_hi; + if (GET_CODE (operands[3]) == UNSPEC) + { + old_lo = old_hi = gcn_gen_undef (<VnSI>mode); + } + else + { + old_lo = gcn_operand_part (<MODE>mode, operands[3], 0); + old_hi = gcn_operand_part (<MODE>mode, operands[3], 1); + } + + rtx undef = gcn_gen_undef (<VnSI>mode); + + emit_insn (gen_mul<vnsi>3_dup_exec (out_lo, left_lo, right_lo, old_lo, + exec)); + emit_insn (gen_umul<vnsi>3_highpart_dup_exec (out_hi, left_lo, right_lo, + old_hi, exec)); + emit_insn (gen_mul<vnsi>3_dup_exec (tmp, left_hi, right_lo, undef, exec)); + emit_insn (gen_add<vnsi>3_exec (out_hi, out_hi, tmp, out_hi, exec)); + emit_insn (gen_mul<vnsi>3_dup_exec (tmp, left_lo, right_hi, undef, exec)); + emit_insn (gen_add<vnsi>3_exec (out_hi, out_hi, tmp, out_hi, exec)); + emit_insn (gen_mul<vnsi>3_dup_exec (tmp, left_hi, right_hi, undef, exec)); + emit_insn (gen_add<vnsi>3_exec (out_hi, out_hi, tmp, out_hi, exec)); + DONE; + }) + (define_insn_and_split "mul<mode>3_zext" [(set (match_operand:V_DI 0 "register_operand" "=&v") (mult:V_DI @@ -3795,9 +3999,9 @@ /* Unsigned comparisons use the same patterns as signed comparisons, except that they use unsigned operators (e.g. LTU vs LT). The '%E1' directive then does the Right Thing. */ - emit_insn (gen_vec_cmpu<mode>di_exec (operands[0], operands[1], - operands[2], operands[3], - operands[4])); + emit_insn (gen_vec_cmp<mode>di_exec (operands[0], operands[1], + operands[2], operands[3], + operands[4])); DONE; }) @@ -4052,6 +4256,32 @@ DONE; }) +(define_expand "mask_gather_load<mode><vndi>" + [(set:V_MOV (match_operand:V_MOV 0 "register_operand") + (unspec:V_MOV + [(match_operand:DI 1 "register_operand") + (match_operand:<VnDI> 2 "register_operand") + (match_operand 3 "immediate_operand") + (match_operand:SI 4 "gcn_alu_operand") + (match_operand:DI 5 "") + (match_operand:V_MOV 6 "maskload_else_operand")] + UNSPEC_GATHER))] + "" + { + rtx exec = force_reg (DImode, operands[5]); + + rtx addr = gcn_expand_scaled_offsets (DEFAULT_ADDR_SPACE, operands[1], + operands[2], operands[4], + INTVAL (operands[3]), exec); + + emit_insn (gen_gather<mode>_insn_1offset_exec (operands[0], addr, + const0_rtx, const0_rtx, + const0_rtx, + gcn_gen_undef (<MODE>mode), + exec)); + DONE; + }) + (define_expand "mask_scatter_store<mode><vnsi>" [(match_operand:DI 0 "register_operand") (match_operand:<VnSI> 1 "register_operand") @@ -4080,6 +4310,27 @@ DONE; }) +(define_expand "mask_scatter_store<mode><vndi>" + [(match_operand:DI 0 "register_operand") + (match_operand:<VnDI> 1 "register_operand") + (match_operand 2 "immediate_operand") + (match_operand:SI 3 "gcn_alu_operand") + (match_operand:V_MOV 4 "register_operand") + (match_operand:DI 5 "")] + "" + { + rtx exec = force_reg (DImode, operands[5]); + + rtx addr = gcn_expand_scaled_offsets (DEFAULT_ADDR_SPACE, operands[0], + operands[1], operands[3], + INTVAL (operands[2]), exec); + + emit_insn (gen_scatter<mode>_insn_1offset_exec (addr, const0_rtx, + operands[4], const0_rtx, + const0_rtx, exec)); + DONE; + }) + (define_code_iterator cond_op [plus minus mult]) (define_expand "cond_<expander><mode>" @@ -4400,7 +4651,7 @@ rtx tmp = gen_reg_rtx (<MODE>mode); rtx v1 = gen_rtx_REG (<MODE>mode, VGPR_REGNO (1)); - emit_insn (gen_mul<mode>3_dup (tmp, v1, operands[2])); + emit_insn (gen_mul<mode>3_dup (tmp, operands[2], v1)); emit_insn (gen_add<mode>3_dup (operands[0], tmp, operands[1])); DONE; }) diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc index f982dbd7bcfb..3b26d5c6a585 100644 --- a/gcc/config/gcn/gcn.cc +++ b/gcc/config/gcn/gcn.cc @@ -585,9 +585,8 @@ gcn_hard_regno_mode_ok (unsigned int regno, machine_mode mode) case XNACK_MASK_HI_REG: case TBA_HI_REG: case TMA_HI_REG: - return mode == SImode; case VCC_HI_REG: - return false; + return mode == SImode; case EXEC_HI_REG: return mode == SImode /*|| mode == V32BImode */ ; case SCC_REG: @@ -1276,13 +1275,13 @@ gen_##PREFIX##vN##SUFFIX (PARAMS) \ } #define GEN_VNM_NOEXEC(PREFIX, SUFFIX, PARAMS, ARGS) \ -GEN_VN_NOEXEC (PREFIX, qi##SUFFIX, A(PARAMS), A(ARGS)) \ -GEN_VN_NOEXEC (PREFIX, hi##SUFFIX, A(PARAMS), A(ARGS)) \ -GEN_VN_NOEXEC (PREFIX, hf##SUFFIX, A(PARAMS), A(ARGS)) \ +USE_QHF (GEN_VN_NOEXEC (PREFIX, qi##SUFFIX, A(PARAMS), A(ARGS))) \ +USE_QHF (GEN_VN_NOEXEC (PREFIX, hi##SUFFIX, A(PARAMS), A(ARGS))) \ +USE_QHF (GEN_VN_NOEXEC (PREFIX, hf##SUFFIX, A(PARAMS), A(ARGS))) \ GEN_VN_NOEXEC (PREFIX, si##SUFFIX, A(PARAMS), A(ARGS)) \ -GEN_VN_NOEXEC (PREFIX, sf##SUFFIX, A(PARAMS), A(ARGS)) \ +USE_QHF (GEN_VN_NOEXEC (PREFIX, sf##SUFFIX, A(PARAMS), A(ARGS))) \ GEN_VN_NOEXEC (PREFIX, di##SUFFIX, A(PARAMS), A(ARGS)) \ -GEN_VN_NOEXEC (PREFIX, df##SUFFIX, A(PARAMS), A(ARGS)) \ +USE_QHF (GEN_VN_NOEXEC (PREFIX, df##SUFFIX, A(PARAMS), A(ARGS))) \ static rtx \ gen_##PREFIX##vNm##SUFFIX (PARAMS) \ { \ @@ -1290,13 +1289,13 @@ gen_##PREFIX##vNm##SUFFIX (PARAMS) \ \ switch (mode) \ { \ - case E_QImode: return gen_##PREFIX##vNqi##SUFFIX (ARGS); \ - case E_HImode: return gen_##PREFIX##vNhi##SUFFIX (ARGS); \ - case E_HFmode: return gen_##PREFIX##vNhf##SUFFIX (ARGS); \ + USE_QHF (case E_QImode: return gen_##PREFIX##vNqi##SUFFIX (ARGS);) \ + USE_QHF (case E_HImode: return gen_##PREFIX##vNhi##SUFFIX (ARGS);) \ + USE_QHF (case E_HFmode: return gen_##PREFIX##vNhf##SUFFIX (ARGS);) \ case E_SImode: return gen_##PREFIX##vNsi##SUFFIX (ARGS); \ - case E_SFmode: return gen_##PREFIX##vNsf##SUFFIX (ARGS); \ + USE_QHF (case E_SFmode: return gen_##PREFIX##vNsf##SUFFIX (ARGS);) \ case E_DImode: return gen_##PREFIX##vNdi##SUFFIX (ARGS); \ - case E_DFmode: return gen_##PREFIX##vNdf##SUFFIX (ARGS); \ + USE_QHF (case E_DFmode: return gen_##PREFIX##vNdf##SUFFIX (ARGS);) \ default: \ break; \ } \ @@ -1341,13 +1340,13 @@ gen_##PREFIX##vN##SUFFIX (PARAMS, rtx merge_src=NULL, rtx exec=NULL) \ } #define GEN_VNM(PREFIX, SUFFIX, PARAMS, ARGS) \ -GEN_VN (PREFIX, qi##SUFFIX, A(PARAMS), A(ARGS)) \ -GEN_VN (PREFIX, hi##SUFFIX, A(PARAMS), A(ARGS)) \ -GEN_VN (PREFIX, hf##SUFFIX, A(PARAMS), A(ARGS)) \ +USE_QHF (GEN_VN (PREFIX, qi##SUFFIX, A(PARAMS), A(ARGS))) \ +USE_QHF (GEN_VN (PREFIX, hi##SUFFIX, A(PARAMS), A(ARGS))) \ +USE_QHF (GEN_VN (PREFIX, hf##SUFFIX, A(PARAMS), A(ARGS))) \ GEN_VN (PREFIX, si##SUFFIX, A(PARAMS), A(ARGS)) \ -GEN_VN (PREFIX, sf##SUFFIX, A(PARAMS), A(ARGS)) \ +USE_QHF (GEN_VN (PREFIX, sf##SUFFIX, A(PARAMS), A(ARGS))) \ GEN_VN (PREFIX, di##SUFFIX, A(PARAMS), A(ARGS)) \ -GEN_VN (PREFIX, df##SUFFIX, A(PARAMS), A(ARGS)) \ +USE_QHF (GEN_VN (PREFIX, df##SUFFIX, A(PARAMS), A(ARGS))) \ USE_TI (GEN_VN (PREFIX, ti##SUFFIX, A(PARAMS), A(ARGS))) \ static rtx \ gen_##PREFIX##vNm##SUFFIX (PARAMS, rtx merge_src=NULL, rtx exec=NULL) \ @@ -1356,15 +1355,22 @@ gen_##PREFIX##vNm##SUFFIX (PARAMS, rtx merge_src=NULL, rtx exec=NULL) \ \ switch (mode) \ { \ - case E_QImode: return gen_##PREFIX##vNqi##SUFFIX (ARGS, merge_src, exec); \ - case E_HImode: return gen_##PREFIX##vNhi##SUFFIX (ARGS, merge_src, exec); \ - case E_HFmode: return gen_##PREFIX##vNhf##SUFFIX (ARGS, merge_src, exec); \ - case E_SImode: return gen_##PREFIX##vNsi##SUFFIX (ARGS, merge_src, exec); \ - case E_SFmode: return gen_##PREFIX##vNsf##SUFFIX (ARGS, merge_src, exec); \ - case E_DImode: return gen_##PREFIX##vNdi##SUFFIX (ARGS, merge_src, exec); \ - case E_DFmode: return gen_##PREFIX##vNdf##SUFFIX (ARGS, merge_src, exec); \ - case E_TImode: \ - USE_TI (return gen_##PREFIX##vNti##SUFFIX (ARGS, merge_src, exec);) \ + USE_QHF (case E_QImode: \ + return gen_##PREFIX##vNqi##SUFFIX (ARGS, merge_src, exec);) \ + USE_QHF (case E_HImode: \ + return gen_##PREFIX##vNhi##SUFFIX (ARGS, merge_src, exec);) \ + USE_QHF (case E_HFmode: \ + return gen_##PREFIX##vNhf##SUFFIX (ARGS, merge_src, exec);) \ + case E_SImode: \ + return gen_##PREFIX##vNsi##SUFFIX (ARGS, merge_src, exec); \ + USE_QHF (case E_SFmode: \ + return gen_##PREFIX##vNsf##SUFFIX (ARGS, merge_src, exec);) \ + case E_DImode: \ + return gen_##PREFIX##vNdi##SUFFIX (ARGS, merge_src, exec); \ + USE_QHF (case E_DFmode: \ + return gen_##PREFIX##vNdf##SUFFIX (ARGS, merge_src, exec);) \ + USE_TI (case E_TImode: \ + return gen_##PREFIX##vNti##SUFFIX (ARGS, merge_src, exec);) \ default: \ break; \ } \ @@ -1373,7 +1379,8 @@ gen_##PREFIX##vNm##SUFFIX (PARAMS, rtx merge_src=NULL, rtx exec=NULL) \ return NULL_RTX; \ } -/* These have TImode support. */ +/* These support everything. */ +#define USE_QHF(ARGS) ARGS #define USE_TI(ARGS) ARGS GEN_VNM (mov,, A(rtx dest, rtx src), A(dest, src)) GEN_VNM (vec_duplicate,, A(rtx dest, rtx src), A(dest, src)) @@ -1383,6 +1390,7 @@ GEN_VNM (vec_duplicate,, A(rtx dest, rtx src), A(dest, src)) #define USE_TI(ARGS) GEN_VNM (add,3, A(rtx dest, rtx src1, rtx src2), A(dest, src1, src2)) GEN_VN (add,si3_dup, A(rtx dest, rtx src1, rtx src2), A(dest, src1, src2)) +GEN_VN (add,di3_dup, A(rtx dest, rtx src1, rtx src2), A(dest, src1, src2)) GEN_VN (add,si3_vcc_dup, A(rtx dest, rtx src1, rtx src2, rtx vcc), A(dest, src1, src2, vcc)) GEN_VN (add,di3_sext_dup2, A(rtx dest, rtx src1, rtx src2), A(dest, src1, src2)) @@ -1394,15 +1402,20 @@ GEN_VN (add,di3_vcc_zext_dup2, A(rtx dest, rtx src1, rtx src2, rtx vcc), GEN_VN (addc,si3, A(rtx dest, rtx src1, rtx src2, rtx vccout, rtx vccin), A(dest, src1, src2, vccout, vccin)) GEN_VN (and,si3, A(rtx dest, rtx src1, rtx src2), A(dest, src1, src2)) -GEN_VN (ashl,si3, A(rtx dest, rtx src, rtx shift), A(dest, src, shift)) GEN_VNM_NOEXEC (ds_bpermute,, A(rtx dest, rtx addr, rtx src, rtx exec), A(dest, addr, src, exec)) GEN_VNM (gather,_expr, A(rtx dest, rtx addr, rtx as, rtx vol), A(dest, addr, as, vol)) -GEN_VN (mul,si3_dup, A(rtx dest, rtx src1, rtx src2), A(dest, src1, src2)) GEN_VN (sub,si3, A(rtx dest, rtx src1, rtx src2), A(dest, src1, src2)) GEN_VN_NOEXEC (vec_series,si, A(rtx dest, rtx x, rtx c), A(dest, x, c)) +/* These do not have QI, HI, or any FP support. */ +#undef USE_QHF +#define USE_QHF(ARGS) +GEN_VNM (ashl,3, A(rtx dest, rtx src, rtx shift), A(dest, src, shift)) +GEN_VNM (mul,3_dup, A(rtx dest, rtx src1, rtx src2), A(dest, src1, src2)) + +#undef USE_QHF #undef USE_TI #undef GEN_VNM #undef GEN_VN @@ -1996,8 +2009,8 @@ gcn_expand_vector_init (rtx op0, rtx vec) rtx addr = gen_reg_rtx (addrmode); int unit_size = GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (op0))); - emit_insn (gen_mulvNsi3_dup (ramp, gen_rtx_REG (offsetmode, VGPR_REGNO (1)), - GEN_INT (unit_size))); + emit_insn (gen_mulvNsi3_dup (ramp, GEN_INT (unit_size), + gen_rtx_REG (offsetmode, VGPR_REGNO (1)))); bool simple_repeat = true; @@ -2294,36 +2307,46 @@ gcn_expand_scalar_to_vector_address (machine_mode mode, rtx exec, rtx mem, Return values. ADDR_SPACE_FLAT - return VnDImode vector of absolute addresses. - ADDR_SPACE_GLOBAL - return VnSImode vector of offsets. */ + ADDR_SPACE_GLOBAL - return VnSImode vector of offsets. + 64-bit offsets - return VnDImode vector of absolute addresses. */ rtx gcn_expand_scaled_offsets (addr_space_t as, rtx base, rtx offsets, rtx scale, bool unsigned_p, rtx exec) { int vf = GET_MODE_NUNITS (GET_MODE (offsets)); - rtx tmpsi = gen_reg_rtx (VnMODE (vf, SImode)); - rtx tmpdi = gen_reg_rtx (VnMODE (vf, DImode)); + rtx scaled_offsets = gen_reg_rtx (GET_MODE (offsets)); + rtx abs_addr = gen_reg_rtx (VnMODE (vf, DImode)); + bool use_di = GET_MODE_INNER (GET_MODE (scaled_offsets)) == DImode; if (CONST_INT_P (scale) && INTVAL (scale) > 0 && exact_log2 (INTVAL (scale)) >= 0) - emit_insn (gen_ashlvNsi3 (tmpsi, offsets, - GEN_INT (exact_log2 (INTVAL (scale))), - NULL, exec)); + emit_insn (gen_ashlvNm3 (scaled_offsets, offsets, + GEN_INT (exact_log2 (INTVAL (scale))), + NULL, exec)); else - emit_insn (gen_mulvNsi3_dup (tmpsi, offsets, scale, NULL, exec)); + emit_insn (gen_mulvNm3_dup (scaled_offsets, scale, offsets, NULL, exec)); + /* No instructions support DImode offsets. */ + if (use_di) + { + emit_insn (gen_addvNdi3_dup (abs_addr, base, scaled_offsets, NULL, exec)); + return abs_addr; + } /* "Global" instructions do not support negative register offsets. */ - if (as == ADDR_SPACE_FLAT || !unsigned_p) + else if (as == ADDR_SPACE_FLAT || !unsigned_p) { if (unsigned_p) - emit_insn (gen_addvNdi3_zext_dup2 (tmpdi, tmpsi, base, NULL, exec)); + emit_insn (gen_addvNdi3_zext_dup2 (abs_addr, scaled_offsets, base, + NULL, exec)); else - emit_insn (gen_addvNdi3_sext_dup2 (tmpdi, tmpsi, base, NULL, exec)); - return tmpdi; + emit_insn (gen_addvNdi3_sext_dup2 (abs_addr, scaled_offsets, base, + NULL, exec)); + return abs_addr; } else if (as == ADDR_SPACE_GLOBAL) - return tmpsi; + return scaled_offsets; gcc_unreachable (); } @@ -7102,7 +7125,10 @@ print_operand_address (FILE *file, rtx mem) E - print conditional code for v_cmp (eq_u64/ne_u64...) A - print address in formatting suitable for given address space. O - print offset:n for data share operations. - g - print "glc", if appropriate for given MEM + G - print "glc" (or for gfx94x: sc0) unconditionally [+ indep. of regnum] + g - print "glc" (or for gfx94x: sc0), if appropriate for given MEM + NOTE: Do not use 'G' or 'g with scalar memory access ('s_...') as those + require "glc" also with gfx94x. L - print low-part of a multi-reg value H - print second part of a multi-reg value (high-part of 2-reg value) J - print third part of a multi-reg value @@ -7718,10 +7744,13 @@ print_operand (FILE *file, rtx x, int code) else output_addr_const (file, x); return; + case 'G': + fputs (TARGET_GLC_NAME, file); + return; case 'g': gcc_assert (xcode == MEM); if (MEM_VOLATILE_P (x)) - fputs (" glc", file); + fputs (TARGET_GLC_NAME, file); return; default: output_operand_lossage ("invalid %%xn code"); diff --git a/gcc/config/gcn/gcn.h b/gcc/config/gcn/gcn.h index 5198fbca2078..3d42de3b2a8f 100644 --- a/gcc/config/gcn/gcn.h +++ b/gcc/config/gcn/gcn.h @@ -43,6 +43,8 @@ extern const struct gcn_device_def { builtin_define ("__CDNA1__"); \ else if (TARGET_CDNA2) \ builtin_define ("__CDNA2__"); \ + else if (TARGET_CDNA3) \ + builtin_define ("__CDNA3__"); \ else if (TARGET_RDNA2) \ builtin_define ("__RDNA2__"); \ else if (TARGET_RDNA3) \ diff --git a/gcc/config/gcn/gcn.md b/gcc/config/gcn/gcn.md index e0fb735e5ec9..9193461ed49a 100644 --- a/gcc/config/gcn/gcn.md +++ b/gcc/config/gcn/gcn.md @@ -219,7 +219,7 @@ ; flags: offen, idxen, glc, lds, slc, tfe ; ; flat - flat or global memory operations -; flags: glc, slc +; flags: {CDNA3: sc0, nt, sc1 | otherwise: glc, slc, scc} ; addr: vgpr0-255 ; data: vgpr0-255 ; vdst: vgpr0-255 @@ -1136,14 +1136,13 @@ [(set (match_operand:SI 0 "register_operand" "= Sg, Sg, Sg, v") (plus:SI (match_operand:SI 1 "gcn_alu_operand" "%SgA, 0,SgA, v") (match_operand:SI 2 "gcn_alu_operand" " SgA,SgJ, B,vBSv"))) - (clobber (match_scratch:BI 3 "= cs, cs, cs, X")) - (clobber (match_scratch:DI 4 "= X, X, X, cV"))] + (clobber (match_scratch:BI 3 "= cs, cs, cs, X"))] "" "@ s_add_i32\t%0, %1, %2 s_addk_i32\t%0, %2 s_add_i32\t%0, %1, %2 - v_add_co_u32\t%0, vcc, %2, %1" + {v_add_u32|v_add_nc_u32}\t%0, %2, %1" [(set_attr "type" "sop2,sopk,sop2,vop2") (set_attr "length" "4,4,8,8")]) @@ -1151,8 +1150,7 @@ [(parallel [(set (match_operand:SI 0 "register_operand") (plus:SI (match_operand:SI 1 "gcn_alu_operand") (match_operand:SI 2 "gcn_alu_operand"))) - (clobber (reg:BI SCC_REG)) - (clobber (scratch:DI))])] + (clobber (reg:BI SCC_REG))])] "" {}) @@ -1332,14 +1330,13 @@ [(set (match_operand:SI 0 "register_operand" "=Sg, Sg, v, v") (minus:SI (match_operand:SI 1 "gcn_alu_operand" "SgA,SgA, v,vBSv") (match_operand:SI 2 "gcn_alu_operand" "SgA, B, vBSv, v"))) - (clobber (match_scratch:BI 3 "=cs, cs, X, X")) - (clobber (match_scratch:DI 4 "= X, X, cV, cV"))] + (clobber (match_scratch:BI 3 "=cs, cs, X, X"))] "" "@ s_sub_i32\t%0, %1, %2 s_sub_i32\t%0, %1, %2 - v_subrev_co_u32\t%0, vcc, %2, %1 - v_sub_co_u32\t%0, vcc, %1, %2" + {v_subrev_u32|v_subrev_nc_u32}\t%0, %2, %1 + {v_sub_u32|v_sub_nc_u32}\t%0, %1, %2" [(set_attr "type" "sop2,sop2,vop2,vop2") (set_attr "length" "4,8,8,8")]) @@ -1569,8 +1566,7 @@ (mult:DI (match_operand:DI 1 "register_operand" "%Sg, Sg, v, v") (match_operand:DI 2 "nonmemory_operand" "Sg, i,vSv, A"))) (clobber (match_scratch:SI 3 "=&Sg,&Sg,&v,&v")) - (clobber (match_scratch:BI 4 "=cs, cs, X, X")) - (clobber (match_scratch:DI 5 "=X, X,cV,cV"))] + (clobber (match_scratch:BI 4 "=cs, cs, X, X"))] "" "#" "reload_completed" @@ -1585,15 +1581,13 @@ emit_insn (gen_umulsidi3 (operands[0], op1lo, op2lo)); emit_insn (gen_mulsi3 (tmp, op1lo, op2hi)); rtx add = gen_rtx_SET (dsthi, gen_rtx_PLUS (SImode, dsthi, tmp)); - rtx clob1 = gen_rtx_CLOBBER (VOIDmode, operands[4]); - rtx clob2 = gen_rtx_CLOBBER (VOIDmode, operands[5]); - add = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (3, add, clob1, clob2)); + rtx clob = gen_rtx_CLOBBER (VOIDmode, operands[4]); + add = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, add, clob)); emit_insn (add); emit_insn (gen_mulsi3 (tmp, op1hi, op2lo)); add = gen_rtx_SET (dsthi, gen_rtx_PLUS (SImode, dsthi, tmp)); - clob1 = gen_rtx_CLOBBER (VOIDmode, operands[4]); - clob2 = gen_rtx_CLOBBER (VOIDmode, operands[5]); - add = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (3, add, clob1, clob2)); + clob = gen_rtx_CLOBBER (VOIDmode, operands[4]); + add = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, add, clob)); emit_insn (add); DONE; }) @@ -1964,6 +1958,14 @@ [(set_attr "type" "mult") (set_attr "length" "8")]) +(define_insn "*memory_barrier" + [(set (match_operand:BLK 0) + (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))] + "TARGET_TARGET_SC_CACHE" + "buffer_inv sc1" + [(set_attr "type" "mubuf") + (set_attr "length" "4")]) + ; FIXME: These patterns have been disabled as they do not seem to work ; reliably - they can cause hangs or incorrect results. ; TODO: flush caches according to memory model @@ -1980,8 +1982,8 @@ "0 /* Disabled. */" "@ s_atomic_<bare_mnemonic><X>\t%0, %1, %2 glc\;s_waitcnt\tlgkmcnt(0) - flat_atomic_<bare_mnemonic><X>\t%0, %1, %2 glc\;s_waitcnt\t0 - global_atomic_<bare_mnemonic><X>\t%0, %A1, %2%O1 glc\;s_waitcnt\tvmcnt(0)" + flat_atomic_<bare_mnemonic><X>\t%0, %1, %2 %G2\;s_waitcnt\t0 + global_atomic_<bare_mnemonic><X>\t%0, %A1, %2%O1 %G2\;s_waitcnt\tvmcnt(0)" [(set_attr "type" "smem,flat,flat") (set_attr "length" "12")]) @@ -2047,8 +2049,8 @@ "" "@ s_atomic_cmpswap<X>\t%0, %1, %2 glc\;s_waitcnt\tlgkmcnt(0) - flat_atomic_cmpswap<X>\t%0, %1, %2 glc\;s_waitcnt\t0 - global_atomic_cmpswap<X>\t%0, %A1, %2%O1 glc\;s_waitcnt\tvmcnt(0)" + flat_atomic_cmpswap<X>\t%0, %1, %2 %G2\;s_waitcnt\t0 + global_atomic_cmpswap<X>\t%0, %A1, %2%O1 %G2\;s_waitcnt\tvmcnt(0)" [(set_attr "type" "smem,flat,flat") (set_attr "length" "12") (set_attr "delayeduse" "*,yes,yes")]) @@ -2091,12 +2093,12 @@ return "s_load%o0\t%0, %A1 glc\;s_waitcnt\tlgkmcnt(0)"; case 1: return (TARGET_RDNA2 /* Not GFX11. */ - ? "flat_load%o0\t%0, %A1%O1 glc dlc\;s_waitcnt\t0" - : "flat_load%o0\t%0, %A1%O1 glc\;s_waitcnt\t0"); + ? "flat_load%o0\t%0, %A1%O1 %G1 dlc\;s_waitcnt\t0" + : "flat_load%o0\t%0, %A1%O1 %G1\;s_waitcnt\t0"); case 2: return (TARGET_RDNA2 /* Not GFX11. */ - ? "global_load%o0\t%0, %A1%O1 glc dlc\;s_waitcnt\tvmcnt(0)" - : "global_load%o0\t%0, %A1%O1 glc\;s_waitcnt\tvmcnt(0)"); + ? "global_load%o0\t%0, %A1%O1 %G1 dlc\;s_waitcnt\tvmcnt(0)" + : "global_load%o0\t%0, %A1%O1 %G1\;s_waitcnt\tvmcnt(0)"); } break; case MEMMODEL_CONSUME: @@ -2109,21 +2111,27 @@ "s_dcache_wb_vol"; case 1: return (TARGET_RDNA2 - ? "flat_load%o0\t%0, %A1%O1 glc dlc\;s_waitcnt\t0\;" + ? "flat_load%o0\t%0, %A1%O1 %G1 dlc\;s_waitcnt\t0\;" "buffer_gl1_inv\;buffer_gl0_inv" : TARGET_RDNA3 - ? "flat_load%o0\t%0, %A1%O1 glc\;s_waitcnt\t0\;" + ? "flat_load%o0\t%0, %A1%O1 %G1\;s_waitcnt\t0\;" "buffer_gl1_inv\;buffer_gl0_inv" - : "flat_load%o0\t%0, %A1%O1 glc\;s_waitcnt\t0\;" + : TARGET_TARGET_SC_CACHE + ? "flat_load%o0\t%0, %A1%O1 %G1\;s_waitcnt\t0\;" + "buffer_inv sc1" + : "flat_load%o0\t%0, %A1%O1 %G1\;s_waitcnt\t0\;" "buffer_wbinvl1_vol"); case 2: return (TARGET_RDNA2 - ? "global_load%o0\t%0, %A1%O1 glc dlc\;s_waitcnt\tvmcnt(0)\;" + ? "global_load%o0\t%0, %A1%O1 %G1 dlc\;s_waitcnt\tvmcnt(0)\;" "buffer_gl1_inv\;buffer_gl0_inv" : TARGET_RDNA3 - ? "global_load%o0\t%0, %A1%O1 glc\;s_waitcnt\tvmcnt(0)\;" + ? "global_load%o0\t%0, %A1%O1 %G1\;s_waitcnt\tvmcnt(0)\;" "buffer_gl1_inv\;buffer_gl0_inv" - : "global_load%o0\t%0, %A1%O1 glc\;s_waitcnt\tvmcnt(0)\;" + : TARGET_TARGET_SC_CACHE + ? "global_load%o0\t%0, %A1%O1 %G1\;s_waitcnt\tvmcnt(0)\;" + "buffer_inv sc1" + : "global_load%o0\t%0, %A1%O1 %G1\;s_waitcnt\tvmcnt(0)\;" "buffer_wbinvl1_vol"); } break; @@ -2137,21 +2145,27 @@ "s_waitcnt\tlgkmcnt(0)\;s_dcache_inv_vol"; case 1: return (TARGET_RDNA2 - ? "buffer_gl1_inv\;buffer_gl0_inv\;flat_load%o0\t%0, %A1%O1 glc dlc\;" + ? "buffer_gl1_inv\;buffer_gl0_inv\;flat_load%o0\t%0, %A1%O1 %G1 dlc\;" "s_waitcnt\t0\;buffer_gl1_inv\;buffer_gl0_inv" : TARGET_RDNA3 - ? "buffer_gl1_inv\;buffer_gl0_inv\;flat_load%o0\t%0, %A1%O1 glc\;" + ? "buffer_gl1_inv\;buffer_gl0_inv\;flat_load%o0\t%0, %A1%O1 %G1\;" "s_waitcnt\t0\;buffer_gl1_inv\;buffer_gl0_inv" - : "buffer_wbinvl1_vol\;flat_load%o0\t%0, %A1%O1 glc\;" + : TARGET_TARGET_SC_CACHE + ? "buffer_inv sc1\;flat_load%o0\t%0, %A1%O1 %G1\;" + "s_waitcnt\t0\;buffer_inv sc1" + : "buffer_wbinvl1_vol\;flat_load%o0\t%0, %A1%O1 %G1\;" "s_waitcnt\t0\;buffer_wbinvl1_vol"); case 2: return (TARGET_RDNA2 - ? "buffer_gl1_inv\;buffer_gl0_inv\;global_load%o0\t%0, %A1%O1 glc dlc\;" + ? "buffer_gl1_inv\;buffer_gl0_inv\;global_load%o0\t%0, %A1%O1 %G1 dlc\;" "s_waitcnt\tvmcnt(0)\;buffer_gl1_inv\;buffer_gl0_inv" : TARGET_RDNA3 - ? "buffer_gl1_inv\;buffer_gl0_inv\;global_load%o0\t%0, %A1%O1 glc\;" + ? "buffer_gl1_inv\;buffer_gl0_inv\;global_load%o0\t%0, %A1%O1 %G1\;" "s_waitcnt\tvmcnt(0)\;buffer_gl1_inv\;buffer_gl0_inv" - : "buffer_wbinvl1_vol\;global_load%o0\t%0, %A1%O1 glc\;" + : TARGET_TARGET_SC_CACHE + ? "buffer_inv sc1\;global_load%o0\t%0, %A1%O1 %G1\;" + "s_waitcnt\tvmcnt(0)\;buffer_inv sc1" + : "buffer_wbinvl1_vol\;global_load%o0\t%0, %A1%O1 %G1\;" "s_waitcnt\tvmcnt(0)\;buffer_wbinvl1_vol"); } break; @@ -2178,9 +2192,9 @@ case 0: return "s_store%o1\t%1, %A0 glc\;s_waitcnt\tlgkmcnt(0)"; case 1: - return "flat_store%o1\t%A0, %1%O0 glc\;s_waitcnt\t0"; + return "flat_store%o1\t%A0, %1%O0 %G1\;s_waitcnt\t0"; case 2: - return "global_store%o1\t%A0, %1%O0 glc\;s_waitcnt\tvmcnt(0)"; + return "global_store%o1\t%A0, %1%O0 %G1\;s_waitcnt\tvmcnt(0)"; } break; case MEMMODEL_RELEASE: @@ -2191,15 +2205,19 @@ return "s_dcache_wb_vol\;s_store%o1\t%1, %A0 glc"; case 1: return (TARGET_GLn_CACHE - ? "buffer_gl1_inv\;buffer_gl0_inv\;flat_store%o1\t%A0, %1%O0 glc" + ? "buffer_gl1_inv\;buffer_gl0_inv\;flat_store%o1\t%A0, %1%O0 %G1" : TARGET_WBINVL1_CACHE - ? "buffer_wbinvl1_vol\;flat_store%o1\t%A0, %1%O0 glc" + ? "buffer_wbinvl1_vol\;flat_store%o1\t%A0, %1%O0 %G1" + : TARGET_TARGET_SC_CACHE + ? "buffer_inv sc1\;flat_store%o1\t%A0, %1%O0 %G1" : "error: cache architectire unspecified"); case 2: return (TARGET_GLn_CACHE - ? "buffer_gl1_inv\;buffer_gl0_inv\;global_store%o1\t%A0, %1%O0 glc" + ? "buffer_gl1_inv\;buffer_gl0_inv\;global_store%o1\t%A0, %1%O0 %G1" : TARGET_WBINVL1_CACHE - ? "buffer_wbinvl1_vol\;global_store%o1\t%A0, %1%O0 glc" + ? "buffer_wbinvl1_vol\;global_store%o1\t%A0, %1%O0 %G1" + : TARGET_TARGET_SC_CACHE + ? "buffer_inv sc1\;global_store%o1\t%A0, %1%O0 %G1" : "error: cache architecture unspecified"); } break; @@ -2213,19 +2231,25 @@ "s_waitcnt\tlgkmcnt(0)\;s_dcache_inv_vol"; case 1: return (TARGET_GLn_CACHE - ? "buffer_gl1_inv\;buffer_gl0_inv\;flat_store%o1\t%A0, %1%O0 glc\;" + ? "buffer_gl1_inv\;buffer_gl0_inv\;flat_store%o1\t%A0, %1%O0 %G1\;" "s_waitcnt\t0\;buffer_gl1_inv\;buffer_gl0_inv" : TARGET_WBINVL1_CACHE - ? "buffer_wbinvl1_vol\;flat_store%o1\t%A0, %1%O0 glc\;" + ? "buffer_wbinvl1_vol\;flat_store%o1\t%A0, %1%O0 %G1\;" "s_waitcnt\t0\;buffer_wbinvl1_vol" + : TARGET_TARGET_SC_CACHE + ? "buffer_inv sc1\;flat_store%o1\t%A0, %1%O0 %G1\;" + "s_waitcnt\t0\;buffer_inv sc1" : "error: cache architecture unspecified"); case 2: return (TARGET_GLn_CACHE - ? "buffer_gl1_inv\;buffer_gl0_inv\;global_store%o1\t%A0, %1%O0 glc\;" + ? "buffer_gl1_inv\;buffer_gl0_inv\;global_store%o1\t%A0, %1%O0 %G1\;" "s_waitcnt\tvmcnt(0)\;buffer_gl1_inv\;buffer_gl0_inv" : TARGET_WBINVL1_CACHE - ? "buffer_wbinvl1_vol\;global_store%o1\t%A0, %1%O0 glc\;" + ? "buffer_wbinvl1_vol\;global_store%o1\t%A0, %1%O0 %G1\;" "s_waitcnt\tvmcnt(0)\;buffer_wbinvl1_vol" + : TARGET_TARGET_SC_CACHE + ? "buffer_inv sc1\;global_store%o1\t%A0, %1%O0 %G1\;" + "s_waitcnt\tvmcnt(0)\;buffer_inv sc1" : "error: cache architecture unspecified"); } break; @@ -2254,9 +2278,9 @@ case 0: return "s_atomic_swap<X>\t%0, %1, %2 glc\;s_waitcnt\tlgkmcnt(0)"; case 1: - return "flat_atomic_swap<X>\t%0, %1, %2 glc\;s_waitcnt\t0"; + return "flat_atomic_swap<X>\t%0, %1, %2 %G1\;s_waitcnt\t0"; case 2: - return "global_atomic_swap<X>\t%0, %A1, %2%O1 glc\;" + return "global_atomic_swap<X>\t%0, %A1, %2%O1 %G1\;" "s_waitcnt\tvmcnt(0)"; } break; @@ -2270,19 +2294,25 @@ "s_dcache_wb_vol\;s_dcache_inv_vol"; case 1: return (TARGET_GLn_CACHE - ? "flat_atomic_swap<X>\t%0, %1, %2 glc\;s_waitcnt\t0\;" + ? "flat_atomic_swap<X>\t%0, %1, %2 %G1\;s_waitcnt\t0\;" "buffer_gl1_inv\;buffer_gl0_inv" : TARGET_WBINVL1_CACHE - ? "flat_atomic_swap<X>\t%0, %1, %2 glc\;s_waitcnt\t0\;" + ? "flat_atomic_swap<X>\t%0, %1, %2 %G1\;s_waitcnt\t0\;" "buffer_wbinvl1_vol" + : TARGET_TARGET_SC_CACHE + ? "flat_atomic_swap<X>\t%0, %1, %2 %G1\;s_waitcnt\t0\;" + "buffer_inv sc1" : "error: cache architecture unspecified"); case 2: return (TARGET_GLn_CACHE - ? "global_atomic_swap<X>\t%0, %A1, %2%O1 glc\;" + ? "global_atomic_swap<X>\t%0, %A1, %2%O1 %G1\;" "s_waitcnt\tvmcnt(0)\;buffer_gl1_inv\;buffer_gl0_inv" : TARGET_WBINVL1_CACHE - ? "global_atomic_swap<X>\t%0, %A1, %2%O1 glc\;" + ? "global_atomic_swap<X>\t%0, %A1, %2%O1 %G1\;" "s_waitcnt\tvmcnt(0)\;buffer_wbinvl1_vol" + : TARGET_TARGET_SC_CACHE + ? "global_atomic_swap<X>\t%0, %A1, %2%O1 %G1\;" + "s_waitcnt\tvmcnt(0)\;buffer_inv sc1" : "error: cache architecture unspecified"); } break; @@ -2295,20 +2325,27 @@ "s_waitcnt\tlgkmcnt(0)"; case 1: return (TARGET_GLn_CACHE - ? "buffer_gl1_inv\;buffer_gl0_inv\;flat_atomic_swap<X>\t%0, %1, %2 glc\;" + ? "buffer_gl1_inv\;buffer_gl0_inv\;flat_atomic_swap<X>\t%0, %1, %2 %G1\;" "s_waitcnt\t0" : TARGET_WBINVL1_CACHE - ? "buffer_wbinvl1_vol\;flat_atomic_swap<X>\t%0, %1, %2 glc\;" + ? "buffer_wbinvl1_vol\;flat_atomic_swap<X>\t%0, %1, %2 %G1\;" + "s_waitcnt\t0" + : TARGET_TARGET_SC_CACHE + ? "buffer_inv sc1\;flat_atomic_swap<X>\t%0, %1, %2 %G1\;" "s_waitcnt\t0" : "error: cache architecture unspecified"); case 2: return (TARGET_GLn_CACHE ? "buffer_gl1_inv\;buffer_gl0_inv\;" - "global_atomic_swap<X>\t%0, %A1, %2%O1 glc\;" + "global_atomic_swap<X>\t%0, %A1, %2%O1 %G1\;" "s_waitcnt\tvmcnt(0)" : TARGET_WBINVL1_CACHE ? "buffer_wbinvl1_vol\;" - "global_atomic_swap<X>\t%0, %A1, %2%O1 glc\;" + "global_atomic_swap<X>\t%0, %A1, %2%O1 %G1\;" + "s_waitcnt\tvmcnt(0)" + : TARGET_TARGET_SC_CACHE + ? "buffer_inv sc1\;" + "global_atomic_swap<X>\t%0, %A1, %2%O1 %G1\;" "s_waitcnt\tvmcnt(0)" : "error: cache architecture unspecified"); } @@ -2323,21 +2360,28 @@ "s_waitcnt\tlgkmcnt(0)\;s_dcache_inv_vol"; case 1: return (TARGET_GLn_CACHE - ? "buffer_gl1_inv\;buffer_gl0_inv\;flat_atomic_swap<X>\t%0, %1, %2 glc\;" + ? "buffer_gl1_inv\;buffer_gl0_inv\;flat_atomic_swap<X>\t%0, %1, %2 %G1\;" "s_waitcnt\t0\;buffer_gl1_inv\;buffer_gl0_inv" : TARGET_WBINVL1_CACHE - ? "buffer_wbinvl1_vol\;flat_atomic_swap<X>\t%0, %1, %2 glc\;" + ? "buffer_wbinvl1_vol\;flat_atomic_swap<X>\t%0, %1, %2 %G1\;" "s_waitcnt\t0\;buffer_wbinvl1_vol" + : TARGET_TARGET_SC_CACHE + ? "buffer_inv sc1\;flat_atomic_swap<X>\t%0, %1, %2 %G1\;" + "s_waitcnt\t0\;buffer_inv sc1" : "error: cache architecture unspecified"); case 2: return (TARGET_GLn_CACHE ? "buffer_gl1_inv\;buffer_gl0_inv\;" - "global_atomic_swap<X>\t%0, %A1, %2%O1 glc\;" + "global_atomic_swap<X>\t%0, %A1, %2%O1 %G1\;" "s_waitcnt\tvmcnt(0)\;buffer_gl1_inv\;buffer_gl0_inv" : TARGET_WBINVL1_CACHE ? "buffer_wbinvl1_vol\;" - "global_atomic_swap<X>\t%0, %A1, %2%O1 glc\;" + "global_atomic_swap<X>\t%0, %A1, %2%O1 %G1\;" "s_waitcnt\tvmcnt(0)\;buffer_wbinvl1_vol" + : TARGET_TARGET_SC_CACHE + ? "buffer_inv sc1\;" + "global_atomic_swap<X>\t%0, %A1, %2%O1 %G1\;" + "s_waitcnt\tvmcnt(0)\;buffer_inv sc1" : "error: cache architecture unspecified"); } break; diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h index 6b2dd6511b3a..8018b63965de 100644 --- a/gcc/config/h8300/h8300.h +++ b/gcc/config/h8300/h8300.h @@ -610,6 +610,12 @@ struct cum_arg #define DATA_SECTION_ASM_OP "\t.section .data" #define BSS_SECTION_ASM_OP "\t.section .bss" +/* Override default definitions from elfos.h. */ +#undef INIT_SECTION_ASM_OP +#define INIT_SECTION_ASM_OP "\t.section\t.init,\"ax\"" +#undef FINI_SECTION_ASM_OP +#define FINI_SECTION_ASM_OP "\t.section\t.fini,\"ax\"" + #undef DO_GLOBAL_CTORS_BODY #define DO_GLOBAL_CTORS_BODY \ { \ @@ -647,19 +653,11 @@ struct cum_arg /* Globalizing directive for a label. */ #define GLOBAL_ASM_OP "\t.global " +/* Override default definition from elfos.h. */ +#undef ASM_DECLARE_FUNCTION_NAME #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ ASM_OUTPUT_FUNCTION_LABEL (FILE, NAME, DECL) -/* This is how to store into the string LABEL - the symbol_ref name of an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. - This is suitable for output with `assemble_name'. - - N.B.: The h8300.md branch_true and branch_false patterns also know - how to generate internal labels. */ -#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ - sprintf (LABEL, "*.%s%lu", PREFIX, (unsigned long)(NUM)) - /* This is how to output an insn to push a register on the stack. It need not be very fast code. */ @@ -690,9 +688,6 @@ struct cum_arg if ((LOG) != 0) \ fprintf (FILE, "\t.align %d\n", (LOG)) -#define ASM_OUTPUT_SKIP(FILE, SIZE) \ - fprintf (FILE, "\t.space %d\n", (int)(SIZE)) - /* This says how to output an assembler line to define a global common symbol. */ diff --git a/gcc/config/i386/driver-i386.cc b/gcc/config/i386/driver-i386.cc index 63c7d79326d1..fe71f550075e 100644 --- a/gcc/config/i386/driver-i386.cc +++ b/gcc/config/i386/driver-i386.cc @@ -600,7 +600,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) if (has_feature (FEATURE_AVX512F)) { /* Assume Diamond Rapids. */ - if (has_feature (FEATURE_AMX_TRANSPOSE)) + if (has_feature (FEATURE_AMX_FP8)) cpu = "diamondrapids"; /* Assume Granite Rapids D. */ else if (has_feature (FEATURE_AMX_COMPLEX)) diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 181e64a86bf6..09aa9b1461cc 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -387,7 +387,7 @@ ix86_expand_move (machine_mode mode, rtx operands[]) tmp = XEXP (op1, 0); if (GET_CODE (tmp) != PLUS - || GET_CODE (XEXP (tmp, 0)) != SYMBOL_REF) + || !SYMBOL_REF_P (XEXP (tmp, 0))) break; op1 = XEXP (tmp, 0); @@ -487,7 +487,7 @@ ix86_expand_move (machine_mode mode, rtx operands[]) op1 = machopic_legitimize_pic_address (op1, mode, tmp == op1 ? 0 : tmp); } - if (op0 != op1 && GET_CODE (op0) != MEM) + if (op0 != op1 && !MEM_P (op0)) { rtx insn = gen_rtx_SET (op0, op1); emit_insn (insn); @@ -1396,11 +1396,11 @@ ix86_expand_vector_logical_operator (enum rtx_code code, machine_mode mode, to cast them temporarily to integer vectors. */ if (op1 && !TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL - && (SUBREG_P (op2) || GET_CODE (op2) == CONST_VECTOR) + && (SUBREG_P (op2) || CONST_VECTOR_P (op2)) && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op1))) == MODE_VECTOR_FLOAT && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1))) == GET_MODE_SIZE (mode) && SUBREG_BYTE (op1) == 0 - && (GET_CODE (op2) == CONST_VECTOR + && (CONST_VECTOR_P (op2) || (GET_MODE (SUBREG_REG (op1)) == GET_MODE (SUBREG_REG (op2)) && SUBREG_BYTE (op2) == 0)) && can_create_pseudo_p ()) @@ -1415,7 +1415,7 @@ ix86_expand_vector_logical_operator (enum rtx_code code, machine_mode mode, case E_V4DFmode: case E_V8DFmode: dst = gen_reg_rtx (GET_MODE (SUBREG_REG (op1))); - if (GET_CODE (op2) == CONST_VECTOR) + if (CONST_VECTOR_P (op2)) { op2 = gen_lowpart (GET_MODE (dst), op2); op2 = force_reg (GET_MODE (dst), op2); @@ -3609,7 +3609,11 @@ ix86_expand_int_movcc (rtx operands[]) negate_cc_compare_p = true; } - diff = ct - cf; + diff = (unsigned HOST_WIDE_INT) ct - cf; + /* Make sure we can represent the difference between the two values. */ + if ((diff > 0) != ((cf < 0) != (ct < 0) ? cf < 0 : cf < ct)) + return false; + /* Sign bit compares are better done using shifts than we do by using sbb. */ if (sign_bit_compare_p @@ -3667,7 +3671,12 @@ ix86_expand_int_movcc (rtx operands[]) PUT_CODE (compare_op, reverse_condition (GET_CODE (compare_op))); } - diff = ct - cf; + + diff = (unsigned HOST_WIDE_INT) ct - cf; + /* Make sure we can represent the difference + between the two values. */ + if ((diff > 0) != ((cf < 0) != (ct < 0) ? cf < 0 : cf < ct)) + return false; if (reg_overlap_mentioned_p (out, compare_op)) tmp = gen_reg_rtx (mode); @@ -3685,7 +3694,12 @@ ix86_expand_int_movcc (rtx operands[]) else { std::swap (ct, cf); - diff = ct - cf; + + diff = (unsigned HOST_WIDE_INT) ct - cf; + /* Make sure we can represent the difference + between the two values. */ + if ((diff > 0) != ((cf < 0) != (ct < 0) ? cf < 0 : cf < ct)) + return false; } tmp = emit_store_flag (tmp, code, op0, op1, VOIDmode, 0, -1); } @@ -3752,9 +3766,15 @@ ix86_expand_int_movcc (rtx operands[]) tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1); } + HOST_WIDE_INT ival = (unsigned HOST_WIDE_INT) cf - ct; + /* Make sure we can represent the difference + between the two values. */ + if ((ival > 0) != ((ct < 0) != (cf < 0) ? ct < 0 : ct < cf)) + return false; + tmp = expand_simple_binop (mode, AND, copy_rtx (tmp), - gen_int_mode (cf - ct, mode), + gen_int_mode (ival, mode), copy_rtx (tmp), 1, OPTAB_DIRECT); if (ct) tmp = expand_simple_binop (mode, PLUS, @@ -3791,7 +3811,13 @@ ix86_expand_int_movcc (rtx operands[]) if (new_code != UNKNOWN) { std::swap (ct, cf); - diff = -diff; + + diff = (unsigned HOST_WIDE_INT) ct - cf; + /* Make sure we can represent the difference + between the two values. */ + if ((diff > 0) != ((cf < 0) != (ct < 0) ? cf < 0 : cf < ct)) + return false; + code = new_code; } } @@ -3994,8 +4020,14 @@ ix86_expand_int_movcc (rtx operands[]) copy_rtx (out), 1, OPTAB_DIRECT); } + HOST_WIDE_INT ival = (unsigned HOST_WIDE_INT) cf - ct; + /* Make sure we can represent the difference + between the two values. */ + if ((ival > 0) != ((ct < 0) != (cf < 0) ? ct < 0 : ct < cf)) + return false; + out = expand_simple_binop (mode, AND, copy_rtx (out), - gen_int_mode (cf - ct, mode), + gen_int_mode (ival, mode), copy_rtx (out), 1, OPTAB_DIRECT); if (ct) out = expand_simple_binop (mode, PLUS, copy_rtx (out), GEN_INT (ct), @@ -4886,7 +4918,7 @@ ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, rtx cop0, rtx cop1, case LEU: /* x <= cst can be handled as x < cst + 1 unless there is wrap around in cst + 1. */ - if (GET_CODE (cop1) == CONST_VECTOR + if (CONST_VECTOR_P (cop1) && GET_MODE_INNER (mode) != TImode) { unsigned int n_elts = GET_MODE_NUNITS (mode), i; @@ -4930,7 +4962,7 @@ ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, rtx cop0, rtx cop1, case GEU: /* x >= cst can be handled as x > cst - 1 unless there is wrap around in cst - 1. */ - if (GET_CODE (cop1) == CONST_VECTOR + if (CONST_VECTOR_P (cop1) && GET_MODE_INNER (mode) != TImode) { unsigned int n_elts = GET_MODE_NUNITS (mode), i; @@ -5001,9 +5033,9 @@ ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, rtx cop0, rtx cop1, } } - if (GET_CODE (cop0) == CONST_VECTOR) + if (CONST_VECTOR_P (cop0)) cop0 = force_reg (mode, cop0); - else if (GET_CODE (cop1) == CONST_VECTOR) + else if (CONST_VECTOR_P (cop1)) cop1 = force_reg (mode, cop1); rtx optrue = op_true ? op_true : CONSTM1_RTX (data_mode); @@ -5202,7 +5234,7 @@ ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, rtx cop0, rtx cop1, if (*negate) std::swap (op_true, op_false); - if (GET_CODE (cop1) == CONST_VECTOR) + if (CONST_VECTOR_P (cop1)) cop1 = force_reg (mode, cop1); /* Allow the comparison to be done in one mode, but the movcc to @@ -6156,7 +6188,7 @@ ix86_extract_perm_from_pool_constant (int* perm, rtx mem) rtx constant = get_pool_constant (XEXP (mem, 0)); - if (GET_CODE (constant) != CONST_VECTOR) + if (!CONST_VECTOR_P (constant)) return false; /* There could be some rtx like @@ -6166,7 +6198,7 @@ ix86_extract_perm_from_pool_constant (int* perm, rtx mem) { constant = simplify_subreg (mode, constant, GET_MODE (constant), 0); - if (constant == nullptr || GET_CODE (constant) != CONST_VECTOR) + if (constant == nullptr || !CONST_VECTOR_P (constant)) return false; } @@ -6212,7 +6244,7 @@ ix86_split_to_parts (rtx operand, rtx *parts, machine_mode mode) return size; } - if (GET_CODE (operand) == CONST_VECTOR) + if (CONST_VECTOR_P (operand)) { scalar_int_mode imode = int_mode_for_mode (mode).require (); /* Caution: if we looked through a constant pool memory above, @@ -6346,7 +6378,7 @@ ix86_split_long_move (rtx operands[]) fp moves, that force all constants to memory to allow combining. */ if (MEM_P (operands[1]) - && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF + && SYMBOL_REF_P (XEXP (operands[1], 0)) && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))) operands[1] = get_pool_constant (XEXP (operands[1], 0)); if (push_operand (operands[0], VOIDmode)) @@ -7867,7 +7899,8 @@ expand_set_or_cpymem_via_loop (rtx destmem, rtx srcmem, rtx count, machine_mode mode, int unroll, int expected_size, bool issetmem) { - rtx_code_label *out_label, *top_label; + rtx_code_label *out_label = nullptr; + rtx_code_label *top_label = nullptr; rtx iter, tmp; machine_mode iter_mode = counter_mode (count); int piece_size_n = GET_MODE_SIZE (mode) * unroll; @@ -7875,9 +7908,19 @@ expand_set_or_cpymem_via_loop (rtx destmem, rtx srcmem, rtx piece_size_mask = GEN_INT (~((GET_MODE_SIZE (mode) * unroll) - 1)); rtx size; int i; + int loop_count; - top_label = gen_label_rtx (); - out_label = gen_label_rtx (); + if (expected_size != -1 && CONST_INT_P (count)) + loop_count = INTVAL (count) / GET_MODE_SIZE (mode) / unroll; + else + loop_count = -1; + + /* Don't generate the loop if the loop count is 1. */ + if (loop_count != 1) + { + top_label = gen_label_rtx (); + out_label = gen_label_rtx (); + } iter = gen_reg_rtx (iter_mode); size = expand_simple_binop (iter_mode, AND, count, piece_size_mask, @@ -7891,7 +7934,8 @@ expand_set_or_cpymem_via_loop (rtx destmem, rtx srcmem, } emit_move_insn (iter, const0_rtx); - emit_label (top_label); + if (loop_count != 1) + emit_label (top_label); tmp = convert_modes (Pmode, iter_mode, iter, true); @@ -7959,21 +8003,25 @@ expand_set_or_cpymem_via_loop (rtx destmem, rtx srcmem, if (tmp != iter) emit_move_insn (iter, tmp); - emit_cmp_and_jump_insns (iter, size, LT, NULL_RTX, iter_mode, - true, top_label); - if (expected_size != -1) + if (loop_count != 1) { - expected_size /= GET_MODE_SIZE (mode) * unroll; - if (expected_size == 0) - predict_jump (0); - else if (expected_size > REG_BR_PROB_BASE) - predict_jump (REG_BR_PROB_BASE - 1); + emit_cmp_and_jump_insns (iter, size, LT, NULL_RTX, iter_mode, + true, top_label); + if (expected_size != -1) + { + expected_size /= GET_MODE_SIZE (mode) * unroll; + if (expected_size == 0) + predict_jump (0); + else if (expected_size > REG_BR_PROB_BASE) + predict_jump (REG_BR_PROB_BASE - 1); + else + predict_jump (REG_BR_PROB_BASE + - (REG_BR_PROB_BASE + expected_size / 2) + / expected_size); + } else - predict_jump (REG_BR_PROB_BASE - (REG_BR_PROB_BASE + expected_size / 2) - / expected_size); + predict_jump (REG_BR_PROB_BASE * 80 / 100); } - else - predict_jump (REG_BR_PROB_BASE * 80 / 100); iter = ix86_zero_extend_to_Pmode (iter); tmp = expand_simple_binop (Pmode, PLUS, destptr, iter, destptr, true, OPTAB_LIB_WIDEN); @@ -7986,7 +8034,8 @@ expand_set_or_cpymem_via_loop (rtx destmem, rtx srcmem, if (tmp != srcptr) emit_move_insn (srcptr, tmp); } - emit_label (out_label); + if (loop_count != 1) + emit_label (out_label); } /* Divide COUNTREG by SCALE. */ @@ -8189,19 +8238,11 @@ expand_cpymem_epilogue (rtx destmem, rtx srcmem, rtx src, dest; if (CONST_INT_P (count)) { - HOST_WIDE_INT countval = INTVAL (count); - HOST_WIDE_INT epilogue_size = countval % max_size; - int i; - - /* For now MAX_SIZE should be a power of 2. This assert could be - relaxed, but it'll require a bit more complicated epilogue - expanding. */ - gcc_assert ((max_size & (max_size - 1)) == 0); - for (i = max_size; i >= 1; i >>= 1) - { - if (epilogue_size & i) - destmem = emit_memmov (destmem, &srcmem, destptr, srcptr, i); - } + unsigned HOST_WIDE_INT countval = UINTVAL (count); + unsigned HOST_WIDE_INT epilogue_size = countval % max_size; + unsigned int destalign = MEM_ALIGN (destmem); + move_by_pieces (destmem, srcmem, epilogue_size, destalign, + RETURN_BEGIN); return; } if (max_size > 8) @@ -8362,6 +8403,81 @@ expand_setmem_epilogue_via_loop (rtx destmem, rtx destptr, rtx value, 1, max_size / 2, true); } +/* Callback routine for store_by_pieces. Return the RTL of a register + containing GET_MODE_SIZE (MODE) bytes in the RTL register op_p which + is a word or a word vector register. If PREV_P isn't nullptr, it + has the RTL info from the previous iteration. */ + +static rtx +setmem_epilogue_gen_val (void *op_p, void *prev_p, HOST_WIDE_INT, + fixed_size_mode mode) +{ + rtx target; + by_pieces_prev *prev = (by_pieces_prev *) prev_p; + if (prev) + { + rtx prev_op = prev->data; + if (prev_op) + { + machine_mode prev_mode = GET_MODE (prev_op); + if (prev_mode == mode) + return prev_op; + if (VECTOR_MODE_P (prev_mode) + && VECTOR_MODE_P (mode) + && GET_MODE_INNER (prev_mode) == GET_MODE_INNER (mode)) + { + target = gen_rtx_SUBREG (mode, prev_op, 0); + return target; + } + } + } + + rtx op = (rtx) op_p; + machine_mode op_mode = GET_MODE (op); + + gcc_assert (op_mode == word_mode + || (VECTOR_MODE_P (op_mode) + && GET_MODE_INNER (op_mode) == word_mode)); + + if (VECTOR_MODE_P (mode)) + { + gcc_assert (GET_MODE_INNER (mode) == QImode); + + unsigned int op_size = GET_MODE_SIZE (op_mode); + unsigned int size = GET_MODE_SIZE (mode); + unsigned int nunits = op_size / GET_MODE_SIZE (QImode); + machine_mode vec_mode + = mode_for_vector (QImode, nunits).require (); + target = gen_reg_rtx (vec_mode); + op = gen_rtx_SUBREG (vec_mode, op, 0); + emit_move_insn (target, op); + if (op_size == size) + return target; + + rtx tmp = gen_reg_rtx (mode); + target = gen_rtx_SUBREG (mode, target, 0); + emit_move_insn (tmp, target); + return tmp; + } + + target = gen_reg_rtx (word_mode); + if (VECTOR_MODE_P (op_mode)) + { + op = gen_rtx_SUBREG (word_mode, op, 0); + emit_move_insn (target, op); + } + else + target = op; + + if (mode == word_mode) + return target; + + rtx tmp = gen_reg_rtx (mode); + target = gen_rtx_SUBREG (mode, target, 0); + emit_move_insn (tmp, target); + return tmp; +} + /* Output code to set at most count & (max_size - 1) bytes starting by DEST. */ static void expand_setmem_epilogue (rtx destmem, rtx destptr, rtx value, rtx vec_value, @@ -8371,24 +8487,12 @@ expand_setmem_epilogue (rtx destmem, rtx destptr, rtx value, rtx vec_value, if (CONST_INT_P (count)) { - HOST_WIDE_INT countval = INTVAL (count); - HOST_WIDE_INT epilogue_size = countval % max_size; - int i; - - /* For now MAX_SIZE should be a power of 2. This assert could be - relaxed, but it'll require a bit more complicated epilogue - expanding. */ - gcc_assert ((max_size & (max_size - 1)) == 0); - for (i = max_size; i >= 1; i >>= 1) - { - if (epilogue_size & i) - { - if (vec_value && i > GET_MODE_SIZE (GET_MODE (value))) - destmem = emit_memset (destmem, destptr, vec_value, i); - else - destmem = emit_memset (destmem, destptr, value, i); - } - } + unsigned HOST_WIDE_INT countval = UINTVAL (count); + unsigned HOST_WIDE_INT epilogue_size = countval % max_size; + unsigned int destalign = MEM_ALIGN (destmem); + store_by_pieces (destmem, epilogue_size, setmem_epilogue_gen_val, + vec_value ? vec_value : value, destalign, true, + RETURN_BEGIN); return; } if (max_size > 32) @@ -8520,6 +8624,7 @@ expand_small_cpymem_or_setmem (rtx destmem, rtx srcmem, rtx_code_label *label = ix86_expand_aligntest (count, size, false); machine_mode mode = int_mode_for_size (size * BITS_PER_UNIT, 1).else_blk (); rtx modesize; + rtx scalar_value = value; int n; /* If we do not have vector value to copy, we must reduce size. */ @@ -8539,11 +8644,57 @@ expand_small_cpymem_or_setmem (rtx destmem, rtx srcmem, { /* Choose appropriate vector mode. */ if (size >= 32) - mode = TARGET_AVX ? V32QImode : TARGET_SSE ? V16QImode : DImode; + switch (MOVE_MAX) + { + case 64: + if (size >= 64) + { + mode = V64QImode; + break; + } + /* FALLTHRU */ + case 32: + mode = V32QImode; + break; + case 16: + mode = V16QImode; + break; + case 8: + mode = DImode; + break; + default: + gcc_unreachable (); + } else if (size >= 16) mode = TARGET_SSE ? V16QImode : DImode; srcmem = change_address (srcmem, mode, srcptr); } + if (issetmem && vec_value && GET_MODE_SIZE (mode) > size) + { + /* For memset with vector and the size is smaller than the vector + size, first try the narrower vector, otherwise, use the + original value. */ + machine_mode inner_mode = GET_MODE_INNER (mode); + unsigned int nunits = size / GET_MODE_SIZE (inner_mode); + if (nunits > 1) + { + mode = mode_for_vector (GET_MODE_INNER (mode), + nunits).require (); + value = gen_rtx_SUBREG (mode, value, 0); + } + else + { + scalar_int_mode smode + = smallest_int_mode_for_size (size * BITS_PER_UNIT).require (); + gcc_assert (GET_MODE_SIZE (GET_MODE (scalar_value)) + >= GET_MODE_SIZE (smode)); + mode = smode; + if (GET_MODE (scalar_value) == mode) + value = scalar_value; + else + value = gen_rtx_SUBREG (mode, scalar_value, 0); + } + } destmem = change_address (destmem, mode, destptr); modesize = GEN_INT (GET_MODE_SIZE (mode)); gcc_assert (GET_MODE_SIZE (mode) <= size); @@ -9147,13 +9298,26 @@ decide_alignment (int align, static rtx promote_duplicated_reg (machine_mode mode, rtx val) { + if (val == const0_rtx) + return copy_to_mode_reg (mode, CONST0_RTX (mode)); + machine_mode valmode = GET_MODE (val); + if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) + { + /* Duplicate the scalar value for integer vector. */ + gcc_assert ((val == const0_rtx || val == constm1_rtx) + || GET_MODE_INNER (mode) == valmode); + rtx dup = gen_reg_rtx (mode); + bool ok = ix86_expand_vector_init_duplicate (false, mode, dup, + val); + gcc_assert (ok); + return dup; + } + rtx tmp; int nops = mode == DImode ? 3 : 2; - gcc_assert (mode == SImode || mode == DImode || val == const0_rtx); - if (val == const0_rtx) - return copy_to_mode_reg (mode, CONST0_RTX (mode)); + gcc_assert (mode == SImode || mode == DImode); if (CONST_INT_P (val)) { HOST_WIDE_INT v = INTVAL (val) & 255; @@ -9319,7 +9483,6 @@ ix86_expand_set_or_cpymem (rtx dst, rtx src, rtx count_exp, rtx val_exp, bool need_zero_guard = false; bool noalign; machine_mode move_mode = VOIDmode; - machine_mode wider_mode; int unroll_factor = 1; /* TODO: Once value ranges are available, fill in proper data. */ unsigned HOST_WIDE_INT min_size = 0; @@ -9382,11 +9545,6 @@ ix86_expand_set_or_cpymem (rtx dst, rtx src, rtx count_exp, rtx val_exp, return false; gcc_assert (alg != no_stringop); - /* For now vector-version of memset is generated only for memory zeroing, as - creating of promoted vector value is very cheap in this case. */ - if (issetmem && alg == vector_loop && val_exp != const0_rtx) - alg = unrolled_loop; - if (!count) count_exp = copy_to_mode_reg (GET_MODE (count_exp), count_exp); destreg = ix86_copy_addr_to_reg (XEXP (dst, 0)); @@ -9395,6 +9553,7 @@ ix86_expand_set_or_cpymem (rtx dst, rtx src, rtx count_exp, rtx val_exp, unroll_factor = 1; move_mode = word_mode; + int nunits; switch (alg) { case libcall: @@ -9415,27 +9574,14 @@ ix86_expand_set_or_cpymem (rtx dst, rtx src, rtx count_exp, rtx val_exp, case vector_loop: need_zero_guard = true; unroll_factor = 4; - /* Find the widest supported mode. */ - move_mode = word_mode; - while (GET_MODE_WIDER_MODE (move_mode).exists (&wider_mode) - && optab_handler (mov_optab, wider_mode) != CODE_FOR_nothing) - move_mode = wider_mode; - - if (TARGET_AVX256_SPLIT_REGS && GET_MODE_BITSIZE (move_mode) > 128) - move_mode = TImode; - if (TARGET_AVX512_SPLIT_REGS && GET_MODE_BITSIZE (move_mode) > 256) - move_mode = OImode; - - /* Find the corresponding vector mode with the same size as MOVE_MODE. - MOVE_MODE is an integer mode at the moment (SI, DI, TI, etc.). */ - if (GET_MODE_SIZE (move_mode) > GET_MODE_SIZE (word_mode)) + /* Get the vector mode to move MOVE_MAX bytes. */ + nunits = MOVE_MAX / GET_MODE_SIZE (word_mode); + if (nunits > 1) { - int nunits = GET_MODE_SIZE (move_mode) / GET_MODE_SIZE (word_mode); - if (!mode_for_vector (word_mode, nunits).exists (&move_mode) - || optab_handler (mov_optab, move_mode) == CODE_FOR_nothing) - move_mode = word_mode; + move_mode = mode_for_vector (word_mode, nunits).require (); + gcc_assert (optab_handler (mov_optab, move_mode) + != CODE_FOR_nothing); } - gcc_assert (optab_handler (mov_optab, move_mode) != CODE_FOR_nothing); break; case rep_prefix_8_byte: move_mode = DImode; @@ -9491,20 +9637,41 @@ ix86_expand_set_or_cpymem (rtx dst, rtx src, rtx count_exp, rtx val_exp, && ((desired_align > align && !align_bytes) || (!count && epilogue_size_needed > 1))); + /* Destination is aligned after the misaligned prologue. */ + bool aligned_dstmem = misaligned_prologue_used; + + if (noalign && !misaligned_prologue_used) + { + /* Also use misaligned prologue if alignment isn't needed and + destination isn't aligned. Since alignment isn't needed, + the destination after prologue won't be aligned. */ + aligned_dstmem = (GET_MODE_ALIGNMENT (move_mode) + <= MEM_ALIGN (dst)); + if (!aligned_dstmem) + misaligned_prologue_used = true; + } + /* Do the cheap promotion to allow better CSE across the main loop and epilogue (ie one load of the big constant in the front of all code. For now the misaligned move sequences do not have fast path without broadcasting. */ - if (issetmem && ((CONST_INT_P (val_exp) || misaligned_prologue_used))) + if (issetmem + && (alg == vector_loop + || CONST_INT_P (val_exp) + || misaligned_prologue_used)) { if (alg == vector_loop) { - gcc_assert (val_exp == const0_rtx); - vec_promoted_val = promote_duplicated_reg (move_mode, val_exp); promoted_val = promote_duplicated_reg_to_size (val_exp, GET_MODE_SIZE (word_mode), desired_align, align); + /* Duplicate the promoted scalar value if not 0 nor -1. */ + vec_promoted_val + = promote_duplicated_reg (move_mode, + (val_exp == const0_rtx + || val_exp == constm1_rtx) + ? val_exp : promoted_val); } else { @@ -9529,7 +9696,8 @@ ix86_expand_set_or_cpymem (rtx dst, rtx src, rtx count_exp, rtx val_exp, if (!issetmem) src = change_address (src, BLKmode, srcreg); dst = change_address (dst, BLKmode, destreg); - set_mem_align (dst, desired_align * BITS_PER_UNIT); + if (aligned_dstmem) + set_mem_align (dst, desired_align * BITS_PER_UNIT); epilogue_size_needed = 0; if (need_zero_guard && min_size < (unsigned HOST_WIDE_INT) size_needed) @@ -10077,7 +10245,7 @@ construct_plt_address (rtx symbol) { rtx tmp, unspec; - gcc_assert (GET_CODE (symbol) == SYMBOL_REF); + gcc_assert (SYMBOL_REF_P (symbol)); gcc_assert (ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF); gcc_assert (Pmode == DImode); @@ -10111,7 +10279,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, tree fndecl; bool call_no_callee_saved_registers = false; - if (GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF) + if (SYMBOL_REF_P (XEXP (fnaddr, 0))) { fndecl = SYMBOL_REF_DECL (XEXP (fnaddr, 0)); if (fndecl) @@ -10119,9 +10287,11 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, if (lookup_attribute ("interrupt", TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))) error ("interrupt service routine cannot be called directly"); - else if (lookup_attribute ("no_callee_saved_registers", - TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))) + else if (ix86_type_no_callee_saved_registers_p (TREE_TYPE (fndecl))) call_no_callee_saved_registers = true; + if (fndecl == current_function_decl + && decl_binds_to_current_def_p (fndecl)) + cfun->machine->recursive_function = true; } } else @@ -10131,8 +10301,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, tree mem_expr = MEM_EXPR (fnaddr); if (mem_expr != nullptr && TREE_CODE (mem_expr) == MEM_REF - && lookup_attribute ("no_callee_saved_registers", - TYPE_ATTRIBUTES (TREE_TYPE (mem_expr)))) + && ix86_type_no_callee_saved_registers_p (TREE_TYPE (mem_expr))) call_no_callee_saved_registers = true; } @@ -10147,7 +10316,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, if (TARGET_MACHO && !TARGET_64BIT) { #if TARGET_MACHO - if (flag_pic && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF) + if (flag_pic && SYMBOL_REF_P (XEXP (fnaddr, 0))) fnaddr = machopic_indirect_call_target (fnaddr); #endif } @@ -10157,7 +10326,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, check if PLT was explicitly avoided via no-plt or "noplt" attribute, making it an indirect call. */ if (flag_pic - && GET_CODE (addr) == SYMBOL_REF + && SYMBOL_REF_P (addr) && ix86_call_use_plt_p (addr)) { if (flag_plt @@ -10231,7 +10400,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, if (ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF && MEM_P (fnaddr) - && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF + && SYMBOL_REF_P (XEXP (fnaddr, 0)) && !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode)) fnaddr = gen_rtx_MEM (QImode, construct_plt_address (XEXP (fnaddr, 0))); /* Since x32 GOT slot is 64 bit with zero upper 32 bits, indirect @@ -10334,7 +10503,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, } if (TARGET_MACHO && TARGET_64BIT && !sibcall - && ((GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr)) + && ((SYMBOL_REF_P (addr) && !SYMBOL_REF_LOCAL_P (addr)) || !fndecl || TREE_PUBLIC (fndecl))) { /* We allow public functions defined in a TU to bind locally for PIC @@ -10357,6 +10526,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, char c_mask = CALL_USED_REGISTERS_MASK (is_64bit_ms_abi); for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (!fixed_regs[i] + && i != HARD_FRAME_POINTER_REGNUM && !(ix86_call_used_regs[i] == 1 || (ix86_call_used_regs[i] & c_mask)) && !STACK_REGNO_P (i) @@ -12442,7 +12612,7 @@ ix86_expand_args_builtin (const struct builtin_description *d, static rtx ix86_erase_embedded_rounding (rtx pat) { - if (GET_CODE (pat) == INSN) + if (NONJUMP_INSN_P (pat)) pat = PATTERN (pat); gcc_assert (GET_CODE (pat) == SET); @@ -25157,7 +25327,7 @@ const_vector_equal_evenodd_p (rtx op) { machine_mode mode = GET_MODE (op); int i, nunits = GET_MODE_NUNITS (mode); - if (GET_CODE (op) != CONST_VECTOR + if (!CONST_VECTOR_P (op) || nunits != CONST_VECTOR_NUNITS (op)) return false; for (i = 0; i < nunits; i += 2) @@ -25500,7 +25670,7 @@ ix86_notrack_prefixed_insn_p (rtx_insn *insn) /* Do not emit 'notrack' if it's not an indirect call. */ if (MEM_P (addr) - && GET_CODE (XEXP (addr, 0)) == SYMBOL_REF) + && SYMBOL_REF_P (XEXP (addr, 0))) return false; else return find_reg_note (insn, REG_CALL_NOCF_CHECK, 0); @@ -26317,8 +26487,8 @@ ix86_ternlog_idx (rtx op, rtx *args) if (rtx_equal_p (op, args[2])) return 0xaa; /* Check if CONST_VECTOR is the ones-complement of args[2]. */ - if (GET_CODE (op) == CONST_VECTOR - && GET_CODE (args[2]) == CONST_VECTOR + if (CONST_VECTOR_P (op) + && CONST_VECTOR_P (args[2]) && rtx_equal_p (simplify_const_unary_operation (NOT, GET_MODE (op), op, GET_MODE (op)), args[2])) @@ -26331,8 +26501,8 @@ ix86_ternlog_idx (rtx op, rtx *args) if (rtx_equal_p (op, args[0])) return 0xf0; /* Check if CONST_VECTOR is the ones-complement of args[0]. */ - if (GET_CODE (op) == CONST_VECTOR - && GET_CODE (args[0]) == CONST_VECTOR + if (CONST_VECTOR_P (op) + && CONST_VECTOR_P (args[0]) && rtx_equal_p (simplify_const_unary_operation (NOT, GET_MODE (op), op, GET_MODE (op)), args[0])) @@ -26345,8 +26515,8 @@ ix86_ternlog_idx (rtx op, rtx *args) if (rtx_equal_p (op, args[1])) return 0xcc; /* Check if CONST_VECTOR is the ones-complement of args[1]. */ - if (GET_CODE (op) == CONST_VECTOR - && GET_CODE (args[1]) == CONST_VECTOR + if (CONST_VECTOR_P (op) + && CONST_VECTOR_P (args[1]) && rtx_equal_p (simplify_const_unary_operation (NOT, GET_MODE (op), op, GET_MODE (op)), args[1])) @@ -26576,15 +26746,6 @@ ix86_expand_ternlog (machine_mode mode, rtx op0, rtx op1, rtx op2, int idx, && (!op2 || !side_effects_p (op2)) && op0) { - if (GET_MODE (op0) != mode) - op0 = gen_lowpart (mode, op0); - if (!TARGET_64BIT && !register_operand (op0, mode)) - { - /* Avoid force_reg (mode, op0). */ - rtx reg = gen_reg_rtx (mode); - emit_move_insn (reg, op0); - op0 = reg; - } emit_move_insn (target, gen_rtx_XOR (mode, op0, CONSTM1_RTX (mode))); return target; } @@ -26609,15 +26770,6 @@ ix86_expand_ternlog (machine_mode mode, rtx op0, rtx op1, rtx op2, int idx, && (!op2 || !side_effects_p (op2)) && op1) { - if (GET_MODE (op1) != mode) - op1 = gen_lowpart (mode, op1); - if (!TARGET_64BIT && !register_operand (op1, mode)) - { - /* Avoid force_reg (mode, op1). */ - rtx reg = gen_reg_rtx (mode); - emit_move_insn (reg, op1); - op1 = reg; - } emit_move_insn (target, gen_rtx_XOR (mode, op1, CONSTM1_RTX (mode))); return target; } @@ -26649,15 +26801,6 @@ ix86_expand_ternlog (machine_mode mode, rtx op0, rtx op1, rtx op2, int idx, && (!op1 || !side_effects_p (op1)) && op2) { - if (GET_MODE (op2) != mode) - op2 = gen_lowpart (mode, op2); - if (!TARGET_64BIT && !register_operand (op2, mode)) - { - /* Avoid force_reg (mode, op2). */ - rtx reg = gen_reg_rtx (mode); - emit_move_insn (reg, op2); - op2 = reg; - } emit_move_insn (target, gen_rtx_XOR (mode, op2, CONSTM1_RTX (mode))); return target; } diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index b1682c2fad44..c131577805fa 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -2141,7 +2141,7 @@ convertible_comparison_p (rtx_insn *insn, enum machine_mode mode) gcc_assert (GET_CODE (src) == COMPARE); - if (GET_CODE (dst) != REG + if (!REG_P (dst) || REGNO (dst) != FLAGS_REG || GET_MODE (dst) != CCZmode) return false; @@ -2953,7 +2953,7 @@ rest_of_insert_endbr_and_patchable_area (bool need_endbr, /* Also generate ENDBRANCH for non-tail call which may return via indirect branch. */ - if (GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF) + if (SYMBOL_REF_P (XEXP (fnaddr, 0))) fndecl = SYMBOL_REF_DECL (XEXP (fnaddr, 0)); if (fndecl == NULL_TREE) fndecl = MEM_EXPR (fnaddr); @@ -3088,10 +3088,12 @@ ix86_rpad_gate () /* Generate a vector set, DEST = SRC, at entry of the nearest dominator for basic block map BBS, which is in the fake loop that contains the whole function, so that there is only a single vector set in the - whole function. */ + whole function. If not nullptr, INNER_SCALAR is the inner scalar of + SRC, as (reg:SI 99) in (vec_duplicate:V4SI (reg:SI 99)). */ static void -ix86_place_single_vector_set (rtx dest, rtx src, bitmap bbs) +ix86_place_single_vector_set (rtx dest, rtx src, bitmap bbs, + rtx inner_scalar = nullptr) { basic_block bb = nearest_common_dominator_for_set (CDI_DOMINATORS, bbs); while (bb->loop_father->latch @@ -3112,10 +3114,51 @@ ix86_place_single_vector_set (rtx dest, rtx src, bitmap bbs) insn = NEXT_INSN (insn); } + rtx_insn *set_insn; if (insn == BB_HEAD (bb)) - emit_insn_before (set, insn); + { + set_insn = emit_insn_before (set, insn); + if (dump_file) + { + fprintf (dump_file, "\nPlace:\n\n"); + print_rtl_single (dump_file, set_insn); + fprintf (dump_file, "\nbefore:\n\n"); + print_rtl_single (dump_file, insn); + fprintf (dump_file, "\n"); + } + } else - emit_insn_after (set, insn ? PREV_INSN (insn) : BB_END (bb)); + { + rtx_insn *after = insn ? PREV_INSN (insn) : BB_END (bb); + set_insn = emit_insn_after (set, after); + if (dump_file) + { + fprintf (dump_file, "\nPlace:\n\n"); + print_rtl_single (dump_file, set_insn); + fprintf (dump_file, "\nafter:\n\n"); + print_rtl_single (dump_file, after); + fprintf (dump_file, "\n"); + } + } + + if (inner_scalar) + { + /* Set the source in (vec_duplicate:V4SI (reg:SI 99)). */ + rtx reg = XEXP (src, 0); + if ((REG_P (inner_scalar) || MEM_P (inner_scalar)) + && GET_MODE (reg) != GET_MODE (inner_scalar)) + inner_scalar = gen_rtx_SUBREG (GET_MODE (reg), inner_scalar, 0); + rtx set = gen_rtx_SET (reg, inner_scalar); + insn = emit_insn_before (set, set_insn); + if (dump_file) + { + fprintf (dump_file, "\nAdd:\n\n"); + print_rtl_single (dump_file, insn); + fprintf (dump_file, "\nbefore:\n\n"); + print_rtl_single (dump_file, set_insn); + fprintf (dump_file, "\n"); + } + } } /* At entry of the nearest common dominator for basic blocks with @@ -3346,26 +3389,24 @@ make_pass_remove_partial_avx_dependency (gcc::context *ctxt) return new pass_remove_partial_avx_dependency (ctxt); } -/* Return a machine mode suitable for vector SIZE. */ +/* Return a machine mode suitable for vector SIZE with SMODE inner + mode. */ static machine_mode -ix86_get_vector_load_mode (unsigned int size) +ix86_get_vector_cse_mode (unsigned int size, machine_mode smode) { - machine_mode mode; - if (size == 64) - mode = V64QImode; - else if (size == 32) - mode = V32QImode; - else if (size == 16) - mode = V16QImode; - else if (size == 8) - mode = V8QImode; - else if (size == 4) - mode = V4QImode; - else if (size == 2) - mode = V2QImode; - else - gcc_unreachable (); + /* Use the inner scalar mode of vector broadcast source in: + + (set (reg:V8DF 394) + (vec_duplicate:V8DF (reg:V2DF 190 [ alpha ]))) + + to compute the vector mode for broadcast from vector source. + */ + if (VECTOR_MODE_P (smode)) + smode = GET_MODE_INNER (smode); + scalar_mode s_mode = as_a <scalar_mode> (smode); + poly_uint64 nunits = size / GET_MODE_SIZE (smode); + machine_mode mode = mode_for_vector (s_mode, nunits).require (); return mode; } @@ -3374,7 +3415,8 @@ ix86_get_vector_load_mode (unsigned int size) static void replace_vector_const (machine_mode vector_mode, rtx vector_const, - auto_bitmap &vector_insns) + auto_bitmap &vector_insns, + machine_mode scalar_mode) { bitmap_iterator bi; unsigned int id; @@ -3386,7 +3428,8 @@ replace_vector_const (machine_mode vector_mode, rtx vector_const, /* Get the single SET instruction. */ rtx set = single_set (insn); rtx src = SET_SRC (set); - machine_mode mode = GET_MODE (src); + rtx dest = SET_DEST (set); + machine_mode mode = GET_MODE (dest); rtx replace; /* Replace the source operand with VECTOR_CONST. */ @@ -3400,7 +3443,8 @@ replace_vector_const (machine_mode vector_mode, rtx vector_const, /* If the mode size is smaller than its natural size, first insert an extra move with a QI vector SUBREG of the same size to avoid validate_subreg failure. */ - machine_mode vmode = ix86_get_vector_load_mode (size); + machine_mode vmode + = ix86_get_vector_cse_mode (size, scalar_mode); rtx vreg; if (mode == vmode) vreg = vector_const; @@ -3409,7 +3453,15 @@ replace_vector_const (machine_mode vector_mode, rtx vector_const, vreg = gen_reg_rtx (vmode); rtx vsubreg = gen_rtx_SUBREG (vmode, vector_const, 0); rtx pat = gen_rtx_SET (vreg, vsubreg); - emit_insn_before (pat, insn); + rtx_insn *vinsn = emit_insn_before (pat, insn); + if (dump_file) + { + fprintf (dump_file, "\nInsert an extra move:\n\n"); + print_rtl_single (dump_file, vinsn); + fprintf (dump_file, "\nbefore:\n\n"); + print_rtl_single (dump_file, insn); + fprintf (dump_file, "\n"); + } } replace = gen_rtx_SUBREG (mode, vreg, 0); } @@ -3417,15 +3469,206 @@ replace_vector_const (machine_mode vector_mode, rtx vector_const, replace = gen_rtx_SUBREG (mode, vector_const, 0); } + if (dump_file) + { + fprintf (dump_file, "\nReplace:\n\n"); + print_rtl_single (dump_file, insn); + } SET_SRC (set) = replace; /* Drop possible dead definitions. */ PATTERN (insn) = set; INSN_CODE (insn) = -1; recog_memoized (insn); + if (dump_file) + { + fprintf (dump_file, "\nwith:\n\n"); + print_rtl_single (dump_file, insn); + fprintf (dump_file, "\n"); + } df_insn_rescan (insn); } } +enum x86_cse_kind +{ + X86_CSE_CONST0_VECTOR, + X86_CSE_CONSTM1_VECTOR, + X86_CSE_VEC_DUP +}; + +struct redundant_load +{ + /* Bitmap of basic blocks with broadcast instructions. */ + auto_bitmap bbs; + /* Bitmap of broadcast instructions. */ + auto_bitmap insns; + /* The broadcast inner scalar. */ + rtx val; + /* The inner scalar mode. */ + machine_mode mode; + /* The instruction which sets the inner scalar. Nullptr if the inner + scalar is applied to the whole function, instead of within the same + block. */ + rtx_insn *def_insn; + /* The widest broadcast source. */ + rtx broadcast_source; + /* The widest broadcast register. */ + rtx broadcast_reg; + /* The basic block of the broadcast instruction. */ + basic_block bb; + /* The number of broadcast instructions with the same inner scalar. */ + unsigned HOST_WIDE_INT count; + /* The threshold of broadcast instructions with the same inner + scalar. */ + unsigned int threshold; + /* The widest broadcast size in bytes. */ + unsigned int size; + /* Load kind. */ + x86_cse_kind kind; +}; + +/* Return the inner scalar if OP is a broadcast, else return nullptr. */ + +static rtx +ix86_broadcast_inner (rtx op, machine_mode mode, + machine_mode *scalar_mode_p, + x86_cse_kind *kind_p, rtx_insn **insn_p) +{ + switch (standard_sse_constant_p (op, mode)) + { + case 1: + *scalar_mode_p = QImode; + *kind_p = X86_CSE_CONST0_VECTOR; + *insn_p = nullptr; + return const0_rtx; + case 2: + *scalar_mode_p = QImode; + *kind_p = X86_CSE_CONSTM1_VECTOR; + *insn_p = nullptr; + return constm1_rtx; + default: + break; + } + + mode = GET_MODE (op); + int nunits = GET_MODE_NUNITS (mode); + if (nunits < 2) + return nullptr; + + *kind_p = X86_CSE_VEC_DUP; + + rtx reg; + if (GET_CODE (op) == VEC_DUPLICATE) + { + /* Only + (vec_duplicate:V4SI (reg:SI 99)) + (vec_duplicate:V2DF (mem/u/c:DF (symbol_ref/u:DI ("*.LC1") [flags 0x2]) [0 S8 A64])) + are supported. Set OP to the broadcast source by default. */ + op = XEXP (op, 0); + reg = op; + if (SUBREG_P (op) + && SUBREG_BYTE (op) == 0 + && !paradoxical_subreg_p (op)) + reg = SUBREG_REG (op); + if (!REG_P (reg)) + { + if (MEM_P (op) + && SYMBOL_REF_P (XEXP (op, 0)) + && CONSTANT_POOL_ADDRESS_P (XEXP (op, 0))) + { + /* Handle constant broadcast from memory. */ + *scalar_mode_p = GET_MODE_INNER (mode); + *insn_p = nullptr; + return op; + } + return nullptr; + } + } + else if (CONST_VECTOR_P (op)) + { + rtx first = XVECEXP (op, 0, 0); + for (int i = 1; i < nunits; ++i) + { + rtx tmp = XVECEXP (op, 0, i); + /* Vector duplicate value. */ + if (!rtx_equal_p (tmp, first)) + return nullptr; + } + *scalar_mode_p = GET_MODE (first); + *insn_p = nullptr; + return first; + } + else + return nullptr; + + mode = GET_MODE (op); + + /* Only single def chain is supported. */ + df_ref ref = DF_REG_DEF_CHAIN (REGNO (reg)); + if (!ref + || DF_REF_IS_ARTIFICIAL (ref) + || DF_REF_NEXT_REG (ref) != nullptr) + return nullptr; + + rtx_insn *insn = DF_REF_INSN (ref); + rtx set = single_set (insn); + if (!set) + return nullptr; + + rtx src = SET_SRC (set); + + if (CONST_INT_P (src)) + { + /* Handle sequences like + + (set (reg:SI 99) + (const_int 34 [0x22])) + (set (reg:V4SI 98) + (vec_duplicate:V4SI (reg:SI 99))) + + Set *INSN_P to nullptr and return SET_SRC if SET_SRC is an + integer constant. */ + op = src; + *insn_p = nullptr; + } + else + { + /* Handle sequences like + + (set (reg:QI 105 [ c ]) + (reg:QI 5 di [ c ])) + (set (reg:V64QI 102 [ _1 ]) + (vec_duplicate:V64QI (reg:QI 105 [ c ]))) + + (set (reg/v:SI 116 [ argc ]) + (mem/c:SI (reg:SI 135) [2 argc+0 S4 A32])) + (set (reg:V4SI 119 [ _45 ]) + (vec_duplicate:V4SI (reg/v:SI 116 [ argc ]))) + + (set (reg:SI 98 [ _1 ]) + (sign_extend:SI (reg:QI 106 [ c ]))) + (set (reg:V16SI 103 [ _2 ]) + (vec_duplicate:V16SI (reg:SI 98 [ _1 ]))) + + (set (reg:SI 102 [ cost ]) + (mem/c:SI (symbol_ref:DI ("cost") [flags 0x40]))) + (set (reg:V4HI 103 [ _16 ]) + (vec_duplicate:V4HI (subreg:HI (reg:SI 102 [ cost ]) 0))) + + (set (subreg:SI (reg/v:HI 107 [ cr_val ]) 0) + (ashift:SI (reg:SI 158) + (subreg:QI (reg:SI 156 [ _2 ]) 0))) + (set (reg:V16HI 183 [ _61 ]) + (vec_duplicate:V16HI (reg/v:HI 107 [ cr_val ]))) + + Set *INSN_P to INSN and return the broadcast source otherwise. */ + *insn_p = insn; + } + + *scalar_mode_p = mode; + return op; +} + /* At entry of the nearest common dominator for basic blocks with vector CONST0_RTX and integer CONSTM1_RTX uses, generate a single widest vector set instruction for all CONST0_RTX and integer CONSTM1_RTX @@ -3440,20 +3683,16 @@ remove_redundant_vector_load (void) { timevar_push (TV_MACH_DEP); - auto_bitmap zero_bbs; - auto_bitmap m1_bbs; - auto_bitmap zero_insns; - auto_bitmap m1_insns; - + auto_vec<redundant_load *> loads; + redundant_load *load; basic_block bb; rtx_insn *insn; - unsigned HOST_WIDE_INT zero_count = 0; - unsigned HOST_WIDE_INT m1_count = 0; - unsigned int zero_size = 0; - unsigned int m1_size = 0; + unsigned int i; df_set_flags (DF_DEFER_INSN_RESCAN); + bool recursive_call_p = cfun->machine->recursive_function; + FOR_EACH_BB_FN (bb, cfun) { FOR_BB_INSNS (bb, insn) @@ -3481,82 +3720,182 @@ remove_redundant_vector_load (void) if (!REG_P (dest) && !SUBREG_P (dest)) continue; - if (src == CONST0_RTX (mode)) - { - /* Record vector instruction with CONST0_RTX. */ - bitmap_set_bit (zero_insns, INSN_UID (insn)); + rtx_insn *def_insn; + machine_mode scalar_mode; + x86_cse_kind kind; + rtx val = ix86_broadcast_inner (src, mode, &scalar_mode, + &kind, &def_insn); + if (!val) + continue; - /* Record the maximum vector size. */ - if (zero_size < GET_MODE_SIZE (mode)) - zero_size = GET_MODE_SIZE (mode); + /* Remove redundant register loads if there are more than 2 + loads will be used. */ + unsigned int threshold = 2; + + /* Check if there is a matching redundant vector load. */ + bool matched = false; + FOR_EACH_VEC_ELT (loads, i, load) + if (load->val + && load->kind == kind + && load->mode == scalar_mode + && (load->bb == bb + || kind < X86_CSE_VEC_DUP + /* Non all 0s/1s vector load must be in the same + basic block if it is in a recursive call. */ + || !recursive_call_p) + && rtx_equal_p (load->val, val)) + { + /* Record vector instruction. */ + bitmap_set_bit (load->insns, INSN_UID (insn)); - /* Record the basic block with CONST0_RTX. */ - bitmap_set_bit (zero_bbs, bb->index); - zero_count++; - } - else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT - && src == CONSTM1_RTX (mode)) - { - /* Record vector instruction with CONSTM1_RTX. */ - bitmap_set_bit (m1_insns, INSN_UID (insn)); + /* Record the maximum vector size. */ + if (load->size < GET_MODE_SIZE (mode)) + load->size = GET_MODE_SIZE (mode); - /* Record the maximum vector size. */ - if (m1_size < GET_MODE_SIZE (mode)) - m1_size = GET_MODE_SIZE (mode); + /* Record the basic block. */ + bitmap_set_bit (load->bbs, bb->index); + load->count++; + matched = true; + break; + } - /* Record the basic block with CONSTM1_RTX. */ - bitmap_set_bit (m1_bbs, bb->index); - m1_count++; - } - } - } + if (matched) + continue; - if (zero_count > 1 || m1_count > 1) - { - machine_mode zero_mode, m1_mode; - rtx vector_const0, vector_constm1; + /* We see this vector broadcast the first time. */ + load = new redundant_load; - if (zero_count > 1) - { - zero_mode = ix86_get_vector_load_mode (zero_size); - vector_const0 = gen_reg_rtx (zero_mode); - replace_vector_const (zero_mode, vector_const0, zero_insns); - } - else - { - zero_mode = VOIDmode; - vector_const0 = nullptr; - } + load->val = copy_rtx (val); + load->mode = scalar_mode; + load->size = GET_MODE_SIZE (mode); + load->def_insn = def_insn; + load->count = 1; + load->threshold = threshold; + load->bb = BLOCK_FOR_INSN (insn); + load->kind = kind; - if (m1_count > 1) - { - m1_mode = ix86_get_vector_load_mode (m1_size); - vector_constm1 = gen_reg_rtx (m1_mode); - replace_vector_const (m1_mode, vector_constm1, m1_insns); - } - else - { - m1_mode = VOIDmode; - vector_constm1 = nullptr; + bitmap_set_bit (load->insns, INSN_UID (insn)); + bitmap_set_bit (load->bbs, bb->index); + + loads.safe_push (load); } + } + + bool replaced = false; + rtx reg, broadcast_source, broadcast_reg; + FOR_EACH_VEC_ELT (loads, i, load) + if (load->count >= load->threshold) + { + machine_mode mode = ix86_get_vector_cse_mode (load->size, + load->mode); + broadcast_reg = gen_reg_rtx (mode); + if (load->def_insn) + { + /* Replace redundant vector loads with a single vector load + in the same basic block. */ + reg = load->val; + if (load->mode != GET_MODE (reg)) + reg = gen_rtx_SUBREG (load->mode, reg, 0); + broadcast_source = gen_rtx_VEC_DUPLICATE (mode, reg); + replace_vector_const (mode, broadcast_reg, load->insns, + load->mode); + } + else + { + /* This is a constant integer/double vector. If the + inner scalar is 0 or -1, set vector to CONST0_RTX + or CONSTM1_RTX directly. */ + rtx reg; + switch (load->kind) + { + case X86_CSE_CONST0_VECTOR: + broadcast_source = CONST0_RTX (mode); + break; + case X86_CSE_CONSTM1_VECTOR: + broadcast_source = CONSTM1_RTX (mode); + break; + default: + reg = gen_reg_rtx (load->mode); + broadcast_source = gen_rtx_VEC_DUPLICATE (mode, reg); + break; + } + replace_vector_const (mode, broadcast_reg, load->insns, + load->mode); + } + load->broadcast_source = broadcast_source; + load->broadcast_reg = broadcast_reg; + replaced = true; + } + + if (replaced) + { + auto_vec<rtx_insn *> control_flow_insns; /* (Re-)discover loops so that bb->loop_father can be used in the analysis below. */ calculate_dominance_info (CDI_DOMINATORS); loop_optimizer_init (AVOID_CFG_MODIFICATIONS); - if (vector_const0) - ix86_place_single_vector_set (vector_const0, - CONST0_RTX (zero_mode), - zero_bbs); - - if (vector_constm1) - ix86_place_single_vector_set (vector_constm1, - CONSTM1_RTX (m1_mode), - m1_bbs); + FOR_EACH_VEC_ELT (loads, i, load) + if (load->count >= load->threshold) + { + if (load->def_insn) + { + /* Insert a broadcast after the original scalar + definition. */ + rtx set = gen_rtx_SET (load->broadcast_reg, + load->broadcast_source); + insn = emit_insn_after (set, load->def_insn); + + if (cfun->can_throw_non_call_exceptions) + { + /* Handle REG_EH_REGION note in DEF_INSN. */ + rtx note = find_reg_note (load->def_insn, + REG_EH_REGION, nullptr); + if (note) + { + control_flow_insns.safe_push (load->def_insn); + add_reg_note (insn, REG_EH_REGION, + XEXP (note, 0)); + } + } + + if (dump_file) + { + fprintf (dump_file, "\nAdd:\n\n"); + print_rtl_single (dump_file, insn); + fprintf (dump_file, "\nafter:\n\n"); + print_rtl_single (dump_file, load->def_insn); + fprintf (dump_file, "\n"); + } + } + else + ix86_place_single_vector_set (load->broadcast_reg, + load->broadcast_source, + load->bbs, + (load->kind == X86_CSE_VEC_DUP + ? load->val + : nullptr)); + } loop_optimizer_finalize (); + if (!control_flow_insns.is_empty ()) + { + free_dominance_info (CDI_DOMINATORS); + + FOR_EACH_VEC_ELT (control_flow_insns, i, insn) + if (control_flow_insn_p (insn)) + { + /* Split the block after insn. There will be a fallthru + edge, which is OK so we keep it. We have to create + the exception edges ourselves. */ + bb = BLOCK_FOR_INSN (insn); + split_block (bb, insn); + rtl_make_eh_edge (NULL, bb, BB_END (bb)); + } + } + df_process_deferred_rescans (); } @@ -4284,7 +4623,6 @@ ix86_get_function_versions_dispatcher (void *decl) struct cgraph_node *node = NULL; struct cgraph_node *default_node = NULL; struct cgraph_function_version_info *node_v = NULL; - struct cgraph_function_version_info *first_v = NULL; tree dispatch_decl = NULL; @@ -4301,37 +4639,16 @@ ix86_get_function_versions_dispatcher (void *decl) if (node_v->dispatcher_resolver != NULL) return node_v->dispatcher_resolver; - /* Find the default version and make it the first node. */ - first_v = node_v; - /* Go to the beginning of the chain. */ - while (first_v->prev != NULL) - first_v = first_v->prev; - default_version_info = first_v; - while (default_version_info != NULL) - { - if (is_function_default_version - (default_version_info->this_node->decl)) - break; - default_version_info = default_version_info->next; - } + /* The default node is always the beginning of the chain. */ + default_version_info = node_v; + while (default_version_info->prev != NULL) + default_version_info = default_version_info->prev; + default_node = default_version_info->this_node; /* If there is no default node, just return NULL. */ - if (default_version_info == NULL) + if (!is_function_default_version (default_node->decl)) return NULL; - /* Make default info the first node. */ - if (first_v != default_version_info) - { - default_version_info->prev->next = default_version_info->next; - if (default_version_info->next) - default_version_info->next->prev = default_version_info->prev; - first_v->prev = default_version_info; - default_version_info->next = first_v; - default_version_info->prev = NULL; - } - - default_node = default_version_info->this_node; - #if defined (ASM_OUTPUT_TYPE_DIRECTIVE) if (targetm.has_ifunc_p ()) { diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index 124386735039..d244b225afee 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -760,63 +760,63 @@ static unsigned HOST_WIDE_INT initial_ix86_arch_features[X86_ARCH_LAST] = { /* This table must be in sync with enum processor_type in i386.h. */ static const struct processor_costs *processor_cost_table[] = { - &generic_cost, - &i386_cost, - &i486_cost, - &pentium_cost, - &lakemont_cost, - &pentiumpro_cost, - &pentium4_cost, - &nocona_cost, - &core_cost, - &core_cost, - &core_cost, - &core_cost, - &atom_cost, - &slm_cost, - &slm_cost, - &slm_cost, - &tremont_cost, - &alderlake_cost, - &alderlake_cost, - &alderlake_cost, - &skylake_cost, - &skylake_cost, - &icelake_cost, - &icelake_cost, - &icelake_cost, - &skylake_cost, - &icelake_cost, - &skylake_cost, - &icelake_cost, - &alderlake_cost, - &icelake_cost, - &icelake_cost, - &icelake_cost, - &alderlake_cost, - &alderlake_cost, - &alderlake_cost, - &icelake_cost, - &intel_cost, - &lujiazui_cost, - &yongfeng_cost, - &shijidadao_cost, - &geode_cost, - &k6_cost, - &athlon_cost, - &k8_cost, - &amdfam10_cost, - &bdver_cost, - &bdver_cost, - &bdver_cost, - &bdver_cost, - &btver1_cost, - &btver2_cost, - &znver1_cost, - &znver2_cost, - &znver3_cost, - &znver4_cost, - &znver5_cost + &generic_cost, /* PROCESSOR_GENERIC. */ + &i386_cost, /* PROCESSOR_I386. */ + &i486_cost, /* PROCESSOR_I486. */ + &pentium_cost, /* PROCESSOR_PENTIUM. */ + &lakemont_cost, /* PROCESSOR_LAKEMONT. */ + &pentiumpro_cost, /* PROCESSOR_PENTIUMPRO. */ + &pentium4_cost, /* PROCESSOR_PENTIUM4. */ + &nocona_cost, /* PROCESSOR_NOCONA. */ + &core_cost, /* PROCESSOR_CORE2. */ + &core_cost, /* PROCESSOR_NEHALEM. */ + &core_cost, /* PROCESSOR_SANDYBRIDGE. */ + &core_cost, /* PROCESSOR_HASWELL. */ + &atom_cost, /* PROCESSOR_BONNELL. */ + &slm_cost, /* PROCESSOR_SILVERMONT. */ + &slm_cost, /* PROCESSOR_GOLDMONT. */ + &slm_cost, /* PROCESSOR_GOLDMONT_PLUS. */ + &tremont_cost, /* PROCESSOR_TREMONT. */ + &alderlake_cost, /* PROCESSOR_SIERRAFOREST. */ + &alderlake_cost, /* PROCESSOR_GRANDRIDGE. */ + &alderlake_cost, /* PROCESSOR_CLEARWATERFOREST. */ + &skylake_cost, /* PROCESSOR_SKYLAKE. */ + &skylake_cost, /* PROCESSOR_SKYLAKE_AVX512. */ + &icelake_cost, /* PROCESSOR_CANNONLAKE. */ + &icelake_cost, /* PROCESSOR_ICELAKE_CLIENT. */ + &icelake_cost, /* PROCESSOR_ICELAKE_SERVER. */ + &skylake_cost, /* PROCESSOR_CASCADELAKE. */ + &icelake_cost, /* PROCESSOR_TIGERLAKE. */ + &skylake_cost, /* PROCESSOR_COOPERLAKE. */ + &icelake_cost, /* PROCESSOR_SAPPHIRERAPIDS. */ + &alderlake_cost, /* PROCESSOR_ALDERLAKE. */ + &icelake_cost, /* PROCESSOR_ROCKETLAKE. */ + &icelake_cost, /* PROCESSOR_GRANITERAPIDS. */ + &icelake_cost, /* PROCESSOR_GRANITERAPIDS_D. */ + &alderlake_cost, /* PROCESSOR_ARROWLAKE. */ + &alderlake_cost, /* PROCESSOR_ARROWLAKE_S. */ + &alderlake_cost, /* PROCESSOR_PANTHERLAKE. */ + &icelake_cost, /* PROCESSOR_DIAMONDRAPIDS. */ + &alderlake_cost, /* PROCESSOR_INTEL. */ + &lujiazui_cost, /* PROCESSOR_LUJIAZUI. */ + &yongfeng_cost, /* PROCESSOR_YONGFENG. */ + &shijidadao_cost, /* PROCESSOR_SHIJIDADAO. */ + &geode_cost, /* PROCESSOR_GEODE. */ + &k6_cost, /* PROCESSOR_K6. */ + &athlon_cost, /* PROCESSOR_ATHLON. */ + &k8_cost, /* PROCESSOR_K8. */ + &amdfam10_cost, /* PROCESSOR_AMDFAM10. */ + &bdver_cost, /* PROCESSOR_BDVER1. */ + &bdver_cost, /* PROCESSOR_BDVER2. */ + &bdver_cost, /* PROCESSOR_BDVER3. */ + &bdver_cost, /* PROCESSOR_BDVER4. */ + &btver1_cost, /* PROCESSOR_BTVER1. */ + &btver2_cost, /* PROCESSOR_BTVER2. */ + &znver1_cost, /* PROCESSOR_ZNVER1. */ + &znver2_cost, /* PROCESSOR_ZNVER2. */ + &znver3_cost, /* PROCESSOR_ZNVER3. */ + &znver4_cost, /* PROCESSOR_ZNVER4. */ + &znver5_cost /* PROCESSOR_ZNVER5. */ }; /* Guarantee that the array is aligned with enum processor_type. */ @@ -2839,7 +2839,9 @@ ix86_option_override_internal (bool main_args_p, /* Set the default value for -mfentry. */ if (!opts_set->x_flag_fentry) - opts->x_flag_fentry = TARGET_SEH; + opts->x_flag_fentry = (TARGET_SEH + || (TARGET_64BIT_P (opts->x_ix86_isa_flags) + && ENABLE_X86_64_MFENTRY)); else { if (!TARGET_64BIT_P (opts->x_ix86_isa_flags) && opts->x_flag_pic @@ -2850,6 +2852,17 @@ ix86_option_override_internal (bool main_args_p, sorry ("%<-mno-fentry%> isn%'t compatible with SEH"); } +#ifdef OPTION_GLIBC_P + /* -mfentry is supported only on glibc targets. */ + if (!opts->x_flag_fentry + && OPTION_GLIBC_P (opts) + && (TARGET_64BIT_P (opts->x_ix86_isa_flags) || !opts->x_flag_pic) + && opts->x_flag_shrink_wrap + && opts->x_profile_flag) + warning (0, "%<-pg%> without %<-mfentry%> may be unreliable with " + "shrink wrapping"); +#endif + if (TARGET_SEH && TARGET_CALL_MS2SYSV_XLOGUES) sorry ("%<-mcall-ms2sysv-xlogues%> isn%'t currently supported with SEH"); @@ -3277,19 +3290,21 @@ ix86_set_func_type (tree fndecl) interrupt function in this case. */ enum call_saved_registers_type no_callee_saved_registers = TYPE_DEFAULT_CALL_SAVED_REGISTERS; - if (lookup_attribute ("no_callee_saved_registers", - TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))) + if (lookup_attribute ("preserve_none", + TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))) + no_callee_saved_registers = TYPE_PRESERVE_NONE; + else if ((lookup_attribute ("no_callee_saved_registers", + TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))) + || (ix86_noreturn_no_callee_saved_registers + && TREE_THIS_VOLATILE (fndecl) + && optimize + && !optimize_debug + && (TREE_NOTHROW (fndecl) || !flag_exceptions) + && !lookup_attribute ("interrupt", + TYPE_ATTRIBUTES (TREE_TYPE (fndecl))) + && !lookup_attribute ("no_caller_saved_registers", + TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))) no_callee_saved_registers = TYPE_NO_CALLEE_SAVED_REGISTERS; - else if (ix86_noreturn_no_callee_saved_registers - && TREE_THIS_VOLATILE (fndecl) - && optimize - && !optimize_debug - && (TREE_NOTHROW (fndecl) || !flag_exceptions) - && !lookup_attribute ("interrupt", - TYPE_ATTRIBUTES (TREE_TYPE (fndecl))) - && !lookup_attribute ("no_caller_saved_registers", - TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))) - no_callee_saved_registers = TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP; if (cfun->machine->func_type == TYPE_UNKNOWN) { @@ -3301,9 +3316,16 @@ ix86_set_func_type (tree fndecl) "interrupt and naked attributes are not compatible"); if (no_callee_saved_registers) - error_at (DECL_SOURCE_LOCATION (fndecl), - "%qs and %qs attributes are not compatible", - "interrupt", "no_callee_saved_registers"); + { + const char *attr; + if (no_callee_saved_registers == TYPE_PRESERVE_NONE) + attr = "preserve_none"; + else + attr = "no_callee_saved_registers"; + error_at (DECL_SOURCE_LOCATION (fndecl), + "%qs and %qs attributes are not compatible", + "interrupt", attr); + } int nargs = 0; for (tree arg = DECL_ARGUMENTS (fndecl); @@ -3325,21 +3347,13 @@ ix86_set_func_type (tree fndecl) else { cfun->machine->func_type = TYPE_NORMAL; - if (lookup_attribute ("no_caller_saved_registers", - TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))) + if (no_callee_saved_registers) + cfun->machine->call_saved_registers + = no_callee_saved_registers; + else if (lookup_attribute ("no_caller_saved_registers", + TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))) cfun->machine->call_saved_registers = TYPE_NO_CALLER_SAVED_REGISTERS; - if (no_callee_saved_registers) - { - if (cfun->machine->call_saved_registers - == TYPE_NO_CALLER_SAVED_REGISTERS) - error_at (DECL_SOURCE_LOCATION (fndecl), - "%qs and %qs attributes are not compatible", - "no_caller_saved_registers", - "no_callee_saved_registers"); - cfun->machine->call_saved_registers - = no_callee_saved_registers; - } } } } @@ -3528,11 +3542,21 @@ ix86_set_current_function (tree fndecl) || (cfun->machine->call_saved_registers == TYPE_NO_CALLER_SAVED_REGISTERS)) { - /* Don't allow SSE, MMX nor x87 instructions since they - may change processor state. */ + /* Don't allow AVX, AVX512, MMX nor x87 instructions since they + may change processor state. Don't allow SSE instructions in + exception/interrupt service routines. */ const char *isa; if (TARGET_SSE) - isa = "SSE"; + { + if (TARGET_AVX512F) + isa = "AVX512"; + else if (TARGET_AVX) + isa = "AVX"; + else if (cfun->machine->func_type != TYPE_NORMAL) + isa = "SSE"; + else + isa = NULL; + } else if (TARGET_MMX) isa = "MMX/3Dnow"; else if (TARGET_80387) @@ -3957,9 +3981,50 @@ ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int, } static tree -ix86_handle_call_saved_registers_attribute (tree *, tree, tree, +ix86_handle_call_saved_registers_attribute (tree *node, tree name, tree, int, bool *) { + const char *attr1 = nullptr; + const char *attr2 = nullptr; + + if (is_attribute_p ("no_callee_saved_registers", name)) + { + /* Disallow preserve_none and no_caller_saved_registers + attributes. */ + attr1 = "no_callee_saved_registers"; + if (lookup_attribute ("preserve_none", TYPE_ATTRIBUTES (*node))) + attr2 = "preserve_none"; + else if (lookup_attribute ("no_caller_saved_registers", + TYPE_ATTRIBUTES (*node))) + attr2 = "no_caller_saved_registers"; + } + else if (is_attribute_p ("no_caller_saved_registers", name)) + { + /* Disallow preserve_none and no_callee_saved_registers + attributes. */ + attr1 = "no_caller_saved_registers"; + if (lookup_attribute ("preserve_none", TYPE_ATTRIBUTES (*node))) + attr2 = "preserve_none"; + else if (lookup_attribute ("no_callee_saved_registers", + TYPE_ATTRIBUTES (*node))) + attr2 = "no_callee_saved_registers"; + } + else if (is_attribute_p ("preserve_none", name)) + { + /* Disallow no_callee_saved_registers and no_caller_saved_registers + attributes. */ + attr1 = "preserve_none"; + if (lookup_attribute ("no_callee_saved_registers", + TYPE_ATTRIBUTES (*node))) + attr2 = "no_caller_saved_registers"; + else if (lookup_attribute ("no_callee_saved_registers", + TYPE_ATTRIBUTES (*node))) + attr2 = "no_callee_saved_registers"; + } + + if (attr2) + error ("%qs and %qs attributes are not compatible", attr1, attr2); + return NULL_TREE; } @@ -4121,6 +4186,8 @@ static const attribute_spec ix86_gnu_attributes[] = ix86_handle_interrupt_attribute, NULL }, { "no_caller_saved_registers", 0, 0, false, true, true, false, ix86_handle_call_saved_registers_attribute, NULL }, + { "preserve_none", 0, 0, false, true, true, true, + ix86_handle_call_saved_registers_attribute, NULL }, { "no_callee_saved_registers", 0, 0, false, true, true, true, ix86_handle_call_saved_registers_attribute, NULL }, { "naked", 0, 0, true, false, false, false, diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 10863ab9e9de..69bc0ee570dd 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -282,6 +282,7 @@ extern tree ix86_valid_target_attribute_tree (tree, tree, struct gcc_options *, struct gcc_options *, bool); extern unsigned int ix86_get_callcvt (const_tree); +extern bool ix86_type_no_callee_saved_registers_p (const_tree); #endif @@ -437,6 +438,13 @@ extern rtl_opt_pass *make_pass_align_tight_loops (gcc::context *); extern bool ix86_has_no_direct_extern_access; extern bool ix86_rpad_gate (); +extern sbitmap ix86_get_separate_components (void); +extern sbitmap ix86_components_for_bb (basic_block); +extern void ix86_disqualify_components (sbitmap, edge, sbitmap, bool); +extern void ix86_emit_prologue_components (sbitmap); +extern void ix86_emit_epilogue_components (sbitmap); +extern void ix86_set_handled_components (sbitmap); + /* In i386-expand.cc. */ bool ix86_check_builtin_isa_match (unsigned int, HOST_WIDE_INT*, HOST_WIDE_INT*); diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index d48654a729a1..4682db85ce4c 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -335,6 +335,14 @@ static int const x86_64_ms_abi_int_parameter_registers[4] = CX_REG, DX_REG, R8_REG, R9_REG }; +/* Similar as Clang's preserve_none function parameter passing. + NB: Use DI_REG and SI_REG, see ix86_function_value_regno_p. */ + +static int const x86_64_preserve_none_int_parameter_registers[6] = +{ + R12_REG, R13_REG, R14_REG, R15_REG, DI_REG, SI_REG +}; + static int const x86_64_int_return_registers[4] = { AX_REG, DX_REG, DI_REG, SI_REG @@ -460,7 +468,8 @@ int ix86_arch_specified; red-zone. NB: Don't use red-zone for functions with no_caller_saved_registers - and 32 GPRs since 128-byte red-zone is too small for 31 GPRs. + and 32 GPRs or 16 XMM registers since 128-byte red-zone is too small + for 31 GPRs or 15 GPRs + 16 XMM registers. TODO: If we can reserve the first 2 WORDs, for PUSH and, another for CALL, in red-zone, we can allow local indirect jumps with @@ -471,7 +480,7 @@ ix86_using_red_zone (void) { return (TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI - && (!TARGET_APX_EGPR + && ((!TARGET_APX_EGPR && !TARGET_SSE) || (cfun->machine->call_saved_registers != TYPE_NO_CALLER_SAVED_REGISTERS)) && (!cfun->machine->has_local_indirect_jump @@ -898,6 +907,18 @@ x86_64_elf_unique_section (tree decl, int reloc) default_unique_section (decl, reloc); } +/* Return true if TYPE has no_callee_saved_registers or preserve_none + attribute. */ + +bool +ix86_type_no_callee_saved_registers_p (const_tree type) +{ + return (lookup_attribute ("no_callee_saved_registers", + TYPE_ATTRIBUTES (type)) != NULL + || lookup_attribute ("preserve_none", + TYPE_ATTRIBUTES (type)) != NULL); +} + #ifdef COMMON_ASM_OP #ifndef LARGECOMM_SECTION_ASM_OP @@ -1019,11 +1040,10 @@ ix86_function_ok_for_sibcall (tree decl, tree exp) /* Sibling call isn't OK if callee has no callee-saved registers and the calling function has callee-saved registers. */ - if (cfun->machine->call_saved_registers != TYPE_NO_CALLEE_SAVED_REGISTERS - && (cfun->machine->call_saved_registers - != TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP) - && lookup_attribute ("no_callee_saved_registers", - TYPE_ATTRIBUTES (type))) + if ((cfun->machine->call_saved_registers + != TYPE_NO_CALLEE_SAVED_REGISTERS) + && cfun->machine->call_saved_registers != TYPE_PRESERVE_NONE + && ix86_type_no_callee_saved_registers_p (type)) return false; /* If outgoing reg parm stack space changes, we cannot do sibcall. */ @@ -1188,10 +1208,16 @@ ix86_comp_type_attributes (const_tree type1, const_tree type2) != ix86_function_regparm (type2, NULL)) return 0; - if (lookup_attribute ("no_callee_saved_registers", - TYPE_ATTRIBUTES (type1)) - != lookup_attribute ("no_callee_saved_registers", - TYPE_ATTRIBUTES (type2))) + if (ix86_type_no_callee_saved_registers_p (type1) + != ix86_type_no_callee_saved_registers_p (type2)) + return 0; + + /* preserve_none attribute uses a different calling convention is + only for 64-bit. */ + if (TARGET_64BIT + && (lookup_attribute ("preserve_none", TYPE_ATTRIBUTES (type1)) + != lookup_attribute ("preserve_none", + TYPE_ATTRIBUTES (type2)))) return 0; return 1; @@ -1553,7 +1579,10 @@ ix86_function_arg_regno_p (int regno) if (call_abi == SYSV_ABI && regno == AX_REG) return true; - if (call_abi == MS_ABI) + if (cfun + && cfun->machine->call_saved_registers == TYPE_PRESERVE_NONE) + parm_regs = x86_64_preserve_none_int_parameter_registers; + else if (call_abi == MS_ABI) parm_regs = x86_64_ms_abi_int_parameter_registers; else parm_regs = x86_64_int_parameter_registers; @@ -1835,6 +1864,7 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */ memset (cum, 0, sizeof (*cum)); + tree preserve_none_type; if (fndecl) { target = cgraph_node::get (fndecl); @@ -1843,12 +1873,24 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */ target = target->function_symbol (); local_info_node = cgraph_node::local_info_node (target->decl); cum->call_abi = ix86_function_abi (target->decl); + preserve_none_type = TREE_TYPE (target->decl); } else - cum->call_abi = ix86_function_abi (fndecl); + { + cum->call_abi = ix86_function_abi (fndecl); + preserve_none_type = TREE_TYPE (fndecl); + } } else - cum->call_abi = ix86_function_type_abi (fntype); + { + cum->call_abi = ix86_function_type_abi (fntype); + preserve_none_type = fntype; + } + cum->preserve_none_abi + = (preserve_none_type + && (lookup_attribute ("preserve_none", + TYPE_ATTRIBUTES (preserve_none_type)) + != nullptr)); cum->caller = caller; @@ -3421,9 +3463,15 @@ function_arg_64 (const CUMULATIVE_ARGS *cum, machine_mode mode, break; } + const int *parm_regs; + if (cum->preserve_none_abi) + parm_regs = x86_64_preserve_none_int_parameter_registers; + else + parm_regs = x86_64_int_parameter_registers; + return construct_container (mode, orig_mode, type, 0, cum->nregs, cum->sse_nregs, - &x86_64_int_parameter_registers [cum->regno], + &parm_regs[cum->regno], cum->sse_regno); } @@ -4588,6 +4636,12 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum) if (max > X86_64_REGPARM_MAX) max = X86_64_REGPARM_MAX; + const int *parm_regs; + if (cum->preserve_none_abi) + parm_regs = x86_64_preserve_none_int_parameter_registers; + else + parm_regs = x86_64_int_parameter_registers; + for (i = cum->regno; i < max; i++) { mem = gen_rtx_MEM (word_mode, @@ -4595,8 +4649,7 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum) MEM_NOTRAP_P (mem) = 1; set_mem_alias_set (mem, set); emit_move_insn (mem, - gen_rtx_REG (word_mode, - x86_64_int_parameter_registers[i])); + gen_rtx_REG (word_mode, parm_regs[i])); } if (ix86_varargs_fpr_size) @@ -5703,7 +5756,7 @@ ix86_get_ssemov (rtx *operands, unsigned size, : "%vmovaps"); else opcode = (misaligned_p - ? (TARGET_AVX512BW + ? (TARGET_AVX512BW && evex_reg_p ? "vmovdqu16" : "%vmovdqu") : "%vmovdqa"); @@ -5745,7 +5798,7 @@ ix86_get_ssemov (rtx *operands, unsigned size, : "%vmovaps"); else opcode = (misaligned_p - ? (TARGET_AVX512BW + ? (TARGET_AVX512BW && evex_reg_p ? "vmovdqu8" : "%vmovdqu") : "%vmovdqa"); @@ -5765,7 +5818,7 @@ ix86_get_ssemov (rtx *operands, unsigned size, : "%vmovaps"); else opcode = (misaligned_p - ? (TARGET_AVX512BW + ? (TARGET_AVX512BW && evex_reg_p ? "vmovdqu16" : "%vmovdqu") : "%vmovdqa"); @@ -5926,7 +5979,7 @@ symbolic_reference_mentioned_p (rtx op) const char *fmt; int i; - if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF) + if (SYMBOL_REF_P (op) || LABEL_REF_P (op)) return true; fmt = GET_RTX_FORMAT (GET_CODE (op)); @@ -6473,7 +6526,7 @@ output_set_got (rtx dest, rtx label) xops[0] = dest; - if (TARGET_VXWORKS_RTP && flag_pic) + if (TARGET_VXWORKS_GOTTPIC && TARGET_VXWORKS_RTP && flag_pic) { /* Load (*VXWORKS_GOTT_BASE) into the PIC register. */ xops[2] = gen_rtx_MEM (Pmode, @@ -6718,9 +6771,7 @@ ix86_save_reg (unsigned int regno, bool maybe_eh_return, bool ignore_outlined) || !frame_pointer_needed)); case TYPE_NO_CALLEE_SAVED_REGISTERS: - return false; - - case TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP: + case TYPE_PRESERVE_NONE: if (regno != HARD_FRAME_POINTER_REGNUM) return false; break; @@ -6797,7 +6848,9 @@ ix86_nsaved_sseregs (void) int nregs = 0; int regno; - if (!TARGET_64BIT_MS_ABI) + if (!TARGET_64BIT_MS_ABI + && (cfun->machine->call_saved_registers + != TYPE_NO_CALLER_SAVED_REGISTERS)) return 0; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true, true)) @@ -6905,6 +6958,26 @@ ix86_pro_and_epilogue_can_use_push2pop2 (int nregs) && (nregs + aligned) >= 3; } +/* Check if push/pop should be used to save/restore registers. */ +static bool +save_regs_using_push_pop (HOST_WIDE_INT to_allocate) +{ + return ((!to_allocate && cfun->machine->frame.nregs <= 1) + || (TARGET_64BIT && to_allocate >= HOST_WIDE_INT_C (0x80000000)) + /* If static stack checking is enabled and done with probes, + the registers need to be saved before allocating the frame. */ + || flag_stack_check == STATIC_BUILTIN_STACK_CHECK + /* If stack clash probing needs a loop, then it needs a + scratch register. But the returned register is only guaranteed + to be safe to use after register saves are complete. So if + stack clash protections are enabled and the allocated frame is + larger than the probe interval, then use pushes to save + callee saved registers. */ + || (flag_stack_clash_protection + && !ix86_target_stack_probe () + && to_allocate > get_probe_interval ())); +} + /* Fill structure ix86_frame about frame of currently computed function. */ static void @@ -6985,12 +7058,18 @@ ix86_compute_frame_layout (void) gcc_assert (preferred_alignment >= STACK_BOUNDARY / BITS_PER_UNIT); gcc_assert (preferred_alignment <= stack_alignment_needed); - /* The only ABI saving SSE regs should be 64-bit ms_abi. */ - gcc_assert (TARGET_64BIT || !frame->nsseregs); + /* The only ABI saving SSE regs should be 64-bit ms_abi or with + no_caller_saved_registers attribue. */ + gcc_assert (TARGET_64BIT + || (cfun->machine->call_saved_registers + == TYPE_NO_CALLER_SAVED_REGISTERS) + || !frame->nsseregs); if (TARGET_64BIT && m->call_ms2sysv) { gcc_assert (stack_alignment_needed >= 16); - gcc_assert (!frame->nsseregs); + gcc_assert ((cfun->machine->call_saved_registers + == TYPE_NO_CALLER_SAVED_REGISTERS) + || !frame->nsseregs); } /* For SEH we have to limit the amount of code movement into the prologue. @@ -7189,20 +7268,7 @@ ix86_compute_frame_layout (void) /* Size prologue needs to allocate. */ to_allocate = offset - frame->sse_reg_save_offset; - if ((!to_allocate && frame->nregs <= 1) - || (TARGET_64BIT && to_allocate >= HOST_WIDE_INT_C (0x80000000)) - /* If static stack checking is enabled and done with probes, - the registers need to be saved before allocating the frame. */ - || flag_stack_check == STATIC_BUILTIN_STACK_CHECK - /* If stack clash probing needs a loop, then it needs a - scratch register. But the returned register is only guaranteed - to be safe to use after register saves are complete. So if - stack clash protections are enabled and the allocated frame is - larger than the probe interval, then use pushes to save - callee saved registers. */ - || (flag_stack_clash_protection - && !ix86_target_stack_probe () - && to_allocate > get_probe_interval ())) + if (save_regs_using_push_pop (to_allocate)) frame->save_regs_using_mov = false; if (ix86_using_red_zone () @@ -7660,7 +7726,9 @@ ix86_emit_save_regs_using_mov (HOST_WIDE_INT cfa_offset) for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true)) { - ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset); + /* Skip registers, already processed by shrink wrap separate. */ + if (!cfun->machine->reg_is_wrapped_separately[regno]) + ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset); cfa_offset -= UNITS_PER_WORD; } } @@ -7753,8 +7821,15 @@ pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset, add_frame_related_expr = true; } - insn = emit_insn (gen_pro_epilogue_adjust_stack_add - (Pmode, dest, src, addend)); + /* Shrink wrap separate may insert prologue between TEST and JMP. In order + not to affect EFlags, emit add without reg clobbering. */ + if (crtl->shrink_wrapped_separate) + insn = emit_insn (gen_pro_epilogue_adjust_stack_add_nocc + (Pmode, dest, src, addend)); + else + insn = emit_insn (gen_pro_epilogue_adjust_stack_add + (Pmode, dest, src, addend)); + if (style >= 0) ix86_add_queued_cfa_restore_notes (insn); @@ -9219,11 +9294,22 @@ ix86_expand_prologue (void) doing this if we have to probe the stack; at least on x86_64 the stack probe can turn into a call that clobbers a red zone location. */ else if (ix86_using_red_zone () - && (! TARGET_STACK_PROBE - || frame.stack_pointer_offset < CHECK_STACK_LIMIT)) + && (! TARGET_STACK_PROBE + || frame.stack_pointer_offset < CHECK_STACK_LIMIT)) { + HOST_WIDE_INT allocate_offset; + if (crtl->shrink_wrapped_separate) + { + allocate_offset = m->fs.sp_offset - frame.stack_pointer_offset; + + /* Adjust the total offset at the beginning of the function. */ + pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx, + GEN_INT (allocate_offset), -1, + m->fs.cfa_reg == stack_pointer_rtx); + m->fs.sp_offset = cfun->machine->frame.stack_pointer_offset; + } + ix86_emit_save_regs_using_mov (frame.reg_save_offset); - cfun->machine->red_zone_used = true; int_registers_saved = true; } } @@ -9801,30 +9887,35 @@ ix86_emit_restore_regs_using_mov (HOST_WIDE_INT cfa_offset, for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return, true)) { - rtx reg = gen_rtx_REG (word_mode, regno); - rtx mem; - rtx_insn *insn; - mem = choose_baseaddr (cfa_offset, NULL); - mem = gen_frame_mem (word_mode, mem); - insn = emit_move_insn (reg, mem); - - if (m->fs.cfa_reg == crtl->drap_reg && regno == REGNO (crtl->drap_reg)) + /* Skip registers, already processed by shrink wrap separate. */ + if (!cfun->machine->reg_is_wrapped_separately[regno]) { - /* Previously we'd represented the CFA as an expression - like *(%ebp - 8). We've just popped that value from - the stack, which means we need to reset the CFA to - the drap register. This will remain until we restore - the stack pointer. */ - add_reg_note (insn, REG_CFA_DEF_CFA, reg); - RTX_FRAME_RELATED_P (insn) = 1; + rtx reg = gen_rtx_REG (word_mode, regno); + rtx mem; + rtx_insn *insn; - /* This means that the DRAP register is valid for addressing. */ - m->fs.drap_valid = true; - } - else - ix86_add_cfa_restore_note (NULL, reg, cfa_offset); + mem = choose_baseaddr (cfa_offset, NULL); + mem = gen_frame_mem (word_mode, mem); + insn = emit_move_insn (reg, mem); + + if (m->fs.cfa_reg == crtl->drap_reg + && regno == REGNO (crtl->drap_reg)) + { + /* Previously we'd represented the CFA as an expression + like *(%ebp - 8). We've just popped that value from + the stack, which means we need to reset the CFA to + the drap register. This will remain until we restore + the stack pointer. */ + add_reg_note (insn, REG_CFA_DEF_CFA, reg); + RTX_FRAME_RELATED_P (insn) = 1; + /* DRAP register is valid for addressing. */ + m->fs.drap_valid = true; + } + else + ix86_add_cfa_restore_note (NULL, reg, cfa_offset); + } cfa_offset -= UNITS_PER_WORD; } } @@ -10103,10 +10194,11 @@ ix86_expand_epilogue (int style) less work than reloading sp and popping the register. */ else if (!sp_valid_at (frame.hfp_save_offset) && frame.nregs <= 1) restore_regs_via_mov = true; - else if (TARGET_EPILOGUE_USING_MOVE - && cfun->machine->use_fast_prologue_epilogue - && (frame.nregs > 1 - || m->fs.sp_offset != reg_save_offset)) + else if (crtl->shrink_wrapped_separate + || (TARGET_EPILOGUE_USING_MOVE + && cfun->machine->use_fast_prologue_epilogue + && (frame.nregs > 1 + || m->fs.sp_offset != reg_save_offset))) restore_regs_via_mov = true; else if (frame_pointer_needed && !frame.nregs @@ -10120,6 +10212,9 @@ ix86_expand_epilogue (int style) else restore_regs_via_mov = false; + if (crtl->shrink_wrapped_separate) + gcc_assert (restore_regs_via_mov); + if (restore_regs_via_mov || frame.nsseregs) { /* Ensure that the entire register save area is addressable via @@ -10172,6 +10267,7 @@ ix86_expand_epilogue (int style) gcc_assert (m->fs.sp_offset == UNITS_PER_WORD); gcc_assert (!crtl->drap_reg); gcc_assert (!frame.nregs); + gcc_assert (!crtl->shrink_wrapped_separate); } else if (restore_regs_via_mov) { @@ -10186,6 +10282,8 @@ ix86_expand_epilogue (int style) rtx sa = EH_RETURN_STACKADJ_RTX; rtx_insn *insn; + gcc_assert (!crtl->shrink_wrapped_separate); + /* Stack realignment doesn't work with eh_return. */ if (crtl->stack_realign_needed) sorry ("Stack realignment not supported with " @@ -10626,8 +10724,7 @@ split_stack_prologue_scratch_regno (void) static GTY(()) rtx split_stack_fn; -/* A SYMBOL_REF for the more stack function when using the large - model. */ +/* A SYMBOL_REF for the more stack function when using the large model. */ static GTY(()) rtx split_stack_fn_large; @@ -11315,7 +11412,7 @@ ix86_force_load_from_GOT_p (rtx x, bool call_p) && (!flag_pic || this_is_asm_operands) && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC - && GET_CODE (x) == SYMBOL_REF + && SYMBOL_REF_P (x) && ((!call_p && (!ix86_direct_extern_access || (SYMBOL_REF_DECL (x) @@ -11361,23 +11458,23 @@ ix86_legitimate_constant_p (machine_mode mode, rtx x) case UNSPEC_TPOFF: case UNSPEC_NTPOFF: x = XVECEXP (x, 0, 0); - return (GET_CODE (x) == SYMBOL_REF + return (SYMBOL_REF_P (x) && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC); case UNSPEC_DTPOFF: x = XVECEXP (x, 0, 0); - return (GET_CODE (x) == SYMBOL_REF + return (SYMBOL_REF_P (x) && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC); case UNSPEC_SECREL32: x = XVECEXP (x, 0, 0); - return GET_CODE (x) == SYMBOL_REF; + return SYMBOL_REF_P (x); default: return false; } /* We must have drilled down to a symbol. */ - if (GET_CODE (x) == LABEL_REF) + if (LABEL_REF_P (x)) return true; - if (GET_CODE (x) != SYMBOL_REF) + if (!SYMBOL_REF_P (x)) return false; /* FALLTHRU */ @@ -11504,11 +11601,11 @@ legitimate_pic_operand_p (rtx x) return TARGET_64BIT; case UNSPEC_TPOFF: x = XVECEXP (inner, 0, 0); - return (GET_CODE (x) == SYMBOL_REF + return (SYMBOL_REF_P (x) && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC); case UNSPEC_SECREL32: x = XVECEXP (inner, 0, 0); - return GET_CODE (x) == SYMBOL_REF; + return SYMBOL_REF_P (x); case UNSPEC_MACHOPIC_OFFSET: return legitimate_pic_address_disp_p (x); default: @@ -11559,7 +11656,7 @@ legitimate_pic_address_disp_p (rtx disp) if (INTVAL (op1) >= 16*1024*1024 || INTVAL (op1) < -16*1024*1024) break; - if (GET_CODE (op0) == LABEL_REF) + if (LABEL_REF_P (op0)) return true; if (GET_CODE (op0) == CONST && GET_CODE (XEXP (op0, 0)) == UNSPEC @@ -11568,7 +11665,7 @@ legitimate_pic_address_disp_p (rtx disp) if (GET_CODE (op0) == UNSPEC && XINT (op0, 1) == UNSPEC_PCREL) return true; - if (GET_CODE (op0) != SYMBOL_REF) + if (!SYMBOL_REF_P (op0)) break; /* FALLTHRU */ @@ -11633,8 +11730,8 @@ legitimate_pic_address_disp_p (rtx disp) && XINT (disp, 1) != UNSPEC_PLTOFF)) return false; - if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF - && GET_CODE (XVECEXP (disp, 0, 0)) != LABEL_REF) + if (!SYMBOL_REF_P (XVECEXP (disp, 0, 0)) + && !LABEL_REF_P (XVECEXP (disp, 0, 0))) return false; return true; } @@ -11662,14 +11759,14 @@ legitimate_pic_address_disp_p (rtx disp) /* We need to check for both symbols and labels because VxWorks loads text labels with @GOT rather than @GOTOFF. See gotoff_operand for details. */ - return (GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF - || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF); + return (SYMBOL_REF_P (XVECEXP (disp, 0, 0)) + || LABEL_REF_P (XVECEXP (disp, 0, 0))); case UNSPEC_GOTOFF: /* Refuse GOTOFF in 64bit mode since it is always 64bit when used. While ABI specify also 32bit relocation but we don't produce it in small PIC model at all. */ - if ((GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF - || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF) + if ((SYMBOL_REF_P (XVECEXP (disp, 0, 0)) + || LABEL_REF_P (XVECEXP (disp, 0, 0))) && !TARGET_64BIT) return !TARGET_PECOFF && gotoff_operand (XVECEXP (disp, 0, 0), Pmode); return false; @@ -11679,19 +11776,19 @@ legitimate_pic_address_disp_p (rtx disp) if (saw_plus) return false; disp = XVECEXP (disp, 0, 0); - return (GET_CODE (disp) == SYMBOL_REF + return (SYMBOL_REF_P (disp) && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_INITIAL_EXEC); case UNSPEC_NTPOFF: disp = XVECEXP (disp, 0, 0); - return (GET_CODE (disp) == SYMBOL_REF + return (SYMBOL_REF_P (disp) && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_EXEC); case UNSPEC_DTPOFF: disp = XVECEXP (disp, 0, 0); - return (GET_CODE (disp) == SYMBOL_REF + return (SYMBOL_REF_P (disp) && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_DYNAMIC); case UNSPEC_SECREL32: disp = XVECEXP (disp, 0, 0); - return GET_CODE (disp) == SYMBOL_REF; + return SYMBOL_REF_P (disp); } return false; @@ -12033,11 +12130,11 @@ ix86_legitimate_address_p (machine_mode, rtx addr, bool strict, that never results in lea, this seems to be easier and correct fix for crash to disable this test. */ } - else if (GET_CODE (disp) != LABEL_REF + else if (!LABEL_REF_P (disp) && !CONST_INT_P (disp) && (GET_CODE (disp) != CONST || !ix86_legitimate_constant_p (Pmode, disp)) - && (GET_CODE (disp) != SYMBOL_REF + && (!SYMBOL_REF_P (disp) || !ix86_legitimate_constant_p (Pmode, disp))) /* Displacement is not constant. */ return false; @@ -12144,10 +12241,10 @@ legitimize_pic_address (rtx orig, rtx reg) else new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx); } - else if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (addr) == 0) + else if ((SYMBOL_REF_P (addr) && SYMBOL_REF_TLS_MODEL (addr) == 0) /* We can't always use @GOTOFF for text labels on VxWorks, see gotoff_operand. */ - || (TARGET_VXWORKS_RTP && GET_CODE (addr) == LABEL_REF)) + || (TARGET_VXWORKS_VAROFF && LABEL_REF_P (addr))) { #if TARGET_PECOFF rtx tmp = legitimize_pe_coff_symbol (addr, true); @@ -12282,8 +12379,8 @@ legitimize_pic_address (rtx orig, rtx reg) /* For %rip addressing, we have to use just disp32, not base nor index. */ if (TARGET_64BIT - && (GET_CODE (base) == SYMBOL_REF - || GET_CODE (base) == LABEL_REF)) + && (SYMBOL_REF_P (base) + || LABEL_REF_P (base))) base = force_reg (mode, base); if (GET_CODE (new_rtx) == PLUS && CONSTANT_P (XEXP (new_rtx, 1))) @@ -12464,11 +12561,12 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov) if (TARGET_64BIT) { rtx rax = gen_rtx_REG (Pmode, AX_REG); + rtx rdi = gen_rtx_REG (Pmode, DI_REG); rtx_insn *insns; start_sequence (); emit_call_insn - (gen_tls_global_dynamic_64 (Pmode, rax, x, caddr)); + (gen_tls_global_dynamic_64 (Pmode, rax, x, caddr, rdi)); insns = end_sequence (); if (GET_MODE (x) != Pmode) @@ -12517,12 +12615,13 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov) if (TARGET_64BIT) { rtx rax = gen_rtx_REG (Pmode, AX_REG); + rtx rdi = gen_rtx_REG (Pmode, DI_REG); rtx_insn *insns; rtx eqv; start_sequence (); emit_call_insn - (gen_tls_local_dynamic_base_64 (Pmode, rax, caddr)); + (gen_tls_local_dynamic_base_64 (Pmode, rax, caddr, rdi)); insns = end_sequence (); /* Attach a unique REG_EQUAL, to allow the RTL optimizers to @@ -12783,12 +12882,12 @@ ix86_legitimize_address (rtx x, rtx, machine_mode mode) bool changed = false; unsigned log; - log = GET_CODE (x) == SYMBOL_REF ? SYMBOL_REF_TLS_MODEL (x) : 0; + log = SYMBOL_REF_P (x) ? SYMBOL_REF_TLS_MODEL (x) : 0; if (log) return legitimize_tls_address (x, (enum tls_model) log, false); if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF + && SYMBOL_REF_P (XEXP (XEXP (x, 0), 0)) && (log = SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)))) { rtx t = legitimize_tls_address (XEXP (XEXP (x, 0), 0), @@ -13205,7 +13304,7 @@ ix86_delegitimize_tls_address (rtx orig_x) if (GET_CODE (unspec) != UNSPEC || XINT (unspec, 1) != UNSPEC_NTPOFF) return orig_x; x = XVECEXP (unspec, 0, 0); - gcc_assert (GET_CODE (x) == SYMBOL_REF); + gcc_assert (SYMBOL_REF_P (x)); if (unspec != XEXP (addr.disp, 0)) x = gen_rtx_PLUS (Pmode, x, XEXP (XEXP (addr.disp, 0), 1)); if (addr.index) @@ -13372,7 +13471,7 @@ ix86_delegitimize_address_1 (rtx x, bool base_term_p) else if (base_term_p && pic_offset_table_rtx && !TARGET_MACHO - && !TARGET_VXWORKS_RTP) + && !TARGET_VXWORKS_VAROFF) { rtx tmp = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME); tmp = gen_rtx_MINUS (Pmode, copy_rtx (addend), tmp); @@ -14569,7 +14668,7 @@ ix86_print_operand (FILE *file, rtx x, int code) /* We have patterns that allow zero sets of memory, for instance. In 64-bit mode, we should probably support all 8-byte vectors, since we can in fact encode that into an immediate. */ - if (GET_CODE (x) == CONST_VECTOR) + if (CONST_VECTOR_P (x)) { if (x != CONST0_RTX (GET_MODE (x))) output_operand_lossage ("invalid vector immediate"); @@ -14599,8 +14698,8 @@ ix86_print_operand (FILE *file, rtx x, int code) if (ASSEMBLER_DIALECT == ASM_ATT) putc ('$', file); } - else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF - || GET_CODE (x) == LABEL_REF) + else if (GET_CODE (x) == CONST || SYMBOL_REF_P (x) + || LABEL_REF_P (x)) { if (ASSEMBLER_DIALECT == ASM_ATT) putc ('$', file); @@ -14695,8 +14794,8 @@ ix86_print_operand_address_as (FILE *file, rtx addr, && CONST_INT_P (XEXP (XEXP (disp, 0), 1))) symbol = XEXP (XEXP (disp, 0), 0); - if (GET_CODE (symbol) == LABEL_REF - || (GET_CODE (symbol) == SYMBOL_REF + if (LABEL_REF_P (symbol) + || (SYMBOL_REF_P (symbol) && SYMBOL_REF_TLS_MODEL (symbol) == 0)) base = pc_rtx; } @@ -14784,7 +14883,7 @@ ix86_print_operand_address_as (FILE *file, rtx addr, { if (flag_pic) output_pic_addr_const (file, disp, 0); - else if (GET_CODE (disp) == LABEL_REF) + else if (LABEL_REF_P (disp)) output_asm_label (disp); else output_addr_const (file, disp); @@ -14820,7 +14919,7 @@ ix86_print_operand_address_as (FILE *file, rtx addr, if (flag_pic) output_pic_addr_const (file, disp, 0); - else if (GET_CODE (disp) == LABEL_REF) + else if (LABEL_REF_P (disp)) output_asm_label (disp); else if (CONST_INT_P (disp)) offset = disp; @@ -15772,7 +15871,7 @@ ix86_output_addr_diff_elt (FILE *file, int value, int rel) gcc_assert (!TARGET_64BIT); #endif /* We can't use @GOTOFF for text labels on VxWorks; see gotoff_operand. */ - if (TARGET_64BIT || TARGET_VXWORKS_RTP) + if (TARGET_64BIT || TARGET_VXWORKS_VAROFF) fprintf (file, "%s%s%d-%s%d\n", directive, LPREFIX, value, LPREFIX, rel); #if TARGET_MACHO @@ -16604,6 +16703,10 @@ ix86_convert_const_vector_to_integer (rtx op, machine_mode mode) val = wi::insert (val, wv, innermode_bits * i, innermode_bits); } break; + case E_V1SImode: + case E_V1DImode: + op = CONST_VECTOR_ELT (op, 0); + return INTVAL (op); case E_V2HFmode: case E_V2BFmode: case E_V4HFmode: @@ -17579,8 +17682,8 @@ ix86_rip_relative_addr_p (struct ix86_address *parts) && CONST_INT_P (XEXP (symbol, 1))) symbol = XEXP (symbol, 0); - if (GET_CODE (symbol) == LABEL_REF - || (GET_CODE (symbol) == SYMBOL_REF + if (LABEL_REF_P (symbol) + || (SYMBOL_REF_P (symbol) && SYMBOL_REF_TLS_MODEL (symbol) == 0) || (GET_CODE (symbol) == UNSPEC && (XINT (symbol, 1) == UNSPEC_GOTPCREL @@ -22938,7 +23041,17 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno, } /* This is masked instruction, assume the same cost, as nonmasked variant. */ - else if (TARGET_AVX512F && register_operand (mask, GET_MODE (mask))) + else if (TARGET_AVX512F + && (register_operand (mask, GET_MODE (mask)) + /* Redunduant clean up of high bits for kmask with VL=2/4 + .i.e (vec_merge op0, op1, (and op3 15)). */ + || (GET_CODE (mask) == AND + && register_operand (XEXP (mask, 0), GET_MODE (mask)) + && CONST_INT_P (XEXP (mask, 1)) + && ((INTVAL (XEXP (mask, 1)) == 3 + && GET_MODE_NUNITS (mode) == 2) + || (INTVAL (XEXP (mask, 1)) == 15 + && GET_MODE_NUNITS (mode) == 4))))) { *total = rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed) + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed); @@ -22977,7 +23090,7 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno, /* Make (subreg:V4SI (not:V16QI (reg:V16QI ..)) 0) cost the same as register. This is used by avx_cmp<mode>3_ltint_not. */ - if (GET_CODE (unsop0) == SUBREG) + if (SUBREG_P (unsop0)) unsop0 = XEXP (unsop0, 0); if (GET_CODE (unsop0) == NOT) unsop0 = XEXP (unsop0, 0); @@ -23248,7 +23361,9 @@ x86_this_parameter (tree function) { const int *parm_regs; - if (ix86_function_type_abi (type) == MS_ABI) + if (lookup_attribute ("preserve_none", TYPE_ATTRIBUTES (type))) + parm_regs = x86_64_preserve_none_int_parameter_registers; + else if (ix86_function_type_abi (type) == MS_ABI) parm_regs = x86_64_ms_abi_int_parameter_registers; else parm_regs = x86_64_int_parameter_registers; @@ -23574,19 +23689,21 @@ x86_field_alignment (tree type, int computed) /* Print call to TARGET to FILE. */ static void -x86_print_call_or_nop (FILE *file, const char *target) +x86_print_call_or_nop (FILE *file, const char *target, + const char *label) { if (flag_nop_mcount || !strcmp (target, "nop")) /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1) */ - fprintf (file, "1:" ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n"); + fprintf (file, "%s" ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n", + label); else if (!TARGET_PECOFF && flag_pic) { gcc_assert (flag_plt); - fprintf (file, "1:\tcall\t%s@PLT\n", target); + fprintf (file, "%s\tcall\t%s@PLT\n", label, target); } else - fprintf (file, "1:\tcall\t%s\n", target); + fprintf (file, "%s\tcall\t%s\n", label, target); } static bool @@ -23671,6 +23788,13 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED) const char *mcount_name = MCOUNT_NAME; + bool fentry_section_p + = (flag_record_mcount + || lookup_attribute ("fentry_section", + DECL_ATTRIBUTES (current_function_decl))); + + const char *label = fentry_section_p ? "1:" : ""; + if (current_fentry_name (&mcount_name)) ; else if (fentry_name) @@ -23706,11 +23830,12 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED) reg = legacy_reg; } if (ASSEMBLER_DIALECT == ASM_INTEL) - fprintf (file, "1:\tmovabs\t%s, OFFSET FLAT:%s\n" - "\tcall\t%s\n", reg, mcount_name, reg); + fprintf (file, "%s\tmovabs\t%s, OFFSET FLAT:%s\n" + "\tcall\t%s\n", label, reg, mcount_name, + reg); else - fprintf (file, "1:\tmovabsq\t$%s, %%%s\n\tcall\t*%%%s\n", - mcount_name, reg, reg); + fprintf (file, "%s\tmovabsq\t$%s, %%%s\n\tcall\t*%%%s\n", + label, mcount_name, reg, reg); break; case CM_LARGE_PIC: #ifdef NO_PROFILE_COUNTERS @@ -23751,21 +23876,21 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED) if (!flag_plt) { if (ASSEMBLER_DIALECT == ASM_INTEL) - fprintf (file, "1:\tcall\t[QWORD PTR %s@GOTPCREL[rip]]\n", - mcount_name); + fprintf (file, "%s\tcall\t[QWORD PTR %s@GOTPCREL[rip]]\n", + label, mcount_name); else - fprintf (file, "1:\tcall\t*%s@GOTPCREL(%%rip)\n", - mcount_name); + fprintf (file, "%s\tcall\t*%s@GOTPCREL(%%rip)\n", + label, mcount_name); break; } /* fall through */ default: - x86_print_call_or_nop (file, mcount_name); + x86_print_call_or_nop (file, mcount_name, label); break; } } else - x86_print_call_or_nop (file, mcount_name); + x86_print_call_or_nop (file, mcount_name, label); } else if (flag_pic) { @@ -23780,11 +23905,13 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED) LPREFIX, labelno); #endif if (flag_plt) - x86_print_call_or_nop (file, mcount_name); + x86_print_call_or_nop (file, mcount_name, label); else if (ASSEMBLER_DIALECT == ASM_INTEL) - fprintf (file, "1:\tcall\t[DWORD PTR %s@GOT[ebx]]\n", mcount_name); + fprintf (file, "%s\tcall\t[DWORD PTR %s@GOT[ebx]]\n", + label, mcount_name); else - fprintf (file, "1:\tcall\t*%s@GOT(%%ebx)\n", mcount_name); + fprintf (file, "%s\tcall\t*%s@GOT(%%ebx)\n", + label, mcount_name); } else { @@ -23797,12 +23924,10 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED) fprintf (file, "\tmovl\t$%sP%d, %%" PROFILE_COUNT_REGISTER "\n", LPREFIX, labelno); #endif - x86_print_call_or_nop (file, mcount_name); + x86_print_call_or_nop (file, mcount_name, label); } - if (flag_record_mcount - || lookup_attribute ("fentry_section", - DECL_ATTRIBUTES (current_function_decl))) + if (fentry_section_p) { const char *sname = "__mcount_loc"; @@ -24663,6 +24788,12 @@ static void map_egpr_constraints (vec<const char *> &constraints) buf.safe_push (cur[j + 1]); j++; break; + case '{': + do + { + buf.safe_push (cur[j]); + } while (cur[j++] != '}'); + break; default: buf.safe_push (cur[j]); break; @@ -25676,6 +25807,14 @@ ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind, if (scalar_p) mode = TYPE_MODE (TREE_TYPE (vectype)); } + /* When we are costing a scalar stmt use the scalar stmt to get at the + type of the operation. */ + else if (scalar_p && stmt_info) + if (tree lhs = gimple_get_lhs (stmt_info->stmt)) + { + fp = FLOAT_TYPE_P (TREE_TYPE (lhs)); + mode = TYPE_MODE (TREE_TYPE (lhs)); + } if ((kind == vector_stmt || kind == scalar_stmt) && stmt_info @@ -26173,6 +26312,65 @@ ix86_vector_costs::finish_cost (const vector_costs *scalar_costs) && LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant () >= 16) m_suggested_epilogue_mode = V8QImode; + /* When X86_TUNE_AVX512_MASKED_EPILOGUES is enabled try to use + a masked epilogue if that doesn't seem detrimental. */ + if (loop_vinfo + && !LOOP_VINFO_EPILOGUE_P (loop_vinfo) + && LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant () > 2 + && ix86_tune_features[X86_TUNE_AVX512_MASKED_EPILOGUES] + && !OPTION_SET_P (param_vect_partial_vector_usage)) + { + bool avoid = false; + if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) + && LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) >= 0) + { + unsigned int peel_niter + = LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo); + if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo)) + peel_niter += 1; + /* When we know the number of scalar iterations of the epilogue, + avoid masking when a single vector epilog iteration handles + it in full. */ + if (pow2p_hwi ((LOOP_VINFO_INT_NITERS (loop_vinfo) - peel_niter) + % LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant ())) + avoid = true; + } + if (!avoid && loop_outer (loop_outer (LOOP_VINFO_LOOP (loop_vinfo)))) + for (auto ddr : LOOP_VINFO_DDRS (loop_vinfo)) + { + if (DDR_ARE_DEPENDENT (ddr) == chrec_known) + ; + else if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know) + ; + else + { + int loop_depth + = index_in_loop_nest (LOOP_VINFO_LOOP (loop_vinfo)->num, + DDR_LOOP_NEST (ddr)); + if (DDR_NUM_DIST_VECTS (ddr) == 1 + && DDR_DIST_VECTS (ddr)[0][loop_depth] == 0) + { + /* Avoid the case when there's an outer loop that might + traverse a multi-dimensional array with the inner + loop just executing the masked epilogue with a + read-write where the next outer iteration might + read from the masked part of the previous write, + 'n' filling half a vector. + for (j = 0; j < m; ++j) + for (i = 0; i < n; ++i) + a[j][i] = c * a[j][i]; */ + avoid = true; + break; + } + } + } + if (!avoid) + { + m_suggested_epilogue_mode = loop_vinfo->vector_mode; + m_masked_epilogue = 1; + } + } + vector_costs::finish_cost (scalar_costs); } @@ -26609,7 +26807,7 @@ ix86_reloc_rw_mask (void) static bool symbolic_base_address_p (rtx addr) { - if (GET_CODE (addr) == SYMBOL_REF) + if (SYMBOL_REF_P (addr)) return true; if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_GOTOFF) @@ -28066,6 +28264,195 @@ ix86_cannot_copy_insn_p (rtx_insn *insn) #undef TARGET_DOCUMENTATION_NAME #define TARGET_DOCUMENTATION_NAME "x86" +/* Implement TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS. */ +sbitmap +ix86_get_separate_components (void) +{ + HOST_WIDE_INT offset, to_allocate; + sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER); + bitmap_clear (components); + struct machine_function *m = cfun->machine; + + offset = m->frame.stack_pointer_offset; + to_allocate = offset - m->frame.sse_reg_save_offset; + + /* Shrink wrap separate uses MOV, which means APX PPX cannot be used. + Experiments show that APX PPX can speed up the prologue. If the function + does not exit early during actual execution, then using APX PPX is faster. + If the function always exits early during actual execution, then shrink + wrap separate reduces the number of MOV (PUSH/POP) instructions actually + executed, thus speeding up execution. + foo: + movl $1, %eax + testq %rdi, %rdi + jne.L60 + ret ---> early return. + .L60: + subq $88, %rsp ---> belong to prologue. + xorl %eax, %eax + movq %rbx, 40 (%rsp) ---> belong to prologue. + movq 8 (%rdi), %rbx + movq %rbp, 48 (%rsp) ---> belong to prologue. + movq %rdi, %rbp + testq %rbx, %rbx + jne.L61 + movq 40 (%rsp), %rbx + movq 48 (%rsp), %rbp + addq $88, %rsp + ret + .L61: + movq %r12, 56 (%rsp) ---> belong to prologue. + movq %r13, 64 (%rsp) ---> belong to prologue. + movq %r14, 72 (%rsp) ---> belong to prologue. + ... ... + + Disable shrink wrap separate when PPX is enabled. */ + if ((TARGET_APX_PPX && !crtl->calls_eh_return) + || cfun->machine->func_type != TYPE_NORMAL + || TARGET_SEH + || crtl->stack_realign_needed + || m->call_ms2sysv) + return components; + + /* Since shrink wrapping separate uses MOV instead of PUSH/POP. + Disable shrink wrap separate when MOV is prohibited. */ + if (save_regs_using_push_pop (to_allocate)) + return components; + + for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true)) + { + /* Skip registers with large offsets, where a pseudo may be needed. */ + if (IN_RANGE (offset, -0x8000, 0x7fff)) + bitmap_set_bit (components, regno); + offset += UNITS_PER_WORD; + } + + /* Don't mess with the following registers. */ + if (frame_pointer_needed) + bitmap_clear_bit (components, HARD_FRAME_POINTER_REGNUM); + + if (crtl->drap_reg) + bitmap_clear_bit (components, REGNO (crtl->drap_reg)); + + if (pic_offset_table_rtx) + bitmap_clear_bit (components, REAL_PIC_OFFSET_TABLE_REGNUM); + + return components; +} + +/* Implement TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB. */ +sbitmap +ix86_components_for_bb (basic_block bb) +{ + bitmap in = DF_LIVE_IN (bb); + bitmap gen = &DF_LIVE_BB_INFO (bb)->gen; + bitmap kill = &DF_LIVE_BB_INFO (bb)->kill; + + sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER); + bitmap_clear (components); + + function_abi_aggregator callee_abis; + rtx_insn *insn; + FOR_BB_INSNS (bb, insn) + if (CALL_P (insn)) + callee_abis.note_callee_abi (insn_callee_abi (insn)); + HARD_REG_SET extra_caller_saves = callee_abis.caller_save_regs (*crtl->abi); + + /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets. */ + for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (!fixed_regs[regno] + && (TEST_HARD_REG_BIT (extra_caller_saves, regno) + || bitmap_bit_p (in, regno) + || bitmap_bit_p (gen, regno) + || bitmap_bit_p (kill, regno))) + bitmap_set_bit (components, regno); + + return components; +} + +/* Implement TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS. */ +void +ix86_disqualify_components (sbitmap, edge, sbitmap, bool) +{ + /* Nothing to do for x86. */ +} + +/* Implement TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS. */ +void +ix86_emit_prologue_components (sbitmap components) +{ + HOST_WIDE_INT cfa_offset; + struct machine_function *m = cfun->machine; + + cfa_offset = m->frame.reg_save_offset + m->fs.sp_offset + - m->frame.stack_pointer_offset; + for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true)) + { + if (bitmap_bit_p (components, regno)) + ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset); + cfa_offset -= UNITS_PER_WORD; + } +} + +/* Implement TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS. */ +void +ix86_emit_epilogue_components (sbitmap components) +{ + HOST_WIDE_INT cfa_offset; + struct machine_function *m = cfun->machine; + cfa_offset = m->frame.reg_save_offset + m->fs.sp_offset + - m->frame.stack_pointer_offset; + + for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true)) + { + if (bitmap_bit_p (components, regno)) + { + rtx reg = gen_rtx_REG (word_mode, regno); + rtx mem; + rtx_insn *insn; + + mem = choose_baseaddr (cfa_offset, NULL); + mem = gen_frame_mem (word_mode, mem); + insn = emit_move_insn (reg, mem); + + RTX_FRAME_RELATED_P (insn) = 1; + add_reg_note (insn, REG_CFA_RESTORE, reg); + } + cfa_offset -= UNITS_PER_WORD; + } +} + +/* Implement TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS. */ +void +ix86_set_handled_components (sbitmap components) +{ + for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (bitmap_bit_p (components, regno)) + { + cfun->machine->reg_is_wrapped_separately[regno] = true; + cfun->machine->use_fast_prologue_epilogue = true; + cfun->machine->frame.save_regs_using_mov = true; + } +} + +#undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS +#define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS ix86_get_separate_components +#undef TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB +#define TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB ix86_components_for_bb +#undef TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS +#define TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS ix86_disqualify_components +#undef TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS +#define TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS \ + ix86_emit_prologue_components +#undef TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS +#define TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS \ + ix86_emit_epilogue_components +#undef TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS +#define TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS ix86_set_handled_components + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-i386.h" diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index d32d9ad997e6..791f3b9e1338 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1696,6 +1696,8 @@ typedef struct ix86_args { int stdarg; /* Set to 1 if function is stdarg. */ enum calling_abi call_abi; /* Set to SYSV_ABI for sysv abi. Otherwise MS_ABI for ms abi. */ + bool preserve_none_abi; /* Set to true if the preserve_none ABI is + used. */ tree decl; /* Callee decl. */ } CUMULATIVE_ARGS; @@ -1840,8 +1842,8 @@ typedef struct ix86_args { #define STRIP_UNARY(X) (UNARY_P (X) ? XEXP (X, 0) : X) #define SYMBOLIC_CONST(X) \ - (GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == LABEL_REF \ + (SYMBOL_REF_P (X) \ + || LABEL_REF_P (X) \ || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X))) /* Max number of args passed in registers. If this is more than 3, we will @@ -2446,12 +2448,14 @@ constexpr wide_int_bitmask PTA_GOLDMONT_PLUS = PTA_GOLDMONT | PTA_RDPID | PTA_SGX | PTA_PTWRITE; constexpr wide_int_bitmask PTA_TREMONT = PTA_GOLDMONT_PLUS | PTA_CLWB | PTA_GFNI | PTA_MOVDIRI | PTA_MOVDIR64B | PTA_CLDEMOTE | PTA_WAITPKG; -constexpr wide_int_bitmask PTA_ALDERLAKE = PTA_TREMONT | PTA_ADX | PTA_AVX +constexpr wide_int_bitmask PTA_ALDERLAKE = PTA_GOLDMONT_PLUS | PTA_CLWB + | PTA_GFNI | PTA_MOVDIRI | PTA_MOVDIR64B | PTA_WAITPKG | PTA_ADX | PTA_AVX | PTA_AVX2 | PTA_BMI | PTA_BMI2 | PTA_F16C | PTA_FMA | PTA_LZCNT | PTA_PCONFIG | PTA_PKU | PTA_VAES | PTA_VPCLMULQDQ | PTA_SERIALIZE | PTA_HRESET | PTA_KL | PTA_WIDEKL | PTA_AVXVNNI; -constexpr wide_int_bitmask PTA_SIERRAFOREST = PTA_ALDERLAKE | PTA_AVXIFMA - | PTA_AVXVNNIINT8 | PTA_AVXNECONVERT | PTA_CMPCCXADD | PTA_ENQCMD | PTA_UINTR; +constexpr wide_int_bitmask PTA_SIERRAFOREST = PTA_ALDERLAKE | PTA_CLDEMOTE + | PTA_AVXIFMA | PTA_AVXVNNIINT8 | PTA_AVXNECONVERT | PTA_CMPCCXADD + | PTA_ENQCMD | PTA_UINTR; constexpr wide_int_bitmask PTA_GRANITERAPIDS = PTA_SAPPHIRERAPIDS | PTA_AMX_FP16 | PTA_PREFETCHI | PTA_AVX10_1; constexpr wide_int_bitmask PTA_GRANITERAPIDS_D = PTA_GRANITERAPIDS @@ -2461,10 +2465,11 @@ constexpr wide_int_bitmask PTA_ARROWLAKE = PTA_ALDERLAKE | PTA_AVXIFMA | PTA_AVXVNNIINT8 | PTA_AVXNECONVERT | PTA_CMPCCXADD | PTA_UINTR; constexpr wide_int_bitmask PTA_ARROWLAKE_S = PTA_ARROWLAKE | PTA_AVXVNNIINT16 | PTA_SHA512 | PTA_SM3 | PTA_SM4; -constexpr wide_int_bitmask PTA_CLEARWATERFOREST = PTA_SIERRAFOREST - | PTA_AVXVNNIINT16 | PTA_SHA512 | PTA_SM3 | PTA_SM4 | PTA_USER_MSR - | PTA_PREFETCHI; -constexpr wide_int_bitmask PTA_PANTHERLAKE = PTA_ARROWLAKE_S | PTA_PREFETCHI; +constexpr wide_int_bitmask PTA_CLEARWATERFOREST = + (PTA_SIERRAFOREST & (~(PTA_KL | PTA_WIDEKL))) | PTA_AVXVNNIINT16 | PTA_SHA512 + | PTA_SM3 | PTA_SM4 | PTA_USER_MSR | PTA_PREFETCHI; +constexpr wide_int_bitmask PTA_PANTHERLAKE = + (PTA_ARROWLAKE_S & (~(PTA_KL | PTA_WIDEKL))) | PTA_PREFETCHI; constexpr wide_int_bitmask PTA_DIAMONDRAPIDS = PTA_GRANITERAPIDS_D | PTA_AVXIFMA | PTA_AVXNECONVERT | PTA_AVXVNNIINT16 | PTA_AVXVNNIINT8 | PTA_CMPCCXADD | PTA_SHA512 | PTA_SM3 | PTA_SM4 | PTA_AVX10_2 @@ -2798,11 +2803,13 @@ enum call_saved_registers_type or "no_caller_saved_registers" attribute. */ TYPE_NO_CALLER_SAVED_REGISTERS, /* The current function is a function specified with the - "no_callee_saved_registers" attribute. */ + "no_callee_saved_registers" attribute or a function specified with + the "noreturn" attribute when compiled with + "-mnoreturn-no-callee-saved-registers". */ TYPE_NO_CALLEE_SAVED_REGISTERS, - /* The current function is a function specified with the "noreturn" - attribute. */ - TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP, + /* The current function is a function specified with the + "preserve_none" attribute. */ + TYPE_PRESERVE_NONE, }; enum queued_insn_type @@ -2821,6 +2828,10 @@ struct GTY(()) machine_function { /* Cached initial frame layout for the current function. */ struct ix86_frame frame; + /* The components already handled by separate shrink-wrapping, which should + not be considered by the prologue and epilogue. */ + bool reg_is_wrapped_separately[FIRST_PSEUDO_REGISTER]; + /* For -fsplit-stack support: A stack local which holds a pointer to the stack arguments for a function with a variable number of arguments. This is set at the start of the function and is used @@ -2875,7 +2886,7 @@ struct GTY(()) machine_function { ENUM_BITFIELD(indirect_branch) function_return_type : 3; /* Call saved registers type. */ - ENUM_BITFIELD(call_saved_registers_type) call_saved_registers : 2; + ENUM_BITFIELD(call_saved_registers_type) call_saved_registers : 3; /* If true, there is register available for argument passing. This is used only in ix86_function_ok_for_sibcall by 32-bit to determine @@ -2920,6 +2931,9 @@ struct GTY(()) machine_function { /* True if inline asm with redzone clobber has been seen. */ BOOL_BITFIELD asm_redzone_clobber_seen : 1; + /* True if this is a recursive function. */ + BOOL_BITFIELD recursive_function : 1; + /* The largest alignment, in bytes, of stack slot actually used. */ unsigned int max_used_stack_alignment; diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 40b43cf092ac..eb526997584b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -2438,22 +2438,32 @@ (set_attr "mode" "SI") (set_attr "length_immediate" "0")]) -(define_insn "*mov<mode>_and" +;; Generate shorter "and $0,mem" for -Oz. Split it to "mov $0,mem" +;; otherwise. +(define_insn_and_split "*mov<mode>_and" [(set (match_operand:SWI248 0 "memory_operand" "=m") (match_operand:SWI248 1 "const0_operand")) (clobber (reg:CC FLAGS_REG))] "reload_completed" "and{<imodesuffix>}\t{%1, %0|%0, %1}" + "&& !(optimize_insn_for_size_p () && optimize_size > 1)" + [(set (match_dup 0) (match_dup 1))] + "" [(set_attr "type" "alu1") (set_attr "mode" "<MODE>") (set_attr "length_immediate" "1")]) -(define_insn "*mov<mode>_or" +;; Generate shorter "or $-1,mem" for -Oz. Split it to "mov $-1,mem" +;; otherwise. +(define_insn_and_split "*mov<mode>_or" [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm") (match_operand:SWI248 1 "constm1_operand")) (clobber (reg:CC FLAGS_REG))] "reload_completed" "or{<imodesuffix>}\t{%1, %0|%0, %1}" + "&& !(optimize_insn_for_size_p () && optimize_size > 1)" + [(set (match_dup 0) (match_dup 1))] + "" [(set_attr "type" "alu1") (set_attr "mode" "<MODE>") (set_attr "length_immediate" "1")]) @@ -2958,6 +2968,7 @@ (match_operand:SWI248 1 "const_int_operand"))] "optimize_insn_for_size_p () && optimize_size > 1 && operands[1] != const0_rtx + && operands[1] != constm1_rtx && IN_RANGE (INTVAL (operands[1]), -128, 127) && !ix86_red_zone_used && REGNO (operands[0]) != SP_REG" @@ -12799,8 +12810,8 @@ (zero_extend:DI (and:SI (match_dup 1) (match_dup 2)))) (clobber (reg:CC FLAGS_REG))])] { - if (GET_CODE (operands[2]) == SYMBOL_REF - || GET_CODE (operands[2]) == LABEL_REF) + if (SYMBOL_REF_P (operands[2]) + || LABEL_REF_P (operands[2])) { operands[2] = shallow_copy_rtx (operands[2]); PUT_MODE (operands[2], SImode); @@ -14758,6 +14769,17 @@ (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0))) (set (match_dup 0) (neg:SWI (match_dup 0)))])]) +;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384) with APX_F +(define_peephole2 + [(parallel [(set (match_operand:SWI 0 "general_reg_operand") + (neg:SWI (match_operand:SWI 1 "general_reg_operand"))) + (clobber (reg:CC FLAGS_REG))]) + (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))] + "TARGET_APX_NDD" + [(parallel [(set (reg:CCZ FLAGS_REG) + (compare:CCZ (neg:SWI (match_dup 1)) (const_int 0))) + (set (match_dup 0) (neg:SWI (match_dup 1)))])]) + ;; Special expand pattern to handle integer mode abs (define_expand "abs<mode>2" @@ -20091,7 +20113,7 @@ /* We can't use @GOTOFF for text labels on VxWorks; see gotoff_operand. */ - if (TARGET_64BIT || TARGET_VXWORKS_RTP) + if (TARGET_64BIT || TARGET_VXWORKS_VAROFF) { code = PLUS; op0 = operands[0]; @@ -20959,7 +20981,7 @@ (clobber (reg:CC FLAGS_REG))])] "!TARGET_64BIT" { - if (flag_pic && !TARGET_VXWORKS_RTP) + if (flag_pic && !TARGET_VXWORKS_GOTTPIC) ix86_pc_thunk_call_expanded = true; }) @@ -20980,7 +21002,7 @@ (clobber (reg:CC FLAGS_REG))])] "!TARGET_64BIT" { - if (flag_pic && !TARGET_VXWORKS_RTP) + if (flag_pic && !TARGET_VXWORKS_GOTTPIC) ix86_pc_thunk_call_expanded = true; }) @@ -21512,11 +21534,12 @@ (set_attr "mode" "SI")]) ; As bsr is undefined behavior on zero and for other input -; values it is in range 0 to 63, we can optimize away sign-extends. -(define_insn_and_split "*bsr_rex64_2" +; values it is in range 0 to 63, we can optimize away sign-extends +; or zero-extends. +(define_insn_and_split "*bsr_rex64<u>_2" [(set (match_operand:DI 0 "register_operand") (xor:DI - (sign_extend:DI + (any_extend:DI (minus:SI (const_int 63) (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand")) @@ -21538,9 +21561,9 @@ operands[3] = lowpart_subreg (SImode, operands[2], DImode); }) -(define_insn_and_split "*bsr_2" +(define_insn_and_split "*bsr<u>_2" [(set (match_operand:DI 0 "register_operand") - (sign_extend:DI + (any_extend:DI (xor:SI (minus:SI (const_int 31) @@ -21617,7 +21640,7 @@ (minus:DI (match_operand:DI 2 "const_int_operand") (xor:DI - (sign_extend:DI + (any_extend:DI (minus:SI (const_int 63) (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand")) @@ -21647,7 +21670,7 @@ [(set (match_operand:DI 0 "register_operand") (minus:DI (match_operand:DI 2 "const_int_operand") - (sign_extend:DI + (any_extend:DI (xor:SI (minus:SI (const_int 31) (clz:SI (match_operand:SI 1 "nonimmediate_operand"))) @@ -23189,7 +23212,8 @@ (match_operand 3))) (unspec:P [(match_operand 1 "tls_symbolic_operand") (reg:P SP_REG)] - UNSPEC_TLS_GD)] + UNSPEC_TLS_GD) + (clobber (match_operand:P 4 "register_operand" "=D"))] "TARGET_64BIT" { if (!TARGET_X32) @@ -23206,7 +23230,7 @@ Use data16 prefix instead, which doesn't have this problem. */ fputs ("\tdata16", asm_out_file); output_asm_insn - ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); + ("lea{q}\t{%E1@tlsgd(%%rip), %q4|%q4, %E1@tlsgd[rip]}", operands); if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) fputs (ASM_SHORT "0x6666\n", asm_out_file); else @@ -23230,14 +23254,15 @@ (match_operand 4))) (unspec:DI [(match_operand 1 "tls_symbolic_operand") (reg:DI SP_REG)] - UNSPEC_TLS_GD)] + UNSPEC_TLS_GD) + (clobber (match_operand:DI 5 "register_operand" "=D"))] "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF && GET_CODE (operands[3]) == CONST && GET_CODE (XEXP (operands[3], 0)) == UNSPEC && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF" { output_asm_insn - ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); + ("lea{q}\t{%E1@tlsgd(%%rip), %5|%5, %E1@tlsgd[rip]}", operands); output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands); output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands); return "call\t{*%%rax|rax}"; @@ -23253,7 +23278,8 @@ (const_int 0))) (unspec:P [(match_operand 1 "tls_symbolic_operand") (reg:P SP_REG)] - UNSPEC_TLS_GD)])] + UNSPEC_TLS_GD) + (clobber (match_operand:P 3 "register_operand"))])] "TARGET_64BIT" "ix86_tls_descriptor_calls_expanded_in_cfun = true;") @@ -23304,11 +23330,12 @@ (call:P (mem:QI (match_operand 1 "constant_call_address_operand" "Bz")) (match_operand 2))) - (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)] + (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE) + (clobber (match_operand:P 3 "register_operand" "=D"))] "TARGET_64BIT" { output_asm_insn - ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); + ("lea{q}\t{%&@tlsld(%%rip), %q3|%q3, %&@tlsld[rip]}", operands); if (TARGET_SUN_TLS) return "call\t%p1@plt"; if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) @@ -23324,14 +23351,15 @@ (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b") (match_operand:DI 2 "immediate_operand" "i"))) (match_operand 3))) - (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)] + (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE) + (clobber (match_operand:DI 4 "register_operand" "=D"))] "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF && GET_CODE (operands[2]) == CONST && GET_CODE (XEXP (operands[2], 0)) == UNSPEC && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF" { output_asm_insn - ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); + ("lea{q}\t{%&@tlsld(%%rip), %4|%4, %&@tlsld[rip]}", operands); output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands); output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands); return "call\t{*%%rax|rax}"; @@ -23345,7 +23373,8 @@ (call:P (mem:QI (match_operand 1)) (const_int 0))) - (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])] + (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE) + (clobber (match_operand:P 2 "register_operand"))])] "TARGET_64BIT" "ix86_tls_descriptor_calls_expanded_in_cfun = true;") @@ -26478,8 +26507,8 @@ (define_expand "mov<mode>cc" [(set (match_operand:SWIM 0 "register_operand") (if_then_else:SWIM (match_operand 1 "comparison_operator") - (match_operand:SWIM 2 "<general_operand>") - (match_operand:SWIM 3 "<general_operand>")))] + (match_operand:SWIM 2 "general_operand") + (match_operand:SWIM 3 "general_operand")))] "" "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;") @@ -27437,7 +27466,7 @@ (cond [(and (eq_attr "alternative" "0") (not (match_test "TARGET_OPT_AGU"))) (const_string "alu") - (match_operand:<MODE> 2 "const0_operand") + (match_operand 2 "const0_operand") (const_string "imov") ] (const_string "lea"))) @@ -27451,6 +27480,46 @@ (const_string "*"))) (set_attr "mode" "<MODE>")]) +(define_insn "@pro_epilogue_adjust_stack_add_nocc<mode>" + [(set (match_operand:P 0 "register_operand" "=r") + (plus:P (match_operand:P 1 "register_operand" "r") + (match_operand:P 2 "<nonmemory_operand>" "l<i>"))) + (clobber (mem:BLK (scratch)))] + "" +{ + if (get_attr_type (insn) == TYPE_IMOV) + return "mov{<imodesuffix>}\t{%1, %0|%0, %1}"; + else + { + operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); + return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}"; + } +} + [(set (attr "type") + (cond [(match_operand 2 "const0_operand") + (const_string "imov") + ] + (const_string "lea"))) + (set (attr "length_immediate") + (cond [(eq_attr "type" "imov") + (const_string "0") + ] + (const_string "*"))) + (set_attr "mode" "<MODE>")]) + +(define_peephole2 + [(parallel + [(set (match_operand:P 0 "register_operand") + (plus:P (match_dup 0) + (match_operand:P 1 "<nonmemory_operand>"))) + (clobber (mem:BLK (scratch)))])] + "peep2_regno_dead_p (0, FLAGS_REG)" + [(parallel + [(set (match_dup 0) + (plus:P (match_dup 0) (match_dup 1))) + (clobber (reg:CC FLAGS_REG)) + (clobber (mem:BLK (scratch)))])]) + (define_insn "@pro_epilogue_adjust_stack_sub_<mode>" [(set (match_operand:P 0 "register_operand" "=r") (minus:P (match_operand:P 1 "register_operand" "0") @@ -29471,6 +29540,23 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) +(define_expand "crc_rev<SWI124:mode>si4" + [(match_operand:SI 0 "register_operand") + (match_operand:SI 1 "register_operand") + (match_operand:SWI124 2 "nonimmediate_operand") + (match_operand:SI 3)] + "TARGET_CRC32" +{ + /* crc32 uses iSCSI polynomial */ + if (INTVAL (operands[3]) == 0x1EDC6F41) + emit_insn (gen_sse4_2_crc32<mode> (operands[0], operands[1], operands[2])); + else + expand_reversed_crc_table_based (operands[0], operands[1], operands[2], + operands[3], <SWI124:MODE>mode, + generate_reflecting_code_standard); + DONE; +}) + (define_insn "rdpmc" [(set (match_operand:DI 0 "register_operand" "=A") (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")] diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index 79202323e534..1f9799344b64 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -81,12 +81,13 @@ ;; 4-byte and 2-byte QImode vector modes (define_mode_iterator VI1_16_32 [V4QI V2QI]) -;; All 2-byte, 4-byte and 8-byte vector modes with more than 1 element +;; All 2-byte, 4-byte and 8-byte vector modes. (define_mode_iterator V_16_32_64 - [V2QI V4QI V2HI V2HF + [V2QI V4QI V2HI V1SI V2HF V2BF (V8QI "TARGET_64BIT") (V4HI "TARGET_64BIT") (V4HF "TARGET_64BIT") (V4BF "TARGET_64BIT") - (V2SI "TARGET_64BIT") (V2SF "TARGET_64BIT")]) + (V2SI "TARGET_64BIT") (V2SF "TARGET_64BIT") + (V1DI "TARGET_64BIT")]) ;; V2S* modes (define_mode_iterator V2FI [V2SF V2SI]) @@ -107,6 +108,7 @@ [(V8QI "DI") (V4QI "SI") (V2QI "HI") (V4HI "DI") (V2HI "SI") (V2SI "DI") + (V1DI "DI") (V1SI "SI") (V4HF "DI") (V2HF "SI") (V4BF "DI") (V2BF "SI") (V2SF "DI")]) @@ -329,7 +331,7 @@ (define_expand "mov<mode>" [(set (match_operand:V_32 0 "nonimmediate_operand") - (match_operand:V_32 1 "nonimmediate_operand"))] + (match_operand:V_32 1 "nonimm_or_0_operand"))] "" { ix86_expand_vector_move (<MODE>mode, operands); @@ -339,7 +341,7 @@ (define_insn "*mov<mode>_internal" [(set (match_operand:V_32 0 "nonimmediate_operand" "=r ,m ,v,v,v,m,r,v") - (match_operand:V_32 1 "general_operand" + (match_operand:V_32 1 "nonimm_or_0_operand" "rmC,rC,C,v,m,v,v,r"))] "!(MEM_P (operands[0]) && MEM_P (operands[1])) && ix86_hardreg_mov_ok (operands[0], operands[1])" @@ -407,22 +409,6 @@ ] (symbol_ref "true")))]) -;; 16-bit, 32-bit and 64-bit constant vector stores. After reload, -;; convert them to immediate integer stores. -(define_insn_and_split "*mov<mode>_imm" - [(set (match_operand:V_16_32_64 0 "memory_operand" "=m") - (match_operand:V_16_32_64 1 "x86_64_const_vector_operand" "i"))] - "" - "#" - "&& reload_completed" - [(set (match_dup 0) (match_dup 1))] -{ - HOST_WIDE_INT val = ix86_convert_const_vector_to_integer (operands[1], - <MODE>mode); - operands[1] = GEN_INT (val); - operands[0] = lowpart_subreg (<mmxinsnmode>mode, operands[0], <MODE>mode); -}) - ;; For TARGET_64BIT we always round up to 8 bytes. (define_insn "*push<mode>2_rex64" [(set (match_operand:V_32 0 "push_operand" "=X,X") @@ -457,7 +443,7 @@ (define_expand "movv2qi" [(set (match_operand:V2QI 0 "nonimmediate_operand") - (match_operand:V2QI 1 "nonimmediate_operand"))] + (match_operand:V2QI 1 "nonimm_or_0_operand"))] "" { ix86_expand_vector_move (V2QImode, operands); @@ -467,9 +453,10 @@ (define_insn "*movv2qi_internal" [(set (match_operand:V2QI 0 "nonimmediate_operand" "=r,r,r,m ,v,v,v,jm,m,r,v") - (match_operand:V2QI 1 "general_operand" + (match_operand:V2QI 1 "nonimm_or_0_operand" "r ,C,m,rC,C,v,m,x,v,v,r"))] - "!(MEM_P (operands[0]) && MEM_P (operands[1]))" + "!(MEM_P (operands[0]) && MEM_P (operands[1])) + && ix86_hardreg_mov_ok (operands[0], operands[1])" { switch (get_attr_type (insn)) { @@ -587,6 +574,42 @@ ] (symbol_ref "true")))]) +(define_split + [(set (match_operand:V_16_32_64 0 "general_reg_operand") + (match_operand:V_16_32_64 1 "memory_operand"))] + "reload_completed + && SYMBOL_REF_P (XEXP (operands[1], 0)) + && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))" + [(set (match_dup 0) (match_dup 1))] +{ + rtx op1 = avoid_constant_pool_reference (operands[1]); + + if (!CONST_VECTOR_P (op1)) + FAIL; + + HOST_WIDE_INT val = ix86_convert_const_vector_to_integer (op1, <MODE>mode); + + operands[0] = lowpart_subreg (<mmxinsnmode>mode, operands[0], <MODE>mode); + operands[1] = GEN_INT (val); +}) + +;; 16-bit, 32-bit and 64-bit constant vector stores. After reload, +;; convert them to immediate integer stores. +(define_insn_and_split "*mov<mode>_imm" + [(set (match_operand:V_16_32_64 0 "memory_operand" "=m") + (match_operand:V_16_32_64 1 "x86_64_const_vector_operand" "i"))] + "" + "#" + "&& reload_completed" + [(set (match_dup 0) (match_dup 1))] +{ + rtx op1 = operands[1]; + HOST_WIDE_INT val = ix86_convert_const_vector_to_integer (op1, <MODE>mode); + + operands[0] = adjust_address (operands[0], <mmxinsnmode>mode, 0); + operands[1] = GEN_INT (val); +}) + ;; We always round up to UNITS_PER_WORD bytes. (define_insn "*pushv2qi2" [(set (match_operand:V2QI 0 "push_operand" "=X,X") diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 1bd63b2367e1..b2d2eecc64f6 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -573,8 +573,8 @@ case CONST: op = XEXP (op, 0); - if (GET_CODE (op) == SYMBOL_REF - || GET_CODE (op) == LABEL_REF + if (SYMBOL_REF_P (op) + || LABEL_REF_P (op) || (GET_CODE (op) == UNSPEC && (XINT (op, 1) == UNSPEC_GOT || XINT (op, 1) == UNSPEC_GOTOFF @@ -586,8 +586,8 @@ return false; op = XEXP (op, 0); - if (GET_CODE (op) == SYMBOL_REF - || GET_CODE (op) == LABEL_REF) + if (SYMBOL_REF_P (op) + || LABEL_REF_P (op)) return true; /* Only @GOTOFF gets offsets. */ if (GET_CODE (op) != UNSPEC @@ -595,8 +595,8 @@ return false; op = XVECEXP (op, 0, 0); - if (GET_CODE (op) == SYMBOL_REF - || GET_CODE (op) == LABEL_REF) + if (SYMBOL_REF_P (op) + || LABEL_REF_P (op)) return true; return false; @@ -614,10 +614,10 @@ && CONST_INT_P (XEXP (XEXP (op, 0), 1))) op = XEXP (XEXP (op, 0), 0); - if (GET_CODE (op) == LABEL_REF) + if (LABEL_REF_P (op)) return true; - if (GET_CODE (op) != SYMBOL_REF) + if (!SYMBOL_REF_P (op)) return false; if (SYMBOL_REF_TLS_MODEL (op)) @@ -649,7 +649,7 @@ && CONST_INT_P (XEXP (XEXP (op, 0), 1))) op = XEXP (XEXP (op, 0), 0); - if (GET_CODE (op) == SYMBOL_REF + if (SYMBOL_REF_P (op) && !SYMBOL_REF_FUNCTION_P (op)) return false; @@ -664,8 +664,9 @@ ;; same segment as the GOT. Unfortunately, the flexibility of linker ;; scripts means that we can't be sure of that in general, so assume ;; @GOTOFF is not valid on VxWorks, except with the large code model. +;; The comments above seem to apply only to VxWorks releases before 7. (define_predicate "gotoff_operand" - (and (ior (not (match_test "TARGET_VXWORKS_RTP")) + (and (ior (not (match_test "TARGET_VXWORKS_VAROFF")) (match_test "ix86_cmodel == CM_LARGE") (match_test "ix86_cmodel == CM_LARGE_PIC")) (match_operand 0 "local_symbolic_operand"))) @@ -1144,7 +1145,7 @@ unsigned n_elts; op = avoid_constant_pool_reference (op); - if (GET_CODE (op) != CONST_VECTOR) + if (!CONST_VECTOR_P (op)) return false; n_elts = CONST_VECTOR_NUNITS (op); @@ -1172,7 +1173,7 @@ if (MEM_P (op)) { op = get_pool_constant (XEXP (op, 0)); - if (GET_CODE (op) != CONST_VECTOR) + if (!CONST_VECTOR_P (op)) return false; if (GET_MODE (op) != mode @@ -1421,8 +1422,8 @@ } if (TARGET_64BIT && flag_pic - && (GET_CODE (disp) == SYMBOL_REF - || GET_CODE (disp) == LABEL_REF)) + && (SYMBOL_REF_P (disp) + || LABEL_REF_P (disp))) return false; } diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index aea5e2cad7e1..d88c3d60bffe 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -1589,6 +1589,44 @@ "&& 1" [(set (match_dup 0) (match_dup 1))]) +(define_insn_and_split "*<avx512>_load<mode>mask_and15" + [(set (match_operand:V48_AVX512VL_4 0 "register_operand" "=v") + (vec_merge:V48_AVX512VL_4 + (unspec:V48_AVX512VL_4 + [(match_operand:V48_AVX512VL_4 1 "memory_operand" "m")] + UNSPEC_MASKLOAD) + (match_operand:V48_AVX512VL_4 2 "nonimm_or_0_operand" "0C") + (and:QI + (match_operand:QI 3 "register_operand" "Yk") + (const_int 15))))] + "TARGET_AVX512F" + "#" + "&& 1" + [(set (match_dup 0) + (vec_merge:V48_AVX512VL_4 + (unspec:V48_AVX512VL_4 [(match_dup 1)] UNSPEC_MASKLOAD) + (match_dup 2) + (match_dup 3)))]) + +(define_insn_and_split "*<avx512>_load<mode>mask_and3" + [(set (match_operand:V8_AVX512VL_2 0 "register_operand" "=v") + (vec_merge:V8_AVX512VL_2 + (unspec:V8_AVX512VL_2 + [(match_operand:V8_AVX512VL_2 1 "memory_operand" "m")] + UNSPEC_MASKLOAD) + (match_operand:V8_AVX512VL_2 2 "nonimm_or_0_operand" "0C") + (and:QI + (match_operand:QI 3 "register_operand" "Yk") + (const_int 3))))] + "TARGET_AVX512F" + "#" + "&& 1" + [(set (match_dup 0) + (vec_merge:V8_AVX512VL_2 + (unspec:V8_AVX512VL_2 [(match_dup 1)] UNSPEC_MASKLOAD) + (match_dup 2) + (match_dup 3)))]) + (define_expand "<avx512>_load<mode>_mask" [(set (match_operand:VI12_AVX512VL 0 "register_operand") (vec_merge:VI12_AVX512VL @@ -12718,7 +12756,7 @@ lo insns have =m and 0C constraints. */ : (operands[2] != const0_rtx || (!rtx_equal_p (dest, operands[3]) - && GET_CODE (operands[3]) != CONST_VECTOR)))) + && !CONST_VECTOR_P (operands[3]))))) dest = gen_reg_rtx (<ssehalfvecmode>mode); switch (INTVAL (operands[2])) { @@ -13418,7 +13456,7 @@ (const_int 6) (const_int 14)])))] "TARGET_AVX512F" "vmovddup\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}" - [(set_attr "type" "sselog1") + [(set_attr "type" "ssemov") (set_attr "prefix" "evex") (set_attr "mode" "V8DF")]) @@ -13449,7 +13487,7 @@ (const_int 2) (const_int 6)])))] "TARGET_AVX && <mask_avx512vl_condition>" "vmovddup\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}" - [(set_attr "type" "sselog1") + [(set_attr "type" "ssemov") (set_attr "prefix" "<mask_prefix>") (set_attr "mode" "V4DF")]) @@ -27839,7 +27877,7 @@ %vmovddup\t{%1, %0|%0, %1} movlhps\t%0, %0" [(set_attr "isa" "sse2_noavx,avx,avx512f,sse3,noavx") - (set_attr "type" "sselog1,sselog1,ssemov,sselog1,ssemov") + (set_attr "type" "sselog1,sselog1,ssemov,ssemov,ssemov") (set_attr "prefix" "orig,maybe_evex,evex,maybe_vex,orig") (set (attr "mode") (cond [(and (eq_attr "alternative" "2") diff --git a/gcc/config/i386/x86-tune-costs.h b/gcc/config/i386/x86-tune-costs.h index b08081e37cfb..c8603b982af4 100644 --- a/gcc/config/i386/x86-tune-costs.h +++ b/gcc/config/i386/x86-tune-costs.h @@ -3568,127 +3568,6 @@ struct processor_costs tremont_cost = { COSTS_N_INSNS (2), /* Branch mispredict scale. */ }; -static stringop_algs intel_memcpy[2] = { - {libcall, {{11, loop, false}, {-1, rep_prefix_4_byte, false}}}, - {libcall, {{32, loop, false}, {64, rep_prefix_4_byte, false}, - {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; -static stringop_algs intel_memset[2] = { - {libcall, {{8, loop, false}, {15, unrolled_loop, false}, - {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}}, - {libcall, {{24, loop, false}, {32, unrolled_loop, false}, - {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; -static const -struct processor_costs intel_cost = { - { - /* Start of register allocator costs. integer->integer move cost is 2. */ - 6, /* cost for loading QImode using movzbl */ - {4, 4, 4}, /* cost of loading integer registers - in QImode, HImode and SImode. - Relative to reg-reg move (2). */ - {6, 6, 6}, /* cost of storing integer registers */ - 2, /* cost of reg,reg fld/fst */ - {6, 6, 8}, /* cost of loading fp registers - in SFmode, DFmode and XFmode */ - {6, 6, 10}, /* cost of storing fp registers - in SFmode, DFmode and XFmode */ - 2, /* cost of moving MMX register */ - {6, 6}, /* cost of loading MMX registers - in SImode and DImode */ - {6, 6}, /* cost of storing MMX registers - in SImode and DImode */ - 2, 2, 2, /* cost of moving XMM,YMM,ZMM register */ - {6, 6, 6, 6, 6}, /* cost of loading SSE registers - in 32,64,128,256 and 512-bit */ - {6, 6, 6, 6, 6}, /* cost of storing SSE registers - in 32,64,128,256 and 512-bit */ - 4, 4, /* SSE->integer and integer->SSE moves */ - 4, 4, /* mask->integer and integer->mask moves */ - {4, 4, 4}, /* cost of loading mask register - in QImode, HImode, SImode. */ - {6, 6, 6}, /* cost if storing mask register - in QImode, HImode, SImode. */ - 2, /* cost of moving mask register. */ - /* End of register allocator costs. */ - }, - - COSTS_N_INSNS (1), /* cost of an add instruction */ - COSTS_N_INSNS (1) + 1, /* cost of a lea instruction */ - COSTS_N_INSNS (1), /* variable shift costs */ - COSTS_N_INSNS (1), /* constant shift costs */ - {COSTS_N_INSNS (3), /* cost of starting multiply for QI */ - COSTS_N_INSNS (3), /* HI */ - COSTS_N_INSNS (3), /* SI */ - COSTS_N_INSNS (4), /* DI */ - COSTS_N_INSNS (2)}, /* other */ - 0, /* cost of multiply per each bit set */ - {COSTS_N_INSNS (18), /* cost of a divide/mod for QI */ - COSTS_N_INSNS (26), /* HI */ - COSTS_N_INSNS (42), /* SI */ - COSTS_N_INSNS (74), /* DI */ - COSTS_N_INSNS (74)}, /* other */ - COSTS_N_INSNS (1), /* cost of movsx */ - COSTS_N_INSNS (1), /* cost of movzx */ - 8, /* "large" insn */ - 17, /* MOVE_RATIO */ - 6, /* CLEAR_RATIO */ - {4, 4, 4}, /* cost of loading integer registers - in QImode, HImode and SImode. - Relative to reg-reg move (2). */ - {6, 6, 6}, /* cost of storing integer registers */ - {6, 6, 6, 6, 6}, /* cost of loading SSE register - in 32bit, 64bit, 128bit, 256bit and 512bit */ - {6, 6, 6, 6, 6}, /* cost of storing SSE register - in 32bit, 64bit, 128bit, 256bit and 512bit */ - {10, 10, 10, 10, 10}, /* cost of unaligned loads. */ - {10, 10, 10, 10, 10}, /* cost of unaligned loads. */ - 2, 2, 2, /* cost of moving XMM,YMM,ZMM register */ - 4, /* cost of moving SSE register to integer. */ - 4, /* cost of moving integer register to SSE. */ - 6, 6, /* Gather load static, per_elt. */ - 6, 6, /* Gather store static, per_elt. */ - 32, /* size of l1 cache. */ - 256, /* size of l2 cache. */ - 64, /* size of prefetch block */ - 6, /* number of parallel prefetches */ - 3, /* Branch cost */ - COSTS_N_INSNS (8), /* cost of FADD and FSUB insns. */ - COSTS_N_INSNS (8), /* cost of FMUL instruction. */ - COSTS_N_INSNS (20), /* cost of FDIV instruction. */ - COSTS_N_INSNS (8), /* cost of FABS instruction. */ - COSTS_N_INSNS (8), /* cost of FCHS instruction. */ - COSTS_N_INSNS (40), /* cost of FSQRT instruction. */ - - COSTS_N_INSNS (1), /* cost of cheap SSE instruction. */ - COSTS_N_INSNS (8), /* cost of ADDSS/SD SUBSS/SD insns. */ - COSTS_N_INSNS (8), /* cost of MULSS instruction. */ - COSTS_N_INSNS (8), /* cost of MULSD instruction. */ - COSTS_N_INSNS (6), /* cost of FMA SS instruction. */ - COSTS_N_INSNS (6), /* cost of FMA SD instruction. */ - COSTS_N_INSNS (20), /* cost of DIVSS instruction. */ - COSTS_N_INSNS (20), /* cost of DIVSD instruction. */ - COSTS_N_INSNS (40), /* cost of SQRTSS instruction. */ - COSTS_N_INSNS (40), /* cost of SQRTSD instruction. */ - COSTS_N_INSNS (8), /* cost of CVTSS2SD etc. */ - COSTS_N_INSNS (16), /* cost of 256bit VCVTPS2PD etc. */ - COSTS_N_INSNS (32), /* cost of 512bit VCVTPS2PD etc. */ - COSTS_N_INSNS (8), /* cost of CVTSI2SS instruction. */ - COSTS_N_INSNS (8), /* cost of CVT(T)SS2SI instruction. */ - COSTS_N_INSNS (8), /* cost of CVTPI2PS instruction. */ - COSTS_N_INSNS (8), /* cost of CVT(T)PS2PI instruction. */ - 1, 4, 1, 1, /* reassoc int, fp, vec_int, vec_fp. */ - intel_memcpy, - intel_memset, - COSTS_N_INSNS (3), /* cond_taken_branch_cost. */ - COSTS_N_INSNS (1), /* cond_not_taken_branch_cost. */ - "16", /* Loop alignment. */ - "16:8:8", /* Jump alignment. */ - "0:0:8", /* Label alignment. */ - "16", /* Func alignment. */ - 4, /* Small unroll limit. */ - 2, /* Small unroll factor. */ - COSTS_N_INSNS (2), /* Branch mispredict scale. */ -}; - /* lujiazui_cost should produce code tuned for ZHAOXIN lujiazui CPU. */ static stringop_algs lujiazui_memcpy[2] = { {libcall, {{32, loop, false}, {8192, rep_prefix_4_byte, false}, @@ -4065,19 +3944,36 @@ struct processor_costs shijidadao_cost = { -/* Generic should produce code tuned for Core-i7 (and newer chips) - and btver1 (and newer chips). */ +/* Generic should produce code tuned for Haswell (and newer chips) + and znver1 (and newer chips): + 1. Don't align memory. + 2. For known sizes, prefer vector loop, unroll loop with 4 moves or + stores per iteration without aligning the loop, up to 256 bytes. + 3. For unknown sizes, use memcpy/memset. + 4. Since each loop iteration has 4 stores and 8 stores for zeroing + with unroll loop may be needed, change CLEAR_RATIO to 10 so that + zeroing up to 72 bytes are fully unrolled with 9 stores without + SSE. + */ static stringop_algs generic_memcpy[2] = { - {libcall, {{32, loop, false}, {8192, rep_prefix_4_byte, false}, - {-1, libcall, false}}}, - {libcall, {{32, loop, false}, {8192, rep_prefix_8_byte, false}, - {-1, libcall, false}}}}; + {libcall, + {{256, vector_loop, true}, + {256, unrolled_loop, true}, + {-1, libcall, true}}}, + {libcall, + {{256, vector_loop, true}, + {256, unrolled_loop, true}, + {-1, libcall, true}}}}; static stringop_algs generic_memset[2] = { - {libcall, {{32, loop, false}, {8192, rep_prefix_4_byte, false}, - {-1, libcall, false}}}, - {libcall, {{32, loop, false}, {8192, rep_prefix_8_byte, false}, - {-1, libcall, false}}}}; + {libcall, + {{256, vector_loop, true}, + {256, unrolled_loop, true}, + {-1, libcall, true}}}, + {libcall, + {{256, vector_loop, true}, + {256, unrolled_loop, true}, + {-1, libcall, true}}}}; static const struct processor_costs generic_cost = { { @@ -4134,7 +4030,7 @@ struct processor_costs generic_cost = { COSTS_N_INSNS (1), /* cost of movzx */ 8, /* "large" insn */ 17, /* MOVE_RATIO */ - 6, /* CLEAR_RATIO */ + 10, /* CLEAR_RATIO */ {6, 6, 6}, /* cost of loading integer registers in QImode, HImode and SImode. Relative to reg-reg move (2). */ diff --git a/gcc/config/i386/x86-tune-sched.cc b/gcc/config/i386/x86-tune-sched.cc index 15d3d91a83b6..ff9c2683007f 100644 --- a/gcc/config/i386/x86-tune-sched.cc +++ b/gcc/config/i386/x86-tune-sched.cc @@ -45,7 +45,6 @@ ix86_issue_rate (void) case PROCESSOR_LAKEMONT: case PROCESSOR_BONNELL: case PROCESSOR_SILVERMONT: - case PROCESSOR_INTEL: case PROCESSOR_K6: case PROCESSOR_BTVER2: case PROCESSOR_PENTIUM4: @@ -80,6 +79,8 @@ ix86_issue_rate (void) case PROCESSOR_ALDERLAKE: case PROCESSOR_YONGFENG: case PROCESSOR_SHIJIDADAO: + case PROCESSOR_SIERRAFOREST: + case PROCESSOR_INTEL: case PROCESSOR_GENERIC: /* For znver5 decoder can handle 4 or 8 instructions per cycle, op cache 12 instruction/cycle, dispatch 8 instructions @@ -99,6 +100,14 @@ ix86_issue_rate (void) return 5; case PROCESSOR_SAPPHIRERAPIDS: + case PROCESSOR_GRANITERAPIDS: + case PROCESSOR_GRANITERAPIDS_D: + case PROCESSOR_DIAMONDRAPIDS: + case PROCESSOR_GRANDRIDGE: + case PROCESSOR_CLEARWATERFOREST: + case PROCESSOR_ARROWLAKE: + case PROCESSOR_ARROWLAKE_S: + case PROCESSOR_PANTHERLAKE: return 6; default: @@ -488,6 +497,7 @@ ix86_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost, case PROCESSOR_HASWELL: case PROCESSOR_TREMONT: case PROCESSOR_ALDERLAKE: + case PROCESSOR_INTEL: case PROCESSOR_GENERIC: /* Stack engine allows to execute push&pop instructions in parall. */ if ((insn_type == TYPE_PUSH || insn_type == TYPE_POP) @@ -510,7 +520,6 @@ ix86_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost, break; case PROCESSOR_SILVERMONT: - case PROCESSOR_INTEL: if (!reload_completed) return cost; diff --git a/gcc/config/i386/x86-tune.def b/gcc/config/i386/x86-tune.def index 91cdca7fbfc2..a86cbad281c1 100644 --- a/gcc/config/i386/x86-tune.def +++ b/gcc/config/i386/x86-tune.def @@ -31,7 +31,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - Updating ix86_issue_rate and ix86_adjust_cost in i386.md - possibly updating ia32_multipass_dfa_lookahead, ix86_sched_reorder and ix86_sched_init_global if those tricks are needed. - - Tunning the flags bellow. Those are split into sections and each + - tuning flags below; those are split into sections and each section is very roughly ordered by importance. */ /*****************************************************************************/ @@ -639,6 +639,11 @@ DEF_TUNE (X86_TUNE_AVX512_STORE_BY_PIECES, "avx512_store_by_pieces", DEF_TUNE (X86_TUNE_AVX512_TWO_EPILOGUES, "avx512_two_epilogues", m_ZNVER4 | m_ZNVER5) +/* X86_TUNE_AVX512_MAKED_EPILOGUES: Use two masked vector epilogues + when fit. */ +DEF_TUNE (X86_TUNE_AVX512_MASKED_EPILOGUES, "avx512_masked_epilogues", + m_ZNVER4 | m_ZNVER5) + /*****************************************************************************/ /*****************************************************************************/ /* Historical relics: tuning flags that helps a specific old CPU designs */ diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md index 43e3ab0026ab..3d71f30a54be 100644 --- a/gcc/config/loongarch/lasx.md +++ b/gcc/config/loongarch/lasx.md @@ -2060,9 +2060,9 @@ [(set_attr "type" "simd_int_arith") (set_attr "mode" "<MODE>")]) -(define_insn "lasx_xvshuf_<lasxfmt_f>" +(define_insn "@lasx_xvshuf_<lasxfmt_f>" [(set (match_operand:LASX_DWH 0 "register_operand" "=f") - (unspec:LASX_DWH [(match_operand:LASX_DWH 1 "register_operand" "0") + (unspec:LASX_DWH [(match_operand:<VIMODE> 1 "register_operand" "0") (match_operand:LASX_DWH 2 "register_operand" "f") (match_operand:LASX_DWH 3 "register_operand" "f")] UNSPEC_LASX_XVSHUF))] diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index f62e4163c716..b00fcc71a20a 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -8380,7 +8380,7 @@ static bool loongarch_try_expand_lsx_vshuf_const (struct expand_vec_perm_d *d) { int i; - rtx target, op0, op1, sel, tmp; + rtx target, op0, op1; rtx rperm[MAX_VECT_LEN]; if (GET_MODE_SIZE (d->vmode) == 16) @@ -8399,47 +8399,23 @@ loongarch_try_expand_lsx_vshuf_const (struct expand_vec_perm_d *d) for (i = 0; i < d->nelt; i += 1) rperm[i] = GEN_INT (d->perm[i]); - if (d->vmode == E_V2DFmode) - { - sel = gen_rtx_CONST_VECTOR (E_V2DImode, gen_rtvec_v (d->nelt, rperm)); - tmp = simplify_gen_subreg (E_V2DImode, d->target, d->vmode, 0); - emit_move_insn (tmp, sel); - } - else if (d->vmode == E_V4SFmode) - { - sel = gen_rtx_CONST_VECTOR (E_V4SImode, gen_rtvec_v (d->nelt, rperm)); - tmp = simplify_gen_subreg (E_V4SImode, d->target, d->vmode, 0); - emit_move_insn (tmp, sel); - } + machine_mode sel_mode = related_int_vector_mode (d->vmode) + .require (); + rtvec sel_v = gen_rtvec_v (d->nelt, rperm); + + /* Despite vshuf.* (except vshuf.b) needs sel == target, we cannot + load sel into target right now: here we are dealing with + pseudo regs, and target may be the same pseudo as one of op0 + or op1. Then we'd clobber the input. Instead, we use a new + pseudo reg here. The reload pass will look at the constraint + of vshuf.* and move sel into target first if needed. */ + rtx sel = force_reg (sel_mode, + gen_rtx_CONST_VECTOR (sel_mode, sel_v)); + + if (d->vmode == E_V16QImode) + emit_insn (gen_lsx_vshuf_b (target, op1, op0, sel)); else - { - sel = gen_rtx_CONST_VECTOR (d->vmode, gen_rtvec_v (d->nelt, rperm)); - emit_move_insn (d->target, sel); - } - - switch (d->vmode) - { - case E_V2DFmode: - emit_insn (gen_lsx_vshuf_d_f (target, target, op1, op0)); - break; - case E_V2DImode: - emit_insn (gen_lsx_vshuf_d (target, target, op1, op0)); - break; - case E_V4SFmode: - emit_insn (gen_lsx_vshuf_w_f (target, target, op1, op0)); - break; - case E_V4SImode: - emit_insn (gen_lsx_vshuf_w (target, target, op1, op0)); - break; - case E_V8HImode: - emit_insn (gen_lsx_vshuf_h (target, target, op1, op0)); - break; - case E_V16QImode: - emit_insn (gen_lsx_vshuf_b (target, op1, op0, target)); - break; - default: - break; - } + emit_insn (gen_lsx_vshuf (d->vmode, target, sel, op1, op0)); return true; } @@ -9435,7 +9411,7 @@ loongarch_expand_vec_perm_const (struct expand_vec_perm_d *d) bool flag = false; unsigned int i; unsigned char idx; - rtx target, op0, op1, sel, tmp; + rtx target, op0, op1; rtx rperm[MAX_VECT_LEN]; unsigned int remapped[MAX_VECT_LEN]; unsigned char perm2[MAX_VECT_LEN]; @@ -9615,63 +9591,23 @@ loongarch_expand_vec_perm_const (struct expand_vec_perm_d *d) expand_perm_const_end: if (flag) { - /* Copy selector vector from memory to vector register for later insn - gen function. - If vector's element in floating point value, we cannot fit - selector argument into insn gen function directly, because of the - insn template definition. As a solution, generate a integral mode - subreg of target, then copy selector vector (that is in integral - mode) to this subreg. */ - switch (d->vmode) - { - case E_V4DFmode: - sel = gen_rtx_CONST_VECTOR (E_V4DImode, gen_rtvec_v (d->nelt, - rperm)); - tmp = simplify_gen_subreg (E_V4DImode, d->target, d->vmode, 0); - emit_move_insn (tmp, sel); - break; - case E_V8SFmode: - sel = gen_rtx_CONST_VECTOR (E_V8SImode, gen_rtvec_v (d->nelt, - rperm)); - tmp = simplify_gen_subreg (E_V8SImode, d->target, d->vmode, 0); - emit_move_insn (tmp, sel); - break; - default: - sel = gen_rtx_CONST_VECTOR (d->vmode, gen_rtvec_v (d->nelt, - rperm)); - emit_move_insn (d->target, sel); - break; - } - target = d->target; op0 = d->op0; op1 = d->one_vector_p ? d->op0 : d->op1; - /* We FINALLY can generate xvshuf.* insn. */ - switch (d->vmode) - { - case E_V4DFmode: - emit_insn (gen_lasx_xvshuf_d_f (target, target, op1, op0)); - break; - case E_V4DImode: - emit_insn (gen_lasx_xvshuf_d (target, target, op1, op0)); - break; - case E_V8SFmode: - emit_insn (gen_lasx_xvshuf_w_f (target, target, op1, op0)); - break; - case E_V8SImode: - emit_insn (gen_lasx_xvshuf_w (target, target, op1, op0)); - break; - case E_V16HImode: - emit_insn (gen_lasx_xvshuf_h (target, target, op1, op0)); - break; - case E_V32QImode: - emit_insn (gen_lasx_xvshuf_b (target, op1, op0, target)); - break; - default: - gcc_unreachable (); - break; - } + machine_mode sel_mode = related_int_vector_mode (d->vmode) + .require (); + rtvec sel_v = gen_rtvec_v (d->nelt, rperm); + + /* See the comment in loongarch_expand_lsx_shuffle for why + we don't simply use a SUBREG to pun target. */ + rtx sel = force_reg (sel_mode, + gen_rtx_CONST_VECTOR (sel_mode, sel_v)); + + if (d->vmode == E_V32QImode) + emit_insn (gen_lasx_xvshuf_b (target, op1, op0, sel)); + else + emit_insn (gen_lasx_xvshuf (d->vmode, target, sel, op1, op0)); return true; } diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index f7005dee5b61..32ef9809b108 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -4573,9 +4573,10 @@ "&& true" [(set (match_dup 3) (match_dup 2)) (set (match_dup 0) - (unspec:SI [(match_dup 3) (subreg:SI (match_dup 1) 0)] CRC))] + (unspec:SI [(match_dup 3) (match_dup 1)] CRC))] { operands[3] = gen_reg_rtx (<MODE>mode); + operands[1] = lowpart_subreg (SImode, operands[1], DImode); }) ;; With normal or medium code models, if the only use of a pc-relative diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md index 407c86870dfc..fb0236ba0f1b 100644 --- a/gcc/config/loongarch/lsx.md +++ b/gcc/config/loongarch/lsx.md @@ -535,9 +535,9 @@ DONE; }) -(define_insn "lsx_vshuf_<lsxfmt_f>" +(define_insn "@lsx_vshuf_<lsxfmt_f>" [(set (match_operand:LSX_DWH 0 "register_operand" "=f") - (unspec:LSX_DWH [(match_operand:LSX_DWH 1 "register_operand" "0") + (unspec:LSX_DWH [(match_operand:<VIMODE> 1 "register_operand" "0") (match_operand:LSX_DWH 2 "register_operand" "f") (match_operand:LSX_DWH 3 "register_operand" "f")] UNSPEC_LSX_VSHUF))] diff --git a/gcc/config/mcore/mcore.cc b/gcc/config/mcore/mcore.cc index cd5f2c526490..c4fc145a47ad 100644 --- a/gcc/config/mcore/mcore.cc +++ b/gcc/config/mcore/mcore.cc @@ -2984,9 +2984,7 @@ mcore_mark_dllimport (tree decl) /* ??? At least I think that's why we do this. */ idp = get_identifier (newname); - newrtl = gen_rtx_MEM (Pmode, - gen_rtx_SYMBOL_REF (Pmode, - IDENTIFIER_POINTER (idp))); + newrtl = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp)); XEXP (DECL_RTL (decl), 0) = newrtl; } diff --git a/gcc/config/or1k/or1k.cc b/gcc/config/or1k/or1k.cc index 62e2168e0ee3..868df676d352 100644 --- a/gcc/config/or1k/or1k.cc +++ b/gcc/config/or1k/or1k.cc @@ -1408,8 +1408,9 @@ static bool or1k_can_change_mode_class (machine_mode from, machine_mode to, reg_class_t rclass) { + /* Allow cnoverting special flags to SI mode subregs. */ if (rclass == FLAG_REGS) - return from == to; + return from == to || (from == BImode && to == SImode); return true; } @@ -1653,6 +1654,63 @@ or1k_rtx_costs (rtx x, machine_mode mode, int outer_code, int /* opno */, #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS or1k_rtx_costs +static bool +or1k_is_cmov_insn (rtx_insn *seq) +{ + rtx_insn *curr_insn = seq; + rtx set = NULL_RTX; + + /* The pattern may start with a simple set with register operands. Skip + through any of those. */ + while (curr_insn) + { + set = single_set (curr_insn); + if (!set + || !REG_P (SET_DEST (set))) + return false; + + /* If it's not a simple reg or immediate break. */ + if (REG_P (SET_SRC (set)) || CONST_INT_P (SET_SRC (set))) + curr_insn = NEXT_INSN (curr_insn); + else + break; + } + + if (!curr_insn) + return false; + + /* The next instruction should be a compare. OpenRISC has many operators used + for comparison so skip and confirm the next is IF_THEN_ELSE. */ + curr_insn = NEXT_INSN (curr_insn); + if (!curr_insn) + return false; + + /* And the last instruction should be an IF_THEN_ELSE. */ + set = single_set (curr_insn); + if (!set + || !REG_P (SET_DEST (set)) + || GET_CODE (SET_SRC (set)) != IF_THEN_ELSE) + return false; + + return !NEXT_INSN (curr_insn); +} + +/* Implement TARGET_NOCE_CONVERSION_PROFITABLE_P. We detect if the conversion + resulted in a l.cmov instruction and if so we consider it more profitable than + branch instructions. */ + +static bool +or1k_noce_conversion_profitable_p (rtx_insn *seq, + struct noce_if_info *if_info) +{ + if (TARGET_CMOV) + return or1k_is_cmov_insn (seq); + + return default_noce_conversion_profitable_p (seq, if_info); +} + +#undef TARGET_NOCE_CONVERSION_PROFITABLE_P +#define TARGET_NOCE_CONVERSION_PROFITABLE_P or1k_noce_conversion_profitable_p /* A subroutine of the atomic operation splitters. Jump to LABEL if COND is true. Mark the jump as unlikely to be taken. */ diff --git a/gcc/config/or1k/or1k.md b/gcc/config/or1k/or1k.md index 627e40084b34..bf7125375ac4 100644 --- a/gcc/config/or1k/or1k.md +++ b/gcc/config/or1k/or1k.md @@ -515,6 +515,31 @@ (ne:SI (reg:BI SR_F_REGNUM) (const_int 0)))] "") +;; Allowing "extending" the BImode SR_F to a general register +;; avoids 'convert_mode_scalar' from trying to do subregging +;; which we don't have support for. +;; We require signed and unsigned extend instructions because +;; signed comparisons require signed extention, but for SR_F +;; it doesn't matter. + +(define_expand "zero_extendbisi2_sr_f" + [(set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:BI 1 "sr_f_reg_operand" "")))] + "" +{ + emit_insn(gen_sne_sr_f (operands[0])); + DONE; +}) + +(define_expand "extendbisi2_sr_f" + [(set (match_operand:SI 0 "register_operand" "") + (sign_extend:SI (match_operand:BI 1 "sr_f_reg_operand" "")))] + "" +{ + emit_insn(gen_sne_sr_f (operands[0])); + DONE; +}) + (define_insn_and_split "*scc" [(set (match_operand:SI 0 "register_operand" "=r") (match_operator:SI 1 "equality_comparison_operator" @@ -584,7 +609,7 @@ ;; Branch instructions ;; ------------------------------------------------------------------------- -(define_expand "cbranchsi4" +(define_insn_and_split "cbranchsi4" [(set (pc) (if_then_else (match_operator 0 "comparison_operator" @@ -593,13 +618,27 @@ (label_ref (match_operand 3 "" "")) (pc)))] "" + "#" + "&& 1" + [(const_int 0)] { + rtx label; + + /* Generate *scc */ or1k_expand_compare (operands); + /* Generate *cbranch */ + label = gen_rtx_LABEL_REF (VOIDmode, operands[3]); + emit_jump_insn (gen_rtx_SET (pc_rtx, + gen_rtx_IF_THEN_ELSE (VOIDmode, + operands[0], + label, + pc_rtx))); + DONE; }) ;; Support FP branching -(define_expand "cbranch<F:mode>4" +(define_insn_and_split "cbranch<F:mode>4" [(set (pc) (if_then_else (match_operator 0 "fp_comparison_operator" @@ -608,8 +647,22 @@ (label_ref (match_operand 3 "" "")) (pc)))] "TARGET_HARD_FLOAT" + "#" + "&& 1" + [(const_int 0)] { + rtx label; + + /* Generate *scc */ or1k_expand_compare (operands); + /* Generate *cbranch */ + label = gen_rtx_LABEL_REF (VOIDmode, operands[3]); + emit_jump_insn (gen_rtx_SET (pc_rtx, + gen_rtx_IF_THEN_ELSE (VOIDmode, + operands[0], + label, + pc_rtx))); + DONE; }) (define_insn "*cbranch" diff --git a/gcc/config/or1k/predicates.md b/gcc/config/or1k/predicates.md index 144f4d7b5778..7ccfd09985dd 100644 --- a/gcc/config/or1k/predicates.md +++ b/gcc/config/or1k/predicates.md @@ -60,6 +60,10 @@ (and (match_operand 0 "register_operand") (match_test "TARGET_ROR")))) +(define_predicate "sr_f_reg_operand" + (and (match_operand 0 "register_operand") + (match_test "REGNO (op) == SR_F_REGNUM"))) + (define_predicate "call_insn_operand" (ior (and (match_code "symbol_ref") (match_test "!TARGET_CMODEL_LARGE")) diff --git a/gcc/config/pru/pru-pragma.cc b/gcc/config/pru/pru-pragma.cc index c3f3d33d5470..933878051424 100644 --- a/gcc/config/pru/pru-pragma.cc +++ b/gcc/config/pru/pru-pragma.cc @@ -46,21 +46,24 @@ pru_pragma_ctable_entry (cpp_reader *) enum cpp_ttype type; type = pragma_lex (&ctable_index); - if (type == CPP_NUMBER && tree_fits_uhwi_p (ctable_index)) + if (type == CPP_NUMBER && tree_fits_shwi_p (ctable_index)) { type = pragma_lex (&base_addr); - if (type == CPP_NUMBER && tree_fits_uhwi_p (base_addr)) + if (type == CPP_NUMBER && tree_fits_shwi_p (base_addr)) { - unsigned HOST_WIDE_INT i = tree_to_uhwi (ctable_index); - unsigned HOST_WIDE_INT base = tree_to_uhwi (base_addr); + HOST_WIDE_INT i = tree_to_shwi (ctable_index); + HOST_WIDE_INT base = sext_hwi (tree_to_shwi (base_addr), + POINTER_SIZE); type = pragma_lex (&base_addr); if (type != CPP_EOF) error ("junk at end of %<#pragma CTABLE_ENTRY%>"); - else if (i >= ARRAY_SIZE (pru_ctable)) + else if (!IN_RANGE (i, 0, ARRAY_SIZE (pru_ctable) - 1)) error ("%<CTABLE_ENTRY%> index %wd is not valid", i); else if (pru_ctable[i].valid && pru_ctable[i].base != base) error ("redefinition of %<CTABLE_ENTRY %wd%>", i); + else if (!IN_RANGE (base, INT32_MIN, INT32_MAX)) + error ("%<CTABLE_ENTRY%> base address does not fit in 32-bits"); else { if (base & 0xff) diff --git a/gcc/config/pru/pru-protos.h b/gcc/config/pru/pru-protos.h index c73fad870c21..4750f0e10077 100644 --- a/gcc/config/pru/pru-protos.h +++ b/gcc/config/pru/pru-protos.h @@ -23,7 +23,7 @@ struct pru_ctable_entry { bool valid; - unsigned HOST_WIDE_INT base; + HOST_WIDE_INT base; }; extern struct pru_ctable_entry pru_ctable[32]; @@ -66,9 +66,9 @@ pru_regno_ok_for_index_p (int regno, bool strict_p) return pru_regno_ok_for_base_p (regno, strict_p); } -extern int pru_get_ctable_exact_base_index (unsigned HOST_WIDE_INT caddr); -extern int pru_get_ctable_base_index (unsigned HOST_WIDE_INT caddr); -extern int pru_get_ctable_base_offset (unsigned HOST_WIDE_INT caddr); +extern int pru_get_ctable_exact_base_index (HOST_WIDE_INT caddr); +extern int pru_get_ctable_base_index (HOST_WIDE_INT caddr); +extern int pru_get_ctable_base_offset (HOST_WIDE_INT caddr); extern int pru_symref2ioregno (rtx op); diff --git a/gcc/config/pru/pru.cc b/gcc/config/pru/pru.cc index 47e5f248ce79..322e3196a6e4 100644 --- a/gcc/config/pru/pru.cc +++ b/gcc/config/pru/pru.cc @@ -1428,7 +1428,7 @@ pru_valid_const_ubyte_offset (machine_mode mode, HOST_WIDE_INT offset) /* Recognize a CTABLE base address. Return CTABLE entry index, or -1 if base was not found in the pragma-filled pru_ctable. */ int -pru_get_ctable_exact_base_index (unsigned HOST_WIDE_INT caddr) +pru_get_ctable_exact_base_index (HOST_WIDE_INT caddr) { unsigned int i; @@ -1444,7 +1444,7 @@ pru_get_ctable_exact_base_index (unsigned HOST_WIDE_INT caddr) /* Check if the given address can be addressed via CTABLE_BASE + UBYTE_OFFS, and return the base CTABLE index if possible. */ int -pru_get_ctable_base_index (unsigned HOST_WIDE_INT caddr) +pru_get_ctable_base_index (HOST_WIDE_INT caddr) { unsigned int i; @@ -1461,7 +1461,7 @@ pru_get_ctable_base_index (unsigned HOST_WIDE_INT caddr) /* Return the offset from some CTABLE base for this address. */ int -pru_get_ctable_base_offset (unsigned HOST_WIDE_INT caddr) +pru_get_ctable_base_offset (HOST_WIDE_INT caddr) { int i; @@ -2004,7 +2004,7 @@ pru_print_operand_address (FILE *file, machine_mode mode, rtx op) case CONST_INT: { - unsigned HOST_WIDE_INT caddr = INTVAL (op); + HOST_WIDE_INT caddr = INTVAL (op); int base = pru_get_ctable_base_index (caddr); int offs = pru_get_ctable_base_offset (caddr); if (base < 0) diff --git a/gcc/config/pru/pru.md b/gcc/config/pru/pru.md index fcd310613f50..3504e42e9002 100644 --- a/gcc/config/pru/pru.md +++ b/gcc/config/pru/pru.md @@ -283,6 +283,83 @@ [(set_attr "type" "st,ld,alu,alu,alu,alu,alu,alu") (set_attr "length" "4,4,4,4,8,8,8,16")]) +; Break 64-bit register-to-register moves into 32-bit moves. +; If only a subreg of the destination is used, this split would allow +; for the other 32-bit subreg of the DI register to be eliminated. +(define_split + [(set (match_operand:DI 0 "register_operand") + (match_operand:DI 1 "register_operand"))] + " + /* TODO - LRA does not yet handle subregs efficiently. + So it is profitable to split only after register allocation is + complete. + Once https://gcc.gnu.org/pipermail/gcc-patches/2024-May/651366.html + is merged, this condition should be removed to allow splitting + before LRA. */ + reload_completed + /* Sign-extended paradoxical registers require expansion + of the proper pattern. We can do only zero extension here. */ + && (SUBREG_P (operands[1]) && paradoxical_subreg_p (operands[1]) + ? SUBREG_PROMOTED_VAR_P (operands[1]) + && SUBREG_PROMOTED_UNSIGNED_P (operands[1]) > 0 + : true)" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))] + " + rtx dst_lo = simplify_gen_subreg (SImode, operands[0], DImode, 0); + rtx dst_hi = simplify_gen_subreg (SImode, operands[0], DImode, 4); + rtx src_lo = simplify_gen_subreg (SImode, operands[1], DImode, 0); + rtx src_hi = simplify_gen_subreg (SImode, operands[1], DImode, 4); + + if (SUBREG_P (operands[1]) && paradoxical_subreg_p (operands[1])) + { + gcc_assert (SUBREG_PROMOTED_VAR_P (operands[1])); + gcc_assert (SUBREG_PROMOTED_UNSIGNED_P (operands[1]) > 0); + + operands[0] = dst_lo; + operands[1] = src_lo; + operands[2] = dst_hi; + operands[3] = const0_rtx; + } + else if (!reg_overlap_mentioned_p (dst_lo, src_hi)) + { + operands[0] = dst_lo; + operands[1] = src_lo; + operands[2] = dst_hi; + operands[3] = src_hi; + } + else + { + operands[0] = dst_hi; + operands[1] = src_hi; + operands[2] = dst_lo; + operands[3] = src_lo; + } + " +) + +; Break loading of non-trivial 64-bit constant integers. The split +; will not generate better code sequence, but at least would allow +; dropping a non-live 32-bit part of the destination, or better +; constant propagation. +(define_split + [(set (match_operand:DI 0 "register_operand") + (match_operand:DI 1 "const_int_operand"))] + "reload_completed + && !satisfies_constraint_Z (operands[1]) + && !satisfies_constraint_Um (operands[1]) + && !satisfies_constraint_T (operands[1])" + + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))] + " + operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, 4); + operands[3] = simplify_gen_subreg (SImode, operands[1], DImode, 4);; + operands[0] = simplify_gen_subreg (SImode, operands[0], DImode, 0); + operands[1] = simplify_gen_subreg (SImode, operands[1], DImode, 0); + " +) + ; ; load_multiple pattern(s). ; diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md index 19eb16c75400..d88494227913 100644 --- a/gcc/config/riscv/autovec-opt.md +++ b/gcc/config/riscv/autovec-opt.md @@ -1682,7 +1682,7 @@ ;; ============================================================================= (define_insn_and_split "*<optab>_vx_<mode>" [(set (match_operand:V_VLSI 0 "register_operand") - (any_int_binop_no_shift_vx:V_VLSI + (any_int_binop_no_shift_vdup_v:V_VLSI (vec_duplicate:V_VLSI (match_operand:<VEL> 1 "register_operand")) (match_operand:V_VLSI 2 "<binop_rhs2_predicate>")))] @@ -1699,7 +1699,7 @@ (define_insn_and_split "*<optab>_vx_<mode>" [(set (match_operand:V_VLSI 0 "register_operand") - (any_int_binop_no_shift_vx:V_VLSI + (any_int_binop_no_shift_v_vdup:V_VLSI (match_operand:V_VLSI 1 "<binop_rhs2_predicate>") (vec_duplicate:V_VLSI (match_operand:<VEL> 2 "register_operand"))))] @@ -1714,29 +1714,99 @@ } [(set_attr "type" "vialu")]) +(define_insn_and_split "*uavg_floor_vx_<mode>" + [(set (match_operand:V_VLSI 0 "register_operand") + (if_then_else:V_VLSI + (unspec:<VM> + [(match_operand:<VM> 1 "vector_mask_operand") + (match_operand 5 "vector_length_operand") + (match_operand 6 "const_int_operand") + (match_operand 7 "const_int_operand") + (match_operand 8 "const_int_operand") + (match_operand 9 "const_int_operand") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM) + (reg:SI VXRM_REGNUM)] UNSPEC_VPREDICATE) + (unspec:V_VLSI + [(match_operand:V_VLSI 3 "register_operand") + (vec_duplicate:V_VLSI + (match_operand:<VEL> 4 "register_operand"))] UNSPEC_VAADDU) + (unspec:V_VLSI + [(match_operand:DI 2 "register_operand")] UNSPEC_VUNDEF)))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + insn_code code = code_for_pred_scalar (UNSPEC_VAADDU, <MODE>mode); + rtx ops[] = {operands[0], operands[3], operands[4]}; + riscv_vector::emit_vlmax_insn (code, riscv_vector::BINARY_OP_VXRM_RDN, ops); + DONE; + } + [(set_attr "type" "vaalu")]) + +(define_insn_and_split "*uavg_floor_vx_<mode>" + [(set (match_operand:V_VLSI 0 "register_operand") + (if_then_else:V_VLSI + (unspec:<VM> + [(match_operand:<VM> 1 "vector_mask_operand") + (match_operand 5 "vector_length_operand") + (match_operand 6 "const_int_operand") + (match_operand 7 "const_int_operand") + (match_operand 8 "const_int_operand") + (match_operand 9 "const_int_operand") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM) + (reg:SI VXRM_REGNUM)] UNSPEC_VPREDICATE) + (unspec:V_VLSI + [(vec_duplicate:V_VLSI + (match_operand:<VEL> 4 "register_operand")) + (match_operand:V_VLSI 3 "register_operand")] UNSPEC_VAADDU) + (unspec:V_VLSI + [(match_operand:DI 2 "register_operand")] UNSPEC_VUNDEF)))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + insn_code code = code_for_pred_scalar (UNSPEC_VAADDU, <MODE>mode); + rtx ops[] = {operands[0], operands[3], operands[4]}; + riscv_vector::emit_vlmax_insn (code, riscv_vector::BINARY_OP_VXRM_RDN, ops); + DONE; + } + [(set_attr "type" "vaalu")]) + ;; ============================================================================= ;; Combine vec_duplicate + op.vv to op.vf ;; Include ;; - vfmadd.vf ;; - vfmsub.vf +;; - vfnmadd.vf +;; - vfnmsub.vf +;; - vfmacc.vf +;; - vfmsac.vf +;; - vfnmacc.vf +;; - vfnmsac.vf +;; - vfwmacc.vf +;; - vfwmsac.vf ;; ============================================================================= - +;; vfmadd.vf, vfmsub.vf, vfmacc.vf, vfmsac.vf (define_insn_and_split "*<optab>_vf_<mode>" - [(set (match_operand:V_VLSF 0 "register_operand" "=vd") + [(set (match_operand:V_VLSF 0 "register_operand") (plus_minus:V_VLSF (mult:V_VLSF (vec_duplicate:V_VLSF - (match_operand:<VEL> 1 "register_operand" " f")) - (match_operand:V_VLSF 2 "register_operand" " 0")) - (match_operand:V_VLSF 3 "register_operand" " vr")))] + (match_operand:<VEL> 1 "register_operand")) + (match_operand:V_VLSF 2 "register_operand")) + (match_operand:V_VLSF 3 "register_operand")))] "TARGET_VECTOR && can_create_pseudo_p ()" "#" "&& 1" [(const_int 0)] { rtx ops[] = {operands[0], operands[1], operands[2], operands[3], - operands[2]}; + RVV_VUNDEF(<MODE>mode)}; riscv_vector::emit_vlmax_insn (code_for_pred_mul_scalar (<CODE>, <MODE>mode), riscv_vector::TERNARY_OP_FRM_DYN, ops); DONE; @@ -1744,24 +1814,146 @@ [(set_attr "type" "vfmuladd")] ) -(define_insn_and_split "*<optab>_vf_<mode>" - [(set (match_operand:V_VLSF 0 "register_operand" "=vd") - (plus_minus:V_VLSF - (match_operand:V_VLSF 3 "register_operand" " vr") - (mult:V_VLSF - (vec_duplicate:V_VLSF - (match_operand:<VEL> 1 "register_operand" " f")) - (match_operand:V_VLSF 2 "register_operand" " 0"))))] +;; vfnmsub.vf, vfnmsac.vf +(define_insn_and_split "*vfnmsub_<mode>" + [(set (match_operand:V_VLSF 0 "register_operand") + (minus:V_VLSF + (match_operand:V_VLSF 3 "register_operand") + (mult:V_VLSF + (vec_duplicate:V_VLSF + (match_operand:<VEL> 1 "register_operand")) + (match_operand:V_VLSF 2 "register_operand"))))] "TARGET_VECTOR && can_create_pseudo_p ()" "#" "&& 1" [(const_int 0)] { rtx ops[] = {operands[0], operands[1], operands[2], operands[3], - operands[2]}; - riscv_vector::emit_vlmax_insn (code_for_pred_mul_scalar (<CODE>, <MODE>mode), + RVV_VUNDEF(<MODE>mode)}; + riscv_vector::emit_vlmax_insn (code_for_pred_mul_neg_scalar (PLUS, <MODE>mode), + riscv_vector::TERNARY_OP_FRM_DYN, ops); + DONE; + } + [(set_attr "type" "vfmuladd")] +) + +;; vfnmadd.vf, vfnmacc.vf +(define_insn_and_split "*vfnmadd_<mode>" + [(set (match_operand:V_VLSF 0 "register_operand") + (minus:V_VLSF + (mult:V_VLSF + (neg:V_VLSF + (match_operand:V_VLSF 2 "register_operand")) + (vec_duplicate:V_VLSF + (match_operand:<VEL> 1 "register_operand"))) + (match_operand:V_VLSF 3 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + rtx ops[] = {operands[0], operands[1], operands[2], operands[3], + RVV_VUNDEF(<MODE>mode)}; + riscv_vector::emit_vlmax_insn (code_for_pred_mul_neg_scalar (MINUS, <MODE>mode), riscv_vector::TERNARY_OP_FRM_DYN, ops); DONE; } [(set_attr "type" "vfmuladd")] ) + +;; vfwmacc.vf, vfwmsac.vf +(define_insn_and_split "*vfwmacc_vf_<mode>" + [(set (match_operand:VWEXTF 0 "register_operand") + (plus_minus:VWEXTF + (mult:VWEXTF + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")) + (vec_duplicate:VWEXTF + (float_extend:<VEL> + (match_operand:<VSUBEL> 2 "register_operand")))) + (match_operand:VWEXTF 1 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + rtx ops[] = {operands[0], operands[1], operands[2], operands[3]}; + riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_scalar (<CODE>, <MODE>mode), + riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, ops); + DONE; + } + [(set_attr "type" "vfwmuladd")] +) + +;; Intermediate pattern for vfwmacc.vf and vfwmsac.vf used by combine +(define_insn_and_split "*extend_vf_<mode>" + [(set (match_operand:VWEXTF 0 "register_operand") + (vec_duplicate:VWEXTF + (float_extend:<VEL> + (match_operand:<VSUBEL> 1 "register_operand"))))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + rtx tmp = gen_reg_rtx (<VEL>mode); + emit_insn (gen_extend<vsubel><vel>2(tmp, operands[1])); + + rtx ops[] = {operands[0], tmp}; + riscv_vector::emit_vlmax_insn (code_for_pred_broadcast (<MODE>mode), + riscv_vector::UNARY_OP, ops); + DONE; + } + [(set_attr "type" "vfwmuladd")] +) + +;; vfwnmacc.vf +(define_insn_and_split "*vfwnmacc_vf_<mode>" + [(set (match_operand:VWEXTF 0 "register_operand") + (minus:VWEXTF + (mult:VWEXTF + (neg:VWEXTF + (vec_duplicate:VWEXTF + (float_extend:<VEL> + (match_operand:<VSUBEL> 2 "register_operand")))) + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))) + (match_operand:VWEXTF 1 "register_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + rtx ops[] = {operands[0], operands[1], operands[2], operands[3]}; + riscv_vector::emit_vlmax_insn( + code_for_pred_widen_mul_neg_scalar(MINUS, <MODE>mode), + riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, ops); + DONE; + } + [(set_attr "type" "vfwmuladd")] +) + +;; vfwnmsac.vf +(define_insn_and_split "*vfwnmsac_vf_<mode>" + [(set (match_operand:VWEXTF 0 "register_operand") + (minus:VWEXTF + (match_operand:VWEXTF 1 "register_operand") + (mult:VWEXTF + (float_extend:VWEXTF + (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")) + (vec_duplicate:VWEXTF + (float_extend:<VEL> + (match_operand:<VSUBEL> 2 "register_operand"))))))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + rtx ops[] = {operands[0], operands[1], operands[2], operands[3]}; + riscv_vector::emit_vlmax_insn( + code_for_pred_widen_mul_neg_scalar (PLUS, <MODE>mode), + riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, ops); + DONE; + } + [(set_attr "type" "vfwmuladd")] +) diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index c678eefc7003..1fff8ac2fc46 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -1338,7 +1338,7 @@ (define_expand "select_vl<mode>" [(match_operand:P 0 "register_operand") (match_operand:P 1 "vector_length_operand") - (match_operand:P 2 "")] + (match_operand:P 2 "immediate_operand")] "TARGET_VECTOR" { riscv_vector::expand_select_vl (operands); @@ -2489,7 +2489,8 @@ (sign_extend:VWEXTI (match_operand:<V_DOUBLE_TRUNC> 1 "register_operand")) (sign_extend:VWEXTI - (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))))))] + (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))) + (const_int 1))))] "TARGET_VECTOR" { insn_code icode = code_for_pred (UNSPEC_VAADD, <V_DOUBLE_TRUNC>mode); @@ -2499,6 +2500,19 @@ } ) +(define_expand "avg<mode>3_floor" + [(match_operand:V_VLSI_D 0 "register_operand") + (match_operand:V_VLSI_D 1 "register_operand") + (match_operand:V_VLSI_D 2 "register_operand")] + "TARGET_VECTOR" + { + insn_code icode = code_for_pred (UNSPEC_VAADD, <MODE>mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP_VXRM_RDN, + operands); + DONE; + } +) + (define_expand "avg<v_double_trunc>3_ceil" [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand") (truncate:<V_DOUBLE_TRUNC> @@ -2509,7 +2523,8 @@ (match_operand:<V_DOUBLE_TRUNC> 1 "register_operand")) (sign_extend:VWEXTI (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))) - (const_int 1)))))] + (const_int 1)) + (const_int 1))))] "TARGET_VECTOR" { insn_code icode = code_for_pred (UNSPEC_VAADD, <V_DOUBLE_TRUNC>mode); @@ -2519,6 +2534,19 @@ } ) +(define_expand "avg<mode>3_ceil" + [(match_operand:V_VLSI_D 0 "register_operand") + (match_operand:V_VLSI_D 1 "register_operand") + (match_operand:V_VLSI_D 2 "register_operand")] + "TARGET_VECTOR" + { + insn_code icode = code_for_pred (UNSPEC_VAADD, <MODE>mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP_VXRM_RNU, + operands); + DONE; + } +) + ;; csrwi vxrm, 2 ;; vaaddu.vv vd, vs2, vs1 (define_expand "uavg<mode>3_floor" diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index 58355cf03f2f..5ecaa19eb014 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -237,10 +237,11 @@ (and (match_code "const_vector") (match_test "rtx_equal_p (op, riscv_vector::gen_scalar_move_mask (GET_MODE (op)))"))) -(define_memory_constraint "Wdm" +(define_constraint "Wdm" "Vector duplicate memory operand" - (and (match_code "mem") - (match_code "reg" "0"))) + (and (match_test "strided_load_broadcast_p ()") + (and (match_code "mem") + (match_code "reg" "0")))) ;; Vendor ISA extension constraints. @@ -325,3 +326,7 @@ "A 2-bit unsigned immediate." (and (match_code "const_int") (match_test "IN_RANGE (ival, 0, 3)"))) + +(define_constraint "Q" + "An address operand that is valid for a prefetch instruction" + (match_operand 0 "prefetch_operand")) diff --git a/gcc/config/riscv/generic-vector-ooo.md b/gcc/config/riscv/generic-vector-ooo.md index ab9e57f5cbf7..773003b49aeb 100644 --- a/gcc/config/riscv/generic-vector-ooo.md +++ b/gcc/config/riscv/generic-vector-ooo.md @@ -17,6 +17,9 @@ ;; <http://www.gnu.org/licenses/>. ;; Vector load/store +;; The insn reservations include "generic" as we won't have a in-order +;; generic definition for vector instructions. + (define_automaton "vector_ooo") ;; Separate issue queue for vector instructions. @@ -29,119 +32,141 @@ (define_cpu_unit "vxu_ooo_multicycle" "vector_ooo") (define_insn_reservation "vec_load" 6 - (eq_attr "type" "vlde,vldm,vlds,vldux,vldox,vldff,vldr") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vlde,vldm,vlds,vldux,vldox,vldff,vldr")) "vxu_ooo_issue,vxu_ooo_alu") (define_insn_reservation "vec_store" 6 - (eq_attr "type" "vste,vstm,vsts,vstux,vstox,vstr") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vste,vstm,vsts,vstux,vstox,vstr")) "vxu_ooo_issue,vxu_ooo_alu") ;; Vector segment loads/stores. (define_insn_reservation "vec_loadstore_seg" 10 - (eq_attr "type" "vlsegde,vlsegds,vlsegdux,vlsegdox,vlsegdff,\ - vssegte,vssegts,vssegtux,vssegtox") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vlsegde,vlsegds,vlsegdux,vlsegdox,vlsegdff,\ + vssegte,vssegts,vssegtux,vssegtox")) "vxu_ooo_issue,vxu_ooo_alu") ;; Regular vector operations and integer comparisons. (define_insn_reservation "vec_alu" 3 - (eq_attr "type" "vialu,viwalu,vext,vicalu,vshift,vnshift,viminmax,vicmp,\ - vimov,vsalu,vaalu,vsshift,vnclip,vmov,vfmov,vector,\ - vandn,vbrev,vbrev8,vrev8,vclz,vctz,vrol,vror,vwsll") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vialu,viwalu,vext,vicalu,vshift,vnshift,viminmax,vicmp,\ + vimov,vsalu,vaalu,vsshift,vnclip,vmov,vfmov,vector,\ + vandn,vbrev,vbrev8,vrev8,vclz,vctz,vrol,vror,vwsll")) "vxu_ooo_issue,vxu_ooo_alu") ;; Vector float comparison, conversion etc. (define_insn_reservation "vec_fcmp" 3 - (eq_attr "type" "vfrecp,vfminmax,vfcmp,vfsgnj,vfclass,vfcvtitof,\ - vfcvtftoi,vfwcvtitof,vfwcvtftoi,vfwcvtftof,vfncvtitof,\ - vfncvtftoi,vfncvtftof,vfncvtbf16,vfwcvtbf16") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vfrecp,vfminmax,vfcmp,vfsgnj,vfclass,vfcvtitof,\ + vfcvtftoi,vfwcvtitof,vfwcvtftoi,vfwcvtftof,vfncvtitof,\ + vfncvtftoi,vfncvtftof,vfncvtbf16,vfwcvtbf16")) "vxu_ooo_issue,vxu_ooo_alu") ;; Vector integer multiplication. (define_insn_reservation "vec_imul" 4 - (eq_attr "type" "vimul,viwmul,vimuladd,viwmuladd,vsmul,vclmul,vclmulh,\ - vghsh,vgmul") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vimul,viwmul,vimuladd,viwmuladd,vsmul,vclmul,vclmulh,\ + vghsh,vgmul")) "vxu_ooo_issue,vxu_ooo_alu") ;; Vector float addition. (define_insn_reservation "vec_fadd" 4 - (eq_attr "type" "vfalu,vfwalu") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vfalu,vfwalu")) "vxu_ooo_issue,vxu_ooo_alu") ;; Vector float multiplication and FMA. (define_insn_reservation "vec_fmul" 6 - (eq_attr "type" "vfmul,vfwmul,vfmuladd,vfwmuladd,vfwmaccbf16,sf_vqmacc,sf_vfnrclip") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vfmul,vfwmul,vfmuladd,vfwmuladd,vfwmaccbf16,sf_vqmacc,sf_vfnrclip")) "vxu_ooo_issue,vxu_ooo_alu") ;; Vector crypto, assumed to be a generic operation for now. (define_insn_reservation "vec_crypto" 4 - (eq_attr "type" "crypto,vclz,vctz,vcpop") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "crypto,vclz,vctz,vcpop")) "vxu_ooo_issue,vxu_ooo_alu") ;; Vector crypto, AES (define_insn_reservation "vec_crypto_aes" 4 - (eq_attr "type" "vaesef,vaesem,vaesdf,vaesdm,vaeskf1,vaeskf2,vaesz") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vaesef,vaesem,vaesdf,vaesdm,vaeskf1,vaeskf2,vaesz")) "vxu_ooo_issue,vxu_ooo_alu") ;; Vector crypto, sha (define_insn_reservation "vec_crypto_sha" 4 - (eq_attr "type" "vsha2ms,vsha2ch,vsha2cl") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vsha2ms,vsha2ch,vsha2cl")) "vxu_ooo_issue,vxu_ooo_alu") ;; Vector crypto, SM3/4 (define_insn_reservation "vec_crypto_sm" 4 - (eq_attr "type" "vsm4k,vsm4r,vsm3me,vsm3c") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vsm4k,vsm4r,vsm3me,vsm3c")) "vxu_ooo_issue,vxu_ooo_alu") ;; Vector permute. (define_insn_reservation "vec_perm" 3 - (eq_attr "type" "vimerge,vfmerge,vslideup,vslidedown,vislide1up,\ - vislide1down,vfslide1up,vfslide1down,vgather,vcompress") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vimerge,vfmerge,vslideup,vslidedown,vislide1up,\ + vislide1down,vfslide1up,vfslide1down,vgather,vcompress")) "vxu_ooo_issue,vxu_ooo_alu") ;; Vector reduction. (define_insn_reservation "vec_reduction" 8 - (eq_attr "type" "vired,viwred,vfredu,vfwredu") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vired,viwred,vfredu,vfwredu")) "vxu_ooo_issue,vxu_ooo_multicycle") ;; Vector ordered reduction, assume the latency number is for ;; a 128-bit vector. It is scaled in riscv_sched_adjust_cost ;; for larger vectors. (define_insn_reservation "vec_ordered_reduction" 10 - (eq_attr "type" "vfredo,vfwredo") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vfredo,vfwredo")) "vxu_ooo_issue,vxu_ooo_multicycle*3") ;; Vector integer division, assume not pipelined. (define_insn_reservation "vec_idiv" 16 - (eq_attr "type" "vidiv") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vidiv")) "vxu_ooo_issue,vxu_ooo_multicycle*3") ;; Vector float divisions and sqrt, assume not pipelined. (define_insn_reservation "vec_float_divsqrt" 16 - (eq_attr "type" "vfdiv,vfsqrt") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vfdiv,vfsqrt")) "vxu_ooo_issue,vxu_ooo_multicycle*3") ;; Vector mask operations. (define_insn_reservation "vec_mask" 2 - (eq_attr "type" "vmalu,vmpop,vmffs,vmsfs,vmiota,vmidx,vimovvx,vimovxv,\ - vfmovvf,vfmovfv") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vmalu,vmpop,vmffs,vmsfs,vmiota,vmidx,vimovvx,vimovxv,\ + vfmovvf,vfmovfv")) "vxu_ooo_issue,vxu_ooo_alu") ;; Vector vsetvl. (define_insn_reservation "vec_vesetvl" 1 - (eq_attr "type" "vsetvl,vsetvl_pre") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "vsetvl,vsetvl_pre")) "vxu_ooo_issue") ;; Vector rounding mode setters, assume pipeline barrier. (define_insn_reservation "vec_setrm" 20 - (eq_attr "type" "wrvxrm,wrfrm") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "wrvxrm,wrfrm")) "vxu_ooo_issue,vxu_ooo_issue*3") ;; Vector read vlen/vlenb. (define_insn_reservation "vec_readlen" 4 - (eq_attr "type" "rdvlenb,rdvl") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "rdvlenb,rdvl")) "vxu_ooo_issue,vxu_ooo_issue") ;; Vector sf_vcp. (define_insn_reservation "vec_sf_vcp" 2 - (eq_attr "type" "sf_vc,sf_vc_se") + (and (eq_attr "tune" "generic_ooo,generic") + (eq_attr "type" "sf_vc,sf_vc_se")) "vxu_ooo_issue") diff --git a/gcc/config/riscv/mips-insn.md b/gcc/config/riscv/mips-insn.md new file mode 100644 index 000000000000..ad46026739c6 --- /dev/null +++ b/gcc/config/riscv/mips-insn.md @@ -0,0 +1,35 @@ +;; Machine description for MIPS custom instructions. +;; Copyright (C) 2025 Free Software Foundation, Inc. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; <http://www.gnu.org/licenses/>. + +(define_insn "*mov<GPR:mode><X:mode>cc_bitmanip" + [(set (match_operand:GPR 0 "register_operand" "=r") + (if_then_else:GPR (any_eq:X (match_operand:X 1 "register_operand" "r") + (match_operand:X 2 "const_0_operand" "J")) + (match_operand:GPR 3 "reg_or_0_operand" "rJ") + (match_operand:GPR 4 "reg_or_0_operand" "rJ")))] + "TARGET_XMIPSCMOV" +{ + enum rtx_code code = <CODE>; + if (code == NE) + return "mips.ccmov\t%0,%1,%z3,%z4"; + else + return "mips.ccmov\t%0,%1,%z4,%z3"; +} +[(set_attr "type" "condmove") + (set_attr "mode" "<GPR:MODE>")]) diff --git a/gcc/config/riscv/mips-p8700.md b/gcc/config/riscv/mips-p8700.md index ae0ea8dc896f..fac9abbb198b 100644 --- a/gcc/config/riscv/mips-p8700.md +++ b/gcc/config/riscv/mips-p8700.md @@ -163,5 +163,5 @@ vgather,vcompress,vmov,vector,vandn,vbrev,vbrev8,vrev8,vclz,vctz,vcpop,vrol,vror,vwsll, vclmul,vclmulh,vghsh,vgmul,vaesef,vaesem,vaesdf,vaesdm,vaeskf1,vaeskf2,vaesz, vsha2ms,vsha2ch,vsha2cl,vsm4k,vsm4r,vsm3me,vsm3c,vfncvtbf16,vfwcvtbf16,vfwmaccbf16, - sf_vc,sf_vc_se")) + sf_vc,sf_vc_se,ghost")) "mips_p8700_dummies") diff --git a/gcc/config/riscv/pipeline-checker b/gcc/config/riscv/pipeline-checker new file mode 100755 index 000000000000..815698b0e20f --- /dev/null +++ b/gcc/config/riscv/pipeline-checker @@ -0,0 +1,191 @@ +#!/usr/bin/env python3 + +# RISC-V pipeline model checker. +# Copyright (C) 2025 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +import re +import sys +import argparse +from pathlib import Path +from typing import List +import pprint + +def remove_line_comments(text: str) -> str: + # Remove ';;' and everything after it on each line + cleaned_lines = [] + for line in text.splitlines(): + comment_index = line.find(';;') + if comment_index != -1: + line = line[:comment_index] + cleaned_lines.append(line) + return '\n'.join(cleaned_lines) + + +def tokenize_sexpr(s: str) -> List[str]: + # Tokenize input string, including support for balanced {...} C blocks + tokens = [] + i = 0 + while i < len(s): + c = s[i] + if c.isspace(): + i += 1 + elif c == '(' or c == ')': + tokens.append(c) + i += 1 + elif c == '"': + # Parse quoted string + j = i + 1 + while j < len(s) and s[j] != '"': + if s[j] == '\\': + j += 1 # Skip escape + j += 1 + tokens.append(s[i:j+1]) + i = j + 1 + elif c == '{': + # Parse balanced C block + depth = 1 + j = i + 1 + while j < len(s) and depth > 0: + if s[j] == '{': + depth += 1 + elif s[j] == '}': + depth -= 1 + j += 1 + tokens.append(s[i:j]) # Include enclosing braces + i = j + else: + # Parse atom + j = i + while j < len(s) and not s[j].isspace() and s[j] not in '()"{}': + j += 1 + tokens.append(s[i:j]) + i = j + return tokens + + +def parse_sexpr(tokens: List[str]) -> any: + # Recursively parse tokenized S-expression + token = tokens.pop(0) + if token == '(': + lst = [] + while tokens[0] != ')': + lst.append(parse_sexpr(tokens)) + tokens.pop(0) # Discard closing parenthesis + return lst + elif token.startswith('"') and token.endswith('"'): + return token[1:-1] # Remove surrounding quotes + elif token.startswith('{') and token.endswith('}'): + return token # Keep C code block as-is + else: + return token + + +def find_define_attr_type(ast: any) -> List[List[str]]: + # Traverse AST to find all (define_attr "type" ...) entries + result = [] + if isinstance(ast, list): + if ast and ast[0] == 'define_attr' and len(ast) >= 2 and ast[1] == 'type': + result.append(ast) + for elem in ast: + result.extend(find_define_attr_type(elem)) + return result + + +def parse_md_file(path: Path): + # Read file, remove comments, and parse all top-level S-expressions + with open(path, encoding='utf-8') as f: + raw_content = f.read() + clean_content = remove_line_comments(raw_content) + tokens = tokenize_sexpr(clean_content) + items = [] + while tokens: + items.append(parse_sexpr(tokens)) + return items + +def parsing_str_set(s: str) -> set: + s = s.replace('\\','').split(',') + s = set(map(lambda x: x.strip(), s)) + return s + +def get_avaliable_types(md_file_path: str): + # Main logic: parse input file and print define_attr "type" expressions + ast = parse_md_file(Path(md_file_path)) + + # Get all type from define_attr type + define_attr_types = find_define_attr_type(ast) + types = parsing_str_set (define_attr_types[0][2]) + return types + +def get_consumed_type(entry: List[str]) -> set: + # Extract the consumed type from a define_insn_reservation entry + current_type = entry[0] + if current_type in ['and', 'or']: + return get_consumed_type(entry[1]) | get_consumed_type(entry[2]) + elif current_type == 'eq_attr' and entry[1] == 'type': + return parsing_str_set(entry[2]) + return set() + +def check_pipemodel(md_file_path: str): + # Load the RISCV MD file and check for pipemodel + ast = parse_md_file(Path(md_file_path)) + + consumed_type = set() + + for entry in ast: + entry_type = entry[0] + if entry_type not in ["define_insn_reservation"]: + continue + consumed_type |= get_consumed_type(entry[3]) + return consumed_type + + +def main(): + parser = argparse.ArgumentParser(description='Check GCC pipeline model for instruction type coverage') + parser.add_argument('pipeline_model', help='Pipeline model file to check') + parser.add_argument('--base-md', + help='Base machine description file (default: riscv.md in script directory)', + default=None) + parser.add_argument('-v', '--verbose', + help='Show detailed type information', + action='store_true') + args = parser.parse_args() + + # Set default base-md path if not provided + if args.base_md is None: + script_dir = Path(__file__).parent + base_md_path = script_dir / "riscv.md" + else: + base_md_path = Path(args.base_md) + avaliable_types = get_avaliable_types(str(base_md_path)) + consumed_type = check_pipemodel(args.pipeline_model) + + if args.verbose: + print("Available types:\n", avaliable_types) + print("Consumed types:\n", consumed_type) + + if not avaliable_types.issubset(consumed_type): + print("Error: Some types are not consumed by the pipemodel") + print("Missing types:\n", avaliable_types - consumed_type) + sys.exit(1) + else: + print("All available types are consumed by the pipemodel.") + + +if __name__ == '__main__': + main() diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 23690792b32e..1f9a6b562e53 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -27,6 +27,18 @@ (ior (match_operand 0 "const_arith_operand") (match_operand 0 "register_operand"))) +;; REG or REG+D where D fits in a simm12 and has the low 5 bits +;; off. The REG+D form can be reloaded into a temporary if needed +;; after FP elimination if that exposes an invalid offset. +(define_predicate "prefetch_operand" + (ior (match_operand 0 "register_operand") + (and (match_test "const_arith_operand (op, VOIDmode)") + (match_test "(INTVAL (op) & 0x1f) == 0")) + (and (match_code "plus") + (match_test "register_operand (XEXP (op, 0), word_mode)") + (match_test "const_arith_operand (XEXP (op, 1), VOIDmode)") + (match_test "(INTVAL (XEXP (op, 1)) & 0x1f) == 0")))) + (define_predicate "lui_operand" (and (match_code "const_int") (match_test "LUI_OPERAND (INTVAL (op))"))) @@ -605,7 +617,7 @@ ;; The scalar operand can be directly broadcast by RVV instructions. (define_predicate "direct_broadcast_operand" - (match_test "riscv_vector::can_be_broadcasted_p (op)")) + (match_test "riscv_vector::can_be_broadcast_p (op)")) ;; A CONST_INT operand that has exactly two bits cleared. (define_predicate "const_nottwobits_operand" diff --git a/gcc/config/riscv/riscv-avlprop.cc b/gcc/config/riscv/riscv-avlprop.cc index bb4aceb75064..3031c29ae63c 100644 --- a/gcc/config/riscv/riscv-avlprop.cc +++ b/gcc/config/riscv/riscv-avlprop.cc @@ -508,7 +508,7 @@ pass_avlprop::execute (function *fn) simplify_replace_vlmax_avl (rinsn, prop.second); } - if (rvv_vector_bits == RVV_VECTOR_BITS_ZVL) + if (rvv_vector_bits == RVV_VECTOR_BITS_ZVL && !TARGET_XTHEADVECTOR) { /* Simplify VLMAX AVL into immediate AVL. E.g. Simplify this following case: diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def index 118fef23cad4..98f347034fbb 100644 --- a/gcc/config/riscv/riscv-cores.def +++ b/gcc/config/riscv/riscv-cores.def @@ -33,6 +33,7 @@ #define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO) #endif +RISCV_TUNE("generic", generic, generic_tune_info) RISCV_TUNE("rocket", generic, rocket_tune_info) RISCV_TUNE("sifive-3-series", generic, rocket_tune_info) RISCV_TUNE("sifive-5-series", generic, rocket_tune_info) @@ -48,6 +49,7 @@ RISCV_TUNE("xt-c910v2", generic, generic_ooo_tune_info) RISCV_TUNE("xt-c920", generic, generic_ooo_tune_info) RISCV_TUNE("xt-c920v2", generic, generic_ooo_tune_info) RISCV_TUNE("xiangshan-nanhu", xiangshan, xiangshan_nanhu_tune_info) +RISCV_TUNE("xiangshan-kunminghu", xiangshan, generic_ooo_tune_info) RISCV_TUNE("generic-ooo", generic_ooo, generic_ooo_tune_info) RISCV_TUNE("size", generic, optimize_size_tune_info) RISCV_TUNE("mips-p8700", mips_p8700, mips_p8700_tune_info) @@ -154,7 +156,19 @@ RISCV_CORE("xiangshan-nanhu", "rv64imafdc_zba_zbb_zbc_zbs_" "svinval_zicbom_zicboz", "xiangshan-nanhu") -RISCV_CORE("mips-p8700", "rv64imafd_zicsr_zmmul_" - "zaamo_zalrsc_zba_zbb", +RISCV_CORE("xiangshan-kunminghu", "rv64imafdcbvh_sdtrig_sha_shcounterenw_" + "shgatpa_shlcofideleg_shtvala_shvsatpa_shvstvala_shvstvecd_" + "smaia_smcsrind_smdbltrp_smmpm_smnpm_smrnmi_smstateen_" + "ssaia_ssccptr_sscofpmf_sscounterenw_sscsrind_ssdbltrp_" + "ssnpm_sspm_ssstateen_ssstrict_sstc_sstvala_sstvecd_" + "ssu64xl_supm_svade_svbare_svinval_svnapot_svpbmt_za64rs_" + "zacas_zawrs_zba_zbb_zbc_zbkb_zbkc_zbkx_zbs_zcb_zcmop_" + "zfa_zfh_zfhmin_zic64b_zicbom_zicbop_zicboz_ziccif_" + "zicclsm_ziccrse_zicntr_zicond_zicsr_zifencei_zihintpause_" + "zihpm_zimop_zkn_zknd_zkne_zknh_zksed_zksh_zkt_zvbb_zvfh_" + "zvfhmin_zvkt_zvl128b_zvl32b_zvl64b", + "xiangshan-kunminghu") + +RISCV_CORE("mips-p8700", "rv64imfd_zicsr_zifencei_zalrsc_zba_zbb", "mips-p8700") #undef RISCV_CORE diff --git a/gcc/config/riscv/riscv-ext-mips.def b/gcc/config/riscv/riscv-ext-mips.def new file mode 100644 index 000000000000..5d7836d59998 --- /dev/null +++ b/gcc/config/riscv/riscv-ext-mips.def @@ -0,0 +1,35 @@ +/* MIPS extension definition file for RISC-V. + Copyright (C) 2025 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + +Please run `make riscv-regen` in build folder to make sure updated anything. + +Format of DEFINE_RISCV_EXT, please refer to riscv-ext.def. */ + +DEFINE_RISCV_EXT ( + /* NAME. */ xmipscmov, + /* UPPERCASE_NAME. */ XMIPSCMOV, + /* FULL_NAME. */ "Mips conditional move extension", + /* DESC. */ "", + /* URL. */ , + /* DEP_EXTS. */ ({}), + /* SUPPORTED_VERSIONS. */ ({{1, 0}}), + /* FLAG_GROUP. */ xmips, + /* BITMASK_GROUP_ID. */ BITMASK_NOT_YET_ALLOCATED, + /* BITMASK_BIT_POSITION. */ BITMASK_NOT_YET_ALLOCATED, + /* EXTRA_EXTENSION_FLAGS. */ 0) diff --git a/gcc/config/riscv/riscv-ext.def b/gcc/config/riscv/riscv-ext.def index 0e989e122195..6fc6d3886350 100644 --- a/gcc/config/riscv/riscv-ext.def +++ b/gcc/config/riscv/riscv-ext.def @@ -73,7 +73,7 @@ Format of DEFINE_RISCV_EXT: DEFINE_RISCV_EXT( /* NAME */ e, - /* UPPERCAE_NAME */ RVE, + /* UPPERCASE_NAME */ RVE, /* FULL_NAME */ "Reduced base integer extension", /* DESC */ "", /* URL */ , @@ -86,7 +86,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ i, - /* UPPERCAE_NAME */ RVI, + /* UPPERCASE_NAME */ RVI, /* FULL_NAME */ "Base integer extension", /* DESC */ "", /* URL */ , @@ -101,7 +101,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ m, - /* UPPERCAE_NAME */ MUL, + /* UPPERCASE_NAME */ MUL, /* FULL_NAME */ "Integer multiplication and division extension", /* DESC */ "", /* URL */ , @@ -114,7 +114,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ a, - /* UPPERCAE_NAME */ ATOMIC, + /* UPPERCASE_NAME */ ATOMIC, /* FULL_NAME */ "Atomic extension", /* DESC */ "", /* URL */ , @@ -129,7 +129,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ f, - /* UPPERCAE_NAME */ HARD_FLOAT, + /* UPPERCASE_NAME */ HARD_FLOAT, /* FULL_NAME */ "Single-precision floating-point extension", /* DESC */ "", /* URL */ , @@ -144,7 +144,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ d, - /* UPPERCAE_NAME */ DOUBLE_FLOAT, + /* UPPERCASE_NAME */ DOUBLE_FLOAT, /* FULL_NAME */ "Double-precision floating-point extension", /* DESC */ "", /* URL */ , @@ -159,7 +159,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ c, - /* UPPERCAE_NAME */ RVC, + /* UPPERCASE_NAME */ RVC, /* FULL_NAME */ "Compressed extension", /* DESC */ "", /* URL */ , @@ -183,7 +183,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ b, - /* UPPERCAE_NAME */ RVB, + /* UPPERCASE_NAME */ RVB, /* FULL_NAME */ "b extension", /* DESC */ "", /* URL */ , @@ -196,7 +196,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ v, - /* UPPERCAE_NAME */ RVV, + /* UPPERCASE_NAME */ RVV, /* FULL_NAME */ "Vector extension", /* DESC */ "", /* URL */ , @@ -209,7 +209,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ h, - /* UPPERCAE_NAME */ RVH, + /* UPPERCASE_NAME */ RVH, /* FULL_NAME */ "Hypervisor extension", /* DESC */ "", /* URL */ , @@ -222,7 +222,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zic64b, - /* UPPERCAE_NAME */ ZIC64B, + /* UPPERCASE_NAME */ ZIC64B, /* FULL_NAME */ "Cache block size isf 64 bytes", /* DESC */ "", /* URL */ , @@ -235,7 +235,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zicbom, - /* UPPERCAE_NAME */ ZICBOM, + /* UPPERCASE_NAME */ ZICBOM, /* FULL_NAME */ "Cache-block management extension", /* DESC */ "", /* URL */ , @@ -248,7 +248,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zicbop, - /* UPPERCAE_NAME */ ZICBOP, + /* UPPERCASE_NAME */ ZICBOP, /* FULL_NAME */ "Cache-block prefetch extension", /* DESC */ "", /* URL */ , @@ -261,7 +261,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zicboz, - /* UPPERCAE_NAME */ ZICBOZ, + /* UPPERCASE_NAME */ ZICBOZ, /* FULL_NAME */ "Cache-block zero extension", /* DESC */ "", /* URL */ , @@ -274,7 +274,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ ziccamoa, - /* UPPERCAE_NAME */ ZICCAMOA, + /* UPPERCASE_NAME */ ZICCAMOA, /* FULL_NAME */ "Main memory supports all atomics in A", /* DESC */ "", /* URL */ , @@ -287,7 +287,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ ziccif, - /* UPPERCAE_NAME */ ZICCIF, + /* UPPERCASE_NAME */ ZICCIF, /* FULL_NAME */ "Main memory supports instruction fetch with atomicity requirement", /* DESC */ "", /* URL */ , @@ -300,7 +300,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zicclsm, - /* UPPERCAE_NAME */ ZICCLSM, + /* UPPERCASE_NAME */ ZICCLSM, /* FULL_NAME */ "Main memory supports misaligned loads/stores", /* DESC */ "", /* URL */ , @@ -313,7 +313,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ ziccrse, - /* UPPERCAE_NAME */ ZICCRSE, + /* UPPERCASE_NAME */ ZICCRSE, /* FULL_NAME */ "Main memory supports forward progress on LR/SC sequences", /* DESC */ "", /* URL */ , @@ -326,7 +326,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zicfilp, - /* UPPERCAE_NAME */ ZICFILP, + /* UPPERCASE_NAME */ ZICFILP, /* FULL_NAME */ "zicfilp extension", /* DESC */ "", /* URL */ , @@ -339,7 +339,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zicfiss, - /* UPPERCAE_NAME */ ZICFISS, + /* UPPERCASE_NAME */ ZICFISS, /* FULL_NAME */ "zicfiss extension", /* DESC */ "", /* URL */ , @@ -352,7 +352,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zicntr, - /* UPPERCAE_NAME */ ZICNTR, + /* UPPERCASE_NAME */ ZICNTR, /* FULL_NAME */ "Standard extension for base counters and timers", /* DESC */ "", /* URL */ , @@ -365,7 +365,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zicond, - /* UPPERCAE_NAME */ ZICOND, + /* UPPERCASE_NAME */ ZICOND, /* FULL_NAME */ "Integer conditional operations extension", /* DESC */ "", /* URL */ , @@ -378,7 +378,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zicsr, - /* UPPERCAE_NAME */ ZICSR, + /* UPPERCASE_NAME */ ZICSR, /* FULL_NAME */ "Control and status register access extension", /* DESC */ "", /* URL */ , @@ -391,7 +391,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zifencei, - /* UPPERCAE_NAME */ ZIFENCEI, + /* UPPERCASE_NAME */ ZIFENCEI, /* FULL_NAME */ "Instruction-fetch fence extension", /* DESC */ "", /* URL */ , @@ -404,7 +404,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zihintntl, - /* UPPERCAE_NAME */ ZIHINTNTL, + /* UPPERCASE_NAME */ ZIHINTNTL, /* FULL_NAME */ "Non-temporal locality hints extension", /* DESC */ "", /* URL */ , @@ -417,7 +417,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zihintpause, - /* UPPERCAE_NAME */ ZIHINTPAUSE, + /* UPPERCASE_NAME */ ZIHINTPAUSE, /* FULL_NAME */ "Pause hint extension", /* DESC */ "", /* URL */ , @@ -430,7 +430,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zihpm, - /* UPPERCAE_NAME */ ZIHPM, + /* UPPERCASE_NAME */ ZIHPM, /* FULL_NAME */ "Standard extension for hardware performance counters", /* DESC */ "", /* URL */ , @@ -443,7 +443,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zimop, - /* UPPERCAE_NAME */ ZIMOP, + /* UPPERCASE_NAME */ ZIMOP, /* FULL_NAME */ "zimop extension", /* DESC */ "", /* URL */ , @@ -456,7 +456,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zilsd, - /* UPPERCAE_NAME */ ZILSD, + /* UPPERCASE_NAME */ ZILSD, /* FULL_NAME */ "Load/Store pair instructions extension", /* DESC */ "", /* URL */ , @@ -469,7 +469,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zmmul, - /* UPPERCAE_NAME */ ZMMUL, + /* UPPERCASE_NAME */ ZMMUL, /* FULL_NAME */ "Integer multiplication extension", /* DESC */ "", /* URL */ , @@ -482,7 +482,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ za128rs, - /* UPPERCAE_NAME */ ZA128RS, + /* UPPERCASE_NAME */ ZA128RS, /* FULL_NAME */ "Reservation set size of 128 bytes", /* DESC */ "", /* URL */ , @@ -495,7 +495,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ za64rs, - /* UPPERCAE_NAME */ ZA64RS, + /* UPPERCASE_NAME */ ZA64RS, /* FULL_NAME */ "Reservation set size of 64 bytes", /* DESC */ "", /* URL */ , @@ -508,7 +508,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zaamo, - /* UPPERCAE_NAME */ ZAAMO, + /* UPPERCASE_NAME */ ZAAMO, /* FULL_NAME */ "zaamo extension", /* DESC */ "", /* URL */ , @@ -521,7 +521,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zabha, - /* UPPERCAE_NAME */ ZABHA, + /* UPPERCASE_NAME */ ZABHA, /* FULL_NAME */ "zabha extension", /* DESC */ "", /* URL */ , @@ -534,7 +534,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zacas, - /* UPPERCAE_NAME */ ZACAS, + /* UPPERCASE_NAME */ ZACAS, /* FULL_NAME */ "zacas extension", /* DESC */ "", /* URL */ , @@ -547,7 +547,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zalrsc, - /* UPPERCAE_NAME */ ZALRSC, + /* UPPERCASE_NAME */ ZALRSC, /* FULL_NAME */ "zalrsc extension", /* DESC */ "", /* URL */ , @@ -560,7 +560,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zawrs, - /* UPPERCAE_NAME */ ZAWRS, + /* UPPERCASE_NAME */ ZAWRS, /* FULL_NAME */ "Wait-on-reservation-set extension", /* DESC */ "", /* URL */ , @@ -573,7 +573,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zama16b, - /* UPPERCAE_NAME */ ZAMA16B, + /* UPPERCASE_NAME */ ZAMA16B, /* FULL_NAME */ "Zama16b extension", /* DESC */ "Misaligned loads, stores, and AMOs to main memory regions that do" " not cross a naturally aligned 16-byte boundary are atomic.", @@ -587,7 +587,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zfa, - /* UPPERCAE_NAME */ ZFA, + /* UPPERCASE_NAME */ ZFA, /* FULL_NAME */ "Additional floating-point extension", /* DESC */ "", /* URL */ , @@ -600,7 +600,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zfbfmin, - /* UPPERCAE_NAME */ ZFBFMIN, + /* UPPERCASE_NAME */ ZFBFMIN, /* FULL_NAME */ "zfbfmin extension", /* DESC */ "", /* URL */ , @@ -613,7 +613,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zfh, - /* UPPERCAE_NAME */ ZFH, + /* UPPERCASE_NAME */ ZFH, /* FULL_NAME */ "Half-precision floating-point extension", /* DESC */ "", /* URL */ , @@ -626,7 +626,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zfhmin, - /* UPPERCAE_NAME */ ZFHMIN, + /* UPPERCASE_NAME */ ZFHMIN, /* FULL_NAME */ "Minimal half-precision floating-point extension", /* DESC */ "", /* URL */ , @@ -639,7 +639,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zfinx, - /* UPPERCAE_NAME */ ZFINX, + /* UPPERCASE_NAME */ ZFINX, /* FULL_NAME */ "Single-precision floating-point in integer registers extension", /* DESC */ "", /* URL */ , @@ -652,7 +652,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zdinx, - /* UPPERCAE_NAME */ ZDINX, + /* UPPERCASE_NAME */ ZDINX, /* FULL_NAME */ "Double-precision floating-point in integer registers extension", /* DESC */ "", /* URL */ , @@ -665,7 +665,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zca, - /* UPPERCAE_NAME */ ZCA, + /* UPPERCASE_NAME */ ZCA, /* FULL_NAME */ "Integer compressed instruction extension", /* DESC */ "", /* URL */ , @@ -709,7 +709,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zcb, - /* UPPERCAE_NAME */ ZCB, + /* UPPERCASE_NAME */ ZCB, /* FULL_NAME */ "Simple compressed instruction extension", /* DESC */ "", /* URL */ , @@ -722,7 +722,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zcd, - /* UPPERCAE_NAME */ ZCD, + /* UPPERCASE_NAME */ ZCD, /* FULL_NAME */ "Compressed double-precision floating point loads and stores extension", /* DESC */ "", /* URL */ , @@ -735,7 +735,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zce, - /* UPPERCAE_NAME */ ZCE, + /* UPPERCASE_NAME */ ZCE, /* FULL_NAME */ "Compressed instruction extensions for embedded processors", /* DESC */ "", /* URL */ , @@ -754,7 +754,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zcf, - /* UPPERCAE_NAME */ ZCF, + /* UPPERCASE_NAME */ ZCF, /* FULL_NAME */ "Compressed single-precision floating point loads and stores extension", /* DESC */ "", /* URL */ , @@ -767,7 +767,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zcmop, - /* UPPERCAE_NAME */ ZCMOP, + /* UPPERCASE_NAME */ ZCMOP, /* FULL_NAME */ "zcmop extension", /* DESC */ "", /* URL */ , @@ -780,7 +780,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zcmp, - /* UPPERCAE_NAME */ ZCMP, + /* UPPERCASE_NAME */ ZCMP, /* FULL_NAME */ "Compressed push pop extension", /* DESC */ "", /* URL */ , @@ -793,7 +793,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zcmt, - /* UPPERCAE_NAME */ ZCMT, + /* UPPERCASE_NAME */ ZCMT, /* FULL_NAME */ "Table jump instruction extension", /* DESC */ "", /* URL */ , @@ -806,7 +806,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zclsd, - /* UPPERCAE_NAME */ ZCLSD, + /* UPPERCASE_NAME */ ZCLSD, /* FULL_NAME */ "Compressed load/store pair instructions extension", /* DESC */ "", /* URL */ , @@ -819,7 +819,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zba, - /* UPPERCAE_NAME */ ZBA, + /* UPPERCASE_NAME */ ZBA, /* FULL_NAME */ "Address calculation extension", /* DESC */ "", /* URL */ , @@ -832,7 +832,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zbb, - /* UPPERCAE_NAME */ ZBB, + /* UPPERCASE_NAME */ ZBB, /* FULL_NAME */ "Basic bit manipulation extension", /* DESC */ "", /* URL */ , @@ -845,7 +845,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zbc, - /* UPPERCAE_NAME */ ZBC, + /* UPPERCASE_NAME */ ZBC, /* FULL_NAME */ "Carry-less multiplication extension", /* DESC */ "", /* URL */ , @@ -858,7 +858,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zbkb, - /* UPPERCAE_NAME */ ZBKB, + /* UPPERCASE_NAME */ ZBKB, /* FULL_NAME */ "Cryptography bit-manipulation extension", /* DESC */ "", /* URL */ , @@ -871,7 +871,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zbkc, - /* UPPERCAE_NAME */ ZBKC, + /* UPPERCASE_NAME */ ZBKC, /* FULL_NAME */ "Cryptography carry-less multiply extension", /* DESC */ "", /* URL */ , @@ -884,7 +884,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zbkx, - /* UPPERCAE_NAME */ ZBKX, + /* UPPERCASE_NAME */ ZBKX, /* FULL_NAME */ "Cryptography crossbar permutation extension", /* DESC */ "", /* URL */ , @@ -897,7 +897,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zbs, - /* UPPERCAE_NAME */ ZBS, + /* UPPERCASE_NAME */ ZBS, /* FULL_NAME */ "Single-bit operation extension", /* DESC */ "", /* URL */ , @@ -910,7 +910,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zk, - /* UPPERCAE_NAME */ ZK, + /* UPPERCASE_NAME */ ZK, /* FULL_NAME */ "Standard scalar cryptography extension", /* DESC */ "", /* URL */ , @@ -923,7 +923,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zkn, - /* UPPERCAE_NAME */ ZKN, + /* UPPERCASE_NAME */ ZKN, /* FULL_NAME */ "NIST algorithm suite extension", /* DESC */ "", /* URL */ , @@ -936,7 +936,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zknd, - /* UPPERCAE_NAME */ ZKND, + /* UPPERCASE_NAME */ ZKND, /* FULL_NAME */ "AES Decryption extension", /* DESC */ "", /* URL */ , @@ -949,7 +949,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zkne, - /* UPPERCAE_NAME */ ZKNE, + /* UPPERCASE_NAME */ ZKNE, /* FULL_NAME */ "AES Encryption extension", /* DESC */ "", /* URL */ , @@ -962,7 +962,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zknh, - /* UPPERCAE_NAME */ ZKNH, + /* UPPERCASE_NAME */ ZKNH, /* FULL_NAME */ "Hash function extension", /* DESC */ "", /* URL */ , @@ -975,7 +975,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zkr, - /* UPPERCAE_NAME */ ZKR, + /* UPPERCASE_NAME */ ZKR, /* FULL_NAME */ "Entropy source extension", /* DESC */ "", /* URL */ , @@ -988,7 +988,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zks, - /* UPPERCAE_NAME */ ZKS, + /* UPPERCASE_NAME */ ZKS, /* FULL_NAME */ "ShangMi algorithm suite extension", /* DESC */ "", /* URL */ , @@ -1001,7 +1001,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zksed, - /* UPPERCAE_NAME */ ZKSED, + /* UPPERCASE_NAME */ ZKSED, /* FULL_NAME */ "SM4 block cipher extension", /* DESC */ "", /* URL */ , @@ -1014,7 +1014,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zksh, - /* UPPERCAE_NAME */ ZKSH, + /* UPPERCASE_NAME */ ZKSH, /* FULL_NAME */ "SM3 hash function extension", /* DESC */ "", /* URL */ , @@ -1027,7 +1027,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zkt, - /* UPPERCAE_NAME */ ZKT, + /* UPPERCASE_NAME */ ZKT, /* FULL_NAME */ "Data independent execution latency extension", /* DESC */ "", /* URL */ , @@ -1040,7 +1040,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ ztso, - /* UPPERCAE_NAME */ ZTSO, + /* UPPERCASE_NAME */ ZTSO, /* FULL_NAME */ "Total store ordering extension", /* DESC */ "", /* URL */ , @@ -1053,7 +1053,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvbb, - /* UPPERCAE_NAME */ ZVBB, + /* UPPERCASE_NAME */ ZVBB, /* FULL_NAME */ "Vector basic bit-manipulation extension", /* DESC */ "", /* URL */ , @@ -1066,7 +1066,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvbc, - /* UPPERCAE_NAME */ ZVBC, + /* UPPERCASE_NAME */ ZVBC, /* FULL_NAME */ "Vector carryless multiplication extension", /* DESC */ "", /* URL */ , @@ -1079,7 +1079,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zve32f, - /* UPPERCAE_NAME */ ZVE32F, + /* UPPERCASE_NAME */ ZVE32F, /* FULL_NAME */ "Vector extensions for embedded processors", /* DESC */ "", /* URL */ , @@ -1092,7 +1092,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zve32x, - /* UPPERCAE_NAME */ ZVE32X, + /* UPPERCASE_NAME */ ZVE32X, /* FULL_NAME */ "Vector extensions for embedded processors", /* DESC */ "", /* URL */ , @@ -1105,7 +1105,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zve64d, - /* UPPERCAE_NAME */ ZVE64D, + /* UPPERCASE_NAME */ ZVE64D, /* FULL_NAME */ "Vector extensions for embedded processors", /* DESC */ "", /* URL */ , @@ -1118,7 +1118,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zve64f, - /* UPPERCAE_NAME */ ZVE64F, + /* UPPERCASE_NAME */ ZVE64F, /* FULL_NAME */ "Vector extensions for embedded processors", /* DESC */ "", /* URL */ , @@ -1131,7 +1131,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zve64x, - /* UPPERCAE_NAME */ ZVE64X, + /* UPPERCASE_NAME */ ZVE64X, /* FULL_NAME */ "Vector extensions for embedded processors", /* DESC */ "", /* URL */ , @@ -1144,7 +1144,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvfbfmin, - /* UPPERCAE_NAME */ ZVFBFMIN, + /* UPPERCASE_NAME */ ZVFBFMIN, /* FULL_NAME */ "Vector BF16 converts extension", /* DESC */ "", /* URL */ , @@ -1157,7 +1157,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvfbfwma, - /* UPPERCAE_NAME */ ZVFBFWMA, + /* UPPERCASE_NAME */ ZVFBFWMA, /* FULL_NAME */ "zvfbfwma extension", /* DESC */ "", /* URL */ , @@ -1170,7 +1170,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvfh, - /* UPPERCAE_NAME */ ZVFH, + /* UPPERCASE_NAME */ ZVFH, /* FULL_NAME */ "Vector half-precision floating-point extension", /* DESC */ "", /* URL */ , @@ -1183,7 +1183,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvfhmin, - /* UPPERCAE_NAME */ ZVFHMIN, + /* UPPERCASE_NAME */ ZVFHMIN, /* FULL_NAME */ "Vector minimal half-precision floating-point extension", /* DESC */ "", /* URL */ , @@ -1196,7 +1196,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvkb, - /* UPPERCAE_NAME */ ZVKB, + /* UPPERCASE_NAME */ ZVKB, /* FULL_NAME */ "Vector cryptography bit-manipulation extension", /* DESC */ "", /* URL */ , @@ -1209,7 +1209,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvkg, - /* UPPERCAE_NAME */ ZVKG, + /* UPPERCASE_NAME */ ZVKG, /* FULL_NAME */ "Vector GCM/GMAC extension", /* DESC */ "", /* URL */ , @@ -1222,7 +1222,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvkn, - /* UPPERCAE_NAME */ ZVKN, + /* UPPERCASE_NAME */ ZVKN, /* FULL_NAME */ "Vector NIST Algorithm Suite extension", /* DESC */ "@samp{zvkn} will expand to", /* URL */ , @@ -1235,7 +1235,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvknc, - /* UPPERCAE_NAME */ ZVKNC, + /* UPPERCASE_NAME */ ZVKNC, /* FULL_NAME */ "Vector NIST Algorithm Suite with carryless multiply extension, @samp{zvknc}", /* DESC */ "", /* URL */ , @@ -1248,7 +1248,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvkned, - /* UPPERCAE_NAME */ ZVKNED, + /* UPPERCASE_NAME */ ZVKNED, /* FULL_NAME */ "Vector AES block cipher extension", /* DESC */ "", /* URL */ , @@ -1261,7 +1261,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvkng, - /* UPPERCAE_NAME */ ZVKNG, + /* UPPERCASE_NAME */ ZVKNG, /* FULL_NAME */ "Vector NIST Algorithm Suite with GCM extension, @samp{zvkng} will expand", /* DESC */ "", /* URL */ , @@ -1274,7 +1274,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvknha, - /* UPPERCAE_NAME */ ZVKNHA, + /* UPPERCASE_NAME */ ZVKNHA, /* FULL_NAME */ "Vector SHA-2 secure hash extension", /* DESC */ "", /* URL */ , @@ -1287,7 +1287,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvknhb, - /* UPPERCAE_NAME */ ZVKNHB, + /* UPPERCASE_NAME */ ZVKNHB, /* FULL_NAME */ "Vector SHA-2 secure hash extension", /* DESC */ "", /* URL */ , @@ -1300,7 +1300,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvks, - /* UPPERCAE_NAME */ ZVKS, + /* UPPERCASE_NAME */ ZVKS, /* FULL_NAME */ "Vector ShangMi algorithm suite extension, @samp{zvks} will expand", /* DESC */ "", /* URL */ , @@ -1313,7 +1313,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvksc, - /* UPPERCAE_NAME */ ZVKSC, + /* UPPERCASE_NAME */ ZVKSC, /* FULL_NAME */ "Vector ShangMi algorithm suite with carryless multiplication extension,", /* DESC */ "", /* URL */ , @@ -1326,7 +1326,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvksed, - /* UPPERCAE_NAME */ ZVKSED, + /* UPPERCASE_NAME */ ZVKSED, /* FULL_NAME */ "Vector SM4 Block Cipher extension", /* DESC */ "", /* URL */ , @@ -1339,7 +1339,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvksg, - /* UPPERCAE_NAME */ ZVKSG, + /* UPPERCASE_NAME */ ZVKSG, /* FULL_NAME */ "Vector ShangMi algorithm suite with GCM extension, @samp{zvksg} will expand", /* DESC */ "", /* URL */ , @@ -1352,7 +1352,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvksh, - /* UPPERCAE_NAME */ ZVKSH, + /* UPPERCASE_NAME */ ZVKSH, /* FULL_NAME */ "Vector SM3 Secure Hash extension", /* DESC */ "", /* URL */ , @@ -1365,7 +1365,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvkt, - /* UPPERCAE_NAME */ ZVKT, + /* UPPERCASE_NAME */ ZVKT, /* FULL_NAME */ "Vector data independent execution latency extension", /* DESC */ "", /* URL */ , @@ -1378,7 +1378,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvl1024b, - /* UPPERCAE_NAME */ ZVL1024B, + /* UPPERCASE_NAME */ ZVL1024B, /* FULL_NAME */ "Minimum vector length standard extensions", /* DESC */ "", /* URL */ , @@ -1391,7 +1391,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvl128b, - /* UPPERCAE_NAME */ ZVL128B, + /* UPPERCASE_NAME */ ZVL128B, /* FULL_NAME */ "Minimum vector length standard extensions", /* DESC */ "", /* URL */ , @@ -1404,7 +1404,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvl16384b, - /* UPPERCAE_NAME */ ZVL16384B, + /* UPPERCASE_NAME */ ZVL16384B, /* FULL_NAME */ "zvl16384b extension", /* DESC */ "", /* URL */ , @@ -1417,7 +1417,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvl2048b, - /* UPPERCAE_NAME */ ZVL2048B, + /* UPPERCASE_NAME */ ZVL2048B, /* FULL_NAME */ "Minimum vector length standard extensions", /* DESC */ "", /* URL */ , @@ -1430,7 +1430,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvl256b, - /* UPPERCAE_NAME */ ZVL256B, + /* UPPERCASE_NAME */ ZVL256B, /* FULL_NAME */ "Minimum vector length standard extensions", /* DESC */ "", /* URL */ , @@ -1443,7 +1443,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvl32768b, - /* UPPERCAE_NAME */ ZVL32768B, + /* UPPERCASE_NAME */ ZVL32768B, /* FULL_NAME */ "zvl32768b extension", /* DESC */ "", /* URL */ , @@ -1456,7 +1456,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvl32b, - /* UPPERCAE_NAME */ ZVL32B, + /* UPPERCASE_NAME */ ZVL32B, /* FULL_NAME */ "Minimum vector length standard extensions", /* DESC */ "", /* URL */ , @@ -1469,7 +1469,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvl4096b, - /* UPPERCAE_NAME */ ZVL4096B, + /* UPPERCASE_NAME */ ZVL4096B, /* FULL_NAME */ "Minimum vector length standard extensions", /* DESC */ "", /* URL */ , @@ -1482,7 +1482,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvl512b, - /* UPPERCAE_NAME */ ZVL512B, + /* UPPERCASE_NAME */ ZVL512B, /* FULL_NAME */ "Minimum vector length standard extensions", /* DESC */ "", /* URL */ , @@ -1495,7 +1495,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvl64b, - /* UPPERCAE_NAME */ ZVL64B, + /* UPPERCASE_NAME */ ZVL64B, /* FULL_NAME */ "Minimum vector length standard extensions", /* DESC */ "", /* URL */ , @@ -1508,7 +1508,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvl65536b, - /* UPPERCAE_NAME */ ZVL65536B, + /* UPPERCASE_NAME */ ZVL65536B, /* FULL_NAME */ "zvl65536b extension", /* DESC */ "", /* URL */ , @@ -1521,7 +1521,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zvl8192b, - /* UPPERCAE_NAME */ ZVL8192B, + /* UPPERCASE_NAME */ ZVL8192B, /* FULL_NAME */ "zvl8192b extension", /* DESC */ "", /* URL */ , @@ -1534,7 +1534,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zhinx, - /* UPPERCAE_NAME */ ZHINX, + /* UPPERCASE_NAME */ ZHINX, /* FULL_NAME */ "Half-precision floating-point in integer registers extension", /* DESC */ "", /* URL */ , @@ -1547,7 +1547,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ zhinxmin, - /* UPPERCAE_NAME */ ZHINXMIN, + /* UPPERCASE_NAME */ ZHINXMIN, /* FULL_NAME */ "Minimal half-precision floating-point in integer registers extension", /* DESC */ "", /* URL */ , @@ -1560,7 +1560,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ sdtrig, - /* UPPERCAE_NAME */ SDTRIG, + /* UPPERCASE_NAME */ SDTRIG, /* FULL_NAME */ "sdtrig extension", /* DESC */ "", /* URL */ , @@ -1573,7 +1573,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ sha, - /* UPPERCAE_NAME */ SHA, + /* UPPERCASE_NAME */ SHA, /* FULL_NAME */ "The augmented hypervisor extension", /* DESC */ "", /* URL */ , @@ -1586,7 +1586,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ shcounterenw, - /* UPPERCAE_NAME */ SHCOUNTERENW, + /* UPPERCASE_NAME */ SHCOUNTERENW, /* FULL_NAME */ "Support writeable enables for any supported counter", /* DESC */ "", /* URL */ , @@ -1599,7 +1599,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ shgatpa, - /* UPPERCAE_NAME */ SHGATPA, + /* UPPERCASE_NAME */ SHGATPA, /* FULL_NAME */ "SvNNx4 mode supported for all modes supported by satp", /* DESC */ "", /* URL */ , @@ -1625,7 +1625,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ shtvala, - /* UPPERCAE_NAME */ SHTVALA, + /* UPPERCASE_NAME */ SHTVALA, /* FULL_NAME */ "The htval register provides all needed values", /* DESC */ "", /* URL */ , @@ -1638,7 +1638,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ shvstvala, - /* UPPERCAE_NAME */ SHVSTVALA, + /* UPPERCASE_NAME */ SHVSTVALA, /* FULL_NAME */ "The vstval register provides all needed values", /* DESC */ "", /* URL */ , @@ -1651,7 +1651,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ shvstvecd, - /* UPPERCAE_NAME */ SHVSTVECD, + /* UPPERCASE_NAME */ SHVSTVECD, /* FULL_NAME */ "The vstvec register supports Direct mode", /* DESC */ "", /* URL */ , @@ -1664,7 +1664,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ shvsatpa, - /* UPPERCAE_NAME */ SHVSATPA, + /* UPPERCASE_NAME */ SHVSATPA, /* FULL_NAME */ "The vsatp register supports all modes supported by satp", /* DESC */ "", /* URL */ , @@ -1677,7 +1677,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ smaia, - /* UPPERCAE_NAME */ SMAIA, + /* UPPERCASE_NAME */ SMAIA, /* FULL_NAME */ "Advanced interrupt architecture extension", /* DESC */ "", /* URL */ , @@ -1690,7 +1690,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ smcntrpmf, - /* UPPERCAE_NAME */ SMCNTRPMF, + /* UPPERCASE_NAME */ SMCNTRPMF, /* FULL_NAME */ "Cycle and instret privilege mode filtering", /* DESC */ "", /* URL */ , @@ -1701,9 +1701,22 @@ DEFINE_RISCV_EXT( /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, /* EXTRA_EXTENSION_FLAGS */ 0) +DEFINE_RISCV_EXT( + /* NAME */ smcsrind, + /* UPPERCASE_NAME */ SMCSRIND, + /* FULL_NAME */ "Machine-Level Indirect CSR Access", + /* DESC */ "", + /* URL */ , + /* DEP_EXTS */ ({"zicsr", "sscsrind"}), + /* SUPPORTED_VERSIONS */ ({{1, 0}}), + /* FLAG_GROUP */ sm, + /* BITMASK_GROUP_ID */ BITMASK_NOT_YET_ALLOCATED, + /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, + /* EXTRA_EXTENSION_FLAGS */ 0) + DEFINE_RISCV_EXT( /* NAME */ smepmp, - /* UPPERCAE_NAME */ SMEPMP, + /* UPPERCASE_NAME */ SMEPMP, /* FULL_NAME */ "PMP Enhancements for memory access and execution prevention on Machine mode", /* DESC */ "", /* URL */ , @@ -1716,7 +1729,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ smmpm, - /* UPPERCAE_NAME */ SMMPM, + /* UPPERCASE_NAME */ SMMPM, /* FULL_NAME */ "smmpm extension", /* DESC */ "", /* URL */ , @@ -1729,7 +1742,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ smnpm, - /* UPPERCAE_NAME */ SMNPM, + /* UPPERCASE_NAME */ SMNPM, /* FULL_NAME */ "smnpm extension", /* DESC */ "", /* URL */ , @@ -1740,9 +1753,22 @@ DEFINE_RISCV_EXT( /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, /* EXTRA_EXTENSION_FLAGS */ 0) +DEFINE_RISCV_EXT( + /* NAME */ smrnmi, + /* UPPERCASE_NAME */ SMRNMI, + /* FULL_NAME */ "Resumable non-maskable interrupts", + /* DESC */ "", + /* URL */ , + /* DEP_EXTS */ ({"zicsr"}), + /* SUPPORTED_VERSIONS */ ({{1, 0}}), + /* FLAG_GROUP */ sm, + /* BITMASK_GROUP_ID */ BITMASK_NOT_YET_ALLOCATED, + /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, + /* EXTRA_EXTENSION_FLAGS */ 0) + DEFINE_RISCV_EXT( /* NAME */ smstateen, - /* UPPERCAE_NAME */ SMSTATEEN, + /* UPPERCASE_NAME */ SMSTATEEN, /* FULL_NAME */ "State enable extension", /* DESC */ "", /* URL */ , @@ -1755,7 +1781,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ smdbltrp, - /* UPPERCAE_NAME */ SMDBLTRP, + /* UPPERCASE_NAME */ SMDBLTRP, /* FULL_NAME */ "Double Trap Extensions", /* DESC */ "", /* URL */ , @@ -1768,7 +1794,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ ssaia, - /* UPPERCAE_NAME */ SSAIA, + /* UPPERCASE_NAME */ SSAIA, /* FULL_NAME */ "Advanced interrupt architecture extension for supervisor-mode", /* DESC */ "", /* URL */ , @@ -1779,9 +1805,22 @@ DEFINE_RISCV_EXT( /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, /* EXTRA_EXTENSION_FLAGS */ 0) +DEFINE_RISCV_EXT( + /* NAME */ ssccptr, + /* UPPERCASE_NAME */ SSCCPTR, + /* FULL_NAME */ "Main memory supports page table reads", + /* DESC */ "", + /* URL */ , + /* DEP_EXTS */ ({}), + /* SUPPORTED_VERSIONS */ ({{1, 0}}), + /* FLAG_GROUP */ ss, + /* BITMASK_GROUP_ID */ BITMASK_NOT_YET_ALLOCATED, + /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, + /* EXTRA_EXTENSION_FLAGS */ 0) + DEFINE_RISCV_EXT( /* NAME */ sscofpmf, - /* UPPERCAE_NAME */ SSCOFPMF, + /* UPPERCASE_NAME */ SSCOFPMF, /* FULL_NAME */ "Count overflow & filtering extension", /* DESC */ "", /* URL */ , @@ -1792,9 +1831,35 @@ DEFINE_RISCV_EXT( /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, /* EXTRA_EXTENSION_FLAGS */ 0) +DEFINE_RISCV_EXT( + /* NAME */ sscounterenw, + /* UPPERCASE_NAME */ SSCOUNTERENW, + /* FULL_NAME */ "Support writeable enables for any supported counter", + /* DESC */ "", + /* URL */ , + /* DEP_EXTS */ ({"zicsr"}), + /* SUPPORTED_VERSIONS */ ({{1, 0}}), + /* FLAG_GROUP */ ss, + /* BITMASK_GROUP_ID */ BITMASK_NOT_YET_ALLOCATED, + /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, + /* EXTRA_EXTENSION_FLAGS */ 0) + +DEFINE_RISCV_EXT( + /* NAME */ sscsrind, + /* UPPERCASE_NAME */ SSCSRIND, + /* FULL_NAME */ "Supervisor-Level Indirect CSR Access", + /* DESC */ "", + /* URL */ , + /* DEP_EXTS */ ({"zicsr"}), + /* SUPPORTED_VERSIONS */ ({{1, 0}}), + /* FLAG_GROUP */ ss, + /* BITMASK_GROUP_ID */ BITMASK_NOT_YET_ALLOCATED, + /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, + /* EXTRA_EXTENSION_FLAGS */ 0) + DEFINE_RISCV_EXT( /* NAME */ ssnpm, - /* UPPERCAE_NAME */ SSNPM, + /* UPPERCASE_NAME */ SSNPM, /* FULL_NAME */ "ssnpm extension", /* DESC */ "", /* URL */ , @@ -1807,7 +1872,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ sspm, - /* UPPERCAE_NAME */ SSPM, + /* UPPERCASE_NAME */ SSPM, /* FULL_NAME */ "sspm extension", /* DESC */ "", /* URL */ , @@ -1820,7 +1885,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ ssstateen, - /* UPPERCAE_NAME */ SSSTATEEN, + /* UPPERCASE_NAME */ SSSTATEEN, /* FULL_NAME */ "State-enable extension for supervisor-mode", /* DESC */ "", /* URL */ , @@ -1833,7 +1898,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ sstc, - /* UPPERCAE_NAME */ SSTC, + /* UPPERCASE_NAME */ SSTC, /* FULL_NAME */ "Supervisor-mode timer interrupts extension", /* DESC */ "", /* URL */ , @@ -1844,9 +1909,35 @@ DEFINE_RISCV_EXT( /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, /* EXTRA_EXTENSION_FLAGS */ 0) +DEFINE_RISCV_EXT( + /* NAME */ sstvala, + /* UPPERCASE_NAME */ SSTVALA, + /* FULL_NAME */ "Stval provides all needed values", + /* DESC */ "", + /* URL */ , + /* DEP_EXTS */ ({"zicsr"}), + /* SUPPORTED_VERSIONS */ ({{1, 0}}), + /* FLAG_GROUP */ ss, + /* BITMASK_GROUP_ID */ BITMASK_NOT_YET_ALLOCATED, + /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, + /* EXTRA_EXTENSION_FLAGS */ 0) + +DEFINE_RISCV_EXT( + /* NAME */ sstvecd, + /* UPPERCASE_NAME */ SSTVECD, + /* FULL_NAME */ "Stvec supports Direct mode", + /* DESC */ "", + /* URL */ , + /* DEP_EXTS */ ({"zicsr"}), + /* SUPPORTED_VERSIONS */ ({{1, 0}}), + /* FLAG_GROUP */ ss, + /* BITMASK_GROUP_ID */ BITMASK_NOT_YET_ALLOCATED, + /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, + /* EXTRA_EXTENSION_FLAGS */ 0) + DEFINE_RISCV_EXT( /* NAME */ ssstrict, - /* UPPERCAE_NAME */ SSSTRICT, + /* UPPERCASE_NAME */ SSSTRICT, /* FULL_NAME */ "ssstrict extension", /* DESC */ "", /* URL */ , @@ -1859,7 +1950,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ ssdbltrp, - /* UPPERCAE_NAME */ SSDBLTRP, + /* UPPERCASE_NAME */ SSDBLTRP, /* FULL_NAME */ "Double Trap Extensions", /* DESC */ "", /* URL */ , @@ -1870,9 +1961,22 @@ DEFINE_RISCV_EXT( /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, /* EXTRA_EXTENSION_FLAGS */ 0) +DEFINE_RISCV_EXT( + /* NAME */ ssu64xl, + /* UPPERCASE_NAME */ SSU64XL, + /* FULL_NAME */ "UXLEN=64 must be supported", + /* DESC */ "", + /* URL */ , + /* DEP_EXTS */ ({"zicsr"}), + /* SUPPORTED_VERSIONS */ ({{1, 0}}), + /* FLAG_GROUP */ ss, + /* BITMASK_GROUP_ID */ BITMASK_NOT_YET_ALLOCATED, + /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED, + /* EXTRA_EXTENSION_FLAGS */ 0) + DEFINE_RISCV_EXT( /* NAME */ supm, - /* UPPERCAE_NAME */ SUPM, + /* UPPERCASE_NAME */ SUPM, /* FULL_NAME */ "supm extension", /* DESC */ "", /* URL */ , @@ -1885,7 +1989,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ svinval, - /* UPPERCAE_NAME */ SVINVAL, + /* UPPERCASE_NAME */ SVINVAL, /* FULL_NAME */ "Fine-grained address-translation cache invalidation extension", /* DESC */ "", /* URL */ , @@ -1898,7 +2002,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ svnapot, - /* UPPERCAE_NAME */ SVNAPOT, + /* UPPERCASE_NAME */ SVNAPOT, /* FULL_NAME */ "NAPOT translation contiguity extension", /* DESC */ "", /* URL */ , @@ -1911,7 +2015,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ svpbmt, - /* UPPERCAE_NAME */ SVPBMT, + /* UPPERCASE_NAME */ SVPBMT, /* FULL_NAME */ "Page-based memory types extension", /* DESC */ "", /* URL */ , @@ -1924,7 +2028,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ svvptc, - /* UPPERCAE_NAME */ SVVPTC, + /* UPPERCASE_NAME */ SVVPTC, /* FULL_NAME */ "svvptc extension", /* DESC */ "", /* URL */ , @@ -1937,7 +2041,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ svadu, - /* UPPERCAE_NAME */ SVADU, + /* UPPERCASE_NAME */ SVADU, /* FULL_NAME */ "Hardware Updating of A/D Bits extension", /* DESC */ "", /* URL */ , @@ -1950,7 +2054,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ svade, - /* UPPERCAE_NAME */ SVADE, + /* UPPERCASE_NAME */ SVADE, /* FULL_NAME */ "Cause exception when hardware updating of A/D bits is disabled", /* DESC */ "", /* URL */ , @@ -1963,7 +2067,7 @@ DEFINE_RISCV_EXT( DEFINE_RISCV_EXT( /* NAME */ svbare, - /* UPPERCAE_NAME */ SVBARE, + /* UPPERCASE_NAME */ SVBARE, /* FULL_NAME */ "Satp mode bare is supported", /* DESC */ "", /* URL */ , @@ -1978,3 +2082,4 @@ DEFINE_RISCV_EXT( #include "riscv-ext-sifive.def" #include "riscv-ext-thead.def" #include "riscv-ext-ventana.def" +#include "riscv-ext-mips.def" diff --git a/gcc/config/riscv/riscv-ext.opt b/gcc/config/riscv/riscv-ext.opt index 3e5cbb34898e..26d6e683acd6 100644 --- a/gcc/config/riscv/riscv-ext.opt +++ b/gcc/config/riscv/riscv-ext.opt @@ -46,6 +46,9 @@ int riscv_sv_subext TargetVariable int riscv_xcv_subext +TargetVariable +int riscv_xmips_subext + TargetVariable int riscv_xsf_subext @@ -339,20 +342,30 @@ Mask(SMAIA) Var(riscv_sm_subext) Mask(SMCNTRPMF) Var(riscv_sm_subext) +Mask(SMCSRIND) Var(riscv_sm_subext) + Mask(SMEPMP) Var(riscv_sm_subext) Mask(SMMPM) Var(riscv_sm_subext) Mask(SMNPM) Var(riscv_sm_subext) +Mask(SMRNMI) Var(riscv_sm_subext) + Mask(SMSTATEEN) Var(riscv_sm_subext) Mask(SMDBLTRP) Var(riscv_sm_subext) Mask(SSAIA) Var(riscv_ss_subext) +Mask(SSCCPTR) Var(riscv_ss_subext) + Mask(SSCOFPMF) Var(riscv_ss_subext) +Mask(SSCOUNTERENW) Var(riscv_ss_subext) + +Mask(SSCSRIND) Var(riscv_ss_subext) + Mask(SSNPM) Var(riscv_ss_subext) Mask(SSPM) Var(riscv_ss_subext) @@ -361,10 +374,16 @@ Mask(SSSTATEEN) Var(riscv_ss_subext) Mask(SSTC) Var(riscv_ss_subext) +Mask(SSTVALA) Var(riscv_ss_subext) + +Mask(SSTVECD) Var(riscv_ss_subext) + Mask(SSSTRICT) Var(riscv_ss_subext) Mask(SSDBLTRP) Var(riscv_ss_subext) +Mask(SSU64XL) Var(riscv_ss_subext) + Mask(SUPM) Var(riscv_su_subext) Mask(SVINVAL) Var(riscv_sv_subext) @@ -429,3 +448,4 @@ Mask(XTHEADVECTOR) Var(riscv_xthead_subext) Mask(XVENTANACONDOPS) Var(riscv_xventana_subext) +Mask(XMIPSCMOV) Var(riscv_xmips_subext) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index a0331204479f..a41c4c299fac 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -137,6 +137,7 @@ extern void riscv_expand_usadd (rtx, rtx, rtx); extern void riscv_expand_ssadd (rtx, rtx, rtx); extern void riscv_expand_ussub (rtx, rtx, rtx); extern void riscv_expand_sssub (rtx, rtx, rtx); +extern void riscv_expand_usmul (rtx, rtx, rtx); extern void riscv_expand_ustrunc (rtx, rtx); extern void riscv_expand_sstrunc (rtx, rtx); extern int riscv_register_move_cost (machine_mode, reg_class_t, reg_class_t); @@ -603,6 +604,7 @@ void emit_vlmax_vsetvl (machine_mode, rtx); void emit_hard_vlmax_vsetvl (machine_mode, rtx); void emit_vlmax_insn (unsigned, unsigned, rtx *); void emit_nonvlmax_insn (unsigned, unsigned, rtx *, rtx); +void emit_avltype_insn (unsigned, unsigned, rtx *, avl_type, rtx = nullptr); void emit_vlmax_insn_lra (unsigned, unsigned, rtx *, rtx); enum vlmul_type get_vlmul (machine_mode); rtx get_vlmax_rtx (machine_mode); @@ -759,7 +761,7 @@ uint8_t get_sew (rtx_insn *); enum vlmul_type get_vlmul (rtx_insn *); int count_regno_occurrences (rtx_insn *, unsigned int); bool imm_avl_p (machine_mode); -bool can_be_broadcasted_p (rtx); +bool can_be_broadcast_p (rtx); bool gather_scatter_valid_offset_p (machine_mode); HOST_WIDE_INT estimated_poly_value (poly_int64, unsigned int); bool whole_reg_to_reg_move_p (rtx *, machine_mode, int); @@ -812,6 +814,7 @@ extern const char *th_output_move (rtx, rtx); extern bool th_print_operand_address (FILE *, machine_mode, rtx); #endif +extern bool strided_load_broadcast_p (void); extern bool riscv_use_divmod_expander (void); void riscv_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int); extern bool diff --git a/gcc/config/riscv/riscv-selftests.cc b/gcc/config/riscv/riscv-selftests.cc index 34d01ac76b75..9ca1ffee394f 100644 --- a/gcc/config/riscv/riscv-selftests.cc +++ b/gcc/config/riscv/riscv-selftests.cc @@ -342,9 +342,13 @@ run_broadcast_selftests (void) expand_vector_broadcast (mode, mem); \ insn = get_last_insn (); \ src = SET_SRC (PATTERN (insn)); \ - ASSERT_TRUE (MEM_P (XEXP (src, 0))); \ - ASSERT_TRUE ( \ - rtx_equal_p (src, gen_rtx_VEC_DUPLICATE (mode, XEXP (src, 0)))); \ + if (strided_load_broadcast_p ()) \ + { \ + ASSERT_TRUE (MEM_P (XEXP (src, 0))); \ + ASSERT_TRUE ( \ + rtx_equal_p (src, \ + gen_rtx_VEC_DUPLICATE (mode, XEXP (src, 0)))); \ + } \ end_sequence (); \ /* Test vmv.v.x or vfmv.v.f. */ \ start_sequence (); \ diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index a41317f322f7..242ac087764f 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -408,7 +408,7 @@ emit_vlmax_insn_lra (unsigned icode, unsigned insn_flags, rtx *ops, rtx vl) gcc_assert (!can_create_pseudo_p ()); machine_mode mode = GET_MODE (ops[0]); - if (imm_avl_p (mode)) + if (imm_avl_p (mode) && !TARGET_XTHEADVECTOR) { /* Even though VL is a real hardreg already allocated since it is post-RA now, we still gain benefits that we emit @@ -437,6 +437,26 @@ emit_nonvlmax_insn (unsigned icode, unsigned insn_flags, rtx *ops, rtx vl) e.emit_insn ((enum insn_code) icode, ops); } +/* Emit either a VLMAX insn or a non-VLMAX insn depending on TYPE. For a + non-VLMAX insn, the length must be specified in VL. */ + +void +emit_avltype_insn (unsigned icode, unsigned insn_flags, rtx *ops, + avl_type type, rtx vl) +{ + if (type != avl_type::VLMAX && vl != NULL_RTX) + { + insn_expander<RVV_INSN_OPERANDS_MAX> e (insn_flags, false); + e.set_vl (vl); + e.emit_insn ((enum insn_code) icode, ops); + } + else + { + insn_expander<RVV_INSN_OPERANDS_MAX> e (insn_flags, true); + e.emit_insn ((enum insn_code) icode, ops); + } +} + /* Return true if the vector duplicated by a super element which is the fusion of consecutive elements. @@ -1598,7 +1618,7 @@ expand_const_vector_interleaved_stepped_npatterns (rtx target, rtx src, shifted_vid = gen_reg_rtx (mode); rtx shift = gen_int_mode (1, Xmode); rtx shift_ops[] = {shifted_vid, vid, shift}; - emit_vlmax_insn (code_for_pred_scalar (ASHIFT, mode), BINARY_OP, + emit_vlmax_insn (code_for_pred_scalar (LSHIFTRT, mode), BINARY_OP, shift_ops); } else @@ -2144,21 +2164,40 @@ sew64_scalar_helper (rtx *operands, rtx *scalar_op, rtx vl, return false; } + bool avoid_strided_broadcast = false; if (CONST_INT_P (*scalar_op)) { if (maybe_gt (GET_MODE_SIZE (scalar_mode), GET_MODE_SIZE (Pmode))) - *scalar_op = force_const_mem (scalar_mode, *scalar_op); + { + if (strided_load_broadcast_p ()) + *scalar_op = force_const_mem (scalar_mode, *scalar_op); + else + avoid_strided_broadcast = true; + } else *scalar_op = force_reg (scalar_mode, *scalar_op); } rtx tmp = gen_reg_rtx (vector_mode); - rtx ops[] = {tmp, *scalar_op}; - if (type == VLMAX) - emit_vlmax_insn (code_for_pred_broadcast (vector_mode), UNARY_OP, ops); + if (!avoid_strided_broadcast) + { + rtx ops[] = {tmp, *scalar_op}; + emit_avltype_insn (code_for_pred_broadcast (vector_mode), UNARY_OP, ops, + type, vl); + } else - emit_nonvlmax_insn (code_for_pred_broadcast (vector_mode), UNARY_OP, ops, - vl); + { + /* Load scalar as V1DI and broadcast via vrgather.vi. */ + rtx tmp1 = gen_reg_rtx (V1DImode); + emit_move_insn (tmp1, lowpart_subreg (V1DImode, *scalar_op, + scalar_mode)); + tmp1 = lowpart_subreg (vector_mode, tmp1, V1DImode); + + rtx ops[] = {tmp, tmp1, CONST0_RTX (Pmode)}; + emit_vlmax_insn (code_for_pred_gather_scalar (vector_mode), + BINARY_OP, ops); + } + emit_vector_func (operands, tmp); return true; @@ -4723,7 +4762,7 @@ prepare_ternary_operands (rtx *ops) ops[4], ops[1], ops[6], ops[7], ops[9])); ops[5] = ops[4] = ops[0]; } - else + else if (VECTOR_MODE_P (GET_MODE (ops[2]))) { /* Swap the multiplication ops if the fallback value is the second of the two. */ @@ -4733,8 +4772,10 @@ prepare_ternary_operands (rtx *ops) /* TODO: ??? Maybe we could support splitting FMA (a, 4, b) into PLUS (ASHIFT (a, 2), b) according to uarchs. */ } - gcc_assert (rtx_equal_p (ops[5], RVV_VUNDEF (mode)) - || rtx_equal_p (ops[5], ops[2]) || rtx_equal_p (ops[5], ops[4])); + gcc_assert ( + rtx_equal_p (ops[5], RVV_VUNDEF (mode)) || rtx_equal_p (ops[5], ops[2]) + || (!VECTOR_MODE_P (GET_MODE (ops[2])) && rtx_equal_p (ops[5], ops[3])) + || rtx_equal_p (ops[5], ops[4])); } /* Expand VEC_MASK_LEN_{LOAD_LANES,STORE_LANES}. */ @@ -5537,6 +5578,12 @@ expand_vx_binary_vec_dup_vec (rtx op_0, rtx op_1, rtx op_2, case IOR: case XOR: case MULT: + case SMAX: + case UMAX: + case SMIN: + case UMIN: + case US_PLUS: + case SS_PLUS: icode = code_for_pred_scalar (code, mode); break; case MINUS: @@ -5568,6 +5615,17 @@ expand_vx_binary_vec_vec_dup (rtx op_0, rtx op_1, rtx op_2, case XOR: case MULT: case DIV: + case UDIV: + case MOD: + case UMOD: + case SMAX: + case UMAX: + case SMIN: + case UMIN: + case US_PLUS: + case US_MINUS: + case SS_PLUS: + case SS_MINUS: icode = code_for_pred_scalar (code, mode); break; default: @@ -5750,9 +5808,9 @@ count_regno_occurrences (rtx_insn *rinsn, unsigned int regno) return count; } -/* Return true if the OP can be directly broadcasted. */ +/* Return true if the OP can be directly broadcast. */ bool -can_be_broadcasted_p (rtx op) +can_be_broadcast_p (rtx op) { machine_mode mode = GET_MODE (op); /* We don't allow RA (register allocation) reload generate @@ -5764,7 +5822,8 @@ can_be_broadcasted_p (rtx op) return false; if (satisfies_constraint_K (op) || register_operand (op, mode) - || satisfies_constraint_Wdm (op) || rtx_equal_p (op, CONST0_RTX (mode))) + || (strided_load_broadcast_p () && satisfies_constraint_Wdm (op)) + || rtx_equal_p (op, CONST0_RTX (mode))) return true; return can_create_pseudo_p () && nonmemory_operand (op, mode); diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index f652a125dc35..8810af0d9ccb 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -4977,6 +4977,12 @@ registered_function::overloaded_hash () const for (unsigned int i = 0; i < argument_types.length (); i++) { type = argument_types[i]; + + /* If we're passed something entirely unreasonable, just ignore here. + We'll warn later anyway. */ + if (TREE_CODE_CLASS (TREE_CODE (type)) != tcc_type) + continue; + unsigned_p = POINTER_TYPE_P (type) ? TYPE_UNSIGNED (TREE_TYPE (type)) : TYPE_UNSIGNED (type); mode_p = POINTER_TYPE_P (type) ? TYPE_MODE (TREE_TYPE (type)) diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index 4891b6c95e85..4fe0ae6d97b7 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -100,31 +100,28 @@ using namespace riscv_vector; static void bitmap_union_of_preds_with_entry (sbitmap dst, sbitmap *src, basic_block b) { - unsigned int set_size = dst->size; - edge e; - unsigned ix; - - for (ix = 0; ix < EDGE_COUNT (b->preds); ix++) + /* Handle case with no predecessors (including ENTRY block). */ + if (EDGE_COUNT (b->preds) == 0) { - e = EDGE_PRED (b, ix); - bitmap_copy (dst, src[e->src->index]); - break; + bitmap_clear (dst); + return; } - if (ix == EDGE_COUNT (b->preds)) - bitmap_clear (dst); - else - for (ix++; ix < EDGE_COUNT (b->preds); ix++) - { - unsigned int i; - SBITMAP_ELT_TYPE *p, *r; - - e = EDGE_PRED (b, ix); - p = src[e->src->index]->elms; - r = dst->elms; - for (i = 0; i < set_size; i++) - *r++ |= *p++; - } + edge e; + edge_iterator ei; + /* Union remaining predecessors' bitmaps. */ + FOR_EACH_EDGE (e, ei, b->preds) + { + /* Initialize with first predecessor's bitmap. */ + if (ei.index == 0) + { + bitmap_copy (dst, src[e->src->index]); + continue; + } + + /* Perform bitmap OR operation element-wise. */ + bitmap_ior (dst, dst, src[e->src->index]); + } } /* Compute the reaching definition in and out based on the gen and KILL diff --git a/gcc/config/riscv/riscv-vsetvl.def b/gcc/config/riscv/riscv-vsetvl.def index d7a5ada772d0..0f999d2276d4 100644 --- a/gcc/config/riscv/riscv-vsetvl.def +++ b/gcc/config/riscv/riscv-vsetvl.def @@ -79,7 +79,7 @@ DEF_SEW_LMUL_RULE (sew_only, sew_only, sew_only, sew_eq_p, sew_eq_p, nop) DEF_SEW_LMUL_RULE (sew_only, ge_sew, sew_only, sew_ge_and_prev_sew_le_next_max_sew_p, sew_ge_p, nop) DEF_SEW_LMUL_RULE ( - sew_only, ratio_and_ge_sew, sew_lmul, + sew_only, ratio_and_ge_sew, ratio_and_ge_sew, sew_ge_and_prev_sew_le_next_max_sew_and_next_ratio_valid_for_prev_sew_p, always_false, modify_lmul_with_next_ratio) @@ -104,9 +104,9 @@ DEF_SEW_LMUL_RULE (ratio_and_ge_sew, sew_lmul, sew_lmul, DEF_SEW_LMUL_RULE (ratio_and_ge_sew, ratio_only, ratio_and_ge_sew, ratio_eq_p, ratio_eq_p, use_max_sew_and_lmul_with_prev_ratio) DEF_SEW_LMUL_RULE ( - ratio_and_ge_sew, sew_only, sew_only, + ratio_and_ge_sew, sew_only, ratio_and_ge_sew, sew_le_and_next_sew_le_prev_max_sew_and_prev_ratio_valid_for_next_sew_p, - always_false, use_next_sew_with_prev_ratio) + sew_eq_p, use_next_sew_with_prev_ratio) DEF_SEW_LMUL_RULE (ratio_and_ge_sew, ge_sew, ratio_and_ge_sew, max_sew_overlap_and_prev_ratio_valid_for_next_sew_p, sew_ge_p, use_max_sew_and_lmul_with_prev_ratio) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 3254ec9f9e13..3324819864a0 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -87,6 +87,10 @@ along with GCC; see the file COPYING3. If not see #include "riscv-vector-costs.h" #include "riscv-subset.h" +/* Target variants that support full conditional move. */ +#define TARGET_COND_MOV \ + (TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_XMIPSCMOV) + /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */ #define UNSPEC_ADDRESS_P(X) \ (GET_CODE (X) == UNSPEC \ @@ -107,6 +111,8 @@ along with GCC; see the file COPYING3. If not see /* True the mode switching has static frm, or false. */ #define STATIC_FRM_P(c) ((c)->machine->mode_sw_info.static_frm_p) +#define CFUN_IN_CALL(c) ((c)->machine->mode_sw_info.cfun_call) + /* True if we can use the instructions in the XTheadInt extension to handle interrupts, or false. */ #define TH_INT_INTERRUPT(c) \ @@ -176,10 +182,13 @@ struct GTY(()) mode_switching_info { mode instruction in the function or not. */ bool static_frm_p; + bool cfun_call; + mode_switching_info () { dynamic_frm = NULL_RTX; static_frm_p = false; + cfun_call = false; } }; @@ -278,6 +287,10 @@ enum riscv_fusion_pairs RISCV_FUSE_AUIPC_LD = (1 << 7), RISCV_FUSE_LDPREINCREMENT = (1 << 8), RISCV_FUSE_ALIGNED_STD = (1 << 9), + RISCV_FUSE_CACHE_ALIGNED_STD = (1 << 10), + RISCV_FUSE_BFEXT = (1 << 11), + RISCV_FUSE_EXPANDED_LD = (1 << 12), + RISCV_FUSE_B_ALUI = (1 << 13), }; /* Costs of various operations on the different architectures. */ @@ -297,6 +310,8 @@ struct riscv_tune_param bool vector_unaligned_access; bool use_divmod_expansion; bool overlap_op_by_pieces; + bool use_zero_stride_load; + bool speculative_sched_vsetvl; unsigned int fusible_ops; const struct cpu_vector_cost *vec_costs; const char *function_align; @@ -444,6 +459,30 @@ static const struct cpu_vector_cost generic_vector_cost = { &rvv_regmove_vector_cost, /* regmove */ }; +/* Costs to use when optimizing for generic. */ +static const struct riscv_tune_param generic_tune_info = { + {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */ + {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */ + {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */ + {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */ + {COSTS_N_INSNS (33), COSTS_N_INSNS (65)}, /* int_div */ + 1, /* issue_rate */ + 4, /* branch_cost */ + 5, /* memory_cost */ + 8, /* fmv_cost */ + true, /* slow_unaligned_access */ + false, /* vector_unaligned_access */ + false, /* use_divmod_expansion */ + false, /* overlap_op_by_pieces */ + true, /* use_zero_stride_load */ + false, /* speculative_sched_vsetvl */ + RISCV_FUSE_NOTHING, /* fusible_ops */ + NULL, /* vector cost */ + NULL, /* function_align */ + NULL, /* jump_align */ + NULL, /* loop_align */ +}; + /* Costs to use when optimizing for rocket. */ static const struct riscv_tune_param rocket_tune_info = { {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */ @@ -459,6 +498,8 @@ static const struct riscv_tune_param rocket_tune_info = { false, /* vector_unaligned_access */ false, /* use_divmod_expansion */ false, /* overlap_op_by_pieces */ + true, /* use_zero_stride_load */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_NOTHING, /* fusible_ops */ NULL, /* vector cost */ NULL, /* function_align */ @@ -481,6 +522,8 @@ static const struct riscv_tune_param sifive_7_tune_info = { false, /* vector_unaligned_access */ false, /* use_divmod_expansion */ false, /* overlap_op_by_pieces */ + true, /* use_zero_stride_load */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_NOTHING, /* fusible_ops */ NULL, /* vector cost */ NULL, /* function_align */ @@ -503,6 +546,8 @@ static const struct riscv_tune_param sifive_p400_tune_info = { false, /* vector_unaligned_access */ false, /* use_divmod_expansion */ false, /* overlap_op_by_pieces */ + true, /* use_zero_stride_load */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_LUI_ADDI | RISCV_FUSE_AUIPC_ADDI, /* fusible_ops */ &generic_vector_cost, /* vector cost */ NULL, /* function_align */ @@ -525,6 +570,8 @@ static const struct riscv_tune_param sifive_p600_tune_info = { false, /* vector_unaligned_access */ false, /* use_divmod_expansion */ false, /* overlap_op_by_pieces */ + true, /* use_zero_stride_load */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_LUI_ADDI | RISCV_FUSE_AUIPC_ADDI, /* fusible_ops */ &generic_vector_cost, /* vector cost */ NULL, /* function_align */ @@ -547,6 +594,8 @@ static const struct riscv_tune_param thead_c906_tune_info = { false, /* vector_unaligned_access */ false, /* use_divmod_expansion */ false, /* overlap_op_by_pieces */ + true, /* use_zero_stride_load */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_NOTHING, /* fusible_ops */ NULL, /* vector cost */ NULL, /* function_align */ @@ -569,6 +618,8 @@ static const struct riscv_tune_param xiangshan_nanhu_tune_info = { false, /* vector_unaligned_access */ false, /* use_divmod_expansion */ false, /* overlap_op_by_pieces */ + true, /* use_zero_stride_load */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_ZEXTW | RISCV_FUSE_ZEXTH, /* fusible_ops */ NULL, /* vector cost */ NULL, /* function_align */ @@ -591,6 +642,8 @@ static const struct riscv_tune_param generic_ooo_tune_info = { true, /* vector_unaligned_access */ false, /* use_divmod_expansion */ true, /* overlap_op_by_pieces */ + true, /* use_zero_stride_load */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_NOTHING, /* fusible_ops */ &generic_vector_cost, /* vector cost */ NULL, /* function_align */ @@ -613,6 +666,8 @@ static const struct riscv_tune_param tt_ascalon_d8_tune_info = { true, /* vector_unaligned_access */ true, /* use_divmod_expansion */ true, /* overlap_op_by_pieces */ + true, /* use_zero_stride_load */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_NOTHING, /* fusible_ops */ &generic_vector_cost, /* vector cost */ NULL, /* function_align */ @@ -635,6 +690,8 @@ static const struct riscv_tune_param optimize_size_tune_info = { false, /* vector_unaligned_access */ false, /* use_divmod_expansion */ false, /* overlap_op_by_pieces */ + true, /* use_zero_stride_load */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_NOTHING, /* fusible_ops */ NULL, /* vector cost */ NULL, /* function_align */ @@ -657,6 +714,8 @@ static const struct riscv_tune_param mips_p8700_tune_info = { false, /* vector_unaligned_access */ true, /* use_divmod_expansion */ false, /* overlap_op_by_pieces */ + true, /* use_zero_stride_load */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_NOTHING, /* fusible_ops */ NULL, /* vector cost */ NULL, /* function_align */ @@ -798,6 +857,16 @@ void riscv_frame_info::reset(void) arg_pointer_offset = 0; } +/* Check if the mode is twice the size of the XLEN mode. */ + +static bool +riscv_2x_xlen_mode_p (machine_mode mode) +{ + poly_int64 mode_size = GET_MODE_SIZE (mode); + return mode_size.is_constant () + && (mode_size.to_constant () == UNITS_PER_WORD * 2); +} + /* Implement TARGET_MIN_ARITHMETIC_PRECISION. */ static unsigned int @@ -1029,16 +1098,16 @@ riscv_build_integer_1 (struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS], /* Now iterate over the bits we want to clear until the cost is too high or we're done. */ nval = value ^ HOST_WIDE_INT_C (-1); - nval &= HOST_WIDE_INT_C (~0x7fffffff); + nval &= ~HOST_WIDE_INT_C (0x7fffffff); while (nval && alt_cost < cost) { HOST_WIDE_INT bit = ctz_hwi (nval); alt_codes[alt_cost].code = AND; - alt_codes[alt_cost].value = ~(1UL << bit); + alt_codes[alt_cost].value = ~(HOST_WIDE_INT_UC (1) << bit); alt_codes[alt_cost].use_uw = false; alt_codes[alt_cost].save_temporary = false; alt_cost++; - nval &= ~(1UL << bit); + nval &= ~(HOST_WIDE_INT_UC (1) << bit); } if (nval == 0 && alt_cost <= cost) @@ -3762,10 +3831,8 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src) return true; } - if (TARGET_ZILSD - && (GET_MODE_UNIT_SIZE (mode) == (UNITS_PER_WORD * 2)) - && ((REG_P (dest) && MEM_P (src)) - || (MEM_P (dest) && REG_P (src))) + if (TARGET_ZILSD && riscv_2x_xlen_mode_p (mode) + && ((REG_P (dest) && MEM_P (src)) || (MEM_P (dest) && REG_P (src))) && can_create_pseudo_p ()) { rtx reg = REG_P (dest) ? dest : src; @@ -3852,7 +3919,7 @@ static int riscv_binary_cost (rtx x, int single_insns, int double_insns) { if (!riscv_v_ext_mode_p (GET_MODE (x)) - && GET_MODE_SIZE (GET_MODE (x)).to_constant () == UNITS_PER_WORD * 2) + && riscv_2x_xlen_mode_p (GET_MODE (x))) return COSTS_N_INSNS (double_insns); return COSTS_N_INSNS (single_insns); } @@ -3900,12 +3967,28 @@ get_vector_binary_rtx_cost (rtx x, int scalar2vr_cost) { gcc_assert (riscv_v_ext_mode_p (GET_MODE (x))); - rtx op_0 = XEXP (x, 0); - rtx op_1 = XEXP (x, 1); + rtx neg; + rtx op_0; + rtx op_1; + + if (GET_CODE (x) == UNSPEC) + { + op_0 = XVECEXP (x, 0, 0); + op_1 = XVECEXP (x, 0, 1); + } + else + { + op_0 = XEXP (x, 0); + op_1 = XEXP (x, 1); + } if (GET_CODE (op_0) == VEC_DUPLICATE || GET_CODE (op_1) == VEC_DUPLICATE) return (scalar2vr_cost + 1) * COSTS_N_INSNS (1); + else if (GET_CODE (neg = op_0) == NEG + && (GET_CODE (op_1) == VEC_DUPLICATE + || GET_CODE (XEXP (neg, 0)) == VEC_DUPLICATE)) + return (scalar2vr_cost + 1) * COSTS_N_INSNS (1); else return COSTS_N_INSNS (1); } @@ -3943,8 +4026,29 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN switch (GET_CODE (op)) { case DIV: + case UDIV: + case MOD: + case UMOD: + case US_PLUS: + case US_MINUS: + case SS_PLUS: + case SS_MINUS: *total = get_vector_binary_rtx_cost (op, scalar2vr_cost); break; + case UNSPEC: + { + switch (XINT (op, 1)) + { + case UNSPEC_VAADDU: + *total + = get_vector_binary_rtx_cost (op, scalar2vr_cost); + break; + default: + *total = COSTS_N_INSNS (1); + break; + } + } + break; default: *total = COSTS_N_INSNS (1); break; @@ -3957,6 +4061,10 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN case IOR: case XOR: case MULT: + case SMAX: + case UMAX: + case SMIN: + case UMIN: { rtx op; rtx op_0 = XEXP (x, 0); @@ -3999,10 +4107,41 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN *total = COSTS_N_INSNS (1); return true; } + + /* Register move for XLEN * 2. */ + if (TARGET_ZILSD + && register_operand (SET_SRC (x), GET_MODE (SET_SRC (x))) + && riscv_2x_xlen_mode_p (mode)) + { + /* We still need two instruction for move with ZILSD, + but let minus one cost to let subreg split don't. + TODO: Add riscv_tune_param for this. */ + *total = COSTS_N_INSNS (2) - 1; + return true; + } + + /* Load for XLEN * 2. */ + if (TARGET_ZILSD && MEM_P (SET_SRC (x)) + && riscv_2x_xlen_mode_p (mode)) + { + /* TODO: Add riscv_tune_param for this. */ + *total = COSTS_N_INSNS (1); + return true; + } + riscv_rtx_costs (SET_SRC (x), mode, SET, opno, total, speed); return true; } + /* Store for XLEN * 2. */ + if (TARGET_ZILSD && MEM_P (SET_DEST (x)) && REG_P (SET_SRC (x)) + && riscv_2x_xlen_mode_p (mode)) + { + /* TODO: Add riscv_tune_param for this. */ + *total = COSTS_N_INSNS (1); + return true; + } + /* Otherwise return FALSE indicating we should recurse into both the SET_DEST and SET_SRC combining the cost of both. */ return false; @@ -4062,7 +4201,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN return false; case IF_THEN_ELSE: - if ((TARGET_SFB_ALU || TARGET_XTHEADCONDMOV) + if (TARGET_COND_MOV && reg_or_0_operand (XEXP (x, 1), mode) && sfb_alu_operand (XEXP (x, 2), mode) && comparison_operator (XEXP (x, 0), VOIDmode)) @@ -4602,16 +4741,14 @@ riscv_noce_conversion_profitable_p (rtx_insn *seq, rtx dest = SET_DEST (x); - /* Do something similar for the moves that are likely to + /* Do something similar for the moves that are likely to turn into NOP moves by the time the register allocator is - done. These are also side effects of how our sCC expanders - work. We'll want to check and update LAST_DEST here too. */ - if (last_dest - && REG_P (dest) + done. We don't require src to be something set in this + sequence, just a promoted SUBREG. */ + if (REG_P (dest) && GET_MODE (dest) == SImode && SUBREG_P (src) - && SUBREG_PROMOTED_VAR_P (src) - && REGNO (SUBREG_REG (src)) == REGNO (last_dest)) + && SUBREG_PROMOTED_VAR_P (src)) { riscv_if_info.original_cost += COSTS_N_INSNS (1); riscv_if_info.max_seq_cost += COSTS_N_INSNS (1); @@ -5382,40 +5519,137 @@ riscv_expand_conditional_branch (rtx label, rtx_code code, rtx op0, rtx op1) emit_jump_insn (gen_condjump (condition, label)); } +/* canonicalization of the comparands. */ +void +canonicalize_comparands (rtx_code code, rtx *op0, rtx *op1) +{ + /* An integer comparison must be comparing WORD_MODE objects. + Extend the comparison arguments as necessary. */ + if ((INTEGRAL_MODE_P (GET_MODE (*op0)) && GET_MODE (*op0) != word_mode) + || (INTEGRAL_MODE_P (GET_MODE (*op1)) && GET_MODE (*op1) != word_mode)) + riscv_extend_comparands (code, op0, op1); + + /* We might have been handed back a SUBREG. Just to make things + easy, force it into a REG. */ + if (!REG_P (*op0) && !CONST_INT_P (*op0)) + *op0 = force_reg (word_mode, *op0); + if (!REG_P (*op1) && !CONST_INT_P (*op1)) + *op1 = force_reg (word_mode, *op1); +} + +/* Emit target specific conditional move like TARGET_XMIPSCMOV etc. */ +bool +riscv_target_conditional_move (rtx dest, rtx op0, rtx op1, rtx_code code, + rtx cons, rtx alt) +{ + machine_mode dst_mode = GET_MODE (dest); + rtx target; + + /* force the operands to the register. */ + cons = force_reg (dst_mode, cons); + alt = force_reg (dst_mode, alt); + + if (TARGET_XMIPSCMOV) + { + if (code == EQ || code == NE) + { + op0 = riscv_zero_if_equal (op0, op1); + op1 = const0_rtx; + } + else + { + target = gen_reg_rtx (GET_MODE (op0)); + riscv_emit_int_order_test (code, 0, target, op0, op1); + op0 = target; + op1 = const0_rtx; + code = NE; + } + riscv_emit_int_compare (&code, &op0, &op1); + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); + emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (dst_mode, + cond, cons, alt))); + return true; + } + /* TARGET_SFB_ALU || TARGET_XTHEADCONDMOV. */ + else + { + riscv_emit_int_compare (&code, &op0, &op1, !TARGET_SFB_ALU); + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); + emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (dst_mode, cond, + cons, alt))); + return true; + } +} + /* Emit a cond move: If OP holds, move CONS to DEST; else move ALT to DEST. Return 0 if expansion failed. */ bool riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt) { - machine_mode mode = GET_MODE (dest); + machine_mode dst_mode = GET_MODE (dest); + machine_mode cond_mode = GET_MODE (dest); rtx_code code = GET_CODE (op); rtx op0 = XEXP (op, 0); rtx op1 = XEXP (op, 1); + /* General note. This is called from the conditional move + expander. That simplifies the cases we need to worry about + as we know the destination will have the same mode as the + true/false arms. Furthermore we know that mode will be + DI/SI for rv64 or SI for rv32. */ + + /* For some tests, we can easily construct a 0, -1 value + which can then be used to synthesize more efficient + sequences that don't use zicond. */ + if ((code == LT || code == GE) + && (REG_P (op0) || SUBREG_P (op0)) + && op1 == CONST0_RTX (GET_MODE (op0))) + { + /* The code to expand signed division by a power of 2 uses a + conditional add by 2^n-1 idiom. It can be more efficiently + synthesized without zicond using srai+srli+add. + + But we don't see the constants here. Just a conditional move + with registers as the true/false values. So this is a little + over-aggressive and can result in a few missed if-conversions. */ + if ((REG_P (cons) || SUBREG_P (cons)) + && (REG_P (alt) || SUBREG_P (alt))) + return false; + + /* If one value is a nonzero constant and the other value is + not a constant, then avoid zicond as more efficient sequences + using the splatted sign bit are often possible. */ + if (CONST_INT_P (alt) + && alt != CONST0_RTX (dst_mode) + && !CONST_INT_P (cons)) + return false; + + if (CONST_INT_P (cons) + && cons != CONST0_RTX (dst_mode) + && !CONST_INT_P (alt)) + return false; + + /* If we need more special cases, add them here. */ + } + + if (((TARGET_ZICOND_LIKE - || (arith_operand (cons, mode) && arith_operand (alt, mode))) - && (GET_MODE_CLASS (mode) == MODE_INT)) - || TARGET_SFB_ALU || TARGET_XTHEADCONDMOV) + || (arith_operand (cons, dst_mode) && arith_operand (alt, dst_mode))) + && GET_MODE_CLASS (dst_mode) == MODE_INT + && GET_MODE_CLASS (cond_mode) == MODE_INT) + || TARGET_COND_MOV) { machine_mode mode0 = GET_MODE (op0); - machine_mode mode1 = GET_MODE (op1); - - /* An integer comparison must be comparing WORD_MODE objects. We - must enforce that so that we don't strip away a sign_extension - thinking it is unnecessary. We might consider using - riscv_extend_operands if they are not already properly extended. */ - if ((INTEGRAL_MODE_P (mode0) && mode0 != word_mode) - || (INTEGRAL_MODE_P (mode1) && mode1 != word_mode)) - return false; - /* In the fallback generic case use MODE rather than WORD_MODE for - the output of the SCC instruction, to match the mode of the NEG + canonicalize_comparands (code,&op0,&op1); + + /* In the fallback generic case use DST_MODE rather than WORD_MODE + for the output of the SCC instruction, to match the mode of the NEG operation below. The output of SCC is 0 or 1 boolean, so it is valid for input in any scalar integer mode. */ - rtx tmp = gen_reg_rtx ((TARGET_ZICOND_LIKE - || TARGET_SFB_ALU || TARGET_XTHEADCONDMOV) - ? word_mode : mode); + rtx tmp = gen_reg_rtx ((TARGET_ZICOND_LIKE || TARGET_COND_MOV) + ? word_mode : dst_mode); bool invert = false; /* Canonicalize the comparison. It must be an equality comparison @@ -5444,41 +5678,28 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt) else return false; - op = gen_rtx_fmt_ee (invert ? EQ : NE, mode, tmp, const0_rtx); + op = gen_rtx_fmt_ee (invert ? EQ : NE, cond_mode, tmp, const0_rtx); /* We've generated a new comparison. Update the local variables. */ code = GET_CODE (op); op0 = XEXP (op, 0); op1 = XEXP (op, 1); } - else if (!TARGET_ZICOND_LIKE && !TARGET_SFB_ALU && !TARGET_XTHEADCONDMOV) + else if (!TARGET_ZICOND_LIKE && !TARGET_COND_MOV) riscv_expand_int_scc (tmp, code, op0, op1, &invert); - if (TARGET_SFB_ALU || TARGET_XTHEADCONDMOV) - { - riscv_emit_int_compare (&code, &op0, &op1, !TARGET_SFB_ALU); - rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); + if (TARGET_COND_MOV) + return riscv_target_conditional_move (dest, op0, op1, code, cons, alt); - /* The expander is a bit loose in its specification of the true - arm of the conditional move. That allows us to support more - cases for extensions which are more general than SFB. But - does mean we need to force CONS into a register at this point. */ - cons = force_reg (mode, cons); - /* With XTheadCondMov we need to force ALT into a register too. */ - alt = force_reg (mode, alt); - emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode, cond, - cons, alt))); - return true; - } else if (!TARGET_ZICOND_LIKE) { if (invert) std::swap (cons, alt); - rtx reg1 = gen_reg_rtx (mode); - rtx reg2 = gen_reg_rtx (mode); - rtx reg3 = gen_reg_rtx (mode); - rtx reg4 = gen_reg_rtx (mode); + rtx reg1 = gen_reg_rtx (dst_mode); + rtx reg2 = gen_reg_rtx (dst_mode); + rtx reg3 = gen_reg_rtx (dst_mode); + rtx reg4 = gen_reg_rtx (dst_mode); riscv_emit_unary (NEG, reg1, tmp); riscv_emit_binary (AND, reg2, reg1, cons); @@ -5488,48 +5709,52 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt) return true; } /* 0, reg or 0, imm */ - else if (cons == CONST0_RTX (mode) - && (REG_P (alt) - || (CONST_INT_P (alt) && alt != CONST0_RTX (mode)))) + else if (cons == CONST0_RTX (dst_mode) + && ((REG_P (alt) || SUBREG_P (alt)) + || (CONST_INT_P (alt) && alt != CONST0_RTX (dst_mode)))) { riscv_emit_int_compare (&code, &op0, &op1, true); rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); - alt = force_reg (mode, alt); + alt = force_reg (dst_mode, alt); emit_insn (gen_rtx_SET (dest, - gen_rtx_IF_THEN_ELSE (mode, cond, + gen_rtx_IF_THEN_ELSE (dst_mode, cond, cons, alt))); return true; } /* imm, imm */ - else if (CONST_INT_P (cons) && cons != CONST0_RTX (mode) - && CONST_INT_P (alt) && alt != CONST0_RTX (mode)) + else if (CONST_INT_P (cons) && cons != CONST0_RTX (dst_mode) + && CONST_INT_P (alt) && alt != CONST0_RTX (dst_mode)) { riscv_emit_int_compare (&code, &op0, &op1, true); rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); HOST_WIDE_INT t = INTVAL (alt) - INTVAL (cons); - alt = force_reg (mode, gen_int_mode (t, mode)); + alt = force_reg (dst_mode, gen_int_mode (t, dst_mode)); emit_insn (gen_rtx_SET (dest, - gen_rtx_IF_THEN_ELSE (mode, cond, - CONST0_RTX (mode), + gen_rtx_IF_THEN_ELSE (dst_mode, cond, + CONST0_RTX (dst_mode), alt))); /* CONS might not fit into a signed 12 bit immediate suitable for an addi instruction. If that's the case, force it into a register. */ if (!SMALL_OPERAND (INTVAL (cons))) - cons = force_reg (mode, cons); + cons = force_reg (dst_mode, cons); riscv_emit_binary (PLUS, dest, dest, cons); return true; } /* imm, reg */ - else if (CONST_INT_P (cons) && cons != CONST0_RTX (mode) && REG_P (alt)) + else if (CONST_INT_P (cons) + && cons != CONST0_RTX (dst_mode) + && (REG_P (alt) || SUBREG_P (alt))) { /* Optimize for register value of 0. */ - if (code == NE && rtx_equal_p (op0, alt) && op1 == CONST0_RTX (mode)) + if (code == NE + && rtx_equal_p (op0, alt) + && op1 == CONST0_RTX (dst_mode)) { rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); - cons = force_reg (mode, cons); + cons = force_reg (dst_mode, cons); emit_insn (gen_rtx_SET (dest, - gen_rtx_IF_THEN_ELSE (mode, cond, + gen_rtx_IF_THEN_ELSE (dst_mode, cond, cons, alt))); return true; } @@ -5537,47 +5762,51 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt) riscv_emit_int_compare (&code, &op0, &op1, true); rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); - rtx temp1 = gen_reg_rtx (mode); - rtx temp2 = gen_int_mode (-1 * INTVAL (cons), mode); + rtx temp1 = gen_reg_rtx (dst_mode); + rtx temp2 = gen_int_mode (-1 * INTVAL (cons), dst_mode); /* TEMP2 and/or CONS might not fit into a signed 12 bit immediate suitable for an addi instruction. If that's the case, force it into a register. */ if (!SMALL_OPERAND (INTVAL (temp2))) - temp2 = force_reg (mode, temp2); + temp2 = force_reg (dst_mode, temp2); if (!SMALL_OPERAND (INTVAL (cons))) - cons = force_reg (mode, cons); + cons = force_reg (dst_mode, cons); riscv_emit_binary (PLUS, temp1, alt, temp2); emit_insn (gen_rtx_SET (dest, - gen_rtx_IF_THEN_ELSE (mode, cond, - CONST0_RTX (mode), + gen_rtx_IF_THEN_ELSE (dst_mode, cond, + CONST0_RTX (dst_mode), temp1))); riscv_emit_binary (PLUS, dest, dest, cons); return true; } /* reg, 0 or imm, 0 */ - else if ((REG_P (cons) - || (CONST_INT_P (cons) && cons != CONST0_RTX (mode))) - && alt == CONST0_RTX (mode)) + else if (((REG_P (cons) || SUBREG_P (cons)) + || (CONST_INT_P (cons) && cons != CONST0_RTX (dst_mode))) + && alt == CONST0_RTX (dst_mode)) { riscv_emit_int_compare (&code, &op0, &op1, true); rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); - cons = force_reg (mode, cons); - emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode, cond, + cons = force_reg (dst_mode, cons); + emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (dst_mode, cond, cons, alt))); return true; } /* reg, imm */ - else if (REG_P (cons) && CONST_INT_P (alt) && alt != CONST0_RTX (mode)) + else if ((REG_P (cons) || (SUBREG_P (cons))) + && CONST_INT_P (alt) + && alt != CONST0_RTX (dst_mode)) { /* Optimize for register value of 0. */ - if (code == EQ && rtx_equal_p (op0, cons) && op1 == CONST0_RTX (mode)) + if (code == EQ + && rtx_equal_p (op0, cons) + && op1 == CONST0_RTX (dst_mode)) { rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); - alt = force_reg (mode, alt); + alt = force_reg (dst_mode, alt); emit_insn (gen_rtx_SET (dest, - gen_rtx_IF_THEN_ELSE (mode, cond, + gen_rtx_IF_THEN_ELSE (dst_mode, cond, cons, alt))); return true; } @@ -5585,53 +5814,54 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt) riscv_emit_int_compare (&code, &op0, &op1, true); rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); - rtx temp1 = gen_reg_rtx (mode); - rtx temp2 = gen_int_mode (-1 * INTVAL (alt), mode); + rtx temp1 = gen_reg_rtx (dst_mode); + rtx temp2 = gen_int_mode (-1 * INTVAL (alt), dst_mode); /* TEMP2 and/or ALT might not fit into a signed 12 bit immediate suitable for an addi instruction. If that's the case, force it into a register. */ if (!SMALL_OPERAND (INTVAL (temp2))) - temp2 = force_reg (mode, temp2); + temp2 = force_reg (dst_mode, temp2); if (!SMALL_OPERAND (INTVAL (alt))) - alt = force_reg (mode, alt); + alt = force_reg (dst_mode, alt); riscv_emit_binary (PLUS, temp1, cons, temp2); emit_insn (gen_rtx_SET (dest, - gen_rtx_IF_THEN_ELSE (mode, cond, + gen_rtx_IF_THEN_ELSE (dst_mode, cond, temp1, - CONST0_RTX (mode)))); + CONST0_RTX (dst_mode)))); riscv_emit_binary (PLUS, dest, dest, alt); return true; } /* reg, reg */ - else if (REG_P (cons) && REG_P (alt)) + else if ((REG_P (cons) || SUBREG_P (cons)) + && (REG_P (alt) || SUBREG_P (alt))) { if (((code == EQ && rtx_equal_p (cons, op0)) || (code == NE && rtx_equal_p (alt, op0))) - && op1 == CONST0_RTX (mode)) + && op1 == CONST0_RTX (dst_mode)) { rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); - alt = force_reg (mode, alt); + alt = force_reg (dst_mode, alt); emit_insn (gen_rtx_SET (dest, - gen_rtx_IF_THEN_ELSE (mode, cond, + gen_rtx_IF_THEN_ELSE (dst_mode, cond, cons, alt))); return true; } - rtx reg1 = gen_reg_rtx (mode); - rtx reg2 = gen_reg_rtx (mode); + rtx reg1 = gen_reg_rtx (dst_mode); + rtx reg2 = gen_reg_rtx (dst_mode); riscv_emit_int_compare (&code, &op0, &op1, true); rtx cond1 = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); rtx cond2 = gen_rtx_fmt_ee (code == NE ? EQ : NE, GET_MODE (op0), op0, op1); emit_insn (gen_rtx_SET (reg2, - gen_rtx_IF_THEN_ELSE (mode, cond2, - CONST0_RTX (mode), + gen_rtx_IF_THEN_ELSE (dst_mode, cond2, + CONST0_RTX (dst_mode), cons))); emit_insn (gen_rtx_SET (reg1, - gen_rtx_IF_THEN_ELSE (mode, cond1, - CONST0_RTX (mode), + gen_rtx_IF_THEN_ELSE (dst_mode, cond1, + CONST0_RTX (dst_mode), alt))); riscv_emit_binary (PLUS, dest, reg1, reg2); return true; @@ -8835,12 +9065,20 @@ riscv_allocate_and_probe_stack_space (rtx temp1, HOST_WIDE_INT size) temp2 = riscv_force_temporary (temp2, gen_int_mode (rounded_size, Pmode)); insn = emit_insn (gen_sub3_insn (temp2, stack_pointer_rtx, temp2)); + /* The size does not represent actual stack pointer address shift + from the top of the frame, as it might be lowered before. + To consider the correct SP addresses for the CFA notes, it is needed + to correct them with the initial offset value. */ + HOST_WIDE_INT initial_cfa_offset + = cfun->machine->frame.total_size.to_constant () - size; + if (!frame_pointer_needed) { /* We want the CFA independent of the stack pointer for the duration of the loop. */ add_reg_note (insn, REG_CFA_DEF_CFA, - plus_constant (Pmode, temp1, rounded_size)); + plus_constant (Pmode, temp2, + initial_cfa_offset + rounded_size)); RTX_FRAME_RELATED_P (insn) = 1; } @@ -8853,7 +9091,8 @@ riscv_allocate_and_probe_stack_space (rtx temp1, HOST_WIDE_INT size) { insn = get_last_insn (); add_reg_note (insn, REG_CFA_DEF_CFA, - plus_constant (Pmode, stack_pointer_rtx, rounded_size)); + plus_constant (Pmode, stack_pointer_rtx, + initial_cfa_offset + rounded_size)); RTX_FRAME_RELATED_P (insn) = 1; } @@ -9896,9 +10135,7 @@ riscv_hard_regno_mode_ok (unsigned int regno, machine_mode mode) return false; /* Zilsd require load/store with even-odd reg pair. */ - if (TARGET_ZILSD - && (GET_MODE_UNIT_SIZE (mode) == (UNITS_PER_WORD * 2)) - && ((regno % 2) != 0)) + if (TARGET_ZILSD && riscv_2x_xlen_mode_p (mode) && ((regno % 2) != 0)) return false; if (!GP_REG_P (regno + nregs - 1)) @@ -10053,23 +10290,114 @@ riscv_fusion_enabled_p(enum riscv_fusion_pairs op) return tune_param->fusible_ops & op; } +/* Matches an add: + (set (reg:DI rd) (plus:SI (reg:SI rs1) (reg:SI rs2))) */ + +static bool +riscv_set_is_add (rtx set) +{ + return (GET_CODE (SET_SRC (set)) == PLUS + && REG_P (XEXP (SET_SRC (set), 0)) + && REG_P (XEXP (SET_SRC (set), 1)) + && REG_P (SET_DEST (set))); +} + +/* Matches an addi: + (set (reg:DI rd) (plus:SI (reg:SI rs1) (const_int imm))) */ + +static bool +riscv_set_is_addi (rtx set) +{ + return (GET_CODE (SET_SRC (set)) == PLUS + && REG_P (XEXP (SET_SRC (set), 0)) + && CONST_INT_P (XEXP (SET_SRC (set), 1)) + && REG_P (SET_DEST (set))); +} + +/* Matches an add.uw: + (set (reg:DI rd) + (plus:DI (zero_extend:DI (reg:SI rs1)) (reg:DI rs2))) */ + +static bool +riscv_set_is_adduw (rtx set) +{ + return (GET_CODE (SET_SRC (set)) == PLUS + && GET_CODE (XEXP (SET_SRC (set), 0)) == ZERO_EXTEND + && REG_P (XEXP (XEXP (SET_SRC (set), 0), 0)) + && REG_P (XEXP (SET_SRC (set), 1)) + && REG_P (SET_DEST (set))); +} + +/* Matches a shNadd: + (set (reg:DI rd) + (plus:DI (ashift:DI (reg:DI rs1) (const_int N)) (reg:DI rS2)) */ + +static bool +riscv_set_is_shNadd (rtx set) +{ + return (GET_CODE (SET_SRC (set)) == PLUS + && GET_CODE (XEXP (SET_SRC (set), 0)) == ASHIFT + && REG_P (XEXP (XEXP (SET_SRC (set), 0), 0)) + && CONST_INT_P (XEXP (XEXP (SET_SRC (set), 0), 1)) + && (INTVAL (XEXP (XEXP (SET_SRC (set), 0), 1)) == 1 + || INTVAL (XEXP (XEXP (SET_SRC (set), 0), 1)) == 2 + || INTVAL (XEXP (XEXP (SET_SRC (set), 0), 1)) == 3) + && REG_P (SET_DEST (set))); +} + +/* Matches a shNadd.uw: + (set (reg:DI rd) + (plus:DI (and:DI (ashift:DI (reg:DI rs1) (const_int N)) + (const_int N)) + (reg:DI rs2)) */ + +static bool +riscv_set_is_shNadduw (rtx set) +{ + return (GET_CODE (SET_SRC (set)) == PLUS + && GET_CODE (XEXP (SET_SRC (set), 0)) == AND + && GET_CODE (XEXP (XEXP (SET_SRC (set), 0), 0)) == ASHIFT + && REG_P (XEXP (XEXP (XEXP (SET_SRC (set), 0), 0), 0)) + && CONST_INT_P (XEXP (XEXP (XEXP (SET_SRC (set), 0), 0), 1)) + && (INTVAL (XEXP (XEXP (XEXP (SET_SRC (set), 0), 0), 1)) == 1 + || INTVAL (XEXP (XEXP (XEXP (SET_SRC (set), 0), 0), 1)) == 2 + || INTVAL (XEXP (XEXP (XEXP (SET_SRC (set), 0), 0), 1)) == 3) + && REG_P (SET_DEST (set))); +} + /* Implement TARGET_SCHED_MACRO_FUSION_PAIR_P. Return true if PREV and CURR should be kept together during scheduling. */ static bool riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr) { + /* If fusion is not enabled, then there's nothing to do. */ + if (!riscv_macro_fusion_p ()) + return false; + + /* If PREV is already marked as fused, then we can't fuse CURR with PREV + and if we were to fuse them we'd end up with a blob of insns that + essentially are an atomic unit which is bad for scheduling. */ + if (SCHED_GROUP_P (prev)) + return false; + rtx prev_set = single_set (prev); rtx curr_set = single_set (curr); /* prev and curr are simple SET insns i.e. no flag setting or branching. */ bool simple_sets_p = prev_set && curr_set && !any_condjump_p (curr); + bool sched1 = can_create_pseudo_p (); - if (!riscv_macro_fusion_p ()) - return false; + unsigned int prev_dest_regno = (prev_set && REG_P (SET_DEST (prev_set)) + ? REGNO (SET_DEST (prev_set)) + : FIRST_PSEUDO_REGISTER); + unsigned int curr_dest_regno = (curr_set && REG_P (SET_DEST (curr_set)) + ? REGNO (SET_DEST (curr_set)) + : FIRST_PSEUDO_REGISTER); if (simple_sets_p && (riscv_fusion_enabled_p (RISCV_FUSE_ZEXTW) - || riscv_fusion_enabled_p (RISCV_FUSE_ZEXTWS))) + || riscv_fusion_enabled_p (RISCV_FUSE_ZEXTWS)) + && (sched1 || prev_dest_regno == curr_dest_regno)) { /* We are trying to match the following: prev (slli) == (set (reg:DI rD) @@ -10083,19 +10411,23 @@ riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr) && GET_CODE (SET_SRC (curr_set)) == LSHIFTRT && REG_P (SET_DEST (prev_set)) && REG_P (SET_DEST (curr_set)) - && REGNO (SET_DEST (prev_set)) == REGNO (SET_DEST (curr_set)) - && REGNO (XEXP (SET_SRC (curr_set), 0)) == REGNO(SET_DEST (curr_set)) + && REGNO (XEXP (SET_SRC (curr_set), 0)) == curr_dest_regno && CONST_INT_P (XEXP (SET_SRC (prev_set), 1)) && CONST_INT_P (XEXP (SET_SRC (curr_set), 1)) && INTVAL (XEXP (SET_SRC (prev_set), 1)) == 32 - && (( INTVAL (XEXP (SET_SRC (curr_set), 1)) == 32 - && riscv_fusion_enabled_p(RISCV_FUSE_ZEXTW) ) - || ( INTVAL (XEXP (SET_SRC (curr_set), 1)) < 32 - && riscv_fusion_enabled_p(RISCV_FUSE_ZEXTWS)))) - return true; + && ((INTVAL (XEXP (SET_SRC (curr_set), 1)) == 32 + && riscv_fusion_enabled_p (RISCV_FUSE_ZEXTW) ) + || (INTVAL (XEXP (SET_SRC (curr_set), 1)) < 32 + && riscv_fusion_enabled_p (RISCV_FUSE_ZEXTWS)))) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_ZEXTWS\n"); + return true; + } } - if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_ZEXTH)) + if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_ZEXTH) + && (sched1 || prev_dest_regno == curr_dest_regno)) { /* We are trying to match the following: prev (slli) == (set (reg:DI rD) @@ -10107,16 +10439,20 @@ riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr) && GET_CODE (SET_SRC (curr_set)) == LSHIFTRT && REG_P (SET_DEST (prev_set)) && REG_P (SET_DEST (curr_set)) - && REGNO (SET_DEST (prev_set)) == REGNO (SET_DEST (curr_set)) - && REGNO (XEXP (SET_SRC (curr_set), 0)) == REGNO(SET_DEST (curr_set)) + && REGNO (XEXP (SET_SRC (curr_set), 0)) == curr_dest_regno && CONST_INT_P (XEXP (SET_SRC (prev_set), 1)) && CONST_INT_P (XEXP (SET_SRC (curr_set), 1)) && INTVAL (XEXP (SET_SRC (prev_set), 1)) == 48 && INTVAL (XEXP (SET_SRC (curr_set), 1)) == 48) - return true; + { + if (dump_file) + fprintf (dump_file,"RISCV_FUSE_ZEXTH\n"); + return true; + } } - if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LDINDEXED)) + if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LDINDEXED) + && (sched1 || prev_dest_regno == curr_dest_regno)) { /* We are trying to match the following: prev (add) == (set (reg:DI rD) @@ -10125,12 +10461,17 @@ riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr) (mem:DI (reg:DI rD))) */ if (MEM_P (SET_SRC (curr_set)) + && SCALAR_INT_MODE_P (GET_MODE (SET_DEST (curr_set))) && REG_P (XEXP (SET_SRC (curr_set), 0)) - && REGNO (XEXP (SET_SRC (curr_set), 0)) == REGNO (SET_DEST (prev_set)) + && REGNO (XEXP (SET_SRC (curr_set), 0)) == prev_dest_regno && GET_CODE (SET_SRC (prev_set)) == PLUS && REG_P (XEXP (SET_SRC (prev_set), 0)) && REG_P (XEXP (SET_SRC (prev_set), 1))) - return true; + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_LDINDEXED\n"); + return true; + } /* We are trying to match the following: prev (add) == (set (reg:DI rD) @@ -10140,15 +10481,154 @@ riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr) if ((GET_CODE (SET_SRC (curr_set)) == SIGN_EXTEND || (GET_CODE (SET_SRC (curr_set)) == ZERO_EXTEND)) && MEM_P (XEXP (SET_SRC (curr_set), 0)) + && SCALAR_INT_MODE_P (GET_MODE (SET_DEST (curr_set))) && REG_P (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) - && REGNO (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) == REGNO (SET_DEST (prev_set)) + && REGNO (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) == prev_dest_regno && GET_CODE (SET_SRC (prev_set)) == PLUS && REG_P (XEXP (SET_SRC (prev_set), 0)) && REG_P (XEXP (SET_SRC (prev_set), 1))) - return true; + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_LDINDEXED\n"); + return true; + } } - if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LDPREINCREMENT)) + if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_EXPANDED_LD) + && (sched1 || prev_dest_regno == curr_dest_regno)) + { + /* For the "expanded add/load fusion" family we have 2 main + categories: memory loads with displacement (i.e. with imm offset) + and loads without displacement (i.e. with offset = x0). + + For loads without displacement we'll need: + - add + ld (done in RISCV_FUSE_LDINDEXED) + - addi + ld (done in RISCV_FUSE_LDPREINCREMENT) + - shNadd + ld + - add.uw + lw + - shNadd.uw + lw + + For loads with displacement/immediates: + with lw with immediate): + - add + ld with displacement + - addi + ld with displacement + - shNadd + ld with displacement + - add.uw + lw with displacement + - shNadd.uw + lw with displacement */ + + /* We're trying to match a curr_set ld with displacement: + prev (add|addi) = (set (reg:DI rd) (...)) + curr (ld) == (set (reg:DI rD) + (mem:DI (plus:DI (reg:DI rD) (const_int IMM12)))) */ + if (MEM_P (SET_SRC (curr_set)) + && SCALAR_INT_MODE_P (GET_MODE (SET_DEST (curr_set))) + && GET_CODE (XEXP (SET_SRC (curr_set), 0)) == PLUS + && REGNO (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) == prev_dest_regno) + { + if (riscv_set_is_add (prev_set)) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_EXPANDED_LD\n"); + return true; + } + + if (riscv_set_is_addi (prev_set)) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_EXPANDED_LD\n"); + return true; + } + + if (riscv_set_is_shNadd (prev_set)) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_EXPANDED_LD\n"); + return true; + } + } + + /* We're trying to match a ld without displacement: + prev (addi|shNadd) = (reg:DI rD) (...)) + curr (ld) == (set (reg:DI rD) + (mem:DI (reg:DI rD))) */ + if (MEM_P (SET_SRC (curr_set)) + && SCALAR_INT_MODE_P (GET_MODE (SET_DEST (curr_set))) + && REG_P (XEXP (SET_SRC (curr_set), 0)) + && REGNO (XEXP (SET_SRC (curr_set), 0)) == prev_dest_regno) + { + if (riscv_set_is_addi (prev_set)) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_EXPANDED_LD\n"); + return true; + } + + if (riscv_set_is_shNadd (prev_set)) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_EXPANDED_LD\n"); + return true; + } + } + + /* We're trying to match a curr_set lw with displacement: + prev (add.uw|shNadd.uw) = (set (reg:DI rd) (...)) + curr (lw) == (set (reg:DI rd) + (any_extend:DI (mem:SUBX (plus:DI ((reg:DI rd) + (const_int IMM)))) */ + if ((GET_CODE (SET_SRC (curr_set)) == SIGN_EXTEND + || (GET_CODE (SET_SRC (curr_set)) == ZERO_EXTEND)) + && MEM_P (XEXP (SET_SRC (curr_set), 0)) + && SCALAR_INT_MODE_P (GET_MODE (SET_DEST (curr_set))) + && GET_CODE (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) == PLUS + && REG_P (XEXP (XEXP (XEXP (SET_SRC (curr_set), 0), 0),0)) + && (REGNO (XEXP (XEXP (XEXP (SET_SRC (curr_set), 0), 0),0)) + == prev_dest_regno)) + { + if (riscv_set_is_adduw (prev_set)) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_EXPANDED_LD\n"); + return true; + } + + if (riscv_set_is_shNadduw (prev_set)) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_EXPANDED_LD\n"); + return true; + } + } + + /* We're trying to match a curr_set lw without displacement: + prev (add.uw|shNadd.uw) = (set (reg:DI rd) (...)) + curr (ld|lh|lw) == (set (reg:DI rd) + (any_extend:DI (mem:SUBX (reg:DI rsd)))) */ + if ((GET_CODE (SET_SRC (curr_set)) == SIGN_EXTEND + || (GET_CODE (SET_SRC (curr_set)) == ZERO_EXTEND)) + && MEM_P (XEXP (SET_SRC (curr_set), 0)) + && SCALAR_INT_MODE_P (GET_MODE (SET_DEST (curr_set))) + && REG_P (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) + && REGNO (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) == prev_dest_regno) + { + if (riscv_set_is_adduw (prev_set)) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_EXPANDED_LD\n"); + return true; + } + + if (riscv_set_is_shNadduw (prev_set)) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_EXPANDED_LD\n"); + return true; + } + } + } + + if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LDPREINCREMENT) + && (sched1 || prev_dest_regno == curr_dest_regno)) { /* We are trying to match the following: prev (add) == (set (reg:DI rS) @@ -10157,15 +10637,21 @@ riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr) (mem:DI (reg:DI rS))) */ if (MEM_P (SET_SRC (curr_set)) + && SCALAR_INT_MODE_P (GET_MODE (SET_DEST (curr_set))) && REG_P (XEXP (SET_SRC (curr_set), 0)) - && REGNO (XEXP (SET_SRC (curr_set), 0)) == REGNO (SET_DEST (prev_set)) + && REGNO (XEXP (SET_SRC (curr_set), 0)) == prev_dest_regno && GET_CODE (SET_SRC (prev_set)) == PLUS && REG_P (XEXP (SET_SRC (prev_set), 0)) && CONST_INT_P (XEXP (SET_SRC (prev_set), 1))) - return true; + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_LDPREINCREMENT\n"); + return true; + } } - if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LUI_ADDI)) + if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LUI_ADDI) + && (sched1 || prev_dest_regno == curr_dest_regno)) { /* We are trying to match the following: prev (lui) == (set (reg:DI rD) (const_int UPPER_IMM_20)) @@ -10179,10 +10665,15 @@ riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr) && (GET_CODE (SET_SRC (prev_set)) == HIGH || (CONST_INT_P (SET_SRC (prev_set)) && LUI_OPERAND (INTVAL (SET_SRC (prev_set)))))) - return true; + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_LUI_ADDI\n"); + return true; + } } - if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_AUIPC_ADDI)) + if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_AUIPC_ADDI) + && (sched1 || prev_dest_regno == curr_dest_regno)) { /* We are trying to match the following: prev (auipc) == (set (reg:DI rD) (unspec:DI [...] UNSPEC_AUIPC)) @@ -10200,38 +10691,64 @@ riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr) && CONST_INT_P (XEXP (SET_SRC (curr_set), 1)) && SMALL_OPERAND (INTVAL (XEXP (SET_SRC (curr_set), 1)))))) - return true; + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_AUIPC_ADDI\n"); + return true; + } } - if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LUI_LD)) + if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_LUI_LD) + && (sched1 || prev_dest_regno == curr_dest_regno)) { /* We are trying to match the following: prev (lui) == (set (reg:DI rD) (const_int UPPER_IMM_20)) curr (ld) == (set (reg:DI rD) (mem:DI (plus:DI (reg:DI rD) (const_int IMM12)))) */ + /* A LUI_OPERAND accepts (const_int 0), but we won't emit that as LUI. So + reject that case explicitly. */ if (CONST_INT_P (SET_SRC (prev_set)) + && SET_SRC (prev_set) != CONST0_RTX (GET_MODE (SET_DEST (prev_set))) && LUI_OPERAND (INTVAL (SET_SRC (prev_set))) && MEM_P (SET_SRC (curr_set)) - && GET_CODE (XEXP (SET_SRC (curr_set), 0)) == PLUS) - return true; + && SCALAR_INT_MODE_P (GET_MODE (SET_DEST (curr_set))) + && GET_CODE (XEXP (SET_SRC (curr_set), 0)) == PLUS + && REGNO (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) == prev_dest_regno) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_LUI_LD\n"); + return true; + } if (GET_CODE (SET_SRC (prev_set)) == HIGH && MEM_P (SET_SRC (curr_set)) + && SCALAR_INT_MODE_P (GET_MODE (SET_DEST (curr_set))) && GET_CODE (XEXP (SET_SRC (curr_set), 0)) == LO_SUM - && REGNO (SET_DEST (prev_set)) == REGNO (XEXP (XEXP (SET_SRC (curr_set), 0), 0))) - return true; + && REGNO (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) == prev_dest_regno) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_LUI_LD\n"); + return true; + } if (GET_CODE (SET_SRC (prev_set)) == HIGH && (GET_CODE (SET_SRC (curr_set)) == SIGN_EXTEND || GET_CODE (SET_SRC (curr_set)) == ZERO_EXTEND) && MEM_P (XEXP (SET_SRC (curr_set), 0)) + && SCALAR_INT_MODE_P (GET_MODE (SET_DEST (curr_set))) && (GET_CODE (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) == LO_SUM - && REGNO (SET_DEST (prev_set)) == REGNO (XEXP (XEXP (XEXP (SET_SRC (curr_set), 0), 0), 0)))) - return true; + && (REGNO (XEXP (XEXP (XEXP (SET_SRC (curr_set), 0), 0), 0)) + == prev_dest_regno))) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_LUI_LD\n"); + return true; + } } - if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_AUIPC_LD)) + if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_AUIPC_LD) + && (sched1 || prev_dest_regno == curr_dest_regno)) { /* We are trying to match the following: prev (auipc) == (set (reg:DI rD) (unspec:DI [...] UNSPEC_AUIPC)) @@ -10241,11 +10758,16 @@ riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr) if (GET_CODE (SET_SRC (prev_set)) == UNSPEC && XINT (prev_set, 1) == UNSPEC_AUIPC && MEM_P (SET_SRC (curr_set)) + && SCALAR_INT_MODE_P (GET_MODE (SET_DEST (curr_set))) && GET_CODE (XEXP (SET_SRC (curr_set), 0)) == PLUS) - return true; + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_AUIPC_LD\n"); + return true; + } } - if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_ALIGNED_STD)) + if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_CACHE_ALIGNED_STD)) { /* We are trying to match the following: prev (sd) == (set (mem (plus (reg sp|fp) (const_int))) @@ -10255,6 +10777,7 @@ riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr) if (MEM_P (SET_DEST (prev_set)) && MEM_P (SET_DEST (curr_set)) + && SCALAR_INT_MODE_P (GET_MODE (SET_DEST (curr_set))) /* We can probably relax this condition. The documentation is a bit unclear about sub-word cases. So we just model DImode for now. */ && GET_MODE (SET_DEST (curr_set)) == DImode @@ -10265,43 +10788,205 @@ riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr) extract_base_offset_in_addr (SET_DEST (prev_set), &base_prev, &offset_prev); extract_base_offset_in_addr (SET_DEST (curr_set), &base_curr, &offset_curr); - /* Fail if we did not find both bases. */ - if (base_prev == NULL_RTX || base_curr == NULL_RTX) - return false; + /* Proceed only if we find both bases, both bases are register and + bases are the same register. */ + if (base_prev != NULL_RTX && base_curr != NULL_RTX + && REG_P (base_prev) && REG_P (base_curr) + && REGNO (base_prev) != REGNO (base_curr) + /* The alignment of hte base pointer is more useful than the + alignment of the memory reference for determining if we're + on opposite sides of a cache line. */ + && REGNO_POINTER_ALIGN (ORIGINAL_REGNO (base_prev)) >= 128) + { + /* The two stores must be contained within opposite halves of the + same 16 byte aligned block of memory. We know the pointer + has suitable alignment, so we just need to check the offsets + of the two stores for suitable alignment. */ + + /* Get the smaller offset into OFFSET_PREV. */ + if (INTVAL (offset_prev) > INTVAL (offset_curr)) + std::swap (offset_prev, offset_curr); + + /* We have a match if the smaller offset (OFFSET_PREV) is 16 + byte aligned and the higher offset is 8 bytes more than the + lower offset. */ + if ((INTVAL (offset_prev) % 16) == 0 + && (INTVAL (offset_prev) + 8 == INTVAL (offset_curr))) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_ALIGNED_STD\n"); + return true; + } + } + } + } - /* Fail if either base is not a register. */ - if (!REG_P (base_prev) || !REG_P (base_curr)) - return false; + /* More general form of the RISCV_FUSE_CACHE_ALIGNED_STD. The + major difference is the dependency on the stores being opposite + halves of a cache line is dropped. Instead the lowest address + needs 2X the alignment of the object and the higher address + immediately followed the first object. */ + if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_ALIGNED_STD)) + { + /* We are trying to match the following: + prev (sd) == (set (mem (plus (reg rS1) (const_int))) + (reg rS2)) + curr (sd) == (set (mem (plus (reg rS1) (const_int))) + (reg rS3)) */ - /* Fail if the bases are not the same register. */ - if (REGNO (base_prev) != REGNO (base_curr)) - return false; + if (MEM_P (SET_DEST (prev_set)) + && SCALAR_INT_MODE_P (GET_MODE (SET_DEST (curr_set))) + && MEM_P (SET_DEST (curr_set)) + /* Stores must have the same width */ + && GET_MODE (SET_DEST (curr_set)) == GET_MODE (SET_DEST (prev_set))) + { + rtx base_prev, base_curr, offset_prev, offset_curr; + unsigned mode_size; + + extract_base_offset_in_addr (SET_DEST (prev_set), + &base_prev, &offset_prev); + extract_base_offset_in_addr (SET_DEST (curr_set), + &base_curr, &offset_curr); + + /* Proceed only if we find both bases, both bases + are registers and bases are the same register. */ + if (base_prev != NULL_RTX && base_curr != NULL_RTX + && REG_P (base_prev) && REG_P (base_curr) + && REGNO (base_prev) == REGNO (base_curr)) + { + machine_mode mode = GET_MODE (SET_DEST (curr_set)); + mode_size = estimated_poly_value (GET_MODE_SIZE (mode)); + + HOST_WIDE_INT offset_prev_int = INTVAL (offset_prev); + HOST_WIDE_INT offset_curr_int = INTVAL (offset_curr); + + /* Get the smaller offset into OFFSET_PREV_INT. */ + if (offset_prev_int > offset_curr_int) + std::swap (offset_prev_int, offset_curr_int); + + /* We've normalized, so we need to check that the lower + address is aligned to 2X the size of the object. The + higher address must be the lower address plus the + size of the object. */ + if (((offset_prev_int % (2 * mode_size)) == 0) + && offset_prev_int + mode_size == offset_curr_int) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_ALIGNED_STD\n"); + return true; + } + } + } + } - /* Originally the thought was to check MEM_ALIGN, but that was - reporting incorrect alignments, even for SP/FP accesses, so we - gave up on that approach. Instead just check for stack/hfp - which we know are aligned. */ - if (REGNO (base_prev) != STACK_POINTER_REGNUM - && REGNO (base_prev) != HARD_FRAME_POINTER_REGNUM) - return false; + if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_BFEXT) + && (sched1 || prev_dest_regno == curr_dest_regno)) + { + /* We are trying to match the following: + prev (slli) == (set (reg:DI rD) + (ashift:DI (reg:DI rS) (const_int))) + curr (srli) == (set (reg:DI rD) + (lshiftrt:DI (reg:DI rD) (const_int))) */ - /* The two stores must be contained within opposite halves of the - same 16 byte aligned block of memory. We know that the stack - pointer and the frame pointer have suitable alignment. So we - just need to check the offsets of the two stores for suitable - alignment. */ - /* Get the smaller offset into OFFSET_PREV. */ - if (INTVAL (offset_prev) > INTVAL (offset_curr)) - std::swap (offset_prev, offset_curr); - - /* If the smaller offset (OFFSET_PREV) is not 16 byte aligned, - then fail. */ - if ((INTVAL (offset_prev) % 16) != 0) - return false; + if (GET_CODE (SET_SRC (prev_set)) == ASHIFT + && (GET_CODE (SET_SRC (curr_set)) == LSHIFTRT + || GET_CODE (SET_SRC (curr_set)) == ASHIFTRT) + && REG_P (SET_DEST (prev_set)) + && REG_P (SET_DEST (curr_set)) + && REGNO (XEXP (SET_SRC (curr_set), 0)) == prev_dest_regno + && CONST_INT_P (XEXP (SET_SRC (prev_set), 1)) + && CONST_INT_P (XEXP (SET_SRC (curr_set), 1))) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_BFEXT\n"); + return true; + } + } + + if (simple_sets_p && riscv_fusion_enabled_p (RISCV_FUSE_B_ALUI) + && (sched1 || prev_dest_regno == curr_dest_regno)) + { + /* We are trying to match the following: + prev (orc.b) == (set (reg rD) + (unspec (reg rS1))) + curr (not) == (set (reg rD2) (not (reg rD))) */ + + if (GET_CODE (SET_SRC (prev_set)) == UNSPEC + && GET_CODE (SET_SRC (curr_set)) == NOT + && XINT (SET_SRC (prev_set), 1) == UNSPEC_ORC_B + && REG_P (SET_DEST (prev_set)) + && REG_P (SET_DEST (curr_set)) + && REG_P (XEXP (SET_SRC (curr_set), 0)) + && REGNO (XEXP (SET_SRC (curr_set), 0)) == prev_dest_regno) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_B_ALUI\n"); + return true; + } + + /* We are trying to match the following: + prev (ctz) == (set (reg rD) (ctz (reg rS1))) + curr (andi) == (set (reg rD) + (and (reg rD) (const_int 63))) */ + + if (GET_CODE (SET_SRC (prev_set)) == CTZ + && GET_CODE (SET_SRC (curr_set)) == AND + && CONST_INT_P (XEXP (SET_SRC (curr_set), 1)) + && INTVAL (XEXP (SET_SRC (curr_set), 1)) == 63 + && REG_P (SET_DEST (prev_set)) + && REG_P (SET_DEST (curr_set)) + && REG_P (XEXP (SET_SRC (curr_set), 0)) + && REGNO (XEXP (SET_SRC (curr_set), 0)) == prev_dest_regno) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_B_ALUI\n"); + return true; + } + + /* We are trying to match the following: + prev (sub) == (set (reg rD) + (minus (const_int 0) (reg rS2)) + curr (max) == (set (reg rD) + (smax (reg rD) (reg rS2))) */ + + if (GET_CODE (SET_SRC (prev_set)) == MINUS + && (XEXP (SET_SRC (prev_set), 0) + == CONST0_RTX (GET_MODE (SET_SRC (prev_set)))) + && CONST_INT_P (XEXP (SET_SRC (prev_set), 0)) + && GET_CODE (SET_SRC (curr_set)) == SMAX + && REG_P (SET_DEST (prev_set)) + && REG_P (SET_DEST (curr_set)) + && REG_P (XEXP (SET_SRC (curr_set), 0)) + && REGNO (XEXP (SET_SRC (curr_set), 0)) == prev_dest_regno + && REG_P (XEXP (SET_SRC (prev_set), 1)) + && REG_P (XEXP (SET_SRC (curr_set), 1)) + && (REGNO (XEXP (SET_SRC (prev_set), 1)) + == REGNO (XEXP (SET_SRC (curr_set), 1)))) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_B_ALUI\n"); + return true; + } + + /* We are trying to match the following: + prev (neg) == (set (reg rD) (neg (reg rS1))) + curr (max) == (set (reg rD) + (smax (reg rD) (reg rS1))) */ - /* The higher offset must be 8 bytes more than the lower - offset. */ - return (INTVAL (offset_prev) + 8 == INTVAL (offset_curr)); + if (GET_CODE (SET_SRC (prev_set)) == NEG + && GET_CODE (SET_SRC (curr_set)) == SMAX + && REG_P (SET_DEST (prev_set)) + && REG_P (SET_DEST (curr_set)) + && REG_P (XEXP (SET_SRC (curr_set), 0)) + && REGNO (XEXP (SET_SRC (curr_set), 0)) == prev_dest_regno + && REG_P (XEXP (SET_SRC (prev_set), 0)) + && REG_P (XEXP (SET_SRC (curr_set), 1)) + && (REGNO (XEXP (SET_SRC (prev_set), 0)) + == REGNO (XEXP (SET_SRC (curr_set), 1)))) + { + if (dump_file) + fprintf (dump_file, "RISCV_FUSE_B_ALUI\n"); + return true; } } @@ -10377,6 +11062,27 @@ riscv_sched_adjust_cost (rtx_insn *, int, rtx_insn *insn, int cost, return new_cost; } +/* Implement TARGET_SCHED_CAN_SPECULATE_INSN hook. Return true if insn can + can be scheduled for speculative execution. Reject vsetvl instructions to + prevent the scheduler from hoisting them out of basic blocks without + checking for data dependencies PR117974. */ +static bool +riscv_sched_can_speculate_insn (rtx_insn *insn) +{ + /* Gate speculative scheduling of vsetvl instructions behind tune param. */ + if (tune_param->speculative_sched_vsetvl) + return true; + + switch (get_attr_type (insn)) + { + case TYPE_VSETVL: + case TYPE_VSETVL_PRE: + return false; + default: + return true; + } +} + /* Auxiliary function to emit RISC-V ELF attribute. */ static void riscv_emit_attribute () @@ -12140,6 +12846,14 @@ riscv_lshift_subword (machine_mode mode ATTRIBUTE_UNUSED, rtx value, rtx shift, gen_lowpart (QImode, shift))); } +/* Return TRUE if we should use the zero stride load, FALSE otherwise. */ + +bool +strided_load_broadcast_p () +{ + return tune_param->use_zero_stride_load; +} + /* Return TRUE if we should use the divmod expander, FALSE otherwise. This allows the behavior to be tuned for specific implementations as well as when optimizing for size. */ @@ -12220,7 +12934,7 @@ riscv_emit_frm_mode_set (int mode, int prev_mode) && prev_mode != riscv_vector::FRM_DYN && prev_mode != riscv_vector::FRM_DYN_CALL) /* Restore frm value when switch to DYN mode. */ - || (mode == riscv_vector::FRM_DYN + || (STATIC_FRM_P (cfun) && mode == riscv_vector::FRM_DYN && prev_mode != riscv_vector::FRM_DYN_CALL); if (restore_p) @@ -12247,57 +12961,6 @@ riscv_emit_mode_set (int entity, int mode, int prev_mode, } } -/* Adjust the FRM_NONE insn after a call to FRM_DYN for the - underlying emit. */ - -static int -riscv_frm_adjust_mode_after_call (rtx_insn *cur_insn, int mode) -{ - rtx_insn *insn = prev_nonnote_nondebug_insn_bb (cur_insn); - - if (insn && CALL_P (insn)) - return riscv_vector::FRM_DYN; - - return mode; -} - -/* Insert the backup frm insn to the end of the bb if and only if the call - is the last insn of this bb. */ - -static void -riscv_frm_emit_after_bb_end (rtx_insn *cur_insn) -{ - edge eg; - bool abnormal_edge_p = false; - edge_iterator eg_iterator; - basic_block bb = BLOCK_FOR_INSN (cur_insn); - - FOR_EACH_EDGE (eg, eg_iterator, bb->succs) - { - if (eg->flags & EDGE_ABNORMAL) - abnormal_edge_p = true; - else - { - start_sequence (); - emit_insn (gen_frrmsi (DYNAMIC_FRM_RTL (cfun))); - rtx_insn *backup_insn = end_sequence (); - - insert_insn_on_edge (backup_insn, eg); - } - } - - if (abnormal_edge_p) - { - start_sequence (); - emit_insn (gen_frrmsi (DYNAMIC_FRM_RTL (cfun))); - rtx_insn *backup_insn = end_sequence (); - - insert_insn_end_basic_block (backup_insn, bb); - } - - commit_edge_insertions (); -} - /* Return mode that frm must be switched into prior to the execution of insn. */ @@ -12309,33 +12972,25 @@ riscv_frm_mode_needed (rtx_insn *cur_insn, int code) /* The dynamic frm will be initialized only onece during cfun. */ DYNAMIC_FRM_RTL (cfun) = gen_reg_rtx (SImode); emit_insn_at_entry (gen_frrmsi (DYNAMIC_FRM_RTL (cfun))); + CFUN_IN_CALL (cfun) = false; } if (CALL_P (cur_insn)) { - rtx_insn *insn = next_nonnote_nondebug_insn_bb (cur_insn); - - if (!insn) - riscv_frm_emit_after_bb_end (cur_insn); - + CFUN_IN_CALL (cfun) = true; return riscv_vector::FRM_DYN_CALL; } int mode = code >= 0 ? get_attr_frm_mode (cur_insn) : riscv_vector::FRM_NONE; if (mode == riscv_vector::FRM_NONE) - /* After meet a call, we need to backup the frm because it may be - updated during the call. Here, for each insn, we will check if - the previous insn is a call or not. When previous insn is call, - there will be 2 cases for the emit mode set. - - 1. Current insn is not MODE_NONE, then the mode switch framework - will do the mode switch from MODE_CALL to MODE_NONE natively. - 2. Current insn is MODE_NONE, we need to adjust the MODE_NONE to - the MODE_DYN, and leave the mode switch itself to perform - the emit mode set. - */ - mode = riscv_frm_adjust_mode_after_call (cur_insn, mode); + { + if (CFUN_IN_CALL (cfun)) + { + CFUN_IN_CALL (cfun) = false; + return riscv_vector::FRM_DYN; + } + } return mode; } @@ -12428,41 +13083,6 @@ riscv_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET) } } -/* Return TRUE if the rouding mode is dynamic. */ - -static bool -riscv_dynamic_frm_mode_p (int mode) -{ - return mode == riscv_vector::FRM_DYN - || mode == riscv_vector::FRM_DYN_CALL - || mode == riscv_vector::FRM_DYN_EXIT; -} - -/* Implement TARGET_MODE_CONFLUENCE. */ - -static int -riscv_mode_confluence (int entity, int mode1, int mode2) -{ - switch (entity) - { - case RISCV_VXRM: - return VXRM_MODE_NONE; - case RISCV_FRM: - { - /* FRM_DYN, FRM_DYN_CALL and FRM_DYN_EXIT are all compatible. - Although we already try to set the mode needed to FRM_DYN after a - function call, there are still some corner cases where both FRM_DYN - and FRM_DYN_CALL may appear on incoming edges. */ - if (riscv_dynamic_frm_mode_p (mode1) - && riscv_dynamic_frm_mode_p (mode2)) - return riscv_vector::FRM_DYN; - return riscv_vector::FRM_NONE; - } - default: - gcc_unreachable (); - } -} - /* Return TRUE that an insn is asm. */ static bool @@ -13198,6 +13818,88 @@ riscv_expand_sssub (rtx dest, rtx x, rtx y) emit_move_insn (dest, gen_lowpart (mode, xmode_dest)); } +/* Implement the Xmode usmul. + + b = SAT_MUL (a, b); + => + _1 = a * b; + _2 = mulhu (a, b); + _overflow_p = _2 == 0; + _mask = - _overflow_p; + b = _1 | _mask; + */ + +static void +riscv_expand_xmode_usmul (rtx dest, rtx x, rtx y) +{ + machine_mode mode = GET_MODE (dest); + + gcc_assert (mode == Xmode); + + rtx mul = gen_reg_rtx (Xmode); + rtx mulhu = gen_reg_rtx (Xmode); + rtx overflow_p = gen_reg_rtx (Xmode); + + riscv_emit_binary (MULT, mul, x, y); + + if (TARGET_64BIT) + emit_insn (gen_usmuldi3_highpart (mulhu, x, y)); + else + emit_insn (gen_usmulsi3_highpart (mulhu, x, y)); + + riscv_emit_binary (NE, overflow_p, mulhu, CONST0_RTX (Xmode)); + riscv_emit_unary (NEG, overflow_p, overflow_p); + riscv_emit_binary (IOR, dest, mul, overflow_p); +} + +/* Implement the non-Xmode usmul. + + b = SAT_MUL (a, b); + => + _1 = a * b; + _max = (T)-1 + _overflow_p = _1 > _max; + _mask = - _overflow_p; + b = _1 | _mask; + */ + +static void +riscv_expand_non_xmode_usmul (rtx dest, rtx x, rtx y) +{ + machine_mode mode = GET_MODE (dest); + unsigned bitsize = GET_MODE_BITSIZE (mode).to_constant (); + + gcc_assert (mode != Xmode); + + rtx xmode_x = riscv_extend_to_xmode_reg (x, mode, ZERO_EXTEND); + rtx xmode_y = riscv_extend_to_xmode_reg (y, mode, ZERO_EXTEND); + rtx xmode_mul = gen_reg_rtx (Xmode); + rtx mul_max = gen_reg_rtx (Xmode); + rtx overflow_p = gen_reg_rtx (Xmode); + + uint64_t max = ((uint64_t)1 << bitsize) - 1; + + emit_move_insn (mul_max, GEN_INT (max)); + riscv_emit_binary (MULT, xmode_mul, xmode_x, xmode_y); + + riscv_emit_binary (LTU, overflow_p, mul_max, xmode_mul); + riscv_emit_unary (NEG, overflow_p, overflow_p); + riscv_emit_binary (IOR, xmode_mul, xmode_mul, overflow_p); + + emit_move_insn (dest, gen_lowpart (mode, xmode_mul)); +} + +/* Implements the unsigned saturation mult standard name usmul for int mode. */ + +void +riscv_expand_usmul (rtx dest, rtx x, rtx y) +{ + if (GET_MODE (dest) == Xmode) + return riscv_expand_xmode_usmul (dest, x, y) ; + else + return riscv_expand_non_xmode_usmul (dest, x, y); +} + /* Implement the unsigned saturation truncation for int mode. b = SAT_TRUNC (a); @@ -13951,7 +14653,6 @@ riscv_get_function_versions_dispatcher (void *decl) struct cgraph_node *node = NULL; struct cgraph_node *default_node = NULL; struct cgraph_function_version_info *node_v = NULL; - struct cgraph_function_version_info *first_v = NULL; tree dispatch_decl = NULL; @@ -13968,41 +14669,16 @@ riscv_get_function_versions_dispatcher (void *decl) if (node_v->dispatcher_resolver != NULL) return node_v->dispatcher_resolver; - /* Find the default version and make it the first node. */ - first_v = node_v; - /* Go to the beginning of the chain. */ - while (first_v->prev != NULL) - first_v = first_v->prev; - default_version_info = first_v; - - while (default_version_info != NULL) - { - struct riscv_feature_bits res; - int priority; /* Unused. */ - parse_features_for_version (default_version_info->this_node->decl, - res, priority); - if (res.length == 0) - break; - default_version_info = default_version_info->next; - } + /* The default node is always the beginning of the chain. */ + default_version_info = node_v; + while (default_version_info->prev) + default_version_info = default_version_info->prev; + default_node = default_version_info->this_node; /* If there is no default node, just return NULL. */ - if (default_version_info == NULL) + if (!is_function_default_version (default_node->decl)) return NULL; - /* Make default info the first node. */ - if (first_v != default_version_info) - { - default_version_info->prev->next = default_version_info->next; - if (default_version_info->next) - default_version_info->next->prev = default_version_info->prev; - first_v->prev = default_version_info; - default_version_info->next = first_v; - default_version_info->prev = NULL; - } - - default_node = default_version_info->this_node; - if (targetm.has_ifunc_p ()) { struct cgraph_function_version_info *it_v = NULL; @@ -14775,6 +15451,9 @@ synthesize_and (rtx operands[3]) #undef TARGET_SCHED_ADJUST_COST #define TARGET_SCHED_ADJUST_COST riscv_sched_adjust_cost +#undef TARGET_SCHED_CAN_SPECULATE_INSN +#define TARGET_SCHED_CAN_SPECULATE_INSN riscv_sched_can_speculate_insn + #undef TARGET_FUNCTION_OK_FOR_SIBCALL #define TARGET_FUNCTION_OK_FOR_SIBCALL riscv_function_ok_for_sibcall @@ -15066,8 +15745,6 @@ synthesize_and (rtx operands[3]) #define TARGET_MODE_EMIT riscv_emit_mode_set #undef TARGET_MODE_NEEDED #define TARGET_MODE_NEEDED riscv_mode_needed -#undef TARGET_MODE_CONFLUENCE -#define TARGET_MODE_CONFLUENCE riscv_mode_confluence #undef TARGET_MODE_AFTER #define TARGET_MODE_AFTER riscv_mode_after #undef TARGET_MODE_ENTRY diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 2759a4cb1c9f..45fa521f219f 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -43,7 +43,7 @@ along with GCC; see the file COPYING3. If not see #endif #ifndef RISCV_TUNE_STRING_DEFAULT -#define RISCV_TUNE_STRING_DEFAULT "rocket" +#define RISCV_TUNE_STRING_DEFAULT "generic" #endif extern const char *riscv_expand_arch (int argc, const char **argv); diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 92fe7c7741a2..c3b504d08836 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -884,7 +884,7 @@ ;; Where C1 is not a LUI operand, but ~C1 is a LUI operand (define_insn_and_split "*lui_constraint<X:mode>_and_to_or" - [(set (match_operand:X 0 "register_operand" "=r") + [(set (match_operand:X 0 "register_operand" "=r") (plus:X (and:X (match_operand:X 1 "register_operand" "r") (match_operand 2 "const_int_operand")) (match_operand 3 "const_int_operand"))) @@ -898,13 +898,21 @@ <= riscv_const_insns (operands[3], false)))" "#" "&& reload_completed" - [(set (match_dup 4) (match_dup 5)) - (set (match_dup 0) (ior:X (match_dup 1) (match_dup 4))) - (set (match_dup 4) (match_dup 6)) - (set (match_dup 0) (minus:X (match_dup 0) (match_dup 4)))] + [(const_int 0)] { operands[5] = GEN_INT (~INTVAL (operands[2])); operands[6] = GEN_INT ((~INTVAL (operands[2])) | (-INTVAL (operands[3]))); + + /* This is always a LUI operand, so it's safe to just emit. */ + emit_move_insn (operands[4], operands[5]); + + rtx x = gen_rtx_IOR (word_mode, operands[1], operands[4]); + emit_move_insn (operands[0], x); + + /* This may require multiple steps to synthesize. */ + riscv_emit_move (operands[4], operands[6]); + x = gen_rtx_MINUS (word_mode, operands[0], operands[4]); + emit_move_insn (operands[0], x); } [(set_attr "type" "arith")]) @@ -3290,7 +3298,7 @@ (match_operand:GPR 2 "movcc_operand") (match_operand:GPR 3 "movcc_operand")))] "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_ZICOND_LIKE - || TARGET_MOVCC" + || TARGET_MOVCC || TARGET_XMIPSCMOV" { if (riscv_expand_conditional_move (operands[0], operands[1], operands[2], operands[3])) @@ -4394,7 +4402,7 @@ ) (define_insn "prefetch" - [(prefetch (match_operand 0 "address_operand" "r") + [(prefetch (match_operand 0 "prefetch_operand" "Qr") (match_operand 1 "imm5_operand" "i") (match_operand 2 "const_int_operand" "n"))] "TARGET_ZICBOP" @@ -4414,7 +4422,7 @@ (const_string "4")))]) (define_insn "riscv_prefetchi_<mode>" - [(unspec_volatile:X [(match_operand:X 0 "address_operand" "r") + [(unspec_volatile:X [(match_operand:X 0 "prefetch_operand" "Q") (match_operand:X 1 "imm5_operand" "i")] UNSPECV_PREI)] "TARGET_ZICBOP" @@ -4626,6 +4634,17 @@ } ) +(define_expand "usmul<mode>3" + [(match_operand:ANYI 0 "register_operand") + (match_operand:ANYI 1 "register_operand") + (match_operand:ANYI 2 "register_operand")] + "" + { + riscv_expand_usmul (operands[0], operands[1], operands[2]); + DONE; + } +) + (define_expand "ustrunc<mode><anyi_double_truncated>2" [(match_operand:<ANYI_DOUBLE_TRUNCATED> 0 "register_operand") (match_operand:ANYI_DOUBLE_TRUNC 1 "register_operand")] @@ -4834,6 +4853,25 @@ [(set_attr "type" "move") (set_attr "mode" "<MODE>")]) +;; If we're trying to create 0 or 2^n-1 based on the result of +;; a test such as (lt (reg) (const_int 0)), we'll see a splat of +;; the sign bit across a GPR using srai, then a logical and to +;; mask off high bits. We can replace the logical and with +;; a logical right shift which works without constant synthesis +;; for larger constants. +(define_split + [(set (match_operand:X 0 "register_operand") + (and:X (ashiftrt:X (match_operand:X 1 "register_operand") + (match_operand 2 "const_int_operand")) + (match_operand 3 "const_int_operand")))] + "(INTVAL (operands[2]) == BITS_PER_WORD - 1 + && exact_log2 (INTVAL (operands[3]) + 1) >= 0)" + [(set (match_dup 0) (ashiftrt:X (match_dup 1) (match_dup 2))) + (set (match_dup 0) (lshiftrt:X (match_dup 0) (match_dup 3)))] + { operands[3] = GEN_INT (BITS_PER_WORD + - exact_log2 (INTVAL (operands[3]) + 1)); }) + +;; Standard extensions and pattern for optimization (include "bitmanip.md") (include "crypto.md") (include "sync.md") @@ -4841,19 +4879,22 @@ (include "sync-ztso.md") (include "peephole.md") (include "pic.md") -(include "generic.md") -(include "sifive-7.md") -(include "sifive-p400.md") -(include "sifive-p600.md") -(include "thead.md") -(include "generic-vector-ooo.md") -(include "generic-ooo.md") (include "vector.md") (include "vector-crypto.md") (include "vector-bfloat16.md") (include "zicond.md") +(include "mips-insn.md") (include "sfb.md") (include "zc.md") +;; Vendor extensions +(include "thead.md") (include "corev.md") +;; Pipeline models +(include "generic.md") (include "xiangshan.md") (include "mips-p8700.md") +(include "sifive-7.md") +(include "sifive-p400.md") +(include "sifive-p600.md") +(include "generic-vector-ooo.md") +(include "generic-ooo.md") diff --git a/gcc/config/riscv/sifive-7.md b/gcc/config/riscv/sifive-7.md index c20854108893..a04b80bff04d 100644 --- a/gcc/config/riscv/sifive-7.md +++ b/gcc/config/riscv/sifive-7.md @@ -1,4 +1,4 @@ -(define_automaton "sifive_7") +(define_automaton "sifive_7,sifive_7_vec,sifive_7_vec_mem") ;; Sifive 7 Series Base Core ;; This has two pipelines, A (Address) and B (Branch). @@ -11,6 +11,14 @@ (define_cpu_unit "sifive_7_idiv" "sifive_7") (define_cpu_unit "sifive_7_fpu" "sifive_7") +;; Vector command queue +(define_cpu_unit "sifive_7_vcq" "sifive_7") +;; Vector arithmetic sequencer +(define_cpu_unit "sifive_7_va" "sifive_7_vec") +;; Vector store sequencer +(define_cpu_unit "sifive_7_vs" "sifive_7_vec_mem") +;; Vector load sequencer +(define_cpu_unit "sifive_7_vl" "sifive_7_vec_mem") (define_insn_reservation "sifive_7_load" 3 (and (eq_attr "tune" "sifive_7") @@ -60,9 +68,14 @@ (define_insn_reservation "sifive_7_alu" 2 (and (eq_attr "tune" "sifive_7") (eq_attr "type" "unknown,arith,shift,slt,multi,logical,move,bitmanip,\ - rotate,min,max,minu,maxu,clz,ctz,atomic,condmove,mvpair,zicond")) + min,max,minu,maxu,atomic,condmove,mvpair,zicond")) "sifive_7_A|sifive_7_B") +(define_insn_reservation "sifive_7_alu_b" 2 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "clz,ctz,rotate")) + "sifive_7_B") + (define_insn_reservation "sifive_7_load_immediate" 1 (and (eq_attr "tune" "sifive_7") (eq_attr "type" "nop,const,auipc")) @@ -91,6 +104,12 @@ (eq_attr "type" "fcvt,fcvt_i2f,fcvt_f2i,fcmp,fmove")) "sifive_7_B") +(define_insn_reservation "sifive_7_fdiv_h" 14 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "fdiv,fsqrt") + (eq_attr "mode" "HF")) + "sifive_7_B,sifive_7_fpu*13") + (define_insn_reservation "sifive_7_fdiv_s" 27 (and (eq_attr "tune" "sifive_7") (eq_attr "type" "fdiv,fsqrt") @@ -119,6 +138,21 @@ (eq_attr "type" "cpop,clmul")) "sifive_7_A") +(define_insn_reservation "sifive_7_csr" 5 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "rdfrm,wrfrm,wrvxrm")) + "sifive_7_A") + +(define_insn_reservation "sifive_7_crypto" 10 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "crypto")) + "sifive_7_A") + +(define_insn_reservation "sifive_7_unknown" 10 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "ghost")) + "sifive_7_A") + (define_bypass 1 "sifive_7_load,sifive_7_alu,sifive_7_mul,sifive_7_f2i,sifive_7_sfb_alu" "sifive_7_alu,sifive_7_branch") @@ -129,13 +163,140 @@ "sifive_7_store" "riscv_store_data_bypass_p") (define_bypass 2 "sifive_7_i2f" - "sifive_7_sfma,sifive_7_dfma,sifive_7_fp_other,sifive_7_fdiv_s,sifive_7_fdiv_d") + "sifive_7_sfma,sifive_7_dfma,sifive_7_fp_other,sifive_7_fdiv_h,sifive_7_fdiv_s,sifive_7_fdiv_d,sifive_7_hfma") (define_bypass 2 "sifive_7_fp_other" - "sifive_7_sfma,sifive_7_dfma,sifive_7_fp_other,sifive_7_fdiv_s,sifive_7_fdiv_d") + "sifive_7_sfma,sifive_7_dfma,sifive_7_fp_other,sifive_7_fdiv_h,sifive_7_fdiv_s,sifive_7_fdiv_d,sifive_7_hfma") (define_bypass 2 "sifive_7_fp_other" "sifive_7_alu,sifive_7_branch") (define_bypass 2 "sifive_7_fp_other" "sifive_7_store" "riscv_store_data_bypass_p") + +;; Vector pipeline +;; The latency is depend on LMUL, but we didn't model that yet since we don't +;; want to expand the rule too much unless we prove model that could get +;; meaningful performance difference. + +(define_insn_reservation "sifive_7_vsetvl" 2 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vsetvl_pre,vsetvl,rdvlenb,rdvl")) + "sifive_7_A") + +(define_insn_reservation "sifive_7_vec_load" 4 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vlde,vldm,vlds,vldux,vldox,vldff,vldr, + vlsegde,vlsegds,vlsegdux,vlsegdox,vlsegdff")) + "sifive_7_vcq,sifive_7_vl*3") + +(define_insn_reservation "sifive_7_vec_store" 4 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vste,vstm,vsts,vstux,vstox,vstr, + vssegte,vssegts,vssegtux,vssegtox")) + "sifive_7_vcq,sifive_7_vs*3") + +(define_insn_reservation "sifive_7_vec_ialu" 4 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vimovxv,vmov,vimovvx,vialu,vicalu,vext, + vshift,viminmax,vimerge,vbrev,vrev8, + vimov,vext,vbrev8,vclz,vctz,vcpop,vrol,vror,vandn")) + "sifive_7_vcq,sifive_7_va*3") + +(define_insn_reservation "sifive_7_vec_slow_ialu" 8 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vshift,vimul,vimuladd")) + "sifive_7_vcq,sifive_7_va*7") + +(define_insn_reservation "sifive_7_vec_cmp" 4 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vicmp")) + "sifive_7_vcq,sifive_7_va*3") + +(define_insn_reservation "sifive_7_vec_iwalu" 8 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "viwalu,viwmul,viwmuladd,vnshift,vwsll")) + "sifive_7_vcq,sifive_7_va*7") + +(define_insn_reservation "sifive_7_vec_div" 16 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vidiv,vfdiv")) + "sifive_7_vcq,sifive_7_va*15") + +(define_insn_reservation "sifive_7_vec_fixed_point" 8 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vsalu,vaalu,vsmul,vsshift")) + "sifive_7_vcq,sifive_7_va*7") + +(define_insn_reservation "sifive_7_vec_narrow_fixed_point" 8 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vnclip")) + "sifive_7_vcq,sifive_7_va*7") + +(define_insn_reservation "sifive_7_vec_fsimple" 4 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vfmovvf,vfmovfv,vfclass")) + "sifive_7_vcq,sifive_7_va*3") + +(define_insn_reservation "sifive_7_vec_falu" 8 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vfalu,vfmul,vfmuladd,vfrecp, + vfcvtitof,vfcvtftoi,vfmerge,vfmov,vfsgnj")) + "sifive_7_vcq,sifive_7_va*7") + +(define_insn_reservation "sifive_7_vec_fcmp" 4 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vfcmp,vfminmax")) + "sifive_7_vcq,sifive_7_va*3") + +(define_insn_reservation "sifive_7_vec_fsqrt_fdiv" 16 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vfsqrt,vfdiv")) + "sifive_7_vcq,sifive_7_va*15") + +(define_insn_reservation "sifive_7_vec_fwalu" 8 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vfwalu,vfwmul,vfwmuladd,vfwmaccbf16,vfwcvtitof, + vfwcvtftoi,vfwcvtftof,vfwcvtbf16, + vfncvtitof,vfncvtftoi,vfncvtftof,vfncvtbf16, + sf_vfnrclip,sf_vqmacc")) + "sifive_7_vcq,sifive_7_va*7") + +(define_insn_reservation "sifive_7_vec_red" 12 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vired,vfredu,vfredo,viwred,vfwredu,vfwredo")) + "sifive_7_vcq,sifive_7_va*11") + +(define_insn_reservation "sifive_7_vec_mask" 4 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vmalu,vmpop,vmffs,vmsfs")) + "sifive_7_vcq,sifive_7_va*3") + +(define_insn_reservation "sifive_7_vec_mask_special" 4 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vmiota,vmidx")) + "sifive_7_vcq,sifive_7_va*3") + +(define_insn_reservation "sifive_7_vec_gather" 8 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vgather")) + "sifive_7_vcq,sifive_7_va*7") + +(define_insn_reservation "sifive_7_vec_compress" 16 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vcompress")) + "sifive_7_vcq,sifive_7_va*15") + +(define_insn_reservation "sifive_7_vec_slide" 4 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vslideup,vslidedown,vislide1up,vislide1down,vfslide1up,vfslide1down")) + "sifive_7_vcq,sifive_7_va*3") + +;; Assume that's slow if it's unknown instruction vector type. +(define_insn_reservation "sifive_7_vec_unknown" 16 + (and (eq_attr "tune" "sifive_7") + (eq_attr "type" "vector,vclmul,vclmulh,vghsh,vgmul, + vaesef,vaesem,vaesdf,vaesdm,vaeskf1,vaeskf2, + vaesz,vsha2ms,vsha2ch,vsha2cl, + vsm4k,vsm4r,vsm3me,vsm3c,sf_vc,sf_vc_se")) + "sifive_7_vcq,sifive_7_va*15") diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md index 726800a96623..50ec8b38f723 100644 --- a/gcc/config/riscv/sync.md +++ b/gcc/config/riscv/sync.md @@ -405,18 +405,17 @@ (match_operand:SI 3 "const_int_operand")] ;; model UNSPEC_SYNC_EXCHANGE)) (set (match_dup 1) - (match_operand:GPR 2 "register_operand" "0")) + (match_operand:GPR 2 "reg_or_0_operand" "rJ")) (clobber (match_scratch:GPR 4 "=&r"))] ;; tmp_1 "!TARGET_ZAAMO && TARGET_ZALRSC" { return "1:\;" - "lr.<amo>%I3\t%4, %1\;" - "sc.<amo>%J3\t%0, %0, %1\;" - "bnez\t%0, 1b\;" - "mv\t%0, %4"; + "lr.<amo>%I3\t%0, %1\;" + "sc.<amo>%J3\t%4, %z2, %1\;" + "bnez\t%4, 1b\"; } [(set_attr "type" "atomic") - (set (attr "length") (const_int 16))]) + (set (attr "length") (const_int 12))]) (define_expand "atomic_exchange<mode>" [(match_operand:SHORT 0 "register_operand") ;; old value at mem @@ -628,7 +627,7 @@ (match_operand:SHORT 1 "memory_operand" "+A")) ;; memory (set (match_dup 1) (unspec_volatile:SHORT [(match_operand:SHORT 2 "register_operand" "0") ;; expected_val - (match_operand:SHORT 3 "register_operand" "rJ") ;; desired_val + (match_operand:SHORT 3 "reg_or_0_operand" "rJ") ;; desired_val (match_operand:SI 4 "const_int_operand") ;; mod_s (match_operand:SI 5 "const_int_operand")] ;; mod_f UNSPEC_COMPARE_AND_SWAP))] diff --git a/gcc/config/riscv/t-riscv b/gcc/config/riscv/t-riscv index 32092d856878..7aac56ac86cc 100644 --- a/gcc/config/riscv/t-riscv +++ b/gcc/config/riscv/t-riscv @@ -194,7 +194,8 @@ RISCV_EXT_DEFS = \ $(srcdir)/config/riscv/riscv-ext.def \ $(srcdir)/config/riscv/riscv-ext-sifive.def \ $(srcdir)/config/riscv/riscv-ext-thead.def \ - $(srcdir)/config/riscv/riscv-ext-ventana.def + $(srcdir)/config/riscv/riscv-ext-ventana.def \ + $(srcdir)/config/riscv/riscv-ext-mips.def $(srcdir)/config/riscv/riscv-ext.opt: $(RISCV_EXT_DEFS) diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 62fd1c09400b..5f6cc42b46b9 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -2418,6 +2418,47 @@ (RVVM1x2DF "rvvm1df") ]) +(define_mode_attr vsubel [ + (RVVM8HI "qi") (RVVM4HI "qi") (RVVM2HI "qi") (RVVM1HI "qi") (RVVMF2HI "qi") (RVVMF4HI "qi") + + (RVVM8SI "hi") (RVVM4SI "hi") (RVVM2SI "hi") (RVVM1SI "hi") (RVVMF2SI "hi") + + (RVVM8SF "hf") (RVVM4SF "hf") (RVVM2SF "hf") (RVVM1SF "hf") (RVVMF2SF "hf") + + (RVVM8DI "si") (RVVM4DI "si") (RVVM2DI "si") (RVVM1DI "si") + + (RVVM8DF "sf") (RVVM4DF "sf") (RVVM2DF "sf") (RVVM1DF "sf") + + ;; VLS modes. + (V1HI "qi") (V2HI "qi") (V4HI "qi") (V8HI "qi") (V16HI "qi") (V32HI "qi") (V64HI "qi") (V128HI "qi") (V256HI "qi") + (V512HI "qi") (V1024HI "qi") (V2048HI "qi") + (V1SI "hi") (V2SI "hi") (V4SI "hi") (V8SI "hi") (V16SI "hi") (V32SI "hi") (V64SI "hi") (V128SI "hi") (V256SI "hi") + (V512SI "hi") (V1024SI "hi") + (V1DI "si") (V2DI "si") (V4DI "si") (V8DI "si") (V16DI "si") (V32DI "si") (V64DI "si") (V128DI "si") (V256DI "si") (V512DI "si") + + (V1SF "hf") + (V2SF "hf") + (V4SF "hf") + (V8SF "hf") + (V16SF "hf") + (V32SF "hf") + (V64SF "hf") + (V128SF "hf") + (V256SF "hf") + (V512SF "hf") + (V1024SF "hf") + (V1DF "sf") + (V2DF "sf") + (V4DF "sf") + (V8DF "sf") + (V16DF "sf") + (V32DF "sf") + (V64DF "sf") + (V128DF "sf") + (V256DF "sf") + (V512DF "sf") +]) + (define_mode_attr VSUBEL [ (RVVM8HI "QI") (RVVM4HI "QI") (RVVM2HI "QI") (RVVM1HI "QI") (RVVMF2HI "QI") (RVVMF4HI "QI") @@ -4041,8 +4082,13 @@ smax umax smin umin mult div udiv mod umod ]) -(define_code_iterator any_int_binop_no_shift_vx [ - plus minus and ior xor mult div +(define_code_iterator any_int_binop_no_shift_v_vdup [ + plus minus and ior xor mult div udiv mod umod smax umax smin umin us_plus + us_minus ss_plus ss_minus +]) + +(define_code_iterator any_int_binop_no_shift_vdup_v [ + plus minus and ior xor mult smax umax smin umin us_plus ss_plus ]) (define_code_iterator any_int_unop [neg not]) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 851ba4a9490a..c498166791e2 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -1580,8 +1580,22 @@ "&& 1" [(const_int 0)] { - riscv_vector::emit_vlmax_insn (code_for_pred_broadcast (<MODE>mode), - riscv_vector::UNARY_OP, operands); + if (!strided_load_broadcast_p () + && TARGET_ZVFHMIN && !TARGET_ZVFH && <VEL>mode == HFmode) + { + /* For Float16, reinterpret as HImode, broadcast and reinterpret + back. */ + poly_uint64 nunits = GET_MODE_NUNITS (<MODE>mode); + machine_mode vmodehi + = riscv_vector::get_vector_mode (HImode, nunits).require (); + rtx ops[] = {lowpart_subreg (vmodehi, operands[0], <MODE>mode), + lowpart_subreg (HImode, operands[1], HFmode)}; + riscv_vector::emit_vlmax_insn (code_for_pred_broadcast (vmodehi), + riscv_vector::UNARY_OP, ops); + } + else + riscv_vector::emit_vlmax_insn (code_for_pred_broadcast (<MODE>mode), + riscv_vector::UNARY_OP, operands); DONE; } [(set_attr "type" "vector")] @@ -1783,7 +1797,7 @@ [(set_attr "type" "vsetvl") (set_attr "mode" "SI")]) -;; This pattern use to combine bellow two insns and then further remove +;; This pattern use to combine below two insns and then further remove ;; unnecessary sign_extend operations: ;; (set (reg:DI 134 [ _1 ]) ;; (unspec:DI [ @@ -2171,7 +2185,7 @@ } } else if (GET_MODE_BITSIZE (<VEL>mode) > GET_MODE_BITSIZE (Pmode) - && (immediate_operand (operands[3], Pmode) + && (immediate_operand (operands[3], Pmode) || (CONST_POLY_INT_P (operands[3]) && known_ge (rtx_to_poly_int64 (operands[3]), 0U) && known_le (rtx_to_poly_int64 (operands[3]), GET_MODE_SIZE (<MODE>mode))))) @@ -2224,12 +2238,7 @@ "(register_operand (operands[3], <VEL>mode) || CONST_POLY_INT_P (operands[3])) && GET_MODE_BITSIZE (<VEL>mode) > GET_MODE_BITSIZE (Pmode)" - [(set (match_dup 0) - (if_then_else:V_VLSI (unspec:<VM> [(match_dup 1) (match_dup 4) - (match_dup 5) (match_dup 6) (match_dup 7) - (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (vec_duplicate:V_VLSI (match_dup 3)) - (match_dup 2)))] + [(const_int 0)] { gcc_assert (can_create_pseudo_p ()); if (CONST_POLY_INT_P (operands[3])) @@ -2238,12 +2247,6 @@ emit_move_insn (tmp, operands[3]); operands[3] = tmp; } - rtx m = assign_stack_local (<VEL>mode, GET_MODE_SIZE (<VEL>mode), - GET_MODE_ALIGNMENT (<VEL>mode)); - m = validize_mem (m); - emit_move_insn (m, operands[3]); - m = gen_rtx_MEM (<VEL>mode, force_reg (Pmode, XEXP (m, 0))); - operands[3] = m; /* For SEW = 64 in RV32 system, we expand vmv.s.x: andi a2,a2,1 @@ -2254,6 +2257,35 @@ operands[4] = riscv_vector::gen_avl_for_scalar_move (operands[4]); operands[1] = CONSTM1_RTX (<VM>mode); } + + /* If the target doesn't want a strided-load broadcast we go with a regular + V1DImode load and a broadcast gather. */ + if (strided_load_broadcast_p ()) + { + rtx mem = assign_stack_local (<VEL>mode, GET_MODE_SIZE (<VEL>mode), + GET_MODE_ALIGNMENT (<VEL>mode)); + mem = validize_mem (mem); + emit_move_insn (mem, operands[3]); + mem = gen_rtx_MEM (<VEL>mode, force_reg (Pmode, XEXP (mem, 0))); + + emit_insn + (gen_pred_broadcast<mode> + (operands[0], operands[1], operands[2], mem, + operands[4], operands[5], operands[6], operands[7])); + } + else + { + rtx tmp = gen_reg_rtx (V1DImode); + emit_move_insn (tmp, lowpart_subreg (V1DImode, operands[3], + <VEL>mode)); + tmp = lowpart_subreg (<MODE>mode, tmp, V1DImode); + + emit_insn + (gen_pred_gather<mode>_scalar + (operands[0], operands[1], operands[2], tmp, CONST0_RTX (Pmode), + operands[4], operands[5], operands[6], operands[7])); + } + DONE; } [(set_attr "type" "vimov,vimov,vlds,vlds,vlds,vlds,vimovxv,vimovxv") (set_attr "mode" "<MODE>")]) @@ -2293,9 +2325,9 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (vec_duplicate:V_VLSF_ZVFHMIN - (match_operand:<VEL> 3 "direct_broadcast_operand" "Wdm, Wdm, Wdm, Wdm")) + (match_operand:<VEL> 3 "direct_broadcast_operand" " A, A, A, A")) (match_operand:V_VLSF_ZVFHMIN 2 "vector_merge_operand" " vu, 0, vu, 0")))] - "TARGET_VECTOR" + "TARGET_VECTOR && strided_load_broadcast_p ()" "@ vlse<sew>.v\t%0,%3,zero,%1.t vlse<sew>.v\t%0,%3,zero,%1.t @@ -4607,8 +4639,8 @@ ;; Handle GET_MODE_INNER (mode) = DImode. We need to split them since ;; we need to deal with SEW = 64 in RV32 system. (define_expand "@pred_<sat_op><mode>_scalar" - [(set (match_operand:VI_D 0 "register_operand") - (if_then_else:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand") + (if_then_else:V_VLSI_D (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand") (match_operand 5 "vector_length_operand") @@ -4619,10 +4651,10 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI VXRM_REGNUM)] UNSPEC_VPREDICATE) - (unspec:VI_D - [(match_operand:VI_D 3 "register_operand") + (unspec:V_VLSI_D + [(match_operand:V_VLSI_D 3 "register_operand") (match_operand:<VEL> 4 "reg_or_int_operand")] VSAT_ARITH_OP) - (match_operand:VI_D 2 "vector_merge_operand")))] + (match_operand:V_VLSI_D 2 "vector_merge_operand")))] "TARGET_VECTOR" { if (riscv_vector::sew64_scalar_helper ( @@ -4641,8 +4673,8 @@ }) (define_insn "*pred_<sat_op><mode>_scalar" - [(set (match_operand:VI_D 0 "register_operand" "=vd, vr, vd, vr") - (if_then_else:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand" "=vd, vr, vd, vr") + (if_then_else:V_VLSI_D (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") (match_operand 5 "vector_length_operand" "rvl,rvl,rvl,rvl") @@ -4653,18 +4685,18 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI VXRM_REGNUM)] UNSPEC_VPREDICATE) - (unspec:VI_D - [(match_operand:VI_D 3 "register_operand" " vr, vr, vr, vr") + (unspec:V_VLSI_D + [(match_operand:V_VLSI_D 3 "register_operand" " vr, vr, vr, vr") (match_operand:<VEL> 4 "reg_or_0_operand" " rJ, rJ, rJ, rJ")] VSAT_ARITH_OP) - (match_operand:VI_D 2 "vector_merge_operand" " vu, 0, vu, 0")))] + (match_operand:V_VLSI_D 2 "vector_merge_operand" " vu, 0, vu, 0")))] "TARGET_VECTOR" "v<sat_op>.vx\t%0,%3,%z4%p1" [(set_attr "type" "<sat_insn_type>") (set_attr "mode" "<MODE>")]) (define_insn "*pred_<sat_op><mode>_extended_scalar" - [(set (match_operand:VI_D 0 "register_operand" "=vd, vr, vd, vr") - (if_then_else:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand" "=vd, vr, vd, vr") + (if_then_else:V_VLSI_D (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") (match_operand 5 "vector_length_operand" "rvl,rvl,rvl,rvl") @@ -4675,11 +4707,11 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI VXRM_REGNUM)] UNSPEC_VPREDICATE) - (unspec:VI_D - [(match_operand:VI_D 3 "register_operand" " vr, vr, vr, vr") + (unspec:V_VLSI_D + [(match_operand:V_VLSI_D 3 "register_operand" " vr, vr, vr, vr") (sign_extend:<VEL> (match_operand:<VSUBEL> 4 "reg_or_0_operand" " rJ, rJ, rJ, rJ"))] VSAT_ARITH_OP) - (match_operand:VI_D 2 "vector_merge_operand" " vu, 0, vu, 0")))] + (match_operand:V_VLSI_D 2 "vector_merge_operand" " vu, 0, vu, 0")))] "TARGET_VECTOR && !TARGET_64BIT" "v<sat_op>.vx\t%0,%3,%z4%p1" [(set_attr "type" "<sat_insn_type>") @@ -6599,9 +6631,42 @@ (match_operand:<VEL> 2 "register_operand")) (match_operand:V_VLSF 3 "register_operand")) (match_operand:V_VLSF 4 "register_operand")) - (match_operand:V_VLSF 5 "register_operand")))] + (match_operand:V_VLSF 5 "vector_merge_operand")))] "TARGET_VECTOR" -{}) +{ + riscv_vector::prepare_ternary_operands (operands); +}) + +(define_insn "*pred_mul_<optab><mode>_scalar_undef" + [(set (match_operand:V_VLSF 0 "register_operand" "=vd,vd, vr, vr") + (if_then_else:V_VLSF + (unspec:<VM> + [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") + (match_operand 6 "vector_length_operand" "rvl,rvl,rvl,rvl") + (match_operand 7 "const_int_operand" " i, i, i, i") + (match_operand 8 "const_int_operand" " i, i, i, i") + (match_operand 9 "const_int_operand" " i, i, i, i") + (match_operand 10 "const_int_operand" " i, i, i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM) + (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) + (plus_minus:V_VLSF + (mult:V_VLSF + (vec_duplicate:V_VLSF + (match_operand:<VEL> 3 "register_operand" " f, f, f, f")) + (match_operand:V_VLSF 4 "register_operand" " 0, vr, 0, vr")) + (match_operand:V_VLSF 5 "register_operand" " vr, 0, vr, 0")) + (match_operand:V_VLSF 2 "vector_undef_operand")))] + "TARGET_VECTOR" + "@ + vf<madd_msub>.vf\t%0,%3,%5%p1 + vf<macc_msac>.vf\t%0,%3,%4%p1 + vf<madd_msub>.vf\t%0,%3,%5%p1 + vf<macc_msac>.vf\t%0,%3,%4%p1" + [(set_attr "type" "vfmuladd") + (set_attr "mode" "<MODE>") + (set (attr "frm_mode") + (symbol_ref "riscv_vector::get_frm_mode (operands[10])"))]) (define_insn "*pred_<madd_msub><mode>_scalar" [(set (match_operand:V_VLSF 0 "register_operand" "=vd, vr") @@ -6815,9 +6880,43 @@ (match_operand:<VEL> 2 "register_operand")) (match_operand:V_VLSF 3 "register_operand"))) (match_operand:V_VLSF 4 "register_operand")) - (match_operand:V_VLSF 5 "register_operand")))] + (match_operand:V_VLSF 5 "vector_merge_operand")))] "TARGET_VECTOR" -{}) +{ + riscv_vector::prepare_ternary_operands (operands); +}) + +(define_insn "*pred_mul_neg_<optab><mode>_scalar_undef" + [(set (match_operand:V_VLSF 0 "register_operand" "=vd,vd, vr, vr") + (if_then_else:V_VLSF + (unspec:<VM> + [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") + (match_operand 6 "vector_length_operand" "rvl,rvl,rvl,rvl") + (match_operand 7 "const_int_operand" " i, i, i, i") + (match_operand 8 "const_int_operand" " i, i, i, i") + (match_operand 9 "const_int_operand" " i, i, i, i") + (match_operand 10 "const_int_operand" " i, i, i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM) + (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) + (plus_minus:V_VLSF + (neg:V_VLSF + (mult:V_VLSF + (vec_duplicate:V_VLSF + (match_operand:<VEL> 3 "register_operand" " f, f, f, f")) + (match_operand:V_VLSF 4 "register_operand" " 0, vr, 0, vr"))) + (match_operand:V_VLSF 5 "register_operand" " vr, 0, vr, 0")) + (match_operand:V_VLSF 2 "vector_undef_operand")))] + "TARGET_VECTOR" + "@ + vf<nmsub_nmadd>.vf\t%0,%3,%5%p1 + vf<nmsac_nmacc>.vf\t%0,%3,%4%p1 + vf<nmsub_nmadd>.vf\t%0,%3,%5%p1 + vf<nmsac_nmacc>.vf\t%0,%3,%4%p1" + [(set_attr "type" "vfmuladd") + (set_attr "mode" "<MODE>") + (set (attr "frm_mode") + (symbol_ref "riscv_vector::get_frm_mode (operands[10])"))]) (define_insn "*pred_<nmsub_nmadd><mode>_scalar" [(set (match_operand:V_VLSF 0 "register_operand" "=vd, vr") @@ -7200,10 +7299,10 @@ (plus_minus:VWEXTF (mult:VWEXTF (float_extend:VWEXTF - (vec_duplicate:<V_DOUBLE_TRUNC> - (match_operand:<VSUBEL> 3 "register_operand" " f"))) - (float_extend:VWEXTF - (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" " vr"))) + (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" " vr")) + (vec_duplicate:VWEXTF + (float_extend:<VEL> + (match_operand:<VSUBEL> 3 "register_operand" " f")))) (match_operand:VWEXTF 2 "register_operand" " 0")) (match_dup 2)))] "TARGET_VECTOR" diff --git a/gcc/config/riscv/xiangshan.md b/gcc/config/riscv/xiangshan.md index 5ed6bacdd702..34b4a8f1f3fc 100644 --- a/gcc/config/riscv/xiangshan.md +++ b/gcc/config/riscv/xiangshan.md @@ -107,7 +107,8 @@ ;; they are just dummies like this one. (define_insn_reservation "xiangshan_alu_unknown" 1 (and (eq_attr "tune" "xiangshan") - (eq_attr "type" "zicond,min,max,minu,maxu,clz,ctz,cpop,ghost,rotate,clmul,condmove,crypto,mvpair,rdvlenb,rdvl,wrvxrm,wrfrm,rdfrm,vsetvl,vsetvl_pre,vlde,vste,vldm,vstm,vlds,vsts,vldux,vldox,vstux,vstox,vldff,vldr,vstr,vlsegde,vssegte,vlsegds,vssegts,vlsegdux,vlsegdox,vssegtux,vssegtox,vlsegdff,vialu,viwalu,vext,vicalu,vshift,vnshift,vicmp,viminmax,vimul,vidiv,viwmul,vimuladd,sf_vqmacc,viwmuladd,vimerge,vimov,vsalu,vaalu,vsmul,vsshift,vnclip,sf_vfnrclip,vfalu,vfwalu,vfmul,vfdiv,vfwmul,vfmuladd,vfwmuladd,vfsqrt,vfrecp,vfcmp,vfminmax,vfsgnj,vfclass,vfmerge,vfmov,vfcvtitof,vfcvtftoi,vfwcvtitof,vfwcvtftoi,vfwcvtftof,vfncvtitof,vfncvtftoi,vfncvtftof,vired,viwred,vfredu,vfredo,vfwredu,vfwredo,vmalu,vmpop,vmffs,vmsfs,vmiota,vmidx,vimovvx,vimovxv,vfmovvf,vfmovfv,vslideup,vslidedown,vislide1up,vislide1down,vfslide1up,vfslide1down,vgather,vcompress,vmov,vector,vandn,vbrev,vbrev8,vrev8,vclz,vctz,vcpop,vrol,vror,vwsll,vclmul,vclmulh,vghsh,vgmul,vaesef,vaesem,vaesdf,vaesdm,vaeskf1,vaeskf2,vaesz,vsha2ms,vsha2ch,vsha2cl,vsm4k,vsm4r,vsm3me,vsm3c,vfncvtbf16,vfwcvtbf16,vfwmaccbf16")) + (eq_attr "type" "zicond,min,max,minu,maxu,clz,ctz,cpop,ghost,rotate,clmul,condmove,crypto,mvpair,rdvlenb,rdvl,wrvxrm,wrfrm,rdfrm,vsetvl,vsetvl_pre,vlde,vste,vldm,vstm,vlds,vsts,vldux,vldox,vstux,vstox,vldff,vldr,vstr,vlsegde,vssegte,vlsegds,vssegts,vlsegdux,vlsegdox,vssegtux,vssegtox,vlsegdff,vialu,viwalu,vext,vicalu,vshift,vnshift,vicmp,viminmax,vimul,vidiv,viwmul,vimuladd,sf_vqmacc,viwmuladd,vimerge,vimov,vsalu,vaalu,vsmul,vsshift,vnclip,sf_vfnrclip,vfalu,vfwalu,vfmul,vfdiv,vfwmul,vfmuladd,vfwmuladd,vfsqrt,vfrecp,vfcmp,vfminmax,vfsgnj,vfclass,vfmerge,vfmov,vfcvtitof,vfcvtftoi,vfwcvtitof,vfwcvtftoi,vfwcvtftof,vfncvtitof,vfncvtftoi,vfncvtftof,vired,viwred,vfredu,vfredo,vfwredu,vfwredo,vmalu,vmpop,vmffs,vmsfs,vmiota,vmidx,vimovvx,vimovxv,vfmovvf,vfmovfv,vslideup,vslidedown,vislide1up,vislide1down,vfslide1up,vfslide1down,vgather,vcompress,vmov,vector,vandn,vbrev,vbrev8,vrev8,vclz,vctz,vcpop,vrol,vror,vwsll,vclmul,vclmulh,vghsh,vgmul,vaesef,vaesem,vaesdf,vaesdm,vaeskf1,vaeskf2,vaesz,vsha2ms,vsha2ch,vsha2cl,vsm4k,vsm4r,vsm3me,vsm3c,vfncvtbf16,vfwcvtbf16,vfwmaccbf16,sf_vc,sf_vc_se")) + "xs_alu_rs") ;; ---------------------------------------------------- diff --git a/gcc/config/riscv/zicond.md b/gcc/config/riscv/zicond.md index f87b4f25c0b0..d170f6ab2628 100644 --- a/gcc/config/riscv/zicond.md +++ b/gcc/config/riscv/zicond.md @@ -234,5 +234,39 @@ (const_int 0) (match_dup 4)))]) +;; We can splat the sign bit across a GPR with a arithmetic right shift +;; which gives us a 0, -1 result. We then turn on bit #0 unconditionally +;; which results in 1, -1. There's probably other cases that could be +;; handled, this seems particularly important though. +(define_split + [(set (match_operand:X 0 "register_operand") + (plus:X (if_then_else:X (ge:X (match_operand:X 1 "register_operand") + (const_int 0)) + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")) + (match_operand 4 "const_int_operand")))] + "((TARGET_ZICOND_LIKE || TARGET_XTHEADCONDMOV) + && INTVAL (operands[2]) + INTVAL (operands[4]) == 1 + && INTVAL (operands[3]) + INTVAL (operands[4]) == -1)" + [(set (match_dup 0) (ashiftrt:X (match_dup 1) (match_dup 2))) + (set (match_dup 0) (ior:X (match_dup 0) (const_int 1)))] + { operands[2] = GEN_INT (GET_MODE_BITSIZE (word_mode) - 1); }) - +;; Similarly, but the condition and true/false values are reversed +;; +;; Note the case where the condition is reversed, but not the true/false +;; values. Or vice-versa is not handled because we don't support 4->3 +;; splits. +(define_split + [(set (match_operand:X 0 "register_operand") + (plus:X (if_then_else:X (lt:X (match_operand:X 1 "register_operand") + (const_int 0)) + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")) + (match_operand 4 "const_int_operand")))] + "((TARGET_ZICOND_LIKE || TARGET_XTHEADCONDMOV) + && INTVAL (operands[2]) + INTVAL (operands[4]) == -1 + && INTVAL (operands[3]) + INTVAL (operands[4]) == 1)" + [(set (match_dup 0) (ashiftrt:X (match_dup 1) (match_dup 2))) + (set (match_dup 0) (ior:X (match_dup 0) (const_int 1)))] + { operands[2] = GEN_INT (GET_MODE_BITSIZE (word_mode) - 1); }) diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md index 50e577ab44d0..85f3a9266827 100644 --- a/gcc/config/rs6000/mma.md +++ b/gcc/config/rs6000/mma.md @@ -30,7 +30,6 @@ (define_c_enum "unspec" [UNSPEC_VSX_ASSEMBLE - UNSPEC_MMA_EXTRACT UNSPEC_MMA_PMXVBF16GER2 UNSPEC_MMA_PMXVBF16GER2NN UNSPEC_MMA_PMXVBF16GER2NP @@ -398,29 +397,8 @@ (match_operand 2 "const_0_to_1_operand")] "TARGET_MMA" { - rtx src; - int regoff = INTVAL (operands[2]); - src = gen_rtx_UNSPEC (V16QImode, - gen_rtvec (2, operands[1], GEN_INT (regoff)), - UNSPEC_MMA_EXTRACT); - emit_move_insn (operands[0], src); - DONE; -}) - -(define_insn_and_split "*vsx_disassemble_pair" - [(set (match_operand:V16QI 0 "mma_disassemble_output_operand" "=mwa") - (unspec:V16QI [(match_operand:OO 1 "vsx_register_operand" "wa") - (match_operand 2 "const_0_to_1_operand")] - UNSPEC_MMA_EXTRACT))] - "TARGET_MMA - && vsx_register_operand (operands[1], OOmode)" - "#" - "&& reload_completed" - [(const_int 0)] -{ - int reg = REGNO (operands[1]); - int regoff = INTVAL (operands[2]); - rtx src = gen_rtx_REG (V16QImode, reg + regoff); + int regoff = INTVAL (operands[2]) * 16; + rtx src = simplify_gen_subreg (V16QImode, operands[1], OOmode, regoff); emit_move_insn (operands[0], src); DONE; }) @@ -472,29 +450,8 @@ (match_operand 2 "const_0_to_3_operand")] "TARGET_MMA" { - rtx src; - int regoff = INTVAL (operands[2]); - src = gen_rtx_UNSPEC (V16QImode, - gen_rtvec (2, operands[1], GEN_INT (regoff)), - UNSPEC_MMA_EXTRACT); - emit_move_insn (operands[0], src); - DONE; -}) - -(define_insn_and_split "*mma_disassemble_acc" - [(set (match_operand:V16QI 0 "mma_disassemble_output_operand" "=mwa") - (unspec:V16QI [(match_operand:XO 1 "fpr_reg_operand" "d") - (match_operand 2 "const_0_to_3_operand")] - UNSPEC_MMA_EXTRACT))] - "TARGET_MMA - && fpr_reg_operand (operands[1], XOmode)" - "#" - "&& reload_completed" - [(const_int 0)] -{ - int reg = REGNO (operands[1]); - int regoff = INTVAL (operands[2]); - rtx src = gen_rtx_REG (V16QImode, reg + regoff); + int regoff = INTVAL (operands[2]) * 16; + rtx src = simplify_gen_subreg (V16QImode, operands[1], XOmode, regoff); emit_move_insn (operands[0], src); DONE; }) diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc index 111802381acb..bc1580f051b0 100644 --- a/gcc/config/rs6000/rs6000-builtin.cc +++ b/gcc/config/rs6000/rs6000-builtin.cc @@ -915,7 +915,7 @@ fold_build_vec_cmp (tree_code code, tree type, tree arg0, tree arg1, tree cmp_type = truth_type_for (type); tree zero_vec = build_zero_cst (type); tree minus_one_vec = build_minus_one_cst (type); - tree temp = create_tmp_reg_or_ssa_name (cmp_type); + tree temp = make_ssa_name (cmp_type); gimple *g = gimple_build_assign (temp, code, arg0, arg1); gsi_insert_before (gsi, g, GSI_SAME_STMT); return fold_build3 (VEC_COND_EXPR, type, temp, minus_one_vec, zero_vec); @@ -1106,7 +1106,7 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi, if (TREE_TYPE (src_ptr) != src_type) src_ptr = build1 (NOP_EXPR, src_type, src_ptr); - tree src = create_tmp_reg_or_ssa_name (TREE_TYPE (src_type)); + tree src = make_ssa_name (TREE_TYPE (src_type)); gimplify_assign (src, build_simple_mem_ref (src_ptr), &new_seq); /* If we are not disassembling an accumulator/pair or our destination is @@ -1130,7 +1130,7 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi, { new_decl = rs6000_builtin_decls[RS6000_BIF_XXMFACC_INTERNAL]; new_call = gimple_build_call (new_decl, 1, src); - src = create_tmp_reg_or_ssa_name (vector_quad_type_node); + src = make_ssa_name (vector_quad_type_node); gimple_call_set_lhs (new_call, src); gimple_seq_add_stmt (&new_seq, new_call); } @@ -1146,7 +1146,7 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi, unsigned index = WORDS_BIG_ENDIAN ? i : nvec - 1 - i; tree dst = build2 (MEM_REF, unsigned_V16QI_type_node, dst_base, build_int_cst (dst_type, index * 16)); - tree dstssa = create_tmp_reg_or_ssa_name (unsigned_V16QI_type_node); + tree dstssa = make_ssa_name (unsigned_V16QI_type_node); new_call = gimple_build_call (new_decl, 2, src, build_int_cstu (uint16_type_node, i)); gimple_call_set_lhs (new_call, dstssa); @@ -1204,7 +1204,7 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi, { /* This built-in has a pass-by-reference accumulator input, so load it into a temporary accumulator for use as a pass-by-value input. */ - op[0] = create_tmp_reg_or_ssa_name (vector_quad_type_node); + op[0] = make_ssa_name (vector_quad_type_node); for (unsigned i = 1; i < nopnds; i++) op[i] = gimple_call_arg (stmt, i); gimplify_assign (op[0], build_simple_mem_ref (acc), &new_seq); @@ -1252,9 +1252,9 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi, } if (fncode == RS6000_BIF_BUILD_PAIR || fncode == RS6000_BIF_ASSEMBLE_PAIR_V) - lhs = create_tmp_reg_or_ssa_name (vector_pair_type_node); + lhs = make_ssa_name (vector_pair_type_node); else - lhs = create_tmp_reg_or_ssa_name (vector_quad_type_node); + lhs = make_ssa_name (vector_quad_type_node); gimple_call_set_lhs (new_call, lhs); gimple_seq_add_stmt (&new_seq, new_call); gimplify_assign (build_simple_mem_ref (acc), lhs, &new_seq); @@ -1450,7 +1450,7 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) arg0 = gimple_call_arg (stmt, 0); arg1 = gimple_call_arg (stmt, 1); lhs = gimple_call_lhs (stmt); - temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1)); + temp = make_ssa_name (TREE_TYPE (arg1)); g = gimple_build_assign (temp, BIT_NOT_EXPR, arg1); gimple_set_location (g, gimple_location (stmt)); gsi_insert_before (gsi, g, GSI_SAME_STMT); @@ -1472,7 +1472,7 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) arg0 = gimple_call_arg (stmt, 0); arg1 = gimple_call_arg (stmt, 1); lhs = gimple_call_lhs (stmt); - temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1)); + temp = make_ssa_name (TREE_TYPE (arg1)); g = gimple_build_assign (temp, BIT_AND_EXPR, arg0, arg1); gimple_set_location (g, gimple_location (stmt)); gsi_insert_before (gsi, g, GSI_SAME_STMT); @@ -1512,7 +1512,7 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) arg0 = gimple_call_arg (stmt, 0); arg1 = gimple_call_arg (stmt, 1); lhs = gimple_call_lhs (stmt); - temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1)); + temp = make_ssa_name (TREE_TYPE (arg1)); g = gimple_build_assign (temp, BIT_NOT_EXPR, arg1); gimple_set_location (g, gimple_location (stmt)); gsi_insert_before (gsi, g, GSI_SAME_STMT); @@ -1552,7 +1552,7 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) arg0 = gimple_call_arg (stmt, 0); arg1 = gimple_call_arg (stmt, 1); lhs = gimple_call_lhs (stmt); - temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1)); + temp = make_ssa_name (TREE_TYPE (arg1)); g = gimple_build_assign (temp, BIT_IOR_EXPR, arg0, arg1); gimple_set_location (g, gimple_location (stmt)); gsi_insert_before (gsi, g, GSI_SAME_STMT); @@ -1643,7 +1643,7 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) arg0 = gimple_call_arg (stmt, 0); arg1 = gimple_call_arg (stmt, 1); lhs = gimple_call_lhs (stmt); - temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1)); + temp = make_ssa_name (TREE_TYPE (arg1)); g = gimple_build_assign (temp, BIT_XOR_EXPR, arg0, arg1); gimple_set_location (g, gimple_location (stmt)); gsi_insert_before (gsi, g, GSI_SAME_STMT); diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 7375c36e406d..7ee26e52b138 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -25312,7 +25312,6 @@ rs6000_get_function_versions_dispatcher (void *decl) struct cgraph_node *node = NULL; struct cgraph_node *default_node = NULL; struct cgraph_function_version_info *node_v = NULL; - struct cgraph_function_version_info *first_v = NULL; tree dispatch_decl = NULL; @@ -25332,38 +25331,16 @@ rs6000_get_function_versions_dispatcher (void *decl) if (node_v->dispatcher_resolver != NULL) return node_v->dispatcher_resolver; - /* Find the default version and make it the first node. */ - first_v = node_v; - /* Go to the beginning of the chain. */ - while (first_v->prev != NULL) - first_v = first_v->prev; - - default_version_info = first_v; - while (default_version_info != NULL) - { - const tree decl2 = default_version_info->this_node->decl; - if (is_function_default_version (decl2)) - break; - default_version_info = default_version_info->next; - } + /* The default node is always the beginning of the chain. */ + default_version_info = node_v; + while (default_version_info->prev) + default_version_info = default_version_info->prev; + default_node = default_version_info->this_node; /* If there is no default node, just return NULL. */ - if (default_version_info == NULL) + if (!is_function_default_version (default_node->decl)) return NULL; - /* Make default info the first node. */ - if (first_v != default_version_info) - { - default_version_info->prev->next = default_version_info->next; - if (default_version_info->next) - default_version_info->next->prev = default_version_info->prev; - first_v->prev = default_version_info; - default_version_info->next = first_v; - default_version_info->prev = NULL; - } - - default_node = default_version_info->this_node; - #ifndef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB error_at (DECL_SOURCE_LOCATION (default_node->decl), "%<target_clones%> attribute needs GLIBC (2.23 and newer) that " diff --git a/gcc/config/rs6000/vxworks.h b/gcc/config/rs6000/vxworks.h index fa2c837b0642..e77247b726ea 100644 --- a/gcc/config/rs6000/vxworks.h +++ b/gcc/config/rs6000/vxworks.h @@ -34,6 +34,21 @@ along with GCC; see the file COPYING3. If not see /* Common definitions first. */ /*-------------------------------------------------------------*/ +/* Default to 64 bits when the target is powerpc64*-wrs-vxworks*, + and to 32 bits otherwise. */ +#undef SUBTARGET_DRIVER_SELF_SPECS +#if TARGET_VXWORKS64 +#define SUBTARGET_DRIVER_SELF_SPECS "%{!m64:%{!m32:-m64}}" +#else +#define SUBTARGET_DRIVER_SELF_SPECS "%{!m32:%{!m64:-m32}}" +#endif + +/* Having used the build-time TARGET_VXWORKS64 to choose the default ABI above, + redefine it so that it matches whichever ABI is selected for each + compilation. */ +#undef TARGET_VXWORKS64 +#define TARGET_VXWORKS64 TARGET_64BIT + /* CPP predefined macros. */ #undef TARGET_OS_CPP_BUILTINS diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index 38267202f668..a474e1354274 100644 --- a/gcc/config/s390/s390.cc +++ b/gcc/config/s390/s390.cc @@ -3862,7 +3862,21 @@ s390_register_move_cost (machine_mode mode, { /* On s390, copy between fprs and gprs is expensive. */ - /* It becomes somewhat faster having ldgr/lgdr. */ + /* With vector extensions any GPR<->VR load up to 8 bytes is supported. */ + if (TARGET_VX && GET_MODE_SIZE (mode) <= 8) + { + /* ldgr/vlvgg take one cycle and vlvg[bhf] take two cycles. */ + if (reg_classes_intersect_p (from, GENERAL_REGS) + && reg_classes_intersect_p (to, VEC_REGS)) + return GET_MODE_SIZE (mode) == 8 ? 1 : 2; + /* lgdr/vlgv[fg] take three cycles and vlgv[bh] take five cycles. */ + if (reg_classes_intersect_p (to, GENERAL_REGS) + && reg_classes_intersect_p (from, VEC_REGS)) + return GET_MODE_SIZE (mode) >= 4 ? 3 : 4; + } + + /* Without vector extensions it still becomes somewhat faster having + ldgr/lgdr. */ if (TARGET_Z10 && GET_MODE_SIZE (mode) == 8) { /* ldgr is single cycle. */ @@ -16566,9 +16580,6 @@ s390_option_override_internal (struct gcc_options *opts, else SET_OPTION_IF_UNSET (opts, opts_set, param_vect_partial_vector_usage, 0); - /* Do not vectorize loops with a low trip count for now. */ - SET_OPTION_IF_UNSET (opts, opts_set, param_min_vect_loop_bound, 2); - /* Set the default alignment. */ s390_default_align (opts); @@ -17832,9 +17843,11 @@ f_constraint_p (const char *constraint) for (size_t i = 0, c_len = strlen (constraint); i < c_len; i += CONSTRAINT_LEN (constraint[i], constraint + i)) { - if (constraint[i] == 'f') + if (constraint[i] == 'f' + || (constraint[i] == '{' && constraint[i + 1] == 'f')) seen_f_p = true; - if (constraint[i] == 'v') + if (constraint[i] == 'v' + || (constraint[i] == '{' && constraint[i + 1] == 'v')) seen_v_p = true; } @@ -17924,7 +17937,8 @@ s390_md_asm_adjust (vec<rtx> &outputs, vec<rtx> &inputs, continue; bool allows_mem, allows_reg, is_inout; bool ok = parse_output_constraint (&constraint, i, ninputs, noutputs, - &allows_mem, &allows_reg, &is_inout); + &allows_mem, &allows_reg, &is_inout, + nullptr); gcc_assert (ok); if (!f_constraint_p (constraint)) /* Long double with a constraint other than "=f" - nothing to do. */ @@ -17969,7 +17983,7 @@ s390_md_asm_adjust (vec<rtx> &outputs, vec<rtx> &inputs, bool allows_mem, allows_reg; bool ok = parse_input_constraint (&constraint, i, ninputs, noutputs, 0, constraints.address (), &allows_mem, - &allows_reg); + &allows_reg, nullptr); gcc_assert (ok); if (!f_constraint_p (constraint)) /* Long double with a constraint other than "f" (or "=f" for inout @@ -18041,9 +18055,34 @@ expand_perm_with_merge (const struct expand_vec_perm_d &d) static const unsigned char lo_perm_qi_swap[16] = {17, 1, 19, 3, 21, 5, 23, 7, 25, 9, 27, 11, 29, 13, 31, 15}; + static const unsigned char hi_perm_qi_di[16] + = {0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}; + static const unsigned char hi_perm_qi_si[16] + = {0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23}; + static const unsigned char hi_perm_qi_hi[16] + = {0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23}; + + static const unsigned char lo_perm_qi_di[16] + = {8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}; + static const unsigned char lo_perm_qi_si[16] + = {8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31}; + static const unsigned char lo_perm_qi_hi[16] + = {8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31}; + + static const unsigned char hi_perm_hi_si[8] = {0, 1, 8, 9, 2, 3, 10, 11}; + static const unsigned char hi_perm_hi_di[8] = {0, 1, 2, 3, 8, 9, 10, 11}; + + static const unsigned char lo_perm_hi_si[8] = {4, 5, 12, 13, 6, 7, 14, 15}; + static const unsigned char lo_perm_hi_di[8] = {4, 5, 6, 7, 12, 13, 14, 15}; + + static const unsigned char hi_perm_si_di[4] = {0, 1, 4, 5}; + + static const unsigned char lo_perm_si_di[4] = {2, 3, 6, 7}; + bool merge_lo_p = false; bool merge_hi_p = false; bool swap_operands_p = false; + machine_mode mergemode = d.vmode; if ((d.nelt == 2 && memcmp (d.perm, hi_perm_di, 2) == 0) || (d.nelt == 4 && memcmp (d.perm, hi_perm_si, 4) == 0) @@ -18075,6 +18114,75 @@ expand_perm_with_merge (const struct expand_vec_perm_d &d) merge_lo_p = true; swap_operands_p = true; } + else if (d.nelt == 16) + { + if (memcmp (d.perm, hi_perm_qi_di, 16) == 0) + { + merge_hi_p = true; + mergemode = E_V2DImode; + } + else if (memcmp (d.perm, hi_perm_qi_si, 16) == 0) + { + merge_hi_p = true; + mergemode = E_V4SImode; + } + else if (memcmp (d.perm, hi_perm_qi_hi, 16) == 0) + { + merge_hi_p = true; + mergemode = E_V8HImode; + } + else if (memcmp (d.perm, lo_perm_qi_di, 16) == 0) + { + merge_lo_p = true; + mergemode = E_V2DImode; + } + else if (memcmp (d.perm, lo_perm_qi_si, 16) == 0) + { + merge_lo_p = true; + mergemode = E_V4SImode; + } + else if (memcmp (d.perm, lo_perm_qi_hi, 16) == 0) + { + merge_lo_p = true; + mergemode = E_V8HImode; + } + } + else if (d.nelt == 8) + { + if (memcmp (d.perm, hi_perm_hi_di, 8) == 0) + { + merge_hi_p = true; + mergemode = E_V2DImode; + } + else if (memcmp (d.perm, hi_perm_hi_si, 8) == 0) + { + merge_hi_p = true; + mergemode = E_V4SImode; + } + else if (memcmp (d.perm, lo_perm_hi_di, 8) == 0) + { + merge_lo_p = true; + mergemode = E_V2DImode; + } + else if (memcmp (d.perm, lo_perm_hi_si, 8) == 0) + { + merge_lo_p = true; + mergemode = E_V4SImode; + } + } + else if (d.nelt == 4) + { + if (memcmp (d.perm, hi_perm_si_di, 4) == 0) + { + merge_hi_p = true; + mergemode = E_V2DImode; + } + else if (memcmp (d.perm, lo_perm_si_di, 4) == 0) + { + merge_lo_p = true; + mergemode = E_V2DImode; + } + } if (!merge_lo_p && !merge_hi_p) return false; @@ -18082,7 +18190,7 @@ expand_perm_with_merge (const struct expand_vec_perm_d &d) if (d.testing_p) return merge_lo_p || merge_hi_p; - rtx op0, op1; + rtx op0, op1, target = d.target; if (swap_operands_p) { op0 = d.op1; @@ -18093,12 +18201,80 @@ expand_perm_with_merge (const struct expand_vec_perm_d &d) op0 = d.op0; op1 = d.op1; } + if (mergemode != d.vmode) + { + target = simplify_gen_subreg (mergemode, target, d.vmode, 0); + op0 = simplify_gen_subreg (mergemode, op0, d.vmode, 0); + op1 = simplify_gen_subreg (mergemode, op1, d.vmode, 0); + } - s390_expand_merge (d.target, op0, op1, merge_hi_p); + s390_expand_merge (target, op0, op1, merge_hi_p); return true; } +/* Try to expand the vector permute operation described by D using the vector + pack instruction vpk. Return true if vector pack could be used. */ +static bool +expand_perm_with_pack (const struct expand_vec_perm_d &d) +{ + static const unsigned char qi_hi[16] + = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}; + static const unsigned char qi_si[16] + = {2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31}; + static const unsigned char qi_di[16] + = {4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31}; + + static const unsigned char hi_si[8] + = {1, 3, 5, 7, 9, 11, 13, 15}; + static const unsigned char hi_di[8] + = {2, 3, 6, 7, 10, 11, 14, 15}; + + static const unsigned char si_di[4] + = {1, 3, 5, 7}; + + machine_mode packmode, resmode; + enum insn_code code = CODE_FOR_nothing; + + if (d.nelt == 16 && memcmp (d.perm, qi_hi, 16) == 0) + { + packmode = E_V8HImode; + resmode = E_V16QImode; + code = CODE_FOR_vec_pack_trunc_v8hi; + } + else if ((d.nelt == 16 && memcmp (d.perm, qi_si, 16) == 0) + || (d.nelt == 8 && memcmp (d.perm, hi_si, 8) == 0)) + { + packmode = E_V4SImode; + resmode = E_V8HImode; + code = CODE_FOR_vec_pack_trunc_v4si; + } + else if ((d.nelt == 16 && memcmp (d.perm, qi_di, 16) == 0) + || (d.nelt == 8 && memcmp (d.perm, hi_di, 8) == 0) + || (d.nelt == 4 && memcmp (d.perm, si_di, 4) == 0)) + { + packmode = E_V2DImode; + resmode = E_V4SImode; + code = CODE_FOR_vec_pack_trunc_v2di; + } + + if (code == CODE_FOR_nothing) + return false; + + if (d.testing_p) + return true; + rtx target = simplify_gen_subreg (resmode, d.target, d.vmode, 0); + rtx op0 = simplify_gen_subreg (packmode, + force_reg (GET_MODE (d.op0), d.op0), + d.vmode, 0); + rtx op1 = simplify_gen_subreg (packmode, + force_reg (GET_MODE (d.op1), d.op1), + d.vmode, 0); + rtx pat = GEN_FCN (code) (target, op0, op1); + emit_insn (pat); + return true; +} + /* Try to expand the vector permute operation described by D using the vector permute doubleword immediate instruction vpdi. Return true if vpdi could be used. @@ -18322,6 +18498,9 @@ vectorize_vec_perm_const_1 (const struct expand_vec_perm_d &d) if (expand_perm_with_merge (d)) return true; + if (expand_perm_with_pack (d)) + return true; + if (expand_perm_with_vpdi (d)) return true; diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 97a4bdf96b2d..1edbfde4a981 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -121,6 +121,7 @@ ; Test Data Class (TDC) UNSPEC_TDC_INSN + UNSPEC_SIGNBIT ; Byte-wise Population Count UNSPEC_POPCNT @@ -139,9 +140,6 @@ UNSPEC_LCBB ; Vector - UNSPEC_VEC_SMULT_HI - UNSPEC_VEC_UMULT_HI - UNSPEC_VEC_SMULT_LO UNSPEC_VEC_SMULT_EVEN UNSPEC_VEC_UMULT_EVEN UNSPEC_VEC_SMULT_ODD @@ -241,9 +239,6 @@ UNSPEC_VEC_MSUM - UNSPEC_VEC_VFMIN - UNSPEC_VEC_VFMAX - UNSPEC_VEC_VBLEND UNSPEC_VEC_VEVAL UNSPEC_VEC_VGEM @@ -256,6 +251,9 @@ UNSPEC_NNPA_VCFN_V8HI UNSPEC_NNPA_VCNF_V8HI + + UNSPEC_FMAX + UNSPEC_FMIN ]) ;; @@ -311,6 +309,9 @@ UNSPECV_SPLIT_STACK_CALL UNSPECV_OSC_BREAK + + ; Stack Protector + UNSPECV_SP_GET_TP ]) ;; @@ -368,6 +369,9 @@ (VR23_REGNUM 45) (VR24_REGNUM 46) (VR31_REGNUM 53) + ; Access registers + (AR0_REGNUM 36) + (AR1_REGNUM 37) ]) ; Rounding modes for binary floating point numbers @@ -510,7 +514,7 @@ S390_TDC_INFINITY S390_TDC_NORMAL_BFP]) -(define_int_attr tdc_insn [(S390_TDC_SIGNBIT_SET "signbit") +(define_int_attr tdc_insn [(S390_TDC_SIGNBIT_SET "signbit_tdc") (S390_TDC_FINITE "isfinite") (S390_TDC_INFINITY "isinf") (S390_TDC_NORMAL_BFP "isnormal") @@ -3779,6 +3783,86 @@ (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))] "TARGET_HARD_DFP") +(define_mode_iterator SIGNBIT_SINGLE [(SF "TARGET_HARD_FLOAT") + (SD "TARGET_HARD_DFP")]) +(define_expand "signbit<mode>2" + [(match_operand:SI 0 "register_operand") + (match_operand:SIGNBIT_SINGLE 1 "nonimmediate_operand")] + "" +{ + if (TARGET_VX && TARGET_64BIT) + { + emit_insn (gen_rtx_SET (operands[0], simplify_gen_subreg (SImode, operands[1], <MODE>mode, 0))); + emit_insn (gen_rtx_SET (operands[0], gen_rtx_LSHIFTRT (SImode, operands[0], GEN_INT (31)))); + } + else if (TARGET_Z10 && TARGET_64BIT) + emit_insn (gen_signbit<mode>2_z10 (operands[0], operands[1])); + else + emit_insn (gen_signbit_tdc<mode>2 (operands[0], force_reg (<MODE>mode, operands[1]))); + DONE; +}) + +(define_insn "signbit<mode>2_z10" + [(set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(match_operand:SIGNBIT_SINGLE 1 "nonimmediate_operand" "fRT")] + UNSPEC_SIGNBIT))] + "TARGET_Z10 && TARGET_64BIT" + "#") + +(define_split + [(set (match_operand:SI 0 "register_operand") + (unspec:SI [(match_operand:SIGNBIT_SINGLE 1 "register_operand")] + UNSPEC_SIGNBIT))] + "TARGET_Z10 && TARGET_64BIT && reload_completed" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 63)))] +{ + operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); + operands[1] = gen_rtx_REG (DImode, REGNO (operands[1])); +}) + +(define_split + [(set (match_operand:SI 0 "register_operand") + (unspec:SI [(match_operand:SIGNBIT_SINGLE 1 "memory_operand")] + UNSPEC_SIGNBIT))] + "TARGET_Z10 && TARGET_64BIT && reload_completed" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))] +{ + operands[1] = change_address (operands[1], SImode, 0); +}) + +(define_mode_iterator SIGNBIT_DBL_TETRA [(DF "TARGET_HARD_FLOAT") + (TF "TARGET_HARD_FLOAT") + (DD "TARGET_HARD_DFP") + (TD "TARGET_HARD_DFP")]) +(define_expand "signbit<mode>2" + [(match_operand:SI 0 "register_operand") + (match_operand:SIGNBIT_DBL_TETRA 1 "nonimmediate_operand")] + "" +{ + if (TARGET_Z10 && TARGET_64BIT) + { + rtx reg_di = gen_reg_rtx (DImode); + if (<MODE>mode == TFmode || <MODE>mode == TDmode) + { + rtx reg_ti = gen_reg_rtx (TImode); + emit_insn (gen_rtx_SET (reg_ti, simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0))); + emit_insn (gen_rtx_SET (reg_di, simplify_gen_subreg (DImode, reg_ti, TImode, 0))); + } + else + emit_insn (gen_rtx_SET (reg_di, simplify_gen_subreg (DImode, operands[1], <MODE>mode, 0))); + emit_insn (gen_rtx_SET (reg_di, gen_rtx_LSHIFTRT (DImode, reg_di, GEN_INT (63)))); + rtx subreg = gen_rtx_SUBREG (SImode, reg_di, 4); + SUBREG_PROMOTED_VAR_P (subreg) = 1; + SUBREG_PROMOTED_SET (subreg, SRP_SIGNED_AND_UNSIGNED); + emit_insn (gen_rtx_SET (operands[0], subreg)); + } + else + emit_insn (gen_signbit_tdc<mode>2 (operands[0], force_reg (<MODE>mode, operands[1]))); + DONE; +}) + ; This extracts CC into a GPR properly shifted. The actual IPM ; instruction will be issued by reload. The constraint of operand 1 ; forces reload to use a GPR. So reload will issue a movcc insn for @@ -11927,15 +12011,43 @@ ; Stack Protector Patterns ; +; Insns stack_protect_get_tp{si,di} are similar to *get_tp_{31,64} but still +; distinct in the sense that they force recomputation of the thread pointer +; instead of potentially reloading it from stack. + +(define_insn_and_split "stack_protect_get_tpsi" + [(set (match_operand:SI 0 "register_operand" "=d") + (unspec_volatile:SI [(const_int 0)] UNSPECV_SP_GET_TP))] + "" + "#" + "&& reload_completed" + [(set (match_dup 0) (reg:SI AR0_REGNUM))]) + +(define_insn_and_split "stack_protect_get_tpdi" + [(set (match_operand:DI 0 "register_operand" "=d") + (unspec_volatile:DI [(const_int 0)] UNSPECV_SP_GET_TP))] + "" + "#" + "&& reload_completed" + [(set (match_dup 1) (reg:SI AR0_REGNUM)) + (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32))) + (set (strict_low_part (match_dup 1)) (reg:SI AR1_REGNUM))] + "operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]));") + (define_expand "stack_protect_set" [(set (match_operand 0 "memory_operand" "") (match_operand 1 "memory_operand" ""))] "" { #ifdef TARGET_THREAD_SSP_OFFSET + rtx tp = gen_reg_rtx (Pmode); + if (TARGET_64BIT) + emit_insn (gen_stack_protect_get_tpdi (tp)); + else + emit_insn (gen_stack_protect_get_tpsi (tp)); operands[1] - = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), - GEN_INT (TARGET_THREAD_SSP_OFFSET))); + = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, tp, + GEN_INT (TARGET_THREAD_SSP_OFFSET))); #endif if (TARGET_64BIT) emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); @@ -11961,9 +12073,14 @@ { rtx cc_reg, test; #ifdef TARGET_THREAD_SSP_OFFSET + rtx tp = gen_reg_rtx (Pmode); + if (TARGET_64BIT) + emit_insn (gen_stack_protect_get_tpdi (tp)); + else + emit_insn (gen_stack_protect_get_tpsi (tp)); operands[1] - = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), - GEN_INT (TARGET_THREAD_SSP_OFFSET))); + = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, tp, + GEN_INT (TARGET_THREAD_SSP_OFFSET))); #endif if (TARGET_64BIT) emit_insn (gen_stack_protect_testdi (operands[0], operands[1])); diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md index 6f4e1929eb80..12bbeb640723 100644 --- a/gcc/config/s390/vector.md +++ b/gcc/config/s390/vector.md @@ -75,7 +75,7 @@ V1DF V2DF (V1TF "TARGET_VXE") (TF "TARGET_VXE")]) -(define_mode_iterator VF [(V2SF "TARGET_VXE") (V4SF "TARGET_VXE") V2DF]) +(define_mode_iterator VF [V2SF V4SF V2DF]) ; All modes present in V_HW1 and VFT. (define_mode_iterator V_HW1_FT [V16QI V8HI V4SI V2DI V1TI V1DF @@ -89,6 +89,13 @@ (define_mode_iterator VF_HW [(V4SF "TARGET_VXE") V2DF (V1TF "TARGET_VXE") (TF "TARGET_VXE")]) +; FP scalar and vector modes +(define_mode_iterator VFT_BFP [SF DF + (V1SF "TARGET_VXE") (V2SF "TARGET_VXE") (V4SF "TARGET_VXE") + V1DF V2DF + (V1TF "TARGET_VXE") (TF "TARGET_VXE")]) + + (define_mode_iterator V_8 [V1QI]) (define_mode_iterator V_16 [V2QI V1HI]) (define_mode_iterator V_32 [V4QI V2HI V1SI V1SF]) @@ -142,13 +149,13 @@ ; The instruction suffix for integer instructions and instructions ; which do not care about whether it is floating point or integer. -(define_mode_attr bhfgq[(V1QI "b") (V2QI "b") (V4QI "b") (V8QI "b") (V16QI "b") - (V1HI "h") (V2HI "h") (V4HI "h") (V8HI "h") - (V1SI "f") (V2SI "f") (V4SI "f") - (V1DI "g") (V2DI "g") +(define_mode_attr bhfgq[(V1QI "b") (V2QI "b") (V4QI "b") (V8QI "b") (V16QI "b") (QI "b") + (V1HI "h") (V2HI "h") (V4HI "h") (V8HI "h") (HI "h") + (V1SI "f") (V2SI "f") (V4SI "f") (SI "f") + (V1DI "g") (V2DI "g") (DI "g") (V1TI "q") (TI "q") - (V1SF "f") (V2SF "f") (V4SF "f") - (V1DF "g") (V2DF "g") + (V1SF "f") (V2SF "f") (V4SF "f") (SF "f") + (V1DF "g") (V2DF "g") (DF "g") (V1TF "q") (TF "q")]) ; This is for vmalhw. It gets an 'w' attached to avoid confusion with @@ -494,6 +501,54 @@ SIL,SIL,RI,RI,RRE,RRE,RIL,RR,RXY,RXY,RIL")]) +; Instructions vlgvb, vlgvh, vlgvf zero all remaining bits of a GPR, i.e., +; an implicit zero extend is done. + +(define_insn "*movdi<mode>_zero_extend_A" + [(set (match_operand:DI 0 "register_operand" "=d") + (zero_extend:DI (match_operand:SINT 1 "register_operand" "v")))] + "TARGET_VX" + "vlgv<bhfgq>\t%0,%v1,0" + [(set_attr "op_type" "VRS")]) + +(define_insn "*movsi<mode>_zero_extend_A" + [(set (match_operand:SI 0 "register_operand" "=d") + (zero_extend:SI (match_operand:HQI 1 "register_operand" "v")))] + "TARGET_VX" + "vlgv<bhfgq>\t%0,%v1,0" + [(set_attr "op_type" "VRS")]) + +(define_mode_iterator VLGV_DI [V1QI V2QI V4QI V8QI V16QI + V1HI V2HI V4HI V8HI + V1SI V2SI V4SI]) +(define_insn "*movdi<mode>_zero_extend_B" + [(set (match_operand:DI 0 "register_operand" "=d") + (zero_extend:DI (vec_select:<non_vec> + (match_operand:VLGV_DI 1 "register_operand" "v") + (parallel [(match_operand:SI 2 "const_int_operand" "n")]))))] + "TARGET_VX" +{ + operands[2] = GEN_INT (UINTVAL (operands[2]) & (GET_MODE_NUNITS (<MODE>mode) - 1)); + return "vlgv<bhfgq>\t%0,%v1,%Y2"; +} + [(set_attr "op_type" "VRS") + (set_attr "mnemonic" "vlgv<bhfgq>")]) + +(define_mode_iterator VLGV_SI [V1QI V2QI V4QI V8QI V16QI + V1HI V2HI V4HI V8HI]) +(define_insn "*movsi<mode>_zero_extend_B" + [(set (match_operand:SI 0 "register_operand" "=d") + (zero_extend:SI (vec_select:<non_vec> + (match_operand:VLGV_SI 1 "register_operand" "v") + (parallel [(match_operand:SI 2 "const_int_operand" "n")]))))] + "TARGET_VX" +{ + operands[2] = GEN_INT (UINTVAL (operands[2]) & (GET_MODE_NUNITS (<MODE>mode) - 1)); + return "vlgv<bhfgq>\t%0,%v1,%Y2"; +} + [(set_attr "op_type" "VRS") + (set_attr "mnemonic" "vlgv<bhfgq>")]) + ; vec_load_lanes? ; vec_store_lanes? @@ -512,7 +567,7 @@ (define_mode_iterator VEC_SET_NONFLOAT [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V2SF V4SF]) ; Iterator for single element float vectors -(define_mode_iterator VEC_SET_SINGLEFLOAT [(V1SF "TARGET_VXE") V1DF (V1TF "TARGET_VXE")]) +(define_mode_iterator VEC_SET_SINGLEFLOAT [V1SF V1DF (V1TF "TARGET_VXE")]) ; FIXME: Support also vector mode operands for 1 ; FIXME: A target memory operand seems to be useful otherwise we end @@ -3565,14 +3620,341 @@ "veval\t%v0,%v1,%v2,%v3,%b4" [(set_attr "op_type" "VRI")]) -; reduc_smin -; reduc_smax -; reduc_umin -; reduc_umax - ; vec_pack_sfix_trunc: convert + pack ? ; vec_pack_ufix_trunc ; vec_unpacks_float_hi ; vec_unpacks_float_lo ; vec_unpacku_float_hi ; vec_unpacku_float_lo + +(define_expand "avg<mode>3_ceil" + [(set (match_operand:VIT_HW_VXE3_T 0 "register_operand") + (unspec:VIT_HW_VXE3_T [(match_operand:VIT_HW_VXE3_T 1 "register_operand") + (match_operand:VIT_HW_VXE3_T 2 "register_operand")] + UNSPEC_VEC_AVG))] + "TARGET_VX") + +(define_expand "uavg<mode>3_ceil" + [(set (match_operand:VIT_HW_VXE3_T 0 "register_operand") + (unspec:VIT_HW_VXE3_T [(match_operand:VIT_HW_VXE3_T 1 "register_operand") + (match_operand:VIT_HW_VXE3_T 2 "register_operand")] + UNSPEC_VEC_AVGU))] + "TARGET_VX") + +(define_expand "smul<mode>3_highpart" + [(set (match_operand:VIT_HW_VXE3_DT 0 "register_operand") + (smul_highpart:VIT_HW_VXE3_DT (match_operand:VIT_HW_VXE3_DT 1 "register_operand") + (match_operand:VIT_HW_VXE3_DT 2 "register_operand")))] + "TARGET_VX") + +(define_expand "umul<mode>3_highpart" + [(set (match_operand:VIT_HW_VXE3_DT 0 "register_operand") + (umul_highpart:VIT_HW_VXE3_DT (match_operand:VIT_HW_VXE3_DT 1 "register_operand") + (match_operand:VIT_HW_VXE3_DT 2 "register_operand")))] + "TARGET_VX") + +; fmax +(define_expand "fmax<mode>3" + [(set (match_operand:VFT_BFP 0 "register_operand") + (unspec:VFT_BFP [(match_operand:VFT_BFP 1 "register_operand") + (match_operand:VFT_BFP 2 "register_operand") + (const_int 4)] + UNSPEC_FMAX))] + "TARGET_VXE") + +; fmin +(define_expand "fmin<mode>3" + [(set (match_operand:VFT_BFP 0 "register_operand") + (unspec:VFT_BFP [(match_operand:VFT_BFP 1 "register_operand") + (match_operand:VFT_BFP 2 "register_operand") + (const_int 4)] + UNSPEC_FMIN))] + "TARGET_VXE") + +; reduc_plus +(define_expand "reduc_plus_scal_<mode>" + [(set (match_dup 4) + (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand") + (match_dup 2)] + UNSPEC_VEC_VSUM)) + (set (match_dup 5) + (unspec:V2DI [(match_dup 4) (match_dup 3)] UNSPEC_VEC_VSUMQ)) + (set (match_operand:<non_vec> 0 "register_operand") + (vec_select:<non_vec> (match_dup 6) + (parallel [(match_dup 7)])))] + "TARGET_VX" +{ + operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode)); + operands[3] = simplify_gen_subreg (V4SImode, operands[2], <MODE>mode, 0); + operands[4] = gen_reg_rtx (V4SImode); + operands[5] = gen_reg_rtx (V2DImode); + operands[6] = simplify_gen_subreg (<MODE>mode, operands[5], V2DImode, 0); + operands[7] = GEN_INT (16 / GET_MODE_SIZE (<non_vec>mode) - 1); +}) + +(define_expand "reduc_plus_scal_<mode>" + [(set (match_dup 3) + (unspec:V2DI [(match_operand:VI_HW_SD 1 "register_operand") + (match_dup 2)] + UNSPEC_VEC_VSUMQ)) + (set (match_operand:<non_vec> 0 "register_operand") + (vec_select:<non_vec> (match_dup 4) + (parallel [(match_dup 5)])))] + "TARGET_VX" +{ + operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode)); + operands[3] = gen_reg_rtx (V2DImode); + operands[4] = simplify_gen_subreg (<MODE>mode, operands[3], V2DImode, 0); + operands[5] = GEN_INT (16 / GET_MODE_SIZE (<non_vec>mode) - 1); +}) + +(define_expand "reduc_plus_scal_v2df" + [(set (match_dup 2) + (unspec:V2DF [(match_operand:V2DF 1 "register_operand") + (match_dup 1) + (const_int 8)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 3) (plus:V2DF (match_dup 1) (match_dup 2))) + (set (match_operand:DF 0 "register_operand") + (vec_select:DF (match_dup 3) (parallel [(const_int 0)])))] + "TARGET_VX" +{ + operands[2] = gen_reg_rtx (V2DFmode); + operands[3] = gen_reg_rtx (V2DFmode); +}) + +(define_expand "reduc_plus_scal_v4sf" + [(set (match_dup 2) + (unspec:V4SF [(match_operand:V4SF 1 "register_operand") + (match_dup 1) + (const_int 4)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 3) (plus:V4SF (match_dup 1) (match_dup 2))) + (set (match_dup 4) + (unspec:V4SF [(match_dup 3) (match_dup 3) (const_int 8)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 5) (plus:V4SF (match_dup 3) (match_dup 4))) + (set (match_operand:SF 0 "register_operand") + (vec_select:SF (match_dup 5) (parallel [(const_int 0)])))] + "TARGET_VXE" +{ + operands[2] = gen_reg_rtx (V4SFmode); + operands[3] = gen_reg_rtx (V4SFmode); + operands[4] = gen_reg_rtx (V4SFmode); + operands[5] = gen_reg_rtx (V4SFmode); +}) + +; reduc_fmin, reduc_fmax, reduc_smin, reduc_smax + +(define_int_iterator REDUC_FMINMAX [UNSPEC_FMAX UNSPEC_FMIN]) +(define_int_attr reduc_fminmax_name [(UNSPEC_FMAX "fmax") (UNSPEC_FMIN "fmin")]) +(define_code_iterator REDUC_MINMAX [smin smax]) +(define_code_attr reduc_minmax_name [(smin "smin") (smax "smax")]) + +(define_expand "reduc_<reduc_fminmax_name>_scal_v2df" + [(set (match_dup 2) + (unspec:V2DF [(match_operand:V2DF 1 "register_operand") + (match_dup 1) + (const_int 8)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 3) + (unspec:V2DF [(match_dup 1) (match_dup 2) (const_int 4)] REDUC_FMINMAX)) + (set (match_operand:DF 0 "register_operand" "") + (vec_select:DF (match_dup 3) (parallel [(const_int 0)])))] + "TARGET_VX" +{ + operands[2] = gen_reg_rtx (V2DFmode); + operands[3] = gen_reg_rtx (V2DFmode); +}) + +(define_expand "reduc_<reduc_fminmax_name>_scal_v4sf" + [(set (match_dup 2) + (unspec:V4SF [(match_operand:V4SF 1 "register_operand") + (match_dup 1) + (const_int 4)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 3) + (unspec:V4SF [(match_dup 1) (match_dup 2) (const_int 4)] REDUC_FMINMAX)) + (set (match_dup 4) + (unspec:V4SF [(match_dup 3) + (match_dup 3) + (const_int 8)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 5) + (unspec:V4SF [(match_dup 3) (match_dup 4) (const_int 4)] REDUC_FMINMAX)) + (set (match_operand:SF 0 "register_operand") + (vec_select:SF (match_dup 5) (parallel [(const_int 0)])))] + "TARGET_VXE" +{ + operands[2] = gen_reg_rtx (V4SFmode); + operands[3] = gen_reg_rtx (V4SFmode); + operands[4] = gen_reg_rtx (V4SFmode); + operands[5] = gen_reg_rtx (V4SFmode); +}) + +(define_expand "reduc_<reduc_minmax_name>_scal_v2df" + [(set (match_dup 2) + (unspec:V2DF [(match_operand:V2DF 1 "register_operand") + (match_dup 1) + (const_int 8)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 3) + (REDUC_MINMAX:V2DF (match_dup 1) (match_dup 2))) + (set (match_operand:DF 0 "register_operand" "") + (vec_select:DF (match_dup 3) (parallel [(const_int 0)])))] + "TARGET_VX" +{ + operands[2] = gen_reg_rtx (V2DFmode); + operands[3] = gen_reg_rtx (V2DFmode); +}) + +(define_expand "reduc_<reduc_minmax_name>_scal_v4sf" + [(set (match_dup 2) + (unspec:V4SF [(match_operand:V4SF 1 "register_operand") + (match_dup 1) + (const_int 4)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 3) + (REDUC_MINMAX:V4SF (match_dup 1) (match_dup 2))) + (set (match_dup 4) + (unspec:V4SF [(match_dup 3) + (match_dup 3) + (const_int 8)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 5) + (REDUC_MINMAX:V4SF (match_dup 3) (match_dup 4))) + (set (match_operand:SF 0 "register_operand" "") + (vec_select:SF (match_dup 5) (parallel [(const_int 0)])))] + "TARGET_VXE" +{ + operands[2] = gen_reg_rtx (V4SFmode); + operands[3] = gen_reg_rtx (V4SFmode); + operands[4] = gen_reg_rtx (V4SFmode); + operands[5] = gen_reg_rtx (V4SFmode); +}) + +; reduce_and, reduc_ior, reduc_xor +; reduc_smin, reduc_smax, reduc_umin, reduc_umax + +(define_code_iterator REDUCBIN [and xor ior smin smax umin umax]) +(define_code_attr reduc_bin_insn [(and "and") (xor "xor") (ior "ior") + (smin "smin") (smax "smax") + (umin "umin") (umax "umax")]) + +(define_expand "reduc_<reduc_bin_insn>_scal_v2di" + [(set (match_dup 2) + (unspec:V2DI [(match_operand:V2DI 1 "register_operand") + (match_dup 1) + (const_int 8)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 3) + (REDUCBIN:V2DI (match_dup 1) (match_dup 2))) + (set (match_operand:DI 0 "register_operand" "") + (vec_select:DI (match_dup 3) (parallel [(const_int 0)])))] + "TARGET_VX" +{ + operands[2] = gen_reg_rtx (V2DImode); + operands[3] = gen_reg_rtx (V2DImode); +}) + +(define_expand "reduc_<reduc_bin_insn>_scal_v4si" + [(set (match_dup 2) + (unspec:V4SI [(match_operand:V4SI 1 "register_operand") + (match_dup 1) + (const_int 4)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 3) + (REDUCBIN:V4SI (match_dup 1) (match_dup 2))) + (set (match_dup 4) + (unspec:V4SI [(match_dup 3) + (match_dup 3) + (const_int 8)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 5) + (REDUCBIN:V4SI (match_dup 3) (match_dup 4))) + (set (match_operand:SI 0 "register_operand" "") + (vec_select:SI (match_dup 5) (parallel [(const_int 0)])))] + "TARGET_VX" +{ + operands[2] = gen_reg_rtx (V4SImode); + operands[3] = gen_reg_rtx (V4SImode); + operands[4] = gen_reg_rtx (V4SImode); + operands[5] = gen_reg_rtx (V4SImode); +}) + +(define_expand "reduc_<reduc_bin_insn>_scal_v8hi" + [(set (match_dup 2) + (unspec:V8HI [(match_operand:V8HI 1 "register_operand") + (match_dup 1) + (const_int 2)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 3) + (REDUCBIN:V8HI (match_dup 1) (match_dup 2))) + (set (match_dup 4) + (unspec:V8HI [(match_dup 3) + (match_dup 3) + (const_int 4)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 5) + (REDUCBIN:V8HI (match_dup 3) (match_dup 4))) + (set (match_dup 6) + (unspec:V8HI [(match_dup 5) + (match_dup 5) + (const_int 8)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 7) + (REDUCBIN:V8HI (match_dup 5) (match_dup 6))) + (set (match_operand:HI 0 "register_operand" "") + (vec_select:HI (match_dup 7) (parallel [(const_int 0)])))] + "TARGET_VX" +{ + operands[2] = gen_reg_rtx (V8HImode); + operands[3] = gen_reg_rtx (V8HImode); + operands[4] = gen_reg_rtx (V8HImode); + operands[5] = gen_reg_rtx (V8HImode); + operands[6] = gen_reg_rtx (V8HImode); + operands[7] = gen_reg_rtx (V8HImode); +}) + +(define_expand "reduc_<reduc_bin_insn>_scal_v16qi" + [(set (match_dup 2) + (unspec:V16QI [(match_operand:V16QI 1 "register_operand") + (match_dup 1) + (const_int 1)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 3) + (REDUCBIN:V16QI (match_dup 1) (match_dup 2))) + (set (match_dup 4) + (unspec:V16QI [(match_dup 3) + (match_dup 3) + (const_int 2)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 5) + (REDUCBIN:V16QI (match_dup 3) (match_dup 4))) + (set (match_dup 6) + (unspec:V16QI [(match_dup 5) + (match_dup 5) + (const_int 4)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 7) + (REDUCBIN:V16QI (match_dup 5) (match_dup 6))) + (set (match_dup 8) + (unspec:V16QI [(match_dup 7) + (match_dup 7) + (const_int 8)] + UNSPEC_VEC_SLDBYTE)) + (set (match_dup 9) + (REDUCBIN:V16QI (match_dup 7) (match_dup 8))) + (set (match_operand:QI 0 "register_operand" "") + (vec_select:QI (match_dup 9) (parallel [(const_int 0)])))] + "TARGET_VX" +{ + operands[2] = gen_reg_rtx (V16QImode); + operands[3] = gen_reg_rtx (V16QImode); + operands[4] = gen_reg_rtx (V16QImode); + operands[5] = gen_reg_rtx (V16QImode); + operands[6] = gen_reg_rtx (V16QImode); + operands[7] = gen_reg_rtx (V16QImode); + operands[8] = gen_reg_rtx (V16QImode); + operands[9] = gen_reg_rtx (V16QImode); +}) diff --git a/gcc/config/s390/vx-builtins.md b/gcc/config/s390/vx-builtins.md index a7bb7ff92f5e..9b89b131a81f 100644 --- a/gcc/config/s390/vx-builtins.md +++ b/gcc/config/s390/vx-builtins.md @@ -982,20 +982,18 @@ ; vmhb, vmhh, vmhf, vmhg, vmhq (define_insn "vec_smulh<mode>" - [(set (match_operand:VIT_HW_VXE3_DT 0 "register_operand" "=v") - (unspec:VIT_HW_VXE3_DT [(match_operand:VIT_HW_VXE3_DT 1 "register_operand" "v") - (match_operand:VIT_HW_VXE3_DT 2 "register_operand" "v")] - UNSPEC_VEC_SMULT_HI))] + [(set (match_operand:VIT_HW_VXE3_DT 0 "register_operand" "=v") + (smul_highpart:VIT_HW_VXE3_DT (match_operand:VIT_HW_VXE3_DT 1 "register_operand" "v") + (match_operand:VIT_HW_VXE3_DT 2 "register_operand" "v")))] "TARGET_VX" "vmh<bhfgq>\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")]) ; vmlhb, vmlhh, vmlhf, vmlhg, vmlhq (define_insn "vec_umulh<mode>" - [(set (match_operand:VIT_HW_VXE3_DT 0 "register_operand" "=v") - (unspec:VIT_HW_VXE3_DT [(match_operand:VIT_HW_VXE3_DT 1 "register_operand" "v") - (match_operand:VIT_HW_VXE3_DT 2 "register_operand" "v")] - UNSPEC_VEC_UMULT_HI))] + [(set (match_operand:VIT_HW_VXE3_DT 0 "register_operand" "=v") + (umul_highpart:VIT_HW_VXE3_DT (match_operand:VIT_HW_VXE3_DT 1 "register_operand" "v") + (match_operand:VIT_HW_VXE3_DT 2 "register_operand" "v")))] "TARGET_VX" "vmlh<bhfgq>\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")]) @@ -2136,23 +2134,22 @@ "<vw>fche<sdx>bs\t%v2,%v0,%v1" [(set_attr "op_type" "VRR")]) - (define_insn "vfmin<mode>" - [(set (match_operand:VF_HW 0 "register_operand" "=v") - (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "v") - (match_operand:VF_HW 2 "register_operand" "v") - (match_operand:QI 3 "const_mask_operand" "C")] - UNSPEC_VEC_VFMIN))] + [(set (match_operand:VFT_BFP 0 "register_operand" "=v") + (unspec:VFT_BFP [(match_operand:VFT_BFP 1 "register_operand" "v") + (match_operand:VFT_BFP 2 "register_operand" "v") + (match_operand:QI 3 "const_mask_operand" "C")] + UNSPEC_FMIN))] "TARGET_VXE" "<vw>fmin<sdx>b\t%v0,%v1,%v2,%b3" [(set_attr "op_type" "VRR")]) (define_insn "vfmax<mode>" - [(set (match_operand:VF_HW 0 "register_operand" "=v") - (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "v") - (match_operand:VF_HW 2 "register_operand" "v") - (match_operand:QI 3 "const_mask_operand" "C")] - UNSPEC_VEC_VFMAX))] + [(set (match_operand:VFT_BFP 0 "register_operand" "=v") + (unspec:VFT_BFP [(match_operand:VFT_BFP 1 "register_operand" "v") + (match_operand:VFT_BFP 2 "register_operand" "v") + (match_operand:QI 3 "const_mask_operand" "C")] + UNSPEC_FMAX))] "TARGET_VXE" "<vw>fmax<sdx>b\t%v0,%v1,%v2,%b3" [(set_attr "op_type" "VRR")]) diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md index 7349c97a2b56..e67ec8a23202 100644 --- a/gcc/config/sh/predicates.md +++ b/gcc/config/sh/predicates.md @@ -630,9 +630,7 @@ ;; Same as treg_set_expr but disallow constants 0 and 1 which can be loaded ;; into the T bit. (define_predicate "treg_set_expr_not_const01" - (and (match_test "op != const0_rtx") - (match_test "op != const1_rtx") - (match_operand 0 "treg_set_expr"))) + (match_test "sh_recog_treg_set_expr_not_01 (op, mode)")) ;; A predicate describing the T bit register in any form. (define_predicate "t_reg_operand" diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h index c8cc19f4dc75..e78b6697a2b1 100644 --- a/gcc/config/sh/sh-protos.h +++ b/gcc/config/sh/sh-protos.h @@ -261,6 +261,7 @@ extern rtx_insn* sh_peephole_emit_move_insn (rtx dst, rtx src); extern bool sh_in_recog_treg_set_expr (void); extern bool sh_recog_treg_set_expr (rtx op, machine_mode mode); +extern bool sh_recog_treg_set_expr_not_01 (rtx op, machine_mode mode); /* Result value of sh_split_treg_set_expr. Contains the first insn emitted and the optional trailing nott insn. */ diff --git a/gcc/config/sh/sh.cc b/gcc/config/sh/sh.cc index 1bc34e0a3e39..09e4ff77c207 100644 --- a/gcc/config/sh/sh.cc +++ b/gcc/config/sh/sh.cc @@ -12348,6 +12348,23 @@ sh_recog_treg_set_expr (rtx op, machine_mode mode) return result >= 0; } +/* Return TRUE if OP is an expression for which there is a pattern to + set the T bit unless the expression is trivially loadable into + the T bit, FALSE otherwise. */ +bool +sh_recog_treg_set_expr_not_01 (rtx op, machine_mode mode) +{ + if (op == const0_rtx || op == const1_rtx) + return false; + + /* A right shift of 31 will return 0 or 1. */ + if ((GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ASHIFTRT) + && INTVAL (XEXP (op, 1)) == 31) + return false; + + return sh_recog_treg_set_expr (op, mode); +} + /* Returns true when recog of a 'treg_set_expr' is currently in progress. This can be used as a condition for insn/split patterns to allow certain T bit setting patters only to be matched as sub expressions of other diff --git a/gcc/config/vxworks-dummy.h b/gcc/config/vxworks-dummy.h index 494799da5f9a..516728c6eff7 100644 --- a/gcc/config/vxworks-dummy.h +++ b/gcc/config/vxworks-dummy.h @@ -40,9 +40,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define TARGET_VXWORKS_RTP false #endif +/* True if offsets between different segments may vary, so we must avoid + cross-segment GOT- and PC-relative address computations. */ +#ifndef TARGET_VXWORKS_VAROFF +#define TARGET_VXWORKS_VAROFF false +#endif + /* The symbol that points to an RTP's table of GOTs. */ #define VXWORKS_GOTT_BASE (gcc_unreachable (), "") /* The symbol that holds the index of the current module's GOT in VXWORKS_GOTT_BASE. */ #define VXWORKS_GOTT_INDEX (gcc_unreachable (), "") + +/* True if PIC relies on the GOTT_* symbols above. As of VxWorks7, they are no + longer used. */ +#ifndef TARGET_VXWORKS_GOTTPIC +#define TARGET_VXWORKS_GOTTPIC false +#endif diff --git a/gcc/config/vxworks.h b/gcc/config/vxworks.h index 204a8e000d40..d2b6025caad9 100644 --- a/gcc/config/vxworks.h +++ b/gcc/config/vxworks.h @@ -159,6 +159,18 @@ extern void vxworks_driver_init (unsigned int *, struct cl_decoded_option **); Earlier versions did not, not even for RTPS. */ #define VXWORKS_HAVE_TLS TARGET_VXWORKS7 +/* RTP segments could be loaded with varying offsets, so cross-segment offsets + could not be assumed to be constant. This rules out some PC- and + GOT-relative addressing. */ +#undef TARGET_VXWORKS_VAROFF +#define TARGET_VXWORKS_VAROFF (!TARGET_VXWORKS7 && TARGET_VXWORKS_RTP) + +/* GOTT_BASE and GOTT_INDEX symbols are only used by some ports up to VxWorks6. + This macro is only used by i386 so far. Other ports seem to keep on using + GOTTPIC from VxWorks7 on, but they don't test this macro. */ +#undef TARGET_VXWORKS_GOTTPIC +#define TARGET_VXWORKS_GOTTPIC (!TARGET_VXWORKS7) + /* On Vx6 and previous, the libraries to pick up depends on the architecture, so cannot be defined for all archs at once. On Vx7, a VSB is always needed and its structure is fixed and does not depend on the arch. We can thus diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md index aad4146074af..9aeaba6ad723 100644 --- a/gcc/config/xtensa/predicates.md +++ b/gcc/config/xtensa/predicates.md @@ -183,19 +183,6 @@ (and (match_code "const_int") (match_test "xtensa_mem_offset (INTVAL (op), SFmode)"))) -(define_predicate "reload_operand" - (match_code "mem") -{ - const_rtx addr = XEXP (op, 0); - if (REG_P (addr)) - return REGNO (addr) == A1_REG; - if (GET_CODE (addr) == PLUS) - return REG_P (XEXP (addr, 0)) - && REGNO (XEXP (addr, 0)) == A1_REG - && CONST_INT_P (XEXP (addr, 1)); - return false; -}) - (define_predicate "branch_operator" (match_code "eq,ne,lt,ge")) diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc index a9d67a56cd6a..b75cec13b28a 100644 --- a/gcc/config/xtensa/xtensa.cc +++ b/gcc/config/xtensa/xtensa.cc @@ -159,6 +159,10 @@ static void xtensa_asm_trampoline_template (FILE *); static void xtensa_trampoline_init (rtx, tree, rtx); static bool xtensa_output_addr_const_extra (FILE *, rtx); static bool xtensa_cannot_force_const_mem (machine_mode, rtx); +static machine_mode xtensa_promote_function_mode (const_tree, + machine_mode, + int *, const_tree, + int); static reg_class_t xtensa_preferred_reload_class (rtx, reg_class_t); static reg_class_t xtensa_preferred_output_reload_class (rtx, reg_class_t); @@ -198,6 +202,7 @@ static void xtensa_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, static rtx xtensa_delegitimize_address (rtx); static reg_class_t xtensa_ira_change_pseudo_allocno_class (int, reg_class_t, reg_class_t); +static HARD_REG_SET xtensa_zero_call_used_regs (HARD_REG_SET); @@ -234,9 +239,7 @@ static reg_class_t xtensa_ira_change_pseudo_allocno_class (int, reg_class_t, #define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start #undef TARGET_PROMOTE_FUNCTION_MODE -#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote -#undef TARGET_PROMOTE_PROTOTYPES -#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true +#define TARGET_PROMOTE_FUNCTION_MODE xtensa_promote_function_mode #undef TARGET_RETURN_IN_MEMORY #define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory @@ -370,6 +373,9 @@ static reg_class_t xtensa_ira_change_pseudo_allocno_class (int, reg_class_t, #undef TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS #define TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS xtensa_ira_change_pseudo_allocno_class +#undef TARGET_ZERO_CALL_USED_REGS +#define TARGET_ZERO_CALL_USED_REGS xtensa_zero_call_used_regs + struct gcc_target targetm = TARGET_INITIALIZER; @@ -417,12 +423,13 @@ xtensa_uimm8x4 (HOST_WIDE_INT v) } -static bool -xtensa_b4const (HOST_WIDE_INT v) +bool +xtensa_b4const_or_zero (HOST_WIDE_INT v) { switch (v) { case -1: + case 0: case 1: case 2: case 3: @@ -444,15 +451,6 @@ xtensa_b4const (HOST_WIDE_INT v) } -bool -xtensa_b4const_or_zero (HOST_WIDE_INT v) -{ - if (v == 0) - return true; - return xtensa_b4const (v); -} - - bool xtensa_b4constu (HOST_WIDE_INT v) { @@ -3047,6 +3045,8 @@ xtensa_modes_tieable_p (machine_mode mode1, machine_mode mode2) 'K' CONST_INT, print number of bits in mask for EXTUI 'R' CONST_INT, print (X & 0x1f) 'L' CONST_INT, print ((32 - X) & 0x1f) + 'U', CONST_DOUBLE:SF, print (REAL_EXP (rval) - 1) + 'V', CONST_DOUBLE:SF, print (1 - REAL_EXP (rval)) 'D' REG, print second register of double-word register operand 'N' MEM, print address of next word following a memory operand 'v' MEM, if memory reference is volatile, output a MEMW before it @@ -3143,6 +3143,20 @@ print_operand (FILE *file, rtx x, int letter) output_operand_lossage ("invalid %%R value"); break; + case 'U': + if (CONST_DOUBLE_P (x) && GET_MODE (x) == SFmode) + fprintf (file, "%d", REAL_EXP (CONST_DOUBLE_REAL_VALUE (x)) - 1); + else + output_operand_lossage ("invalid %%U value"); + break; + + case 'V': + if (CONST_DOUBLE_P (x) && GET_MODE (x) == SFmode) + fprintf (file, "%d", 1 - REAL_EXP (CONST_DOUBLE_REAL_VALUE (x))); + else + output_operand_lossage ("invalid %%V value"); + break; + case 'x': if (CONST_INT_P (x)) printx (file, INTVAL (x)); @@ -4490,7 +4504,8 @@ xtensa_rtx_costs (rtx x, machine_mode mode, int outer_code, } break; case COMPARE: - if ((INTVAL (x) == 0) || xtensa_b4const (INTVAL (x))) + if (xtensa_b4const_or_zero (INTVAL (x)) + || xtensa_b4constu (INTVAL (x))) { *total = 0; return true; @@ -4781,6 +4796,19 @@ xtensa_insn_cost (rtx_insn *insn, bool speed) return pattern_cost (PATTERN (insn), speed); } +/* Worker function for TARGET_PROMOTE_FUNCTION_MODE. */ + +static machine_mode +xtensa_promote_function_mode (const_tree type, machine_mode mode, + int *punsignedp, const_tree, int) +{ + if (GET_MODE_CLASS (mode) == MODE_INT + && GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) + return SImode; + + return promote_mode (type, mode, punsignedp); +} + /* Worker function for TARGET_RETURN_IN_MEMORY. */ static bool @@ -5451,4 +5479,56 @@ xtensa_ira_change_pseudo_allocno_class (int regno, reg_class_t allocno_class, return FLOAT_MODE_P (PSEUDO_REGNO_MODE (regno)) ? FP_REGS : AR_REGS; } +/* Implement TARGET_ZERO_CALL_USED_REGS. */ + +static HARD_REG_SET +xtensa_zero_call_used_regs (HARD_REG_SET selected_regs) +{ + unsigned int regno; + int zeroed_regno = -1; + hard_reg_set_iterator hrsi; + rtvec argvec, convec; + + EXECUTE_IF_SET_IN_HARD_REG_SET (selected_regs, 1, regno, hrsi) + { + if (GP_REG_P (regno)) + { + emit_move_insn (gen_rtx_REG (SImode, regno), const0_rtx); + if (zeroed_regno < 0) + zeroed_regno = regno; + continue; + } + if (TARGET_BOOLEANS && BR_REG_P (regno)) + { + gcc_assert (zeroed_regno >= 0); + argvec = rtvec_alloc (1); + RTVEC_ELT (argvec, 0) = gen_rtx_REG (SImode, zeroed_regno); + convec = rtvec_alloc (1); + RTVEC_ELT (convec, 0) = gen_rtx_ASM_INPUT (SImode, "r"); + emit_insn (gen_rtx_ASM_OPERANDS (VOIDmode, "wsr\t%0, BR", + "", 0, argvec, convec, + rtvec_alloc (0), + UNKNOWN_LOCATION)); + continue; + } + if (TARGET_HARD_FLOAT && FP_REG_P (regno)) + { + gcc_assert (zeroed_regno >= 0); + emit_move_insn (gen_rtx_REG (SFmode, regno), + gen_rtx_REG (SFmode, zeroed_regno)); + continue; + } + if (TARGET_MAC16 && ACC_REG_P (regno)) + { + gcc_assert (zeroed_regno >= 0); + emit_move_insn (gen_rtx_REG (SImode, regno), + gen_rtx_REG (SImode, zeroed_regno)); + continue; + } + CLEAR_HARD_REG_BIT (selected_regs, regno); + } + + return selected_regs; +} + #include "gt-xtensa.h" diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h index 9009db010977..a8a0565c81e7 100644 --- a/gcc/config/xtensa/xtensa.h +++ b/gcc/config/xtensa/xtensa.h @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #define TARGET_MINMAX XCHAL_HAVE_MINMAX #define TARGET_SEXT XCHAL_HAVE_SEXT #define TARGET_CLAMPS XCHAL_HAVE_CLAMPS +#define TARGET_DEPBITS XCHAL_HAVE_DEPBITS #define TARGET_BOOLEANS XCHAL_HAVE_BOOLEANS #define TARGET_HARD_FLOAT XCHAL_HAVE_FP #define TARGET_HARD_FLOAT_DIV XCHAL_HAVE_FP_DIV diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index c7ac456ae5f3..029be99e3b4e 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -41,6 +41,8 @@ UNSPEC_LSETUP_START UNSPEC_LSETUP_END UNSPEC_FRAME_BLOCKAGE + UNSPEC_CEIL + UNSPEC_FLOOR ]) (define_c_enum "unspecv" [ @@ -103,6 +105,11 @@ (define_code_attr m_float [(float "float") (unsigned_float "ufloat")]) (define_code_attr s_float [(float "") (unsigned_float "uns")]) +;; This iterator and attribute allow FP-to-integer rounding of two types +;; to be generated from one template. +(define_int_iterator ANY_ROUND [UNSPEC_CEIL UNSPEC_FLOOR]) +(define_int_attr m_round [(UNSPEC_CEIL "ceil") (UNSPEC_FLOOR "floor")]) + ;; Attributes. @@ -1007,7 +1014,7 @@ (set_attr "length" "3")]) -;; Field extract instructions. +;; Field extract and insert instructions. (define_expand "extvsi" [(set (match_operand:SI 0 "register_operand" "") @@ -1141,6 +1148,25 @@ (set_attr "mode" "SI") (set_attr "length" "6")]) +(define_insn "insvsi" + [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+a") + (match_operand:SI 1 "extui_fldsz_operand" "i") + (match_operand:SI 2 "const_int_operand" "i")) + (match_operand:SI 3 "register_operand" "r"))] + "TARGET_DEPBITS" +{ + int shift; + if (BITS_BIG_ENDIAN) + shift = (32 - (INTVAL (operands[1]) + INTVAL (operands[2]))) & 0x1f; + else + shift = INTVAL (operands[2]) & 0x1f; + operands[2] = GEN_INT (shift); + return "depbits\t%0, %3, %2, %1"; +} + [(set_attr "type" "arith") + (set_attr "mode" "SI") + (set_attr "length" "3")]) + ;; Conversions. @@ -1168,12 +1194,7 @@ (any_fix:SI (mult:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "fix_scaling_operand" "F"))))] "TARGET_HARD_FLOAT" -{ - static char result[64]; - sprintf (result, "<m_fix>.s\t%%0, %%1, %d", - REAL_EXP (CONST_DOUBLE_REAL_VALUE (operands[2])) - 1); - return result; -} + "<m_fix>.s\t%0, %1, %U2" [(set_attr "type" "fconv") (set_attr "mode" "SF") (set_attr "length" "3")]) @@ -1192,12 +1213,36 @@ (mult:SF (any_float:SF (match_operand:SI 1 "register_operand" "a")) (match_operand:SF 2 "float_scaling_operand" "F")))] "TARGET_HARD_FLOAT" -{ - static char result[64]; - sprintf (result, "<m_float>.s\t%%0, %%1, %d", - 1 - REAL_EXP (CONST_DOUBLE_REAL_VALUE (operands[2]))); - return result; -} + "<m_float>.s\t%0, %1, %V2" + [(set_attr "type" "fconv") + (set_attr "mode" "SF") + (set_attr "length" "3")]) + +(define_insn "l<m_round>sfsi2" + [(set (match_operand:SI 0 "register_operand" "=a") + (unspec:SI [(match_operand:SF 1 "register_operand" "f")] ANY_ROUND))] + "TARGET_HARD_FLOAT" + "<m_round>.s\t%0, %1, 0" + [(set_attr "type" "fconv") + (set_attr "mode" "SF") + (set_attr "length" "3")]) + +(define_insn "*l<m_round>sfsi2_2x" + [(set (match_operand:SI 0 "register_operand" "=a") + (unspec:SI [(plus:SF (match_operand:SF 1 "register_operand" "f") + (match_dup 1))] ANY_ROUND))] + "TARGET_HARD_FLOAT" + "<m_round>.s\t%0, %1, 1" + [(set_attr "type" "fconv") + (set_attr "mode" "SF") + (set_attr "length" "3")]) + +(define_insn "*l<m_round>sfsi2_scaled" + [(set (match_operand:SI 0 "register_operand" "=a") + (unspec:SI [(mult:SF (match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "fix_scaling_operand" "F"))] ANY_ROUND))] + "TARGET_HARD_FLOAT" + "<m_round>.s\t%0, %1, %U2" [(set_attr "type" "fconv") (set_attr "mode" "SF") (set_attr "length" "3")]) @@ -3319,36 +3364,6 @@ (const_int 8) (const_int 9))))]) -(define_peephole2 - [(set (match_operand:SI 0 "register_operand") - (match_operand:SI 6 "reload_operand")) - (set (match_operand:SI 1 "register_operand") - (match_operand:SI 7 "reload_operand")) - (set (match_operand:SF 2 "register_operand") - (match_operand:SF 4 "register_operand")) - (set (match_operand:SF 3 "register_operand") - (match_operand:SF 5 "register_operand"))] - "REGNO (operands[0]) == REGNO (operands[4]) - && REGNO (operands[1]) == REGNO (operands[5]) - && peep2_reg_dead_p (4, operands[0]) - && peep2_reg_dead_p (4, operands[1])" - [(set (match_dup 2) - (match_dup 6)) - (set (match_dup 3) - (match_dup 7))] -{ - HARD_REG_SET regs; - int i; - CLEAR_HARD_REG_SET (regs); - for (i = 0; i <= 3; ++i) - if (TEST_HARD_REG_BIT (regs, REGNO (operands[i]))) - FAIL; - else - SET_HARD_REG_BIT (regs, REGNO (operands[i])); - operands[6] = gen_rtx_MEM (SFmode, XEXP (operands[6], 0)); - operands[7] = gen_rtx_MEM (SFmode, XEXP (operands[7], 0)); -}) - (define_split [(clobber (match_operand 0 "register_operand"))] "HARD_REGISTER_P (operands[0]) @@ -3434,49 +3449,3 @@ FALLTHRU:; operands[1] = GEN_INT (imm0); operands[2] = GEN_INT (imm1); }) - -(define_peephole2 - [(set (match_operand 0 "register_operand") - (match_operand 1 "register_operand"))] - "REG_NREGS (operands[0]) == 1 && GP_REG_P (REGNO (operands[0])) - && REG_NREGS (operands[1]) == 1 && GP_REG_P (REGNO (operands[1])) - && peep2_reg_dead_p (1, operands[1])" - [(const_int 0)] -{ - basic_block bb = BLOCK_FOR_INSN (curr_insn); - rtx_insn *head = BB_HEAD (bb), *insn; - rtx dest = operands[0], src = operands[1], pattern, t_dest, dest_orig; - for (insn = PREV_INSN (curr_insn); - insn && insn != head; - insn = PREV_INSN (insn)) - if (CALL_P (insn)) - break; - else if (INSN_P (insn)) - { - if (GET_CODE (pattern = PATTERN (insn)) == SET - && REG_P (t_dest = SET_DEST (pattern)) - && REG_NREGS (t_dest) == 1 - && REGNO (t_dest) == REGNO (src)) - { - dest_orig = SET_DEST (pattern); - SET_DEST (pattern) = gen_rtx_REG (GET_MODE (t_dest), - REGNO (dest)); - extract_insn (insn); - if (!constrain_operands (true, get_enabled_alternatives (insn))) - { - SET_DEST (pattern) = dest_orig; - goto ABORT; - } - df_insn_rescan (insn); - goto FALLTHRU; - } - if (reg_overlap_mentioned_p (dest, pattern) - || reg_overlap_mentioned_p (src, pattern) - || set_of (dest, insn) - || set_of (src, insn)) - break; - } -ABORT: - FAIL; -FALLTHRU:; -}) diff --git a/gcc/configure b/gcc/configure index 776b0628c602..7537da20291a 100755 --- a/gcc/configure +++ b/gcc/configure @@ -1064,6 +1064,7 @@ enable_versioned_jit enable_default_pie enable_cet enable_s390_excess_float_precision +enable_x86_64_mfentry ' ac_precious_vars='build_alias host_alias @@ -1842,6 +1843,7 @@ Optional Features: --enable-s390-excess-float-precision on s390 targets, evaluate float with double precision when in standards-conforming mode + --enable-x86-64-mfentry enable -mfentry by default on x86-64 targets Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -21520,7 +21522,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 21523 "configure" +#line 21525 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -21626,7 +21628,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 21629 "configure" +#line 21631 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -28247,6 +28249,43 @@ if test $gcc_cv_as_aarch64_picreloc = yes; then $as_echo "#define HAVE_AS_SMALL_PIC_RELOCS 1" >>confdefs.h +fi + + # Check if we have binutils support for AEABI build attributes. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for support of AEABI build attributes" >&5 +$as_echo_n "checking assembler for support of AEABI build attributes... " >&6; } +if ${gcc_cv_as_aarch64_aeabi_build_attributes+:} false; then : + $as_echo_n "(cached) " >&6 +else + gcc_cv_as_aarch64_aeabi_build_attributes=no + if test x$gcc_cv_as != x; then + $as_echo ' + .aeabi_subsection aeabi_feature_and_bits, optional, ULEB128 + .aeabi_attribute Tag_Feature_BTI, 1 + .aeabi_attribute Tag_Feature_PAC, 1 + .aeabi_attribute Tag_Feature_GCS, 1 + ' > conftest.s + if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + then + gcc_cv_as_aarch64_aeabi_build_attributes=yes + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_aarch64_aeabi_build_attributes" >&5 +$as_echo "$gcc_cv_as_aarch64_aeabi_build_attributes" >&6; } +if test $gcc_cv_as_aarch64_aeabi_build_attributes = yes; then + +$as_echo "#define HAVE_AS_AEABI_BUILD_ATTRIBUTES 1" >>confdefs.h + fi # Enable Branch Target Identification Mechanism and Return Address @@ -34985,6 +35024,46 @@ $as_echo "#define ENABLE_S390_EXCESS_FLOAT_PRECISION 1" >>confdefs.h ;; esac +# On x86-64, when profiling is enabled with shrink wrapping, the mcount +# call may not be placed at the function entry after +# pushq %rbp +# movq %rsp,%rbp +# As the result, the profile data may be skewed which makes PGO less +# effective: +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120881 +# Enable -mfentry by default on x86-64 to put the profiling counter call +# before the prologue. +# Check whether --enable-x86-64-mfentry was given. +if test "${enable_x86_64_mfentry+set}" = set; then : + enableval=$enable_x86_64_mfentry; case "${enableval}" in + yes | no | auto) + enable_x86_64_mfentry=$enableval + ;; + *) + as_fn_error $? "'$enable_x86_64_mfentry' is an invalid value for --enable-x86-64-mfentry. Valid choices are 'yes', 'no' and 'auto'." "$LINENO" 5 + ;; + esac +else + enable_x86_64_mfentry=auto +fi + + +if test x"$enable_x86_64_mfentry" = xauto; then + case "${target}" in + i?86-*-*gnu* | x86_64-*-*gnu*) + # Enable -mfentry by default with glibc on x86. + enable_x86_64_mfentry=yes + ;; + esac +fi + +gif=`if test x$enable_x86_64_mfentry = xyes; then echo 1; else echo 0; fi` + +cat >>confdefs.h <<_ACEOF +#define ENABLE_X86_64_MFENTRY $gif +_ACEOF + + # Check if the linker supports '-z now' ld_now_support=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker -z now option" >&5 diff --git a/gcc/configure.ac b/gcc/configure.ac index b6db9edfc83c..24e0aa69c0f6 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -4467,6 +4467,15 @@ case "$target" in ldr x0, [[x2, #:gotpage_lo15:globalsym]] ],,[AC_DEFINE(HAVE_AS_SMALL_PIC_RELOCS, 1, [Define if your assembler supports relocs needed by -fpic.])]) + # Check if we have binutils support for AEABI build attributes. + gcc_GAS_CHECK_FEATURE([support of AEABI build attributes], gcc_cv_as_aarch64_aeabi_build_attributes,, + [ + .aeabi_subsection aeabi_feature_and_bits, optional, ULEB128 + .aeabi_attribute Tag_Feature_BTI, 1 + .aeabi_attribute Tag_Feature_PAC, 1 + .aeabi_attribute Tag_Feature_GCS, 1 + ],,[AC_DEFINE(HAVE_AS_AEABI_BUILD_ATTRIBUTES, 1, + [Define if your assembler supports AEABI build attributes.])]) # Enable Branch Target Identification Mechanism and Return Address # Signing by default. AC_ARG_ENABLE(standard-branch-protection, @@ -7963,6 +7972,41 @@ standards-compatible mode on s390 targets.]) ;; esac +# On x86-64, when profiling is enabled with shrink wrapping, the mcount +# call may not be placed at the function entry after +# pushq %rbp +# movq %rsp,%rbp +# As the result, the profile data may be skewed which makes PGO less +# effective: +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120881 +# Enable -mfentry by default on x86-64 to put the profiling counter call +# before the prologue. +AC_ARG_ENABLE(x86-64-mfentry, + [AS_HELP_STRING([--enable-x86-64-mfentry], + [enable -mfentry by default on x86-64 targets])], + [case "${enableval}" in + yes | no | auto) + enable_x86_64_mfentry=$enableval + ;; + *) + AC_MSG_ERROR(['$enable_x86_64_mfentry' is an invalid value for --enable-x86-64-mfentry. Valid choices are 'yes', 'no' and 'auto'.]) + ;; + esac], + [enable_x86_64_mfentry=auto]) + +if test x"$enable_x86_64_mfentry" = xauto; then + case "${target}" in + i?86-*-*gnu* | x86_64-*-*gnu*) + # Enable -mfentry by default with glibc on x86. + enable_x86_64_mfentry=yes + ;; + esac +fi + +gif=`if test x$enable_x86_64_mfentry = xyes; then echo 1; else echo 0; fi` +AC_DEFINE_UNQUOTED(ENABLE_X86_64_MFENTRY, $gif, +[Define to enable -mfentry by default on x86-64.]) + # Check if the linker supports '-z now' ld_now_support=no AC_MSG_CHECKING(linker -z now option) diff --git a/gcc/coverage.cc b/gcc/coverage.cc index 7181e7573594..75a24c614486 100644 --- a/gcc/coverage.cc +++ b/gcc/coverage.cc @@ -235,9 +235,10 @@ read_counts_file (void) } else if (tag == GCOV_TAG_OBJECT_SUMMARY) { - profile_info = XCNEW (gcov_summary); + gcov_profile_info = profile_info = XCNEW (gcov_summary); profile_info->runs = gcov_read_unsigned (); profile_info->sum_max = gcov_read_unsigned (); + profile_info->cutoff = 1; } else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident) { @@ -1253,6 +1254,9 @@ coverage_obj_finish (vec<constructor_elt, va_gc> *ctor, void coverage_init (const char *filename) { + /* If we are in LTO, the profile will be read from object files. */ + if (in_lto_p) + return; const char *original_filename = filename; int original_len = strlen (original_filename); #if HAVE_DOS_BASED_FILE_SYSTEM @@ -1312,9 +1316,7 @@ coverage_init (const char *filename) strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX); bbg_file_stamp = local_tick; - if (flag_auto_profile) - read_autofdo_file (); - else if (flag_branch_probabilities) + if (flag_branch_probabilities) read_counts_file (); /* Name of bbg file. */ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 524aa553c11d..a2c127184eaf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,772 @@ +2025-07-21 Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org> + + * semantics.cc (finish_asm_stmt): Pass null pointer to + parse_{input,output}_constraint(). + +2025-07-16 Kwok Cheung Yeung <kcyeung@baylibre.com> + + * pt.cc (tsubst_omp_clause_decl): Use OMP_ITERATOR_DECL_P. + * semantics.cc (handle_omp_array_sections): Likewise. + (finish_omp_clauses): Likewise. + +2025-07-16 Alfie Richards <alfie.richards@arm.com> + + * class.cc (add_method): Remove argument. + * cp-tree.h (maybe_version_functions): Ditto. + * decl.cc (decls_match): Ditto. + (maybe_version_functions): Ditto. + +2025-07-16 Jeremy Rifkin <jeremy@rifkin.dev> + + PR c/82134 + * call.cc (build_call_a): Add suppress_warning + * cp-gimplify.cc (cp_gimplify_expr): Add suppress_warning + +2025-07-15 Jason Merrill <jason@redhat.com> + + PR c++/44677 + * cp-gimplify.cc (cp_fold) [CLEANUP_POINT_EXPR]: Don't force rvalue. + [COMPOUND_EXPR]: Likewise. + * cvt.cc (convert_to_void): Call mark_exp_read later. + * expr.cc (mark_use): Turn off read_p for any void argument. + (mark_exp_read): Return early for void argument. + +2025-07-15 Jason Merrill <jason@redhat.com> + + PR c++/120577 + * constexpr.cc (cxx_eval_call_expression): Set + CONSTRUCTOR_NO_CLEARING on initial value for ctor. + (cxx_eval_component_reference): Make value-initialization + of an aggregate member explicit. + +2025-07-15 Jakub Jelinek <jakub@redhat.com> + Jason Merrill <jason@redhat.com> + + PR c/44677 + * cp-gimplify.cc (cp_fold): Clear DECL_READ_P on lhs of MODIFY_EXPR + after cp_fold_rvalue if it wasn't set before. + * decl.cc (poplevel): Use OPT_Wunused_but_set_variable_ + instead of OPT_Wunused_but_set_variable. + (finish_function): Use OPT_Wunused_but_set_parameter_ + instead of OPT_Wunused_but_set_parameter. + * expr.cc (mark_use): Clear read_p for {PRE,POST}{IN,DE}CREMENT_EXPR + cast to void on {VAR,PARM}_DECL for + -Wunused-but-set-{parameter,variable}={2,3}. + (mark_exp_read): Handle {PRE,POST}{IN,DE}CREMENT_EXPR and don't handle + it when cast to void. + * module.cc (trees_in::fn_parms_fini): Remove unused but set variable + ix. + * semantics.cc (finish_unary_op_expr): Return early for + PRE{IN,DE}CREMENT_EXPR. + * typeck.cc (cp_build_unary_op): Clear DECL_READ_P + after mark_lvalue_use for -Wunused-but-set-{parameter,variable}={2,3} + on PRE{IN,DE}CREMENT_EXPR argument. + (cp_build_modify_expr): Clear DECL_READ_P after cp_build_binary_op + for -Wunused-but-set-{parameter,variable}=3. + +2025-07-11 Jakub Jelinek <jakub@redhat.com> + + PR c++/119064 + * cp-tree.h: Implement C++26 P2786R13 - Trivial Relocatability. + (struct lang_type): Add trivially_relocatable, + trivially_relocatable_computed, replaceable and replaceable_computed + bitfields. Change width of dummy from 2 to 30. + (CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT, + CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED, CLASSTYPE_REPLACEABLE_BIT, + CLASSTYPE_REPLACEABLE_COMPUTED): Define. + (enum virt_specifier): Add VIRT_SPEC_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE + and VIRT_SPEC_REPLACEABLE_IF_ELIGIBLE enumerators. + (trivially_relocatable_type_p, replaceable_type_p): Declare. + * cp-trait.def (IS_NOTHROW_RELOCATABLE, IS_REPLACEABLE, + IS_TRIVIALLY_RELOCATABLE): New traits. + * parser.cc (cp_parser_class_property_specifier_seq_opt): Handle + trivially_relocatable_if_eligible, + __trivially_relocatable_if_eligible, replaceable_if_eligible and + __replaceable_if_eligible. + (cp_parser_class_head): Set CLASSTYPE_REPLACEABLE_BIT + and/or CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT if corresponding + conditional keywords were parsed and assert corresponding *_COMPUTED + macro is false. + * pt.cc (instantiate_class_template): Copy over also + CLASSTYPE_TRIVIALLY_RELOCATABLE_{BIT,COMPUTED} and + CLASSTYPE_REPLACEABLE_{BIT,COMPUTED} bits. + * semantics.cc (referenceable_type_p): Move definition earlier. + (trait_expr_value): Handle CPTK_IS_NOTHROW_RELOCATABLE, + CPTK_IS_REPLACEABLE and CPTK_IS_TRIVIALLY_RELOCATABLE. + (finish_trait_expr): Likewise. + * tree.cc (default_movable_type_p): New function. + (union_with_no_declared_special_member_fns): Likewise. + (trivially_relocatable_type_p): Likewise. + (replaceable_type_p): Likewise. + * constraint.cc (diagnose_trait_expr): Handle + CPTK_IS_NOTHROW_RELOCATABLE, CPTK_IS_REPLACEABLE and + CPTK_IS_TRIVIALLY_RELOCATABLE. + +2025-07-10 Jakub Jelinek <jakub@redhat.com> + + * cp-tree.h (struct lang_type): Add comment before key_method. + Remove lambda_expr. + (CLASSTYPE_KEY_METHOD): Give NULL_TREE if not TYPE_POLYMORPHIC_P. + (SET_CLASSTYPE_KEY_METHOD): Define. + (CLASSTYPE_LAMBDA_EXPR): Give NULL_TREE if TYPE_POLYMORPHIC_P. + Use key_method member instead of lambda_expr. + (SET_CLASSTYPE_LAMBDA_EXPR): Define. + * class.cc (determine_key_method): Use SET_CLASSTYPE_KEY_METHOD + macro. + * decl.cc (xref_tag): Use SET_CLASSTYPE_LAMBDA_EXPR macro. + * lambda.cc (begin_lambda_type): Likewise. + * module.cc (trees_in::read_class_def): Use SET_CLASSTYPE_LAMBDA_EXPR + and SET_CLASSTYPE_KEY_METHOD macros, assert lambda is NULL if + TYPE_POLYMORPHIC_P and otherwise assert key_method is NULL. + +2025-07-10 Jakub Jelinek <jakub@redhat.com> + + PR c++/120628 + * parser.cc (cp_parser_elaborated_type_specifier): Use + cp_parser_nth_token_starts_class_definition_p with extra argument 1 + instead of cp_parser_next_token_starts_class_definition_p. + (cp_parser_class_property_specifier_seq_opt): For final conditional + keyword in C++98 check if the token after it isn't + cp_parser_nth_token_starts_class_definition_p nor CPP_NAME and in + that case break without consuming it nor warning. + (cp_parser_class_head): Use + cp_parser_nth_token_starts_class_definition_p with extra argument 1 + instead of cp_parser_next_token_starts_class_definition_p. + (cp_parser_next_token_starts_class_definition_p): Renamed to ... + (cp_parser_nth_token_starts_class_definition_p): ... this. Add N + argument. Use cp_lexer_peek_nth_token instead of cp_lexer_peek_token. + +2025-07-10 Jakub Jelinek <jakub@redhat.com> + + PR c++/120569 + * parser.cc (cp_parser_class_property_specifier_seq_opt): New + function. + (cp_parser_class_head): Use it instead of + cp_parser_property_specifier_seq_opt. Don't diagnose + VIRT_SPEC_OVERRIDE here. Formatting fix. + +2025-07-10 Jakub Jelinek <jakub@redhat.com> + + PR c++/117785 + * constexpr.cc: Implement C++26 P3068R5 - constexpr exceptions. + (class constexpr_global_ctx): Add caught_exceptions and + uncaught_exceptions members. + (constexpr_global_ctx::constexpr_global_ctx): Initialize + uncaught_exceptions. + (returns, breaks, continues, switches): Move earlier. + (throws): New function. + (exception_what_str, diagnose_std_terminate, + diagnose_uncaught_exception): New functions. + (enum cxa_builtin): New type. + (cxx_cxa_builtin_fn_p, cxx_eval_cxa_builtin_fn): New functions. + (cxx_eval_builtin_function_call): Add jump_target argument. Call + cxx_eval_cxa_builtin_fn for __builtin_eh_ptr_adjust_ref. Adjust + cxx_eval_constant_expression calls, if it results in jmp_target, + set *jump_target to it and return. + (cxx_bind_parameters_in_call): Add jump_target argument. Pass + it through to cxx_eval_constant_expression. If it sets *jump_target, + break. + (fold_operand): Adjust cxx_eval_constant_expression caller. + (cxx_eval_assert): Likewise. If it set jmp_target, return true. + (cxx_eval_internal_function): Add jump_target argument. Pass it + through to cxx_eval_constant_expression. Return early if *jump_target + after recursing on args. + (cxx_eval_dynamic_cast_fn): Likewise. Don't set reference_p for + C++26 with -fexceptions. + (cxx_eval_thunk_call): Add jump_target argument. Pass it through + to cxx_eval_constant_expression. + (cxx_set_object_constness): Likewise. Don't set TREE_READONLY if + throws (jump_target). + (cxx_eval_call_expression): Add jump_target argument. Pass it + through to cxx_eval_internal_function, cxx_eval_builtin_function_call, + cxx_eval_thunk_call, cxx_eval_dynamic_cast_fn and + cxx_set_object_constness. Pass it through also + cxx_eval_constant_expression on arguments, cxx_bind_parameters_in_call + and cxx_fold_indirect_ref and for those cases return early + if *jump_target. Call cxx_eval_cxa_builtin_fn for cxx_cxa_builtin_fn_p + functions. For cxx_eval_constant_expression on body, pass address of + cleared jmp_target automatic variable, if it throws propagate + to *jump_target and make it non-cacheable. For C++26 don't diagnose + calls to non-constexpr functions before cxx_bind_parameters_in_call + could report some argument throwing an exception. + (cxx_eval_unary_expression): Add jump_target argument. Pass it + through to cxx_eval_constant_expression and return early + if *jump_target after the call. + (cxx_fold_pointer_plus_expression): Likewise. + (cxx_eval_binary_expression): Likewise and similarly for + cxx_fold_pointer_plus_expression call. + (cxx_eval_conditional_expression): Pass jump_target to + cxx_eval_constant_expression on first operand and return early + if *jump_target after the call. + (cxx_eval_vector_conditional_expression): Add jump_target argument. + Pass it through to cxx_eval_constant_expression for all 3 arguments + and return early if *jump_target after any of those calls. + (get_array_or_vector_nelts): Add jump_target argument. Pass it + through to cxx_eval_constant_expression. + (eval_and_check_array_index): Add jump_target argument. Pass it + through to cxx_eval_constant_expression calls and return early after + each of them if *jump_target. + (cxx_eval_array_reference): Likewise. + (cxx_eval_component_reference): Likewise. + (cxx_eval_bit_field_ref): Likewise. + (cxx_eval_bit_cast): Likewise. Assert CHECKING_P call doesn't + throw or return. + (cxx_eval_logical_expression): Add jump_target argument. Pass it + through to cxx_eval_constant_expression calls and return early after + each of them if *jump_target. + (cxx_eval_bare_aggregate): Likewise. + (cxx_eval_vec_init_1): Add jump_target argument. Pass it through + to cxx_eval_bare_aggregate and recursive call. Pass it through + to get_array_or_vector_nelts and cxx_eval_constant_expression + and return early after it if *jump_target. + (cxx_eval_vec_init): Add jump_target argument. Pass it through + to cxx_eval_constant_expression and cxx_eval_vec_init_1. + (cxx_union_active_member): Add jump_target argument. Pass it + through to cxx_eval_constant_expression and return early after it + if *jump_target. + (cxx_fold_indirect_ref_1): Add jump_target argument. Pass it + through to cxx_union_active_member and recursive calls. + (cxx_eval_indirect_ref): Add jump_target argument. Pass it through + to cxx_fold_indirect_ref_1 calls and to recursive call, in which + case return early after it if *jump_target. + (cxx_fold_indirect_ref): Add jump_target argument. Pass it through + to cxx_fold_indirect_ref and cxx_eval_constant_expression calls and + return early after those if *jump_target. + (cxx_eval_trinary_expression): Add jump_target argument. Pass it + through to cxx_eval_constant_expression calls and return early after + those if *jump_target. + (cxx_eval_store_expression): Add jump_target argument. Pass it + through to cxx_eval_constant_expression and eval_and_check_array_index + calls and return early after those if *jump_target. + (cxx_eval_increment_expression): Add jump_target argument. Pass it + through to cxx_eval_constant_expression calls and return early after + those if *jump_target. + (label_matches): Handle VAR_DECL case. + (cxx_eval_statement_list): Remove local_target variable and + !jump_target handling. Handle throws (jump_target) like returns or + breaks. + (cxx_eval_loop_expr): Remove local_target variable and !jump_target + handling. Pass it through to cxx_eval_constant_expression. Handle + throws (jump_target) like returns. + (cxx_eval_switch_expr): Pass jump_target through to + cxx_eval_constant_expression on cond, return early after it + if *jump_target. + (build_new_constexpr_heap_type): Add jump_target argument. Pass it + through to cxx_eval_constant_expression calls, return early after + those if *jump_target. + (merge_jump_target): New function. + (cxx_eval_constant_expression): Make jump_target argument no longer + defaulted, don't test jump_target for NULL. Pass jump_target + through to recursive calls, cxx_eval_call_expression, + cxx_eval_store_expression, cxx_eval_indirect_ref, + cxx_eval_unary_expression, cxx_eval_binary_expression, + cxx_eval_logical_expression, cxx_eval_array_reference, + cxx_eval_component_reference, cxx_eval_bit_field_ref, + cxx_eval_vector_conditional_expression, cxx_eval_bare_aggregate, + cxx_eval_vec_init, cxx_eval_trinary_expression, cxx_fold_indirect_ref, + build_new_constexpr_heap_type, cxx_eval_increment_expression, + cxx_eval_bit_cast and return earlyu after some of those + if *jump_target as needed. + (cxx_eval_constant_expression) <case TARGET_EXPR>: For C++26 push + also CLEANUP_EH_ONLY cleanups, with NULL_TREE marker after them. + (cxx_eval_constant_expression) <case RETURN_EXPR>: Don't + override *jump_target if throws (jump_target). + (cxx_eval_constant_expression) <case TRY_CATCH_EXPR, case TRY_BLOCK, + case MUST_NOT_THROW_EXPR, case TRY_FINALLY_EXPR, case CLEANUP_STMT>: + Handle C++26 constant expressions. + (cxx_eval_constant_expression) <case CLEANUP_POINT_EXPR>: For C++26 + with throws (jump_target) evaluate the CLEANUP_EH_ONLY cleanups as + well, and if not throws (jump_target) skip those. Set *jump_target + if some of the cleanups threw. + (cxx_eval_constant_expression) <case THROW_EXPR>: Recurse on operand + for C++26. + (cxx_eval_outermost_constant_expr): Diagnose uncaught exceptions both + from main expression and cleanups, diagnose also + break/continue/returns from the main expression. Handle + CLEANUP_EH_ONLY cleanup markers. Don't diagnose mutable poison stuff + if non_constant_p. Use different diagnostics for non-deleted heap + allocations if they were allocated by __cxa_allocate_exception. + (callee_might_throw): New function. + (struct check_for_return_continue_data): Add could_throw field. + (check_for_return_continue): Handle AGGR_INIT_EXPR and CALL_EXPR and + set d->could_throw if they could throw. + (potential_constant_expression_1): For CALL_EXPR allow + cxx_dynamic_cast_fn_p calls. For C++26 set *jump_target to void_node + for calls that could throw. For C++26 if call to non-constexpr call + is seen, try to evaluate arguments first and if they could throw, + don't diagnose call to non-constexpr function nor return false. + Adjust check_for_return_continue_data initializers and + set *jump_target to void_node if data.could_throw_p. For C++26 + recurse on THROW_EXPR argument. Add comment explaining TRY_BLOCK + handling with C++26 exceptions. Handle throws like returns in some + cases. + * cp-tree.h (MUST_NOT_THROW_NOEXCEPT_P, MUST_NOT_THROW_THROW_P, + MUST_NOT_THROW_CATCH_P, DECL_EXCEPTION_REFCOUNT): Define. + (DECL_LOCAL_DECL_P): Fix comment typo, VARIABLE_DECL -> VAR_DECL. + (enum cp_built_in_function): Add CP_BUILT_IN_EH_PTR_ADJUST_REF, + (handler_match_for_exception_type): Declare. + * call.cc (handler_match_for_exception_type): New function. + * except.cc (initialize_handler_parm): Set MUST_NOT_THROW_CATCH_P + on newly created MUST_NOT_THROW_EXPR. + (begin_eh_spec_block): Set MUST_NOT_THROW_NOEXCEPT_P. + (wrap_cleanups_r): Set MUST_NOT_THROW_THROW_P. + (build_throw): Add another TARGET_EXPR whose scope spans + until after the __cxa_throw call and copy pointer value from ptr + to it and use it in __cxa_throw argument. + * tree.cc (builtin_valid_in_constant_expr_p): Handle + CP_BUILT_IN_EH_PTR_ADJUST_REF. + * decl.cc (cxx_init_decl_processing): Initialize + __builtin_eh_ptr_adjust_ref FE builtin. + * pt.cc (tsubst_stmt) <case MUST_NOT_THROW_EXPR>: Copy the + MUST_NOT_THROW_NOEXCEPT_P, MUST_NOT_THROW_THROW_P and + MUST_NOT_THROW_CATCH_P flags. + * cp-gimplify.cc (cp_gimplify_expr) <case CALL_EXPR>: Error on + non-folded CP_BUILT_IN_EH_PTR_ADJUST_REF calls. + +2025-07-09 Jason Merrill <jason@redhat.com> + + PR c++/121012 + PR c++/120917 + * parser.cc (cp_parser_lambda_expression): Clear + parser->in_template_argument_list_p. + +2025-07-09 Jason Merrill <jason@redhat.com> + + PR c++/121008 + PR c++/113563 + * semantics.cc (finish_this_expr): Do check current_class_ref for + non-lambda. + +2025-07-09 Marek Polacek <polacek@redhat.com> + + PR c++/119838 + * parser.cc (cp_parser_nested_name_specifier_opt): New global_p + parameter. Look for "template" when global_p is true. + (cp_parser_simple_type_specifier): Pass global_p to + cp_parser_nested_name_specifier_opt. + +2025-07-08 Marek Polacek <polacek@redhat.com> + Andrew Pinski <quic_apinski@quicinc.com> + + PR c++/83469 + PR c++/93809 + * cp-tree.h (UNION_TYPE_P): Define. + (TYPENAME_IS_UNION_P): Define. + * decl.cc (struct typename_info): Add union_p field. + (struct typename_hasher::equal): Compare union_p field. + (build_typename_type): Use ti.union_p for union_type. Set + TYPENAME_IS_UNION_P. + * error.cc (dump_type) <case TYPENAME_TYPE>: Handle + TYPENAME_IS_UNION_P. + * module.cc (trees_out::type_node): Likewise. + * parser.cc (cp_parser_check_class_key): Allow typename key for union + types and allow union keyword for typename types. + * pt.cc (tsubst) <case TYPENAME_TYPE>: Don't conflate unions with + class_type. For TYPENAME_IS_CLASS_P, check NON_UNION_CLASS_TYPE_P + rather than CLASS_TYPE_P. Add TYPENAME_IS_UNION_P handling. + +2025-07-08 Jakub Jelinek <jakub@redhat.com> + + PR c++/117784 + * decl.cc: Implement part of C++26 P2686R4 - constexpr structured + bindings. + (cp_finish_decl): Pedwarn for C++23 and older on constinit on + structured bindings except for static/thread_local where it uses + earlier error. + (grokdeclarator): Pedwarn on constexpr structured bindings for + C++23 and older instead of emitting error always, don't clear + constexpr_p in that case. + * parser.cc (cp_parser_decomposition_declaration): Copy over + DECL_DECLARED_CONSTEXPR_P and DECL_DECLARED_CONSTINIT_P flags. + +2025-07-07 Alfie Richards <alfie.richards@arm.com> + + PR c++/119498 + * decl.cc (duplicate_decls): Change logic to not always exclude FMV + annotated functions in cases of return type non-ambiguation. + +2025-07-07 Jason Merrill <jason@redhat.com> + + PR c++/120917 + * parser.cc (cp_parser_simple_type_specifier): Attach + auto in targ in parameter to -Wabbreviated-auto-in-template-arg. + (cp_parser_placeholder_type_specifier): Diagnose constrained auto in + template arg. + +2025-07-07 Jakub Jelinek <jakub@redhat.com> + + PR c++/84009 + * parser.cc (cp_parser_decomposition_declaration): Pedwarn + on thread_local, __thread or static in decl_specifiers for + for-range-declaration. + (cp_parser_init_declarator): Likewise, and also for extern + or register. + +2025-07-04 Jason Merrill <jason@redhat.com> + + PR c++/120575 + PR c++/116064 + * parser.cc (cp_parser_abort_tentative_parse): Check seen_error + instead of errorcount. + +2025-07-03 Jason Merrill <jason@redhat.com> + + PR c++/120716 + * lambda.cc (finish_lambda_function): Pass cur_stmt_list to + prune_lambda_captures. + +2025-07-03 Jason Merrill <jason@redhat.com> + + PR c++/120748 + * lambda.cc (lambda_expr_this_capture): Don't return a FIELD_DECL. + * parser.cc (cp_parser_primary_expression): Ignore THIS_FORBIDDEN + if cp_unevaluated_operand. + +2025-07-03 Jakub Jelinek <jakub@redhat.com> + + PR c++/120940 + * typeck.cc (cp_build_array_ref): Fix a pasto. + +2025-07-03 Jason Merrill <jason@redhat.com> + + PR c++/120684 + PR c++/118856 + * constexpr.cc (cxx_eval_constant_expression) [TARGET_EXPR]: Clear + the value first if is_complex. + +2025-07-01 Jakub Jelinek <jakub@redhat.com> + + PR c++/120471 + * typeck.cc (cp_build_array_ref) <case COND_EXPR>: If idx is not + INTEGER_CST, don't optimize the case (but cp_default_conversion on + array early if it has ARRAY_TYPE) or use + SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0> as new op0 depending + on flag_strong_eval_order and whether op1 and op2 are arrays with + invariant address or tree invariant pointers. Formatting fixes. + +2025-06-28 Nathaniel Shead <nathanieloshead@gmail.com> + + * module.cc (trees_out::walking_bit_field_unit): New flag. + (trees_out::trees_out): Initialize it. + (trees_out::core_vals): Set it. + (trees_out::get_merge_kind): Use it, move previous ad-hoc check + into assertion. + +2025-06-28 Nathaniel Shead <nathanieloshead@gmail.com> + + PR c++/120644 + * decl.cc (cp_finish_decl): Also propagate type to partial + templates. + * module.cc (trees_out::decl_value): Add assertion that the + TREE_TYPE of a streamed template decl matches its inner. + (trees_in::is_matching_decl): Clarify function return type + deduction should only occur for non-TEMPLATE_DECL. + * pt.cc (template_for_substitution): Handle partial specs. + +2025-06-27 Marek Polacek <polacek@redhat.com> + + PR c++/120756 + * pt.cc (resolve_nondeduced_context): Pass complain to mark_used. + +2025-06-27 Jakub Jelinek <jakub@redhat.com> + + PR c++/120777 + * constexpr.cc: Implement C++26 P3533R2 - constexpr virtual + inheritance. + (is_valid_constexpr_fn): Don't reject constexpr cdtors in classes + with virtual bases for C++26, adjust error wording. + (cxx_bind_parameters_in_call): Add ORIG_FUN argument, add + values for __in_chrg and __vtt_parm arguments when needed. + (cxx_eval_dynamic_cast_fn): Adjust function comment, HINT -1 + should be possible. For C++26 if obj is cast from POINTER_PLUS_EXPR, + attempt to use cxx_fold_indirect_ref to simplify it and if successful, + build ADDR_EXPR of that. + (cxx_eval_call_expression): Add orig_fun variable, set it to + fun before looking through clones, pass it to + cxx_bind_parameters_in_call. + (reduced_constant_expression_p): Add SZ argument, pass DECL_SIZE + of FIELD_DECL e.index to recursive calls and don't return false + if SZ is non-NULL and there are unfilled fields with bit position + at or above SZ. + (cxx_fold_indirect_ref_1): Handle reading of vtables using + ptrdiff_t dynamic type instead of some pointer type. Set el_sz + to DECL_SIZE_UNIT value rather than TYPE_SIZE_UNIT of + DECL_FIELD_IS_BASE fields in classes with virtual bases. + (cxx_fold_indirect_ref): In canonicalize_obj_off lambda look + through COMPONENT_REFs with DECL_FIELD_IS_BASE in classes with + virtual bases and adjust off correspondingly. Remove assertion that + off is integer_zerop, pass tree_to_uhwi (off) instead of 0 to the + cxx_fold_indirect_ref_1 call. + * cp-tree.h (publicly_virtually_derived_p): Declare. + (reduced_constant_expression_p): Add another tree argument defaulted + to NULL_TREE. + * method.cc (synthesized_method_walk): Don't clear *constexpr_p + if there are virtual bases for C++26. + * class.cc (build_base_path): Compute fixed_type_p and + virtual_access before checks for build_simple_base_path instead of + after that and conditional cp_build_addr_expr. Use build_simple_path + if !virtual_access even when v_binfo is non-NULL. + (layout_virtual_bases): For build_base_field calls use + access_public_node rather than access_private_node if + publicly_virtually_derived_p. + (build_vtbl_initializer): Revert 2018-09-18 and 2018-12-11 changes. + (publicly_virtually_derived_p): New function. + +2025-06-27 Jason Merrill <jason@redhat.com> + + * class.cc (fixed_type_or_null): Handle class-type CALL_EXPR. + * parser.cc (cp_parser_binary_expression): Fix decltype_p handling. + +2025-06-27 Nathaniel Shead <nathanieloshead@gmail.com> + + PR c++/98735 + PR c++/118904 + * cp-gimplify.cc (source_location_id): Remove. + (fold_builtin_source_location): Use generate_internal_label. + * module.cc (enum tree_tag): Add 'tt_internal_id' enumerator. + (trees_out::tree_value): Adjust assertion, write definitions + of uncontexted VAR_DECLs. + (trees_in::tree_value): Read variable definitions. + (trees_out::tree_node): Write internal labels, adjust assert. + (trees_in::tree_node): Read internal labels. + +2025-06-27 Nathaniel Shead <nathanieloshead@gmail.com> + + PR c++/120040 + * constexpr.cc (cxx_eval_constant_expression): Handle TYPE_NAME + now being a TYPE_DECL rather than just an IDENTIFIER_NODE. + * init.cc (build_new_constexpr_heap_type): Build a TYPE_DECL for + the returned type; mark the type as artificial. + * module.cc (trees_out::type_node): Add some assertions. + +2025-06-27 Nathaniel Shead <nathanieloshead@gmail.com> + + PR c++/98735 + PR c++/120040 + * module.cc (trees_out::tree_value): Write TYPE_DECLs. + (trees_in::tree_value): Read TYPE_DECLs. + (trees_out::tree_node): Support uncontexted TYPE_DECLs, and + ensure that all parts of a by-value decl are marked for + streaming. + (trees_out::get_merge_kind): Treat members of uncontexted types + as always unique. + +2025-06-27 Nathaniel Shead <nathanieloshead@gmail.com> + + * decl.cc (grokfndecl): Add explanation of how to attach to + global module. + +2025-06-26 David Malcolm <dmalcolm@redhat.com> + + * error.cc (cxx_initialize_diagnostics): Use + diagnostic_context::set_adjust_diagnostic_info_callback. + +2025-06-26 Jakub Jelinek <jakub@redhat.com> + + * cp-trait.def: Implement C++26 P2830R10 - Constexpr Type Ordering. + (TYPE_ORDER): New. + * method.cc (type_order_value): Define. + * cp-tree.h (type_order_value): Declare. + * semantics.cc (trait_expr_value): Use gcc_unreachable also + for CPTK_TYPE_ORDER, adjust comment. + (finish_trait_expr): Handle CPTK_TYPE_ORDER. + * constraint.cc (diagnose_trait_expr): Likewise. + +2025-06-25 Martin Jambor <mjambor@suse.cz> + + * coroutines.h (class cp_coroutine_transform): Remove member + orig_fn_body. + +2025-06-24 Jakub Jelinek <jakub@redhat.com> + + PR c++/120773 + * decl.cc (grokfndecl): Implement C++26 P3618R0 - Allow attaching + main to the global module. Only pedwarn for current_lang_name + other than lang_name_cplusplus and adjust pedwarn wording. + +2025-06-23 Tobias Burnus <tburnus@baylibre.com> + + * parser.cc (OACC_WAIT_CLAUSE_MASK): Ass if clause. + +2025-06-18 Iain Sandoe <iain@sandoe.co.uk> + + PR c++/115908 + PR c++/118074 + PR c++/95615 + * coroutines.cc (coro_frame_refcount_id): New. + (coro_init_identifiers): Initialise coro_frame_refcount_id. + (build_actor_fn): Set up initial_await_resume_called. Handle + decrementing of the frame reference count. Return directly to + the caller if that is non-zero. + (cp_coroutine_transform::wrap_original_function_body): Use a + conditional eh-only cleanup around the initial await expression + to release the body use on exception before initial await + resume. + (cp_coroutine_transform::build_ramp_function): Wrap the called + body in a cleanup that releases a use of the frame when we + return to the ramp. Implement frame, promise and argument copy + destruction via conditional cleanups when the frame use count + is zero. + +2025-06-17 Iain Sandoe <iain@sandoe.co.uk> + + * coroutines.cc (struct coroutine_info): Update comments. + (struct coro_aw_data): Remove self_handle and add in + information to create the handle in lowering. + (expand_one_await_expression): Build a temporary coroutine + handle. + (build_actor_fn): Remove reference to the frame copy of the + coroutine handle. + (cp_coroutine_transform::wrap_original_function_body): Remove + reference to the frame copy of the coroutine handle. + +2025-06-17 Iain Sandoe <iain@sandoe.co.uk> + + * coroutines.cc (analyze_expression_awaits): Elide assume + attributes containing await expressions, since these have + side effects. Emit a diagnostic that this has been done. + +2025-06-17 Jason Merrill <jason@redhat.com> + + PR c++/120678 + * cp-trait.def (IS_TRIVIALLY_DESTRUCTIBLE): Fix nargs. + +2025-06-17 Jason Merrill <jason@redhat.com> + + * module.cc (module_state::write_diagnostic_classification): New. + (module_state::write_begin): Call it. + (module_state::read_diagnostic_classification): New. + (module_state::read_initial): Call it. + (dk_string, dump_dc_change): New. + +2025-06-17 Iain Sandoe <iain@sandoe.co.uk> + + * coroutines.cc (finish_co_await_expr): Do not allow in an + unevaluated context. + (finish_co_yield_expr): Likewise. + +2025-06-17 Iain Sandoe <iain@sandoe.co.uk> + + PR c++/120273 + * coroutines.cc + (cp_coroutine_transform::wrap_original_function_body): Use + function start and end locations when synthesizing code. + (cp_coroutine_transform::cp_coroutine_transform): Set the + function end location. + +2025-06-16 Jason Merrill <jason@redhat.com> + + * constraint.cc (failed_completions_map): New. + (note_failed_type_completion): Rename from + note_failed_type_completion_for_satisfaction. Add + -Wsfinae-incomplete handling. + (failed_completion_location): New. + * class.cc (finish_struct_1): Add -Wsfinae-incomplete warning. + * decl.cc (require_deduced_type): Adjust. + (finish_function): Add -Wsfinae-incomplete warning. + * typeck.cc (complete_type_or_maybe_complain): Adjust. + (cxx_sizeof_or_alignof_type): Call note_failed_type_completion. + * pt.cc (dependent_template_arg_p): No longer static. + * cp-tree.h: Adjust. + +2025-06-16 yxj-github-437 <2457369732@qq.com> + + * parser.cc (cp_parser_asm_operand_list): Check for unexpanded + parameter packs. + +2025-06-14 Iain Sandoe <iain@sandoe.co.uk> + + * coroutines.cc (build_co_await): Identify diagnostics + for initial and final await expressions. + (cp_coroutine_transform::wrap_original_function_body): Do + not handle initial and final await expressions here ... + (cp_coroutine_transform::apply_transforms): ... handle them + here and avoid duplicate diagnostics. + * coroutines.h: Declare inital and final await expressions + in the transform class. Save the function closing brace + location. + +2025-06-13 Iain Sandoe <iain@sandoe.co.uk> + + PR c++/116775 + * coroutines.cc (analyze_expression_awaits): When we see + a builtin_constant_p call, and that contains one or more + await expressions, then replace the call with its result + and discard the unevaluated operand. + +2025-06-13 Iain Sandoe <iain@sandoe.co.uk> + + * coroutines.cc (build_actor_fn): Set can_throw. + +2025-06-12 Alfie Richards <alfie.richards@arm.com> + + * decl.cc (maybe_version_functions): Change record_function_versions + call to add_function_version. + +2025-06-12 Jakub Jelinek <jakub@redhat.com> + + * cp-tree.h (union lang_type::maybe_objc_info): New type. + (struct lang_type): Use union maybe_objc_info info member + instead of tree objc_info. + * lex.cc (copy_lang_type): Use sizeof (struct lang_type) + just for ObjC++ and otherwise offsetof (struct lang_type, info). + (maybe_add_lang_type_raw): Likewise. + (cxx_make_type): Formatting fix. + +2025-06-09 Iain Sandoe <iain@sandoe.co.uk> + + PR c++/120495 + PR c++/115605 + * pt.cc (lookup_template_class): Honour provided namespace contexts + when looking up class templates. + +2025-06-06 Jason Merrill <jason@redhat.com> + + PR c++/120555 + * decl2.cc (fn_being_defined, fn_template_being_defined): New. + (mark_used): Check fn_template_being_defined. + +2025-06-05 Patrick Palka <ppalka@redhat.com> + + PR c++/120224 + * pt.cc (tsubst_function_decl): Return error_mark_node if + substituting into the formal parameter list failed. + (tsubst_decl) <case PARM_DECL>: Return error_mark_node + upon TREE_TYPE substitution failure, when in a SFINAE + context. Return error_mark_node upon DECL_CHAIN substitution + failure. + +2025-06-05 Patrick Palka <ppalka@redhat.com> + + PR c++/118340 + * constexpr.cc (maybe_constant_value): First try looking up each + operand in the cv_cache and reusing the result. + +2025-06-05 Iain Sandoe <iain@sandoe.co.uk> + + * coroutines.cc (analyze_fn_parms): Move from free function.. + (cp_coroutine_transform::analyze_fn_parms):... to method. + (cp_coroutine_transform::apply_transforms): Adjust call to + analyze_fn_parms. + * coroutines.h: Declare analyze_fn_parms. + +2025-06-05 Iain Sandoe <iain@sandoe.co.uk> + + * coroutines.cc (expand_one_await_expression): Set the + initial_await_resume_called flag here. + (build_actor_fn): Populate the frame accessor for the + initial_await_resume_called flag. + (cp_coroutine_transform::wrap_original_function_body): Do + not modify the initial_await expression to include the + initial_await_resume_called flag here. + +2025-06-04 Jason Merrill <jason@redhat.com> + + PR c++/120502 + * cp-gimplify.cc (cp_fold_r) [TARGET_EXPR]: Do constexpr evaluation + before genericize. + * constexpr.cc (cxx_eval_store_expression): Add comment. + 2025-06-03 Jason Merrill <jason@redhat.com> * name-lookup.h (operator|, operator|=): Define for WMB_Flags. diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 2c3ef3dfc35d..37ad0a977c22 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -412,6 +412,7 @@ build_call_a (tree function, int n, tree *argarray) /* We're disconnecting the initializer from its target, don't create a temporary. */ arg = TARGET_EXPR_INITIAL (arg); + suppress_warning (arg, OPT_Wunused_result); tree t = build0 (EMPTY_CLASS_EXPR, TREE_TYPE (arg)); arg = build2 (COMPOUND_EXPR, TREE_TYPE (t), arg, t); CALL_EXPR_ARG (function, i) = arg; @@ -1723,6 +1724,56 @@ involves_qualification_conversion_p (tree to, tree from) return false; } +/* Return true if HANDLER is a match for exception object with EXCEPT_TYPE as + per [except.handle]/3. */ + +bool +handler_match_for_exception_type (tree handler, tree except_type) +{ + tree handler_type = HANDLER_TYPE (handler); + if (handler_type == NULL_TREE) + return true; /* ... */ + if (same_type_ignoring_top_level_qualifiers_p (handler_type, except_type)) + return true; + if (CLASS_TYPE_P (except_type) && CLASS_TYPE_P (handler_type)) + { + base_kind b_kind; + tree binfo = lookup_base (except_type, handler_type, ba_check, &b_kind, + tf_none); + if (binfo && binfo != error_mark_node) + return true; + } + if (TYPE_PTR_P (handler_type) || TYPE_PTRDATAMEM_P (handler_type)) + { + if (TREE_CODE (except_type) == NULLPTR_TYPE) + return true; + if ((TYPE_PTR_P (handler_type) && TYPE_PTR_P (except_type)) + || (TYPE_PTRDATAMEM_P (handler_type) + && TYPE_PTRDATAMEM_P (except_type))) + { + conversion *conv + = standard_conversion (handler_type, except_type, NULL_TREE, + /*c_cast_p=*/false, 0, tf_none); + if (conv && !conv->bad_p) + { + for (conversion *t = conv; t; t = next_conversion (t)) + switch (t->kind) + { + case ck_ptr: + case ck_fnptr: + case ck_qual: + case ck_identity: + break; + default: + return false; + } + return true; + } + } + } + return false; +} + /* A reference of the indicated TYPE is being bound directly to the expression represented by the implicit conversion sequence CONV. Return a conversion sequence for this binding. */ diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index db39e579870c..f5d20e5c5392 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -347,9 +347,18 @@ build_base_path (enum tree_code code, || processing_template_decl || in_template_context); + fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); + + /* Do we need to look in the vtable for the real offset? */ + virtual_access = (v_binfo && fixed_type_p <= 0); + /* For a non-pointer simple base reference, express it as a COMPONENT_REF without taking its address (and so causing lambda capture, 91933). */ - if (code == PLUS_EXPR && !v_binfo && !want_pointer && !has_empty && !uneval) + if (code == PLUS_EXPR + && !want_pointer + && !has_empty + && !uneval + && !virtual_access) return build_simple_base_path (expr, binfo); if (!want_pointer) @@ -362,7 +371,6 @@ build_base_path (enum tree_code code, expr = mark_rvalue_use (expr); offset = BINFO_OFFSET (binfo); - fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo); /* TARGET_TYPE has been extracted from BINFO, and, is therefore always cv-unqualified. Extract the cv-qualifiers from EXPR so that the @@ -371,9 +379,6 @@ build_base_path (enum tree_code code, (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr)))); ptr_target_type = build_pointer_type (target_type); - /* Do we need to look in the vtable for the real offset? */ - virtual_access = (v_binfo && fixed_type_p <= 0); - /* Don't bother with the calculations inside sizeof; they'll ICE if the source type is incomplete and the pointer value doesn't matter. In a template (even in instantiate_non_dependent_expr), we don't have vtables @@ -1402,7 +1407,7 @@ add_method (tree type, tree method, bool via_using) /* If these are versions of the same function, process and move on. */ if (TREE_CODE (fn) == FUNCTION_DECL - && maybe_version_functions (method, fn, true)) + && maybe_version_functions (method, fn)) continue; if (DECL_INHERITED_CTOR (method)) @@ -6754,9 +6759,11 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets) { /* This virtual base is not a primary base of any class in the hierarchy, so we have to add space for it. */ - next_field = build_base_field (rli, vbase, - access_private_node, - offsets, next_field); + tree access = access_private_node; + if (publicly_virtually_derived_p (BINFO_TYPE (vbase), t)) + access = access_public_node; + next_field = build_base_field (rli, vbase, access, offsets, + next_field); } } } @@ -7445,7 +7452,7 @@ determine_key_method (tree type) && ! DECL_DECLARED_INLINE_P (method) && ! DECL_PURE_VIRTUAL_P (method)) { - CLASSTYPE_KEY_METHOD (type) = method; + SET_CLASSTYPE_KEY_METHOD (type, method); break; } @@ -7920,6 +7927,17 @@ finish_struct_1 (tree t) return; } + if (location_t fcloc = failed_completion_location (t)) + { + auto_diagnostic_group adg; + if (warning (OPT_Wsfinae_incomplete_, + "defining %qT, which previously failed to be complete " + "in a SFINAE context", t) + && warn_sfinae_incomplete == 1) + inform (fcloc, "here. Use %qs for a diagnostic at that point", + "-Wsfinae-incomplete=2"); + } + /* If this type was previously laid out as a forward reference, make sure we lay it out again. */ TYPE_SIZE (t) = NULL_TREE; @@ -8339,6 +8357,15 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp) *nonnull = 1; return TREE_TYPE (instance); } + if (CLASS_TYPE_P (TREE_TYPE (instance))) + { + /* We missed a build_cplus_new somewhere, likely due to tf_decltype + mishandling. */ + gcc_checking_assert (false); + if (nonnull) + *nonnull = 1; + return TREE_TYPE (instance); + } return NULL_TREE; case SAVE_EXPR: @@ -10609,7 +10636,7 @@ build_vtbl_initializer (tree binfo, int i; if (init == size_zero_node) for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i) - CONSTRUCTOR_APPEND_ELT (*inits, size_int (jx++), init); + CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init); else for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i) { @@ -10617,11 +10644,11 @@ build_vtbl_initializer (tree binfo, fn, build_int_cst (NULL_TREE, i)); TREE_CONSTANT (fdesc) = 1; - CONSTRUCTOR_APPEND_ELT (*inits, size_int (jx++), fdesc); + CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, fdesc); } } else - CONSTRUCTOR_APPEND_ELT (*inits, size_int (jx++), init); + CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init); } } @@ -10960,6 +10987,17 @@ publicly_uniquely_derived_p (tree parent, tree type) return base && base != error_mark_node; } +/* TRUE iff TYPE is publicly & virtually derived from PARENT. */ + +bool +publicly_virtually_derived_p (tree parent, tree type) +{ + tree base = lookup_base (type, parent, + ba_ignore_scope | ba_check | ba_require_virtual, + NULL, tf_none); + return base && base != error_mark_node; +} + /* CTX1 and CTX2 are declaration contexts. Return the innermost common class between them, if any. */ diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index c0e37b2fd35c..ee06858f7153 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -303,17 +303,19 @@ is_valid_constexpr_fn (tree fun, bool complain) } } } - else if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fun))) + else if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fun)) && cxx_dialect < cxx26) { ret = false; if (complain) { if (DECL_CONSTRUCTOR_P (fun)) error ("%<constexpr%> constructor in %q#T that has " - "virtual base classes", DECL_CONTEXT (fun)); + "virtual base classes only available with " + "%<-std=c++2c%> or %<-std=gnu++2c%>", DECL_CONTEXT (fun)); else error ("%<constexpr%> destructor in %q#T that has " - "virtual base classes", DECL_CONTEXT (fun)); + "virtual base classes only available with " + "%<-std=c++2c%> or %<-std=gnu++2c%>", DECL_CONTEXT (fun)); } } @@ -1182,6 +1184,10 @@ class constexpr_global_ctx { /* Heap VAR_DECLs created during the evaluation of the outermost constant expression. */ auto_vec<tree, 16> heap_vars; + /* Vector of caught exceptions, including exceptions still not active at + the start of a handler (those are immediately followed up by HANDLER_TYPE + until __cxa_begin_catch finishes). */ + auto_vec<tree, 2> caught_exceptions; /* Cleanups that need to be evaluated at the end of CLEANUP_POINT_EXPR. */ vec<tree> *cleanups; /* If non-null, only allow modification of existing values of the variables @@ -1189,10 +1195,13 @@ class constexpr_global_ctx { hash_set<tree> *modifiable; /* Number of heap VAR_DECL deallocations. */ unsigned heap_dealloc_count; + /* Number of uncaught exceptions. */ + unsigned uncaught_exceptions; + /* Constructor. */ constexpr_global_ctx () : constexpr_ops_count (0), cleanups (NULL), modifiable (nullptr), - heap_dealloc_count (0) {} + heap_dealloc_count (0), uncaught_exceptions (0) {} bool is_outside_lifetime (tree t) { @@ -1306,6 +1315,48 @@ struct constexpr_ctx { mce_value manifestly_const_eval; }; +/* Predicates for the meaning of *jump_target. */ + +static bool +returns (tree *jump_target) +{ + return *jump_target && TREE_CODE (*jump_target) == RETURN_EXPR; +} + +static bool +breaks (tree *jump_target) +{ + return (*jump_target + && ((TREE_CODE (*jump_target) == LABEL_DECL + && LABEL_DECL_BREAK (*jump_target)) + || TREE_CODE (*jump_target) == BREAK_STMT + || TREE_CODE (*jump_target) == EXIT_EXPR)); +} + +static bool +continues (tree *jump_target) +{ + return (*jump_target + && ((TREE_CODE (*jump_target) == LABEL_DECL + && LABEL_DECL_CONTINUE (*jump_target)) + || TREE_CODE (*jump_target) == CONTINUE_STMT)); +} + +static bool +switches (tree *jump_target) +{ + return *jump_target && TREE_CODE (*jump_target) == INTEGER_CST; +} + +static bool +throws (tree *jump_target) +{ + /* void_node is for use in potential_constant_expression_1, otherwise + it should an artificial VAR_DECL created by constant evaluation + of __cxa_allocate_exception (). */ + return (*jump_target && (VAR_P (*jump_target) || *jump_target == void_node)); +} + /* True if the constexpr relaxations afforded by P2280R4 for unknown references and objects are in effect. */ @@ -1541,13 +1592,672 @@ enum value_cat { }; static tree cxx_eval_constant_expression (const constexpr_ctx *, tree, - value_cat, bool *, bool *, tree * = NULL); + value_cat, bool *, bool *, tree *); static tree cxx_eval_bare_aggregate (const constexpr_ctx *, tree, - value_cat, bool *, bool *); + value_cat, bool *, bool *, tree *); static tree cxx_fold_indirect_ref (const constexpr_ctx *, location_t, tree, tree, - bool * = NULL); + bool *, tree *); static tree find_heap_var_refs (tree *, int *, void *); +/* For exception object EXC if it has class type and usable what () method + which returns cv char * return the xmalloced string literal which it returns + if possible, otherwise return NULL. */ + +static char * +exception_what_str (const constexpr_ctx *ctx, tree exc) +{ + tree type = strip_array_types (TREE_TYPE (exc)); + if (!CLASS_TYPE_P (type)) + return NULL; + tree std_exception = lookup_qualified_name (std_node, "exception", + LOOK_want::NORMAL, false); + if (TREE_CODE (std_exception) != TYPE_DECL) + return NULL; + if (!CLASS_TYPE_P (TREE_TYPE (std_exception))) + return NULL; + base_kind b_kind; + tree binfo = lookup_base (type, TREE_TYPE (std_exception), ba_check, &b_kind, + tf_none); + if (binfo == NULL_TREE || binfo == error_mark_node) + return NULL; + if (type != TREE_TYPE (exc)) + exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL); + tree call + = finish_class_member_access_expr (exc, get_identifier ("what"), false, + tf_none); + if (call == error_mark_node) + return NULL; + releasing_vec what_args; + call = finish_call_expr (call, &what_args, false, false, tf_none); + if (call == error_mark_node) + return NULL; + if (TREE_CODE (TREE_TYPE (call)) != POINTER_TYPE + || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (call))) + || !COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (call))) + || !tree_int_cst_equal (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (call))), + TYPE_SIZE_UNIT (char_type_node)) + || TYPE_PRECISION (TREE_TYPE (TREE_TYPE (call))) != BITS_PER_UNIT) + return NULL; + if (!potential_constant_expression (call)) + return NULL; + bool non_constant_p = false, overflow_p = false; + tree jmp_target = NULL; + tree ptr = cxx_eval_constant_expression (ctx, call, vc_prvalue, + &non_constant_p, &overflow_p, + &jmp_target); + if (throws (&jmp_target) || non_constant_p) + return NULL; + if (reduced_constant_expression_p (ptr)) + if (const char *msg = c_getstr (ptr)) + return xstrdup (msg); + auto_vec <char, 32> v; + for (unsigned i = 0; i < INT_MAX; ++i) + { + tree t = call; + if (i) + t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, size_int (i)); + t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t); + non_constant_p = false; + overflow_p = false; + jmp_target = NULL; + tree t2 = cxx_eval_constant_expression (ctx, t, vc_prvalue, + &non_constant_p, &overflow_p, + &jmp_target); + if (throws (&jmp_target) + || non_constant_p + || !tree_fits_shwi_p (t2)) + return NULL; + char c = tree_to_shwi (t2); + v.safe_push (c); + if (c == '\0') + break; + } + return xstrdup (v.address ()); +} + +/* Diagnose constant expression evaluation encountering call to + std::terminate due to exception EXC. */ + +static void +diagnose_std_terminate (location_t loc, const constexpr_ctx *ctx, tree exc) +{ + tree type = strip_array_types (TREE_TYPE (exc)); + if (char *str = exception_what_str (ctx, exc)) + { + error_at (loc, "%qs called after throwing an exception of type %qT; " + "%<what()%>: %qs", "std::terminate", type, str); + free (str); + } + else + { + if (type != TREE_TYPE (exc)) + exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL); + bool non_constant_p = false, overflow_p = false; + tree jmp_target = NULL; + tree val = cxx_eval_constant_expression (ctx, exc, vc_prvalue, + &non_constant_p, &overflow_p, + &jmp_target); + gcc_assert (!throws (&jmp_target) && !non_constant_p); + if (reduced_constant_expression_p (val)) + error_at (loc, "%qs called after throwing an exception %qE", + "std::terminate", val); + else + error_at (loc, "%qs called after throwing an exception of type %qT", + "std::terminate", type); + } +} + +/* Diagnose constant expression evaluation encountering call to + uncaught exception EXC. */ + +static void +diagnose_uncaught_exception (location_t loc, const constexpr_ctx *ctx, tree exc) +{ + tree type = strip_array_types (TREE_TYPE (exc)); + if (char *str = exception_what_str (ctx, exc)) + { + error_at (loc, "uncaught exception of type %qT; %<what()%>: %qs", type, str); + free (str); + } + else + { + if (type != TREE_TYPE (exc)) + exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL); + bool non_constant_p = false, overflow_p = false; + tree jmp_target = NULL; + tree val = cxx_eval_constant_expression (ctx, exc, vc_prvalue, + &non_constant_p, &overflow_p, + &jmp_target); + gcc_assert (!throws (&jmp_target) && !non_constant_p); + if (reduced_constant_expression_p (val)) + error_at (loc, "uncaught exception %qE", val); + else + error_at (loc, "uncaught exception of type %qT", type); + } +} + +/* Kinds of __cxa_* functions (and a few other EH related ones) we handle as + magic constexpr functions for C++26. */ + +enum cxa_builtin { + CXA_NONE = 0, + CXA_ALLOCATE_EXCEPTION = 1, + CXA_FREE_EXCEPTION = 2, + CXA_THROW = 3, + CXA_BEGIN_CATCH = 4, + CXA_END_CATCH = 5, + CXA_RETHROW = 6, + CXA_GET_EXCEPTION_PTR = 7, + CXA_BAD_CAST = 8, + CXA_BAD_TYPEID = 9, + CXA_THROW_BAD_ARRAY_NEW_LENGTH = 10, + STD_UNCAUGHT_EXCEPTIONS = 11, + STD_CURRENT_EXCEPTION = 12, + STD_RETHROW_EXCEPTION = 13, + BUILTIN_EH_PTR_ADJUST_REF = 14 +}; + +/* Return cxa_builtin if FNDECL is a __cxa_* function handled as + magic constexpr function for C++26. Return CXA_NONE otherwise. */ + +static enum cxa_builtin +cxx_cxa_builtin_fn_p (tree fndecl) +{ + if (cxx_dialect < cxx26) + return CXA_NONE; + if (DECL_LANGUAGE (fndecl) != lang_c) + { + if (!decl_in_std_namespace_p (fndecl)) + return CXA_NONE; + if (id_equal (DECL_NAME (fndecl), "uncaught_exceptions")) + return STD_UNCAUGHT_EXCEPTIONS; + if (id_equal (DECL_NAME (fndecl), "current_exception")) + return STD_CURRENT_EXCEPTION; + if (id_equal (DECL_NAME (fndecl), "rethrow_exception")) + return STD_RETHROW_EXCEPTION; + return CXA_NONE; + } + if (!startswith (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "__cxa_")) + return CXA_NONE; + if (id_equal (DECL_NAME (fndecl), "__cxa_allocate_exception")) + return CXA_ALLOCATE_EXCEPTION; + if (id_equal (DECL_NAME (fndecl), "__cxa_free_exception")) + return CXA_FREE_EXCEPTION; + if (id_equal (DECL_NAME (fndecl), "__cxa_throw")) + return CXA_THROW; + if (id_equal (DECL_NAME (fndecl), "__cxa_begin_catch")) + return CXA_BEGIN_CATCH; + if (id_equal (DECL_NAME (fndecl), "__cxa_end_catch")) + return CXA_END_CATCH; + if (id_equal (DECL_NAME (fndecl), "__cxa_rethrow")) + return CXA_RETHROW; + if (id_equal (DECL_NAME (fndecl), "__cxa_get_exception_ptr")) + return CXA_GET_EXCEPTION_PTR; + if (id_equal (DECL_NAME (fndecl), "__cxa_bad_cast")) + return CXA_BAD_CAST; + if (id_equal (DECL_NAME (fndecl), "__cxa_bad_typeid")) + return CXA_BAD_TYPEID; + if (id_equal (DECL_NAME (fndecl), "__cxa_throw_bad_array_new_length")) + return CXA_THROW_BAD_ARRAY_NEW_LENGTH; + return CXA_NONE; +} + +/* Helper function for cxx_eval_cxa_builtin_fn. + Check if ARG is a valid first argument of __cxa_throw or + __cxa_free_exception or __builtin_eh_ptr_adjust_ref. Return NULL_TREE if + not, otherwise return the artificial __cxa_allocate_exception allocated + VAR_DECL. FREE_EXC is true for __cxa_free_exception, false otherwise. */ + +static tree +cxa_check_throw_arg (tree arg, bool free_exc) +{ + STRIP_NOPS (arg); + if (TREE_CODE (arg) != ADDR_EXPR) + return NULL_TREE; + arg = TREE_OPERAND (arg, 0); + if (!VAR_P (arg) + || !DECL_ARTIFICIAL (arg) + || ((!free_exc || DECL_NAME (arg) != heap_uninit_identifier) + && DECL_NAME (arg) != heap_identifier) + || !DECL_LANG_SPECIFIC (arg)) + return NULL_TREE; + return arg; +} + +/* Helper function for cxx_eval_cxa_builtin_fn. + "Allocate" on the constexpr heap an exception object of TYPE + with REFCOUNT. */ + +static tree +cxa_allocate_exception (location_t loc, const constexpr_ctx *ctx, tree type, + tree refcount) +{ + tree var = build_decl (loc, VAR_DECL, heap_uninit_identifier, type); + DECL_ARTIFICIAL (var) = 1; + retrofit_lang_decl (var); + DECL_EXCEPTION_REFCOUNT (var) = refcount; + ctx->global->heap_vars.safe_push (var); + return var; +} + +/* Evaluate various __cxa_* calls as magic constexpr builtins for + C++26 constexpr exception support (P3068R5). */ + +static tree +cxx_eval_cxa_builtin_fn (const constexpr_ctx *ctx, tree call, + enum cxa_builtin kind, tree fndecl, + bool *non_constant_p, bool *overflow_p, + tree *jump_target) +{ + int nargs = call_expr_nargs (call); + location_t loc = cp_expr_loc_or_input_loc (call); + tree args[4], arg; + if (nargs > 4) + { + invalid_nargs: + if (!ctx->quiet) + error_at (loc, "call to %qD function with incorrect" + "number of arguments", fndecl); + *non_constant_p = true; + return call; + } + if ((kind == CXA_BEGIN_CATCH || kind == CXA_GET_EXCEPTION_PTR) + && nargs == 1 + && (arg = CALL_EXPR_ARG (call, 0)) + && TREE_CODE (arg) == CALL_EXPR + && call_expr_nargs (arg) == 1 + && integer_zerop (CALL_EXPR_ARG (arg, 0))) + if (tree fun = get_function_named_in_call (arg)) + if (fndecl_built_in_p (fun, BUILT_IN_EH_POINTER)) + { + if (ctx->global->caught_exceptions.length () < 2) + { + no_caught_exceptions: + if (!ctx->quiet) + error_at (loc, "%qD called with no caught exceptions pending", + fndecl); + *non_constant_p = true; + return call; + } + /* Both __cxa_get_exception_ptr (__builtin_eh_pointer (0)) + and __cxa_begin_catch (__builtin_eh_pointer (0)) calls expect + ctx->global->caught_exceptions vector to end with + __cxa_allocate_exception created artificial VAR_DECL (the + exception object) followed by handler type, pushed by TRY_BLOCK + evaluation. The only difference between the functions is that + __cxa_begin_catch pops the handler type from the vector and keeps + the VAR_DECL last and decreases uncaught_exceptions. The + VAR_DECL after __cxa_begin_catch serves as the current exception + and is then popped in __cxa_end_catch evaluation. */ + tree handler_type = ctx->global->caught_exceptions.last (); + if (handler_type && VAR_P (handler_type)) + goto no_caught_exceptions; + unsigned idx = ctx->global->caught_exceptions.length () - 2; + arg = ctx->global->caught_exceptions[idx]; + gcc_assert (VAR_P (arg)); + if (kind == CXA_BEGIN_CATCH) + { + ctx->global->caught_exceptions.pop (); + --ctx->global->uncaught_exceptions; + } + if (handler_type == NULL_TREE) + /* Used for catch (...). Just return void. */ + return void_node; + else if (POINTER_TYPE_P (handler_type)) + { + /* Used for catch of a pointer. */ + if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE) + arg = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (arg)), arg, + size_zero_node, NULL_TREE, NULL_TREE); + arg = cp_convert (handler_type, arg, + ctx->quiet ? tf_none : tf_warning_or_error); + if (arg == error_mark_node) + { + *non_constant_p = true; + return call; + } + } + else + { + /* Used for catch of a non-pointer type. */ + tree exc_type = strip_array_types (TREE_TYPE (arg)); + tree exc_ptr_type = build_pointer_type (exc_type); + arg = build_fold_addr_expr_with_type (arg, exc_ptr_type); + if (CLASS_TYPE_P (handler_type)) + { + tree ptr_type = build_pointer_type (handler_type); + arg = cp_convert (ptr_type, arg, + ctx->quiet ? tf_none + : tf_warning_or_error); + if (arg == error_mark_node) + { + *non_constant_p = true; + return call; + } + } + } + return cxx_eval_constant_expression (ctx, arg, vc_prvalue, + non_constant_p, overflow_p, + jump_target); + } + for (int i = 0; i < nargs; ++i) + { + args[i] = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (call, i), + vc_prvalue, non_constant_p, + overflow_p, jump_target); + if (*non_constant_p) + return call; + if (*jump_target) + return NULL_TREE; + } + switch (kind) + { + case CXA_ALLOCATE_EXCEPTION: + if (nargs != 1) + goto invalid_nargs; + if (!tree_fits_uhwi_p (args[0])) + { + if (!ctx->quiet) + error_at (loc, "cannot allocate exception: size not constant"); + *non_constant_p = true; + return call; + } + else + { + tree type = build_array_type_nelts (char_type_node, + tree_to_uhwi (args[0])); + tree var = cxa_allocate_exception (loc, ctx, type, size_zero_node); + ctx->global->put_value (var, NULL_TREE); + return fold_convert (ptr_type_node, build_address (var)); + } + case CXA_FREE_EXCEPTION: + if (nargs != 1) + goto invalid_nargs; + arg = cxa_check_throw_arg (args[0], true); + if (arg == NULL_TREE) + { + invalid_ptr: + if (!ctx->quiet) + error_at (loc, "first argument to %qD function not result of " + "%<__cxa_allocate_exception%>", fndecl); + *non_constant_p = true; + return call; + } + DECL_NAME (arg) = heap_deleted_identifier; + ctx->global->destroy_value (arg); + ctx->global->heap_dealloc_count++; + return void_node; + case CXA_THROW: + if (nargs != 3) + goto invalid_nargs; + arg = cxa_check_throw_arg (args[0], false); + if (arg == NULL_TREE) + goto invalid_ptr; + DECL_EXCEPTION_REFCOUNT (arg) + = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), + size_one_node); + ++ctx->global->uncaught_exceptions; + *jump_target = arg; + return void_node; + case CXA_BEGIN_CATCH: + case CXA_GET_EXCEPTION_PTR: + goto invalid_nargs; + case CXA_END_CATCH: + if (nargs != 0) + goto invalid_nargs; + if (ctx->global->caught_exceptions.is_empty ()) + { + no_active_exc: + if (!ctx->quiet) + error_at (loc, "%qD called with no caught exceptions active", + fndecl); + *non_constant_p = true; + return call; + } + else + { + arg = ctx->global->caught_exceptions.pop (); + if (arg == NULL_TREE || !VAR_P (arg)) + goto no_active_exc; + free_except: + DECL_EXCEPTION_REFCOUNT (arg) + = size_binop (MINUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), + size_one_node); + if (integer_zerop (DECL_EXCEPTION_REFCOUNT (arg))) + { + if (type_build_dtor_call (TREE_TYPE (arg))) + { + tree cleanup + = cxx_maybe_build_cleanup (arg, (ctx->quiet ? tf_none + : tf_warning_or_error)); + if (cleanup == error_mark_node) + *non_constant_p = true; + tree jmp_target = NULL_TREE; + cxx_eval_constant_expression (ctx, cleanup, vc_discard, + non_constant_p, overflow_p, + &jmp_target); + if (throws (&jmp_target)) + *jump_target = jmp_target; + } + DECL_NAME (arg) = heap_deleted_identifier; + ctx->global->destroy_value (arg); + ctx->global->heap_dealloc_count++; + } + } + return void_node; + case CXA_RETHROW: + if (nargs != 0) + goto invalid_nargs; + unsigned idx; + FOR_EACH_VEC_ELT_REVERSE (ctx->global->caught_exceptions, idx, arg) + if (arg == NULL_TREE || !VAR_P (arg)) + --idx; + else + break; + if (arg == NULL_TREE) + { + if (!ctx->quiet) + error_at (loc, "%qD called with no caught exceptions active", + fndecl); + *non_constant_p = true; + return call; + } + DECL_EXCEPTION_REFCOUNT (arg) + = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), size_one_node); + ++ctx->global->uncaught_exceptions; + *jump_target = arg; + return void_node; + case CXA_BAD_CAST: + case CXA_BAD_TYPEID: + case CXA_THROW_BAD_ARRAY_NEW_LENGTH: + if (nargs != 0) + goto invalid_nargs; + else + { + tree name; + switch (kind) + { + case CXA_BAD_CAST: + name = get_identifier ("bad_cast"); + break; + case CXA_BAD_TYPEID: + name = get_identifier ("bad_typeid"); + break; + case CXA_THROW_BAD_ARRAY_NEW_LENGTH: + name = get_identifier ("bad_array_new_length"); + break; + default: + gcc_unreachable (); + } + tree decl = lookup_qualified_name (std_node, name); + if (TREE_CODE (decl) != TYPE_DECL + || !CLASS_TYPE_P (TREE_TYPE (decl)) + || !type_build_ctor_call (TREE_TYPE (decl))) + { + if (!ctx->quiet) + error_at (loc, "%qD called without %<std::%D%> being defined", + fndecl, name); + *non_constant_p = true; + return call; + } + tree type = TREE_TYPE (decl); + tree var = cxa_allocate_exception (loc, ctx, type, size_one_node); + tree ctor + = build_special_member_call (var, complete_ctor_identifier, + NULL, type, LOOKUP_NORMAL, + ctx->quiet ? tf_none + : tf_warning_or_error); + if (ctor == error_mark_node) + { + *non_constant_p = true; + return call; + } + if (TREE_CONSTANT (ctor)) + ctx->global->put_value (var, ctor); + else + { + ctx->global->put_value (var, NULL_TREE); + cxx_eval_constant_expression (ctx, ctor, vc_discard, + non_constant_p, overflow_p, + jump_target); + if (*non_constant_p) + return call; + if (throws (jump_target)) + return NULL_TREE; + } + ++ctx->global->uncaught_exceptions; + *jump_target = var; + } + return void_node; + case STD_UNCAUGHT_EXCEPTIONS: + if (nargs != 0) + goto invalid_nargs; + /* Similarly to __builtin_is_constant_evaluated (), we don't + want to give a definite answer during mce_unknown evaluation, + because that might prevent evaluation later on when some + exceptions might be uncaught. But unlike that, we don't + want to constant fold it even during cp_fold, because at runtime + std::uncaught_exceptions () might still be non-zero. */ + if (ctx->manifestly_const_eval != mce_true) + { + *non_constant_p = true; + return call; + } + return build_int_cst (integer_type_node, + ctx->global->uncaught_exceptions); + case STD_CURRENT_EXCEPTION: + if (nargs != 0) + goto invalid_nargs; + else + { + tree name = get_identifier ("exception_ptr"); + tree decl = lookup_qualified_name (std_node, name); + tree fld; + if (TREE_CODE (decl) != TYPE_DECL + || !CLASS_TYPE_P (TREE_TYPE (decl)) + || !COMPLETE_TYPE_P (TREE_TYPE (decl)) + || !(fld = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (decl)))) + || DECL_ARTIFICIAL (fld) + || TREE_CODE (TREE_TYPE (fld)) != POINTER_TYPE + || next_aggregate_field (DECL_CHAIN (fld)) + || !tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (decl)), + TYPE_SIZE (TREE_TYPE (fld)))) + { + if (!ctx->quiet) + error_at (loc, "%qD called without supportable %qs", + fndecl, "std::exception_ptr"); + *non_constant_p = true; + return call; + } + FOR_EACH_VEC_ELT_REVERSE (ctx->global->caught_exceptions, idx, arg) + if (arg == NULL_TREE || !VAR_P (arg)) + --idx; + else + break; + /* Similarly to __builtin_is_constant_evaluated (), we don't + want to give a definite answer during mce_unknown evaluation, + because that might prevent evaluation later on when some + exceptions might be current. But unlike that, we don't + want to constant fold it to null even during cp_fold, because + at runtime std::current_exception () might still be non-null. */ + if (ctx->manifestly_const_eval != mce_true && arg == NULL_TREE) + { + *non_constant_p = true; + return call; + } + if (arg == NULL_TREE) + arg = build_zero_cst (TREE_TYPE (fld)); + else + { + DECL_EXCEPTION_REFCOUNT (arg) + = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), + size_one_node); + arg = fold_convert (ptr_type_node, build_address (arg)); + } + return build_constructor_single (TREE_TYPE (decl), fld, arg); + } + case STD_RETHROW_EXCEPTION: + if (nargs != 1) + goto invalid_nargs; + if (TYPE_REF_P (TREE_TYPE (args[0]))) + { + arg = args[0]; + STRIP_NOPS (arg); + if (TREE_CODE (arg) == ADDR_EXPR) + { + args[0] + = cxx_eval_constant_expression (ctx, TREE_OPERAND (arg, 0), + vc_prvalue, non_constant_p, + overflow_p, jump_target); + if (*non_constant_p) + return call; + if (*jump_target) + return NULL_TREE; + } + } + if (TREE_CODE (args[0]) != CONSTRUCTOR + || CONSTRUCTOR_NELTS (args[0]) != 1) + { + invalid_std_rethrow: + if (!ctx->quiet) + error_at (loc, "%qD called with unexpected %qs argument", + fndecl, "std::exception_ptr"); + *non_constant_p = true; + return void_node; + } + arg = cxa_check_throw_arg (CONSTRUCTOR_ELT (args[0], 0)->value, false); + if (arg == NULL_TREE) + goto invalid_std_rethrow; + DECL_EXCEPTION_REFCOUNT (arg) + = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), size_one_node); + ++ctx->global->uncaught_exceptions; + *jump_target = arg; + return void_node; + case BUILTIN_EH_PTR_ADJUST_REF: + if (nargs != 2) + goto invalid_nargs; + arg = cxa_check_throw_arg (args[0], false); + if (arg == NULL_TREE) + goto invalid_ptr; + if (integer_onep (args[1])) + DECL_EXCEPTION_REFCOUNT (arg) + = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), + size_one_node); + else if (integer_minus_onep (args[1])) + goto free_except; + else + { + if (!ctx->quiet) + error_at (loc, "%qD called with second argument " + "other than 1 or -1", fndecl); + *non_constant_p = true; + } + return void_node; + default: + gcc_unreachable (); + } +} + /* Attempt to evaluate T which represents a call to a builtin function. We assume here that all builtin functions evaluate to scalar types represented by _CST nodes. */ @@ -1555,7 +2265,8 @@ static tree find_heap_var_refs (tree *, int *, void *); static tree cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { const int nargs = call_expr_nargs (t); tree *args = (tree *) alloca (nargs * sizeof (tree)); @@ -1601,6 +2312,12 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, return fold_builtin_source_location (t); } + if (fndecl_built_in_p (fun, CP_BUILT_IN_EH_PTR_ADJUST_REF, + BUILT_IN_FRONTEND)) + return cxx_eval_cxa_builtin_fn (ctx, t, BUILTIN_EH_PTR_ADJUST_REF, + fun, non_constant_p, overflow_p, + jump_target); + int strops = 0; int strret = 0; if (fndecl_built_in_p (fun, BUILT_IN_NORMAL)) @@ -1675,8 +2392,14 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, || potential_constant_expression (arg)) { bool dummy1 = false, dummy2 = false; + tree jmp_target = NULL_TREE; arg = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue, - &dummy1, &dummy2); + &dummy1, &dummy2, &jmp_target); + if (jmp_target) + { + *jump_target = jmp_target; + return NULL_TREE; + } } if (bi_const_p) @@ -1765,7 +2488,8 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, } return cxx_eval_constant_expression (&new_ctx, new_call, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); } /* TEMP is the constant value of a temporary object of type TYPE. Adjust @@ -1879,20 +2603,29 @@ addr_of_non_const_var (tree *tp, int *walk_subtrees, void *data) static tree cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun, - bool *non_constant_p, bool *overflow_p, - bool *non_constant_args) + tree orig_fun, bool *non_constant_p, + bool *overflow_p, bool *non_constant_args, + tree *jump_target) { - const int nargs = call_expr_nargs (t); + int nargs = call_expr_nargs (t); tree parms = DECL_ARGUMENTS (fun); - int i; + int i, j = 0; + if (DECL_HAS_IN_CHARGE_PARM_P (fun) && fun != orig_fun) + ++nargs; + if (DECL_HAS_VTT_PARM_P (fun) + && fun != orig_fun + && (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun) + || DECL_COMPLETE_DESTRUCTOR_P (orig_fun))) + ++nargs; /* We don't record ellipsis args below. */ int nparms = list_length (parms); int nbinds = nargs < nparms ? nargs : nparms; tree binds = make_tree_vec (nbinds); /* The call is not a constant expression if it involves the cdtor for a type - with virtual bases. */ - if (DECL_HAS_IN_CHARGE_PARM_P (fun) || DECL_HAS_VTT_PARM_P (fun)) + with virtual bases before C++26. */ + if (cxx_dialect < cxx26 + && (DECL_HAS_IN_CHARGE_PARM_P (fun) || DECL_HAS_VTT_PARM_P (fun))) { if (!ctx->quiet) { @@ -1910,7 +2643,30 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun, tree type = parms ? TREE_TYPE (parms) : void_type_node; if (parms && DECL_BY_REFERENCE (parms)) type = TREE_TYPE (type); - x = get_nth_callarg (t, i); + if (i == 1 + && j == 0 + && DECL_HAS_IN_CHARGE_PARM_P (fun) + && orig_fun != fun) + { + if (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun) + || DECL_COMPLETE_DESTRUCTOR_P (orig_fun)) + x = boolean_true_node; + else + x = boolean_false_node; + j = -1; + } + else if (i == 2 + && j == -1 + && DECL_HAS_VTT_PARM_P (fun) + && orig_fun != fun + && (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun) + || DECL_COMPLETE_DESTRUCTOR_P (orig_fun))) + { + x = build_zero_cst (type); + j = -2; + } + else + x = get_nth_callarg (t, i + j); /* For member function, the first argument is a pointer to the implied object. For a constructor, it might still be a dummy object, in which case we get the real argument from ctx. */ @@ -1925,14 +2681,16 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun, /* Undo convert_for_arg_passing work here. */ x = convert_from_reference (x); arg = cxx_eval_constant_expression (ctx, x, vc_glvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); } else /* Normally we would strip a TARGET_EXPR in an initialization context such as this, but here we do the elision differently: we keep the TARGET_EXPR, and use its CONSTRUCTOR as the value of the parm. */ arg = cxx_eval_constant_expression (ctx, x, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); /* Check we aren't dereferencing a null pointer when calling a non-static member function, which is undefined behaviour. */ if (i == 0 && DECL_OBJECT_MEMBER_FUNCTION_P (fun) @@ -1950,6 +2708,8 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun, /* Don't VERIFY_CONSTANT here. */ if (*non_constant_p && ctx->quiet) break; + if (*jump_target) + break; /* Just discard ellipsis args after checking their constantitude. */ if (!parms) continue; @@ -2061,9 +2821,10 @@ fold_operand (tree e, const constexpr_ctx *ctx) if (ctx) { bool new_non_constant_p = false, new_overflow_p = false; + tree jmp_target = NULL_TREE; e = cxx_eval_constant_expression (ctx, e, vc_prvalue, &new_non_constant_p, - &new_overflow_p); + &new_overflow_p, &jmp_target); } else e = fold_non_dependent_expr (e, tf_none, /*manifestly_const_eval=*/true); @@ -2150,7 +2911,7 @@ cxx_eval_assert (const constexpr_ctx *ctx, tree arg, const char *msg, if (*non_constant_p) return true; - tree eval; + tree eval, jmp_target = NULL_TREE; if (!evaluated) { if (!potential_rvalue_constant_expression (arg)) @@ -2163,12 +2924,15 @@ cxx_eval_assert (const constexpr_ctx *ctx, tree arg, const char *msg, modifiable_tracker ms (new_ctx.global); eval = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue, &new_non_constant_p, - &new_overflow_p); + &new_overflow_p, &jmp_target); } else eval = cxx_eval_constant_expression (ctx, arg, vc_prvalue, non_constant_p, - overflow_p); + overflow_p, &jmp_target); + if (jmp_target) + return true; + if (!*non_constant_p && integer_zerop (eval)) { if (!ctx->quiet) @@ -2200,7 +2964,8 @@ cxx_eval_assert (const constexpr_ctx *ctx, tree arg, const char *msg, static tree cxx_eval_internal_function (const constexpr_ctx *ctx, tree t, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { enum tree_code opcode = ERROR_MARK; @@ -2233,13 +2998,15 @@ cxx_eval_internal_function (const constexpr_ctx *ctx, tree t, case IFN_LAUNDER: return cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0), vc_prvalue, non_constant_p, - overflow_p); + overflow_p, jump_target); case IFN_VEC_CONVERT: { tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0), vc_prvalue, non_constant_p, - overflow_p); + overflow_p, jump_target); + if (*jump_target) + return NULL_TREE; if (TREE_CODE (arg) == VECTOR_CST) if (tree r = fold_const_call (CFN_VEC_CONVERT, TREE_TYPE (t), arg)) return r; @@ -2257,10 +3024,13 @@ cxx_eval_internal_function (const constexpr_ctx *ctx, tree t, /* Evaluate constant arguments using OPCODE and return a complex number containing the result and the overflow bit. */ tree arg0 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0), lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); tree arg1 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 1), lval, - non_constant_p, overflow_p); - + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST) { location_t loc = cp_expr_loc_or_input_loc (t); @@ -2529,14 +3299,12 @@ get_component_with_type (tree path, tree type, tree stop) dst_ptr + src2dst == src_ptr -1: unspecified relationship -2: src_type is not a public base of dst_type - -3: src_type is a multiple public non-virtual base of dst_type - - Since literal types can't have virtual bases, we only expect hint >=0, - -2, or -3. */ + -3: src_type is a multiple public non-virtual base of dst_type */ static tree cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { /* T will be something like __dynamic_cast ((B*) b, &_ZTI1B, &_ZTI1D, 8) @@ -2555,19 +3323,42 @@ cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call, /* TYPE can only be either T* or T&. We can't know which of these it is by looking at TYPE, but OBJ will be "(T*) x" in the first case, - and something like "(T*)(T&)(T*) x" in the second case. */ - bool reference_p = false; + and something like "(T*)(T&)(T*) x" in the second case. + This is true for the reference cases in C++ < 26 or when exceptions + aren't enabled, in that case we should diagnose errors. For C++26 + with exceptions we should silently evaluate to null pointer and + let the callers call __cxa_bad_cast () later to throw an exception. */ + bool fail_for_non_constant_p = false; while (CONVERT_EXPR_P (obj) || TREE_CODE (obj) == SAVE_EXPR) { - reference_p |= TYPE_REF_P (TREE_TYPE (obj)); + if (cxx_dialect < cxx26 || !flag_exceptions) + fail_for_non_constant_p |= TYPE_REF_P (TREE_TYPE (obj)); obj = TREE_OPERAND (obj, 0); } /* Evaluate the object so that we know its dynamic type. */ obj = cxx_eval_constant_expression (ctx, obj, vc_prvalue, non_constant_p, - overflow_p); + overflow_p, jump_target); if (*non_constant_p) return call; + if (*jump_target) + return NULL_TREE; + + /* For dynamic_cast from classes with virtual bases we can get something + like (virt_base *)(&d + 16) as OBJ. Try to convert that into + d.D.1234 using cxx_fold_indirect_ref. */ + if (cxx_dialect >= cxx26 && CONVERT_EXPR_P (obj)) + { + tree objo = obj; + STRIP_NOPS (objo); + if (TREE_CODE (objo) == POINTER_PLUS_EXPR) + { + objo = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (TREE_TYPE (obj)), + obj, NULL, jump_target); + if (objo) + obj = build_fold_addr_expr (objo); + } + } /* We expect OBJ to be in form of &d.D.2102 when HINT == 0, but when HINT is > 0, it can also be something like @@ -2579,7 +3370,7 @@ cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call, ? TREE_OPERAND (obj, 1) : obj)) if (TREE_CODE (t) != FIELD_DECL || !DECL_FIELD_IS_BASE (t)) { - if (reference_p) + if (fail_for_non_constant_p) { if (!ctx->quiet) { @@ -2601,9 +3392,12 @@ cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call, constructor or destructor's class. */ tree vtable = build_vfield_ref (obj, objtype); vtable = cxx_eval_constant_expression (ctx, vtable, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); if (*non_constant_p) return call; + if (*jump_target) + return NULL_TREE; /* With -fsanitize=vptr, we initialize all vtable pointers to null, so it's possible that we got a null pointer now. */ if (integer_zerop (vtable)) @@ -2635,7 +3429,7 @@ cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call, /* If not accessible, give an error. */ if (t == error_mark_node) { - if (reference_p) + if (fail_for_non_constant_p) { if (!ctx->quiet) { @@ -2668,7 +3462,7 @@ cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call, obj = get_component_with_type (obj, mdtype, NULL_TREE); if (obj == error_mark_node) { - if (reference_p) + if (fail_for_non_constant_p) { if (!ctx->quiet) { @@ -2690,7 +3484,7 @@ cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call, tree binfo = lookup_base (mdtype, type, ba_check, &b_kind, tf_none); if (!binfo || binfo == error_mark_node) { - if (reference_p) + if (fail_for_non_constant_p) { if (!ctx->quiet) { @@ -2786,7 +3580,7 @@ replace_decl (tree *tp, tree decl, tree replacement) static tree cxx_eval_thunk_call (const constexpr_ctx *ctx, tree t, tree thunk_fndecl, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, tree *jump_target) { tree function = THUNK_TARGET (thunk_fndecl); @@ -2829,7 +3623,8 @@ cxx_eval_thunk_call (const constexpr_ctx *ctx, tree t, tree thunk_fndecl, new_call, offset); return cxx_eval_constant_expression (ctx, new_call, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); } /* If OBJECT is of const class type, evaluate it to a CONSTRUCTOR and set @@ -2839,7 +3634,7 @@ cxx_eval_thunk_call (const constexpr_ctx *ctx, tree t, tree thunk_fndecl, static void cxx_set_object_constness (const constexpr_ctx *ctx, tree object, bool readonly_p, bool *non_constant_p, - bool *overflow_p) + bool *overflow_p, tree *jump_target) { if (CLASS_TYPE_P (TREE_TYPE (object)) && CP_TYPE_CONST_P (TREE_TYPE (object))) @@ -2847,8 +3642,11 @@ cxx_set_object_constness (const constexpr_ctx *ctx, tree object, /* Subobjects might not be stored in ctx->global->values but we can get its CONSTRUCTOR by evaluating *this. */ tree e = cxx_eval_constant_expression (ctx, object, vc_prvalue, - non_constant_p, overflow_p); - if (TREE_CODE (e) == CONSTRUCTOR && !*non_constant_p) + non_constant_p, overflow_p, + jump_target); + if (!*non_constant_p + && !throws (jump_target) + && TREE_CODE (e) == CONSTRUCTOR) TREE_READONLY (e) = readonly_p; } } @@ -2860,20 +3658,25 @@ cxx_set_object_constness (const constexpr_ctx *ctx, tree object, static tree cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { location_t loc = cp_expr_loc_or_input_loc (t); tree fun = get_function_named_in_call (t); if (fun == NULL_TREE) return cxx_eval_internal_function (ctx, t, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); if (TREE_CODE (fun) != FUNCTION_DECL) { /* Might be a constexpr function pointer. */ fun = cxx_eval_constant_expression (ctx, fun, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; STRIP_NOPS (fun); if (TREE_CODE (fun) == ADDR_EXPR) fun = TREE_OPERAND (fun, 0); @@ -2916,6 +3719,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, *non_constant_p = true; return t; } + tree orig_fun = fun; if (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun)) fun = DECL_CLONED_FUNCTION (fun); @@ -2924,9 +3728,12 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, if (fndecl_built_in_p (fun)) return cxx_eval_builtin_function_call (ctx, t, fun, - lval, non_constant_p, overflow_p); + lval, non_constant_p, overflow_p, + jump_target); if (DECL_THUNK_P (fun)) - return cxx_eval_thunk_call (ctx, t, fun, lval, non_constant_p, overflow_p); + return cxx_eval_thunk_call (ctx, t, fun, lval, non_constant_p, overflow_p, + jump_target); + bool non_constexpr_call = false; if (!maybe_constexpr_fn (fun)) { if (TREE_CODE (t) == CALL_EXPR @@ -2941,7 +3748,10 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, { tree arg = CALL_EXPR_ARG (t, i); arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; /* Deleting a non-constant pointer has a better error message below. */ if (new_op_p || i != 0) @@ -3056,7 +3866,10 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, { tree arg = CALL_EXPR_ARG (t, i); arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; if (i == 1) arg1 = arg; else @@ -3066,16 +3879,31 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, return arg1; } else if (cxx_dynamic_cast_fn_p (fun)) - return cxx_eval_dynamic_cast_fn (ctx, t, non_constant_p, overflow_p); + return cxx_eval_dynamic_cast_fn (ctx, t, non_constant_p, overflow_p, + jump_target); + else if (enum cxa_builtin kind = cxx_cxa_builtin_fn_p (fun)) + return cxx_eval_cxa_builtin_fn (ctx, t, kind, fun, + non_constant_p, overflow_p, + jump_target); - if (!ctx->quiet) + /* Calls to non-constexpr functions can be diagnosed right away + before C++26, though in C++26 evaluation of the arguments might + throw and if caught it could be still constant expression. + So for C++26 this is diagnosed only after + cxx_bind_parameters_in_call. */ + if (cxx_dialect >= cxx26) + non_constexpr_call = true; + else { - if (!lambda_static_thunk_p (fun)) - error_at (loc, "call to non-%<constexpr%> function %qD", fun); - explain_invalid_constexpr_fn (fun); + if (!ctx->quiet) + { + if (!lambda_static_thunk_p (fun)) + error_at (loc, "call to non-%<constexpr%> function %qD", fun); + explain_invalid_constexpr_fn (fun); + } + *non_constant_p = true; + return t; } - *non_constant_p = true; - return t; } constexpr_ctx new_ctx = *ctx; @@ -3110,8 +3938,9 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, bool non_constant_args = false; constexpr_call new_call; new_call.bindings - = cxx_bind_parameters_in_call (ctx, t, fun, non_constant_p, - overflow_p, &non_constant_args); + = cxx_bind_parameters_in_call (ctx, t, fun, orig_fun, non_constant_p, + overflow_p, &non_constant_args, + jump_target); /* We build up the bindings list before we know whether we already have this call cached. If we don't end up saving these bindings, ggc_free them when @@ -3125,8 +3954,21 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, void preserve () { bindings = NULL; } } fb (new_call.bindings); + if (*jump_target) + return NULL_TREE; if (*non_constant_p) return t; + if (non_constexpr_call) + { + if (!ctx->quiet) + { + if (!lambda_static_thunk_p (fun)) + error_at (loc, "call to non-%<constexpr%> function %qD", fun); + explain_invalid_constexpr_fn (fun); + } + *non_constant_p = true; + return t; + } /* We can't defer instantiating the function any longer. */ if (!DECL_INITIAL (fun) @@ -3199,7 +4041,9 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, new_obj = TREE_VEC_ELT (new_call.bindings, 0); bool empty_base = false; new_obj = cxx_fold_indirect_ref (ctx, loc, DECL_CONTEXT (fun), new_obj, - &empty_base); + &empty_base, jump_target); + if (*jump_target) + return NULL_TREE; /* If we're initializing an empty class, don't set constness, because cxx_fold_indirect_ref will return the wrong object to set constness of. */ @@ -3348,7 +4192,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, semantics are no longer in effect; see [class.dtor]p5. */ if (new_obj && DECL_DESTRUCTOR_P (fun)) cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/false, - non_constant_p, overflow_p); + non_constant_p, overflow_p, jump_target); /* If this is a constructor, we are beginning the lifetime of the object we are initializing. */ @@ -3357,21 +4201,30 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, && TREE_CODE (new_obj) == COMPONENT_REF && TREE_CODE (TREE_TYPE (TREE_OPERAND (new_obj, 0))) == UNION_TYPE) { + tree ctor = build_constructor (TREE_TYPE (new_obj), NULL); + CONSTRUCTOR_NO_CLEARING (ctor) = true; tree activate = build2 (INIT_EXPR, TREE_TYPE (new_obj), - new_obj, - build_constructor (TREE_TYPE (new_obj), - NULL)); + new_obj, ctor); cxx_eval_constant_expression (ctx, activate, - lval, non_constant_p, overflow_p); + lval, non_constant_p, overflow_p, + jump_target); ggc_free (activate); + if (*jump_target) + return NULL_TREE; } - tree jump_target = NULL_TREE; + tree jmp_target = NULL_TREE; cxx_eval_constant_expression (&call_ctx, body, vc_discard, non_constant_p, overflow_p, - &jump_target); + &jmp_target); - if (DECL_CONSTRUCTOR_P (fun)) + if (!*non_constant_p && throws (&jmp_target)) + { + result = NULL_TREE; + cacheable = false; + *jump_target = jmp_target; + } + else if (DECL_CONSTRUCTOR_P (fun)) /* This can be null for a subobject constructor call, in which case what we care about is the initialization side-effects rather than the value. We could get at the @@ -3399,7 +4252,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, marking the CONSTRUCTOR TREE_READONLY. */ if (new_obj && DECL_CONSTRUCTOR_P (fun)) cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/true, - non_constant_p, overflow_p); + non_constant_p, overflow_p, jump_target); /* Remove the parms/result from the values map. */ destroy_value_checked (ctx, res, non_constant_p); @@ -3459,7 +4312,13 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, cacheable = false; result = cxx_eval_constant_expression (ctx, result, lval, non_constant_p, - overflow_p); + overflow_p, + jump_target); + if (*jump_target) + { + cacheable = false; + result = NULL_TREE; + } } } @@ -3514,11 +4373,12 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, /* Return true if T is a valid constant initializer. If a CONSTRUCTOR initializes all the members, the CONSTRUCTOR_NO_CLEARING flag will be - cleared. + cleared. If called recursively on a FIELD_DECL's CONSTRUCTOR, SZ + is DECL_SIZE of the FIELD_DECL, otherwise NULL. FIXME speed this up, it's taking 16% of compile time on sieve testcase. */ bool -reduced_constant_expression_p (tree t) +reduced_constant_expression_p (tree t, tree sz /* = NULL_TREE */) { if (t == NULL_TREE) return false; @@ -3586,7 +4446,12 @@ reduced_constant_expression_p (tree t) { /* If VAL is null, we're in the middle of initializing this element. */ - if (!reduced_constant_expression_p (e.value)) + if (!reduced_constant_expression_p (e.value, + (e.index + && (TREE_CODE (e.index) + == FIELD_DECL)) + ? DECL_SIZE (e.index) + : NULL_TREE)) return false; /* We want to remove initializers for empty fields in a struct to avoid confusing output_constructor. */ @@ -3606,7 +4471,16 @@ reduced_constant_expression_p (tree t) /* There could be a non-empty field at the end. */ for (; field; field = next_subobject_field (DECL_CHAIN (field))) if (!is_really_empty_class (TREE_TYPE (field), /*ignore_vptr*/false)) - return false; + { + /* Ignore FIELD_DECLs with bit positions beyond DECL_SIZE of + the parent FIELD_DECL (if any) for classes with virtual + bases. */ + if (cxx_dialect >= cxx26 + && sz + && tree_int_cst_le (sz, bit_position (field))) + break; + return false; + } ok: if (CONSTRUCTOR_NO_CLEARING (t)) /* All the fields are initialized. */ @@ -3802,12 +4676,16 @@ cxx_eval_check_shift_p (location_t loc, const constexpr_ctx *ctx, static tree cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t, bool /*lval*/, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { tree r; tree orig_arg = TREE_OPERAND (t, 0); tree arg = cxx_eval_constant_expression (ctx, orig_arg, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; VERIFY_CONSTANT (arg); location_t loc = EXPR_LOCATION (t); enum tree_code code = TREE_CODE (t); @@ -3831,7 +4709,7 @@ cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t, static tree cxx_fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t, tree lhs, tree rhs, bool *non_constant_p, - bool *overflow_p) + bool *overflow_p, tree *jump_target) { STRIP_NOPS (lhs); if (TREE_CODE (lhs) != ADDR_EXPR) @@ -3853,9 +4731,12 @@ cxx_fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t, t = fold_convert_loc (loc, ssizetype, TREE_OPERAND (lhs, 1)); tree nelts = array_type_nelts_top (TREE_TYPE (TREE_OPERAND (lhs, 0))); nelts = cxx_eval_constant_expression (ctx, nelts, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); if (*non_constant_p) return NULL_TREE; + if (*jump_target) + return NULL_TREE; /* Don't fold an out-of-bound access. */ if (!tree_int_cst_le (t, nelts)) return NULL_TREE; @@ -3875,7 +4756,8 @@ cxx_fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t, t = cp_build_addr_expr (t, tf_warning_or_error); t = cp_fold_convert (orig_type, t); return cxx_eval_constant_expression (ctx, t, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); } return NULL_TREE; @@ -3919,22 +4801,29 @@ cxx_maybe_fold_addr_pointer_plus (tree t) static tree cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { tree r = NULL_TREE; tree orig_lhs = TREE_OPERAND (t, 0); tree orig_rhs = TREE_OPERAND (t, 1); tree lhs, rhs; lhs = cxx_eval_constant_expression (ctx, orig_lhs, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); /* Don't VERIFY_CONSTANT here, it's unnecessary and will break pointer subtraction. */ if (*non_constant_p) return t; + if (*jump_target) + return NULL_TREE; rhs = cxx_eval_constant_expression (ctx, orig_rhs, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); if (*non_constant_p) return t; + if (*jump_target) + return NULL_TREE; location_t loc = EXPR_LOCATION (t); enum tree_code code = TREE_CODE (t); @@ -3990,13 +4879,17 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t, return t; } else if (code == POINTER_PLUS_EXPR) - r = cxx_fold_pointer_plus_expression (ctx, t, lhs, rhs, non_constant_p, - overflow_p); + { + r = cxx_fold_pointer_plus_expression (ctx, t, lhs, rhs, non_constant_p, + overflow_p, jump_target); + if (*jump_target) + return NULL_TREE; + } else if (code == SPACESHIP_EXPR) { r = genericize_spaceship (loc, type, lhs, rhs); return cxx_eval_constant_expression (ctx, r, lval, non_constant_p, - overflow_p); + overflow_p, jump_target); } if (r == NULL_TREE) @@ -4055,7 +4948,10 @@ cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t, { tree val = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; VERIFY_CONSTANT (val); if (TREE_CODE (t) == IF_STMT && IF_STMT_CONSTEVAL_P (t)) { @@ -4116,19 +5012,29 @@ cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t, static tree cxx_eval_vector_conditional_expression (const constexpr_ctx *ctx, tree t, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { tree arg1 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; VERIFY_CONSTANT (arg1); tree arg2 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; VERIFY_CONSTANT (arg2); tree arg3 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2), vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; VERIFY_CONSTANT (arg3); location_t loc = EXPR_LOCATION (t); tree type = TREE_TYPE (t); @@ -4516,7 +5422,8 @@ diag_array_subscript (location_t loc, const constexpr_ctx *ctx, tree array, tree static tree get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { tree nelts; if (TREE_CODE (type) == ARRAY_TYPE) @@ -4533,7 +5440,8 @@ get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type, /* For VLAs, the number of elements won't be an integer constant. */ nelts = cxx_eval_constant_expression (ctx, nelts, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); return nelts; } @@ -4564,13 +5472,17 @@ extract_string_elt (tree string, unsigned chars_per_elt, unsigned index) static tree eval_and_check_array_index (const constexpr_ctx *ctx, tree t, bool allow_one_past, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { location_t loc = cp_expr_loc_or_input_loc (t); tree ary = TREE_OPERAND (t, 0); t = TREE_OPERAND (t, 1); tree index = cxx_eval_constant_expression (ctx, t, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; VERIFY_CONSTANT (index); if (!tree_fits_shwi_p (index) @@ -4582,7 +5494,9 @@ eval_and_check_array_index (const constexpr_ctx *ctx, } tree nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary), non_constant_p, - overflow_p); + overflow_p, jump_target); + if (*jump_target) + return NULL_TREE; VERIFY_CONSTANT (nelts); if (allow_one_past ? !tree_int_cst_le (index, nelts) @@ -4602,14 +5516,18 @@ eval_and_check_array_index (const constexpr_ctx *ctx, static tree cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { tree oldary = TREE_OPERAND (t, 0); tree ary = cxx_eval_constant_expression (ctx, oldary, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); if (*non_constant_p) return t; + if (*jump_target) + return NULL_TREE; if (!lval && TREE_CODE (ary) == VIEW_CONVERT_EXPR && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0))) @@ -4619,9 +5537,12 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, tree oldidx = TREE_OPERAND (t, 1); tree index = eval_and_check_array_index (ctx, t, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); if (*non_constant_p) return t; + if (*jump_target) + return NULL_TREE; if (lval && ary == oldary && index == oldidx) return t; @@ -4739,7 +5660,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, ctx = &new_ctx; } t = cxx_eval_constant_expression (ctx, val, lval, non_constant_p, - overflow_p); + overflow_p, jump_target); if (new_ctor && t != ctx->ctor) free_constructor (ctx->ctor); return t; @@ -4751,7 +5672,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, static tree cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { unsigned HOST_WIDE_INT i; tree field; @@ -4760,9 +5682,12 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, tree orig_whole = TREE_OPERAND (t, 0); tree whole = cxx_eval_constant_expression (ctx, orig_whole, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); if (*non_constant_p) return t; + if (*jump_target) + return NULL_TREE; if (INDIRECT_REF_P (whole) && integer_zerop (TREE_OPERAND (whole, 0))) { @@ -4868,10 +5793,23 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, } /* If there's no explicit init for this field, it's value-initialized. */ + + if (AGGREGATE_TYPE_P (TREE_TYPE (t))) + { + /* As in cxx_eval_store_expression, insert an empty CONSTRUCTOR + and copy the flags. */ + constructor_elt *e = get_or_insert_ctor_field (whole, part); + e->value = value = build_constructor (TREE_TYPE (part), NULL); + CONSTRUCTOR_ZERO_PADDING_BITS (value) + = CONSTRUCTOR_ZERO_PADDING_BITS (whole); + return value; + } + value = build_value_init (TREE_TYPE (t), tf_warning_or_error); return cxx_eval_constant_expression (ctx, value, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); } /* Subroutine of cxx_eval_constant_expression. @@ -4881,7 +5819,8 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, static tree cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { tree orig_whole = TREE_OPERAND (t, 0); tree retval, fldval, utype, mask; @@ -4889,10 +5828,13 @@ cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t, HOST_WIDE_INT istart, isize; tree whole = cxx_eval_constant_expression (ctx, orig_whole, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); tree start, field, value; unsigned HOST_WIDE_INT i; + if (*jump_target) + return NULL_TREE; if (whole == orig_whole) return t; /* Don't VERIFY_CONSTANT here; we only want to check that we got a @@ -5173,7 +6115,7 @@ clear_uchar_or_std_byte_in_mask (location_t loc, tree t, unsigned char *mask) static tree cxx_eval_bit_cast (const constexpr_ctx *ctx, tree t, bool *non_constant_p, - bool *overflow_p) + bool *overflow_p, tree *jump_target) { if (check_bit_cast_type (ctx, EXPR_LOCATION (t), TREE_TYPE (t), TREE_TYPE (t)) @@ -5187,9 +6129,12 @@ cxx_eval_bit_cast (const constexpr_ctx *ctx, tree t, bool *non_constant_p, } tree op = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); if (*non_constant_p) return t; + if (*jump_target) + return NULL_TREE; location_t loc = EXPR_LOCATION (t); if (BITS_PER_UNIT != 8 || CHAR_BIT != 8) @@ -5267,8 +6212,9 @@ cxx_eval_bit_cast (const constexpr_ctx *ctx, tree t, bool *non_constant_p, if (CHECKING_P) { tree e = cxx_eval_bare_aggregate (ctx, r, vc_prvalue, - non_constant_p, overflow_p); - gcc_checking_assert (e == r); + non_constant_p, overflow_p, + jump_target); + gcc_checking_assert (e == r && !*jump_target); r = e; } } @@ -5309,19 +6255,24 @@ cxx_eval_bit_cast (const constexpr_ctx *ctx, tree t, bool *non_constant_p, static tree cxx_eval_logical_expression (const constexpr_ctx *ctx, tree t, tree bailout_value, tree continue_value, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { tree r; tree lhs = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_prvalue, non_constant_p, - overflow_p); + overflow_p, jump_target); + if (*jump_target) + return NULL_TREE; VERIFY_CONSTANT (lhs); if (tree_int_cst_equal (lhs, bailout_value)) return lhs; gcc_assert (tree_int_cst_equal (lhs, continue_value)); r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_prvalue, non_constant_p, - overflow_p); + overflow_p, jump_target); + if (*jump_target) + return NULL_TREE; VERIFY_CONSTANT (r); return r; } @@ -5478,7 +6429,8 @@ verify_ctor_sanity (const constexpr_ctx *ctx, tree type) static tree cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t); bool changed = false; @@ -5531,7 +6483,10 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t, get_or_insert_ctor_field (ctx->ctor, index); tree elt = cxx_eval_constant_expression (&new_ctx, value, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; /* Don't VERIFY_CONSTANT here. */ if (ctx->quiet && *non_constant_p) break; @@ -5621,7 +6576,8 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t, static tree cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, bool value_init, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { tree elttype = TREE_TYPE (atype); verify_ctor_sanity (ctx, atype); @@ -5632,7 +6588,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, if (init && TREE_CODE (init) == CONSTRUCTOR) return cxx_eval_bare_aggregate (ctx, init, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, jump_target); /* For the default constructor, build up a call to the default constructor of the element type. We only need to handle class types @@ -5669,7 +6625,9 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, } tree nelts = get_array_or_vector_nelts (ctx, atype, non_constant_p, - overflow_p); + overflow_p, jump_target); + if (*jump_target) + return NULL_TREE; unsigned HOST_WIDE_INT max = tree_to_uhwi (nelts); for (i = 0; i < max; ++i) { @@ -5695,9 +6653,9 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, } else eltinit = cp_build_array_ref (input_location, init, idx, complain); - eltinit = cxx_eval_vec_init_1 (&new_ctx, elttype, eltinit, value_init, - lval, - non_constant_p, overflow_p); + eltinit = cxx_eval_vec_init_1 (&new_ctx, elttype, eltinit, + value_init, lval, non_constant_p, + overflow_p, jump_target); } else if (pre_init) { @@ -5711,7 +6669,8 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, /* Clarify what object is being initialized (118285). */ eltinit = build2 (INIT_EXPR, elttype, new_ctx.object, eltinit); eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); reuse = i == 0; } else @@ -5727,8 +6686,11 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, /* Clarify what object is being initialized (118285). */ eltinit = build2 (INIT_EXPR, elttype, new_ctx.object, eltinit); eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); } + if (*jump_target) + return NULL_TREE; if (*non_constant_p) break; if (no_slot) @@ -5778,7 +6740,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, static tree cxx_eval_vec_init (const constexpr_ctx *ctx, tree t, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, tree *jump_target) { tree atype = TREE_TYPE (t); tree init = VEC_INIT_EXPR_INIT (t); @@ -5810,10 +6772,10 @@ cxx_eval_vec_init (const constexpr_ctx *ctx, tree t, } init = expand_vec_init_expr (ctx->object, t, complain); return cxx_eval_constant_expression (ctx, init, lval, non_constant_p, - overflow_p); + overflow_p, jump_target); } tree r = cxx_eval_vec_init_1 (ctx, atype, init, value_init, - lval, non_constant_p, overflow_p); + lval, non_constant_p, overflow_p, jump_target); if (*non_constant_p) return t; else @@ -5842,14 +6804,16 @@ same_type_ignoring_tlq_and_bounds_p (tree type1, tree type2) otherwise return NULL_TREE. */ static tree -cxx_union_active_member (const constexpr_ctx *ctx, tree t) +cxx_union_active_member (const constexpr_ctx *ctx, tree t, tree *jump_target) { constexpr_ctx new_ctx = *ctx; new_ctx.quiet = true; bool non_constant_p = false, overflow_p = false; tree ctor = cxx_eval_constant_expression (&new_ctx, t, vc_prvalue, &non_constant_p, - &overflow_p); + &overflow_p, jump_target); + if (*jump_target) + return NULL_TREE; if (TREE_CODE (ctor) == CONSTRUCTOR && CONSTRUCTOR_NELTS (ctor) == 1 && CONSTRUCTOR_ELT (ctor, 0)->index @@ -5862,12 +6826,28 @@ cxx_union_active_member (const constexpr_ctx *ctx, tree t) static tree cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type, - tree op, unsigned HOST_WIDE_INT off, bool *empty_base) + tree op, unsigned HOST_WIDE_INT off, bool *empty_base, + tree *jump_target) { tree optype = TREE_TYPE (op); unsigned HOST_WIDE_INT const_nunits; if (off == 0 && similar_type_p (optype, type)) return op; + else if (cxx_dialect >= cxx26 + && VAR_P (op) + && DECL_VTABLE_OR_VTT_P (op) + && same_type_ignoring_top_level_qualifiers_p (type, + ptrdiff_type_node) + && POINTER_TYPE_P (strip_array_types (optype))) + { + /* We often read some virtual table elements using ptrdiff_t rather + than pointer type. */ + if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, + strip_array_types (optype), + op, off, empty_base, + jump_target)) + return fold_convert (type, ret); + } else if (TREE_CODE (optype) == COMPLEX_TYPE && similar_type_p (type, TREE_TYPE (optype))) { @@ -5911,7 +6891,7 @@ cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type, op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index, NULL_TREE, NULL_TREE); return cxx_fold_indirect_ref_1 (ctx, loc, type, op, rem, - empty_base); + empty_base, jump_target); } } /* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */ @@ -5920,7 +6900,7 @@ cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type, { if (TREE_CODE (optype) == UNION_TYPE) /* For unions prefer the currently active member. */ - if (tree field = cxx_union_active_member (ctx, op)) + if (tree field = cxx_union_active_member (ctx, op, jump_target)) { unsigned HOST_WIDE_INT el_sz = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field))); @@ -5929,7 +6909,8 @@ cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type, tree cop = build3 (COMPONENT_REF, TREE_TYPE (field), op, field, NULL_TREE); if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, type, cop, - off, empty_base)) + off, empty_base, + jump_target)) return ret; } } @@ -5961,15 +6942,21 @@ cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type, if (!tree_fits_uhwi_p (pos)) continue; unsigned HOST_WIDE_INT upos = tree_to_uhwi (pos); - unsigned HOST_WIDE_INT el_sz - = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field))); + unsigned HOST_WIDE_INT el_sz; + if (DECL_FIELD_IS_BASE (field) + && CLASS_TYPE_P (optype) + && CLASSTYPE_VBASECLASSES (optype)) + el_sz = tree_to_uhwi (DECL_SIZE_UNIT (field)); + else + el_sz = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field))); if (upos <= off && off < upos + el_sz) { tree cop = build3 (COMPONENT_REF, TREE_TYPE (field), op, field, NULL_TREE); if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, type, cop, off - upos, - empty_base)) + empty_base, + jump_target)) return ret; } } @@ -5989,7 +6976,7 @@ cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type, static tree cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type, - tree op0, bool *empty_base /* = NULL*/) + tree op0, bool *empty_base, tree *jump_target) { tree sub = op0; tree subtype; @@ -6013,6 +7000,25 @@ cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type, offset positive, so that cxx_fold_indirect_ref_1 can identify more folding opportunities. */ auto canonicalize_obj_off = [] (tree& obj, tree& off) { + if (cxx_dialect >= cxx26) + { + /* For C++26, we need to fold *(B *)(&x.D.1234 + 32) used + to access virtual base members. */ + tree nobj = obj; + while (TREE_CODE (nobj) == COMPONENT_REF + && DECL_FIELD_IS_BASE (TREE_OPERAND (nobj, 1))) + nobj = TREE_OPERAND (nobj, 0); + if (nobj != obj + && CLASS_TYPE_P (TREE_TYPE (nobj)) + && CLASSTYPE_VBASECLASSES (TREE_TYPE (nobj))) + while (obj != nobj) + { + tree field = TREE_OPERAND (obj, 1); + tree pos = byte_position (field); + off = int_const_binop (PLUS_EXPR, off, pos); + obj = TREE_OPERAND (obj, 0); + } + } while (TREE_CODE (obj) == COMPONENT_REF /* We need to preserve union member accesses so that we can later properly diagnose accessing the wrong member. */ @@ -6051,8 +7057,9 @@ cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type, { tree off = integer_zero_node; canonicalize_obj_off (op, off); - gcc_assert (integer_zerop (off)); - return cxx_fold_indirect_ref_1 (ctx, loc, type, op, 0, empty_base); + return cxx_fold_indirect_ref_1 (ctx, loc, type, op, + tree_to_uhwi (off), empty_base, + jump_target); } } else if (TREE_CODE (sub) == POINTER_PLUS_EXPR @@ -6067,7 +7074,8 @@ cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type, tree obj = TREE_OPERAND (op00, 0); canonicalize_obj_off (obj, off); return cxx_fold_indirect_ref_1 (ctx, loc, type, obj, - tree_to_uhwi (off), empty_base); + tree_to_uhwi (off), empty_base, + jump_target); } } /* *(foo *)fooarrptr => (*fooarrptr)[0] */ @@ -6077,7 +7085,10 @@ cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type, tree type_domain; tree min_val = size_zero_node; tree newsub - = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (subtype), sub, NULL); + = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (subtype), sub, NULL, + jump_target); + if (*jump_target) + return NULL_TREE; if (newsub) sub = newsub; else @@ -6095,7 +7106,8 @@ cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type, static tree cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { tree orig_op0 = TREE_OPERAND (t, 0); bool empty_base = false; @@ -6113,13 +7125,17 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t, /* First try to simplify it directly. */ tree r = cxx_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t), - orig_op0, &empty_base); + orig_op0, &empty_base, jump_target); + if (*jump_target) + return NULL_TREE; if (!r) { /* If that didn't work, evaluate the operand first. */ tree op0 = cxx_eval_constant_expression (ctx, orig_op0, vc_prvalue, non_constant_p, - overflow_p); + overflow_p, jump_target); + if (*jump_target) + return NULL_TREE; /* Don't VERIFY_CONSTANT here. */ if (*non_constant_p) return t; @@ -6133,7 +7149,9 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t, } r = cxx_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t), op0, - &empty_base); + &empty_base, jump_target); + if (*jump_target) + return NULL_TREE; if (r == NULL_TREE) { /* We couldn't fold to a constant value. Make sure it's not @@ -6163,7 +7181,10 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t, } r = cxx_eval_constant_expression (ctx, r, - lval, non_constant_p, overflow_p); + lval, non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; if (*non_constant_p) return t; @@ -6273,7 +7294,8 @@ non_const_var_error (location_t loc, tree r, bool fundef_p) static tree cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { int i; tree args[3]; @@ -6283,7 +7305,10 @@ cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t, { args[i] = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, i), lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; VERIFY_CONSTANT (args[i]); } @@ -6405,7 +7430,8 @@ modifying_const_object_p (tree_code code, tree obj, bool mutable_p) static tree cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { constexpr_ctx new_ctx = *ctx; @@ -6431,7 +7457,10 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, if (!SCALAR_TYPE_P (type)) new_ctx.ctor = new_ctx.object = NULL_TREE; init = cxx_eval_constant_expression (&new_ctx, init, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; if (*non_constant_p) return t; } @@ -6443,8 +7472,11 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, as a whole; otherwise, only evaluate the innermost piece to avoid building up unnecessary *_REFs. */ target = cxx_eval_constant_expression (ctx, target, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); evaluated = true; + if (*jump_target) + return NULL_TREE; if (*non_constant_p) return t; } @@ -6470,7 +7502,10 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, if (TREE_CODE (probe) == ARRAY_REF) { elt = eval_and_check_array_index (ctx, probe, false, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; if (*non_constant_p) return t; } @@ -6527,8 +7562,11 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, break; } probe = cxx_eval_constant_expression (ctx, probe, vc_glvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); evaluated = true; + if (*jump_target) + return NULL_TREE; if (*non_constant_p) return t; } @@ -6872,7 +7910,10 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, if (tree tinit = TARGET_EXPR_INITIAL (init)) init = tinit; init = cxx_eval_constant_expression (&new_ctx, init, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; /* The hash table might have moved since the get earlier, and the initializer might have mutated the underlying CONSTRUCTORs, so we must recompute VALP. */ @@ -6998,7 +8039,8 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, static tree cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t, value_cat lval, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { enum tree_code code = TREE_CODE (t); tree type = TREE_TYPE (t); @@ -7012,12 +8054,18 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t, /* The operand as an lvalue. */ op = cxx_eval_constant_expression (ctx, op, vc_glvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; /* The operand as an rvalue. */ tree val = cxx_eval_constant_expression (ctx, op, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to a local array in a constexpr function. */ bool ptr = INDIRECT_TYPE_P (TREE_TYPE (val)); @@ -7056,8 +8104,11 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t, tree store = build2_loc (cp_expr_loc_or_loc (t, input_location), MODIFY_EXPR, type, op, mod); mod = cxx_eval_constant_expression (ctx, store, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); ggc_free (store); + if (*jump_target) + return NULL_TREE; if (*non_constant_p) return t; @@ -7071,42 +8122,6 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t, return val; } -/* Predicates for the meaning of *jump_target. */ - -static bool -returns (tree *jump_target) -{ - return *jump_target - && TREE_CODE (*jump_target) == RETURN_EXPR; -} - -static bool -breaks (tree *jump_target) -{ - return *jump_target - && ((TREE_CODE (*jump_target) == LABEL_DECL - && LABEL_DECL_BREAK (*jump_target)) - || TREE_CODE (*jump_target) == BREAK_STMT - || TREE_CODE (*jump_target) == EXIT_EXPR); -} - -static bool -continues (tree *jump_target) -{ - return *jump_target - && ((TREE_CODE (*jump_target) == LABEL_DECL - && LABEL_DECL_CONTINUE (*jump_target)) - || TREE_CODE (*jump_target) == CONTINUE_STMT); - -} - -static bool -switches (tree *jump_target) -{ - return *jump_target - && TREE_CODE (*jump_target) == INTEGER_CST; -} - /* Subroutine of cxx_eval_statement_list. Determine whether the statement STMT matches *jump_target. If we're looking for a case label and we see the default label, note it in ctx->css_state. */ @@ -7154,6 +8169,11 @@ label_matches (const constexpr_ctx *ctx, tree *jump_target, tree stmt) breaks (jump_target) or continues (jump_target). */ break; + case VAR_DECL: + /* Uncaught exception. This is handled by TRY_BLOCK evaluation + and other places by testing throws (jump_target). */ + break; + default: gcc_unreachable (); } @@ -7168,15 +8188,9 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t, bool *non_constant_p, bool *overflow_p, tree *jump_target) { - tree local_target; /* In a statement-expression we want to return the last value. For empty statement expression return void_node. */ tree r = void_node; - if (!jump_target) - { - local_target = NULL_TREE; - jump_target = &local_target; - } for (tree_stmt_iterator i = tsi_start (t); !tsi_end_p (i); ++i) { tree stmt = *i; @@ -7204,18 +8218,11 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t, jump_target); if (*non_constant_p) break; - if (returns (jump_target) || breaks (jump_target)) + if (returns (jump_target) + || breaks (jump_target) + || throws (jump_target)) break; } - if (*jump_target && jump_target == &local_target) - { - /* We aren't communicating the jump to our caller, so give up. We don't - need to support evaluation of jumps out of statement-exprs. */ - if (!ctx->quiet) - error_at (cp_expr_loc_or_input_loc (r), - "statement is not a constant expression"); - *non_constant_p = true; - } return r; } @@ -7227,13 +8234,6 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t, bool *non_constant_p, bool *overflow_p, tree *jump_target) { - tree local_target; - if (!jump_target) - { - local_target = NULL_TREE; - jump_target = &local_target; - } - tree body, cond = NULL_TREE, expr = NULL_TREE; tree cond_prep = NULL_TREE, cond_cleanup = NULL_TREE; unsigned cond_cleanup_depth = 0; @@ -7289,7 +8289,7 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t, tree c; FOR_EACH_VEC_ELT_REVERSE (cleanups, i, c) cxx_eval_constant_expression (ctx, c, vc_discard, non_constant_p, - overflow_p); + overflow_p, jump_target); } if (cond_prep) for (tree decl = BIND_EXPR_VARS (cond_prep); @@ -7384,7 +8384,8 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t, if (*non_constant_p || returns (jump_target) || breaks (jump_target) - || continues (jump_target)) + || continues (jump_target) + || throws (jump_target)) { depth = 1; break; @@ -7431,6 +8432,7 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t, && !breaks (jump_target) && !continues (jump_target) && (!switches (jump_target) || count == 0) + && !throws (jump_target) && !*non_constant_p); cleanup_cond (); @@ -7449,7 +8451,10 @@ cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t, tree cond = TREE_CODE (t) == SWITCH_STMT ? SWITCH_STMT_COND (t) : SWITCH_COND (t); cond = cxx_eval_constant_expression (ctx, cond, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; VERIFY_CONSTANT (cond); if (TREE_CODE (cond) != INTEGER_CST) { @@ -7582,7 +8587,8 @@ maybe_warn_about_constant_value (location_t loc, tree decl) static tree build_new_constexpr_heap_type (const constexpr_ctx *ctx, tree elt_type, tree cookie_size, tree full_size, tree arg_size, - bool *non_constant_p, bool *overflow_p) + bool *non_constant_p, bool *overflow_p, + tree *jump_target) { gcc_assert (cookie_size == NULL_TREE || tree_fits_uhwi_p (cookie_size)); gcc_assert (tree_fits_uhwi_p (full_size)); @@ -7618,13 +8624,17 @@ build_new_constexpr_heap_type (const constexpr_ctx *ctx, tree elt_type, if (integer_zerop (op0)) arg_size = cxx_eval_constant_expression (ctx, op1, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); else if (integer_zerop (op1)) arg_size = cxx_eval_constant_expression (ctx, op0, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); else arg_size = NULL_TREE; + if (*jump_target) + return NULL_TREE; } else arg_size = NULL_TREE; @@ -7645,6 +8655,38 @@ build_new_constexpr_heap_type (const constexpr_ctx *ctx, tree elt_type, return build_new_constexpr_heap_type (elt_type, cookie_size, itype2); } +/* Handle the case when a cleanup of some expression throws. JMP_TARGET + indicates whether the cleanup threw or not, *JUMP_TARGET indicates whether + the expression which needed the cleanup threw. If both threw, diagnose + it and return NULL, otherwise return R. If only the cleanup threw, set + *JUMP_TARGET to the exception object from the cleanup. */ + +static tree +merge_jump_target (location_t loc, const constexpr_ctx *ctx, tree r, + bool *non_constant_p, tree *jump_target, tree jmp_target) +{ + if (!throws (&jmp_target)) + return r; + if (throws (jump_target)) + { + /* [except.throw]/9 - If the exception handling mechanism + handling an uncaught exception directly invokes a function + that exits via an exception, the function std::terminate is + invoked. */ + if (!ctx->quiet) + { + auto_diagnostic_group d; + diagnose_std_terminate (loc, ctx, *jump_target); + inform (loc, "destructor exited with an exception"); + } + *non_constant_p = true; + *jump_target = NULL_TREE; + return NULL_TREE; + } + *jump_target = jmp_target; + return r; +} + /* Attempt to reduce the expression T to a constant value. On failure, issue diagnostic and return error_mark_node. */ /* FIXME unify with c_fully_fold */ @@ -7654,9 +8696,9 @@ static tree cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, value_cat lval, bool *non_constant_p, bool *overflow_p, - tree *jump_target /* = NULL */) + tree *jump_target) { - if (jump_target && *jump_target) + if (*jump_target) { /* If we are jumping, ignore all statements/expressions except those that could have LABEL_EXPR or CASE_LABEL_EXPR in their bodies. */ @@ -7780,7 +8822,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, r = convert_from_reference (r); } return cxx_eval_constant_expression (ctx, r, lval, non_constant_p, - overflow_p); + overflow_p, jump_target); } /* fall through */ case CONST_DECL: @@ -7858,7 +8900,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, r = v; if (TREE_ADDRESSABLE (TREE_TYPE (t))) r = cxx_eval_constant_expression (ctx, r, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; } else if (lval) /* Defer in case this is only used for its type. */; @@ -7891,7 +8936,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, case CALL_EXPR: case AGGR_INIT_EXPR: r = cxx_eval_call_expression (ctx, t, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, jump_target); break; case DECL_EXPR: @@ -7955,7 +9000,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, if (tree init = DECL_INITIAL (r)) { init = cxx_eval_constant_expression (ctx, init, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; /* Don't share a CONSTRUCTOR that might be changed. */ init = unshare_constructor (init); /* Remember that a constant object's constructor has already @@ -8014,14 +9062,23 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, ctx->global->put_value (new_ctx.object, new_ctx.ctor); ctx = &new_ctx; } + + /* If the initializer is complex, evaluate it to initialize slot. */ + bool is_complex = target_expr_needs_replace (t); + if (is_complex) + /* In case no initialization actually happens, clear out any + void_node from a previous evaluation. */ + ctx->global->put_value (slot, NULL_TREE); + /* Pass vc_prvalue because this indicates initialization of a temporary. */ r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); if (*non_constant_p) break; - /* If the initializer is complex, evaluate it to initialize slot. */ - bool is_complex = target_expr_needs_replace (t); + if (*jump_target) + return NULL_TREE; if (!is_complex) { r = unshare_constructor (r); @@ -8029,8 +9086,15 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, r = adjust_temp_type (type, r); ctx->global->put_value (slot, r); } - if (TARGET_EXPR_CLEANUP (t) && !CLEANUP_EH_ONLY (t)) - ctx->global->cleanups->safe_push (TARGET_EXPR_CLEANUP (t)); + if (TARGET_EXPR_CLEANUP (t) + && (!CLEANUP_EH_ONLY (t) || cxx_dialect >= cxx26)) + { + ctx->global->cleanups->safe_push (TARGET_EXPR_CLEANUP (t)); + /* Mark CLEANUP_EH_ONLY cleanups by pushing NULL_TREE after + them. */ + if (CLEANUP_EH_ONLY (t)) + ctx->global->cleanups->safe_push (NULL_TREE); + } if (ctx->save_exprs) ctx->save_exprs->safe_push (slot); if (lval) @@ -8044,33 +9108,28 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, case MODIFY_EXPR: gcc_assert (jump_target == NULL || *jump_target == NULL_TREE); r = cxx_eval_store_expression (ctx, t, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, jump_target); break; case SCOPE_REF: r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); break; case RETURN_EXPR: if (TREE_OPERAND (t, 0) != NULL_TREE) r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval, - non_constant_p, overflow_p); - /* FALLTHRU */ + non_constant_p, overflow_p, + jump_target); + if (!throws (jump_target)) + *jump_target = t; + break; case BREAK_STMT: case CONTINUE_STMT: - if (jump_target) - *jump_target = t; - else - { - /* Can happen with ({ return true; }) && false; passed to - maybe_constant_value. There is nothing to jump over in this - case, and the bug will be diagnosed later. */ - gcc_assert (ctx->quiet); - *non_constant_p = true; - } + *jump_target = t; break; case SAVE_EXPR: @@ -8079,9 +9138,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, r = v; else { - r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_prvalue, - non_constant_p, overflow_p); - if (*non_constant_p) + r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), + vc_prvalue, non_constant_p, + overflow_p, jump_target); + if (*non_constant_p || *jump_target) break; ctx->global->put_value (t, r); if (ctx->save_exprs) @@ -8089,16 +9149,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, } break; - case TRY_CATCH_EXPR: - if (TREE_OPERAND (t, 0) == NULL_TREE) - { - r = void_node; - break; - } - /* FALLTHRU */ case NON_LVALUE_EXPR: - case TRY_BLOCK: - case MUST_NOT_THROW_EXPR: case EXPR_STMT: case EH_SPEC_BLOCK: r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), @@ -8107,6 +9158,42 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, jump_target); break; + case TRY_BLOCK: + r = cxx_eval_constant_expression (ctx, TRY_STMTS (t), lval, + non_constant_p, overflow_p, + jump_target); + if (!*non_constant_p && throws (jump_target)) + if (tree h = TRY_HANDLERS (t)) + { + tree type = strip_array_types (TREE_TYPE (*jump_target)); + if (TREE_CODE (h) == STATEMENT_LIST) + { + for (tree stmt : tsi_range (h)) + if (TREE_CODE (stmt) == HANDLER + && handler_match_for_exception_type (stmt, type)) + { + h = stmt; + break; + } + if (TREE_CODE (h) == STATEMENT_LIST) + h = NULL_TREE; + } + else if (TREE_CODE (h) != HANDLER + || !handler_match_for_exception_type (h, type)) + h = NULL_TREE; + if (h) + { + gcc_assert (VAR_P (*jump_target)); + ctx->global->caught_exceptions.safe_push (*jump_target); + ctx->global->caught_exceptions.safe_push (HANDLER_TYPE (h)); + *jump_target = NULL_TREE; + r = cxx_eval_constant_expression (ctx, HANDLER_BODY (h), + vc_discard, non_constant_p, + overflow_p, jump_target); + } + } + break; + case CLEANUP_POINT_EXPR: { auto_vec<tree, 2> cleanups; @@ -8124,47 +9211,132 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, ctx->global->cleanups = prev_cleanups; unsigned int i; - tree cleanup; + tree cleanup, jmp_target = NULL_TREE; + bool eh = throws (jump_target); /* Evaluate the cleanups. */ FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup) - cxx_eval_constant_expression (&new_ctx, cleanup, vc_discard, - non_constant_p, overflow_p); + if (cleanup == NULL_TREE) + { + /* NULL_TREE cleanup is a marker that before it is + CLEANUP_EH_ONLY cleanup. Skip the cleanup before it + if the body didn't throw. */ + if (!eh) + --i; + } + else + cxx_eval_constant_expression (&new_ctx, cleanup, vc_discard, + non_constant_p, overflow_p, + &jmp_target); /* Forget SAVE_EXPRs and TARGET_EXPRs created by this full-expression. */ for (tree save_expr : save_exprs) destroy_value_checked (ctx, save_expr, non_constant_p); + if (throws (&jmp_target)) + *jump_target = jmp_target; } break; + case MUST_NOT_THROW_EXPR: + r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), + lval, + non_constant_p, overflow_p, + jump_target); + if (throws (jump_target)) + { + /* [except.handle]/7 - If the search for a handler exits the + function body of a function with a non-throwing exception + specification, the function std::terminate is invoked. */ + if (!ctx->quiet) + { + auto_diagnostic_group d; + diagnose_std_terminate (loc, ctx, *jump_target); + if (MUST_NOT_THROW_NOEXCEPT_P (t) + && ctx->call + && ctx->call->fundef) + inform (loc, "uncaught exception exited from %<noexcept%> " + "function %qD", + ctx->call->fundef->decl); + else if (MUST_NOT_THROW_THROW_P (t)) + inform (loc, "destructor exited with an exception after " + "initializing the exception object"); + else if (MUST_NOT_THROW_CATCH_P (t)) + inform (loc, "constructor exited with another exception while " + "entering handler"); + } + *non_constant_p = true; + *jump_target = NULL_TREE; + r = NULL_TREE; + } + break; + + case TRY_CATCH_EXPR: + if (TREE_OPERAND (t, 0) == NULL_TREE) + { + r = void_node; + break; + } + r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval, + non_constant_p, overflow_p, + jump_target); + if (!*non_constant_p && throws (jump_target)) + { + tree jmp_target = NULL_TREE; + cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_discard, + non_constant_p, overflow_p, + &jmp_target); + r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target, + jmp_target); + } + break; + case TRY_FINALLY_EXPR: r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval, non_constant_p, overflow_p, jump_target); if (!*non_constant_p) - /* Also evaluate the cleanup. */ - cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_discard, - non_constant_p, overflow_p); + { + tree jmp_target = NULL_TREE; + /* Also evaluate the cleanup. */ + if (TREE_CODE (TREE_OPERAND (t, 1)) == EH_ELSE_EXPR + && throws (jump_target)) + cxx_eval_constant_expression (ctx, + TREE_OPERAND (TREE_OPERAND (t, 1), + 1), vc_discard, + non_constant_p, overflow_p, + &jmp_target); + else + cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_discard, + non_constant_p, overflow_p, + &jmp_target); + r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target, + jmp_target); + } break; case EH_ELSE_EXPR: /* Evaluate any cleanup that applies to non-EH exits. */ cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_discard, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); - /* We do not have constexpr exceptions yet, so skip the EH path. */ + /* The EH path is handled in TRY_FINALLY_EXPR handling above. */ break; case CLEANUP_STMT: r = cxx_eval_constant_expression (ctx, CLEANUP_BODY (t), lval, non_constant_p, overflow_p, jump_target); - if (!CLEANUP_EH_ONLY (t) && !*non_constant_p) + if ((!CLEANUP_EH_ONLY (t) || throws (jump_target)) && !*non_constant_p) { iloc_sentinel ils (loc); + tree jmp_target = NULL_TREE; /* Also evaluate the cleanup. */ cxx_eval_constant_expression (ctx, CLEANUP_EXPR (t), vc_discard, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + &jmp_target); + r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target, + jmp_target); } break; @@ -8174,14 +9346,18 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, case MEM_REF: case INDIRECT_REF: r = cxx_eval_indirect_ref (ctx, t, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); break; case ADDR_EXPR: { tree oldop = TREE_OPERAND (t, 0); tree op = cxx_eval_constant_expression (ctx, oldop, vc_glvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; /* Don't VERIFY_CONSTANT here. */ if (*non_constant_p) return t; @@ -8201,7 +9377,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, if (lval) { r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; if (r == error_mark_node) ; else if (r == TREE_OPERAND (t, 0) || lval == vc_discard) @@ -8222,7 +9401,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, case FIXED_CONVERT_EXPR: case VEC_DUPLICATE_EXPR: r = cxx_eval_unary_expression (ctx, t, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); break; case SIZEOF_EXPR: @@ -8260,6 +9440,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, cxx_eval_constant_expression (ctx, op0, vc_discard, non_constant_p, overflow_p, jump_target); + if (*jump_target) + return NULL_TREE; if (*non_constant_p) return t; op1 = TREE_OPERAND (t, 1); @@ -8312,7 +9494,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, case RANGE_EXPR: case COMPLEX_EXPR: r = cxx_eval_binary_expression (ctx, t, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); break; /* fold can introduce non-IF versions of these; still treat them as @@ -8321,19 +9504,22 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, case TRUTH_ANDIF_EXPR: r = cxx_eval_logical_expression (ctx, t, boolean_false_node, boolean_true_node, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); break; case TRUTH_OR_EXPR: case TRUTH_ORIF_EXPR: r = cxx_eval_logical_expression (ctx, t, boolean_true_node, boolean_false_node, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); break; case ARRAY_REF: r = cxx_eval_array_reference (ctx, t, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); break; case COMPONENT_REF: @@ -8348,17 +9534,19 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, return t; } r = cxx_eval_component_reference (ctx, t, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); break; case BIT_FIELD_REF: r = cxx_eval_bit_field_ref (ctx, t, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); break; case COND_EXPR: case IF_STMT: - if (jump_target && *jump_target) + if (*jump_target) { tree orig_jump = *jump_target; tree arg = ((TREE_CODE (t) != IF_STMT || TREE_OPERAND (t, 1)) @@ -8396,7 +9584,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, break; case VEC_COND_EXPR: r = cxx_eval_vector_conditional_expression (ctx, t, non_constant_p, - overflow_p); + overflow_p, jump_target); break; case CONSTRUCTOR: @@ -8408,7 +9596,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, return t; } r = cxx_eval_bare_aggregate (ctx, t, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, jump_target); break; case VEC_INIT_EXPR: @@ -8418,12 +9606,13 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, or xvalue of the same type, meaning direct-initialization from the corresponding member. */ r = cxx_eval_vec_init (ctx, t, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, jump_target); break; case VEC_PERM_EXPR: r = cxx_eval_trinary_expression (ctx, t, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); break; case PAREN_EXPR: @@ -8431,7 +9620,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, /* A PAREN_EXPR resulting from __builtin_assoc_barrier has no effect in constant expressions since it's unaffected by -fassociative-math. */ r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); break; case NOP_EXPR: @@ -8455,7 +9645,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, ? vc_discard : tcode == VIEW_CONVERT_EXPR ? lval : vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; if (*non_constant_p) return t; tree type = TREE_TYPE (t); @@ -8512,7 +9705,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, { if (integer_zerop (sop)) return build_int_cst (type, 0); - r = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), sop); + r = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), sop, + NULL, jump_target); + if (*jump_target) + return NULL_TREE; if (r) { r = build1 (ADDR_EXPR, type, r); @@ -8618,7 +9814,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, tree cookie_size = NULL_TREE; tree arg_size = NULL_TREE; if (TREE_CODE (elt_type) == RECORD_TYPE - && TYPE_NAME (elt_type) == heap_identifier) + && TYPE_IDENTIFIER (elt_type) == heap_identifier) { tree fld1 = TYPE_FIELDS (elt_type); tree fld2 = DECL_CHAIN (fld1); @@ -8639,10 +9835,14 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, if (cxx_replaceable_global_alloc_fn (fun) && IDENTIFIER_NEW_OP_P (DECL_NAME (fun))) arg_size = CALL_EXPR_ARG (oldop, 0); - TREE_TYPE (var) + tree new_type = build_new_constexpr_heap_type (ctx, elt_type, cookie_size, var_size, arg_size, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; + TREE_TYPE (var) = new_type; TREE_TYPE (TREE_OPERAND (op, 0)) = build_pointer_type (TREE_TYPE (var)); } @@ -8681,7 +9881,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, tree op = cxx_eval_constant_expression (ctx, oldop, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; if (*non_constant_p) return t; r = fold_convert (TREE_TYPE (t), op); @@ -8718,14 +9921,20 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, case PREDECREMENT_EXPR: case POSTDECREMENT_EXPR: return cxx_eval_increment_expression (ctx, t, - lval, non_constant_p, overflow_p); + lval, non_constant_p, overflow_p, + jump_target); + case THROW_EXPR: + if (cxx_dialect >= cxx26) + return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval, + non_constant_p, overflow_p, + jump_target); + /* FALLTHROUGH */ case LAMBDA_EXPR: case NEW_EXPR: case VEC_NEW_EXPR: case DELETE_EXPR: case VEC_DELETE_EXPR: - case THROW_EXPR: case MODOP_EXPR: /* GCC internal stuff. */ case VA_ARG_EXPR: @@ -8739,7 +9948,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, case OBJ_TYPE_REF: /* Virtual function lookup. We don't need to do anything fancy. */ return cxx_eval_constant_expression (ctx, OBJ_TYPE_REF_EXPR (t), - lval, non_constant_p, overflow_p); + lval, non_constant_p, overflow_p, + jump_target); case PLACEHOLDER_EXPR: /* Use of the value or address of the current object. */ @@ -8749,7 +9959,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, return ctor; else return cxx_eval_constant_expression (ctx, ctor, lval, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); } /* A placeholder without a referent. We can get here when checking whether NSDMIs are noexcept, or in massage_init_elt; @@ -8762,7 +9973,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, { tree cond = TREE_OPERAND (t, 0); cond = cxx_eval_constant_expression (ctx, cond, vc_prvalue, - non_constant_p, overflow_p); + non_constant_p, overflow_p, + jump_target); + if (*jump_target) + return NULL_TREE; VERIFY_CONSTANT (cond); if (integer_nonzerop (cond)) *jump_target = t; @@ -8874,7 +10088,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, *non_constant_p = true; return t; } - r = cxx_eval_bit_cast (ctx, t, non_constant_p, overflow_p); + r = cxx_eval_bit_cast (ctx, t, non_constant_p, overflow_p, jump_target); break; case OMP_PARALLEL: @@ -9193,8 +10407,34 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, if (manifestly_const_eval == mce_true) instantiate_constexpr_fns (r); + tree jmp_target = NULL_TREE; r = cxx_eval_constant_expression (&ctx, r, vc_prvalue, - &non_constant_p, &overflow_p); + &non_constant_p, &overflow_p, + &jmp_target); + if (throws (&jmp_target) && !non_constant_p) + { + if (!ctx.quiet) + diagnose_uncaught_exception (input_location, &ctx, jmp_target); + non_constant_p = true; + jmp_target = NULL_TREE; + r = t; + } + else if (!non_constant_p && jmp_target) + { + non_constant_p = true; + if (!ctx.quiet) + { + if (breaks (&jmp_target)) + error ("%<break%> outside of a loop or %<switch%>"); + else if (continues (&jmp_target)) + error ("%<continue%> outside of a loop"); + else if (returns (&jmp_target)) + error ("%<return%> in a statement expression"); + else + gcc_unreachable (); + } + r = t; + } /* If we got a non-simple TARGET_EXPR, the initializer was a sequence of statements, and the result ought to be stored in ctx.ctor. */ @@ -9203,15 +10443,31 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, unsigned int i; tree cleanup; + jmp_target = NULL_TREE; /* Evaluate the cleanups. */ FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup) - cxx_eval_constant_expression (&ctx, cleanup, vc_discard, - &non_constant_p, &overflow_p); + if (cleanup == NULL_TREE) + /* NULL_TREE cleanup is a marker that before it is + CLEANUP_EH_ONLY cleanup. Skip the cleanup before it. */ + --i; + else + cxx_eval_constant_expression (&ctx, cleanup, vc_discard, + &non_constant_p, &overflow_p, + &jmp_target); + if (throws (&jmp_target) && !non_constant_p) + { + if (!ctx.quiet) + diagnose_uncaught_exception (input_location, &ctx, jmp_target); + non_constant_p = true; + r = t; + } /* Mutable logic is a bit tricky: we want to allow initialization of constexpr variables with mutable members, but we can't copy those members to another constexpr variable. */ - if (TREE_CODE (r) == CONSTRUCTOR && CONSTRUCTOR_MUTABLE_POISON (r)) + if (!non_constant_p + && TREE_CODE (r) == CONSTRUCTOR + && CONSTRUCTOR_MUTABLE_POISON (r)) { if (!allow_non_constant) error ("%qE is not a constant expression because it refers to " @@ -9229,8 +10485,13 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, { if (!allow_non_constant && !non_constant_p) { - error ("%qE is not a constant expression because it refers to " - "a result of %<operator new%>", t); + if (DECL_LANG_SPECIFIC (heap_var)) + error ("%qE is not a constant expression because it refers to " + "exception object allocated with " + "%<__cxa_allocate_exception%>", t); + else + error ("%qE is not a constant expression because it refers to " + "a result of %<operator new%>", t); inform (DECL_SOURCE_LOCATION (heap_var), "allocated here"); } r = t; @@ -9488,8 +10749,35 @@ tree maybe_constant_value (tree t, tree decl /* = NULL_TREE */, mce_value manifestly_const_eval /* = mce_unknown */) { + tree orig_t = t; tree r; + if (EXPR_P (t) && manifestly_const_eval == mce_unknown) + { + /* Look up each operand in the cv_cache first to see if we've already + reduced it, and reuse that result to avoid quadratic behavior if + we're called when building up a large expression. */ + int n = cp_tree_operand_length (t); + tree *ops = XALLOCAVEC (tree, n); + bool rebuild = false; + for (int i = 0; i < n; ++i) + { + ops[i] = TREE_OPERAND (t, i); + if (tree *cached = hash_map_safe_get (cv_cache, ops[i])) + if (*cached != ops[i]) + { + ops[i] = *cached; + rebuild = true; + } + } + if (rebuild) + { + t = copy_node (t); + for (int i = 0; i < n; ++i) + TREE_OPERAND (t, i) = ops[i]; + } + } + if (!is_nondependent_constant_expression (t)) { if (TREE_OVERFLOW_P (t) @@ -9507,6 +10795,10 @@ maybe_constant_value (tree t, tree decl /* = NULL_TREE */, return fold_to_constant (t); if (manifestly_const_eval != mce_unknown) + /* TODO: Extend the cache to be mce_value aware. And if we have a + previously cached mce_unknown result that's TREE_CONSTANT, it means + the reduced value is independent of mce_value and so we should + be able to reuse it in the mce_true/false case. */ return cxx_eval_outermost_constant_expr (t, true, true, manifestly_const_eval, false, decl); @@ -9536,7 +10828,7 @@ maybe_constant_value (tree t, tree decl /* = NULL_TREE */, || (TREE_CONSTANT (t) && !TREE_CONSTANT (r)) || !cp_tree_equal (r, t)); if (!c.evaluation_restricted_p ()) - cv_cache->put (t, r); + cv_cache->put (orig_t, r); return r; } @@ -9780,6 +11072,24 @@ cxx_constant_init (tree t, tree decl) return maybe_constant_init_1 (t, decl, false, mce_true); } +/* Return true if CALL_EXPR T might throw during constant evaluation. */ + +static bool +callee_might_throw (tree t) +{ + if (cxx_dialect < cxx26 || !flag_exceptions) + return false; + tree callee = cp_get_callee (t); + if (callee == NULL_TREE) + return false; + tree callee_fn = cp_get_fndecl_from_callee (callee, false); + return (!flag_enforce_eh_specs + || type_dependent_expression_p (callee) + || !POINTER_TYPE_P (TREE_TYPE (callee)) + || (!type_noexcept_p (TREE_TYPE (TREE_TYPE (callee))) + && (callee_fn == NULL_TREE || !TREE_NOTHROW (callee_fn)))); +} + #if 0 /* FIXME see ADDR_EXPR section in potential_constant_expression_1. */ /* Return true if the object referred to by REF has automatic or thread @@ -9812,11 +11122,13 @@ struct check_for_return_continue_data { hash_set<tree> *pset; tree continue_stmt; tree break_stmt; + bool could_throw; }; /* Helper function for potential_constant_expression_1 SWITCH_STMT handling, called through cp_walk_tree. Return the first RETURN_EXPR found, or note - the first CONTINUE_STMT and/or BREAK_STMT if RETURN_EXPR is not found. */ + the first CONTINUE_STMT and/or BREAK_STMT if RETURN_EXPR is not found. + For C++26 also note presence of possibly throwing calls. */ static tree check_for_return_continue (tree *tp, int *walk_subtrees, void *data) { @@ -9901,6 +11213,13 @@ check_for_return_continue (tree *tp, int *walk_subtrees, void *data) case CONSTRUCTOR: break; + case AGGR_INIT_EXPR: + case CALL_EXPR: + /* In C++26 a function could throw. */ + if (callee_might_throw (t)) + d->could_throw = true; + break; + default: if (!EXPR_P (t)) *walk_subtrees = 0; @@ -10106,8 +11425,27 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, || TREE_CODE (t) != CALL_EXPR || current_function_decl == NULL_TREE || !is_std_construct_at (current_function_decl)) - && !cxx_dynamic_cast_fn_p (fun)) + && !cxx_dynamic_cast_fn_p (fun) + && !cxx_cxa_builtin_fn_p (fun)) { + /* In C++26 evaluation of the function arguments might + throw and in that case it is irrelevant whether + fun is constexpr or not. */ + if (cxx_dialect >= cxx26) + for (; i < nargs; ++i) + { + tree x = get_nth_callarg (t, i); + bool rv = processing_template_decl ? any : rval; + bool sub_now = false; + if (!potential_constant_expression_1 (x, rv, strict, + sub_now, + fundef_p, + flags, + jump_target)) + return false; + if (throws (jump_target)) + return true; + } if ((flags & tf_error) && constexpr_error (loc, fundef_p, "call to non-%<constexpr%> " @@ -10152,7 +11490,12 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, sub_now, fundef_p, flags, jump_target)) return false; + if (throws (jump_target)) + return true; } + /* In C++26 a function could throw. */ + if (*jump_target == NULL_TREE && callee_might_throw (t)) + *jump_target = void_node; return true; } @@ -10375,11 +11718,13 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, a return. */ hash_set<tree> pset; check_for_return_continue_data data = { &pset, NULL_TREE, - NULL_TREE }; + NULL_TREE, false }; if (tree ret_expr = cp_walk_tree (&FOR_BODY (t), check_for_return_continue, &data, &pset)) *jump_target = ret_expr; + if (data.could_throw) + *jump_target = void_node; return true; } } @@ -10419,11 +11764,13 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, a return. */ hash_set<tree> pset; check_for_return_continue_data data = { &pset, NULL_TREE, - NULL_TREE }; + NULL_TREE, false }; if (tree ret_expr = cp_walk_tree (&WHILE_BODY (t), check_for_return_continue, &data, &pset)) *jump_target = ret_expr; + if (data.could_throw) + *jump_target = void_node; return true; } if (!RECUR (WHILE_BODY (t), any)) @@ -10447,7 +11794,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, { hash_set<tree> pset; check_for_return_continue_data data = { &pset, NULL_TREE, - NULL_TREE }; + NULL_TREE, false }; if (tree ret_expr = cp_walk_tree (&SWITCH_STMT_BODY (t), check_for_return_continue, &data, &pset)) @@ -10456,6 +11803,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, else if (data.continue_stmt) /* The switch can't return, but might continue. */ *jump_target = data.continue_stmt; + if (data.could_throw) + *jump_target = void_node; } return true; @@ -10485,7 +11834,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, case DYNAMIC_CAST_EXPR: case PSEUDO_DTOR_EXPR: - case THROW_EXPR: case OMP_PARALLEL: case OMP_TASK: case OMP_FOR: @@ -10541,6 +11889,11 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, constant. */ return true; + case THROW_EXPR: + if (cxx_dialect < cxx26) + goto fail; + return RECUR (TREE_OPERAND (t, 0), rval); + case ASM_EXPR: if (flags & tf_error) inline_asm_in_constexpr_error (loc, fundef_p); @@ -10669,6 +12022,22 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, case CLEANUP_POINT_EXPR: case MUST_NOT_THROW_EXPR: case TRY_CATCH_EXPR: + /* Even for C++26 handle TRY_BLOCK conservatively, if we detect the + body could throw, even with catch (...) among handlers we'd need + to analyze them in detail if they couldn't rethrow it. More + importantly though, throws (jump_target) is just conservative, + and there could be e.g. + try + { + possibly_throwing_fn (args); + break; + } + catch (...) + { + } + or continue or return instead of break. So, clearing *jump_target + because we see catch (...) handler might mean we missed break + etc. */ case TRY_BLOCK: case EH_SPEC_BLOCK: case EXPR_STMT: @@ -10910,9 +12279,9 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, want_rval, strict, now, fundef_p, tf_none, &this_jump_target)) { - if (returns (&this_jump_target)) + if (returns (&this_jump_target) || throws (&this_jump_target)) *jump_target = this_jump_target; - else if (!returns (jump_target)) + else if (!returns (jump_target) && !throws (jump_target)) { if (breaks (&this_jump_target) || continues (&this_jump_target)) @@ -10924,7 +12293,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, couldn't return, break or continue. */ hash_set<tree> pset; check_for_return_continue_data data = { &pset, NULL_TREE, - NULL_TREE }; + NULL_TREE, + false }; if (tree ret_expr = cp_walk_tree (&TREE_OPERAND (t, 2), check_for_return_continue, &data, @@ -10937,6 +12307,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, else if (data.break_stmt) *jump_target = data.break_stmt; } + if (data.could_throw) + *jump_target = void_node; } } return true; diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 90625707043f..8d7aec337a81 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -1836,7 +1836,7 @@ tsubst_parameter_mapping (tree map, tree args, tsubst_flags_t complain, tree in_ static bool satisfying_constraint; /* A vector of incomplete types (and of declarations with undeduced return type), - appended to by note_failed_type_completion_for_satisfaction. The + appended to by note_failed_type_completion. The satisfaction caches use this in order to keep track of "potentially unstable" satisfaction results. @@ -1845,21 +1845,69 @@ static bool satisfying_constraint; static GTY((deletable)) vec<tree, va_gc> *failed_type_completions; +/* A map of where types were found to be incomplete in SFINAE context, for + warning if they are later completed. */ + +static GTY((cache)) hash_map<tree, location_t, decl_location_traits> *failed_completions_map; + /* Called whenever a type completion (or return type deduction) failure occurs that definitely affects the meaning of the program, by e.g. inducing substitution failure. */ void -note_failed_type_completion_for_satisfaction (tree t) +note_failed_type_completion (tree t, tsubst_flags_t complain) { + if (dependent_template_arg_p (t)) + return; + + gcc_checking_assert ((TYPE_P (t) && !COMPLETE_TYPE_P (t)) + || (DECL_P (t) && undeduced_auto_decl (t))); + if (satisfying_constraint) + vec_safe_push (failed_type_completions, t); + + if (TYPE_P (t)) { - gcc_checking_assert ((TYPE_P (t) && !COMPLETE_TYPE_P (t)) - || (DECL_P (t) && undeduced_auto_decl (t))); - vec_safe_push (failed_type_completions, t); + if (!CLASS_TYPE_P (t)) + return; + t = TYPE_MAIN_DECL (t); + } + if (!(complain & tf_error) + && warning_enabled_at (DECL_SOURCE_LOCATION (t), + OPT_Wsfinae_incomplete_)) + { + if (warn_sfinae_incomplete > 1) + { + if (TREE_CODE (t) == TYPE_DECL) + warning (OPT_Wsfinae_incomplete_, + "failed to complete %qT in SFINAE context", TREE_TYPE (t)); + else + warning (OPT_Wsfinae_incomplete_, + "failed to deduce %qD in SFINAE context", t); + } + if (!failed_completions_map) + failed_completions_map + = hash_map<tree, location_t, decl_location_traits>::create_ggc (); + failed_completions_map->put (t, input_location); } } +/* If T was previously found to be incomplete in SFINAE context, return the + location where that happened, otherwise UNKNOWN_LOCATION. */ + +location_t +failed_completion_location (tree t) +{ + if (failed_completions_map) + { + if (TYPE_P (t)) + t = TYPE_MAIN_DECL (t); + if (location_t *p = failed_completions_map->get (t)) + return *p; + } + return UNKNOWN_LOCATION; +} + /* Returns true if the range [BEGIN, END) of elements within the failed_type_completions vector contains a complete type (or a declaration with a non-placeholder return type). */ @@ -3157,6 +3205,9 @@ diagnose_trait_expr (tree expr, tree args) else inform (loc, " %qT is not nothrow invocable by %qE", t1, t2); break; + case CPTK_IS_NOTHROW_RELOCATABLE: + inform (loc, " %qT is not nothrow relocatable", t1); + break; case CPTK_IS_OBJECT: inform (loc, " %qT is not an object type", t1); break; @@ -3176,6 +3227,9 @@ diagnose_trait_expr (tree expr, tree args) case CPTK_IS_REFERENCE: inform (loc, " %qT is not a reference", t1); break; + case CPTK_IS_REPLACEABLE: + inform (loc, " %qT is not replaceable", t1); + break; case CPTK_IS_SAME: inform (loc, " %qT is not the same as %qT", t1, t2); break; @@ -3203,6 +3257,9 @@ diagnose_trait_expr (tree expr, tree args) case CPTK_IS_TRIVIALLY_DESTRUCTIBLE: inform (loc, " %qT is not trivially destructible", t1); break; + case CPTK_IS_TRIVIALLY_RELOCATABLE: + inform (loc, " %qT is not trivially relocatable", t1); + break; case CPTK_IS_UNBOUNDED_ARRAY: inform (loc, " %qT is not an unbounded array", t1); break; @@ -3218,6 +3275,9 @@ diagnose_trait_expr (tree expr, tree args) case CPTK_RANK: inform (loc, " %qT cannot yield a rank", t1); break; + case CPTK_TYPE_ORDER: + inform (loc, " %qT and %qT cannot be ordered", t1, t2); + break; case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY: inform (loc, " %qT is not a reference that binds to a temporary " "object of type %qT (direct-initialization)", t1, t2); diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 7f5d30cf9afd..52cc186fbfa8 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -191,8 +191,87 @@ static bool coro_promise_type_found_p (tree, location_t); just syntactic sugar for a co_await). We defer the analysis and transformation until template expansion is - complete so that we have complete types at that time. */ + complete so that we have complete types at that time. + --------------------------------------------------------------------------- + + Coroutine state, and responsibility for its release. + + As noted above, a coroutine has some state that persists across suspensions. + + The state has two components: + * State that is specified by the standard and persists for the entire + life of the coroutine. + * Local state that is constructed/destructed as scopes in the original + function body are entered/exited. The destruction of local state is + always the responsibility of the body code. + + The persistent state (and the overall storage for the state) must be + managed in two places: + * The ramp function (which allocates and builds this - and can, in some + cases, be responsible for destroying it) + * The re-written function body which can destroy it when that body + completes its final suspend - or when the handle.destroy () is called. + + In all cases the ramp holds responsibility for constructing the standard- + mandated persistent state. + + There are four ways in which the ramp might be re-entered after starting + the function body: + A The body could suspend (one might expect that to be the 'normal' case + for most coroutines). + B The body might complete either synchronously or via continuations. + C An exception might be thrown during the setup of the initial await + expression, before the initial awaiter resumes. + D An exception might be processed by promise.unhandled_exception () and + that, in turn, might re-throw it (or throw something else). In this + case, the coroutine is considered suspended at the final suspension + point. + + Until the ramp return value has been constructed, the ramp is considered + to have a use of the state. + + To manage these interacting conditions we allocate a reference counter + for the frame state. This is initialised to 1 by the ramp as part of its + startup (note that failures/exceptions in the startup code are handled + locally to the ramp). + + When the body returns (either normally, or by exception) the ramp releases + its use. + + Once the rewritten coroutine body is started, the body is considered to + have a use of the frame. This use (potentially) needs to be released if + an exception is thrown from the body. We implement this using an eh-only + cleanup around the initial await and function body. If we have the case + D above, then we do not release the use. + + In case: + + A, typically the ramp would be re-entered with the body holding a use, + and therefore the ramp should not destroy the state. + + B, both the body and ramp will have released their uses, and the ramp + should destroy the state. + + C, we must arrange for the body to release its use, because we require + the ramp to cleanup in this circumstance. + + D is an outlier, since the responsibility for destruction of the state + now rests with the user's code (via a handle.destroy() call). + + NOTE: In the case that the body has never suspended before such an + exception occurs, the only reasonable way for the user code to obtain the + necessary handle is if unhandled_exception() throws the handle or some + object that contains the handle. That is outside of the designs here - + if the user code might need this corner-case, then such provision will + have to be made. + + In the ramp, we implement destruction for the persistent frame state by + means of cleanups. These are run conditionally when the reference count + is 0 signalling that both the body and the ramp have completed. + + In the body, once we pass the final suspend, then we test the use and + delete the state if the use is 0. */ /* The state that we collect during parsing (and template expansion) for a coroutine. */ @@ -206,11 +285,10 @@ struct GTY((for_user)) coroutine_info tree traits_type; /* The cached traits type for this function. */ tree handle_type; /* The cached coroutine handle for this function. */ tree self_h_proxy; /* A handle instance that is used as the proxy for the - one that will eventually be allocated in the coroutine - frame. */ + one that will eventually be built in lowering. */ tree promise_proxy; /* Likewise, a proxy promise instance. */ - tree from_address; /* handle_type from_address function. */ - tree return_void; /* The expression for p.return_void() if it exists. */ + tree from_address; /* handle_type from_address() function. */ + tree return_void; /* The expression for p.return_void(), if it exists. */ location_t first_coro_keyword; /* The location of the keyword that made this function into a coroutine. */ @@ -348,6 +426,7 @@ static GTY(()) tree coro_resume_index_id; static GTY(()) tree coro_self_handle_id; static GTY(()) tree coro_actor_continue_id; static GTY(()) tree coro_frame_i_a_r_c_id; +static GTY(()) tree coro_frame_refcount_id; /* Create the identifiers used by the coroutines library interfaces and the implementation frame state. */ @@ -385,6 +464,7 @@ coro_init_identifiers () coro_resume_index_id = get_identifier ("_Coro_resume_index"); coro_self_handle_id = get_identifier ("_Coro_self_handle"); coro_actor_continue_id = get_identifier ("_Coro_actor_continue"); + coro_frame_refcount_id = get_identifier ("_Coro_frame_refcount"); } /* Trees we only need to set up once. */ @@ -1277,8 +1357,14 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind, if (TREE_CODE (o_type) != RECORD_TYPE) { - error_at (loc, "awaitable type %qT is not a structure", - o_type); + if (suspend_kind == FINAL_SUSPEND_POINT) + error_at (loc, "%qs awaitable type %qT is not a structure", + "final_suspend()", o_type); + else if (suspend_kind == INITIAL_SUSPEND_POINT) + error_at (loc, "%qs awaitable type %qT is not a structure", + "initial_suspend()", o_type); + else + error_at (loc, "awaitable type %qT is not a structure", o_type); return error_mark_node; } @@ -1461,6 +1547,12 @@ finish_co_await_expr (location_t kw, tree expr) if (!expr || error_operand_p (expr)) return error_mark_node; + if (cp_unevaluated_operand) + { + error_at (kw, "%qs cannot be used in an unevaluated context","co_await"); + return error_mark_node; + } + if (!coro_common_keyword_context_valid_p (current_function_decl, kw, "co_await")) return error_mark_node; @@ -1541,6 +1633,12 @@ finish_co_yield_expr (location_t kw, tree expr) if (!expr || error_operand_p (expr)) return error_mark_node; + if (cp_unevaluated_operand) + { + error_at (kw, "%qs cannot be used in an unevaluated context","co_yield"); + return error_mark_node; + } + /* Check the general requirements and simple syntax errors. */ if (!coro_common_keyword_context_valid_p (current_function_decl, kw, "co_yield")) @@ -1964,12 +2062,13 @@ struct coro_aw_data tree coro_fp; /* Frame pointer var. */ tree resume_idx; /* This is the index var in the frame. */ tree i_a_r_c; /* initial suspend await_resume() was called if true. */ - tree self_h; /* This is a handle to the current coro (frame var). */ tree cleanup; /* This is where to go once we complete local destroy. */ tree cororet; /* This is where to go if we suspend. */ tree corocont; /* This is where to go if we continue. */ tree dispatch; /* This is where we go if we restart the dispatch. */ tree conthand; /* This is the handle for a continuation. */ + tree handle_type; /* Handle type for this coroutine... */ + tree hfa_m; /* ... and handle.from_address() for this. */ unsigned index; /* This is our current resume index. */ }; @@ -2027,8 +2126,10 @@ expand_one_await_expression (tree *expr, tree *await_expr, void *d) tree awaiter_calls = TREE_OPERAND (saved_co_await, 3); tree source = TREE_OPERAND (saved_co_await, 4); - bool is_final = (source - && TREE_INT_CST_LOW (source) == (int) FINAL_SUSPEND_POINT); + bool is_final + = (source && TREE_INT_CST_LOW (source) == (int) FINAL_SUSPEND_POINT); + bool is_initial + = (source && TREE_INT_CST_LOW (source) == (int) INITIAL_SUSPEND_POINT); /* Build labels for the destinations of the control flow when we are resuming or destroying. */ @@ -2085,6 +2186,18 @@ expand_one_await_expression (tree *expr, tree *await_expr, void *d) tree suspend = TREE_VEC_ELT (awaiter_calls, 1); /* await_suspend(). */ tree susp_type = TREE_TYPE (suspend); + tree susp_call = suspend; + if (TREE_CODE (suspend) == TARGET_EXPR) + susp_call = TARGET_EXPR_INITIAL (suspend); + gcc_checking_assert (TREE_CODE (susp_call) == CALL_EXPR); + tree dummy_ch = build_dummy_object (data->handle_type); + r = fold_convert (build_pointer_type (void_type_node), data->coro_fp); + vec<tree, va_gc> *args = make_tree_vector_single (r); + tree hfa = cp_fold_rvalue ( + build_new_method_call (dummy_ch, data->hfa_m, &args, NULL_TREE, + LOOKUP_NORMAL, NULL, tf_warning_or_error)); + release_tree_vector (args); + CALL_EXPR_ARG (susp_call, call_expr_nargs (susp_call) - 1) = hfa; bool is_cont = false; /* NOTE: final suspend can't resume; the "resume" label in that case @@ -2156,6 +2269,13 @@ expand_one_await_expression (tree *expr, tree *await_expr, void *d) /* Resume point. */ add_stmt (build_stmt (loc, LABEL_EXPR, resume_label)); + if (is_initial && data->i_a_r_c) + { + r = cp_build_modify_expr (loc, data->i_a_r_c, NOP_EXPR, boolean_true_node, + tf_warning_or_error); + finish_expr_stmt (r); + } + /* This will produce the value (if one is provided) from the co_await expression. */ tree resume_call = TREE_VEC_ELT (awaiter_calls, 2); /* await_resume(). */ @@ -2397,6 +2517,11 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody, bool spf = start_preparsed_function (actor, NULL_TREE, SF_PRE_PARSED); gcc_checking_assert (spf); gcc_checking_assert (cfun && current_function_decl && TREE_STATIC (actor)); + if (flag_exceptions) + /* We, unconditionally, add a try/catch and rethrow. + TODO: Determine if the combination of initial suspend and the original + body cannot throw, and elide these additions. */ + cp_function_chain->can_throw = true; tree stmt = begin_function_body (); tree actor_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL); @@ -2554,21 +2679,16 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody, /* Now we start building the rewritten function body. */ add_stmt (build_stmt (loc, LABEL_EXPR, actor_begin_label)); - /* actor's coroutine 'self handle'. */ - tree ash = coro_build_frame_access_expr (actor_frame, coro_self_handle_id, - false, tf_warning_or_error); - /* So construct the self-handle from the frame address. */ - tree hfa_m = get_coroutine_from_address (orig); - /* Should have been set earlier by coro_promise_type_found_p. */ - gcc_assert (hfa_m); - - tree r = build1 (CONVERT_EXPR, build_pointer_type (void_type_node), actor_fp); - vec<tree, va_gc> *args = make_tree_vector_single (r); - tree hfa = build_new_method_call (ash, hfa_m, &args, NULL_TREE, LOOKUP_NORMAL, - NULL, tf_warning_or_error); - r = cp_build_init_expr (ash, hfa); - finish_expr_stmt (r); - release_tree_vector (args); + tree i_a_r_c = NULL_TREE; + if (flag_exceptions) + { + i_a_r_c + = coro_build_frame_access_expr (actor_frame, coro_frame_i_a_r_c_id, + false, tf_warning_or_error); + tree m = cp_build_modify_expr (loc, i_a_r_c, NOP_EXPR, + boolean_false_node, tf_warning_or_error); + finish_expr_stmt (m); + } /* Now we know the real promise, and enough about the frame layout to decide where to put things. */ @@ -2583,7 +2703,28 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody, /* Add in our function body with the co_returns rewritten to final form. */ add_stmt (fnbody); - /* Now do the tail of the function; first cleanups. */ + /* We are done with the frame, but if the ramp still has a hold on it + we should not cleanup. So decrement the refcount and then return to + the ramp if it is > 0. */ + tree coro_frame_refcount + = coro_build_frame_access_expr (actor_frame, coro_frame_refcount_id, + false, tf_warning_or_error); + tree released = build2_loc (loc, MINUS_EXPR, short_unsigned_type_node, + coro_frame_refcount, + build_int_cst (short_unsigned_type_node, 1)); + tree r = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR, released, + tf_warning_or_error); + finish_expr_stmt (r); + tree cond = build2_loc (loc, NE_EXPR, short_unsigned_type_node, + coro_frame_refcount, + build_int_cst (short_unsigned_type_node, 0)); + tree ramp_cu_if = begin_if_stmt (); + finish_if_stmt_cond (cond, ramp_cu_if); + finish_return_stmt (NULL_TREE); + finish_then_clause (ramp_cu_if); + finish_if_stmt (ramp_cu_if); + + /* Otherwise, do the tail of the function; first cleanups. */ r = build_stmt (loc, LABEL_EXPR, del_promise_label); add_stmt (r); @@ -2652,12 +2793,19 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody, gcc_checking_assert (maybe_cleanup_point_expr_void (r) == r); add_stmt (r); + /* How to construct the handle for this coroutine from the frame address. */ + tree hfa_m = get_coroutine_from_address (orig); + /* Should have been set earlier by coro_promise_type_found_p. */ + gcc_assert (hfa_m); + tree handle_type = TREE_TYPE (get_coroutine_self_handle_proxy (orig)); + /* We've now rewritten the tree and added the initial and final co_awaits. Now pass over the tree and expand the co_awaits. */ - coro_aw_data data = {actor, actor_fp, resume_idx_var, NULL_TREE, - ash, del_promise_label, ret_label, - continue_label, restart_dispatch_label, continuation, 2}; + coro_aw_data data = {actor, actor_fp, resume_idx_var, i_a_r_c, + del_promise_label, ret_label, + continue_label, restart_dispatch_label, continuation, + handle_type, hfa_m, 2}; cp_walk_tree (&actor_body, await_statement_expander, &data, NULL); BIND_EXPR_BODY (actor_bind) = pop_stmt_list (actor_body); @@ -3407,7 +3555,8 @@ maybe_promote_temps (tree *stmt, void *d) return cp_walk_tree (stmt, register_awaits, d, &visited); } -/* Lightweight callback to determine two key factors: +/* Relatively lightweight callback to do initial assessment: + 0) Rewrite some await expressions. 1) If the statement/expression contains any await expressions. 2) If the statement/expression potentially requires a re-write to handle TRUTH_{AND,OR}IF_EXPRs since, in most cases, they will need expansion @@ -3424,6 +3573,39 @@ analyze_expression_awaits (tree *stmt, int *do_subtree, void *d) switch (TREE_CODE (*stmt)) { default: return NULL_TREE; + case CALL_EXPR: + { + tree fn = cp_get_callee_fndecl_nofold (*stmt); + /* Special-cases where we want to re-write await expressions to some + other value before they are otherwise processed. */ + if (fn && DECL_IS_BUILTIN_CONSTANT_P (fn)) + { + gcc_checking_assert (call_expr_nargs (*stmt) == 1); + tree expr = CALL_EXPR_ARG (*stmt, 0); + if (cp_walk_tree (&expr, find_any_await, nullptr, NULL)) + { + if (TREE_CONSTANT (maybe_constant_value (expr))) + *stmt = integer_one_node; + else + *stmt = integer_zero_node; + } + *do_subtree = 0; + } + else if (!fn && CALL_EXPR_IFN (*stmt) == IFN_ASSUME) + { + tree expr = CALL_EXPR_ARG (*stmt, 0); + if (TREE_SIDE_EFFECTS (expr)) + { + location_t loc_e = cp_expr_location (expr); + location_t loc_s = cp_expr_location (*stmt); + location_t loc_n = make_location (loc_e, loc_s, loc_s); + warning_at (loc_n, OPT_Wattributes,"assumption ignored" + " because it contains an await-expression"); + *stmt = build_empty_stmt (loc_n); + } + } + } + break; case CO_YIELD_EXPR: /* co_yield is syntactic sugar, re-write it to co_await. */ *stmt = TREE_OPERAND (*stmt, 1); @@ -4014,12 +4196,14 @@ rewrite_param_uses (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d) } /* Build up a set of info that determines how each param copy will be - handled. */ + handled. We store this in a hash map so that we can access it from + a tree walk callback that re-writes the original parameters to their + copies. */ -static void -analyze_fn_parms (tree orig, hash_map<tree, param_info> *param_uses) +void +cp_coroutine_transform::analyze_fn_parms () { - if (!DECL_ARGUMENTS (orig)) + if (!DECL_ARGUMENTS (orig_fn_decl)) return; /* Build a hash map with an entry for each param. @@ -4029,19 +4213,19 @@ analyze_fn_parms (tree orig, hash_map<tree, param_info> *param_uses) Then a tree list of the uses. The second two entries start out empty - and only get populated when we see uses. */ - bool lambda_p = LAMBDA_FUNCTION_P (orig); + bool lambda_p = LAMBDA_FUNCTION_P (orig_fn_decl); /* Count the param copies from 1 as per the std. */ unsigned parm_num = 1; - for (tree arg = DECL_ARGUMENTS (orig); arg != NULL; + for (tree arg = DECL_ARGUMENTS (orig_fn_decl); arg != NULL; ++parm_num, arg = DECL_CHAIN (arg)) { bool existed; - param_info &parm = param_uses->get_or_insert (arg, &existed); + param_info &parm = param_uses.get_or_insert (arg, &existed); gcc_checking_assert (!existed); parm.body_uses = NULL; tree actual_type = TREE_TYPE (arg); - actual_type = complete_type_or_else (actual_type, orig); + actual_type = complete_type_or_else (actual_type, orig_fn_decl); if (actual_type == NULL_TREE) actual_type = error_mark_node; parm.orig_type = actual_type; @@ -4266,8 +4450,7 @@ cp_coroutine_transform::wrap_original_function_body () { /* Avoid the code here attaching a location that makes the debugger jump. */ iloc_sentinel stable_input_loc (fn_start); - location_t loc = UNKNOWN_LOCATION; - input_location = loc; + location_t loc = fn_start; /* This will be our new outer scope. */ tree update_body @@ -4315,7 +4498,6 @@ cp_coroutine_transform::wrap_original_function_body () /* Wrap the function body in a try {} catch (...) {} block, if exceptions are enabled. */ tree var_list = NULL_TREE; - tree initial_await = build_init_or_final_await (fn_start, false); /* [stmt.return.coroutine] / 3 If p.return_void() is a valid expression, flowing off the end of a @@ -4354,16 +4536,6 @@ cp_coroutine_transform::wrap_original_function_body () var_list = promise; add_decl_expr (promise); - /* We need a handle to this coroutine, which is passed to every - await_suspend(). This was created on demand when parsing we now link it - into our scope. */ - var = get_coroutine_self_handle_proxy (orig_fn_decl); - DECL_CONTEXT (var) = orig_fn_decl; - DECL_SOURCE_LOCATION (var) = loc; - DECL_CHAIN (var) = var_list; - var_list = var; - add_decl_expr (var); - /* If we have function parms, then these will be copied to the coroutine frame as per [dcl.fct.def.coroutine] / 13. Here, we create a local (proxy) variable for each parm, since the original @@ -4407,21 +4579,38 @@ cp_coroutine_transform::wrap_original_function_body () var_list = resume_idx_var; add_decl_expr (resume_idx_var); + tree coro_frame_refcount + = coro_build_artificial_var (loc, coro_frame_refcount_id, + short_unsigned_type_node, orig_fn_decl, + NULL_TREE); + DECL_CHAIN (coro_frame_refcount) = var_list; + var_list = coro_frame_refcount; + add_decl_expr (coro_frame_refcount); + /* If the coroutine has a frame that needs to be freed, this will be set by the ramp. */ - var = coro_build_artificial_var (fn_start, coro_frame_needs_free_id, + var = coro_build_artificial_var (loc, coro_frame_needs_free_id, boolean_type_node, orig_fn_decl, NULL_TREE); DECL_CHAIN (var) = var_list; var_list = var; add_decl_expr (var); + /* We consider that the body has a use of the frame once we start to process + the initial suspend expression. (the use might be relinquished if we + encounter an exception before the body is finished). */ + tree body_use + = build2_loc (loc, PLUS_EXPR, short_unsigned_type_node, coro_frame_refcount, + build_int_cst (short_unsigned_type_node, 1)); + body_use = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR, body_use, + tf_warning_or_error); + finish_expr_stmt (body_use); if (flag_exceptions) { /* Build promise.unhandled_exception(); */ tree ueh = coro_build_promise_expression (orig_fn_decl, promise, coro_unhandled_exception_identifier, - fn_start, NULL, /*musthave=*/true); + loc, NULL, /*musthave=*/true); /* Create and initialize the initial-await-resume-called variable per [dcl.fct.def.coroutine] / 5.3. */ tree i_a_r_c @@ -4435,34 +4624,28 @@ cp_coroutine_transform::wrap_original_function_body () tree tcb = build_stmt (loc, TRY_BLOCK, NULL_TREE, NULL_TREE); add_stmt (tcb); TRY_STMTS (tcb) = push_stmt_list (); - if (initial_await != error_mark_node) - { - /* Build a compound expression that sets the - initial-await-resume-called variable true and then calls the - initial suspend expression await resume. - In the case that the user decides to make the initial await - await_resume() return a value, we need to discard it and, it is - a reference type, look past the indirection. */ - if (INDIRECT_REF_P (initial_await)) - initial_await = TREE_OPERAND (initial_await, 0); - /* In the case that the initial_await returns a target expression - we might need to look through that to update the await expr. */ - tree iaw = initial_await; - if (TREE_CODE (iaw) == TARGET_EXPR) - iaw = TARGET_EXPR_INITIAL (iaw); - gcc_checking_assert (TREE_CODE (iaw) == CO_AWAIT_EXPR); - tree vec = TREE_OPERAND (iaw, 3); - tree aw_r = TREE_VEC_ELT (vec, 2); - aw_r = convert_to_void (aw_r, ICV_STATEMENT, tf_warning_or_error); - tree update = build2 (MODIFY_EXPR, boolean_type_node, i_a_r_c, - boolean_true_node); - aw_r = cp_build_compound_expr (update, aw_r, tf_warning_or_error); - TREE_VEC_ELT (vec, 2) = aw_r; - } + /* We need a new scope to handle the cleanup for the ramp use that is + needed for exceptions. */ + tree except_scope = begin_compound_stmt (0); + current_binding_level->artificial = 1; + tree release + = build2_loc (loc, MINUS_EXPR, short_unsigned_type_node, + coro_frame_refcount, build_int_cst (short_unsigned_type_node, 1)); + release = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR, + release, tf_warning_or_error); + /* Once we pass the initial await resume, the cleanup rules on exception + change so that the responsibility lies with the caller. */ + release = build3 (COND_EXPR, void_type_node, i_a_r_c, + build_empty_stmt (loc), release); + push_cleanup (NULL_TREE, release, /*ehonly*/true); /* Add the initial await to the start of the user-authored function. */ finish_expr_stmt (initial_await); + /* End the scope that handles the remove of frame-use on exception. */ + finish_compound_stmt (except_scope); + /* Append the original function body. */ add_stmt (coroutine_body); + if (return_void) add_stmt (return_void); TRY_STMTS (tcb) = pop_stmt_list (TRY_STMTS (tcb)); @@ -4507,9 +4690,9 @@ cp_coroutine_transform::wrap_original_function_body () tree ueh_meth = lookup_promise_method (orig_fn_decl, coro_unhandled_exception_identifier, - fn_start, /*musthave=*/false); + loc, /*musthave=*/false); if (!ueh_meth || ueh_meth == error_mark_node) - warning_at (fn_start, 0, "no member named %qE in %qT", + warning_at (loc, 0, "no member named %qE in %qT", coro_unhandled_exception_identifier, get_coroutine_promise_type (orig_fn_decl)); } @@ -4522,6 +4705,10 @@ cp_coroutine_transform::wrap_original_function_body () add_stmt (return_void); } + /* We are now doing actions associated with the end of the function, so + point to the closing brace. */ + input_location = loc = fn_end; + /* co_return branches to the final_suspend label, so declare that now. */ fs_label = create_named_label_with_ctx (loc, "final.suspend", NULL_TREE); @@ -4533,7 +4720,8 @@ cp_coroutine_transform::wrap_original_function_body () zero_resume = build2_loc (loc, MODIFY_EXPR, act_des_fn_ptr_type, resume_fn_ptr, zero_resume); finish_expr_stmt (zero_resume); - finish_expr_stmt (build_init_or_final_await (fn_start, true)); + finish_expr_stmt (final_await); + BIND_EXPR_BODY (update_body) = pop_stmt_list (BIND_EXPR_BODY (update_body)); BIND_EXPR_VARS (update_body) = nreverse (var_list); BLOCK_VARS (top_block) = BIND_EXPR_VARS (update_body); @@ -4902,31 +5090,18 @@ cp_coroutine_transform::build_ramp_function () just set it true. */ TREE_USED (frame_needs_free) = true; - tree iarc_x = NULL_TREE; - tree coro_before_return = NULL_TREE; - if (flag_exceptions) - { - coro_before_return - = coro_build_and_push_artificial_var (loc, "_Coro_before_return", - boolean_type_node, orig_fn_decl, - boolean_true_node); - iarc_x - = coro_build_and_push_artificial_var_with_dve (loc, - coro_frame_i_a_r_c_id, - boolean_type_node, - orig_fn_decl, - boolean_false_node, - deref_fp); - tree frame_cleanup = push_stmt_list (); - tree do_fr_cleanup - = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, iarc_x); - do_fr_cleanup = build2_loc (loc, TRUTH_ANDIF_EXPR, boolean_type_node, - coro_before_return, do_fr_cleanup); - r = build3 (COND_EXPR, void_type_node, do_fr_cleanup, - delete_frame_call, void_node); - finish_expr_stmt (r); - push_cleanup (coro_fp, pop_stmt_list (frame_cleanup), /*eh_only*/true); - } + tree coro_frame_refcount + = coro_build_and_push_artificial_var_with_dve (loc, coro_frame_refcount_id, + short_unsigned_type_node, + orig_fn_decl, NULL_TREE, + deref_fp); + /* Cleanup if both the ramp and the body have finished. */ + tree cond + = build2_loc (loc, EQ_EXPR, short_unsigned_type_node, coro_frame_refcount, + build_int_cst (short_unsigned_type_node, 0)); + r = build3 (COND_EXPR, void_type_node, cond, delete_frame_call, + build_empty_stmt (loc)); + push_cleanup (coro_fp, r, /*eh_only*/false); /* Put the resumer and destroyer functions in. */ @@ -5001,24 +5176,20 @@ cp_coroutine_transform::build_ramp_function () /* Arrange for parm copies to be cleaned up when an exception is thrown before initial await resume. */ - if (flag_exceptions && !parm.trivial_dtor) + if (!parm.trivial_dtor) { parm.fr_copy_dtor = cxx_maybe_build_cleanup (fld_idx, tf_warning_or_error); if (parm.fr_copy_dtor && parm.fr_copy_dtor != error_mark_node) { param_dtor_list.safe_push (parm.field_id); - tree param_cleanup = push_stmt_list (); - tree do_cleanup - = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, iarc_x); - do_cleanup - = build2_loc (loc, TRUTH_ANDIF_EXPR, boolean_type_node, - coro_before_return, do_cleanup); - r = build3_loc (loc, COND_EXPR, void_type_node, do_cleanup, - parm.fr_copy_dtor, void_node); - finish_expr_stmt (r); - push_cleanup (fld_idx, pop_stmt_list (param_cleanup), - /*eh_only*/true); + cond + = build2_loc (loc, EQ_EXPR, short_unsigned_type_node, + coro_frame_refcount, + build_int_cst (short_unsigned_type_node, 0)); + r = build3_loc (loc, COND_EXPR, void_type_node, cond, + parm.fr_copy_dtor, build_empty_stmt (loc)); + push_cleanup (fld_idx, r, /*eh_only*/false); } } } @@ -5063,22 +5234,16 @@ cp_coroutine_transform::build_ramp_function () finish_expr_stmt (r); } - if (flag_exceptions) + tree promise_dtor = cxx_maybe_build_cleanup (p, tf_warning_or_error); + /* If the promise is live, then run its dtor if that's available. */ + if (promise_dtor && promise_dtor != error_mark_node) { - tree promise_dtor = cxx_maybe_build_cleanup (p, tf_warning_or_error); - /* If the promise is live, then run its dtor if that's available. */ - if (promise_dtor && promise_dtor != error_mark_node) - { - tree promise_cleanup = push_stmt_list (); - tree do_cleanup - = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, iarc_x); - do_cleanup = build2_loc (loc, TRUTH_ANDIF_EXPR, boolean_type_node, - coro_before_return, do_cleanup); - r = build3 (COND_EXPR, void_type_node, do_cleanup, - promise_dtor, void_node); - finish_expr_stmt (r); - push_cleanup (p, pop_stmt_list (promise_cleanup), /*eh_only*/true); - } + cond = build2_loc (loc, EQ_EXPR, short_unsigned_type_node, + coro_frame_refcount, + build_int_cst (short_unsigned_type_node, 0)); + r = build3 (COND_EXPR, void_type_node, cond, promise_dtor, + build_empty_stmt (loc)); + push_cleanup (p, r, /*eh_only*/false); } tree get_ro @@ -5143,16 +5308,22 @@ cp_coroutine_transform::build_ramp_function () push_cleanup (coro_gro, coro_gro_cleanup, /*eh_only*/false); } - /* Start the coroutine body. */ - r = build_call_expr_loc (fn_start, resumer, 1, coro_fp); + /* Start the coroutine body, we now have a use of the frame... */ + r = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR, + build_int_cst (short_unsigned_type_node, 1), + tf_warning_or_error); finish_expr_stmt (r); + /* ... but when we finish we want to release that, and we want to do that + before any of the other cleanups run. */ + tree released + = build2_loc (loc, MINUS_EXPR, short_unsigned_type_node, coro_frame_refcount, + build_int_cst (short_unsigned_type_node, 1)); + released = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR, released, + tf_warning_or_error); + push_cleanup (NULL_TREE, released, /*eh_only*/false); - if (flag_exceptions) - { - r = cp_build_modify_expr (input_location, coro_before_return, NOP_EXPR, - boolean_false_node, tf_warning_or_error); - finish_expr_stmt (r); - } + r = build_call_expr_loc (fn_start, resumer, 1, coro_fp); + finish_expr_stmt (r); /* The ramp is done, we just need the return statement, which we build from the return object we constructed before we called the actor. */ @@ -5190,9 +5361,10 @@ cp_coroutine_transform::cp_coroutine_transform (tree _orig_fn, bool _inl) } /* We don't have the locus of the opening brace - it's filled in later (and - there doesn't really seem to be any easy way to get at it). - The closing brace is assumed to be input_location. */ + there doesn't really seem to be any easy way to get at it). */ fn_start = DECL_SOURCE_LOCATION (orig_fn_decl); + /* The closing brace is assumed to be input_location. */ + fn_end = input_location; /* Build types we need. */ tree fr_name = get_fn_local_identifier (orig_fn_decl, "Frame"); @@ -5233,7 +5405,6 @@ cp_coroutine_transform::~cp_coroutine_transform () bool _Coro_frame_needs_free; free the coro frame mem if set. bool _Coro_i_a_r_c; [dcl.fct.def.coroutine] / 5.3 short _Coro_resume_index; - handle_type _Coro_self_handle; parameter copies (were required). local variables saved (including awaitables) (maybe) trailing space. @@ -5260,7 +5431,7 @@ cp_coroutine_transform::apply_transforms () /* Collect information on the original function params and their use in the function body. */ - analyze_fn_parms (orig_fn_decl, ¶m_uses); + analyze_fn_parms (); /* Declare the actor and destroyer functions, the following code needs to see these. */ @@ -5271,6 +5442,16 @@ cp_coroutine_transform::apply_transforms () = coro_build_actor_or_destroy_function (orig_fn_decl, act_des_fn_type, frame_ptr_type, false); + /* Avoid repeating diagnostics about promise or awaiter fails. */ + if (!seen_error ()) + { + iloc_sentinel stable_input_loc (fn_start); + initial_await = build_init_or_final_await (fn_start, false); + input_location = fn_end; + if (initial_await && initial_await != error_mark_node) + final_await = build_init_or_final_await (fn_end, true); + } + /* Transform the function body as per [dcl.fct.def.coroutine] / 5. */ wrap_original_function_body (); diff --git a/gcc/cp/coroutines.h b/gcc/cp/coroutines.h index 10698cf2e129..fcc464579157 100644 --- a/gcc/cp/coroutines.h +++ b/gcc/cp/coroutines.h @@ -100,8 +100,8 @@ class cp_coroutine_transform { private: tree orig_fn_decl; /* The original function decl. */ - tree orig_fn_body = NULL_TREE; /* The original function body. */ location_t fn_start = UNKNOWN_LOCATION; + location_t fn_end = UNKNOWN_LOCATION; tree resumer = error_mark_node; tree destroyer = error_mark_node; tree coroutine_body = NULL_TREE; @@ -126,6 +126,10 @@ class cp_coroutine_transform { bool inline_p = false; bool valid_coroutine = false; + tree initial_await = error_mark_node; + tree final_await = error_mark_node; + + void analyze_fn_parms (); void wrap_original_function_body (); bool build_ramp_function (); }; diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc index 0fcfa16d2c59..4ff8f36a9fb6 100644 --- a/gcc/cp/cp-gimplify.cc +++ b/gcc/cp/cp-gimplify.cc @@ -690,6 +690,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) && (REFERENCE_CLASS_P (op1) || DECL_P (op1))) op1 = build_fold_addr_expr (op1); + suppress_warning (op1, OPT_Wunused_result); gimplify_and_add (op1, pre_p); } gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, @@ -889,6 +890,12 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) (EXPR_LOCATION (*expr_p), call_expr_nargs (*expr_p), &CALL_EXPR_ARG (*expr_p, 0)); break; + case CP_BUILT_IN_EH_PTR_ADJUST_REF: + error_at (EXPR_LOCATION (*expr_p), + "%qs used outside of constant expressions", + "__builtin_eh_ptr_adjust_ref"); + *expr_p = void_node; + break; default: break; } @@ -3022,7 +3029,7 @@ cp_fold (tree x, fold_flags_t flags) case CLEANUP_POINT_EXPR: /* Strip CLEANUP_POINT_EXPR if the expression doesn't have side effects. */ - r = cp_fold_rvalue (TREE_OPERAND (x, 0), flags); + r = cp_fold (TREE_OPERAND (x, 0), flags); if (!TREE_SIDE_EFFECTS (r)) x = r; break; @@ -3211,7 +3218,16 @@ cp_fold (tree x, fold_flags_t flags) loc = EXPR_LOCATION (x); op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags); - op1 = cp_fold_rvalue (TREE_OPERAND (x, 1), flags); + bool clear_decl_read; + clear_decl_read = false; + if (code == MODIFY_EXPR + && (VAR_P (op0) || TREE_CODE (op0) == PARM_DECL) + && !DECL_READ_P (op0)) + clear_decl_read = true; + op1 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 1), + code != COMPOUND_EXPR, flags); + if (clear_decl_read) + DECL_READ_P (op0) = 0; /* decltype(nullptr) has only one value, so optimize away all comparisons with that type right away, keeping them in the IL causes troubles for @@ -3887,7 +3903,6 @@ struct source_location_table_entry_hash static GTY(()) hash_table <source_location_table_entry_hash> *source_location_table; -static GTY(()) unsigned int source_location_id; /* Fold the __builtin_source_location () call T. */ @@ -3920,9 +3935,7 @@ fold_builtin_source_location (const_tree t) var = entryp->var; else { - char tmp_name[32]; - ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lsrc_loc", source_location_id++); - var = build_decl (loc, VAR_DECL, get_identifier (tmp_name), + var = build_decl (loc, VAR_DECL, generate_internal_label ("Lsrc_loc"), source_location_impl); TREE_STATIC (var) = 1; TREE_PUBLIC (var) = 0; diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def index 9c7380d7398e..9fedfd71a38f 100644 --- a/gcc/cp/cp-trait.def +++ b/gcc/cp/cp-trait.def @@ -87,12 +87,14 @@ DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, "__is_nothrow_constructible", -1) DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, "__is_nothrow_convertible", 2) DEFTRAIT_EXPR (IS_NOTHROW_DESTRUCTIBLE, "__is_nothrow_destructible", 1) DEFTRAIT_EXPR (IS_NOTHROW_INVOCABLE, "__is_nothrow_invocable", -1) +DEFTRAIT_EXPR (IS_NOTHROW_RELOCATABLE, "__builtin_is_nothrow_relocatable", 1) DEFTRAIT_EXPR (IS_OBJECT, "__is_object", 1) DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, "__is_pointer_interconvertible_base_of", 2) DEFTRAIT_EXPR (IS_POD, "__is_pod", 1) DEFTRAIT_EXPR (IS_POINTER, "__is_pointer", 1) DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1) DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1) +DEFTRAIT_EXPR (IS_REPLACEABLE, "__builtin_is_replaceable", 1) DEFTRAIT_EXPR (IS_SAME, "__is_same", 2) DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1) DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1) @@ -100,7 +102,8 @@ DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1) DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2) DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1) DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1) -DEFTRAIT_EXPR (IS_TRIVIALLY_DESTRUCTIBLE, "__is_trivially_destructible", -1) +DEFTRAIT_EXPR (IS_TRIVIALLY_DESTRUCTIBLE, "__is_trivially_destructible", 1) +DEFTRAIT_EXPR (IS_TRIVIALLY_RELOCATABLE, "__builtin_is_trivially_relocatable", 1) DEFTRAIT_EXPR (IS_UNBOUNDED_ARRAY, "__is_unbounded_array", 1) DEFTRAIT_EXPR (IS_UNION, "__is_union", 1) DEFTRAIT_EXPR (IS_VIRTUAL_BASE_OF, "__builtin_is_virtual_base_of", 2) @@ -114,6 +117,7 @@ DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1) DEFTRAIT_TYPE (REMOVE_EXTENT, "__remove_extent", 1) DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1) DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1) +DEFTRAIT_EXPR (TYPE_ORDER, "__builtin_type_order", 2) DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1) DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3cf4a7654b39..681025015690 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -452,6 +452,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; contract_semantic (in ASSERTION_, PRECONDITION_, POSTCONDITION_STMT) RETURN_EXPR_LOCAL_ADDR_P (in RETURN_EXPR) PACK_INDEX_PARENTHESIZED_P (in PACK_INDEX_*) + MUST_NOT_THROW_NOEXCEPT_P (in MUST_NOT_THROW_EXPR) 1: IDENTIFIER_KIND_BIT_1 (in IDENTIFIER_NODE) TI_PENDING_TEMPLATE_FLAG. TEMPLATE_PARMS_FOR_INLINE. @@ -472,6 +473,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; BIND_EXPR_VEC_DTOR (in BIND_EXPR) ATOMIC_CONSTR_EXPR_FROM_CONCEPT_P (in ATOMIC_CONSTR) STATIC_INIT_DECOMP_BASE_P (in the TREE_LIST for {static,tls}_aggregates) + MUST_NOT_THROW_THROW_P (in MUST_NOT_THROW_EXPR) 2: IDENTIFIER_KIND_BIT_2 (in IDENTIFIER_NODE) ICS_THIS_FLAG (in _CONV) DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL) @@ -493,6 +495,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; contract_semantic (in ASSERTION_, PRECONDITION_, POSTCONDITION_STMT) STATIC_INIT_DECOMP_NONBASE_P (in the TREE_LIST for {static,tls}_aggregates) + MUST_NOT_THROW_CATCH_P (in MUST_NOT_THROW_EXPR) 3: IMPLICIT_RVALUE_P (in NON_LVALUE_EXPR or STATIC_CAST_EXPR) ICS_BAD_FLAG (in _CONV) FN_TRY_BLOCK_P (in TRY_BLOCK) @@ -506,6 +509,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; LAMBDA_EXPR_STATIC_P (in LAMBDA_EXPR) TARGET_EXPR_ELIDING_P (in TARGET_EXPR) contract_semantic (in ASSERTION_, PRECONDITION_, POSTCONDITION_STMT) + TYPENAME_IS_UNION_P (in TYPENAME_TYPE) 4: IDENTIFIER_MARKED (IDENTIFIER_NODEs) TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, CALL_EXPR, or FIELD_DECL). @@ -2354,6 +2358,10 @@ enum languages { lang_c, lang_cplusplus }; #define NON_UNION_CLASS_TYPE_P(T) \ (TREE_CODE (T) == RECORD_TYPE && TYPE_LANG_FLAG_5 (T)) +/* Nonzero if T is a class type and is a union. */ +#define UNION_TYPE_P(T) \ + (TREE_CODE (T) == UNION_TYPE && TYPE_LANG_FLAG_5 (T)) + /* Keep these checks in ascending code order. */ #define RECORD_OR_UNION_CODE_P(T) \ ((T) == RECORD_TYPE || (T) == UNION_TYPE) @@ -2492,6 +2500,11 @@ struct GTY(()) lang_type { bool erroneous : 1; bool non_pod_aggregate : 1; bool non_aggregate_pod : 1; + bool trivially_relocatable : 1; + bool trivially_relocatable_computed : 1; + + bool replaceable : 1; + bool replaceable_computed : 1; /* When adding a flag here, consider whether or not it ought to apply to a template instance if it applies to the template. If @@ -2500,7 +2513,7 @@ struct GTY(()) lang_type { /* There are some bits left to fill out a 32-bit word. Keep track of this by updating the size of this bitfield whenever you add or remove a flag. */ - unsigned dummy : 2; + unsigned dummy : 30; tree primary_base; vec<tree_pair_s, va_gc> *vcall_indices; @@ -2511,15 +2524,19 @@ struct GTY(()) lang_type { vec<tree, va_gc> *pure_virtuals; tree friend_classes; vec<tree, va_gc> * GTY((reorder ("resort_type_member_vec"))) members; + /* CLASSTYPE_KEY_METHOD for TYPE_POLYMORPHIC_P types, CLASSTYPE_LAMBDA_EXPR + otherwise. */ tree key_method; tree decl_list; tree befriending_classes; - /* In a RECORD_TYPE, information specific to Objective-C++, such - as a list of adopted protocols or a pointer to a corresponding - @interface. See objc/objc-act.h for details. */ - tree objc_info; - /* FIXME reuse another field? */ - tree lambda_expr; + union maybe_objc_info { + /* If not c_dialect_objc, this part is not even allocated. */ + char GTY((tag ("0"))) non_objc; + /* In a RECORD_TYPE, information specific to Objective-C, such + as a list of adopted protocols or a pointer to a corresponding + @interface. See objc/objc-act.h for details. */ + tree GTY((tag ("1"))) objc_info; + } GTY ((desc ("c_dialect_objc ()"))) info; }; /* We used to have a variant type for lang_type. Keep the name of the @@ -2634,7 +2651,13 @@ struct GTY(()) lang_type { /* The member function with which the vtable will be emitted: the first noninline non-pure-virtual member function. NULL_TREE if there is no key function or if this is a class template */ -#define CLASSTYPE_KEY_METHOD(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->key_method) +#define CLASSTYPE_KEY_METHOD(NODE) \ + (TYPE_POLYMORPHIC_P (NODE) \ + ? LANG_TYPE_CLASS_CHECK (NODE)->key_method \ + : NULL_TREE) +#define SET_CLASSTYPE_KEY_METHOD(NODE, VALUE) \ + (gcc_checking_assert (TYPE_POLYMORPHIC_P (NODE)), \ + LANG_TYPE_CLASS_CHECK (NODE)->key_method = (VALUE)) /* Vector of members. During definition, it is unordered and only member functions are present. After completion it is sorted and @@ -2766,7 +2789,12 @@ struct GTY(()) lang_type { /* The associated LAMBDA_EXPR that made this class. */ #define CLASSTYPE_LAMBDA_EXPR(NODE) \ - (LANG_TYPE_CLASS_CHECK (NODE)->lambda_expr) + (TYPE_POLYMORPHIC_P (NODE) \ + ? NULL_TREE \ + : LANG_TYPE_CLASS_CHECK (NODE)->key_method) +#define SET_CLASSTYPE_LAMBDA_EXPR(NODE, VALUE) \ + (gcc_checking_assert (!TYPE_POLYMORPHIC_P (NODE)), \ + LANG_TYPE_CLASS_CHECK (NODE)->key_method = (VALUE)) /* The extra mangling scope for this closure type. */ #define LAMBDA_TYPE_EXTRA_SCOPE(NODE) \ (LAMBDA_EXPR_EXTRA_SCOPE (CLASSTYPE_LAMBDA_EXPR (NODE))) @@ -2832,6 +2860,29 @@ struct GTY(()) lang_type { above (c++/120012). This could also be a hash_set. */ #define CLASSTYPE_NON_AGGREGATE_POD(NODE) \ (LANG_TYPE_CLASS_CHECK (NODE)->non_aggregate_pod) + +/* If CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED, true if this class is + trivially relocatable. + If !CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED, true if this class + is marked with trivially_relocatable_if_eligible conditional keyword. */ +#define CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->trivially_relocatable) + +/* True if whether this class is trivially relocatable or not + has been computed already. */ +#define CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->trivially_relocatable_computed) + +/* If CLASSTYPE_REPLACEABLE_COMPUTED, true if this class is replaceable. + If !CLASSTYPE_REPLACEABLE_COMPUTED, true if this class is marked with + replaceable_if_eligible conditional keyword. */ +#define CLASSTYPE_REPLACEABLE_BIT(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->replaceable) + +/* True if whether this class is replaceable or not has been computed + already. */ +#define CLASSTYPE_REPLACEABLE_COMPUTED(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->replaceable_computed) /* Additional macros for inheritance information. */ @@ -3007,6 +3058,8 @@ struct GTY(()) lang_decl_min { In a lambda-capture proxy VAR_DECL, this is DECL_CAPTURED_VARIABLE. In a function-scope TREE_STATIC VAR_DECL or IMPLICIT_TYPEDEF_P TYPE_DECL, this is DECL_DISCRIMINATOR. + In constexpr exception artificial VAR_DECL, this is + DECL_EXCEPTION_REFCOUNT. In a DECL_LOCAL_DECL_P decl, this is the namespace decl it aliases. Otherwise, in a class-scope DECL, this is DECL_ACCESS. */ tree access; @@ -4461,6 +4514,23 @@ get_vec_init_expr (tree t) #define MUST_NOT_THROW_COND(NODE) \ TREE_OPERAND (MUST_NOT_THROW_EXPR_CHECK (NODE), 1) +/* Reasons why MUST_NOT_THROW_EXPR has been created. */ + +/* Indicates MUST_NOT_THROW_EXPR has been created to wrap body of + a noexcept function. */ +#define MUST_NOT_THROW_NOEXCEPT_P(NODE) \ + TREE_LANG_FLAG_0 (MUST_NOT_THROW_EXPR_CHECK (NODE)) + +/* Indicates MUST_NOT_THROW_EXPR has been created to wrap construction of + exception object during throw. */ +#define MUST_NOT_THROW_THROW_P(NODE) \ + TREE_LANG_FLAG_1 (MUST_NOT_THROW_EXPR_CHECK (NODE)) + +/* Indicates MUST_NOT_THROW_EXPR has been created to wrap construction of + handler parameter during catch. */ +#define MUST_NOT_THROW_CATCH_P(NODE) \ + TREE_LANG_FLAG_2 (MUST_NOT_THROW_EXPR_CHECK (NODE)) + /* The TYPE_MAIN_DECL for a class template type is a TYPE_DECL, not a TEMPLATE_DECL. This macro determines whether or not a given class type is really a template type, as opposed to an instantiation or @@ -4481,11 +4551,14 @@ get_vec_init_expr (tree t) #define TYPENAME_IS_ENUM_P(NODE) \ (TREE_LANG_FLAG_0 (TYPENAME_TYPE_CHECK (NODE))) -/* True if a TYPENAME_TYPE was declared as a "class", "struct", or - "union". */ +/* True if a TYPENAME_TYPE was declared as a "class" or "struct". */ #define TYPENAME_IS_CLASS_P(NODE) \ (TREE_LANG_FLAG_1 (TYPENAME_TYPE_CHECK (NODE))) +/* True if a TYPENAME_TYPE was declared as a "union". */ +#define TYPENAME_IS_UNION_P(NODE) \ + (TREE_LANG_FLAG_3 (TYPENAME_TYPE_CHECK (NODE))) + /* True if a TYPENAME_TYPE is in the process of being resolved. */ #define TYPENAME_IS_RESOLVING_P(NODE) \ (TREE_LANG_FLAG_2 (TYPENAME_TYPE_CHECK (NODE))) @@ -4500,7 +4573,7 @@ get_vec_init_expr (tree t) #define TYPE_CONTAINS_VPTR_P(NODE) \ (TYPE_POLYMORPHIC_P (NODE) || CLASSTYPE_VBASECLASSES (NODE)) -/* Nonzero if NODE is a FUNCTION_DECL or VARIABLE_DECL (for a decl +/* Nonzero if NODE is a FUNCTION_DECL or VAR_DECL (for a decl with namespace scope) declared in a local scope. */ #define DECL_LOCAL_DECL_P(NODE) \ DECL_LANG_FLAG_0 (VAR_OR_FUNCTION_DECL_CHECK (NODE)) @@ -5141,6 +5214,10 @@ get_vec_init_expr (tree t) protected_access_node will appear in the DECL_ACCESS for the node. */ #define DECL_ACCESS(NODE) (LANG_DECL_MIN_CHECK (NODE)->access) +/* In artificial VAR_DECL created by cxa_allocate_exception + this is reference count. */ +#define DECL_EXCEPTION_REFCOUNT(NODE) (LANG_DECL_MIN_CHECK (NODE)->access) + /* Nonzero if the FUNCTION_DECL is a global constructor. */ #define DECL_GLOBAL_CTOR_P(NODE) \ (LANG_DECL_FN_CHECK (NODE)->global_ctor_p) @@ -6459,7 +6536,9 @@ enum virt_specifier { VIRT_SPEC_UNSPECIFIED = 0x0, VIRT_SPEC_FINAL = 0x1, - VIRT_SPEC_OVERRIDE = 0x2 + VIRT_SPEC_OVERRIDE = 0x2, + VIRT_SPEC_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE = 0x4, + VIRT_SPEC_REPLACEABLE_IF_ELIGIBLE = 0x8 }; /* A type-qualifier, or bitmask therefore, using the VIRT_SPEC @@ -6801,6 +6880,7 @@ enum cp_built_in_function { CP_BUILT_IN_IS_CORRESPONDING_MEMBER, CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS, CP_BUILT_IN_SOURCE_LOCATION, + CP_BUILT_IN_EH_PTR_ADJUST_REF, CP_BUILT_IN_LAST }; @@ -6981,6 +7061,7 @@ extern bool type_has_extended_temps (tree); extern tree strip_top_quals (tree); extern bool reference_related_p (tree, tree); extern bool reference_compatible_p (tree, tree); +extern bool handler_match_for_exception_type (tree, tree); extern int remaining_arguments (tree); extern tree build_implicit_conv_flags (tree, tree, int); extern tree perform_implicit_conversion (tree, tree, tsubst_flags_t); @@ -7100,6 +7181,7 @@ extern void adjust_clone_args (tree); extern void deduce_noexcept_on_destructor (tree); extern bool uniquely_derived_from_p (tree, tree); extern bool publicly_uniquely_derived_p (tree, tree); +extern bool publicly_virtually_derived_p (tree, tree); extern tree common_enclosing_class (tree, tree); /* in cvt.cc */ @@ -7150,7 +7232,7 @@ extern void determine_local_discriminator (tree, tree = NULL_TREE); extern bool member_like_constrained_friend_p (tree); extern bool fns_correspond (tree, tree); extern int decls_match (tree, tree, bool = true); -extern bool maybe_version_functions (tree, tree, bool); +extern bool maybe_version_functions (tree, tree); extern bool validate_constexpr_redeclaration (tree, tree); extern bool merge_default_template_args (tree, tree, bool); extern tree duplicate_decls (tree, tree, @@ -7553,6 +7635,8 @@ extern bool ctor_omit_inherited_parms (tree); extern tree locate_ctor (tree); extern tree implicitly_declare_fn (special_function_kind, tree, bool, tree, tree); +extern tree type_order_value (tree, tree); + /* In module.cc */ class module_state; /* Forward declare. */ inline bool modules_p () { return flag_modules != 0; } @@ -7809,6 +7893,7 @@ extern bool type_dependent_expression_p_push (tree); extern bool value_dependent_expression_p (tree); extern bool instantiation_dependent_uneval_expression_p (tree); extern bool any_value_dependent_elements_p (const_tree); +extern bool dependent_template_arg_p (tree); extern bool dependent_omp_for_p (tree, tree, tree, tree, tree); extern tree resolve_typename_type (tree, bool); extern tree template_for_substitution (tree); @@ -8227,6 +8312,8 @@ extern bool pod_type_p (const_tree); extern bool layout_pod_type_p (const_tree); extern bool std_layout_type_p (const_tree); extern bool trivial_type_p (const_tree); +extern bool trivially_relocatable_type_p (tree); +extern bool replaceable_type_p (tree); extern bool trivially_copyable_p (const_tree); extern bool type_has_unique_obj_representations (const_tree); extern bool scalarish_type_p (const_tree); @@ -8838,7 +8925,8 @@ extern hashval_t iterative_hash_constraint (tree, hashval_t); extern hashval_t hash_atomic_constraint (tree); extern void diagnose_constraints (location_t, tree, tree); -extern void note_failed_type_completion_for_satisfaction (tree); +extern void note_failed_type_completion (tree, tsubst_flags_t); +extern location_t failed_completion_location (tree); /* in logic.cc */ extern bool subsumes (tree, tree); @@ -8906,7 +8994,7 @@ extern tree fold_non_dependent_init (tree, bool = false, tree = NULL_TREE); extern tree fold_simple (tree); extern tree fold_to_constant (tree); -extern bool reduced_constant_expression_p (tree); +extern bool reduced_constant_expression_p (tree, tree = NULL_TREE); extern bool is_instantiation_of_constexpr (tree); extern bool var_in_constexpr_fn (tree); extern bool var_in_maybe_constexpr_fn (tree); diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc index f663a6d08c89..55be12db9513 100644 --- a/gcc/cp/cvt.cc +++ b/gcc/cp/cvt.cc @@ -1186,13 +1186,6 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) expr = maybe_undo_parenthesized_ref (expr); - expr = mark_discarded_use (expr); - if (implicit == ICV_CAST) - /* An explicit cast to void avoids all -Wunused-but-set* warnings. */ - mark_exp_read (expr); - - if (!TREE_TYPE (expr)) - return expr; if (invalid_nonstatic_memfn_p (loc, expr, complain)) return error_mark_node; if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR) @@ -1209,6 +1202,12 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) if (VOID_TYPE_P (TREE_TYPE (expr))) return expr; + + expr = mark_discarded_use (expr); + if (implicit == ICV_CAST) + /* An explicit cast to void avoids all -Wunused-but-set* warnings. */ + mark_exp_read (expr); + switch (TREE_CODE (expr)) { case COND_EXPR: diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 9a20ed62738f..0ac92f84b0e9 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -747,11 +747,11 @@ poplevel (int keep, int reverse, int functionbody) { if (!DECL_NAME (decl) && DECL_DECOMPOSITION_P (decl)) warning_at (DECL_SOURCE_LOCATION (decl), - OPT_Wunused_but_set_variable, "structured " + OPT_Wunused_but_set_variable_, "structured " "binding declaration set but not used"); else warning_at (DECL_SOURCE_LOCATION (decl), - OPT_Wunused_but_set_variable, + OPT_Wunused_but_set_variable_, "variable %qD set but not used", decl); unused_but_set_errorcount = errorcount; } @@ -1214,9 +1214,7 @@ decls_match (tree newdecl, tree olddecl, bool record_versions /* = true */) && targetm.target_option.function_versions (newdecl, olddecl)) { if (record_versions) - maybe_version_functions (newdecl, olddecl, - (!DECL_FUNCTION_VERSIONED (newdecl) - || !DECL_FUNCTION_VERSIONED (olddecl))); + maybe_version_functions (newdecl, olddecl); return 0; } } @@ -1283,11 +1281,11 @@ maybe_mark_function_versioned (tree decl) } /* NEWDECL and OLDDECL have identical signatures. If they are - different versions adjust them and return true. - If RECORD is set to true, record function versions. */ + different versions adjust them, record function versions, and return + true. */ bool -maybe_version_functions (tree newdecl, tree olddecl, bool record) +maybe_version_functions (tree newdecl, tree olddecl) { if (!targetm.target_option.function_versions (newdecl, olddecl)) return false; @@ -1310,8 +1308,13 @@ maybe_version_functions (tree newdecl, tree olddecl, bool record) maybe_mark_function_versioned (newdecl); } - if (record) - cgraph_node::record_function_versions (olddecl, newdecl); + /* Add the new version to the function version structure. */ + cgraph_node *fn_node = cgraph_node::get_create (olddecl); + cgraph_function_version_info *fn_v = fn_node->function_version (); + if (!fn_v) + fn_v = fn_node->insert_new_function_version (); + + cgraph_node::add_function_version (fn_v, newdecl); return true; } @@ -2006,8 +2009,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) } /* For function versions, params and types match, but they are not ambiguous. */ - else if ((!DECL_FUNCTION_VERSIONED (newdecl) - && !DECL_FUNCTION_VERSIONED (olddecl)) + else if (((!DECL_FUNCTION_VERSIONED (newdecl) + && !DECL_FUNCTION_VERSIONED (olddecl)) + || !same_type_p (fndecl_declared_return_type (newdecl), + fndecl_declared_return_type (olddecl))) /* Let constrained hidden friends coexist for now, we'll check satisfaction later. */ && !member_like_constrained_friend_p (newdecl) @@ -4360,6 +4365,7 @@ struct typename_info { tree template_id; bool enum_p; bool class_p; + bool union_p; }; struct typename_hasher : ggc_ptr_hash<tree_node> @@ -4398,7 +4404,8 @@ struct typename_hasher : ggc_ptr_hash<tree_node> && TYPE_CONTEXT (t1) == t2->scope && TYPENAME_TYPE_FULLNAME (t1) == t2->template_id && TYPENAME_IS_ENUM_P (t1) == t2->enum_p - && TYPENAME_IS_CLASS_P (t1) == t2->class_p); + && TYPENAME_IS_CLASS_P (t1) == t2->class_p + && TYPENAME_IS_UNION_P (t1) == t2->union_p); } }; @@ -4422,9 +4429,8 @@ build_typename_type (tree context, tree name, tree fullname, ti.name = name; ti.template_id = fullname; ti.enum_p = tag_type == enum_type; - ti.class_p = (tag_type == class_type - || tag_type == record_type - || tag_type == union_type); + ti.class_p = (tag_type == class_type || tag_type == record_type); + ti.union_p = tag_type == union_type; hashval_t hash = typename_hasher::hash (&ti); /* See if we already have this type. */ @@ -4440,6 +4446,7 @@ build_typename_type (tree context, tree name, tree fullname, TYPENAME_TYPE_FULLNAME (t) = ti.template_id; TYPENAME_IS_ENUM_P (t) = ti.enum_p; TYPENAME_IS_CLASS_P (t) = ti.class_p; + TYPENAME_IS_UNION_P (t) = ti.union_p; /* Build the corresponding TYPE_DECL. */ tree d = build_decl (input_location, TYPE_DECL, name, t); @@ -5070,6 +5077,18 @@ cxx_init_decl_processing (void) BUILT_IN_FRONTEND, NULL, NULL_TREE); set_call_expr_flags (decl, ECF_CONST | ECF_NOTHROW | ECF_LEAF); + if (cxx_dialect >= cxx26) + { + tree void_ptrintftype + = build_function_type_list (void_type_node, ptr_type_node, + integer_type_node, NULL_TREE); + decl = add_builtin_function ("__builtin_eh_ptr_adjust_ref", + void_ptrintftype, + CP_BUILT_IN_EH_PTR_ADJUST_REF, + BUILT_IN_FRONTEND, NULL, NULL_TREE); + set_call_expr_flags (decl, ECF_NOTHROW | ECF_LEAF); + } + integer_two_node = build_int_cst (NULL_TREE, 2); /* Guess at the initial static decls size. */ @@ -8915,10 +8934,12 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, cp_apply_type_quals_to_decl (cp_type_quals (type), decl); /* Update the type of the corresponding TEMPLATE_DECL to match. */ - if (DECL_LANG_SPECIFIC (decl) - && DECL_TEMPLATE_INFO (decl) - && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl)) == decl) - TREE_TYPE (DECL_TI_TEMPLATE (decl)) = type; + if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)) + { + tree tmpl = template_for_substitution (decl); + if (DECL_TEMPLATE_RESULT (tmpl) == decl) + TREE_TYPE (tmpl) = type; + } } if (ensure_literal_type_for_constexpr_object (decl) == error_mark_node) @@ -9162,6 +9183,10 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (decomp) { + if (DECL_DECLARED_CONSTINIT_P (decl) && cxx_dialect < cxx26) + pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wc__26_extensions, + "%<constinit%> can be applied to structured binding " + "only with %<-std=c++2c%> or %<-std=gnu++2c%>"); cp_maybe_mangle_decomp (decl, decomp); if (TREE_STATIC (decl) && !DECL_FUNCTION_SCOPE_P (decl)) { @@ -11318,11 +11343,16 @@ grokfndecl (tree ctype, "cannot declare %<::main%> to be %qs", "consteval"); if (!publicp) error_at (location, "cannot declare %<::main%> to be static"); - if (current_lang_depth () != 0) + if (current_lang_name != lang_name_cplusplus) pedwarn (location, OPT_Wpedantic, "cannot declare %<::main%> with a" - " linkage specification"); + " linkage specification other than %<extern \"C++\"%>"); if (module_attach_p ()) - error_at (location, "cannot attach %<::main%> to a named module"); + { + auto_diagnostic_group adg; + error_at (location, "cannot attach %<::main%> to a named module"); + inform (location, "use %<extern \"C++\"%> to attach it to the " + "global module instead"); + } inlinep = 0; publicp = 1; } @@ -13604,9 +13634,10 @@ grokdeclarator (const cp_declarator *declarator, if (typedef_p) error_at (declspecs->locations[ds_typedef], "structured binding declaration cannot be %qs", "typedef"); - if (constexpr_p && !concept_p) - error_at (declspecs->locations[ds_constexpr], "structured " - "binding declaration cannot be %qs", "constexpr"); + if (constexpr_p && !concept_p && cxx_dialect < cxx26) + pedwarn (declspecs->locations[ds_constexpr], OPT_Wc__26_extensions, + "structured binding declaration can be %qs only with " + "%<-std=c++2c%> or %<-std=gnu++2c%>", "constexpr"); if (consteval_p) error_at (declspecs->locations[ds_consteval], "structured " "binding declaration cannot be %qs", "consteval"); @@ -13617,8 +13648,11 @@ grokdeclarator (const cp_declarator *declarator, declspecs->gnu_thread_keyword_p ? "__thread" : "thread_local"); if (concept_p) - error_at (declspecs->locations[ds_concept], - "structured binding declaration cannot be %qs", "concept"); + { + error_at (declspecs->locations[ds_concept], + "structured binding declaration cannot be %qs", "concept"); + constexpr_p = 0; + } /* [dcl.struct.bind] "A cv that includes volatile is deprecated." */ if (type_quals & TYPE_QUAL_VOLATILE) warning_at (declspecs->locations[ds_volatile], OPT_Wvolatile, @@ -13673,7 +13707,6 @@ grokdeclarator (const cp_declarator *declarator, "%<auto%> type %qT", type); inlinep = 0; typedef_p = 0; - constexpr_p = 0; consteval_p = 0; concept_p = 0; if (storage_class != sc_static) @@ -17251,7 +17284,7 @@ xref_tag (enum tag_types tag_code, tree name, if (IDENTIFIER_LAMBDA_P (name)) /* Mark it as a lambda type right now. Our caller will correct the value. */ - CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node; + SET_CLASSTYPE_LAMBDA_EXPR (t, error_mark_node); t = pushtag (name, t, how); } else @@ -19328,6 +19361,19 @@ finish_function (bool inline_p) } } + if (FNDECL_USED_AUTO (fndecl) + && TREE_TYPE (fntype) != DECL_SAVED_AUTO_RETURN_TYPE (fndecl)) + if (location_t fcloc = failed_completion_location (fndecl)) + { + auto_diagnostic_group adg; + if (warning (OPT_Wsfinae_incomplete_, + "defining %qD, which previously failed to be deduced " + "in a SFINAE context", fndecl) + && warn_sfinae_incomplete == 1) + inform (fcloc, "here. Use %qs for a diagnostic at that point", + "-Wsfinae-incomplete=2"); + } + /* Remember that we were in class scope. */ if (current_class_name) ctype = current_class_type; @@ -19445,14 +19491,14 @@ finish_function (bool inline_p) && !DECL_READ_P (decl) && DECL_NAME (decl) && !DECL_ARTIFICIAL (decl) - && !warning_suppressed_p (decl,OPT_Wunused_but_set_parameter) + && !warning_suppressed_p (decl, OPT_Wunused_but_set_parameter_) && !DECL_IN_SYSTEM_HEADER (decl) && TREE_TYPE (decl) != error_mark_node && !TYPE_REF_P (TREE_TYPE (decl)) && (!CLASS_TYPE_P (TREE_TYPE (decl)) || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))) warning_at (DECL_SOURCE_LOCATION (decl), - OPT_Wunused_but_set_parameter, + OPT_Wunused_but_set_parameter_, "parameter %qD set but not used", decl); unused_but_set_errorcount = errorcount; } @@ -19981,7 +20027,7 @@ require_deduced_type (tree decl, tsubst_flags_t complain) /* We probably already complained about deduction failure. */; else if (complain & tf_error) error ("use of %qD before deduction of %<auto%>", decl); - note_failed_type_completion_for_satisfaction (decl); + note_failed_type_completion (decl, complain); return false; } return true; diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index e3fbc4093929..2bbc6180b0b9 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -6269,6 +6269,33 @@ mark_single_function (tree expr, tsubst_flags_t complain) return true; } +/* True iff we have started, but not finished, defining FUNCTION_DECL DECL. */ + +bool +fn_being_defined (tree decl) +{ + /* DECL_INITIAL is set to error_mark_node in grokfndecl for a definition, and + changed to BLOCK by poplevel at the end of the function. */ + return (TREE_CODE (decl) == FUNCTION_DECL + && DECL_INITIAL (decl) == error_mark_node); +} + +/* True if DECL is an instantiation of a function template currently being + defined. */ + +bool +fn_template_being_defined (tree decl) +{ + if (TREE_CODE (decl) != FUNCTION_DECL + || !DECL_LANG_SPECIFIC (decl) + || !DECL_TEMPLOID_INSTANTIATION (decl) + || DECL_TEMPLATE_INSTANTIATED (decl)) + return false; + tree tinfo = DECL_TEMPLATE_INFO (decl); + tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo)); + return fn_being_defined (pattern); +} + /* Mark DECL (either a _DECL or a BASELINK) as "used" in the program. If DECL is a specialization or implicitly declared class member, generate the actual definition. Return false if something goes @@ -6422,6 +6449,9 @@ mark_used (tree decl, tsubst_flags_t complain /* = tf_warning_or_error */) maybe_instantiate_decl (decl); if (!decl_dependent_p (decl) + /* Don't require this yet for an instantiation of a function template + we're currently defining (c++/120555). */ + && !fn_template_being_defined (decl) && !require_deduced_type (decl, complain)) return false; @@ -6436,9 +6466,6 @@ mark_used (tree decl, tsubst_flags_t complain /* = tf_warning_or_error */) && uses_template_parms (DECL_TI_ARGS (decl))) return true; - if (!require_deduced_type (decl, complain)) - return false; - if (builtin_pack_fn_p (decl)) { error ("use of built-in parameter pack %qD outside of a template", diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc index 69da381a355b..eb2ff33ac308 100644 --- a/gcc/cp/error.cc +++ b/gcc/cp/error.cc @@ -308,7 +308,7 @@ cxx_initialize_diagnostics (diagnostic_context *context) diagnostic_text_starter (context) = cp_diagnostic_text_starter; /* diagnostic_finalizer is already c_diagnostic_text_finalizer. */ context->set_format_decoder (cp_printer); - context->m_adjust_diagnostic_info = cp_adjust_diagnostic_info; + context->set_adjust_diagnostic_info_callback (cp_adjust_diagnostic_info); } /* Dump an '@module' name suffix for DECL, if it's attached to an import. */ @@ -810,6 +810,7 @@ dump_type (cxx_pretty_printer *pp, tree t, int flags) pp_cxx_ws_string (pp, TYPENAME_IS_ENUM_P (t) ? "enum" : TYPENAME_IS_CLASS_P (t) ? "class" + : TYPENAME_IS_UNION_P (t) ? "union" : "typename"); dump_typename (pp, t, flags); break; diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc index a9d8e2ffb57a..a7f35e4314d4 100644 --- a/gcc/cp/except.cc +++ b/gcc/cp/except.cc @@ -367,6 +367,8 @@ initialize_handler_parm (tree decl, tree exp) MUST_NOT_THROW_EXPR. */ init = fold_build_cleanup_point_expr (TREE_TYPE (init), init); init = build_must_not_throw_expr (init, NULL_TREE); + if (init && TREE_CODE (init) == MUST_NOT_THROW_EXPR) + MUST_NOT_THROW_CATCH_P (init) = 1; } decl = pushdecl (decl); @@ -523,6 +525,7 @@ begin_eh_spec_block (void) r = build_stmt (spec_location, MUST_NOT_THROW_EXPR, NULL_TREE, NULL_TREE); TREE_SIDE_EFFECTS (r) = 1; + MUST_NOT_THROW_NOEXCEPT_P (r) = 1; } else r = build_stmt (spec_location, EH_SPEC_BLOCK, NULL_TREE, NULL_TREE); @@ -614,6 +617,7 @@ wrap_cleanups_r (tree *tp, int *walk_subtrees, void * /*data*/) { cleanup = build2 (MUST_NOT_THROW_EXPR, void_type_node, cleanup, NULL_TREE); + MUST_NOT_THROW_THROW_P (cleanup) = 1; TARGET_EXPR_CLEANUP (exp) = cleanup; } @@ -712,6 +716,11 @@ build_throw (location_t loc, tree exp, tsubst_flags_t complain) allocate_expr = do_allocate_exception (temp_type); if (allocate_expr == error_mark_node) return error_mark_node; + /* Copy ptr inside of the CLEANUP_POINT_EXPR + added below to a TARGET_EXPR slot added outside of it, + otherwise during constant evaluation of throw expression + we'd diagnose accessing ptr outside of its lifetime. */ + tree ptr_copy = get_internal_target_expr (null_pointer_node); allocate_expr = get_internal_target_expr (allocate_expr); ptr = TARGET_EXPR_SLOT (allocate_expr); TARGET_EXPR_CLEANUP (allocate_expr) = do_free_exception (ptr); @@ -763,10 +772,17 @@ build_throw (location_t loc, tree exp, tsubst_flags_t complain) /* Prepend the allocation. */ exp = build2 (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp); + exp = build2 (COMPOUND_EXPR, void_type_node, exp, + build2 (MODIFY_EXPR, void_type_node, + TARGET_EXPR_SLOT (ptr_copy), ptr)); + ptr = TARGET_EXPR_SLOT (ptr_copy); + /* Force all the cleanups to be evaluated here so that we don't have to do them during unwinding. */ exp = build1 (CLEANUP_POINT_EXPR, void_type_node, exp); + exp = build2 (COMPOUND_EXPR, TREE_TYPE (exp), ptr_copy, exp); + throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object))); cleanup = NULL_TREE; diff --git a/gcc/cp/expr.cc b/gcc/cp/expr.cc index 2157cfba2ebb..32dc3eee78f9 100644 --- a/gcc/cp/expr.cc +++ b/gcc/cp/expr.cc @@ -102,6 +102,9 @@ mark_use (tree expr, bool rvalue_p, bool read_p, if (reject_builtin && reject_gcc_builtin (expr, loc)) return error_mark_node; + if (TREE_TYPE (expr) && VOID_TYPE_P (TREE_TYPE (expr))) + read_p = false; + if (read_p) mark_exp_read (expr); @@ -211,7 +214,7 @@ mark_use (tree expr, bool rvalue_p, bool read_p, } return expr; } - gcc_fallthrough(); + gcc_fallthrough (); CASE_CONVERT: recurse_op[0] = true; break; @@ -352,6 +355,9 @@ mark_exp_read (tree exp) if (exp == NULL) return; + if (TREE_TYPE (exp) && VOID_TYPE_P (TREE_TYPE (exp))) + return; + switch (TREE_CODE (exp)) { case VAR_DECL: @@ -361,16 +367,20 @@ mark_exp_read (tree exp) case PARM_DECL: DECL_READ_P (exp) = 1; break; + CASE_CONVERT: case ARRAY_REF: case COMPONENT_REF: case MODIFY_EXPR: case REALPART_EXPR: case IMAGPART_EXPR: - CASE_CONVERT: case ADDR_EXPR: case INDIRECT_REF: case FLOAT_EXPR: case VIEW_CONVERT_EXPR: + case PREINCREMENT_EXPR: + case PREDECREMENT_EXPR: + case POSTINCREMENT_EXPR: + case POSTDECREMENT_EXPR: mark_exp_read (TREE_OPERAND (exp, 0)); break; case COMPOUND_EXPR: diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index 80a37a14a806..0a389fb6ecde 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -3010,7 +3010,6 @@ build_new_constexpr_heap_type (tree elt_type, tree cookie_size, tree itype2) tree atype1 = build_cplus_array_type (sizetype, itype1); tree atype2 = build_cplus_array_type (elt_type, itype2); tree rtype = cxx_make_type (RECORD_TYPE); - TYPE_NAME (rtype) = heap_identifier; tree fld1 = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, atype1); tree fld2 = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, atype2); DECL_FIELD_CONTEXT (fld1) = rtype; @@ -3019,7 +3018,16 @@ build_new_constexpr_heap_type (tree elt_type, tree cookie_size, tree itype2) DECL_ARTIFICIAL (fld2) = true; TYPE_FIELDS (rtype) = fld1; DECL_CHAIN (fld1) = fld2; + TYPE_ARTIFICIAL (rtype) = true; layout_type (rtype); + + tree decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL, heap_identifier, rtype); + TYPE_NAME (rtype) = decl; + TYPE_STUB_DECL (rtype) = decl; + DECL_CONTEXT (decl) = NULL_TREE; + DECL_ARTIFICIAL (decl) = true; + layout_decl (decl, 0); + return rtype; } diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc index 2a9061acf550..525e8ef4b341 100644 --- a/gcc/cp/lambda.cc +++ b/gcc/cp/lambda.cc @@ -150,7 +150,7 @@ begin_lambda_type (tree lambda) /* Cross-reference the expression and the type. */ LAMBDA_EXPR_CLOSURE (lambda) = type; - CLASSTYPE_LAMBDA_EXPR (type) = lambda; + SET_CLASSTYPE_LAMBDA_EXPR (type, lambda); /* In C++17, assume the closure is literal; we'll clear the flag later if necessary. */ @@ -823,6 +823,14 @@ lambda_expr_this_capture (tree lambda, int add_capture_p) if (cp_unevaluated_operand) add_capture_p = false; + /* If we captured 'this' but don't have a capture proxy yet, look up the + captured 'this' again. */ + if (this_capture && TREE_CODE (this_capture) == FIELD_DECL) + { + gcc_assert (!add_capture_p); + this_capture = NULL_TREE; + } + /* Try to default capture 'this' if we can. */ if (!this_capture) { @@ -940,6 +948,9 @@ lambda_expr_this_capture (tree lambda, int add_capture_p) result = rvalue (result); } + gcc_checking_assert (!result || result == error_mark_node + || TYPE_PTR_P (TREE_TYPE (result))); + return result; } @@ -1939,7 +1950,7 @@ finish_lambda_function (tree body) { finish_function_body (body); - prune_lambda_captures (body); + prune_lambda_captures (cur_stmt_list); /* Finish the function and generate code for it if necessary. */ tree fn = finish_function (/*inline_p=*/true); diff --git a/gcc/cp/lex.cc b/gcc/cp/lex.cc index 12af81ed078c..08a634830f52 100644 --- a/gcc/cp/lex.cc +++ b/gcc/cp/lex.cc @@ -1082,15 +1082,17 @@ copy_lang_type (tree node) if (! TYPE_LANG_SPECIFIC (node)) return; - auto *lt = (struct lang_type *) ggc_internal_alloc (sizeof (struct lang_type)); + size_t sz = (c_dialect_objc () ? sizeof (struct lang_type) + : offsetof (struct lang_type, info)); + auto *lt = (struct lang_type *) ggc_internal_alloc (sz); - memcpy (lt, TYPE_LANG_SPECIFIC (node), (sizeof (struct lang_type))); + memcpy (lt, TYPE_LANG_SPECIFIC (node), sz); TYPE_LANG_SPECIFIC (node) = lt; if (GATHER_STATISTICS) { tree_node_counts[(int)lang_type] += 1; - tree_node_sizes[(int)lang_type] += sizeof (struct lang_type); + tree_node_sizes[(int)lang_type] += sz; } } @@ -1114,14 +1116,15 @@ maybe_add_lang_type_raw (tree t) if (!RECORD_OR_UNION_CODE_P (TREE_CODE (t))) return false; - auto *lt = (struct lang_type *) (ggc_internal_cleared_alloc - (sizeof (struct lang_type))); + size_t sz = (c_dialect_objc () ? sizeof (struct lang_type) + : offsetof (struct lang_type, info)); + auto *lt = (struct lang_type *) (ggc_internal_cleared_alloc (sz)); TYPE_LANG_SPECIFIC (t) = lt; if (GATHER_STATISTICS) { tree_node_counts[(int)lang_type] += 1; - tree_node_sizes[(int)lang_type] += sizeof (struct lang_type); + tree_node_sizes[(int)lang_type] += sz; } return true; @@ -1135,8 +1138,8 @@ cxx_make_type (enum tree_code code MEM_STAT_DECL) if (maybe_add_lang_type_raw (t)) { /* Set up some flags that give proper default behavior. */ - struct c_fileinfo *finfo = - get_fileinfo (LOCATION_FILE (input_location)); + struct c_fileinfo *finfo + = get_fileinfo (LOCATION_FILE (input_location)); SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown); CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only; } diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc index 67a80a387ba7..a4089c53c67b 100644 --- a/gcc/cp/method.cc +++ b/gcc/cp/method.cc @@ -3024,7 +3024,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, /* Vbase cdtors are not relevant. */; else { - if (constexpr_p) + if (constexpr_p && cxx_dialect < cxx26) *constexpr_p = false; FOR_EACH_VEC_ELT (*vbases, i, base_binfo) @@ -3951,5 +3951,26 @@ num_artificial_parms_for (const_tree fn) return count; } +/* Return value of the __builtin_type_order trait. */ + +tree +type_order_value (tree type1, tree type2) +{ + tree rettype = lookup_comparison_category (cc_strong_ordering); + if (rettype == error_mark_node) + return rettype; + int ret; + if (type1 == type2) + ret = 0; + else + { + const char *name1 = ASTRDUP (mangle_type_string (type1)); + const char *name2 = mangle_type_string (type2); + ret = strcmp (name1, name2); + } + return lookup_comparison_result (cc_strong_ordering, rettype, + ret == 0 ? 0 : ret > 0 ? 1 : 2); +} + #include "gt-cp-method.h" diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index ad2acaf559fb..e3c1a686b732 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -2811,12 +2811,13 @@ enum tree_tag { tt_decl, /* By-value mergeable decl. */ tt_tpl_parm, /* Template parm. */ - /* The ordering of the following 4 is relied upon in + /* The ordering of the following 5 is relied upon in trees_out::tree_node. */ tt_id, /* Identifier node. */ tt_conv_id, /* Conversion operator name. */ tt_anon_id, /* Anonymous name. */ tt_lambda_id, /* Lambda name. */ + tt_internal_id, /* Internal name. */ tt_typedef_type, /* A (possibly implicit) typedefed type. */ tt_derived_type, /* A type derived from another type. */ @@ -3096,6 +3097,9 @@ class trees_out : public bytes_out { unsigned section; bool writing_local_entities; /* Whether we might walk into a TU-local entity we need to emit placeholders for. */ + bool walking_bit_field_unit; /* Whether we're walking the underlying + storage for a bit field. There's no other + great way to detect this. */ #if CHECKING_P int importedness; /* Checker that imports not occurring inappropriately. +ve imports ok, @@ -3262,7 +3266,7 @@ trees_out::trees_out (allocator *mem, module_state *state, depset::hash &deps, unsigned section) :parent (mem), state (state), tree_map (500), dep_hash (&deps), ref_num (0), section (section), - writing_local_entities (false) + writing_local_entities (false), walking_bit_field_unit (false) { #if CHECKING_P importedness = 0; @@ -3879,6 +3883,10 @@ class GTY((chain_next ("%h.parent"), for_user)) module_state { void write_macro_maps (elf_out *to, range_t &, unsigned *crc_ptr); bool read_macro_maps (line_map_uint_t); + void write_diagnostic_classification (elf_out *, diagnostic_context *, + unsigned *); + bool read_diagnostic_classification (diagnostic_context *); + private: void write_define (bytes_out &, const cpp_macro *); cpp_macro *read_define (bytes_in &, cpp_reader *) const; @@ -6507,7 +6515,10 @@ trees_out::core_vals (tree t) case FIELD_DECL: WT (t->field_decl.offset); WT (t->field_decl.bit_field_type); - WT (t->field_decl.qualifier); /* bitfield unit. */ + { + auto ovr = make_temp_override (walking_bit_field_unit, true); + WT (t->field_decl.qualifier); /* bitfield unit. */ + } WT (t->field_decl.bit_offset); WT (t->field_decl.fcontext); WT (t->decl_common.initial); @@ -8208,6 +8219,10 @@ trees_out::decl_value (tree decl, depset *dep) inner = DECL_TEMPLATE_RESULT (decl); inner_tag = insert (inner, WK_value); + /* On stream-in we assume that a template and its result will + have the same type. */ + gcc_checking_assert (TREE_TYPE (decl) == TREE_TYPE (inner)); + if (streaming_p ()) { int code = TREE_CODE (inner); @@ -9362,6 +9377,7 @@ trees_out::type_node (tree type) tree root = (TYPE_NAME (type) ? TREE_TYPE (TYPE_NAME (type)) : TYPE_MAIN_VARIANT (type)); + gcc_checking_assert (root); if (type != root) { @@ -9440,6 +9456,8 @@ trees_out::type_node (tree type) || TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == ENUMERAL_TYPE) { + gcc_checking_assert (DECL_P (name)); + /* We can meet template parms that we didn't meet in the tpl_parms walk, because we're referring to a derived type that was previously constructed from equivalent template @@ -9601,6 +9619,8 @@ trees_out::type_node (tree type) tag_type = enum_type; else if (TYPENAME_IS_CLASS_P (type)) tag_type = class_type; + else if (TYPENAME_IS_UNION_P (type)) + tag_type = union_type; u (int (tag_type)); } } @@ -9654,11 +9674,14 @@ trees_out::tree_value (tree t) if (DECL_P (t)) /* No template, type, var or function, except anonymous - non-context vars. */ + non-context vars and types. */ gcc_checking_assert ((TREE_CODE (t) != TEMPLATE_DECL - && TREE_CODE (t) != TYPE_DECL + && (TREE_CODE (t) != TYPE_DECL + || (DECL_ARTIFICIAL (t) && !DECL_CONTEXT (t))) && (TREE_CODE (t) != VAR_DECL - || (!DECL_NAME (t) && !DECL_CONTEXT (t))) + || ((!DECL_NAME (t) + || IDENTIFIER_INTERNAL_P (DECL_NAME (t))) + && !DECL_CONTEXT (t))) && TREE_CODE (t) != FUNCTION_DECL)); if (streaming_p ()) @@ -9670,7 +9693,7 @@ trees_out::tree_value (tree t) tree_node_bools (t); } - if (TREE_CODE (t) == TREE_BINFO) + if (TREE_CODE (t) == TREE_BINFO) /* Binfos are decl-like and need merging information. */ binfo_mergeable (t); @@ -9679,8 +9702,57 @@ trees_out::tree_value (tree t) dump (dumper::TREE) && dump ("Writing tree:%d %C:%N", tag, TREE_CODE (t), t); + int type_tag = 0; + tree type = NULL_TREE; + if (TREE_CODE (t) == TYPE_DECL) + { + type = TREE_TYPE (t); + + /* We only support a limited set of features for uncontexted types; + these are typically types created in the language-independent + parts of the frontend (such as ubsan). */ + gcc_checking_assert (RECORD_OR_UNION_TYPE_P (type) + && TYPE_MAIN_VARIANT (type) == type + && TYPE_NAME (type) == t + && TYPE_STUB_DECL (type) == t + && !TYPE_VFIELD (type) + && !TYPE_BINFO (type) + && !CLASS_TYPE_P (type)); + + if (streaming_p ()) + { + start (type); + tree_node_bools (type); + } + + type_tag = insert (type, WK_value); + if (streaming_p ()) + dump (dumper::TREE) + && dump ("Writing type: %d %C:%N", type_tag, + TREE_CODE (type), type); + } + tree_node_vals (t); + if (type) + { + tree_node_vals (type); + tree_node (TYPE_SIZE (type)); + tree_node (TYPE_SIZE_UNIT (type)); + chained_decls (TYPE_FIELDS (type)); + if (streaming_p ()) + dump (dumper::TREE) + && dump ("Written type:%d %C:%N", type_tag, TREE_CODE (type), type); + } + + /* For uncontexted VAR_DECLs we need to stream the definition so that + importers can recreate their value. */ + if (TREE_CODE (t) == VAR_DECL) + { + gcc_checking_assert (!DECL_NONTRIVIALLY_INITIALIZED_P (t)); + tree_node (DECL_INITIAL (t)); + } + if (streaming_p ()) dump (dumper::TREE) && dump ("Written tree:%d %C:%N", tag, TREE_CODE (t), t); } @@ -9719,14 +9791,55 @@ trees_in::tree_value () dump (dumper::TREE) && dump ("Reading tree:%d %C", tag, TREE_CODE (t)); - if (!tree_node_vals (t)) + int type_tag = 0; + tree type = NULL_TREE; + if (TREE_CODE (t) == TYPE_DECL) + { + type = start (); + if (!type || !tree_node_bools (type)) + t = NULL_TREE; + + type_tag = insert (type); + if (t) + dump (dumper::TREE) + && dump ("Reading type:%d %C", type_tag, TREE_CODE (type)); + } + + if (!t) { +bail: back_refs[~tag] = NULL_TREE; + if (type_tag) + back_refs[~type_tag] = NULL_TREE; set_overrun (); - /* Bail. */ return NULL_TREE; } + if (!tree_node_vals (t)) + goto bail; + + if (type) + { + if (!tree_node_vals (type)) + goto bail; + + TYPE_SIZE (type) = tree_node (); + TYPE_SIZE_UNIT (type) = tree_node (); + TYPE_FIELDS (type) = chained_decls (); + if (get_overrun ()) + goto bail; + + dump (dumper::TREE) + && dump ("Read type:%d %C:%N", type_tag, TREE_CODE (type), type); + } + + if (TREE_CODE (t) == VAR_DECL) + { + DECL_INITIAL (t) = tree_node (); + if (TREE_STATIC (t)) + varpool_node::finalize_decl (t); + } + if (TREE_CODE (t) == LAMBDA_EXPR && CLASSTYPE_LAMBDA_EXPR (TREE_TYPE (t))) { @@ -9869,10 +9982,13 @@ trees_out::tree_node (tree t) if (TREE_CODE (t) == IDENTIFIER_NODE) { - /* An identifier node -> tt_id, tt_conv_id, tt_anon_id, tt_lambda_id. */ + /* An identifier node -> tt_id, tt_conv_id, tt_anon_id, tt_lambda_id, + tt_internal_id. */ int code = tt_id; if (IDENTIFIER_ANON_P (t)) code = IDENTIFIER_LAMBDA_P (t) ? tt_lambda_id : tt_anon_id; + else if (IDENTIFIER_INTERNAL_P (t)) + code = tt_internal_id; else if (IDENTIFIER_CONV_OP_P (t)) code = tt_conv_id; @@ -9887,13 +10003,15 @@ trees_out::tree_node (tree t) } else if (code == tt_id && streaming_p ()) str (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t)); + else if (code == tt_internal_id && streaming_p ()) + str (prefix_for_internal_label (t)); int tag = insert (t); if (streaming_p ()) { - /* We know the ordering of the 4 id tags. */ + /* We know the ordering of the 5 id tags. */ static const char *const kinds[] = - {"", "conv_op ", "anon ", "lambda "}; + {"", "conv_op ", "anon ", "lambda ", "internal "}; dump (dumper::TREE) && dump ("Written:%d %sidentifier:%N", tag, kinds[code - tt_id], @@ -9970,8 +10088,11 @@ trees_out::tree_node (tree t) break; case VAR_DECL: - /* AGGR_INIT_EXPRs cons up anonymous uncontexted VAR_DECLs. */ - gcc_checking_assert (!DECL_NAME (t) + /* AGGR_INIT_EXPRs cons up anonymous uncontexted VAR_DECLs, + and internal vars are created by sanitizers and + __builtin_source_location. */ + gcc_checking_assert ((!DECL_NAME (t) + || IDENTIFIER_INTERNAL_P (DECL_NAME (t))) && DECL_ARTIFICIAL (t)); break; @@ -9980,7 +10101,18 @@ trees_out::tree_node (tree t) PARM_DECLS. It'd be nice if they had a distinguishing flag to double check. */ break; + + case TYPE_DECL: + /* Some parts of the compiler need internal struct types; + these types may not have an appropriate context to use. + Walk the whole type (including its definition) by value. */ + gcc_checking_assert (DECL_ARTIFICIAL (t) + && TYPE_ARTIFICIAL (TREE_TYPE (t)) + && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)) + && !CLASS_TYPE_P (TREE_TYPE (t))); + break; } + mark_declaration (t, has_definition (t)); goto by_value; } } @@ -10117,6 +10249,17 @@ trees_in::tree_node (bool is_use) } break; + case tt_internal_id: + /* An internal label. */ + { + const char *prefix = str (); + res = generate_internal_label (prefix); + int tag = insert (res); + dump (dumper::TREE) + && dump ("Read internal identifier:%d %N", tag, res); + } + break; + case tt_typedef_type: res = tree_node (); if (res) @@ -10981,8 +11124,7 @@ trees_in::fn_parms_fini (int tag, tree fn, tree existing, bool is_defn) { tree existing_parm = existing ? DECL_ARGUMENTS (existing) : NULL_TREE; tree parms = DECL_ARGUMENTS (fn); - unsigned ix = 0; - for (tree parm = parms; parm; parm = DECL_CHAIN (parm), ix++) + for (tree parm = parms; parm; parm = DECL_CHAIN (parm)) { if (existing_parm) { @@ -11120,6 +11262,11 @@ trees_out::get_merge_kind (tree decl, depset *dep) return MK_local_friend; gcc_checking_assert (TYPE_P (ctx)); + + /* Internal-only types will not need to dedup their members. */ + if (!DECL_CONTEXT (TYPE_NAME (ctx))) + return MK_unique; + if (TREE_CODE (decl) == USING_DECL) return MK_field; @@ -11132,15 +11279,16 @@ trees_out::get_merge_kind (tree decl, depset *dep) return MK_named; } - if (!DECL_NAME (decl) - && !RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)) - && !DECL_BIT_FIELD_REPRESENTATIVE (decl)) + if (walking_bit_field_unit) { /* The underlying storage unit for a bitfield. We do not need to dedup it, because it's only reachable through the bitfields it represents. And those are deduped. */ // FIXME: Is that assertion correct -- do we ever fish it // out and put it in an expr? + gcc_checking_assert (!DECL_NAME (decl) + && !RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)) + && !DECL_BIT_FIELD_REPRESENTATIVE (decl)); gcc_checking_assert ((TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE ? TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) : TREE_CODE (TREE_TYPE (decl))) @@ -12189,7 +12337,8 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef) { dump (dumper::MERGE) && dump ("Propagating deduced return type to %N", existing); - FNDECL_USED_AUTO (e_inner) = true; + gcc_checking_assert (existing == e_inner); + FNDECL_USED_AUTO (existing) = true; DECL_SAVED_AUTO_RETURN_TYPE (existing) = TREE_TYPE (e_type); TREE_TYPE (existing) = change_return_type (TREE_TYPE (d_type), e_type); } @@ -13243,13 +13392,19 @@ trees_in::read_class_def (tree defn, tree maybe_template) if (TYPE_LANG_SPECIFIC (type)) { - CLASSTYPE_LAMBDA_EXPR (type) = lambda; + if (!TYPE_POLYMORPHIC_P (type)) + SET_CLASSTYPE_LAMBDA_EXPR (type, lambda); + else + gcc_checking_assert (lambda == NULL_TREE); CLASSTYPE_MEMBER_VEC (type) = member_vec; CLASSTYPE_PURE_VIRTUALS (type) = pure_virts; CLASSTYPE_VCALL_INDICES (type) = vcall_indices; - CLASSTYPE_KEY_METHOD (type) = key_method; + if (TYPE_POLYMORPHIC_P (type)) + SET_CLASSTYPE_KEY_METHOD (type, key_method); + else + gcc_checking_assert (key_method == NULL_TREE); CLASSTYPE_VBASECLASSES (type) = vbase_vec; @@ -18167,6 +18322,168 @@ module_state::write_ordinary_maps (elf_out *to, range_t &info, dump.outdent (); } +/* Return the prefix to use for dumping a #pragma diagnostic change to DK. */ + +static const char * +dk_string (diagnostic_t dk) +{ + gcc_assert (dk > DK_UNSPECIFIED && dk < DK_LAST_DIAGNOSTIC_KIND); + if (dk == DK_IGNORED) + /* diagnostic.def has an empty string for ignored. */ + return "ignored: "; + else + return get_diagnostic_kind_text (dk); +} + +/* Dump one #pragma GCC diagnostic entry. */ + +static bool +dump_dc_change (unsigned index, unsigned opt, diagnostic_t dk) +{ + if (dk == DK_POP) + return dump (" Index %u: pop from %d", index, opt); + else + return dump (" Index %u: %s%s", index, dk_string (dk), + cl_options[opt].opt_text); +} + +/* Write out any #pragma GCC diagnostic info to the .dgc section. */ + +void +module_state::write_diagnostic_classification (elf_out *to, + diagnostic_context *dc, + unsigned *crc_p) +{ + auto &changes = dc->get_classification_history (); + + bytes_out sec (to); + if (sec.streaming_p ()) + { + sec.begin (); + dump () && dump ("Writing diagnostic change locations"); + dump.indent (); + } + + unsigned len = changes.length (); + + /* We don't want to write out any entries that came from one of our imports. + But then we need to adjust the total, and change DK_POP targets to match + the index in our actual output. So remember how many lines we had skipped + at each step, where -1 means this line itself is skipped. */ + int skips = 0; + auto_vec<int> skips_at (len); + skips_at.safe_grow (len); + + for (unsigned i = 0; i < len; ++i) + { + const auto &c = changes[i]; + skips_at[i] = skips; + if (linemap_location_from_module_p (line_table, c.location)) + { + ++skips; + skips_at[i] = -1; + continue; + } + } + + if (sec.streaming_p ()) + { + sec.u (len - skips); + dump () && dump ("Diagnostic changes: %u", len - skips); + } + + for (unsigned i = 0; i < len; ++i) + { + if (skips_at[i] == -1) + continue; + + const auto &c = changes[i]; + write_location (sec, c.location); + if (sec.streaming_p ()) + { + unsigned opt = c.option; + if (c.kind == DK_POP) + opt -= skips_at[opt]; + sec.u (opt); + sec.u (c.kind); + dump () && dump_dc_change (i - skips_at[i], opt, c.kind); + } + } + + if (sec.streaming_p ()) + { + sec.end (to, to->name (MOD_SNAME_PFX ".dgc"), crc_p); + dump.outdent (); + } +} + +/* Read any #pragma GCC diagnostic info from the .dgc section. */ + +bool +module_state::read_diagnostic_classification (diagnostic_context *dc) +{ + bytes_in sec; + + if (!sec.begin (loc, from (), MOD_SNAME_PFX ".dgc")) + return false; + + dump () && dump ("Reading diagnostic change locations"); + dump.indent (); + + unsigned len = sec.u (); + dump () && dump ("Diagnostic changes: %u", len); + + auto &changes = dc->get_classification_history (); + int offset = changes.length (); + changes.reserve (len + 1); + for (unsigned i = 0; i < len; ++i) + { + location_t loc = read_location (sec); + int opt = sec.u (); + diagnostic_t kind = (diagnostic_t) sec.u (); + if (kind == DK_POP) + /* For a pop, opt is the 'changes' index to return to. */ + opt += offset; + changes.quick_push ({ loc, opt, kind }); + dump () && dump_dc_change (changes.length () - 1, opt, kind); + } + + /* Did the import pop all its diagnostic changes? */ + bool last_was_reset = (len == 0); + if (len) + for (int i = changes.length () - 1; ; --i) + { + gcc_checking_assert (i >= offset); + + const auto &c = changes[i]; + if (c.kind != DK_POP) + break; + else if (c.option == offset) + { + last_was_reset = true; + break; + } + else + /* As in update_effective_level_from_pragmas, the loop will decrement + i so we actually jump to c.option - 1. */ + i = c.option; + } + if (!last_was_reset) + { + /* It didn't, so add a pop at its last location to avoid affecting later + imports. */ + location_t last_loc = ordinary_locs.first + ordinary_locs.second - 1; + changes.quick_push ({ last_loc, offset, DK_POP }); + dump () && dump (" Adding final pop from index %d", offset); + } + + dump.outdent (); + if (!sec.end (from ())) + return false; + + return true; +} + void module_state::write_macro_maps (elf_out *to, range_t &info, unsigned *crc_p) { @@ -19853,6 +20170,8 @@ module_state::write_begin (elf_out *to, cpp_reader *reader, } ool->qsort (ool_cmp); + write_diagnostic_classification (nullptr, global_dc, nullptr); + vec<cpp_hashnode *> *macros = nullptr; if (is_header ()) macros = prepare_macros (reader); @@ -19998,7 +20317,10 @@ module_state::write_begin (elf_out *to, cpp_reader *reader, /* Write the line maps. */ if (config.ordinary_locs) - write_ordinary_maps (to, map_info, bool (config.num_partitions), &crc); + { + write_ordinary_maps (to, map_info, bool (config.num_partitions), &crc); + write_diagnostic_classification (to, global_dc, &crc); + } if (config.macro_locs) write_macro_maps (to, map_info, &crc); @@ -20071,6 +20393,10 @@ module_state::read_initial (cpp_reader *reader) else if (!read_ordinary_maps (config.ordinary_locs, config.loc_range_bits)) ok = false; + if (ok && have_locs && config.ordinary_locs + && !read_diagnostic_classification (global_dc)) + ok = false; + /* Allocate the REMAP vector. */ slurp->alloc_remap (config.num_imports); diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 86337635f48d..0d9ed2ea82b1 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -2519,7 +2519,7 @@ static cp_expr cp_parser_id_expression static cp_expr cp_parser_unqualified_id (cp_parser *, bool, bool, bool, bool); static tree cp_parser_nested_name_specifier_opt - (cp_parser *, bool, bool, bool, bool, bool = false); + (cp_parser *, bool, bool, bool, bool, bool = false, bool = false); static tree cp_parser_nested_name_specifier (cp_parser *, bool, bool, bool, bool); static tree cp_parser_qualifying_entity @@ -3091,8 +3091,8 @@ static cp_token *cp_parser_require_keyword (cp_parser *, enum rid, required_token); static bool cp_parser_token_starts_function_definition_p (cp_token *); -static bool cp_parser_next_token_starts_class_definition_p - (cp_parser *); +static bool cp_parser_nth_token_starts_class_definition_p + (cp_parser *, size_t); static bool cp_parser_next_token_ends_template_argument_p (cp_parser *); static bool cp_parser_nth_token_starts_template_argument_list_p @@ -6307,7 +6307,10 @@ cp_parser_primary_expression (cp_parser *parser, /* Recognize the `this' keyword. */ case RID_THIS: cp_lexer_consume_token (parser->lexer); - if (parser->local_variables_forbidden_p & THIS_FORBIDDEN) + if ((parser->local_variables_forbidden_p & THIS_FORBIDDEN) + /* It's OK to refer to 'this' in an unevaluated operand in a + lambda default argument (lambda-targ16.C). */ + && !cp_unevaluated_operand) { error_at (token->location, "%<this%> may not be used in this context"); @@ -7239,18 +7242,22 @@ check_template_keyword_in_nested_name_spec (tree name) nested-name-specifier template [opt] simple-template-id :: PARSER->SCOPE should be set appropriately before this function is - called. TYPENAME_KEYWORD_P is TRUE if the `typename' keyword is in - effect. TYPE_P is TRUE if we non-type bindings should be ignored - in name lookups. + called. TYPENAME_KEYWORD_P is true if the `typename' keyword is in + effect. TYPE_P is true if we non-type bindings should be ignored + in name lookups. TEMPLATE_KEYWORD_P is true if the `template' keyword + was seen. GLOBAL_P is true if `::' has already been parsed. + TODO: This function doesn't handle the C++14 change to make `::' + a nested-name-specifier by itself. If it did, GLOBAL_P could probably + go. Sets PARSER->SCOPE to the class (TYPE) or namespace (NAMESPACE_DECL) specified by the nested-name-specifier, or leaves it unchanged if there is no nested-name-specifier. Returns the new scope iff there is a nested-name-specifier, or NULL_TREE otherwise. - If CHECK_DEPENDENCY_P is FALSE, names are looked up in dependent scopes. + If CHECK_DEPENDENCY_P is false, names are looked up in dependent scopes. - If IS_DECLARATION is TRUE, the nested-name-specifier is known to be + If IS_DECLARATION is true, the nested-name-specifier is known to be part of a declaration and/or decl-specifier. */ static tree @@ -7259,7 +7266,8 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, bool check_dependency_p, bool type_p, bool is_declaration, - bool template_keyword_p /* = false */) + bool template_keyword_p /* = false */, + bool global_p /* = false */) { bool success = false; cp_token_position start = 0; @@ -7307,8 +7315,9 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, /* Spot cases that cannot be the beginning of a nested-name-specifier. On the second and subsequent times - through the loop, we look for the `template' keyword. */ - if (success && token->keyword == RID_TEMPLATE) + (or the first, if '::' has already been parsed) through the + loop, we look for the `template' keyword. */ + if ((success || global_p) && token->keyword == RID_TEMPLATE) ; /* A template-id can start a nested-name-specifier. */ else if (token->type == CPP_TEMPLATE_ID) @@ -7356,8 +7365,11 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, cp_parser_parse_tentatively (parser); /* Look for the optional `template' keyword, if this isn't the - first time through the loop. */ - if (success) + first time through the loop, or if we've already parsed '::'; + this is then the + nested-name-specifier template [opt] simple-template-id :: + production. */ + if (success || global_p) { template_keyword_p = cp_parser_optional_template_keyword (parser); /* DR1710: "In a qualified-id used as the name in @@ -10835,6 +10847,14 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, goto pop; } + /* If we skipped build_cplus_new in build_cxx_call because of decltype_p, + call it now that we know current.lhs is a subexpression. */ + if (decltype_p && !processing_template_decl + && TREE_CODE (current.lhs) == CALL_EXPR + && CLASS_TYPE_P (TREE_TYPE (current.lhs))) + current.lhs = build_cplus_new (TREE_TYPE (current.lhs), current.lhs, + tf_warning_or_error); + get_rhs: current.tree_type = binops_by_token[token->type].tree_type; current.loc = token->location; @@ -11818,6 +11838,7 @@ cp_parser_lambda_expression (cp_parser* parser) bool auto_is_implicit_function_template_parm_p = parser->auto_is_implicit_function_template_parm_p; bool saved_omp_array_section_p = parser->omp_array_section_p; + bool saved_in_targ = parser->in_template_argument_list_p; parser->num_template_parameter_lists = 0; parser->in_statement = 0; @@ -11827,6 +11848,7 @@ cp_parser_lambda_expression (cp_parser* parser) parser->implicit_template_scope = 0; parser->auto_is_implicit_function_template_parm_p = false; parser->omp_array_section_p = false; + parser->in_template_argument_list_p = false; /* Inside the lambda, outside unevaluated context do not apply. */ cp_evaluated ev; @@ -11881,6 +11903,7 @@ cp_parser_lambda_expression (cp_parser* parser) parser->auto_is_implicit_function_template_parm_p = auto_is_implicit_function_template_parm_p; parser->omp_array_section_p = saved_omp_array_section_p; + parser->in_template_argument_list_p = saved_in_targ; } /* This lambda shouldn't have any proxies left at this point. */ @@ -16859,7 +16882,11 @@ cp_parser_decomposition_declaration (cp_parser *parser, decl = error_mark_node; } else - prev = decl2; + { + prev = decl2; + DECL_DECLARED_CONSTEXPR_P (decl2) = DECL_DECLARED_CONSTEXPR_P (decl); + DECL_DECLARED_CONSTINIT_P (decl2) = DECL_DECLARED_CONSTINIT_P (decl); + } if (elt_pushed_scope) pop_scope (elt_pushed_scope); } @@ -16908,6 +16935,15 @@ cp_parser_decomposition_declaration (cp_parser *parser, /* Ensure DECL_VALUE_EXPR is created for all the decls but the underlying DECL. */ cp_finish_decomp (decl, &decomp); + if (decl_spec_seq_has_spec_p (decl_specifiers, ds_thread)) + pedwarn (decl_specifiers->locations[ds_thread], + 0, "for-range-declaration cannot be %qs", + decl_specifiers->gnu_thread_keyword_p + ? "__thread" : "thread_local"); + else if (decl_specifiers->storage_class == sc_static) + pedwarn (decl_specifiers->locations[ds_storage_class], + 0, "for-range-declaration cannot be %qs", + "static"); } if (pushed_scope) @@ -21001,9 +21037,6 @@ cp_parser_simple_type_specifier (cp_parser* parser, "only available with " "%<-std=c++14%> or %<-std=gnu++14%>"); } - else if (parser->in_template_argument_list_p) - error_at (token->location, - "use of %<auto%> in template argument"); else if (!flag_concepts) pedwarn (token->location, OPT_Wc__20_extensions, "use of %<auto%> in parameter declaration " @@ -21013,6 +21046,11 @@ cp_parser_simple_type_specifier (cp_parser* parser, "use of %<auto%> in parameter declaration " "only available with " "%<-std=c++14%> or %<-std=gnu++14%>"); + + if (parser->in_template_argument_list_p) + permerror_opt (token->location, + OPT_Wabbreviated_auto_in_template_arg, + "use of %<auto%> in template argument"); } else type = make_auto (); @@ -21141,7 +21179,9 @@ cp_parser_simple_type_specifier (cp_parser* parser, /*typename_keyword_p=*/false, /*check_dependency_p=*/true, /*type_p=*/false, - /*is_declaration=*/false) + /*is_declaration=*/false, + /*template_keyword_p=*/false, + global_p) != NULL_TREE); /* If we have seen a nested-name-specifier, and the next token is `template', then we are using the template-id production. */ @@ -21459,6 +21499,10 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, error_at (loc, "cannot declare a parameter with %<decltype(auto)%>"); return error_mark_node; } + if (parser->in_template_argument_list_p) + permerror_opt (placeholder->location, + OPT_Wabbreviated_auto_in_template_arg, + "use of %<auto%> in template argument"); tree parm = build_constrained_parameter (con, proto, args); return synthesize_implicit_template_parm (parser, parm); } @@ -21987,7 +22031,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, bool template_p = (template_parm_lists_apply - && (cp_parser_next_token_starts_class_definition_p (parser) + && (cp_parser_nth_token_starts_class_definition_p (parser, 1) || cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))); /* An unqualified name was used to reference this type, so there were no qualifying templates. */ @@ -24151,7 +24195,26 @@ cp_parser_init_declarator (cp_parser* parser, && token->type != CPP_SEMICOLON) { if (maybe_range_for_decl && *maybe_range_for_decl != error_mark_node) - range_for_decl_p = true; + { + range_for_decl_p = true; + if (decl_spec_seq_has_spec_p (decl_specifiers, ds_thread)) + pedwarn (decl_specifiers->locations[ds_thread], + 0, "for-range-declaration cannot be %qs", + decl_specifiers->gnu_thread_keyword_p + ? "__thread" : "thread_local"); + else if (decl_specifiers->storage_class == sc_static) + pedwarn (decl_specifiers->locations[ds_storage_class], + 0, "for-range-declaration cannot be %qs", + "static"); + else if (decl_specifiers->storage_class == sc_extern) + pedwarn (decl_specifiers->locations[ds_storage_class], + 0, "for-range-declaration cannot be %qs", + "extern"); + else if (decl_specifiers->storage_class == sc_register) + pedwarn (decl_specifiers->locations[ds_storage_class], + 0, "for-range-declaration cannot be %qs", + "register"); + } else { if (!maybe_range_for_decl) @@ -28005,6 +28068,98 @@ cp_parser_class_specifier (cp_parser* parser) return type; } +/* Parse an (optional) class-property-specifier-seq. + + class-property-specifier-seq: + class-property-specifier class-property-specifier-seq [opt] + + class-property-specifier: + final + trivially_relocatable_if_eligible (C++26) + replaceable_if_eligible (C++26) + + Returns a bitmask representing the class-property-specifiers. */ + +static cp_virt_specifiers +cp_parser_class_property_specifier_seq_opt (cp_parser *parser) +{ + cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED; + + while (true) + { + cp_token *token; + cp_virt_specifiers virt_specifier; + + /* Peek at the next token. */ + token = cp_lexer_peek_token (parser->lexer); + /* See if it's a class-property-specifier. */ + if (token->type != CPP_NAME) + break; + if (id_equal (token->u.value, "final")) + { + /* For C++98, quietly ignore final in e.g. + struct S final = 24; */ + if (cxx_dialect == cxx98 + && virt_specifiers == VIRT_SPEC_UNSPECIFIED + && !cp_parser_nth_token_starts_class_definition_p (parser, 2) + && !cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME)) + break; + maybe_warn_cpp0x (CPP0X_OVERRIDE_CONTROLS); + virt_specifier = VIRT_SPEC_FINAL; + } + else if (id_equal (token->u.value, "__final")) + virt_specifier = VIRT_SPEC_FINAL; + else if (id_equal (token->u.value, "trivially_relocatable_if_eligible")) + { + if (cxx_dialect < cxx26) + { + /* Warn about the C++26 conditional keyword (but don't parse + it). */ + warning_at (token->location, OPT_Wc__26_compat, + "identifier %qE is a conditional keyword in C++26", + token->u.value); + break; + } + virt_specifier = VIRT_SPEC_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE; + } + else if (id_equal (token->u.value, + "__trivially_relocatable_if_eligible")) + virt_specifier = VIRT_SPEC_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE; + else if (id_equal (token->u.value, "replaceable_if_eligible")) + { + if (cxx_dialect < cxx26) + { + /* Warn about the C++26 conditional keyword (but don't parse + it). */ + warning_at (token->location, OPT_Wc__26_compat, + "identifier %qE is a conditional keyword in C++26", + token->u.value); + break; + } + virt_specifier = VIRT_SPEC_REPLACEABLE_IF_ELIGIBLE; + } + else if (id_equal (token->u.value, + "__replaceable_if_eligible")) + virt_specifier = VIRT_SPEC_REPLACEABLE_IF_ELIGIBLE; + else + break; + + if (virt_specifiers & virt_specifier) + { + gcc_rich_location richloc (token->location); + richloc.add_fixit_remove (); + error_at (&richloc, "duplicate %qD specifier", token->u.value); + cp_lexer_purge_token (parser->lexer); + } + else + { + cp_lexer_consume_token (parser->lexer); + virt_specifiers |= virt_specifier; + } + } + return virt_specifiers; +} + /* Parse a class-head. class-head: @@ -28195,18 +28350,16 @@ cp_parser_class_head (cp_parser* parser, pop_deferring_access_checks (); if (id) - { - cp_parser_check_for_invalid_template_id (parser, id, - class_key, - type_start_token->location); - } - virt_specifiers = cp_parser_virt_specifier_seq_opt (parser); + cp_parser_check_for_invalid_template_id (parser, id, + class_key, + type_start_token->location); + virt_specifiers = cp_parser_class_property_specifier_seq_opt (parser); /* If it's not a `:' or a `{' then we can't really be looking at a class-head, since a class-head only appears as part of a class-specifier. We have to detect this situation before calling xref_tag, since that has irreversible side-effects. */ - if (!cp_parser_next_token_starts_class_definition_p (parser)) + if (!cp_parser_nth_token_starts_class_definition_p (parser, 1)) { cp_parser_error (parser, "expected %<{%> or %<:%>"); type = error_mark_node; @@ -28216,13 +28369,6 @@ cp_parser_class_head (cp_parser* parser, /* At this point, we're going ahead with the class-specifier, even if some other problem occurs. */ cp_parser_commit_to_tentative_parse (parser); - if (virt_specifiers & VIRT_SPEC_OVERRIDE) - { - cp_parser_error (parser, - "cannot specify %<override%> for a class"); - type = error_mark_node; - goto out; - } /* Issue the error about the overly-qualified name now. */ if (qualified_p) { @@ -28550,6 +28696,16 @@ cp_parser_class_head (cp_parser* parser, DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location; if (type && (virt_specifiers & VIRT_SPEC_FINAL)) CLASSTYPE_FINAL (type) = 1; + if (type && (virt_specifiers & VIRT_SPEC_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE)) + { + gcc_assert (!CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED (type)); + CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (type) = 1; + } + if (type && (virt_specifiers & VIRT_SPEC_REPLACEABLE_IF_ELIGIBLE)) + { + gcc_assert (!CLASSTYPE_REPLACEABLE_COMPUTED (type)); + CLASSTYPE_REPLACEABLE_BIT (type) = 1; + } out: parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p; return type; @@ -30421,6 +30577,9 @@ cp_parser_asm_operand_list (cp_parser* parser) parens.require_open (parser); /* Parse the expression. */ tree expression = cp_parser_expression (parser); + if (check_for_bare_parameter_packs (expression)) + expression = error_mark_node; + /* Look for the `)'. */ parens.require_close (parser); @@ -35588,15 +35747,15 @@ cp_parser_token_starts_function_definition_p (cp_token* token) || token->keyword == RID_RETURN); } -/* Returns TRUE iff the next token is the ":" or "{" beginning a class +/* Returns TRUE iff the Nth token is the ":" or "{" beginning a class definition. */ static bool -cp_parser_next_token_starts_class_definition_p (cp_parser *parser) +cp_parser_nth_token_starts_class_definition_p (cp_parser *parser, size_t n) { cp_token *token; - token = cp_lexer_peek_token (parser->lexer); + token = cp_lexer_peek_nth_token (parser->lexer, n); return (token->type == CPP_OPEN_BRACE || (token->type == CPP_COLON && !parser->colon_doesnt_start_class_def_p)); @@ -35876,7 +36035,9 @@ cp_parser_check_class_key (cp_parser *parser, location_t key_loc, return; bool seen_as_union = TREE_CODE (type) == UNION_TYPE; - if (seen_as_union != (class_key == union_type)) + if (class_key != typename_type + && TREE_CODE (type) != TYPENAME_TYPE + && seen_as_union != (class_key == union_type)) { auto_diagnostic_group d; if (permerror (input_location, "%qs tag used in naming %q#T", @@ -36650,7 +36811,7 @@ static void cp_parser_abort_tentative_parse (cp_parser* parser) { gcc_assert (parser->context->status != CP_PARSER_STATUS_KIND_COMMITTED - || errorcount > 0); + || seen_error ()); cp_parser_simulate_error (parser); /* Now, pretend that we want to see if the construct was successfully parsed. */ @@ -49701,7 +49862,8 @@ cp_parser_oacc_update (cp_parser *parser, cp_token *pragma_tok) */ #define OACC_WAIT_CLAUSE_MASK \ - ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)) + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)) static tree cp_parser_oacc_wait (cp_parser *parser, cp_token *pragma_tok) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index c5a3abe6d8b9..d63fa68058b9 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -202,7 +202,6 @@ static tree for_each_template_parm_r (tree *, int *, void *); static tree copy_default_args_to_explicit_spec_1 (tree, tree); static void copy_default_args_to_explicit_spec (tree); static bool invalid_nontype_parm_type_p (tree, tsubst_flags_t); -static bool dependent_template_arg_p (tree); static bool dependent_type_p_r (tree); static tree tsubst_stmt (tree, tree, tsubst_flags_t, tree); static tree tsubst_decl (tree, tree, tsubst_flags_t, bool = true); @@ -10052,15 +10051,20 @@ tsubst_entering_scope (tree t, tree args, tsubst_flags_t complain, tree in_decl) D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments. + If D1 is an identifier and CONTEXT is non-NULL, then the lookup is + carried out in CONTEXT. Currently, only namespaces are supported for + CONTEXT. + + If D1 is an identifier and CONTEXT is NULL, the lookup is performed + in the innermost non-namespace binding. + + Otherwise CONTEXT is ignored and no lookup is carried out. + IN_DECL, if non-NULL, is the template declaration we are trying to instantiate. Issue error and warning messages under control of COMPLAIN. - If the template class is really a local class in a template - function, then the FUNCTION_CONTEXT is the function in which it is - being instantiated. - ??? Note that this function is currently called *twice* for each template-id: the first time from the parser, while creating the incomplete type (finish_template_type), and the second type during the @@ -10079,20 +10083,23 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, spec_entry **slot; spec_entry *entry; - if (identifier_p (d1)) + if (identifier_p (d1) && context) + { + gcc_checking_assert (TREE_CODE (context) == NAMESPACE_DECL); + push_decl_namespace (context); + templ = lookup_name (d1, LOOK_where::NAMESPACE, LOOK_want::NORMAL); + pop_decl_namespace (); + } + else if (identifier_p (d1)) { tree value = innermost_non_namespace_value (d1); if (value && DECL_TEMPLATE_TEMPLATE_PARM_P (value)) templ = value; else - { - if (context) - push_decl_namespace (context); + { templ = lookup_name (d1); templ = maybe_get_template_decl_from_type_decl (templ); - if (context) - pop_decl_namespace (); - } + } } else if (TREE_CODE (d1) == TYPE_DECL && MAYBE_CLASS_TYPE_P (TREE_TYPE (d1))) { @@ -12692,7 +12699,17 @@ instantiate_class_template (tree type) determine_visibility (TYPE_MAIN_DECL (type)); } if (CLASS_TYPE_P (type)) - CLASSTYPE_FINAL (type) = CLASSTYPE_FINAL (pattern); + { + CLASSTYPE_FINAL (type) = CLASSTYPE_FINAL (pattern); + CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (type) + = CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (pattern); + CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED (type) + = CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED (pattern); + CLASSTYPE_REPLACEABLE_BIT (type) + = CLASSTYPE_REPLACEABLE_BIT (pattern); + CLASSTYPE_REPLACEABLE_COMPUTED (type) + = CLASSTYPE_REPLACEABLE_COMPUTED (pattern); + } pbinfo = TYPE_BINFO (pattern); @@ -14983,6 +15000,8 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, if (closure && DECL_IOBJ_MEMBER_FUNCTION_P (t)) parms = DECL_CHAIN (parms); parms = tsubst (parms, args, complain, t); + if (parms == error_mark_node) + return error_mark_node; for (tree parm = parms; parm; parm = DECL_CHAIN (parm)) DECL_CONTEXT (parm) = r; if (closure && DECL_IOBJ_MEMBER_FUNCTION_P (t)) @@ -15555,6 +15574,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain, /* We're dealing with a normal parameter. */ type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (type == error_mark_node && !(complain & tf_error)) + RETURN (error_mark_node); + type = type_decays_to (type); TREE_TYPE (r) = type; cp_apply_type_quals_to_decl (cp_type_quals (type), r); @@ -15592,8 +15614,13 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain, /* If cp_unevaluated_operand is set, we're just looking for a single dummy parameter, so don't keep going. */ if (DECL_CHAIN (t) && !cp_unevaluated_operand) - DECL_CHAIN (r) = tsubst (DECL_CHAIN (t), args, - complain, DECL_CHAIN (t)); + { + tree chain = tsubst (DECL_CHAIN (t), args, + complain, DECL_CHAIN (t)); + if (chain == error_mark_node) + RETURN (error_mark_node); + DECL_CHAIN (r) = chain; + } /* FIRST_R contains the start of the chain we've built. */ r = first_r; @@ -17233,13 +17260,14 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) return error_mark_node; } - /* FIXME: TYPENAME_IS_CLASS_P conflates 'class' vs 'struct' vs 'union' - tags. TYPENAME_TYPE should probably remember the exact tag that - was written. */ + /* FIXME: TYPENAME_IS_CLASS_P conflates 'class' vs 'struct' tags. + TYPENAME_TYPE should probably remember the exact tag that + was written for -Wmismatched-tags. */ enum tag_types tag_type - = TYPENAME_IS_CLASS_P (t) ? class_type - : TYPENAME_IS_ENUM_P (t) ? enum_type - : typename_type; + = (TYPENAME_IS_CLASS_P (t) ? class_type + : TYPENAME_IS_UNION_P (t) ? union_type + : TYPENAME_IS_ENUM_P (t) ? enum_type + : typename_type); tsubst_flags_t tcomplain = complain | tf_keep_type_decl; tcomplain |= tst_ok_flag | qualifying_scope_flag; f = make_typename_type (ctx, f, tag_type, tcomplain); @@ -17261,10 +17289,18 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) else return error_mark_node; } - else if (TYPENAME_IS_CLASS_P (t) && !CLASS_TYPE_P (f)) + else if (TYPENAME_IS_CLASS_P (t) && !NON_UNION_CLASS_TYPE_P (f)) + { + if (complain & tf_error) + error ("%qT resolves to %qT, which is not a non-union " + "class type", t, f); + else + return error_mark_node; + } + else if (TYPENAME_IS_UNION_P (t) && !UNION_TYPE_P (f)) { if (complain & tf_error) - error ("%qT resolves to %qT, which is not a class type", + error ("%qT resolves to %qT, which is not a union type", t, f); else return error_mark_node; @@ -17950,9 +17986,7 @@ tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain, return decl; /* Handle OpenMP iterators. */ - if (TREE_CODE (decl) == TREE_LIST - && TREE_PURPOSE (decl) - && TREE_CODE (TREE_PURPOSE (decl)) == TREE_VEC) + if (OMP_ITERATOR_DECL_P (decl)) { tree ret; if (iterator_cache[0] == TREE_PURPOSE (decl)) @@ -20121,7 +20155,14 @@ tsubst_stmt (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree op0 = RECUR (TREE_OPERAND (t, 0)); tree cond = RECUR (MUST_NOT_THROW_COND (t)); - RETURN (build_must_not_throw_expr (op0, cond)); + stmt = build_must_not_throw_expr (op0, cond); + if (stmt && TREE_CODE (stmt) == MUST_NOT_THROW_EXPR) + { + MUST_NOT_THROW_NOEXCEPT_P (stmt) = MUST_NOT_THROW_NOEXCEPT_P (t); + MUST_NOT_THROW_THROW_P (stmt) = MUST_NOT_THROW_THROW_P (t); + MUST_NOT_THROW_CATCH_P (stmt) = MUST_NOT_THROW_CATCH_P (t); + } + RETURN (stmt); } case EXPR_PACK_EXPANSION: @@ -24587,7 +24628,8 @@ resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain) } if (good == 1) { - mark_used (goodfn); + if (!mark_used (goodfn, complain) && !(complain & tf_error)) + return error_mark_node; expr = goodfn; if (baselink) expr = build_baselink (BASELINK_BINFO (baselink), @@ -27519,6 +27561,10 @@ tree template_for_substitution (tree decl) { tree tmpl = DECL_TI_TEMPLATE (decl); + if (VAR_P (decl)) + if (tree partial = most_specialized_partial_spec (decl, tf_none)) + if (partial != error_mark_node) + tmpl = TI_TEMPLATE (partial); /* Set TMPL to the template whose DECL_TEMPLATE_RESULT is the pattern for the instantiation. This is not always the most general diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 7bc346b0f294..ee77d31f0976 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -2338,7 +2338,8 @@ finish_asm_stmt (location_t loc, int volatile_p, tree string, oconstraints[i] = constraint; if (parse_output_constraint (&constraint, i, ninputs, noutputs, - &allows_mem, &allows_reg, &is_inout)) + &allows_mem, &allows_reg, &is_inout, + nullptr)) { /* If the operand is going to end up in memory, mark it addressable. */ @@ -2397,7 +2398,8 @@ finish_asm_stmt (location_t loc, int volatile_p, tree string, constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))); bool constraint_parsed = parse_input_constraint (&constraint, i, ninputs, noutputs, 0, - oconstraints, &allows_mem, &allows_reg); + oconstraints, &allows_mem, &allows_reg, + nullptr); /* If the operand is going to end up in memory, don't call decay_conversion. */ if (constraint_parsed && !allows_reg && allows_mem) @@ -3605,11 +3607,13 @@ finish_this_expr (void) { tree result = NULL_TREE; - if (current_class_type && LAMBDA_TYPE_P (current_class_type)) + if (current_class_ref && !LAMBDA_TYPE_P (TREE_TYPE (current_class_ref))) + result = current_class_ptr; + else if (current_class_type && LAMBDA_TYPE_P (current_class_type)) result = (lambda_expr_this_capture (CLASSTYPE_LAMBDA_EXPR (current_class_type), /*add*/true)); - else if (current_class_ptr) - result = current_class_ptr; + else + gcc_checking_assert (!current_class_ptr); if (result) /* The keyword 'this' is a prvalue expression. */ @@ -3739,6 +3743,11 @@ finish_unary_op_expr (location_t op_loc, enum tree_code code, cp_expr expr, if (!(complain & tf_warning)) return result; + /* These will never fold into a constant, so no need to check for + overflow for them. */ + if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR) + return result; + tree result_ovl = result; tree expr_ovl = expr; @@ -6295,9 +6304,7 @@ handle_omp_array_sections (tree &c, enum c_omp_region_type ort) tree *tp = &OMP_CLAUSE_DECL (c); if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY) - && TREE_CODE (*tp) == TREE_LIST - && TREE_PURPOSE (*tp) - && TREE_CODE (TREE_PURPOSE (*tp)) == TREE_VEC) + && OMP_ITERATOR_DECL_P (*tp)) tp = &TREE_VALUE (*tp); tree first = handle_omp_array_sections_1 (c, *tp, types, maybe_zero_len, first_non_one, @@ -8817,9 +8824,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) /* FALLTHRU */ case OMP_CLAUSE_AFFINITY: t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) == TREE_LIST - && TREE_PURPOSE (t) - && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) + if (OMP_ITERATOR_DECL_P (t)) { if (TREE_PURPOSE (t) != last_iterators) last_iterators_remove @@ -13359,6 +13364,18 @@ object_type_p (const_tree type) && !VOID_TYPE_P (type)); } +/* [defns.referenceable] True iff TYPE is a referenceable type. */ + +static bool +referenceable_type_p (const_tree type) +{ + return (TYPE_REF_P (type) + || object_type_p (type) + || (FUNC_OR_METHOD_TYPE_P (type) + && type_memfn_quals (type) == TYPE_UNQUALIFIED + && type_memfn_rqual (type) == REF_QUAL_NONE)); +} + /* Actually evaluates the trait. */ static bool @@ -13528,6 +13545,21 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_NOTHROW_INVOCABLE: return expr_noexcept_p (build_invoke (type1, type2, tf_none), tf_none); + case CPTK_IS_NOTHROW_RELOCATABLE: + if (trivially_relocatable_type_p (type1)) + return true; + else + { + type1 = strip_array_types (type1); + if (!referenceable_type_p (type1)) + return false; + tree arg = make_tree_vec (1); + TREE_VEC_ELT (arg, 0) + = cp_build_reference_type (type1, /*rval=*/true); + return (is_nothrow_xible (INIT_EXPR, type1, arg) + && is_nothrow_xible (BIT_NOT_EXPR, type1, NULL_TREE)); + } + case CPTK_IS_OBJECT: return object_type_p (type1); @@ -13546,6 +13578,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_REFERENCE: return type_code1 == REFERENCE_TYPE; + case CPTK_IS_REPLACEABLE: + return replaceable_type_p (type1); + case CPTK_IS_SAME: return same_type_p (type1, type2); @@ -13570,6 +13605,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_TRIVIALLY_DESTRUCTIBLE: return is_trivially_xible (BIT_NOT_EXPR, type1, NULL_TREE); + case CPTK_IS_TRIVIALLY_RELOCATABLE: + return trivially_relocatable_type_p (type1); + case CPTK_IS_UNBOUNDED_ARRAY: return array_of_unknown_bound_p (type1); @@ -13593,8 +13631,10 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_DEDUCIBLE: return type_targs_deducible_from (type1, type2); - /* __array_rank is handled in finish_trait_expr. */ + /* __array_rank and __builtin_type_order are handled in + finish_trait_expr. */ case CPTK_RANK: + case CPTK_TYPE_ORDER: gcc_unreachable (); #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \ @@ -13698,18 +13738,6 @@ same_type_ref_bind_p (cp_trait_kind kind, tree type1, tree type2) (non_reference (to), non_reference (from)))); } -/* [defns.referenceable] True iff TYPE is a referenceable type. */ - -static bool -referenceable_type_p (const_tree type) -{ - return (TYPE_REF_P (type) - || object_type_p (type) - || (FUNC_OR_METHOD_TYPE_P (type) - && (type_memfn_quals (type) == TYPE_UNQUALIFIED - && type_memfn_rqual (type) == REF_QUAL_NONE))); -} - /* Process a trait expression. */ tree @@ -13724,6 +13752,12 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) tree trait_expr = make_node (TRAIT_EXPR); if (kind == CPTK_RANK) TREE_TYPE (trait_expr) = size_type_node; + else if (kind == CPTK_TYPE_ORDER) + { + tree val = type_order_value (type1, type1); + if (val != error_mark_node) + TREE_TYPE (trait_expr) = TREE_TYPE (val); + } else TREE_TYPE (trait_expr) = boolean_type_node; TRAIT_EXPR_TYPE1 (trait_expr) = type1; @@ -13752,8 +13786,11 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_LITERAL_TYPE: case CPTK_IS_POD: case CPTK_IS_STD_LAYOUT: + case CPTK_IS_REPLACEABLE: + case CPTK_IS_NOTHROW_RELOCATABLE: case CPTK_IS_TRIVIAL: case CPTK_IS_TRIVIALLY_COPYABLE: + case CPTK_IS_TRIVIALLY_RELOCATABLE: case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: if (!check_trait_type (type1, /* kind = */ 2)) return error_mark_node; @@ -13831,6 +13868,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_UNION: case CPTK_IS_VOLATILE: case CPTK_RANK: + case CPTK_TYPE_ORDER: break; case CPTK_IS_LAYOUT_COMPATIBLE: @@ -13870,6 +13908,8 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) ++rank; val = build_int_cst (size_type_node, rank); } + else if (kind == CPTK_TYPE_ORDER) + val = type_order_value (type1, type2); else val = (trait_expr_value (kind, type1, type2) ? boolean_true_node : boolean_false_node); diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index 5863b6878f02..a7b890884abd 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -488,6 +488,7 @@ builtin_valid_in_constant_expr_p (const_tree decl) case CP_BUILT_IN_SOURCE_LOCATION: case CP_BUILT_IN_IS_CORRESPONDING_MEMBER: case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS: + case CP_BUILT_IN_EH_PTR_ADJUST_REF: return true; default: break; @@ -4715,6 +4716,293 @@ trivial_type_p (const_tree t) return scalarish_type_p (t); } +/* Returns 1 iff type T is a default-movable type, as defined in + [class.prop]. */ + +static bool +default_movable_type_p (tree t) +{ + if (!CLASS_TYPE_P (t) || !COMPLETE_TYPE_P (t)) + return false; + if (CLASSTYPE_LAZY_DESTRUCTOR (t)) + lazily_declare_fn (sfk_destructor, t); + if (tree dtor = CLASSTYPE_DESTRUCTOR (t)) + if (user_provided_p (dtor) || DECL_DELETED_FN (dtor)) + return false; + + tree copy_ctor = NULL_TREE, move_ctor = NULL_TREE; + tree copy_assign = NULL_TREE, move_assign = NULL_TREE; + if (CLASSTYPE_LAZY_MOVE_CTOR (t)) + move_ctor = lazily_declare_fn (sfk_move_constructor, t); + if (CLASSTYPE_LAZY_MOVE_ASSIGN (t)) + move_assign = lazily_declare_fn (sfk_move_assignment, t); + if (!move_ctor) + for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter) + if (TREE_CODE (*iter) == FUNCTION_DECL) + { + if (copy_fn_p (*iter)) + copy_ctor = *iter; + else if (move_fn_p (*iter)) + { + move_ctor = *iter; + break; + } + } + if (!move_assign) + for (ovl_iterator iter (get_class_binding_direct (t, + assign_op_identifier)); + iter; ++iter) + if (TREE_CODE (*iter) == FUNCTION_DECL) + { + if (copy_fn_p (*iter)) + copy_assign = *iter; + else if (move_fn_p (*iter)) + { + move_assign = *iter; + break; + } + } + if (!move_ctor) + { + if (CLASSTYPE_LAZY_COPY_CTOR (t)) + copy_ctor = lazily_declare_fn (sfk_copy_constructor, t); + if (!copy_ctor) + return false; + if (user_provided_p (copy_ctor) + || DECL_DELETED_FN (copy_ctor) + || DECL_CONTEXT (copy_ctor) != t + || DECL_INHERITED_CTOR (copy_ctor)) + return false; + } + else if (user_provided_p (move_ctor) + || DECL_DELETED_FN (move_ctor) + || DECL_CONTEXT (move_ctor) != t + || DECL_INHERITED_CTOR (move_ctor)) + return false; + if (!move_assign) + { + if (CLASSTYPE_LAZY_COPY_ASSIGN (t)) + copy_assign = lazily_declare_fn (sfk_copy_assignment, t); + if (!copy_assign) + return false; + if (user_provided_p (copy_assign) + || DECL_DELETED_FN (copy_assign) + || DECL_CONTEXT (copy_assign) != t) + return false; + } + else if (user_provided_p (move_assign) + || DECL_DELETED_FN (move_assign) + || DECL_CONTEXT (move_assign) != t) + return false; + return true; +} + +/* Returns 1 iff type T is a union with no user declared special member + functions. */ + +static bool +union_with_no_declared_special_member_fns (tree t) +{ + if (TREE_CODE (t) != UNION_TYPE) + return false; + + for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter) + if (TREE_CODE (*iter) == FUNCTION_DECL + && !DECL_ARTIFICIAL (*iter) + && (default_ctor_p (*iter) || copy_fn_p (*iter) || move_fn_p (*iter))) + return false; + + for (ovl_iterator iter (get_class_binding_direct (t, assign_op_identifier)); + iter; ++iter) + if (TREE_CODE (*iter) == FUNCTION_DECL + && !DECL_ARTIFICIAL (*iter) + && (copy_fn_p (*iter) || move_fn_p (*iter))) + return false; + + if (tree dtor = CLASSTYPE_DESTRUCTOR (t)) + if (!DECL_ARTIFICIAL (dtor)) + return false; + + return true; +} + +/* Returns 1 iff type T is a trivially relocatable type, as defined in + [basic.types.general] and [class.prop]. */ + +bool +trivially_relocatable_type_p (tree t) +{ + t = strip_array_types (t); + + if (!CLASS_TYPE_P (t)) + return scalarish_type_p (t); + + t = TYPE_MAIN_VARIANT (t); + if (CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED (t)) + return CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (t); + if (!COMPLETE_TYPE_P (t)) + return false; + + if (!CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (t) + && !union_with_no_declared_special_member_fns (t) + && !default_movable_type_p (t)) + { + nontriv: + CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (t) = 0; + CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED (t) = 1; + return false; + } + + if (CLASSTYPE_VBASECLASSES (t)) + goto nontriv; + + if (CLASSTYPE_LAZY_DESTRUCTOR (t)) + lazily_declare_fn (sfk_destructor, t); + if (tree dtor = CLASSTYPE_DESTRUCTOR (t)) + if (DECL_DELETED_FN (dtor)) + goto nontriv; + + tree binfo, base_binfo; + unsigned int i; + for (binfo = TYPE_BINFO (t), i = 0; + BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) + { + tree basetype = TREE_TYPE (base_binfo); + if (!trivially_relocatable_type_p (basetype)) + goto nontriv; + } + + for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) + if (TREE_CODE (field) == FIELD_DECL + && !DECL_ARTIFICIAL (field) + && !DECL_UNNAMED_BIT_FIELD (field)) + { + tree type = TREE_TYPE (field); + if (type == error_mark_node) + goto nontriv; + if (!TYPE_REF_P (type) && !trivially_relocatable_type_p (type)) + goto nontriv; + } + + CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (t) = 1; + CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED (t) = 1; + return true; +} + +/* Returns 1 iff type T is a replaceable type, as defined in [basic.types] + and [class]. */ + +bool +replaceable_type_p (tree t) +{ + t = strip_array_types (t); + + if (cv_qualified_p (t)) + return false; + + if (!CLASS_TYPE_P (t)) + return scalarish_type_p (t); + + t = TYPE_MAIN_VARIANT (t); + if (CLASSTYPE_REPLACEABLE_COMPUTED (t)) + return CLASSTYPE_REPLACEABLE_BIT (t); + if (!COMPLETE_TYPE_P (t)) + return false; + + if (!CLASSTYPE_REPLACEABLE_BIT (t) + && !union_with_no_declared_special_member_fns (t) + && !default_movable_type_p (t)) + { + nonrepl: + CLASSTYPE_REPLACEABLE_BIT (t) = 0; + CLASSTYPE_REPLACEABLE_COMPUTED (t) = 1; + return false; + } + + if (CLASSTYPE_LAZY_DESTRUCTOR (t)) + lazily_declare_fn (sfk_destructor, t); + if (tree dtor = CLASSTYPE_DESTRUCTOR (t)) + if (DECL_DELETED_FN (dtor)) + goto nonrepl; + + tree copy_ctor = NULL_TREE, move_ctor = NULL_TREE; + tree copy_assign = NULL_TREE, move_assign = NULL_TREE; + if (CLASSTYPE_LAZY_MOVE_CTOR (t)) + move_ctor = lazily_declare_fn (sfk_move_constructor, t); + if (CLASSTYPE_LAZY_MOVE_ASSIGN (t)) + move_assign = lazily_declare_fn (sfk_move_assignment, t); + if (!move_ctor) + for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter) + if (TREE_CODE (*iter) == FUNCTION_DECL) + { + if (copy_fn_p (*iter)) + copy_ctor = *iter; + else if (move_fn_p (*iter)) + { + move_ctor = *iter; + break; + } + } + if (!move_assign) + for (ovl_iterator iter (get_class_binding_direct (t, + assign_op_identifier)); + iter; ++iter) + if (TREE_CODE (*iter) == FUNCTION_DECL) + { + if (copy_fn_p (*iter)) + copy_assign = *iter; + else if (move_fn_p (*iter)) + { + move_assign = *iter; + break; + } + } + if (!move_ctor) + { + if (CLASSTYPE_LAZY_COPY_CTOR (t)) + copy_ctor = lazily_declare_fn (sfk_copy_constructor, t); + if (!copy_ctor || DECL_DELETED_FN (copy_ctor)) + goto nonrepl; + } + else if (DECL_DELETED_FN (move_ctor)) + goto nonrepl; + if (!move_assign) + { + if (CLASSTYPE_LAZY_COPY_ASSIGN (t)) + copy_assign = lazily_declare_fn (sfk_copy_assignment, t); + if (!copy_assign || DECL_DELETED_FN (copy_assign)) + goto nonrepl; + } + else if (DECL_DELETED_FN (move_assign)) + goto nonrepl; + + tree binfo, base_binfo; + unsigned int i; + for (binfo = TYPE_BINFO (t), i = 0; + BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) + { + tree basetype = TREE_TYPE (base_binfo); + if (!replaceable_type_p (basetype)) + goto nonrepl; + } + + for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) + if (TREE_CODE (field) == FIELD_DECL + && !DECL_ARTIFICIAL (field) + && !DECL_UNNAMED_BIT_FIELD (field)) + { + tree type = TREE_TYPE (field); + if (type == error_mark_node) + goto nonrepl; + if (!replaceable_type_p (type)) + goto nonrepl; + } + + CLASSTYPE_REPLACEABLE_BIT (t) = 1; + CLASSTYPE_REPLACEABLE_COMPUTED (t) = 1; + return true; +} + /* Returns 1 iff type T is a POD type, as defined in [basic.types]. */ bool diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index ac1eb397f011..a604511db710 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -156,7 +156,7 @@ complete_type_or_maybe_complain (tree type, tree value, tsubst_flags_t complain) { if (complain & tf_error) cxx_incomplete_type_diagnostic (value, type, DK_ERROR); - note_failed_type_completion_for_satisfaction (type); + note_failed_type_completion (type, complain); return NULL_TREE; } else @@ -2084,7 +2084,14 @@ cxx_sizeof_or_alignof_type (location_t loc, tree type, enum tree_code op, bool dependent_p = dependent_type_p (type); if (!dependent_p) - complete_type (type); + { + complete_type (type); + if (!COMPLETE_TYPE_P (type)) + /* Call this here because the incompleteness diagnostic comes from + c_sizeof_or_alignof_type instead of + complete_type_or_maybe_complain. */ + note_failed_type_completion (type, complain); + } if (dependent_p /* VLA types will have a non-constant size. In the body of an uninstantiated template, we don't need to try to compute the @@ -2106,7 +2113,7 @@ cxx_sizeof_or_alignof_type (location_t loc, tree type, enum tree_code op, return c_sizeof_or_alignof_type (loc, complete_type (type), op == SIZEOF_EXPR, std_alignof, - complain); + complain & (tf_warning_or_error)); } /* Return the size of the type, without producing any warnings for @@ -3994,13 +4001,61 @@ cp_build_array_ref (location_t loc, tree array, tree idx, } case COND_EXPR: - ret = build_conditional_expr - (loc, TREE_OPERAND (array, 0), - cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx, - complain), - cp_build_array_ref (loc, TREE_OPERAND (array, 2), idx, - complain), - complain); + tree op0, op1, op2; + op0 = TREE_OPERAND (array, 0); + op1 = TREE_OPERAND (array, 1); + op2 = TREE_OPERAND (array, 2); + if (TREE_SIDE_EFFECTS (idx) || !tree_invariant_p (idx)) + { + /* If idx could possibly have some SAVE_EXPRs, turning + (op0 ? op1 : op2)[idx] into + op0 ? op1[idx] : op2[idx] can lead into temporaries + initialized in one conditional path and uninitialized + uses of them in the other path. + And if idx is a really large expression, evaluating it + twice is also not optimal. + On the other side, op0 must be sequenced before evaluation + of op1 and op2 and for C++17 op0, op1 and op2 must be + sequenced before idx. + If idx is INTEGER_CST, we can just do the optimization + without any SAVE_EXPRs, if op1 and op2 are both ARRAY_TYPE + VAR_DECLs or COMPONENT_REFs thereof (so their address + is constant or relative to frame), optimize into + (SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0>) + ? op1[SAVE_EXPR <idx>] : op2[SAVE_EXPR <idx>] + Otherwise avoid this optimization. */ + if (flag_strong_eval_order == 2) + { + if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE) + { + if (!address_invariant_p (op1) || !address_invariant_p (op2)) + { + /* Force default conversion on array if + we can't optimize this and array is ARRAY_TYPE + COND_EXPR, we can't leave COND_EXPRs with + ARRAY_TYPE in the IL. */ + array = cp_default_conversion (array, complain); + if (error_operand_p (array)) + return error_mark_node; + break; + } + } + else if (!POINTER_TYPE_P (TREE_TYPE (array)) + || !tree_invariant_p (op1) + || !tree_invariant_p (op2)) + break; + } + if (TREE_SIDE_EFFECTS (idx)) + { + idx = save_expr (idx); + op0 = save_expr (op0); + tree tem = build_compound_expr (loc, op0, idx); + op0 = build_compound_expr (loc, tem, op0); + } + } + op1 = cp_build_array_ref (loc, op1, idx, complain); + op2 = cp_build_array_ref (loc, op2, idx, complain); + ret = build_conditional_expr (loc, op0, op1, op2, complain); protected_set_expr_location (ret, loc); return ret; @@ -7625,7 +7680,18 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert, if (val != 0) goto return_build_unary_op; - arg = mark_lvalue_use (arg); + tree stripped_arg; + stripped_arg = tree_strip_any_location_wrapper (arg); + if ((VAR_P (stripped_arg) || TREE_CODE (stripped_arg) == PARM_DECL) + && !DECL_READ_P (stripped_arg) + && (VAR_P (stripped_arg) ? warn_unused_but_set_variable + : warn_unused_but_set_parameter) > 1) + { + arg = mark_lvalue_use (arg); + DECL_READ_P (stripped_arg) = 0; + } + else + arg = mark_lvalue_use (arg); /* Increment or decrement the real part of the value, and don't change the imaginary part. */ @@ -9741,7 +9807,22 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, { auto_diagnostic_group d; rhs = stabilize_expr (rhs, &init); + bool clear_decl_read = false; + tree stripped_lhs = tree_strip_any_location_wrapper (lhs); + if ((VAR_P (stripped_lhs) || TREE_CODE (stripped_lhs) == PARM_DECL) + && !DECL_READ_P (stripped_lhs) + && (VAR_P (stripped_lhs) ? warn_unused_but_set_variable + : warn_unused_but_set_parameter) > 2 + && !CLASS_TYPE_P (TREE_TYPE (lhs)) + && !CLASS_TYPE_P (TREE_TYPE (rhs))) + { + mark_exp_read (rhs); + if (!DECL_READ_P (stripped_lhs)) + clear_decl_read = true; + } newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain); + if (clear_decl_read) + DECL_READ_P (stripped_lhs) = 0; if (newrhs == error_mark_node) { if (complain & tf_error) diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index b6815d37bc30..6153b350a983 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,8 @@ +2025-07-21 Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org> + + * toir.cc: Pass null pointer to + parse_{input,output}_constraint(). + 2025-04-29 Iain Buclaw <ibuclaw@gdcproject.org> PR d/103044 diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc index b70db7a0e507..554399b2b0c2 100644 --- a/gcc/d/toir.cc +++ b/gcc/d/toir.cc @@ -1450,7 +1450,8 @@ class IRVisitor : public Visitor oconstraints[i] = constraint; if (parse_output_constraint (&constraint, i, ninputs, noutputs, - &allows_mem, &allows_reg, &is_inout)) + &allows_mem, &allows_reg, &is_inout, + nullptr)) { /* If the output argument is going to end up in memory. */ if (!allows_reg) @@ -1469,7 +1470,8 @@ class IRVisitor : public Visitor = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))); if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0, - oconstraints, &allows_mem, &allows_reg)) + oconstraints, &allows_mem, &allows_reg, + nullptr)) { /* If the input argument is going to end up in memory. */ if (!allows_reg && allows_mem) diff --git a/gcc/dfp.cc b/gcc/dfp.cc index 5c2bf1ae0686..74e964214b5c 100644 --- a/gcc/dfp.cc +++ b/gcc/dfp.cc @@ -619,11 +619,21 @@ decimal_real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision) decNumber dn, dn2, dn3; REAL_VALUE_TYPE to; char string[256]; + int scale = 0; decContextDefault (&set, DEC_INIT_DECIMAL128); set.traps = 0; set.round = DEC_ROUND_DOWN; decimal128ToNumber ((const decimal128 *) r->sig, &dn); + if (precision > 64 && decNumberIsFinite (&dn) && dn.exponent > 0) + { + /* libdecNumber doesn't really handle too large integers. + So when precision is large and exponent as well, trim the + exponent and adjust the resulting wide_int by multiplying + it multiple times with powers of ten. */ + scale = dn.exponent; + dn.exponent = 0; + } decNumberToIntegralValue (&dn2, &dn, &set); decNumberZero (&dn3); @@ -633,7 +643,74 @@ decimal_real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision) function. */ decNumberToString (&dn, string); real_from_string (&to, string); - return real_to_integer (&to, fail, precision); + bool failp = false; + wide_int w = real_to_integer (&to, &failp, precision); + if (failp) + *fail = true; + if (scale && !failp) + { + bool isneg = wi::neg_p (w); + if (isneg) + w = -w; + enum wi::overflow_type ovf = wi::OVF_NONE; + unsigned HOST_WIDE_INT pow10s[] = { + HOST_WIDE_INT_UC (10), + HOST_WIDE_INT_UC (100), + HOST_WIDE_INT_UC (1000), + HOST_WIDE_INT_UC (10000), + HOST_WIDE_INT_UC (100000), + HOST_WIDE_INT_UC (1000000), + HOST_WIDE_INT_UC (10000000), + HOST_WIDE_INT_UC (100000000), + HOST_WIDE_INT_UC (1000000000), + HOST_WIDE_INT_UC (10000000000), + HOST_WIDE_INT_UC (100000000000), + HOST_WIDE_INT_UC (1000000000000), + HOST_WIDE_INT_UC (10000000000000), + HOST_WIDE_INT_UC (100000000000000), + HOST_WIDE_INT_UC (1000000000000000), + HOST_WIDE_INT_UC (10000000000000000), + HOST_WIDE_INT_UC (100000000000000000), + HOST_WIDE_INT_UC (1000000000000000000), + HOST_WIDE_INT_UC (10000000000000000000), + }; + int s = scale % 19; + if (s) + { + wide_int wm = wi::uhwi (pow10s[s - 1], w.get_precision ()); + w = wi::umul (w, wm, &ovf); + if (ovf) + scale = 0; + } + scale /= 19; + wide_int wm = wi::uhwi (pow10s[18], w.get_precision ()); + while (scale) + { + if (scale & 1) + { + w = wi::umul (w, wm, &ovf); + if (ovf) + break; + } + scale >>= 1; + if (!scale) + break; + wm = wi::umul (wm, wm, &ovf); + if (ovf) + break; + } + if (ovf) + { + *fail = true; + if (isneg) + return wi::set_bit_in_zero (precision - 1, precision); + else + return ~wi::set_bit_in_zero (precision - 1, precision); + } + if (isneg) + w = -w; + } + return w; } /* Perform the decimal floating point operation described by CODE. diff --git a/gcc/diagnostic-color.cc b/gcc/diagnostic-color.cc index b3bd6f997c6f..e95aaeb869cf 100644 --- a/gcc/diagnostic-color.cc +++ b/gcc/diagnostic-color.cc @@ -234,7 +234,7 @@ diagnostic_color_dict::parse_envvar_value (const char *const envvar_value) size_t name_len = 0, val_len = 0; name = q = envvar_value; - val = NULL; + val = nullptr; /* From now on, be well-formed or you're gone. */ for (;;) if (*q == ':' || *q == '\0') @@ -259,7 +259,7 @@ diagnostic_color_dict::parse_envvar_value (const char *const envvar_value) if (*q == '\0') return true; name = ++q; - val = NULL; + val = nullptr; } else if (*q == '=') { @@ -269,7 +269,7 @@ diagnostic_color_dict::parse_envvar_value (const char *const envvar_value) name_len = q - name; val = ++q; /* Can be the empty string. */ } - else if (val == NULL) + else if (val == nullptr) q++; /* Accumulate name. */ else if (*q == ';' || (*q >= '0' && *q <= '9')) q++; /* Accumulate val. Protect the terminal from being sent @@ -308,7 +308,7 @@ should_colorize (void) handle = GetStdHandle (STD_ERROR_HANDLE); - if ((handle != INVALID_HANDLE_VALUE) && (handle != NULL)) + if ((handle != INVALID_HANDLE_VALUE) && (handle != nullptr)) isconsole = GetConsoleMode (handle, &mode); #ifdef ENABLE_VIRTUAL_TERMINAL_PROCESSING @@ -362,10 +362,10 @@ parse_env_vars_for_urls () const char *p; p = getenv ("GCC_URLS"); /* Plural! */ - if (p == NULL) + if (p == nullptr) p = getenv ("TERM_URLS"); - if (p == NULL) + if (p == nullptr) return URL_FORMAT_DEFAULT; if (*p == '\0') @@ -400,7 +400,7 @@ auto_enable_urls () DWORD mode; handle = GetStdHandle (STD_ERROR_HANDLE); - if ((handle == INVALID_HANDLE_VALUE) || (handle == NULL)) + if ((handle == INVALID_HANDLE_VALUE) || (handle == nullptr)) return false; /* If ansi escape sequences aren't supported by the console, then URLs will diff --git a/gcc/diagnostic-digraphs.cc b/gcc/diagnostic-digraphs.cc new file mode 100644 index 000000000000..85c0c5166c0a --- /dev/null +++ b/gcc/diagnostic-digraphs.cc @@ -0,0 +1,484 @@ +/* Directed graphs associated with a diagnostic. + Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by David Malcolm <dmalcolm@redhat.com>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#define INCLUDE_ALGORITHM +#define INCLUDE_MAP +#define INCLUDE_SET +#define INCLUDE_STRING +#define INCLUDE_VECTOR +#include "config.h" +#include "system.h" +#include "coretypes.h" + +#include "graphviz.h" +#include "diagnostic-digraphs.h" +#include "diagnostic-format-sarif.h" + +#include "selftest.h" + +using digraph = diagnostics::digraphs::digraph; +using digraph_node = diagnostics::digraphs::node; +using digraph_edge = diagnostics::digraphs::edge; + +namespace { + +class conversion_to_dot +{ +public: + std::unique_ptr<dot::graph> + make_dot_graph_from_diagnostic_graph (const digraph &); + + std::unique_ptr<dot::stmt> + make_dot_node_from_digraph_node (const digraph_node &); + + std::unique_ptr<dot::edge_stmt> + make_dot_edge_from_digraph_edge (const digraph_edge &); + + dot::id + get_dot_id_for_node (const digraph_node &); + + bool + has_edges_p (const digraph_node &); + +private: + std::set<const digraph_node *> m_nodes_with_edges; + std::map<const digraph_node *, dot::stmt *> m_node_map; +}; + +} // anonymous namespace + +// class conversion_to_dot + +std::unique_ptr<dot::graph> +conversion_to_dot:: +make_dot_graph_from_diagnostic_graph (const diagnostics::digraphs::digraph &input_graph) +{ + auto output_graph = std::make_unique<dot::graph> (); + + if (const char *description = input_graph.get_description ()) + output_graph->m_stmt_list.add_attr (dot::id ("label"), + dot::id (description)); + + const int num_nodes = input_graph.get_num_nodes (); + const int num_edges = input_graph.get_num_edges (); + + /* Determine which nodes have in-edges and out-edges. */ + for (int i = 0; i < num_edges; ++i) + { + const digraph_edge &input_edge = input_graph.get_edge (i); + m_nodes_with_edges.insert (&input_edge.get_src_node ()); + m_nodes_with_edges.insert (&input_edge.get_dst_node ()); + } + + for (int i = 0; i < num_nodes; ++i) + { + const digraph_node &input_node = input_graph.get_node (i); + auto dot_node_stmt = make_dot_node_from_digraph_node (input_node); + output_graph->m_stmt_list.add_stmt (std::move (dot_node_stmt)); + } + + for (int i = 0; i < num_edges; ++i) + { + const digraph_edge &input_edge = input_graph.get_edge (i); + auto dot_edge_stmt = make_dot_edge_from_digraph_edge (input_edge); + output_graph->m_stmt_list.add_stmt (std::move (dot_edge_stmt)); + } + + return output_graph; +} + +std::unique_ptr<dot::stmt> +conversion_to_dot:: +make_dot_node_from_digraph_node (const diagnostics::digraphs::node &input_node) +{ + dot::id dot_id (get_dot_id_for_node (input_node)); + + /* For now, we can only do either edges or children, not both + ...but see https://graphviz.org/docs/attrs/compound/ */ + + if (has_edges_p (input_node)) + { + auto output_node + = std::make_unique<dot::node_stmt> (std::move (dot_id)); + m_node_map[&input_node] = output_node.get (); + if (const char *label = input_node.get_label ()) + output_node->set_label (dot::id (label)); + return output_node; + } + else + { + auto output_node = std::make_unique<dot::subgraph> (std::move (dot_id)); + m_node_map[&input_node] = output_node.get (); + if (const char *label = input_node.get_label ()) + output_node->add_attr (dot::id ("label"), dot::id (label)); + const int num_children = input_node.get_num_children (); + for (int i = 0; i < num_children; ++i) + { + const digraph_node &input_child = input_node.get_child (i); + auto dot_child_stmt = make_dot_node_from_digraph_node (input_child); + output_node->m_stmt_list.add_stmt (std::move (dot_child_stmt)); + } + return output_node; + } +} + +std::unique_ptr<dot::edge_stmt> +conversion_to_dot:: +make_dot_edge_from_digraph_edge (const digraph_edge &input_edge) +{ + const digraph_node &src_dnode = input_edge.get_src_node (); + const digraph_node &dst_dnode = input_edge.get_dst_node (); + auto output_edge + = std::make_unique<dot::edge_stmt> + (get_dot_id_for_node (src_dnode), + get_dot_id_for_node (dst_dnode)); + if (const char *label = input_edge.get_label ()) + output_edge->set_label (dot::id (label)); + return output_edge; +} + +dot::id +conversion_to_dot::get_dot_id_for_node (const digraph_node &input_node) +{ + if (has_edges_p (input_node)) + return input_node.get_id (); + else + return std::string ("cluster_") + input_node.get_id (); +} + +bool +conversion_to_dot::has_edges_p (const digraph_node &input_node) +{ + return m_nodes_with_edges.find (&input_node) != m_nodes_with_edges.end (); +} + +// class object + +const char * +diagnostics::digraphs::object:: +get_attr (const char *key_prefix, const char *key) const +{ + if (!m_property_bag) + return nullptr; + std::string prefixed_key = std::string (key_prefix) + key; + if (json::value *jv = m_property_bag->get (prefixed_key.c_str ())) + if (json::string *jstr = jv->dyn_cast_string ()) + return jstr->get_string (); + return nullptr; +} + +void +diagnostics::digraphs::object:: +set_attr (const char *key_prefix, const char *key, const char *value) +{ + set_json_attr (key_prefix, key, std::make_unique<json::string> (value)); +} + +void +diagnostics::digraphs::object:: +set_json_attr (const char *key_prefix, const char *key, std::unique_ptr<json::value> value) +{ + std::string prefixed_key = std::string (key_prefix) + key; + if (!m_property_bag) + m_property_bag = std::make_unique<json::object> (); + m_property_bag->set (prefixed_key.c_str (), std::move (value)); +} + +// class digraph + +DEBUG_FUNCTION void +diagnostics::digraphs::digraph::dump () const +{ + make_json_sarif_graph ()->dump (); +} + +std::unique_ptr<json::object> +diagnostics::digraphs::digraph::make_json_sarif_graph () const +{ + return make_sarif_graph (*this, nullptr, nullptr); +} + +std::unique_ptr<dot::graph> +diagnostics::digraphs::digraph::make_dot_graph () const +{ + conversion_to_dot to_dot; + return to_dot.make_dot_graph_from_diagnostic_graph (*this); +} + +std::unique_ptr<diagnostics::digraphs::digraph> +diagnostics::digraphs::digraph::clone () const +{ + auto result = std::make_unique<diagnostics::digraphs::digraph> (); + + if (get_property_bag ()) + result->set_property_bag (get_property_bag ()->clone_as_object ()); + + std::map<diagnostics::digraphs::node *, diagnostics::digraphs::node *> node_mapping; + + for (auto &iter : m_nodes) + result->add_node (iter->clone (*result, node_mapping)); + for (auto &iter : m_edges) + result->add_edge (iter->clone (*result, node_mapping)); + + return result; +} + +void +diagnostics::digraphs::digraph::add_edge (const char *id, + node &src_node, + node &dst_node, + const char *label) +{ + auto e = std::make_unique<digraph_edge> (*this, + id, + src_node, + dst_node); + if (label) + e->set_label (label); + add_edge (std::move (e)); +} + +/* Utility function for edge ids: either use EDGE_ID, or + generate a unique one for when we don't care about the name. + + Edges in SARIF "SHALL" have an id that's unique within the graph + (SARIF 2.1.0 §3.41.2). This is so that graph traversals can refer + to edges by id (SARIF 2.1.0's §3.43.2 edgeId property). */ + +std::string +diagnostics::digraphs::digraph::make_edge_id (const char *edge_id) +{ + /* If we have an id, use it. */ + if (edge_id) + return edge_id; + + /* Otherwise, generate a unique one of the form "edgeN". */ + while (true) + { + auto candidate (std::string ("edge") + + std::to_string (m_next_edge_id_index++)); + auto iter = m_id_to_edge_map.find (candidate); + if (iter != m_id_to_edge_map.end ()) + { + // Try again with the next index... + continue; + } + return candidate; + } +} + +// class node + +DEBUG_FUNCTION void +diagnostics::digraphs::node::dump () const +{ + to_json_sarif_node ()->dump (); +} + +std::unique_ptr<json::object> +diagnostics::digraphs::node::to_json_sarif_node () const +{ + return make_sarif_node (*this, nullptr, nullptr); +} + +std::unique_ptr<diagnostics::digraphs::node> +diagnostics::digraphs::node::clone (digraph &new_graph, + std::map<node *, node *> &node_mapping) const +{ + auto result + = std::make_unique<diagnostics::digraphs::node> (new_graph, + get_id ()); + node_mapping.insert ({const_cast <node *> (this), result.get ()}); + + result->set_logical_loc (m_logical_loc); + + if (get_property_bag ()) + result->set_property_bag (get_property_bag ()->clone_as_object ()); + + for (auto &iter : m_children) + result->add_child (iter->clone (new_graph, node_mapping)); + + return result; +} + +// class edge + +std::unique_ptr<digraph_edge> +digraph_edge::clone (digraph &new_graph, + const std::map<node *, node *> &node_mapping) const +{ + auto iter_new_src = node_mapping.find (&m_src_node); + gcc_assert (iter_new_src != node_mapping.end ()); + auto iter_new_dst = node_mapping.find (&m_dst_node); + gcc_assert (iter_new_dst != node_mapping.end ()); + auto result + = std::make_unique<digraph_edge> (new_graph, + m_id.c_str (), + *iter_new_src->second, + *iter_new_dst->second); + if (get_property_bag ()) + result->set_property_bag (get_property_bag ()->clone_as_object ()); + + return result; +} + +DEBUG_FUNCTION void +diagnostics::digraphs::edge::dump () const +{ + to_json_sarif_edge ()->dump (); +} + +std::unique_ptr<json::object> +diagnostics::digraphs::edge::to_json_sarif_edge () const +{ + return make_sarif_edge (*this, nullptr); +} + +// class lazy_digraph + +const diagnostics::digraphs::digraph & +diagnostics::digraphs::lazy_digraph::get_or_create_digraph () const +{ + if (!m_digraph) + m_digraph = create_digraph (); + gcc_assert (m_digraph); + return *m_digraph; +} + +// class lazy_digraphs + +const std::vector<std::unique_ptr<diagnostics::digraphs::digraph>> & +diagnostics::digraphs::lazy_digraphs::get_or_create_digraphs () const +{ + if (!m_digraphs) + m_digraphs = create_digraphs (); + gcc_assert (m_digraphs); + return *m_digraphs; +} + +#if CHECKING_P + +namespace selftest { + +static void +test_empty_graph () +{ + digraph g; + + { + auto sarif = g.make_json_sarif_graph (); + + pretty_printer pp; + sarif->print (&pp, true); + ASSERT_STREQ + (pp_formatted_text (&pp), + ("{\"nodes\": [],\n" + " \"edges\": []}")); + } + + { + auto dg = g.make_dot_graph (); + + pretty_printer pp; + dot::writer w (pp); + dg->print (w); + ASSERT_STREQ + (pp_formatted_text (&pp), + ("digraph {\n" + "}\n")); + } +} + +static void +test_simple_graph () +{ +#define KEY_PREFIX "/placeholder/" + auto g = std::make_unique<digraph> (); + g->set_description ("test graph"); + g->set_attr (KEY_PREFIX, "date", "1066"); + + auto a = std::make_unique<digraph_node> (*g, "a"); + auto b = std::make_unique<digraph_node> (*g, "b"); + b->set_attr (KEY_PREFIX, "color", "red"); + auto c = std::make_unique<digraph_node> (*g, "c"); + c->set_label ("I am a node label"); + + auto e = std::make_unique<digraph_edge> (*g, nullptr, *a, *c); + e->set_attr (KEY_PREFIX, "status", "copacetic"); + e->set_label ("I am an edge label"); + g->add_edge (std::move (e)); + + g->add_node (std::move (a)); + + b->add_child (std::move (c)); + g->add_node (std::move (b)); +#undef KEY_PREFIX + + { + auto sarif = g->make_json_sarif_graph (); + + pretty_printer pp; + sarif->print (&pp, true); + ASSERT_STREQ + (pp_formatted_text (&pp), + ("{\"properties\": {\"/placeholder/date\": \"1066\"},\n" + " \"nodes\": [{\"id\": \"a\"},\n" + " {\"id\": \"b\",\n" + " \"properties\": {\"/placeholder/color\": \"red\"},\n" + " \"children\": [{\"id\": \"c\"}]}],\n" + " \"edges\": [{\"id\": \"edge0\",\n" + " \"properties\": {\"/placeholder/status\": \"copacetic\"},\n" + " \"sourceNodeId\": \"a\",\n" + " \"targetNodeId\": \"c\"}]}")); + } + + { + auto dg = g->make_dot_graph (); + + pretty_printer pp; + dot::writer w (pp); + dg->print (w); + ASSERT_STREQ + (pp_formatted_text (&pp), + ("digraph {\n" + " label=\"test graph\";\n" + " a;\n" + " \n" + " subgraph cluster_b {\n" + " c [label=\"I am a node label\"];\n" + "\n" + " };\n" + " a -> c [label=\"I am an edge label\"];\n" + "}\n")); + } +} + +/* Run all of the selftests within this file. */ + +void +diagnostic_digraphs_cc_tests () +{ + test_empty_graph (); + test_simple_graph (); +} + +} // namespace selftest + +#endif /* CHECKING_P */ diff --git a/gcc/diagnostic-digraphs.h b/gcc/diagnostic-digraphs.h new file mode 100644 index 000000000000..d6f8e7e11ac4 --- /dev/null +++ b/gcc/diagnostic-digraphs.h @@ -0,0 +1,421 @@ +/* Directed graphs associated with a diagnostic. + Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by David Malcolm <dmalcolm@redhat.com> + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_DIAGNOSTIC_DIGRAPHS_H +#define GCC_DIAGNOSTIC_DIGRAPHS_H + +#include "json.h" +#include "logical-location.h" + +class graphviz_out; + +class sarif_graph; +class sarif_node; +class sarif_edge; + +namespace dot { class graph; } + +namespace diagnostics { +namespace digraphs { + +/* A family of classes: digraph, node, and edge, closely related to + SARIF's graph, node, and edge types (SARIF v2.1.0 sections 3.39-3.41). + + Nodes can have child nodes, allowing for arbitrarily deep nesting. + Edges can be between any pair of nodes (potentially at different + nesting levels). + + Digraphs, nodes, and edges also optionally have a JSON property bag, + allowing round-tripping of arbitrary key/value pairs through SARIF. */ + +class digraph; +class node; +class edge; + +/* A base class for digraph, node, and edge to allow them to have + an optional JSON property bag. */ + +class object +{ +public: + const char * + get_attr (const char *key_prefix, + const char *key) const; + + void + set_attr (const char *key_prefix, + const char *key, + const char *value); + + void + set_json_attr (const char *key_prefix, + const char *key, + std::unique_ptr<json::value> value); + + json::object * + get_property_bag () const { return m_property_bag.get (); } + + void + set_property_bag (std::unique_ptr<json::object> property_bag) + { + m_property_bag = std::move (property_bag); + } + +private: + std::unique_ptr<json::object> m_property_bag; +}; + +// A directed graph, corresponding to SARIF v2.1.0 section 3.39. + +class digraph : public object +{ + public: + friend class node; + friend class edge; + + digraph () : m_next_edge_id_index (0) {} + virtual ~digraph () {} + + const char * + get_description () const + { + if (!m_description) + return nullptr; + return m_description->c_str (); + } + + void + set_description (const char *desc) + { + if (desc) + m_description = std::make_unique<std::string> (desc); + else + m_description = nullptr; + } + void + set_description (std::string desc) + { + m_description = std::make_unique<std::string> (std::move (desc)); + } + + node * + get_node_by_id (const char *id) const + { + auto iter = m_id_to_node_map.find (id); + if (iter == m_id_to_node_map.end ()) + return nullptr; + return iter->second; + } + + edge * + get_edge_by_id (const char *id) const + { + auto iter = m_id_to_edge_map.find (id); + if (iter == m_id_to_edge_map.end ()) + return nullptr; + return iter->second; + } + + size_t + get_num_nodes () const + { + return m_nodes.size (); + } + + node & + get_node (size_t idx) const + { + return *m_nodes[idx].get (); + } + + size_t + get_num_edges () const + { + return m_edges.size (); + } + + edge & + get_edge (size_t idx) const + { + return *m_edges[idx].get (); + } + + void + dump () const; + + std::unique_ptr<json::object> + make_json_sarif_graph () const; + + std::unique_ptr<dot::graph> + make_dot_graph () const; + + void + add_node (std::unique_ptr<node> n) + { + gcc_assert (n); + m_nodes.push_back (std::move (n)); + } + + void + add_edge (std::unique_ptr<edge> e) + { + gcc_assert (e); + m_edges.push_back (std::move (e)); + } + + void + add_edge (const char *id, + node &src_node, + node &dst_node, + const char *label = nullptr); + + std::unique_ptr<digraph> clone () const; + + private: + void + add_node_id (std::string node_id, node &new_node) + { + m_id_to_node_map.insert ({std::move (node_id), &new_node}); + } + void + add_edge_id (std::string edge_id, edge &new_edge) + { + m_id_to_edge_map.insert ({std::move (edge_id), &new_edge}); + } + + std::string + make_edge_id (const char *edge_id); + + std::unique_ptr<std::string> m_description; + std::map<std::string, node *> m_id_to_node_map; + std::map<std::string, edge *> m_id_to_edge_map; + std::vector<std::unique_ptr<node>> m_nodes; + std::vector<std::unique_ptr<edge>> m_edges; + size_t m_next_edge_id_index; +}; + +// A node in a directed graph, corresponding to SARIF v2.1.0 section 3.40. + +class node : public object +{ + public: + virtual ~node () {} + + node (digraph &g, std::string id) + : m_id (id), + m_physical_loc (UNKNOWN_LOCATION) + { + g.add_node_id (std::move (id), *this); + } + node (const node &) = delete; + + std::string + get_id () const { return m_id; } + + const char * + get_label () const + { + if (!m_label) + return nullptr; + return m_label->c_str (); + } + + void + set_label (const char *label) + { + if (label) + m_label = std::make_unique<std::string> (label); + else + m_label = nullptr; + } + void + set_label (std::string label) + { + m_label = std::make_unique<std::string> (std::move (label)); + } + + size_t + get_num_children () const { return m_children.size (); } + + node & + get_child (size_t idx) const { return *m_children[idx].get (); } + + void + add_child (std::unique_ptr<node> child) + { + gcc_assert (child); + m_children.push_back (std::move (child)); + } + + location_t + get_physical_loc () const + { + return m_physical_loc; + } + + void + set_physical_loc (location_t physical_loc) + { + m_physical_loc = physical_loc; + } + + logical_location + get_logical_loc () const + { + return m_logical_loc; + } + + void + set_logical_loc (logical_location logical_loc) + { + m_logical_loc = logical_loc; + } + + void print (graphviz_out &gv) const; + + void + dump () const; + + std::unique_ptr<json::object> + to_json_sarif_node () const; + + std::unique_ptr<node> + clone (digraph &new_graph, + std::map<node *, node *> &node_mapping) const; + + private: + std::string m_id; + std::unique_ptr<std::string> m_label; + std::vector<std::unique_ptr<node>> m_children; + location_t m_physical_loc; + logical_location m_logical_loc; +}; + +// An edge in a directed graph, corresponding to SARIF v2.1.0 section 3.41. + +class edge : public object +{ + public: + virtual ~edge () {} + + /* SARIF requires us to provide unique edge IDs within a graph, + but otherwise we don't need them. + Pass in nullptr for the id to get the graph to generate a unique + edge id for us. */ + edge (digraph &g, + const char *id, + node &src_node, + node &dst_node) + : m_id (g.make_edge_id (id)), + m_src_node (src_node), + m_dst_node (dst_node) + { + g.add_edge_id (m_id, *this); + } + + std::string + get_id () const { return m_id; } + + const char * + get_label () const + { + if (!m_label) + return nullptr; + return m_label->c_str (); + } + + void + set_label (const char *label) + { + if (label) + m_label = std::make_unique<std::string> (label); + else + m_label = nullptr; + } + + node & + get_src_node () const { return m_src_node; } + + node & + get_dst_node () const { return m_dst_node; } + + void + dump () const; + + std::unique_ptr<json::object> + to_json_sarif_edge () const; + + std::unique_ptr<edge> + clone (digraph &new_graph, + const std::map<diagnostics::digraphs::node *, diagnostics::digraphs::node *> &node_mapping) const; + +private: + std::string m_id; + std::unique_ptr<std::string> m_label; + node &m_src_node; + node &m_dst_node; +}; + +/* Abstract base class for lazily creating + a digraph on demand. + + This allows us to avoid the work of creating the digraph for + the common case where we just have a text sink. */ + +class lazy_digraph +{ +public: + virtual ~lazy_digraph () {} + + const digraph & + get_or_create_digraph () const; + +private: + virtual std::unique_ptr<digraph> + create_digraph () const = 0; + + mutable std::unique_ptr<digraph> m_digraph; +}; + +/* Abstract base class for lazily creating a collection of + digraphs on demand. + + This allows us to avoid the work of creating the digraphs for + the common case where we just have a text sink. */ + +class lazy_digraphs +{ +public: + virtual ~lazy_digraphs () {} + + const std::vector<std::unique_ptr<digraph>> & + get_or_create_digraphs () const; + +private: + virtual std::unique_ptr<std::vector<std::unique_ptr<digraph>>> + create_digraphs () const = 0; + + mutable std::unique_ptr<std::vector<std::unique_ptr<digraph>>> m_digraphs; +}; + +} // namespace digraphs +} // namespace diagnostics + +#endif /* ! GCC_DIAGNOSTIC_DIGRAPHS_H */ diff --git a/gcc/diagnostic-format-html.cc b/gcc/diagnostic-format-html.cc index 05d4273c2c61..becac39f5dcc 100644 --- a/gcc/diagnostic-format-html.cc +++ b/gcc/diagnostic-format-html.cc @@ -29,8 +29,11 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-format.h" #include "diagnostic-format-html.h" #include "diagnostic-format-text.h" +#include "diagnostic-format-sarif.h" #include "diagnostic-output-file.h" #include "diagnostic-buffer.h" +#include "diagnostic-path.h" +#include "diagnostic-client-data-hooks.h" #include "selftest.h" #include "selftest-diagnostic.h" #include "pretty-print-format-impl.h" @@ -39,266 +42,23 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" #include "xml.h" #include "xml-printer.h" +#include "diagnostic-digraphs.h" +#include "diagnostic-state-graphs.h" +#include "graphviz.h" #include "json.h" +#include "selftest-xml.h" // struct html_generation_options html_generation_options::html_generation_options () : m_css (true), - m_javascript (true) + m_javascript (true), + m_show_state_diagrams (false), + m_show_state_diagrams_sarif (false), + m_show_state_diagrams_dot_src (false) { } -namespace xml { - -/* Disable warnings about quoting issues in the pp_xxx calls below - that (intentionally) don't follow GCC diagnostic conventions. */ -#if __GNUC__ >= 10 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wformat-diag" -#endif - - -/* Implementation. */ - -static void -write_escaped_text (pretty_printer *pp, const char *text) -{ - gcc_assert (text); - - for (const char *p = text; *p; ++p) - { - char ch = *p; - switch (ch) - { - default: - pp_character (pp, ch); - break; - case '\'': - pp_string (pp, "'"); - break; - case '"': - pp_string (pp, """); - break; - case '&': - pp_string (pp, "&"); - break; - case '<': - pp_string (pp, "<"); - break; - case '>': - pp_string (pp, ">"); - break; - } - } -} - -/* struct node. */ - -void -node::dump (FILE *out) const -{ - pretty_printer pp; - pp.set_output_stream (out); - write_as_xml (&pp, 0, true); - pp_flush (&pp); -} - -/* struct text : public node. */ - -void -text::write_as_xml (pretty_printer *pp, int depth, bool indent) const -{ - if (indent) - { - for (int i = 0; i < depth; ++i) - pp_string (pp, " "); - } - write_escaped_text (pp, m_str.c_str ()); - if (indent) - pp_newline (pp); -} - -/* struct node_with_children : public node. */ - -void -node_with_children::add_child (std::unique_ptr<node> node) -{ - gcc_assert (node.get ()); - m_children.push_back (std::move (node)); -} - -void -node_with_children::add_text (std::string str) -{ - // Consolidate runs of text - if (!m_children.empty ()) - if (text *t = m_children.back ()->dyn_cast_text ()) - { - t->m_str += std::move (str); - return; - } - add_child (std::make_unique <text> (std::move (str))); -} - - -/* struct document : public node_with_children. */ - -void -document::write_as_xml (pretty_printer *pp, int depth, bool indent) const -{ - pp_string (pp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); - pp_string (pp, "<!DOCTYPE html\n" - " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n" - " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"); - if (indent) - pp_newline (pp); - for (auto &iter : m_children) - iter->write_as_xml (pp, depth, indent); -} - -/* struct element : public node_with_children. */ - -void -element::write_as_xml (pretty_printer *pp, int depth, bool indent) const -{ - if (indent) - { - for (int i = 0; i < depth; ++i) - pp_string (pp, " "); - } - - pp_printf (pp, "<%s", m_kind.c_str ()); - for (auto &key : m_key_insertion_order) - { - auto iter = m_attributes.find (key); - if (iter != m_attributes.end ()) - { - pp_printf (pp, " %s=\"", key.c_str ()); - write_escaped_text (pp, iter->second.c_str ()); - pp_string (pp, "\""); - } - } - if (m_children.empty ()) - pp_string (pp, "/>"); - else - { - const bool indent_children = m_preserve_whitespace ? false : indent; - pp_string (pp, ">"); - if (indent_children) - pp_newline (pp); - for (auto &child : m_children) - child->write_as_xml (pp, depth + 1, indent_children); - if (indent_children) - { - for (int i = 0; i < depth; ++i) - pp_string (pp, " "); - } - pp_printf (pp, "</%s>", m_kind.c_str ()); - } - - if (indent) - pp_newline (pp); -} - -void -element::set_attr (const char *name, std::string value) -{ - auto iter = m_attributes.find (name); - if (iter == m_attributes.end ()) - m_key_insertion_order.push_back (name); - m_attributes[name] = std::move (value); -} - -// struct raw : public node - -void -raw::write_as_xml (pretty_printer *pp, - int /*depth*/, bool /*indent*/) const -{ - pp_string (pp, m_xml_src.c_str ()); -} - -#if __GNUC__ >= 10 -# pragma GCC diagnostic pop -#endif - -// class printer - -printer::printer (element &insertion_point) -{ - m_open_tags.push_back (&insertion_point); -} - -void -printer::push_tag (std::string name, - bool preserve_whitespace) -{ - push_element - (std::make_unique<element> (std::move (name), - preserve_whitespace)); -} - -void -printer::push_tag_with_class (std::string name, std::string class_, - bool preserve_whitespace) -{ - auto new_element - = std::make_unique<element> (std::move (name), - preserve_whitespace); - new_element->set_attr ("class", class_); - push_element (std::move (new_element)); -} - -void -printer::pop_tag () -{ - m_open_tags.pop_back (); -} - -void -printer::set_attr (const char *name, std::string value) -{ - m_open_tags.back ()->set_attr (name, value); -} - -void -printer::add_text (std::string text) -{ - element *parent = m_open_tags.back (); - parent->add_text (std::move (text)); -} - -void -printer::add_raw (std::string text) -{ - element *parent = m_open_tags.back (); - parent->add_child (std::make_unique<xml::raw> (std::move (text))); -} - -void -printer::push_element (std::unique_ptr<element> new_element) -{ - element *parent = m_open_tags.back (); - m_open_tags.push_back (new_element.get ()); - parent->add_child (std::move (new_element)); -} - -void -printer::append (std::unique_ptr<node> new_node) -{ - element *parent = m_open_tags.back (); - parent->add_child (std::move (new_node)); -} - -element * -printer::get_insertion_point () const -{ - return m_open_tags.back (); -} - -} // namespace xml - class html_builder; /* Concrete buffering implementation subclass for HTML output. */ @@ -354,10 +114,15 @@ class html_builder const line_maps *line_maps, const html_generation_options &html_gen_opts); + void + set_main_input_filename (const char *name); + void on_report_diagnostic (const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind, diagnostic_html_format_buffer *buffer); void emit_diagram (const diagnostic_diagram &diagram); + void emit_global_graph (const diagnostics::digraphs::lazy_digraph &); + void end_group (); std::unique_ptr<xml::element> take_current_diagnostic () @@ -385,26 +150,54 @@ class html_builder m_ui_focus_ids.append_string (focus_id.c_str ()); } + std::unique_ptr<xml::node> + maybe_make_state_diagram (const diagnostic_event &event); + private: + void + add_stylesheet (std::string url); + std::unique_ptr<xml::element> make_element_for_diagnostic (const diagnostic_info &diagnostic, - diagnostic_t orig_diag_kind); + diagnostic_t orig_diag_kind, + bool alert); std::unique_ptr<xml::element> make_metadata_element (label_text label, label_text url); + void + add_at_nesting_level (size_t nesting_level, + std::unique_ptr<xml::element> child_diag_element); + + void + push_nesting_level (); + + void + pop_nesting_level (); + + void + add_graph (const diagnostics::digraphs::digraph &dg, + xml::element &parent_element); + diagnostic_context &m_context; pretty_printer *m_printer; const line_maps *m_line_maps; html_generation_options m_html_gen_opts; + const logical_location_manager *m_logical_loc_mgr; std::unique_ptr<xml::document> m_document; xml::element *m_head_element; + xml::element *m_title_element; + xml::element *m_body_element; xml::element *m_diagnostics_element; std::unique_ptr<xml::element> m_cur_diagnostic_element; + std::vector<xml::element *> m_cur_nesting_levels; int m_next_diag_id; // for handing out unique IDs json::array m_ui_focus_ids; + logical_location m_last_logical_location; + location_t m_last_location; + expanded_location m_last_expanded_location; }; static std::unique_ptr<xml::element> @@ -483,8 +276,10 @@ static const char * const HTML_STYLE " .ruler { color: red;\n" " white-space: pre; }\n" " .source { color: blue;\n" + " background-color: white;\n" " white-space: pre; }\n" " .annotation { color: green;\n" + " background-color: white;\n" " white-space: pre; }\n" " .linenum-gap { text-align: center;\n" " border-top: 1px solid black;\n" @@ -515,6 +310,8 @@ static const char * const HTML_STYLE " font-weight: bold; }\n" " .highlight-b { color: #3f9c35;\n" // pf-green-400 " font-weight: bold; }\n" + " .gcc-quoted-text { font-weight: bold;\n" + " font-family: mono; }\n" " </style>\n"); /* A little JavaScript for ease of navigation. @@ -530,14 +327,27 @@ const char * const HTML_SCRIPT " const element_id = focus_ids[focus_idx];\n" " return document.getElementById(element_id);\n" " }\n" + " function get_any_state_diagram (focus_idx)\n" + " {\n" + " const element_id = focus_ids[focus_idx];\n" + " return document.getElementById(element_id + \"-state-diagram\");\n" + " }\n" " function unhighlight_current_focus_idx ()\n" " {\n" " get_focus_span (current_focus_idx).classList.remove ('selected');\n" + " state_diagram = get_any_state_diagram (current_focus_idx);\n" + " if (state_diagram) {\n" + " state_diagram.style.visibility = \"hidden\";\n" + " }\n" " }\n" " function highlight_current_focus_idx ()\n" " {\n" " const el = get_focus_span (current_focus_idx);\n" " el.classList.add ('selected');\n" + " state_diagram = get_any_state_diagram (current_focus_idx);\n" + " if (state_diagram) {\n" + " state_diagram.style.visibility = \"visible\";\n" + " }\n" " // Center the element on the screen\n" " const top_y = el.getBoundingClientRect ().top + window.pageYOffset;\n" " const middle = top_y - (window.innerHeight / 2);\n" @@ -569,6 +379,24 @@ const char * const HTML_SCRIPT " });\n" " highlight_current_focus_idx ();\n"); +struct html_doctypedecl : public xml::doctypedecl +{ + void write_as_xml (pretty_printer *pp, + int depth, bool indent) const final override + { + if (indent) + { + for (int i = 0; i < depth; ++i) + pp_string (pp, " "); + } + pp_string (pp, "<!DOCTYPE html\n" + " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n" + " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"); + if (indent) + pp_newline (pp); + } +}; + /* html_builder's ctor. */ html_builder::html_builder (diagnostic_context &context, @@ -579,13 +407,22 @@ html_builder::html_builder (diagnostic_context &context, m_printer (&pp), m_line_maps (line_maps), m_html_gen_opts (html_gen_opts), + m_logical_loc_mgr (nullptr), m_head_element (nullptr), + m_title_element (nullptr), + m_body_element (nullptr), m_diagnostics_element (nullptr), - m_next_diag_id (0) + m_next_diag_id (0), + m_last_location (UNKNOWN_LOCATION), + m_last_expanded_location ({}) { gcc_assert (m_line_maps); + if (auto client_data_hooks = context.get_client_data_hooks ()) + m_logical_loc_mgr = client_data_hooks->get_logical_location_manager (); + m_document = std::make_unique<xml::document> (); + m_document->m_doctypedecl = std::make_unique<html_doctypedecl> (); { auto html_element = std::make_unique<xml::element> ("html", false); html_element->set_attr ("xmlns", @@ -598,22 +435,29 @@ html_builder::html_builder (diagnostic_context &context, m_head_element = xp.get_insertion_point (); { xml::auto_print_element title (xp, "title", true); - xp.add_text ("Title goes here"); + m_title_element = xp.get_insertion_point (); + m_title_element->add_text (" "); } + if (m_html_gen_opts.m_css) - xp.add_raw (HTML_STYLE); + { + add_stylesheet ("https://cdnjs.cloudflare.com/ajax/libs/patternfly/3.24.0/css/patternfly.min.css"); + add_stylesheet ("https://cdnjs.cloudflare.com/ajax/libs/patternfly/3.24.0/css/patternfly-additions.min.css"); + xp.add_raw (HTML_STYLE); + } if (m_html_gen_opts.m_javascript) { xp.push_tag ("script"); /* Escaping rules are different for HTML <script> elements, so add the script "raw" for now. */ xp.add_raw (HTML_SCRIPT); - xp.pop_tag (); // script + xp.pop_tag ("script"); } } { xml::auto_print_element body (xp, "body"); + m_body_element = xp.get_insertion_point (); { auto diagnostics_element = make_div ("gcc-diagnostic-list"); m_diagnostics_element = diagnostics_element.get (); @@ -623,6 +467,29 @@ html_builder::html_builder (diagnostic_context &context, } } +void +html_builder::set_main_input_filename (const char *name) +{ + gcc_assert (m_title_element); + if (name) + { + m_title_element->m_children.clear (); + m_title_element->add_text (name); + } +} + +void +html_builder::add_stylesheet (std::string url) +{ + gcc_assert (m_head_element); + + xml::printer xp (*m_head_element); + xp.push_tag ("link", false); + xp.set_attr ("rel", "stylesheet"); + xp.set_attr ("type", "text/css"); + xp.set_attr ("href", std::move (url)); +} + /* Implementation of "on_report_diagnostic" for HTML output. */ void @@ -640,8 +507,14 @@ html_builder::on_report_diagnostic (const diagnostic_info &diagnostic, fnotice (stderr, "Internal compiler error:\n"); } + const int nesting_level = m_context.get_diagnostic_nesting_level (); + bool alert = true; + if (m_cur_diagnostic_element && nesting_level > 0) + alert = false; + if (!m_cur_diagnostic_element) + m_last_logical_location = logical_location (); auto diag_element - = make_element_for_diagnostic (diagnostic, orig_diag_kind); + = make_element_for_diagnostic (diagnostic, orig_diag_kind, alert); if (buffer) { gcc_assert (!m_cur_diagnostic_element); @@ -650,12 +523,136 @@ html_builder::on_report_diagnostic (const diagnostic_info &diagnostic, else { if (m_cur_diagnostic_element) - /* Nested diagnostic. */ - m_cur_diagnostic_element->add_child (std::move (diag_element)); + { + /* Nested diagnostic. */ + gcc_assert (nesting_level >= 0); + add_at_nesting_level (nesting_level, std::move (diag_element)); + } else /* Top-level diagnostic. */ - m_cur_diagnostic_element = std::move (diag_element); + { + m_cur_diagnostic_element = std::move (diag_element); + m_cur_nesting_levels.clear (); + } + } +} + +// For ease of comparison with experimental-nesting-show-levels=yes + +static void +add_nesting_level_attr (xml::element &element, + int nesting_level) +{ + element.set_attr ("nesting-level", std::to_string (nesting_level)); +} + +void +html_builder:: +add_at_nesting_level (size_t nesting_level, + std::unique_ptr<xml::element> child_diag_element) +{ + gcc_assert (m_cur_diagnostic_element); + while (nesting_level > m_cur_nesting_levels.size ()) + push_nesting_level (); + while (nesting_level < m_cur_nesting_levels.size ()) + pop_nesting_level (); + + if (nesting_level > 0) + { + gcc_assert (!m_cur_nesting_levels.empty ()); + auto current_nesting_level = m_cur_nesting_levels.back (); + xml::printer xp (*current_nesting_level); + xp.push_tag ("li"); + add_nesting_level_attr (*xp.get_insertion_point (), + m_cur_nesting_levels.size ()); + xp.append (std::move (child_diag_element)); + xp.pop_tag ("li"); + } + else + m_cur_diagnostic_element->add_child (std::move (child_diag_element)); +} + +void +html_builder::push_nesting_level () +{ + gcc_assert (m_cur_diagnostic_element); + auto new_nesting_level = std::make_unique<xml::element> ("ul", false); + add_nesting_level_attr (*new_nesting_level, + m_cur_nesting_levels.size () + 1); + xml::element *current_nesting_level = nullptr; + if (!m_cur_nesting_levels.empty ()) + current_nesting_level = m_cur_nesting_levels.back (); + m_cur_nesting_levels.push_back (new_nesting_level.get ()); + if (current_nesting_level) + current_nesting_level->add_child (std::move (new_nesting_level)); + else + m_cur_diagnostic_element->add_child (std::move (new_nesting_level)); +} + +void +html_builder::pop_nesting_level () +{ + gcc_assert (m_cur_diagnostic_element); + m_cur_nesting_levels.pop_back (); +} + +static void +print_pre_source (xml::printer &xp, const char *text) +{ + xp.push_tag_with_class ("pre", "source", true); + xp.add_text (text); + xp.pop_tag ("pre"); +} + +std::unique_ptr<xml::node> +html_builder::maybe_make_state_diagram (const diagnostic_event &event) +{ + if (!m_html_gen_opts.m_show_state_diagrams) + return nullptr; + + if (!m_logical_loc_mgr) + return nullptr; + + /* Get state graph; if we're going to print it later, also request + the debug version. */ + auto state_graph + = event.maybe_make_diagnostic_state_graph + (m_html_gen_opts.m_show_state_diagrams_sarif); + if (!state_graph) + return nullptr; + + // Convert it to .dot AST + auto dot_graph + = diagnostics::state_graphs::make_dot_graph (*state_graph, + *m_logical_loc_mgr); + gcc_assert (dot_graph); + + auto wrapper = std::make_unique<xml::element> ("div", false); + xml::printer xp (*wrapper); + + if (m_html_gen_opts.m_show_state_diagrams_sarif) + { + // For debugging, show the SARIF src inline: + pretty_printer pp; + state_graph->make_json_sarif_graph ()->print (&pp, true); + print_pre_source (xp, pp_formatted_text (&pp)); } + + if (m_html_gen_opts.m_show_state_diagrams_dot_src) + { + // For debugging, show the dot src inline: + pretty_printer pp; + dot::writer w (pp); + dot_graph->print (w); + print_pre_source (xp, pp_formatted_text (&pp)); + } + + // Turn the .dot into SVG and splice into place + auto svg = dot::make_svg_from_graph (*dot_graph); + if (svg) + xp.append (std::move (svg)); + + return wrapper; } /* Custom subclass of html_label_writer. @@ -667,111 +664,290 @@ class html_path_label_writer : public html_label_writer public: html_path_label_writer (xml::printer &xp, html_builder &builder, + const diagnostic_path &path, const std::string &event_id_prefix) : m_xp (xp), m_html_builder (builder), + m_path (path), m_event_id_prefix (event_id_prefix), - m_next_event_idx (0) + m_next_event_idx (0), + m_curr_event_id () { } void begin_label () final override { + m_curr_event_id = m_next_event_idx++; m_xp.push_tag_with_class ("span", "event", true); - pretty_printer pp; - pp_printf (&pp, "%s%i", - m_event_id_prefix.c_str (), m_next_event_idx++); - m_xp.set_attr ("id", pp_formatted_text (&pp)); - m_html_builder.add_focus_id (pp_formatted_text (&pp)); + m_xp.set_attr ("id", get_element_id ()); + m_html_builder.add_focus_id (get_element_id ()); } void end_label () final override { - m_xp.pop_tag (); // span + const diagnostic_event &event + = m_path.get_event (m_curr_event_id.zero_based ()); + if (auto state_doc = m_html_builder.maybe_make_state_diagram (event)) + { + m_xp.push_tag_with_class ("div", "state-diagram", false); + m_xp.set_attr ("id", get_element_id () + "-state-diagram"); + m_xp.set_attr ("style", + ("position: absolute;" + " z-index: 1;" + " visibility: hidden;")); + m_xp.append (std::move (state_doc)); + m_xp.pop_tag ("div"); + } + + m_xp.pop_tag ("span"); // from begin_label } private: + std::string + get_element_id () const + { + gcc_assert (m_curr_event_id.known_p ()); + return (m_event_id_prefix + + std::to_string (m_curr_event_id.zero_based ())); + } + xml::printer &m_xp; html_builder &m_html_builder; + const diagnostic_path &m_path; const std::string &m_event_id_prefix; int m_next_event_idx; + diagnostic_event_id_t m_curr_event_id; }; -std::unique_ptr<xml::element> -html_builder::make_element_for_diagnostic (const diagnostic_info &diagnostic, - diagnostic_t orig_diag_kind) +/* See https://pf3.patternfly.org/v3/pattern-library/widgets/#alerts */ +static const char * +get_pf_class_for_alert_div (diagnostic_t diag_kind) { - class html_token_printer : public token_printer - { - public: - html_token_printer (xml::printer &xp) - : m_xp (xp) + switch (diag_kind) + { + case DK_DEBUG: + case DK_NOTE: + return "alert alert-info"; + + case DK_ANACHRONISM: + case DK_WARNING: + return "alert alert-warning"; + + case DK_ERROR: + case DK_SORRY: + case DK_ICE: + case DK_ICE_NOBT: + case DK_FATAL: + return "alert alert-danger"; + + default: + gcc_unreachable (); + } +} + +static const char * +get_pf_class_for_alert_icon (diagnostic_t diag_kind) +{ + switch (diag_kind) { + case DK_DEBUG: + case DK_NOTE: + return "pficon pficon-info"; + + case DK_ANACHRONISM: + case DK_WARNING: + return "pficon pficon-warning-triangle-o"; + + case DK_ERROR: + case DK_SORRY: + case DK_ICE: + case DK_ICE_NOBT: + case DK_FATAL: + return "pficon pficon-error-circle-o"; + + default: + gcc_unreachable (); } - void print_tokens (pretty_printer */*pp*/, - const pp_token_list &tokens) final override +} + +static const char * +get_label_for_logical_location_kind (enum logical_location_kind kind) +{ + switch (kind) { - /* Implement print_tokens by adding child elements to - m_parent_element. */ - for (auto iter = tokens.m_first; iter; iter = iter->m_next) - switch (iter->m_kind) + default: + gcc_unreachable (); + case logical_location_kind::unknown: + return nullptr; + + /* Kinds within executable code. */ + case logical_location_kind::function: + return "Function"; + case logical_location_kind::member: + return "Member"; + case logical_location_kind::module_: + return "Module"; + case logical_location_kind::namespace_: + return "Namespace"; + case logical_location_kind::type: + return "Type"; + case logical_location_kind::return_type: + return "Return type"; + case logical_location_kind::parameter: + return "Parameter"; + case logical_location_kind::variable: + return "Variable"; + + /* Kinds within XML or HTML documents. */ + case logical_location_kind::element: + return "Element"; + case logical_location_kind::attribute: + return "Attribute"; + case logical_location_kind::text: + return "Text"; + case logical_location_kind::comment: + return "Comment"; + case logical_location_kind::processing_instruction: + return "Processing Instruction"; + case logical_location_kind::dtd: + return "DTD"; + case logical_location_kind::declaration: + return "Declaration"; + + /* Kinds within JSON documents. */ + case logical_location_kind::object: + return "Object"; + case logical_location_kind::array: + return "Array"; + case logical_location_kind::property: + return "Property"; + case logical_location_kind::value: + return "Value"; + } +} + +static void +add_labelled_value (xml::printer &xp, + std::string id, + std::string label, + std::string value, + bool quote_value) +{ + xp.push_tag ("div", true); + xp.set_attr ("id", id); + xp.push_tag ("span"); + xp.add_text (label); + xp.add_text (" "); + xp.pop_tag ("span"); + xp.push_tag ("span"); + if (quote_value) + xp.set_attr ("class", "gcc-quoted-text"); + xp.add_text (std::move (value)); + xp.pop_tag ("span"); + xp.pop_tag ("div"); +} + +class html_token_printer : public token_printer +{ +public: + html_token_printer (xml::element &parent_element) + /* Ideally pp_token_lists that reach a token_printer should be + "balanced", but for now they can have mismatching pp_tokens + e.g. a begin_color without an end_color (PR other/120610). + Give html_token_printer its own xml::printer as a firewall to + limit the scope of the mismatches in the HTML. */ + : m_xp (parent_element, + /* Similarly we don't check that the popped tags match. */ + false) + { + } + void print_tokens (pretty_printer */*pp*/, + const pp_token_list &tokens) final override + { + /* Implement print_tokens by adding child elements to + m_parent_element. */ + for (auto iter = tokens.m_first; iter; iter = iter->m_next) + switch (iter->m_kind) + { + default: + gcc_unreachable (); + + case pp_token::kind::text: { - default: - gcc_unreachable (); - - case pp_token::kind::text: - { - pp_token_text *sub = as_a <pp_token_text *> (iter); - /* The value might be in the obstack, so we may need to - copy it. */ - m_xp.add_text (sub->m_value.get ()); + pp_token_text *sub = as_a <pp_token_text *> (iter); + /* The value might be in the obstack, so we may need to + copy it. */ + m_xp.add_text (sub->m_value.get ()); } - break; + break; - case pp_token::kind::begin_color: - { - pp_token_begin_color *sub = as_a <pp_token_begin_color *> (iter); - gcc_assert (sub->m_value.get ()); - m_xp.push_tag_with_class ("span", sub->m_value.get ()); - } - break; + case pp_token::kind::begin_color: + { + pp_token_begin_color *sub = as_a <pp_token_begin_color *> (iter); + gcc_assert (sub->m_value.get ()); + m_xp.push_tag_with_class ("span", sub->m_value.get ()); + } + break; - case pp_token::kind::end_color: - m_xp.pop_tag (); - break; + case pp_token::kind::end_color: + m_xp.pop_tag ("span"); + break; - case pp_token::kind::begin_quote: - { - m_xp.add_text (open_quote); - m_xp.push_tag_with_class ("span", "gcc-quoted-text"); - } - break; - case pp_token::kind::end_quote: - { - m_xp.pop_tag (); - m_xp.add_text (close_quote); - } - break; + case pp_token::kind::begin_quote: + { + m_xp.add_text (open_quote); + m_xp.push_tag_with_class ("span", "gcc-quoted-text"); + } + break; + case pp_token::kind::end_quote: + { + m_xp.pop_tag ("span"); + m_xp.add_text (close_quote); + } + break; - case pp_token::kind::begin_url: - { - pp_token_begin_url *sub = as_a <pp_token_begin_url *> (iter); - m_xp.push_tag ("a", true); - m_xp.set_attr ("href", sub->m_value.get ()); - } - break; - case pp_token::kind::end_url: - m_xp.pop_tag (); - break; + case pp_token::kind::begin_url: + { + pp_token_begin_url *sub = as_a <pp_token_begin_url *> (iter); + m_xp.push_tag ("a", true); + m_xp.set_attr ("href", sub->m_value.get ()); } - } + break; + case pp_token::kind::end_url: + m_xp.pop_tag ("a"); + break; - private: - xml::printer &m_xp; - }; + case pp_token::kind::event_id: + { + pp_token_event_id *sub = as_a <pp_token_event_id *> (iter); + gcc_assert (sub->m_event_id.known_p ()); + m_xp.add_text ("("); + m_xp.add_text (std::to_string (sub->m_event_id.one_based ())); + m_xp.add_text (")"); + } + break; + } + } - auto diag_element = make_div ("gcc-diagnostic"); +private: + xml::printer m_xp; +}; + +/* Make a <div class="gcc-diagnostic"> for DIAGNOSTIC. + + If ALERT is true, make it be a PatternFly alert (see + https://pf3.patternfly.org/v3/pattern-library/widgets/#alerts) and + show severity text (e.g. "error: "). + If ALERT is false, don't show the severity text and don't show + the filename if it's the same as the previous diagnostic within the + diagnostic group. */ + +std::unique_ptr<xml::element> +html_builder::make_element_for_diagnostic (const diagnostic_info &diagnostic, + diagnostic_t orig_diag_kind, + bool alert) +{ const int diag_idx = m_next_diag_id++; std::string diag_id; { @@ -779,30 +955,75 @@ html_builder::make_element_for_diagnostic (const diagnostic_info &diagnostic, pp_printf (&pp, "gcc-diag-%i", diag_idx); diag_id = pp_formatted_text (&pp); } - diag_element->set_attr ("id", diag_id); // TODO: might be nice to emulate the text output format, but colorize it - auto message_span = make_span ("gcc-message"); - std::string message_span_id (diag_id + "-message"); - message_span->set_attr ("id", message_span_id); - add_focus_id (message_span_id); + /* See https://pf3.patternfly.org/v3/pattern-library/widgets/#alerts + which has this example: +<div class="alert alert-danger"> + <span class="pficon pficon-error-circle-o"></span> + <strong>Hey there is a problem!</strong> Yeah this is really messed up and you should <a href="#" class="alert-link">know about it</a>. +</div> + */ + auto diag_element = make_div ("gcc-diagnostic"); + diag_element->set_attr ("id", diag_id); + if (alert) + diag_element->set_attr ("class", + get_pf_class_for_alert_div (diagnostic.kind)); + + xml::printer xp (*diag_element.get ()); + const size_t depth_within_alert_div = 1; + + gcc_assert (xp.get_num_open_tags () == depth_within_alert_div); + + if (alert) + { + xp.push_tag_with_class ("span", + get_pf_class_for_alert_icon (diagnostic.kind), + true); + xp.add_text (" "); + xp.pop_tag ("span"); + } + + // The rest goes in the <div>... + gcc_assert (xp.get_num_open_tags () == depth_within_alert_div); + + xp.push_tag_with_class ("div", "gcc-message", true); + std::string message_alert_id (diag_id + "-message"); + xp.set_attr ("id", message_alert_id); + add_focus_id (message_alert_id); - xml::printer xp (*message_span.get ()); - html_token_printer tok_printer (xp); + const size_t depth_within_message_div = depth_within_alert_div + 1; + gcc_assert (xp.get_num_open_tags () == depth_within_message_div); + + // Severity e.g. "warning: " + bool show_severity = true; + if (!alert) + show_severity = false; + if (show_severity) + { + xp.push_tag ("strong"); + xp.add_text (_(get_diagnostic_kind_text (diagnostic.kind))); + xp.pop_tag ("strong"); + xp.add_text (" "); + } + + // Add the message itself: + html_token_printer tok_printer (*xp.get_insertion_point ()); m_printer->set_token_printer (&tok_printer); pp_output_formatted_text (m_printer, m_context.get_urlifier ()); m_printer->set_token_printer (nullptr); pp_clear_output_area (m_printer); - diag_element->add_child (std::move (message_span)); + // Add any metadata as a suffix to the message if (diagnostic.metadata) { - diag_element->add_text (" "); - diag_element->add_child - (make_element_for_metadata (*diagnostic.metadata)); + xp.add_text (" "); + xp.append (make_element_for_metadata (*diagnostic.metadata)); } + // Add any option as a suffix to the message + label_text option_text = label_text::take (m_context.make_option_name (diagnostic.option_id, orig_diag_kind, diagnostic.kind)); @@ -811,7 +1032,7 @@ html_builder::make_element_for_diagnostic (const diagnostic_info &diagnostic, label_text option_url = label_text::take (m_context.make_option_url (diagnostic.option_id)); - diag_element->add_text (" "); + xp.add_text (" "); auto option_span = make_span ("gcc-option"); option_span->add_text ("["); { @@ -826,35 +1047,120 @@ html_builder::make_element_for_diagnostic (const diagnostic_info &diagnostic, option_span->add_text (option_text.get ()); option_span->add_text ("]"); } - diag_element->add_child (std::move (option_span)); + xp.append (std::move (option_span)); + } + + gcc_assert (xp.get_num_open_tags () == depth_within_message_div); + + xp.pop_tag ("div"); + + gcc_assert (xp.get_num_open_tags () == depth_within_alert_div); + + /* Show any logical location. */ + if (m_logical_loc_mgr) + if (auto client_data_hooks = m_context.get_client_data_hooks ()) + if (auto logical_loc = client_data_hooks->get_current_logical_location ()) + if (logical_loc != m_last_logical_location) + { + enum logical_location_kind kind + = m_logical_loc_mgr->get_kind (logical_loc);; + if (const char *label = get_label_for_logical_location_kind (kind)) + if (const char *name_with_scope + = m_logical_loc_mgr->get_name_with_scope (logical_loc)) + add_labelled_value (xp, "logical-location", + label, name_with_scope, true); + m_last_logical_location = logical_loc; + } + + /* Show any physical location. */ + const expanded_location s + = diagnostic_expand_location (&diagnostic); + if (s != m_last_expanded_location + || alert) + { + if (s.file + && (s.file != m_last_expanded_location.file + || alert)) + add_labelled_value (xp, "file", "File", s.file, false); + if (s.line) + { + add_labelled_value (xp, "line", "Line", std::to_string (s.line), false); + diagnostic_column_policy column_policy (m_context); + int converted_column = column_policy.converted_column (s); + if (converted_column >= 0) + add_labelled_value (xp, "column", "Column", + std::to_string (converted_column), + false); + } + if (s.file) + m_last_expanded_location = s; } /* Source (and fix-it hints). */ { - xml::printer xp (*diag_element); - m_context.m_last_location = UNKNOWN_LOCATION; + // TODO: m_context.m_last_location should be moved into the sink + location_t saved = m_context.m_last_location; + m_context.m_last_location = m_last_location; m_context.maybe_show_locus_as_html (*diagnostic.richloc, m_context.m_source_printing, diagnostic.kind, xp, nullptr, nullptr); + m_context.m_last_location = saved; + m_last_location = m_context.m_last_location; } + gcc_assert (xp.get_num_open_tags () == depth_within_alert_div); + /* Execution path. */ if (auto path = diagnostic.richloc->get_path ()) { - xml::printer xp (*diag_element); + xp.push_tag ("div"); + xp.set_attr ("id", "execution-path"); + + xp.push_tag ("label", true); + const int num_events = path->num_events (); + pretty_printer pp; + pp_printf_n (&pp, num_events, + "Execution path with %i event", + "Execution path with %i events", + num_events); + xp.add_text_from_pp (pp); + xp.pop_tag ("label"); + std::string event_id_prefix (diag_id + "-event-"); - html_path_label_writer event_label_writer (xp, *this, + html_path_label_writer event_label_writer (xp, *this, *path, event_id_prefix); + diagnostic_source_print_policy dspp (m_context); print_path_as_html (xp, *path, m_context, &event_label_writer, dspp); + + xp.pop_tag ("div"); } + gcc_assert (xp.get_num_open_tags () == depth_within_alert_div); + + // Try to display any per-diagnostic graphs + if (diagnostic.metadata) + if (auto ldg = diagnostic.metadata->get_lazy_digraphs ()) + { + auto &digraphs = ldg->get_or_create_digraphs (); + for (auto &dg : digraphs) + add_graph (*dg, *xp.get_insertion_point ()); + } + if (auto patch_element = make_element_for_patch (diagnostic)) - diag_element->add_child (std::move (patch_element)); + { + xp.push_tag ("div"); + xp.set_attr ("id", "suggested-fix"); + xp.push_tag ("label", true); + xp.add_text ("Suggested fix"); + xp.pop_tag ("label"); + xp.append (std::move (patch_element)); + xp.pop_tag ("div"); + } return diag_element; } @@ -895,7 +1201,7 @@ html_builder::make_metadata_element (label_text label, } xp.add_text (label.get ()); if (url.get ()) - xp.pop_tag (); + xp.pop_tag ("a"); } xp.add_text ("]"); return item; @@ -941,6 +1247,35 @@ html_builder::emit_diagram (const diagnostic_diagram &/*diagram*/) // TODO: currently a no-op } +void +html_builder::add_graph (const diagnostics::digraphs::digraph &dg, + xml::element &parent_element) +{ + if (auto dot_graph = dg.make_dot_graph ()) + if (auto svg_element = dot::make_svg_from_graph (*dot_graph)) + { + auto div = std::make_unique<xml::element> ("div", false); + div->set_attr ("class", "gcc-directed-graph"); + xml::printer xp (*div); + if (const char *description = dg.get_description ()) + { + xp.push_tag ("h2", true); + xp.add_text (description); + xp.pop_tag ("h2"); + } + xp.append (std::move (svg_element)); + parent_element.add_child (std::move (div)); + } +} + +void +html_builder::emit_global_graph (const diagnostics::digraphs::lazy_digraph &ldg) +{ + auto &dg = ldg.get_or_create_digraph (); + gcc_assert (m_body_element); + add_graph (dg, *m_body_element); +} + /* Implementation of "end_group_cb" for HTML output. */ void @@ -970,7 +1305,7 @@ html_builder::flush_to_file (FILE *outf) m_ui_focus_ids.print (&pp, true); pp_string (&pp, ";\n"); xp.add_raw (pp_formatted_text (&pp)); - xp.pop_tag (); // script + xp.pop_tag ("script"); } auto top = m_document.get (); top->dump (outf); @@ -996,6 +1331,12 @@ class html_output_format : public diagnostic_output_format diagnostic_output_format::dump (out, indent); } + void + set_main_input_filename (const char *name) final override + { + m_builder.set_main_input_filename (name); + } + std::unique_ptr<diagnostic_per_format_buffer> make_per_format_buffer () final override { @@ -1026,7 +1367,7 @@ class html_output_format : public diagnostic_output_format { m_builder.emit_diagram (diagram); } - void after_diagnostic (const diagnostic_info &) + void after_diagnostic (const diagnostic_info &) final override { /* No-op, but perhaps could show paths here. */ } @@ -1048,6 +1389,12 @@ class html_output_format : public diagnostic_output_format m_builder.set_printer (*get_printer ()); } + void + report_global_digraph (const diagnostics::digraphs::lazy_digraph &ldg) final override + { + m_builder.emit_global_graph (ldg); + } + const xml::document &get_document () const { return m_builder.get_document (); @@ -1155,6 +1502,62 @@ make_html_sink (diagnostic_context &context, namespace selftest { +/* Helper for writing tests of html_token_printer. + Printing to m_pp will appear as HTML within m_top_element, a <div>. */ + +struct token_printer_test +{ + token_printer_test () + : m_top_element ("div", true), + m_tok_printer (m_top_element) + { + m_pp.set_token_printer (&m_tok_printer); + } + + xml::element m_top_element; + html_token_printer m_tok_printer; + pretty_printer m_pp; +}; + +static void +test_token_printer () +{ + { + token_printer_test t; + pp_printf (&t.m_pp, "hello world"); + ASSERT_XML_PRINT_EQ + (t.m_top_element, + "<div>hello world</div>\n"); + } + + { + token_printer_test t; + pp_printf (&t.m_pp, "%qs: %qs", "foo", "bar"); + ASSERT_XML_PRINT_EQ + (t.m_top_element, + "<div>" + "`" + "<span class=\"gcc-quoted-text\">" + "foo" + "</span>" + "': `" + "<span class=\"gcc-quoted-text\">" + "bar" + "</span>" + "'" + "</div>\n"); + } + + { + token_printer_test t; + diagnostic_event_id_t event_id (0); + pp_printf (&t.m_pp, "foo %@ bar", &event_id); + ASSERT_XML_PRINT_EQ + (t.m_top_element, + "<div>foo (1) bar</div>\n"); + } +} + /* A subclass of html_output_format for writing selftests. The XML output is cached internally, rather than written out to a file. */ @@ -1171,6 +1574,7 @@ class test_html_diagnostic_context : public test_diagnostic_context line_table, html_gen_opts); sink->update_printer (); + sink->set_main_input_filename ("(main input filename)"); m_format = sink.get (); // borrowed set_output_format (std::move (sink)); @@ -1219,22 +1623,21 @@ test_simple_log () const xml::document &doc = dc.get_document (); - pretty_printer pp; - doc.write_as_xml (&pp, 0, true); - ASSERT_STREQ - (pp_formatted_text (&pp), + ASSERT_XML_PRINT_EQ + (doc, ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<!DOCTYPE html\n" " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n" " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" " <head>\n" - " <title>Title goes here\n" + " (main input filename)\n" " \n" " \n" "
\n" - "
\n" - " this is a test: `foo'\n" + "
\n" + " \n" + "
error: this is a test: `foo'
\n" "
\n" "
\n" " \n" @@ -1251,10 +1654,8 @@ test_metadata () diagnostic_metadata metadata; metadata.add_cwe (415); auto element = b.make_element_for_metadata (metadata); - pretty_printer pp; - element->write_as_xml (&pp, 0, true); - ASSERT_STREQ - (pp_formatted_text (&pp), + ASSERT_XML_PRINT_EQ + (*element, "" "
- """ diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus.py b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus.py index d963b29830b5..aca1b6cdaccd 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus.py +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus.py @@ -46,7 +46,8 @@ def test_very_wide_line(html_tree): def test_fixit_insert(html_tree): diag = get_diag_by_index(html_tree, 3) msg = get_message_within_diag(diag) - assert msg.text == 'example of insertion hints' + assert msg[0].text == 'warning: ' + assert msg[0].tail == ' example of insertion hints' src = get_locus_within_diag(diag) @@ -62,7 +63,8 @@ def test_fixit_insert(html_tree): def test_fixit_remove(html_tree): diag = get_diag_by_index(html_tree, 4) msg = get_message_within_diag(diag) - assert msg.text == 'example of a removal hint' + assert msg[0].text == 'warning: ' + assert msg[0].tail == ' example of a removal hint' src = get_locus_within_diag(diag) @@ -78,7 +80,8 @@ def test_fixit_remove(html_tree): def test_fixit_replace(html_tree): diag = get_diag_by_index(html_tree, 5) msg = get_message_within_diag(diag) - assert msg.text == 'example of a replacement hint' + assert msg[0].text == 'warning: ' + assert msg[0].tail == ' example of a replacement hint' src = get_locus_within_diag(diag) @@ -94,7 +97,8 @@ def test_fixit_replace(html_tree): def test_fixit_insert_newline(html_tree): diag = get_diag_by_index(html_tree, 6) msg = get_message_within_diag(diag) - assert msg.text == 'example of newline insertion hint' + assert msg[0].text == 'warning: ' + assert msg[0].tail == ' example of newline insertion hint' src = get_locus_within_diag(diag) diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc new file mode 100644 index 000000000000..d43216170631 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc @@ -0,0 +1,283 @@ +/* This plugin exercises diagnostic graphs. + We emit an error with a pair of digraphs associated with it, + and a global digraph showing the optimization passes. */ + +#define INCLUDE_MAP +#define INCLUDE_STRING +#define INCLUDE_VECTOR +#include "gcc-plugin.h" +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "stringpool.h" +#include "toplev.h" +#include "basic-block.h" +#include "hash-table.h" +#include "vec.h" +#include "ggc.h" +#include "basic-block.h" +#include "tree-ssa-alias.h" +#include "internal-fn.h" +#include "gimple.h" +#include "gimple-iterator.h" +#include "gimple-fold.h" +#include "tree-eh.h" +#include "gimple-expr.h" +#include "is-a.h" +#include "tree.h" +#include "tree-pass.h" +#include "intl.h" +#include "plugin-version.h" +#include "diagnostic.h" +#include "context.h" +#include "gcc-rich-location.h" +#include "diagnostic-metadata.h" +#include "diagnostic-digraphs.h" +#include "pass_manager.h" + + +int plugin_is_GPL_compatible; + +const pass_data pass_data_test_graph_emission = +{ + GIMPLE_PASS, /* type */ + "test_graph_emission", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + TV_NONE, /* tv_id */ + PROP_ssa, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_test_graph_emission : public gimple_opt_pass +{ +public: + pass_test_graph_emission(gcc::context *ctxt) + : gimple_opt_pass(pass_data_test_graph_emission, ctxt) + {} + + /* opt_pass methods: */ + bool gate (function *) { return true; } + virtual unsigned int execute (function *); + +}; // class pass_test_graph_emission + +/* Determine if STMT is a call with NUM_ARGS arguments to a function + named FUNCNAME. + If so, return STMT as a gcall *. Otherwise return NULL. */ + +static gcall * +check_for_named_call (gimple *stmt, + const char *funcname, unsigned int num_args) +{ + gcc_assert (funcname); + + gcall *call = dyn_cast (stmt); + if (!call) + return NULL; + + tree fndecl = gimple_call_fndecl (call); + if (!fndecl) + return NULL; + + if (strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), funcname)) + return NULL; + + if (gimple_call_num_args (call) != num_args) + { + error_at (stmt->location, "expected number of args: %i (got %i)", + num_args, gimple_call_num_args (call)); + return NULL; + } + + return call; +} + +class lazy_passes_graph : public diagnostics::digraphs::lazy_digraph +{ +public: + lazy_passes_graph (const ::gcc::pass_manager &pass_manager_) + : m_pass_manager (pass_manager_) + { + } + + std::unique_ptr + create_digraph () const final override + { + auto g = std::make_unique (); + g->set_description ("Optimization Passes"); + +#define DEF_PASS_LIST(NAME) \ + add_top_level_pass_list (*g, #NAME, m_pass_manager.NAME); + + GCC_PASS_LISTS + +#undef DEF_PASS_LIST + + return g; + } + + void + add_top_level_pass_list (diagnostics::digraphs::digraph &g, + const char *pass_list_name, + const opt_pass *p) const + { + gcc_assert (p); + auto n = std::make_unique (g, pass_list_name); + n->set_label (pass_list_name); + add_child_pass (g, *n, *p); + g.add_node (std::move (n)); + } + + diagnostics::digraphs::node & + add_child_pass (diagnostics::digraphs::digraph &g, + diagnostics::digraphs::node &parent_node, + const opt_pass &p) const + { + std::string node_label; + std::string node_id; + if (p.static_pass_number > 0 ) + { + node_label = std::to_string (p.static_pass_number) + "_" + p.name; + node_id = node_label; + } + else + { + node_label = std::string (p.name); + pretty_printer pp; + pp_printf (&pp, "%s_%p", p.name, &p); + node_id = pp_formatted_text (&pp); + } + auto n + = std::make_unique (g, + std::move (node_id)); + n->set_label (node_label.c_str ()); + diagnostics::digraphs::node &result = *n; + parent_node.add_child (std::move (n)); + + // TODO: add attrs for things like type, properties_*, etc + + if (p.sub) + { + auto &other_node = add_child_pass (g, parent_node, *p.sub); + g.add_edge (nullptr, result, other_node, "sub"); + } + + if (p.next) + { + auto &other_node = add_child_pass (g, parent_node, *p.next); + g.add_edge (nullptr, result, other_node, "next"); + } + + return result; + } + +private: + const ::gcc::pass_manager &m_pass_manager; +}; + +static void +report_diag_with_graphs (location_t loc) +{ + class my_lazy_digraphs : public diagnostics::digraphs::lazy_digraphs + { + public: + using diagnostic_graph = diagnostics::digraphs::digraph; + using diagnostic_node = diagnostics::digraphs::node; + using diagnostic_edge = diagnostics::digraphs::edge; + + std::unique_ptr>> + create_digraphs () const final override + { + auto graphs + = std::make_unique>> (); + + graphs->push_back (make_test_graph ("foo")); + graphs->push_back (make_test_graph ("bar")); + + return graphs; + } + + private: + std::unique_ptr + make_test_graph (const char *desc) const + { + auto g = std::make_unique (); + g->set_description (desc); + auto a = std::make_unique (*g, "a"); + auto b = std::make_unique (*g, "b"); +#define KEY_PREFIX "/placeholder-prefix/" + b->set_attr (KEY_PREFIX, "color", "red"); +#undef KEY_PREFIX + auto c = std::make_unique (*g, "c"); + c->set_label ("I am a node label"); + + auto e = std::make_unique (*g, "my-edge", *a, *c); + e->set_label ("I am an edge label"); + g->add_edge (std::move (e)); + + g->add_node (std::move (a)); + + b->add_child (std::move (c)); + g->add_node (std::move (b)); + + return g; + } + }; + + gcc_rich_location rich_loc (loc); + diagnostic_metadata meta; + my_lazy_digraphs ldg; + meta.set_lazy_digraphs (&ldg); + error_meta (&rich_loc, meta, + "this is a placeholder error, with graphs"); +} + +/* Exercise diagnostic graph emission. */ + +unsigned int +pass_test_graph_emission::execute (function *fun) +{ + gimple_stmt_iterator gsi; + basic_block bb; + + FOR_EACH_BB_FN (bb, fun) + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple *stmt = gsi_stmt (gsi); + + if (gcall *call = check_for_named_call (stmt, "here", 0)) + report_diag_with_graphs (gimple_location (call)); + } + + return 0; +} + +int +plugin_init (struct plugin_name_args *plugin_info, + struct plugin_gcc_version *version) +{ + struct register_pass_info pass_info; + const char *plugin_name = plugin_info->base_name; + int argc = plugin_info->argc; + struct plugin_argument *argv = plugin_info->argv; + + if (!plugin_default_version_check (version, &gcc_version)) + return 1; + + pass_info.pass = new pass_test_graph_emission (g); + pass_info.reference_pass_name = "ssa"; + pass_info.ref_pass_instance_number = 1; + pass_info.pos_op = PASS_POS_INSERT_AFTER; + register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, + &pass_info); + + gcc_assert (::g->get_passes ()); + global_dc->report_global_digraph (lazy_passes_graph (*::g->get_passes ())); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp index a066b67bb9a1..ce25c0ab3abd 100644 --- a/gcc/testsuite/gcc.dg/plugin/plugin.exp +++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp @@ -107,6 +107,10 @@ set plugin_test_list [list \ diagnostic-test-metadata.c \ diagnostic-test-metadata-html.c \ diagnostic-test-metadata-sarif.c } \ + { diagnostic_plugin_test_graphs.cc + diagnostic-test-graphs.c \ + diagnostic-test-graphs-html.c \ + diagnostic-test-graphs-sarif.c } \ { diagnostic_plugin_test_nesting.cc \ diagnostic-test-nesting-text-plain.c \ diagnostic-test-nesting-text-indented.c \ @@ -116,7 +120,6 @@ set plugin_test_list [list \ { diagnostic_plugin_test_paths.cc \ diagnostic-test-paths-1.c \ diagnostic-test-paths-2.c \ - diagnostic-test-paths-3.c \ diagnostic-test-paths-4.c \ diagnostic-test-paths-5.c \ diagnostic-test-paths-multithreaded-inline-events.c \ diff --git a/gcc/testsuite/gcc.dg/pr118948-1.c b/gcc/testsuite/gcc.dg/pr118948-1.c new file mode 100644 index 000000000000..2a46cf14a261 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr118948-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +/* PR c/118948 */ + +/* Used to ICE in tree_expr_nonnegative_p after an error. */ + +void f(void) { + int i; /* { dg-note "previous" } */ + for (i = 0; i < 2; i++) ; + float i; /* { dg-error "conflicting types for" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr119039-1.c b/gcc/testsuite/gcc.dg/pr119039-1.c new file mode 100644 index 000000000000..f91d5eb7139a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr119039-1.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + +extern void foo (void); +extern void bar (void); +extern void baz (void); + +/* Tests the ability to remove cases that are subranges. */ + +void +test (int i) +{ + if (i < 0 || i > 45) + return; + if (i >= 7 && i <= 8) + return; + + switch (i) + { + case 1: + bar (); + break; + case 7 ... 8: + foo (); + case 14: + baz (); + break; + default: + break; + } +} +/* { dg-final { scan-tree-dump-not "foo " "evrp" } } */ diff --git a/gcc/testsuite/gcc.dg/pr119039-2.c b/gcc/testsuite/gcc.dg/pr119039-2.c new file mode 100644 index 000000000000..634b40028209 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr119039-2.c @@ -0,0 +1,60 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + +extern void good (void); +extern void bad (void); + +/* Switch simplification should remove 'case 2:' because 'i' will always + * have its 0th bit set (odd). */ + +void bitmask_elimination_1(int i) +{ + i = i | 1; + + switch (i) + { + case 1: + good (); + break; + + // This case should be removed; + case 2: + bad (); + break; + + case 3: + good (); + break; + + default: + break; + } +} + +/* Switch simplification should remove 'case 20-28:' because 'i' will always + * be a multiple of 16. */ +void bitmask_elimination_2 (int i) +{ + int masked_val = i & 0xF0; // This zeroes out the lower 4 bits of 'i' + + switch (masked_val) + { + case 0: + good (); // Reachable. + break; + + // This entire cased should be removed; + case 20 ... 28: + bad (); + break; + + case 32: + good (); // Reachable. + break; + + default: + good (); + break; + } +} +/* { dg-final { scan-tree-dump-not "bad" "evrp" } } */ diff --git a/gcc/testsuite/gcc.dg/pr119160.c b/gcc/testsuite/gcc.dg/pr119160.c index 5743b3b76036..c3d9b811f163 100644 --- a/gcc/testsuite/gcc.dg/pr119160.c +++ b/gcc/testsuite/gcc.dg/pr119160.c @@ -4,6 +4,19 @@ typedef __attribute__((__vector_size__ (32))) int V; +/* Add empty implementations of __cyg_profile_func_enter() and + __cyg_profile_func_exit() to avoid problems on non-glibc + systems. */ +void __attribute__((no_instrument_function)) +__cyg_profile_func_enter(void *this_fn, void *call_site) +{ +} + +void __attribute__((no_instrument_function)) +__cyg_profile_func_exit(void *this_fn, void *call_site) +{ +} + void foo (V v, V, V, V *r) { diff --git a/gcc/testsuite/gcc.dg/pr120303.c b/gcc/testsuite/gcc.dg/pr120303.c new file mode 100644 index 000000000000..caeff9290abd --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr120303.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c2y" } */ + +int t = _Generic (char(1)); /* { dg-error "before numeric constant" } */ + diff --git a/gcc/testsuite/gcc.dg/pr120510.c b/gcc/testsuite/gcc.dg/pr120510.c new file mode 100644 index 000000000000..d99c329c1d7f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr120510.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c23" } */ + +void f (int [_Atomic]); +void f (int [_Atomic]); +void f (int [_Atomic]); + diff --git a/gcc/testsuite/gcc.dg/pr120630.c b/gcc/testsuite/gcc.dg/pr120630.c new file mode 100644 index 000000000000..14b0aaf103d9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr120630.c @@ -0,0 +1,25 @@ +/* PR middle-end/120630 */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-tree-loop-im -fno-tree-loop-optimize -fno-tree-ch" } */ + +int a, c, d; + +void +foo (int b) +{ + a = b; +} + +int +main () +{ + while (d) + ; + for (c = 0; c > -3; c--) + { + long f = c; + foo (f >> 2); + } + if (a != -1) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/pr120638.c b/gcc/testsuite/gcc.dg/pr120638.c new file mode 100644 index 000000000000..4a057a028474 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr120638.c @@ -0,0 +1,31 @@ +/* PR tree-optimization/120638 */ +/* { dg-do run } */ +/* { dg-options "-O2 -ffast-math" } */ + +extern float sqrtf (float x); + +__attribute__((noipa)) float +foo (unsigned int s) +{ + return 0.5f / sqrtf (1.f + s); +} + +__attribute__((noipa)) float +bar (float s) +{ + if (s < 0.0 || s > 65535.0f) + __builtin_unreachable (); + return 0.5f / sqrtf (1.f + s); +} + +int +main () +{ + if (__builtin_fabsf (foo (3) - 0.25f) > 0.00390625f + || __builtin_fabsf (foo (15) - 0.125f) > 0.00390625f + || __builtin_fabsf (foo (63) - 0.0625f) > 0.00390625f + || __builtin_fabsf (bar (3.0f) - 0.25f) > 0.00390625f + || __builtin_fabsf (bar (15.0f) - 0.125f) > 0.00390625f + || __builtin_fabsf (bar (63.0f) - 0.0625f) > 0.00390625f) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/pr120661-1.c b/gcc/testsuite/gcc.dg/pr120661-1.c new file mode 100644 index 000000000000..abf9210050d4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr120661-1.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c23 -Os" } */ + +typedef __builtin_va_list __gnuc_va_list; +typedef __gnuc_va_list va_list; + +int e, a, b; +int f(int b, ...) { + va_list args; + __builtin_c23_va_start(args, b); + unsigned c = 1; + for (int d; d < b; ++d) + c = c ^ 1; + return c; +} +static int fn3(int l, int i, int n) { + int j; + goto k; +r: + j = (f(e) + 1641730381) * l + 1189664732 * n + 1064 * i - 1545337304; + if (903562339 * j + n >= 0) + goto m; + goto ac; +k: + if (0) + goto ad; + goto t; +ad: + if (b) + goto s; + goto r; +m: + goto ad; +t: + j = l; + l = 800794 * j; + goto ad; +s: + b = 2 * b + 1; + if (a + (long)j) + goto t; + i = n; + goto s; +ac: +} +int main() { + if (a) + if (fn3(-1, 1, -1)) + fn3(1, 0, 3); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr120661-2.c b/gcc/testsuite/gcc.dg/pr120661-2.c new file mode 100644 index 000000000000..05d976db450b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr120661-2.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c23 -O2" } */ + +typedef __builtin_va_list __gnuc_va_list; +typedef __gnuc_va_list va_list; + +int a, c, d; +int e(int b, ...) { + va_list args; + __builtin_c23_va_start(args, b); + + int r = 0; + for (int i = 0; i < b; i++) { + int v = __builtin_va_arg(args, int); + r += v; + } + __builtin_va_end (args); + return r; +} +int f() { e(0); } +int main() { + int h = 0, g = 0; + goto l; +i: + if (f() * h) + goto k; +j: + h = h - 2; +k: + d = 1200000000 * h + 10; + g = (long)g + -1000000000 * d + 1; + if (a * h >= 0) { + if (g + (c - (long)1) >= 0) + goto i; + return 0; + } +l: + goto j; +} diff --git a/gcc/testsuite/gcc.dg/pr120701.c b/gcc/testsuite/gcc.dg/pr120701.c new file mode 100644 index 000000000000..09f7b6192eda --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr120701.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int a, b, c, e, f; +int main() { + int d, g, i; +j: + if (d >= 0) + goto k; + if (g >= 0) + goto l; +k: + i = a + 3; +m: + f = 652685095 + 818172564 * g; + if (-1101344938 * f - 1654872807 * d >= 0) + goto n; + goto l; +o: + if (i) { + c = -b; + if (-c >= 0) + goto l; + g = b; + b = i + 5; + if (b * c) + goto n; + goto o; + } + if (e) + goto m; + goto j; +n: + d = 978208086 * g - 1963072513; + if (d + i) + return 0; + goto k; +l: + goto o; +} diff --git a/gcc/testsuite/gcc.dg/pr121035.c b/gcc/testsuite/gcc.dg/pr121035.c new file mode 100644 index 000000000000..fc0edce5d7d3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr121035.c @@ -0,0 +1,94 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fgimple" } */ + +int printf(const char *, ...); +int a, b, d; +unsigned c; +int __GIMPLE (ssa,startwith("pre")) +main () +{ + unsigned int g; + int f; + unsigned int _1; + unsigned int _2; + int _3; + int _4; + int _5; + unsigned int _6; + unsigned int _7; + int _10; + unsigned int _11; + _Bool _19; + _Bool _20; + _Bool _22; + int _25; + + __BB(2): + _25 = a; + if (_25 != 0) + goto __BB11; + else + goto __BB10; + + __BB(11): + goto __BB3; + + __BB(3): + f_26 = __PHI (__BB12: f_18, __BB11: 0); + g_15 = c; + if (f_26 != 0) + goto __BB4; + else + goto __BB5; + + __BB(4): + __builtin_putchar (48); + goto __BB5; + + __BB(5): + _1 = c; + _2 = _1 << 1; + _3 = a; + _4 = d; + _5 = _3 * _4; + if (_5 != 0) + goto __BB7; + else + goto __BB6; + + __BB(6): + goto __BB7; + + __BB(7): + _11 = __PHI (__BB5: 0u, __BB6: 4294967295u); + _6 = g_15 * 4294967294u; + _7 = _6 | _11; + _20 = _3 != 0; + _19 = _7 != 0u; + _22 = _19 & _20; + if (_22 != _Literal (_Bool) 0) + goto __BB9; + else + goto __BB8; + + __BB(8): + goto __BB9; + + __BB(9): + _10 = __PHI (__BB7: 1, __BB8: 0); + b = _10; + f_18 = (int) _1; + if (_3 != 0) + goto __BB12; + else + goto __BB10; + + __BB(12): + goto __BB3; + + __BB(10): + return 0; + +} + + diff --git a/gcc/testsuite/gcc.dg/pr121202.c b/gcc/testsuite/gcc.dg/pr121202.c new file mode 100644 index 000000000000..30ecf4a5e01a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr121202.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-tree-copy-prop" } */ + +int a, b, c; +int e(int f, int g) { return f >> g; } +int h(int f) { return a > 1 ? 0 : f << a; } +int main() { + while (c--) + b = e(h(1), a); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr32450.c b/gcc/testsuite/gcc.dg/pr32450.c index 9606e3021eab..0af262f5c673 100644 --- a/gcc/testsuite/gcc.dg/pr32450.c +++ b/gcc/testsuite/gcc.dg/pr32450.c @@ -4,6 +4,7 @@ /* { dg-require-profiling "-pg" } */ /* { dg-options "-O2 -pg" } */ /* { dg-options "-O2 -pg -mtune=core2" { target { i?86-*-* x86_64-*-* } } } */ +/* { dg-additional-options "-mfentry -fno-pic" { target i?86-*-gnu* x86_64-*-gnu* } } */ /* { dg-options "-O2 -pg -static" { target hppa*-*-hpux* } } */ extern void abort (void); diff --git a/gcc/testsuite/gcc.dg/pr43643.c b/gcc/testsuite/gcc.dg/pr43643.c index 43896abd85af..41c00c8a2af8 100644 --- a/gcc/testsuite/gcc.dg/pr43643.c +++ b/gcc/testsuite/gcc.dg/pr43643.c @@ -4,6 +4,7 @@ /* { dg-require-profiling "-pg" } */ /* { dg-options "-O2 -pg" } */ /* { dg-options "-O2 -pg -static" { target hppa*-*-hpux* } } */ +/* { dg-additional-options "-mfentry -fno-pic" { target i?86-*-gnu* x86_64-*-gnu* } } */ extern char *strdup (const char *); diff --git a/gcc/testsuite/gcc.dg/pr87600-1.c b/gcc/testsuite/gcc.dg/pr87600-1.c index 351795756a31..9d74cadb0110 100644 --- a/gcc/testsuite/gcc.dg/pr87600-1.c +++ b/gcc/testsuite/gcc.dg/pr87600-1.c @@ -1,5 +1,5 @@ /* PR rtl-optimization/87600 */ -/* { dg-do compile { target aarch64*-*-* arm*-*-* i?86-*-* powerpc*-*-* s390*-*-* x86_64-*-* } } */ +/* { dg-do compile { target aarch64*-*-* arm*-*-* i?86-*-* loongarch*-*-* powerpc*-*-* s390*-*-* x86_64-*-* } } */ /* { dg-options "-O2" } */ #include "pr87600.h" diff --git a/gcc/testsuite/gcc.dg/pr87600-2.c b/gcc/testsuite/gcc.dg/pr87600-2.c index e8a9f194b733..822afe04ef1d 100644 --- a/gcc/testsuite/gcc.dg/pr87600-2.c +++ b/gcc/testsuite/gcc.dg/pr87600-2.c @@ -1,5 +1,5 @@ /* PR rtl-optimization/87600 */ -/* { dg-do compile { target aarch64*-*-* arm*-*-* i?86-*-* powerpc*-*-* s390*-*-* x86_64-*-* } } */ +/* { dg-do compile { target aarch64*-*-* arm*-*-* i?86-*-* loongarch*-*-* powerpc*-*-* s390*-*-* x86_64-*-* } } */ /* { dg-options "-O2" } */ #include "pr87600.h" @@ -23,22 +23,3 @@ test1 (void) asm ("blah %0 %1" : "=r" (var1) : "0" (var2)); /* { dg-error "invalid hard register usage between output operand and matching constraint operand" } */ return var1; } - -long -test2 (void) -{ - register long var1 asm (REG1); - register long var2 asm (REG1); - asm ("blah %0 %1" : "=&r" (var1) : "r" (var2)); /* { dg-error "invalid hard register usage between earlyclobber operand and input operand" } */ - return var1; -} - -long -test3 (void) -{ - register long var1 asm (REG1); - register long var2 asm (REG1); - long var3; - asm ("blah %0 %1" : "=&r" (var1), "=r" (var3) : "1" (var2)); /* { dg-error "invalid hard register usage between earlyclobber operand and input operand" } */ - return var1 + var3; -} diff --git a/gcc/testsuite/gcc.dg/pr87600-3.c b/gcc/testsuite/gcc.dg/pr87600-3.c new file mode 100644 index 000000000000..4f43a5f71ad0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr87600-3.c @@ -0,0 +1,26 @@ +/* PR rtl-optimization/87600 */ +/* { dg-do compile { target aarch64*-*-* arm*-*-* i?86-*-* powerpc*-*-* s390*-*-* x86_64-*-* } } */ +/* { dg-options "-O2" } */ + +#include "pr87600.h" + +/* The following are all invalid uses of local register variables. */ + +long +test2 (void) +{ + register long var1 asm (REG1); + register long var2 asm (REG1); + asm ("blah %0 %1" : "=&r" (var1) : "r" (var2)); /* { dg-error "invalid hard register usage between earlyclobber operand and input operand" } */ + return var1; +} + +long +test3 (void) +{ + register long var1 asm (REG1); + register long var2 asm (REG1); + long var3; + asm ("blah %0 %1" : "=&r" (var1), "=r" (var3) : "1" (var2)); /* { dg-error "invalid hard register usage between earlyclobber operand and input operand" } */ + return var1 + var3; +} diff --git a/gcc/testsuite/gcc.dg/pr87600.h b/gcc/testsuite/gcc.dg/pr87600.h index c89071eb7891..29f065e1d058 100644 --- a/gcc/testsuite/gcc.dg/pr87600.h +++ b/gcc/testsuite/gcc.dg/pr87600.h @@ -7,6 +7,9 @@ #elif defined (__i386__) # define REG1 "%eax" # define REG2 "%edx" +#elif defined (__loongarch__) +# define REG1 "$t0" +# define REG2 "$t1" #elif defined (__powerpc__) || defined (__POWERPC__) || defined (__PPC__) # define REG1 "r3" # define REG2 "r4" diff --git a/gcc/testsuite/gcc.dg/rtl/aarch64/vec-series-1.c b/gcc/testsuite/gcc.dg/rtl/aarch64/vec-series-1.c new file mode 100644 index 000000000000..6f795c68ba45 --- /dev/null +++ b/gcc/testsuite/gcc.dg/rtl/aarch64/vec-series-1.c @@ -0,0 +1,35 @@ +/* { dg-do compile { target aarch64*-*-* } } */ +/* { dg-options "-O2 -msve-vector-bits=256 -mlittle-endian" } */ + +#include + +#pragma GCC target "+sve" + +svint64x2_t __RTL (startwith ("vregs")) foo () +{ + (function "foo" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 1 [bb 2] NOTE_INSN_BASIC_BLOCK) + (cnote 2 NOTE_INSN_FUNCTION_BEG) + (insn 3 (set (reg:VNx4DI <0>) + (const_vector:VNx4DI [(const_int 11) + (const_int 12) + (const_int 13) + (const_int 14) + (const_int 15) + (const_int 16) + (const_int 17) + (const_int 18)]))) + (insn 4 (set (reg:VNx4DI v0) (reg:VNx4DI <0>))) + (insn 5 (use (reg:VNx4DI v0))) + (edge-to exit (flags "FALLTHRU")) + ) ;; block 2 + ) ;; insn-chain + (crtl (return_rtx (reg:VNx4DI v0))) + ) ;; function +} + +/* { dg-final { scan-assembler {\tindex\tz0\.d, #11, #1\n} } } */ +/* { dg-final { scan-assembler {\tindex\tz1\.d, #15, #1\n} } } */ diff --git a/gcc/testsuite/gcc.dg/rtl/aarch64/vec-series-2.c b/gcc/testsuite/gcc.dg/rtl/aarch64/vec-series-2.c new file mode 100644 index 000000000000..17e46cbc03c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/rtl/aarch64/vec-series-2.c @@ -0,0 +1,35 @@ +/* { dg-do compile { target aarch64*-*-* } } */ +/* { dg-options "-O2 -msve-vector-bits=256 -mlittle-endian" } */ + +#include + +#pragma GCC target "+sve" + +svint64x2_t __RTL (startwith ("vregs")) foo () +{ + (function "foo" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 1 [bb 2] NOTE_INSN_BASIC_BLOCK) + (cnote 2 NOTE_INSN_FUNCTION_BEG) + (insn 3 (set (reg:VNx4DI <0>) + (const_vector:VNx4DI [(const_int -16) + (const_int -15) + (const_int -14) + (const_int -13) + (const_int -12) + (const_int -11) + (const_int -10) + (const_int -9)]))) + (insn 4 (set (reg:VNx4DI v0) (reg:VNx4DI <0>))) + (insn 5 (use (reg:VNx4DI v0))) + (edge-to exit (flags "FALLTHRU")) + ) ;; block 2 + ) ;; insn-chain + (crtl (return_rtx (reg:VNx4DI v0))) + ) ;; function +} + +/* { dg-final { scan-assembler {\tindex\tz0\.d, #-16, #1\n} } } */ +/* { dg-final { scan-assembler {\tindex\tz1\.d, #-12, #1\n} } } */ diff --git a/gcc/testsuite/gcc.dg/torture/builtin-math-9.c b/gcc/testsuite/gcc.dg/torture/builtin-math-9.c new file mode 100644 index 000000000000..ff79ee5dfd3b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/builtin-math-9.c @@ -0,0 +1,86 @@ +/* Copyright (C) 1988-2025 Free Software Foundation, Inc. + + Verify that built-in math function constant folding of constant + arguments is correctly performed by the compiler. */ + +/* { dg-do link } */ +/* { dg-require-effective-target foldable_pi_based_trigonometry } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ + +extern double acospi (double); +extern double asinpi (double); +extern double atanpi (double); +extern double atan2pi (double, double); +extern double cospi (double); +extern double sinpi (double); +extern double tanpi (double); + +/* All references to link_error should go away at compile-time. */ +extern void link_error (void); + +void +test_normal () +{ + if (acospi (0.5) < 0.3333 || acospi (0.5) > 0.3334 || acospi (-0.5) < 0.6666 + || acospi (-0.5) > 0.6667) + link_error (); + + if (asinpi (0.5) < 0.1666 || asinpi (0.5) > 0.1667 || asinpi (-0.5) < -0.1667 + || asinpi (-0.5) > -0.1666) + link_error (); + + if (atanpi (1.0) != 0.25 || atanpi (-1.0) > -0.25) + link_error (); + + if (atan2pi (1.0, 1.0) > 0.2501 || atan2pi (1.0, 1.0) < 0.2499 + || atan2pi (1.0, -1.0) < 0.7499 || atan2pi (1.0, -1.0) > 0.7501) + link_error (); + + if (cospi (1.0 / 3) > 0.5001 || cospi (-1.0 / 3) < 0.4999 + || cospi (4.0 / 3) > -0.4999 || cospi (4.0 / 3) < -0.5001) + link_error (); + + if (sinpi (1.0 / 6) > 0.5001 || sinpi (-1.0 / 6) > -0.4999 + || sinpi (5.0 / 6) < 0.4999 || sinpi (-7.0 / 6) > 0.5001) + link_error (); + + if (tanpi (0.25) != 1.0000 || tanpi (-0.25) != -1.0000 + || tanpi (1.25) != 1.0000 || tanpi (-1.25) != -1.0000) + link_error (); +} + +void +test_corner () +{ + if (__builtin_signbit (acospi (1.0))) + link_error (); + + if (__builtin_signbit (asinpi (0.0)) || !__builtin_signbit (asinpi (-0.0))) + link_error (); + + if (__builtin_signbit (atanpi (0.0)) || !__builtin_signbit (atanpi (-0.0))) + link_error (); + + if (__builtin_signbit (atan2pi (0.0, 0.0)) + || !__builtin_signbit (atan2pi (-0.0, 0.0)) || atan2pi (0.0, -0.0) != 1 + || atan2pi (-0.0, -0.0) != -1) + link_error (); + + if (__builtin_signbit (cospi (0.5)) || __builtin_signbit (cospi (-0.5))) + link_error (); + + if (__builtin_signbit (sinpi (1)) || !__builtin_signbit (sinpi (-1))) + link_error (); + + if (__builtin_signbit (tanpi (2)) || __builtin_signbit (tanpi (-3)) + || !__builtin_signbit (tanpi (5)) || !__builtin_signbit (tanpi (-6))) + link_error (); +} + +int +main () +{ + test_normal (); + test_corner (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr117811.c b/gcc/testsuite/gcc.dg/torture/pr117811.c index 13d7e1347807..05e8622f25e3 100644 --- a/gcc/testsuite/gcc.dg/torture/pr117811.c +++ b/gcc/testsuite/gcc.dg/torture/pr117811.c @@ -18,8 +18,13 @@ void __attribute__((noclone,noinline)) do_shift (v4 *vec, int shift) int main () { +#if __SIZEOF_INT__ >= 4 v4 vec = {0x1000000, 0x2000, 0x300, 0x40}; v4 vec2 = {0x100000, 0x200, 0x30, 0x4}; +#else + v4 vec = {0x4000, 0x2000, 0x300, 0x40}; + v4 vec2 = {0x400, 0x200, 0x30, 0x4}; +#endif do_shift (&vec, 4); if (memcmp (&vec, &vec2, sizeof (v4)) != 0) __builtin_abort (); diff --git a/gcc/testsuite/gcc.dg/torture/pr120242.c b/gcc/testsuite/gcc.dg/torture/pr120242.c new file mode 100644 index 000000000000..2d0f7dedd033 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr120242.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fsigned-char -fno-strict-aliasing -fwrapv" } */ + +char f1(char a, char b) { + return b == 0 ? a : b; +} +int f2(int a, int b) { + return b ? a : 0; +} +struct l { + unsigned m; + int n; +}; +struct l ae; +char af = -2; +unsigned ah = 4; +int aj = 8; +int *test = &aj; +int main() { +ao: + if (f2(f1(4, af++), *test) <= 0) { + for (; ae.n; ae.n++) + ; + if (ah) + goto ao; + } + if (af != 1) + __builtin_abort (); + __builtin_exit (0); +} diff --git a/gcc/testsuite/gcc.dg/torture/pr120627.c b/gcc/testsuite/gcc.dg/torture/pr120627.c new file mode 100644 index 000000000000..f83cd533b8b3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr120627.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fsigned-char -fno-strict-aliasing -fwrapv" } */ + +unsigned char sub(unsigned char t, unsigned char u) { return t - u; } +unsigned char mul(unsigned char t, unsigned char u) { return t * u; } +int x(int aa, int ab) { + return ab >= 32 || aa > 18446744073709551615UL >> ab ? aa : aa << ab; +} +int ag; +int ah = 249; +char ap; +static short ar[5][9]; +int *as = &ag; +void bf(char cf) { + for (; ap <= 8; ap++) { + (ar[1][7] = mul(x(-1L, sub(cf, 247) / cf), ag <= 0)) || ar[1][4]++; + *as = ag; + } + return; +} +int main() { + bf(ah); + if (ar[1][7] != 255) + __builtin_abort (); + __builtin_exit (0); +} + diff --git a/gcc/testsuite/gcc.dg/torture/pr120654.c b/gcc/testsuite/gcc.dg/torture/pr120654.c new file mode 100644 index 000000000000..aacfeea29c9c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr120654.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ + +int a, c, e, f, h, j; +long g, k; +int b(int m) { + if (m || a) + return 1; + return 0.0f; +} +int d(int m, int p2) { return b(m) + m + (1 + p2 + p2); } +int i() { + long l[] = {2, 9, 7, 8, g, g, 9, 0, 2, g}; + e = l[c] << 6; +} +void n() { + long o; + int *p = __builtin_malloc(sizeof(int)); + k = 1 % j; + for (; i() + f + h; o++) + if (p[d(j + 6, (int)k + 1992695866) + h + f + j + (int)k - 1 + o]) + __builtin_free(p); +} diff --git a/gcc/testsuite/gcc.dg/torture/pr120736.c b/gcc/testsuite/gcc.dg/torture/pr120736.c new file mode 100644 index 000000000000..84f808a5992b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr120736.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fsigned-char -fno-strict-aliasing -fwrapv" } */ + +unsigned char aa (unsigned char ab, int o) { return ab > o ? ab : 0; } +int p; +int s; +static unsigned char q = 255; +int r; +int *v = &s; +int main() { + p = v != 0; + for (; r < 8; ++r) { + if (s) + break; + s = aa(p * q++, 6) <= 0; + } + if (q != 1) + __builtin_abort (); + __builtin_exit (0); +} + diff --git a/gcc/testsuite/gcc.dg/torture/pr120813.c b/gcc/testsuite/gcc.dg/torture/pr120813.c new file mode 100644 index 000000000000..16adbe5d427c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr120813.c @@ -0,0 +1,27 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fsigned-char -fno-strict-aliasing -fwrapv" } */ + +short s (short t, short u) { return u == 0 ? 0 : t / u; } +int x[6]; +int y; +unsigned ak = 1; +unsigned short al = 65527; +unsigned *am = &ak; +int main() { + for (int i = 0; i < 6; i++) { + x[i] = i; + } + for (;;) { + unsigned long ar = 2080554998UL; + char as = 4; + if (s(34, al++) < ar) + if (*am) + break; + } + y = x[al & 5]; + if ((y ^ 5UL) != 4) + __builtin_abort (); + __builtin_exit (0); +} + + diff --git a/gcc/testsuite/gcc.dg/torture/pr120944.c b/gcc/testsuite/gcc.dg/torture/pr120944.c new file mode 100644 index 000000000000..92f3c7749963 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr120944.c @@ -0,0 +1,34 @@ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ +/* { dg-additional-options "-fdump-tree-optimized" } */ + +#include + +typedef union { + int u32; + struct + { + int A:1; + int B:2; + int C:3; + }; +} u_t; + +typedef union { + volatile int u[3]; + volatile struct { + u_t a; + int b; + int c; + }; +} DATA; + +void foo (volatile DATA *d) +{ + d->a.u32 = ~0; + u_t u = d->a; + int v = u.A; + if (v) + abort(); +} + +/* { dg-final { scan-tree-dump-times "if \\\(" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/pr120951-1.c b/gcc/testsuite/gcc.dg/torture/pr120951-1.c new file mode 100644 index 000000000000..4e2b41deb52b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr120951-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-fnon-call-exceptions -fsignaling-nans" } */ + +/* PR tree-optimization/120951 */ + +/* cdce would create a trapping comparison inside a condition. + tests to make sure that does not happen. */ + +double f(double r, double i) { + return __builtin_fmod(r, i); +} + diff --git a/gcc/testsuite/gcc.dg/torture/pr121116.c b/gcc/testsuite/gcc.dg/torture/pr121116.c new file mode 100644 index 000000000000..637324fb4fde --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr121116.c @@ -0,0 +1,21 @@ +/* { dg-do run { target bitint } } */ + +#include +#include +#include +typedef _BitInt(16) bit16; +[[nodiscard]] static bit16 process_data(bit16 input) { + _Static_assert(sizeof(bit16) == 2, "Unexpected size of bit16"); + return (input << 5) | (input >> 9); +} +int main(void) { + const bit16 data = 0b101'0101'0000'0000; + bit16 result = 0; + for (bit16 i = 0; i < 0b1000; ++i) { + result ^= process_data(data ^ i); + } + if (ckd_add(&result, result, 0x1234)) { + return EXIT_FAILURE; + } + return (result & 0xFF00) ? 0 : 1; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr121194.c b/gcc/testsuite/gcc.dg/torture/pr121194.c new file mode 100644 index 000000000000..20f5ff7184ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr121194.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +int a, b, c, d; +void e() { + int *f = &b; + for (a = 0; a < 8; a++) { + *f = 0; + for (c = 0; c < 2; c++) + *f = *f == 0; + } +} +int main() { + e(); + int *g = &b; + *g = *g == (d == 0); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-prof/afdo-crossmodule-1.c b/gcc/testsuite/gcc.dg/tree-prof/afdo-crossmodule-1.c new file mode 100644 index 000000000000..574a08585e6d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/afdo-crossmodule-1.c @@ -0,0 +1,29 @@ +/* { dg-require-effective-target lto } */ +/* { dg-additional-sources "afdo-crossmodule-1b.c" } */ +/* { dg-options "-O3 -flto -fdump-ipa-afdo_offline -fdump-tree-einline-details" } */ +/* { dg-require-profiling "-fauto-profile" } */ +volatile int c; + +int foo2 () +{ + c++; + return 1; +} +int foo (int (*fooptr) ()) +{ + return fooptr (); +} +extern int bar (int (*fooptr) (int (*)())); + +int +main() +{ + int n = 1000000; + int s = 0; + for (int i = 0; i < n; i++) + s += bar (foo); + return n != s; +} +/* { dg-final-use-autofdo { scan-ipa-dump "Removing external inline: main:5 bar" "afdo_offline"} } */ +/* { dg-final-use-autofdo { scan-ipa-dump "Offlining function inlined to other module: bar:2 foo" "afdo_offline"} } */ +/* { dg-final-use-autofdo { scan-tree-dump "Indirect call -> speculative call foo.. => foo2" "einline"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-prof/afdo-crossmodule-1b.c b/gcc/testsuite/gcc.dg/tree-prof/afdo-crossmodule-1b.c new file mode 100644 index 000000000000..79ba529c7475 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/afdo-crossmodule-1b.c @@ -0,0 +1,15 @@ +/* { dg-require-effective-target lto } */ +/* { dg-additional-sources "afdo-crossmodule-1.c" } */ +/* { dg-options "-O3 -flto -fdump-ipa-afdo_offline -fdump-tree-einline-details" } */ +/* { dg-require-profiling "-fauto-profile" } */ + +extern int foo2 (); + +int bar (int (*fooptr) (int (*)())) +{ + return fooptr (foo2); +} +/* { dg-final-use-autofdo { scan-ipa-dump "Offlining function inlined to other module: main:5 bar" "afdo_offline"} } */ +/* { dg-final-use-autofdo { scan-ipa-dump "Offlining function inlined to other module: bar:2 main:5 foo" "afdo_offline"} } */ +/* It would be nice to speculate call to foo, but offlining does not preserve jump target + and currently afdo does not do cross-module indirect call promotion. */ diff --git a/gcc/testsuite/gcc.dg/tree-prof/afdo-inline.c b/gcc/testsuite/gcc.dg/tree-prof/afdo-inline.c new file mode 100644 index 000000000000..ded406866416 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/afdo-inline.c @@ -0,0 +1,36 @@ +/* { dg-options "-O2 -fdump-tree-einline-details --param early-inlining-insns=1" } */ +/* { dg-require-profiling "-fauto-profile" } */ +volatile int a[1000]; + +#define STR1(X) #X +#define STR2(X) STR1(X) + +int reta (int i) +asm(STR2(__USER_LABEL_PREFIX__) "renamed_reta"); +int test () +asm(STR2(__USER_LABEL_PREFIX__) "renamed_test"); + +int reta (int i) +{ + if (a[i]) + __builtin_printf ("It is one\n"); + if (a[i] == 2) + __builtin_printf ("It is two\n"); + return a[i]; +} +int test () +{ + int s = 0; + for (int pos = 0; pos < 1000; pos++) + reta(pos); + if (s) + __builtin_printf ("sum error\n"); +} +int main() +{ + for (int i = 0; i < 10000; i++) + test(); + return 0; +} +/* { dg-final-use-autofdo { scan-tree-dump "Inlining using auto-profile test" "einline"} } */ +/* { dg-final-use-autofdo { scan-tree-dump "Inlining using auto-profile reta.*transitively inlined to main" "einline"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-prof/afdo-vpt-earlyinline.c b/gcc/testsuite/gcc.dg/tree-prof/afdo-vpt-earlyinline.c new file mode 100644 index 000000000000..b5c9024108b7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/afdo-vpt-earlyinline.c @@ -0,0 +1,38 @@ +/* { dg-options "-O2 -fdump-ipa-afdo-details -fdump-tree-einline-details --param early-inlining-insns=1" } */ +/* { dg-require-profiling "-fauto-profile" } */ + +volatile int array[1000]; +int reta (int i) +{ + return array[i]; +} +struct wrapptr +{ + int (*ret)(int); +}; +int test (struct wrapptr *p) +{ + int s = 0; + int (*ret)(int) = p->ret; + for (int pos = 0; pos < 1000; pos++) + ret(pos); + if (s) + __builtin_printf ("sum error\n"); +} +int main() +{ + for (int i = 0; i < 10000; i++) + { + struct wrapptr p={reta}; + + + + test(&p); + } + return 0; +} +/* { dg-final-use-autofdo { scan-tree-dump "Inlining using auto-profile test" "einline"} } */ +/* { dg-final-use-autofdo { scan-tree-dump "Checking indirect call -> direct call ret_" "einline"} } */ +/* { dg-final-use-autofdo { scan-tree-dump "looks good" "einline"} } */ +/* If we inlined reta->test->main, it will contian array[pos]. */ +/* { dg-final-use-autofdo { scan-tree-dump "array.pos_" "einline"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-prof/clone-merge-1.c b/gcc/testsuite/gcc.dg/tree-prof/clone-merge-1.c new file mode 100644 index 000000000000..904dd0cfb28a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/clone-merge-1.c @@ -0,0 +1,34 @@ +/* { dg-options "-O3 -fno-early-inlining -fdump-ipa-afdo_offline-all" } */ +/* { dg-require-profiling "-fauto-profile" } */ + +__attribute__ ((used)) +int a[1000]; + +__attribute__ ((noinline)) +void +test2(int sz) +{ + a[sz]++; + asm volatile (""::"m"(a)); +} + +__attribute__ ((noinline)) +void +test1 (int sz) +{ + for (int i = 0; i < 1000; i++) + if (i % 2) + test2 (sz); + else + test2 (i); + +} +int main() +{ + for (int i = 0; i < 1000; i++) + test1 (1000); + return 0; +} +/* We will have profiles for test2 and test2.constprop.0 that will have to be + merged, */ +/* { dg-final-use-autofdo { scan-ipa-dump "Merging duplicate instance: test2" "afdo_offline"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-prof/clone-test.c b/gcc/testsuite/gcc.dg/tree-prof/clone-test.c new file mode 100644 index 000000000000..74d648bf915c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/clone-test.c @@ -0,0 +1,63 @@ +/* { dg-options "-O3 -fno-early-inlining -fdump-ipa-afdo-all" } */ +/* { dg-require-profiling "-fauto-profile" } */ + +#define N 5000 +__attribute__ ((used)) +int a[N+1]; + +__attribute__ ((noinline)) +static void +test2(int sz) +{ + a[sz]++; + asm volatile (""::"m"(a)); +} + +struct list +{ + struct list *next; + int val; +}; + +__attribute__ ((noinline)) +static int +test3(volatile struct list l, int v) +{ + a [(l.val + v) % N] = v; +} + +__attribute__ ((noinline)) +void +test1 (int sz) +{ + volatile struct list l = {0}; + __attribute__ ((noinline)) + void inner(int i) + { + if (i % 2) + test2 (500); + if (i % 3) + test3 (l,200); + else + test2 (i); + } + for (int i = 0; i < N; i++) + inner(i); + +} + +int main() +{ + for (int i = 0; i < N; i++) + { + test1 (N); + } + return 0; +} +/* Profile will have test1.constprop.0 */ +/* { dg-final-use-autofdo { scan-ipa-dump "Annotating BB profile of test1" "afdo"} } */ +/* { dg-final-use-autofdo { scan-ipa-dump "Annotating BB profile of test2" "afdo"} } */ +/* Profile will have test3.constprop.0.isra.0 */ +/* { dg-final-use-autofdo { scan-ipa-dump "Annotating BB profile of test3" "afdo"} } */ +/* { dg-final-use-autofdo { scan-ipa-dump "Annotating BB profile of inner" "afdo"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c index 1d64d9f3f622..b6c0e4a85b9d 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c +++ b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -fno-early-inlining -fdump-ipa-profile-optimized -fdump-ipa-afdo-optimized" } */ +/* { dg-options "-O2 -fno-early-inlining -fdump-ipa-profile-details -fdump-tree-einline-details" } */ volatile int one; static int add1 (int val) @@ -31,5 +31,5 @@ main (void) } /* { dg-final-use-not-autofdo { scan-ipa-dump "Indirect call -> direct call.* add1 .will resolve by ipa-profile" "profile"} } */ /* { dg-final-use-not-autofdo { scan-ipa-dump "Indirect call -> direct call.* sub1 .will resolve by ipa-profile" "profile"} } */ -/* { dg-final-use-autofdo { scan-ipa-dump "Inlining add1/1 into main/4." "afdo"} } */ -/* { dg-final-use-autofdo { scan-ipa-dump "Inlining sub1/2 into main/4." "afdo"} } */ +/* { dg-final-use-autofdo { scan-tree-dump "Inlining using auto-profile add1/. into do_op/. which is transitively inlined to main/" "einline"} } */ +/* { dg-final-use-autofdo { scan-tree-dump "Inlining using auto-profile sub1/. into do_op/. which is transitively inlined to main/" "einline"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cmp-2.c b/gcc/testsuite/gcc.dg/tree-ssa/cmp-2.c new file mode 100644 index 000000000000..9b029019c06f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/cmp-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-forwprop" } */ + +/* PR tree-optimization/110949 */ +/* Transform `(cmp) - 1` into `-icmp`. */ + +int f1(int a) +{ + int t = a == 115; + return t - 1; +} + +/* { dg-final { scan-tree-dump " != 115" "forwprop1" } } */ +/* { dg-final { scan-tree-dump-not " == 115" "forwprop1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-1.c new file mode 100644 index 000000000000..801a53fa30bd --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-1.c @@ -0,0 +1,19 @@ + /* { dg-do compile } */ + /* { dg-options "-O2 -ftree-vectorize -fdump-tree-ifcvt-stats" } */ + +void +test (int *dst, float *arr, int *pred, int n) +{ + for (int i = 0; i < n; i++) + { + int pred_i = pred[i]; + float arr_i = arr[i]; + + dst[i] = pred_i ? (int)arr_i : 5; + } +} + +/* We expect this to fail if_convertible_loop_p so long as we have no + conditional IFN for FIX_TRUNC_EXPR. */ + +/* { dg-final { scan-tree-dump-times "Applying if-conversion" 0 "ifcvt" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-2.c new file mode 100644 index 000000000000..628b754e94d9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-2.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math -fdump-tree-ifcvt-stats" } */ + +#include "ifcvt-fix-trunc-1.c" + +/* { dg-final { scan-tree-dump-times "Applying if-conversion" 1 "ifcvt" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/max-bitcmp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/max-bitcmp-1.c new file mode 100644 index 000000000000..81b5a27c0458 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/max-bitcmp-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-forwprop -fdump-tree-optimized" } */ + +/* PR tree-optimization/95906 */ +/* this should become MAX_EXPR */ + +int f2(int a, int b) +{ + int cmp = -(a > b); + return (cmp & a) | (~cmp & b); +} + +/* we should not end up with -_2 */ +/* we should not end up and & nor a `+ -1` */ +/* In optimized we should have a max. */ +/* { dg-final { scan-tree-dump-not " -\[a-zA-Z_\]" "forwprop1" } } */ +/* { dg-final { scan-tree-dump-not " & " "forwprop1" } } */ +/* { dg-final { scan-tree-dump-not " . -1" "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR " 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phiprop-2.c b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-2.c index 7181787db5eb..ae0d181a43ac 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/phiprop-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -fdump-tree-phiopt2 -fdump-tree-phiprop1-details" } */ +/* { dg-options "-O1 -fdump-tree-phiopt1 -fdump-tree-phiprop1-details" } */ /* PR tree-optimization/116824 */ @@ -24,5 +24,4 @@ int g(int i, int *tt) /* Check that phiprop1 can do the insert of the loads. */ /* { dg-final { scan-tree-dump-times "Inserting PHI for result of load" 1 "phiprop1"} } */ -/* Should be able to get MIN_EXPR in phiopt2 after cselim and phiprop. */ -/* { dg-final { scan-tree-dump-times "MIN_EXPR " 1 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times "MIN_EXPR " 1 "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr117423.c b/gcc/testsuite/gcc.dg/tree-ssa/pr117423.c new file mode 100644 index 000000000000..a5d3b29886f8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr117423.c @@ -0,0 +1,49 @@ +/* { dg-do run } */ +/* { dg-options "-O1" } */ + +struct s4 { + int _0; +}; +struct s1 { + unsigned char _4; + long _1; +}; +struct s2 { + union { + struct s3 { + unsigned char _1; + struct s4 _0; + } var_0; + struct s1 var_1; + } DATA; +}; +int f1(int arg0) { return arg0 > 12345; } +__attribute__((noinline)) +struct s4 f2(int arg0) { + struct s4 rv = {arg0}; + return rv; +} +struct s2 f3(int arg0) { + struct s2 rv; + struct s1 var6 = {0}; + struct s4 var7; + if (f1(arg0)) { + rv.DATA.var_1 = var6; + return rv; + } else { + rv.DATA.var_0._1 = 2; + var7 = f2(arg0); + rv.DATA.var_0._0 = var7; + return rv; + } +} +int main() { + if (f3(12345).DATA.var_0._0._0 == 12345) + ; + else + __builtin_abort(); + if (f3(12344).DATA.var_0._0._0 == 12344) + ; + else + __builtin_abort(); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr120231-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr120231-2.c new file mode 100644 index 000000000000..d2b41baacda7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr120231-2.c @@ -0,0 +1,107 @@ +/* PR tree-optimization/120231 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-add-options float64 } */ +/* { dg-require-effective-target float64 } */ +/* { dg-final { scan-tree-dump-not "link_failure \\\(\\\);" "optimized" } } */ + +void link_failure (void); + +static _Float64 __attribute__((noinline)) +f1 (signed char x) +{ + return x; +} + +static _Float64 __attribute__((noinline)) +f2 (signed char x) +{ + if (x >= -37 && x <= 42) + return x; + return 0.0f64; +} + +void +f3 (signed char x) +{ + _Float64 y = f1 (x); + if (y < (_Float64) (-__SCHAR_MAX__ - 1) || y > (_Float64) __SCHAR_MAX__) + link_failure (); + y = f2 (x); + if (y < -37.0f64 || y > 42.0f64) + link_failure (); +} + +static _Float64 __attribute__((noinline)) +f4 (long long x) +{ + return x; +} + +static _Float64 __attribute__((noinline)) +f5 (long long x) +{ + if (x >= -0x3ffffffffffffffeLL && x <= 0x3ffffffffffffffeLL) + return x; + return 0.0f64; +} + +void +f6 (long long x) +{ + _Float64 y = f4 (x); + if (y < (_Float64) (-__LONG_LONG_MAX__ - 1) || y > (_Float64) __LONG_LONG_MAX__) + link_failure (); + y = f5 (x); + if (y < (_Float64) -0x3ffffffffffffffeLL || y > (_Float64) 0x3ffffffffffffffeLL) + link_failure (); +} + +static signed char __attribute__((noinline)) +f7 (_Float64 x) +{ + if (x >= -78.5f64 && x <= 98.25f64) + return x; + return 0; +} + +static unsigned char __attribute__((noinline)) +f8 (_Float64 x) +{ + if (x >= -0.75f64 && x <= 231.625f64) + return x; + return 31; +} + +static long long __attribute__((noinline)) +f9 (_Float64 x) +{ + if (x >= -3372587051122780362.75f64 && x <= 3955322825938799366.25f64) + return x; + return 0; +} + +static unsigned long long __attribute__((noinline)) +f10 (_Float64 x) +{ + if (x >= 31.25f64 && x <= 16751991430751148048.125f64) + return x; + return 4700; +} + +void +f11 (_Float64 x) +{ + signed char a = f7 (x); + if (a < -78 || a > 98) + link_failure (); + unsigned char b = f8 (x); + if (b > 231) + link_failure (); + long long c = f9 (x); + if (c < -3372587051122780160LL || c > 3955322825938799616LL) + link_failure (); + unsigned long long d = f10 (x); + if (d < 31 || d > 16751991430751148032ULL) + link_failure (); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr120231-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr120231-3.c new file mode 100644 index 000000000000..d578c5b669f2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr120231-3.c @@ -0,0 +1,40 @@ +/* PR tree-optimization/120231 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-add-options float64 } */ +/* { dg-require-effective-target float64 } */ +/* { dg-final { scan-tree-dump-not "link_failure \\\(\\\);" "optimized" } } */ + +void link_failure (void); + +void +foo (long long x) +{ + _Float64 y = x; + if (y >= -8577328745032543176.25f64 && y <= 699563045341050951.75f64) + { + if (x < -8577328745032544256LL || x > 699563045341051136LL) + link_failure (); + } + if (y >= -49919160463252.125f64 && y <= 757060336735329.625f64) + { + if (x < -49919160463252LL || x > 757060336735329LL) + link_failure (); + } +} + +void +bar (_Float64 x) +{ + long long y = x; + if (y >= -6923230004751524066LL && y <= 2202103129706786704LL) + { + if (x < -6923230004751524864.0f64 || x > 2202103129706786816.0f64) + link_failure (); + } + if (y >= -171621738469699LL && y <= 45962470357748LL) + { + if (x <= -1716217384696970.f64 || x >= 45962470357749.0f64) + link_failure (); + } +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr35286.c b/gcc/testsuite/gcc.dg/tree-ssa/pr35286.c index 4429cc857bf6..b4f8c7ce4fce 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr35286.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr35286.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-code-hoisting -fno-tree-cselim -fdump-tree-pre-stats" } */ +/* { dg-options "-O2 -fno-code-hoisting -fno-tree-cselim -fno-ssa-phiopt -fdump-tree-pre-stats" } */ int g2; struct A { int a; int b; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c index 71e6362b10c8..e2b0a9571f0d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fdump-tree-split-paths-details -fno-finite-loops -fno-tree-dominator-opts -fno-tree-vrp -w" } */ +/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fno-ssa-phiopt -fdump-tree-split-paths-details -fno-finite-loops -fno-tree-dominator-opts -fno-tree-vrp -w" } */ struct __sFILE { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c index 252fe06c666a..35634ab3bd86 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fno-tree-sink -fdump-tree-split-paths-details -w" } */ +/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fno-ssa-phiopt -fno-tree-sink -fdump-tree-split-paths-details -w" } */ struct _reent diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c index 59891f29132c..1c2cfa4fa8d5 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c @@ -11,8 +11,8 @@ to change decisions in switch expansion which in turn can expose new jump threading opportunities. Skip the later tests on aarch64. */ /* { dg-final { scan-tree-dump-not "Jumps threaded" "dom3" { target { ! aarch64*-*-* } } } } */ -/* { dg-final { scan-tree-dump "Jumps threaded: 10" "thread2" { target { ! aarch64*-*-* } } } } */ -/* { dg-final { scan-tree-dump "Jumps threaded: 17" "thread2" { target { aarch64*-*-* } } } } */ +/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread2" { target { ! aarch64*-*-* } } } } */ +/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread2" { target { aarch64*-*-* } } } } */ enum STATE { S0=0, diff --git a/gcc/testsuite/gcc.dg/ubsan/pr120837.c b/gcc/testsuite/gcc.dg/ubsan/pr120837.c new file mode 100644 index 000000000000..97c85c751790 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/pr120837.c @@ -0,0 +1,32 @@ +/* PR c/120837 */ +/* { dg-do run } */ +/* { dg-options "-O1 -fsanitize=undefined -fno-sanitize-recover=undefined" } */ + +[[gnu::noipa]] void +bar (void **x, void **y) +{ + x[0] = 0; + x[1] = 0; + x[2] = 0; + y[0] = 0; + y[1] = 0; + y[2] = 0; + y[3] = 0; + y[4] = 0; +} + +[[gnu::noipa]] void * +foo (int x, int y) +{ + void *a[3]; + void *b[5]; + bar (a, b); + return (x > y ? b : a)[y - 1]; +} + +int +main () +{ + if (foo (2, 1) != 0) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/uninit-pr120924.c b/gcc/testsuite/gcc.dg/uninit-pr120924.c new file mode 100644 index 000000000000..bfc8ae9fd508 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr120924.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wmaybe-uninitialized" } */ + +int foo(int); +enum { + BPF_TRACE_RAW_TP, + BPF_MODIFY_RETURN, + BPF_LSM_MAC, + BPF_TRACE_ITER, + BPF_LSM_CGROUP +}; +int btf_get_kernel_prefix_kind_prefix, obj_1, attach_name___trans_tmp_1; +char attach_name_fn_name; +void attach_name(int attach_type) +{ + int mod_len; + char mod_name = attach_name_fn_name; + if (attach_name_fn_name) + mod_len = mod_name; + for (; obj_1;) { + if (mod_name && foo(mod_len)) + continue; + switch (attach_type) { + case BPF_TRACE_RAW_TP: + case BPF_LSM_MAC: + case BPF_LSM_CGROUP: + btf_get_kernel_prefix_kind_prefix = 1; + case BPF_TRACE_ITER: + attach_name_fn_name = 2; + } + if (attach_name___trans_tmp_1) + return; + } +} diff --git a/gcc/testsuite/gcc.dg/unused-9.c b/gcc/testsuite/gcc.dg/unused-9.c index bdf36e1f50e8..ad1ad0ec8abc 100644 --- a/gcc/testsuite/gcc.dg/unused-9.c +++ b/gcc/testsuite/gcc.dg/unused-9.c @@ -2,12 +2,9 @@ /* { dg-do compile } */ /* { dg-options "-Wunused" } */ - void g(void) { - int i = 0; - volatile int x; - (x, i++); /* { dg-bogus "set but not used" } */ + int i = 0; /* { dg-warning "variable 'i' set but not used" } */ + volatile int x; /* { dg-bogus "variable 'x' set but not used" } */ + (x, i++); } - - diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-39.c b/gcc/testsuite/gcc.dg/vect/bb-slp-39.c index f05ce8f2847b..255bb1095dc5 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-39.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-39.c @@ -16,5 +16,4 @@ void foo (double *p) } /* See that we vectorize three SLP instances. */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "slp2" { target { ! { s390*-*-* riscv*-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 5 "slp2" { target { s390*-*-* riscv*-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "slp2" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr120808.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr120808.c new file mode 100644 index 000000000000..acb7472279a6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr120808.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ffp-contract=on" } */ +/* { dg-additional-options "-mfma -mfpmath=sse" { target { x86_64-*-* i?86-*-* } } } */ + +void f(double x[restrict], double *y, double *z) +{ + x[0] = x[0] * y[0] + z[0]; + x[1] = x[1] * y[1] - z[1]; +} + +/* The following should check for SLP build covering the loads. */ +/* { dg-final { scan-tree-dump "Found VEC_FMSUBADD pattern" "slp2" { target { x86_64-*-* i?86-*-* } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr101145.c b/gcc/testsuite/gcc.dg/vect/pr101145.c index cd11c030d576..c055ae6359fc 100644 --- a/gcc/testsuite/gcc.dg/vect/pr101145.c +++ b/gcc/testsuite/gcc.dg/vect/pr101145.c @@ -2,7 +2,7 @@ /* { dg-additional-options "-O3" } */ #include -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) foo (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) { while (n < ++l) @@ -10,7 +10,7 @@ foo (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) foo_1 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned) { while (UINT_MAX - 64 < ++l) @@ -18,7 +18,7 @@ foo_1 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) foo_2 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) { l = UINT_MAX - 32; @@ -27,7 +27,7 @@ foo_2 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) foo_3 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) { while (n <= ++l) @@ -35,7 +35,7 @@ foo_3 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) foo_4 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) { // infininate while (0 <= ++l) @@ -43,7 +43,7 @@ foo_4 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) foo_5 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) { //no loop @@ -53,7 +53,7 @@ foo_5 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) bar (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) { while (--l < n) @@ -61,7 +61,7 @@ bar (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) bar_1 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned) { while (--l < 64) @@ -69,7 +69,7 @@ bar_1 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) bar_2 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) { l = 32; diff --git a/gcc/testsuite/gcc.dg/vect/pr120817.c b/gcc/testsuite/gcc.dg/vect/pr120817.c new file mode 100644 index 000000000000..199189a8b9ad --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr120817.c @@ -0,0 +1,41 @@ +/* { dg-additional-options "-O1" } */ +/* { dg-require-effective-target aarch64_sve_hw { target aarch64*-*-* } } */ +/* { dg-additional-options "-march=armv8-a+sve -mtune=neoverse-n2" { target aarch64*-*-* } } */ + +#include "tree-vect.h" + +typedef struct { + int _M_current; +} __normal_iterator; + +typedef struct { + char _M_elems[5]; +} array_5; + +__normal_iterator __trans_tmp_1 = {-5}; + +__attribute__((noipa)) +array_5 copySourceIntoTarget() { + array_5 target; + char* target_it = target._M_elems; + + while (__trans_tmp_1._M_current != 0) { + *target_it = 1; + __trans_tmp_1._M_current++; + target_it++; + } + + return target; +} + +int main () +{ + check_vect (); + + array_5 res = copySourceIntoTarget(); + +#pragma GCC novector + for (int i = 0; i < 5; i++) + if (res._M_elems[i] != 1) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/vect/pr120922.c b/gcc/testsuite/gcc.dg/vect/pr120922.c new file mode 100644 index 000000000000..1a7247a4b2f5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr120922.c @@ -0,0 +1,18 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-additional-options "-fsigned-char -fno-strict-aliasing -fwrapv" } */ +/* { dg-additional-options "-march=rv64gcv_zvl1024b -mrvv-vector-bits=zvl -mrvv-max-lmul=m8 -O3" { target { riscv_v } } } */ + +char g; +unsigned char h; +int i[9][6]; +int main() { + int k[5]; + if (g) + goto l; + for (; h <= 5; h++) + i[0][h] = *k; +l: + return 0; +} + +/* { dg-final { scan-tree-dump "loop vectorized" "vect" { target riscv_v } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr121034.c b/gcc/testsuite/gcc.dg/vect/pr121034.c new file mode 100644 index 000000000000..de207814aa91 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr121034.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3" } */ + +int b, e; +char c, d; +unsigned g; +int abs(int); +void f() { + char *a = &d; + int h; + for (; e; e++) { + h = 0; + for (; h < 16; h++) + g += __builtin_abs(a[h] - c); + a += b; + } +} diff --git a/gcc/testsuite/gcc.dg/vect/pr121049.c b/gcc/testsuite/gcc.dg/vect/pr121049.c new file mode 100644 index 000000000000..558c92ab884d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr121049.c @@ -0,0 +1,25 @@ +/* { dg-additional-options "--param vect-partial-vector-usage=1" } */ +/* { dg-additional-options "-march=x86-64-v4" { target avx512f_runtime } } */ + +#include "tree-vect.h" + +int mon_lengths[12] = { 1, 10, 100 }; + +__attribute__ ((noipa)) long +transtime (int mon) +{ + long value = 0; + for (int i = 0; i < mon; ++i) + value += mon_lengths[i] * 2l; + return value; +} + +int +main () +{ + check_vect (); + if (transtime (3) != 222) + __builtin_abort (); + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/vect/pr121059.c b/gcc/testsuite/gcc.dg/vect/pr121059.c new file mode 100644 index 000000000000..2bbfcead86da --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr121059.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3 --param vect-partial-vector-usage=1" } */ +/* { dg-additional-options "-march=x86-64-v4" { target avx512f } } */ + +typedef struct { + long left, right, top, bottom; +} MngBox; +typedef struct { + MngBox object_clip[6]; + char exists[256], frozen[]; +} MngReadInfo; +MngReadInfo mng_info; + +long ReadMNGImage_i; + +void ReadMNGImage(int ReadMNGImage_i) +{ + for (; ReadMNGImage_i < 256; ReadMNGImage_i++) + if (mng_info.exists[ReadMNGImage_i] && mng_info.frozen[ReadMNGImage_i]) + mng_info.object_clip[ReadMNGImage_i].left = + mng_info.object_clip[ReadMNGImage_i].right = + mng_info.object_clip[ReadMNGImage_i].top = + mng_info.object_clip[ReadMNGImage_i].bottom = 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr121126.c b/gcc/testsuite/gcc.dg/vect/pr121126.c new file mode 100644 index 000000000000..ae6603bb1e5f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr121126.c @@ -0,0 +1,30 @@ +/* { dg-additional-options "--param vect-partial-vector-usage=2" } */ + +#include "tree-vect.h" + +unsigned char a; +unsigned b; +int r[11]; +static void __attribute__((noipa)) +c(int e, unsigned s[][11][11]) +{ + for (int u = -(e ? 2000424973 : 0) - 2294542319; u < 7; u += 4) + for (int x = 0; x < 300000011; x += 4) + for (int y = 0; y < (0 < s[u][4][1]) + 11; y += 3) { + a = a ?: 1; + b = r[2]; + } +} +long long ab; +int e = 1; +unsigned s[11][11][11]; +int main() +{ + check_vect (); + for (int t = 0; t < 11; ++t) + r[t] = 308100; + c(e,s); + ab = b; + if (ab != 308100) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/vect/slp-28.c b/gcc/testsuite/gcc.dg/vect/slp-28.c index 67b7be29b22b..1f987874f0df 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-28.c +++ b/gcc/testsuite/gcc.dg/vect/slp-28.c @@ -59,8 +59,8 @@ main1 () abort (); } - /* Not vectorizable because of data dependencies: distance 3 is greater than - the actual VF with SLP (2), but the analysis fail to detect that for now. */ + /* Dependence distance 3 is greater than the actual VF with SLP (2), + thus vectorizable. */ for (i = 3; i < N/4; i++) { in3[i*4] = in3[(i-3)*4] + 5; @@ -91,7 +91,6 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! vect32 } } } } */ -/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target vect32 } } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { ! vect32 } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-127.c b/gcc/testsuite/gcc.dg/vect/vect-127.c new file mode 100644 index 000000000000..8b913dcf944f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-127.c @@ -0,0 +1,15 @@ +// { dg-do compile } +// { dg-require-effective-target vect_int } + +void foo (int *p) +{ + for (int i = 0; i < 1024; ++i) + { + int a0 = p[2*i + 0]; + int a1 = p[2*i + 1]; + p[2*i + 4] = a0; + p[2*i + 5] = a1; + } +} + +/* { dg-final { scan-tree-dump "loop vectorized using 16 byte vectors" "vect" { target { vect128 && vect_hw_misalign } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_133_pfa6.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_133_pfa6.c index ee123df6ed2b..7787d037d9dc 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-early-break_133_pfa6.c +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_133_pfa6.c @@ -20,4 +20,4 @@ unsigned test4(char x, char *vect_a, char *vect_b, int n) return ret; } -/* { dg-final { scan-tree-dump "Versioning for alignment will be applied" "vect" } } */ +/* { dg-final { scan-tree-dump "Both peeling and versioning will be applied" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-pr120927-2.c b/gcc/testsuite/gcc.dg/vect/vect-pr120927-2.c new file mode 100644 index 000000000000..e38cebeb9201 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-pr120927-2.c @@ -0,0 +1,24 @@ +/* { dg-additional-options "--param vect-partial-vector-usage=1" } */ +/* { dg-additional-options "-mavx512bw -mavx512vl" { target avx512f_runtime } } */ + +#include "tree-vect.h" + +static const double __attribute__((aligned(__BIGGEST_ALIGNMENT__))) a[] = { 1., 2., 3., 4., 5. }; + +void __attribute__((noipa)) +foo (double *b, double *bp, double c, int n) +{ + for (int i = 0; i < n; ++i) + b[i] = bp[i] = a[i] * c; +} + +int main() +{ + double b[6], bp[6]; + b[5] = bp[5] = 13.; + check_vect (); + foo (b, bp, 3., 5); + if (b[5] != 13. || bp[5] != 13.) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-pr120927.c b/gcc/testsuite/gcc.dg/vect/vect-pr120927.c new file mode 100644 index 000000000000..793593f758f2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-pr120927.c @@ -0,0 +1,24 @@ +/* { dg-additional-options "--param vect-partial-vector-usage=1" } */ +/* { dg-additional-options "-mavx512bw -mavx512vl" { target avx512f_runtime } } */ + +#include "tree-vect.h" + +static const double a[] = { 1., 2., 3., 4., 5. }; + +void __attribute__((noipa)) +foo (double *b, double *bp, double c, int n) +{ + for (int i = 0; i < n; ++i) + b[i] = bp[i] = a[i] * c; +} + +int main() +{ + double b[6], bp[6]; + b[5] = bp[5] = 13.; + check_vect (); + foo (b, bp, 3., 5); + if (b[5] != 13. || bp[5] != 13.) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-cond-1.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-cond-1.c new file mode 100644 index 000000000000..258f17e3d366 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-cond-1.c @@ -0,0 +1,60 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_condition } */ + +#include +#include "tree-vect.h" + +/* PR tree-optimization/119920 */ + +#define N 32 + +unsigned int ub[N]; + +/* Test vectorization of reduction of unsigned-int. */ + +__attribute__ ((noinline, noipa)) +void init(void) +{ + #pragma GCC novector + for(int i = 0;i < N; i++) + ub[i] = i; +} + + +__attribute__ ((noinline, noipa)) +void main1 (unsigned int b, unsigned int c) +{ + int i; + unsigned int usum = 0; + + init(); + + /* Summation. */ + for (i = 0; i < N; i++) { + if ( ub[i] < N/2 ) + { + usum += b; + } + else + { + usum += c; + } + } + + /* check results: */ + /* __builtin_printf("%d : %d\n", usum, (N/2*b + N/2*c)); */ + if (usum != N/2*b + N/2*c) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (0, 0); + main1 (1, 1); + main1 (10, 1); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_int_add } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-cond-2.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-cond-2.c new file mode 100644 index 000000000000..126a50f3e56f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-cond-2.c @@ -0,0 +1,62 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_condition } */ +/* { dg-additional-options "-fdump-tree-ifcvt-details" } */ + +#include +#include "tree-vect.h" + +/* PR tree-optimization/119920 */ + +#define N 32 + +unsigned int ub[N]; +unsigned int ua[N]; + +/* Test vectorization of reduction of unsigned-int. */ + +__attribute__ ((noinline, noipa)) +void init(void) +{ + #pragma GCC novector + for(int i = 0;i < N; i++) { + ub[i] = i; + ua[i] = 1; + } +} + + +__attribute__ ((noinline, noipa)) +void main1 (unsigned int b, unsigned int c) +{ + int i; + unsigned int usum = 0; + + init(); + + /* Summation. */ + for (i = 0; i < N; i++) { + unsigned t = ua[i]; + if ( ub[i] < N/2 ) + usum += b * t; + else + usum += c * t; + } + + /* check results: */ + /* __builtin_printf("%d : %d\n", usum, (N/2*b*1 + N/2*c*1)); */ + if (usum != N/2*b + N/2*c) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (0, 0); + main1 (1, 1); + main1 (10, 1); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_int_add } } } } */ +/* { dg-final { scan-tree-dump-times "changed to factor operation out from COND_EXPR" 2 "ifcvt" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-cond-3.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-cond-3.c new file mode 100644 index 000000000000..e425869ccf9f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-cond-3.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" + +/* PR tree-optimization/112324 */ +/* PR tree-optimization/110015 */ + +#define N 32 + +int ub[N]; + +/* Test vectorization of reduction of int max with some extra code involed. */ + +__attribute__ ((noinline, noipa)) +void init(void) +{ + #pragma GCC novector + for(int i = 0;i < N; i++) + ub[i] = (i&4) && (i&1) ? -i : i; +} + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +__attribute__ ((noinline, noipa)) +void main1 (void) +{ + int i; + int max = 0; + + init(); + + /* Summation. */ + for (i = 0; i < N; i++) { + int tmp = ub[i]; + if (tmp < 0) + max = MAX (-tmp, max); + else + max = MAX (tmp, max); + } + + /* check results: */ + /* __builtin_printf("%d : %d\n", max, N); */ + if (max != N - 1) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_int_min_max } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-fma-1.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-fma-1.c new file mode 100644 index 000000000000..e958b43e23b6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-fma-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-mfma" { target { x86_64-*-* i?86-*-* } } } */ + +double f(double x[], long n) +{ + double r0 = 0, r1 = 0; + for (; n; x += 2, n--) { + r0 = __builtin_fma(x[0], x[0], r0); + r1 = __builtin_fma(x[1], x[1], r1); + } + return r0 + r1; +} + +/* We should vectorize this as SLP reduction. */ +/* { dg-final { scan-tree-dump "loop vectorized using 16 byte vectors and unroll factor 1" "vect" { target { x86_64-*-* i?86-*-* } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-fma-2.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-fma-2.c new file mode 100644 index 000000000000..ea1ca9720e5a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-fma-2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ffp-contract=on" } */ +/* { dg-additional-options "-mfma" { target { x86_64-*-* i?86-*-* } } } */ + +static double muladd(double x, double y, double z) +{ + return x * y + z; +} +double g(double x[], long n) +{ + double r0 = 0, r1 = 0; + for (; n; x += 2, n--) { + r0 = muladd(x[0], x[0], r0); + r1 = muladd(x[1], x[1], r1); + } + return r0 + r1; +} + +/* We should vectorize this as SLP reduction. */ +/* { dg-final { scan-tree-dump "loop vectorized using 16 byte vectors and unroll factor 1" "vect" { target { x86_64-*-* i?86-*-* } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-fma-3.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-fma-3.c new file mode 100644 index 000000000000..10cecedd8e5f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-fma-3.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ffast-math" } */ +/* { dg-additional-options "-mfma" { target { x86_64-*-* i?86-*-* } } } */ + +double f(double x[], long n) +{ + double r0 = 0, r1 = 0; + for (; n; x += 2, n--) { + r0 = __builtin_fma(x[0], x[0], r0); + r1 = __builtin_fma(x[1], x[1], r1); + } + return r0 + r1; +} + +/* We should vectorize this as SLP reduction, higher VF possible. */ +/* { dg-final { scan-tree-dump "optimized: loop vectorized" "vect" { target { x86_64-*-* i?86-*-* } } } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/asm-hard-reg-1.c b/gcc/testsuite/gcc.target/aarch64/asm-hard-reg-1.c new file mode 100644 index 000000000000..7441dd7def01 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/asm-hard-reg-1.c @@ -0,0 +1,55 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* Ensure that we error out in case no hard regs are available for an operand + with constraint y. The position/order of the y-constrained operand does not + matter. */ + +void +test (void) +{ + int x, a, b, c, d, e, f, g, h; + + __asm__ __volatile__ ("" : + "={v0}" (a), + "={v1}" (b), + "={v2}" (c), + "={v3}" (d), + "={v4}" (e), + "={v5}" (f), + "={v6}" (g), + "={v7}" (h)); + + __asm__ __volatile__ ("" : /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + "=y" (x), + "={v0}" (a), + "={v1}" (b), + "={v2}" (c), + "={v3}" (d), + "={v4}" (e), + "={v5}" (f), + "={v6}" (g), + "={v7}" (h)); + + __asm__ __volatile__ ("" : /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + "={v0}" (a), + "={v1}" (b), + "={v2}" (c), + "={v3}" (d), + "=y" (x), + "={v4}" (e), + "={v5}" (f), + "={v6}" (g), + "={v7}" (h)); + + __asm__ __volatile__ ("" : /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + "={v0}" (a), + "={v1}" (b), + "={v2}" (c), + "={v3}" (d), + "={v4}" (e), + "={v5}" (f), + "={v6}" (g), + "={v7}" (h), + "=y" (x)); +} diff --git a/gcc/testsuite/gcc.target/aarch64/asm-hard-reg-2.c b/gcc/testsuite/gcc.target/aarch64/asm-hard-reg-2.c new file mode 100644 index 000000000000..7434063646ce --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/asm-hard-reg-2.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv8-a+sve" } */ + +/* Test register pairs. */ + +#include + +void +test (void) +{ + svuint32x2_t x, y; + svuint32x4_t z; + + __asm__ __volatile__ ("" : "={z4}" (x), "={z6}" (y)); + __asm__ __volatile__ ("" : "={z5}" (x), "={z6}" (y)); /* { dg-error "multiple outputs to hard register: v6" } */ + __asm__ __volatile__ ("" : "={z4}" (z), "={z6}" (y)); /* { dg-error "multiple outputs to hard register: v6" } */ +} diff --git a/gcc/testsuite/gcc.target/aarch64/autovec_param_asimd-only_2.c b/gcc/testsuite/gcc.target/aarch64/autovec_param_asimd-only_2.c new file mode 100644 index 000000000000..6aeac0b76f4b --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/autovec_param_asimd-only_2.c @@ -0,0 +1,4 @@ +/* { dg-options "-mautovec-preference=asimd-only" } */ + +void +foo (void) {} diff --git a/gcc/testsuite/gcc.target/aarch64/autovec_param_default_2.c b/gcc/testsuite/gcc.target/aarch64/autovec_param_default_2.c new file mode 100644 index 000000000000..589cc502fdad --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/autovec_param_default_2.c @@ -0,0 +1,4 @@ +/* { dg-options "-mautovec-preference=default" } */ + +void +foo (void) {} diff --git a/gcc/testsuite/gcc.target/aarch64/autovec_param_prefer-asimd_2.c b/gcc/testsuite/gcc.target/aarch64/autovec_param_prefer-asimd_2.c new file mode 100644 index 000000000000..ad8978649926 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/autovec_param_prefer-asimd_2.c @@ -0,0 +1,4 @@ +/* { dg-options "-mautovec-preference=prefer-asimd" } */ + +void +foo (void) {} diff --git a/gcc/testsuite/gcc.target/aarch64/autovec_param_prefer-sve_2.c b/gcc/testsuite/gcc.target/aarch64/autovec_param_prefer-sve_2.c new file mode 100644 index 000000000000..2acea69e056d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/autovec_param_prefer-sve_2.c @@ -0,0 +1,4 @@ +/* { dg-options "-mautovec-preference=prefer-sve" } */ + +void +foo (void) {} diff --git a/gcc/testsuite/gcc.target/aarch64/autovec_param_sve-only_2.c b/gcc/testsuite/gcc.target/aarch64/autovec_param_sve-only_2.c new file mode 100644 index 000000000000..a7df0ebda807 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/autovec_param_sve-only_2.c @@ -0,0 +1,4 @@ +/* { dg-options "-mautovec-preference=sve-only" } */ + +void +foo (void) {} diff --git a/gcc/testsuite/gcc.target/aarch64/avoid-store-forwarding-be.c b/gcc/testsuite/gcc.target/aarch64/avoid-store-forwarding-be.c new file mode 100644 index 000000000000..2e8946b25e34 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/avoid-store-forwarding-be.c @@ -0,0 +1,23 @@ +/* { dg-do run } */ +/* { dg-require-effective-target aarch64_big_endian } */ +/* { dg-options "-O2 -favoid-store-forwarding" } */ + +typedef union { + char arr[2]; + short value; +} DataUnion; + +short __attribute__ ((noinline)) +ssll (DataUnion *data, char x, char y) +{ + data->arr[0] = x; + data->arr[1] = y; + return data->value; +} + +int main () { + DataUnion data = {}; + short value = ssll (&data, 0, 1); + if (value != 1) + __builtin_abort (); +} \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/aarch64/bti-1.c b/gcc/testsuite/gcc.target/aarch64/bti-1.c index 5a556b08ed15..53dc2d3cd8b2 100644 --- a/gcc/testsuite/gcc.target/aarch64/bti-1.c +++ b/gcc/testsuite/gcc.target/aarch64/bti-1.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* -Os to create jump table. */ -/* { dg-options "-Os" } */ +/* { dg-options "-Os -dA" } */ /* { dg-require-effective-target lp64 } */ /* If configured with --enable-standard-branch-protection, don't use command line option. */ @@ -44,8 +44,8 @@ f_jump_table (int y, int n) return (y == 0)? y+1:4; } /* f_jump_table should have PACIASP and AUTIASP. */ -/* { dg-final { scan-assembler-times "hint\t25" 1 } } */ -/* { dg-final { scan-assembler-times "hint\t29" 1 } } */ +/* { dg-final { scan-assembler-times "hint\t25 // paciasp" 1 } } */ +/* { dg-final { scan-assembler-times "hint\t29 // autiasp" 1 } } */ int f_label_address () @@ -59,6 +59,7 @@ f_label_address () addr = &&lab1; return 2; } -/* { dg-final { scan-assembler-times "hint\t34" 1 } } */ -/* { dg-final { scan-assembler-times "hint\t36" 12 } } */ -/* { dg-final { scan-assembler ".note.gnu.property" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler-times "hint\t34 // bti c" 1 } } */ +/* { dg-final { scan-assembler-times "hint\t36 // bti j" 12 } } */ +/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" { target *-*-linux* } } } */ +/* { dg-final { scan-assembler "\.word\t0x7\t\/\/ GNU_PROPERTY_AARCH64_FEATURE_1_AND \\(BTI, PAC, GCS\\)" { target *-*-linux* } } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/aarch64-build-attributes.exp b/gcc/testsuite/gcc.target/aarch64/build-attributes/aarch64-build-attributes.exp new file mode 100644 index 000000000000..c106c93c5ada --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/aarch64-build-attributes.exp @@ -0,0 +1,35 @@ +# Copyright (C) 2024-2025 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't an AArch64 target. +if ![istarget aarch64*-*-*] then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \ + "" "" + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-bti.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-bti.c new file mode 100644 index 000000000000..363a6de56ab0 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-bti.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { aarch64*-*-linux* && { aarch64_gas_has_build_attributes } } } } */ +/* { dg-options "-mbranch-protection=bti -dA" } */ + +int main() +{ + return 0; +} + +/* { dg-final { scan-assembler "\.aeabi_subsection aeabi_feature_and_bits, optional, ULEB128" } } */ +/* { dg-final { scan-assembler "\.aeabi_attribute Tag_Feature_BTI, 1\t\/\/ Tag_Feature_BTI: true" } } */ +/* { dg-final { scan-assembler-not "\.section\t\.note\.gnu\.property" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-gcs.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-gcs.c new file mode 100644 index 000000000000..5368915a133b --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-gcs.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { aarch64*-*-linux* && { aarch64_gas_has_build_attributes } } } } */ +/* { dg-options "-mbranch-protection=gcs -dA" } */ + +int main() +{ + return 0; +} + +/* { dg-final { scan-assembler "\.aeabi_subsection aeabi_feature_and_bits, optional, ULEB128" } } */ +/* { dg-final { scan-assembler "\.aeabi_attribute Tag_Feature_GCS, 1\t\/\/ Tag_Feature_GCS: true" } } */ +/* { dg-final { scan-assembler-not "\.section\t\.note\.gnu\.property" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-pac.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-pac.c new file mode 100644 index 000000000000..79d36c1af2d8 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-pac.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { aarch64*-*-linux* && { aarch64_gas_has_build_attributes } } } } */ +/* { dg-options "-mbranch-protection=pac-ret -dA" } */ + +int main() +{ + return 0; +} + +/* { dg-final { scan-assembler "\.aeabi_subsection aeabi_feature_and_bits, optional, ULEB128" } } */ +/* { dg-final { scan-assembler "\.aeabi_attribute Tag_Feature_PAC, 1\t\/\/ Tag_Feature_PAC: true" } } */ +/* { dg-final { scan-assembler-not "\.section\t\.note\.gnu\.property" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-standard.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-standard.c new file mode 100644 index 000000000000..7ffa717c63c1 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-standard.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target { aarch64*-*-linux* && aarch64_gas_has_build_attributes } } } */ +/* { dg-options "-mbranch-protection=standard -dA" } */ + +int main() +{ + return 0; +} + +/* { dg-final { scan-assembler "\.aeabi_subsection aeabi_feature_and_bits, optional, ULEB128" } } */ +/* { dg-final { scan-assembler "\.aeabi_attribute Tag_Feature_BTI, 1\t\/\/ Tag_Feature_BTI: true" } } */ +/* { dg-final { scan-assembler "\.aeabi_attribute Tag_Feature_PAC, 1\t\/\/ Tag_Feature_PAC: true" } } */ +/* { dg-final { scan-assembler "\.aeabi_attribute Tag_Feature_GCS, 1\t\/\/ Tag_Feature_GCS: true" } } */ +/* { dg-final { scan-assembler-not "\.section\t\.note\.gnu\.property" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-bti.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-bti.c new file mode 100644 index 000000000000..013c76e5a2a3 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-bti.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { aarch64*-*-linux* && { ! aarch64_gas_has_build_attributes } } } } */ +/* { dg-options "-mbranch-protection=bti -dA" } */ + +int main() +{ + return 0; +} + +/* { dg-final { scan-assembler-not "\.aeabi_subsection" } } */ +/* { dg-final { scan-assembler-not "\.aeabi_attribute" } } */ +/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */ +/* { dg-final { scan-assembler "\.word\t0x1\t\/\/ GNU_PROPERTY_AARCH64_FEATURE_1_AND \\(BTI\\)" } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-gcs.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-gcs.c new file mode 100644 index 000000000000..954bf3ac8c36 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-gcs.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { aarch64*-*-linux* && { ! aarch64_gas_has_build_attributes } } } } */ +/* { dg-options "-mbranch-protection=gcs -dA" } */ + +int main() +{ + return 0; +} + +/* { dg-final { scan-assembler-not "\.aeabi_subsection" } } */ +/* { dg-final { scan-assembler-not "\.aeabi_attribute" } } */ +/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */ +/* { dg-final { scan-assembler "\.word\t0x4\t\/\/ GNU_PROPERTY_AARCH64_FEATURE_1_AND \\(GCS\\)" } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-pac.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-pac.c new file mode 100644 index 000000000000..10195ecdbd94 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-pac.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { aarch64*-*-linux* && { ! aarch64_gas_has_build_attributes } } } } */ +/* { dg-options "-mbranch-protection=pac-ret -dA" } */ + +int main() +{ + return 0; +} + +/* { dg-final { scan-assembler-not "\.aeabi_subsection" } } */ +/* { dg-final { scan-assembler-not "\.aeabi_attribute" } } */ +/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */ +/* { dg-final { scan-assembler "\.word\t0x2\t\/\/ GNU_PROPERTY_AARCH64_FEATURE_1_AND \\(PAC\\)" } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-standard.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-standard.c new file mode 100644 index 000000000000..52cad2863f27 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-standard.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { aarch64*-*-linux* && { ! aarch64_gas_has_build_attributes } } } } */ +/* { dg-options "-mbranch-protection=standard -dA" } */ + +int main() +{ + return 0; +} + +/* { dg-final { scan-assembler-not "\.aeabi_subsection" } } */ +/* { dg-final { scan-assembler-not "\.aeabi_attribute" } } */ +/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */ +/* { dg-final { scan-assembler "\.word\t0x7\t\/\/ GNU_PROPERTY_AARCH64_FEATURE_1_AND \\(BTI, PAC, GCS\\)" } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/aarch64/cmpbr.c b/gcc/testsuite/gcc.target/aarch64/cmpbr.c new file mode 100644 index 000000000000..a86af9dce8e6 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/cmpbr.c @@ -0,0 +1,1824 @@ +// Test that the instructions added by FEAT_CMPBR are emitted +// { dg-do compile } +// { dg-do-if assemble { target aarch64_asm_cmpbr_ok } } +// { dg-options "-march=armv9.5-a+cmpbr -O2" } +// { dg-final { check-function-bodies "**" "*/" "" { target *-*-* } {\.L[0-9]+} } } + +#include + +typedef uint8_t u8; +typedef int8_t i8; + +typedef uint16_t u16; +typedef int16_t i16; + +typedef uint32_t u32; +typedef int32_t i32; + +typedef uint64_t u64; +typedef int64_t i64; + +int taken(); +int not_taken(); + +#define COMPARE(ty, name, op, rhs) \ + int ty##_x0_##name##_##rhs(ty x0, ty x1) { \ + return __builtin_expect(x0 op rhs, 0) ? taken() : not_taken(); \ + } + +#define COMPARE_ALL(unsigned_ty, signed_ty, rhs) \ + COMPARE(unsigned_ty, eq, ==, rhs); \ + COMPARE(unsigned_ty, ne, !=, rhs); \ + \ + COMPARE(unsigned_ty, ult, <, rhs); \ + COMPARE(unsigned_ty, ule, <=, rhs); \ + COMPARE(unsigned_ty, ugt, >, rhs); \ + COMPARE(unsigned_ty, uge, >=, rhs); \ + \ + COMPARE(signed_ty, slt, <, rhs); \ + COMPARE(signed_ty, sle, <=, rhs); \ + COMPARE(signed_ty, sgt, >, rhs); \ + COMPARE(signed_ty, sge, >=, rhs); + +// ==== CBB (register) ==== +COMPARE_ALL(u8, i8, x1); + +// ==== CBH (register) ==== +COMPARE_ALL(u16, i16, x1); + +// ==== CB (register) ==== +COMPARE_ALL(u32, i32, x1); +COMPARE_ALL(u64, i64, x1); + +// ==== CB (immediate) ==== +COMPARE_ALL(u32, i32, 42); +COMPARE_ALL(u64, i64, 42); + +// ==== Special cases ==== +// Comparisons against the immediate 0 can be done for all types, +// because we can use the wzr/xzr register as one of the operands. +// However, we should prefer to use CBZ/CBNZ or TBZ/TBNZ when possible, +// because they have larger range. +COMPARE_ALL(u8, i8, 0); +COMPARE_ALL(u16, i16, 0); +COMPARE_ALL(u32, i32, 0); +COMPARE_ALL(u64, i64, 0); + +// CBB and CBH cannot have immediate operands. +// Instead we have to do a MOV+CB. +COMPARE_ALL(u8, i8, 42); +COMPARE_ALL(u16, i16, 42); + +// 64 is out of the range for immediate operands (0 to 63). +// * For 8/16-bit types, use a MOV+CB as above. +// * For 32/64-bit types, use a CMP+B instead, +// because B has a longer range than CB. +COMPARE_ALL(u8, i8, 64); +COMPARE_ALL(u16, i16, 64); +COMPARE_ALL(u32, i32, 64); +COMPARE_ALL(u64, i64, 64); + +// 4098 is out of the range for CMP (0 to 4095, optionally shifted by left by 12 +// bits), but it can be materialized in a single MOV. +COMPARE_ALL(u16, i16, 4098); +COMPARE_ALL(u32, i32, 4098); +COMPARE_ALL(u64, i64, 4098); + +// If the branch destination is out of range (1KiB), we have to generate an +// extra B instruction (which can handle larger displacements) and branch around +// it + +// clang-format off +#define STORE_1() z = 0; +#define STORE_2() STORE_1() STORE_1() +#define STORE_4() STORE_2() STORE_2() +#define STORE_8() STORE_4() STORE_4() +#define STORE_16() STORE_8() STORE_8() +#define STORE_32() STORE_16() STORE_16() +#define STORE_64() STORE_32() STORE_32() +#define STORE_128() STORE_64() STORE_64() +#define STORE_256() STORE_128() STORE_128() +// clang-format on + +#define FAR_BRANCH(ty, rhs) \ + int far_branch_##ty##_x0_eq_##rhs(ty x0, ty x1) { \ + volatile int z = 0; \ + if (__builtin_expect(x0 == rhs, 1)) { \ + STORE_256(); \ + } \ + return taken(); \ + } + +FAR_BRANCH(u8, x1); +FAR_BRANCH(u16, x1); +FAR_BRANCH(u32, x1); +FAR_BRANCH(u64, x1); + +FAR_BRANCH(u8, 42); +FAR_BRANCH(u16, 42); +FAR_BRANCH(u32, 42); +FAR_BRANCH(u64, 42); + +/* +** u8_x0_eq_x1: +** cbbeq w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u8_x0_ne_x1: +** cbbne w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u8_x0_ult_x1: +** cbbhi w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u8_x0_ule_x1: +** cbbhs w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u8_x0_ugt_x1: +** cbblo w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u8_x0_uge_x1: +** cbbls w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i8_x0_slt_x1: +** cbbgt w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i8_x0_sle_x1: +** cbbge w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i8_x0_sgt_x1: +** cbblt w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i8_x0_sge_x1: +** cbble w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u16_x0_eq_x1: +** cbheq w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u16_x0_ne_x1: +** cbhne w0|w1, w1|w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u16_x0_ult_x1: +** cbhhi w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u16_x0_ule_x1: +** cbhhs w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u16_x0_ugt_x1: +** cbhlo w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u16_x0_uge_x1: +** cbhls w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i16_x0_slt_x1: +** cbhgt w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i16_x0_sle_x1: +** cbhge w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i16_x0_sgt_x1: +** cbhlt w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i16_x0_sge_x1: +** cbhle w1, w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_eq_x1: +** cbeq w0, w1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_ne_x1: +** cbne w0, w1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_ult_x1: +** cblo w0, w1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_ule_x1: +** cbls w0, w1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_ugt_x1: +** cbhi w0, w1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_uge_x1: +** cbhs w0, w1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i32_x0_slt_x1: +** cblt w0, w1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i32_x0_sle_x1: +** cble w0, w1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i32_x0_sgt_x1: +** cbgt w0, w1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i32_x0_sge_x1: +** cbge w0, w1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_eq_x1: +** cbeq x0, x1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_ne_x1: +** cbne x0, x1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_ult_x1: +** cblo x0, x1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_ule_x1: +** cbls x0, x1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_ugt_x1: +** cbhi x0, x1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_uge_x1: +** cbhs x0, x1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i64_x0_slt_x1: +** cblt x0, x1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i64_x0_sle_x1: +** cble x0, x1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i64_x0_sgt_x1: +** cbgt x0, x1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i64_x0_sge_x1: +** cbge x0, x1, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_eq_42: +** cbeq w0, 42, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_ne_42: +** cbne w0, 42, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_ult_42: +** cbls w0, 41, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_ule_42: +** cbls w0, 42, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_ugt_42: +** cbhi w0, 42, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_uge_42: +** cbhi w0, 41, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i32_x0_slt_42: +** cble w0, 41, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i32_x0_sle_42: +** cble w0, 42, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i32_x0_sgt_42: +** cbgt w0, 42, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i32_x0_sge_42: +** cbgt w0, 41, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_eq_42: +** cbeq x0, 42, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_ne_42: +** cbne x0, 42, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_ult_42: +** cbls x0, 41, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_ule_42: +** cbls x0, 42, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_ugt_42: +** cbhi x0, 42, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_uge_42: +** cbhi x0, 41, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i64_x0_slt_42: +** cble x0, 41, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i64_x0_sle_42: +** cble x0, 42, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i64_x0_sgt_42: +** cbgt x0, 42, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i64_x0_sge_42: +** cbgt x0, 41, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u8_x0_eq_0: +** cbbeq w0, wzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u8_x0_ne_0: +** cbbne w0, wzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u8_x0_ult_0: +** b not_taken +*/ + +/* +** u8_x0_ule_0: +** cbbeq w0, wzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u8_x0_ugt_0: +** cbbne w0, wzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u8_x0_uge_0: +** b taken +*/ + +/* +** i8_x0_slt_0: +** tbnz w0, #7, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i8_x0_sle_0: +** cbble w0, wzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i8_x0_sgt_0: +** cbbgt w0, wzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i8_x0_sge_0: +** tbz w0, #7, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u16_x0_eq_0: +** cbheq w0, wzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u16_x0_ne_0: +** cbhne w0, wzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u16_x0_ult_0: +** b not_taken +*/ + +/* +** u16_x0_ule_0: +** cbheq w0, wzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u16_x0_ugt_0: +** cbhne w0, wzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u16_x0_uge_0: +** b taken +*/ + +/* +** i16_x0_slt_0: +** tbnz w0, #15, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i16_x0_sle_0: +** cbhle w0, wzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i16_x0_sgt_0: +** cbhgt w0, wzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i16_x0_sge_0: +** tbz w0, #15, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_eq_0: +** cbz w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_ne_0: +** cbnz w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_ult_0: +** b not_taken +*/ + +/* +** u32_x0_ule_0: +** cbz w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_ugt_0: +** cbnz w0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_uge_0: +** b taken +*/ + +/* +** i32_x0_slt_0: +** tbnz w0, #31, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i32_x0_sle_0: +** cble w0, wzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i32_x0_sgt_0: +** cbgt w0, wzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i32_x0_sge_0: +** tbz w0, #31, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_eq_0: +** cbz x0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_ne_0: +** cbnz x0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_ult_0: +** b not_taken +*/ + +/* +** u64_x0_ule_0: +** cbz x0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_ugt_0: +** cbnz x0, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_uge_0: +** b taken +*/ + +/* +** i64_x0_slt_0: +** tbnz x0, #63, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i64_x0_sle_0: +** cble x0, xzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i64_x0_sgt_0: +** cbgt x0, xzr, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i64_x0_sge_0: +** tbz x0, #63, .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u8_x0_eq_42: +** mov w([0-9]+), 42 +** cbbeq w0, w\1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u8_x0_ne_42: +** mov (w[0-9]+), 42 +** cbbne w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u8_x0_ult_42: +** mov (w[0-9]+), 41 +** cbbls w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u8_x0_ule_42: +** mov (w[0-9]+), 42 +** cbbls w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u8_x0_ugt_42: +** mov (w[0-9]+), 42 +** cbbhi w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u8_x0_uge_42: +** mov (w[0-9]+), 41 +** cbbhi w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i8_x0_slt_42: +** mov (w[0-9]+), 41 +** cbble w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i8_x0_sle_42: +** mov (w[0-9]+), 42 +** cbble w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i8_x0_sgt_42: +** mov (w[0-9]+), 42 +** cbbgt w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i8_x0_sge_42: +** mov (w[0-9]+), 41 +** cbbgt w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_eq_42: +** mov w([0-9]+), 42 +** cbheq w0, w\1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_ne_42: +** mov (w[0-9]+), 42 +** cbhne w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_ult_42: +** mov (w[0-9]+), 41 +** cbhls w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_ule_42: +** mov (w[0-9]+), 42 +** cbhls w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_ugt_42: +** mov (w[0-9]+), 42 +** cbhhi w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_uge_42: +** mov (w[0-9]+), 41 +** cbhhi w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i16_x0_slt_42: +** mov (w[0-9]+), 41 +** cbhle w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i16_x0_sle_42: +** mov (w[0-9]+), 42 +** cbhle w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i16_x0_sgt_42: +** mov (w[0-9]+), 42 +** cbhgt w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i16_x0_sge_42: +** mov (w[0-9]+), 41 +** cbhgt w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u8_x0_eq_64: +** mov w([0-9]+), 64 +** cbbeq w0, w\1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u8_x0_ne_64: +** mov (w[0-9]+), 64 +** cbbne w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u8_x0_ult_64: +** mov (w[0-9]+), 63 +** cbbls w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u8_x0_ule_64: +** mov (w[0-9]+), 64 +** cbbls w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u8_x0_ugt_64: +** mov (w[0-9]+), 64 +** cbbhi w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u8_x0_uge_64: +** mov (w[0-9]+), 63 +** cbbhi w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i8_x0_slt_64: +** mov (w[0-9]+), 63 +** cbble w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i8_x0_sle_64: +** mov (w[0-9]+), 64 +** cbble w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i8_x0_sgt_64: +** mov (w[0-9]+), 64 +** cbbgt w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i8_x0_sge_64: +** mov (w[0-9]+), 63 +** cbbgt w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_eq_64: +** mov w([0-9]+), 64 +** cbheq w0, w\1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_ne_64: +** mov (w[0-9]+), 64 +** cbhne w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_ult_64: +** mov (w[0-9]+), 63 +** cbhls w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_ule_64: +** mov (w[0-9]+), 64 +** cbhls w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_ugt_64: +** mov (w[0-9]+), 64 +** cbhhi w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_uge_64: +** mov (w[0-9]+), 63 +** cbhhi w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i16_x0_slt_64: +** mov (w[0-9]+), 63 +** cbhle w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i16_x0_sle_64: +** mov (w[0-9]+), 64 +** cbhle w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i16_x0_sgt_64: +** mov (w[0-9]+), 64 +** cbhgt w0, w1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i16_x0_sge_64: +** mov (w[0-9]+), 63 +** cbhgt w0, w1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u32_x0_eq_64: +** cmp w0, 64 +** beq .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_ne_64: +** cmp w0, 64 +** bne .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_ult_64: +** cbhi w0, 63, .L([0-9]+) +** b taken +** .L\1: +** b not_taken +*/ + +/* +** u32_x0_ule_64: +** cmp w0, 64 +** bls .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_ugt_64: +** cmp w0, 64 +** bhi .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u32_x0_uge_64: +** cmp w0, 63 +** bhi .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i32_x0_slt_64: +** cbgt w0, 63, .L([0-9]+) +** b taken +** .L\1: +** b not_taken +*/ + +/* +** i32_x0_sle_64: +** cmp w0, 64 +** ble .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i32_x0_sgt_64: +** cmp w0, 64 +** bgt .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i32_x0_sge_64: +** cmp w0, 63 +** bgt .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_eq_64: +** cmp x0, 64 +** beq .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_ne_64: +** cmp x0, 64 +** bne .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_ult_64: +** cbhi x0, 63, .L([0-9]+) +** b taken +** .L\1: +** b not_taken +*/ + +/* +** u64_x0_ule_64: +** cmp x0, 64 +** bls .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_ugt_64: +** cmp x0, 64 +** bhi .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u64_x0_uge_64: +** cmp x0, 63 +** bhi .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i64_x0_slt_64: +** cbgt x0, 63, .L([0-9]+) +** b taken +** .L\1: +** b not_taken +*/ + +/* +** i64_x0_sle_64: +** cmp x0, 64 +** ble .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i64_x0_sgt_64: +** cmp x0, 64 +** bgt .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** i64_x0_sge_64: +** cmp x0, 63 +** bgt .L([0-9]+) +** b not_taken +** .L\1: +** b taken +*/ + +/* +** u16_x0_eq_4098: +** mov w([0-9]+), 4098 +** cbheq w0, w\1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_ne_4098: +** mov (w[0-9]+), 4098 +** cbhne w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_ult_4098: +** mov (w[0-9]+), 4097 +** cbhls w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_ule_4098: +** mov (w[0-9]+), 4098 +** cbhls w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_ugt_4098: +** mov (w[0-9]+), 4098 +** cbhhi w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u16_x0_uge_4098: +** mov (w[0-9]+), 4097 +** cbhhi w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i16_x0_slt_4098: +** mov (w[0-9]+), 4097 +** cbhle w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i16_x0_sle_4098: +** mov (w[0-9]+), 4098 +** cbhle w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i16_x0_sgt_4098: +** mov (w[0-9]+), 4098 +** cbhgt w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i16_x0_sge_4098: +** mov (w[0-9]+), 4097 +** cbhgt w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u32_x0_eq_4098: +** mov w([0-9]+), 4098 +** cbeq w0, w\1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u32_x0_ne_4098: +** mov (w[0-9]+), 4098 +** cbne w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u32_x0_ult_4098: +** mov (w[0-9]+), 4097 +** cbls w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u32_x0_ule_4098: +** mov (w[0-9]+), 4098 +** cbls w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u32_x0_ugt_4098: +** mov (w[0-9]+), 4098 +** cbhi w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u32_x0_uge_4098: +** mov (w[0-9]+), 4097 +** cbhi w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i32_x0_slt_4098: +** mov (w[0-9]+), 4097 +** cble w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i32_x0_sle_4098: +** mov (w[0-9]+), 4098 +** cble w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i32_x0_sgt_4098: +** mov (w[0-9]+), 4098 +** cbgt w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i32_x0_sge_4098: +** mov (w[0-9]+), 4097 +** cbgt w0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u64_x0_eq_4098: +** mov x([0-9]+), 4098 +** cbeq x0, x\1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u64_x0_ne_4098: +** mov (x[0-9]+), 4098 +** cbne x0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u64_x0_ult_4098: +** mov (x[0-9]+), 4097 +** cbls x0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u64_x0_ule_4098: +** mov (x[0-9]+), 4098 +** cbls x0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u64_x0_ugt_4098: +** mov (x[0-9]+), 4098 +** cbhi x0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** u64_x0_uge_4098: +** mov (x[0-9]+), 4097 +** cbhi x0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i64_x0_slt_4098: +** mov (x[0-9]+), 4097 +** cble x0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i64_x0_sle_4098: +** mov (x[0-9]+), 4098 +** cble x0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i64_x0_sgt_4098: +** mov (x[0-9]+), 4098 +** cbgt x0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** i64_x0_sge_4098: +** mov (x[0-9]+), 4097 +** cbgt x0, \1, .L([0-9]+) +** b not_taken +** .L\2: +** b taken +*/ + +/* +** far_branch_u8_x0_eq_x1: +** sub sp, sp, #16 +** str wzr, \[sp, 12\] +** cbbeq w0|w1, w1|w0, .L([0-9]+) +** b .L([0-9]+) +** .L\1: +** str wzr, \[sp, 12\] +** ... +** str wzr, \[sp, 12\] +** .L\2: +** add sp, sp, 16 +** b taken +*/ + +/* +** far_branch_u16_x0_eq_x1: +** sub sp, sp, #16 +** str wzr, \[sp, 12\] +** cbheq w0|w1, w1|w0, .L([0-9]+) +** b .L([0-9]+) +** .L\1: +** str wzr, \[sp, 12\] +** ... +** str wzr, \[sp, 12\] +** .L\2: +** add sp, sp, 16 +** b taken +*/ + +/* +** far_branch_u32_x0_eq_x1: +** sub sp, sp, #16 +** str wzr, \[sp, 12\] +** cbeq w0, w1, .L([0-9]+) +** b .L([0-9]+) +** .L\1: +** str wzr, \[sp, 12\] +** ... +** str wzr, \[sp, 12\] +** .L\2: +** add sp, sp, 16 +** b taken +*/ + +/* +** far_branch_u64_x0_eq_x1: +** sub sp, sp, #16 +** str wzr, \[sp, 12\] +** cbeq x0, x1, .L([0-9]+) +** b .L([0-9]+) +** .L\1: +** str wzr, \[sp, 12\] +** ... +** str wzr, \[sp, 12\] +** .L\2: +** add sp, sp, 16 +** b taken +*/ + +/* +** far_branch_u8_x0_eq_42: +** sub sp, sp, #16 +** mov w([0-9]+), 42 +** str wzr, \[sp, 12\] +** cbbeq w0, w\1, .L([0-9]+) +** b .L([0-9]+) +** .L\2: +** str wzr, \[sp, 12\] +** ... +** str wzr, \[sp, 12\] +** .L\3: +** add sp, sp, 16 +** b taken +*/ + +/* +** far_branch_u16_x0_eq_42: +** sub sp, sp, #16 +** mov w([0-9]+), 42 +** str wzr, \[sp, 12\] +** cbheq w0, w\1, .L([0-9]+) +** b .L([0-9]+) +** .L\2: +** str wzr, \[sp, 12\] +** ... +** str wzr, \[sp, 12\] +** .L\3: +** add sp, sp, 16 +** b taken +*/ + +/* +** far_branch_u32_x0_eq_42: +** sub sp, sp, #16 +** str wzr, \[sp, 12\] +** cbeq w0, 42, .L([0-9]+) +** b .L([0-9]+) +** .L\1: +** str wzr, \[sp, 12\] +** ... +** str wzr, \[sp, 12\] +** .L\2: +** add sp, sp, 16 +** b taken +*/ + +/* +** far_branch_u64_x0_eq_42: +** sub sp, sp, #16 +** str wzr, \[sp, 12\] +** cbeq x0, 42, .L([0-9]+) +** b .L([0-9]+) +** .L\1: +** str wzr, \[sp, 12\] +** ... +** str wzr, \[sp, 12\] +** .L\2: +** add sp, sp, 16 +** b taken +*/ diff --git a/gcc/testsuite/gcc.target/aarch64/inszero_split_1.c b/gcc/testsuite/gcc.target/aarch64/inszero_split_1.c new file mode 100644 index 000000000000..5c739bd7bb1a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/inszero_split_1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O2" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* Avoid INS from WZR register when optimizing for speed. */ + +#include + +/* +** foo: +** movi? [vdz]([0-9]+)\.?(?:[0-9]*[bhsd])?, #?0 +** ins v0.h\[2\], v(\1).h\[0\] +** ret +*/ +uint16x8_t foo(uint16x8_t a) { + a[2] = 0; + return a; +} diff --git a/gcc/testsuite/gcc.target/aarch64/ldapr-sext.c b/gcc/testsuite/gcc.target/aarch64/ldapr-sext.c index f57c09d05806..e8a545a01f9c 100644 --- a/gcc/testsuite/gcc.target/aarch64/ldapr-sext.c +++ b/gcc/testsuite/gcc.target/aarch64/ldapr-sext.c @@ -33,7 +33,7 @@ TEST(s8_s64, s8, long long) /* **test_s16_s64: **... -** ldapursh x0, \[x[0-9]+\] +** ldapursh x0, \[x[0-9]+, [0-9]+\] ** ret */ @@ -42,7 +42,7 @@ TEST(s16_s64, s16, long long) /* **test_s32_s64: **... -** ldapursw x0, \[x[0-9]+\] +** ldapursw x0, \[x[0-9]+, [0-9]+\] ** ret */ @@ -60,7 +60,7 @@ TEST(s8_s32, s8, int) /* **test_s16_s32: **... -** ldapursh w0, \[x[0-9]+\] +** ldapursh w0, \[x[0-9]+, [0-9]+\] ** ret */ diff --git a/gcc/testsuite/gcc.target/aarch64/ldapur.c b/gcc/testsuite/gcc.target/aarch64/ldapur.c new file mode 100644 index 000000000000..5c68bdde35dd --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ldapur.c @@ -0,0 +1,77 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -std=c99" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +#include +#include + +#pragma GCC target "arch=armv8.8-a" + +atomic_ullong u64; +atomic_uint u32; +atomic_ushort u16; +atomic_uchar u8[2]; /* Force an offset for u8 */ + +#define TEST(name, ldsize, rettype) \ +rettype \ +test_##name (void) \ +{ \ + return atomic_load_explicit (&ldsize, memory_order_acquire); \ +} \ + + +/* +** test_u8_u64: +** ... +** ldapurb w[0-9]+, \[x[0-9]+, [0-9]+\] +** ret +*/ +TEST(u8_u64, u8[1], uint64_t) + +/* +** test_u16_u64: +** ... +** ldapurh w[0-9]+, \[x[0-9]+, [0-9]+\] +** ret +*/ +TEST(u16_u64, u16, uint64_t) + +/* +**test_u32_u64: +** ... +** ldapur w[0-9]+, \[x[0-9]+, [0-9]+\] +** ret +*/ +TEST(u32_u64, u32, uint64_t) + +/* +**test_u64_u64: +** ... +** ldapur x[0-9]+, \[x[0-9]+, [0-9]+\] +** ret +*/ +TEST(u64_u64, u64, uint64_t) + +/* +**test_u8_u32: +** ... +** ldapurb w[0-9]+, \[x[0-9]+, [0-9]+\] +** ret +*/ +TEST(u8_u32, u8[1], uint32_t) + +/* +**test_u16_u32: +** ... +** ldapurh w[0-9]+, \[x[0-9]+, [0-9]+\] +** ret +*/ +TEST(u16_u32, u16, uint32_t) + +/* +**test_u32_u32: +** ... +** ldapur w[0-9]+, \[x[0-9]+, [0-9]+\] +** ret +*/ +TEST(u32_u32, u32, uint32_t) \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/aarch64/ldapur_avoid.c b/gcc/testsuite/gcc.target/aarch64/ldapur_avoid.c new file mode 100644 index 000000000000..ad87a30752a2 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ldapur_avoid.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -std=c99 -moverride=tune=avoid_ldapur" } */ + +#include +#include + +#pragma GCC target "arch=armv8.8-a" +/* LDAPUR is only avoided for armv8.4 to armv8.7. This checks for the working +of avoid_ldapur flag. */ + +/* { dg-final { scan-assembler-not "ldapur\t" } } */ + +atomic_ullong u64; +atomic_uint u32; +atomic_ushort u16; +atomic_uchar u8[2]; /* Force an offset for u8 */ + +#define TEST(name, ldsize, rettype) \ +rettype \ +test_##name (void) \ +{ \ + return atomic_load_explicit (&ldsize, memory_order_acquire); \ +} \ + +TEST(u8_u64, u8[1], uint64_t) +TEST(u16_u64, u16, uint64_t) +TEST(u32_u64, u32, uint64_t) +TEST(u64_u64, u64, uint64_t) +TEST(u8_u32, u8[1], uint32_t) +TEST(u16_u32, u16, uint32_t) +TEST(u32_u32, u32, uint32_t) + +/* { dg-final { scan-assembler-times "ldapr\t" 3 } } */ +/* { dg-final { scan-assembler-times "ldaprh\t" 2 } } */ +/* { dg-final { scan-assembler-times "ldaprb\t" 2 } } */ + + diff --git a/gcc/testsuite/gcc.target/aarch64/popcnt13.c b/gcc/testsuite/gcc.target/aarch64/popcnt13.c new file mode 100644 index 000000000000..2a30e9843322 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/popcnt13.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#pragma GCC target "+nocssc+sve" + +/* +** h128: +** ldr q([0-9]+), \[x0\] +** ptrue p([0-9]+).b, vl16 +** cnt z([0-9]+).d, p\2/m, z\1.d +** addp d([0-9]+), v\3.2d +** fmov x0, d\4 +** ret +*/ + +unsigned h128 (const unsigned __int128 *a) { + return __builtin_popcountg (a[0]); +} + +/* There should be only one POPCOUNT. */ +/* { dg-final { scan-tree-dump-times "POPCOUNT " 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-not " __builtin_popcount" "optimized" } } */ + diff --git a/gcc/testsuite/gcc.target/aarch64/popcnt9.c b/gcc/testsuite/gcc.target/aarch64/popcnt9.c index c778fc7f4206..cfed8c58b7e0 100644 --- a/gcc/testsuite/gcc.target/aarch64/popcnt9.c +++ b/gcc/testsuite/gcc.target/aarch64/popcnt9.c @@ -3,7 +3,7 @@ /* { dg-final { check-function-bodies "**" "" } } */ /* PR target/113042 */ -#pragma GCC target "+nocssc" +#pragma GCC target "+nocssc+nosve" /* ** h128: diff --git a/gcc/testsuite/gcc.target/aarch64/pr113027-1.c b/gcc/testsuite/gcc.target/aarch64/pr113027-1.c new file mode 100644 index 000000000000..6d9a51fd408f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr113027-1.c @@ -0,0 +1,27 @@ +/* { dg-options "-O2" } */ + +#include + +float64x2x2_t +f1 (float64x2x2_t x) +{ + x.val[0][1] += 1.0; + return x; +} + +float64x2x3_t +f2 (float64x2x3_t x) +{ + x.val[0][0] = x.val[1][1] + x.val[2][0]; + return x; +} + +float64x2x4_t +f3 (float64x2x4_t x) +{ + x.val[0][0] = x.val[1][1] + x.val[2][0] - x.val[3][1]; + return x; +} + +/* { dg-final { scan-assembler-not {\tmov\t} } } */ +/* { dg-final { scan-assembler-not {\[sp,} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/pr113027-2.c b/gcc/testsuite/gcc.target/aarch64/pr113027-2.c new file mode 100644 index 000000000000..ec756ec86e47 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr113027-2.c @@ -0,0 +1,268 @@ +/* { dg-options "-O2" } */ +/* { dg-final { check-function-bodies "**" "" "" { target aarch64_little_endian } } } */ + +#include + +#define TEST(TYPE, A, B, C, D) \ + TYPE \ + test_##TYPE (TYPE a) \ + { \ + a.val[A][B] = a.val[C][D]; \ + return a; \ + } + +/* +** test_bfloat16x4x2_t: +** ins v1\.h\[3\], v0\.h\[2\] +** ret +*/ +TEST (bfloat16x4x2_t, 1, 3, 0, 2) + +/* +** test_float16x4x2_t: +** ins v1\.h\[1\], v0\.h\[3\] +** ret +*/ +TEST (float16x4x2_t, 1, 1, 0, 3) + +/* +** test_float32x2x2_t: +** ins v1\.s\[0\], v0\.s\[1\] +** ret +*/ +TEST (float32x2x2_t, 1, 0, 0, 1) + +/* +** test_float64x1x2_t: +** fmov d1, d0 +** ret +*/ +TEST (float64x1x2_t, 1, 0, 0, 0) + +/* +** test_int8x8x2_t: +** ins v0\.b\[5\], v1\.b\[7\] +** ret +*/ +TEST (int8x8x2_t, 0, 5, 1, 7) + +/* +** test_int16x4x2_t: +** ins v0\.h\[2\], v1\.h\[2\] +** ret +*/ +TEST (int16x4x2_t, 0, 2, 1, 2) + +/* +** test_int32x2x2_t: +** ins v0\.s\[0\], v1\.s\[1\] +** ret +*/ +TEST (int32x2x2_t, 0, 0, 1, 1) + +/* +** test_int64x1x2_t: +** fmov d0, d1 +** ret +*/ +TEST (int64x1x2_t, 0, 0, 1, 0) + +/* +** test_uint8x8x2_t: +** ins v1\.b\[6\], v0\.b\[3\] +** ret +*/ +TEST (uint8x8x2_t, 1, 6, 0, 3) + +/* +** test_uint16x4x2_t: +** ins v1\.h\[2\], v1\.h\[0\] +** ret +*/ +TEST (uint16x4x2_t, 1, 2, 1, 0) + +/* +** test_uint32x2x2_t: +** ins v1\.s\[0\], v1\.s\[1\] +** ret +*/ +TEST (uint32x2x2_t, 1, 0, 1, 1) + +/* +** test_uint64x1x2_t: +** fmov d1, d0 +** ret +*/ +TEST (uint64x1x2_t, 1, 0, 0, 0) + +//-------------------------------------------------------------- + +/* +** test_bfloat16x4x3_t: +** ins v2\.h\[3\], v0\.h\[2\] +** ret +*/ +TEST (bfloat16x4x3_t, 2, 3, 0, 2) + +/* +** test_float16x4x3_t: +** ins v0\.h\[1\], v1\.h\[3\] +** ret +*/ +TEST (float16x4x3_t, 0, 1, 1, 3) + +/* +** test_float32x2x3_t: +** ins v1\.s\[0\], v2\.s\[1\] +** ret +*/ +TEST (float32x2x3_t, 1, 0, 2, 1) + +/* +** test_float64x1x3_t: +** fmov d1, d2 +** ret +*/ +TEST (float64x1x3_t, 1, 0, 2, 0) + +/* +** test_int8x8x3_t: +** ins v0\.b\[5\], v2\.b\[6\] +** ret +*/ +TEST (int8x8x3_t, 0, 5, 2, 6) + +/* +** test_int16x4x3_t: +** ins v2\.h\[2\], v1\.h\[1\] +** ret +*/ +TEST (int16x4x3_t, 2, 2, 1, 1) + +/* +** test_int32x2x3_t: +** ins v1\.s\[0\], v1\.s\[1\] +** ret +*/ +TEST (int32x2x3_t, 1, 0, 1, 1) + +/* +** test_int64x1x3_t: +** fmov d2, d1 +** ret +*/ +TEST (int64x1x3_t, 2, 0, 1, 0) + +/* +** test_uint8x8x3_t: +** ins v1\.b\[6\], v2\.b\[7\] +** ret +*/ +TEST (uint8x8x3_t, 1, 6, 2, 7) + +/* +** test_uint16x4x3_t: +** ins v2\.h\[2\], v1\.h\[3\] +** ret +*/ +TEST (uint16x4x3_t, 2, 2, 1, 3) + +/* +** test_uint32x2x3_t: +** ins v2\.s\[0\], v0\.s\[1\] +** ret +*/ +TEST (uint32x2x3_t, 2, 0, 0, 1) + +/* +** test_uint64x1x3_t: +** fmov d1, d2 +** ret +*/ +TEST (uint64x1x3_t, 1, 0, 2, 0) + +//-------------------------------------------------------------- + +/* +** test_bfloat16x4x4_t: +** ins v2\.h\[3\], v3\.h\[2\] +** ret +*/ +TEST (bfloat16x4x4_t, 2, 3, 3, 2) + +/* +** test_float16x4x4_t: +** ins v0\.h\[2\], v3\.h\[1\] +** ret +*/ +TEST (float16x4x4_t, 0, 2, 3, 1) + +/* +** test_float32x2x4_t: +** ins v3\.s\[0\], v2\.s\[1\] +** ret +*/ +TEST (float32x2x4_t, 3, 0, 2, 1) + +/* +** test_float64x1x4_t: +** fmov d1, d3 +** ret +*/ +TEST (float64x1x4_t, 1, 0, 3, 0) + +/* +** test_int8x8x4_t: +** ins v0\.b\[4\], v3\.b\[7\] +** ret +*/ +TEST (int8x8x4_t, 0, 4, 3, 7) + +/* +** test_int16x4x4_t: +** ins v3\.h\[3\], v1\.h\[1\] +** ret +*/ +TEST (int16x4x4_t, 3, 3, 1, 1) + +/* +** test_int32x2x4_t: +** ins v1\.s\[0\], v3\.s\[1\] +** ret +*/ +TEST (int32x2x4_t, 1, 0, 3, 1) + +/* +** test_int64x1x4_t: +** fmov d3, d1 +** ret +*/ +TEST (int64x1x4_t, 3, 0, 1, 0) + +/* +** test_uint8x8x4_t: +** ins v3\.b\[6\], v2\.b\[4\] +** ret +*/ +TEST (uint8x8x4_t, 3, 6, 2, 4) + +/* +** test_uint16x4x4_t: +** ins v3\.h\[1\], v1\.h\[3\] +** ret +*/ +TEST (uint16x4x4_t, 3, 1, 1, 3) + +/* +** test_uint32x2x4_t: +** ins v0\.s\[0\], v3\.s\[1\] +** ret +*/ +TEST (uint32x2x4_t, 0, 0, 3, 1) + +/* +** test_uint64x1x4_t: +** fmov d1, d3 +** ret +*/ +TEST (uint64x1x4_t, 1, 0, 3, 0) diff --git a/gcc/testsuite/gcc.target/aarch64/pr113027-3.c b/gcc/testsuite/gcc.target/aarch64/pr113027-3.c new file mode 100644 index 000000000000..561e6721a800 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr113027-3.c @@ -0,0 +1,268 @@ +/* { dg-options "-O2" } */ +/* { dg-final { check-function-bodies "**" "" "" { target aarch64_little_endian } } } */ + +#include + +#define TEST(TYPE, A, B, C, D) \ + TYPE \ + test_##TYPE (TYPE a) \ + { \ + a.val[A][B] = a.val[C][D]; \ + return a; \ + } + +/* +** test_bfloat16x8x2_t: +** ins v1\.h\[6\], v0\.h\[5\] +** ret +*/ +TEST (bfloat16x8x2_t, 1, 6, 0, 5) + +/* +** test_float16x8x2_t: +** ins v1\.h\[2\], v0\.h\[7\] +** ret +*/ +TEST (float16x8x2_t, 1, 2, 0, 7) + +/* +** test_float32x4x2_t: +** ins v1\.s\[3\], v0\.s\[1\] +** ret +*/ +TEST (float32x4x2_t, 1, 3, 0, 1) + +/* +** test_float64x2x2_t: +** ins v1\.d\[0\], v0\.d\[0\] +** ret +*/ +TEST (float64x2x2_t, 1, 0, 0, 0) + +/* +** test_int8x16x2_t: +** ins v0\.b\[15\], v1\.b\[13\] +** ret +*/ +TEST (int8x16x2_t, 0, 15, 1, 13) + +/* +** test_int16x8x2_t: +** ins v0\.h\[2\], v1\.h\[7\] +** ret +*/ +TEST (int16x8x2_t, 0, 2, 1, 7) + +/* +** test_int32x4x2_t: +** ins v0\.s\[3\], v1\.s\[1\] +** ret +*/ +TEST (int32x4x2_t, 0, 3, 1, 1) + +/* +** test_int64x2x2_t: +** ins v0\.d\[0\], v1\.d\[1\] +** ret +*/ +TEST (int64x2x2_t, 0, 0, 1, 1) + +/* +** test_uint8x16x2_t: +** ins v1\.b\[13\], v0\.b\[11\] +** ret +*/ +TEST (uint8x16x2_t, 1, 13, 0, 11) + +/* +** test_uint16x8x2_t: +** ins v1\.h\[6\], v1\.h\[3\] +** ret +*/ +TEST (uint16x8x2_t, 1, 6, 1, 3) + +/* +** test_uint32x4x2_t: +** ins v1\.s\[3\], v1\.s\[1\] +** ret +*/ +TEST (uint32x4x2_t, 1, 3, 1, 1) + +/* +** test_uint64x2x2_t: +** ins v1\.d\[0\], v1\.d\[1\] +** ret +*/ +TEST (uint64x2x2_t, 1, 0, 1, 1) + +//-------------------------------------------------------------- + +/* +** test_bfloat16x8x3_t: +** ins v2\.h\[3\], v0\.h\[7\] +** ret +*/ +TEST (bfloat16x8x3_t, 2, 3, 0, 7) + +/* +** test_float16x8x3_t: +** ins v0\.h\[4\], v1\.h\[6\] +** ret +*/ +TEST (float16x8x3_t, 0, 4, 1, 6) + +/* +** test_float32x4x3_t: +** ins v1\.s\[2\], v2\.s\[1\] +** ret +*/ +TEST (float32x4x3_t, 1, 2, 2, 1) + +/* +** test_float64x2x3_t: +** ins v1\.d\[0\], v2\.d\[1\] +** ret +*/ +TEST (float64x2x3_t, 1, 0, 2, 1) + +/* +** test_int8x16x3_t: +** ins v0\.b\[9\], v2\.b\[14\] +** ret +*/ +TEST (int8x16x3_t, 0, 9, 2, 14) + +/* +** test_int16x8x3_t: +** ins v2\.h\[6\], v1\.h\[3\] +** ret +*/ +TEST (int16x8x3_t, 2, 6, 1, 3) + +/* +** test_int32x4x3_t: +** ins v1\.s\[3\], v1\.s\[1\] +** ret +*/ +TEST (int32x4x3_t, 1, 3, 1, 1) + +/* +** test_int64x2x3_t: +** ins v2\.d\[1\], v1\.d\[0\] +** ret +*/ +TEST (int64x2x3_t, 2, 1, 1, 0) + +/* +** test_uint8x16x3_t: +** ins v1\.b\[10\], v2\.b\[8\] +** ret +*/ +TEST (uint8x16x3_t, 1, 10, 2, 8) + +/* +** test_uint16x8x3_t: +** ins v2\.h\[5\], v1\.h\[2\] +** ret +*/ +TEST (uint16x8x3_t, 2, 5, 1, 2) + +/* +** test_uint32x4x3_t: +** ins v2\.s\[3\], v0\.s\[1\] +** ret +*/ +TEST (uint32x4x3_t, 2, 3, 0, 1) + +/* +** test_uint64x2x3_t: +** ins v1\.d\[0\], v2\.d\[1\] +** ret +*/ +TEST (uint64x2x3_t, 1, 0, 2, 1) + +//-------------------------------------------------------------- + +/* +** test_bfloat16x8x4_t: +** ins v2\.h\[5\], v3\.h\[6\] +** ret +*/ +TEST (bfloat16x8x4_t, 2, 5, 3, 6) + +/* +** test_float16x8x4_t: +** ins v0\.h\[3\], v3\.h\[5\] +** ret +*/ +TEST (float16x8x4_t, 0, 3, 3, 5) + +/* +** test_float32x4x4_t: +** ins v3\.s\[2\], v2\.s\[1\] +** ret +*/ +TEST (float32x4x4_t, 3, 2, 2, 1) + +/* +** test_float64x2x4_t: +** ins v1\.d\[1\], v3\.d\[0\] +** ret +*/ +TEST (float64x2x4_t, 1, 1, 3, 0) + +/* +** test_int8x16x4_t: +** ins v0\.b\[14\], v3\.b\[10\] +** ret +*/ +TEST (int8x16x4_t, 0, 14, 3, 10) + +/* +** test_int16x8x4_t: +** ins v3\.h\[4\], v1\.h\[6\] +** ret +*/ +TEST (int16x8x4_t, 3, 4, 1, 6) + +/* +** test_int32x4x4_t: +** ins v1\.s\[3\], v3\.s\[1\] +** ret +*/ +TEST (int32x4x4_t, 1, 3, 3, 1) + +/* +** test_int64x2x4_t: +** ins v3\.d\[0\], v2\.d\[0\] +** ret +*/ +TEST (int64x2x4_t, 3, 0, 2, 0) + +/* +** test_uint8x16x4_t: +** ins v3\.b\[13\], v2\.b\[6\] +** ret +*/ +TEST (uint8x16x4_t, 3, 13, 2, 6) + +/* +** test_uint16x8x4_t: +** ins v3\.h\[2\], v1\.h\[7\] +** ret +*/ +TEST (uint16x8x4_t, 3, 2, 1, 7) + +/* +** test_uint32x4x4_t: +** ins v0\.s\[3\], v3\.s\[2\] +** ret +*/ +TEST (uint32x4x4_t, 0, 3, 3, 2) + +/* +** test_uint64x2x4_t: +** ins v1\.d\[0\], v3\.d\[1\] +** ret +*/ +TEST (uint64x2x4_t, 1, 0, 3, 1) diff --git a/gcc/testsuite/gcc.target/aarch64/pr113027-4.c b/gcc/testsuite/gcc.target/aarch64/pr113027-4.c new file mode 100644 index 000000000000..67f45dfa4f02 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr113027-4.c @@ -0,0 +1,268 @@ +/* { dg-options "-O2" } */ +/* { dg-final { check-function-bodies "**" "" "" { target aarch64_little_endian } } } */ + +#include + +#define TEST(TYPE, A, B) \ + TYPE \ + test_##TYPE (TYPE a, TYPE *ptr) \ + { \ + a.val[A][B] = ptr->val[0][0]; \ + return a; \ + } + +/* +** test_bfloat16x4x2_t: +** ld1 \{v1\.h\}\[3\], \[x0\] +** ret +*/ +TEST (bfloat16x4x2_t, 1, 3) + +/* +** test_float16x4x2_t: +** ld1 \{v1\.h\}\[1\], \[x0\] +** ret +*/ +TEST (float16x4x2_t, 1, 1) + +/* +** test_float32x2x2_t: +** ld1 \{v1\.s\}\[0\], \[x0\] +** ret +*/ +TEST (float32x2x2_t, 1, 0) + +/* +** test_float64x1x2_t: +** ldr d1, \[x0\] +** ret +*/ +TEST (float64x1x2_t, 1, 0) + +/* +** test_int8x8x2_t: +** ld1 \{v0\.b\}\[5\], \[x0\] +** ret +*/ +TEST (int8x8x2_t, 0, 5) + +/* +** test_int16x4x2_t: +** ld1 \{v0\.h\}\[2\], \[x0\] +** ret +*/ +TEST (int16x4x2_t, 0, 2) + +/* +** test_int32x2x2_t: +** ld1 \{v0\.s\}\[0\], \[x0\] +** ret +*/ +TEST (int32x2x2_t, 0, 0) + +/* +** test_int64x1x2_t: +** ldr d0, \[x0\] +** ret +*/ +TEST (int64x1x2_t, 0, 0) + +/* +** test_uint8x8x2_t: +** ld1 \{v1\.b\}\[6\], \[x0\] +** ret +*/ +TEST (uint8x8x2_t, 1, 6) + +/* +** test_uint16x4x2_t: +** ld1 \{v1\.h\}\[2\], \[x0\] +** ret +*/ +TEST (uint16x4x2_t, 1, 2) + +/* +** test_uint32x2x2_t: +** ld1 \{v1\.s\}\[0\], \[x0\] +** ret +*/ +TEST (uint32x2x2_t, 1, 0) + +/* +** test_uint64x1x2_t: +** ldr d1, \[x0\] +** ret +*/ +TEST (uint64x1x2_t, 1, 0) + +//-------------------------------------------------------------- + +/* +** test_bfloat16x4x3_t: +** ld1 \{v2\.h\}\[3\], \[x0\] +** ret +*/ +TEST (bfloat16x4x3_t, 2, 3) + +/* +** test_float16x4x3_t: +** ld1 \{v0\.h\}\[1\], \[x0\] +** ret +*/ +TEST (float16x4x3_t, 0, 1) + +/* +** test_float32x2x3_t: +** ld1 \{v1\.s\}\[0\], \[x0\] +** ret +*/ +TEST (float32x2x3_t, 1, 0) + +/* +** test_float64x1x3_t: +** ldr d1, \[x0\] +** ret +*/ +TEST (float64x1x3_t, 1, 0) + +/* +** test_int8x8x3_t: +** ld1 \{v0\.b\}\[5\], \[x0\] +** ret +*/ +TEST (int8x8x3_t, 0, 5) + +/* +** test_int16x4x3_t: +** ld1 \{v2\.h\}\[2\], \[x0\] +** ret +*/ +TEST (int16x4x3_t, 2, 2) + +/* +** test_int32x2x3_t: +** ld1 \{v1\.s\}\[0\], \[x0\] +** ret +*/ +TEST (int32x2x3_t, 1, 0) + +/* +** test_int64x1x3_t: +** ldr d2, \[x0\] +** ret +*/ +TEST (int64x1x3_t, 2, 0) + +/* +** test_uint8x8x3_t: +** ld1 \{v1\.b\}\[6\], \[x0\] +** ret +*/ +TEST (uint8x8x3_t, 1, 6) + +/* +** test_uint16x4x3_t: +** ld1 \{v2\.h\}\[2\], \[x0\] +** ret +*/ +TEST (uint16x4x3_t, 2, 2) + +/* +** test_uint32x2x3_t: +** ld1 \{v2\.s\}\[0\], \[x0\] +** ret +*/ +TEST (uint32x2x3_t, 2, 0) + +/* +** test_uint64x1x3_t: +** ldr d1, \[x0\] +** ret +*/ +TEST (uint64x1x3_t, 1, 0) + +//-------------------------------------------------------------- + +/* +** test_bfloat16x4x4_t: +** ld1 \{v2\.h\}\[3\], \[x0\] +** ret +*/ +TEST (bfloat16x4x4_t, 2, 3) + +/* +** test_float16x4x4_t: +** ld1 \{v0\.h\}\[2\], \[x0\] +** ret +*/ +TEST (float16x4x4_t, 0, 2) + +/* +** test_float32x2x4_t: +** ld1 \{v3\.s\}\[0\], \[x0\] +** ret +*/ +TEST (float32x2x4_t, 3, 0) + +/* +** test_float64x1x4_t: +** ldr d1, \[x0\] +** ret +*/ +TEST (float64x1x4_t, 1, 0) + +/* +** test_int8x8x4_t: +** ld1 \{v0\.b\}\[4\], \[x0\] +** ret +*/ +TEST (int8x8x4_t, 0, 4) + +/* +** test_int16x4x4_t: +** ld1 \{v3\.h\}\[3\], \[x0\] +** ret +*/ +TEST (int16x4x4_t, 3, 3) + +/* +** test_int32x2x4_t: +** ld1 \{v1\.s\}\[0\], \[x0\] +** ret +*/ +TEST (int32x2x4_t, 1, 0) + +/* +** test_int64x1x4_t: +** ldr d3, \[x0\] +** ret +*/ +TEST (int64x1x4_t, 3, 0) + +/* +** test_uint8x8x4_t: +** ld1 \{v3\.b\}\[6\], \[x0\] +** ret +*/ +TEST (uint8x8x4_t, 3, 6) + +/* +** test_uint16x4x4_t: +** ld1 \{v3\.h\}\[1\], \[x0\] +** ret +*/ +TEST (uint16x4x4_t, 3, 1) + +/* +** test_uint32x2x4_t: +** ld1 \{v0\.s\}\[0\], \[x0\] +** ret +*/ +TEST (uint32x2x4_t, 0, 0) + +/* +** test_uint64x1x4_t: +** ldr d1, \[x0\] +** ret +*/ +TEST (uint64x1x4_t, 1, 0) diff --git a/gcc/testsuite/gcc.target/aarch64/pr113027-5.c b/gcc/testsuite/gcc.target/aarch64/pr113027-5.c new file mode 100644 index 000000000000..5695ecab8ae2 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr113027-5.c @@ -0,0 +1,268 @@ +/* { dg-options "-O2" } */ +/* { dg-final { check-function-bodies "**" "" "" { target aarch64_little_endian } } } */ + +#include + +#define TEST(TYPE, A, B) \ + TYPE \ + test_##TYPE (TYPE a, TYPE *ptr) \ + { \ + a.val[A][B] = ptr->val[0][0]; \ + return a; \ + } + +/* +** test_bfloat16x8x2_t: +** ld1 \{v1\.h\}\[6\], \[x0\] +** ret +*/ +TEST (bfloat16x8x2_t, 1, 6) + +/* +** test_float16x8x2_t: +** ld1 \{v1\.h\}\[2\], \[x0\] +** ret +*/ +TEST (float16x8x2_t, 1, 2) + +/* +** test_float32x4x2_t: +** ld1 \{v1\.s\}\[3\], \[x0\] +** ret +*/ +TEST (float32x4x2_t, 1, 3) + +/* +** test_float64x2x2_t: +** ld1 \{v1\.d\}\[0\], \[x0\] +** ret +*/ +TEST (float64x2x2_t, 1, 0) + +/* +** test_int8x16x2_t: +** ld1 \{v0\.b\}\[15\], \[x0\] +** ret +*/ +TEST (int8x16x2_t, 0, 15) + +/* +** test_int16x8x2_t: +** ld1 \{v0\.h\}\[2\], \[x0\] +** ret +*/ +TEST (int16x8x2_t, 0, 2) + +/* +** test_int32x4x2_t: +** ld1 \{v0\.s\}\[3\], \[x0\] +** ret +*/ +TEST (int32x4x2_t, 0, 3) + +/* +** test_int64x2x2_t: +** ld1 \{v0\.d\}\[0\], \[x0\] +** ret +*/ +TEST (int64x2x2_t, 0, 0) + +/* +** test_uint8x16x2_t: +** ld1 \{v1\.b\}\[13\], \[x0\] +** ret +*/ +TEST (uint8x16x2_t, 1, 13) + +/* +** test_uint16x8x2_t: +** ld1 \{v1\.h\}\[6\], \[x0\] +** ret +*/ +TEST (uint16x8x2_t, 1, 6) + +/* +** test_uint32x4x2_t: +** ld1 \{v1\.s\}\[3\], \[x0\] +** ret +*/ +TEST (uint32x4x2_t, 1, 3) + +/* +** test_uint64x2x2_t: +** ld1 \{v1\.d\}\[0\], \[x0\] +** ret +*/ +TEST (uint64x2x2_t, 1, 0) + +//-------------------------------------------------------------- + +/* +** test_bfloat16x8x3_t: +** ld1 \{v2\.h\}\[3\], \[x0\] +** ret +*/ +TEST (bfloat16x8x3_t, 2, 3) + +/* +** test_float16x8x3_t: +** ld1 \{v0\.h\}\[4\], \[x0\] +** ret +*/ +TEST (float16x8x3_t, 0, 4) + +/* +** test_float32x4x3_t: +** ld1 \{v1\.s\}\[2\], \[x0\] +** ret +*/ +TEST (float32x4x3_t, 1, 2) + +/* +** test_float64x2x3_t: +** ld1 \{v1\.d\}\[0\], \[x0\] +** ret +*/ +TEST (float64x2x3_t, 1, 0) + +/* +** test_int8x16x3_t: +** ld1 \{v0\.b\}\[9\], \[x0\] +** ret +*/ +TEST (int8x16x3_t, 0, 9) + +/* +** test_int16x8x3_t: +** ld1 \{v2\.h\}\[6\], \[x0\] +** ret +*/ +TEST (int16x8x3_t, 2, 6) + +/* +** test_int32x4x3_t: +** ld1 \{v1\.s\}\[3\], \[x0\] +** ret +*/ +TEST (int32x4x3_t, 1, 3) + +/* +** test_int64x2x3_t: +** ld1 \{v2\.d\}\[1\], \[x0\] +** ret +*/ +TEST (int64x2x3_t, 2, 1) + +/* +** test_uint8x16x3_t: +** ld1 \{v1\.b\}\[10\], \[x0\] +** ret +*/ +TEST (uint8x16x3_t, 1, 10) + +/* +** test_uint16x8x3_t: +** ld1 \{v2\.h\}\[5\], \[x0\] +** ret +*/ +TEST (uint16x8x3_t, 2, 5) + +/* +** test_uint32x4x3_t: +** ld1 \{v2\.s\}\[3\], \[x0\] +** ret +*/ +TEST (uint32x4x3_t, 2, 3) + +/* +** test_uint64x2x3_t: +** ld1 \{v1\.d\}\[0\], \[x0\] +** ret +*/ +TEST (uint64x2x3_t, 1, 0) + +//-------------------------------------------------------------- + +/* +** test_bfloat16x8x4_t: +** ld1 \{v2\.h\}\[5\], \[x0\] +** ret +*/ +TEST (bfloat16x8x4_t, 2, 5) + +/* +** test_float16x8x4_t: +** ld1 \{v0\.h\}\[3\], \[x0\] +** ret +*/ +TEST (float16x8x4_t, 0, 3) + +/* +** test_float32x4x4_t: +** ld1 \{v3\.s\}\[2\], \[x0\] +** ret +*/ +TEST (float32x4x4_t, 3, 2) + +/* +** test_float64x2x4_t: +** ld1 \{v1\.d\}\[1\], \[x0\] +** ret +*/ +TEST (float64x2x4_t, 1, 1) + +/* +** test_int8x16x4_t: +** ld1 \{v0\.b\}\[14\], \[x0\] +** ret +*/ +TEST (int8x16x4_t, 0, 14) + +/* +** test_int16x8x4_t: +** ld1 \{v3\.h\}\[4\], \[x0\] +** ret +*/ +TEST (int16x8x4_t, 3, 4) + +/* +** test_int32x4x4_t: +** ld1 \{v1\.s\}\[3\], \[x0\] +** ret +*/ +TEST (int32x4x4_t, 1, 3) + +/* +** test_int64x2x4_t: +** ld1 \{v3\.d\}\[0\], \[x0\] +** ret +*/ +TEST (int64x2x4_t, 3, 0) + +/* +** test_uint8x16x4_t: +** ld1 \{v3\.b\}\[13\], \[x0\] +** ret +*/ +TEST (uint8x16x4_t, 3, 13) + +/* +** test_uint16x8x4_t: +** ld1 \{v3\.h\}\[2\], \[x0\] +** ret +*/ +TEST (uint16x8x4_t, 3, 2) + +/* +** test_uint32x4x4_t: +** ld1 \{v0\.s\}\[3\], \[x0\] +** ret +*/ +TEST (uint32x4x4_t, 0, 3) + +/* +** test_uint64x2x4_t: +** ld1 \{v1\.d\}\[0\], \[x0\] +** ret +*/ +TEST (uint64x2x4_t, 1, 0) diff --git a/gcc/testsuite/gcc.target/aarch64/pr113027-6.c b/gcc/testsuite/gcc.target/aarch64/pr113027-6.c new file mode 100644 index 000000000000..12d3a38f74b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr113027-6.c @@ -0,0 +1,267 @@ +/* { dg-options "-O2" } */ +/* { dg-final { check-function-bodies "**" "" "" { target aarch64_little_endian } } } */ + +#include + +#define TEST(TYPE, A, B) \ + void \ + test_##TYPE (TYPE a, TYPE *ptr) \ + { \ + ptr->val[0][0] = a.val[A][B]; \ + } + +/* +** test_bfloat16x4x2_t: +** st1 \{v1\.h\}\[3\], \[x0\] +** ret +*/ +TEST (bfloat16x4x2_t, 1, 3) + +/* +** test_float16x4x2_t: +** st1 \{v1\.h\}\[1\], \[x0\] +** ret +*/ +TEST (float16x4x2_t, 1, 1) + +/* +** test_float32x2x2_t: +** str s1, \[x0\] +** ret +*/ +TEST (float32x2x2_t, 1, 0) + +/* +** test_float64x1x2_t: +** str d1, \[x0\] +** ret +*/ +TEST (float64x1x2_t, 1, 0) + +/* +** test_int8x8x2_t: +** st1 \{v0\.b\}\[5\], \[x0\] +** ret +*/ +TEST (int8x8x2_t, 0, 5) + +/* +** test_int16x4x2_t: +** st1 \{v0\.h\}\[2\], \[x0\] +** ret +*/ +TEST (int16x4x2_t, 0, 2) + +/* +** test_int32x2x2_t: +** str s0, \[x0\] +** ret +*/ +TEST (int32x2x2_t, 0, 0) + +/* +** test_int64x1x2_t: +** str d0, \[x0\] +** ret +*/ +TEST (int64x1x2_t, 0, 0) + +/* +** test_uint8x8x2_t: +** st1 \{v1\.b\}\[6\], \[x0\] +** ret +*/ +TEST (uint8x8x2_t, 1, 6) + +/* +** test_uint16x4x2_t: +** st1 \{v1\.h\}\[2\], \[x0\] +** ret +*/ +TEST (uint16x4x2_t, 1, 2) + +/* +** test_uint32x2x2_t: +** str s1, \[x0\] +** ret +*/ +TEST (uint32x2x2_t, 1, 0) + +/* +** test_uint64x1x2_t: +** str d1, \[x0\] +** ret +*/ +TEST (uint64x1x2_t, 1, 0) + +//-------------------------------------------------------------- + +/* +** test_bfloat16x4x3_t: +** st1 \{v2\.h\}\[3\], \[x0\] +** ret +*/ +TEST (bfloat16x4x3_t, 2, 3) + +/* +** test_float16x4x3_t: +** st1 \{v0\.h\}\[1\], \[x0\] +** ret +*/ +TEST (float16x4x3_t, 0, 1) + +/* +** test_float32x2x3_t: +** str s1, \[x0\] +** ret +*/ +TEST (float32x2x3_t, 1, 0) + +/* +** test_float64x1x3_t: +** str d1, \[x0\] +** ret +*/ +TEST (float64x1x3_t, 1, 0) + +/* +** test_int8x8x3_t: +** st1 \{v0\.b\}\[5\], \[x0\] +** ret +*/ +TEST (int8x8x3_t, 0, 5) + +/* +** test_int16x4x3_t: +** st1 \{v2\.h\}\[2\], \[x0\] +** ret +*/ +TEST (int16x4x3_t, 2, 2) + +/* +** test_int32x2x3_t: +** str s1, \[x0\] +** ret +*/ +TEST (int32x2x3_t, 1, 0) + +/* +** test_int64x1x3_t: +** str d2, \[x0\] +** ret +*/ +TEST (int64x1x3_t, 2, 0) + +/* +** test_uint8x8x3_t: +** st1 \{v1\.b\}\[6\], \[x0\] +** ret +*/ +TEST (uint8x8x3_t, 1, 6) + +/* +** test_uint16x4x3_t: +** st1 \{v2\.h\}\[2\], \[x0\] +** ret +*/ +TEST (uint16x4x3_t, 2, 2) + +/* +** test_uint32x2x3_t: +** str s2, \[x0\] +** ret +*/ +TEST (uint32x2x3_t, 2, 0) + +/* +** test_uint64x1x3_t: +** str d1, \[x0\] +** ret +*/ +TEST (uint64x1x3_t, 1, 0) + +//-------------------------------------------------------------- + +/* +** test_bfloat16x4x4_t: +** st1 \{v2\.h\}\[3\], \[x0\] +** ret +*/ +TEST (bfloat16x4x4_t, 2, 3) + +/* +** test_float16x4x4_t: +** st1 \{v0\.h\}\[2\], \[x0\] +** ret +*/ +TEST (float16x4x4_t, 0, 2) + +/* +** test_float32x2x4_t: +** str s3, \[x0\] +** ret +*/ +TEST (float32x2x4_t, 3, 0) + +/* +** test_float64x1x4_t: +** str d1, \[x0\] +** ret +*/ +TEST (float64x1x4_t, 1, 0) + +/* +** test_int8x8x4_t: +** st1 \{v0\.b\}\[4\], \[x0\] +** ret +*/ +TEST (int8x8x4_t, 0, 4) + +/* +** test_int16x4x4_t: +** st1 \{v3\.h\}\[3\], \[x0\] +** ret +*/ +TEST (int16x4x4_t, 3, 3) + +/* +** test_int32x2x4_t: +** str s1, \[x0\] +** ret +*/ +TEST (int32x2x4_t, 1, 0) + +/* +** test_int64x1x4_t: +** str d3, \[x0\] +** ret +*/ +TEST (int64x1x4_t, 3, 0) + +/* +** test_uint8x8x4_t: +** st1 \{v3\.b\}\[6\], \[x0\] +** ret +*/ +TEST (uint8x8x4_t, 3, 6) + +/* +** test_uint16x4x4_t: +** st1 \{v3\.h\}\[1\], \[x0\] +** ret +*/ +TEST (uint16x4x4_t, 3, 1) + +/* +** test_uint32x2x4_t: +** str s0, \[x0\] +** ret +*/ +TEST (uint32x2x4_t, 0, 0) + +/* +** test_uint64x1x4_t: +** str d1, \[x0\] +** ret +*/ +TEST (uint64x1x4_t, 1, 0) diff --git a/gcc/testsuite/gcc.target/aarch64/pr113027-7.c b/gcc/testsuite/gcc.target/aarch64/pr113027-7.c new file mode 100644 index 000000000000..b3ae1a74f76c --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr113027-7.c @@ -0,0 +1,267 @@ +/* { dg-options "-O2" } */ +/* { dg-final { check-function-bodies "**" "" "" { target aarch64_little_endian } } } */ + +#include + +#define TEST(TYPE, A, B) \ + void \ + test_##TYPE (TYPE a, TYPE *ptr) \ + { \ + ptr->val[0][0] = a.val[A][B]; \ + } + +/* +** test_bfloat16x8x2_t: +** st1 \{v1\.h\}\[6\], \[x0\] +** ret +*/ +TEST (bfloat16x8x2_t, 1, 6) + +/* +** test_float16x8x2_t: +** st1 \{v1\.h\}\[2\], \[x0\] +** ret +*/ +TEST (float16x8x2_t, 1, 2) + +/* +** test_float32x4x2_t: +** st1 \{v1\.s\}\[3\], \[x0\] +** ret +*/ +TEST (float32x4x2_t, 1, 3) + +/* +** test_float64x2x2_t: +** str d1, \[x0\] +** ret +*/ +TEST (float64x2x2_t, 1, 0) + +/* +** test_int8x16x2_t: +** st1 \{v0\.b\}\[15\], \[x0\] +** ret +*/ +TEST (int8x16x2_t, 0, 15) + +/* +** test_int16x8x2_t: +** st1 \{v0\.h\}\[2\], \[x0\] +** ret +*/ +TEST (int16x8x2_t, 0, 2) + +/* +** test_int32x4x2_t: +** st1 \{v0\.s\}\[3\], \[x0\] +** ret +*/ +TEST (int32x4x2_t, 0, 3) + +/* +** test_int64x2x2_t: +** str d0, \[x0\] +** ret +*/ +TEST (int64x2x2_t, 0, 0) + +/* +** test_uint8x16x2_t: +** st1 \{v1\.b\}\[13\], \[x0\] +** ret +*/ +TEST (uint8x16x2_t, 1, 13) + +/* +** test_uint16x8x2_t: +** st1 \{v1\.h\}\[6\], \[x0\] +** ret +*/ +TEST (uint16x8x2_t, 1, 6) + +/* +** test_uint32x4x2_t: +** st1 \{v1\.s\}\[3\], \[x0\] +** ret +*/ +TEST (uint32x4x2_t, 1, 3) + +/* +** test_uint64x2x2_t: +** str d1, \[x0\] +** ret +*/ +TEST (uint64x2x2_t, 1, 0) + +//-------------------------------------------------------------- + +/* +** test_bfloat16x8x3_t: +** st1 \{v2\.h\}\[3\], \[x0\] +** ret +*/ +TEST (bfloat16x8x3_t, 2, 3) + +/* +** test_float16x8x3_t: +** st1 \{v0\.h\}\[4\], \[x0\] +** ret +*/ +TEST (float16x8x3_t, 0, 4) + +/* +** test_float32x4x3_t: +** st1 \{v1\.s\}\[2\], \[x0\] +** ret +*/ +TEST (float32x4x3_t, 1, 2) + +/* +** test_float64x2x3_t: +** str d1, \[x0\] +** ret +*/ +TEST (float64x2x3_t, 1, 0) + +/* +** test_int8x16x3_t: +** st1 \{v0\.b\}\[9\], \[x0\] +** ret +*/ +TEST (int8x16x3_t, 0, 9) + +/* +** test_int16x8x3_t: +** st1 \{v2\.h\}\[6\], \[x0\] +** ret +*/ +TEST (int16x8x3_t, 2, 6) + +/* +** test_int32x4x3_t: +** st1 \{v1\.s\}\[3\], \[x0\] +** ret +*/ +TEST (int32x4x3_t, 1, 3) + +/* +** test_int64x2x3_t: +** st1 \{v2\.d\}\[1\], \[x0\] +** ret +*/ +TEST (int64x2x3_t, 2, 1) + +/* +** test_uint8x16x3_t: +** st1 \{v1\.b\}\[10\], \[x0\] +** ret +*/ +TEST (uint8x16x3_t, 1, 10) + +/* +** test_uint16x8x3_t: +** st1 \{v2\.h\}\[5\], \[x0\] +** ret +*/ +TEST (uint16x8x3_t, 2, 5) + +/* +** test_uint32x4x3_t: +** st1 \{v2\.s\}\[3\], \[x0\] +** ret +*/ +TEST (uint32x4x3_t, 2, 3) + +/* +** test_uint64x2x3_t: +** str d1, \[x0\] +** ret +*/ +TEST (uint64x2x3_t, 1, 0) + +//-------------------------------------------------------------- + +/* +** test_bfloat16x8x4_t: +** st1 \{v2\.h\}\[5\], \[x0\] +** ret +*/ +TEST (bfloat16x8x4_t, 2, 5) + +/* +** test_float16x8x4_t: +** st1 \{v0\.h\}\[3\], \[x0\] +** ret +*/ +TEST (float16x8x4_t, 0, 3) + +/* +** test_float32x4x4_t: +** st1 \{v3\.s\}\[2\], \[x0\] +** ret +*/ +TEST (float32x4x4_t, 3, 2) + +/* +** test_float64x2x4_t: +** st1 \{v1\.d\}\[1\], \[x0\] +** ret +*/ +TEST (float64x2x4_t, 1, 1) + +/* +** test_int8x16x4_t: +** st1 \{v0\.b\}\[14\], \[x0\] +** ret +*/ +TEST (int8x16x4_t, 0, 14) + +/* +** test_int16x8x4_t: +** st1 \{v3\.h\}\[4\], \[x0\] +** ret +*/ +TEST (int16x8x4_t, 3, 4) + +/* +** test_int32x4x4_t: +** st1 \{v1\.s\}\[3\], \[x0\] +** ret +*/ +TEST (int32x4x4_t, 1, 3) + +/* +** test_int64x2x4_t: +** str d3, \[x0\] +** ret +*/ +TEST (int64x2x4_t, 3, 0) + +/* +** test_uint8x16x4_t: +** st1 \{v3\.b\}\[13\], \[x0\] +** ret +*/ +TEST (uint8x16x4_t, 3, 13) + +/* +** test_uint16x8x4_t: +** st1 \{v3\.h\}\[2\], \[x0\] +** ret +*/ +TEST (uint16x8x4_t, 3, 2) + +/* +** test_uint32x4x4_t: +** st1 \{v0\.s\}\[3\], \[x0\] +** ret +*/ +TEST (uint32x4x4_t, 0, 3) + +/* +** test_uint64x2x4_t: +** str d1, \[x0\] +** ret +*/ +TEST (uint64x2x4_t, 1, 0) diff --git a/gcc/testsuite/gcc.target/aarch64/pr118348_1.c b/gcc/testsuite/gcc.target/aarch64/pr118348_1.c index 75f6dada63a3..2715dcb8b12f 100644 --- a/gcc/testsuite/gcc.target/aarch64/pr118348_1.c +++ b/gcc/testsuite/gcc.target/aarch64/pr118348_1.c @@ -1,4 +1,4 @@ -/* { dg-do run { target aarch64_sve128_hw } } */ +/* { dg-do run { target { aarch64_sve128_hw && fstack_protector } } } */ /* { dg-options "-O2 -fopenmp-simd -fno-trapping-math -msve-vector-bits=128 --param aarch64-autovec-preference=sve-only -fstack-protector-strong" } */ #pragma GCC target "+sve" diff --git a/gcc/testsuite/gcc.target/aarch64/pr118348_2.c b/gcc/testsuite/gcc.target/aarch64/pr118348_2.c index 2e200044637a..4ce8d20236cc 100644 --- a/gcc/testsuite/gcc.target/aarch64/pr118348_2.c +++ b/gcc/testsuite/gcc.target/aarch64/pr118348_2.c @@ -1,4 +1,4 @@ -/* { dg-do run { target aarch64_sve256_hw } } */ +/* { dg-do run { target { aarch64_sve256_hw && fstack_protector } } } */ /* { dg-options "-O2 -fopenmp-simd -fno-trapping-math -msve-vector-bits=256 --param aarch64-autovec-preference=sve-only -fstack-protector-strong" } */ #include "pr118348_1.c" diff --git a/gcc/testsuite/gcc.target/aarch64/simd/bcax_d.c b/gcc/testsuite/gcc.target/aarch64/simd/bcax_d.c new file mode 100644 index 000000000000..a7640c3f6f1e --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/bcax_d.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include + +#pragma GCC target "+sha3" + +#define BCAX(x,y,z) ((x) ^ ((y) & ~(z))) + +/* When the inputs come from GP regs don't form a BCAX. */ +uint64_t bcax_d_gp (uint64_t a, uint64_t b, uint64_t c) { return BCAX (a, b, c); } + +uint64x1_t bcax_d (uint64x1_t a, uint64x1_t b, uint64x1_t c) { return BCAX (a, b, c); } +uint32x2_t bcax_s (uint32x2_t a, uint32x2_t b, uint32x2_t c) { return BCAX (a, b, c); } +uint16x4_t bcax_h (uint16x4_t a, uint16x4_t b, uint16x4_t c) { return BCAX (a, b, c); } +uint8x8_t bcax_b (uint8x8_t a, uint8x8_t b, uint8x8_t c) { return BCAX (a, b, c); } + +/* { dg-final { scan-assembler-times {bcax\tv0.16b, v0.16b, v1.16b, v2.16b} 4 } } */ + diff --git a/gcc/testsuite/gcc.target/aarch64/simd/eor3_d.c b/gcc/testsuite/gcc.target/aarch64/simd/eor3_d.c new file mode 100644 index 000000000000..7f2b2b422685 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/eor3_d.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include + +#pragma GCC target "+sha3" + +#define EOR3(x,y,z) ((x) ^ (y) ^ (z)) + +uint32x2_t bcax_s (uint32x2_t a, uint32x2_t b, uint32x2_t c) { return EOR3 (a, b, c); } +uint16x4_t bcax_h (uint16x4_t a, uint16x4_t b, uint16x4_t c) { return EOR3 (a, b, c); } +uint8x8_t bcax_b (uint8x8_t a, uint8x8_t b, uint8x8_t c) { return EOR3 (a, b, c); } + +/* { dg-final { scan-assembler-times {eor3\tv0.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b} 3 } } */ + diff --git a/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_1.c b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_1.c new file mode 100644 index 000000000000..f082198b54bc --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_1.c @@ -0,0 +1,716 @@ +/* { dg-do compile } */ +/* { dg-options "-O -march=armv9-a+bf16" } */ + +#include + +/* We should use the highpart instruction where doing so would avoid data + movement instructions. This case, where all the arguments are non-constant + vector highparts, can be handled by either gimple_fold_builtin or combine. */ + +#ifndef TEST_UN_HIGHPARTS +#define TEST_UN_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (INTYPE a) \ + { \ + return FN##_##SUFF (vget_high_##SUFF (a)); \ + } +#endif + +#ifndef TEST_BIN_W_HIGHPARTS +#define TEST_BIN_W_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (RETTYPE a, INTYPE b) \ + { \ + return FN##_##SUFF (a, vget_high_##SUFF (b)); \ + } +#endif + +#ifndef TEST_BIN_N_HIGHPARTS +#define TEST_BIN_N_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (INTYPE a) \ + { \ + return FN##_##SUFF (vget_high_##SUFF (a), a[1]); \ + } +#endif + +#ifndef TEST_TERN_N_HIGHPARTS +#define TEST_TERN_N_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (RETTYPE a, INTYPE b) \ + { \ + return FN##_##SUFF (a, vget_high_##SUFF (b), b[1]); \ + } +#endif + +#ifndef TEST_BIN_HIGHPARTS +#define TEST_BIN_HIGHPARTS(FN, RETTYPE, INTYPE, H_INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (INTYPE a, INTYPE b) \ + { \ + return FN##_##SUFF (vget_high_##SUFF (a), \ + vget_high_##SUFF (b)); \ + } +#endif + +#ifndef TEST_TERN_HIGHPARTS +#define TEST_TERN_HIGHPARTS(FN, RETTYPE, INTYPE, H_INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (RETTYPE a, INTYPE b, INTYPE c) \ + { \ + return FN##_##SUFF(a, vget_high_##SUFF (b), \ + vget_high_##SUFF (c)); \ + } +#endif + +#define TEST_UNOP(FN) \ + TEST_UN_HIGHPARTS (FN, int16x8_t, int8x16_t, s8) \ + TEST_UN_HIGHPARTS (FN, uint16x8_t, uint8x16_t, u8) \ + TEST_UN_HIGHPARTS (FN, int32x4_t, int16x8_t, s16) \ + TEST_UN_HIGHPARTS (FN, uint32x4_t, uint16x8_t, u16) \ + TEST_UN_HIGHPARTS (FN, int64x2_t, int32x4_t, s32) \ + TEST_UN_HIGHPARTS (FN, uint64x2_t, uint32x4_t, u32) + +#define TEST_BINOP(FN) \ + TEST_BIN_HIGHPARTS (FN, int16x8_t, int8x16_t, int8x8_t, s8) \ + TEST_BIN_HIGHPARTS (FN, uint16x8_t, uint8x16_t, uint8x8_t, u8) \ + TEST_BIN_HIGHPARTS (FN, int32x4_t, int16x8_t, int16x4_t, s16) \ + TEST_BIN_HIGHPARTS (FN, uint32x4_t, uint16x8_t, uint16x4_t, u16) \ + TEST_BIN_HIGHPARTS (FN, int64x2_t, int32x4_t, int32x2_t, s32) \ + TEST_BIN_HIGHPARTS (FN, uint64x2_t, uint32x4_t, uint32x2_t, u32) + +#define TEST_BINOP_N(FN) \ + TEST_BIN_N_HIGHPARTS (FN, int32x4_t, int16x8_t, s16) \ + TEST_BIN_N_HIGHPARTS (FN, uint32x4_t, uint16x8_t, u16) \ + TEST_BIN_N_HIGHPARTS (FN, int64x2_t, int32x4_t, s32) \ + TEST_BIN_N_HIGHPARTS (FN, uint64x2_t, uint32x4_t, u32) + +#define TEST_BINOP_W(FN) \ + TEST_BIN_W_HIGHPARTS (FN, int16x8_t, int8x16_t, s8) \ + TEST_BIN_W_HIGHPARTS (FN, uint16x8_t, uint8x16_t, u8) \ + TEST_BIN_W_HIGHPARTS (FN, int32x4_t, int16x8_t, s16) \ + TEST_BIN_W_HIGHPARTS (FN, uint32x4_t, uint16x8_t, u16) \ + TEST_BIN_W_HIGHPARTS (FN, int64x2_t, int32x4_t, s32) \ + TEST_BIN_W_HIGHPARTS (FN, uint64x2_t, uint32x4_t, u32) + +#define TEST_TERNOP_N(FN) \ + TEST_TERN_N_HIGHPARTS (FN, int32x4_t, int16x8_t, s16) \ + TEST_TERN_N_HIGHPARTS (FN, uint32x4_t, uint16x8_t, u16) \ + TEST_TERN_N_HIGHPARTS (FN, int64x2_t, int32x4_t, s32) \ + TEST_TERN_N_HIGHPARTS (FN, uint64x2_t, uint32x4_t, u32) + +#define TEST_TERNOP(FN) \ + TEST_TERN_HIGHPARTS (FN, int16x8_t, int8x16_t, int8x8_t, s8) \ + TEST_TERN_HIGHPARTS (FN, uint16x8_t, uint8x16_t, uint8x8_t, u8) \ + TEST_TERN_HIGHPARTS (FN, int32x4_t, int16x8_t, int16x4_t, s16) \ + TEST_TERN_HIGHPARTS (FN, uint32x4_t, uint16x8_t, uint16x4_t, u16) \ + TEST_TERN_HIGHPARTS (FN, int64x2_t, int32x4_t, int32x2_t, s32) \ + TEST_TERN_HIGHPARTS (FN, uint64x2_t, uint32x4_t, uint32x2_t, u32) + +#define TEST_VQDMULL \ + TEST_BIN_HIGHPARTS (vqdmull, int32x4_t, int16x8_t, int16x4_t, s16) \ + TEST_BIN_HIGHPARTS (vqdmull, int64x2_t, int32x4_t, int32x2_t, s32) + +#define TEST_VQDMULL_N \ + TEST_BIN_N_HIGHPARTS (vqdmull_n, int32x4_t, int16x8_t, s16) \ + TEST_BIN_N_HIGHPARTS (vqdmull_n, int64x2_t, int32x4_t, s32) + +#define TEST_VQMLAL \ + TEST_TERN_HIGHPARTS (vqdmlal, int32x4_t, int16x8_t, int16x4_t, s16) \ + TEST_TERN_HIGHPARTS (vqdmlal, int64x2_t, int32x4_t, int32x2_t, s32) + +#define TEST_VQMLAL_N \ + TEST_TERN_N_HIGHPARTS (vqdmlal_n, int32x4_t, int16x8_t, s16) \ + TEST_TERN_N_HIGHPARTS (vqdmlal_n, int64x2_t, int32x4_t, s32) + +#define TEST_VQMLSL \ + TEST_TERN_HIGHPARTS (vqdmlsl, int32x4_t, int16x8_t, int16x4_t, s16) \ + TEST_TERN_HIGHPARTS (vqdmlsl, int64x2_t, int32x4_t, int32x2_t, s32) + +#define TEST_VQMLSL_N \ + TEST_TERN_N_HIGHPARTS (vqdmlsl_n, int32x4_t, int16x8_t, s16) \ + TEST_TERN_N_HIGHPARTS (vqdmlsl_n, int64x2_t, int32x4_t, s32) + +#define TEST_VMOVL \ + TEST_UNOP (vmovl) + +#define TEST_VMULL \ + TEST_BINOP (vmull) \ + TEST_BIN_HIGHPARTS (vmull, poly16x8_t, poly8x16_t, poly8x8_t, p8) + +#define TEST_VMULL_N \ + TEST_BINOP_N (vmull_n) + +#define TEST_VADDL \ + TEST_BINOP (vaddl) + +#define TEST_VSUBL \ + TEST_BINOP (vsubl) + +#define TEST_VMLAL \ + TEST_TERNOP (vmlal) + +#define TEST_VMLAL_N \ + TEST_TERNOP_N (vmlal_n) + +#define TEST_VMLSL \ + TEST_TERNOP (vmlsl) + +#define TEST_VMLSL_N \ + TEST_TERNOP_N (vmlsl_n) + +#define TEST_VABDL \ + TEST_BINOP (vabdl) + +#define TEST_VABAL \ + TEST_TERNOP (vabal) + +#define TEST_VSUBW \ + TEST_BINOP_W (vsubw) + +#define TEST_VADDW \ + TEST_BINOP_W (vaddw) + +/* +** test_vmovl_s8: +** sxtl2 v0\.8h, v0\.16b +** ret +*/ + +/* +** test_vmovl_u8: +** uxtl2 v0\.8h, v0\.16b +** ret +*/ + +/* +** test_vmovl_s16: +** sxtl2 v0\.4s, v0\.8h +** ret +*/ + +/* +** test_vmovl_u16: +** uxtl2 v0\.4s, v0\.8h +** ret +*/ + +/* +** test_vmovl_s32: +** sxtl2 v0\.2d, v0\.4s +** ret +*/ + +/* +** test_vmovl_u32: +** uxtl2 v0\.2d, v0\.4s +** ret +*/ + +TEST_VMOVL + +/* +** test_vmull_s8: +** smull2 v0\.8h, (v0\.16b, v1\.16b|v1\.16b, v0\.16b) +** ret +*/ + +/* +** test_vmull_u8: +** umull2 v0\.8h, (v0\.16b, v1\.16b|v1\.16b, v0\.16b) +** ret +*/ + +/* +** test_vmull_s16: +** smull2 v0\.4s, (v0\.8h, v1\.8h|v1\.8h, v0\.8h) +** ret +*/ + +/* +** test_vmull_u16: +** umull2 v0\.4s, (v0\.8h, v1\.8h|v1\.8h, v0\.8h) +** ret +*/ + +/* +** test_vmull_s32: +** smull2 v0\.2d, (v0\.4s, v1\.4s|v1\.4s, v0\.4s) +** ret +*/ + +/* +** test_vmull_u32: +** umull2 v0\.2d, (v0\.4s, v1\.4s|v1\.4s, v0\.4s) +** ret +*/ + +/* +** test_vmull_p8: +** pmull2 v0\.8h, (v0\.16b, v1\.16b|v1\.16b, v0\.16b) +** ret +*/ + +TEST_VMULL + +/* +** test_vmull_n_s16: +** smull2 v0\.4s, v0\.8h, v0\.h\[[0-7]\] +** ret +*/ + +/* +** test_vmull_n_u16: +** umull2 v0\.4s, v0\.8h, v0\.h\[[0-7]\] +** ret +*/ + +/* +** test_vmull_n_s32: +** smull2 v0\.2d, v0\.4s, v0\.s\[[0-3]\] +** ret +*/ + +/* +** test_vmull_n_u32: +** umull2 v0\.2d, v0\.4s, v0\.s\[[0-3]\] +** ret +*/ + +TEST_VMULL_N + +/* +** test_vaddl_s8: +** saddl2 v0\.8h, (v0\.16b, v1\.16b|v1\.16b, v0\.16b) +** ret +*/ + +/* +** test_vaddl_u8: +** uaddl2 v0\.8h, (v0\.16b, v1\.16b|v1\.16b, v0\.16b) +** ret +*/ + +/* +** test_vaddl_s16: +** saddl2 v0\.4s, (v0\.8h, v1\.8h|v1\.8h, v0\.8h) +** ret +*/ + +/* +** test_vaddl_u16: +** uaddl2 v0\.4s, (v0\.8h, v1\.8h|v1\.8h, v0\.8h) +** ret +*/ + +/* +** test_vaddl_s32: +** saddl2 v0\.2d, (v0\.4s, v1\.4s|v1\.4s, v0\.4s) +** ret +*/ + +/* +** test_vaddl_u32: +** uaddl2 v0\.2d, (v0\.4s, v1\.4s|v1\.4s, v0\.4s) +** ret +*/ + +TEST_VADDL + +/* +** test_vsubl_s8: +** ssubl2 v0\.8h, v0\.16b, v1\.16b +** ret +*/ + +/* +** test_vsubl_u8: +** usubl2 v0\.8h, v0\.16b, v1\.16b +** ret +*/ + +/* +** test_vsubl_s16: +** ssubl2 v0\.4s, v0\.8h, v1\.8h +** ret +*/ + +/* +** test_vsubl_u16: +** usubl2 v0\.4s, v0\.8h, v1\.8h +** ret +*/ + +/* +** test_vsubl_s32: +** ssubl2 v0\.2d, v0\.4s, v1\.4s +** ret +*/ + +/* +** test_vsubl_u32: +** usubl2 v0\.2d, v0\.4s, v1\.4s +** ret +*/ + +TEST_VSUBL + +/* +** test_vabal_s8: +** sabal2 v0\.8h, (v1\.16b, v2\.16b|v2\.16b, v1\.16b) +** ret +*/ + +/* +** test_vabal_u8: +** uabal2 v0\.8h, (v1\.16b, v2\.16b|v2\.16b, v1\.16b) +** ret +*/ + +/* +** test_vabal_s16: +** sabal2 v0\.4s, (v1\.8h, v2\.8h|v2\.8h, v1\.8h) +** ret +*/ + +/* +** test_vabal_u16: +** uabal2 v0\.4s, (v1\.8h, v2\.8h|v2\.8h, v1\.8h) +** ret +*/ + +/* +** test_vabal_s32: +** sabal2 v0\.2d, (v1\.4s, v2\.4s|v2\.4s, v1\.4s) +** ret +*/ + +/* +** test_vabal_u32: +** uabal2 v0\.2d, (v1\.4s, v2\.4s|v2\.4s, v1\.4s) +** ret +*/ + +TEST_VABAL + +/* +** test_vsubw_s8: +** ssubw2 v0\.8h, v0\.8h, v1\.16b +** ret +*/ + +/* +** test_vsubw_u8: +** usubw2 v0\.8h, v0\.8h, v1\.16b +** ret +*/ + +/* +** test_vsubw_s16: +** ssubw2 v0\.4s, v0\.4s, v1\.8h +** ret +*/ + +/* +** test_vsubw_u16: +** usubw2 v0\.4s, v0\.4s, v1\.8h +** ret +*/ + +/* +** test_vsubw_s32: +** ssubw2 v0\.2d, v0\.2d, v1\.4s +** ret +*/ + +/* +** test_vsubw_u32: +** usubw2 v0\.2d, v0\.2d, v1\.4s +** ret +*/ + +TEST_VSUBW + +/* +** test_vaddw_s8: +** saddw2 v0\.8h, v0\.8h, v1\.16b +** ret +*/ + +/* +** test_vaddw_u8: +** uaddw2 v0\.8h, v0\.8h, v1\.16b +** ret +*/ + +/* +** test_vaddw_s16: +** saddw2 v0\.4s, v0\.4s, v1\.8h +** ret +*/ + +/* +** test_vaddw_u16: +** uaddw2 v0\.4s, v0\.4s, v1\.8h +** ret +*/ + +/* +** test_vaddw_s32: +** saddw2 v0\.2d, v0\.2d, v1\.4s +** ret +*/ + +/* +** test_vaddw_u32: +** uaddw2 v0\.2d, v0\.2d, v1\.4s +** ret +*/ + +TEST_VADDW + +/* +** test_vabdl_s8: +** sabdl2 v0\.8h, (v0\.16b, v1\.16b|v1\.16b, v0\.16b) +** ret +*/ + +/* +** test_vabdl_u8: +** uabdl2 v0\.8h, (v0\.16b, v1\.16b|v1\.16b, v0\.16b) +** ret +*/ + +/* +** test_vabdl_s16: +** sabdl2 v0\.4s, (v0\.8h, v1\.8h|v1\.8h, v0\.8h) +** ret +*/ + +/* +** test_vabdl_u16: +** uabdl2 v0\.4s, (v0\.8h, v1\.8h|v1\.8h, v0\.8h) +** ret +*/ + +/* +** test_vabdl_s32: +** sabdl2 v0\.2d, (v0\.4s, v1\.4s|v1\.4s, v0\.4s) +** ret +*/ + +/* +** test_vabdl_u32: +** uabdl2 v0\.2d, (v0\.4s, v1\.4s|v1\.4s, v0\.4s) +** ret +*/ + +TEST_VABDL + +/* +** test_vmlal_s8: +** smlal2 v0\.8h, (v1\.16b, v2\.16b|v2\.16b, v1\.16b) +** ret +*/ + +/* +** test_vmlal_u8: +** umlal2 v0\.8h, (v1\.16b, v2\.16b|v2\.16b, v1\.16b) +** ret +*/ + +/* +** test_vmlal_s16: +** smlal2 v0\.4s, (v1\.8h, v2\.8h|v2\.8h, v1\.8h) +** ret +*/ + +/* +** test_vmlal_u16: +** umlal2 v0\.4s, (v1\.8h, v2\.8h|v2\.8h, v1\.8h) +** ret +*/ + +/* +** test_vmlal_s32: +** smlal2 v0\.2d, (v1\.4s, v2\.4s|v2\.4s, v1\.4s) +** ret +*/ + +/* +** test_vmlal_u32: +** umlal2 v0\.2d, (v1\.4s, v2\.4s|v2\.4s, v1\.4s) +** ret +*/ + +TEST_VMLAL + +/* +** test_vmlal_n_s16: +** smlal2 v0\.4s, v1\.8h, v1\.h\[[0-7]\] +** ret +*/ + +/* +** test_vmlal_n_u16: +** umlal2 v0\.4s, v1\.8h, v1\.h\[[0-7]\] +** ret +*/ + +/* +** test_vmlal_n_s32: +** smlal2 v0\.2d, v1\.4s, v1\.s\[[0-3]\] +** ret +*/ + +/* +** test_vmlal_n_u32: +** umlal2 v0\.2d, v1\.4s, v1\.s\[[0-3]\] +** ret +*/ + +TEST_VMLAL_N + +/* +** test_vmlsl_s8: +** smlsl2 v0\.8h, v1\.16b, v2\.16b +** ret +*/ + +/* +** test_vmlsl_u8: +** umlsl2 v0\.8h, v1\.16b, v2\.16b +** ret +*/ + +/* +** test_vmlsl_s16: +** smlsl2 v0\.4s, v1\.8h, v2\.8h +** ret +*/ + +/* +** test_vmlsl_u16: +** umlsl2 v0\.4s, v1\.8h, v2\.8h +** ret +*/ + +/* +** test_vmlsl_s32: +** smlsl2 v0\.2d, v1\.4s, v2\.4s +** ret +*/ + +/* +** test_vmlsl_u32: +** umlsl2 v0\.2d, v1\.4s, v2\.4s +** ret +*/ + +TEST_VMLSL + +/* +** test_vmlsl_n_s16: +** smlsl2 v0\.4s, v1\.8h, v1\.h\[[0-7]\] +** ret +*/ + +/* +** test_vmlsl_n_u16: +** umlsl2 v0\.4s, v1\.8h, v1\.h\[[0-7]\] +** ret +*/ + +/* +** test_vmlsl_n_s32: +** smlsl2 v0\.2d, v1\.4s, v1\.s\[[0-3]\] +** ret +*/ + +/* +** test_vmlsl_n_u32: +** umlsl2 v0\.2d, v1\.4s, v1\.s\[[0-3]\] +** ret +*/ + +TEST_VMLSL_N + +/* +** test_vqdmull_s16: +** sqdmull2 v0\.4s, (v0\.8h, v1\.8h|v1\.8h, v0\.8h) +** ret +*/ + +/* +** test_vqdmull_s32: +** sqdmull2 v0\.2d, (v0\.4s, v1\.4s|v1\.4s, v0\.4s) +** ret +*/ + +TEST_VQDMULL + +/* +** test_vqdmull_n_s16: +** sqdmull2 v0\.4s, v0\.8h, v0\.h\[[0-7]\] +** ret +*/ + +/* +** test_vqdmull_n_s32: +** sqdmull2 v0\.2d, v0\.4s, v0\.s\[[0-3]\] +** ret +*/ + +TEST_VQDMULL_N + +/* +** test_vqdmlal_s16: +** sqdmlal2 v0\.4s, (v1\.8h, v2\.8h|v2\.8h, v1\.8h) +** ret +*/ + +/* +** test_vqdmlal_s32: +** sqdmlal2 v0\.2d, (v1\.4s, v2\.4s|v2\.4s, v1\.4s) +** ret +*/ + +TEST_VQMLAL + +/* +** test_vqdmlal_n_s16: +** sqdmlal2 v0\.4s, v1\.8h, v1\.h\[[0-7]\] +** ret +*/ + +/* +** test_vqdmlal_n_s32: +** sqdmlal2 v0\.2d, v1\.4s, v1\.s\[[0-3]\] +** ret +*/ + +TEST_VQMLAL_N + +/* +** test_vqdmlsl_s16: +** sqdmlsl2 v0\.4s, v1\.8h, v2\.8h +** ret +*/ + +/* +** test_vqdmlsl_s32: +** sqdmlsl2 v0\.2d, v1\.4s, v2\.4s +** ret +*/ + +TEST_VQMLSL + +/* +** test_vqdmlsl_n_s16: +** sqdmlsl2 v0\.4s, v1\.8h, v1\.h\[[0-7]\] +** ret +*/ + +/* +** test_vqdmlsl_n_s32: +** sqdmlsl2 v0\.2d, v1\.4s, v1\.s\[[0-3]\] +** ret +*/ + +TEST_VQMLSL_N + +/* { dg-final { check-function-bodies "**" ""} } */ diff --git a/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_2.c b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_2.c new file mode 100644 index 000000000000..5885b282ce1f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_2.c @@ -0,0 +1,88 @@ +/* { dg-do compile } */ +/* { dg-options "-O -march=armv9-a+bf16" } */ + +/* We should not use the highpart instruction unless doing so would avoid + data movement instructions. That is, unless at least one argument is a + reference to the highpart of a non-constant vector. */ + +#define TEST_UN_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_##FN##_## SUFF () \ + { \ + INTYPE a = vdupq_n_##SUFF (0x1A); \ + return FN##_##SUFF (vget_high_##SUFF (a)); \ + } + +#define TEST_BIN_W_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (RETTYPE a) \ + { \ + INTYPE b = vdupq_n_##SUFF (0x1A); \ + return FN##_##SUFF (a, vget_high_##SUFF (b)); \ + } + +#define TEST_BIN_N_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (INTYPE c) \ + { \ + INTYPE a = vdupq_n_##SUFF (0x1A); \ + return FN##_##SUFF (vget_high_##SUFF (a), c[1]); \ + } + +#define TEST_TERN_N_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (RETTYPE a) \ + { \ + INTYPE b = vdupq_n_##SUFF (0x1A); \ + return FN##_##SUFF (a, vget_high_##SUFF (b), b[1]); \ + } + +#define TEST_BIN_HIGHPARTS(FN, RETTYPE, INTYPE, H_INTYPE, SUFF) \ + RETTYPE test_##FN##_## SUFF (H_INTYPE b) \ + { \ + INTYPE a = vdupq_n_##SUFF (0x1A); \ + return FN##_##SUFF (vget_high_##SUFF (a), b); \ + } + +#define TEST_TERN_HIGHPARTS(FN, RETTYPE, INTYPE, H_INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (RETTYPE a, H_INTYPE b) \ + { \ + INTYPE c = vdupq_n_##SUFF (0x1A); \ + return FN##_##SUFF (a, vget_high_##SUFF (c), b); \ + } + +#include "fold_to_highpart_1.c" + + +/* { dg-final { scan-assembler-not {uxtl2\t} } } */ +/* { dg-final { scan-assembler-not {sxtl2\t} } } */ + +/* { dg-final { scan-assembler-not {umull2\t} } } */ +/* { dg-final { scan-assembler-not {smull2\t} } } */ +/* { dg-final { scan-assembler-not {pmull2\t} } } */ + +/* { dg-final { scan-assembler-not {uaddl2\t} } } */ +/* { dg-final { scan-assembler-not {saddl2\t} } } */ + +/* { dg-final { scan-assembler-not {usubl2\t} } } */ +/* { dg-final { scan-assembler-not {ssubl2\t} } } */ + +/* { dg-final { scan-assembler-not {uabal2\t} } } */ +/* { dg-final { scan-assembler-not {sabal2\t} } } */ + +/* { dg-final { scan-assembler-not {uabdl2\t} } } */ +/* { dg-final { scan-assembler-not {sabdl2\t} } } */ + +/* { dg-final { scan-assembler-not {usubw2\t} } } */ +/* { dg-final { scan-assembler-not {ssubw2\t} } } */ + +/* { dg-final { scan-assembler-not {uaddw2\t} } } */ +/* { dg-final { scan-assembler-not {saddw2\t} } } */ + +/* { dg-final { scan-assembler-not {umlal2\t} } } */ +/* { dg-final { scan-assembler-not {smlal2\t} } } */ + +/* { dg-final { scan-assembler-not {umlsl2\t} } } */ +/* { dg-final { scan-assembler-not {smlsl2\t} } } */ + +/* { dg-final { scan-assembler-not {sqdmull2\t} } } */ + +/* { dg-final { scan-assembler-not {sqdmlal2\t} } } */ + +/* { dg-final { scan-assembler-not {sqdmlsl2\t} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_3.c b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_3.c new file mode 100644 index 000000000000..3baf826c6772 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_3.c @@ -0,0 +1,83 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +/* PR117850 */ + +/* We should use the highpart instruction where doing so would avoid data + movement instructions. We avoid a DUP here after extending the + VECTOR_CSTs to 128-bits. */ + +#define TEST_UN_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) +#define TEST_BIN_W_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) +#define TEST_BIN_N_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) +#define TEST_TERN_N_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) + +#define TEST_BIN_HIGHPART_A1(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_a1_##FN##_##SUFF (INTYPE a) \ + { \ + INTYPE b = vdupq_n_##SUFF (0x1A); \ + return FN##_##SUFF (vget_high_##SUFF (a), \ + vget_high_##SUFF (b)); \ + } + +#define TEST_BIN_HIGHPART_A2(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_a2_##FN##_##SUFF (INTYPE a) \ + { \ + INTYPE b = vdupq_n_##SUFF (0x1A); \ + return FN##_##SUFF (vget_high_##SUFF (b), \ + vget_high_##SUFF (a)); \ + } + +#define TEST_TERN_HIGHPART_A1(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_a1_##FN##_##SUFF (RETTYPE a, INTYPE b) \ + { \ + INTYPE c = vdupq_n_##SUFF (0x1A); \ + return FN##_##SUFF (a, vget_high_##SUFF (b), \ + vget_high_##SUFF (c)); \ + } + +#define TEST_TERN_HIGHPART_A2(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_a2_##FN##_##SUFF (RETTYPE a, INTYPE b) \ + { \ + INTYPE c = vdupq_n_##SUFF (0x1A); \ + return FN##_##SUFF (a, vget_high_##SUFF (c), \ + vget_high_##SUFF (b)); \ + } + +#define TEST_BIN_HIGHPARTS(FN, RETTYPE, INTYPE, H_INTYPE, SUFF) \ + TEST_BIN_HIGHPART_A1 (FN, RETTYPE, INTYPE, SUFF) \ + TEST_BIN_HIGHPART_A2 (FN, RETTYPE, INTYPE, SUFF) + +#define TEST_TERN_HIGHPARTS(FN, RETTYPE, INTYPE, H_INTYPE, SUFF) \ + TEST_TERN_HIGHPART_A1 (FN, RETTYPE, INTYPE, SUFF) \ + TEST_TERN_HIGHPART_A2 (FN, RETTYPE, INTYPE, SUFF) + + +#include "fold_to_highpart_1.c" + +/* { dg-final { scan-assembler-not {dup\t} } } */ + +/* { dg-final { scan-assembler-times {smull2\t} 6} } */ +/* { dg-final { scan-assembler-times {umull2\t} 6} } */ +/* { dg-final { scan-assembler-times {pmull2\t} 2} } */ + +/* { dg-final { scan-assembler-times {saddl2\t} 6} } */ +/* { dg-final { scan-assembler-times {uaddl2\t} 6} } */ + +/* { dg-final { scan-assembler-times {ssubl2\t} 6} } */ +/* { dg-final { scan-assembler-times {usubl2\t} 6} } */ + +/* { dg-final { scan-assembler-times {sabdl2\t} 6} } */ +/* { dg-final { scan-assembler-times {uabdl2\t} 6} } */ + +/* { dg-final { scan-assembler-times {smlal2\t} 6} } */ +/* { dg-final { scan-assembler-times {umlal2\t} 6} } */ + +/* { dg-final { scan-assembler-times {smlsl2\t} 6} } */ +/* { dg-final { scan-assembler-times {umlsl2\t} 6} } */ + +/* { dg-final { scan-assembler-times {sqdmull2\t} 4} } */ + +/* { dg-final { scan-assembler-times {sqdmlal2\t} 4} } */ + +/* { dg-final { scan-assembler-times {sqdmlsl2\t} 4} } */ diff --git a/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_4.c b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_4.c new file mode 100644 index 000000000000..046c7a00def2 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_4.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target aarch64_little_endian } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +#include "arm_neon.h" + +#define VEC_CST_u8 0x0102030405060708 +#define VEC_CST_u16 0x0001000200030004 +#define VEC_CST_u32 0x0000000100000002 + +/* Extend the 64b VECTOR_CST to the type required by the hi builtin. */ + +uint16x8_t +test_u8 (uint8x16_t a) +{ + const uint8x8_t b = vcreate_u8 (VEC_CST_u8); + return vmull_u8 (vget_high_u8 (a), b); +} + +/* { dg-final { scan-tree-dump-times "\{ 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1 \}" 1 "optimized" } } */ + +uint32x4_t +test_u16 (uint16x8_t a) +{ + const uint16x4_t b = vcreate_u16 (VEC_CST_u16); + return vmull_u16 (vget_high_u16 (a), b); +} + +/* { dg-final { scan-tree-dump-times "\{ 4, 3, 2, 1, 4, 3, 2, 1 \}" 1 "optimized" } } */ + +uint64x2_t +test_u32 (uint32x4_t a) +{ + const uint32x2_t b = vcreate_u32 (VEC_CST_u32); + return vmull_u32 (vget_high_u32 (a), b); +} + +/* { dg-final { scan-tree-dump-times "\{ 2, 1, 2, 1 \}" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_5.c b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_5.c new file mode 100644 index 000000000000..4f39b675bff1 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_5.c @@ -0,0 +1,93 @@ +/* { dg-do compile } */ +/* { dg-options "-O -march=armv9-a+bf16" } */ + +/* Test that we can still fold when the base type of the vector who's + highpart we are referring to is incompatible with that of the hi + builtin. + + Use float64x2_t as it is never INTYPE. */ + +#define TEST_UN_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (float64x2_t a) \ + { \ + INTYPE x = vreinterpretq_##SUFF##_f64 (a); \ + return FN##_##SUFF(vget_high_##SUFF (x)); \ + } + +#define TEST_BIN_W_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (RETTYPE a, float64x2_t b) \ + { \ + INTYPE x = vreinterpretq_##SUFF##_f64 (b); \ + return FN##_##SUFF (a, vget_high_##SUFF (x)); \ + } + +#define TEST_BIN_N_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (float64x2_t a) \ + { \ + INTYPE x = vreinterpretq_##SUFF##_f64 (a); \ + return FN##_##SUFF (vget_high_##SUFF (x), x[1]); \ + } + +#define TEST_TERN_N_HIGHPARTS(FN, RETTYPE, INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (RETTYPE a, float64x2_t b) \ + { \ + INTYPE x = vreinterpretq_##SUFF##_f64 (b); \ + return FN##_##SUFF (a, vget_high_##SUFF (x), x[1]); \ + } + +#define TEST_BIN_HIGHPARTS(FN, RETTYPE, INTYPE, H_INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (float64x2_t a, float64x2_t b) \ + { \ + INTYPE x = vreinterpretq_##SUFF##_f64 (a); \ + INTYPE y = vreinterpretq_##SUFF##_f64 (b); \ + return FN##_##SUFF (vget_high_##SUFF (x), \ + vget_high_##SUFF (y)); \ + } + +#define TEST_TERN_HIGHPARTS(FN, RETTYPE, INTYPE, H_INTYPE, SUFF) \ + RETTYPE test_##FN##_##SUFF (RETTYPE a, float64x2_t b, float64x2_t c) \ + { \ + INTYPE x = vreinterpretq_##SUFF##_f64 (b); \ + INTYPE y = vreinterpretq_##SUFF##_f64 (c); \ + return FN##_##SUFF (a, vget_high_## SUFF (x), \ + vget_high_## SUFF (y)); \ + } + +#include "fold_to_highpart_1.c" + +/* { dg-final { scan-assembler-times {sxtl2\t} 3} } */ +/* { dg-final { scan-assembler-times {uxtl2\t} 3} } */ + +/* { dg-final { scan-assembler-times {smull2\t} 5} } */ +/* { dg-final { scan-assembler-times {umull2\t} 5} } */ +/* { dg-final { scan-assembler-times {pmull2\t} 1} } */ + +/* { dg-final { scan-assembler-times {saddl2\t} 3} } */ +/* { dg-final { scan-assembler-times {uaddl2\t} 3} } */ + +/* { dg-final { scan-assembler-times {ssubl2\t} 3} } */ +/* { dg-final { scan-assembler-times {usubl2\t} 3} } */ + +/* { dg-final { scan-assembler-times {sabdl2\t} 3} } */ +/* { dg-final { scan-assembler-times {uabdl2\t} 3} } */ + +/* { dg-final { scan-assembler-times {saddw2\t} 3} } */ +/* { dg-final { scan-assembler-times {uaddw2\t} 3} } */ + +/* { dg-final { scan-assembler-times {ssubw2\t} 3} } */ +/* { dg-final { scan-assembler-times {usubw2\t} 3} } */ + +/* { dg-final { scan-assembler-times {sabdl2\t} 3} } */ +/* { dg-final { scan-assembler-times {uabdl2\t} 3} } */ + +/* { dg-final { scan-assembler-times {smlal2\t} 5} } */ +/* { dg-final { scan-assembler-times {umlal2\t} 5} } */ + +/* { dg-final { scan-assembler-times {smlsl2\t} 5} } */ +/* { dg-final { scan-assembler-times {umlsl2\t} 5} } */ + +/* { dg-final { scan-assembler-times {sqdmull2\t} 4} } */ + +/* { dg-final { scan-assembler-times {sqdmlal2\t} 4} } */ + +/* { dg-final { scan-assembler-times {sqdmlsl2\t} 4} } */ diff --git a/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_6.c b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_6.c new file mode 100644 index 000000000000..3570d4da34b5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/fold_to_highpart_6.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target aarch64_little_endian } */ +/* { dg-options "-O2 -march=armv8-a+sve" } */ + +#include + +typedef int16_t int16x16_t __attribute__ ((vector_size (32))); + +/* Edge cases where we don't/can't fold, reject these gracefully. */ + +int8x16_t z; + +int16x8_t +test_addressable () +{ + return vmovl_s8 (vget_high_s8 (z)); +} + +int16x8_t +test_scalable_type (svint8_t scalable) +{ + return vmovl_s8 (vget_high_s8 (svget_neonq_s8 (scalable))); +} + +int16x8_t +test_scalar_type (__int128_t foo) +{ + return vmovl_s8 (vget_high_s8 (vreinterpretq_s8_p128 (foo))); +} + +int32x4_t +test_256b_type (int16x16_t foo) +{ + return vmovl_s16 ((int16x4_t) { foo[4], foo[5], foo[6], foo[7] }); +} + +/* { dg-final { scan-assembler-not {sxtl2\t} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/simd/mf8_data_1.c b/gcc/testsuite/gcc.target/aarch64/simd/mf8_data_1.c index a3fd9b800e1e..79d1ccf6f7d5 100644 --- a/gcc/testsuite/gcc.target/aarch64/simd/mf8_data_1.c +++ b/gcc/testsuite/gcc.target/aarch64/simd/mf8_data_1.c @@ -1016,7 +1016,12 @@ mfloat8x8_t test_set_lane3(mfloat8x8_t a, const mfloat8_t *ptr) /* ** test_set_lane4: +** ( ** ins v0.b\[6\], wzr +** | +** movi? [vdz]([0-9]+)\.?(?:[0-9]*[bhsd])?, #?0 +** ins v0.b\[6\], v(\1).b\[0\] +** ) ** ret */ mfloat8x8_t test_set_lane4(mfloat8x8_t a) @@ -1056,7 +1061,12 @@ mfloat8x16_t test_setq_lane3(mfloat8x16_t a, const mfloat8_t *ptr) /* ** test_setq_lane4: +** ( ** ins v0.b\[14\], wzr +** | +** movi? [vdz]([0-9]+)\.?(?:[0-9]*[bhsd])?, #?0 +** ins v0.b\[14\], v(\1).b\[0\] +** ) ** ret */ mfloat8x16_t test_setq_lane4(mfloat8x16_t a) diff --git a/gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c b/gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c new file mode 100644 index 000000000000..f90ea134f093 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c @@ -0,0 +1,36 @@ +/* This test case checks that replacing a not+shift by a sub -1 works. */ +/* { dg-do compile } */ +/* { dg-additional-options "-O1" } */ +/* { dg-final { scan-assembler-times "\\tsubhn\\t" 6 } } */ + +#include + +uint8x8_t neg_narrow_v8hi(uint16x8_t a) { + uint16x8_t b = vmvnq_u16(a); + return vshrn_n_u16(b, 8); +} + +uint8x8_t neg_narrow_vsubhn_v8hi(uint16x8_t a) { + uint16x8_t ones = vdupq_n_u16(0xffff); + return vsubhn_u16(ones, a); +} + +uint16x4_t neg_narrow_v4si(uint32x4_t a) { + uint32x4_t b = vmvnq_u32(a); + return vshrn_n_u32(b, 16); +} + +uint16x4_t neg_narrow_vsubhn_v4si(uint32x4_t a) { + uint32x4_t ones = vdupq_n_u32(0xffffffff); + return vsubhn_u32(ones, a); +} + +uint32x2_t neg_narrow_v2di(uint64x2_t a) { + uint64x2_t b = ~a; + return vshrn_n_u64(b, 32); +} + +uint32x2_t neg_narrow_vsubhn_v2di(uint64x2_t a) { + uint64x2_t ones = vdupq_n_u64(0xffffffffffffffff); + return vsubhn_u64(ones, a); +} diff --git a/gcc/testsuite/gcc.target/aarch64/simd/vabal_combine.c b/gcc/testsuite/gcc.target/aarch64/simd/vabal_combine.c deleted file mode 100644 index c51878aa2265..000000000000 --- a/gcc/testsuite/gcc.target/aarch64/simd/vabal_combine.c +++ /dev/null @@ -1,72 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O" } */ -/* { dg-final { check-function-bodies "**" "" "" } } */ - -#include - -/* -** test_vabal_s8: -** sabal2 v0.8h, v2.16b, v1.16b -** ret -*/ -int16x8_t -test_vabal_s8 (int16x8_t sadv, int8x16_t pv, int8x16_t sv) -{ - return vabal_s8 (sadv, vget_high_s8 (pv), vget_high_s8 (sv)); -} - -/* -** test_vabal_u8: -** uabal2 v0.8h, v2.16b, v1.16b -** ret -*/ -uint16x8_t -test_vabal_u8 (uint16x8_t sadv, uint8x16_t pv, uint8x16_t sv) -{ - return vabal_u8 (sadv, vget_high_u8 (pv), vget_high_u8 (sv)); -} - -/* -** test_vabal_s16: -** sabal2 v0.4s, v2.8h, v1.8h -** ret -*/ -int32x4_t -test_vabal_s16 (int32x4_t sadv, int16x8_t pv, int16x8_t sv) -{ - return vabal_s16 (sadv, vget_high_s16 (pv), vget_high_s16 (sv)); -} - -/* -** test_vabal_u16: -** uabal2 v0.4s, v2.8h, v1.8h -** ret -*/ -uint32x4_t -test_vabal_u16 (uint32x4_t sadv, uint16x8_t pv, uint16x8_t sv) -{ - return vabal_u16 (sadv, vget_high_u16 (pv), vget_high_u16 (sv)); -} - -/* -** test_vabal_s32: -** sabal2 v0.2d, v2.4s, v1.4s -** ret -*/ -int64x2_t -test_vabal_s32 (int64x2_t sadv, int32x4_t pv, int32x4_t sv) -{ - return vabal_s32 (sadv, vget_high_s32 (pv), vget_high_s32 (sv)); -} - -/* -** test_vabal_u32: -** uabal2 v0.2d, v2.4s, v1.4s -** ret -*/ -uint64x2_t -test_vabal_u32 (uint64x2_t sadv, uint32x4_t pv, uint32x4_t sv) -{ - return vabal_u32 (sadv, vget_high_u32 (pv), vget_high_u32 (sv)); -} - diff --git a/gcc/testsuite/gcc.target/aarch64/sme/za_state_7.c b/gcc/testsuite/gcc.target/aarch64/sme/za_state_7.c new file mode 100644 index 000000000000..38bc13471591 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme/za_state_7.c @@ -0,0 +1,21 @@ +// { dg-options "-O -fno-optimize-sibling-calls -fomit-frame-pointer" } + +#include + +void callee(); + +__arm_new("za") __arm_locally_streaming int test() +{ + svbool_t all = svptrue_b8(); + svint8_t expected = svindex_s8(1, 1); + svwrite_hor_za8_m(0, 0, all, expected); + + callee(); + + svint8_t actual = svread_hor_za8_m(svdup_s8(0), all, 0, 0); + return svptest_any(all, svcmpne(all, expected, actual)); +} + +// { dg-final { scan-assembler {\tbl\t__arm_tpidr2_save\n} } } +// { dg-final { scan-assembler {\tbl\t__arm_tpidr2_restore\n} } } +// { dg-final { scan-assembler-times {\tsmstart\tza\n} 2 } } diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f16_x2.c b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f16_x2.c new file mode 100644 index 000000000000..90b5438e1738 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f16_x2.c @@ -0,0 +1,97 @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sme2_acle.h" +#pragma GCC target "+faminmax" + +/* +** amax_z0_z0_z4: +** famax {z0\.h - z1\.h}, {z0\.h - z1\.h}, {z4\.h - z5\.h} +** ret +*/ +TEST_XN (amax_z0_z0_z4, svfloat16x2_t, z0, + svamax_f16_x2 (z0, z4), + svamax (z0, z4)) + +/* +** amax_z0_z4_z0: +** famax {z0\.h - z1\.h}, {z0\.h - z1\.h}, {z4\.h - z5\.h} +** ret +*/ +TEST_XN (amax_z0_z4_z0, svfloat16x2_t, z0, + svamax_f16_x2 (z4, z0), + svamax (z4, z0)) + +/* +** amax_z0_z4_z28: +** ( +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z28\.h - z29\.h} +** | +** famax [^\n]+, {z28\.h - z29\.h} +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z0_z4_z28, svfloat16x2_t, z0, + svamax_f16_x2 (z4, z28), + svamax (z4, z28)) + +/* +** amax_z18_z18_z4: +** famax {z18\.h - z19\.h}, {z18\.h - z19\.h}, {z4\.h - z5\.h} +** ret +*/ +TEST_XN (amax_z18_z18_z4, svfloat16x2_t, z18, + svamax_f16_x2 (z18, z4), + svamax (z18, z4)) + +/* +** amax_z23_z23_z18: +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z18\.h - z19\.h} +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amax_z23_z23_z18, svfloat16x2_t, z23, + svamax_f16_x2 (z23, z18), + svamax (z23, z18)) + +/* +** amax_z28_z28_z0: +** famax {z28\.h - z29\.h}, {z28\.h - z29\.h}, {z0\.h - z1\.h} +** ret +*/ +TEST_XN (amax_z28_z28_z0, svfloat16x2_t, z28, + svamax_f16_x2 (z28, z0), + svamax (z28, z0)) + +/* +** amax_z0_z0_z18: +** famax {z0\.h - z1\.h}, {z0\.h - z1\.h}, {z18\.h - z19\.h} +** ret +*/ +TEST_XN (amax_z0_z0_z18, svfloat16x2_t, z0, + svamax_f16_x2 (z0, z18), + svamax (z0, z18)) + +/* +** amax_z4_z4_z23: +** ( +** mov [^\n]+ +** mov [^\n]+ +** famax {z4\.h - z5\.h}, {z4\.h - z5\.h}, [^\n]+ +** | +** famax {z4\.h - z5\.h}, {z4\.h - z5\.h}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z4_z4_z23, svfloat16x2_t, z4, + svamax_f16_x2 (z4, z23), + svamax (z4, z23)) + diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f16_x4.c b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f16_x4.c new file mode 100644 index 000000000000..d168ad7ee8e2 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f16_x4.c @@ -0,0 +1,128 @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sme2_acle.h" +#pragma GCC target "+faminmax" + +/* +** amax_z0_z0_z4: +** famax {z0\.h - z3\.h}, {z0\.h - z3\.h}, {z4\.h - z7\.h} +** ret +*/ +TEST_XN (amax_z0_z0_z4, svfloat16x4_t, z0, + svamax_f16_x4 (z0, z4), + svamax (z0, z4)) + +/* +** amax_z0_z4_z0: +** famax {z0\.h - z3\.h}, {z0\.h - z3\.h}, {z4\.h - z7\.h} +** ret +*/ +TEST_XN (amax_z0_z4_z0, svfloat16x4_t, z0, + svamax_f16_x4 (z4, z0), + svamax (z4, z0)) + +/* +** amax_z0_z4_z28: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z28\.h - z31\.h} +** | +** famax [^\n]+, {z28\.h - z31\.h} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z0_z4_z28, svfloat16x4_t, z0, + svamax_f16_x4 (z4, z28), + svamax (z4, z28)) + +/* +** amax_z18_z18_z4: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z4\.h - z7\.h} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amax_z18_z18_z4, svfloat16x4_t, z18, + svamax_f16_x4 (z18, z4), + svamax (z18, z4)) + +/* +** amax_z23_z23_z28: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z28\.h - z31\.h} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amax_z23_z23_z28, svfloat16x4_t, z23, + svamax_f16_x4 (z23, z28), + svamax (z23, z28)) + +/* +** amax_z28_z28_z0: +** famax {z28\.h - z31\.h}, {z28\.h - z31\.h}, {z0\.h - z3\.h} +** ret +*/ +TEST_XN (amax_z28_z28_z0, svfloat16x4_t, z28, + svamax_f16_x4 (z28, z0), + svamax (z28, z0)) + +/* +** amax_z0_z0_z18: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax {z0\.h - z3\.h}, {z0\.h - z3\.h}, [^\n]+ +** | +** famax {z0\.h - z3\.h}, {z0\.h - z3\.h}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z0_z0_z18, svfloat16x4_t, z0, + svamax_f16_x4 (z0, z18), + svamax (z0, z18)) + +/* +** amax_z4_z4_z23: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax {z4\.h - z7\.h}, {z4\.h - z7\.h}, [^\n]+ +** | +** famax {z4\.h - z7\.h}, {z4\.h - z7\.h}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z4_z4_z23, svfloat16x4_t, z4, + svamax_f16_x4 (z4, z23), + svamax (z4, z23)) diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f32_x2.c b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f32_x2.c new file mode 100644 index 000000000000..618d50b9b61d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f32_x2.c @@ -0,0 +1,96 @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sme2_acle.h" +#pragma GCC target "+faminmax" + +/* +** amax_z0_z0_z4: +** famax {z0\.s - z1\.s}, {z0\.s - z1\.s}, {z4\.s - z5\.s} +** ret +*/ +TEST_XN (amax_z0_z0_z4, svfloat32x2_t, z0, + svamax_f32_x2 (z0, z4), + svamax (z0, z4)) + +/* +** amax_z0_z4_z0: +** famax {z0\.s - z1\.s}, {z0\.s - z1\.s}, {z4\.s - z5\.s} +** ret +*/ +TEST_XN (amax_z0_z4_z0, svfloat32x2_t, z0, + svamax_f32_x2 (z4, z0), + svamax (z4, z0)) + +/* +** amax_z0_z4_z28: +** ( +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z28\.s - z29\.s} +** | +** famax [^\n]+, {z28\.s - z29\.s} +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z0_z4_z28, svfloat32x2_t, z0, + svamax_f32_x2 (z4, z28), + svamax (z4, z28)) + +/* +** amax_z18_z18_z4: +** famax {z18\.s - z19\.s}, {z18\.s - z19\.s}, {z4\.s - z5\.s} +** ret +*/ +TEST_XN (amax_z18_z18_z4, svfloat32x2_t, z18, + svamax_f32_x2 (z18, z4), + svamax (z18, z4)) + +/* +** amax_z23_z23_z18: +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z18\.s - z19\.s} +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amax_z23_z23_z18, svfloat32x2_t, z23, + svamax_f32_x2 (z23, z18), + svamax (z23, z18)) + +/* +** amax_z28_z28_z0: +** famax {z28\.s - z29\.s}, {z28\.s - z29\.s}, {z0\.s - z1\.s} +** ret +*/ +TEST_XN (amax_z28_z28_z0, svfloat32x2_t, z28, + svamax_f32_x2 (z28, z0), + svamax (z28, z0)) + +/* +** amax_z0_z0_z18: +** famax {z0\.s - z1\.s}, {z0\.s - z1\.s}, {z18\.s - z19\.s} +** ret +*/ +TEST_XN (amax_z0_z0_z18, svfloat32x2_t, z0, + svamax_f32_x2 (z0, z18), + svamax (z0, z18)) + +/* +** amax_z4_z4_z23: +** ( +** mov [^\n]+ +** mov [^\n]+ +** famax {z4\.s - z5\.s}, {z4\.s - z5\.s}, [^\n]+ +** | +** famax {z4\.s - z5\.s}, {z4\.s - z5\.s}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z4_z4_z23, svfloat32x2_t, z4, + svamax_f32_x2 (z4, z23), + svamax (z4, z23)) diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f32_x4.c b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f32_x4.c new file mode 100644 index 000000000000..981e78c1b5c7 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f32_x4.c @@ -0,0 +1,129 @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sme2_acle.h" +#pragma GCC target "+faminmax" + +/* +** amax_z0_z0_z4: +** famax {z0\.s - z3\.s}, {z0\.s - z3\.s}, {z4\.s - z7\.s} +** ret +*/ +TEST_XN (amax_z0_z0_z4, svfloat32x4_t, z0, + svamax_f32_x4 (z0, z4), + svamax (z0, z4)) + +/* +** amax_z0_z4_z0: +** famax {z0\.s - z3\.s}, {z0\.s - z3\.s}, {z4\.s - z7\.s} +** ret +*/ +TEST_XN (amax_z0_z4_z0, svfloat32x4_t, z0, + svamax_f32_x4 (z4, z0), + svamax (z4, z0)) + +/* +** amax_z0_z4_z28: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z28\.s - z31\.s} +** | +** famax [^\n]+, {z28\.s - z31\.s} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z0_z4_z28, svfloat32x4_t, z0, + svamax_f32_x4 (z4, z28), + svamax (z4, z28)) + +/* +** amax_z18_z18_z4: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z4\.s - z7\.s} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amax_z18_z18_z4, svfloat32x4_t, z18, + svamax_f32_x4 (z18, z4), + svamax (z18, z4)) + +/* +** amax_z23_z23_z28: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z28\.s - z31\.s} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amax_z23_z23_z28, svfloat32x4_t, z23, + svamax_f32_x4 (z23, z28), + svamax (z23, z28)) + +/* +** amax_z28_z28_z0: +** famax {z28\.s - z31\.s}, {z28\.s - z31\.s}, {z0\.s - z3\.s} +** ret +*/ +TEST_XN (amax_z28_z28_z0, svfloat32x4_t, z28, + svamax_f32_x4 (z28, z0), + svamax (z28, z0)) + +/* +** amax_z0_z0_z18: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax {z0\.s - z3\.s}, {z0\.s - z3\.s}, [^\n]+ +** | +** famax {z0\.s - z3\.s}, {z0\.s - z3\.s}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z0_z0_z18, svfloat32x4_t, z0, + svamax_f32_x4 (z0, z18), + svamax (z0, z18)) + +/* +** amax_z4_z4_z23: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax {z4\.s - z7\.s}, {z4\.s - z7\.s}, [^\n]+ +** | +** famax {z4\.s - z7\.s}, {z4\.s - z7\.s}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z4_z4_z23, svfloat32x4_t, z4, + svamax_f32_x4 (z4, z23), + svamax (z4, z23)) + diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f64_x2.c b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f64_x2.c new file mode 100644 index 000000000000..e93a409475e0 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f64_x2.c @@ -0,0 +1,96 @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sme2_acle.h" +#pragma GCC target "+faminmax" + +/* +** amax_z0_z0_z4: +** famax {z0\.d - z1\.d}, {z0\.d - z1\.d}, {z4\.d - z5\.d} +** ret +*/ +TEST_XN (amax_z0_z0_z4, svfloat64x2_t, z0, + svamax_f64_x2 (z0, z4), + svamax (z0, z4)) + +/* +** amax_z0_z4_z0: +** famax {z0\.d - z1\.d}, {z0\.d - z1\.d}, {z4\.d - z5\.d} +** ret +*/ +TEST_XN (amax_z0_z4_z0, svfloat64x2_t, z0, + svamax_f64_x2 (z4, z0), + svamax (z4, z0)) + +/* +** amax_z0_z4_z28: +** ( +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z28\.d - z29\.d} +** | +** famax [^\n]+, {z28\.d - z29\.d} +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z0_z4_z28, svfloat64x2_t, z0, + svamax_f64_x2 (z4, z28), + svamax (z4, z28)) + +/* +** amax_z18_z18_z4: +** famax {z18\.d - z19\.d}, {z18\.d - z19\.d}, {z4\.d - z5\.d} +** ret +*/ +TEST_XN (amax_z18_z18_z4, svfloat64x2_t, z18, + svamax_f64_x2 (z18, z4), + svamax (z18, z4)) + +/* +** amax_z23_z23_z18: +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z18\.d - z19\.d} +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amax_z23_z23_z18, svfloat64x2_t, z23, + svamax_f64_x2 (z23, z18), + svamax (z23, z18)) + +/* +** amax_z28_z28_z0: +** famax {z28\.d - z29\.d}, {z28\.d - z29\.d}, {z0\.d - z1\.d} +** ret +*/ +TEST_XN (amax_z28_z28_z0, svfloat64x2_t, z28, + svamax_f64_x2 (z28, z0), + svamax (z28, z0)) + +/* +** amax_z0_z0_z18: +** famax {z0\.d - z1\.d}, {z0\.d - z1\.d}, {z18\.d - z19\.d} +** ret +*/ +TEST_XN (amax_z0_z0_z18, svfloat64x2_t, z0, + svamax_f64_x2 (z0, z18), + svamax (z0, z18)) + +/* +** amax_z4_z4_z23: +** ( +** mov [^\n]+ +** mov [^\n]+ +** famax {z4\.d - z5\.d}, {z4\.d - z5\.d}, [^\n]+ +** | +** famax {z4\.d - z5\.d}, {z4\.d - z5\.d}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z4_z4_z23, svfloat64x2_t, z4, + svamax_f64_x2 (z4, z23), + svamax (z4, z23)) diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f64_x4.c b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f64_x4.c new file mode 100644 index 000000000000..2db629e147c5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amax_f64_x4.c @@ -0,0 +1,128 @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sme2_acle.h" +#pragma GCC target "+faminmax" + +/* +** amax_z0_z0_z4: +** famax {z0\.d - z3\.d}, {z0\.d - z3\.d}, {z4\.d - z7\.d} +** ret +*/ +TEST_XN (amax_z0_z0_z4, svfloat64x4_t, z0, + svamax_f64_x4 (z0, z4), + svamax (z0, z4)) + +/* +** amax_z0_z4_z0: +** famax {z0\.d - z3\.d}, {z0\.d - z3\.d}, {z4\.d - z7\.d} +** ret +*/ +TEST_XN (amax_z0_z4_z0, svfloat64x4_t, z0, + svamax_f64_x4 (z4, z0), + svamax (z4, z0)) + +/* +** amax_z0_z4_z28: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z28\.d - z31\.d} +** | +** famax [^\n]+, {z28\.d - z31\.d} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z0_z4_z28, svfloat64x4_t, z0, + svamax_f64_x4 (z4, z28), + svamax (z4, z28)) + +/* +** amax_z18_z18_z4: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z4\.d - z7\.d} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amax_z18_z18_z4, svfloat64x4_t, z18, + svamax_f64_x4 (z18, z4), + svamax (z18, z4)) + +/* +** amax_z23_z23_z28: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax [^\n]+, {z28\.d - z31\.d} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amax_z23_z23_z28, svfloat64x4_t, z23, + svamax_f64_x4 (z23, z28), + svamax (z23, z28)) + +/* +** amax_z28_z28_z0: +** famax {z28\.d - z31\.d}, {z28\.d - z31\.d}, {z0\.d - z3\.d} +** ret +*/ +TEST_XN (amax_z28_z28_z0, svfloat64x4_t, z28, + svamax_f64_x4 (z28, z0), + svamax (z28, z0)) + +/* +** amax_z0_z0_z18: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax {z0\.d - z3\.d}, {z0\.d - z3\.d}, [^\n]+ +** | +** famax {z0\.d - z3\.d}, {z0\.d - z3\.d}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z0_z0_z18, svfloat64x4_t, z0, + svamax_f64_x4 (z0, z18), + svamax (z0, z18)) + +/* +** amax_z4_z4_z23: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famax {z4\.d - z7\.d}, {z4\.d - z7\.d}, [^\n]+ +** | +** famax {z4\.d - z7\.d}, {z4\.d - z7\.d}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amax_z4_z4_z23, svfloat64x4_t, z4, + svamax_f64_x4 (z4, z23), + svamax (z4, z23)) diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f16_x2.c b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f16_x2.c new file mode 100644 index 000000000000..74604e14f019 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f16_x2.c @@ -0,0 +1,96 @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sme2_acle.h" +#pragma GCC target "+faminmax" + +/* +** amin_z0_z0_z4: +** famin {z0\.h - z1\.h}, {z0\.h - z1\.h}, {z4\.h - z5\.h} +** ret +*/ +TEST_XN (amin_z0_z0_z4, svfloat16x2_t, z0, + svamin_f16_x2 (z0, z4), + svamin (z0, z4)) + +/* +** amin_z0_z4_z0: +** famin {z0\.h - z1\.h}, {z0\.h - z1\.h}, {z4\.h - z5\.h} +** ret +*/ +TEST_XN (amin_z0_z4_z0, svfloat16x2_t, z0, + svamin_f16_x2 (z4, z0), + svamin (z4, z0)) + +/* +** amin_z0_z4_z28: +** ( +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z28\.h - z29\.h} +** | +** famin [^\n]+, {z28\.h - z29\.h} +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z0_z4_z28, svfloat16x2_t, z0, + svamin_f16_x2 (z4, z28), + svamin (z4, z28)) + +/* +** amin_z18_z18_z4: +** famin {z18\.h - z19\.h}, {z18\.h - z19\.h}, {z4\.h - z5\.h} +** ret +*/ +TEST_XN (amin_z18_z18_z4, svfloat16x2_t, z18, + svamin_f16_x2 (z18, z4), + svamin (z18, z4)) + +/* +** amin_z23_z23_z18: +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z18\.h - z19\.h} +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amin_z23_z23_z18, svfloat16x2_t, z23, + svamin_f16_x2 (z23, z18), + svamin (z23, z18)) + +/* +** amin_z28_z28_z0: +** famin {z28\.h - z29\.h}, {z28\.h - z29\.h}, {z0\.h - z1\.h} +** ret +*/ +TEST_XN (amin_z28_z28_z0, svfloat16x2_t, z28, + svamin_f16_x2 (z28, z0), + svamin (z28, z0)) + +/* +** amin_z0_z0_z18: +** famin {z0\.h - z1\.h}, {z0\.h - z1\.h}, {z18\.h - z19\.h} +** ret +*/ +TEST_XN (amin_z0_z0_z18, svfloat16x2_t, z0, + svamin_f16_x2 (z0, z18), + svamin (z0, z18)) + +/* +** amin_z4_z4_z23: +** ( +** mov [^\n]+ +** mov [^\n]+ +** famin {z4\.h - z5\.h}, {z4\.h - z5\.h}, [^\n]+ +** | +** famin {z4\.h - z5\.h}, {z4\.h - z5\.h}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z4_z4_z23, svfloat16x2_t, z4, + svamin_f16_x2 (z4, z23), + svamin (z4, z23)) diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f16_x4.c b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f16_x4.c new file mode 100644 index 000000000000..bc3779bca6ca --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f16_x4.c @@ -0,0 +1,128 @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sme2_acle.h" +#pragma GCC target "+faminmax" + +/* +** amin_z0_z0_z4: +** famin {z0\.h - z3\.h}, {z0\.h - z3\.h}, {z4\.h - z7\.h} +** ret +*/ +TEST_XN (amin_z0_z0_z4, svfloat16x4_t, z0, + svamin_f16_x4 (z0, z4), + svamin (z0, z4)) + +/* +** amin_z0_z4_z0: +** famin {z0\.h - z3\.h}, {z0\.h - z3\.h}, {z4\.h - z7\.h} +** ret +*/ +TEST_XN (amin_z0_z4_z0, svfloat16x4_t, z0, + svamin_f16_x4 (z4, z0), + svamin (z4, z0)) + +/* +** amin_z0_z4_z28: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z28\.h - z31\.h} +** | +** famin [^\n]+, {z28\.h - z31\.h} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z0_z4_z28, svfloat16x4_t, z0, + svamin_f16_x4 (z4, z28), + svamin (z4, z28)) + +/* +** amin_z18_z18_z4: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z4\.h - z7\.h} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amin_z18_z18_z4, svfloat16x4_t, z18, + svamin_f16_x4 (z18, z4), + svamin (z18, z4)) + +/* +** amin_z23_z23_z28: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z28\.h - z31\.h} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amin_z23_z23_z28, svfloat16x4_t, z23, + svamin_f16_x4 (z23, z28), + svamin (z23, z28)) + +/* +** amin_z28_z28_z0: +** famin {z28\.h - z31\.h}, {z28\.h - z31\.h}, {z0\.h - z3\.h} +** ret +*/ +TEST_XN (amin_z28_z28_z0, svfloat16x4_t, z28, + svamin_f16_x4 (z28, z0), + svamin (z28, z0)) + +/* +** amin_z0_z0_z18: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin {z0\.h - z3\.h}, {z0\.h - z3\.h}, [^\n]+ +** | +** famin {z0\.h - z3\.h}, {z0\.h - z3\.h}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z0_z0_z18, svfloat16x4_t, z0, + svamin_f16_x4 (z0, z18), + svamin (z0, z18)) + +/* +** amin_z4_z4_z23: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin {z4\.h - z7\.h}, {z4\.h - z7\.h}, [^\n]+ +** | +** famin {z4\.h - z7\.h}, {z4\.h - z7\.h}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z4_z4_z23, svfloat16x4_t, z4, + svamin_f16_x4 (z4, z23), + svamin (z4, z23)) diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f32_x2.c b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f32_x2.c new file mode 100644 index 000000000000..43e3075d40fc --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f32_x2.c @@ -0,0 +1,96 @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sme2_acle.h" +#pragma GCC target "+faminmax" + +/* +** amin_z0_z0_z4: +** famin {z0\.s - z1\.s}, {z0\.s - z1\.s}, {z4\.s - z5\.s} +** ret +*/ +TEST_XN (amin_z0_z0_z4, svfloat32x2_t, z0, + svamin_f32_x2 (z0, z4), + svamin (z0, z4)) + +/* +** amin_z0_z4_z0: +** famin {z0\.s - z1\.s}, {z0\.s - z1\.s}, {z4\.s - z5\.s} +** ret +*/ +TEST_XN (amin_z0_z4_z0, svfloat32x2_t, z0, + svamin_f32_x2 (z4, z0), + svamin (z4, z0)) + +/* +** amin_z0_z4_z28: +** ( +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z28\.s - z29\.s} +** | +** famin [^\n]+, {z28\.s - z29\.s} +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z0_z4_z28, svfloat32x2_t, z0, + svamin_f32_x2 (z4, z28), + svamin (z4, z28)) + +/* +** amin_z18_z18_z4: +** famin {z18\.s - z19\.s}, {z18\.s - z19\.s}, {z4\.s - z5\.s} +** ret +*/ +TEST_XN (amin_z18_z18_z4, svfloat32x2_t, z18, + svamin_f32_x2 (z18, z4), + svamin (z18, z4)) + +/* +** amin_z23_z23_z18: +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z18\.s - z19\.s} +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amin_z23_z23_z18, svfloat32x2_t, z23, + svamin_f32_x2 (z23, z18), + svamin (z23, z18)) + +/* +** amin_z28_z28_z0: +** famin {z28\.s - z29\.s}, {z28\.s - z29\.s}, {z0\.s - z1\.s} +** ret +*/ +TEST_XN (amin_z28_z28_z0, svfloat32x2_t, z28, + svamin_f32_x2 (z28, z0), + svamin (z28, z0)) + +/* +** amin_z0_z0_z18: +** famin {z0\.s - z1\.s}, {z0\.s - z1\.s}, {z18\.s - z19\.s} +** ret +*/ +TEST_XN (amin_z0_z0_z18, svfloat32x2_t, z0, + svamin_f32_x2 (z0, z18), + svamin (z0, z18)) + +/* +** amin_z4_z4_z23: +** ( +** mov [^\n]+ +** mov [^\n]+ +** famin {z4\.s - z5\.s}, {z4\.s - z5\.s}, [^\n]+ +** | +** famin {z4\.s - z5\.s}, {z4\.s - z5\.s}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z4_z4_z23, svfloat32x2_t, z4, + svamin_f32_x2 (z4, z23), + svamin (z4, z23)) diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f32_x4.c b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f32_x4.c new file mode 100644 index 000000000000..6bd20f8fdd9b --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f32_x4.c @@ -0,0 +1,128 @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sme2_acle.h" +#pragma GCC target "+faminmax" + +/* +** amin_z0_z0_z4: +** famin {z0\.s - z3\.s}, {z0\.s - z3\.s}, {z4\.s - z7\.s} +** ret +*/ +TEST_XN (amin_z0_z0_z4, svfloat32x4_t, z0, + svamin_f32_x4 (z0, z4), + svamin (z0, z4)) + +/* +** amin_z0_z4_z0: +** famin {z0\.s - z3\.s}, {z0\.s - z3\.s}, {z4\.s - z7\.s} +** ret +*/ +TEST_XN (amin_z0_z4_z0, svfloat32x4_t, z0, + svamin_f32_x4 (z4, z0), + svamin (z4, z0)) + +/* +** amin_z0_z4_z28: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z28\.s - z31\.s} +** | +** famin [^\n]+, {z28\.s - z31\.s} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z0_z4_z28, svfloat32x4_t, z0, + svamin_f32_x4 (z4, z28), + svamin (z4, z28)) + +/* +** amin_z18_z18_z4: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z4\.s - z7\.s} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amin_z18_z18_z4, svfloat32x4_t, z18, + svamin_f32_x4 (z18, z4), + svamin (z18, z4)) + +/* +** amin_z23_z23_z28: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z28\.s - z31\.s} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amin_z23_z23_z28, svfloat32x4_t, z23, + svamin_f32_x4 (z23, z28), + svamin (z23, z28)) + +/* +** amin_z28_z28_z0: +** famin {z28\.s - z31\.s}, {z28\.s - z31\.s}, {z0\.s - z3\.s} +** ret +*/ +TEST_XN (amin_z28_z28_z0, svfloat32x4_t, z28, + svamin_f32_x4 (z28, z0), + svamin (z28, z0)) + +/* +** amin_z0_z0_z18: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin {z0\.s - z3\.s}, {z0\.s - z3\.s}, [^\n]+ +** | +** famin {z0\.s - z3\.s}, {z0\.s - z3\.s}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z0_z0_z18, svfloat32x4_t, z0, + svamin_f32_x4 (z0, z18), + svamin (z0, z18)) + +/* +** amin_z4_z4_z23: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin {z4\.s - z7\.s}, {z4\.s - z7\.s}, [^\n]+ +** | +** famin {z4\.s - z7\.s}, {z4\.s - z7\.s}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z4_z4_z23, svfloat32x4_t, z4, + svamin_f32_x4 (z4, z23), + svamin (z4, z23)) diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f64_x2.c b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f64_x2.c new file mode 100644 index 000000000000..3bbef3f27cda --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f64_x2.c @@ -0,0 +1,96 @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sme2_acle.h" +#pragma GCC target "+faminmax" + +/* +** amin_z0_z0_z4: +** famin {z0\.d - z1\.d}, {z0\.d - z1\.d}, {z4\.d - z5\.d} +** ret +*/ +TEST_XN (amin_z0_z0_z4, svfloat64x2_t, z0, + svamin_f64_x2 (z0, z4), + svamin (z0, z4)) + +/* +** amin_z0_z4_z0: +** famin {z0\.d - z1\.d}, {z0\.d - z1\.d}, {z4\.d - z5\.d} +** ret +*/ +TEST_XN (amin_z0_z4_z0, svfloat64x2_t, z0, + svamin_f64_x2 (z4, z0), + svamin (z4, z0)) + +/* +** amin_z0_z4_z28: +** ( +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z28\.d - z29\.d} +** | +** famin [^\n]+, {z28\.d - z29\.d} +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z0_z4_z28, svfloat64x2_t, z0, + svamin_f64_x2 (z4, z28), + svamin (z4, z28)) + +/* +** amin_z18_z18_z4: +** famin {z18\.d - z19\.d}, {z18\.d - z19\.d}, {z4\.d - z5\.d} +** ret +*/ +TEST_XN (amin_z18_z18_z4, svfloat64x2_t, z18, + svamin_f64_x2 (z18, z4), + svamin (z18, z4)) + +/* +** amin_z23_z23_z18: +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z18\.d - z19\.d} +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amin_z23_z23_z18, svfloat64x2_t, z23, + svamin_f64_x2 (z23, z18), + svamin (z23, z18)) + +/* +** amin_z28_z28_z0: +** famin {z28\.d - z29\.d}, {z28\.d - z29\.d}, {z0\.d - z1\.d} +** ret +*/ +TEST_XN (amin_z28_z28_z0, svfloat64x2_t, z28, + svamin_f64_x2 (z28, z0), + svamin (z28, z0)) + +/* +** amin_z0_z0_z18: +** famin {z0\.d - z1\.d}, {z0\.d - z1\.d}, {z18\.d - z19\.d} +** ret +*/ +TEST_XN (amin_z0_z0_z18, svfloat64x2_t, z0, + svamin_f64_x2 (z0, z18), + svamin (z0, z18)) + +/* +** amin_z4_z4_z23: +** ( +** mov [^\n]+ +** mov [^\n]+ +** famin {z4\.d - z5\.d}, {z4\.d - z5\.d}, [^\n]+ +** | +** famin {z4\.d - z5\.d}, {z4\.d - z5\.d}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z4_z4_z23, svfloat64x2_t, z4, + svamin_f64_x2 (z4, z23), + svamin (z4, z23)) diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f64_x4.c b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f64_x4.c new file mode 100644 index 000000000000..6f4c9b7787a4 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/amin_f64_x4.c @@ -0,0 +1,128 @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sme2_acle.h" +#pragma GCC target "+faminmax" + +/* +** amin_z0_z0_z4: +** famin {z0\.d - z3\.d}, {z0\.d - z3\.d}, {z4\.d - z7\.d} +** ret +*/ +TEST_XN (amin_z0_z0_z4, svfloat64x4_t, z0, + svamin_f64_x4 (z0, z4), + svamin (z0, z4)) + +/* +** amin_z0_z4_z0: +** famin {z0\.d - z3\.d}, {z0\.d - z3\.d}, {z4\.d - z7\.d} +** ret +*/ +TEST_XN (amin_z0_z4_z0, svfloat64x4_t, z0, + svamin_f64_x4 (z4, z0), + svamin (z4, z0)) + +/* +** amin_z0_z4_z28: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z28\.d - z31\.d} +** | +** famin [^\n]+, {z28\.d - z31\.d} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z0_z4_z28, svfloat64x4_t, z0, + svamin_f64_x4 (z4, z28), + svamin (z4, z28)) + +/* +** amin_z18_z18_z4: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z4\.d - z7\.d} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amin_z18_z18_z4, svfloat64x4_t, z18, + svamin_f64_x4 (z18, z4), + svamin (z18, z4)) + +/* +** amin_z23_z23_z28: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin [^\n]+, {z28\.d - z31\.d} +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ret +*/ +TEST_XN (amin_z23_z23_z28, svfloat64x4_t, z23, + svamin_f64_x4 (z23, z28), + svamin (z23, z28)) + +/* +** amin_z28_z28_z0: +** famin {z28\.d - z31\.d}, {z28\.d - z31\.d}, {z0\.d - z3\.d} +** ret +*/ +TEST_XN (amin_z28_z28_z0, svfloat64x4_t, z28, + svamin_f64_x4 (z28, z0), + svamin (z28, z0)) + +/* +** amin_z0_z0_z18: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin {z0\.d - z3\.d}, {z0\.d - z3\.d}, [^\n]+ +** | +** famin {z0\.d - z3\.d}, {z0\.d - z3\.d}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z0_z0_z18, svfloat64x4_t, z0, + svamin_f64_x4 (z0, z18), + svamin (z0, z18)) + +/* +** amin_z4_z4_z23: +** ( +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** famin {z4\.d - z7\.d}, {z4\.d - z7\.d}, [^\n]+ +** | +** famin {z4\.d - z7\.d}, {z4\.d - z7\.d}, [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** ) +** ret +*/ +TEST_XN (amin_z4_z4_z23, svfloat64x4_t, z4, + svamin_f64_x4 (z4, z23), + svamin (z4, z23)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_2.c index 218a66013375..13ebb9fd6fee 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_2.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_2.c @@ -10,6 +10,6 @@ dupq (int x) return svdupq_s32 (x, 1, 2, 3); } -/* { dg-final { scan-assembler {\tindex\tz[0-9]+\.s, #3, #-1} } } */ +/* { dg-final { scan-assembler {\tindex\tz[0-9]+\.s, #0, #1\n} } } */ /* { dg-final { scan-assembler {\tins\tv[0-9]+\.s\[0\], w0\n} } } */ /* { dg-final { scan-assembler {\tdup\tz[0-9]+\.q, z[0-9]+\.q\[0\]\n} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_4.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_4.c index cbee6f27b62f..13d27e2781d1 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_4.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_4.c @@ -10,6 +10,6 @@ dupq (int x) return svdupq_s32 (0, 1, x, 3); } -/* { dg-final { scan-assembler {\tindex\tz[0-9]+\.s, #3, #-1} } } */ +/* { dg-final { scan-assembler {\tindex\tz[0-9]+\.s, #0, #1\n} } } */ /* { dg-final { scan-assembler {\tins\tv[0-9]+\.s\[2\], w0\n} } } */ /* { dg-final { scan-assembler {\tdup\tz[0-9]+\.q, z[0-9]+\.q\[0\]\n} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c new file mode 100644 index 000000000000..875d78885d60 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include + +void +test1 (svbool_t pg, svbool_t x, int *any, svbool_t *ptr) +{ + svbool_t res = svnot_z (pg, x); + *any = svptest_last (pg, res); + *ptr = res; +} + +int +test2 (svbool_t pg, svbool_t x) +{ + svbool_t res = svnot_z (pg, x); + return svptest_first (pg, res); +} + +/* { dg-final { scan-assembler-times {\tnots\t} 2 } } */ +/* { dg-final { scan-assembler-not {\tnot\t} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/perm_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/perm_1.c new file mode 100644 index 000000000000..6b920b8b6812 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/perm_1.c @@ -0,0 +1,14 @@ +/* { dg-options "-O2 -msve-vector-bits=256" } */ + +#include +typedef svbfloat16_t vls_bfloat16_t __attribute__((arm_sve_vector_bits(32 * 8))); +svbfloat16_t foo(vls_bfloat16_t a, vls_bfloat16_t b) +{ + svbfloat16_t zero = svreinterpret_bf16_f32 (svdup_n_f32 (0.0f)); + return svzip2_bf16(zero, svuzp1_bf16(a,b)); +} + + +/* { dg-final { scan-assembler-times {\tuzp1\t} 1 } } */ +/* { dg-final { scan-assembler-times {\tzip2\t} 1 } } */ +/* { dg-final { scan-assembler-not {\ttbl\t} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/adr_7.c b/gcc/testsuite/gcc.target/aarch64/sve/adr_7.c new file mode 100644 index 000000000000..b8a3bdad3db6 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/adr_7.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +#include + +void f(int *p1, int *p2, unsigned long step, unsigned long end, svbool_t pg) { + for (unsigned long i = 0; i < end; i += step) { + svst1(pg, p1, svld1_s32(pg, p2)); + p1 += step; + p2 += step; + } +} + +// Checking that the induction variables are combined into a single variable, +// which is used for all addressing. +// (ie, theres only one scalar add, rather than 3, and the loads and stores use the +// more complex addressing modes) + +/* { dg-final { scan-assembler-not {\tld1w\tz[0-9]+\.s, p[0-9]+/z, \[x[0-9]+\]} } } */ +/* { dg-final { scan-assembler-not {\tst1w\tz[0-9]+\.s, p[0-9]+, \[x[0-9]+\]} } } */ + +/* { dg-final { scan-assembler-times {\tadd\tx[0-9]+, x[0-9]+, x[0-9]+} 1 } } */ +/* { dg-final { scan-assembler-times {\tld1w\tz[0-9]+\.s, p[0-9]+/z, \[x[0-9]+, x[0-9]+, lsl 2\]} 1 } } */ +/* { dg-final { scan-assembler-times {\tst1w\tz[0-9]+\.s, p[0-9]+, \[x[0-9]+, x[0-9]+, lsl 2\]} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cost_model_16.c b/gcc/testsuite/gcc.target/aarch64/sve/cost_model_16.c new file mode 100644 index 000000000000..bfe49ef15f3a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/cost_model_16.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -march=armv8-a+sve --param vect-scalar-cost-multiplier=1000 -fdump-tree-vect-details" } */ + +void +foo (char *restrict a, int *restrict b, int *restrict c, + int *restrict d, int stride) +{ + if (stride <= 1) + return; + + for (int i = 0; i < 3; i++) + { + int res = c[i]; + int t = b[i * stride]; + if (a[i] != 0) + res = t * d[i]; + c[i] = res; + } +} + +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cost_model_17.c b/gcc/testsuite/gcc.target/aarch64/sve/cost_model_17.c new file mode 100644 index 000000000000..c405591a101d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/cost_model_17.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -march=armv8-a+sve -mmax-vectorization -fdump-tree-vect-details" } */ + +void +foo (char *restrict a, int *restrict b, int *restrict c, + int *restrict d, int stride) +{ + if (stride <= 1) + return; + + for (int i = 0; i < 3; i++) + { + int res = c[i]; + int t = b[i * stride]; + if (a[i] != 0) + res = t * d[i]; + c[i] = res; + } +} + +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cost_model_18.c b/gcc/testsuite/gcc.target/aarch64/sve/cost_model_18.c new file mode 100644 index 000000000000..8e91f9e9c299 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/cost_model_18.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -march=armv8-a+sve -fdump-tree-vect-details" } */ + +void __attribute__ (( target ("max-vectorization"))) +foo (char *restrict a, int *restrict b, int *restrict c, + int *restrict d, int stride) +{ + if (stride <= 1) + return; + + for (int i = 0; i < 3; i++) + { + int res = c[i]; + int t = b[i * stride]; + if (a[i] != 0) + res = t * d[i]; + c[i] = res; + } +} + +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/mask_load_2.c b/gcc/testsuite/gcc.target/aarch64/sve/mask_load_2.c new file mode 100644 index 000000000000..66d95101a146 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/mask_load_2.c @@ -0,0 +1,23 @@ +// { dg-do compile } +// { dg-options "-march=armv8-a+sve -msve-vector-bits=128 -O3" } + +typedef struct Array { + int elems[3]; +} Array; + +int loop(Array **pp, int len, int idx) { + int nRet = 0; + + #pragma GCC unroll 0 + for (int i = 0; i < len; i++) { + Array *p = pp[i]; + if (p) { + nRet += p->elems[idx]; + } + } + + return nRet; +} + +// { dg-final { scan-assembler-times {ld1w\tz[0-9]+\.d, p[0-7]/z} 1 } } +// { dg-final { scan-assembler-times {add\tz[0-9]+\.s, p[0-7]/m} 1 } } diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pack_fcvt_signed_1.c b/gcc/testsuite/gcc.target/aarch64/sve/pack_fcvt_signed_1.c index 367fbd967a3e..5c76cbd88da7 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pack_fcvt_signed_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pack_fcvt_signed_1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-vectorize" } */ +/* { dg-options "-O2 -ftree-vectorize --param aarch64-vect-compare-costs=0" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pack_fcvt_unsigned_1.c b/gcc/testsuite/gcc.target/aarch64/sve/pack_fcvt_unsigned_1.c index c5da480c9932..5e3881a895ec 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pack_fcvt_unsigned_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pack_fcvt_unsigned_1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-vectorize" } */ +/* { dg-options "-O2 -ftree-vectorize --param aarch64-vect-compare-costs=0" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pack_float_1.c b/gcc/testsuite/gcc.target/aarch64/sve/pack_float_1.c index 2683a87f4ff4..4810df88e407 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pack_float_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pack_float_1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-vectorize" } */ +/* { dg-options "-O2 -ftree-vectorize --param aarch64-vect-compare-costs=0" } */ void __attribute__ ((noinline, noclone)) pack_float_plus_1point1 (float *d, double *s, int size) diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary.c index a8fd4c8e8f23..4708d57d42bd 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_int_opt_n.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_int_opt_n.c index 08cd6a07c575..4530b18ae905 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_int_opt_n.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_int_opt_n.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_opt_n.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_opt_n.c index f5c9cbf1ae62..3097459af840 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_opt_n.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_opt_n.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_opt_single_n.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_opt_single_n.c index 91ae3c853f8e..5e9d21cce9b2 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_opt_single_n.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_opt_single_n.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_rotate.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_rotate.c index 12368ce39e64..768a7406c981 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_rotate.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_rotate.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_uint64_opt_n.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_uint64_opt_n.c index dd52a5807e85..ce14abba915e 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_uint64_opt_n.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_uint64_opt_n.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_uint_opt_n.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_uint_opt_n.c index e55ddfb674fc..ceeb5ae888be 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_uint_opt_n.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binary_uint_opt_n.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binaryxn.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binaryxn.c index 6796229fb319..f8b6b821814a 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binaryxn.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-binaryxn.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-clast.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-clast.c index 7f2ec4acc26c..45f74ed37fcb 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-clast.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-clast.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-compare_opt_n.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-compare_opt_n.c index d18427bbf26d..fc601a1d4bb2 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-compare_opt_n.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-compare_opt_n.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-compare_wide_opt_n.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-compare_wide_opt_n.c index 983ab5c160d0..4959f1df7a33 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-compare_wide_opt_n.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-compare_wide_opt_n.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-count_pred.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-count_pred.c index de36b66ffc0d..d8a8a81d5889 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-count_pred.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-count_pred.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-unary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-fold_left.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-fold_left.c index 333140d897a7..6cf268391f92 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-fold_left.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-fold_left.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load.c index 93d669373645..a32b636b2780 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_ext.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_ext.c index c88686a2dd8f..72e743b54228 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_ext.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_ext.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_ext_gather_index.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_ext_gather_index.c index 5f4b562fca33..1178104e90c9 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_ext_gather_index.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_ext_gather_index.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_ext_gather_offset.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_ext_gather_offset.c index 0fe8ab3ea612..ebd313a87ecf 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_ext_gather_offset.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_ext_gather_offset.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_gather_sv.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_gather_sv.c index 758f00fe1759..d531987ad5dd 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_gather_sv.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_gather_sv.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_gather_vs.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_gather_vs.c index f82471f3b1e4..55c9cefacb66 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_gather_vs.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_gather_vs.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_replicate.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_replicate.c index ba500b6cab85..5532232f4293 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_replicate.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-load_replicate.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2 -march=armv8.2-a+sve+f64mm" } */ +/* { dg-options "-O2 -march=armv8.2-a+sve+f64mm -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-prefetch.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-prefetch.c index 71894c4b38a6..78bdb0b8ac10 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-prefetch.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-prefetch.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-prefetch_gather_index.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-prefetch_gather_index.c index 1b7cc42b969e..e219007c1d2b 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-prefetch_gather_index.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-prefetch_gather_index.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-prefetch_gather_offset.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-prefetch_gather_offset.c index 7f4ff2df523e..98897e921ba9 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-prefetch_gather_offset.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-prefetch_gather_offset.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-ptest.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-ptest.c index 0a587fca8693..c6fe6b9b01ed 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-ptest.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-ptest.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-unary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-rdffr.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-rdffr.c index d795f8ec3f8c..7e2c1b91e55c 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-rdffr.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-rdffr.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-reduction.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-reduction.c index 42b37aef0b51..f7f75f68ebf0 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-reduction.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-reduction.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fdump-tree-optimized -funwind-tables" } */ #include "../pfalse-unary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-reduction_wide.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-reduction_wide.c index bd9a98076113..54b61975a273 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-reduction_wide.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-reduction_wide.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-unary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-shift_right_imm.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-shift_right_imm.c index 62a07557e82a..e8b8a554a432 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-shift_right_imm.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-shift_right_imm.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-store.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-store.c index 751e60e2ba2f..1539f58c8240 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-store.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-store.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-store_scatter_index.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-store_scatter_index.c index 44792d30b42d..21c8f6b23c91 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-store_scatter_index.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-store_scatter_index.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-store_scatter_offset.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-store_scatter_offset.c index f3820e065f99..a908289466db 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-store_scatter_offset.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-store_scatter_offset.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-storexn.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-storexn.c index e49266dab684..12b5e14aa57c 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-storexn.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-storexn.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-ternary_opt_n.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-ternary_opt_n.c index acdd1417af44..89873fc161e1 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-ternary_opt_n.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-ternary_opt_n.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-ternary_rotate.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-ternary_rotate.c index 7698045d27cb..c6d2cfbbc271 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-ternary_rotate.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-ternary_rotate.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary.c index 037376b3a4a8..8a3b3e0b32ad 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-unary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_convert_narrowt.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_convert_narrowt.c index 1287a70a7edf..04bc049bd468 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_convert_narrowt.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_convert_narrowt.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2 -march=armv8.2-a+sve+bf16" } */ +/* { dg-options "-O2 -march=armv8.2-a+sve+bf16 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_convertxn.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_convertxn.c index f5192666f122..f39d2c5f4d37 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_convertxn.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_convertxn.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2 -march=armv8.2-a+sve+bf16" } */ +/* { dg-options "-O2 -march=armv8.2-a+sve+bf16 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_n.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_n.c index fabde3e52a54..4403e506e4f1 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_n.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_n.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_pred.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_pred.c index 46c9592c47d2..f06b0671a477 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_pred.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_pred.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-unary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_to_uint.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_to_uint.c index b820bde817fc..a851c4afc35e 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_to_uint.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unary_to_uint.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-unary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unaryxn.c b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unaryxn.c index 1e99b7f2f8b4..dde812b1f7d2 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unaryxn.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pfalse-unaryxn.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-unary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr96357.c b/gcc/testsuite/gcc.target/aarch64/sve/pr96357.c index 9a7f912e529f..6dd0409f3c88 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/pr96357.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/pr96357.c @@ -5,10 +5,10 @@ int d; void f1(char f, char *g, char *h, char *l, char *n) { - double i = d, j = 1.0 - f, k = j ? d : j; - if (k == 1.0) - i = 0.0; - *l = *n = *g = *h = i * 0.5; + double j = 1.0 - f, k = j ? d : j; + + char i = (k == 1.0) ? 10 : 50; + *l = *n = *g = *h = i; } void diff --git a/gcc/testsuite/gcc.target/aarch64/sve/unpack_float_1.c b/gcc/testsuite/gcc.target/aarch64/sve/unpack_float_1.c index deb4cf5e940b..d1e74634ece8 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/unpack_float_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/unpack_float_1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-vectorize" } */ +/* { dg-options "-O2 -ftree-vectorize --param aarch64-vect-compare-costs=0" } */ void __attribute__ ((noinline, noclone)) unpack_float_plus_7point9 (double *d, float *s, int size) diff --git a/gcc/testsuite/gcc.target/aarch64/sve/unpacked_cvtf_1.c b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_cvtf_1.c new file mode 100644 index 000000000000..76baffa359b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_cvtf_1.c @@ -0,0 +1,217 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msve-vector-bits=2048 -fno-schedule-insns -fno-schedule-insns2" } */ + +#include + +typedef _Float16 v32hf __attribute__((vector_size(64))); +typedef _Float16 v64hf __attribute__((vector_size(128))); + +typedef float v32sf __attribute__((vector_size(128))); +typedef float v64sf __attribute__((vector_size(256))); + +typedef double v32df __attribute__((vector_size(256))); + +typedef int16_t v32hi __attribute__((vector_size(64))); +typedef int16_t v64hi __attribute__((vector_size(128))); +typedef uint16_t v32uhi __attribute__((vector_size(64))); +typedef uint16_t v64uhi __attribute__((vector_size(128))); + +typedef int32_t v32si __attribute__((vector_size(128))); +typedef int32_t v64si __attribute__((vector_size(256))); +typedef uint32_t v32usi __attribute__((vector_size(128))); +typedef uint32_t v64usi __attribute__((vector_size(256))); + +typedef int64_t v32di __attribute__((vector_size(256))); +typedef uint64_t v32udi __attribute__((vector_size(256))); + +/* +** float_2hf2hi: +** ... +** ld1h (z[0-9]+)\.d, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.d, vl32 +** scvtf (z[0-9]+)\.h, \2/m, \1\.h +** ... +*/ +v32hf +float_2hf2hi (v32hi x) +{ + return __builtin_convertvector (x, v32hf); +} + +/* +** float_2hf2uhi: +** ... +** ld1h (z[0-9]+)\.d, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.d, vl32 +** ucvtf (z[0-9]+)\.h, \2/m, \1\.h +** ... +*/ +v32hf +float_2hf2uhi (v32uhi x) +{ + return __builtin_convertvector (x, v32hf); +} + +/* +** float_2hf2si: +** ... +** ld1w (z[0-9]+)\.d, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.d, vl32 +** scvtf (z[0-9]+)\.h, \2/m, \1\.s +** ... +*/ +v32hf +float_2hf2si (v32si x) +{ + return __builtin_convertvector (x, v32hf); +} + +/* +** float_2hf2usi: +** ... +** ld1w (z[0-9]+)\.d, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.d, vl32 +** ucvtf (z[0-9]+)\.h, \2/m, \1\.s +** ... +*/ +v32hf +float_2hf2usi (v32usi x) +{ + return __builtin_convertvector (x, v32hf); +} + +/* +** float_2hf2di: +** ptrue (p[0-7])\.b, vl256 +** ld1d (z[0-9]+)\.d, \1/z, \[x0\] +** scvtf (z[0-9]+)\.h, \1/m, \2\.d +** ... +*/ +v32hf +float_2hf2di (v32di x) +{ + return __builtin_convertvector (x, v32hf); +} + +/* +** float_2hf2udi: +** ptrue (p[0-7])\.b, vl256 +** ld1d (z[0-9]+)\.d, \1/z, \[x0\] +** ucvtf (z[0-9]+)\.h, \1/m, \2\.d +** ... +*/ +v32hf +float_2hf2udi (v32udi x) +{ + return __builtin_convertvector (x, v32hf); +} + +/* +** float_4hf4hi: +** ... +** ld1h (z[0-9]+)\.s, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.s, vl64 +** scvtf (z[0-9]+)\.h, \2/m, \1\.h +** ... +*/ +v64hf +float_4hf4hi (v64hi x) +{ + return __builtin_convertvector (x, v64hf); +} + +/* +** float_4hf4uhi: +** ... +** ld1h (z[0-9]+)\.s, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.s, vl64 +** ucvtf (z[0-9]+)\.h, \2/m, \1\.h +** ... +*/ +v64hf +float_4hf4uhi (v64uhi x) +{ + return __builtin_convertvector (x, v64hf); +} + +/* +** float_4hf4si: +** ptrue (p[0-7])\.b, vl256 +** ld1w (z[0-9]+)\.s, \1/z, \[x0\] +** scvtf (z[0-9]+)\.h, \1/m, \2\.s +** ... +*/ +v64hf +float_4hf4si (v64si x) +{ + return __builtin_convertvector (x, v64hf); +} + +/* +** float_4hf4usi: +** ptrue (p[0-7])\.b, vl256 +** ld1w (z[0-9]+)\.s, \1/z, \[x0\] +** ucvtf (z[0-9]+)\.h, \1/m, \2\.s +** ... +*/ +v64hf +float_4hf4usi (v64usi x) +{ + return __builtin_convertvector (x, v64hf); +} + +/* +** float_2sf2si: +** ... +** ld1w (z[0-9]+)\.d, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.d, vl32 +** scvtf (z[0-9]+)\.s, \2/m, \1\.s +** ... +*/ +v32sf +float_2sf2si (v32si x) +{ + return __builtin_convertvector (x, v32sf); +} + +/* +** float_2sf2usi: +** ... +** ld1w (z[0-9]+)\.d, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.d, vl32 +** ucvtf (z[0-9]+)\.s, \2/m, \1\.s +** ... +*/ +v32sf +float_2sf2usi (v32usi x) +{ + return __builtin_convertvector (x, v32sf); +} + +/* +** float_2sf2di: +** ptrue (p[0-7])\.b, vl256 +** ld1d (z[0-9]+)\.d, \1/z, \[x0\] +** scvtf (z[0-9]+)\.s, \1/m, \2\.d +** ... +*/ +v32sf +float_2sf2di (v32di x) +{ + return __builtin_convertvector (x, v32sf); +} + +/* +** float_2sf2udi: +** ptrue (p[0-7])\.b, vl256 +** ld1d (z[0-9]+)\.d, \1/z, \[x0\] +** ucvtf (z[0-9]+)\.s, \1/m, \2\.d +** ... +*/ +v32sf +float_2sf2udi (v32udi x) +{ + return __builtin_convertvector (x, v32sf); +} + +/* { dg-final { check-function-bodies "**" "" ""} } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/unpacked_cvtf_2.c b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_cvtf_2.c new file mode 100644 index 000000000000..f578bcfbdef1 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_cvtf_2.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msve-vector-bits=2048 -fno-trapping-math" } */ + +#include "unpacked_cvtf_1.c" + +/* { dg-final { scan-assembler-not {\tptrue\tp[0-7]\.d} } } */ +/* { dg-final { scan-assembler-not {\tptrue\tp[0-7]\.s} } } */ +/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b} 14 } } */ + +/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tucvtf\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.s\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tucvtf\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.s\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.d\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tucvtf\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.d\n} 1 } } */ + +/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tucvtf\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 1 } } */ + +/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.d\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tucvtf\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.d\n} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/unpacked_cvtf_3.c b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_cvtf_3.c new file mode 100644 index 000000000000..6324bdd8db77 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_cvtf_3.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize" } */ + +#include + +void f64_i32 (double *restrict x, int32_t *restrict y, int n) +{ + for (int i = 0; i < n; i++) + x[i] = (double)y[i]; +} + +/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.[sd], p[0-7]/m, z[0-9]+\.d\n} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcm_1.c b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcm_1.c new file mode 100644 index 000000000000..bf9c12738577 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcm_1.c @@ -0,0 +1,602 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -moverride=sve_width=2048 --param=aarch64-autovec-preference=sve-only -fno-schedule-insns -fno-schedule-insns2" } */ + +#include + +#define UNLT(A, B) (!__builtin_isgreaterequal (A, B)) +#define UNLE(A, B) (!__builtin_isgreater (A, B)) +#define UNGT(A, B) (!__builtin_islessequal (A, B)) +#define UNGE(A, B) (!__builtin_isless (A, B)) +#define UNEQ(A, B) (!__builtin_islessgreater (A, B)) + +#define EQ(A, B) ((A) == (B)) +#define NE(A, B) ((A) != (B)) +#define LE(A, B) ((A) <= (B)) +#define LT(A, B) ((A) < (B)) +#define GE(A, B) ((A) >= (B)) +#define GT(A, B) ((A) > (B)) +#define ORDERED(A, B) (!__builtin_isunordered (A, B)) +#define UNORDERED(A, B) (__builtin_isunordered (A, B)) + +#define b_i b[i] + +#define TEST_FCM(TYPE0, TYPE1, CMP, RHS, COUNT) \ + void \ + f_##TYPE0##_##TYPE1##_##CMP##_##RHS (TYPE0 *__restrict out, \ + TYPE1 *__restrict a, \ + TYPE1 *__restrict b) \ + { \ + for (unsigned int i = 0; i < COUNT; i++) \ + out[i] = CMP (a[i], RHS) ? 3 : out[i]; \ + } + +#define TEST_CC_REG(CMP) \ + TEST_FCM (uint64_t, float, CMP, b_i, 32) \ + TEST_FCM (uint32_t, _Float16, CMP, b_i, 64) \ + TEST_FCM (uint64_t, _Float16, CMP, b_i, 32) + +#define TEST_CC_ALL(CMP) \ + TEST_CC_REG (CMP) \ + TEST_FCM (uint64_t, float, CMP, 0, 32) \ + TEST_FCM (uint32_t, _Float16, CMP, 0, 64) \ + TEST_FCM (uint64_t, _Float16, CMP, 0, 32) + + +/* +** f_uint64_t_float_UNLT_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmuo (p[0-9]+)\.s, \1/z, z[0-9]+\.s, z[0-9]+\.s +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmge p[0-9]+\.s, \3/z, z[0-9]+\.s, z[0-9]+\.s +** ... +*/ + +/* +** f_uint32_t__Float16_UNLT_b_i: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmuo (p[0-9]+)\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmge p[0-9]+\.h, \3/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t__Float16_UNLT_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmuo (p[0-9]+)\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmge p[0-9]+\.h, \3/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ +TEST_CC_REG (UNLT) + +/* +** f_uint64_t_float_UNLE_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmuo (p[0-9]+)\.s, \1/z, z[0-9]+\.s, z[0-9]+\.s +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmgt p[0-9]+\.s, \3/z, z[0-9]+\.s, z[0-9]+\.s +** ... +*/ + +/* +** f_uint32_t__Float16_UNLE_b_i: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmuo (p[0-9]+)\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmgt p[0-9]+\.h, \3/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t__Float16_UNLE_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmuo (p[0-9]+)\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmgt p[0-9]+\.h, \3/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ +TEST_CC_REG (UNLE) + +/* +** f_uint64_t_float_UNGT_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmuo (p[0-9]+)\.s, \1/z, z[0-9]+\.s, z[0-9]+\.s +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmle p[0-9]+\.s, \3/z, z[0-9]+\.s, z[0-9]+\.s +** ... +*/ + +/* +** f_uint32_t__Float16_UNGT_b_i: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmuo (p[0-9]+)\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmle p[0-9]+\.h, \3/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t__Float16_UNGT_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmuo (p[0-9]+)\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmle p[0-9]+\.h, \3/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ +TEST_CC_REG (UNGT) + +/* +** f_uint64_t_float_UNGE_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmuo (p[0-9]+)\.s, \1/z, z[0-9]+\.s, z[0-9]+\.s +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmlt p[0-9]+\.s, \3/z, z[0-9]+\.s, z[0-9]+\.s +** ... +*/ + +/* +** f_uint32_t__Float16_UNGE_b_i: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmuo (p[0-9]+)\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmlt p[0-9]+\.h, \3/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t__Float16_UNGE_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmuo (p[0-9]+)\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmlt p[0-9]+\.h, \3/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ +TEST_CC_REG (UNGE) + +/* +** f_uint64_t_float_UNEQ_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmuo (p[0-9]+)\.s, \1/z, z[0-9]+\.s, z[0-9]+\.s +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmne p[0-9]+\.s, \3/z, z[0-9]+\.s, z[0-9]+\.s +** ... +*/ + +/* +** f_uint32_t__Float16_UNEQ_b_i: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmuo (p[0-9]+)\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmne p[0-9]+\.h, \3/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t__Float16_UNEQ_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmuo (p[0-9]+)\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** not (p[0-9]+)\.b, \1/z, \2\.b +** fcmne p[0-9]+\.h, \3/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ +TEST_CC_REG (UNEQ) + +/* +** f_uint64_t_float_EQ_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmeq p[0-9]+\.s, \1/z, z[0-9]+\.s, z[0-9]+\.s +** ... +*/ + +/* +** f_uint32_t__Float16_EQ_b_i: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmeq p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t__Float16_EQ_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmeq p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t_float_EQ_0: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmeq p[0-9]+\.s, \1/z, z[0-9]+\.s, #0.0 +** ... +*/ + +/* +** f_uint32_t__Float16_EQ_0: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmeq p[0-9]+\.h, \1/z, z[0-9]+\.h, #0.0 +** ... +*/ + +/* +** f_uint64_t__Float16_EQ_0: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmeq p[0-9]+\.h, \1/z, z[0-9]+\.h, #0.0 +** ... +*/ +TEST_CC_ALL (EQ) + +/* +** f_uint64_t_float_NE_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmne p[0-9]+\.s, \1/z, z[0-9]+\.s, z[0-9]+\.s +** ... +*/ + +/* +** f_uint32_t__Float16_NE_b_i: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmne p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t__Float16_NE_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmne p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t_float_NE_0: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmne p[0-9]+\.s, \1/z, z[0-9]+\.s, #0.0 +** ... +*/ + +/* +** f_uint32_t__Float16_NE_0: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmne p[0-9]+\.h, \1/z, z[0-9]+\.h, #0.0 +** ... +*/ + +/* +** f_uint64_t__Float16_NE_0: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmne p[0-9]+\.h, \1/z, z[0-9]+\.h, #0.0 +** ... +*/ +TEST_CC_ALL (NE) + +/* +** f_uint64_t_float_LE_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmle p[0-9]+\.s, \1/z, z[0-9]+\.s, z[0-9]+\.s +** ... +*/ + +/* +** f_uint32_t__Float16_LE_b_i: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmle p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t__Float16_LE_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmle p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t_float_LE_0: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmle p[0-9]+\.s, \1/z, z[0-9]+\.s, #0.0 +** ... +*/ + +/* +** f_uint32_t__Float16_LE_0: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmle p[0-9]+\.h, \1/z, z[0-9]+\.h, #0.0 +** ... +*/ + +/* +** f_uint64_t__Float16_LE_0: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmle p[0-9]+\.h, \1/z, z[0-9]+\.h, #0.0 +** ... +*/ +TEST_CC_ALL (LE) + +/* +** f_uint64_t_float_LT_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmlt p[0-9]+\.s, \1/z, z[0-9]+\.s, z[0-9]+\.s +** ... +*/ + +/* +** f_uint32_t__Float16_LT_b_i: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmlt p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t__Float16_LT_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmlt p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t_float_LT_0: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmlt p[0-9]+\.s, \1/z, z[0-9]+\.s, #0.0 +** ... +*/ + +/* +** f_uint32_t__Float16_LT_0: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmlt p[0-9]+\.h, \1/z, z[0-9]+\.h, #0.0 +** ... +*/ + +/* +** f_uint64_t__Float16_LT_0: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmlt p[0-9]+\.h, \1/z, z[0-9]+\.h, #0.0 +** ... +*/ +TEST_CC_ALL (LT) + +/* +** f_uint64_t_float_GE_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmge p[0-9]+\.s, \1/z, z[0-9]+\.s, z[0-9]+\.s +** ... +*/ + +/* +** f_uint32_t__Float16_GE_b_i: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmge p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t__Float16_GE_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmge p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t_float_GE_0: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmge p[0-9]+\.s, \1/z, z[0-9]+\.s, #0.0 +** ... +*/ + +/* +** f_uint32_t__Float16_GE_0: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmge p[0-9]+\.h, \1/z, z[0-9]+\.h, #0.0 +** ... +*/ + +/* +** f_uint64_t__Float16_GE_0: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmge p[0-9]+\.h, \1/z, z[0-9]+\.h, #0.0 +** ... +*/ +TEST_CC_ALL (GE) + +/* +** f_uint64_t_float_GT_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmgt p[0-9]+\.s, \1/z, z[0-9]+\.s, z[0-9]+\.s +** ... +*/ + +/* +** f_uint32_t__Float16_GT_b_i: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmgt p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t__Float16_GT_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmgt p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t_float_GT_0: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmgt p[0-9]+\.s, \1/z, z[0-9]+\.s, #0.0 +** ... +*/ + +/* +** f_uint32_t__Float16_GT_0: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmgt p[0-9]+\.h, \1/z, z[0-9]+\.h, #0.0 +** ... +*/ + +/* +** f_uint64_t__Float16_GT_0: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmgt p[0-9]+\.h, \1/z, z[0-9]+\.h, #0.0 +** ... +*/ +TEST_CC_ALL (GT) + +/* +** f_uint64_t_float_ORDERED_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmuo p[0-9]+\.s, \1/z, z[0-9]+\.s, z[0-9]+\.s +** ... +*/ + +/* +** f_uint32_t__Float16_ORDERED_b_i: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmuo p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t__Float16_ORDERED_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmuo p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ +TEST_CC_REG (ORDERED) + +/* +** f_uint64_t_float_UNORDERED_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmuo p[0-9]+\.s, \1/z, z[0-9]+\.s, z[0-9]+\.s +** ... +*/ + +/* +** f_uint32_t__Float16_UNORDERED_b_i: +** ... +** ptrue (p[0-9]+)\.s, all +** ... +** fcmuo p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ + +/* +** f_uint64_t__Float16_UNORDERED_b_i: +** ... +** ptrue (p[0-9]+)\.d, all +** ... +** fcmuo p[0-9]+\.h, \1/z, z[0-9]+\.h, z[0-9]+\.h +** ... +*/ +TEST_CC_REG (UNORDERED) + + +/* { dg-final { check-function-bodies "**" "" ""} } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcm_2.c b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcm_2.c new file mode 100644 index 000000000000..ab210da157af --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcm_2.c @@ -0,0 +1,50 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -moverride=sve_width=2048 --param=aarch64-autovec-preference=sve-only -fno-trapping-math" } */ + +#include "unpacked_fcm_1.c" + +/* { dg-final { scan-assembler-not {\tptrue\tp[0-7]\.s} } } */ +/* { dg-final { scan-assembler-not {\tptrue\tp[0-7]\.d} } } */ + +/* { dg-final { scan-assembler-times {\tld1w\tz[0-9]+\.d} 32 } } */ +/* { dg-final { scan-assembler-times {\tld1h\tz[0-9]+\.s} 32 } } */ +/* { dg-final { scan-assembler-times {\tld1h\tz[0-9]+\.d} 32 } } */ + +/* { dg-final { scan-assembler-times {\tfcmeq\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tfcmeq\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} 4 } } */ + +/* { dg-final { scan-assembler-times {\tfcmeq\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, #0.0\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcmeq\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, #0.0\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tfcmne\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcmne\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tfcmne\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, #0.0\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcmne\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, #0.0\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tfcmle\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tfcmle\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} 4 } } */ + +/* { dg-final { scan-assembler-times {\tfcmle\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, #0.0\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcmle\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, #0.0\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tfcmlt\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tfcmlt\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} 4 } } */ + +/* { dg-final { scan-assembler-times {\tfcmlt\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, #0.0\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcmlt\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, #0.0\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tfcmge\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tfcmge\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} 4 } } */ + +/* { dg-final { scan-assembler-times {\tfcmge\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, #0.0\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcmge\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, #0.0\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tfcmgt\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tfcmgt\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} 4 } } */ + +/* { dg-final { scan-assembler-times {\tfcmgt\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, #0.0\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcmgt\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, #0.0\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tfcmuo\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, z[0-9]+\.s\n} 3 } } */ +/* { dg-final { scan-assembler-times {\tfcmuo\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} 6 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcm_combines_1.c b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcm_combines_1.c new file mode 100644 index 000000000000..d793a6c95df9 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcm_combines_1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -moverride=sve_width=2048 --param=aarch64-autovec-preference=sve-only -fno-trapping-math" } */ + +#include "unpacked_fcm_1.c" + +/* { dg-final { scan-assembler-times {\tld1w\tz[0-9]+\.d} 32 } } */ +/* { dg-final { scan-assembler-times {\tld1h\tz[0-9]+\.s} 32 } } */ +/* { dg-final { scan-assembler-times {\tld1h\tz[0-9]+\.d} 32 } } */ + +/* Drop a PTRUE predicated AND with the loop mask and comparison result in + favour of predicating the comparison with the loop mask. */ +/* { dg-final { scan-assembler-not {\tand\t} } } */ + +/* Similarly, for codes that are implemented via an inversion, prefer + NOT (predicated with the loop mask) over BIC+PTRUE. */ +/* { dg-final { scan-assembler-not {\tbic\t} } } */ +/* { dg-final { scan-assembler-times {\tnot\t} 15 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcm_combines_2.c b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcm_combines_2.c new file mode 100644 index 000000000000..b85391b9aae8 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcm_combines_2.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -moverride=sve_width=2048 --param=aarch64-autovec-preference=sve-only -fno-trapping-math" } */ + +#include + +/* Ensure that we still emit NOR here, rather than two NOTs. */ + +#define TEST_FCM_NOR(TYPE0, TYPE1, CMP, COUNT) \ + void \ + f_##TYPE0##_##TYPE1##_##CMP (TYPE0 *__restrict out, \ + TYPE1 *__restrict a, \ + TYPE1 *__restrict b, \ + TYPE1 *__restrict c) \ + { \ + for (unsigned int i = 0; i < COUNT; i++) \ + out[i] = !(CMP (a[i], c[i]) | CMP (b[i], c[i])) ? 3 : out[i]; \ + } + +#define GT(A, B) ((A) > (B)) + +TEST_FCM_NOR (uint64_t, float, GT, 32) +TEST_FCM_NOR (uint64_t, _Float16, GT, 32) +TEST_FCM_NOR (uint32_t, _Float16, GT, 64) + +TEST_FCM_NOR (uint64_t, float, __builtin_isunordered, 32) +TEST_FCM_NOR (uint64_t, _Float16, __builtin_isunordered, 32) +TEST_FCM_NOR (uint32_t, _Float16, __builtin_isunordered, 64) + +/* { dg-final { scan-assembler-times {\tld1w\tz[0-9]+\.d} 6 } } */ +/* { dg-final { scan-assembler-times {\tld1h\tz[0-9]+\.s} 6 } } */ +/* { dg-final { scan-assembler-times {\tld1h\tz[0-9]+\.d} 6 } } */ + +/* { dg-final { scan-assembler-not {\tbic\t} } } */ +/* { dg-final { scan-assembler-not {\tnot\t} } } */ +/* { dg-final { scan-assembler-times {\tnor\tp[0-9]+\.b, p[0-9]+/z, p[0-9]+\.b, p[0-9]+\.b\n} 6 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcvt_1.c b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcvt_1.c new file mode 100644 index 000000000000..0babf1523849 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcvt_1.c @@ -0,0 +1,118 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msve-vector-bits=2048 -fno-schedule-insns -fno-schedule-insns2" } */ + +typedef _Float16 v32hf __attribute__((vector_size(64))); +typedef _Float16 v64hf __attribute__((vector_size(128))); + +typedef float v32sf __attribute__((vector_size(128))); +typedef float v64sf __attribute__((vector_size(256))); + +typedef double v32df __attribute__((vector_size(256))); + +/* +** trunc_2sf2df: +** ptrue (p[0-7])\.b, vl256 +** ld1d (z[0-9]+)\.d, \1/z, \[x0\] +** fcvt (z[0-9]+)\.s, \1/m, \2\.d +** ... +*/ +v32sf +trunc_2sf2df (v32df x) +{ + return __builtin_convertvector (x, v32sf); +} + +/* +** trunc_2hf2df: +** ptrue (p[0-7])\.b, vl256 +** ld1d (z[0-9]+)\.d, \1/z, \[x0\] +** fcvt (z[0-9]+)\.h, \1/m, \2\.d +** ... +*/ +v32hf +trunc_2hf2df (v32df x) +{ + return __builtin_convertvector (x, v32hf); +} + +/* +** trunc_4hf4sf: +** ptrue (p[0-7])\.b, vl256 +** ld1w (z[0-9]+)\.s, \1/z, \[x0\] +** fcvt (z[0-9]+)\.h, \1/m, \2\.s +** ... +*/ +v64hf +trunc_4hf4sf (v64sf x) +{ + return __builtin_convertvector (x, v64hf); +} + +/* +** trunc_2hf2sf: +** ... +** ld1w (z[0-9]+)\.d, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.d, vl32 +** fcvt (z[0-9]+)\.h, \2/m, \1\.s +** ... +*/ +v32hf +trunc_2hf2sf (v32sf x) +{ + return __builtin_convertvector (x, v32hf); +} + +/* +** extend_2df2hf: +** ptrue (p[0-7])\.b, vl256 +** ld1h (z[0-9]+)\.d, \1/z, \[x0\] +** fcvt (z[0-9]+)\.d, \1/m, \2\.h +** ... +*/ +v32df +extend_2df2hf (v32hf x) +{ + return __builtin_convertvector (x, v32df); +} + +/* +** extend_2df2sf: +** ptrue (p[0-7])\.b, vl256 +** ld1w (z[0-9]+)\.d, \1/z, \[x0\] +** fcvt (z[0-9]+)\.d, \1/m, \2\.s +** ... +*/ +v32df +extend_2df2sf (v32sf x) +{ + return __builtin_convertvector (x, v32df); +} + +/* +** extend_4sf4hf: +** ptrue (p[0-7])\.b, vl256 +** ld1h (z[0-9]+)\.s, \1/z, \[x0\] +** fcvt (z[0-9]+)\.s, \1/m, \2\.h +** ... +*/ +v64sf +extend_4sf4hf (v64hf x) +{ + return __builtin_convertvector (x, v64sf); +} + +/* +** extend_2sf2hf: +** ... +** ld1h (z[0-9]+)\.d, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.d, vl32 +** fcvt (z[0-9]+)\.s, \2/m, \1\.h +** ... +*/ +v32sf +extend_2sf2hf (v32hf x) +{ + return __builtin_convertvector (x, v32sf); +} + +/* { dg-final { check-function-bodies "**" "" ""} } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcvt_2.c b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcvt_2.c new file mode 100644 index 000000000000..8c369eec6aed --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcvt_2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msve-vector-bits=2048 -fno-trapping-math" } */ + +#include "unpacked_fcvt_1.c" + +/* { dg-final { scan-assembler-not {\tptrue\tp[0-7]\.d} } } */ +/* { dg-final { scan-assembler-not {\tptrue\tp[0-7]\.s} } } */ +/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b} 8 } } */ + +/* { dg-final { scan-assembler-times {\tfcvt\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.d\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcvt\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.d\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcvt\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.s\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tfcvt\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.h\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcvt\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.s\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcvt\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.h\n} 2 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcvtz_1.c b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcvtz_1.c new file mode 100644 index 000000000000..773a3dc961da --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcvtz_1.c @@ -0,0 +1,244 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msve-vector-bits=2048 -fno-schedule-insns -fno-schedule-insns2" } */ + +#include + +typedef _Float16 v32hf __attribute__((vector_size(64))); +typedef _Float16 v64hf __attribute__((vector_size(128))); + +typedef float v32sf __attribute__((vector_size(128))); +typedef float v64sf __attribute__((vector_size(256))); + +typedef double v32df __attribute__((vector_size(256))); + +typedef int16_t v32hi __attribute__((vector_size(64))); +typedef int16_t v64hi __attribute__((vector_size(128))); +typedef uint16_t v32uhi __attribute__((vector_size(64))); +typedef uint16_t v64uhi __attribute__((vector_size(128))); + +typedef int32_t v32si __attribute__((vector_size(128))); +typedef int32_t v64si __attribute__((vector_size(256))); +typedef uint32_t v32usi __attribute__((vector_size(128))); +typedef uint32_t v64usi __attribute__((vector_size(256))); + +typedef int64_t v32di __attribute__((vector_size(256))); +typedef uint64_t v32udi __attribute__((vector_size(256))); + + +/* +** fix_trunc_2hi2hf: +** ... +** ld1h (z[0-9]+)\.d, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.d, vl32 +** fcvtzs (z[0-9]+)\.h, \2/m, \1\.h +** ... +*/ +v32hi +fix_trunc_2hi2hf (v32hf x) +{ + return __builtin_convertvector (x, v32hi); +} + +/* +** fix_trunc_2uhi2hf: +** ... +** ld1h (z[0-9]+)\.d, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.d, vl32 +** fcvtzu (z[0-9]+)\.h, \2/m, \1\.h +** ... +*/ +v32uhi +fix_trunc_2uhi2hf (v32hf x) +{ + return __builtin_convertvector (x, v32uhi); +} + +/* +** fix_trunc_2si2hf: +** ... +** ld1h (z[0-9]+)\.d, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.d, vl32 +** fcvtzs (z[0-9]+)\.s, \2/m, \1\.h +** ... +*/ +v32si +fix_trunc_2si2hf (v32hf x) +{ + return __builtin_convertvector (x, v32si); +} + +/* +** fix_trunc_2usi2hf: +** ... +** ld1h (z[0-9]+)\.d, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.d, vl32 +** fcvtzu (z[0-9]+)\.s, \2/m, \1\.h +** ... +*/ +v32usi +fix_trunc_2usi2hf (v32hf x) +{ + return __builtin_convertvector (x, v32usi); +} + +/* +** fix_trunc_2di2hf: +** ptrue (p[0-7])\.b, vl256 +** ld1h (z[0-9]+)\.d, \1/z, \[x0\] +** fcvtzs (z[0-9]+)\.d, \1/m, \2\.h +** ... +*/ +v32di +fix_trunc_2di2hf (v32hf x) +{ + return __builtin_convertvector (x, v32di); +} + +/* +** fix_trunc_2udi2hf: +** ptrue (p[0-7])\.b, vl256 +** ld1h (z[0-9]+)\.d, \1/z, \[x0\] +** fcvtzu (z[0-9]+)\.d, \1/m, \2\.h +** ... +*/ +v32udi +fix_trunc_2udi2hf (v32hf x) +{ + return __builtin_convertvector (x, v32udi); +} + +/* +** fix_trunc_4hi4hf: +** ... +** ld1h (z[0-9]+)\.s, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.s, vl64 +** fcvtzs (z[0-9]+)\.h, \2/m, \1\.h +** ... +*/ +v64hi +fix_trunc_4hi4hf (v64hf x) +{ + return __builtin_convertvector (x, v64hi); +} + +/* +** fix_trunc_4uhi4hf: +** ... +** ld1h (z[0-9]+)\.s, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.s, vl64 +** fcvtzu (z[0-9]+)\.h, \2/m, \1\.h +** ... +*/ +v64uhi +fix_trunc_4uhi4hf (v64hf x) +{ + return __builtin_convertvector (x, v64uhi); +} + +/* +** fix_trunc_4si4hf: +** ptrue (p[0-7])\.b, vl256 +** ld1h (z[0-9]+)\.s, \1/z, \[x0\] +** fcvtzs (z[0-9]+)\.s, \1/m, \2\.h +** ... +*/ +v64si +fix_trunc_4si4hf (v64hf x) +{ + return __builtin_convertvector (x, v64si); +} + +/* +** fix_trunc_4usi4hf: +** ptrue (p[0-7])\.b, vl256 +** ld1h (z[0-9]+)\.s, \1/z, \[x0\] +** fcvtzu (z[0-9]+)\.s, \1/m, \2\.h +** ... +*/ +v64usi +fix_trunc_4usi4hf (v64hf x) +{ + return __builtin_convertvector (x, v64usi); +} + +/* +** fix_trunc_2si2sf: +** ... +** ld1w (z[0-9]+)\.d, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.d, vl32 +** fcvtzs (z[0-9]+)\.s, \2/m, \1\.s +** ... +*/ +v32si +fix_trunc_2si2sf (v32sf x) +{ + return __builtin_convertvector (x, v32si); +} + +/* +** fix_trunc_2usi2sf: +** ... +** ld1w (z[0-9]+)\.d, p[0-7]/z, \[x0\] +** ptrue (p[0-7])\.d, vl32 +** fcvtzu (z[0-9]+)\.s, \2/m, \1\.s +** ... +*/ +v32usi +fix_trunc_2usi2sf (v32sf x) +{ + return __builtin_convertvector (x, v32usi); +} + +/* +** fix_trunc_2di2sf: +** ptrue (p[0-7])\.b, vl256 +** ld1w (z[0-9]+)\.d, \1/z, \[x0\] +** fcvtzs (z[0-9]+)\.d, \1/m, \2\.s +** ... +*/ +v32di +fix_trunc_2di2sf (v32sf x) +{ + return __builtin_convertvector (x, v32di); +} + +/* +** fix_trunc_2udi2sf: +** ptrue (p[0-7])\.b, vl256 +** ld1w (z[0-9]+)\.d, \1/z, \[x0\] +** fcvtzu (z[0-9]+)\.d, \1/m, \2\.s +** ... +*/ +v32udi +fix_trunc_2udi2sf (v32sf x) +{ + return __builtin_convertvector (x, v32udi); +} + +/* +** fix_trunc_2si2df: +** ptrue (p[0-7])\.b, vl256 +** ld1d (z[0-9]+)\.d, \1/z, \[x0\] +** fcvtzs (z[0-9]+)\.s, \1/m, \2\.d +** ... +*/ +v32si +fix_trunc_2si2df (v32df x) +{ + return __builtin_convertvector (x, v32si); +} + +/* +** fix_trunc_2usi2df: +** ptrue (p[0-7])\.b, vl256 +** ld1d (z[0-9]+)\.d, \1/z, \[x0\] +** fcvtzu (z[0-9]+)\.s, \1/m, \2\.d +** ... +*/ +v32usi +fix_trunc_2usi2df (v32df x) +{ + return __builtin_convertvector (x, v32usi); +} + +/* { dg-final { check-function-bodies "**" "" ""} } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcvtz_2.c b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcvtz_2.c new file mode 100644 index 000000000000..0587753d15e2 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/unpacked_fcvtz_2.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msve-vector-bits=2048 -fno-trapping-math" } */ + +#include "unpacked_fcvtz_1.c" + +/* { dg-final { scan-assembler-not {\tptrue\tp[0-7]\.d} } } */ +/* { dg-final { scan-assembler-not {\tptrue\tp[0-7]\.s} } } */ +/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b} 16 } } */ + +/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.h\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.h\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.h\n} 1 } } */ + +/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 1 } } */ + +/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.s\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.s\n} 1 } } */ + +/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.d\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.d\n} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vec_init_3.c b/gcc/testsuite/gcc.target/aarch64/sve/vec_init_3.c index 25910dbfa1fb..5100a87c0d93 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/vec_init_3.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/vec_init_3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -mlittle-endian" } */ /* { dg-final { check-function-bodies "**" "" "" } } */ typedef char v16qi __attribute__ ((vector_size (16))); @@ -8,7 +8,7 @@ typedef short v8hi __attribute__ ((vector_size (16))); typedef short v4hi __attribute__ ((vector_size (8))); typedef int v4si __attribute__ ((vector_size (16))); typedef int v2si __attribute__ ((vector_size (8))); -typedef long v2di __attribute__ ((vector_size (16))); +typedef long long v2di __attribute__ ((vector_size (16))); /* ** f_v16qi: @@ -97,3 +97,113 @@ g_v4si (void) { return (v4si){ 3, -1, -5, -9 }; } + +/* +** g_min_1: +** index z0\.s, #-16, #1 +** ret +*/ +v4si +g_min_1 (void) +{ + return (v4si){ -16, -15, -14, -13 }; +} + +/* +** g_min_min: +** index z0\.s, #-16, #-16 +** ret +*/ +v4si +g_min_min (void) +{ + return (v4si){ -16, -32, -48, -64 }; +} + +/* +** g_min_max: +** index z0\.s, #-16, #15 +** ret +*/ +v4si +g_min_max (void) +{ + return (v4si){ -16, -1, 14, 29 }; +} + +/* +** g_max_1: +** index z0\.s, #15, #1 +** ret +*/ +v4si +g_max_1 (void) +{ + return (v4si){ 15, 16, 17, 18 }; +} + +/* +** g_max_min: +** index z0\.s, #15, #-16 +** ret +*/ +v4si +g_max_min (void) +{ + return (v4si){ 15, -1, -17, -33 }; +} + +/* +** g_max_max: +** index z0\.s, #15, #15 +** ret +*/ +v4si +g_max_max (void) +{ + return (v4si){ 15, 30, 45, 60 }; +} + +/* +** g_ob_1: +** ((?!index).)* +** ret +*/ +v4si +g_ob_1 (void) +{ + return (v4si){ -17, -16, -15, -14 }; +} + +/* +** g_ob_2: +** ((?!index).)* +** ret +*/ +v4si +g_ob_2 (void) +{ + return (v4si){ 16, 17, 18, 19 }; +} + +/* +** g_ob_3: +** ((?!index).)* +** ret +*/ +v4si +g_ob_3 (void) +{ + return (v4si){ 0, -17, -34, -51 }; +} + +/* +** g_ob_4: +** ((?!index).)* +** ret +*/ +v4si +g_ob_4 (void) +{ + return (v4si){ 0, 16, 32, 48 }; +} diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vec_init_4.c b/gcc/testsuite/gcc.target/aarch64/sve/vec_init_4.c new file mode 100644 index 000000000000..0681d9591010 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/vec_init_4.c @@ -0,0 +1,209 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mbig-endian" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +typedef char v16qi __attribute__ ((vector_size (16))); +typedef char v8qi __attribute__ ((vector_size (8))); +typedef short v8hi __attribute__ ((vector_size (16))); +typedef short v4hi __attribute__ ((vector_size (8))); +typedef int v4si __attribute__ ((vector_size (16))); +typedef int v2si __attribute__ ((vector_size (8))); +typedef long long v2di __attribute__ ((vector_size (16))); + +/* +** f_v16qi: +** index z0\.b, #15, #-1 +** ret +*/ +v16qi +f_v16qi (void) +{ + return (v16qi){ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; +} + +/* +** f_v8qi: +** index z0\.b, #7, #-1 +** ret +*/ +v8qi +f_v8qi (void) +{ + return (v8qi){ 0, 1, 2, 3, 4, 5, 6, 7 }; +} + +/* +** f_v8hi: +** index z0\.h, #7, #-1 +** ret +*/ +v8hi +f_v8hi (void) +{ + return (v8hi){ 0, 1, 2, 3, 4, 5, 6, 7 }; +} + +/* +** f_v4hi: +** index z0\.h, #3, #-1 +** ret +*/ +v4hi +f_v4hi (void) +{ + return (v4hi){ 0, 1, 2, 3 }; +} + +/* +** f_v4si: +** index z0\.s, #3, #-1 +** ret +*/ +v4si +f_v4si (void) +{ + return (v4si){ 0, 1, 2, 3 }; +} + +/* +** f_v2si: +** index z0\.s, #1, #-1 +** ret +*/ +v2si +f_v2si (void) +{ + return (v2si){ 0, 1 }; +} + +/* +** f_v2di: +** index z0\.d, #1, #-1 +** ret +*/ +v2di +f_v2di (void) +{ + return (v2di){ 0, 1 }; +} + +/* +** g_v4si: +** index z0\.s, #-9, #4 +** ret +*/ +v4si +g_v4si (void) +{ + return (v4si){ 3, -1, -5, -9 }; +} + +/* +** g_min_1: +** index z0\.s, #-16, #1 +** ret +*/ +v4si +g_min_1 (void) +{ + return (v4si){ -13, -14, -15, -16 }; +} + +/* +** g_min_min: +** index z0\.s, #-16, #-16 +** ret +*/ +v4si +g_min_min (void) +{ + return (v4si){ -64, -48, -32, -16 }; +} + +/* +** g_min_max: +** index z0\.s, #-16, #15 +** ret +*/ +v4si +g_min_max (void) +{ + return (v4si){ 29, 14, -1, -16 }; +} + +/* +** g_max_1: +** index z0\.s, #15, #1 +** ret +*/ +v4si +g_max_1 (void) +{ + return (v4si){ 18, 17, 16, 15 }; +} + +/* +** g_max_min: +** index z0\.s, #15, #-16 +** ret +*/ +v4si +g_max_min (void) +{ + return (v4si){ -33, -17, -1, 15 }; +} + +/* +** g_max_max: +** index z0\.s, #15, #15 +** ret +*/ +v4si +g_max_max (void) +{ + return (v4si){ 60, 45, 30, 15 }; +} + +/* +** g_ob_1: +** ((?!index).)* +** ret +*/ +v4si +g_ob_1 (void) +{ + return (v4si){ -14, -15, -16, -17 }; +} + +/* +** g_ob_2: +** ((?!index).)* +** ret +*/ +v4si +g_ob_2 (void) +{ + return (v4si){ 19, 18, 17, 16 }; +} + +/* +** g_ob_3: +** ((?!index).)* +** ret +*/ +v4si +g_ob_3 (void) +{ + return (v4si){ -51, -34, -17, 0 }; +} + +/* +** g_ob_4: +** ((?!index).)* +** ret +*/ +v4si +g_ob_4 (void) +{ + return (v4si){ 48, 32, 16, 0 }; +} diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/dupq_1.c b/gcc/testsuite/gcc.target/aarch64/sve2/dupq_1.c index 5472e30f812a..9db60b1ea4f2 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/dupq_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/dupq_1.c @@ -1,5 +1,5 @@ /* { dg-options "-O2 -msve-vector-bits=256" } */ -/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ #include @@ -15,7 +15,7 @@ typedef svuint64_t fixed_uint64_t __attribute__((arm_sve_vector_bits(256))); ** trn1 z0\.d, z0\.d, z0\.d ** ret */ -fixed_uint64_t +[[gnu::noipa]] fixed_uint64_t f1 (fixed_uint64_t z0) { return __builtin_shufflevector (z0, z0, 0, 0, 2, 2); @@ -26,7 +26,7 @@ f1 (fixed_uint64_t z0) ** trn2 z0\.d, z0\.d, z0\.d ** ret */ -fixed_uint64_t +[[gnu::noipa]] fixed_uint64_t f2 (fixed_uint64_t z0) { return __builtin_shufflevector (z0, z0, 1, 1, 3, 3); @@ -37,7 +37,7 @@ f2 (fixed_uint64_t z0) ** dupq z0\.s, z0\.s\[0\] ** ret */ -fixed_int32_t +[[gnu::noipa]] fixed_int32_t f3 (fixed_int32_t z0) { return __builtin_shufflevector (z0, z0, 0, 0, 0, 0, 4, 4, 4, 4); @@ -48,7 +48,7 @@ f3 (fixed_int32_t z0) ** dupq z0\.s, z0\.s\[1\] ** ret */ -fixed_int32_t +[[gnu::noipa]] fixed_int32_t f4 (fixed_int32_t z0) { return __builtin_shufflevector (z0, z0, 1, 1, 1, 1, 5, 5, 5, 5); @@ -59,7 +59,7 @@ f4 (fixed_int32_t z0) ** dupq z0\.s, z0\.s\[2\] ** ret */ -fixed_int32_t +[[gnu::noipa]] fixed_int32_t f5 (fixed_int32_t z0) { return __builtin_shufflevector (z0, z0, 2, 2, 2, 2, 6, 6, 6, 6); @@ -70,7 +70,7 @@ f5 (fixed_int32_t z0) ** dupq z0\.s, z0\.s\[3\] ** ret */ -fixed_int32_t +[[gnu::noipa]] fixed_int32_t f6 (fixed_int32_t z0) { return __builtin_shufflevector (z0, z0, 3, 3, 3, 3, 7, 7, 7, 7); @@ -81,7 +81,7 @@ f6 (fixed_int32_t z0) ** dupq z0\.h, z0\.h\[0\] ** ret */ -fixed_uint16_t +[[gnu::noipa]] fixed_uint16_t f7 (fixed_uint16_t z0) { return __builtin_shufflevector (z0, z0, @@ -95,7 +95,7 @@ f7 (fixed_uint16_t z0) ** dupq z0\.h, z0\.h\[5\] ** ret */ -fixed_uint16_t +[[gnu::noipa]] fixed_uint16_t f8 (fixed_uint16_t z0) { return __builtin_shufflevector (z0, z0, @@ -108,7 +108,7 @@ f8 (fixed_uint16_t z0) ** dupq z0\.h, z0\.h\[7\] ** ret */ -fixed_uint16_t +[[gnu::noipa]] fixed_uint16_t f9 (fixed_uint16_t z0) { return __builtin_shufflevector (z0, z0, @@ -121,7 +121,7 @@ f9 (fixed_uint16_t z0) ** dupq z0\.b, z0\.b\[0\] ** ret */ -fixed_uint8_t +[[gnu::noipa]] fixed_uint8_t f10 (fixed_uint8_t z0) { return __builtin_shufflevector (z0, z0, @@ -136,7 +136,7 @@ f10 (fixed_uint8_t z0) ** dupq z0\.b, z0\.b\[13\] ** ret */ -fixed_uint8_t +[[gnu::noipa]] fixed_uint8_t f11 (fixed_uint8_t z0) { return __builtin_shufflevector (z0, z0, @@ -151,7 +151,7 @@ f11 (fixed_uint8_t z0) ** dupq z0\.b, z0\.b\[15\] ** ret */ -fixed_uint8_t +[[gnu::noipa]] fixed_uint8_t f12 (fixed_uint8_t z0) { return __builtin_shufflevector (z0, z0, diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/dupq_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve2/dupq_1_run.c new file mode 100644 index 000000000000..fd25034c4b46 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/dupq_1_run.c @@ -0,0 +1,87 @@ +/* { dg-do run { target { aarch64_sve256_hw && aarch64_sve2p1_hw } } } */ +/* { dg-options "-O2 -msve-vector-bits=256" } */ + +#include "dupq_1.c" + +#define TEST(A, B) \ + do { \ + typeof(B) actual_ = (A); \ + if (__builtin_memcmp (&actual_, &(B), sizeof (actual_)) != 0) \ + __builtin_abort (); \ + } while (0) + +int +main () +{ + fixed_uint64_t a64 = { 0x1122, -1, 0x5566, -2 }; + fixed_int32_t a32 = { 0x1122, -0x3344, 0x5566, -0x7788, + 0x99aa, -0xbbcc, 0xddee, -0xff00 }; + fixed_uint16_t a16 = { 0x9a12, 0xbc34, 0xde56, 0xf078, + 0x00ff, 0x11ee, 0x22dd, 0x33cc, + 0x44bb, 0x55aa, 0x6699, 0x7788, + 0xfe01, 0xdc23, 0xba45, 0x9867 }; + fixed_uint8_t a8 = { 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x70, + 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf8, + 0xfe, 0xed, 0xdc, 0xcb, 0xba, 0xa9, 0x98, 0x8f, + 0x76, 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x07 }; + + fixed_uint64_t expected1 = { 0x1122, 0x1122, 0x5566, 0x5566 }; + TEST (f1 (a64), expected1); + + fixed_uint64_t expected2 = { -1, -1, -2, -2 }; + TEST (f2 (a64), expected2); + + fixed_int32_t expected3 = { 0x1122, 0x1122, 0x1122, 0x1122, + 0x99aa, 0x99aa, 0x99aa, 0x99aa }; + TEST (f3 (a32), expected3); + + fixed_int32_t expected4 = { -0x3344, -0x3344, -0x3344, -0x3344, + -0xbbcc, -0xbbcc, -0xbbcc, -0xbbcc }; + TEST (f4 (a32), expected4); + + fixed_int32_t expected5 = { 0x5566, 0x5566, 0x5566, 0x5566, + 0xddee, 0xddee, 0xddee, 0xddee }; + TEST (f5 (a32), expected5); + + fixed_int32_t expected6 = { -0x7788, -0x7788, -0x7788, -0x7788, + -0xff00, -0xff00, -0xff00, -0xff00 }; + TEST (f6 (a32), expected6); + + fixed_uint16_t expected7 = { 0x9a12, 0x9a12, 0x9a12, 0x9a12, + 0x9a12, 0x9a12, 0x9a12, 0x9a12, + 0x44bb, 0x44bb, 0x44bb, 0x44bb, + 0x44bb, 0x44bb, 0x44bb, 0x44bb }; + TEST (f7 (a16), expected7); + + fixed_uint16_t expected8 = { 0x11ee, 0x11ee, 0x11ee, 0x11ee, + 0x11ee, 0x11ee, 0x11ee, 0x11ee, + 0xdc23, 0xdc23, 0xdc23, 0xdc23, + 0xdc23, 0xdc23, 0xdc23, 0xdc23 }; + TEST (f8 (a16), expected8); + + fixed_uint16_t expected9 = { 0x33cc, 0x33cc, 0x33cc, 0x33cc, + 0x33cc, 0x33cc, 0x33cc, 0x33cc, + 0x9867, 0x9867, 0x9867, 0x9867, + 0x9867, 0x9867, 0x9867, 0x9867 }; + TEST (f9 (a16), expected9); + + fixed_uint8_t expected10 = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe }; + TEST (f10 (a8), expected10); + + fixed_uint8_t expected11 = { 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, + 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21 }; + TEST (f11 (a8), expected11); + + fixed_uint8_t expected12 = { 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07 }; + TEST (f12 (a8), expected12); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/eon_bsl2n.c b/gcc/testsuite/gcc.target/aarch64/sve2/eon_bsl2n.c new file mode 100644 index 000000000000..74b463763735 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/eon_bsl2n.c @@ -0,0 +1,52 @@ +/* { dg-options "-O2" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +#include +#include + +#define EON(x, y) (~((x) ^ (y))) + +/* +** eon_d: +** bsl2n z0.d, z0.d, z0.d, z1.d +** ret +*/ +uint32x2_t eon_d(uint32x2_t a, uint32x2_t b) { return EON(a, b); } + +/* +** eon_d_mp: +** movprfx z0, z1 +** bsl2n z0.d, z0.d, z1.d, z2.d +** ret +*/ +uint32x2_t eon_d_mp(uint32x2_t c, uint32x2_t a, uint32x2_t b) { return EON(a, b); } + +/* +** eon_q: +** bsl2n z0.d, z0.d, z0.d, z1.d +** ret +*/ +uint64x2_t eon_q(uint64x2_t a, uint64x2_t b) { return EON(a, b); } + +/* +** eon_q_mp: +** movprfx z0, z1 +** bsl2n z0.d, z0.d, z1.d, z2.d +** ret +*/ +uint64x2_t eon_q_mp(uint64x2_t c, uint64x2_t a, uint64x2_t b) { return EON(a, b); } + +/* +** eon_z: +** bsl2n z0.d, z0.d, z0.d, z1.d +** ret +*/ +svuint64_t eon_z(svuint64_t a, svuint64_t b) { return EON(a, b); } + +/* +** eon_z_mp: +** movprfx z0, z1 +** bsl2n z0.d, z0.d, z1.d, z2.d +** ret +*/ +svuint64_t eon_z_mp(svuint64_t c, svuint64_t a, svuint64_t b) { return EON(a, b); } diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/extq_1.c b/gcc/testsuite/gcc.target/aarch64/sve2/extq_1.c index 03c5fb143f7e..be5ae71de83c 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/extq_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/extq_1.c @@ -1,5 +1,5 @@ /* { dg-options "-O2 -msve-vector-bits=256" } */ -/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ #include @@ -15,7 +15,7 @@ typedef svfloat64_t fixed_float64_t __attribute__((arm_sve_vector_bits(256))); ** extq z0\.b, z0\.b, z1\.b, #8 ** ret */ -fixed_float64_t +[[gnu::noipa]] fixed_float64_t f1 (fixed_float64_t z0, fixed_float64_t z1) { return __builtin_shufflevector (z0, z1, 1, 4, 3, 6); @@ -26,7 +26,7 @@ f1 (fixed_float64_t z0, fixed_float64_t z1) ** extq z0\.b, z0\.b, z1\.b, #4 ** ret */ -fixed_uint32_t +[[gnu::noipa]] fixed_uint32_t f2 (fixed_uint32_t z0, fixed_uint32_t z1) { return __builtin_shufflevector (z0, z1, 1, 2, 3, 8, 5, 6, 7, 12); @@ -37,7 +37,7 @@ f2 (fixed_uint32_t z0, fixed_uint32_t z1) ** extq z0\.b, z0\.b, z1\.b, #12 ** ret */ -fixed_uint32_t +[[gnu::noipa]] fixed_uint32_t f3 (fixed_uint32_t z0, fixed_uint32_t z1) { return __builtin_shufflevector (z0, z1, 3, 8, 9, 10, 7, 12, 13, 14); @@ -48,7 +48,7 @@ f3 (fixed_uint32_t z0, fixed_uint32_t z1) ** extq z0\.b, z0\.b, z1\.b, #2 ** ret */ -fixed_float16_t +[[gnu::noipa]] fixed_float16_t f4 (fixed_float16_t z0, fixed_float16_t z1) { return __builtin_shufflevector (z0, z1, @@ -61,7 +61,7 @@ f4 (fixed_float16_t z0, fixed_float16_t z1) ** extq z0\.b, z0\.b, z1\.b, #10 ** ret */ -fixed_float16_t +[[gnu::noipa]] fixed_float16_t f5 (fixed_float16_t z0, fixed_float16_t z1) { return __builtin_shufflevector (z0, z1, @@ -74,7 +74,7 @@ f5 (fixed_float16_t z0, fixed_float16_t z1) ** extq z0\.b, z0\.b, z1\.b, #14 ** ret */ -fixed_float16_t +[[gnu::noipa]] fixed_float16_t f6 (fixed_float16_t z0, fixed_float16_t z1) { return __builtin_shufflevector (z0, z1, @@ -87,7 +87,7 @@ f6 (fixed_float16_t z0, fixed_float16_t z1) ** extq z0\.b, z0\.b, z1\.b, #1 ** ret */ -fixed_int8_t +[[gnu::noipa]] fixed_int8_t f7 (fixed_int8_t z0, fixed_int8_t z1) { return __builtin_shufflevector (z0, z1, @@ -102,7 +102,7 @@ f7 (fixed_int8_t z0, fixed_int8_t z1) ** extq z0\.b, z0\.b, z1\.b, #11 ** ret */ -fixed_int8_t +[[gnu::noipa]] fixed_int8_t f8 (fixed_int8_t z0, fixed_int8_t z1) { return __builtin_shufflevector (z0, z1, @@ -117,7 +117,7 @@ f8 (fixed_int8_t z0, fixed_int8_t z1) ** extq z0\.b, z0\.b, z1\.b, #15 ** ret */ -fixed_int8_t +[[gnu::noipa]] fixed_int8_t f9 (fixed_int8_t z0, fixed_int8_t z1) { return __builtin_shufflevector (z0, z1, diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/extq_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve2/extq_1_run.c new file mode 100644 index 000000000000..6b72c98a22cb --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/extq_1_run.c @@ -0,0 +1,73 @@ +/* { dg-do run { target { aarch64_sve256_hw && aarch64_sve2p1_hw } } } */ +/* { dg-options "-O2 -msve-vector-bits=256" } */ + +#include "extq_1.c" + +#define TEST(A, B) \ + do { \ + typeof(B) actual_ = (A); \ + if (__builtin_memcmp (&actual_, &(B), sizeof (actual_)) != 0) \ + __builtin_abort (); \ + } while (0) + +int +main () +{ + fixed_float64_t a64 = { 1.5, 3.75, -5.25, 9 }; + fixed_float64_t b64 = { -2, 4.125, -6.375, 11.5 }; + fixed_float64_t expected1 = { 3.75, -2, 9, -6.375 }; + TEST (f1 (a64, b64), expected1); + + fixed_uint32_t a32 = { 0x1122, -0x3344, 0x5566, -0x7788, + 0x99aa, -0xbbcc, 0xddee, -0xff00 }; + fixed_uint32_t b32 = { 1 << 20, 1 << 21, 1 << 22, 1 << 23, + 5 << 6, 5 << 7, 5 << 8, 5 << 9 }; + fixed_uint32_t expected2 = { -0x3344, 0x5566, -0x7788, 1 << 20, + -0xbbcc, 0xddee, -0xff00, 5 << 6 }; + fixed_uint32_t expected3 = { -0x7788, 1 << 20, 1 << 21, 1 << 22, + -0xff00, 5 << 6, 5 << 7, 5 << 8 }; + TEST (f2 (a32, b32), expected2); + TEST (f3 (a32, b32), expected3); + + fixed_float16_t a16 = { 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, + 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.25 }; + fixed_float16_t b16 = { -0.5, -0.75, -1, -1.25, -1.5, -1.75, -2, -2.25, + -2.5, -2.75, -3, -3.25, -3.5, -3.75, -4, -4.25 }; + fixed_float16_t expected4 = { 0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, -0.5, + 2.75, 3, 3.25, 3.5, 3.75, 4, 4.25, -2.5 }; + fixed_float16_t expected5 = { 1.75, 2, 2.25, -0.5, -0.75, -1, -1.25, -1.5, + 3.75, 4, 4.25, -2.5, -2.75, -3, -3.25, -3.5 }; + fixed_float16_t expected6 = { 2.25, -0.5, -0.75, -1, + -1.25, -1.5, -1.75, -2, + 4.25, -2.5, -2.75, -3, + -3.25, -3.5, -3.75, -4 }; + TEST (f4 (a16, b16), expected4); + TEST (f5 (a16, b16), expected5); + TEST (f6 (a16, b16), expected6); + + fixed_int8_t a8 = { 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x70, + 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf8, + 0xfe, 0xed, 0xdc, 0xcb, 0xba, 0xa9, 0x98, 0x8f, + 0x76, 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x07 }; + fixed_int8_t b8 = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, + 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, + 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, 0x8a, + 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1, 0x02 }; + fixed_int8_t expected7 = { 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x70, 0x89, + 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf8, 0x11, + 0xed, 0xdc, 0xcb, 0xba, 0xa9, 0x98, 0x8f, 0x76, + 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x07, 0x13 }; + fixed_int8_t expected8 = { 0xbc, 0xcd, 0xde, 0xef, 0xf8, 0x11, 0x22, 0x33, + 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, + 0x43, 0x32, 0x21, 0x10, 0x07, 0x13, 0x24, 0x35, + 0x46, 0x57, 0x68, 0x79, 0x8a, 0x9b, 0xac, 0xbd }; + fixed_int8_t expected9 = { 0xf8, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0x07, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, + 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }; + TEST (f7 (a8, b8), expected7); + TEST (f8 (a8, b8), expected8); + TEST (f9 (a8, b8), expected9); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/nbsl_nor_nand_neon.c b/gcc/testsuite/gcc.target/aarch64/sve2/nbsl_nor_nand_neon.c new file mode 100644 index 000000000000..09bfc194f88a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/nbsl_nor_nand_neon.c @@ -0,0 +1,68 @@ +/* { dg-options "-O2" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +#include + +#define NAND(x, y) (~((x) & (y))) +#define NOR(x, y) (~((x) | (y))) + +/* +** nand_d: +** nbsl z0.d, z0.d, z1.d, z1.d +** ret +*/ +uint32x2_t nand_d(uint32x2_t a, uint32x2_t b) { return NAND(a, b); } + +/* +** nand_d_mp: +** movprfx z0, z1 +** nbsl z0.d, z0.d, z2.d, z2.d +** ret +*/ +uint32x2_t nand_d_mp(uint32x2_t c, uint32x2_t a, uint32x2_t b) { return NAND(a, b); } + +/* +** nor_d: +** nbsl z0.d, z0.d, z1.d, z0.d +** ret +*/ +uint32x2_t nor_d(uint32x2_t a, uint32x2_t b) { return NOR(a, b); } + +/* +** nor_d_mp: +** movprfx z0, z1 +** nbsl z0.d, z0.d, z2.d, z1.d +** ret +*/ +uint32x2_t nor_d_mp(uint32x2_t c, uint32x2_t a, uint32x2_t b) { return NOR(a, b); } + +/* +** nand_q: +** nbsl z0.d, z0.d, z1.d, z1.d +** ret +*/ +uint64x2_t nand_q(uint64x2_t a, uint64x2_t b) { return NAND(a, b); } + +/* +** nand_q_mp: +** movprfx z0, z1 +** nbsl z0.d, z0.d, z2.d, z2.d +** ret +*/ +uint32x4_t nand_q_mp(uint32x4_t c, uint32x4_t a, uint32x4_t b) { return NAND(a, b); } + +/* +** nor_q: +** nbsl z0.d, z0.d, z1.d, z0.d +** ret +*/ +uint64x2_t nor_q(uint64x2_t a, uint64x2_t b) { return NOR(a, b); } + +/* +** nor_q_mp: +** movprfx z0, z1 +** nbsl z0.d, z0.d, z2.d, z1.d +** ret +*/ +uint32x4_t nor_q_mp(uint32x4_t c, uint32x4_t a, uint32x4_t b) { return NOR(a, b); } + diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary.c index 94470a5d617d..977fa3908dee 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_int_opt_n.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_int_opt_n.c index b8747b8d50a0..b816fa1aa5b2 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_int_opt_n.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_int_opt_n.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_int_opt_single_n.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_int_opt_single_n.c index 7cb7ee5203c0..0e4427a32aa2 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_int_opt_single_n.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_int_opt_single_n.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_opt_n.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_opt_n.c index 787126f70bd8..81d0c8275c40 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_opt_n.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_opt_n.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_opt_single_n.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_opt_single_n.c index 6b2b0a424d3f..3920bdb181ff 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_opt_single_n.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_opt_single_n.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2 -march=armv8.2-a+sve2+faminmax" } */ +/* { dg-options "-O2 -march=armv8.2-a+sve2+faminmax -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_to_uint.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_to_uint.c index a0a7f809f829..c7d10b3161c3 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_to_uint.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_to_uint.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_uint_opt_n.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_uint_opt_n.c index c13db48948b1..122fba7a8fbd 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_uint_opt_n.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_uint_opt_n.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_wide.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_wide.c index 145b07760d73..7f3585938707 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_wide.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-binary_wide.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-compare.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-compare.c index da175db92e40..b079a56e7873 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-compare.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-compare.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-binary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_ext_gather_index_restricted.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_ext_gather_index_restricted.c index c0476ce9c749..14e77c00adda 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_ext_gather_index_restricted.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_ext_gather_index_restricted.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_ext_gather_offset_restricted.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_ext_gather_offset_restricted.c index f64402466834..b68054849e05 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_ext_gather_offset_restricted.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_ext_gather_offset_restricted.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_gather_sv_restricted.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_gather_sv_restricted.c index a48a8a9db512..6d1a356fb031 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_gather_sv_restricted.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_gather_sv_restricted.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_gather_vs.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_gather_vs.c index 1fc08a3c53b7..9cb4471aa0c0 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_gather_vs.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-load_gather_vs.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-shift_left_imm_to_uint.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-shift_left_imm_to_uint.c index bd2c9371e65c..e57a650b4c5c 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-shift_left_imm_to_uint.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-shift_left_imm_to_uint.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-shift_right_imm.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-shift_right_imm.c index f4994de4c80c..710ca73b65a5 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-shift_right_imm.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-shift_right_imm.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-store_scatter_index_restricted.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-store_scatter_index_restricted.c index 6bec3b34ece5..dc9cf46c88dd 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-store_scatter_index_restricted.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-store_scatter_index_restricted.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-store_scatter_offset_restricted.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-store_scatter_offset_restricted.c index bcb4a148d62b..2728c9b32c3f 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-store_scatter_offset_restricted.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-store_scatter_offset_restricted.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary.c index ba7e931f058f..9f332955da34 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2 -march=armv9.2-a+sve+sme" } */ +/* { dg-options "-O2 -march=armv9.2-a+sve+sme -funwind-tables" } */ #include "../pfalse-unary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary_convert.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary_convert.c index 7aa59ff866f3..68769fecff33 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary_convert.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary_convert.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary_convert_narrowt.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary_convert_narrowt.c index 1a4525cc769e..692891f3fe97 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary_convert_narrowt.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary_convert_narrowt.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary_to_int.c b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary_to_int.c index b64bfc319446..7dffa1ca4f79 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary_to_int.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pfalse-unary_to_int.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target elf } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -funwind-tables" } */ #include "../pfalse-unary_0.h" diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pr120999.c b/gcc/testsuite/gcc.target/aarch64/sve2/pr120999.c new file mode 100644 index 000000000000..2dca36aea228 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/pr120999.c @@ -0,0 +1,17 @@ +/* PR target/120999. */ +/* { dg-do assemble } */ +/* { dg-options "-O2 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +#include + +#define NOR(x, y) (~((x) | (y))) + +/* +** nor_z: +** movprfx z0, z1 +** nbsl z0.d, z0.d, z2.d, z1.d +** ret +*/ +svuint64_t nor_z(svuint64_t c, svuint64_t a, svuint64_t b) { return NOR(a, b); } + diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/uzpq_1.c b/gcc/testsuite/gcc.target/aarch64/sve2/uzpq_1.c index f923e9447ec3..587f67076b64 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/uzpq_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/uzpq_1.c @@ -1,5 +1,5 @@ /* { dg-options "-O2 -msve-vector-bits=256" } */ -/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ #include @@ -15,7 +15,7 @@ typedef svint64_t fixed_int64_t __attribute__((arm_sve_vector_bits(256))); ** trn1 z0\.d, z0\.d, z1\.d ** ret */ -fixed_int64_t +[[gnu::noipa]] fixed_int64_t f1 (fixed_int64_t z0, fixed_int64_t z1) { return __builtin_shufflevector (z0, z1, 0, 4, 2, 6); @@ -26,7 +26,7 @@ f1 (fixed_int64_t z0, fixed_int64_t z1) ** trn2 z0\.d, z0\.d, z1\.d ** ret */ -fixed_int64_t +[[gnu::noipa]] fixed_int64_t f2 (fixed_int64_t z0, fixed_int64_t z1) { return __builtin_shufflevector (z0, z1, 1, 5, 3, 7); @@ -37,7 +37,7 @@ f2 (fixed_int64_t z0, fixed_int64_t z1) ** uzpq1 z0\.s, z0\.s, z1\.s ** ret */ -fixed_float32_t +[[gnu::noipa]] fixed_float32_t f3 (fixed_float32_t z0, fixed_float32_t z1) { return __builtin_shufflevector (z0, z1, 0, 2, 8, 10, 4, 6, 12, 14); @@ -48,7 +48,7 @@ f3 (fixed_float32_t z0, fixed_float32_t z1) ** uzpq2 z0\.s, z0\.s, z1\.s ** ret */ -fixed_float32_t +[[gnu::noipa]] fixed_float32_t f4 (fixed_float32_t z0, fixed_float32_t z1) { return __builtin_shufflevector (z0, z1, 1, 3, 9, 11, 5, 7, 13, 15); @@ -59,7 +59,7 @@ f4 (fixed_float32_t z0, fixed_float32_t z1) ** uzpq1 z0\.h, z0\.h, z1\.h ** ret */ -fixed_bfloat16_t +[[gnu::noipa]] fixed_bfloat16_t f5 (fixed_bfloat16_t z0, fixed_bfloat16_t z1) { return __builtin_shufflevector (z0, z1, @@ -72,7 +72,7 @@ f5 (fixed_bfloat16_t z0, fixed_bfloat16_t z1) ** uzpq2 z0\.h, z0\.h, z1\.h ** ret */ -fixed_bfloat16_t +[[gnu::noipa]] fixed_bfloat16_t f6 (fixed_bfloat16_t z0, fixed_bfloat16_t z1) { return __builtin_shufflevector (z0, z1, @@ -85,7 +85,7 @@ f6 (fixed_bfloat16_t z0, fixed_bfloat16_t z1) ** uzpq1 z0\.b, z0\.b, z1\.b ** ret */ -fixed_uint8_t +[[gnu::noipa]] fixed_uint8_t f7 (fixed_uint8_t z0, fixed_uint8_t z1) { return __builtin_shufflevector (z0, z1, @@ -100,7 +100,7 @@ f7 (fixed_uint8_t z0, fixed_uint8_t z1) ** uzpq2 z0\.b, z0\.b, z1\.b ** ret */ -fixed_uint8_t +[[gnu::noipa]] fixed_uint8_t f8 (fixed_uint8_t z0, fixed_uint8_t z1) { return __builtin_shufflevector (z0, z1, diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/uzpq_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve2/uzpq_1_run.c new file mode 100644 index 000000000000..9044cae659b3 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/uzpq_1_run.c @@ -0,0 +1,78 @@ +/* { dg-do run { target { aarch64_sve256_hw && aarch64_sve2p1_hw } } } */ +/* { dg-options "-O2 -msve-vector-bits=256" } */ + +#include "uzpq_1.c" + +typedef svuint16_t fixed_uint16_t __attribute__((arm_sve_vector_bits(256))); + +#define TEST(A, B) \ + do { \ + typeof(A) actual_ = (A); \ + if (__builtin_memcmp (&actual_, &(B), sizeof (actual_)) != 0) \ + __builtin_abort (); \ + } while (0) + +int +main () +{ + fixed_int64_t a64 = { 0x1122LL << 31, -1LL << 47, 0x5566 << 15, -2 }; + fixed_int64_t b64 = { 42, -0x3344LL << 19, 303, -0x7788LL << 27 }; + fixed_int64_t expected1 = { 0x1122LL << 31, 42, + 0x5566 << 15, 303 }; + fixed_int64_t expected2 = { -1LL << 47, -0x3344LL << 19, + -2, -0x7788LL << 27 }; + TEST (f1 (a64, b64), expected1); + TEST (f2 (a64, b64), expected2); + + fixed_float32_t a32 = { 0.5, 0.75, 1, 1.25, 2.5, 2.75, 3, 3.25 }; + fixed_float32_t b32 = { -0.5, -0.75, -1, -1.25, -2.5, -2.75, -3, -3.25 }; + fixed_float32_t expected3 = { 0.5, 1, -0.5, -1, + 2.5, 3, -2.5, -3 }; + fixed_float32_t expected4 = { 0.75, 1.25, -0.75, -1.25, + 2.75, 3.25, -2.75, -3.25 }; + TEST (f3 (a32, b32), expected3); + TEST (f4 (a32, b32), expected4); + + fixed_uint16_t a16_i = { 0x9a12, 0xbc34, 0xde56, 0xf078, + 0x00ff, 0x11ee, 0x22dd, 0x33cc, + 0x44bb, 0x55aa, 0x6699, 0x7788, + 0xfe01, 0xdc23, 0xba45, 0x9867 }; + fixed_uint16_t b16_i = { 0x1010, 0x2020, 0x3030, 0x4040, + 0x5050, 0x6060, 0x7070, 0x8080, + 0x9090, 0xa0a0, 0xb0b0, 0xc0c0, + 0xd0d0, 0xe0e0, 0xf0f0, 0x0f0f }; + fixed_uint16_t expected5 = { 0x9a12, 0xde56, 0x00ff, 0x22dd, + 0x1010, 0x3030, 0x5050, 0x7070, + 0x44bb, 0x6699, 0xfe01, 0xba45, + 0x9090, 0xb0b0, 0xd0d0, 0xf0f0 }; + fixed_uint16_t expected6 = { 0xbc34, 0xf078, 0x11ee, 0x33cc, + 0x2020, 0x4040, 0x6060, 0x8080, + 0x55aa, 0x7788, 0xdc23, 0x9867, + 0xa0a0, 0xc0c0, 0xe0e0, 0x0f0f }; + fixed_bfloat16_t a16, b16; + __builtin_memcpy (&a16, &a16_i, sizeof (a16)); + __builtin_memcpy (&b16, &b16_i, sizeof (b16)); + TEST (f5 (a16, b16), expected5); + TEST (f6 (a16, b16), expected6); + + fixed_uint8_t a8 = { 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x70, + 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf8, + 0xfe, 0xed, 0xdc, 0xcb, 0xba, 0xa9, 0x98, 0x8f, + 0x76, 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x07 }; + fixed_uint8_t b8 = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, + 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, + 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, 0x8a, + 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1, 0x02 }; + fixed_uint8_t expected7 = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x11, 0x33, 0x55, 0x77, 0x99, 0xbb, 0xdd, 0xff, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x13, 0x35, 0x57, 0x79, 0x9b, 0xbd, 0xdf, 0xf1 }; + fixed_uint8_t expected8 = { 0x12, 0x34, 0x56, 0x70, 0x9a, 0xbc, 0xde, 0xf8, + 0x22, 0x44, 0x66, 0x88, 0xaa, 0xcc, 0xee, 0x00, + 0xed, 0xcb, 0xa9, 0x8f, 0x65, 0x43, 0x21, 0x07, + 0x24, 0x46, 0x68, 0x8a, 0xac, 0xce, 0xe0, 0x02 }; + TEST (f7 (a8, b8), expected7); + TEST (f8 (a8, b8), expected8); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/zipq_1.c b/gcc/testsuite/gcc.target/aarch64/sve2/zipq_1.c index fa420a959c72..76fb4b4440b7 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve2/zipq_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve2/zipq_1.c @@ -1,5 +1,5 @@ /* { dg-options "-O2 -msve-vector-bits=256" } */ -/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ #include @@ -15,7 +15,7 @@ typedef svint64_t fixed_int64_t __attribute__((arm_sve_vector_bits(256))); ** trn1 z0\.d, z0\.d, z1\.d ** ret */ -fixed_int64_t +[[gnu::noipa]] fixed_int64_t f1 (fixed_int64_t z0, fixed_int64_t z1) { return __builtin_shufflevector (z0, z1, 0, 4, 2, 6); @@ -26,7 +26,7 @@ f1 (fixed_int64_t z0, fixed_int64_t z1) ** trn2 z0\.d, z0\.d, z1\.d ** ret */ -fixed_int64_t +[[gnu::noipa]] fixed_int64_t f2 (fixed_int64_t z0, fixed_int64_t z1) { return __builtin_shufflevector (z0, z1, 1, 5, 3, 7); @@ -37,7 +37,7 @@ f2 (fixed_int64_t z0, fixed_int64_t z1) ** zipq1 z0\.s, z0\.s, z1\.s ** ret */ -fixed_float32_t +[[gnu::noipa]] fixed_float32_t f3 (fixed_float32_t z0, fixed_float32_t z1) { return __builtin_shufflevector (z0, z1, 0, 8, 1, 9, 4, 12, 5, 13); @@ -48,7 +48,7 @@ f3 (fixed_float32_t z0, fixed_float32_t z1) ** zipq2 z0\.s, z0\.s, z1\.s ** ret */ -fixed_float32_t +[[gnu::noipa]] fixed_float32_t f4 (fixed_float32_t z0, fixed_float32_t z1) { return __builtin_shufflevector (z0, z1, 2, 10, 3, 11, 6, 14, 7, 15); @@ -59,7 +59,7 @@ f4 (fixed_float32_t z0, fixed_float32_t z1) ** zipq1 z0\.h, z0\.h, z1\.h ** ret */ -fixed_bfloat16_t +[[gnu::noipa]] fixed_bfloat16_t f5 (fixed_bfloat16_t z0, fixed_bfloat16_t z1) { return __builtin_shufflevector (z0, z1, @@ -72,7 +72,7 @@ f5 (fixed_bfloat16_t z0, fixed_bfloat16_t z1) ** zipq2 z0\.h, z0\.h, z1\.h ** ret */ -fixed_bfloat16_t +[[gnu::noipa]] fixed_bfloat16_t f6 (fixed_bfloat16_t z0, fixed_bfloat16_t z1) { return __builtin_shufflevector (z0, z1, @@ -85,7 +85,7 @@ f6 (fixed_bfloat16_t z0, fixed_bfloat16_t z1) ** zipq1 z0\.b, z0\.b, z1\.b ** ret */ -fixed_uint8_t +[[gnu::noipa]] fixed_uint8_t f7 (fixed_uint8_t z0, fixed_uint8_t z1) { return __builtin_shufflevector (z0, z1, @@ -100,7 +100,7 @@ f7 (fixed_uint8_t z0, fixed_uint8_t z1) ** zipq2 z0\.b, z0\.b, z1\.b ** ret */ -fixed_uint8_t +[[gnu::noipa]] fixed_uint8_t f8 (fixed_uint8_t z0, fixed_uint8_t z1) { return __builtin_shufflevector (z0, z1, diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/zipq_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve2/zipq_1_run.c new file mode 100644 index 000000000000..211f9d945edf --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/zipq_1_run.c @@ -0,0 +1,78 @@ +/* { dg-do run { target { aarch64_sve256_hw && aarch64_sve2p1_hw } } } */ +/* { dg-options "-O2 -msve-vector-bits=256" } */ + +#include "zipq_1.c" + +typedef svuint16_t fixed_uint16_t __attribute__((arm_sve_vector_bits(256))); + +#define TEST(A, B) \ + do { \ + typeof(A) actual_ = (A); \ + if (__builtin_memcmp (&actual_, &(B), sizeof (actual_)) != 0) \ + __builtin_abort (); \ + } while (0) + +int +main () +{ + fixed_int64_t a64 = { 0x1122LL << 31, -1LL << 47, 0x5566 << 15, -2 }; + fixed_int64_t b64 = { 42, -0x3344LL << 19, 303, -0x7788LL << 27 }; + fixed_int64_t expected1 = { 0x1122LL << 31, 42, + 0x5566 << 15, 303 }; + fixed_int64_t expected2 = { -1LL << 47, -0x3344LL << 19, + -2, -0x7788LL << 27 }; + TEST (f1 (a64, b64), expected1); + TEST (f2 (a64, b64), expected2); + + fixed_float32_t a32 = { 0.5, 0.75, 1, 1.25, 2.5, 2.75, 3, 3.25 }; + fixed_float32_t b32 = { -0.5, -0.75, -1, -1.25, -2.5, -2.75, -3, -3.25 }; + fixed_float32_t expected3 = { 0.5, -0.5, 0.75, -0.75, + 2.5, -2.5, 2.75, -2.75 }; + fixed_float32_t expected4 = { 1, -1, 1.25, -1.25, + 3, -3, 3.25, -3.25 }; + TEST (f3 (a32, b32), expected3); + TEST (f4 (a32, b32), expected4); + + fixed_uint16_t a16_i = { 0x9a12, 0xbc34, 0xde56, 0xf078, + 0x00ff, 0x11ee, 0x22dd, 0x33cc, + 0x44bb, 0x55aa, 0x6699, 0x7788, + 0xfe01, 0xdc23, 0xba45, 0x9867 }; + fixed_uint16_t b16_i = { 0x1010, 0x2020, 0x3030, 0x4040, + 0x5050, 0x6060, 0x7070, 0x8080, + 0x9090, 0xa0a0, 0xb0b0, 0xc0c0, + 0xd0d0, 0xe0e0, 0xf0f0, 0x0f0f }; + fixed_uint16_t expected5 = { 0x9a12, 0x1010, 0xbc34, 0x2020, + 0xde56, 0x3030, 0xf078, 0x4040, + 0x44bb, 0x9090, 0x55aa, 0xa0a0, + 0x6699, 0xb0b0, 0x7788, 0xc0c0 }; + fixed_uint16_t expected6 = { 0x00ff, 0x5050, 0x11ee, 0x6060, + 0x22dd, 0x7070, 0x33cc, 0x8080, + 0xfe01, 0xd0d0, 0xdc23, 0xe0e0, + 0xba45, 0xf0f0, 0x9867, 0x0f0f }; + fixed_bfloat16_t a16, b16; + __builtin_memcpy (&a16, &a16_i, sizeof (a16)); + __builtin_memcpy (&b16, &b16_i, sizeof (b16)); + TEST (f5 (a16, b16), expected5); + TEST (f6 (a16, b16), expected6); + + fixed_uint8_t a8 = { 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x70, + 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf8, + 0xfe, 0xed, 0xdc, 0xcb, 0xba, 0xa9, 0x98, 0x8f, + 0x76, 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x07 }; + fixed_uint8_t b8 = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, + 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, + 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, 0x8a, + 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1, 0x02 }; + fixed_uint8_t expected7 = { 0x01, 0x11, 0x12, 0x22, 0x23, 0x33, 0x34, 0x44, + 0x45, 0x55, 0x56, 0x66, 0x67, 0x77, 0x70, 0x88, + 0xfe, 0x13, 0xed, 0x24, 0xdc, 0x35, 0xcb, 0x46, + 0xba, 0x57, 0xa9, 0x68, 0x98, 0x79, 0x8f, 0x8a }; + fixed_uint8_t expected8 = { 0x89, 0x99, 0x9a, 0xaa, 0xab, 0xbb, 0xbc, 0xcc, + 0xcd, 0xdd, 0xde, 0xee, 0xef, 0xff, 0xf8, 0x00, + 0x76, 0x9b, 0x65, 0xac, 0x54, 0xbd, 0x43, 0xce, + 0x32, 0xdf, 0x21, 0xe0, 0x10, 0xf1, 0x07, 0x02 }; + TEST (f7 (a8, b8), expected7); + TEST (f8 (a8, b8), expected8); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/unroll-vect.c b/gcc/testsuite/gcc.target/aarch64/unroll-vect.c new file mode 100644 index 000000000000..3cb774ba9578 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/unroll-vect.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3 -march=armv8-a --param aarch64-autovec-preference=asimd-only -std=gnu99" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +** f1: +** ... +** add v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s +** add v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s +** add v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s +** add v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s +** ... +*/ +void f1 (int *restrict a, int n) +{ +#pragma GCC unroll 16 + for (int i = 0; i < n; i++) + a[i] *= 2; +} + diff --git a/gcc/testsuite/gcc.target/aarch64/vec-set-zero.c b/gcc/testsuite/gcc.target/aarch64/vec-set-zero.c index b34b902cf27b..ba4696e5840f 100644 --- a/gcc/testsuite/gcc.target/aarch64/vec-set-zero.c +++ b/gcc/testsuite/gcc.target/aarch64/vec-set-zero.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2" } */ +/* { dg-options "-Os" } */ #include "arm_neon.h" diff --git a/gcc/testsuite/gcc.target/aarch64/vector-compare-5.c b/gcc/testsuite/gcc.target/aarch64/vector-compare-5.c new file mode 100644 index 000000000000..a1a601dc1958 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/vector-compare-5.c @@ -0,0 +1,67 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-fdump-tree-original-all" } */ + +typedef int v4i __attribute__((vector_size(4*sizeof(int)))); + +/* Ensure we can simplify `VEC_COND_EXPR(a OP1 b) OP2 VEC_COND_EXPR(a OP3 b)` + * into `VEC_COND_EXPR(a OP4 b)` + */ + +void use (v4i const *z); + +void +g (v4i *x, v4i const *y, v4i *z, v4i *t) +{ + *z = *x > *y | *x == *y; // expect >= + *t = *x > *y | *x <= *y; // expect true +} + +void +h (v4i *x, v4i const *y, v4i *z, v4i *t) +{ + *z = *x <= *y & *x >= *y; // expect x == y + *t = *x <= *y & *x != *y; // expect x *y; // expect false +} + +void +m (v4i *x, v4i const *y, v4i *z, v4i *t) +{ + *z = *x <= *y ^ *x >= *y; /* expect x != y */ + *t = *x <= *y ^ *x != *y; /* expect x <= y */ +} + +void +n (v4i *x, v4i const *y, v4i *z, v4i *t) +{ + *z = *x == *y ^ *x != *y; /* expect true */ + *t = *x == *y ^ *x == *y; /* expect false */ +} + + +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*>=\\s*VIEW_CONVERT_EXPR\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*==\\s*VIEW_CONVERT_EXPR\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*<\\s*VIEW_CONVERT_EXPR\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*<=\\s*VIEW_CONVERT_EXPR\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*!=\\s*VIEW_CONVERT_EXPR\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*>=\\s*VIEW_CONVERT_EXPR\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*;" "original" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/vld2-1.c b/gcc/testsuite/gcc.target/aarch64/vld2-1.c new file mode 100644 index 000000000000..8a267674df17 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/vld2-1.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-forwprop1-details" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ +/* PR tree-optimization/89606 */ + +#include + +/* +**func1: +** ld2 {v0.2d - v1.2d}, \[x0\] +** ld2 {v0.d - v1.d}\[1\], \[x1\] +** ret +*/ +float64x2x2_t func1(const double *p1, const double *p2) +{ + float64x2x2_t v = vld2q_f64(p1); + return vld2q_lane_f64(p2, v, 1); +} + +/* +**func2: +** ld2 {v0.2s - v1.2s}, \[x0\] +** ld2 {v0.s - v1.s}\[1\], \[x1\] +** ret +*/ +float32x2x2_t func2(const float *p1, const float *p2) +{ + float32x2x2_t v = vld2_f32(p1); + return vld2_lane_f32(p2, v, 1); +} + +/* +**func3: +** ld2 {v([0-9]+).2s - v([0-9]+).2s}, \[x1\] +** ld2 {v\1.s - v\2.s}\[1\], \[x2\] +** stp d\1, d\2, \[x0\] +** ret +*/ +void func3(float32x2x2_t *p, const float *p1, const float *p2) +{ + float32x2x2_t v = vld2_f32(p1); + *p = vld2_lane_f32(p2, v, 1); +} + +/* { dg-final { scan-tree-dump-times "after previous" 3 "forwprop1" } } */ diff --git a/gcc/testsuite/gcc.target/arc/fma-1.c b/gcc/testsuite/gcc.target/arc/fma-1.c index c195ad98127c..b32989fced1b 100644 --- a/gcc/testsuite/gcc.target/arc/fma-1.c +++ b/gcc/testsuite/gcc.target/arc/fma-1.c @@ -2,7 +2,8 @@ /* { dg-skip-if "FPU not available" { arc700 || arc6xx } } */ /* { dg-options "-s -std=gnu11 -O2 -frounding-math -mfpu=fpus_all" } */ -const float a, b = 7.8539818525e01; +const float b = 7.8539818525e01; +extern const float a; /* Check if the fma operation is generated correctly. */ diff --git a/gcc/testsuite/gcc.target/arc/mult-cmp0.c b/gcc/testsuite/gcc.target/arc/mult-cmp0.c new file mode 100644 index 000000000000..680c72eaa6de --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/mult-cmp0.c @@ -0,0 +1,66 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +/* mpy.f r1,r0,r1 + mov_s r0,5 ;3 + j_s.d [blink] + mov.ne r0,r1 */ +unsigned int +ubar (unsigned int a, unsigned int b) +{ + unsigned int c = a * b; + if (c == 0) + { + return 5; + } + return c; +} + +/* mpy.f r1,r0,r1 + mov_s r0,5 ;3 + j_s.d [blink] + mov.ne r0,r1 */ +signed int +bar (signed int a, signed int b) +{ + signed int c = a * b; + if (c == 0) + { + return 5; + } + return c; +} + +/* mpy.f 0,r0,r1 + mov_s r0,1 ;3 + j_s.d [blink] + mov.eq r0,5 */ +unsigned int +ufoo (unsigned int a, unsigned int b) +{ + if (a * b == 0) + { + return 5; + } + return 1; +} + +/* mpy.f 0,r0,r1 + mov_s r0,1 ;3 + j_s.d [blink] + mov.eq r0,5 */ +unsigned int +foo (signed int a, signed int b) +{ + if (a * b == 0) + { + return 5; + } + return 1; +} + +/* { dg-final { scan-assembler-times "mpy\\.f\\s+0" 2 } } */ +/* { dg-final { scan-assembler-times "mov\\.ne\\s+" 2 } } */ +/* { dg-final { scan-assembler-times "mpy\\.f\\s+r" 2 } } */ +/* { dg-final { scan-assembler-times "mov\\.eq\\s+" 2 } } */ + diff --git a/gcc/testsuite/gcc.target/arc/overflow-1.c b/gcc/testsuite/gcc.target/arc/overflow-1.c new file mode 100644 index 000000000000..cf1d0d0902c6 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/overflow-1.c @@ -0,0 +1,98 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +#include +#include + +/* + * add.f r0,r0,r1 + * st_s r0,[r2] + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool add_overflow (int32_t a, int32_t b, int32_t *res) +{ + return __builtin_add_overflow (a, b, res); +} + +/* + * add.f r0,r0,-1234 + * st_s r0,[r1] + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool addi_overflow (int32_t a, int32_t *res) +{ + return __builtin_add_overflow (a, -1234, res); +} + +/* + * add.f r0,r0,r1 + * st_s r0,[r2] + * j_s.d [blink] + * rlc r0,0 + */ +bool uadd_overflow (uint32_t a, uint32_t b, uint32_t *res) +{ + return __builtin_add_overflow (a, b, res); +} + +/* + * add.f r2,r0, 4321 + * seths r0,r0,-4321 + * j_s.d [blink] + * st_s r2,[r1] + */ +bool uaddi_overflow (uint32_t a, uint32_t *res) +{ + return __builtin_add_overflow (a, 4321, res); +} + +/* + * add.f r0,r0,r1 + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool add_overflow_p (int32_t a, int32_t b, int32_t res) +{ + return __builtin_add_overflow_p (a, b, res); +} + +/* + * add.f r0,r0,-1000 + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool addi_overflow_p (int32_t a, int32_t res) +{ + return __builtin_add_overflow_p (a, -1000, res); +} + +/* + * add.f 0,r0,r1 + * j_s.d [blink] + * rlc r0,0 + */ +bool uadd_overflow_p (uint32_t a, uint32_t b, uint32_t res) +{ + return __builtin_add_overflow_p (a, b, res); +} + +/* + * j_s.d [blink] + * seths r0,r0,-2000 + */ +bool uaddi_overflow_p (uint32_t a, uint32_t res) +{ + return __builtin_add_overflow_p (a, 2000, res); +} + +/* { dg-final { scan-assembler-times "add.f\\s\+" 7 } } */ +/* { dg-final { scan-assembler-times "mov\.nv\\s\+" 4 } } */ +/* { dg-final { scan-assembler-times "rlc\\s\+" 2 } } */ +/* { dg-final { scan-assembler-times "seths\\s\+" 2 } } */ +/* { dg-final { scan-assembler-not "cmp" } } */ diff --git a/gcc/testsuite/gcc.target/arc/overflow-2.c b/gcc/testsuite/gcc.target/arc/overflow-2.c new file mode 100644 index 000000000000..b4de8c03b228 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/overflow-2.c @@ -0,0 +1,97 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +#include +#include + +/* + * sub.f r0,r0,r1 + * st_s r0,[r2] + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool sub_overflow (int32_t a, int32_t b, int32_t *res) +{ + return __builtin_sub_overflow (a, b, res); +} + +/* + * sub.f r0,r0,-1234 + * st_s r0,[r1] + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool subi_overflow (int32_t a, int32_t *res) +{ + return __builtin_sub_overflow (a, -1234, res); +} + +/* + * sub.f r3,r0,r1 + * st_s r3,[r2] + * j_s.d [blink] + * setlo r0,r0,r1 + */ +bool usub_overflow (uint32_t a, uint32_t b, uint32_t *res) +{ + return __builtin_sub_overflow (a, b, res); +} + +/* + * sub.f r2,r0,4321 + * seths r0,4320,r0 + * j_s.d [blink] + * st_s r2,[r1] + */ +bool usubi_overflow (uint32_t a, uint32_t *res) +{ + return __builtin_sub_overflow (a, 4321, res); +} + +/* + * sub.f r0,r0,r1 + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool sub_overflow_p (int32_t a, int32_t b, int32_t res) +{ + return __builtin_sub_overflow_p (a, b, res); +} + +/* + * sub.f r0,r0,-1000 + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool subi_overflow_p (int32_t a, int32_t res) +{ + return __builtin_sub_overflow_p (a, -1000, res); +} + +/* + * j_s.d [blink] + * setlo r0,r0,r1 + */ +bool usub_overflow_p (uint32_t a, uint32_t b, uint32_t res) +{ + return __builtin_sub_overflow_p (a, b, res); +} + +/* + * seths r0,1999,r0 + * j_s.d [blink] + */ +bool usubi_overflow_p (uint32_t a, uint32_t res) +{ + return __builtin_sub_overflow_p (a, 2000, res); +} + +/* { dg-final { scan-assembler-times "sub.f\\s\+" 6 } } */ +/* { dg-final { scan-assembler-times "mov\.nv\\s\+" 4 } } */ +/* { dg-final { scan-assembler-times "setlo\\s\+" 2 } } */ +/* { dg-final { scan-assembler-times "seths\\s\+" 2 } } */ +/* { dg-final { scan-assembler-not "cmp" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr121065.c b/gcc/testsuite/gcc.target/arm/pr121065.c new file mode 100644 index 000000000000..dfc6059a46d2 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr121065.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=cortex-m55" } */ + +_Accum sa; +char c; + +void +div_csa () +{ + c /= sa; +} diff --git a/gcc/testsuite/gcc.target/avr/torture/pr120423-1.c b/gcc/testsuite/gcc.target/avr/torture/pr120423-1.c new file mode 100644 index 000000000000..91b4bbc812c8 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr120423-1.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ + +struct data +{ + int a; + int b; + long c; +}; + +unsigned char val; +unsigned val2; + +void func1 (struct data *d) +{ + d->a = 0; + d->b = 0x100 * val - 1; +} + +void func2 (struct data *d) +{ + d->a = 0; + d->c = 0x10000 * val2 - 1; +} + +void func3 (struct data *d) +{ + d->a = 0; + d->c = 0x1000000 * val - 1; +} diff --git a/gcc/testsuite/gcc.target/avr/torture/pr120423-116389.c b/gcc/testsuite/gcc.target/avr/torture/pr120423-116389.c new file mode 100644 index 000000000000..928c1358c3c3 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr120423-116389.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ + +struct T { int val; }; + +void f_int (int); +char* get_pos (void); +struct T* get_pT (void); + +void func (char i) +{ + struct T t = * get_pT (); + unsigned diff = get_pos () - &i; + + if (diff) + { + long val32 = t.val; + if (get_pos ()) + val32 = diff; + if (get_pos ()) + f_int (2 * val32); + } +} diff --git a/gcc/testsuite/gcc.target/avr/torture/pr120423-2.c b/gcc/testsuite/gcc.target/avr/torture/pr120423-2.c new file mode 100644 index 000000000000..56e61415afb9 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr120423-2.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ffixed-18 -ffixed-20 -ffixed-22" } */ + +struct data +{ + int a; + int b; + long c; +}; + +unsigned char val; +unsigned val2; + +void func1 (struct data *d) +{ + d->a = 0; + d->b = 0x100 * val - 1; +} + +void func2 (struct data *d) +{ + d->a = 0; + d->c = 0x10000 * val2 - 1; +} + +void func3 (struct data *d) +{ + d->a = 0; + d->c = 0x1000000 * val - 1; +} diff --git a/gcc/testsuite/gcc.target/i386/amxavx512-cvtrowd2ps-2.c b/gcc/testsuite/gcc.target/i386/amxavx512-cvtrowd2ps-2.c index cfd5644c5bb1..c9a2d19a726a 100644 --- a/gcc/testsuite/gcc.target/i386/amxavx512-cvtrowd2ps-2.c +++ b/gcc/testsuite/gcc.target/i386/amxavx512-cvtrowd2ps-2.c @@ -1,6 +1,6 @@ /* { dg-do run { target { ! ia32 } } } */ /* { dg-require-effective-target amx_avx512 } */ -/* { dg-options "-O2 -march=x86-64-v3 -mamx-avx512" } */ +/* { dg-options "-O2 -march=x86-64-v3 -mamx-avx512 -mavx512fp16" } */ #define AMX_AVX512 #define DO_TEST test_amx_avx512_cvtrowd2ps void test_amx_avx512_cvtrowd2ps(); diff --git a/gcc/testsuite/gcc.target/i386/amxavx512-cvtrowps2bf16-2.c b/gcc/testsuite/gcc.target/i386/amxavx512-cvtrowps2bf16-2.c index acd5f76c96cb..2014ec6f8111 100644 --- a/gcc/testsuite/gcc.target/i386/amxavx512-cvtrowps2bf16-2.c +++ b/gcc/testsuite/gcc.target/i386/amxavx512-cvtrowps2bf16-2.c @@ -1,6 +1,6 @@ /* { dg-do run { target { ! ia32 } } } */ /* { dg-require-effective-target amx_avx512 } */ -/* { dg-options "-O2 -march=x86-64-v3 -mamx-avx512" } */ +/* { dg-options "-O2 -march=x86-64-v3 -mamx-avx512 -mavx512fp16" } */ #define AMX_AVX512 #define DO_TEST test_amx_avx512_cvtrowps2bf16 void test_amx_avx512_cvtrowps2bf16(); diff --git a/gcc/testsuite/gcc.target/i386/amxavx512-cvtrowps2ph-2.c b/gcc/testsuite/gcc.target/i386/amxavx512-cvtrowps2ph-2.c index 1fd28def9342..ca53ed009cf6 100644 --- a/gcc/testsuite/gcc.target/i386/amxavx512-cvtrowps2ph-2.c +++ b/gcc/testsuite/gcc.target/i386/amxavx512-cvtrowps2ph-2.c @@ -1,6 +1,6 @@ /* { dg-do run { target { ! ia32 } } } */ /* { dg-require-effective-target amx_avx512 } */ -/* { dg-options "-O2 -march=x86-64-v3 -mamx-avx512" } */ +/* { dg-options "-O2 -march=x86-64-v3 -mamx-avx512 -mavx512fp16" } */ #define AMX_AVX512 #define DO_TEST test_amx_avx512_cvtrowps2ph void test_amx_avx512_cvtrowps2ph(); diff --git a/gcc/testsuite/gcc.target/i386/amxavx512-movrow-2.c b/gcc/testsuite/gcc.target/i386/amxavx512-movrow-2.c index ea28d82507ef..b2dee1474bb9 100644 --- a/gcc/testsuite/gcc.target/i386/amxavx512-movrow-2.c +++ b/gcc/testsuite/gcc.target/i386/amxavx512-movrow-2.c @@ -1,6 +1,6 @@ /* { dg-do run { target { ! ia32 } } } */ /* { dg-require-effective-target amx_avx512 } */ -/* { dg-options "-O2 -march=x86-64-v3 -mamx-avx512" } */ +/* { dg-options "-O2 -march=x86-64-v3 -mamx-avx512 -mavx512fp16" } */ #define AMX_AVX512 #define DO_TEST test_amx_avx512_movrow void test_amx_avx512_movrow(); diff --git a/gcc/testsuite/gcc.target/i386/asm-hard-reg-1.c b/gcc/testsuite/gcc.target/i386/asm-hard-reg-1.c new file mode 100644 index 000000000000..8080f5678f57 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/asm-hard-reg-1.c @@ -0,0 +1,80 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void +test (void) +{ + int x, y; + + __asm__ __volatile__ ("" : "=a" (x), "={rbx}" (y)); + __asm__ __volatile__ ("" : "=a" (x), "={rax}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "=a" (x) : "{rax}" (y)); + __asm__ __volatile__ ("" : "=&a" (x) : "{rax}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "a" (x), "{rax}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + + __asm__ __volatile__ ("" : "={rbx}" (x), "=a" (y)); + __asm__ __volatile__ ("" : "={rax}" (x), "=a" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "={rax}" (x) : "a" (y)); + __asm__ __volatile__ ("" : "=&{rax}" (x) : "a" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "{rax}" (x), "a" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + + __asm__ __volatile__ ("" : "=b" (x), "={rax}" (y)); + __asm__ __volatile__ ("" : "=b" (x), "={rbx}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "=b" (x) : "{rbx}" (y)); + __asm__ __volatile__ ("" : "=&b" (x) : "{rbx}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "b" (x), "{rbx}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + + __asm__ __volatile__ ("" : "={rax}" (x), "=b" (y)); + __asm__ __volatile__ ("" : "={rbx}" (x), "=b" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "={rbx}" (x) : "b" (y)); + __asm__ __volatile__ ("" : "=&{rbx}" (x) : "b" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "{rbx}" (x), "b" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + + __asm__ __volatile__ ("" : "=c" (x), "={rax}" (y)); + __asm__ __volatile__ ("" : "=c" (x), "={rcx}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "=c" (x) : "{rcx}" (y)); + __asm__ __volatile__ ("" : "=&c" (x) : "{rcx}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "c" (x), "{rcx}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + + __asm__ __volatile__ ("" : "={rax}" (x), "=c" (y)); + __asm__ __volatile__ ("" : "={rcx}" (x), "=c" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "={rcx}" (x) : "c" (y)); + __asm__ __volatile__ ("" : "=&{rcx}" (x) : "c" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "{rcx}" (x), "c" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + + __asm__ __volatile__ ("" : "=d" (x), "={rax}" (y)); + __asm__ __volatile__ ("" : "=d" (x), "={rdx}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "=d" (x) : "{rdx}" (y)); + __asm__ __volatile__ ("" : "=&d" (x) : "{rdx}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "d" (x), "{rdx}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + + __asm__ __volatile__ ("" : "={rax}" (x), "=d" (y)); + __asm__ __volatile__ ("" : "={rdx}" (x), "=d" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "={rdx}" (x) : "d" (y)); + __asm__ __volatile__ ("" : "=&{rdx}" (x) : "d" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "{rdx}" (x), "d" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + + __asm__ __volatile__ ("" : "=S" (x), "={rax}" (y)); + __asm__ __volatile__ ("" : "=S" (x), "={rsi}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "=S" (x) : "{rsi}" (y)); + __asm__ __volatile__ ("" : "=&S" (x) : "{rsi}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "S" (x), "{rsi}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + + __asm__ __volatile__ ("" : "={rax}" (x), "=S" (y)); + __asm__ __volatile__ ("" : "={rsi}" (x), "=S" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "={rsi}" (x) : "S" (y)); + __asm__ __volatile__ ("" : "=&{rsi}" (x) : "S" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "{rsi}" (x), "S" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + + __asm__ __volatile__ ("" : "=D" (x), "={rax}" (y)); + __asm__ __volatile__ ("" : "=D" (x), "={rdi}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "=D" (x) : "{rdi}" (y)); + __asm__ __volatile__ ("" : "=&D" (x) : "{rdi}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "D" (x), "{rdi}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + + __asm__ __volatile__ ("" : "={rax}" (x), "=D" (y)); + __asm__ __volatile__ ("" : "={rdi}" (x), "=D" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "={rdi}" (x) : "D" (y)); + __asm__ __volatile__ ("" : "=&{rdi}" (x) : "D" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "{rdi}" (x), "D" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ +} diff --git a/gcc/testsuite/gcc.target/i386/asm-hard-reg-2.c b/gcc/testsuite/gcc.target/i386/asm-hard-reg-2.c new file mode 100644 index 000000000000..b35cf53c5cc0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/asm-hard-reg-2.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void +test (void) +{ + int x, y, yy; +#ifdef __x86_64__ + int z __attribute__ ((mode (TI))); +#else + long z; +#endif + + __asm__ __volatile__ ("" : "=A" (z), "={rbx}" (y)); + __asm__ __volatile__ ("" : "=A" (z), "={rax}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "=A" (z), "={rdx}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "=A" (z) : "{rax}" (y)); + __asm__ __volatile__ ("" : "=A" (z) : "{rdx}" (y)); + __asm__ __volatile__ ("" : "=&A" (z) : "{rax}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "=&A" (z) : "{rdx}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "A" (z), "{rax}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "A" (z), "{rdx}" (y)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + + __asm__ __volatile__ ("" : "={rbx}" (y), "=A" (z)); + __asm__ __volatile__ ("" : "={rax}" (y), "=A" (z)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "={rdx}" (y), "=A" (z)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "={rax}" (y) : "A" (z)); + __asm__ __volatile__ ("" : "={rdx}" (y) : "A" (z)); + __asm__ __volatile__ ("" : "=&{rax}" (y) : "A" (z)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "=&{rdx}" (y) : "A" (z)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "{rax}" (y), "A" (z)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" :: "{rdx}" (y), "A" (z)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + + /* Note, we do not error for */ + __asm__ __volatile__ ("" : "=A" (x), "={rax}" (y)); + __asm__ __volatile__ ("" : "=A" (x), "={rdx}" (y)); + /* This is due to how constraint A is implemented. RA has the freedom to + choose between rax or rdx for operand 0 since x fits into a single + register and does not require a register pair. Of course, we error out if + rax and rdx are taken by other operands as in the following: */ + __asm__ __volatile__ ("" : "=A" (x), "={rax}" (y), "={rdx}" (yy)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + __asm__ __volatile__ ("" : "=A" (x), "={rdx}" (y), "={rax}" (yy)); /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ +} diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-3.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-3.c index 7c20a28508ff..a12069a039d4 100644 --- a/gcc/testsuite/gcc.target/i386/auto-init-padding-3.c +++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-3.c @@ -23,8 +23,5 @@ int foo () return var.four.internal1; } -/* { dg-final { scan-assembler "movl\t\\\$0," } } */ -/* { dg-final { scan-assembler "movl\t\\\$16," { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler "rep stosq" { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler "movl\t\\\$32," { target ia32 } } } */ -/* { dg-final { scan-assembler "rep stosl" { target ia32 } } } */ +/* { dg-final { scan-assembler-times "pxor\t%xmm0, %xmm0" 1 } } */ +/* { dg-final { scan-assembler-times "movaps\t%xmm0, " 8 } } */ diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-9.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-9.c index a87b68b255b0..4f26aa47802c 100644 --- a/gcc/testsuite/gcc.target/i386/auto-init-padding-9.c +++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-9.c @@ -2,6 +2,36 @@ padding. */ /* { dg-do compile } */ /* { dg-options "-ftrivial-auto-var-init=zero -march=x86-64" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**... +** leaq -160\(%rbp\), %rax +** movq %rax, %rcx +** pxor %xmm0, %xmm0 +** movl \$160, %edx +** movl %edx, %edi +** andl \$-64, %edi +** movl \$0, %esi +**.L[0-9]+: +** movl %esi, %edx +** movaps %xmm0, \(%rax,%rdx\) +** movaps %xmm0, 16\(%rax,%rdx\) +** movaps %xmm0, 32\(%rax,%rdx\) +** movaps %xmm0, 48\(%rax,%rdx\) +** addl \$64, %esi +** cmpl %edi, %esi +** jb .L[0-9]+ +** movl %esi, %eax +** addq %rax, %rcx +** movaps %xmm0, \(%rcx\) +** movaps %xmm0, 16\(%rcx\) +** movzbl -116\(%rbp\), %eax +** movsbl %al, %eax +**... +*/ struct test_trailing_hole { int one; @@ -18,8 +48,4 @@ int foo () return var[2].four; } -/* { dg-final { scan-assembler "movl\t\\\$0," } } */ -/* { dg-final { scan-assembler "movl\t\\\$20," { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler "rep stosq" { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler "movl\t\\\$40," { target ia32} } } */ -/* { dg-final { scan-assembler "rep stosl" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/avx10_2-comibf-1.c b/gcc/testsuite/gcc.target/i386/avx10_2-comibf-1.c index 3862f1e0d900..532a9a045add 100644 --- a/gcc/testsuite/gcc.target/i386/avx10_2-comibf-1.c +++ b/gcc/testsuite/gcc.target/i386/avx10_2-comibf-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=x86-64-v3 -mavx10.2 -O2 -fno-trapping-math" } */ +/* { dg-options "-march=x86-64-v3 -mavx10.2 -O2 -fno-trapping-math -fno-shrink-wrap" } */ /* { dg-final { scan-assembler-times "vcomisbf16\[ \\t\]+\[^{}\n\]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 6 } } */ /* { dg-final { scan-assembler-times {j[a-z]+\s} 6 } } */ diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-1.c b/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-1.c index 8603a1909c79..ee8e5cfc81ad 100644 --- a/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-1.c +++ b/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-1.c @@ -16,11 +16,11 @@ /* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*\\)\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */ /* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*\\)\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */ /* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%zmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ -/* { dg-final { scan-assembler-times "(?:vmovdqu16|vinserti128)\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ -/* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "(?:vmovdqu|vinserti128)\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ /* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*\\)(?:\n|\[ \\t\]+#)" 1 } } */ -/* { dg-final { scan-assembler-times "(?:vmovdqu16|vextracti128)\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*\\)(?:\n|\[ \\t\]+#)" 1 } } */ -/* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*\\)(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "(?:vmovdqu|vextracti128)\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*\\)(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*\\)(?:\n|\[ \\t\]+#)" 1 } } */ #include diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu8-1.c b/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu8-1.c index d1e33926c81f..4c4cddb17f1c 100644 --- a/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu8-1.c +++ b/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu8-1.c @@ -16,9 +16,9 @@ /* { dg-final { scan-assembler-times "vmovdqu8\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*\\)\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */ /* { dg-final { scan-assembler-times "vmovdqu8\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*\\)\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */ /* { dg-final { scan-assembler-times "vmovdqu8\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%zmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ -/* { dg-final { scan-assembler-times "vmovdqu8\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ /* { dg-final { scan-assembler-times "vmovdqu8\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*\\)(?:\n|\[ \\t\]+#)" 1 } } */ -/* { dg-final { scan-assembler-times "vmovdqu8\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*\\)(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*\\)(?:\n|\[ \\t\]+#)" 1 } } */ #include diff --git a/gcc/testsuite/gcc.target/i386/avx512f-pr103750-3.c b/gcc/testsuite/gcc.target/i386/avx512f-pr103750-3.c new file mode 100644 index 000000000000..9965e633b201 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512f-pr103750-3.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v4 -mprefer-vector-width=256 -Ofast" } */ +/* { dg-final { scan-assembler-not "kmov" } } */ + +void +foo (double* a, double* __restrict b, double* c, double* d, int n) +{ + for (int i = 0; i != n; i++) + { + double tmp = 0.0; + if (c[i] > d[i]) + tmp = b[i]; + a[i] = tmp; + } +} + +void +foo1 (double* a, double* __restrict b, double* c, double* d, int n) +{ + for (int i = 0; i != n; i++) + { + double tmp = 0.0; + if (c[i] > d[i]) + a[i] = b[i]; + } +} diff --git a/gcc/testsuite/gcc.target/i386/avx512fp16-13.c b/gcc/testsuite/gcc.target/i386/avx512fp16-13.c index 2416c67de53a..92ac197e1066 100644 --- a/gcc/testsuite/gcc.target/i386/avx512fp16-13.c +++ b/gcc/testsuite/gcc.target/i386/avx512fp16-13.c @@ -71,7 +71,7 @@ load256u_ph (void const *p) return _mm256_loadu_ph (p); } -/* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]*\[^,\]*,\[^\{\n\]*%ymm\[0-9\]" 1 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]*\[^,\]*,\[^\{\n\]*%ymm\[0-9\]" 1 } } */ __m128h __attribute__ ((noinline, noclone)) @@ -80,7 +80,7 @@ load128u_ph (void const *p) return _mm_loadu_ph (p); } -/* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]*\[^,\]*,\[^\{\n\]*%xmm\[0-9\]" 1 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]*\[^,\]*,\[^\{\n\]*%xmm\[0-9\]" 1 } } */ void __attribute__ ((noinline, noclone)) @@ -89,7 +89,7 @@ store512u_ph (void *p, __m512h a) return _mm512_storeu_ph (p, a); } -/* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]*\[^\{\n\]*%zmm\[0-9\], *\[^,\]*" 1 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]*\[^\{\n\]*%zmm\[0-9\], *\[^,\]*" 1 } } */ void __attribute__ ((noinline, noclone)) @@ -98,7 +98,7 @@ store256u_ph (void *p, __m256h a) return _mm256_storeu_ph (p, a); } -/* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]*\[^\{\n\]*%ymm\[0-9\], *\[^,\]*" 1 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]*\[^\{\n\]*%ymm\[0-9\], *\[^,\]*" 1 } } */ void __attribute__ ((noinline, noclone)) @@ -107,7 +107,7 @@ storeu_ph (void *p, __m128h a) return _mm_storeu_ph (p, a); } -/* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]*\[^\{\n\]*%xmm\[0-9\], *\[^,\]*" 1 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]*\[^\{\n\]*%xmm\[0-9\], *\[^,\]*" 1 } } */ __m512h __attribute__ ((noinline, noclone)) diff --git a/gcc/testsuite/gcc.target/i386/cold-attribute-4.c b/gcc/testsuite/gcc.target/i386/cold-attribute-4.c index 37a41e954daf..e0808c539051 100644 --- a/gcc/testsuite/gcc.target/i386/cold-attribute-4.c +++ b/gcc/testsuite/gcc.target/i386/cold-attribute-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2" } */ +/* { dg-options "-Oz" } */ #include int diff --git a/gcc/testsuite/gcc.target/i386/crc-builtin-crc32.c b/gcc/testsuite/gcc.target/i386/crc-builtin-crc32.c new file mode 100644 index 000000000000..0b4ff978817d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-builtin-crc32.c @@ -0,0 +1,22 @@ +/* PR target/120719 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcrc32" } */ + +#include + +int32_t rev_crc32_data8 (int8_t v) +{ + return __builtin_rev_crc32_data8 (0xffffffff, v, 0x1EDC6F41); +} + +int32_t rev_crc32_data16 (int16_t v) +{ + return __builtin_rev_crc32_data16 (0xffffffff, v, 0x1EDC6F41); +} + +int32_t rev_crc32_data32 (int32_t v) +{ + return __builtin_rev_crc32_data32 (0xffffffff, v, 0x1EDC6F41); +} + +/* { dg-final { scan-assembler-times "\tcrc32" 3 } } */ diff --git a/gcc/testsuite/gcc.target/i386/interrupt-16.c b/gcc/testsuite/gcc.target/i386/interrupt-16.c index cb45ba54e3dc..ca4441b3aee6 100644 --- a/gcc/testsuite/gcc.target/i386/interrupt-16.c +++ b/gcc/testsuite/gcc.target/i386/interrupt-16.c @@ -18,5 +18,5 @@ foo (int i) /* { dg-final { scan-assembler-not "(push|pop)(l|q)\[\\t \]*%(r|e)bp" } } */ /* { dg-final { scan-assembler-not "(push|pop)l\[\\t \]*%edi" { target ia32 } } } */ /* { dg-final { scan-assembler-not "(push|pop)q\[\\t \]*%r\[0-9\]+" { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-times "pushq\[\\t \]*%rdi" 1 { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-times "popq\[\\t \]*%rdi" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "(pushq.*%rdi|subq.*\\\$8,.*%rsp)" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "(popq.*%rdi|addq.*\\\$8,.*%rsp)" 1 { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide128kl.c b/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide128kl.c index 93806e515086..e73ba35ddd10 100644 --- a/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide128kl.c +++ b/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide128kl.c @@ -19,14 +19,14 @@ /* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm5,\[^\\n\\r\]*80\[^\\n\\r\]*" } } */ /* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm6,\[^\\n\\r\]*96\[^\\n\\r\]*" } } */ /* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm7,\[^\\n\\r\]*112\[^\\n\\r\]*" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm0, %xmm0" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm1, %xmm1" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm2, %xmm2" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm3, %xmm3" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm4, %xmm4" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm5, %xmm5" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm6, %xmm6" } } */ /* { dg-final { scan-assembler "pxor\[ \t\]+%xmm7, %xmm7" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm0" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm1" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm2" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm3" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm4" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm5" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm6" } } */ #include diff --git a/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide256kl.c b/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide256kl.c index f9ccc82c7ca0..33cd998bfdf3 100644 --- a/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide256kl.c +++ b/gcc/testsuite/gcc.target/i386/keylocker-aesdecwide256kl.c @@ -19,14 +19,14 @@ /* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm5,\[^\\n\\r\]*80\[^\\n\\r\]*" } } */ /* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm6,\[^\\n\\r\]*96\[^\\n\\r\]*" } } */ /* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm7,\[^\\n\\r\]*112\[^\\n\\r\]*" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm0, %xmm0" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm1, %xmm1" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm2, %xmm2" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm3, %xmm3" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm4, %xmm4" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm5, %xmm5" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm6, %xmm6" } } */ /* { dg-final { scan-assembler "pxor\[ \t\]+%xmm7, %xmm7" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm0" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm1" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm2" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm3" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm4" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm5" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm6" } } */ #include diff --git a/gcc/testsuite/gcc.target/i386/keylocker-aesencwide128kl.c b/gcc/testsuite/gcc.target/i386/keylocker-aesencwide128kl.c index c0fcd28fb077..75106e59b77f 100644 --- a/gcc/testsuite/gcc.target/i386/keylocker-aesencwide128kl.c +++ b/gcc/testsuite/gcc.target/i386/keylocker-aesencwide128kl.c @@ -19,14 +19,14 @@ /* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm5,\[^\\n\\r\]*80\[^\\n\\r\]*" } } */ /* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm6,\[^\\n\\r\]*96\[^\\n\\r\]*" } } */ /* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm7,\[^\\n\\r\]*112\[^\\n\\r\]*" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm0, %xmm0" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm1, %xmm1" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm2, %xmm2" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm3, %xmm3" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm4, %xmm4" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm5, %xmm5" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm6, %xmm6" } } */ /* { dg-final { scan-assembler "pxor\[ \t\]+%xmm7, %xmm7" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm0" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm1" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm2" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm3" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm4" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm5" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm6" } } */ #include diff --git a/gcc/testsuite/gcc.target/i386/keylocker-aesencwide256kl.c b/gcc/testsuite/gcc.target/i386/keylocker-aesencwide256kl.c index 31463a8b2da4..2787732229a3 100644 --- a/gcc/testsuite/gcc.target/i386/keylocker-aesencwide256kl.c +++ b/gcc/testsuite/gcc.target/i386/keylocker-aesencwide256kl.c @@ -19,14 +19,14 @@ /* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm5,\[^\\n\\r\]*80\[^\\n\\r\]*" } } */ /* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm6,\[^\\n\\r\]*96\[^\\n\\r\]*" } } */ /* { dg-final { scan-assembler "(?:movdqu|movups)\[ \\t\]+\[^\\n\\r\]*%xmm7,\[^\\n\\r\]*112\[^\\n\\r\]*" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm0, %xmm0" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm1, %xmm1" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm2, %xmm2" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm3, %xmm3" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm4, %xmm4" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm5, %xmm5" } } */ -/* { dg-final { scan-assembler "pxor\[ \t\]+%xmm6, %xmm6" } } */ /* { dg-final { scan-assembler "pxor\[ \t\]+%xmm7, %xmm7" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm0" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm1" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm2" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm3" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm4" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm5" } } */ +/* { dg-final { scan-assembler "movdqa\[ \t\]+%xmm7, %xmm6" } } */ #include diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120683-1.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120683-1.c new file mode 100644 index 000000000000..b1f66789e140 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120683-1.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mno-sse -mmemcpy-strategy=unrolled_loop:256:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** movq 221\(%rsi\), %rax +** xorl %edx, %edx +** movq %rax, 221\(%rdi\) +** movq 229\(%rsi\), %rax +** movq %rax, 229\(%rdi\) +** movq 237\(%rsi\), %rax +** movq %rax, 237\(%rdi\) +** movq 245\(%rsi\), %rax +** movq %rax, 245\(%rdi\) +**.L[0-9]+: +** movl %edx, %eax +** addl \$32, %edx +** movq \(%rsi,%rax\), %r10 +** movq 8\(%rsi,%rax\), %r9 +** movq 16\(%rsi,%rax\), %r8 +** movq 24\(%rsi,%rax\), %rcx +** movq %r10, \(%rdi,%rax\) +** movq %r9, 8\(%rdi,%rax\) +** movq %r8, 16\(%rdi,%rax\) +** movq %rcx, 24\(%rdi,%rax\) +** cmpl \$224, %edx +** jb .L[0-9]+ +** ret +**... +*/ + +void +foo (char *dest, char *src) +{ + __builtin_memcpy (dest, src, 253); +} + +/* { dg-final { scan-assembler-not "rep mov" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120683-2.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120683-2.c new file mode 100644 index 000000000000..0d0e34860e91 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120683-2.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemcpy-strategy=vector_loop:2048:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** xorl %edx, %edx +**.L[0-9]+: +** movl %edx, %eax +** addl \$64, %edx +** movdqa src\(%rax\), %xmm3 +** movdqa src\+16\(%rax\), %xmm2 +** movdqa src\+32\(%rax\), %xmm1 +** movdqa src\+48\(%rax\), %xmm0 +** movaps %xmm3, dest\(%rax\) +** movaps %xmm2, dest\+16\(%rax\) +** movaps %xmm1, dest\+32\(%rax\) +** movaps %xmm0, dest\+48\(%rax\) +** cmpl \$256, %edx +** jb .L[0-9]+ +** movdqa src\(%rdx\), %xmm0 +** movaps %xmm0, dest\(%rdx\) +** ret +**... +*/ + +#define SIZE (16 + 1) * 16 + +char dest[SIZE]; +char src[SIZE]; + +void +foo (void) +{ + __builtin_memcpy (dest, src, SIZE); +} + +/* { dg-final { scan-assembler-not "rep mov" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120683-3.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120683-3.c new file mode 100644 index 000000000000..e5aca32a5880 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120683-3.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemcpy-strategy=vector_loop:2048:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** xorl %edx, %edx +**.L[0-9]+: +** movl %edx, %eax +** addl \$64, %edx +** movdqa src\(%rax\), %xmm3 +** movdqa src\+16\(%rax\), %xmm2 +** movdqa src\+32\(%rax\), %xmm1 +** movdqa src\+48\(%rax\), %xmm0 +** movaps %xmm3, dest\(%rax\) +** movaps %xmm2, dest\+16\(%rax\) +** movaps %xmm1, dest\+32\(%rax\) +** movaps %xmm0, dest\+48\(%rax\) +** cmpl \$256, %edx +** jb .L[0-9]+ +** movdqa src\(%rdx\), %xmm0 +** movaps %xmm0, dest\(%rdx\) +** movdqu src\+15\(%rdx\), %xmm0 +** movups %xmm0, dest\+15\(%rdx\) +** ret +**... +*/ + +#define SIZE 16 * 16 + 31 + +char dest[SIZE]; +char src[SIZE]; + +void +foo (void) +{ + __builtin_memcpy (dest, src, SIZE); +} + +/* { dg-final { scan-assembler-not "rep mov" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120683-4.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120683-4.c new file mode 100644 index 000000000000..27f7bedc7037 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120683-4.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v3 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemcpy-strategy=vector_loop:2048:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** xorl %edx, %edx +**.L[0-9]+: +** movl %edx, %eax +** subl \$-128, %edx +** vmovdqa src\(%rax\), %ymm3 +** vmovdqa src\+32\(%rax\), %ymm2 +** vmovdqa src\+64\(%rax\), %ymm1 +** vmovdqa src\+96\(%rax\), %ymm0 +** vmovdqa %ymm3, dest\(%rax\) +** vmovdqa %ymm2, dest\+32\(%rax\) +** vmovdqa %ymm1, dest\+64\(%rax\) +** vmovdqa %ymm0, dest\+96\(%rax\) +** cmpl \$512, %edx +** jb .L[0-9]+ +** vmovdqa src\(%rdx\), %ymm0 +** vmovdqa %ymm0, dest\(%rdx\) +** vzeroupper +** ret +**... +*/ + +#define SIZE (16 + 1) * 32 + +char dest[SIZE]; +char src[SIZE]; + +void +foo (void) +{ + __builtin_memcpy (dest, src, SIZE); +} + +/* { dg-final { scan-assembler-not "rep mov" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120683-5.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120683-5.c new file mode 100644 index 000000000000..34a74080f21a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120683-5.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v3 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemcpy-strategy=vector_loop:2048:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** xorl %edx, %edx +**.L[0-9]+: +** movl %edx, %eax +** subl \$-128, %edx +** vmovdqa src\(%rax\), %ymm3 +** vmovdqa src\+32\(%rax\), %ymm2 +** vmovdqa src\+64\(%rax\), %ymm1 +** vmovdqa src\+96\(%rax\), %ymm0 +** vmovdqa %ymm3, dest\(%rax\) +** vmovdqa %ymm2, dest\+32\(%rax\) +** vmovdqa %ymm1, dest\+64\(%rax\) +** vmovdqa %ymm0, dest\+96\(%rax\) +** cmpl \$512, %edx +** jb .L[0-9]+ +** vmovdqa src\(%rdx\), %ymm0 +** vmovdqa %ymm0, dest\(%rdx\) +** vmovdqu src\+31\(%rdx\), %ymm0 +** vmovdqu %ymm0, dest\+31\(%rdx\) +** vzeroupper +** ret +**... +*/ + +#define SIZE 16 * 32 + 32 + 31 + +char dest[SIZE]; +char src[SIZE]; + +void +foo (void) +{ + __builtin_memcpy (dest, src, SIZE); +} + +/* { dg-final { scan-assembler-not "rep mov" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120683-6.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120683-6.c new file mode 100644 index 000000000000..aa5d90d62e4b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120683-6.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemcpy-strategy=vector_loop:2048:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** xorl %edx, %edx +**.L[0-9]+: +** movl %edx, %eax +** addl \$256, %edx +** vmovdqa64 src\(%rax\), %zmm3 +** vmovdqa64 src\+64\(%rax\), %zmm2 +** vmovdqa64 src\+128\(%rax\), %zmm1 +** vmovdqa64 src\+192\(%rax\), %zmm0 +** vmovdqa64 %zmm3, dest\(%rax\) +** vmovdqa64 %zmm2, dest\+64\(%rax\) +** vmovdqa64 %zmm1, dest\+128\(%rax\) +** vmovdqa64 %zmm0, dest\+192\(%rax\) +** cmpl \$1024, %edx +** jb .L[0-9]+ +** vmovdqa64 src\(%rdx\), %zmm0 +** vmovdqa64 %zmm0, dest\(%rdx\) +** vzeroupper +** ret +**... +*/ + +#define SIZE (16 + 1) * 64 + +char dest[SIZE] __attribute__((aligned(64))); +char src[SIZE] __attribute__((aligned(64))); + +void +foo (void) +{ + __builtin_memcpy (dest, src, SIZE); +} + +/* { dg-final { scan-assembler-not "rep mov" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120683-7.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120683-7.c new file mode 100644 index 000000000000..63d8a1521a16 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120683-7.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemcpy-strategy=vector_loop:2048:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** xorl %edx, %edx +**.L[0-9]+: +** movl %edx, %eax +** addl \$256, %edx +** vmovdqa64 src\(%rax\), %zmm3 +** vmovdqa64 src\+64\(%rax\), %zmm2 +** vmovdqa64 src\+128\(%rax\), %zmm1 +** vmovdqa64 src\+192\(%rax\), %zmm0 +** vmovdqa64 %zmm3, dest\(%rax\) +** vmovdqa64 %zmm2, dest\+64\(%rax\) +** vmovdqa64 %zmm1, dest\+128\(%rax\) +** vmovdqa64 %zmm0, dest\+192\(%rax\) +** cmpl \$1024, %edx +** jb .L[0-9]+ +** vmovdqa src\(%rdx\), %ymm0 +** vmovdqa %ymm0, dest\(%rdx\) +** vmovdqu src\+31\(%rdx\), %ymm0 +** vmovdqu %ymm0, dest\+31\(%rdx\) +** vzeroupper +** ret +**... +*/ + +#define SIZE 16 * 64 + 63 + +char dest[SIZE] __attribute__((aligned(64))); +char src[SIZE] __attribute__((aligned(64))); + +void +foo (void) +{ + __builtin_memcpy (dest, src, SIZE); +} + +/* { dg-final { scan-assembler-not "rep mov" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-1.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-1.c new file mode 100644 index 000000000000..d4fe2adc7ffd --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ +/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ +/* { dg-final { scan-assembler-not "movdqa" } } */ + +char a[2048]; +char b[2048]; +void t (void) +{ + __builtin_memcpy (a, b, 2048); +} diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-2.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-2.c new file mode 100644 index 000000000000..9a6fcfd171b1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ +/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ +/* { dg-final { scan-assembler-not "movdqa" } } */ + +char *a; +char *b; +void t (void) +{ + __builtin_memcpy (a, b, 2048); +} diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-3.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-3.c new file mode 100644 index 000000000000..010ac24d50f8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ +/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:-1:align" } */ +/* { dg-final { scan-assembler-not "movdqa" } } */ + +char a[2048]; +char b[2048]; +void t (void) +{ + __builtin_memcpy (a, b, 2048); +} diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-4.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-4.c new file mode 100644 index 000000000000..87a58ef369a0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-4.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ +/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:3000:align,libcall:-1:align" } */ +/* { dg-final { scan-assembler-not "movdqa" } } */ + +char a[2048]; +char b[2048]; +void t (void) +{ + __builtin_memcpy (a, b, 2048); +} diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-5.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-5.c new file mode 100644 index 000000000000..19e060075cf6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-5.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -mprefer-vector-width=128 -mmemcpy-strategy=vector_loop:2048:noalign,libcall:-1:noalign" } */ + +#define SIZE (16 + 1) * 16 + +char dest[SIZE]; +char src[SIZE]; + +void +foo (void) +{ + __builtin_memcpy (dest, src, SIZE); +} + +/* { dg-final { scan-assembler-times "vmovdqa\[ \t]\+\[^\n\r]*%xmm\[0-9\]\+" 10 } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-6.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-6.c new file mode 100644 index 000000000000..17b101f130ec --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-6.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -mprefer-vector-width=256 -mmemcpy-strategy=vector_loop:2048:noalign,libcall:-1:noalign" } */ + +#define SIZE (16 + 1) * 32 + +char dest[SIZE]; +char src[SIZE]; + +void +foo (void) +{ + __builtin_memcpy (dest, src, SIZE); +} + +/* { dg-final { scan-assembler-times "vmovdqa\[ \t]\+\[^\n\r]*%ymm\[0-9\]\+" 10 } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c b/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c index 6ac80c910533..b29867388928 100644 --- a/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c +++ b/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c @@ -1,6 +1,5 @@ /* { dg-do compile } */ -/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ -/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:-1:align" } */ +/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -mmemcpy-strategy=vector_loop:-1:align" } */ /* { dg-final { scan-assembler-times "movdqa" 8 } } */ char a[2048]; diff --git a/gcc/testsuite/gcc.target/i386/memcpy-strategy-12.c b/gcc/testsuite/gcc.target/i386/memcpy-strategy-12.c new file mode 100644 index 000000000000..c60cef0cd4f8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-strategy-12.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic -mno-sse -fasynchronous-unwind-tables -fdwarf2-cfi-asm" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** movq 221\(%rsi\), %rax +** xorl %edx, %edx +** movq %rax, 221\(%rdi\) +** movq 229\(%rsi\), %rax +** movq %rax, 229\(%rdi\) +** movq 237\(%rsi\), %rax +** movq %rax, 237\(%rdi\) +** movq 245\(%rsi\), %rax +** movq %rax, 245\(%rdi\) +**.L[0-9]+: +** movl %edx, %eax +** addl \$32, %edx +** movq \(%rsi,%rax\), %r10 +** movq 8\(%rsi,%rax\), %r9 +** movq 16\(%rsi,%rax\), %r8 +** movq 24\(%rsi,%rax\), %rcx +** movq %r10, \(%rdi,%rax\) +** movq %r9, 8\(%rdi,%rax\) +** movq %r8, 16\(%rdi,%rax\) +** movq %rcx, 24\(%rdi,%rax\) +** cmpl \$224, %edx +** jb .L[0-9]+ +** ret +**... +*/ + +void +foo (char *dest, char *src) +{ + __builtin_memcpy (dest, src, 253); +} + +/* { dg-final { scan-assembler-not "rep mov" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-strategy-13.c b/gcc/testsuite/gcc.target/i386/memcpy-strategy-13.c new file mode 100644 index 000000000000..109bd675a51b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-strategy-13.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic -mno-avx" } */ +/* { dg-final { scan-assembler "jmp\tmemcpy" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "call\tmemcpy" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "rep movsb" } } */ + +void +foo (char *dest, char *src) +{ + __builtin_memcpy (dest, src, 257); +} diff --git a/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c b/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c index c103896a1106..18e260b0191a 100644 --- a/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c +++ b/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c @@ -1,6 +1,5 @@ /* { dg-do compile } */ -/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ -/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:3000:align,libcall:-1:align" } */ +/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -mmemcpy-strategy=vector_loop:3000:align,libcall:-1:align" } */ /* { dg-final { scan-assembler-times "movdqa" 8 } } */ char a[2048]; diff --git a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c index 93f428acc859..cec8c90e5655 100644 --- a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c +++ b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c @@ -1,6 +1,5 @@ /* { dg-do compile } */ -/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ -/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ +/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -minline-all-stringops -mstringop-strategy=vector_loop" } */ /* { dg-final { scan-assembler-times "movdqa" 8 } } */ char a[2048]; diff --git a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c index ab235401972f..314eb3d5b53e 100644 --- a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c +++ b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c @@ -1,7 +1,6 @@ /* { dg-do compile } */ -/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ -/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ -/* { dg-final { scan-assembler-times "movdqa" 4} } */ +/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -minline-all-stringops -mstringop-strategy=vector_loop" } */ +/* { dg-final { scan-assembler-times "movdqa" 4 } } */ char *a; char *b; diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-1.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-1.c new file mode 100644 index 000000000000..06e3892841e1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-1.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** pxor %xmm0, %xmm0 +** xorl %eax, %eax +** movups %xmm0, 190\(%rdi\) +** movups %xmm0, 206\(%rdi\) +** movups %xmm0, 222\(%rdi\) +** movups %xmm0, 238\(%rdi\) +**.L[0-9]+: +** movl %eax, %edx +** addl \$64, %eax +** movups %xmm0, \(%rdi,%rdx\) +** movups %xmm0, 16\(%rdi,%rdx\) +** movups %xmm0, 32\(%rdi,%rdx\) +** movups %xmm0, 48\(%rdi,%rdx\) +** cmpl \$192, %eax +** jb .L[0-9]+ +** ret +**... +*/ + +void +foo (char *dest) +{ + __builtin_memset (dest, 0, 254); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-10.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-10.c new file mode 100644 index 000000000000..36a924d6079e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-10.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-sse -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=unrolled_loop:256:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** movq \$0, 48\(%rdi\) +** movq \$0, \(%rdi\) +** movq \$0, 8\(%rdi\) +** movq \$0, 16\(%rdi\) +** movq \$0, 24\(%rdi\) +** movq \$0, 32\(%rdi\) +** movq \$0, 40\(%rdi\) +** movq \$0, 53\(%rdi\) +** ret +**... +*/ + +void +foo (char *dest) +{ + __builtin_memset (dest, 0, 61); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-11.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-11.c new file mode 100644 index 000000000000..4868e563bddb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-11.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-sse -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=unrolled_loop:256:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** movabsq \$289360691352306692, %rax +** movq %rax, 48\(%rdi\) +** movq %rax, \(%rdi\) +** movq %rax, 8\(%rdi\) +** movq %rax, 16\(%rdi\) +** movq %rax, 24\(%rdi\) +** movq %rax, 32\(%rdi\) +** movq %rax, 40\(%rdi\) +** movq %rax, 53\(%rdi\) +** ret +**... +*/ + +void +foo (char *dest) +{ + __builtin_memset (dest, 4, 61); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-12.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-12.c new file mode 100644 index 000000000000..91128977fadf --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-12.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-sse -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=unrolled_loop:256:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** movabsq \$72340172838076673, %rax +** movzbl %sil, %esi +** imulq %rax, %rsi +** movq %rsi, 48\(%rdi\) +** movq %rsi, \(%rdi\) +** movq %rsi, 8\(%rdi\) +** movq %rsi, 16\(%rdi\) +** movq %rsi, 24\(%rdi\) +** movq %rsi, 32\(%rdi\) +** movq %rsi, 40\(%rdi\) +** movq %rsi, 53\(%rdi\) +** ret +**... +*/ + +void +foo (char *dest, int c) +{ + __builtin_memset (dest, c, 61); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-13.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-13.c new file mode 100644 index 000000000000..69ec6c6472cf --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-13.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** pxor %xmm0, %xmm0 +** xorl %eax, %eax +**.L[0-9]+: +** movl %eax, %edx +** addl \$64, %eax +** movaps %xmm0, dest\(%rdx\) +** movaps %xmm0, dest\+16\(%rdx\) +** movaps %xmm0, dest\+32\(%rdx\) +** movaps %xmm0, dest\+48\(%rdx\) +** cmpl \$192, %eax +** jb .L[0-9]+ +** movaps %xmm0, dest\(%rax\) +** movaps %xmm0, dest\+16\(%rax\) +** movaps %xmm0, dest\+32\(%rax\) +** ret +**... +*/ + +char dest[240]; + +void +foo (void) +{ + __builtin_memset (dest, 0, sizeof (dest)); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-14.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-14.c new file mode 100644 index 000000000000..209cd679f741 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-14.c @@ -0,0 +1,91 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign -minline-all-stringops" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** pxor %xmm0, %xmm0 +** cmpq \$64, %rsi +** jnb .L2 +** testb \$32, %sil +** jne .L19 +** testb \$16, %sil +** jne .L20 +** testb \$8, %sil +** jne .L21 +** testb \$4, %sil +** jne .L22 +** testq %rsi, %rsi +** jne .L23 +**.L1: +** ret +** .p2align 4,,10 +** .p2align 3 +**.L2: +** movups %xmm0, -64\(%rdi,%rsi\) +** movups %xmm0, -48\(%rdi,%rsi\) +** movups %xmm0, -32\(%rdi,%rsi\) +** movups %xmm0, -16\(%rdi,%rsi\) +** subq \$1, %rsi +** cmpq \$64, %rsi +** jb .L1 +** andq \$-64, %rsi +** xorl %eax, %eax +**.L9: +** movups %xmm0, \(%rdi,%rax\) +** movups %xmm0, 16\(%rdi,%rax\) +** movups %xmm0, 32\(%rdi,%rax\) +** movups %xmm0, 48\(%rdi,%rax\) +** addq \$64, %rax +** cmpq %rsi, %rax +** jb .L9 +** ret +** .p2align 4,,10 +** .p2align 3 +**.L23: +** movb \$0, \(%rdi\) +** testb \$2, %sil +** je .L1 +** xorl %eax, %eax +** movw %ax, -2\(%rdi,%rsi\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L19: +** movups %xmm0, \(%rdi\) +** movups %xmm0, 16\(%rdi\) +** movups %xmm0, -32\(%rdi,%rsi\) +** movups %xmm0, -16\(%rdi,%rsi\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L20: +** movups %xmm0, \(%rdi\) +** movups %xmm0, -16\(%rdi,%rsi\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L21: +** movq \$0, \(%rdi\) +** movq \$0, -8\(%rdi,%rsi\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L22: +** movl \$0, \(%rdi\) +** movl \$0, -4\(%rdi,%rsi\) +** ret +** .cfi_endproc +**... +*/ + +void +foo (char *dest, __SIZE_TYPE__ n) +{ + __builtin_memset (dest, 0, n); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-15.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-15.c new file mode 100644 index 000000000000..d19188f1f457 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-15.c @@ -0,0 +1,103 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v3 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign -minline-all-stringops" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** vpxor %xmm0, %xmm0, %xmm0 +** cmpq \$128, %rsi +** jnb .L2 +** testb \$64, %sil +** jne .L22 +** testb \$32, %sil +** jne .L23 +** testb \$16, %sil +** jne .L24 +** testb \$8, %sil +** jne .L25 +** testb \$4, %sil +** jne .L26 +** testq %rsi, %rsi +** jne .L27 +**.L20: +** ret +** .p2align 4,,10 +** .p2align 3 +**.L2: +** vmovdqu %ymm0, -128\(%rdi,%rsi\) +** vmovdqu %ymm0, -96\(%rdi,%rsi\) +** vmovdqu %ymm0, -64\(%rdi,%rsi\) +** vmovdqu %ymm0, -32\(%rdi,%rsi\) +** subq \$1, %rsi +** cmpq \$128, %rsi +** jb .L19 +** andq \$-128, %rsi +** xorl %eax, %eax +**.L10: +** vmovdqu %ymm0, \(%rdi,%rax\) +** vmovdqu %ymm0, 32\(%rdi,%rax\) +** vmovdqu %ymm0, 64\(%rdi,%rax\) +** vmovdqu %ymm0, 96\(%rdi,%rax\) +** subq \$-128, %rax +** cmpq %rsi, %rax +** jb .L10 +**.L19: +** vzeroupper +** ret +** .p2align 4,,10 +** .p2align 3 +**.L27: +** movb \$0, \(%rdi\) +** testb \$2, %sil +** je .L20 +** xorl %eax, %eax +** movw %ax, -2\(%rdi,%rsi\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L22: +** vmovdqu %ymm0, \(%rdi\) +** vmovdqu %ymm0, 32\(%rdi\) +** vmovdqu %ymm0, -64\(%rdi,%rsi\) +** vmovdqu %ymm0, -32\(%rdi,%rsi\) +** vzeroupper +** ret +** .p2align 4,,10 +** .p2align 3 +**.L23: +** vmovdqu %ymm0, \(%rdi\) +** vmovdqu %ymm0, -32\(%rdi,%rsi\) +** vzeroupper +** ret +** .p2align 4,,10 +** .p2align 3 +**.L24: +** vmovdqu %xmm0, \(%rdi\) +** vmovdqu %xmm0, -16\(%rdi,%rsi\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L25: +** movq \$0, \(%rdi\) +** movq \$0, -8\(%rdi,%rsi\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L26: +** movl \$0, \(%rdi\) +** movl \$0, -4\(%rdi,%rsi\) +** ret +** .cfi_endproc +**... +*/ + +void +foo (char *dest, __SIZE_TYPE__ n) +{ + __builtin_memset (dest, 0, n); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-16.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-16.c new file mode 100644 index 000000000000..539714c2b3d0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-16.c @@ -0,0 +1,112 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign -minline-all-stringops" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** vpxor %xmm0, %xmm0, %xmm0 +** cmpq \$256, %rsi +** jnb .L2 +** testb \$-128, %sil +** jne .L23 +** testb \$64, %sil +** jne .L24 +** testb \$32, %sil +** jne .L25 +** testb \$16, %sil +** jne .L26 +** testb \$8, %sil +** jne .L27 +** testb \$4, %sil +** jne .L28 +** testq %rsi, %rsi +** jne .L29 +**.L21: +** ret +** .p2align 4,,10 +** .p2align 3 +**.L2: +** vmovdqu64 %zmm0, -256\(%rdi,%rsi\) +** vmovdqu64 %zmm0, -192\(%rdi,%rsi\) +** vmovdqu64 %zmm0, -128\(%rdi,%rsi\) +** vmovdqu64 %zmm0, -64\(%rdi,%rsi\) +** subq \$1, %rsi +** cmpq \$256, %rsi +** jb .L20 +** xorb %sil, %sil +** xorl %eax, %eax +**.L11: +** vmovdqu64 %zmm0, \(%rdi,%rax\) +** vmovdqu64 %zmm0, 64\(%rdi,%rax\) +** vmovdqu64 %zmm0, 128\(%rdi,%rax\) +** vmovdqu64 %zmm0, 192\(%rdi,%rax\) +** addq \$256, %rax +** cmpq %rsi, %rax +** jb .L11 +**.L20: +** vzeroupper +** ret +** .p2align 4,,10 +** .p2align 3 +**.L29: +** movb \$0, \(%rdi\) +** testb \$2, %sil +** je .L21 +** xorl %eax, %eax +** movw %ax, -2\(%rdi,%rsi\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L23: +** vmovdqu64 %zmm0, \(%rdi\) +** vmovdqu64 %zmm0, 64\(%rdi\) +** vmovdqu64 %zmm0, -128\(%rdi,%rsi\) +** vmovdqu64 %zmm0, -64\(%rdi,%rsi\) +** vzeroupper +** ret +** .p2align 4,,10 +** .p2align 3 +**.L24: +** vmovdqu64 %zmm0, \(%rdi\) +** vmovdqu64 %zmm0, -64\(%rdi,%rsi\) +** vzeroupper +** ret +** .p2align 4,,10 +** .p2align 3 +**.L25: +** vmovdqu %ymm0, \(%rdi\) +** vmovdqu %ymm0, -32\(%rdi,%rsi\) +** vzeroupper +** ret +** .p2align 4,,10 +** .p2align 3 +**.L26: +** vmovdqu %xmm0, \(%rdi\) +** vmovdqu %xmm0, -16\(%rdi,%rsi\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L27: +** movq \$0, \(%rdi\) +** movq \$0, -8\(%rdi,%rsi\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L28: +** movl \$0, \(%rdi\) +** movl \$0, -4\(%rdi,%rsi\) +** ret +** .cfi_endproc +**... +*/ + +void +foo (char *dest, __SIZE_TYPE__ n) +{ + __builtin_memset (dest, 0, n); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-17.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-17.c new file mode 100644 index 000000000000..f58cb28cff07 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-17.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** pxor %xmm0, %xmm0 +** xorl %eax, %eax +**.L[0-9]+: +** movl %eax, %edx +** addl \$64, %eax +** movaps %xmm0, dest\(%rdx\) +** movaps %xmm0, dest\+16\(%rdx\) +** movaps %xmm0, dest\+32\(%rdx\) +** movaps %xmm0, dest\+48\(%rdx\) +** cmpl \$128, %eax +** jb .L[0-9]+ +** movq \$0, dest\+48\(%rax\) +** movaps %xmm0, dest\(%rax\) +** movaps %xmm0, dest\+16\(%rax\) +** movaps %xmm0, dest\+32\(%rax\) +** ret +**... +*/ + +char dest[184]; + +void +foo (void) +{ + __builtin_memset (dest, 0, sizeof (dest)); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-18.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-18.c new file mode 100644 index 000000000000..a127028d472d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-18.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** pxor %xmm0, %xmm0 +** xorl %eax, %eax +**.L[0-9]+: +** movl %eax, %edx +** addl \$64, %eax +** movaps %xmm0, dest\(%rdx\) +** movaps %xmm0, dest\+16\(%rdx\) +** movaps %xmm0, dest\+32\(%rdx\) +** movaps %xmm0, dest\+48\(%rdx\) +** cmpl \$128, %eax +** jb .L[0-9]+ +** movaps %xmm0, dest\+32\(%rax\) +** movaps %xmm0, dest\(%rax\) +** movl \$0, dest\+47\(%rax\) +** movaps %xmm0, dest\+16\(%rax\) +** ret +**... +*/ + +char dest[179]; + +void +foo (void) +{ + __builtin_memset (dest, 0, sizeof (dest)); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-19.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-19.c new file mode 100644 index 000000000000..8dd5ae6da4a5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-19.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** pxor %xmm0, %xmm0 +** xorl %eax, %eax +**.L[0-9]+: +** movl %eax, %edx +** addl \$64, %eax +** movaps %xmm0, dest\(%rdx\) +** movaps %xmm0, dest\+16\(%rdx\) +** movaps %xmm0, dest\+32\(%rdx\) +** movaps %xmm0, dest\+48\(%rdx\) +** cmpl \$128, %eax +** jb .L[0-9]+ +** movb \$0, dest\+48\(%rax\) +** movaps %xmm0, dest\(%rax\) +** movaps %xmm0, dest\+16\(%rax\) +** movaps %xmm0, dest\+32\(%rax\) +** ret +**... +*/ + +char dest[177]; + +void +foo (void) +{ + __builtin_memset (dest, 0, sizeof (dest)); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-2.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-2.c new file mode 100644 index 000000000000..3b84b29bfd91 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-2.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v3 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** vpxor %xmm0, %xmm0, %xmm0 +** vmovdqu %ymm0, 192\(%rdi\) +** vmovdqu %ymm0, \(%rdi\) +** vmovdqu %ymm0, 32\(%rdi\) +** vmovdqu %ymm0, 64\(%rdi\) +** vmovdqu %ymm0, 96\(%rdi\) +** vmovdqu %ymm0, 128\(%rdi\) +** vmovdqu %ymm0, 160\(%rdi\) +** vmovdqu %ymm0, 222\(%rdi\) +** vzeroupper +** ret +**... +*/ + +void +foo (char *dest) +{ + __builtin_memset (dest, 0, 254); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-20.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-20.c new file mode 100644 index 000000000000..b8b9cb7a4ab8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-20.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** movd %edi, %xmm0 +** punpcklbw %xmm0, %xmm0 +** punpcklwd %xmm0, %xmm0 +** pshufd \$0, %xmm0, %xmm0 +** movaps %xmm0, dest\+160\(%rip\) +** movaps %xmm0, dest\(%rip\) +** movaps %xmm0, dest\+16\(%rip\) +** movaps %xmm0, dest\+32\(%rip\) +** movaps %xmm0, dest\+48\(%rip\) +** movaps %xmm0, dest\+64\(%rip\) +** movaps %xmm0, dest\+80\(%rip\) +** movaps %xmm0, dest\+96\(%rip\) +** movaps %xmm0, dest\+112\(%rip\) +** movaps %xmm0, dest\+128\(%rip\) +** movaps %xmm0, dest\+144\(%rip\) +** movd %xmm0, dest\+175\(%rip\) +** ret +**... +*/ + +char dest[179]; + +void +foo (int c) +{ + __builtin_memset (dest, c, sizeof (dest)); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-21.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-21.c new file mode 100644 index 000000000000..3c7bb7c4fef9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-21.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** movd %edi, %xmm0 +** movb %dil, dest\+176\(%rip\) +** punpcklbw %xmm0, %xmm0 +** punpcklwd %xmm0, %xmm0 +** pshufd \$0, %xmm0, %xmm0 +** movaps %xmm0, dest\(%rip\) +** movaps %xmm0, dest\+16\(%rip\) +** movaps %xmm0, dest\+32\(%rip\) +** movaps %xmm0, dest\+48\(%rip\) +** movaps %xmm0, dest\+64\(%rip\) +** movaps %xmm0, dest\+80\(%rip\) +** movaps %xmm0, dest\+96\(%rip\) +** movaps %xmm0, dest\+112\(%rip\) +** movaps %xmm0, dest\+128\(%rip\) +** movaps %xmm0, dest\+144\(%rip\) +** movaps %xmm0, dest\+160\(%rip\) +** ret +**... +*/ + +char dest[177]; + +void +foo (int c) +{ + __builtin_memset (dest, c, sizeof (dest)); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-22.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-22.c new file mode 100644 index 000000000000..96a21c877ed2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-22.c @@ -0,0 +1,27 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=rep_8byte:8192:align,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** movl \$25, %ecx +** xorl %eax, %eax +** movl \$dest, %edi +** rep stosq +** movl \$0, \(%rdi\) +** ret +**... +*/ + +#define SIZE 204 + +char dest[SIZE]; + +void +foo (void) +{ + __builtin_memset (dest, 0, sizeof (dest)); +} diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-23.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-23.c new file mode 100644 index 000000000000..f3f5d8053016 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-23.c @@ -0,0 +1,67 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -minline-all-stringops -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** movzbl %dil, %edi +** movl \$p, %eax +** movabsq \$72340172838076673, %rdx +** imulq %rdx, %rdi +** movq %rdi, %xmm0 +** punpcklqdq %xmm0, %xmm0 +** cmpq \$64, %rsi +** jnb .L18 +**.L2: +** movq %rsi, %rcx +** andl \$63, %ecx +** je .L1 +** xorl %edx, %edx +** andl \$1, %esi +** je .L5 +** movl \$1, %edx +** movb %dil, \(%rax\) +** cmpq %rcx, %rdx +** jnb .L19 +**.L5: +** movb %dil, \(%rax,%rdx\) +** movb %dil, 1\(%rax,%rdx\) +** addq \$2, %rdx +** cmpq %rcx, %rdx +** jb .L5 +**.L1: +** ret +** .p2align 4,,10 +** .p2align 3 +**.L18: +** movq %rsi, %rdx +** xorl %eax, %eax +** andq \$-64, %rdx +**.L3: +** movaps %xmm0, p\(%rax\) +** addq \$64, %rax +** movaps %xmm0, p-48\(%rax\) +** movaps %xmm0, p-32\(%rax\) +** movaps %xmm0, p-16\(%rax\) +** cmpq %rdx, %rax +** jb .L3 +** addq \$p, %rax +** jmp .L2 +**.L19: +** ret +** .cfi_endproc +**... +*/ + + +#define WRITE_CHUNK 256 +char p[WRITE_CHUNK]; + +void +foo (int c, __SIZE_TYPE__ nbyte) +{ + __builtin_memset (p, c, nbyte); +} diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-3.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-3.c new file mode 100644 index 000000000000..faa47ca34317 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-3.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** vpxor %xmm0, %xmm0, %xmm0 +** vmovdqu8 %zmm0, 128\(%rdi\) +** vmovdqu8 %zmm0, \(%rdi\) +** vmovdqu8 %zmm0, 64\(%rdi\) +** vmovdqu8 %zmm0, 190\(%rdi\) +** vzeroupper +** ret +**... +*/ + +void +foo (char *dest) +{ + __builtin_memset (dest, 0, 254); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-4.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-4.c new file mode 100644 index 000000000000..dc3aa57b2a56 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-4.c @@ -0,0 +1,93 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign -minline-all-stringops" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** movabsq \$289360691352306692, %rax +** movq %rax, %xmm0 +** punpcklqdq %xmm0, %xmm0 +** cmpq \$64, %rsi +** jnb .L2 +** testb \$32, %sil +** jne .L19 +** testb \$16, %sil +** jne .L20 +** testb \$8, %sil +** jne .L21 +** testb \$4, %sil +** jne .L22 +** testq %rsi, %rsi +** jne .L23 +**.L1: +** ret +** .p2align 4,,10 +** .p2align 3 +**.L2: +** movups %xmm0, -64\(%rdi,%rsi\) +** movups %xmm0, -48\(%rdi,%rsi\) +** movups %xmm0, -32\(%rdi,%rsi\) +** movups %xmm0, -16\(%rdi,%rsi\) +** subq \$1, %rsi +** cmpq \$64, %rsi +** jb .L1 +** andq \$-64, %rsi +** xorl %eax, %eax +**.L9: +** movups %xmm0, \(%rdi,%rax\) +** movups %xmm0, 16\(%rdi,%rax\) +** movups %xmm0, 32\(%rdi,%rax\) +** movups %xmm0, 48\(%rdi,%rax\) +** addq \$64, %rax +** cmpq %rsi, %rax +** jb .L9 +** ret +** .p2align 4,,10 +** .p2align 3 +**.L23: +** movb \$4, \(%rdi\) +** testb \$2, %sil +** je .L1 +** movl \$1028, %eax +** movw %ax, -2\(%rdi,%rsi\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L19: +** movups %xmm0, \(%rdi\) +** movups %xmm0, 16\(%rdi\) +** movups %xmm0, -32\(%rdi,%rsi\) +** movups %xmm0, -16\(%rdi,%rsi\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L20: +** movups %xmm0, \(%rdi\) +** movups %xmm0, -16\(%rdi,%rsi\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L21: +** movq %rax, \(%rdi\) +** movq %rax, -8\(%rdi,%rsi\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L22: +** movl \$67372036, \(%rdi\) +** movl \$67372036, -4\(%rdi,%rsi\) +** ret +** .cfi_endproc +**... +*/ + +void +foo (char *dest, __SIZE_TYPE__ n) +{ + __builtin_memset (dest, 4, n); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-5.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-5.c new file mode 100644 index 000000000000..a324f8e5b0ea --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-5.c @@ -0,0 +1,102 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v3 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign -minline-all-stringops" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** movabsq \$289360691352306692, %rax +** vmovq %rax, %xmm1 +** vpbroadcastq %xmm1, %ymm0 +** cmpq \$128, %rsi +** jnb .L2 +** testb \$64, %sil +** jne .L21 +** testb \$32, %sil +** jne .L22 +** testb \$16, %sil +** jne .L23 +** testb \$8, %sil +** jne .L24 +** testb \$4, %sil +** jne .L25 +** testq %rsi, %rsi +** jne .L26 +**.L19: +** vzeroupper +** ret +** .p2align 4,,10 +** .p2align 3 +**.L2: +** vmovdqu %ymm0, -128\(%rdi,%rsi\) +** vmovdqu %ymm0, -96\(%rdi,%rsi\) +** vmovdqu %ymm0, -64\(%rdi,%rsi\) +** vmovdqu %ymm0, -32\(%rdi,%rsi\) +** subq \$1, %rsi +** cmpq \$128, %rsi +** jb .L19 +** andq \$-128, %rsi +** xorl %eax, %eax +**.L10: +** vmovdqu %ymm0, \(%rdi,%rax\) +** vmovdqu %ymm0, 32\(%rdi,%rax\) +** vmovdqu %ymm0, 64\(%rdi,%rax\) +** vmovdqu %ymm0, 96\(%rdi,%rax\) +** subq \$-128, %rax +** cmpq %rsi, %rax +** jb .L10 +** jmp .L19 +** .p2align 4,,10 +** .p2align 3 +**.L26: +** movb \$4, \(%rdi\) +** testb \$2, %sil +** je .L19 +** movl \$1028, %eax +** movw %ax, -2\(%rdi,%rsi\) +** jmp .L19 +** .p2align 4,,10 +** .p2align 3 +**.L21: +** vmovdqu %ymm0, \(%rdi\) +** vmovdqu %ymm0, 32\(%rdi\) +** vmovdqu %ymm0, -64\(%rdi,%rsi\) +** vmovdqu %ymm0, -32\(%rdi,%rsi\) +** jmp .L19 +** .p2align 4,,10 +** .p2align 3 +**.L22: +** vmovdqu %ymm0, \(%rdi\) +** vmovdqu %ymm0, -32\(%rdi,%rsi\) +** jmp .L19 +** .p2align 4,,10 +** .p2align 3 +**.L23: +** vmovdqu %xmm0, \(%rdi\) +** vmovdqu %xmm0, -16\(%rdi,%rsi\) +** jmp .L19 +** .p2align 4,,10 +** .p2align 3 +**.L24: +** movq %rax, \(%rdi\) +** movq %rax, -8\(%rdi,%rsi\) +** jmp .L19 +** .p2align 4,,10 +** .p2align 3 +**.L25: +** movl \$67372036, \(%rdi\) +** movl \$67372036, -4\(%rdi,%rsi\) +** jmp .L19 +** .cfi_endproc +**... +*/ + +void +foo (char *dest, __SIZE_TYPE__ n) +{ + __builtin_memset (dest, 4, n); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-6.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-6.c new file mode 100644 index 000000000000..64e75895232f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-6.c @@ -0,0 +1,109 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign -minline-all-stringops" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** movabsq \$289360691352306692, %rax +** vpbroadcastq %rax, %zmm0 +** cmpq \$256, %rsi +** jnb .L2 +** testb \$-128, %sil +** jne .L22 +** testb \$64, %sil +** jne .L23 +** testb \$32, %sil +** jne .L24 +** testb \$16, %sil +** jne .L25 +** testb \$8, %sil +** jne .L26 +** testb \$4, %sil +** jne .L27 +** testq %rsi, %rsi +** jne .L28 +**.L20: +** vzeroupper +** ret +** .p2align 4,,10 +** .p2align 3 +**.L2: +** vmovdqu64 %zmm0, -256\(%rdi,%rsi\) +** vmovdqu64 %zmm0, -192\(%rdi,%rsi\) +** vmovdqu64 %zmm0, -128\(%rdi,%rsi\) +** vmovdqu64 %zmm0, -64\(%rdi,%rsi\) +** subq \$1, %rsi +** cmpq \$256, %rsi +** jb .L20 +** xorb %sil, %sil +** xorl %eax, %eax +**.L11: +** vmovdqu64 %zmm0, \(%rdi,%rax\) +** vmovdqu64 %zmm0, 64\(%rdi,%rax\) +** vmovdqu64 %zmm0, 128\(%rdi,%rax\) +** vmovdqu64 %zmm0, 192\(%rdi,%rax\) +** addq \$256, %rax +** cmpq %rsi, %rax +** jb .L11 +** jmp .L20 +** .p2align 4,,10 +** .p2align 3 +**.L28: +** movb \$4, \(%rdi\) +** testb \$2, %sil +** je .L20 +** movl \$1028, %eax +** movw %ax, -2\(%rdi,%rsi\) +** jmp .L20 +** .p2align 4,,10 +** .p2align 3 +**.L22: +** vmovdqu64 %zmm0, \(%rdi\) +** vmovdqu64 %zmm0, 64\(%rdi\) +** vmovdqu64 %zmm0, -128\(%rdi,%rsi\) +** vmovdqu64 %zmm0, -64\(%rdi,%rsi\) +** jmp .L20 +** .p2align 4,,10 +** .p2align 3 +**.L23: +** vmovdqu64 %zmm0, \(%rdi\) +** vmovdqu64 %zmm0, -64\(%rdi,%rsi\) +** jmp .L20 +** .p2align 4,,10 +** .p2align 3 +**.L24: +** vmovdqu %ymm0, \(%rdi\) +** vmovdqu %ymm0, -32\(%rdi,%rsi\) +** jmp .L20 +** .p2align 4,,10 +** .p2align 3 +**.L25: +** vmovdqu %xmm0, \(%rdi\) +** vmovdqu %xmm0, -16\(%rdi,%rsi\) +** jmp .L20 +** .p2align 4,,10 +** .p2align 3 +**.L26: +** movq %rax, \(%rdi\) +** movq %rax, -8\(%rdi,%rsi\) +** jmp .L20 +** .p2align 4,,10 +** .p2align 3 +**.L27: +** movl \$67372036, \(%rdi\) +** movl \$67372036, -4\(%rdi,%rsi\) +** jmp .L20 +** .cfi_endproc +**... +*/ + +void +foo (char *dest, __SIZE_TYPE__ n) +{ + __builtin_memset (dest, 4, n); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-7.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-7.c new file mode 100644 index 000000000000..022f6f9a1eb6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-7.c @@ -0,0 +1,94 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign -minline-all-stringops" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** movabsq \$72340172838076673, %rax +** movzbl %sil, %esi +** imulq %rax, %rsi +** movq %rsi, %xmm0 +** punpcklqdq %xmm0, %xmm0 +** cmpq \$64, %rdx +** jnb .L2 +** testb \$32, %dl +** jne .L19 +** testb \$16, %dl +** jne .L20 +** testb \$8, %dl +** jne .L21 +** testb \$4, %dl +** jne .L22 +** testq %rdx, %rdx +** jne .L23 +**.L1: +** ret +** .p2align 4,,10 +** .p2align 3 +**.L2: +** movups %xmm0, -64\(%rdi,%rdx\) +** movups %xmm0, -48\(%rdi,%rdx\) +** movups %xmm0, -32\(%rdi,%rdx\) +** movups %xmm0, -16\(%rdi,%rdx\) +** subq \$1, %rdx +** cmpq \$64, %rdx +** jb .L1 +** andq \$-64, %rdx +** xorl %eax, %eax +**.L9: +** movups %xmm0, \(%rdi,%rax\) +** movups %xmm0, 16\(%rdi,%rax\) +** movups %xmm0, 32\(%rdi,%rax\) +** movups %xmm0, 48\(%rdi,%rax\) +** addq \$64, %rax +** cmpq %rdx, %rax +** jb .L9 +** ret +** .p2align 4,,10 +** .p2align 3 +**.L23: +** movb %sil, \(%rdi\) +** testb \$2, %dl +** je .L1 +** movw %si, -2\(%rdi,%rdx\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L19: +** movups %xmm0, \(%rdi\) +** movups %xmm0, 16\(%rdi\) +** movups %xmm0, -32\(%rdi,%rdx\) +** movups %xmm0, -16\(%rdi,%rdx\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L20: +** movups %xmm0, \(%rdi\) +** movups %xmm0, -16\(%rdi,%rdx\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L21: +** movq %rsi, \(%rdi\) +** movq %rsi, -8\(%rdi,%rdx\) +** ret +** .p2align 4,,10 +** .p2align 3 +**.L22: +** movl %esi, \(%rdi\) +** movl %esi, -4\(%rdi,%rdx\) +** ret +** .cfi_endproc +**... +*/ + +void +foo (char *dest, int c, __SIZE_TYPE__ n) +{ + __builtin_memset (dest, c, n); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-8.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-8.c new file mode 100644 index 000000000000..5254e21fe176 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-8.c @@ -0,0 +1,103 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v3 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign -minline-all-stringops" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** movabsq \$72340172838076673, %rax +** movzbl %sil, %esi +** imulq %rax, %rsi +** vmovq %rsi, %xmm1 +** vpbroadcastq %xmm1, %ymm0 +** cmpq \$128, %rdx +** jnb .L2 +** testb \$64, %dl +** jne .L21 +** testb \$32, %dl +** jne .L22 +** testb \$16, %dl +** jne .L23 +** testb \$8, %dl +** jne .L24 +** testb \$4, %dl +** jne .L25 +** testq %rdx, %rdx +** jne .L26 +**.L19: +** vzeroupper +** ret +** .p2align 4,,10 +** .p2align 3 +**.L2: +** vmovdqu %ymm0, -128\(%rdi,%rdx\) +** vmovdqu %ymm0, -96\(%rdi,%rdx\) +** vmovdqu %ymm0, -64\(%rdi,%rdx\) +** vmovdqu %ymm0, -32\(%rdi,%rdx\) +** subq \$1, %rdx +** cmpq \$128, %rdx +** jb .L19 +** andq \$-128, %rdx +** xorl %eax, %eax +**.L10: +** vmovdqu %ymm0, \(%rdi,%rax\) +** vmovdqu %ymm0, 32\(%rdi,%rax\) +** vmovdqu %ymm0, 64\(%rdi,%rax\) +** vmovdqu %ymm0, 96\(%rdi,%rax\) +** subq \$-128, %rax +** cmpq %rdx, %rax +** jb .L10 +** jmp .L19 +** .p2align 4,,10 +** .p2align 3 +**.L26: +** movb %sil, \(%rdi\) +** testb \$2, %dl +** je .L19 +** movw %si, -2\(%rdi,%rdx\) +** jmp .L19 +** .p2align 4,,10 +** .p2align 3 +**.L21: +** vmovdqu %ymm0, \(%rdi\) +** vmovdqu %ymm0, 32\(%rdi\) +** vmovdqu %ymm0, -64\(%rdi,%rdx\) +** vmovdqu %ymm0, -32\(%rdi,%rdx\) +** jmp .L19 +** .p2align 4,,10 +** .p2align 3 +**.L22: +** vmovdqu %ymm0, \(%rdi\) +** vmovdqu %ymm0, -32\(%rdi,%rdx\) +** jmp .L19 +** .p2align 4,,10 +** .p2align 3 +**.L23: +** vmovdqu %xmm0, \(%rdi\) +** vmovdqu %xmm0, -16\(%rdi,%rdx\) +** jmp .L19 +** .p2align 4,,10 +** .p2align 3 +**.L24: +** movq %rsi, \(%rdi\) +** movq %rsi, -8\(%rdi,%rdx\) +** jmp .L19 +** .p2align 4,,10 +** .p2align 3 +**.L25: +** movl %esi, \(%rdi\) +** movl %esi, -4\(%rdi,%rdx\) +** jmp .L19 +** .cfi_endproc +**... +*/ + +void +foo (char *dest, int c, __SIZE_TYPE__ n) +{ + __builtin_memset (dest, c, n); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120683-9.c b/gcc/testsuite/gcc.target/i386/memset-pr120683-9.c new file mode 100644 index 000000000000..1719de610cac --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120683-9.c @@ -0,0 +1,110 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign -minline-all-stringops" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB0: +** .cfi_startproc +** movabsq \$72340172838076673, %rax +** movzbl %sil, %esi +** imulq %rax, %rsi +** vpbroadcastq %rsi, %zmm0 +** cmpq \$256, %rdx +** jnb .L2 +** testb \$-128, %dl +** jne .L22 +** testb \$64, %dl +** jne .L23 +** testb \$32, %dl +** jne .L24 +** testb \$16, %dl +** jne .L25 +** testb \$8, %dl +** jne .L26 +** testb \$4, %dl +** jne .L27 +** testq %rdx, %rdx +** jne .L28 +**.L20: +** vzeroupper +** ret +** .p2align 4,,10 +** .p2align 3 +**.L2: +** vmovdqu64 %zmm0, -256\(%rdi,%rdx\) +** vmovdqu64 %zmm0, -192\(%rdi,%rdx\) +** vmovdqu64 %zmm0, -128\(%rdi,%rdx\) +** vmovdqu64 %zmm0, -64\(%rdi,%rdx\) +** subq \$1, %rdx +** cmpq \$256, %rdx +** jb .L20 +** xorb %dl, %dl +** xorl %eax, %eax +**.L11: +** vmovdqu64 %zmm0, \(%rdi,%rax\) +** vmovdqu64 %zmm0, 64\(%rdi,%rax\) +** vmovdqu64 %zmm0, 128\(%rdi,%rax\) +** vmovdqu64 %zmm0, 192\(%rdi,%rax\) +** addq \$256, %rax +** cmpq %rdx, %rax +** jb .L11 +** jmp .L20 +** .p2align 4,,10 +** .p2align 3 +**.L28: +** movb %sil, \(%rdi\) +** testb \$2, %dl +** je .L20 +** movw %si, -2\(%rdi,%rdx\) +** jmp .L20 +** .p2align 4,,10 +** .p2align 3 +**.L22: +** vmovdqu64 %zmm0, \(%rdi\) +** vmovdqu64 %zmm0, 64\(%rdi\) +** vmovdqu64 %zmm0, -128\(%rdi,%rdx\) +** vmovdqu64 %zmm0, -64\(%rdi,%rdx\) +** jmp .L20 +** .p2align 4,,10 +** .p2align 3 +**.L23: +** vmovdqu64 %zmm0, \(%rdi\) +** vmovdqu64 %zmm0, -64\(%rdi,%rdx\) +** jmp .L20 +** .p2align 4,,10 +** .p2align 3 +**.L24: +** vmovdqu %ymm0, \(%rdi\) +** vmovdqu %ymm0, -32\(%rdi,%rdx\) +** jmp .L20 +** .p2align 4,,10 +** .p2align 3 +**.L25: +** vmovdqu %xmm0, \(%rdi\) +** vmovdqu %xmm0, -16\(%rdi,%rdx\) +** jmp .L20 +** .p2align 4,,10 +** .p2align 3 +**.L26: +** movq %rsi, \(%rdi\) +** movq %rsi, -8\(%rdi,%rdx\) +** jmp .L20 +** .p2align 4,,10 +** .p2align 3 +**.L27: +** movl %esi, \(%rdi\) +** movl %esi, -4\(%rdi,%rdx\) +** jmp .L20 +** .cfi_endproc +**... +*/ + +void +foo (char *dest, int c, __SIZE_TYPE__ n) +{ + __builtin_memset (dest, c, n); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120708-1.c b/gcc/testsuite/gcc.target/i386/memset-pr120708-1.c new file mode 100644 index 000000000000..fba05883db5c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120708-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -mprefer-vector-width=128 -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */ + +void +foo (char *dest) +{ + __builtin_memset (dest, 0, 254); +} + +/* { dg-final { scan-assembler "vmovdqu\[ \t]\+%xmm\[0-9\]+, \\(\[^\n\r]*\\)" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120708-2.c b/gcc/testsuite/gcc.target/i386/memset-pr120708-2.c new file mode 100644 index 000000000000..d9a3e7ebc673 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120708-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -mprefer-vector-width=256 -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */ + +void +foo (char *dest) +{ + __builtin_memset (dest, 0, 254); +} + +/* { dg-final { scan-assembler "vmovdqu\[ \t]\+%ymm\[0-9\]+, \\(\[^\n\r]*\\)" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr70308-1a.c b/gcc/testsuite/gcc.target/i386/memset-pr70308-1a.c new file mode 100644 index 000000000000..5cc4eee11920 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr70308-1a.c @@ -0,0 +1,46 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** subq \$16, %rsp +** .cfi_def_cfa_offset 24 +** pxor %xmm0, %xmm0 +** movaps %xmm0, -120\(%rsp\) +** movaps %xmm0, -104\(%rsp\) +** movaps %xmm0, -88\(%rsp\) +** movaps %xmm0, -72\(%rsp\) +** movaps %xmm0, -56\(%rsp\) +** movaps %xmm0, -40\(%rsp\) +** movaps %xmm0, -24\(%rsp\) +** movaps %xmm0, -8\(%rsp\) +** xorl %eax, %eax +** addq \$16, %rsp +** .cfi_def_cfa_offset 8 +** ret +**... +*/ + +extern int scanf (const char *, ...); +extern void *memset (void *, int, __SIZE_TYPE__); + +int +foo (void) +{ + char buf[128]; + +#if USE_SCANF + if (scanf("%s", buf) != 1) + return 42; +#endif + + memset (buf,0, sizeof (buf)); + asm volatile("": : :"memory"); + return 0; +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr70308-1b.c b/gcc/testsuite/gcc.target/i386/memset-pr70308-1b.c new file mode 100644 index 000000000000..15996ea4e2cd --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr70308-1b.c @@ -0,0 +1,61 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -fasynchronous-unwind-tables -fdwarf2-cfi-asm -fomit-frame-pointer -DUSE_SCANF" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** subq \$136, %rsp +** .cfi_def_cfa_offset 144 +** xorl %eax, %eax +** movl \$.LC[0-9]+, %edi +** movq %rsp, %rsi +** call scanf +** cmpl \$1, %eax +** je .L[0-9]+ +** movl \$42, %eax +** addq \$136, %rsp +** .cfi_remember_state +** .cfi_def_cfa_offset 8 +** ret +** .p2align 4,,10 +** .p2align 3 +**.L[0-9]+: +** .cfi_restore_state +** pxor %xmm0, %xmm0 +** movaps %xmm0, \(%rsp\) +** movaps %xmm0, 16\(%rsp\) +** movaps %xmm0, 32\(%rsp\) +** movaps %xmm0, 48\(%rsp\) +** movaps %xmm0, 64\(%rsp\) +** movaps %xmm0, 80\(%rsp\) +** movaps %xmm0, 96\(%rsp\) +** movaps %xmm0, 112\(%rsp\) +** xorl %eax, %eax +** addq \$136, %rsp +** .cfi_def_cfa_offset 8 +** ret +**... +*/ + +extern int scanf (const char *, ...); +extern void *memset (void *, int, __SIZE_TYPE__); + +int +foo (void) +{ + char buf[128]; + +#if USE_SCANF + if (scanf("%s", buf) != 1) + return 42; +#endif + + memset (buf,0, sizeof (buf)); + asm volatile("": : :"memory"); + return 0; +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-strategy-25.c b/gcc/testsuite/gcc.target/i386/memset-strategy-25.c new file mode 100644 index 000000000000..7bd5d43c8cd5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-strategy-25.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic -mno-sse -fasynchronous-unwind-tables -fdwarf2-cfi-asm" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** movq \$0, 221\(%rdi\) +** xorl %eax, %eax +** movq \$0, 229\(%rdi\) +** movq \$0, 237\(%rdi\) +** movq \$0, 245\(%rdi\) +**.L[0-9]+: +** movl %eax, %edx +** addl \$32, %eax +** movq \$0, \(%rdi,%rdx\) +** movq \$0, 8\(%rdi,%rdx\) +** movq \$0, 16\(%rdi,%rdx\) +** movq \$0, 24\(%rdi,%rdx\) +** cmpl \$224, %eax +** jb .L[0-9]+ +** ret +**... +*/ + +void +foo (char *dest) +{ + __builtin_memset (dest, 0, 253); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-strategy-26.c b/gcc/testsuite/gcc.target/i386/memset-strategy-26.c new file mode 100644 index 000000000000..c53bce52e178 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-strategy-26.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic -mno-sse" } */ +/* { dg-final { scan-assembler-not "jmp\tmemset" } } */ +/* { dg-final { scan-assembler-not "rep stosb" } } */ + +struct foo +{ + char buf[41]; +}; + +void +zero(struct foo *f) +{ + __builtin_memset(f->buf, 0, sizeof(f->buf)); +} diff --git a/gcc/testsuite/gcc.target/i386/memset-strategy-27.c b/gcc/testsuite/gcc.target/i386/memset-strategy-27.c new file mode 100644 index 000000000000..685d6e5a5c21 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-strategy-27.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic -mno-avx" } */ +/* { dg-final { scan-assembler "jmp\tmemset" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "call\tmemset" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "rep stosb" } } */ + +void +foo (char *dest) +{ + __builtin_memset (dest, 0, 257); +} diff --git a/gcc/testsuite/gcc.target/i386/memset-strategy-28.c b/gcc/testsuite/gcc.target/i386/memset-strategy-28.c new file mode 100644 index 000000000000..eef113fa366b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-strategy-28.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic -mno-sse -fasynchronous-unwind-tables -fdwarf2-cfi-asm" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +** .cfi_startproc +** movq \$0, \(%rdi\) +** movq \$0, 8\(%rdi\) +** movq \$0, 16\(%rdi\) +** movq \$0, 24\(%rdi\) +** movq \$0, 32\(%rdi\) +** movq \$0, 40\(%rdi\) +** movq \$0, 48\(%rdi\) +** movq \$0, 56\(%rdi\) +** movb \$0, 64\(%rdi\) +** ret +**... +*/ + +void +foo (char *dest) +{ + __builtin_memset (dest, 0, 65); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-strategy-29.c b/gcc/testsuite/gcc.target/i386/memset-strategy-29.c new file mode 100644 index 000000000000..a33bf9232c09 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-strategy-29.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic -mno-sse -fasynchronous-unwind-tables -fdwarf2-cfi-asm" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**... +**.LFB[0-9]+: +** .cfi_startproc +** movq \$0, 49\(%rdi\) +** xorl %eax, %eax +** movq \$0, 57\(%rdi\) +** movq \$0, 65\(%rdi\) +** movq \$0, 73\(%rdi\) +**.L[0-9]+: +** movl %eax, %edx +** addl \$32, %eax +** movq \$0, \(%rdi,%rdx\) +** movq \$0, 8\(%rdi,%rdx\) +** movq \$0, 16\(%rdi,%rdx\) +** movq \$0, 24\(%rdi,%rdx\) +** cmpl \$64, %eax +** jb .L[0-9]+ +** ret +**... +*/ + +void +foo (char *dest) +{ + __builtin_memset (dest, 0, 81); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-strategy-30.c b/gcc/testsuite/gcc.target/i386/memset-strategy-30.c new file mode 100644 index 000000000000..f3912f8c03b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-strategy-30.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic -mno-sse -fasynchronous-unwind-tables -fdwarf2-cfi-asm" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**... +**.LFB[0-9]+: +** .cfi_startproc +** movq \$0, 63\(%rdi\) +** xorl %eax, %eax +** movq \$0, 71\(%rdi\) +** movq \$0, 79\(%rdi\) +** movq \$0, 87\(%rdi\) +**.L[0-9]+: +** movl %eax, %edx +** addl \$32, %eax +** movq \$0, \(%rdi,%rdx\) +** movq \$0, 8\(%rdi,%rdx\) +** movq \$0, 16\(%rdi,%rdx\) +** movq \$0, 24\(%rdi,%rdx\) +** cmpl \$64, %eax +** jb .L[0-9]+ +** ret +**... +*/ + +void +foo (char *dest) +{ + __builtin_memset (dest, 0, 95); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-strategy-31.c b/gcc/testsuite/gcc.target/i386/memset-strategy-31.c new file mode 100644 index 000000000000..4791c4dd17c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-strategy-31.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic -mno-avx -msse2" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +**... +** pxor %xmm0, %xmm0 +** xorl %eax, %eax +** movups %xmm0, 190\(%rdi\) +** movups %xmm0, 206\(%rdi\) +** movups %xmm0, 222\(%rdi\) +** movups %xmm0, 238\(%rdi\) +**.L[0-9]+: +** movl %eax, %edx +** addl \$64, %eax +** movups %xmm0, \(%rdi,%rdx\) +** movups %xmm0, 16\(%rdi,%rdx\) +** movups %xmm0, 32\(%rdi,%rdx\) +** movups %xmm0, 48\(%rdi,%rdx\) +** cmpl \$192, %eax +** jb .L[0-9]+ +**... +*/ + +void +foo (char *dest) +{ + __builtin_memset (dest, 0, 254); +} + +/* { dg-final { scan-assembler-not "rep stos" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c b/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c index d6fdc9819081..5bb30a844eab 100644 --- a/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c +++ b/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c @@ -1,6 +1,5 @@ /* { dg-do compile } */ -/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ -/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ +/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -minline-all-stringops -mstringop-strategy=vector_loop" } */ /* { dg-final { scan-assembler-times "movdqa" 4 } } */ char a[2048]; diff --git a/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c b/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c index bce8be0ffae2..6e31070ee86c 100644 --- a/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c +++ b/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c @@ -1,6 +1,5 @@ /* { dg-do compile } */ -/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ -/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ +/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -mstringop-strategy=vector_loop" } */ /* { dg-final { scan-assembler-times "movdqa" 4} } */ char *a; diff --git a/gcc/testsuite/gcc.target/i386/mvc17.c b/gcc/testsuite/gcc.target/i386/mvc17.c index 8b83c1aecb36..dbf35ac36dc4 100644 --- a/gcc/testsuite/gcc.target/i386/mvc17.c +++ b/gcc/testsuite/gcc.target/i386/mvc17.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ /* { dg-require-ifunc "" } */ /* { dg-options "-O2 -march=x86-64" } */ -/* { dg-final { scan-assembler-times "rep mov" 1 } } */ +/* { dg-final { scan-assembler-not "rep mov" } } */ __attribute__((target_clones("default","arch=icelake-server"))) void diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-1.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-1.c index 599c2a3fa191..e535485b1cf3 100644 --- a/gcc/testsuite/gcc.target/i386/no-callee-saved-1.c +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-1.c @@ -26,5 +26,7 @@ foo (void *frame) } } -/* { dg-final { scan-assembler-not "push" } } */ -/* { dg-final { scan-assembler-not "pop" } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*" 1 } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-10.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-10.c index 87766c6cd886..6c54144350e6 100644 --- a/gcc/testsuite/gcc.target/i386/no-callee-saved-10.c +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-10.c @@ -18,7 +18,7 @@ foo (void) /* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ /* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)cx" 1 } } */ /* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)dx" 1 } } */ -/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ /* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)si" 1 } } */ /* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)di" 1 } } */ /* { dg-final { scan-assembler-times "pushq\[\\t \]*%r8" 1 { target { ! ia32 } } } } */ @@ -33,7 +33,7 @@ foo (void) /* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ /* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)cx" 1 } } */ /* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)dx" 1 } } */ -/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ /* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)si" 1 } } */ /* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)di" 1 } } */ /* { dg-final { scan-assembler-times "popq\[\\t \]*%r8" 1 { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-18.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-18.c index e7101009be47..128b9c46e8ec 100644 --- a/gcc/testsuite/gcc.target/i386/no-callee-saved-18.c +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-18.c @@ -19,7 +19,7 @@ foo (uintptr_t p) /* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ /* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ /* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ -/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ /* { dg-final { scan-assembler-times "pushl\[\\t \]*%esi" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-not "pushq\[\\t \]*%rsi" { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "pushl\[\\t \]*%edi" 1 { target ia32 } } } */ @@ -36,7 +36,7 @@ foo (uintptr_t p) /* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ /* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ /* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ -/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ /* { dg-final { scan-assembler-times "popl\[\\t \]*%esi" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-not "popq\[\\t \]*%rsi" { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "popl\[\\t \]*%edi" 1 { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-19a.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-19a.c new file mode 100644 index 000000000000..12f35cfa8bba --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-19a.c @@ -0,0 +1,164 @@ +/* { dg-do compile { target { *-*-linux* && lp64 } } } */ +/* { dg-options "-O2 -fno-pic -mtune=generic -msse2 -mno-apxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* end must be empty. */ + +/* +**end: +**.LFB[0-9]+: +** .cfi_startproc +** ret +** .cfi_endproc +**... +*/ + +#define NEXT { op_t *op = next; [[gnu::musttail]] return (*op)(op + 1); } +#ifdef __x86_64__ +# define CLOBBER asm("" ::: "r12","r13","r14","r15","rbx") +#else +# define CLOBBER asm("" ::: "ebx") +#endif +#define DONT_SAVE_REGS __attribute__((no_callee_saved_registers)) +#define SAVE_REGS __attribute__((no_caller_saved_registers)) + +typedef DONT_SAVE_REGS void (*op_t)(void *next); + +extern int accumulator; + +static DONT_SAVE_REGS void end(void *next) +{ +} + +/* inc doesn't have any callee saved registers. */ + +/* +**inc: +**.LFB[0-9]+: +** .cfi_startproc +** addl \$1, accumulator\(%rip\) +** movq \(%rdi\), %rax +** addq \$8, %rdi +** jmp \*%rax +** .cfi_endproc +**... +*/ + +static DONT_SAVE_REGS void inc(void *next) +{ + accumulator += 1; + CLOBBER; + NEXT; +} + +/* dec doesn't have any callee saved registers. */ + +/* +**dec: +**.LFB[0-9]+: +** .cfi_startproc +** subl \$1, accumulator\(%rip\) +** movq \(%rdi\), %rax +** addq \$8, %rdi +** jmp \*%rax +** .cfi_endproc +**... +*/ + +static DONT_SAVE_REGS void dec(void *next) +{ + accumulator -= 1; + CLOBBER; + NEXT; +} + +op_t code[] = { inc, inc, dec, end, }; + +/* start must save and restore all caller saved registers. */ + +/* +**start: +**.LFB[0-9]+: +** .cfi_startproc +** subq \$376, %rsp +**... +** movq %rdi, 304\(%rsp\) +**... +** movl \$code\+8, %edi +** movq %rax, 264\(%rsp\) +** movq %rdx, 272\(%rsp\) +** movq %rcx, 280\(%rsp\) +** movq %rbx, 288\(%rsp\) +** movq %rsi, 296\(%rsp\) +** movq %r8, 312\(%rsp\) +** movq %r9, 320\(%rsp\) +** movq %r10, 328\(%rsp\) +** movq %r11, 336\(%rsp\) +** movq %r12, 344\(%rsp\) +** movq %r13, 352\(%rsp\) +** movq %r14, 360\(%rsp\) +** movq %r15, 368\(%rsp\) +** movaps %xmm0, \(%rsp\) +** movaps %xmm1, 16\(%rsp\) +** movaps %xmm2, 32\(%rsp\) +** movaps %xmm3, 48\(%rsp\) +** movaps %xmm4, 64\(%rsp\) +** movaps %xmm5, 80\(%rsp\) +** movaps %xmm6, 96\(%rsp\) +** movaps %xmm7, 112\(%rsp\) +** movaps %xmm8, 128\(%rsp\) +** movaps %xmm9, 144\(%rsp\) +** movaps %xmm10, 160\(%rsp\) +** movaps %xmm11, 176\(%rsp\) +** movaps %xmm12, 192\(%rsp\) +** movaps %xmm13, 208\(%rsp\) +** movaps %xmm14, 224\(%rsp\) +** movaps %xmm15, 240\(%rsp\) +**... +** call \*code\(%rip\) +** movaps \(%rsp\), %xmm0 +** movaps 16\(%rsp\), %xmm1 +** movaps 32\(%rsp\), %xmm2 +** movaps 48\(%rsp\), %xmm3 +** movaps 64\(%rsp\), %xmm4 +** movaps 80\(%rsp\), %xmm5 +** movaps 96\(%rsp\), %xmm6 +** movaps 112\(%rsp\), %xmm7 +** movaps 128\(%rsp\), %xmm8 +** movaps 144\(%rsp\), %xmm9 +** movaps 160\(%rsp\), %xmm10 +** movaps 176\(%rsp\), %xmm11 +** movaps 192\(%rsp\), %xmm12 +** movaps 208\(%rsp\), %xmm13 +** movq 264\(%rsp\), %rax +** movq 272\(%rsp\), %rdx +** movq 280\(%rsp\), %rcx +** movq 288\(%rsp\), %rbx +** movq 296\(%rsp\), %rsi +** movq 304\(%rsp\), %rdi +** movq 312\(%rsp\), %r8 +** movq 320\(%rsp\), %r9 +** movq 328\(%rsp\), %r10 +** movq 336\(%rsp\), %r11 +** movq 344\(%rsp\), %r12 +** movq 352\(%rsp\), %r13 +** movq 360\(%rsp\), %r14 +** movq 368\(%rsp\), %r15 +** movaps 224\(%rsp\), %xmm14 +** movaps 240\(%rsp\), %xmm15 +** addq \$376, %rsp +**... +** ret +** .cfi_endproc +**... +*/ + +/* This function should have normal ABI to interoperate with others */ +SAVE_REGS void start() +{ + void *next = code; + + // musttail doesn't work here because the registers need to be restored + code[0](code + 1); +} diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-19b.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-19b.c new file mode 100644 index 000000000000..c9343a654702 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-19b.c @@ -0,0 +1,129 @@ +/* { dg-do compile { target { *-*-linux* && maybe_x32 } } } */ +/* { dg-options "-O2 -mx32 -fno-pic -mtune=generic -msse2 -mno-apxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* end must be empty. */ + +/* +**end: +**.LFB[0-9]+: +** .cfi_startproc +** ret +** .cfi_endproc +**... +*/ + +/* inc doesn't have any callee saved registers. */ + +/* +**inc: +**.LFB[0-9]+: +** .cfi_startproc +** addl \$1, accumulator\(%rip\) +** movq %rdi, %rax +** movl \(%eax\), %eax +** leal 4\(%rdi\), %edi +** jmp \*%rax +** .cfi_endproc +**... +*/ + +/* dec doesn't have any callee saved registers. */ + +/* +**dec: +**.LFB[0-9]+: +** .cfi_startproc +** subl \$1, accumulator\(%rip\) +** movq %rdi, %rax +** movl \(%eax\), %eax +** leal 4\(%rdi\), %edi +** jmp \*%rax +** .cfi_endproc +**... +*/ + +/* start must save and restore all caller saved registers. */ + +/* +**start: +**.LFB[0-9]+: +** .cfi_startproc +** subl \$376, %esp +**... +** movq %rax, 256\(%rsp\) +** movq %rdx, 264\(%rsp\) +** movq %rcx, 272\(%rsp\) +** movq %rbx, 280\(%rsp\) +** movq %rsi, 288\(%rsp\) +** movq %rdi, 296\(%rsp\) +**... +** movl \$code\+4, %edi +** movq %rbp, 304\(%rsp\) +** movq %r8, 312\(%rsp\) +** movq %r9, 320\(%rsp\) +** movq %r10, 328\(%rsp\) +** movq %r11, 336\(%rsp\) +** movq %r12, 344\(%rsp\) +** movq %r13, 352\(%rsp\) +** movq %r14, 360\(%rsp\) +** movq %r15, 368\(%rsp\) +** movaps %xmm0, \(%rsp\) +** movaps %xmm1, 16\(%rsp\) +** movaps %xmm2, 32\(%rsp\) +** movaps %xmm3, 48\(%rsp\) +** movaps %xmm4, 64\(%rsp\) +** movaps %xmm5, 80\(%rsp\) +** movaps %xmm6, 96\(%rsp\) +** movaps %xmm7, 112\(%rsp\) +** movaps %xmm8, 128\(%rsp\) +** movaps %xmm9, 144\(%rsp\) +** movaps %xmm10, 160\(%rsp\) +** movaps %xmm11, 176\(%rsp\) +** movaps %xmm12, 192\(%rsp\) +** movaps %xmm13, 208\(%rsp\) +** movaps %xmm14, 224\(%rsp\) +** movaps %xmm15, 240\(%rsp\) +**... +** movl code\(%rip\), %ebp +** call \*%rbp +** movaps \(%rsp\), %xmm0 +** movaps 16\(%rsp\), %xmm1 +** movaps 32\(%rsp\), %xmm2 +** movaps 48\(%rsp\), %xmm3 +** movaps 64\(%rsp\), %xmm4 +** movaps 80\(%rsp\), %xmm5 +** movaps 96\(%rsp\), %xmm6 +** movaps 112\(%rsp\), %xmm7 +** movaps 128\(%rsp\), %xmm8 +** movaps 144\(%rsp\), %xmm9 +** movaps 160\(%rsp\), %xmm10 +** movaps 176\(%rsp\), %xmm11 +** movaps 192\(%rsp\), %xmm12 +** movaps 208\(%rsp\), %xmm13 +** movaps 224\(%rsp\), %xmm14 +** movaps 240\(%rsp\), %xmm15 +** movq 256\(%rsp\), %rax +** movq 264\(%rsp\), %rdx +** movq 272\(%rsp\), %rcx +** movq 280\(%rsp\), %rbx +** movq 288\(%rsp\), %rsi +** movq 296\(%rsp\), %rdi +** movq 304\(%rsp\), %rbp +** movq 312\(%rsp\), %r8 +** movq 320\(%rsp\), %r9 +** movq 328\(%rsp\), %r10 +** movq 336\(%rsp\), %r11 +** movq 344\(%rsp\), %r12 +** movq 352\(%rsp\), %r13 +** movq 360\(%rsp\), %r14 +** movq 368\(%rsp\), %r15 +** addl \$376, %esp +**... +** ret +** .cfi_endproc +**... +*/ + +#include "no-callee-saved-19a.c" diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-19c.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-19c.c new file mode 100644 index 000000000000..05aca9f4b119 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-19c.c @@ -0,0 +1,92 @@ +/* { dg-do compile { target { *-*-linux* && ia32 } } } */ +/* { dg-options "-O2 -fno-pic -mtune=generic -msse2 -mtune-ctrl=prologue_using_move,epilogue_using_move" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* end must be empty. */ + +/* +**end: +**.LFB[0-9]+: +** .cfi_startproc +** ret +** .cfi_endproc +**... +*/ + +/* inc doesn't have any callee saved registers. */ + +/* +**inc: +**.LFB[0-9]+: +** .cfi_startproc +** addl \$1, accumulator +** movl 4\(%esp\), %eax +** leal 4\(%eax\), %edx +** movl %edx, 4\(%esp\) +** jmp \*\(%eax\) +** .cfi_endproc +**... +*/ + +/* dec doesn't have any callee saved registers. */ + +/* +**dec: +**.LFB[0-9]+: +** .cfi_startproc +** subl \$1, accumulator +** movl 4\(%esp\), %eax +** leal 4\(%eax\), %edx +** movl %edx, 4\(%esp\) +** jmp \*\(%eax\) +** .cfi_endproc +**... +*/ + +/* start must save and restore all caller saved registers. */ + +/* +**start: +**.LFB[0-9]+: +** .cfi_startproc +**... +** movl %eax, 144\(%esp\) +** movl %edx, 148\(%esp\) +** movl %ecx, 152\(%esp\) +** movl %ebx, 156\(%esp\) +** movl %esi, 160\(%esp\) +** movl %edi, 164\(%esp\) +** movaps %xmm0, 12\(%esp\) +** movaps %xmm1, 28\(%esp\) +** movaps %xmm2, 44\(%esp\) +** movaps %xmm3, 60\(%esp\) +** movaps %xmm4, 76\(%esp\) +** movaps %xmm5, 92\(%esp\) +** movaps %xmm6, 108\(%esp\) +** movaps %xmm7, 124\(%esp\) +**... +** pushl \$code\+4 +**... +** call \*code +** movaps 16\(%esp\), %xmm0 +** movaps 32\(%esp\), %xmm1 +** movaps 48\(%esp\), %xmm2 +** movaps 64\(%esp\), %xmm3 +** movaps 80\(%esp\), %xmm4 +** movaps 96\(%esp\), %xmm5 +** movaps 112\(%esp\), %xmm6 +** movaps 128\(%esp\), %xmm7 +** movl 148\(%esp\), %eax +** movl 152\(%esp\), %edx +** movl 156\(%esp\), %ecx +** movl 160\(%esp\), %ebx +** movl 164\(%esp\), %esi +** movl 168\(%esp\), %edi +**... +** ret +** .cfi_endproc +**... +*/ + +#include "no-callee-saved-19a.c" diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-19d.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-19d.c new file mode 100644 index 000000000000..b3caa3d81b2d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-19d.c @@ -0,0 +1,157 @@ +/* { dg-do compile { target { *-*-linux* && lp64 } } } */ +/* { dg-options "-O2 -fno-pic -mtune=generic -msse2 -mapxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* end must be empty. */ + +/* +**end: +**.LFB[0-9]+: +** .cfi_startproc +** ret +** .cfi_endproc +**... +*/ + +/* inc doesn't have any callee saved registers. */ + +/* +**inc: +**.LFB[0-9]+: +** .cfi_startproc +** addl \$1, accumulator\(%rip\) +** movq \(%rdi\), %rax +** addq \$8, %rdi +** jmp \*%rax +** .cfi_endproc +**... +*/ + +/* dec doesn't have any callee saved registers. */ + +/* +**dec: +**.LFB[0-9]+: +** .cfi_startproc +** subl \$1, accumulator\(%rip\) +** movq \(%rdi\), %rax +** addq \$8, %rdi +** jmp \*%rax +** .cfi_endproc +**... +*/ + +/* start must save and restore all caller saved registers. */ + +/* +**start: +**.LFB[0-9]+: +** .cfi_startproc +** subq \$504, %rsp +**... +** movq %rax, 264\(%rsp\) +** movq %rdx, 272\(%rsp\) +** movq %rcx, 280\(%rsp\) +** movq %rbx, 288\(%rsp\) +** movq %rsi, 296\(%rsp\) +** movq %rdi, 304\(%rsp\) +**... +** movl \$code\+8, %edi +** movq %r8, 312\(%rsp\) +** movq %r9, 320\(%rsp\) +** movq %r10, 328\(%rsp\) +** movq %r11, 336\(%rsp\) +** movq %r12, 344\(%rsp\) +** movq %r13, 352\(%rsp\) +** movq %r14, 360\(%rsp\) +** movq %r15, 368\(%rsp\) +** movq %r16, 376\(%rsp\) +** movq %r17, 384\(%rsp\) +** movq %r18, 392\(%rsp\) +** movq %r19, 400\(%rsp\) +** movq %r20, 408\(%rsp\) +** movq %r21, 416\(%rsp\) +** movq %r22, 424\(%rsp\) +** movq %r23, 432\(%rsp\) +** movq %r24, 440\(%rsp\) +** movq %r25, 448\(%rsp\) +** movq %r26, 456\(%rsp\) +** movq %r27, 464\(%rsp\) +** movq %r28, 472\(%rsp\) +** movq %r29, 480\(%rsp\) +** movq %r30, 488\(%rsp\) +** movq %r31, 496\(%rsp\) +**... +** movaps %xmm0, \(%rsp\) +** movaps %xmm1, 16\(%rsp\) +** movaps %xmm2, 32\(%rsp\) +** movaps %xmm3, 48\(%rsp\) +** movaps %xmm4, 64\(%rsp\) +** movaps %xmm5, 80\(%rsp\) +** movaps %xmm6, 96\(%rsp\) +** movaps %xmm7, 112\(%rsp\) +** movaps %xmm8, 128\(%rsp\) +** movaps %xmm9, 144\(%rsp\) +** movaps %xmm10, 160\(%rsp\) +** movaps %xmm11, 176\(%rsp\) +** movaps %xmm12, 192\(%rsp\) +** movaps %xmm13, 208\(%rsp\) +** movaps %xmm14, 224\(%rsp\) +** movaps %xmm15, 240\(%rsp\) +**... +** call \*code\(%rip\) +** movaps \(%rsp\), %xmm0 +** movaps 16\(%rsp\), %xmm1 +** movaps 32\(%rsp\), %xmm2 +** movaps 48\(%rsp\), %xmm3 +** movaps 64\(%rsp\), %xmm4 +** movaps 80\(%rsp\), %xmm5 +** movaps 96\(%rsp\), %xmm6 +** movaps 112\(%rsp\), %xmm7 +** movaps 128\(%rsp\), %xmm8 +** movaps 144\(%rsp\), %xmm9 +** movaps 160\(%rsp\), %xmm10 +** movaps 176\(%rsp\), %xmm11 +** movaps 192\(%rsp\), %xmm12 +** movaps 208\(%rsp\), %xmm13 +** movq 264\(%rsp\), %rax +** movq 272\(%rsp\), %rdx +** movq 280\(%rsp\), %rcx +** movq 288\(%rsp\), %rbx +** movq 296\(%rsp\), %rsi +** movq 304\(%rsp\), %rdi +** movq 312\(%rsp\), %r8 +** movq 320\(%rsp\), %r9 +** movq 328\(%rsp\), %r10 +** movq 336\(%rsp\), %r11 +** movq 344\(%rsp\), %r12 +** movq 352\(%rsp\), %r13 +** movq 360\(%rsp\), %r14 +** movq 368\(%rsp\), %r15 +** movq 376\(%rsp\), %r16 +** movq 384\(%rsp\), %r17 +** movaps 224\(%rsp\), %xmm14 +** movaps 240\(%rsp\), %xmm15 +** movq 392\(%rsp\), %r18 +** movq 400\(%rsp\), %r19 +** movq 408\(%rsp\), %r20 +** movq 416\(%rsp\), %r21 +** movq 424\(%rsp\), %r22 +** movq 432\(%rsp\), %r23 +** movq 440\(%rsp\), %r24 +** movq 448\(%rsp\), %r25 +** movq 456\(%rsp\), %r26 +** movq 464\(%rsp\), %r27 +** movq 472\(%rsp\), %r28 +** movq 480\(%rsp\), %r29 +** movq 488\(%rsp\), %r30 +** movq 496\(%rsp\), %r31 +** addq \$504, %rsp +**... +** ret +** .cfi_endproc +**... +*/ + +#include "no-callee-saved-19a.c" diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-19e.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-19e.c new file mode 100644 index 000000000000..3fcb41ff1969 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-19e.c @@ -0,0 +1,162 @@ +/* { dg-do compile { target { *-*-linux* && maybe_x32 } } } */ +/* { dg-options "-O2 -mx32 -fno-pic -mtune=generic -msse2 -mapxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* end must be empty. */ + +/* +**end: +**.LFB[0-9]+: +** .cfi_startproc +** ret +** .cfi_endproc +**... +*/ + +/* inc doesn't have any callee saved registers. */ + +/* +**inc: +**.LFB[0-9]+: +** .cfi_startproc +** addl \$1, accumulator\(%rip\) +** movq %rdi, %rax +** movl \(%eax\), %eax +** leal 4\(%rdi\), %edi +** jmp \*%rax +** .cfi_endproc +**... +*/ + +/* dec doesn't have any callee saved registers. */ + +/* +**dec: +**.LFB[0-9]+: +** .cfi_startproc +** subl \$1, accumulator\(%rip\) +** movq %rdi, %rax +** movl \(%eax\), %eax +** leal 4\(%rdi\), %edi +** jmp \*%rax +** .cfi_endproc +**... +*/ + +/* start must save and restore all caller saved registers. */ + +/* +**start: +**.LFB[0-9]+: +** .cfi_startproc +** subl \$504, %esp +**... +** movq %rax, 256\(%rsp\) +** movq %rdx, 264\(%rsp\) +** movq %rcx, 272\(%rsp\) +** movq %rbx, 280\(%rsp\) +** movq %rsi, 288\(%rsp\) +** movq %rdi, 296\(%rsp\) +**... +** movl \$code\+4, %edi +** movq %rbp, 304\(%rsp\) +** movq %r8, 312\(%rsp\) +** movq %r9, 320\(%rsp\) +** movq %r10, 328\(%rsp\) +** movq %r11, 336\(%rsp\) +** movq %r12, 344\(%rsp\) +** movq %r13, 352\(%rsp\) +** movq %r14, 360\(%rsp\) +** movq %r15, 368\(%rsp\) +** movq %r16, 376\(%rsp\) +** movq %r17, 384\(%rsp\) +** movq %r18, 392\(%rsp\) +** movq %r19, 400\(%rsp\) +** movq %r20, 408\(%rsp\) +** movq %r21, 416\(%rsp\) +** movq %r22, 424\(%rsp\) +** movq %r23, 432\(%rsp\) +** movq %r24, 440\(%rsp\) +** movq %r25, 448\(%rsp\) +** movq %r26, 456\(%rsp\) +** movq %r27, 464\(%rsp\) +** movq %r28, 472\(%rsp\) +** movq %r29, 480\(%rsp\) +** movq %r30, 488\(%rsp\) +** movq %r31, 496\(%rsp\) +**... +** movl code\(%rip\), %ebp +** movaps %xmm0, \(%rsp\) +** movaps %xmm1, 16\(%rsp\) +** movaps %xmm2, 32\(%rsp\) +** movaps %xmm3, 48\(%rsp\) +** movaps %xmm4, 64\(%rsp\) +** movaps %xmm5, 80\(%rsp\) +** movaps %xmm6, 96\(%rsp\) +** movaps %xmm7, 112\(%rsp\) +** movaps %xmm8, 128\(%rsp\) +** movaps %xmm9, 144\(%rsp\) +** movaps %xmm10, 160\(%rsp\) +** movaps %xmm11, 176\(%rsp\) +** movaps %xmm12, 192\(%rsp\) +** movaps %xmm13, 208\(%rsp\) +** movaps %xmm14, 224\(%rsp\) +** movaps %xmm15, 240\(%rsp\) +**... +** call \*%rbp +** movaps \(%rsp\), %xmm0 +** movaps 16\(%rsp\), %xmm1 +** movaps 32\(%rsp\), %xmm2 +** movaps 48\(%rsp\), %xmm3 +** movaps 64\(%rsp\), %xmm4 +** movaps 80\(%rsp\), %xmm5 +** movaps 96\(%rsp\), %xmm6 +** movaps 112\(%rsp\), %xmm7 +** movaps 128\(%rsp\), %xmm8 +** movaps 144\(%rsp\), %xmm9 +** movaps 160\(%rsp\), %xmm10 +** movaps 176\(%rsp\), %xmm11 +** movaps 192\(%rsp\), %xmm12 +** movaps 208\(%rsp\), %xmm13 +** movaps 224\(%rsp\), %xmm14 +** movaps 240\(%rsp\), %xmm15 +** movq 256\(%rsp\), %rax +** movq 264\(%rsp\), %rdx +** movq 272\(%rsp\), %rcx +** movq 280\(%rsp\), %rbx +** movq 288\(%rsp\), %rsi +** movq 296\(%rsp\), %rdi +** movq 304\(%rsp\), %rbp +** movq 312\(%rsp\), %r8 +** movq 320\(%rsp\), %r9 +** movq 328\(%rsp\), %r10 +** movq 336\(%rsp\), %r11 +** movq 344\(%rsp\), %r12 +** movq 352\(%rsp\), %r13 +** movq 360\(%rsp\), %r14 +** movq 368\(%rsp\), %r15 +** movq 376\(%rsp\), %r16 +** movq 384\(%rsp\), %r17 +** movq 392\(%rsp\), %r18 +** movq 400\(%rsp\), %r19 +** movq 408\(%rsp\), %r20 +** movq 416\(%rsp\), %r21 +** movq 424\(%rsp\), %r22 +** movq 432\(%rsp\), %r23 +** movq 440\(%rsp\), %r24 +** movq 448\(%rsp\), %r25 +** movq 456\(%rsp\), %r26 +** movq 464\(%rsp\), %r27 +** movq 472\(%rsp\), %r28 +** movq 480\(%rsp\), %r29 +** movq 488\(%rsp\), %r30 +** movq 496\(%rsp\), %r31 +** addl \$504, %esp +**... +** ret +** .cfi_endproc +**... +*/ + +#include "no-callee-saved-19a.c" diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-2.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-2.c index 98e2701d925e..e074ca51df40 100644 --- a/gcc/testsuite/gcc.target/i386/no-callee-saved-2.c +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-2.c @@ -26,5 +26,7 @@ foo (void *frame) } } -/* { dg-final { scan-assembler-not "push" } } */ -/* { dg-final { scan-assembler-not "pop" } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*" 1 } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-3.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-3.c index 453272e11c08..44ad0b2114e4 100644 --- a/gcc/testsuite/gcc.target/i386/no-callee-saved-3.c +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-3.c @@ -3,6 +3,6 @@ __attribute__ ((no_callee_saved_registers, no_caller_saved_registers)) void -foo (void) /* { dg-error "attributes are not compatible" } */ -{ +foo (void) +{ /* { dg-error "attributes are not compatible" } */ } diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-7.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-7.c index a1837fdfd4b5..821d1e2a4d42 100644 --- a/gcc/testsuite/gcc.target/i386/no-callee-saved-7.c +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-7.c @@ -17,7 +17,7 @@ foo (void) /* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ /* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ /* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ -/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ /* { dg-final { scan-assembler-times "pushl\[\\t \]*%esi" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-not "pushq\[\\t \]*%rsi" { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "pushl\[\\t \]*%edi" 1 { target ia32 } } } */ @@ -34,7 +34,7 @@ foo (void) /* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ /* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ /* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ -/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ /* { dg-final { scan-assembler-times "popl\[\\t \]*%esi" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-not "popq\[\\t \]*%rsi" { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "popl\[\\t \]*%edi" 1 { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-8.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-8.c index 90b98a21aef7..ed3d96bdca05 100644 --- a/gcc/testsuite/gcc.target/i386/no-callee-saved-8.c +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-8.c @@ -18,7 +18,7 @@ foo (void) /* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ /* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ /* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ -/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ /* { dg-final { scan-assembler-times "pushl\[\\t \]*%esi" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-not "pushq\[\\t \]*%rsi" { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "pushl\[\\t \]*%edi" 1 { target ia32 } } } */ @@ -35,7 +35,7 @@ foo (void) /* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ /* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ /* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ -/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ /* { dg-final { scan-assembler-times "popl\[\\t \]*%esi" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-not "popq\[\\t \]*%rsi" { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "popl\[\\t \]*%edi" 1 { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-9.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-9.c index e261100ac1a1..7730c5903d4b 100644 --- a/gcc/testsuite/gcc.target/i386/no-callee-saved-9.c +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-9.c @@ -17,7 +17,7 @@ foo (fn_t bar) /* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ /* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ /* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ -/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ /* { dg-final { scan-assembler-times "pushl\[\\t \]*%esi" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-not "pushq\[\\t \]*%rsi" { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "pushl\[\\t \]*%edi" 1 { target ia32 } } } */ @@ -34,7 +34,7 @@ foo (fn_t bar) /* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ /* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ /* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ -/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ /* { dg-final { scan-assembler-times "popl\[\\t \]*%esi" 1 { target ia32 } } } */ /* { dg-final { scan-assembler-not "popq\[\\t \]*%rsi" { target { ! ia32 } } } } */ /* { dg-final { scan-assembler-times "popl\[\\t \]*%edi" 1 { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr100865-10b.c b/gcc/testsuite/gcc.target/i386/pr100865-10b.c index f60d1bfd2c78..17847ac97272 100644 --- a/gcc/testsuite/gcc.target/i386/pr100865-10b.c +++ b/gcc/testsuite/gcc.target/i386/pr100865-10b.c @@ -4,4 +4,4 @@ #include "pr100865-10a.c" /* { dg-final { scan-assembler-times "vpbroadcastd\[\\t \]+%(?:r|e)\[^\n\]*, %ymm\[0-9\]+" 1 } } */ -/* { dg-final { scan-assembler-times "vmovdqu8\[\\t \]%ymm\[0-9\]+, " 8 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%ymm\[0-9\]+, " 8 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr100865-3.c b/gcc/testsuite/gcc.target/i386/pr100865-3.c index 433fd81cb0db..caa083c8b8a1 100644 --- a/gcc/testsuite/gcc.target/i386/pr100865-3.c +++ b/gcc/testsuite/gcc.target/i386/pr100865-3.c @@ -11,6 +11,6 @@ foo (void) } /* { dg-final { scan-assembler-times "vpbroadcastd\[\\t \]+%(?:r|e)\[^\n\]*, %xmm\[0-9\]+" 1 } } */ -/* { dg-final { scan-assembler-times "vmovdqu8\[\\t \]%xmm\[0-9\]+, \\(%\[\^,\]+\\)" 1 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%xmm\[0-9\]+, \\(%\[\^,\]+\\)" 1 } } */ /* { dg-final { scan-assembler-not "vpbroadcastd\[\\t \]+%xmm\[0-9\]+, %xmm\[0-9\]+" } } */ /* { dg-final { scan-assembler-not "vmovdqa" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr100865-4b.c b/gcc/testsuite/gcc.target/i386/pr100865-4b.c index 6fd703e8049f..7017de9032d9 100644 --- a/gcc/testsuite/gcc.target/i386/pr100865-4b.c +++ b/gcc/testsuite/gcc.target/i386/pr100865-4b.c @@ -5,7 +5,7 @@ #include "pr100865-4a.c" /* { dg-final { scan-assembler-times "vpbroadcastd\[\\t \]+%(?:r|e)\[^\n\]*, %ymm\[0-9\]+" 1 } } */ -/* { dg-final { scan-assembler-times "vmovdqu8\[\\t \]%ymm\[0-9\]+, " 2 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%ymm\[0-9\]+, " 2 } } */ /* { dg-final { scan-assembler-times "vzeroupper" 1 } } */ /* { dg-final { scan-assembler-not "vpbroadcastd\[\\t \]+%xmm\[0-9\]+, %ymm\[0-9\]+" } } */ /* { dg-final { scan-assembler-not "vmovdqa" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr100865-5b.c b/gcc/testsuite/gcc.target/i386/pr100865-5b.c index 6c2b33d6c69d..8b8ed9356df4 100644 --- a/gcc/testsuite/gcc.target/i386/pr100865-5b.c +++ b/gcc/testsuite/gcc.target/i386/pr100865-5b.c @@ -5,6 +5,6 @@ #include "pr100865-5a.c" /* { dg-final { scan-assembler-times "vpbroadcastd\[\\t \]+%(?:r|e)\[^\n\]*, %ymm\[0-9\]+" 1 } } */ -/* { dg-final { scan-assembler-times "vmovdqu16\[\\t \]%ymm\[0-9\]+, " 4 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%ymm\[0-9\]+, " 4 } } */ /* { dg-final { scan-assembler-not "vpbroadcastd\[\\t \]+%xmm\[0-9\]+, %ymm\[0-9\]+" } } */ /* { dg-final { scan-assembler-not "vmovdqa" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr104447.c b/gcc/testsuite/gcc.target/i386/pr104447.c index cb618c7b8bb3..145ba90ac0c3 100644 --- a/gcc/testsuite/gcc.target/i386/pr104447.c +++ b/gcc/testsuite/gcc.target/i386/pr104447.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-require-profiling "-pg" } */ /* { dg-options "-O2 -pg" } */ +/* { dg-additional-options "-mfentry -fno-pic" { target *-*-gnu* } } */ int bar (int x) diff --git a/gcc/testsuite/gcc.target/i386/pr111657-1.c b/gcc/testsuite/gcc.target/i386/pr111657-1.c index a4ba21073f52..fa9f4cfe5c53 100644 --- a/gcc/testsuite/gcc.target/i386/pr111657-1.c +++ b/gcc/testsuite/gcc.target/i386/pr111657-1.c @@ -1,5 +1,26 @@ /* { dg-do assemble } */ /* { dg-options "-O2 -mno-sse -mtune=generic -save-temps" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**bar: +**... +**.L[0-9]+: +** movl %edx, %eax +** addl \$32, %edx +** movq %gs:m\(%rax\), %r9 +** movq %gs:m\+8\(%rax\), %r8 +** movq %gs:m\+16\(%rax\), %rsi +** movq %gs:m\+24\(%rax\), %rcx +** movq %r9, \(%rdi,%rax\) +** movq %r8, 8\(%rdi,%rax\) +** movq %rsi, 16\(%rdi,%rax\) +** movq %rcx, 24\(%rdi,%rax\) +** cmpl \$224, %edx +** jb .L[0-9]+ +**... +*/ typedef unsigned long uword __attribute__ ((mode (word))); @@ -8,5 +29,4 @@ struct a { uword arr[30]; }; __seg_gs struct a m; void bar (struct a *dst) { *dst = m; } -/* { dg-final { scan-assembler "gs\[ \t\]+rep\[; \t\]+movs(l|q)" { target { ! x32 } } } } */ -/* { dg-final { scan-assembler-not "gs\[ \t\]+rep\[; \t\]+movs(l|q)" { target x32 } } } */ +/* { dg-final { scan-assembler-not "rep movs" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr113122-3.c b/gcc/testsuite/gcc.target/i386/pr113122-3.c index 71aa240ba98c..87b76de1a21a 100644 --- a/gcc/testsuite/gcc.target/i386/pr113122-3.c +++ b/gcc/testsuite/gcc.target/i386/pr113122-3.c @@ -2,6 +2,7 @@ /* { dg-do assemble { target *-*-linux* } } */ /* { dg-require-effective-target masm_intel } */ /* { dg-options "-fprofile -O2 -masm=intel" } */ +/* { dg-additional-options "-mfentry -fno-pic" { target *-*-gnu* } } */ void func (void) diff --git a/gcc/testsuite/gcc.target/i386/pr119386-1.c b/gcc/testsuite/gcc.target/i386/pr119386-1.c index 9a0dc64b5b93..7a56eacc221d 100644 --- a/gcc/testsuite/gcc.target/i386/pr119386-1.c +++ b/gcc/testsuite/gcc.target/i386/pr119386-1.c @@ -1,7 +1,9 @@ /* PR target/119386 */ /* { dg-do compile { target *-*-linux* } } */ /* { dg-options "-O2 -fpic -pg" } */ -/* { dg-final { scan-assembler "call\[ \t\]+mcount@PLT" } } */ +/* { dg-additional-options "-mfentry" { target { *-*-gnu* && { ! ia32 } } } } */ +/* { dg-final { scan-assembler "call\[ \t\]+mcount@PLT" { target ia32 } } } */ +/* { dg-final { scan-assembler "call\[ \t\]+__fentry__@PLT" { target { *-*-gnu* && { ! ia32 } } } } } */ int main () diff --git a/gcc/testsuite/gcc.target/i386/pr119386-2.c b/gcc/testsuite/gcc.target/i386/pr119386-2.c index 3ea978ecfdfd..cddaaf0705c7 100644 --- a/gcc/testsuite/gcc.target/i386/pr119386-2.c +++ b/gcc/testsuite/gcc.target/i386/pr119386-2.c @@ -1,7 +1,8 @@ /* PR target/119386 */ /* { dg-do compile { target *-*-linux* } } */ /* { dg-options "-O2 -fpic -fno-plt -pg" } */ -/* { dg-final { scan-assembler "call\[ \t\]+\\*mcount@GOTPCREL\\(" { target { ! ia32 } } } } */ +/* { dg-additional-options "-mfentry" { target { *-*-gnu* && { ! ia32 } } } } */ +/* { dg-final { scan-assembler "call\[ \t\]+\\*__fentry__@GOTPCREL" { target { *-*-gnu* && { ! ia32 } } } } } */ /* { dg-final { scan-assembler "call\[ \t\]+\\*mcount@GOT\\(" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr119784a.c b/gcc/testsuite/gcc.target/i386/pr119784a.c index 8a119d4cc1f8..a3b7e4aa7cca 100644 --- a/gcc/testsuite/gcc.target/i386/pr119784a.c +++ b/gcc/testsuite/gcc.target/i386/pr119784a.c @@ -11,14 +11,12 @@ ** .cfi_startproc ** subq \$248, %rsp **... -** movq %rax, \(%rsp\) -** movq %rdx, 8\(%rsp\) -** movq %rcx, 16\(%rsp\) -** movq %rbx, 24\(%rsp\) -** movq %rsi, 32\(%rsp\) -** movq %rdi, 40\(%rsp\) -**... -** movq %rbp, 48\(%rsp\) +** movq %rax, 8\(%rsp\) +** movq %rdx, 16\(%rsp\) +** movq %rcx, 24\(%rsp\) +** movq %rbx, 32\(%rsp\) +** movq %rsi, 40\(%rsp\) +** movq %rdi, 48\(%rsp\) ** movq %r8, 56\(%rsp\) ** movq %r9, 64\(%rsp\) ** movq %r10, 72\(%rsp\) @@ -45,13 +43,12 @@ ** movq %r31, 240\(%rsp\) **... ** call \*code\(%rip\) -** movq \(%rsp\), %rax -** movq 8\(%rsp\), %rdx -** movq 16\(%rsp\), %rcx -** movq 24\(%rsp\), %rbx -** movq 32\(%rsp\), %rsi -** movq 40\(%rsp\), %rdi -** movq 48\(%rsp\), %rbp +** movq 8\(%rsp\), %rax +** movq 16\(%rsp\), %rdx +** movq 24\(%rsp\), %rcx +** movq 32\(%rsp\), %rbx +** movq 40\(%rsp\), %rsi +** movq 48\(%rsp\), %rdi ** movq 56\(%rsp\), %r8 ** movq 64\(%rsp\), %r9 ** movq 72\(%rsp\), %r10 diff --git a/gcc/testsuite/gcc.target/i386/pr120032-1.c b/gcc/testsuite/gcc.target/i386/pr120032-1.c new file mode 100644 index 000000000000..c51512492b6f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120032-1.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlzcnt" } */ + +unsigned int +ZSTD_countLeadingZeros32_fallback(unsigned int val) +{ + static const unsigned int DeBruijnClz[32] + = { 0, 9, 1, 10, 13, 21, 2, 29, + 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, + 19, 27, 23, 6, 26, 5, 4, 31}; + if (val == 0) + __builtin_abort (); + val |= val >> 1; + val |= val >> 2; + val |= val >> 4; + val |= val >> 8; + val |= val >> 16; + return 31 - DeBruijnClz[(val * 0x07C4ACDDU) >> 27]; +} + +/* { dg-final { scan-assembler "lzcnt" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr120032-2.c b/gcc/testsuite/gcc.target/i386/pr120032-2.c new file mode 100644 index 000000000000..ea2ad4086189 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120032-2.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlzcnt" } */ + +unsigned int +ZSTD_countLeadingZeros32_fallback(unsigned int val) +{ + static const unsigned char DeBruijnClz[32] + = { 0, 9, 1, 10, 13, 21, 2, 29, + 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, + 19, 27, 23, 6, 26, 5, 4, 31}; + if (val == 0) + __builtin_abort (); + val |= val >> 1; + val |= val >> 2; + val |= val >> 4; + val |= val >> 8; + val |= val >> 16; + return 31 - DeBruijnClz[(val * 0x07C4ACDDU) >> 27]; +} + +/* { dg-final { scan-assembler "lzcnt" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr120032-3.c b/gcc/testsuite/gcc.target/i386/pr120032-3.c new file mode 100644 index 000000000000..9523bbb0f5b5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120032-3.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlzcnt" } */ + +unsigned int +ZSTD_countLeadingZeros32_fallback(unsigned int val) +{ + static const unsigned int DeBruijnClz[32] + = { 0, 9, 1, 10, 13, 21, 2, 29, + 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, + 19, 27, 23, 6, 26, 5, 4, 31}; + val |= val >> 1; + val |= val >> 2; + val |= val >> 4; + val |= val >> 8; + val |= val >> 16; + return 31 - DeBruijnClz[(val * 0x07C4ACDDU) >> 27]; +} + +/* { dg-final { scan-assembler "lzcnt" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr120427-1.c b/gcc/testsuite/gcc.target/i386/pr120427-1.c new file mode 100644 index 000000000000..7f1690e49b4d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120427-1.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=sapphirerapids" } */ +/* { dg-final { scan-assembler-not "and\[lq\]?\[\\t \]+\\\$0, \[0-9\]*\\(" } } */ + +struct __pthread_mutex_s +{ + int __lock; + unsigned int __count; + int __owner; + unsigned int __nusers; + int __kind; + short __spins; + short __elision; + void *p[2]; +}; +typedef union +{ + struct __pthread_mutex_s __data; + char __size[40]; + long int __align; +} pthread_mutex_t; +typedef struct { pthread_mutex_t mutex; } __rtld_lock_recursive_t; +void +foo (__rtld_lock_recursive_t *lock, int i) +{ + lock[i] = (__rtld_lock_recursive_t) {{ { 0, 0, 0, 0, 1, + 0, 0, { ((void *)0) , ((void *)0) } } }}; +} diff --git a/gcc/testsuite/gcc.target/i386/pr120427-2.c b/gcc/testsuite/gcc.target/i386/pr120427-2.c new file mode 100644 index 000000000000..a380c128ccb0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120427-2.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=sapphirerapids" } */ +/* { dg-final { scan-assembler-not "or\[lq\]?\[\\t \]+\\\$-1, \[0-9\]*\\(" } } */ + +struct __pthread_mutex_s +{ + int __lock; + unsigned int __count; + int __owner; + unsigned int __nusers; + int __kind; + short __spins; + short __elision; + void *p[2]; +}; +typedef union +{ + struct __pthread_mutex_s __data; + char __size[40]; + long int __align; +} pthread_mutex_t; +typedef struct { pthread_mutex_t mutex; } __rtld_lock_recursive_t; +void +foo (__rtld_lock_recursive_t *lock, int i) +{ + lock[i] = (__rtld_lock_recursive_t) {{ { -1, -1, -1, -1, 1, + -1, -1, { ((void *)-1) , ((void *)-1) } } }}; +} diff --git a/gcc/testsuite/gcc.target/i386/pr120427-3.c b/gcc/testsuite/gcc.target/i386/pr120427-3.c new file mode 100644 index 000000000000..951cb1f5ddbc --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120427-3.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); +typedef UDItype __attribute__ ((__may_alias__)) bar_t; + +static inline __attribute__((__always_inline__)) SItype +bar (const bar_t **p, SItype prec) +{ + bar_t mslimb = 0; + SItype i = 20; + SItype n = ((USItype) prec) % 4; + if (n) + { + prec -= n; + if (prec == 0) + return 1; + mslimb = (*p)[i]; + } + while (mslimb == 0) + { + prec -= 4; + if (prec == 0) + return 1; + --i; + mslimb = (*p)[i]; + } + return prec; +} +UDItype +foo (const bar_t *i, SItype iprec) +{ + iprec = bar (&i, iprec); + USItype aiprec = iprec < 0 ? -iprec : iprec; + bar_t msb = *i; + UDItype mantissa = 0; + if (aiprec % 4) + msb &= ((bar_t) 1 << aiprec) - 1; + if (aiprec >= 54) + mantissa = (UDItype) msb << 32; + + return (mantissa ^ (UDItype) 0x20000000000000); +} diff --git a/gcc/testsuite/gcc.target/i386/pr120427-4.c b/gcc/testsuite/gcc.target/i386/pr120427-4.c new file mode 100644 index 000000000000..2b453b787ecd --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120427-4.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include "cold-attribute-4.c" + +/* { dg-final { scan-assembler "movl" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr120434-1.c b/gcc/testsuite/gcc.target/i386/pr120434-1.c new file mode 100644 index 000000000000..889b6f420a04 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120434-1.c @@ -0,0 +1,28 @@ +/* PR middle-end/120434 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic -masm=att" } */ +/* { dg-final { scan-assembler-times "\tsar\[lq]\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tshr\[lq]\t" 2 } } */ + +[[gnu::noipa]] int +foo (int x) +{ + return x / 200; +} + +[[gnu::noipa]] int +bar (int x) +{ + if (x < 0) + __builtin_unreachable (); + return x / 200; +} + +[[gnu::noipa]] int +baz (int x) +{ + if (x >= 0) + return x / 200; + else + return 24; +} diff --git a/gcc/testsuite/gcc.target/i386/pr120434-2.c b/gcc/testsuite/gcc.target/i386/pr120434-2.c new file mode 100644 index 000000000000..4381e3b3bfdc --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120434-2.c @@ -0,0 +1,15 @@ +/* PR middle-end/120434 */ +/* { dg-do compile { target lp64 } } */ +/* { dg-options "-O2 -mtune=generic -masm=att" } */ +/* { dg-final { scan-assembler-not "\tmovslq\t%edi, %rdi" } } */ +/* { dg-final { scan-assembler "\tmovl\t%edi, %edi" } } */ + +extern unsigned long long foo (unsigned long long x); + +unsigned long long +bar (int x) +{ + if (x < 50) + return 0; + return foo (x); +} diff --git a/gcc/testsuite/gcc.target/i386/pr120553.c b/gcc/testsuite/gcc.target/i386/pr120553.c new file mode 100644 index 000000000000..abbf58c67223 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120553.c @@ -0,0 +1,6 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2" } */ + +long long foo (long long c) { return c >= 0 ? 0x400000000ll : -1ll; } + +/* { dg-final { scan-assembler "bts" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr120689.c b/gcc/testsuite/gcc.target/i386/pr120689.c new file mode 100644 index 000000000000..cd10cdb487df --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120689.c @@ -0,0 +1,17 @@ +/* PR target/120689 */ +/* { dg-do compile { target lp64 } } */ +/* { dg-options "-O2 -mtune=generic -fno-stack-protector -masm=att" } */ +/* { dg-final { scan-assembler-not "\t\(movzbl\|shrl\|salq\|orq\)\t" } } */ + +struct S { char a, b, c; }; + +[[gnu::noipa]] +void foo (struct S x, struct S y, struct S z) +{ +} + +void +bar (struct S x, struct S y, struct S z) +{ + [[gnu::musttail]] return foo (x, y, z); +} diff --git a/gcc/testsuite/gcc.target/i386/pr120728.c b/gcc/testsuite/gcc.target/i386/pr120728.c new file mode 100644 index 000000000000..93d2cd07e2fb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120728.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4" } */ +/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+, " 3 } } */ +/* { dg-final { scan-assembler-not "vmovdqu8" } } */ +/* { dg-final { scan-assembler-not "vmovdqu16" } } */ + +typedef char __v32qi __attribute__ ((__vector_size__ (32))); +typedef char __v32qi_u __attribute__ ((__vector_size__ (32), + __aligned__ (1))); +typedef short __v16hi __attribute__ ((__vector_size__ (32))); +typedef short __v16hi_u __attribute__ ((__vector_size__ (32), + __aligned__ (1))); +typedef _Float16 __v16hf __attribute__ ((__vector_size__ (32))); +typedef _Float16 __v16hf_u __attribute__ ((__vector_size__ (32), + __aligned__ (1))); + +extern __v32qi_u v1; +extern __v16hi_u v2; +extern __v16hf_u v3; + +void +foo (__v32qi x1, __v16hi x2, __v16hf x3) +{ + v1 = x1; + v2 = x2; + v3 = x3; +} diff --git a/gcc/testsuite/gcc.target/i386/pr120741.c b/gcc/testsuite/gcc.target/i386/pr120741.c new file mode 100644 index 000000000000..b59a58c48b89 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120741.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mstack-arg-probe" } */ + +short __mingw_swformat_format; +__builtin_va_list __mingw_swformat_arg; +int __mingw_swformat_fc; +typedef struct { + void *fp; + int bch[1024]; +} _IFP; +void __mingw_swformat(_IFP *s) { + if (s->fp) + while (__mingw_swformat_format) + if (__mingw_swformat_fc == 'A') + *__builtin_va_arg(__mingw_swformat_arg, double *) = 0; +} +void +__mingw_vswscanf (void) +{ + _IFP ifp; + __mingw_swformat(&ifp); +} diff --git a/gcc/testsuite/gcc.target/i386/pr120840-1a.c b/gcc/testsuite/gcc.target/i386/pr120840-1a.c new file mode 100644 index 000000000000..cc5800311b30 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120840-1a.c @@ -0,0 +1,83 @@ +/* { dg-do run } */ +/* { dg-options "-save-temps -O2 -fno-omit-frame-pointer -mtune-ctrl=prologue_using_move,epilogue_using_move,use_leave" } */ + +#ifndef DONT_SAVE_REGS1 +# define DONT_SAVE_REGS1 __attribute__((no_callee_saved_registers)) +#endif +#ifndef DONT_SAVE_REGS2 +# define DONT_SAVE_REGS2 __attribute__((no_callee_saved_registers)) +#endif + +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-linux*" } {^\t?\.} } } */ + +/* +**do_test: +**.LFB[0-9]+: +**... +** leave +**... +** ret +**... +*/ + +#include + +DONT_SAVE_REGS1 +__attribute__ ((weak, __optimize__ ("-fomit-frame-pointer"))) +void +continuation (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) +{ + /* Clobber frame pointer register. */ + asm ("xor %%ebp, %%ebp" ::: "ebp"); + + if (arg1 != 17) + abort (); + if (arg2 != 8) + abort (); + if (arg3 != 20) + abort (); + if (arg4 != -3) + abort (); + if (arg5 != -4) + abort (); + if (arg6 != 26) + abort (); +} + +DONT_SAVE_REGS2 +__attribute__ ((weak, __optimize__ ("-fomit-frame-pointer"))) +void +entry (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) +{ + /* Clobber frame pointer register. */ + asm ("xor %%ebp, %%ebp" ::: "ebp"); + + if (arg1 != 17) + abort (); + if (arg2 != 8) + abort (); + if (arg3 != 20) + abort (); + if (arg4 != -3) + abort (); + if (arg5 != -4) + abort (); + if (arg6 != 26) + abort (); + continuation (arg1, arg2, arg3, arg4, arg5, arg6); +} + +__attribute__ ((weak)) +void +do_test (void) +{ + entry (17, 8, 20, -3, -4, 26); +} + +int +main (void) +{ + do_test (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr120840-1b.c b/gcc/testsuite/gcc.target/i386/pr120840-1b.c new file mode 100644 index 000000000000..a759e3402b5c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120840-1b.c @@ -0,0 +1,20 @@ +/* { dg-do run } */ +/* { dg-options "-save-temps -O2 -fno-omit-frame-pointer -mtune-ctrl=prologue_using_move,epilogue_using_move,use_leave" } */ + +#define DONT_SAVE_REGS1 __attribute__((preserve_none)) +#define DONT_SAVE_REGS2 __attribute__((no_callee_saved_registers)) + +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-linux*" } {^\t?\.} } } */ + +/* +**do_test: +**.LFB[0-9]+: +**... +** leave +**... +** ret +**... +*/ + +#include "pr120840-1a.c" diff --git a/gcc/testsuite/gcc.target/i386/pr120840-1c.c b/gcc/testsuite/gcc.target/i386/pr120840-1c.c new file mode 100644 index 000000000000..84aa353d705b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120840-1c.c @@ -0,0 +1,20 @@ +/* { dg-do run } */ +/* { dg-options "-save-temps -O2 -fno-omit-frame-pointer -mtune-ctrl=prologue_using_move,epilogue_using_move,use_leave" } */ + +#define DONT_SAVE_REGS1 __attribute__((no_callee_saved_registers)) +#define DONT_SAVE_REGS2 __attribute__((preserve_none)) + +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-linux*" } {^\t?\.} } } */ + +/* +**do_test: +**.LFB[0-9]+: +**... +** leave +**... +** ret +**... +*/ + +#include "pr120840-1a.c" diff --git a/gcc/testsuite/gcc.target/i386/pr120840-1d.c b/gcc/testsuite/gcc.target/i386/pr120840-1d.c new file mode 100644 index 000000000000..a6b38a6aff17 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120840-1d.c @@ -0,0 +1,20 @@ +/* { dg-do run } */ +/* { dg-options "-save-temps -O2 -fno-omit-frame-pointer -mtune-ctrl=prologue_using_move,epilogue_using_move,use_leave" } */ + +#define DONT_SAVE_REGS1 __attribute__((preserve_none)) +#define DONT_SAVE_REGS2 __attribute__((preserve_none)) + +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-linux*" } {^\t?\.} } } */ + +/* +**do_test: +**.LFB[0-9]+: +**... +** leave +**... +** ret +**... +*/ + +#include "pr120840-1a.c" diff --git a/gcc/testsuite/gcc.target/i386/pr120881-1a.c b/gcc/testsuite/gcc.target/i386/pr120881-1a.c new file mode 100644 index 000000000000..3d9ac0e9e866 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120881-1a.c @@ -0,0 +1,4 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-require-profiling "-pg" } */ +/* { dg-options "-O2 -pg -mno-fentry -fno-pic" } */ +/* { dg-message "'-pg' without '-mfentry' may be unreliable with shrink wrapping" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.target/i386/pr120881-1b.c b/gcc/testsuite/gcc.target/i386/pr120881-1b.c new file mode 100644 index 000000000000..082640726b1d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120881-1b.c @@ -0,0 +1,4 @@ +/* { dg-do compile { target { fpic && { ! ia32 } } } } */ +/* { dg-require-profiling "-pg" } */ +/* { dg-options "-O2 -pg -mno-fentry -fpic" } */ +/* { dg-message "'-pg' without '-mfentry' may be unreliable with shrink wrapping" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.target/i386/pr120881-1c.c b/gcc/testsuite/gcc.target/i386/pr120881-1c.c new file mode 100644 index 000000000000..c21979f8eb1f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120881-1c.c @@ -0,0 +1,3 @@ +/* { dg-do compile { target { fpic && ia32 } } } */ +/* { dg-require-profiling "-pg" } */ +/* { dg-options "-O2 -pg -mno-fentry -fpic" } */ diff --git a/gcc/testsuite/gcc.target/i386/pr120881-1d.c b/gcc/testsuite/gcc.target/i386/pr120881-1d.c new file mode 100644 index 000000000000..f74af23ff5c8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120881-1d.c @@ -0,0 +1,3 @@ +/* { dg-do compile { target { fpic && ia32 } } } */ +/* { dg-require-profiling "-pg" } */ +/* { dg-options "-O2 -pg -mno-fentry -fno-shrink-wrap -fno-pic" } */ diff --git a/gcc/testsuite/gcc.target/i386/pr120881-2a.c b/gcc/testsuite/gcc.target/i386/pr120881-2a.c new file mode 100644 index 000000000000..52e3e5292e5f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120881-2a.c @@ -0,0 +1,21 @@ +/* { dg-do compile { target fentry } } */ +/* { dg-options "-O2 -pg" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**f2: +**.LFB[0-9]+: +** .cfi_startproc +** call __fentry__ +**... +*/ + +extern void f1 (void); + +void +f2 (int count) +{ + for (int i = 0; i < count; ++i) + f1 (); +} diff --git a/gcc/testsuite/gcc.target/i386/pr120881-2b.c b/gcc/testsuite/gcc.target/i386/pr120881-2b.c new file mode 100644 index 000000000000..43a12f007749 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120881-2b.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-rtl-pro_and_epilogue -march=x86-64" } */ +/* { dg-final { scan-rtl-dump "Now spread 1 times" "pro_and_epilogue" } } */ + +#include "pr120881-2a.c" + diff --git a/gcc/testsuite/gcc.target/i386/pr120908.c b/gcc/testsuite/gcc.target/i386/pr120908.c new file mode 100644 index 000000000000..10e5a46d8d4e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120908.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target { lp64 && fpic } } } */ +/* { dg-options "-O2 -fpic -mtls-dialect=gnu -mcmodel=large" } */ + +extern __thread long bar1; +long * +foo1 (void) +{ + return &bar1; +} + +static __thread long bar2; +long * +foo2 (void) +{ + return &bar2; +} diff --git a/gcc/testsuite/gcc.target/i386/pr120936-1.c b/gcc/testsuite/gcc.target/i386/pr120936-1.c new file mode 100644 index 000000000000..a20680d85483 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120936-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-O2 -pg -mno-fentry -fno-pic -fno-shrink-wrap" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +**... +** .cfi_.* +** call mcount +**... +*/ + +void +foo (void) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/pr120936-10.c b/gcc/testsuite/gcc.target/i386/pr120936-10.c new file mode 100644 index 000000000000..ab95b087ec9b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120936-10.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target { fpic && lp64 } } } */ +/* { dg-options "-O2 -mcmodel=large -pg -mno-fentry -fpic -fno-shrink-wrap" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^(1|\t?\.)} } } */ + +/* +**foo: +**.LFB[0-9]+: +**... +** .cfi_.* +**1: movabsq \$_GLOBAL_OFFSET_TABLE_-1b, %r11 +** leaq 1b\(%rip\), %r10 +** addq %r11, %r10 +** movabsq \$mcount@PLTOFF, %r11 +** addq %r11, %r10 +** call \*%r10 +**... +*/ + +void +foo (void) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/pr120936-11.c b/gcc/testsuite/gcc.target/i386/pr120936-11.c new file mode 100644 index 000000000000..3e39dfe0d374 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120936-11.c @@ -0,0 +1,19 @@ +/* { dg-do compile { target { fpic && lp64 } } } */ +/* { dg-options "-O2 -mrecord-mcount -mcmodel=large -pg -mno-fentry -fno-pic -fno-shrink-wrap" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^(1|\t?\.)} } } */ + +/* +**foo: +**.LFB[0-9]+: +**... +** .cfi_.* +**1: movabsq \$mcount, %r10 +** call \*%r10 +**... +*/ + +void +foo (void) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/pr120936-12.c b/gcc/testsuite/gcc.target/i386/pr120936-12.c new file mode 100644 index 000000000000..b5a2aaced5d8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120936-12.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target { fpic && lp64 } } } */ +/* { dg-options "-O2 -mcmodel=large -mrecord-mcount -pg -mno-fentry -fpic -fno-shrink-wrap" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^(1|\t?\.)} } } */ + +/* +**foo: +**.LFB[0-9]+: +**... +** .cfi_.* +**1: movabsq \$_GLOBAL_OFFSET_TABLE_-1b, %r11 +** leaq 1b\(%rip\), %r10 +** addq %r11, %r10 +** movabsq \$mcount@PLTOFF, %r11 +** addq %r11, %r10 +** call \*%r10 +**... +*/ + +void +foo (void) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/pr120936-2.c b/gcc/testsuite/gcc.target/i386/pr120936-2.c new file mode 100644 index 000000000000..083565801651 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120936-2.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-O2 -pg -mno-fentry -fpic -fno-shrink-wrap" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +**... +** .cfi_.* +** call mcount@PLT +**... +*/ + +void +foo (void) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/pr120936-3.c b/gcc/testsuite/gcc.target/i386/pr120936-3.c new file mode 100644 index 000000000000..dc0a8f1e4243 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120936-3.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-O2 -mnop-mcount -pg -mno-fentry -fno-pic -fno-shrink-wrap" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +**... +** .cfi_.* +** .byte 0x0f, 0x1f, 0x44, 0x00, 0x00 +**... +*/ + +void +foo (void) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/pr120936-4.c b/gcc/testsuite/gcc.target/i386/pr120936-4.c new file mode 100644 index 000000000000..2420f0ba0b40 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120936-4.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-O2 -pg -mno-fentry -mrecord-mcount -fno-pic -fno-shrink-wrap" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^(1|\t?\.)} } } */ + +/* +**foo: +**.LFB[0-9]+: +**... +** .cfi_.* +**1: call mcount +**... +*/ + +void +foo (void) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/pr120936-5.c b/gcc/testsuite/gcc.target/i386/pr120936-5.c new file mode 100644 index 000000000000..20ecd37790d5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120936-5.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-O2 -pg -mrecord-mcount -mno-fentry -fpic -fno-shrink-wrap" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^(1|\t?\.)} } } */ + +/* +**foo: +**.LFB[0-9]+: +**... +** .cfi_.* +**1: call mcount@PLT +**... +*/ + +void +foo (void) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/pr120936-6.c b/gcc/testsuite/gcc.target/i386/pr120936-6.c new file mode 100644 index 000000000000..6e2290fda6e8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120936-6.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-O2 -mrecord-mcount -mnop-mcount -pg -mno-fentry -fno-pic -fno-shrink-wrap" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^(1|\t?\.)} } } */ + +/* +**foo: +**.LFB[0-9]+: +**... +** .cfi_.* +**1: .byte 0x0f, 0x1f, 0x44, 0x00, 0x00 +**... +*/ + +void +foo (void) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/pr120936-7.c b/gcc/testsuite/gcc.target/i386/pr120936-7.c new file mode 100644 index 000000000000..0c864671b060 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120936-7.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */ +/* { dg-options "-O2 -pg -mno-fentry -fpic -fno-plt -fno-shrink-wrap" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +**... +** .cfi_.* +** call \*mcount@GOTPCREL\(%rip\) +**... +*/ + +void +foo (void) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/pr120936-8.c b/gcc/testsuite/gcc.target/i386/pr120936-8.c new file mode 100644 index 000000000000..3f86781bcbda --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120936-8.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */ +/* { dg-options "-O2 -pg -mrecord-mcount -mno-fentry -fpic -fno-plt -fno-shrink-wrap" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^(1|\t?\.)} } } */ + +/* +**foo: +**.LFB[0-9]+: +**... +** .cfi_.* +**1: call \*mcount@GOTPCREL\(%rip\) +**... +*/ + +void +foo (void) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/pr120936-9.c b/gcc/testsuite/gcc.target/i386/pr120936-9.c new file mode 100644 index 000000000000..3f4b38724e44 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120936-9.c @@ -0,0 +1,19 @@ +/* { dg-do compile { target { fpic && lp64 } } } */ +/* { dg-options "-O2 -mcmodel=large -pg -mno-fentry -fno-pic -fno-shrink-wrap" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**foo: +**.LFB[0-9]+: +**... +** .cfi_.* +** movabsq \$mcount, %r10 +** call \*%r10 +**... +*/ + +void +foo (void) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/pr121015.c b/gcc/testsuite/gcc.target/i386/pr121015.c new file mode 100644 index 000000000000..57c8bff14efc --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr121015.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v3" } */ + +extern union { + int i; + float f; +} int_as_float_u; + +extern int render_result_from_bake_w; +extern int render_result_from_bake_h_seed_pass; +extern float *render_result_from_bake_h_primitive; +extern float *render_result_from_bake_h_seed; + +float +int_as_float(int i) +{ + int_as_float_u.i = i; + return int_as_float_u.f; +} + +void +render_result_from_bake_h(int tx) +{ + while (render_result_from_bake_w) { + for (; tx < render_result_from_bake_w; tx++) + render_result_from_bake_h_primitive[1] = + render_result_from_bake_h_primitive[2] = int_as_float(-1); + if (render_result_from_bake_h_seed_pass) { + *render_result_from_bake_h_seed = 0; + } + } +} diff --git a/gcc/testsuite/gcc.target/i386/pr121062-1.c b/gcc/testsuite/gcc.target/i386/pr121062-1.c new file mode 100644 index 000000000000..799f8562c9f7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr121062-1.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v3" } */ + +extern union { + int i; + float f; +} int_as_float_u; + +extern int render_result_from_bake_w; +extern int render_result_from_bake_h_seed_pass; +extern float *render_result_from_bake_h_primitive; +extern float *render_result_from_bake_h_seed; + +float +int_as_float(int i) +{ + int_as_float_u.i = i; + return int_as_float_u.f; +} + +void +render_result_from_bake_h(int tx) +{ + while (render_result_from_bake_w) { + for (; tx < render_result_from_bake_w; tx++) + render_result_from_bake_h_primitive[1] = + render_result_from_bake_h_primitive[2] = int_as_float(-1); + if (render_result_from_bake_h_seed_pass) { + *render_result_from_bake_h_seed = 0; + } + } +} + +/* { dg-final { scan-assembler-times "movq\[ \\t\]+\\\$-1, %r\[a-z0-9\]+" 2 { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr121062-2.c b/gcc/testsuite/gcc.target/i386/pr121062-2.c new file mode 100644 index 000000000000..723d68a40031 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr121062-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-Og -fno-dce -mtune=generic" } */ + +typedef int __attribute__((__vector_size__ (4))) S; +extern void bar (S); + +void +foo () +{ + bar ((S){-1}); +} + +/* { dg-final { scan-assembler-times "movl\[ \\t\]+\\\$-1, \\(%esp\\)" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times "movl\[ \\t\]+\\\$-1, %edi" 1 { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr121062-3a.c b/gcc/testsuite/gcc.target/i386/pr121062-3a.c new file mode 100644 index 000000000000..effd4ff53673 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr121062-3a.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-O2 -march=x86-64 -fpic" } */ + +typedef struct { + struct { + unsigned short lo4; + unsigned short lo3; + unsigned short lo2; + unsigned short lo1; + } i; +} BID_BINARY80LDOUBLE; +extern BID_BINARY80LDOUBLE __bid64_to_binary80_x_out; +void +__bid64_to_binary80 (void) +{ + __bid64_to_binary80_x_out.i.lo4 + = __bid64_to_binary80_x_out.i.lo3 + = __bid64_to_binary80_x_out.i.lo2 + = __bid64_to_binary80_x_out.i.lo1 = 65535; +} + +/* { dg-final { scan-assembler-times "movq\[ \\t\]+%xmm\[0-9\]+, " 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times "movq\[ \\t\]+\\\$-1, \\(%(e|r)\[a-z0-9\]+\\)" 1 { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr121062-3b.c b/gcc/testsuite/gcc.target/i386/pr121062-3b.c new file mode 100644 index 000000000000..eb89b5da0914 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr121062-3b.c @@ -0,0 +1,6 @@ +/* { dg-do compile { target { fpic && lp64 } } } */ +/* { dg-options "-O2 -march=x86-64 -fno-pic -mcmodel=large" } */ + +#include "pr121062-3a.c" + +/* { dg-final { scan-assembler-times "movq\[ \\t\]+\\\$-1, \\(%r\[a-z0-9\]+\\)" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr121062-3c.c b/gcc/testsuite/gcc.target/i386/pr121062-3c.c new file mode 100644 index 000000000000..4c07029c4f54 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr121062-3c.c @@ -0,0 +1,6 @@ +/* { dg-do compile { target { fpic && lp64 } } } */ +/* { dg-options "-O2 -march=x86-64 -fpic -mcmodel=large" } */ + +#include "pr121062-3a.c" + +/* { dg-final { scan-assembler-times "movq\[ \\t\]+\\\$-1, \\(%r\[a-z0-9\]+\\)" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr121062-4.c b/gcc/testsuite/gcc.target/i386/pr121062-4.c new file mode 100644 index 000000000000..77a0c2e90bb1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr121062-4.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64" } */ + +typedef long long int __attribute__((__vector_size__ (8))) S; + +void +foo (S *c) +{ + *c = (S){0x12345678badbeefULL}; +} + + +/* { dg-final { scan-assembler-times "movq\[ \\t\]+%xmm\[0-9\]+, " 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times "movabsq\[ \\t\]+\\\$81985529250168559, %r\[a-z0-9\]+" 1 { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr121062-5.c b/gcc/testsuite/gcc.target/i386/pr121062-5.c new file mode 100644 index 000000000000..22c09a6bfec7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr121062-5.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64" } */ + +typedef int __attribute__((__vector_size__ (4))) S; + +void +foo (S *c) +{ + *c = (S){0x12345678}; +} + + +/* { dg-final { scan-assembler-times "movl\[ \\t\]+\\\$305419896, \\(%(e|r)\[a-z0-9\]+\\)" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr121062-6.c b/gcc/testsuite/gcc.target/i386/pr121062-6.c new file mode 100644 index 000000000000..780b496b504e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr121062-6.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-Og -fno-dce -mtune=generic" } */ + +typedef int __attribute__((__vector_size__ (8))) S; + +void +foo (S *c) +{ + *c = (S){0x12345678,0xbadbeefULL}; +} + +/* { dg-final { scan-assembler-times "movq\[ \\t\]+%xmm\[0-9\]+, " 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times "movabsq\[ \\t\]+\\\$841538639400031864, %r\[a-z0-9\]+" 1 { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr121062-7.c b/gcc/testsuite/gcc.target/i386/pr121062-7.c new file mode 100644 index 000000000000..f1834f8e173b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr121062-7.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64" } */ + +typedef __bf16 __attribute__((__vector_size__ (4))) S; + +void +foo (S *c) +{ + *c = (S){-0.1, 2.1}; +} + + +/* { dg-final { scan-assembler-times "movl\[ \\t\]+\\\$1074183629, \\(%(e|r)\[a-z0-9\]+\\)" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr64110.c b/gcc/testsuite/gcc.target/i386/pr64110.c index 99e391916cb7..11a6929835f4 100644 --- a/gcc/testsuite/gcc.target/i386/pr64110.c +++ b/gcc/testsuite/gcc.target/i386/pr64110.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O3 -march=core-avx2" } */ -/* { dg-final { scan-assembler "vmovd\[\\t \]" } } */ +/* { dg-final { scan-assembler "vmovd\[\\t \]" { target { ! ilp32 } } } } */ int foo (void); int a; diff --git a/gcc/testsuite/gcc.target/i386/pr82699-1.c b/gcc/testsuite/gcc.target/i386/pr82699-1.c index 272d0797ff8f..96e3ccb27076 100644 --- a/gcc/testsuite/gcc.target/i386/pr82699-1.c +++ b/gcc/testsuite/gcc.target/i386/pr82699-1.c @@ -1,5 +1,5 @@ /* { dg-do compile { target *-*-linux* } } */ -/* { dg-options "-O2 -fno-pic -fcf-protection -pg -fasynchronous-unwind-tables" } */ +/* { dg-options "-O2 -mfentry -fno-pic -fcf-protection -pg -fasynchronous-unwind-tables" } */ /* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 } } */ extern int bar (int); diff --git a/gcc/testsuite/gcc.target/i386/pr90693-3.c b/gcc/testsuite/gcc.target/i386/pr90693-3.c new file mode 100644 index 000000000000..601c83c1d586 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr90693-3.c @@ -0,0 +1,5 @@ +/* PR tree-optimization/90693 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mpopcnt" } */ + +#include "pr90693.c" diff --git a/gcc/testsuite/gcc.target/i386/pr90693-4.c b/gcc/testsuite/gcc.target/i386/pr90693-4.c new file mode 100644 index 000000000000..b149159d3b97 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr90693-4.c @@ -0,0 +1,5 @@ +/* PR tree-optimization/90693 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mpopcnt" } */ + +#include "pr90693-2.c" diff --git a/gcc/testsuite/gcc.target/i386/pr90693-5.c b/gcc/testsuite/gcc.target/i386/pr90693-5.c new file mode 100644 index 000000000000..0a6a637a44b6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr90693-5.c @@ -0,0 +1,5 @@ +/* PR tree-optimization/90693 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabm" } */ + +#include "pr90693.c" diff --git a/gcc/testsuite/gcc.target/i386/pr90693-6.c b/gcc/testsuite/gcc.target/i386/pr90693-6.c new file mode 100644 index 000000000000..4040b5226501 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr90693-6.c @@ -0,0 +1,5 @@ +/* PR tree-optimization/90693 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabm" } */ + +#include "pr90693-2.c" diff --git a/gcc/testsuite/gcc.target/i386/pr90773-15.c b/gcc/testsuite/gcc.target/i386/pr90773-15.c index 403cdb248a20..880f71d1567b 100644 --- a/gcc/testsuite/gcc.target/i386/pr90773-15.c +++ b/gcc/testsuite/gcc.target/i386/pr90773-15.c @@ -10,5 +10,5 @@ foo (int c) } /* { dg-final { scan-assembler-times "vpbroadcastb\[\\t \]+%.*, %xmm\[0-9\]+" 1 } } */ -/* { dg-final { scan-assembler-times "vmovdqu8\[\\t \]+%xmm\[0-9\]+, \\(%\[\^,\]+\\)" 1 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]+%xmm\[0-9\]+, \\(%\[\^,\]+\\)" 1 } } */ /* { dg-final { scan-assembler-times "movb\[\\t \]+%.*, 16\\(%\[\^,\]+\\)" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr90773-16.c b/gcc/testsuite/gcc.target/i386/pr90773-16.c index bb0aadbc77e9..77d584018b53 100644 --- a/gcc/testsuite/gcc.target/i386/pr90773-16.c +++ b/gcc/testsuite/gcc.target/i386/pr90773-16.c @@ -10,5 +10,5 @@ foo (void) } /* { dg-final { scan-assembler-times "(?:vpcmpeqd|vpternlogd)" 1 } } */ -/* { dg-final { scan-assembler-times "vmovdqu8\[\\t \]+%xmm\[0-9\]+, \\(%\[\^,\]+\\)" 1 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]+%xmm\[0-9\]+, \\(%\[\^,\]+\\)" 1 } } */ /* { dg-final { scan-assembler-times "movb\[\\t \]+\\\$-1, 16\\(%\[\^,\]+\\)" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr90773-17.c b/gcc/testsuite/gcc.target/i386/pr90773-17.c index 61b2bfd7485a..68ff7e091e59 100644 --- a/gcc/testsuite/gcc.target/i386/pr90773-17.c +++ b/gcc/testsuite/gcc.target/i386/pr90773-17.c @@ -11,5 +11,5 @@ foo (void) } /* { dg-final { scan-assembler-times "vpbroadcastd" 1 } } */ -/* { dg-final { scan-assembler-times "vmovdqu8\[\\t \]+%xmm\[0-9\]+, \\(%\[\^,\]+\\)" 1 } } */ +/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]+%xmm\[0-9\]+, \\(%\[\^,\]+\\)" 1 } } */ /* { dg-final { scan-assembler-times "vmovd\[\\t \]+%xmm\[0-9\]+, 16\\(%\[\^,\]+\\)" 1 { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr91384-1.c b/gcc/testsuite/gcc.target/i386/pr91384-1.c new file mode 100644 index 000000000000..4f8823d6da2a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr91384-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -mapxf" } */ + +void foo (void); +void bar (void); + +int +test (int a) +{ + int r; + + if (r = -a) + foo (); + else + bar (); + + return r; +} + +/* { dg-final { scan-assembler-not "testl" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr92080-10.c b/gcc/testsuite/gcc.target/i386/pr92080-10.c new file mode 100644 index 000000000000..b67f9d8d2851 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr92080-10.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-march=sapphirerapids -Ofast" } */ +/* { dg-final { scan-assembler-times "vpbroadcastw" 1 } } */ + +extern short write_picture_p_Vid_0; +extern unsigned short *write_picture_p_2_0_0; +extern int write_picture_p_0, write_picture_p_1, write_picture_i; +void write_picture() { + unsigned short cr_val = 1 << write_picture_p_Vid_0; + for (; write_picture_p_1;) + for (; write_picture_i < write_picture_p_0; write_picture_i++) + write_picture_p_2_0_0[write_picture_i] = cr_val; +} diff --git a/gcc/testsuite/gcc.target/i386/pr92080-11.c b/gcc/testsuite/gcc.target/i386/pr92080-11.c new file mode 100644 index 000000000000..8747fc47640a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr92080-11.c @@ -0,0 +1,33 @@ +/* { dg-do run { target { avx512f_runtime } } } */ +/* { dg-options "-mavx512f -mtune=icelake-server -O3" } */ + +struct s { + char s[sizeof(long double)]; +}; + +union u { + long double d; + struct s s; +}; + +int main() +{ + union u x = {0}; +#if __SIZEOF_LONG_DOUBLE__ == 16 + x.s = (struct s){"xxxxxxxxxxxxxxxx"}; +#elif __SIZEOF_LONG_DOUBLE__ == 12 + x.s = (struct s){"xxxxxxxxxxxx"}; +#elif __SIZEOF_LONG_DOUBLE__ == 8 + x.s = (struct s){"xxxxxxxx"}; +#elif __SIZEOF_LONG_DOUBLE__ == 4 + x.s = (struct s){"xxxx"}; +#endif + + union u y = x; + + for (unsigned char *p = (unsigned char *)&y + sizeof y; + p-- > (unsigned char *)&y;) + if (*p != (unsigned char)'x') + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr92080-12.c b/gcc/testsuite/gcc.target/i386/pr92080-12.c new file mode 100644 index 000000000000..cb09eb2f0a88 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr92080-12.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3 -mno-mmx -march=icelake-server" } */ +/* { dg-final { scan-assembler-times "vpbroadcastb" 1 } } */ + +signed char a; +signed char f (int i, int j) +{ + signed char c; + while (i != 0) + { + a ^= j; + ++c; + ++i; + } + return c; +} diff --git a/gcc/testsuite/gcc.target/i386/pr92080-13.c b/gcc/testsuite/gcc.target/i386/pr92080-13.c new file mode 100644 index 000000000000..24b7616c894d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr92080-13.c @@ -0,0 +1,32 @@ +/* { dg-do run { target { avx512f_runtime } } } */ +/* { dg-options "-mavx512f -mtune=icelake-server -O2 -save-temps" } */ +/* { dg-final { scan-assembler-times "vpbroadcastd" 2 } } */ + +#include + +#define CONTAINER_KIND union + +typedef CONTAINER_KIND container { int value; } container; + +void move(container* end, container* start) { + container* p; + for (p = end; p > start; p--) { + (p)->value = (p-1)->value; + } +} + +#define N 100 + +int main(int argc, char* argv[]) { + container vals[N]; + int i; + for (i=0; i + +extern __m512i sinkz; +extern __m256i sinky; +extern char f; + +void +foo(char c, int x) +{ + c += f; + sinkz = _mm512_set1_epi8(c); + if (x == 2) + f += 3; + sinky = _mm256_set1_epi8(c); +} diff --git a/gcc/testsuite/gcc.target/i386/pr92080-7.c b/gcc/testsuite/gcc.target/i386/pr92080-7.c new file mode 100644 index 000000000000..8691684e96bb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr92080-7.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v4 -O2" } */ +/* { dg-final { scan-assembler-times "vpbroadcastb" 1 } } */ + +#include + +extern __m512i sinkz; +extern __m256i sinky; +extern char f; +extern void bar (void); + +void +foo(char c, int x) +{ + c += f; + sinkz = _mm512_set1_epi8(c); + if (x == 2) + bar (); + sinky = _mm256_set1_epi8(c); +} diff --git a/gcc/testsuite/gcc.target/i386/pr92080-8.c b/gcc/testsuite/gcc.target/i386/pr92080-8.c new file mode 100644 index 000000000000..7ebb62cea753 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr92080-8.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v4 -O2" } */ +/* { dg-final { scan-assembler-times "vpbroadcastd" 1 } } */ +/* { dg-final { scan-assembler-times "vpbroadcastq" 1 } } */ + +typedef int v4si __attribute__((vector_size(16))); +typedef long long int v2di __attribute__((vector_size(16))); +extern v4si s; +extern v2di l; + +void +foo(void) +{ + l = __extension__(v2di){2,2}; + s = __extension__(v4si){2,2,2,2}; +} diff --git a/gcc/testsuite/gcc.target/i386/pr92080-9.c b/gcc/testsuite/gcc.target/i386/pr92080-9.c new file mode 100644 index 000000000000..f44ab563f545 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr92080-9.c @@ -0,0 +1,81 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v4 -O2" } */ +/* { dg-final { scan-assembler-times "vpbroadcastd" 1 } } */ +/* { dg-final { scan-assembler-times "vmovdqa\[\\t \]+" 8 } } */ +/* { dg-final { scan-assembler-times "vmovdqa64\[\\t \]+" 3 } } */ +/* { dg-final { scan-assembler-times "vmovdqa32\[\\t \]+" 1 } } */ + +typedef int v4si __attribute__((vector_size(16))); +typedef long long int v2di __attribute__((vector_size(16))); +typedef long long v2di __attribute__((vector_size(16))); +typedef long long v4di __attribute__((vector_size(32))); +typedef long long v8di __attribute__((vector_size(64))); +typedef int v4si __attribute__((vector_size(16))); +typedef int v8si __attribute__((vector_size(32))); +typedef int v16si __attribute__((vector_size(64))); +typedef short v8hi __attribute__((vector_size(16))); +typedef short v16hi __attribute__((vector_size(32))); +typedef short v32hi __attribute__((vector_size(64))); +typedef char v16qi __attribute__((vector_size(16))); +typedef char v32qi __attribute__((vector_size(32))); +typedef char v64qi __attribute__((vector_size(64))); + +extern v16qi b1; +extern v8hi h1; +extern v4si s1; +extern v2di l1; +extern v32qi b2; +extern v16hi h2; +extern v8si s2; +extern v4di l2; +extern v64qi b3; +extern v32hi h3; +extern v16si s3; +extern v8di l3; + +void +foo(void) +{ + b1 = __extension__(v16qi){0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22}; + h1 = __extension__(v8hi){0x2222, 0x2222, 0x2222, 0x2222, + 0x2222, 0x2222, 0x2222, 0x2222}; + s1 = __extension__(v4si){0x22222222,0x22222222,0x22222222,0x22222222}; + l1 = __extension__(v2di){0x2222222222222222ULL,0x2222222222222222ULL}; + b2 = __extension__(v32qi){0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22}; + h2 = __extension__(v16hi){0x2222, 0x2222, 0x2222, 0x2222, + 0x2222, 0x2222, 0x2222, 0x2222, + 0x2222, 0x2222, 0x2222, 0x2222, + 0x2222, 0x2222, 0x2222, 0x2222}; + s2 = __extension__(v8si){0x22222222,0x22222222,0x22222222,0x22222222, + 0x22222222,0x22222222,0x22222222,0x22222222}; + l2 = __extension__(v4di){0x2222222222222222ULL,0x2222222222222222ULL, + 0x2222222222222222ULL,0x2222222222222222ULL}; + b3 = __extension__(v64qi){0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22}; + h3 = __extension__(v32hi){0x2222, 0x2222, 0x2222, 0x2222, + 0x2222, 0x2222, 0x2222, 0x2222, + 0x2222, 0x2222, 0x2222, 0x2222, + 0x2222, 0x2222, 0x2222, 0x2222, + 0x2222, 0x2222, 0x2222, 0x2222, + 0x2222, 0x2222, 0x2222, 0x2222, + 0x2222, 0x2222, 0x2222, 0x2222, + 0x2222, 0x2222, 0x2222, 0x2222}; + s3 = __extension__(v16si){0x22222222,0x22222222,0x22222222,0x22222222, + 0x22222222,0x22222222,0x22222222,0x22222222, + 0x22222222,0x22222222,0x22222222,0x22222222, + 0x22222222,0x22222222,0x22222222,0x22222222}; + l3 = __extension__(v8di){0x2222222222222222ULL,0x2222222222222222ULL, + 0x2222222222222222ULL,0x2222222222222222ULL, + 0x2222222222222222ULL,0x2222222222222222ULL, + 0x2222222222222222ULL,0x2222222222222222ULL}; +} diff --git a/gcc/testsuite/gcc.target/i386/pr93492-3.c b/gcc/testsuite/gcc.target/i386/pr93492-3.c index b68da30bd365..cdca595bd970 100644 --- a/gcc/testsuite/gcc.target/i386/pr93492-3.c +++ b/gcc/testsuite/gcc.target/i386/pr93492-3.c @@ -10,4 +10,4 @@ f10_endbr (void) { } -/* { dg-final { scan-assembler "\t\.cfi_startproc\n\tendbr(32|64)\n.*\.LPFE0:\n\tnop\n1:\tcall\t\[^\n\]*__fentry__\[^\n\]*\n\tret\n" } } */ +/* { dg-final { scan-assembler "\t\.cfi_startproc\n\tendbr(32|64)\n.*\.LPFE0:\n\tnop\n\tcall\t\[^\n\]*__fentry__\[^\n\]*\n\tret\n" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr93492-5.c b/gcc/testsuite/gcc.target/i386/pr93492-5.c index ee9849ae852e..cc71f67c130a 100644 --- a/gcc/testsuite/gcc.target/i386/pr93492-5.c +++ b/gcc/testsuite/gcc.target/i386/pr93492-5.c @@ -9,4 +9,4 @@ foo (void) { } -/* { dg-final { scan-assembler "\t\.cfi_startproc\n.*\.LPFE0:\n\tnop\n1:\tcall\t\[^\n\]*__fentry__\[^\n\]*\n\tret\n" } } */ +/* { dg-final { scan-assembler "\t\.cfi_startproc\n.*\.LPFE0:\n\tnop\n\tcall\t\[^\n\]*__fentry__\[^\n\]*\n\tret\n" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr95483-5.c b/gcc/testsuite/gcc.target/i386/pr95483-5.c index b52e39dff79f..a21ad01b15d2 100644 --- a/gcc/testsuite/gcc.target/i386/pr95483-5.c +++ b/gcc/testsuite/gcc.target/i386/pr95483-5.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ /* { dg-options "-mavx512bw -mavx512vl -O2" } */ -/* { dg-final { scan-assembler-times "(?:vmovdqu8|vinserti128)\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ -/* { dg-final { scan-assembler-times "(?:vmovdqu8|vextracti128)\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*\\)(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "(?:vmovdqu|vinserti128)\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "(?:vmovdqu|vextracti128)\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*\\)(?:\n|\[ \\t\]+#)" 1 } } */ #include diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-1.c b/gcc/testsuite/gcc.target/i386/preserve-none-1.c new file mode 100644 index 000000000000..25c6494610d6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -fomit-frame-pointer" } */ + +extern void boring(void); + +extern void continuation(void *, void *, void *, void *) + __attribute__((preserve_none)); + +__attribute__((preserve_none)) +void entry(void *a, void *b, void *c, void *d) +{ + boring(); + continuation(a, b, c, d); +} + +/* { dg-final { scan-assembler-not "movq" } } */ +/* { dg-final { scan-assembler "jmp\[\\t \]+_?continuation" } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-10.c b/gcc/testsuite/gcc.target/i386/preserve-none-10.c new file mode 100644 index 000000000000..f22200a9ff15 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-10.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef void (*fn_t) (void *) __attribute__ ((preserve_none)); + +void +foo (void *frame) +{ +} + +fn_t func = foo; /* { dg-error "incompatible pointer type" } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-11.c b/gcc/testsuite/gcc.target/i386/preserve-none-11.c new file mode 100644 index 000000000000..3bc82ba671a1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-11.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef void (*fn_t) (void *) __attribute__ ((preserve_none)); + +__attribute__ ((preserve_none)) +void +foo (void *frame) +{ +} + +fn_t func = foo; diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-12.c b/gcc/testsuite/gcc.target/i386/preserve-none-12.c new file mode 100644 index 000000000000..b2fd0abcd065 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-12.c @@ -0,0 +1,49 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move" } */ + +extern void bar (void) __attribute__ ((preserve_none)); + +void +foo (void) +{ + bar (); +} + +/* foo must save and restore all caller saved registers since bar won't + preserve any. */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]+_?bar" } } */ +/* { dg-final { scan-assembler "call\[\\t \]+_?bar" } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)ax" } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ +/* { dg-final { scan-assembler-times "pushl\[\\t \]*%esi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%rsi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushl\[\\t \]*%edi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%rdi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r8" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r9" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r10" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r11" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r12" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r13" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r14" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r15" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)ax" } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ +/* { dg-final { scan-assembler-times "popl\[\\t \]*%esi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%rsi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popl\[\\t \]*%edi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%rdi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r8" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r9" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r10" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r11" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r12" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r13" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r14" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r15" 1 { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-13.c b/gcc/testsuite/gcc.target/i386/preserve-none-13.c new file mode 100644 index 000000000000..d0f309979c64 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-13.c @@ -0,0 +1,50 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move" } */ + +typedef void (*fn_t) (void) __attribute__ ((preserve_none)); +extern fn_t bar; + +void +foo (void) +{ + bar (); +} + +/* foo must save and restore all caller saved registers since bar won't + preserve any. */ +/* { dg-final { scan-assembler-not "jmp" } } */ +/* { dg-final { scan-assembler "call\[\\t \]+" } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)ax" } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ +/* { dg-final { scan-assembler-times "pushl\[\\t \]*%esi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%rsi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushl\[\\t \]*%edi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%rdi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r8" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r9" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r10" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r11" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r12" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r13" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r14" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r15" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)ax" } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ +/* { dg-final { scan-assembler-times "popl\[\\t \]*%esi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%rsi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popl\[\\t \]*%edi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%rdi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r8" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r9" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r10" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r11" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r12" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r13" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r14" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r15" 1 { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-14.c b/gcc/testsuite/gcc.target/i386/preserve-none-14.c new file mode 100644 index 000000000000..ca23b586fa16 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-14.c @@ -0,0 +1,49 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move" } */ + +typedef void (*fn_t) (void) __attribute__ ((preserve_none)); + +void +foo (fn_t bar) +{ + bar (); +} + +/* foo must save and restore all caller saved registers since bar won't + preserve any. */ +/* { dg-final { scan-assembler-not "jmp" } } */ +/* { dg-final { scan-assembler "call\[\\t \]+" } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)ax" } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ +/* { dg-final { scan-assembler-times "pushl\[\\t \]*%esi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%rsi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushl\[\\t \]*%edi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%rdi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r8" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r9" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r10" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r11" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r12" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r13" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r14" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r15" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)ax" } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ +/* { dg-final { scan-assembler-times "popl\[\\t \]*%esi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%rsi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popl\[\\t \]*%edi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%rdi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r8" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r9" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r10" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r11" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r12" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r13" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r14" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r15" 1 { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-15.c b/gcc/testsuite/gcc.target/i386/preserve-none-15.c new file mode 100644 index 000000000000..54527e3a8479 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-15.c @@ -0,0 +1,46 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -mgeneral-regs-only -mtune-ctrl=^prologue_using_move,^epilogue_using_move" } */ + +extern void bar (void) __attribute__ ((preserve_none)); + +__attribute__ ((no_caller_saved_registers)) +void +foo (void) +{ + bar (); +} + +/* foo must save and restore all caller saved registers since bar won't + preserve any. */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]+_?bar" } } */ +/* { dg-final { scan-assembler "call\[\\t \]+_?bar" } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)ax" 1 } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)cx" 1 } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)dx" 1 } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)si" 1 } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)di" 1 } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r8" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r9" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r10" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r11" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r12" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r13" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r14" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r15" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)ax" 1 } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)cx" 1 } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)dx" 1 } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)si" 1 } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)di" 1 } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r8" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r9" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r10" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r11" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r12" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r13" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r14" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r15" 1 { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-16.c b/gcc/testsuite/gcc.target/i386/preserve-none-16.c new file mode 100644 index 000000000000..680083646fc5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-16.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern void foo (void); /* { dg-note "previous declaration" } */ + +__attribute__ ((preserve_none)) +void +foo (void) /* { dg-error "conflicting types" } */ +{ +} + diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-17.c b/gcc/testsuite/gcc.target/i386/preserve-none-17.c new file mode 100644 index 000000000000..e105da1b7095 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-17.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern void foo (void) __attribute__ ((preserve_none)); /* { dg-note "previous declaration" } */ + +void +foo (void) /* { dg-error "conflicting types" } */ +{ +} + diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-18.c b/gcc/testsuite/gcc.target/i386/preserve-none-18.c new file mode 100644 index 000000000000..a2ac5e32ab56 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-18.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move" } */ +/* { dg-additional-options "-fno-PIE" { target ia32 } } */ + +extern void foo (void); + +__attribute__ ((preserve_none)) +void +bar (void) +{ + foo (); +} + +/* { dg-final { scan-assembler-not "push" } } */ +/* { dg-final { scan-assembler-not "pop" } } */ +/* { dg-final { scan-assembler-not "call\[\\t \]+_?foo" } } */ +/* { dg-final { scan-assembler "jmp\[\\t \]+_?foo" } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-19.c b/gcc/testsuite/gcc.target/i386/preserve-none-19.c new file mode 100644 index 000000000000..5e9cbd26fdaf --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-19.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move" } */ +/* { dg-additional-options "-fno-PIE" { target ia32 } } */ + +extern void bar (void) __attribute__ ((preserve_none)); + +__attribute__ ((no_callee_saved_registers)) +void +foo (void) +{ + bar (); +} + +/* { dg-final { scan-assembler-not "push" } } */ +/* { dg-final { scan-assembler-not "pop" } } */ +/* { dg-final { scan-assembler "jmp\[\\t \]+_?bar" } } */ +/* { dg-final { scan-assembler-not "call\[\\t \]+_?bar" } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-2.c b/gcc/testsuite/gcc.target/i386/preserve-none-2.c new file mode 100644 index 000000000000..027f1816ca23 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef void (*fn_t) (void *) __attribute__ ((preserve_none)); + +__attribute__ ((no_callee_saved_registers)) +void +foo (void *frame) +{ +} + +fn_t func = foo; /* { dg-error "incompatible pointer type" "" { target { ! ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-20.c b/gcc/testsuite/gcc.target/i386/preserve-none-20.c new file mode 100644 index 000000000000..0070ee7253ef --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-20.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move" } */ +/* { dg-additional-options "-fno-PIE" { target ia32 } } */ + +typedef void (*fn_t) (void) __attribute__ ((no_callee_saved_registers)); +extern fn_t bar; + +__attribute__ ((preserve_none)) +void +foo (void) +{ + bar (); +} + +/* { dg-final { scan-assembler-not "push" } } */ +/* { dg-final { scan-assembler-not "pop" } } */ +/* { dg-final { scan-assembler "jmp" } } */ +/* { dg-final { scan-assembler-not "call\[\\t \]+" } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-21.c b/gcc/testsuite/gcc.target/i386/preserve-none-21.c new file mode 100644 index 000000000000..4550d22fe4b0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-21.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move" } */ + +typedef void (*fn_t) (void) __attribute__ ((preserve_none)); + +__attribute__ ((no_callee_saved_registers)) +void +foo (fn_t bar) +{ + bar (); +} + +/* { dg-final { scan-assembler-not "push" } } */ +/* { dg-final { scan-assembler-not "pop" } } */ +/* { dg-final { scan-assembler "jmp" } } */ +/* { dg-final { scan-assembler-not "call\[\\t \]+" } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-22.c b/gcc/testsuite/gcc.target/i386/preserve-none-22.c new file mode 100644 index 000000000000..6ec8d0cfe959 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-22.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move" } */ +/* { dg-additional-options "-fno-PIE" { target ia32 } } */ + +extern void foo (void) __attribute__ ((no_caller_saved_registers)); + +__attribute__ ((preserve_none)) +void +bar (void) +{ + foo (); +} + +/* { dg-final { scan-assembler-not "push" } } */ +/* { dg-final { scan-assembler-not "pop" } } */ +/* { dg-final { scan-assembler-not "call\[\\t \]+_?foo" } } */ +/* { dg-final { scan-assembler "jmp\[\\t \]+_?foo" } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-23.c b/gcc/testsuite/gcc.target/i386/preserve-none-23.c new file mode 100644 index 000000000000..8e83879443fa --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-23.c @@ -0,0 +1,51 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move" } */ + +#include + +typedef void (*fn_t) (void) __attribute__ ((preserve_none)); + +void +foo (uintptr_t p) +{ + ((fn_t) p) (); +} + +/* foo must save and restore all caller saved registers since bar won't + preserve any. */ +/* { dg-final { scan-assembler-not "jmp" } } */ +/* { dg-final { scan-assembler "call\[\\t \]+" } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)ax" } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ +/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ +/* { dg-final { scan-assembler-times "pushl\[\\t \]*%esi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%rsi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushl\[\\t \]*%edi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%rdi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r8" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r9" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r10" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pushq\[\\t \]*%r11" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r12" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r13" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r14" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r15" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)ax" } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)cx" } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)dx" } } */ +/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)bp" } } */ +/* { dg-final { scan-assembler-times "popl\[\\t \]*%esi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%rsi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popl\[\\t \]*%edi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%rdi" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r8" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r9" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r10" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "popq\[\\t \]*%r11" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r12" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r13" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r14" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "popq\[\\t \]*%r15" 1 { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-24.c b/gcc/testsuite/gcc.target/i386/preserve-none-24.c new file mode 100644 index 000000000000..d7adfba8ddd4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-24.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +__attribute__ ((preserve_none, no_callee_saved_registers)) +void +foo (void) +{ /* { dg-error "attributes are not compatible" } */ +} diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-25.c b/gcc/testsuite/gcc.target/i386/preserve-none-25.c new file mode 100644 index 000000000000..e22da50427f9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-25.c @@ -0,0 +1,27 @@ +/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */ +/* { dg-options "-O2 -fno-pic -mtune=generic -msse2 -mno-apxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**entry: +**.LFB[0-9]+: +** .cfi_startproc +** movq %rdi, %r12 +** movq %rsi, %r13 +** movq %rdx, %r14 +** movq %rcx, %r15 +** jmp continuation +** .cfi_endproc +**... +*/ + +extern void continuation (void *, void *, void *, void *) + __attribute__ ((preserve_none)); + +__attribute__ ((no_callee_saved_registers)) +void +entry (void *a, void *b, void *c, void *d) +{ + continuation (a, b, c, d); +} diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-26.c b/gcc/testsuite/gcc.target/i386/preserve-none-26.c new file mode 100644 index 000000000000..926d127b5768 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-26.c @@ -0,0 +1,27 @@ +/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */ +/* { dg-options "-O2 -fno-pic -mtune=generic -msse2 -mno-apxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**entry: +**.LFB[0-9]+: +** .cfi_startproc +** movq %r15, %rcx +** movq %r14, %rdx +** movq %r13, %rsi +** movq %r12, %rdi +** jmp continuation +** .cfi_endproc +**... +*/ + +extern void continuation (void *, void *, void *, void *) + __attribute__ ((no_callee_saved_registers)); + +__attribute__ ((preserve_none)) +void +entry (void *a, void *b, void *c, void *d) +{ + continuation(a, b, c, d); +} diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-27.c b/gcc/testsuite/gcc.target/i386/preserve-none-27.c new file mode 100644 index 000000000000..17aa57d60ed4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-27.c @@ -0,0 +1,33 @@ +/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */ +/* { dg-options "-O2 -fno-pic -mtune=generic -msse2 -mno-apxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**entry: +**.LFB[0-9]+: +** .cfi_startproc +**... +** movl %edi, %r12d +** movl %esi, %r13d +** movl %edx, %r14d +** pushq \$-559038737 +**... +** movl %ecx, %r15d +** movl %r9d, %esi +** movl %r8d, %edi +** xorl %eax, %eax +**... +** call continuation +**... +*/ + +extern void continuation (int, int, int, int, int, int, ...) + __attribute__ ((preserve_none)); + +__attribute__ ((no_callee_saved_registers)) +void +entry (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) +{ + continuation (arg1, arg2, arg3, arg4, arg5, arg6, 0xdeadbeef); +} diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-28.c b/gcc/testsuite/gcc.target/i386/preserve-none-28.c new file mode 100644 index 000000000000..7042b8db667a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-28.c @@ -0,0 +1,48 @@ +/* { dg-do run { target { *-*-linux* && { ! ia32 } } } } */ +/* { dg-options "-O2 -fno-pic -mtune=generic -msse2 -mno-apxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */ + +#include + +__attribute__ ((preserve_none, weak)) +void +continuation (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) +{ + if (arg1 != 17) + abort (); + if (arg2 != 8) + abort (); + if (arg3 != 20) + abort (); + if (arg4 != -3) + abort (); + if (arg5 != -4) + abort (); + if (arg6 != 26) + abort (); +} + +__attribute__ ((no_callee_saved_registers, weak)) +void +entry (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) +{ + if (arg1 != 17) + abort (); + if (arg2 != 8) + abort (); + if (arg3 != 20) + abort (); + if (arg4 != -3) + abort (); + if (arg5 != -4) + abort (); + if (arg6 != 26) + abort (); + continuation (arg1, arg2, arg3, arg4, arg5, arg6); +} + +int +main (void) +{ + entry (17, 8, 20, -3, -4, 26); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-29.c b/gcc/testsuite/gcc.target/i386/preserve-none-29.c new file mode 100644 index 000000000000..e6520fa380be --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-29.c @@ -0,0 +1,57 @@ +/* { dg-do run { target { *-*-linux* && { ! ia32 } } } } */ +/* { dg-options "-O2 -fno-pic -mtune=generic -msse2 -mno-apxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */ + +#include +#include + +__attribute__ ((preserve_none, weak)) +void +continuation (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, + ...) +{ + int a; + va_list va_arglist; + va_start (va_arglist, arg6); + if (arg1 != 17) + abort (); + if (arg2 != 8) + abort (); + if (arg3 != 20) + abort (); + if (arg4 != -3) + abort (); + if (arg5 != -4) + abort (); + if (arg6 != 26) + abort (); + a = va_arg (va_arglist, int); + if (a != 0xdeadbeef) + abort (); + va_end (va_arglist); +} + +__attribute__ ((no_callee_saved_registers, weak)) +void +entry (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) +{ + if (arg1 != 17) + abort (); + if (arg2 != 8) + abort (); + if (arg3 != 20) + abort (); + if (arg4 != -3) + abort (); + if (arg5 != -4) + abort (); + if (arg6 != 26) + abort (); + continuation (arg1, arg2, arg3, arg4, arg5, arg6, 0xdeadbeef); +} + +int +main (void) +{ + entry (17, 8, 20, -3, -4, 26); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-3.c b/gcc/testsuite/gcc.target/i386/preserve-none-3.c new file mode 100644 index 000000000000..df484a5184ce --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-3.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mnoreturn-no-callee-saved-registers" } */ + +extern void bar (void) __attribute__ ((preserve_none)); +extern void fn (void) __attribute__ ((noreturn)); + +__attribute__ ((noreturn)) +void +foo (void) +{ + bar (); + fn (); +} + +/* { dg-final { scan-assembler-not "push\[^\n\r\]*(?:\[abcd\]x|\[sd\]i|sp|r\[0-9\]|\[xyz\]mm)" } } */ +/* { dg-final { scan-assembler-not "pop\[^\n\r\]*(?:\[abcd\]x|\[sd\]i|sp|r\[0-9\]|\[xyz\]mm)" } } */ +/* { dg-final { scan-assembler-not "jmp\[\\t \]+_?bar" } } */ +/* { dg-final { scan-assembler "call\[\\t \]+_?bar" } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-30a.c b/gcc/testsuite/gcc.target/i386/preserve-none-30a.c new file mode 100644 index 000000000000..2a21ef527082 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-30a.c @@ -0,0 +1,31 @@ +/* { dg-do compile { target { *-*-linux* && lp64 } } } */ +/* { dg-options "-O2 -fno-pic -mtune=generic -msse2 -mno-apxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**entry: +**.LFB[0-9]+: +** .cfi_startproc +** subq \$8, %rsp +** .cfi_def_cfa_offset 16 +** call boring +** addq \$8, %rsp +** .cfi_def_cfa_offset 8 +** jmp \*continuation\(%rip\) +** .cfi_endproc +**... +*/ + +extern void boring (void); + +extern void (*continuation) (void *, void *, void *, void *) + __attribute__ ((preserve_none)); + +__attribute__ ((preserve_none)) +void +entry (void *a, void *b, void *c, void *d) +{ + boring (); + continuation (a, b, c, d); +} diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-30b.c b/gcc/testsuite/gcc.target/i386/preserve-none-30b.c new file mode 100644 index 000000000000..425d0aa24a63 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-30b.c @@ -0,0 +1,21 @@ +/* { dg-do compile { target { *-*-linux* && maybe_x32 } } } */ +/* { dg-options "-O2 -mx32 -fno-pic -mtune=generic -msse2 -mno-apxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */ + +/* +**entry: +**.LFB[0-9]+: +** .cfi_startproc +** subl \$8, %esp +** .cfi_def_cfa_offset 16 +** call boring +** movl continuation\(%rip\), %eax +** addl \$8, %esp +** .cfi_def_cfa_offset 8 +** jmp \*%rax +** .cfi_endproc +**... +*/ + +#include "preserve-none-30a.c" diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-4.c b/gcc/testsuite/gcc.target/i386/preserve-none-4.c new file mode 100644 index 000000000000..35c3501f6f07 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-4.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mnoreturn-no-callee-saved-registers" } */ + +typedef void (*fn_t) (void) __attribute__ ((preserve_none)); +extern fn_t bar; +extern void fn (void) __attribute__ ((noreturn)); + +__attribute__ ((noreturn)) +void +foo (void) +{ + bar (); + fn (); +} + +/* { dg-final { scan-assembler-not "push\[^\n\r\]*(?:\[abcd\]x|\[sd\]i|sp|r\[0-9\]|\[xyz\]mm)" } } */ +/* { dg-final { scan-assembler-not "pop\[^\n\r\]*(?:\[abcd\]x|\[sd\]i|sp|r\[0-9\]|\[xyz\]mm)" } } */ +/* { dg-final { scan-assembler-not "jmp" } } */ +/* { dg-final { scan-assembler "call\[\\t \]+" } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-5.c b/gcc/testsuite/gcc.target/i386/preserve-none-5.c new file mode 100644 index 000000000000..1498886a986a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-5.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mnoreturn-no-callee-saved-registers" } */ + +typedef void (*fn_t) (void) __attribute__ ((preserve_none)); +extern void fn (void) __attribute__ ((noreturn)); + +__attribute__ ((noreturn)) +void +foo (fn_t bar) +{ + bar (); + fn (); +} + +/* { dg-final { scan-assembler-not "push\[^\n\r\]*(?:\[abcd\]x|\[sd\]i|sp|r\[0-9\]|\[xyz\]mm)" } } */ +/* { dg-final { scan-assembler-not "pop\[^\n\r\]*(?:\[abcd\]x|\[sd\]i|sp|r\[0-9\]|\[xyz\]mm)" } } */ +/* { dg-final { scan-assembler-not "jmp" } } */ +/* { dg-final { scan-assembler "call\[\\t \]+" } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-6.c b/gcc/testsuite/gcc.target/i386/preserve-none-6.c new file mode 100644 index 000000000000..037f9ecfa036 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-6.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer" } */ + +extern int bar (int) +#ifndef __x86_64__ +__attribute__ ((regparm(3))) +#endif +; + +__attribute__ ((preserve_none)) +void +foo (void *frame) +{ + int a,b,c,d,e,f,i; + a = bar (5); + b = bar (a); + c = bar (b); + d = bar (c); + e = bar (d); + f = bar (e); + for (i = 1; i < 10; i++) + { + a += bar (a + i) + bar (b + i) + + bar (c + i) + bar (d + i) + + bar (e + i) + bar (f + i); + } +} + +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*" 1 } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-7.c b/gcc/testsuite/gcc.target/i386/preserve-none-7.c new file mode 100644 index 000000000000..2c80560887c2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-7.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer" } */ + +extern int bar (int) __attribute__ ((no_caller_saved_registers)) +#ifndef __x86_64__ +__attribute__ ((regparm(3))) +#endif +; + +__attribute__ ((preserve_none)) +void +foo (void *frame) +{ + int a,b,c,d,e,f,i; + a = bar (5); + b = bar (a); + c = bar (b); + d = bar (c); + e = bar (d); + f = bar (e); + for (i = 1; i < 10; i++) + { + a += bar (a + i) + bar (b + i) + + bar (c + i) + bar (d + i) + + bar (e + i) + bar (f + i); + } +} + +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */ +/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*" 1 } } */ +/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-8.c b/gcc/testsuite/gcc.target/i386/preserve-none-8.c new file mode 100644 index 000000000000..9309ceba3887 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-8.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +__attribute__ ((preserve_none, no_caller_saved_registers)) +void +foo (void) +{ /* { dg-error "attributes are not compatible" } */ +} diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-9.c b/gcc/testsuite/gcc.target/i386/preserve-none-9.c new file mode 100644 index 000000000000..f28ddeb17ec9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/preserve-none-9.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mgeneral-regs-only" } */ + +__attribute__ ((preserve_none, interrupt)) +void +foo (void *frame) /* { dg-error "attributes are not compatible" } */ +{ +} diff --git a/gcc/testsuite/gcc.target/i386/shrink-wrap-separate-mingw.c b/gcc/testsuite/gcc.target/i386/shrink-wrap-separate-mingw.c new file mode 100644 index 000000000000..58635e49647a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/shrink-wrap-separate-mingw.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target *-*-mingw* *-*-cygwin* } } */ +/* { dg-options "-std=gnu99 -O2" } */ + +short __mingw_swformat_format; +__builtin_va_list __mingw_swformat_arg; +int __mingw_swformat_fc; +typedef struct { + void *fp; + int bch[1024]; +} _IFP; +void __mingw_swformat(_IFP *s) { + if (s->fp) + while (__mingw_swformat_format) + if (__mingw_swformat_fc == 'A') + *__builtin_va_arg(__mingw_swformat_arg, double *) = 0; +} +void +__mingw_vswscanf (void) +{ + _IFP ifp; + __mingw_swformat(&ifp); +} diff --git a/gcc/testsuite/gcc.target/i386/shrink_wrap_1.c b/gcc/testsuite/gcc.target/i386/shrink_wrap_1.c index 4b286671e90b..30b82ab695aa 100644 --- a/gcc/testsuite/gcc.target/i386/shrink_wrap_1.c +++ b/gcc/testsuite/gcc.target/i386/shrink_wrap_1.c @@ -1,5 +1,5 @@ /* { dg-do compile { target { ! ia32 } } } */ -/* { dg-options "-O2 -fdump-rtl-pro_and_epilogue -fno-stack-protector" } */ +/* { dg-options "-O2 -mmemset-strategy=rep_8byte:-1:align -fdump-rtl-pro_and_epilogue -fno-stack-protector" } */ enum machine_mode { diff --git a/gcc/testsuite/gcc.target/i386/shrink_wrap_separate_check_lea.c b/gcc/testsuite/gcc.target/i386/shrink_wrap_separate_check_lea.c new file mode 100644 index 000000000000..d61de57092cc --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/shrink_wrap_separate_check_lea.c @@ -0,0 +1,29 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -fdump-rtl-pro_and_epilogue" } */ + +/* Avoid inserting sub between test-je-jle to change EFlags, lea should be used here + xorl %eax, %eax + testl %edi, %edi + je .L11 + sub $16, %rsp ------> leaq -16(%rsp), %rsp + movq %r13, 8(%rsp) + movl $1, %r13d + jle .L4 +*/ +int foo (int num) +{ + if (!num) + return 0; + + register int r13 __asm ("r13") = 1; + + for ( int i = 0; i < num; i++) + { + register int r12 __asm ("r12") = 1; + asm volatile ("" : "+r" (r12), "+r" (r13)); + } + + return 1; +} +/* { dg-final { scan-rtl-dump "The components we wrap separately are \\\[sep 40\\\]" "pro_and_epilogue" } } */ +/* { dg-final { scan-assembler "lea(l|q).*(%rsp)" } } */ diff --git a/gcc/testsuite/gcc.target/i386/stack-clash-protection.c b/gcc/testsuite/gcc.target/i386/stack-clash-protection.c new file mode 100644 index 000000000000..5be28cb3ac7b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/stack-clash-protection.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fstack-clash-protection" } */ + +int flag; +void open(); +int getChar(); +typedef enum { QUOTE } CharType; +typedef enum { UNQ } State; +CharType getCharType(); +void expand() { + open(); + if (flag) + return; + int ch = getChar(); + State nextState = getCharType(); + if (nextState) + while (ch) + ; +} diff --git a/gcc/testsuite/gcc.target/i386/sw-1.c b/gcc/testsuite/gcc.target/i386/sw-1.c index b0432279644a..14db3cee206a 100644 --- a/gcc/testsuite/gcc.target/i386/sw-1.c +++ b/gcc/testsuite/gcc.target/i386/sw-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -mtune=generic -fshrink-wrap -fdump-rtl-pro_and_epilogue -fno-stack-protector" } */ +/* { dg-options "-O2 -mtune=generic -mstringop-strategy=rep_byte -fshrink-wrap -fdump-rtl-pro_and_epilogue -fno-stack-protector" } */ /* { dg-additional-options "-mno-avx" { target ia32 } } */ /* { dg-skip-if "No shrink-wrapping preformed" { x86_64-*-mingw* } } */ diff --git a/gcc/testsuite/gcc.target/i386/vect-epilogues-3.c b/gcc/testsuite/gcc.target/i386/vect-epilogues-3.c index 0ee610f5e3ef..e88ab30c770f 100644 --- a/gcc/testsuite/gcc.target/i386/vect-epilogues-3.c +++ b/gcc/testsuite/gcc.target/i386/vect-epilogues-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -mavx512bw -mtune=znver4 -fdump-tree-vect-optimized" } */ +/* { dg-options "-O3 -mavx512bw -mtune=znver4 --param vect-partial-vector-usage=0 -fdump-tree-vect-optimized" } */ int test (signed char *data, int n) { diff --git a/gcc/testsuite/gcc.target/i386/vect-mask-epilogue-1.c b/gcc/testsuite/gcc.target/i386/vect-mask-epilogue-1.c new file mode 100644 index 000000000000..55519aa87fdc --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/vect-mask-epilogue-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=znver5 -fdump-tree-vect-optimized" } */ + +void bar (double *a, double *b, double c, int n, int m) +{ + for (int j = 0; j < m; ++j) + for (int i = 0; i < n; ++i) + a[j*n + i] = b[j*n + i] + c; +} + +/* { dg-final { scan-tree-dump "epilogue loop vectorized using masked 64 byte vectors" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/i386/vect-mask-epilogue-2.c b/gcc/testsuite/gcc.target/i386/vect-mask-epilogue-2.c new file mode 100644 index 000000000000..3dc28b39b625 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/vect-mask-epilogue-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=znver5 -fdump-tree-vect-optimized" } */ + +void foo (double *a, double b, double c, int n, int m) +{ + for (int j = 0; j < m; ++j) + for (int i = 0; i < n; ++i) + a[j*n + i] = a[j*n + i] * b + c; +} + +/* We do not want to use a masked epilogue for the inner loop as the next + outer iteration will possibly immediately read from elements masked of + the previous inner loop epilogue and that never forwards. */ +/* { dg-final { scan-tree-dump "epilogue loop vectorized using 32 byte vectors" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/i386/vect-pr82426-2.c b/gcc/testsuite/gcc.target/i386/vect-pr82426-2.c new file mode 100644 index 000000000000..525940866ad7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/vect-pr82426-2.c @@ -0,0 +1,31 @@ +/* i?86 does not have V2SF, x32 does though. */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O3 -mavx -mfma -ffp-contract=on" } */ + +struct Matrix +{ + float m11; + float m12; + float m21; + float m22; + float dx; + float dy; +}; + +struct Matrix multiply(const struct Matrix *a, const struct Matrix *b) +{ + struct Matrix out; + out.m11 = a->m11*b->m11 + a->m12*b->m21; + out.m12 = a->m11*b->m12 + a->m12*b->m22; + out.m21 = a->m21*b->m11 + a->m22*b->m21; + out.m22 = a->m21*b->m12 + a->m22*b->m22; + + out.dx = a->dx*b->m11 + a->dy*b->m21 + b->dx; + out.dy = a->dx*b->m12 + a->dy*b->m22 + b->dy; + return out; +} + +/* The whole kernel should be vectorized with V4SF and V2SF operations. */ +/* { dg-final { scan-assembler-times "vadd" 1 } } */ +/* { dg-final { scan-assembler-times "vmul" 2 } } */ +/* { dg-final { scan-assembler-times "vfma" 2 } } */ diff --git a/gcc/testsuite/gcc.target/i386/vect-pr82426.c b/gcc/testsuite/gcc.target/i386/vect-pr82426.c index 03b10adff9b6..8ce8fe78a91b 100644 --- a/gcc/testsuite/gcc.target/i386/vect-pr82426.c +++ b/gcc/testsuite/gcc.target/i386/vect-pr82426.c @@ -1,6 +1,6 @@ /* i?86 does not have V2SF, x32 does though. */ /* { dg-do compile { target { ! ia32 } } } */ -/* { dg-options "-O3 -mavx -mfma" } */ +/* { dg-options "-O3 -mavx -mfma -ffp-contract=fast" } */ struct Matrix { diff --git a/gcc/testsuite/gcc.target/i386/vect-pragma-target-1.c b/gcc/testsuite/gcc.target/i386/vect-pragma-target-1.c new file mode 100644 index 000000000000..f5e71e453ec1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/vect-pragma-target-1.c @@ -0,0 +1,194 @@ +/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */ +/* { dg-options "-O0" } */ +/* { dg-final { scan-assembler-times "paddd.+xmm\[0-9]+" 1 } } */ +/* { dg-final { scan-assembler-times "vfmadd132ps.+ymm\[0-9]+" 1 } } */ +/* { dg-final { scan-assembler-times "vpaddw.+zmm\[0-9]+" 1 } } */ +#ifndef CHECK_DEFINES +#define CHECK_DEFINES 0 +#endif + +#define N 1024 + +/* Optimization flags and tree vectorizer shall be disabled at this point */ +#if CHECK_DEFINES && defined(__OPTIMIZE__) +#error "__OPTIMIZE__ is defined (not compiled with -O0?)" +#endif + +#pragma GCC push_options +#pragma GCC optimize ("O2", "tree-vectorize") + +/* Optimization flags and tree vectorizer shall be enabled at this point */ +#if CHECK_DEFINES && !defined(__OPTIMIZE__) +#error "__OPTIMIZE__ is not defined" +#endif + +#pragma GCC push_options +#pragma GCC target ("sse4.2") +#ifdef __cplusplus +namespace { +#endif + +/* Target flags up to including SSE4.2 shall be enabled at this point */ +#if CHECK_DEFINES && !defined(__SSE3__) +#error "Target flag (SSE3) is not defined" +#endif +#if CHECK_DEFINES && !defined(__SSSE3__) +#error "Target flag (SSSE3) is not defined" +#endif +#if CHECK_DEFINES && !defined(__SSE4_1__) +#error "Target flag (SSE4.1) is not defined" +#endif +#if CHECK_DEFINES && !defined(__SSE4_2__) +#error "Target flag (SSE4.2) is not defined" +#endif + +void +__attribute__((__noinline__, __used__)) +vec_saxpy_i32(int y[N], const int a[N], const int x[N]) +{ + int i; + for (i = 0; i < N; i++) + y[i] += a[i] * x[i]; +} + +#ifdef __cplusplus +} +#endif +#pragma GCC pop_options + +/* Target flags up to including SSE4.2 shall be disabled at this point */ +#if CHECK_DEFINES && defined(__SSE3__) +#error "Target flag (SSE3) is still defined" +#endif +#if CHECK_DEFINES && defined(__SSSE3__) +#error "Target flag (SSSE3) is still defined" +#endif +#if CHECK_DEFINES && defined(__SSE4_1__) +#error "Target flag (SSE4.1) is still defined" +#endif +#if CHECK_DEFINES && defined(__SSE4_2__) +#error "Target flag (SSE4.2) is still defined" +#endif + +#pragma GCC push_options +#pragma GCC target ("avx2", "fma") +#ifdef __cplusplus +struct A { +#endif + +/* Target flags up to including AVX2+FMA shall be enabled at this point */ +#if CHECK_DEFINES && !defined(__SSE3__) +#error "Target flag (SSE3) is not defined" +#endif +#if CHECK_DEFINES && !defined(__SSSE3__) +#error "Target flag (SSSE3) is not defined" +#endif +#if CHECK_DEFINES && !defined(__SSE4_1__) +#error "Target flag (SSE4.1) is not defined" +#endif +#if CHECK_DEFINES && !defined(__SSE4_2__) +#error "Target flag (SSE4.2) is not defined" +#endif +#if CHECK_DEFINES && !defined(__AVX__) +#error "Target flag (AVX) is not defined" +#endif +#if CHECK_DEFINES && !defined(__AVX2__) +#error "Target flag (AVX2) is not defined" +#endif +#if CHECK_DEFINES && !defined(__FMA__) +#error "Target flag (FMA) is not defined" +#endif + +void +__attribute__((__noinline__, __used__)) +vec_saxpy_f32(float y[N], const float a[N], const float x[N]) +{ + int i; + for (i = 0; i < N; i++) + y[i] += a[i] * x[i]; +} + +#ifdef __cplusplus +}; +#endif +#pragma GCC pop_options + +/* Target flags up to including AVX2+FMA shall be disabled at this point */ +#if CHECK_DEFINES && defined(__SSE3__) +#error "Target flag (SSE3) is still defined" +#endif +#if CHECK_DEFINES && defined(__SSSE3__) +#error "Target flag (SSSE3) is still defined" +#endif +#if CHECK_DEFINES && defined(__SSE4_1__) +#error "Target flag (SSE4.1) is still defined" +#endif +#if CHECK_DEFINES && defined(__SSE4_2__) +#error "Target flag (SSE4.2) is still defined" +#endif +#if CHECK_DEFINES && defined(__AVX__) +#error "Target flag (AVX) is still defined" +#endif +#if CHECK_DEFINES && defined(__AVX2__) +#error "Target flag (AVX2) is still defined" +#endif +#if CHECK_DEFINES && defined(__FMA__) +#error "Target flag (FMA) is still defined" +#endif + +#pragma GCC push_options +#pragma GCC target ("arch=x86-64-v4") +#ifdef __cplusplus +namespace avx512 { +struct A { +#endif + +/* Essential AVX512 target flags shall be enabled at this point */ +#if CHECK_DEFINES && !defined(__AVX512F__) +#error "Target flag (AVX512F) is not defined" +#endif +#if CHECK_DEFINES && !defined(__AVX512VL__) +#error "Target flag (AVX512VL) is not defined" +#endif +#if CHECK_DEFINES && !defined(__AVX512DQ__) +#error "Target flag (AVX512DQ) is not defined" +#endif +#if CHECK_DEFINES && !defined(__AVX512BW__) +#error "Target flag (AVX512BW) is not defined" +#endif + +void +__attribute__((__noinline__, __used__)) +vec_saxpy_i16(short y[N], const short a[N], const short x[N]) +{ + int i; + for (i = 0; i < N; i++) + y[i] += a[i] * x[i]; +} + +#ifdef __cplusplus +}; +} +#endif +#pragma GCC pop_options + +/* Essential AVX512 target flags shall be disabled at this point */ +#if CHECK_DEFINES && defined(__AVX512F__) +#error "Target flag (AVX512F) is still defined" +#endif +#if CHECK_DEFINES && defined(__AVX512VL__) +#error "Target flag (AVX512VL) is still defined" +#endif +#if CHECK_DEFINES && defined(__AVX512DQ__) +#error "Target flag (AVX512DQ) is still defined" +#endif +#if CHECK_DEFINES && defined(__AVX512BW__) +#error "Target flag (AVX512BW) is still defined" +#endif + +#pragma GCC pop_options + +/* Optimization flags and tree vectorizer shall be disabled at this point */ +#if CHECK_DEFINES && defined(__OPTIMIZE__) +#error "__OPTIMIZE__ is still defined" +#endif diff --git a/gcc/testsuite/gcc.target/i386/vect-pragma-target-2.c b/gcc/testsuite/gcc.target/i386/vect-pragma-target-2.c new file mode 100644 index 000000000000..349680453a49 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/vect-pragma-target-2.c @@ -0,0 +1,7 @@ +/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */ +/* { dg-options "-O0" } */ +/* { dg-final { scan-assembler-times "paddd.+xmm\[0-9]+" 1 } } */ +/* { dg-final { scan-assembler-times "vfmadd132ps.+ymm\[0-9]+" 1 } } */ +/* { dg-final { scan-assembler-times "vpaddw.+zmm\[0-9]+" 1 } } */ +#define CHECK_DEFINES 1 +#include "vect-pragma-target-1.c" diff --git a/gcc/testsuite/gcc.target/loongarch/pr121064.c b/gcc/testsuite/gcc.target/loongarch/pr121064.c new file mode 100644 index 000000000000..a466c7abc70e --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/pr121064.c @@ -0,0 +1,38 @@ +/* { dg-require-effective-target loongarch_sx_hw } */ +/* { dg-do run } */ +/* { dg-options "-march=loongarch64 -mfpu=64 -mlsx -O3" } */ + +typedef __INT32_TYPE__ int32_t; +typedef unsigned __INT32_TYPE__ uint32_t; + +__attribute__ ((noipa)) static int32_t +long_filter_ehigh_3830_1 (int32_t *buffer, int length) +{ + int i, j; + int32_t dotprod = 0; + int32_t delay[4] = { 0 }; + uint32_t coeffs[4] = { 0 }; + + for (i = 0; i < length; i++) + { + dotprod = 0; + for (j = 3; j >= 0; j--) + { + dotprod += delay[j] * coeffs[j]; + coeffs[j] += ((delay[j] >> 31) | 1); + } + for (j = 3; j > 0; j--) + delay[j] = delay[j - 1]; + delay[0] = buffer[i]; + } + + return dotprod; +} + +int +main () +{ + int32_t buffer[] = { -1, 1 }; + if (long_filter_ehigh_3830_1 (buffer, 2) != -1) + __builtin_trap (); +} diff --git a/gcc/testsuite/gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c b/gcc/testsuite/gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c index 4b9043797327..fab7a529e39c 100644 --- a/gcc/testsuite/gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c +++ b/gcc/testsuite/gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c @@ -27,10 +27,10 @@ int main () { int i; signed long sl; - signed char sc, expected_sc; - signed short ss, expected_ss; - signed int si, expected_si; - signed long long int sll, expected_sll; + signed char sc[2], expected_sc; + signed short ss[2], expected_ss; + signed int si[2], expected_si; + signed long long int sll[2], expected_sll; signed char *psc; signed short *pss; signed int *psi; @@ -41,56 +41,56 @@ main () { printf("Data to store [%d] = 0x%llx %llx\n", i, val.ull[1], val.ull[0]); #endif - psc = ≻ - pss = &ss; - psi = &si; - psll = &sll; + psc = &sc[0]; + pss = &ss[0]; + psi = &si[0]; + psll = &sll[0]; sl = 1; - sc = 0xA1; + sc[0] = 0xA1; expected_sc = 0xA1; __builtin_altivec_tr_stxvrbx (store_data, sl, psc); - if (expected_sc != sc & 0xFF) + if (expected_sc != sc[0] & 0xFF) #if DEBUG printf(" ERROR: Signed char = 0x%x doesn't match expected value 0x%x\n", - sc & 0xFF, expected_sc); + sc[0] & 0xFF, expected_sc); #else abort(); #endif - ss = 0x52; + ss[0] = 0x52; expected_ss = 0x1752; __builtin_altivec_tr_stxvrhx (store_data, sl, pss); - if (expected_ss != ss & 0xFFFF) + if (expected_ss != ss[0] & 0xFFFF) #if DEBUG printf(" ERROR: Signed short = 0x%x doesn't match expected value 0x%x\n", - ss, expected_ss) & 0xFFFF; + ss[0], expected_ss) & 0xFFFF; #else abort(); #endif - si = 0x21; + si[0] = 0x21; expected_si = 0x54321721; __builtin_altivec_tr_stxvrwx (store_data, sl, psi); - if (expected_si != si) + if (expected_si != si[0]) #if DEBUG printf(" ERROR: Signed int = 0x%x doesn't match expected value 0x%x\n", - si, expected_si); + si[0], expected_si); #else abort(); #endif - sll = 0x12FFULL; + sll[0] = 0x12FFULL; expected_sll = 0xdcba9876543217FF; __builtin_altivec_tr_stxvrdx (store_data, sl, psll); - if (expected_sll != sll) + if (expected_sll != sll[0]) #if DEBUG printf(" ERROR: Signed long long int = 0x%llx doesn't match expected value 0x%llx\n", - sll, expected_sll); + sll[0], expected_sll); #else abort(); #endif diff --git a/gcc/testsuite/gcc.target/powerpc/pr121007.c b/gcc/testsuite/gcc.target/powerpc/pr121007.c new file mode 100644 index 000000000000..9e6b1be7911f --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr121007.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */ + +typedef struct { int a; } A; +unsigned char *a; +char b; +int c; +void foo (vector char, vector char, vector char); + +void +bar (long stride) +{ + vector char v0, v1, v2, v3, v5; + vector char r0 = __builtin_vec_vsx_ld (0, a); + vector char r2 = __builtin_vec_vsx_ld (2 * stride, a - 3); + vector char r3 = __builtin_vec_vsx_ld (3 * stride, a - 3); + vector char r4; + vector char r6 = __builtin_vec_vsx_ld (6 * stride, a - 3); + vector char r7 = __builtin_vec_vsx_ld (7 * stride, a - 3); + vector char r14, h, i, j; + if (b) + return; + v1 = __builtin_vec_vsx_ld (9 * stride, a); + v2 = __builtin_vec_vsx_ld (10 * stride, a - 3); + v3 = __builtin_vec_vsx_ld (11 * stride, a - 3); + r3 = __builtin_vec_mergeh (r3, v3); + v5 = __builtin_vec_mergel (r2, r6); + r14 = __builtin_vec_mergeh (r3, r7); + r4 = __builtin_vec_mergeh (v2, r14); + v0 = __builtin_vec_mergeh (r0, r4); + union { unsigned char a[16]; A b; } temp; + vector signed char k; + h = __builtin_vec_ld (0, temp.a); + i = __builtin_vec_splat (h, 1); + temp.b.a = c; + k = __builtin_vec_ld (0, (signed char *) temp.a); + j = __builtin_vec_and (i, (vector char) k); + foo (v1, v0, j); + foo (v1, v5, j); +} diff --git a/gcc/testsuite/gcc.target/pru/mov64-subreg-1.c b/gcc/testsuite/gcc.target/pru/mov64-subreg-1.c new file mode 100644 index 000000000000..9b60aa033f15 --- /dev/null +++ b/gcc/testsuite/gcc.target/pru/mov64-subreg-1.c @@ -0,0 +1,9 @@ +/* { dg-do assemble } */ +/* { dg-options "-Os" } */ +/* { dg-final { object-size text == 8 } } */ + + +unsigned test(char a, unsigned long long b) +{ + return b; +} diff --git a/gcc/testsuite/gcc.target/pru/mov64-subreg-2.c b/gcc/testsuite/gcc.target/pru/mov64-subreg-2.c new file mode 100644 index 000000000000..146cf9456087 --- /dev/null +++ b/gcc/testsuite/gcc.target/pru/mov64-subreg-2.c @@ -0,0 +1,8 @@ +/* { dg-do assemble } */ +/* { dg-options "-Os" } */ +/* { dg-final { object-size text == 12 } } */ + +unsigned long long test(void) +{ + return 0xffffffff00000000UL; +} diff --git a/gcc/testsuite/gcc.target/pru/pragma-ctable_entry-2.c b/gcc/testsuite/gcc.target/pru/pragma-ctable_entry-2.c new file mode 100644 index 000000000000..a1c707d5c466 --- /dev/null +++ b/gcc/testsuite/gcc.target/pru/pragma-ctable_entry-2.c @@ -0,0 +1,22 @@ +/* Test for base addresses with bit 31 set (PR121124). */ + +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +/* -O1 in the options is significant. Without it LBCO/SBCO operations may + not be optimized to the respective instructions. */ + + +#pragma ctable_entry 12 0x80beef00 + +unsigned int +test_ctable (unsigned int val1, unsigned int val2) +{ + ((volatile unsigned short int *)0x80beef00)[0] = val2; + ((volatile unsigned int *)0x80beef00)[val1] = val2; + return ((volatile unsigned int *)0x80beef00)[5]; +} + +/* { dg-final { scan-assembler "sbco\\tr15.b\[012\]?, 12, 0, 2" } } */ +/* { dg-final { scan-assembler "sbco\\tr15.b0, 12, r14, 4" } } */ +/* { dg-final { scan-assembler "lbco\\tr14.b0, 12, 20, 4" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/amo/zabha-zacas-atomic-cas.c b/gcc/testsuite/gcc.target/riscv/amo/zabha-zacas-atomic-cas.c new file mode 100644 index 000000000000..d3d84fd30882 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/amo/zabha-zacas-atomic-cas.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* PR target/120995 ICE unrecognized subword atomic cas */ +/* { dg-options "-O" } */ +/* { dg-add-options riscv_zacas } */ +/* { dg-add-options riscv_zabha } */ + +_Bool b; +void atomic_bool_cmpxchg() +{ + __sync_bool_compare_and_swap(&b, 1, 0); +} diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-amo-add-int.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-amo-add-int.c index 4cf617d60357..0dfe816ba291 100644 --- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-amo-add-int.c +++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-amo-add-int.c @@ -9,7 +9,7 @@ /* ** atomic_add_fetch_int_relaxed: -** 1: +**... ** lr.w\t[atx][0-9]+, 0\(a0\) ** add\t[atx][0-9]+, [atx][0-9]+, a1 ** sc.w\t[atx][0-9]+, [atx][0-9]+, 0\(a0\) @@ -23,7 +23,7 @@ void atomic_add_fetch_int_relaxed (int* bar, int baz) /* ** atomic_add_fetch_int_acquire: -** 1: +**... ** lr.w.aq\t[atx][0-9]+, 0\(a0\) ** add\t[atx][0-9]+, [atx][0-9]+, a1 ** sc.w\t[atx][0-9]+, [atx][0-9]+, 0\(a0\) @@ -37,7 +37,7 @@ void atomic_add_fetch_int_acquire (int* bar, int baz) /* ** atomic_add_fetch_int_release: -** 1: +**... ** lr.w\t[atx][0-9]+, 0\(a0\) ** add\t[atx][0-9]+, [atx][0-9]+, a1 ** sc.w.rl\t[atx][0-9]+, [atx][0-9]+, 0\(a0\) @@ -51,7 +51,7 @@ void atomic_add_fetch_int_release (int* bar, int baz) /* ** atomic_add_fetch_int_acq_rel: -** 1: +**... ** lr.w.aq\t[atx][0-9]+, 0\(a0\) ** add\t[atx][0-9]+, [atx][0-9]+, a1 ** sc.w.rl\t[atx][0-9]+, [atx][0-9]+, 0\(a0\) @@ -65,7 +65,7 @@ void atomic_add_fetch_int_acq_rel (int* bar, int baz) /* ** atomic_add_fetch_int_seq_cst: -** 1: +**... ** lr.w.aqrl\t[atx][0-9]+, 0\(a0\) ** add\t[atx][0-9]+, [atx][0-9]+, a1 ** sc.w.rl\t[atx][0-9]+, [atx][0-9]+, 0\(a0\) diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-amo-add-int.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-amo-add-int.c index 3fb16c011918..658b0404b972 100644 --- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-amo-add-int.c +++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-amo-add-int.c @@ -9,7 +9,7 @@ /* ** atomic_add_fetch_int_relaxed: -** 1: +**... ** lr.w\t[atx][0-9]+, 0\(a0\) ** add\t[atx][0-9]+, [atx][0-9]+, a1 ** sc.w\t[atx][0-9]+, [atx][0-9]+, 0\(a0\) @@ -23,7 +23,7 @@ void atomic_add_fetch_int_relaxed (int* bar, int baz) /* ** atomic_add_fetch_int_acquire: -** 1: +**... ** lr.w\t[atx][0-9]+, 0\(a0\) ** add\t[atx][0-9]+, [atx][0-9]+, a1 ** sc.w\t[atx][0-9]+, [atx][0-9]+, 0\(a0\) @@ -37,7 +37,7 @@ void atomic_add_fetch_int_acquire (int* bar, int baz) /* ** atomic_add_fetch_int_release: -** 1: +**... ** lr.w\t[atx][0-9]+, 0\(a0\) ** add\t[atx][0-9]+, [atx][0-9]+, a1 ** sc.w\t[atx][0-9]+, [atx][0-9]+, 0\(a0\) @@ -51,7 +51,7 @@ void atomic_add_fetch_int_release (int* bar, int baz) /* ** atomic_add_fetch_int_acq_rel: -** 1: +**... ** lr.w\t[atx][0-9]+, 0\(a0\) ** add\t[atx][0-9]+, [atx][0-9]+, a1 ** sc.w\t[atx][0-9]+, [atx][0-9]+, 0\(a0\) @@ -65,7 +65,7 @@ void atomic_add_fetch_int_acq_rel (int* bar, int baz) /* ** atomic_add_fetch_int_seq_cst: -** 1: +**... ** lr.w.aqrl\t[atx][0-9]+, 0\(a0\) ** add\t[atx][0-9]+, [atx][0-9]+, a1 ** sc.w.rl\t[atx][0-9]+, [atx][0-9]+, 0\(a0\) diff --git a/gcc/testsuite/gcc.target/riscv/arch-53.c b/gcc/testsuite/gcc.target/riscv/arch-53.c index 8210978ee8ba..43ab23aee4d8 100644 --- a/gcc/testsuite/gcc.target/riscv/arch-53.c +++ b/gcc/testsuite/gcc.target/riscv/arch-53.c @@ -8,4 +8,4 @@ void foo(){} _ziccrse1p0_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0" _za64rs1p0_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcd1p0_zcmop1p0" _zba1p0_zbb1p0_zbs1p0_zkt1p0_zvbb1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0" -_zvfhmin1p0_zvkb1p0_zvkt1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0\"" } } */ +_zvfhmin1p0_zvkb1p0_zvkt1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_supm1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/arch-rva23s.c b/gcc/testsuite/gcc.target/riscv/arch-rva23s.c new file mode 100644 index 000000000000..215249d52b14 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-rva23s.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rva23s64 -mabi=lp64d" } */ + +void foo(){} + +/* { dg-final { scan-assembler-times ".attribute arch, \"rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0" +"_b1p0_v1p0_zic64b1p0_zicbom1p0_zicbop1p0_zicboz1p0_ziccamoa1p0_ziccif1p0_zicclsm1p0" +"_ziccrse1p0_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0" +"_za64rs1p0_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcd1p0_zcmop1p0" +"_zba1p0_zbb1p0_zbs1p0_zkt1p0_zvbb1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0" +"_zvfhmin1p0_zvkb1p0_zvkt1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_sha1p0_shcounterenw1p0" +"_shgatpa1p0_shtvala1p0_shvsatpa1p0_shvstvala1p0_shvstvecd1p0_ssccptr1p0_sscofpmf1p0" +"_sscounterenw1p0_ssnpm1p0_ssstateen1p0_sstc1p0_sstvala1p0_sstvecd1p0_ssu64xl1p0_supm1p0" +"_svade1p0_svbare1p0_svinval1p0_svnapot1p0_svpbmt1p0\" 1} } */ diff --git a/gcc/testsuite/gcc.target/riscv/arch-rvb23s.c b/gcc/testsuite/gcc.target/riscv/arch-rvb23s.c new file mode 100644 index 000000000000..aa71f7dad7d7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-rvb23s.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rvb23s64 -mabi=lp64d" } */ + +void foo(){} + +/* { dg-final { scan-assembler-times ".attribute arch, \"rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0" +"_b1p0_zic64b1p0_zicbom1p0_zicbop1p0_zicboz1p0_ziccamoa1p0_ziccif1p0_zicclsm1p0_ziccrse1p0" +"_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0_zmmul1p0" +"_za64rs1p0_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcd1p0_zcmop1p0" +"_zba1p0_zbb1p0_zbs1p0_zkt1p0_zvbb1p0_zve32f1p0_zve32x1p0_zvfhmin1p0_zvkb1p0_zvkt1p0" +"_zvl32b1p0_ssccptr1p0_sscofpmf1p0_sscounterenw1p0_sstc1p0_sstvala1p0_sstvecd1p0" +"_ssu64xl1p0_supm1p0_svade1p0_svbare1p0_svinval1p0_svnapot1p0_svpbmt1p0\" 1} } */ diff --git a/gcc/testsuite/gcc.target/riscv/arch-smcsrind.c b/gcc/testsuite/gcc.target/riscv/arch-smcsrind.c new file mode 100644 index 000000000000..4d1c10453993 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-smcsrind.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i_smcsrind -mabi=lp64" } */ +int foo() +{ +} diff --git a/gcc/testsuite/gcc.target/riscv/arch-smrnmi.c b/gcc/testsuite/gcc.target/riscv/arch-smrnmi.c new file mode 100644 index 000000000000..8e6254043fa3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-smrnmi.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i_smrnmi -mabi=lp64" } */ +int foo() +{ +} diff --git a/gcc/testsuite/gcc.target/riscv/arch-ssccptr.c b/gcc/testsuite/gcc.target/riscv/arch-ssccptr.c new file mode 100644 index 000000000000..902155a0818c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-ssccptr.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i_ssccptr -mabi=lp64" } */ +int foo() +{ +} diff --git a/gcc/testsuite/gcc.target/riscv/arch-sscounterenw.c b/gcc/testsuite/gcc.target/riscv/arch-sscounterenw.c new file mode 100644 index 000000000000..901b6bc6c9e0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-sscounterenw.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i_sscounterenw -mabi=lp64" } */ +int foo() +{ +} diff --git a/gcc/testsuite/gcc.target/riscv/arch-sstvala.c b/gcc/testsuite/gcc.target/riscv/arch-sstvala.c new file mode 100644 index 000000000000..21ea8a6360c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-sstvala.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i_sstvala -mabi=lp64" } */ +int foo() +{ +} diff --git a/gcc/testsuite/gcc.target/riscv/arch-sstvecd.c b/gcc/testsuite/gcc.target/riscv/arch-sstvecd.c new file mode 100644 index 000000000000..e76f78818ee1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-sstvecd.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i_sstvecd -mabi=lp64" } */ +int foo() +{ +} diff --git a/gcc/testsuite/gcc.target/riscv/arch-ssu64xl.c b/gcc/testsuite/gcc.target/riscv/arch-ssu64xl.c new file mode 100644 index 000000000000..6e151c14f9b7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-ssu64xl.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i_ssu64xl -mabi=lp64" } */ +int foo() +{ +} diff --git a/gcc/testsuite/gcc.target/riscv/jump-table-large-code-model.c b/gcc/testsuite/gcc.target/riscv/jump-table-large-code-model.c index 1ee7f6c07d3d..ab97b0fc0bb8 100644 --- a/gcc/testsuite/gcc.target/riscv/jump-table-large-code-model.c +++ b/gcc/testsuite/gcc.target/riscv/jump-table-large-code-model.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64 -mcmodel=large" } */ +/* { dg-options "-march=rv64gc -mabi=lp64 -mcmodel=large -fno-pie" } */ int foo(int x, int y) { diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-xiangshan-kunminghu.c b/gcc/testsuite/gcc.target/riscv/mcpu-xiangshan-kunminghu.c new file mode 100644 index 000000000000..e3ae65c46444 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/mcpu-xiangshan-kunminghu.c @@ -0,0 +1,95 @@ +/* { dg-do compile { target { rv64 } } } */ +/* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */ +/* { dg-options "-mcpu=xiangshan-kunminghu" } */ +/* XiangShan Kunminghu => rv64imafdcbvh_sdtrig_sha_shcounterenw_shgatpa + _shlcofideleg_shtvala_shvsatpa_shvstvala_shvstvecd + _smaia_smcsrind_smdbltrp_smmpm_smnpm_smrnmi_smstateen + _ssaia_ssccptr_sscofpmf_sscounterenw_sscsrind_ssdbltrp + _ssnpm_sspm_ssstateen_ssstrict_sstc_sstvala_sstvecd + _ssu64xl_supm_svade_svbare_svinval_svnapot_svpbmt + _za64rs_zacas_zawrs_zba_zbb_zbc_zbkb_zbkc_zbkx_zbs_zcb + _zcmop_zfa_zfh_zfhmin_zic64b_zicbom_zicbop_zicboz_ziccif + _zicclsm_ziccrse_zicntr_zicond_zicsr_zifencei_zihintpause + _zihpm_zimop_zkn_zknd_zkne_zknh_zksed_zksh_zkt_zvbb + _zvfh_zvfhmin_zvkt_zvl128b_zvl32b_zvl64b */ + +#if !((__riscv_xlen == 64) \ + && !defined(__riscv_32e) \ + && defined(__riscv_mul) \ + && defined(__riscv_atomic) \ + && (__riscv_flen == 64) \ + && defined(__riscv_compressed) \ + && defined(__riscv_v) \ + && defined(__riscv_zic64b) \ + && defined(__riscv_zicbom) \ + && defined(__riscv_zicbop) \ + && defined(__riscv_zicboz) \ + && defined(__riscv_ziccif) \ + && defined(__riscv_zicclsm) \ + && defined(__riscv_ziccrse) \ + && defined(__riscv_zicntr) \ + && defined(__riscv_zicond) \ + && defined(__riscv_zicsr) \ + && defined(__riscv_zifencei) \ + && defined(__riscv_zihintpause) \ + && defined(__riscv_zihpm) \ + && defined(__riscv_zimop) \ + && defined(__riscv_za64rs) \ + && defined(__riscv_zacas) \ + && defined(__riscv_zawrs) \ + && defined(__riscv_zba) \ + && defined(__riscv_zbb) \ + && defined(__riscv_zbc) \ + && defined(__riscv_zbs) \ + && defined(__riscv_zbkb) \ + && defined(__riscv_zbkc) \ + && defined(__riscv_zbkx) \ + && defined(__riscv_zcb) \ + && defined(__riscv_zcmop) \ + && defined(__riscv_zfa) \ + && defined(__riscv_zfh) \ + && defined(__riscv_zknd) \ + && defined(__riscv_zkne) \ + && defined(__riscv_zknh) \ + && defined(__riscv_zksed) \ + && defined(__riscv_zksh) \ + && defined(__riscv_zkt) \ + && defined(__riscv_zvbb) \ + && defined(__riscv_zvfh) \ + && defined(__riscv_zvkt) \ + && defined(__riscv_sdtrig) \ + && defined(__riscv_sha) \ + && defined(__riscv_shlcofideleg) \ + && defined(__riscv_smaia) \ + && defined(__riscv_smcsrind) \ + && defined(__riscv_smdbltrp) \ + && defined(__riscv_smmpm) \ + && defined(__riscv_smnpm) \ + && defined(__riscv_smrnmi) \ + && defined(__riscv_smstateen) \ + && defined(__riscv_ssaia) \ + && defined(__riscv_ssccptr) \ + && defined(__riscv_sscofpmf) \ + && defined(__riscv_sscounterenw) \ + && defined(__riscv_sscsrind) \ + && defined(__riscv_ssdbltrp) \ + && defined(__riscv_ssnpm) \ + && defined(__riscv_sspm) \ + && defined(__riscv_ssstrict) \ + && defined(__riscv_sstc) \ + && defined(__riscv_sstvala) \ + && defined(__riscv_sstvecd) \ + && defined(__riscv_ssu64xl) \ + && defined(__riscv_supm) \ + && defined(__riscv_svade) \ + && defined(__riscv_svbare) \ + && defined(__riscv_svinval) \ + && defined(__riscv_svnapot) \ + && defined(__riscv_svpbmt)) +#error "unexpected arch" +#endif + +int main() +{ + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c908.c b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c908.c index cb28baf1ce72..4ad82a81dec8 100644 --- a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c908.c +++ b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c908.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { ! riscv_abi_e } } } */ /* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */ /* { dg-options "-mcpu=xt-c908" { target { rv64 } } } */ /* XuanTie C908 => rv64imafdc_zicbom_zicbop_zicboz_zicntr_zicsr_zifencei_ diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c908v.c b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c908v.c index 1b1ee188229f..bb9e3109920a 100644 --- a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c908v.c +++ b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c908v.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { ! riscv_abi_e } } } */ /* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */ /* { dg-options "-mcpu=xt-c908v" { target { rv64 } } } */ /* XuanTie C908v => rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicsr_zifencei_ diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c910.c b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c910.c index 1e276659c3ea..397e7b192670 100644 --- a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c910.c +++ b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c910.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { ! riscv_abi_e } } } */ /* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */ /* { dg-options "-mcpu=xt-c910" { target { rv64 } } } */ /* XuanTie C910 => rv64imafdc_zicntr_zicsr_zifencei_zihpm_zfh_xtheadba_ diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c910v2.c b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c910v2.c index 6a54f0988780..9e39c9f89eb4 100644 --- a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c910v2.c +++ b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c910v2.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { ! riscv_abi_e } } } */ /* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */ /* { dg-options "-mcpu=xt-c910v2" { target { rv64 } } } */ /* XuanTie C910v2 => rv64imafdc_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_ diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c920.c b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c920.c index 6bcd687e7424..4cce90a1e945 100644 --- a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c920.c +++ b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c920.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { ! riscv_abi_e } } } */ /* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */ /* { dg-options "-mcpu=xt-c920" { target { rv64 } } } */ /* XuanTie c920 => rv64imafdc_zicntr_zicsr_zifencei_zihpm_zfh_"xtheadba_xtheadbb_xtheadbs_xtheadcmo_xtheadcondmov_xtheadfmemidx_xtheadmac_xtheadmemidx_xtheadmempair_xtheadsync_xtheadvector */ diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c920v2.c b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c920v2.c index 36a6267849bf..1f21d07f37ad 100644 --- a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c920v2.c +++ b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c920v2.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { ! riscv_abi_e } } } */ /* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */ /* { dg-options "-mcpu=xt-c920v2" { target { rv64 } } } */ /* XuanTie C920v2 => rv64imafdcv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei _zihintntl_zihintpause_zihpm_zawrs_zfa_zfbfmin_zfh_zca_zcb_zcd_zba_zbb_zbc_zbs_zvfbfmin_zvfbfwma_zvfh_sscofpmf_sstc_svinval_svnapot_svpbmt_xtheadba_xtheadbb_xtheadbs_xtheadcmo_xtheadcondmov_xtheadfmemidx_xtheadsync_xtheadvdot */ diff --git a/gcc/testsuite/gcc.target/riscv/mipscondmov.c b/gcc/testsuite/gcc.target/riscv/mipscondmov.c new file mode 100644 index 000000000000..548513352ea8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/mipscondmov.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32imafd_xmipscmov" { target { rv32 } } } */ +/* { dg-options "-march=rv64imafd_xmipscmov -mabi=lp64d" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +#define MYTEST(name, mytype) \ +mytype test1_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a == b) ? c : d; } \ +mytype test2_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a != b) ? c : d; } \ +mytype test3_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a > b) ? c : d; } \ +mytype test4_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a >= b) ? c : d; } \ +mytype test5_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a < b) ? c : d; } \ +mytype test6_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a <= b) ? c : d; } \ +mytype test7_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a == 1) ? c : d; } \ +mytype test8_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a != 1) ? c : d; } \ +mytype test9_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a > 1) ? c : d; } \ +mytype test10_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a >= 1) ? c : d; } \ +mytype test11_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a < 1) ? c : d; } \ +mytype test12_ ## name (mytype a, mytype b, mytype c, mytype d) { return (a <= 1) ? c : d; } + +MYTEST(1, long) +MYTEST(2, unsigned long) +MYTEST(3, int) +MYTEST(4, unsigned int) +MYTEST(5, short) +MYTEST(6, unsigned short) +MYTEST(7, signed char) +MYTEST(8, unsigned char) + +/* { dg-final { scan-assembler-times "mips.ccmov" 96 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/nozicond-1.c b/gcc/testsuite/gcc.target/riscv/nozicond-1.c new file mode 100644 index 000000000000..35ab6fe56949 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/nozicond-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { rv64 } } } */ +/* { dg-additional-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ + + +long foo1 (long c) { return c >= 0 ? 1 : -1; } +long foo2 (long c) { return c < 0 ? -1 : 1; } + +/* { dg-final { scan-assembler-times {srai\t} 2 } } */ +/* { dg-final { scan-assembler-times {ori\t} 2 } } */ + diff --git a/gcc/testsuite/gcc.target/riscv/nozicond-2.c b/gcc/testsuite/gcc.target/riscv/nozicond-2.c new file mode 100644 index 000000000000..f70525342a85 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/nozicond-2.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target { rv64 } } } */ +/* { dg-additional-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ + + +long foo1 (long c) { return c < 0 ? 1 : -1; } +long foo2 (long c) { return c >= 0 ? -1 : 1; } + +/* We don't support 4->3 splitters, so this fails. We could perhaps + try to catch it in the expander as a special case rather than waiting + for combine. */ +/* { dg-final { scan-assembler-times {srai\t} 2 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times {ori\t} 2 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times {not\t} 2 { xfail *-*-* } } } */ + diff --git a/gcc/testsuite/gcc.target/riscv/nozicond-3.c b/gcc/testsuite/gcc.target/riscv/nozicond-3.c new file mode 100644 index 000000000000..5116742bc3e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/nozicond-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { rv64 } } } */ +/* { dg-additional-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" "-Os" "-Oz" } } */ + +long foo1 (long n) { return n / 4096; } + +/* { dg-final { scan-assembler-times {srai\t} 2 } } */ +/* { dg-final { scan-assembler-times {srli\t} 1 } } */ +/* { dg-final { scan-assembler-times {add\t} 1 } } */ +/* { dg-final { scan-assembler-not {czero} } } */ + diff --git a/gcc/testsuite/gcc.target/riscv/pr118241-b.cc b/gcc/testsuite/gcc.target/riscv/pr118241-b.cc new file mode 100644 index 000000000000..b2cc73faa3a9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr118241-b.cc @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64imafdc_zba_zbb_zbs_zicbom_zicbop -mabi=lp64d" } */ + +/* Reduced from libsanitizer::asan_allocator. */ + +enum a { c }; +class d; +struct e { + long count; + void *batch[]; +}; +template class f { +public: + void g() { + if (e *b = h->i()) + for (; b->count;) + if (6 < b->count) + __builtin_prefetch(b->batch[6]); + } + d *h; +}; +class d { +public: + e *i(); +}; +struct j { + f k; + j(a); + void l() { k.g(); } +} a(c); +void m() { a.l(); } + +/* { dg-final { scan-assembler-times "prefetch.r\t0\\(\[a-x0-9\]+\\)" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/pr118241.c b/gcc/testsuite/gcc.target/riscv/pr118241.c new file mode 100644 index 000000000000..768ea050f1aa --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr118241.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target { ! riscv_abi_e } } } */ +/* { dg-options "-march=rv64gc_zicbop" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicbop" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ + +void test1() { __builtin_prefetch((int *)2047); } +void test2() { __builtin_prefetch((int *)1024); } +void test3(char *x) { __builtin_prefetch(&x); } +void test4(char *x) { __builtin_prefetch(&x[2]); } +void test5(char *x) { __builtin_prefetch(&x[1024]); } + +/* So we expect test1, test3 and test4 to be a prefetch + with zero offset. test2 and test5 will have a 1k offset. */ +/* { dg-final { scan-assembler-times "prefetch.r\t0\\(\[a-x0-9\]+\\)" 3 } } */ +/* { dg-final { scan-assembler-times "prefetch.r\t1024" 2 } } */ + diff --git a/gcc/testsuite/gcc.target/riscv/pr119830.c b/gcc/testsuite/gcc.target/riscv/pr119830.c new file mode 100644 index 000000000000..8c7cf3bd79d0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr119830.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbb_zbs -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zbb_zbs -mabi=ilp32" { target { rv32 } } } */ + +#include +void test(int32_t N, int16_t* A, int16_t val) { + int32_t i, j; + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + A[i * N + j] += val; + } + } +} diff --git a/gcc/testsuite/gcc.target/riscv/pr119971.c b/gcc/testsuite/gcc.target/riscv/pr119971.c index c3f23b05ec37..0d73d4ca3f13 100644 --- a/gcc/testsuite/gcc.target/riscv/pr119971.c +++ b/gcc/testsuite/gcc.target/riscv/pr119971.c @@ -1,6 +1,6 @@ /* { dg-do compile { target rv64 } } */ /* { dg-options "-march=rv64gcb -mabi=lp64" } */ -/* { dg-skip-if "" { *-*-* } { "-O0" "-g" "-Oz" "-Os" } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Oz" "-Os" } } */ __attribute__ ((noipa)) unsigned foo (unsigned b, unsigned e, unsigned i) diff --git a/gcc/testsuite/gcc.target/riscv/pr120223.c b/gcc/testsuite/gcc.target/riscv/pr120223.c index fae21b6d1ece..d6afd866c585 100644 --- a/gcc/testsuite/gcc.target/riscv/pr120223.c +++ b/gcc/testsuite/gcc.target/riscv/pr120223.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { ! riscv_abi_e } } } */ /* { dg-options "-mcpu=thead-c906" } */ long foo(long x) { return x ^ 0x80000000; } diff --git a/gcc/testsuite/gcc.target/riscv/pr120659.c b/gcc/testsuite/gcc.target/riscv/pr120659.c new file mode 100644 index 000000000000..91e6e42d4f95 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr120659.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=sifive-x280 -mabi=lp64" } */ + +_Float16 f; +void foo() { f /= 3; } diff --git a/gcc/testsuite/gcc.target/riscv/pr120714.c b/gcc/testsuite/gcc.target/riscv/pr120714.c new file mode 100644 index 000000000000..dd71a3e11d3d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr120714.c @@ -0,0 +1,40 @@ +/* Test checking that the backtrace on large frame size with additional + SP shift in the prologue won't broken when compiled with the + -fstack-clash-protection option. */ +/* { dg-do run { target { *-*-linux* } } } */ +/* -O0 does not have enough optimizations. + -O2/-O3 does inline and reduces number of addresses in the backtrace. */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O2" "-O3" } } */ +/* { dg-options "-g -fstack-clash-protection" } */ + +#include + +#define MAX 4000 + +void goo () +{ + int addresses; + void *buffer[10]; + + addresses = backtrace (buffer, 10); + if (addresses != 6) + __builtin_abort (); +} + +int foo (int a) +{ + long long A[MAX]; + for (int i = 0; i < MAX; i++) + A[i] = i; + + goo (); + + return A[a % MAX]; +} + +int main () +{ + if (foo (20) != 20) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg.h index 4aeb637bba7e..2de7d7c49df8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg.h @@ -3,6 +3,11 @@ #include +#if __riscv_xlen == 64 +typedef unsigned __int128 uint128_t; +typedef signed __int128 int128_t; +#endif + #define DEF_AVG_0(NT, WT, NAME) \ __attribute__((noinline)) \ void \ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i16-from-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i16-from-i32.c index 138124c8c4a0..31d3b43de049 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i16-from-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i16-from-i32.c @@ -6,7 +6,7 @@ #define NT int16_t #define WT int32_t -DEF_AVG_1(NT, WT, avg_ceil) +DEF_AVG_1_WRAP(NT, WT, avg_ceil) /* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 1 } } */ /* { dg-final { scan-assembler-times {vaadd.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i16-from-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i16-from-i64.c index 30438c90abea..7f30b9ec3f16 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i16-from-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i16-from-i64.c @@ -6,7 +6,7 @@ #define NT int16_t #define WT int64_t -DEF_AVG_1(NT, WT, avg_ceil) +DEF_AVG_1_WRAP(NT, WT, avg_ceil) /* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 1 } } */ /* { dg-final { scan-assembler-times {vaadd.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i32-from-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i32-from-i64.c index 2e9cfa509403..2e06d0a3a464 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i32-from-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i32-from-i64.c @@ -6,7 +6,7 @@ #define NT int32_t #define WT int64_t -DEF_AVG_1(NT, WT, avg_ceil) +DEF_AVG_1_WRAP(NT, WT, avg_ceil) /* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 1 } } */ /* { dg-final { scan-assembler-times {vaadd.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i64-from-i128.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i64-from-i128.c new file mode 100644 index 000000000000..ca2306627502 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i64-from-i128.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d" } */ + +#include "avg.h" + +#define NT int64_t +#define WT int128_t + +DEF_AVG_1_WRAP(NT, WT, avg_ceil) + +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 1 } } */ +/* { dg-final { scan-assembler-times {vaadd.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i8-from-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i8-from-i16.c index 2ebf2945a0ee..dda84a6b4379 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i8-from-i16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i8-from-i16.c @@ -6,7 +6,7 @@ #define NT int8_t #define WT int16_t -DEF_AVG_1(NT, WT, avg_ceil) +DEF_AVG_1_WRAP(NT, WT, avg_ceil) /* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 1 } } */ /* { dg-final { scan-assembler-times {vaadd.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i8-from-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i8-from-i32.c index 64fec9135b5d..dfd2bb31357e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i8-from-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i8-from-i32.c @@ -6,7 +6,7 @@ #define NT int8_t #define WT int32_t -DEF_AVG_1(NT, WT, avg_ceil) +DEF_AVG_1_WRAP(NT, WT, avg_ceil) /* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 1 } } */ /* { dg-final { scan-assembler-times {vaadd.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i8-from-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i8-from-i64.c index a72642c9b103..d1060cc663db 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i8-from-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-1-i8-from-i64.c @@ -6,7 +6,7 @@ #define NT int8_t #define WT int64_t -DEF_AVG_1(NT, WT, avg_ceil) +DEF_AVG_1_WRAP(NT, WT, avg_ceil) /* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 1 } } */ /* { dg-final { scan-assembler-times {vaadd.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i16-from-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i16-from-i32.c index 1fa080b3933b..3d872a8a4b5d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i16-from-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i16-from-i32.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-additional-options "-std=c99 -O3" } */ +/* { dg-additional-options "-std=c99 -O3 -Wno-pedantic" } */ #include "avg.h" #include "avg_data.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i16-from-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i16-from-i64.c index deec763131a0..eda9736e42d7 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i16-from-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i16-from-i64.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-additional-options "-std=c99 -O3" } */ +/* { dg-additional-options "-std=c99 -O3 -Wno-pedantic" } */ #include "avg.h" #include "avg_data.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i32-from-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i32-from-i64.c index fa7200064928..21cbb9478bce 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i32-from-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i32-from-i64.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-additional-options "-std=c99 -O3" } */ +/* { dg-additional-options "-std=c99 -O3 -Wno-pedantic" } */ #include "avg.h" #include "avg_data.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i64-from-i128.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i64-from-i128.c new file mode 100644 index 000000000000..ee5330ca8a5d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i64-from-i128.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v && rv64 } } } */ +/* { dg-additional-options "-std=c99 -O3 -Wno-pedantic" } */ + +#include "avg.h" +#include "avg_data.h" + +#define WT int128_t +#define NT int64_t +#define NAME avg_ceil + +DEF_AVG_1_WRAP(NT, WT, NAME) + +#define TEST_DATA TEST_AVG_DATA_WRAP(NT, NAME) +#define TEST_RUN(NT, WT, NAME, a, b, out, n) RUN_AVG_1_WRAP(NT, WT, NAME, a, b, out, n) + +#include "avg_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i8-from-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i8-from-i16.c index 6865cf267629..fd91b6fc48e0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i8-from-i16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i8-from-i16.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-additional-options "-std=c99 -O3" } */ +/* { dg-additional-options "-std=c99 -O3 -Wno-pedantic" } */ #include "avg.h" #include "avg_data.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i8-from-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i8-from-i32.c index 78620f4c920f..38f492066112 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i8-from-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i8-from-i32.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-additional-options "-std=c99 -O3" } */ +/* { dg-additional-options "-std=c99 -O3 -Wno-pedantic" } */ #include "avg.h" #include "avg_data.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i8-from-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i8-from-i64.c index b2c763cad610..f65ee15a09ba 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i8-from-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_ceil-run-1-i8-from-i64.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-additional-options "-std=c99 -O3" } */ +/* { dg-additional-options "-std=c99 -O3 -Wno-pedantic" } */ #include "avg.h" #include "avg_data.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_data.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_data.h index 12b464a3ce27..49103f3f6915 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_data.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_data.h @@ -169,8 +169,8 @@ int64_t TEST_AVG_DATA(int64_t, avg_floor)[][3][N] = }, { 9223372036854775806ull, 9223372036854775806ull, 9223372036854775806ull, 9223372036854775806ull, - 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, -2ull, -2ull, -2ull, -2ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, -9223372036854775807ull, -9223372036854775807ull, -9223372036854775807ull, -9223372036854775807ull, }, { @@ -345,8 +345,8 @@ int64_t TEST_AVG_DATA(int64_t, avg_ceil)[][3][N] = }, { 9223372036854775806ull, 9223372036854775806ull, 9223372036854775806ull, 9223372036854775806ull, - 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, -2ull, -2ull, -2ull, -2ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, -9223372036854775807ull, -9223372036854775807ull, -9223372036854775807ull, -9223372036854775807ull, }, { diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i16-from-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i16-from-i32.c index 16ba96735000..fc7943c5e21e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i16-from-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i16-from-i32.c @@ -6,7 +6,7 @@ #define NT int16_t #define WT int32_t -DEF_AVG_0(NT, WT, avg_floor) +DEF_AVG_0_WRAP(NT, WT, avg_floor) /* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 1 } } */ /* { dg-final { scan-assembler-times {vaadd.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i16-from-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i16-from-i64.c index b229b4b5703a..e02e5df69c47 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i16-from-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i16-from-i64.c @@ -6,7 +6,7 @@ #define NT int16_t #define WT int64_t -DEF_AVG_0(NT, WT, avg_floor) +DEF_AVG_0_WRAP(NT, WT, avg_floor) /* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 1 } } */ /* { dg-final { scan-assembler-times {vaadd.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i32-from-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i32-from-i64.c index 5f946bbc8cd4..e36e4242cb0b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i32-from-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i32-from-i64.c @@ -6,7 +6,7 @@ #define NT int32_t #define WT int64_t -DEF_AVG_0(NT, WT, avg_floor) +DEF_AVG_0_WRAP(NT, WT, avg_floor) /* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 1 } } */ /* { dg-final { scan-assembler-times {vaadd.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i64-from-i128.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i64-from-i128.c new file mode 100644 index 000000000000..3e2d97ddad4c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i64-from-i128.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d" } */ + +#include "avg.h" + +#define NT int64_t +#define WT int128_t + +DEF_AVG_0_WRAP(NT, WT, avg_floor) + +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 1 } } */ +/* { dg-final { scan-assembler-times {vaadd.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i8-from-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i8-from-i16.c index 5d9297a6c394..cdbb2999183a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i8-from-i16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i8-from-i16.c @@ -6,7 +6,7 @@ #define NT int8_t #define WT int16_t -DEF_AVG_0(NT, WT, avg_floor) +DEF_AVG_0_WRAP(NT, WT, avg_floor) /* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 1 } } */ /* { dg-final { scan-assembler-times {vaadd.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i8-from-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i8-from-i32.c index 5c5d4ea40bb1..53508b09ac39 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i8-from-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i8-from-i32.c @@ -6,7 +6,7 @@ #define NT int8_t #define WT int32_t -DEF_AVG_0(NT, WT, avg_floor) +DEF_AVG_0_WRAP(NT, WT, avg_floor) /* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 1 } } */ /* { dg-final { scan-assembler-times {vaadd.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i8-from-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i8-from-i64.c index f297953aadf4..9a6d1a21e52f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i8-from-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-1-i8-from-i64.c @@ -6,7 +6,7 @@ #define NT int8_t #define WT int64_t -DEF_AVG_0(NT, WT, avg_floor) +DEF_AVG_0_WRAP(NT, WT, avg_floor) /* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 1 } } */ /* { dg-final { scan-assembler-times {vaadd.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i16-from-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i16-from-i32.c index 9d0dd618e56b..92239a28160f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i16-from-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i16-from-i32.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-additional-options "-std=c99 -O3" } */ +/* { dg-additional-options "-std=c99 -O3 -Wno-pedantic" } */ #include "avg.h" #include "avg_data.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i16-from-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i16-from-i64.c index 2736baa36e8c..5716c2967d98 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i16-from-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i16-from-i64.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-additional-options "-std=c99 -O3" } */ +/* { dg-additional-options "-std=c99 -O3 -Wno-pedantic" } */ #include "avg.h" #include "avg_data.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i32-from-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i32-from-i64.c index 2334045bfa4b..705e09126bce 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i32-from-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i32-from-i64.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-additional-options "-std=c99 -O3" } */ +/* { dg-additional-options "-std=c99 -O3 -Wno-pedantic" } */ #include "avg.h" #include "avg_data.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i64-from-i128.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i64-from-i128.c new file mode 100644 index 000000000000..91e9809f4881 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i64-from-i128.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v && rv64 } } } */ +/* { dg-additional-options "-std=c99 -O3 -Wno-pedantic" } */ + +#include "avg.h" +#include "avg_data.h" + +#define WT int128_t +#define NT int64_t +#define NAME avg_floor + +DEF_AVG_0_WRAP(NT, WT, NAME) + +#define TEST_DATA TEST_AVG_DATA_WRAP(NT, NAME) +#define TEST_RUN(NT, WT, NAME, a, b, out, n) RUN_AVG_0_WRAP(NT, WT, NAME, a, b, out, n) + +#include "avg_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i8-from-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i8-from-i16.c index 836474844d2a..abe5c5b81e92 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i8-from-i16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i8-from-i16.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-additional-options "-std=c99 -O3" } */ +/* { dg-additional-options "-std=c99 -O3 -Wno-pedantic" } */ #include "avg.h" #include "avg_data.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i8-from-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i8-from-i32.c index 157c9360ce04..355b90fabfc3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i8-from-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i8-from-i32.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-additional-options "-std=c99 -O3" } */ +/* { dg-additional-options "-std=c99 -O3 -Wno-pedantic" } */ #include "avg.h" #include "avg_data.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i8-from-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i8-from-i64.c index 2db0d3cb37e1..a9ae96fdcb84 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i8-from-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/avg_floor-run-1-i8-from-i64.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-additional-options "-std=c99 -O3" } */ +/* { dg-additional-options "-std=c99 -O3 -Wno-pedantic" } */ #include "avg.h" #include "avg_data.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c index 667f457d6584..fab8e79fe723 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d -mrvv-vector-bits=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d -mrvv-vector-bits=scalable -fdump-tree-optimized-details -fno-pie" } */ #include "vadd-template.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv-nofm.c index 1d8a19ce0b2d..80bdb683ad0a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv-nofm.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv-nofm.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d -mrvv-vector-bits=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d -mrvv-vector-bits=scalable -fdump-tree-optimized-details -fno-pie" } */ #include "vadd-template.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv-nofm.c index 4685ed22a784..a8be5edcc70c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv-nofm.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv-nofm.c @@ -5,8 +5,8 @@ /* { dg-final { scan-assembler-times {\tvdiv\.vv} 8 } } */ /* { dg-final { scan-assembler-not {\tvdiv\.vx} } } */ -/* { dg-final { scan-assembler-times {\tvdivu\.vv} 5 } } */ -/* { dg-final { scan-assembler-times {\tvdivu\.vx} 3 } } */ +/* { dg-final { scan-assembler-times {\tvdivu\.vv} 8 } } */ +/* { dg-final { scan-assembler-not {\tvdivu\.vx} } } */ /* { dg-final { scan-assembler-times {\tvfdiv\.vv} 6 } } */ /* { dg-final { scan-assembler-not {\tvfdiv\.vf} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c index 59c48d2d9bae..7feee0ec154a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c @@ -5,8 +5,8 @@ /* { dg-final { scan-assembler-times {\tvdiv\.vv} 8 } } */ /* { dg-final { scan-assembler-not {\tvdiv\.vx} } } */ -/* { dg-final { scan-assembler-times {\tvdivu\.vv} 5 } } */ -/* { dg-final { scan-assembler-times {\tvdivu\.vx} 3 } } */ +/* { dg-final { scan-assembler-times {\tvdivu\.vv} 8 } } */ +/* { dg-final { scan-assembler-not {\tvdivu\.vx} } } */ /* Division by constant is done by calculating a reciprocal and then multiplying. Hence we do not expect 6 vfdivs. */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv-nofm.c index b574dc42182c..766b17fc37da 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv-nofm.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv-nofm.c @@ -5,8 +5,8 @@ /* { dg-final { scan-assembler-times {\tvdiv\.vv} 8 } } */ /* { dg-final { scan-assembler-not {\tvdiv\.vx} } } */ -/* { dg-final { scan-assembler-times {\tvdivu\.vv} 4 } } */ -/* { dg-final { scan-assembler-times {\tvdivu\.vx} 4 } } */ +/* { dg-final { scan-assembler-times {\tvdivu\.vv} 8 } } */ +/* { dg-final { scan-assembler-not {\tvdivu\.vx} } } */ /* { dg-final { scan-assembler-times {\tvfdiv\.vv} 6 } } */ /* { dg-final { scan-assembler-not {\tvfdiv\.vf} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c index 9b46c6be0efb..c59c66439f89 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c @@ -5,8 +5,8 @@ /* { dg-final { scan-assembler-times {\tvdiv\.vv} 8 } } */ /* { dg-final { scan-assembler-not {\tvdiv\.vx} } } */ -/* { dg-final { scan-assembler-times {\tvdivu\.vv} 4 } } */ -/* { dg-final { scan-assembler-times {\tvdivu\.vx} 4 } } */ +/* { dg-final { scan-assembler-times {\tvdivu\.vv} 8 } } */ +/* { dg-final { scan-assembler-not {\tvdivu\.vx} } } */ /* Division by constant is done by calculating a reciprocal and then multiplying. Hence we do not expect 6 vfdivs. */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c index a87a6c70df1f..10de7c268e5e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c @@ -2,10 +2,10 @@ #include "vrem-template.h" -/* { dg-final { scan-assembler-times {\tvrem\.vv} 5 } } */ -/* { dg-final { scan-assembler-times {\tvrem\.vx} 3 } } */ -/* { dg-final { scan-assembler-times {\tvremu\.vv} 5 } } */ -/* { dg-final { scan-assembler-times {\tvremu\.vx} 3 } } */ +/* { dg-final { scan-assembler-times {\tvrem\.vv} 8 } } */ +/* { dg-final { scan-assembler-not {\tvrem\.vx} } } */ +/* { dg-final { scan-assembler-times {\tvremu\.vv} 8 } } */ +/* { dg-final { scan-assembler-not {\tvremu\.vx} } } */ /* { dg-final { scan-tree-dump-times "\.COND_LEN_MOD" 16 "optimized" } } */ /* { dg-final { scan-assembler-not {\tvmv1r\.v} } } */ /* { dg-final { scan-assembler-not {\tvmv2r\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv64gcv.c index 938169574aac..cf187a2bde7c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv64gcv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv64gcv.c @@ -3,10 +3,10 @@ #include "vrem-template.h" -/* { dg-final { scan-assembler-times {\tvrem\.vv} 4 } } */ -/* { dg-final { scan-assembler-times {\tvrem\.vx} 4 } } */ -/* { dg-final { scan-assembler-times {\tvremu\.vv} 4 } } */ -/* { dg-final { scan-assembler-times {\tvremu\.vx} 4 } } */ +/* { dg-final { scan-assembler-times {\tvrem\.vv} 8 } } */ +/* { dg-final { scan-assembler-not {\tvrem\.vx} } } */ +/* { dg-final { scan-assembler-times {\tvremu\.vv} 8 } } */ +/* { dg-final { scan-assembler-not {\tvremu\.vx} } } */ /* { dg-final { scan-tree-dump-times "\.COND_LEN_MOD" 16 "optimized" } } */ /* { dg-final { scan-assembler-not {\tvmv1r\.v} } } */ /* { dg-final { scan-assembler-not {\tvmv2r\.v} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c index 1b6d50ed3bc0..28b923599ea9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d -mrvv-vector-bits=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d -mrvv-vector-bits=scalable -fdump-tree-optimized-details -fno-pie" } */ #include "vsub-template.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv-nofm.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv-nofm.c index 0b22e9ad2905..b0489493b049 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv-nofm.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv-nofm.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d -mrvv-vector-bits=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d -mrvv-vector-bits=scalable -fdump-tree-optimized-details -fno-pie" } */ #include "vsub-template.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120356.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120356.c new file mode 100644 index 000000000000..2913f04e4c83 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120356.c @@ -0,0 +1,26 @@ +/* { dg-do run } */ +/* { dg-require-effective-target rvv_zvl256b_ok } */ +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -mrvv-vector-bits=zvl -O2" } */ + +unsigned char a = 5; +long long c[18]; + +static void d () +{ + for (short i = 0; i < 60; i += 65413) + for (char j = 0; j < 18; j++) + { + for (char k = 0; k < 18; k++) + a *= 143; + for (char k = 0; k < 6; k++) + for (char l = 0; l < 18; l++) + c[l] = 0; + } +} + +int main () +{ + d (); + if (a + c[0] != 69) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120652-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120652-1.c new file mode 100644 index 000000000000..260e4c08f16f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120652-1.c @@ -0,0 +1,5 @@ +/* Test that we do not have ice when compile */ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zvl256b -mabi=lp64d -O3" } */ + +#include "pr120652.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120652-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120652-2.c new file mode 100644 index 000000000000..6f8594267662 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120652-2.c @@ -0,0 +1,5 @@ +/* Test that we do not have ice when compile */ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zvl512b -mabi=lp64d -O3" } */ + +#include "pr120652.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120652-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120652-3.c new file mode 100644 index 000000000000..9852b5de86a4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120652-3.c @@ -0,0 +1,5 @@ +/* Test that we do not have ice when compile */ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zvl1024b -mabi=lp64d -O3" } */ + +#include "pr120652.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120652.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120652.h new file mode 100644 index 000000000000..75f27164b221 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr120652.h @@ -0,0 +1,31 @@ +#ifndef HAVE_DEFINED_PR120652_H +#define HAVE_DEFINED_PR120652_H + +unsigned n; +char ab[6]; +unsigned ac; +unsigned ae; + +int ak(int bb) { +bd: + for (ac = -17; ac != 16; ac++) { + unsigned be = 95; + if (be <= n) { + char *bg = &ab[1]; + *bg ^= bb; + } else { + ae--; + for (n = 8; 0;) + goto bd; + } + } + return 0; +} + +int main() { + ak(7); + + return 0; +} + +#endif diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_arith.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_arith.h index f78bdc047ca1..93c29f091bed 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_arith.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_arith.h @@ -385,6 +385,8 @@ vec_sat_u_sub_##T##_fmt_1 (T *out, T *op_1, T *op_2, unsigned limit) \ out[i] = (x - y) & (-(T)(x >= y)); \ } \ } +#define DEF_VEC_SAT_U_SUB_FMT_1_WRAP(T) \ + DEF_VEC_SAT_U_SUB_FMT_1(T) #define DEF_VEC_SAT_U_SUB_FMT_2(T) \ void __attribute__((noinline)) \ @@ -398,6 +400,8 @@ vec_sat_u_sub_##T##_fmt_2 (T *out, T *op_1, T *op_2, unsigned limit) \ out[i] = (x - y) & (-(T)(x > y)); \ } \ } +#define DEF_VEC_SAT_U_SUB_FMT_2_WRAP(T) \ + DEF_VEC_SAT_U_SUB_FMT_2(T) #define DEF_VEC_SAT_U_SUB_FMT_3(T) \ void __attribute__((noinline)) \ @@ -411,6 +415,8 @@ vec_sat_u_sub_##T##_fmt_3 (T *out, T *op_1, T *op_2, unsigned limit) \ out[i] = x > y ? x - y : 0; \ } \ } +#define DEF_VEC_SAT_U_SUB_FMT_3_WRAP(T) \ + DEF_VEC_SAT_U_SUB_FMT_3(T) #define DEF_VEC_SAT_U_SUB_FMT_4(T) \ void __attribute__((noinline)) \ @@ -424,6 +430,8 @@ vec_sat_u_sub_##T##_fmt_4 (T *out, T *op_1, T *op_2, unsigned limit) \ out[i] = x >= y ? x - y : 0; \ } \ } +#define DEF_VEC_SAT_U_SUB_FMT_4_WRAP(T) \ + DEF_VEC_SAT_U_SUB_FMT_4(T) #define DEF_VEC_SAT_U_SUB_FMT_5(T) \ void __attribute__((noinline)) \ @@ -437,6 +445,8 @@ vec_sat_u_sub_##T##_fmt_5 (T *out, T *op_1, T *op_2, unsigned limit) \ out[i] = x < y ? 0 : x - y; \ } \ } +#define DEF_VEC_SAT_U_SUB_FMT_5_WRAP(T) \ + DEF_VEC_SAT_U_SUB_FMT_5(T) #define DEF_VEC_SAT_U_SUB_FMT_6(T) \ void __attribute__((noinline)) \ @@ -450,6 +460,8 @@ vec_sat_u_sub_##T##_fmt_6 (T *out, T *op_1, T *op_2, unsigned limit) \ out[i] = x <= y ? 0 : x - y; \ } \ } +#define DEF_VEC_SAT_U_SUB_FMT_6_WRAP(T) \ + DEF_VEC_SAT_U_SUB_FMT_6(T) #define DEF_VEC_SAT_U_SUB_FMT_7(T) \ void __attribute__((noinline)) \ @@ -465,6 +477,8 @@ vec_sat_u_sub_##T##_fmt_7 (T *out, T *op_1, T *op_2, unsigned limit) \ out[i] = ret & (T)(overflow - 1); \ } \ } +#define DEF_VEC_SAT_U_SUB_FMT_7_WRAP(T) \ + DEF_VEC_SAT_U_SUB_FMT_7(T) #define DEF_VEC_SAT_U_SUB_FMT_8(T) \ void __attribute__((noinline)) \ @@ -480,6 +494,8 @@ vec_sat_u_sub_##T##_fmt_8 (T *out, T *op_1, T *op_2, unsigned limit) \ out[i] = ret & (T)-(!overflow); \ } \ } +#define DEF_VEC_SAT_U_SUB_FMT_8_WRAP(T) \ + DEF_VEC_SAT_U_SUB_FMT_8(T) #define DEF_VEC_SAT_U_SUB_FMT_9(T) \ void __attribute__((noinline)) \ @@ -495,6 +511,8 @@ vec_sat_u_sub_##T##_fmt_9 (T *out, T *op_1, T *op_2, unsigned limit) \ out[i] = overflow ? 0 : ret; \ } \ } +#define DEF_VEC_SAT_U_SUB_FMT_9_WRAP(T) \ + DEF_VEC_SAT_U_SUB_FMT_9(T) #define DEF_VEC_SAT_U_SUB_FMT_10(T) \ void __attribute__((noinline)) \ @@ -510,6 +528,42 @@ vec_sat_u_sub_##T##_fmt_10 (T *out, T *op_1, T *op_2, unsigned limit) \ out[i] = !overflow ? ret : 0; \ } \ } +#define DEF_VEC_SAT_U_SUB_FMT_10_WRAP(T) \ + DEF_VEC_SAT_U_SUB_FMT_10(T) + +#define DEF_VEC_SAT_U_SUB_FMT_11(T) \ +void __attribute__((noinline)) \ +vec_sat_u_sub_##T##_fmt_11 (T *out, T *op_1, T *op_2, unsigned limit) \ +{ \ + unsigned i; \ + for (i = 0; i < limit; i++) \ + { \ + T x = op_1[i]; \ + T y = op_2[i]; \ + T ret; \ + T overflow = __builtin_sub_overflow (x, y, &ret); \ + out[i] = overflow ? 0 : ret; \ + } \ +} +#define DEF_VEC_SAT_U_SUB_FMT_11_WRAP(T) \ + DEF_VEC_SAT_U_SUB_FMT_11(T) + +#define DEF_VEC_SAT_U_SUB_FMT_12(T) \ +void __attribute__((noinline)) \ +vec_sat_u_sub_##T##_fmt_12 (T *out, T *op_1, T *op_2, unsigned limit) \ +{ \ + unsigned i; \ + for (i = 0; i < limit; i++) \ + { \ + T x = op_1[i]; \ + T y = op_2[i]; \ + T ret; \ + T overflow = __builtin_sub_overflow (x, y, &ret); \ + out[i] = !overflow ? ret : 0; \ + } \ +} +#define DEF_VEC_SAT_U_SUB_FMT_12_WRAP(T) \ + DEF_VEC_SAT_U_SUB_FMT_12(T) #define DEF_VEC_SAT_U_SUB_ZIP(T1, T2) \ void __attribute__((noinline)) \ @@ -669,33 +723,63 @@ vec_sat_s_sub_##T##_fmt_4 (T *out, T *op_1, T *op_2, unsigned limit) \ #define RUN_VEC_SAT_U_SUB_FMT_1(T, out, op_1, op_2, N) \ vec_sat_u_sub_##T##_fmt_1(out, op_1, op_2, N) +#define RUN_VEC_SAT_U_SUB_FMT_1_WRAP(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_1(T, out, op_1, op_2, N) #define RUN_VEC_SAT_U_SUB_FMT_2(T, out, op_1, op_2, N) \ vec_sat_u_sub_##T##_fmt_2(out, op_1, op_2, N) +#define RUN_VEC_SAT_U_SUB_FMT_2_WRAP(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_2(T, out, op_1, op_2, N) #define RUN_VEC_SAT_U_SUB_FMT_3(T, out, op_1, op_2, N) \ vec_sat_u_sub_##T##_fmt_3(out, op_1, op_2, N) +#define RUN_VEC_SAT_U_SUB_FMT_3_WRAP(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_3(T, out, op_1, op_2, N) #define RUN_VEC_SAT_U_SUB_FMT_4(T, out, op_1, op_2, N) \ vec_sat_u_sub_##T##_fmt_4(out, op_1, op_2, N) +#define RUN_VEC_SAT_U_SUB_FMT_4_WRAP(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_4(T, out, op_1, op_2, N) #define RUN_VEC_SAT_U_SUB_FMT_5(T, out, op_1, op_2, N) \ vec_sat_u_sub_##T##_fmt_5(out, op_1, op_2, N) +#define RUN_VEC_SAT_U_SUB_FMT_5_WRAP(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_5(T, out, op_1, op_2, N) #define RUN_VEC_SAT_U_SUB_FMT_6(T, out, op_1, op_2, N) \ vec_sat_u_sub_##T##_fmt_6(out, op_1, op_2, N) +#define RUN_VEC_SAT_U_SUB_FMT_6_WRAP(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_6(T, out, op_1, op_2, N) #define RUN_VEC_SAT_U_SUB_FMT_7(T, out, op_1, op_2, N) \ vec_sat_u_sub_##T##_fmt_7(out, op_1, op_2, N) +#define RUN_VEC_SAT_U_SUB_FMT_7_WRAP(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_7(T, out, op_1, op_2, N) #define RUN_VEC_SAT_U_SUB_FMT_8(T, out, op_1, op_2, N) \ vec_sat_u_sub_##T##_fmt_8(out, op_1, op_2, N) +#define RUN_VEC_SAT_U_SUB_FMT_8_WRAP(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_8(T, out, op_1, op_2, N) #define RUN_VEC_SAT_U_SUB_FMT_9(T, out, op_1, op_2, N) \ vec_sat_u_sub_##T##_fmt_9(out, op_1, op_2, N) +#define RUN_VEC_SAT_U_SUB_FMT_9_WRAP(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_9(T, out, op_1, op_2, N) #define RUN_VEC_SAT_U_SUB_FMT_10(T, out, op_1, op_2, N) \ vec_sat_u_sub_##T##_fmt_10(out, op_1, op_2, N) +#define RUN_VEC_SAT_U_SUB_FMT_10_WRAP(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_10(T, out, op_1, op_2, N) + +#define RUN_VEC_SAT_U_SUB_FMT_11(T, out, op_1, op_2, N) \ + vec_sat_u_sub_##T##_fmt_11(out, op_1, op_2, N) +#define RUN_VEC_SAT_U_SUB_FMT_11_WRAP(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_11(T, out, op_1, op_2, N) + +#define RUN_VEC_SAT_U_SUB_FMT_12(T, out, op_1, op_2, N) \ + vec_sat_u_sub_##T##_fmt_12(out, op_1, op_2, N) +#define RUN_VEC_SAT_U_SUB_FMT_12_WRAP(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_12(T, out, op_1, op_2, N) #define RUN_VEC_SAT_U_SUB_FMT_ZIP(T1, T2, x, b, N) \ vec_sat_u_sub_##T1##_##T2##_fmt_zip(x, b, N) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_data.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_data.h index 9f05c0c9291a..76474393fe3b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_data.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_data.h @@ -744,6 +744,258 @@ uint64_t TEST_UNARY_DATA(uint64_t, sat_u_sub_imm)[][2][N] = }, }; +uint8_t TEST_UNARY_DATA(uint8_t, ussub)[][3][N] = { + { + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, /* arg_0 */ + { + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + }, /* arg_1 */ + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, /* expect */ + }, + { + { + 0, 255, 255, 255, + 0, 255, 255, 255, + 0, 255, 255, 255, + 0, 255, 255, 255, + }, + { + 1, 255, 254, 251, + 1, 255, 254, 251, + 1, 255, 254, 251, + 1, 255, 254, 251, + }, + { + 0, 0, 1, 4, + 0, 0, 1, 4, + 0, 0, 1, 4, + 0, 0, 1, 4, + }, + }, + { + { + 0, 0, 1, 0, + 1, 2, 3, 0, + 1, 2, 3, 255, + 5, 254, 255, 9, + }, + { + 0, 1, 0, 254, + 254, 254, 254, 255, + 255, 255, 0, 252, + 255, 255, 255, 1, + }, + { + 0, 0, 1, 0, + 0, 0, 0, 0, + 0, 0, 3, 3, + 0, 0, 0, 8, + }, + }, +}; + +uint16_t TEST_UNARY_DATA(uint16_t, ussub)[][3][N] = { + { + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, /* arg_0 */ + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, /* arg_1 */ + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, /* expect */ + }, + { + { + 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, + }, + { + 55535, 45535, 35535, 25535, + 55535, 45535, 35535, 25535, + 55535, 45535, 35535, 25535, + 55535, 45535, 35535, 25535, + }, + { + 10000, 20000, 30000, 40000, + 10000, 20000, 30000, 40000, + 10000, 20000, 30000, 40000, + 10000, 20000, 30000, 40000, + }, + }, + { + { + 0, 0, 1, 0, + 1, 2, 3, 0, + 1, 65535, 3, 65535, + 5, 65534, 65535, 9, + }, + { + 0, 1, 1, 65534, + 65534, 65534, 1, 65535, + 0, 65535, 65535, 0, + 65535, 65535, 1, 2, + }, + { + 0, 0, 0, 0, + 0, 0, 2, 0, + 1, 0, 0, 65535, + 0, 0, 65534, 7, + }, + }, +}; + +uint32_t TEST_UNARY_DATA(uint32_t, ussub)[][3][N] = { + { + { + 0, 0, 4, 0, + 0, 0, 4, 0, + 0, 0, 4, 0, + 0, 0, 4, 0, + }, /* arg_0 */ + { + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + }, /* arg_1 */ + { + 0, 0, 2, 0, + 0, 0, 2, 0, + 0, 0, 2, 0, + 0, 0, 2, 0, + }, /* expect */ + }, + { + { + 4294967295, 4294967295, 4294967295, 4294967295, + 4294967295, 4294967295, 4294967295, 4294967295, + 4294967295, 4294967295, 4294967295, 4294967295, + 4294967295, 4294967295, 4294967295, 4294967295, + }, + { + 1294967295, 2294967295, 3294967295, 4294967295, + 1294967295, 2294967295, 3294967295, 4294967295, + 1294967295, 2294967295, 3294967295, 4294967295, + 1294967295, 2294967295, 3294967295, 4294967295, + }, + { + 3000000000, 2000000000, 1000000000, 0, + 3000000000, 2000000000, 1000000000, 0, + 3000000000, 2000000000, 1000000000, 0, + 3000000000, 2000000000, 1000000000, 0, + }, + }, + { + { + 0, 0, 9, 0, + 1, 4294967295, 3, 0, + 1, 2, 3, 4, + 5, 4294967294, 4294967295, 4294967295, + }, + { + 0, 1, 1, 4294967294, + 1, 2, 4294967294, 4294967295, + 1, 4294967295, 4294967295, 1, + 1, 4294967295, 4294967290, 9, + }, + { + 0, 0, 8, 0, + 0, 4294967293, 0, 0, + 0, 0, 0, 3, + 4, 0, 5, 4294967286, + }, + }, +}; + +uint64_t TEST_UNARY_DATA(uint64_t, ussub)[][3][N] = { + { + { + 0, 9, 0, 0, + 0, 9, 0, 0, + 0, 9, 0, 0, + 0, 9, 0, 0, + }, /* arg_0 */ + { + 0, 2, 3, 1, + 0, 2, 3, 1, + 0, 2, 3, 1, + 0, 2, 3, 1, + }, /* arg_1 */ + { + 0, 7, 0, 0, + 0, 7, 0, 0, + 0, 7, 0, 0, + 0, 7, 0, 0, + }, /* expect */ + }, + { + { + 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, + 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, + 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, + 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, + }, + { + 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, + 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, + 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, + 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, + }, + { + 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, + 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, + 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, + 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, + }, + }, + { + { + 0, 18446744073709551615u, 1, 0, + 1, 18446744073709551615u, 3, 0, + 1, 18446744073709551614u, 3, 4, + 5, 18446744073709551614u, 18446744073709551615u, 9, + }, + { + 0, 1, 1, 18446744073709551614u, + 18446744073709551614u, 18446744073709551614u, 18446744073709551614u, 18446744073709551615u, + 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, + 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 1, + }, + { + 0, 18446744073709551614u, 0, 0, + 0, 1, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 8, + }, + }, +}; + int8_t TEST_UNARY_DATA(int8_t, sat_s_add_imm)[][2][N] = { { /* For add imm -128 */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-11-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-11-u16.c new file mode 100644 index 000000000000..57da9e8a4213 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-11-u16.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -ftree-vectorize -fdump-tree-optimized" } */ + +#include "vec_sat_arith.h" + +DEF_VEC_SAT_U_SUB_FMT_11(uint16_t) + +/* { dg-final { scan-tree-dump-times ".SAT_SUB " 2 "optimized" } } */ +/* { dg-final { scan-assembler-times {vssubu\.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-11-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-11-u32.c new file mode 100644 index 000000000000..b5264a323c8a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-11-u32.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -ftree-vectorize -fdump-tree-optimized" } */ + +#include "vec_sat_arith.h" + +DEF_VEC_SAT_U_SUB_FMT_11(uint32_t) + +/* { dg-final { scan-tree-dump-times ".SAT_SUB " 2 "optimized" } } */ +/* { dg-final { scan-assembler-times {vssubu\.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-11-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-11-u64.c new file mode 100644 index 000000000000..1a68b5c04265 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-11-u64.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -ftree-vectorize -fdump-tree-optimized" } */ + +#include "vec_sat_arith.h" + +DEF_VEC_SAT_U_SUB_FMT_11(uint64_t) + +/* { dg-final { scan-tree-dump-times ".SAT_SUB " 2 "optimized" } } */ +/* { dg-final { scan-assembler-times {vssubu\.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-11-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-11-u8.c new file mode 100644 index 000000000000..a1c5c19aea1f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-11-u8.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -ftree-vectorize -fdump-tree-optimized" } */ + +#include "vec_sat_arith.h" + +DEF_VEC_SAT_U_SUB_FMT_11(uint8_t) + +/* { dg-final { scan-tree-dump-times ".SAT_SUB " 2 "optimized" } } */ +/* { dg-final { scan-assembler-times {vssubu\.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-12-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-12-u16.c new file mode 100644 index 000000000000..fd987e9d5880 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-12-u16.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -ftree-vectorize -fdump-tree-optimized" } */ + +#include "vec_sat_arith.h" + +DEF_VEC_SAT_U_SUB_FMT_12(uint16_t) + +/* { dg-final { scan-tree-dump-times ".SAT_SUB " 2 "optimized" } } */ +/* { dg-final { scan-assembler-times {vssubu\.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-12-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-12-u32.c new file mode 100644 index 000000000000..bc380feb3d8b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-12-u32.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -ftree-vectorize -fdump-tree-optimized" } */ + +#include "vec_sat_arith.h" + +DEF_VEC_SAT_U_SUB_FMT_12(uint32_t) + +/* { dg-final { scan-tree-dump-times ".SAT_SUB " 2 "optimized" } } */ +/* { dg-final { scan-assembler-times {vssubu\.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-12-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-12-u64.c new file mode 100644 index 000000000000..c03163f9a1ba --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-12-u64.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -ftree-vectorize -fdump-tree-optimized" } */ + +#include "vec_sat_arith.h" + +DEF_VEC_SAT_U_SUB_FMT_12(uint64_t) + +/* { dg-final { scan-tree-dump-times ".SAT_SUB " 2 "optimized" } } */ +/* { dg-final { scan-assembler-times {vssubu\.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-12-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-12-u8.c new file mode 100644 index 000000000000..91e190969e88 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-12-u8.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -ftree-vectorize -fdump-tree-optimized" } */ + +#include "vec_sat_arith.h" + +DEF_VEC_SAT_U_SUB_FMT_12(uint8_t) + +/* { dg-final { scan-tree-dump-times ".SAT_SUB " 2 "optimized" } } */ +/* { dg-final { scan-assembler-times {vssubu\.vv} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u16.c index 97e50406e603..5878c5b69100 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u16.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint16_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_1 -DEF_VEC_SAT_U_SUB_FMT_1(T) +DEF_VEC_SAT_U_SUB_FMT_1_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - }, - { - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - }, - { - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 65535, 3, 65535, - 5, 65534, 65535, 9, - }, - { - 0, 1, 1, 65534, - 65534, 65534, 1, 65535, - 0, 65535, 65535, 0, - 65535, 65535, 1, 2, - }, - { - 0, 0, 0, 0, - 0, 0, 2, 0, - 1, 0, 0, 65535, - 0, 0, 65534, 7, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_1_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u32.c index a5428c430107..f74979f9e1e0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u32.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint32_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_1 -DEF_VEC_SAT_U_SUB_FMT_1(T) +DEF_VEC_SAT_U_SUB_FMT_1_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - }, /* expect */ - }, - { - { - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - }, - { - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - }, - { - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - }, - }, - { - { - 0, 0, 9, 0, - 1, 4294967295, 3, 0, - 1, 2, 3, 4, - 5, 4294967294, 4294967295, 4294967295, - }, - { - 0, 1, 1, 4294967294, - 1, 2, 4294967294, 4294967295, - 1, 4294967295, 4294967295, 1, - 1, 4294967295, 4294967290, 9, - }, - { - 0, 0, 8, 0, - 0, 4294967293, 0, 0, - 0, 0, 0, 3, - 4, 0, 5, 4294967286, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_1_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u64.c index bdb65d91c1fa..1250e5b36b2d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u64.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint64_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_1 -DEF_VEC_SAT_U_SUB_FMT_1(T) +DEF_VEC_SAT_U_SUB_FMT_1_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - }, /* arg_0 */ - { - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - }, /* arg_1 */ - { - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - }, /* expect */ - }, - { - { - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - }, - { - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - }, - { - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - }, - }, - { - { - 0, 18446744073709551615u, 1, 0, - 1, 18446744073709551615u, 3, 0, - 1, 18446744073709551614u, 3, 4, - 5, 18446744073709551614u, 18446744073709551615u, 9, - }, - { - 0, 1, 1, 18446744073709551614u, - 18446744073709551614u, 18446744073709551614u, 18446744073709551614u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 1, - }, - { - 0, 18446744073709551614u, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_1_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u8.c index 3fe5fe33befb..a2a77dd88e0c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-1-u8.c @@ -2,74 +2,15 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint8_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_1 -DEF_VEC_SAT_U_SUB_FMT_1(T) +DEF_VEC_SAT_U_SUB_FMT_1_WRAP(T) + +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_1_WRAP(T, out, op_1, op_2, N) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - }, - { - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - }, - { - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 2, 3, 255, - 5, 254, 255, 9, - }, - { - 0, 1, 0, 254, - 254, 254, 254, 255, - 255, 255, 0, 252, - 255, 255, 255, 1, - }, - { - 0, 0, 1, 0, - 0, 0, 0, 0, - 0, 0, 3, 3, - 0, 0, 0, 8, - }, - }, -}; #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u16.c index 0f4129ca665f..19c8fa056bf4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u16.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint16_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_10 -DEF_VEC_SAT_U_SUB_FMT_10(T) +DEF_VEC_SAT_U_SUB_FMT_10_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - }, - { - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - }, - { - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 65535, 3, 65535, - 5, 65534, 65535, 9, - }, - { - 0, 1, 1, 65534, - 65534, 65534, 1, 65535, - 0, 65535, 65535, 0, - 65535, 65535, 1, 2, - }, - { - 0, 0, 0, 0, - 0, 0, 2, 0, - 1, 0, 0, 65535, - 0, 0, 65534, 7, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_10_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u32.c index 8b995eb3a16a..ada136f4b945 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u32.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint32_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_10 -DEF_VEC_SAT_U_SUB_FMT_10(T) +DEF_VEC_SAT_U_SUB_FMT_10_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - }, /* expect */ - }, - { - { - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - }, - { - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - }, - { - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - }, - }, - { - { - 0, 0, 9, 0, - 1, 4294967295, 3, 0, - 1, 2, 3, 4, - 5, 4294967294, 4294967295, 4294967295, - }, - { - 0, 1, 1, 4294967294, - 1, 2, 4294967294, 4294967295, - 1, 4294967295, 4294967295, 1, - 1, 4294967295, 4294967290, 9, - }, - { - 0, 0, 8, 0, - 0, 4294967293, 0, 0, - 0, 0, 0, 3, - 4, 0, 5, 4294967286, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_10_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u64.c index d12d9815e83e..488c1588fe66 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u64.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint64_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_10 -DEF_VEC_SAT_U_SUB_FMT_10(T) +DEF_VEC_SAT_U_SUB_FMT_10_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - }, /* arg_0 */ - { - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - }, /* arg_1 */ - { - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - }, /* expect */ - }, - { - { - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - }, - { - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - }, - { - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - }, - }, - { - { - 0, 18446744073709551615u, 1, 0, - 1, 18446744073709551615u, 3, 0, - 1, 18446744073709551614u, 3, 4, - 5, 18446744073709551614u, 18446744073709551615u, 9, - }, - { - 0, 1, 1, 18446744073709551614u, - 18446744073709551614u, 18446744073709551614u, 18446744073709551614u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 1, - }, - { - 0, 18446744073709551614u, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_10_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u8.c index 384ef3e98091..127c27ab1e6d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-10-u8.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint8_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_10 -DEF_VEC_SAT_U_SUB_FMT_10(T) +DEF_VEC_SAT_U_SUB_FMT_10_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - }, - { - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - }, - { - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 2, 3, 255, - 5, 254, 255, 9, - }, - { - 0, 1, 0, 254, - 254, 254, 254, 255, - 255, 255, 0, 252, - 255, 255, 255, 1, - }, - { - 0, 0, 1, 0, - 0, 0, 0, 0, - 0, 0, 3, 3, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_10_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-11-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-11-u16.c new file mode 100644 index 000000000000..4b494672915f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-11-u16.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "vec_sat_arith.h" +#include "vec_sat_data.h" + +#define T uint16_t + +DEF_VEC_SAT_U_SUB_FMT_11_WRAP(T) + +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_11_WRAP(T, out, op_1, op_2, N) + +#include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-11-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-11-u32.c new file mode 100644 index 000000000000..80b55eab5381 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-11-u32.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "vec_sat_arith.h" +#include "vec_sat_data.h" + +#define T uint32_t + +DEF_VEC_SAT_U_SUB_FMT_11_WRAP(T) + +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_11_WRAP(T, out, op_1, op_2, N) + +#include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-11-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-11-u64.c new file mode 100644 index 000000000000..6a89d0f2c9d2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-11-u64.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "vec_sat_arith.h" +#include "vec_sat_data.h" + +#define T uint64_t + +DEF_VEC_SAT_U_SUB_FMT_11_WRAP(T) + +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_11_WRAP(T, out, op_1, op_2, N) + +#include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-11-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-11-u8.c new file mode 100644 index 000000000000..974493eb3029 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-11-u8.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "vec_sat_arith.h" +#include "vec_sat_data.h" + +#define T uint8_t + +DEF_VEC_SAT_U_SUB_FMT_11_WRAP(T) + +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_11_WRAP(T, out, op_1, op_2, N) + +#include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-12-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-12-u16.c new file mode 100644 index 000000000000..28778b9b3f4a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-12-u16.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "vec_sat_arith.h" +#include "vec_sat_data.h" + +#define T uint16_t + +DEF_VEC_SAT_U_SUB_FMT_12_WRAP(T) + +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_12_WRAP(T, out, op_1, op_2, N) + +#include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-12-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-12-u32.c new file mode 100644 index 000000000000..936a39a390d1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-12-u32.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "vec_sat_arith.h" +#include "vec_sat_data.h" + +#define T uint32_t + +DEF_VEC_SAT_U_SUB_FMT_12_WRAP(T) + +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_12_WRAP(T, out, op_1, op_2, N) + +#include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-12-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-12-u64.c new file mode 100644 index 000000000000..b8fa65b8abdf --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-12-u64.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "vec_sat_arith.h" +#include "vec_sat_data.h" + +#define T uint64_t + +DEF_VEC_SAT_U_SUB_FMT_12_WRAP(T) + +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_12_WRAP(T, out, op_1, op_2, N) + +#include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-12-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-12-u8.c new file mode 100644 index 000000000000..6bff1e11557f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-12-u8.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "vec_sat_arith.h" +#include "vec_sat_data.h" + +#define T uint8_t + +DEF_VEC_SAT_U_SUB_FMT_12_WRAP(T) + +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_12_WRAP(T, out, op_1, op_2, N) + +#include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u16.c index 5cf08ac3ed63..45bef8857cb5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u16.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint16_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_2 -DEF_VEC_SAT_U_SUB_FMT_2(T) +DEF_VEC_SAT_U_SUB_FMT_2_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - }, - { - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - }, - { - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 65535, 3, 65535, - 5, 65534, 65535, 9, - }, - { - 0, 1, 1, 65534, - 65534, 65534, 1, 65535, - 0, 65535, 65535, 0, - 65535, 65535, 1, 2, - }, - { - 0, 0, 0, 0, - 0, 0, 2, 0, - 1, 0, 0, 65535, - 0, 0, 65534, 7, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_2_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u32.c index 85c84542e64b..6d8a6533273f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u32.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint32_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_2 -DEF_VEC_SAT_U_SUB_FMT_2(T) +DEF_VEC_SAT_U_SUB_FMT_2_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - }, /* expect */ - }, - { - { - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - }, - { - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - }, - { - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - }, - }, - { - { - 0, 0, 9, 0, - 1, 4294967295, 3, 0, - 1, 2, 3, 4, - 5, 4294967294, 4294967295, 4294967295, - }, - { - 0, 1, 1, 4294967294, - 1, 2, 4294967294, 4294967295, - 1, 4294967295, 4294967295, 1, - 1, 4294967295, 4294967290, 9, - }, - { - 0, 0, 8, 0, - 0, 4294967293, 0, 0, - 0, 0, 0, 3, - 4, 0, 5, 4294967286, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_2_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u64.c index 67d5ac5d8998..0132d467499a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u64.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint64_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_2 -DEF_VEC_SAT_U_SUB_FMT_2(T) +DEF_VEC_SAT_U_SUB_FMT_2_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - }, /* arg_0 */ - { - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - }, /* arg_1 */ - { - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - }, /* expect */ - }, - { - { - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - }, - { - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - }, - { - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - }, - }, - { - { - 0, 18446744073709551615u, 1, 0, - 1, 18446744073709551615u, 3, 0, - 1, 18446744073709551614u, 3, 4, - 5, 18446744073709551614u, 18446744073709551615u, 9, - }, - { - 0, 1, 1, 18446744073709551614u, - 18446744073709551614u, 18446744073709551614u, 18446744073709551614u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 1, - }, - { - 0, 18446744073709551614u, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_2_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u8.c index 809f07fc6fc4..425f86f4fb75 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-2-u8.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint8_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_2 -DEF_VEC_SAT_U_SUB_FMT_2(T) +DEF_VEC_SAT_U_SUB_FMT_2_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - }, - { - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - }, - { - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 2, 3, 255, - 5, 254, 255, 9, - }, - { - 0, 1, 0, 254, - 254, 254, 254, 255, - 255, 255, 0, 252, - 255, 255, 255, 1, - }, - { - 0, 0, 1, 0, - 0, 0, 0, 0, - 0, 0, 3, 3, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_2_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u16.c index 57839a9cd98a..97a8e083063c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u16.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint16_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_3 -DEF_VEC_SAT_U_SUB_FMT_3(T) +DEF_VEC_SAT_U_SUB_FMT_3_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - }, - { - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - }, - { - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 65535, 3, 65535, - 5, 65534, 65535, 9, - }, - { - 0, 1, 1, 65534, - 65534, 65534, 1, 65535, - 0, 65535, 65535, 0, - 65535, 65535, 1, 2, - }, - { - 0, 0, 0, 0, - 0, 0, 2, 0, - 1, 0, 0, 65535, - 0, 0, 65534, 7, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_3_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u32.c index ffb0dcc4d186..912489984b59 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u32.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint32_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_3 -DEF_VEC_SAT_U_SUB_FMT_3(T) +DEF_VEC_SAT_U_SUB_FMT_3_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - }, /* expect */ - }, - { - { - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - }, - { - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - }, - { - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - }, - }, - { - { - 0, 0, 9, 0, - 1, 4294967295, 3, 0, - 1, 2, 3, 4, - 5, 4294967294, 4294967295, 4294967295, - }, - { - 0, 1, 1, 4294967294, - 1, 2, 4294967294, 4294967295, - 1, 4294967295, 4294967295, 1, - 1, 4294967295, 4294967290, 9, - }, - { - 0, 0, 8, 0, - 0, 4294967293, 0, 0, - 0, 0, 0, 3, - 4, 0, 5, 4294967286, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_3_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u64.c index 396667790b56..1e54ede3a8a5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u64.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint64_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_3 -DEF_VEC_SAT_U_SUB_FMT_3(T) +DEF_VEC_SAT_U_SUB_FMT_3_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - }, /* arg_0 */ - { - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - }, /* arg_1 */ - { - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - }, /* expect */ - }, - { - { - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - }, - { - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - }, - { - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - }, - }, - { - { - 0, 18446744073709551615u, 1, 0, - 1, 18446744073709551615u, 3, 0, - 1, 18446744073709551614u, 3, 4, - 5, 18446744073709551614u, 18446744073709551615u, 9, - }, - { - 0, 1, 1, 18446744073709551614u, - 18446744073709551614u, 18446744073709551614u, 18446744073709551614u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 1, - }, - { - 0, 18446744073709551614u, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_3_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u8.c index e795f62bfe2d..d8d53b7777ed 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-3-u8.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint8_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_3 -DEF_VEC_SAT_U_SUB_FMT_3(T) +DEF_VEC_SAT_U_SUB_FMT_3_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - }, - { - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - }, - { - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 2, 3, 255, - 5, 254, 255, 9, - }, - { - 0, 1, 0, 254, - 254, 254, 254, 255, - 255, 255, 0, 252, - 255, 255, 255, 1, - }, - { - 0, 0, 1, 0, - 0, 0, 0, 0, - 0, 0, 3, 3, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_3_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u16.c index 0eecf829686f..b29382316e65 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u16.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint16_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_4 -DEF_VEC_SAT_U_SUB_FMT_4(T) +DEF_VEC_SAT_U_SUB_FMT_4_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - }, - { - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - }, - { - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 65535, 3, 65535, - 5, 65534, 65535, 9, - }, - { - 0, 1, 1, 65534, - 65534, 65534, 1, 65535, - 0, 65535, 65535, 0, - 65535, 65535, 1, 2, - }, - { - 0, 0, 0, 0, - 0, 0, 2, 0, - 1, 0, 0, 65535, - 0, 0, 65534, 7, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_4_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u32.c index 1d0d16b7408d..f0f1c4ff0064 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u32.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint32_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_4 -DEF_VEC_SAT_U_SUB_FMT_4(T) +DEF_VEC_SAT_U_SUB_FMT_4_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - }, /* expect */ - }, - { - { - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - }, - { - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - }, - { - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - }, - }, - { - { - 0, 0, 9, 0, - 1, 4294967295, 3, 0, - 1, 2, 3, 4, - 5, 4294967294, 4294967295, 4294967295, - }, - { - 0, 1, 1, 4294967294, - 1, 2, 4294967294, 4294967295, - 1, 4294967295, 4294967295, 1, - 1, 4294967295, 4294967290, 9, - }, - { - 0, 0, 8, 0, - 0, 4294967293, 0, 0, - 0, 0, 0, 3, - 4, 0, 5, 4294967286, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_4_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u64.c index 98fdfa24b31a..27c28e26753c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u64.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint64_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_4 -DEF_VEC_SAT_U_SUB_FMT_4(T) +DEF_VEC_SAT_U_SUB_FMT_4_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - }, /* arg_0 */ - { - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - }, /* arg_1 */ - { - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - }, /* expect */ - }, - { - { - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - }, - { - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - }, - { - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - }, - }, - { - { - 0, 18446744073709551615u, 1, 0, - 1, 18446744073709551615u, 3, 0, - 1, 18446744073709551614u, 3, 4, - 5, 18446744073709551614u, 18446744073709551615u, 9, - }, - { - 0, 1, 1, 18446744073709551614u, - 18446744073709551614u, 18446744073709551614u, 18446744073709551614u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 1, - }, - { - 0, 18446744073709551614u, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_4_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u8.c index 18a887dd345e..791182513b40 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-4-u8.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint8_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_4 -DEF_VEC_SAT_U_SUB_FMT_4(T) +DEF_VEC_SAT_U_SUB_FMT_4_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - }, - { - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - }, - { - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 2, 3, 255, - 5, 254, 255, 9, - }, - { - 0, 1, 0, 254, - 254, 254, 254, 255, - 255, 255, 0, 252, - 255, 255, 255, 1, - }, - { - 0, 0, 1, 0, - 0, 0, 0, 0, - 0, 0, 3, 3, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_4_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u16.c index ce44c049c57e..6ae7b36e3160 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u16.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint16_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_5 -DEF_VEC_SAT_U_SUB_FMT_5(T) +DEF_VEC_SAT_U_SUB_FMT_5_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - }, - { - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - }, - { - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 65535, 3, 65535, - 5, 65534, 65535, 9, - }, - { - 0, 1, 1, 65534, - 65534, 65534, 1, 65535, - 0, 65535, 65535, 0, - 65535, 65535, 1, 2, - }, - { - 0, 0, 0, 0, - 0, 0, 2, 0, - 1, 0, 0, 65535, - 0, 0, 65534, 7, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_5_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u32.c index 36ae7b322c78..4e6b9e60070c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u32.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint32_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_5 -DEF_VEC_SAT_U_SUB_FMT_5(T) +DEF_VEC_SAT_U_SUB_FMT_5_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - }, /* expect */ - }, - { - { - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - }, - { - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - }, - { - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - }, - }, - { - { - 0, 0, 9, 0, - 1, 4294967295, 3, 0, - 1, 2, 3, 4, - 5, 4294967294, 4294967295, 4294967295, - }, - { - 0, 1, 1, 4294967294, - 1, 2, 4294967294, 4294967295, - 1, 4294967295, 4294967295, 1, - 1, 4294967295, 4294967290, 9, - }, - { - 0, 0, 8, 0, - 0, 4294967293, 0, 0, - 0, 0, 0, 3, - 4, 0, 5, 4294967286, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_5_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u64.c index 7b40ffdbed33..6b269135f6e2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u64.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint64_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_5 -DEF_VEC_SAT_U_SUB_FMT_5(T) +DEF_VEC_SAT_U_SUB_FMT_5_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - }, /* arg_0 */ - { - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - }, /* arg_1 */ - { - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - }, /* expect */ - }, - { - { - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - }, - { - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - }, - { - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - }, - }, - { - { - 0, 18446744073709551615u, 1, 0, - 1, 18446744073709551615u, 3, 0, - 1, 18446744073709551614u, 3, 4, - 5, 18446744073709551614u, 18446744073709551615u, 9, - }, - { - 0, 1, 1, 18446744073709551614u, - 18446744073709551614u, 18446744073709551614u, 18446744073709551614u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 1, - }, - { - 0, 18446744073709551614u, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_5_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u8.c index 3b0807febea5..2bd28cd68329 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-5-u8.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint8_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_5 -DEF_VEC_SAT_U_SUB_FMT_5(T) +DEF_VEC_SAT_U_SUB_FMT_5_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - }, - { - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - }, - { - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 2, 3, 255, - 5, 254, 255, 9, - }, - { - 0, 1, 0, 254, - 254, 254, 254, 255, - 255, 255, 0, 252, - 255, 255, 255, 1, - }, - { - 0, 0, 1, 0, - 0, 0, 0, 0, - 0, 0, 3, 3, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_5_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u16.c index e972078eca5f..69b0be984327 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u16.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint16_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_6 -DEF_VEC_SAT_U_SUB_FMT_6(T) +DEF_VEC_SAT_U_SUB_FMT_6_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - }, - { - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - }, - { - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 65535, 3, 65535, - 5, 65534, 65535, 9, - }, - { - 0, 1, 1, 65534, - 65534, 65534, 1, 65535, - 0, 65535, 65535, 0, - 65535, 65535, 1, 2, - }, - { - 0, 0, 0, 0, - 0, 0, 2, 0, - 1, 0, 0, 65535, - 0, 0, 65534, 7, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_6_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u32.c index 54e28487cac2..2450586b07dc 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u32.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint32_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_6 -DEF_VEC_SAT_U_SUB_FMT_6(T) +DEF_VEC_SAT_U_SUB_FMT_6_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - }, /* expect */ - }, - { - { - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - }, - { - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - }, - { - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - }, - }, - { - { - 0, 0, 9, 0, - 1, 4294967295, 3, 0, - 1, 2, 3, 4, - 5, 4294967294, 4294967295, 4294967295, - }, - { - 0, 1, 1, 4294967294, - 1, 2, 4294967294, 4294967295, - 1, 4294967295, 4294967295, 1, - 1, 4294967295, 4294967290, 9, - }, - { - 0, 0, 8, 0, - 0, 4294967293, 0, 0, - 0, 0, 0, 3, - 4, 0, 5, 4294967286, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_6_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u64.c index 33f3be04deba..0b979100534c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u64.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint64_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_6 -DEF_VEC_SAT_U_SUB_FMT_6(T) +DEF_VEC_SAT_U_SUB_FMT_6_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - }, /* arg_0 */ - { - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - }, /* arg_1 */ - { - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - }, /* expect */ - }, - { - { - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - }, - { - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - }, - { - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - }, - }, - { - { - 0, 18446744073709551615u, 1, 0, - 1, 18446744073709551615u, 3, 0, - 1, 18446744073709551614u, 3, 4, - 5, 18446744073709551614u, 18446744073709551615u, 9, - }, - { - 0, 1, 1, 18446744073709551614u, - 18446744073709551614u, 18446744073709551614u, 18446744073709551614u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 1, - }, - { - 0, 18446744073709551614u, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_6_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u8.c index 13760387814f..afb23f6362f9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-6-u8.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint8_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_6 -DEF_VEC_SAT_U_SUB_FMT_6(T) +DEF_VEC_SAT_U_SUB_FMT_6_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - }, - { - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - }, - { - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 2, 3, 255, - 5, 254, 255, 9, - }, - { - 0, 1, 0, 254, - 254, 254, 254, 255, - 255, 255, 0, 252, - 255, 255, 255, 1, - }, - { - 0, 0, 1, 0, - 0, 0, 0, 0, - 0, 0, 3, 3, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_6_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u16.c index 83241ef6f994..0466d4cd1543 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u16.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint16_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_7 -DEF_VEC_SAT_U_SUB_FMT_7(T) +DEF_VEC_SAT_U_SUB_FMT_7_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - }, - { - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - }, - { - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 65535, 3, 65535, - 5, 65534, 65535, 9, - }, - { - 0, 1, 1, 65534, - 65534, 65534, 1, 65535, - 0, 65535, 65535, 0, - 65535, 65535, 1, 2, - }, - { - 0, 0, 0, 0, - 0, 0, 2, 0, - 1, 0, 0, 65535, - 0, 0, 65534, 7, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_7_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u32.c index f20bb21e3b1f..14b8701e86f2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u32.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint32_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_7 -DEF_VEC_SAT_U_SUB_FMT_7(T) +DEF_VEC_SAT_U_SUB_FMT_7_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - }, /* expect */ - }, - { - { - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - }, - { - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - }, - { - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - }, - }, - { - { - 0, 0, 9, 0, - 1, 4294967295, 3, 0, - 1, 2, 3, 4, - 5, 4294967294, 4294967295, 4294967295, - }, - { - 0, 1, 1, 4294967294, - 1, 2, 4294967294, 4294967295, - 1, 4294967295, 4294967295, 1, - 1, 4294967295, 4294967290, 9, - }, - { - 0, 0, 8, 0, - 0, 4294967293, 0, 0, - 0, 0, 0, 3, - 4, 0, 5, 4294967286, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_7_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u64.c index 4ad0afd3a6f6..7e0afd81ecb9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u64.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint64_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_7 -DEF_VEC_SAT_U_SUB_FMT_7(T) +DEF_VEC_SAT_U_SUB_FMT_7_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - }, /* arg_0 */ - { - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - }, /* arg_1 */ - { - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - }, /* expect */ - }, - { - { - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - }, - { - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - }, - { - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - }, - }, - { - { - 0, 18446744073709551615u, 1, 0, - 1, 18446744073709551615u, 3, 0, - 1, 18446744073709551614u, 3, 4, - 5, 18446744073709551614u, 18446744073709551615u, 9, - }, - { - 0, 1, 1, 18446744073709551614u, - 18446744073709551614u, 18446744073709551614u, 18446744073709551614u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 1, - }, - { - 0, 18446744073709551614u, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_7_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u8.c index 3b33b136d414..40b1a6a2d652 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-7-u8.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint8_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_7 -DEF_VEC_SAT_U_SUB_FMT_7(T) +DEF_VEC_SAT_U_SUB_FMT_7_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - }, - { - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - }, - { - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 2, 3, 255, - 5, 254, 255, 9, - }, - { - 0, 1, 0, 254, - 254, 254, 254, 255, - 255, 255, 0, 252, - 255, 255, 255, 1, - }, - { - 0, 0, 1, 0, - 0, 0, 0, 0, - 0, 0, 3, 3, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_7_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u16.c index b212550fed33..bd33048203e2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u16.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint16_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_8 -DEF_VEC_SAT_U_SUB_FMT_8(T) +DEF_VEC_SAT_U_SUB_FMT_8_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - }, - { - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - }, - { - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 65535, 3, 65535, - 5, 65534, 65535, 9, - }, - { - 0, 1, 1, 65534, - 65534, 65534, 1, 65535, - 0, 65535, 65535, 0, - 65535, 65535, 1, 2, - }, - { - 0, 0, 0, 0, - 0, 0, 2, 0, - 1, 0, 0, 65535, - 0, 0, 65534, 7, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_8_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u32.c index 1fb707c3e807..36f78f51c4bf 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u32.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint32_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_8 -DEF_VEC_SAT_U_SUB_FMT_8(T) +DEF_VEC_SAT_U_SUB_FMT_8_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - }, /* expect */ - }, - { - { - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - }, - { - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - }, - { - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - }, - }, - { - { - 0, 0, 9, 0, - 1, 4294967295, 3, 0, - 1, 2, 3, 4, - 5, 4294967294, 4294967295, 4294967295, - }, - { - 0, 1, 1, 4294967294, - 1, 2, 4294967294, 4294967295, - 1, 4294967295, 4294967295, 1, - 1, 4294967295, 4294967290, 9, - }, - { - 0, 0, 8, 0, - 0, 4294967293, 0, 0, - 0, 0, 0, 3, - 4, 0, 5, 4294967286, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_8_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u64.c index da8c09c1eaa1..3bc5d5df3f26 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u64.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint64_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_8 -DEF_VEC_SAT_U_SUB_FMT_8(T) +DEF_VEC_SAT_U_SUB_FMT_8_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - }, /* arg_0 */ - { - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - }, /* arg_1 */ - { - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - }, /* expect */ - }, - { - { - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - }, - { - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - }, - { - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - }, - }, - { - { - 0, 18446744073709551615u, 1, 0, - 1, 18446744073709551615u, 3, 0, - 1, 18446744073709551614u, 3, 4, - 5, 18446744073709551614u, 18446744073709551615u, 9, - }, - { - 0, 1, 1, 18446744073709551614u, - 18446744073709551614u, 18446744073709551614u, 18446744073709551614u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 1, - }, - { - 0, 18446744073709551614u, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_8_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u8.c index 647607f29cfa..3964d1b21d7e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-8-u8.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint8_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_8 -DEF_VEC_SAT_U_SUB_FMT_8(T) +DEF_VEC_SAT_U_SUB_FMT_8_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - }, - { - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - }, - { - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 2, 3, 255, - 5, 254, 255, 9, - }, - { - 0, 1, 0, 254, - 254, 254, 254, 255, - 255, 255, 0, 252, - 255, 255, 255, 1, - }, - { - 0, 0, 1, 0, - 0, 0, 0, 0, - 0, 0, 3, 3, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_8_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u16.c index 9bb0664aa874..4c0809ac988d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u16.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint16_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_9 -DEF_VEC_SAT_U_SUB_FMT_9(T) +DEF_VEC_SAT_U_SUB_FMT_9_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - 65535, 65535, 65535, 65535, - }, - { - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - 55535, 45535, 35535, 25535, - }, - { - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - 10000, 20000, 30000, 40000, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 65535, 3, 65535, - 5, 65534, 65535, 9, - }, - { - 0, 1, 1, 65534, - 65534, 65534, 1, 65535, - 0, 65535, 65535, 0, - 65535, 65535, 1, 2, - }, - { - 0, 0, 0, 0, - 0, 0, 2, 0, - 1, 0, 0, 65535, - 0, 0, 65534, 7, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_9_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u32.c index f142b8b37fbf..3e700bd1060e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u32.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint32_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_9 -DEF_VEC_SAT_U_SUB_FMT_9(T) +DEF_VEC_SAT_U_SUB_FMT_9_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - 0, 0, 4, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - 0, 0, 2, 0, - }, /* expect */ - }, - { - { - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - 4294967295, 4294967295, 4294967295, 4294967295, - }, - { - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - 1294967295, 2294967295, 3294967295, 4294967295, - }, - { - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - 3000000000, 2000000000, 1000000000, 0, - }, - }, - { - { - 0, 0, 9, 0, - 1, 4294967295, 3, 0, - 1, 2, 3, 4, - 5, 4294967294, 4294967295, 4294967295, - }, - { - 0, 1, 1, 4294967294, - 1, 2, 4294967294, 4294967295, - 1, 4294967295, 4294967295, 1, - 1, 4294967295, 4294967290, 9, - }, - { - 0, 0, 8, 0, - 0, 4294967293, 0, 0, - 0, 0, 0, 3, - 4, 0, 5, 4294967286, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_9_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u64.c index 574b91a12f8b..81b8dc86ebb3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u64.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint64_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_9 -DEF_VEC_SAT_U_SUB_FMT_9(T) +DEF_VEC_SAT_U_SUB_FMT_9_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - 0, 9, 0, 0, - }, /* arg_0 */ - { - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - 0, 2, 3, 1, - }, /* arg_1 */ - { - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - 0, 7, 0, 0, - }, /* expect */ - }, - { - { - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - }, - { - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - 10446744073709551615u, 11446744073709551615u, 12446744073709551615u, 18446744073709551615u, - }, - { - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - 8000000000000000000u, 7000000000000000000u, 6000000000000000000u, 0u, - }, - }, - { - { - 0, 18446744073709551615u, 1, 0, - 1, 18446744073709551615u, 3, 0, - 1, 18446744073709551614u, 3, 4, - 5, 18446744073709551614u, 18446744073709551615u, 9, - }, - { - 0, 1, 1, 18446744073709551614u, - 18446744073709551614u, 18446744073709551614u, 18446744073709551614u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, - 18446744073709551615u, 18446744073709551615u, 18446744073709551615u, 1, - }, - { - 0, 18446744073709551614u, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_9_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u8.c index 2c8ee4232d72..8bc52ae83364 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub-run-9-u8.c @@ -2,74 +2,14 @@ /* { dg-additional-options "-std=c99" } */ #include "vec_sat_arith.h" +#include "vec_sat_data.h" #define T uint8_t -#define N 16 -#define RUN_VEC_SAT_BINARY RUN_VEC_SAT_U_SUB_FMT_9 -DEF_VEC_SAT_U_SUB_FMT_9(T) +DEF_VEC_SAT_U_SUB_FMT_9_WRAP(T) -T test_data[][3][N] = { - { - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* arg_0 */ - { - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - 0, 1, 2, 3, - }, /* arg_1 */ - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - }, /* expect */ - }, - { - { - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - 0, 255, 255, 255, - }, - { - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - 1, 255, 254, 251, - }, - { - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - 0, 0, 1, 4, - }, - }, - { - { - 0, 0, 1, 0, - 1, 2, 3, 0, - 1, 2, 3, 255, - 5, 254, 255, 9, - }, - { - 0, 1, 0, 254, - 254, 254, 254, 255, - 255, 255, 0, 252, - 255, 255, 255, 1, - }, - { - 0, 0, 1, 0, - 0, 0, 0, 0, - 0, 0, 3, 3, - 0, 0, 0, 8, - }, - }, -}; +#define test_data TEST_UNARY_DATA_WRAP(T, ussub) +#define RUN_VEC_SAT_BINARY(T, out, op_1, op_2, N) \ + RUN_VEC_SAT_U_SUB_FMT_9_WRAP(T, out, op_1, op_2, N) #include "vec_sat_binary_vvv_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub_trunc-1-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub_trunc-1-u16.c index 2261872e3de2..b32907afcbb1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub_trunc-1-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub_trunc-1-u16.c @@ -6,5 +6,5 @@ DEF_VEC_SAT_U_SUB_TRUNC_FMT_1(uint16_t, uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ -/* { dg-final { scan-assembler-times {vssubu\.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vssubu\.vv} 1 } } */ /* { dg-final { scan-assembler-times {vnsrl\.wi} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub_trunc-1-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub_trunc-1-u32.c index 4250567686a6..344080cb93a7 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub_trunc-1-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub_trunc-1-u32.c @@ -6,5 +6,5 @@ DEF_VEC_SAT_U_SUB_TRUNC_FMT_1(uint32_t, uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ -/* { dg-final { scan-assembler-times {vssubu\.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vssubu\.vv} 1 } } */ /* { dg-final { scan-assembler-times {vnsrl\.wi} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub_trunc-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub_trunc-1-u8.c index 656aad70165c..492c3168216f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub_trunc-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_u_sub_trunc-1-u8.c @@ -6,5 +6,5 @@ DEF_VEC_SAT_U_SUB_TRUNC_FMT_1(uint8_t, uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ -/* { dg-final { scan-assembler-times {vssubu\.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vssubu\.vv} 1 } } */ /* { dg-final { scan-assembler-times {vnsrl\.wi} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c index 821e5c589a48..811f26c156a9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c @@ -3,8 +3,28 @@ #include "vf_mulop.h" -DEF_VF_MULOP_CASE_0(_Float16, +, add) -DEF_VF_MULOP_CASE_0(_Float16, -, sub) +DEF_VF_MULOP_CASE_0 (_Float16, +, +, add) +DEF_VF_MULOP_CASE_0 (_Float16, -, +, sub) +DEF_VF_MULOP_CASE_0 (_Float16, +, -, nadd) +DEF_VF_MULOP_CASE_0 (_Float16, -, -, nsub) +DEF_VF_MULOP_ACC_CASE_0 (_Float16, +, +, acc) +DEF_VF_MULOP_ACC_CASE_0 (_Float16, -, +, sac) +DEF_VF_MULOP_ACC_CASE_0 (_Float16, +, -, nacc) +DEF_VF_MULOP_ACC_CASE_0 (_Float16, -, -, nsac) +DEF_VF_MULOP_WIDEN_CASE_0 (_Float16, float, +, +, acc) +DEF_VF_MULOP_WIDEN_CASE_0 (_Float16, float, -, +, sac) +DEF_VF_MULOP_WIDEN_CASE_0 (_Float16, float, +, -, nacc) +DEF_VF_MULOP_WIDEN_CASE_0 (_Float16, float, -, -, nsac) /* { dg-final { scan-assembler-times {vfmadd.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfmsub.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfnmadd.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfnmsub.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfmacc.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfmsac.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfnmacc.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfnmsac.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfwmacc.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfwmsac.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfwnmacc.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfwnmsac.vf} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c index 49b42879a51c..ca82ead9d28c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c @@ -3,8 +3,28 @@ #include "vf_mulop.h" -DEF_VF_MULOP_CASE_0(float, +, add) -DEF_VF_MULOP_CASE_0(float, -, sub) +DEF_VF_MULOP_CASE_0 (float, +, +, add) +DEF_VF_MULOP_CASE_0 (float, -, +, sub) +DEF_VF_MULOP_CASE_0 (float, +, -, nadd) +DEF_VF_MULOP_CASE_0 (float, -, -, nsub) +DEF_VF_MULOP_ACC_CASE_0 (float, +, +, acc) +DEF_VF_MULOP_ACC_CASE_0 (float, -, +, sac) +DEF_VF_MULOP_ACC_CASE_0 (float, +, -, nacc) +DEF_VF_MULOP_ACC_CASE_0 (float, -, -, nsac) +DEF_VF_MULOP_WIDEN_CASE_0 (float, double, +, +, acc) +DEF_VF_MULOP_WIDEN_CASE_0 (float, double, -, +, sac) +DEF_VF_MULOP_WIDEN_CASE_0 (float, double, +, -, nacc) +DEF_VF_MULOP_WIDEN_CASE_0 (float, double, -, -, nsac) /* { dg-final { scan-assembler-times {vfmadd.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfmsub.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfnmadd.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfnmsub.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfmacc.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfmsac.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfnmacc.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfnmsac.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfwmacc.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfwmsac.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfwnmacc.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfwnmsac.vf} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c index 2bb5d8912375..4de038c62994 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c @@ -3,8 +3,20 @@ #include "vf_mulop.h" -DEF_VF_MULOP_CASE_0(double, +, add) -DEF_VF_MULOP_CASE_0(double, -, sub) +DEF_VF_MULOP_CASE_0 (double, +, +, add) +DEF_VF_MULOP_CASE_0 (double, -, +, sub) +DEF_VF_MULOP_CASE_0 (double, +, -, nadd) +DEF_VF_MULOP_CASE_0 (double, -, -, nsub) +DEF_VF_MULOP_ACC_CASE_0 (double, +, +, acc) +DEF_VF_MULOP_ACC_CASE_0 (double, -, +, sac) +DEF_VF_MULOP_ACC_CASE_0 (double, +, -, nacc) +DEF_VF_MULOP_ACC_CASE_0 (double, -, -, nsac) /* { dg-final { scan-assembler-times {vfmadd.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfmsub.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfnmadd.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfnmsub.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfmacc.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfmsac.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfnmacc.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfnmsac.vf} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c index cbb43cabe98b..3a39303f9422 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c @@ -1,10 +1,19 @@ /* { dg-do compile } */ /* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d --param=fpr2vr-cost=1" } */ -#include "vf_mulop.h" - -DEF_VF_MULOP_CASE_0(_Float16, +, add) -DEF_VF_MULOP_CASE_0(_Float16, -, sub) +#include "vf-1-f16.c" /* { dg-final { scan-assembler-not {vfmadd.vf} } } */ /* { dg-final { scan-assembler-not {vfmsub.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmadd.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmsub.vf} } } */ +/* { dg-final { scan-assembler-not {vfmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfmsac.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmsac.vf} } } */ +/* { dg-final { scan-assembler-not {vfwmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfwmsac.vf} } } */ +/* { dg-final { scan-assembler-not {vfwnmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfwnmsac.vf} } } */ +/* { dg-final { scan-assembler-times {fcvt.s.h} 4 } } */ +/* { dg-final { scan-assembler-times {vfmv.v.f} 12 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c index 66ff9b8c75e6..b4618bae70eb 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c @@ -1,10 +1,19 @@ /* { dg-do compile } */ /* { dg-options "-march=rv64gcv -mabi=lp64d --param=fpr2vr-cost=1" } */ -#include "vf_mulop.h" - -DEF_VF_MULOP_CASE_0(float, +, add) -DEF_VF_MULOP_CASE_0(float, -, sub) +#include "vf-1-f32.c" /* { dg-final { scan-assembler-not {vfmadd.vf} } } */ /* { dg-final { scan-assembler-not {vfmsub.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmadd.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmsub.vf} } } */ +/* { dg-final { scan-assembler-not {vfmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfmsac.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmsac.vf} } } */ +/* { dg-final { scan-assembler-not {vfwmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfwmsac.vf} } } */ +/* { dg-final { scan-assembler-not {vfwnmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfwnmsac.vf} } } */ +/* { dg-final { scan-assembler-times {fcvt.d.s} 4 } } */ +/* { dg-final { scan-assembler-times {vfmv.v.f} 12 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c index 66ff9b8c75e6..a2ac67e4a8d9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c @@ -1,10 +1,13 @@ /* { dg-do compile } */ /* { dg-options "-march=rv64gcv -mabi=lp64d --param=fpr2vr-cost=1" } */ -#include "vf_mulop.h" - -DEF_VF_MULOP_CASE_0(float, +, add) -DEF_VF_MULOP_CASE_0(float, -, sub) +#include "vf-1-f64.c" /* { dg-final { scan-assembler-not {vfmadd.vf} } } */ /* { dg-final { scan-assembler-not {vfmsub.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmadd.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmsub.vf} } } */ +/* { dg-final { scan-assembler-not {vfmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfmsac.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmsac.vf} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c index 45980f496938..58afaa4aef9a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c @@ -3,8 +3,28 @@ #include "vf_mulop.h" -DEF_VF_MULOP_CASE_1(_Float16, +, add, VF_MULOP_BODY_X16) -DEF_VF_MULOP_CASE_1(_Float16, -, sub, VF_MULOP_BODY_X16) +DEF_VF_MULOP_CASE_1 (_Float16, +, +, add, VF_MULOP_BODY_X16) +DEF_VF_MULOP_CASE_1 (_Float16, -, +, sub, VF_MULOP_BODY_X16) +DEF_VF_MULOP_CASE_1 (_Float16, +, -, nadd, VF_MULOP_BODY_X16) +DEF_VF_MULOP_CASE_1 (_Float16, -, -, nsub, VF_MULOP_BODY_X16) +DEF_VF_MULOP_ACC_CASE_1 (_Float16, +, +, acc, VF_MULOP_ACC_BODY_X128) +DEF_VF_MULOP_ACC_CASE_1 (_Float16, -, +, sac, VF_MULOP_ACC_BODY_X128) +DEF_VF_MULOP_ACC_CASE_1 (_Float16, +, -, nacc, VF_MULOP_ACC_BODY_X128) +DEF_VF_MULOP_ACC_CASE_1 (_Float16, -, -, nsac, VF_MULOP_ACC_BODY_X128) +DEF_VF_MULOP_WIDEN_CASE_1 (_Float16, float, +, +, acc) +DEF_VF_MULOP_WIDEN_CASE_1 (_Float16, float, -, +, sac) +DEF_VF_MULOP_WIDEN_CASE_1 (_Float16, float, +, -, nacc) +DEF_VF_MULOP_WIDEN_CASE_1 (_Float16, float, -, -, nsac) /* { dg-final { scan-assembler {vfmadd.vf} } } */ /* { dg-final { scan-assembler {vfmsub.vf} } } */ +/* { dg-final { scan-assembler {vfnmadd.vf} } } */ +/* { dg-final { scan-assembler {vfnmsub.vf} } } */ +/* { dg-final { scan-assembler {vfmacc.vf} } } */ +/* { dg-final { scan-assembler {vfmsac.vf} } } */ +/* { dg-final { scan-assembler {vfnmacc.vf} } } */ +/* { dg-final { scan-assembler {vfnmsac.vf} } } */ +/* { dg-final { scan-assembler {vfwmacc.vf} } } */ +/* { dg-final { scan-assembler {vfwmsac.vf} } } */ +/* { dg-final { scan-assembler {vfwnmacc.vf} } } */ +/* { dg-final { scan-assembler {vfwnmsac.vf} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c index c853620bb131..0e95774a489a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c @@ -3,8 +3,28 @@ #include "vf_mulop.h" -DEF_VF_MULOP_CASE_1(float, +, add, VF_MULOP_BODY_X16) -DEF_VF_MULOP_CASE_1(float, -, sub, VF_MULOP_BODY_X16) +DEF_VF_MULOP_CASE_1 (float, +, +, add, VF_MULOP_BODY_X16) +DEF_VF_MULOP_CASE_1 (float, -, +, sub, VF_MULOP_BODY_X16) +DEF_VF_MULOP_CASE_1 (float, +, -, nadd, VF_MULOP_BODY_X16) +DEF_VF_MULOP_CASE_1 (float, -, -, nsub, VF_MULOP_BODY_X16) +DEF_VF_MULOP_ACC_CASE_1 (float, +, +, acc, VF_MULOP_ACC_BODY_X128) +DEF_VF_MULOP_ACC_CASE_1 (float, -, +, sac, VF_MULOP_ACC_BODY_X128) +DEF_VF_MULOP_ACC_CASE_1 (float, +, -, nacc, VF_MULOP_ACC_BODY_X128) +DEF_VF_MULOP_ACC_CASE_1 (float, -, -, nsac, VF_MULOP_ACC_BODY_X128) +DEF_VF_MULOP_WIDEN_CASE_1 (float, double, +, +, acc) +DEF_VF_MULOP_WIDEN_CASE_1 (float, double, -, +, sac) +DEF_VF_MULOP_WIDEN_CASE_1 (float, double, +, -, nacc) +DEF_VF_MULOP_WIDEN_CASE_1 (float, double, -, -, nsac) /* { dg-final { scan-assembler {vfmadd.vf} } } */ /* { dg-final { scan-assembler {vfmsub.vf} } } */ +/* { dg-final { scan-assembler {vfnmadd.vf} } } */ +/* { dg-final { scan-assembler {vfnmsub.vf} } } */ +/* { dg-final { scan-assembler {vfmacc.vf} } } */ +/* { dg-final { scan-assembler {vfmsac.vf} } } */ +/* { dg-final { scan-assembler {vfnmacc.vf} } } */ +/* { dg-final { scan-assembler {vfnmsac.vf} } } */ +/* { dg-final { scan-assembler {vfwmacc.vf} } } */ +/* { dg-final { scan-assembler {vfwmsac.vf} } } */ +/* { dg-final { scan-assembler {vfwnmacc.vf} } } */ +/* { dg-final { scan-assembler {vfwnmsac.vf} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c index d38ae8b32209..71bd7e1b9573 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c @@ -3,8 +3,20 @@ #include "vf_mulop.h" -DEF_VF_MULOP_CASE_1(double, +, add, VF_MULOP_BODY_X16) -DEF_VF_MULOP_CASE_1(double, -, sub, VF_MULOP_BODY_X16) +DEF_VF_MULOP_CASE_1 (double, +, +, add, VF_MULOP_BODY_X16) +DEF_VF_MULOP_CASE_1 (double, -, +, sub, VF_MULOP_BODY_X16) +DEF_VF_MULOP_CASE_1 (double, +, -, nadd, VF_MULOP_BODY_X16) +DEF_VF_MULOP_CASE_1 (double, -, -, nsub, VF_MULOP_BODY_X16) +DEF_VF_MULOP_ACC_CASE_1 (double, +, +, acc, VF_MULOP_ACC_BODY_X128) +DEF_VF_MULOP_ACC_CASE_1 (double, -, +, sac, VF_MULOP_ACC_BODY_X128) +DEF_VF_MULOP_ACC_CASE_1 (double, +, -, nacc, VF_MULOP_ACC_BODY_X128) +DEF_VF_MULOP_ACC_CASE_1 (double, -, -, nsac, VF_MULOP_ACC_BODY_X128) /* { dg-final { scan-assembler {vfmadd.vf} } } */ /* { dg-final { scan-assembler {vfmsub.vf} } } */ +/* { dg-final { scan-assembler {vfnmadd.vf} } } */ +/* { dg-final { scan-assembler {vfnmsub.vf} } } */ +/* { dg-final { scan-assembler {vfmacc.vf} } } */ +/* { dg-final { scan-assembler {vfmsac.vf} } } */ +/* { dg-final { scan-assembler {vfnmacc.vf} } } */ +/* { dg-final { scan-assembler {vfnmsac.vf} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c index f1ca34e6d564..559df6c7976b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c @@ -1,10 +1,18 @@ /* { dg-do compile } */ /* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d --param=fpr2vr-cost=4" } */ -#include "vf_mulop.h" - -DEF_VF_MULOP_CASE_1(_Float16, +, add, VF_MULOP_BODY_X16) -DEF_VF_MULOP_CASE_1(_Float16, -, sub, VF_MULOP_BODY_X16) +#include "vf-3-f16.c" /* { dg-final { scan-assembler-not {vfmadd.vf} } } */ /* { dg-final { scan-assembler-not {vfmsub.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmadd.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmsub.vf} } } */ +/* { dg-final { scan-assembler-not {vfmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfmsac.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmsac.vf} } } */ +/* { dg-final { scan-assembler-not {vfwmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfwmsac.vf} } } */ +/* { dg-final { scan-assembler-not {vfwnmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfwnmsac.vf} } } */ +/* { dg-final { scan-assembler {fcvt.s.h} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c index 6730d4b154d0..03f9c5a3d864 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c @@ -1,10 +1,18 @@ /* { dg-do compile } */ /* { dg-options "-march=rv64gcv -mabi=lp64d --param=fpr2vr-cost=4" } */ -#include "vf_mulop.h" - -DEF_VF_MULOP_CASE_1(float, +, add, VF_MULOP_BODY_X16) -DEF_VF_MULOP_CASE_1(float, -, sub, VF_MULOP_BODY_X16) +#include "vf-3-f32.c" /* { dg-final { scan-assembler-not {vfmadd.vf} } } */ /* { dg-final { scan-assembler-not {vfmsub.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmadd.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmsub.vf} } } */ +/* { dg-final { scan-assembler-not {vfmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfmsac.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmsac.vf} } } */ +/* { dg-final { scan-assembler-not {vfwmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfwmsac.vf} } } */ +/* { dg-final { scan-assembler-not {vfwnmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfwnmsac.vf} } } */ +/* { dg-final { scan-assembler {fcvt.d.s} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c index bcb6a6e56964..d71bdde26afe 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c @@ -1,10 +1,13 @@ /* { dg-do compile } */ /* { dg-options "-march=rv64gcv -mabi=lp64d --param=fpr2vr-cost=4" } */ -#include "vf_mulop.h" - -DEF_VF_MULOP_CASE_1(double, +, add, VF_MULOP_BODY_X16) -DEF_VF_MULOP_CASE_1(double, -, sub, VF_MULOP_BODY_X16) +#include "vf-3-f64.c" /* { dg-final { scan-assembler-not {vfmadd.vf} } } */ /* { dg-final { scan-assembler-not {vfmsub.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmadd.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmsub.vf} } } */ +/* { dg-final { scan-assembler-not {vfmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfmsac.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmacc.vf} } } */ +/* { dg-final { scan-assembler-not {vfnmsac.vf} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop.h index 525397889063..b1a324f65ce6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop.h @@ -3,59 +3,160 @@ #include -#define DEF_VF_MULOP_CASE_0(T, OP, NAME) \ - void test_vf_mulop_##NAME##_##T##_case_0(T *restrict out, T *restrict in, \ - T x, unsigned n) { \ +#define DEF_VF_MULOP_CASE_0(T, OP, NEG, NAME) \ + void test_vf_mulop_##NAME##_##T##_case_0 (T *restrict out, T *restrict in, \ + T f, unsigned n) \ + { \ for (unsigned i = 0; i < n; i++) \ - out[i] = in[i] OP out[i] * x; \ + out[i] = NEG (f * out[i] OP in[i]); \ } -#define DEF_VF_MULOP_CASE_0_WRAP(T, OP, NAME) DEF_VF_MULOP_CASE_0(T, OP, NAME) +#define DEF_VF_MULOP_CASE_0_WRAP(T, OP, NEG, NAME) \ + DEF_VF_MULOP_CASE_0 (T, OP, NEG, NAME) #define RUN_VF_MULOP_CASE_0(T, NAME, out, in, x, n) \ test_vf_mulop_##NAME##_##T##_case_0(out, in, x, n) #define RUN_VF_MULOP_CASE_0_WRAP(T, NAME, out, in, x, n) \ RUN_VF_MULOP_CASE_0(T, NAME, out, in, x, n) -#define VF_MULOP_BODY(op) \ - out[k + 0] = in[k + 0] op tmp * out[k + 0]; \ - out[k + 1] = in[k + 1] op tmp * out[k + 1]; \ +#define DEF_VF_MULOP_ACC_CASE_0(T, OP, NEG, NAME) \ + T test_vf_mulop_acc_##NAME##_##T##_case_0 (T *restrict out, T *restrict in, \ + T f, unsigned n) \ + { \ + unsigned i; \ + for (i = 0; i < n; i++) \ + out[i] = NEG (f * in[i] OP out[i]); \ + /* Ensure that we get acc rather than add by reusing the multiplicand. */ \ + return in[i - 1]; \ + } +#define DEF_VF_MULOP_ACC_CASE_0_WRAP(T, OP, NEG, NAME) \ + DEF_VF_MULOP_ACC_CASE_0 (T, OP, NEG, NAME) +#define RUN_VF_MULOP_ACC_CASE_0(T, NAME, out, in, x, n) \ + test_vf_mulop_acc_##NAME##_##T##_case_0 (out, in, x, n) +#define RUN_VF_MULOP_ACC_CASE_0_WRAP(T, NAME, out, in, x, n) \ + RUN_VF_MULOP_ACC_CASE_0 (T, NAME, out, in, x, n) + +#define DEF_VF_MULOP_WIDEN_CASE_0(T1, T2, OP, NEG, NAME) \ + void test_vf_mulop_widen_##NAME##_##T1##_case_0 (T2 *restrict out, \ + T1 *restrict in, \ + T1 *restrict f, unsigned n) \ + { \ + for (unsigned i = 0; i < n; i++) \ + out[i] = NEG ((T2) * f * (T2) in[i] OP out[i]); \ + } +#define DEF_VF_MULOP_WIDEN_CASE_0_WRAP(T1, T2, OP, NEG, NAME) \ + DEF_VF_MULOP_WIDEN_CASE_0 (T1, T2, OP, NEG, NAME) +#define RUN_VF_MULOP_WIDEN_CASE_0(T1, T2, NAME, out, in, x, n) \ + test_vf_mulop_widen_##NAME##_##T1##_case_0 (out, in, x, n) +#define RUN_VF_MULOP_WIDEN_CASE_0_WRAP(T1, T2, NAME, out, in, x, n) \ + RUN_VF_MULOP_WIDEN_CASE_0 (T1, T2, NAME, out, in, x, n) + +#define VF_MULOP_BODY(op, neg) \ + out[k + 0] = neg (tmp * out[k + 0] op in[k + 0]); \ + out[k + 1] = neg (tmp * out[k + 1] op in[k + 1]); \ k += 2; -#define VF_MULOP_BODY_X4(op) \ - VF_MULOP_BODY(op) \ - VF_MULOP_BODY(op) +#define VF_MULOP_BODY_X4(op, neg) \ + VF_MULOP_BODY (op, neg) \ + VF_MULOP_BODY (op, neg) -#define VF_MULOP_BODY_X8(op) \ - VF_MULOP_BODY_X4(op) \ - VF_MULOP_BODY_X4(op) +#define VF_MULOP_BODY_X8(op, neg) \ + VF_MULOP_BODY_X4 (op, neg) \ + VF_MULOP_BODY_X4 (op, neg) -#define VF_MULOP_BODY_X16(op) \ - VF_MULOP_BODY_X8(op) \ - VF_MULOP_BODY_X8(op) +#define VF_MULOP_BODY_X16(op, neg) \ + VF_MULOP_BODY_X8 (op, neg) \ + VF_MULOP_BODY_X8 (op, neg) -#define VF_MULOP_BODY_X32(op) \ - VF_MULOP_BODY_X16(op) \ - VF_MULOP_BODY_X16(op) +#define VF_MULOP_BODY_X32(op, neg) \ + VF_MULOP_BODY_X16 (op, neg) \ + VF_MULOP_BODY_X16 (op, neg) -#define VF_MULOP_BODY_X64(op) \ - VF_MULOP_BODY_X32(op) \ - VF_MULOP_BODY_X32(op) +#define VF_MULOP_BODY_X64(op, neg) \ + VF_MULOP_BODY_X32 (op, neg) \ + VF_MULOP_BODY_X32 (op, neg) -#define VF_MULOP_BODY_X128(op) \ - VF_MULOP_BODY_X64(op) \ - VF_MULOP_BODY_X64(op) +#define VF_MULOP_BODY_X128(op, neg) \ + VF_MULOP_BODY_X64 (op, neg) \ + VF_MULOP_BODY_X64 (op, neg) -#define DEF_VF_MULOP_CASE_1(T, OP, NAME, BODY) \ - void test_vf_mulop_##NAME##_##T##_case_1(T *restrict out, T *restrict in, \ - T x, unsigned n) { \ +#define DEF_VF_MULOP_CASE_1(T, OP, NEG, NAME, BODY) \ + void test_vf_mulop_##NAME##_##T##_case_1 (T *restrict out, T *restrict in, \ + T x, unsigned n) \ + { \ unsigned k = 0; \ T tmp = x + 3; \ \ - while (k < n) { \ - tmp = tmp * 0x3f; \ - BODY(OP) \ - } \ + while (k < n) \ + { \ + tmp = tmp * 0x3f; \ + BODY (OP, NEG) \ + } \ + } +#define DEF_VF_MULOP_CASE_1_WRAP(T, OP, NEG, NAME, BODY) \ + DEF_VF_MULOP_CASE_1 (T, OP, NEG, NAME, BODY) + +#define VF_MULOP_ACC_BODY(op, neg) \ + out[k + 0] = neg (tmp * in[k + 0] op out[k + 1]); \ + out[k + 1] = neg (tmp * in[k + 1] op out[k + 1]); \ + k += 2; + +#define VF_MULOP_ACC_BODY_X4(op, neg) \ + VF_MULOP_ACC_BODY (op, neg) \ + VF_MULOP_ACC_BODY (op, neg) + +#define VF_MULOP_ACC_BODY_X8(op, neg) \ + VF_MULOP_ACC_BODY_X4 (op, neg) \ + VF_MULOP_ACC_BODY_X4 (op, neg) + +#define VF_MULOP_ACC_BODY_X16(op, neg) \ + VF_MULOP_ACC_BODY_X8 (op, neg) \ + VF_MULOP_ACC_BODY_X8 (op, neg) + +#define VF_MULOP_ACC_BODY_X32(op, neg) \ + VF_MULOP_ACC_BODY_X16 (op, neg) \ + VF_MULOP_ACC_BODY_X16 (op, neg) + +#define VF_MULOP_ACC_BODY_X64(op, neg) \ + VF_MULOP_ACC_BODY_X32 (op, neg) \ + VF_MULOP_ACC_BODY_X32 (op, neg) + +#define VF_MULOP_ACC_BODY_X128(op, neg) \ + VF_MULOP_ACC_BODY_X64 (op, neg) \ + VF_MULOP_ACC_BODY_X64 (op, neg) + +#define VF_MULOP_ACC_BODY_X256(op, neg) \ + VF_MULOP_ACC_BODY_X128 (op, neg) \ + VF_MULOP_ACC_BODY_X128 (op, neg) + +#define DEF_VF_MULOP_ACC_CASE_1(T, OP, NEG, NAME, BODY) \ + void test_vf_mulop_acc_##NAME##_##T##_case_1 (T *restrict out, \ + T *restrict in, T x, \ + unsigned n) \ + { \ + unsigned k = 0; \ + T tmp = x + 3; \ + \ + while (k < n) \ + { \ + tmp = tmp * 0x3f; \ + BODY (OP, NEG) \ + } \ + } +#define DEF_VF_MULOP_ACC_CASE_1_WRAP(T, OP, NEG, NAME, BODY) \ + DEF_VF_MULOP_ACC_CASE_1 (T, OP, NEG, NAME, BODY) + +#define DEF_VF_MULOP_WIDEN_CASE_1(TYPE1, TYPE2, OP, NEG, NAME) \ + void test_vf_mulop_widen_##NAME##_##TYPE1##_##TYPE2##_case_1 ( \ + TYPE2 *__restrict dst, TYPE2 *__restrict dst2, TYPE2 *__restrict dst3, \ + TYPE2 *__restrict dst4, TYPE1 *__restrict a, TYPE1 *__restrict b, \ + TYPE1 *__restrict a2, TYPE1 *__restrict b2, int n) \ + { \ + for (int i = 0; i < n; i++) \ + { \ + dst[i] = NEG ((TYPE2) * a * (TYPE2) b[i] OP dst[i]); \ + dst2[i] = NEG ((TYPE2) * a2 * (TYPE2) b[i] OP dst2[i]); \ + dst3[i] = NEG ((TYPE2) * a2 * (TYPE2) a[i] OP dst3[i]); \ + dst4[i] = NEG ((TYPE2) * a * (TYPE2) b2[i] OP dst4[i]); \ + } \ } -#define DEF_VF_MULOP_CASE_1_WRAP(T, OP, NAME, BODY) \ - DEF_VF_MULOP_CASE_1(T, OP, NAME, BODY) #endif diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop_data.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop_data.h index c16c1a971f7c..ffa3d287751d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop_data.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop_data.h @@ -209,6 +209,408 @@ double TEST_MULOP_DATA(double, add)[][4][N] = }; _Float16 TEST_MULOP_DATA(_Float16, sub)[][4][N] = +{ + { + { 5.94f16 }, + { + -20.1f16, -20.1f16, -20.1f16, -20.1f16, + -13.1f16, -13.1f16, -13.1f16, -13.1f16, + -8.92f16, -8.92f16, -8.92f16, -8.92f16, + -43.1f16, -43.1f16, -43.1f16, -43.1f16, + }, + { + 7.44f16, 7.44f16, 7.44f16, 7.44f16, + 5.9f16, 5.9f16, 5.9f16, 5.9f16, + 6.81f16, 6.81f16, 6.81f16, 6.81f16, + 9.03f16, 9.03f16, 9.03f16, 9.03f16, + }, + { + 64.2f16, 64.2f16, 64.2f16, 64.2f16, + 48.1f16, 48.1f16, 48.1f16, 48.1f16, + 49.4f16, 49.4f16, 49.4f16, 49.4f16, + 96.7f16, 96.7f16, 96.7f16, 96.7f16, + } + }, + { + { 0.0475f16 }, + { + -0.0965f16, -0.0965f16, -0.0965f16, -0.0965f16, + -0.23f16, -0.23f16, -0.23f16, -0.23f16, + -0.267f16, -0.267f16, -0.267f16, -0.267f16, + -0.455f16, -0.455f16, -0.455f16, -0.455f16, + }, + { + 0.0748f16, 0.0748f16, 0.0748f16, 0.0748f16, + 0.0372f16, 0.0372f16, 0.0372f16, 0.0372f16, + 0.0183f16, 0.0183f16, 0.0183f16, 0.0183f16, + 0.0411f16, 0.0411f16, 0.0411f16, 0.0411f16, + }, + { + 0.1f16, 0.1f16, 0.1f16, 0.1f16, + 0.232f16, 0.232f16, 0.232f16, 0.232f16, + 0.268f16, 0.268f16, 0.268f16, 0.268f16, + 0.457f16, 0.457f16, 0.457f16, 0.457f16, + } + }, + { + { 2.46e+01f16 }, + { + -1.46e+02f16, -1.46e+02f16, -1.46e+02f16, -1.46e+02f16, + 3.66e+02f16, 3.66e+02f16, 3.66e+02f16, 3.66e+02f16, + 3.47e+02f16, 3.47e+02f16, 3.47e+02f16, 3.47e+02f16, + 6.24e+02f16, 6.24e+02f16, 6.24e+02f16, 6.24e+02f16, + }, + { + 6.17e+00f16, 6.17e+00f16, 6.17e+00f16, 6.17e+00f16, + 2.46e+01f16, 2.46e+01f16, 2.46e+01f16, 2.46e+01f16, + 1.99e+01f16, 1.99e+01f16, 1.99e+01f16, 1.99e+01f16, + 3.29e+01f16, 3.29e+01f16, 3.29e+01f16, 3.29e+01f16, + }, + { + 2.97e+02f16, 2.97e+02f16, 2.97e+02f16, 2.97e+02f16, + 2.39e+02f16, 2.39e+02f16, 2.39e+02f16, 2.39e+02f16, + 1.42e+02f16, 1.42e+02f16, 1.42e+02f16, 1.42e+02f16, + 1.85e+02f16, 1.85e+02f16, 1.85e+02f16, 1.85e+02f16, + } + }, +}; + +float TEST_MULOP_DATA(float, sub)[][4][N] = +{ + { + { 5.96f }, + { + 7.74f, 7.74f, 7.74f, 7.74f, + -57.f, -57.f, -57.f, -57.f, + 32.7f, 32.7f, 32.7f, 32.7f, + 2.44f, 2.44f, 2.44f, 2.44f, + }, + { + 7.37f, 7.37f, 7.37f, 7.37f, + 5.6f, 5.6f, 5.6f, 5.6f, + 9.07f, 9.07f, 9.07f, 9.07f, + 2.87f, 2.87f, 2.87f, 2.87f, + }, + { + 36.2f, 36.2f, 36.2f, 36.2f, + 90.4f, 90.4f, 90.4f, 90.4f, + 21.3f, 21.3f, 21.3f, 21.3f, + 14.6f, 14.6f, 14.6f, 14.6f, + } + }, + { + { 3.00e-02f }, + { + -2.83e-01f, -2.83e-01f, -2.83e-01f, -2.83e-01f, + -5.37e-01f, -5.37e-01f, -5.37e-01f, -5.37e-01f, + -7.87e-01f, -7.87e-01f, -7.87e-01f, -7.87e-01f, + -3.65e-01f, -3.65e-01f, -3.65e-01f, -3.65e-01f, + }, + { + 8.84e-02f, 8.84e-02f, 8.84e-02f, 8.84e-02f, + 9.27e-02f, 9.27e-02f, 9.27e-02f, 9.27e-02f, + 6.51e-02f, 6.51e-02f, 6.51e-02f, 6.51e-02f, + 5.67e-02f, 5.67e-02f, 5.67e-02f, 5.67e-02f, + }, + { + 2.86e-01f, 2.86e-01f, 2.86e-01f, 2.86e-01f, + 5.40e-01f, 5.40e-01f, 5.40e-01f, 5.40e-01f, + 7.89e-01f, 7.89e-01f, 7.89e-01f, 7.89e-01f, + 3.67e-01f, 3.67e-01f, 3.67e-01f, 3.67e-01f, + } + }, + { + { 9.04e+01f }, + { + 2.76e+03f, 2.76e+03f, 2.76e+03f, 2.76e+03f, + 1.05e+03f, 1.05e+03f, 1.05e+03f, 1.05e+03f, + 5.17e+03f, 5.17e+03f, 5.17e+03f, 5.17e+03f, + 3.91e+03f, 3.91e+03f, 3.91e+03f, 3.91e+03f, + }, + { + 3.99e+01f, 3.99e+01f, 3.99e+01f, 3.99e+01f, + 1.38e+01f, 1.38e+01f, 1.38e+01f, 1.38e+01f, + 6.36e+01f, 6.36e+01f, 6.36e+01f, 6.36e+01f, + 4.77e+01f, 4.77e+01f, 4.77e+01f, 4.77e+01f, + }, + { + 8.39e+02f, 8.39e+02f, 8.39e+02f, 8.39e+02f, + 1.97e+02f, 1.97e+02f, 1.97e+02f, 1.97e+02f, + 5.77e+02f, 5.77e+02f, 5.77e+02f, 5.77e+02f, + 4.02e+02f, 4.02e+02f, 4.02e+02f, 4.02e+02f, + } + }, +}; + +double TEST_MULOP_DATA(double, sub)[][4][N] = +{ + { + { 1.69e+01 }, + { + 8.58e+02, 8.58e+02, 8.58e+02, 8.58e+02, + 2.87e+02, 2.87e+02, 2.87e+02, 2.87e+02, + 4.35e+02, 4.35e+02, 4.35e+02, 4.35e+02, + -6.35e+01, -6.35e+01, -6.35e+01, -6.35e+01, + }, + { + 8.02e+01, 8.02e+01, 8.02e+01, 8.02e+01, + 7.51e+01, 7.51e+01, 7.51e+01, 7.51e+01, + 5.85e+01, 5.85e+01, 5.85e+01, 5.85e+01, + 1.65e+01, 1.65e+01, 1.65e+01, 1.65e+01, + }, + { + 4.95e+02, 4.95e+02, 4.95e+02, 4.95e+02, + 9.80e+02, 9.80e+02, 9.80e+02, 9.80e+02, + 5.51e+02, 5.51e+02, 5.51e+02, 5.51e+02, + 3.42e+02, 3.42e+02, 3.42e+02, 3.42e+02, + } + }, + { + { 8.86e-10 }, + { + -8.82e-09, -8.82e-09, -8.82e-09, -8.82e-09, + -3.09e-09, -3.09e-09, -3.09e-09, -3.09e-09, + -4.87e-09, -4.87e-09, -4.87e-09, -4.87e-09, + -5.70e-09, -5.70e-09, -5.70e-09, -5.70e-09, + }, + { + 9.72e-10, 9.72e-10, 9.72e-10, 9.72e-10, + 5.78e-10, 5.78e-10, 5.78e-10, 5.78e-10, + 1.10e-10, 1.10e-10, 1.10e-10, 1.10e-10, + 4.62e-10, 4.62e-10, 4.62e-10, 4.62e-10, + }, + { + 8.82e-09, 8.82e-09, 8.82e-09, 8.82e-09, + 3.09e-09, 3.09e-09, 3.09e-09, 3.09e-09, + 4.87e-09, 4.87e-09, 4.87e-09, 4.87e-09, + 5.70e-09, 5.70e-09, 5.70e-09, 5.70e-09, + } + }, + { + { 1.09e-20 }, + { + -5.46e-19, -5.46e-19, -5.46e-19, -5.46e-19, + -2.28e-19, -2.28e-19, -2.28e-19, -2.28e-19, + -4.77e-19, -4.77e-19, -4.77e-19, -4.77e-19, + -1.76e-19, -1.76e-19, -1.76e-19, -1.76e-19, + }, + { + 5.52e-20, 5.52e-20, 5.52e-20, 5.52e-20, + 2.20e-20, 2.20e-20, 2.20e-20, 2.20e-20, + 2.97e-20, 2.97e-20, 2.97e-20, 2.97e-20, + 3.23e-20, 3.23e-20, 3.23e-20, 3.23e-20, + }, + { + 5.46e-19, 5.46e-19, 5.46e-19, 5.46e-19, + 2.28e-19, 2.28e-19, 2.28e-19, 2.28e-19, + 4.77e-19, 4.77e-19, 4.77e-19, 4.77e-19, + 1.76e-19, 1.76e-19, 1.76e-19, 1.76e-19, + } + }, +}; + +_Float16 TEST_MULOP_DATA(_Float16, nadd)[][4][N] = +{ + { + { 1.09f16 }, + { + -60.7f16, -60.7f16, -60.7f16, -60.7f16, + -25.2f16, -25.2f16, -25.2f16, -25.2f16, + -50.9f16, -50.9f16, -50.9f16, -50.9f16, + -21.1f16, -21.1f16, -21.1f16, -21.1f16, + }, + { + 5.52f16, 5.52f16, 5.52f16, 5.52f16, + 2.2f16, 2.2f16, 2.2f16, 2.2f16, + 2.97f16, 2.97f16, 2.97f16, 2.97f16, + 3.23f16, 3.23f16, 3.23f16, 3.23f16, + }, + { + 54.6f16, 54.6f16, 54.6f16, 54.6f16, + 22.8f16, 22.8f16, 22.8f16, 22.8f16, + 47.7f16, 47.7f16, 47.7f16, 47.7f16, + 17.6f16, 17.6f16, 17.6f16, 17.6f16, + } + }, + { + { 0.794f16 }, + { + -6.8f16, -6.8f16, -6.8f16, -6.8f16, + -6.1f16, -6.1f16, -6.1f16, -6.1f16, + -3.02f16, -3.02f16, -3.02f16, -3.02f16, + -3.15f16, -3.15f16, -3.15f16, -3.15f16, + }, + { + 0.119f16, 0.119f16, 0.119f16, 0.119f16, + 0.774f16, 0.774f16, 0.774f16, 0.774f16, + 0.302f16, 0.302f16, 0.302f16, 0.302f16, + 0.784f16, 0.784f16, 0.784f16, 0.784f16, + }, + { + 6.7f16, 6.7f16, 6.7f16, 6.7f16, + 5.49f16, 5.49f16, 5.49f16, 5.49f16, + 2.78f16, 2.78f16, 2.78f16, 2.78f16, + 2.52f16, 2.52f16, 2.52f16, 2.52f16, + } + }, + { + { -2.62f16 }, + { + 48.6f16, 48.6f16, 48.6f16, 48.6f16, + 28.1f16, 28.1f16, 28.1f16, 28.1f16, + -2.93f16, -2.93f16, -2.93f16, -2.93f16, + 80.6f16, 80.6f16, 80.6f16, 80.6f16, + }, + { + -1.18f16, -1.18f16, -1.18f16, -1.18f16, + -7.52f16, -7.52f16, -7.52f16, -7.52f16, + -5.37f16, -5.37f16, -5.37f16, -5.37f16, + -5.39f16, -5.39f16, -5.39f16, -5.39f16, + }, + { + -51.7f16, -51.7f16, -51.7f16, -51.7f16, + -47.8f16, -47.8f16, -47.8f16, -47.8f16, + -11.2f16, -11.2f16, -11.2f16, -11.2f16, + -94.8f16, -94.8f16, -94.8f16, -94.8f16, + } + }, +}; + +float TEST_MULOP_DATA(float, nadd)[][4][N] = +{ + { + { 1.19f }, + { + -21.4f, -21.4f, -21.4f, -21.4f, + -9.12f, -9.12f, -9.12f, -9.12f, + -51.1f, -51.1f, -51.1f, -51.1f, + -48.8f, -48.8f, -48.8f, -48.8f, + }, + { + 3.83f, 3.83f, 3.83f, 3.83f, + 2.9f, 2.9f, 2.9f, 2.9f, + 4.63f, 4.63f, 4.63f, 4.63f, + 0.65f, 0.65f, 0.65f, 0.65f, + }, + { + 16.8f, 16.8f, 16.8f, 16.8f, + 5.66f, 5.66f, 5.66f, 5.66f, + 45.5f, 45.5f, 45.5f, 45.5f, + 48.1f, 48.1f, 48.1f, 48.1f, + } + }, + { + { 1.60e+01f }, + { + -2.69e+02f, -2.69e+02f, -2.69e+02f, -2.69e+02f, + -5.05e+02f, -5.05e+02f, -5.05e+02f, -5.05e+02f, + -2.92e+02f, -2.92e+02f, -2.92e+02f, -2.92e+02f, + -3.91e+02f, -3.91e+02f, -3.91e+02f, -3.91e+02f, + }, + { + 6.28e+00f, 6.28e+00f, 6.28e+00f, 6.28e+00f, + 1.94e+01f, 1.94e+01f, 1.94e+01f, 1.94e+01f, + 1.02e+01f, 1.02e+01f, 1.02e+01f, 1.02e+01f, + 1.60e+01f, 1.60e+01f, 1.60e+01f, 1.60e+01f, + }, + { + 1.68e+02f, 1.68e+02f, 1.68e+02f, 1.68e+02f, + 1.95e+02f, 1.95e+02f, 1.95e+02f, 1.95e+02f, + 1.30e+02f, 1.30e+02f, 1.30e+02f, 1.30e+02f, + 1.35e+02f, 1.35e+02f, 1.35e+02f, 1.35e+02f, + } + }, + { + { -5.63e+01f }, + { + -3.59e+03f, -3.59e+03f, -3.59e+03f, -3.59e+03f, + -2.25e+02f, -2.25e+02f, -2.25e+02f, -2.25e+02f, + -4.85e+03f, -4.85e+03f, -4.85e+03f, -4.85e+03f, + -1.59e+03f, -1.59e+03f, -1.59e+03f, -1.59e+03f, + }, + { + -7.96e+01f, -7.96e+01f, -7.96e+01f, -7.96e+01f, + -1.07e+01f, -1.07e+01f, -1.07e+01f, -1.07e+01f, + -9.62e+01f, -9.62e+01f, -9.62e+01f, -9.62e+01f, + -3.86e+01f, -3.86e+01f, -3.86e+01f, -3.86e+01f, + }, + { + -8.83e+02f, -8.83e+02f, -8.83e+02f, -8.83e+02f, + -3.79e+02f, -3.79e+02f, -3.79e+02f, -3.79e+02f, + -5.62e+02f, -5.62e+02f, -5.62e+02f, -5.62e+02f, + -5.85e+02f, -5.85e+02f, -5.85e+02f, -5.85e+02f, + } + }, +}; + +double TEST_MULOP_DATA(double, nadd)[][4][N] = +{ + { + { 8.64e+20 }, + { + -2.89e+41, -2.89e+41, -2.89e+41, -2.89e+41, + -6.50e+41, -6.50e+41, -6.50e+41, -6.50e+41, + -8.11e+41, -8.11e+41, -8.11e+41, -8.11e+41, + -4.44e+41, -4.44e+41, -4.44e+41, -4.44e+41, + }, + { + 2.61e+20, 2.61e+20, 2.61e+20, 2.61e+20, + 4.25e+20, 4.25e+20, 4.25e+20, 4.25e+20, + 5.77e+20, 5.77e+20, 5.77e+20, 5.77e+20, + 3.74e+20, 3.74e+20, 3.74e+20, 3.74e+20, + }, + { + 6.38e+40, 6.38e+40, 6.38e+40, 6.38e+40, + 2.83e+41, 2.83e+41, 2.83e+41, 2.83e+41, + 3.13e+41, 3.13e+41, 3.13e+41, 3.13e+41, + 1.21e+41, 1.21e+41, 1.21e+41, 1.21e+41, + } + }, + { + { -3.01e+40 }, + { + -7.27e+81, -7.27e+81, -7.27e+81, -7.27e+81, + -4.10e+81, -4.10e+81, -4.10e+81, -4.10e+81, + -7.82e+81, -7.82e+81, -7.82e+81, -7.82e+81, + -1.54e+81, -1.54e+81, -1.54e+81, -1.54e+81, + }, + { + -5.71e+40, -5.71e+40, -5.71e+40, -5.71e+40, + -1.41e+40, -1.41e+40, -1.41e+40, -1.41e+40, + -3.01e+40, -3.01e+40, -3.01e+40, -3.01e+40, + -2.47e+40, -2.47e+40, -2.47e+40, -2.47e+40, + }, + { + 5.55e+81, 5.55e+81, 5.55e+81, 5.55e+81, + 3.67e+81, 3.67e+81, 3.67e+81, 3.67e+81, + 6.92e+81, 6.92e+81, 6.92e+81, 6.92e+81, + 7.96e+80, 7.96e+80, 7.96e+80, 7.96e+80, + } + }, + { + { 3.65e-20 }, + { + -4.11e-39, -4.11e-39, -4.11e-39, -4.11e-39, + -8.48e-39, -8.48e-39, -8.48e-39, -8.48e-39, + -8.93e-39, -8.93e-39, -8.93e-39, -8.93e-39, + -2.74e-39, -2.74e-39, -2.74e-39, -2.74e-39, + }, + { + 5.78e-20, 5.78e-20, 5.78e-20, 5.78e-20, + 1.61e-20, 1.61e-20, 1.61e-20, 1.61e-20, + 6.91e-20, 6.91e-20, 6.91e-20, 6.91e-20, + 6.18e-20, 6.18e-20, 6.18e-20, 6.18e-20, + }, + { + 2.00e-39, 2.00e-39, 2.00e-39, 2.00e-39, + 7.89e-39, 7.89e-39, 7.89e-39, 7.89e-39, + 6.41e-39, 6.41e-39, 6.41e-39, 6.41e-39, + 4.87e-40, 4.87e-40, 4.87e-40, 4.87e-40, + } + }, +}; + +_Float16 TEST_MULOP_DATA(_Float16, nsub)[][4][N] = { { { 0.676f16 }, @@ -275,7 +677,7 @@ _Float16 TEST_MULOP_DATA(_Float16, sub)[][4][N] = }, }; -float TEST_MULOP_DATA(float, sub)[][4][N] = +float TEST_MULOP_DATA(float, nsub)[][4][N] = { { {8.51f }, @@ -342,7 +744,7 @@ float TEST_MULOP_DATA(float, sub)[][4][N] = }, }; -double TEST_MULOP_DATA(double, sub)[][4][N] = +double TEST_MULOP_DATA(double, nsub)[][4][N] = { { { 80.54 }, diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop_run.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop_run.h index bc6f483deedd..3dadfabfeaff 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop_run.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop_run.h @@ -6,6 +6,10 @@ #define TYPE_FABS(x, T) \ (__builtin_types_compatible_p (T, double) ? fabs (x) : fabsf (x)) +#define MAX_RELATIVE_DIFF(T) \ + (__builtin_types_compatible_p (T, _Float16) ? 0.1f : \ + (__builtin_types_compatible_p (T, float) ? 0.01f : 0.01)) + int main () { @@ -13,17 +17,18 @@ main () for (i = 0; i < sizeof (TEST_DATA) / sizeof (TEST_DATA[0]); i++) { - T x = TEST_DATA[i][0][0]; - T *in = TEST_DATA[i][1]; - T *out = TEST_DATA[i][2]; + T f = TEST_DATA[i][0][0]; + T *b = TEST_DATA[i][1]; + T *c = TEST_DATA[i][2]; T *expect = TEST_DATA[i][3]; - TEST_RUN (T, NAME, out, in, x, N); + TEST_RUN (T, NAME, c, b, f, N); for (k = 0; k < N; k++) { - T diff = expect[k] - out[k]; - if (TYPE_FABS (diff, T) > .01 * TYPE_FABS (expect[k], T)) + T diff = expect[k] - TEST_OUT[k]; + if (TYPE_FABS (diff, T) + > MAX_RELATIVE_DIFF (T) * TYPE_FABS (expect[k], T)) __builtin_abort (); } } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop_widen_run.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop_widen_run.h new file mode 100644 index 000000000000..9f95fbba535d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop_widen_run.h @@ -0,0 +1,32 @@ +#ifndef HAVE_DEFINED_VF_MULOP_WIDEN_RUN_H +#define HAVE_DEFINED_VF_MULOP_WIDEN_RUN_H + +#include + +#define N 512 + +int main () +{ + T1 f[N]; + T1 in[N]; + T2 out[N]; + T2 out2[N]; + + for (int i = 0; i < N; i++) + { + f[i] = LIMIT + i % 8723; + in[i] = LIMIT + i & 1964; + out[i] = LIMIT + i & 628; + out2[i] = LIMIT + i & 628; + asm volatile ("" ::: "memory"); + } + + TEST_RUN (T1, T2, NAME, out, in, f, N); + + for (int i = 0; i < N; i++) + assert (out[i] == NEG(((T2) *f * (T2) in[i]) OP out2[i])); + + return 0; +} + +#endif diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmacc-run-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmacc-run-1-f16.c new file mode 100644 index 000000000000..982dd9736acc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmacc-run-1-f16.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-march=rv64gcv_zvfh --param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T _Float16 +#define NAME add + +DEF_VF_MULOP_ACC_CASE_0_WRAP (T, +, +, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, c, b, x, n) RUN_VF_MULOP_ACC_CASE_0_WRAP(T, NAME, b, c, x, n) +#define TEST_OUT b + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmacc-run-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmacc-run-1-f32.c new file mode 100644 index 000000000000..357c4ffbd8da --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmacc-run-1-f32.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T float +#define NAME add + +DEF_VF_MULOP_ACC_CASE_0_WRAP (T, +, +, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, c, b, x, n) RUN_VF_MULOP_ACC_CASE_0_WRAP(T, NAME, b, c, x, n) +#define TEST_OUT b + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmacc-run-1-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmacc-run-1-f64.c new file mode 100644 index 000000000000..0da46be41b32 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmacc-run-1-f64.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T double +#define NAME add + +DEF_VF_MULOP_ACC_CASE_0_WRAP (T, +, +, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, c, b, x, n) RUN_VF_MULOP_ACC_CASE_0_WRAP(T, NAME, b, c, x, n) +#define TEST_OUT b + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f16.c index 1bcf9e075fe9..400bbcd1d79f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f16.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-additional-options "--param=fpr2vr-cost=0" } */ +/* { dg-additional-options "-march=rv64gcv_zvfh --param=fpr2vr-cost=0" } */ #include "vf_mulop.h" #include "vf_mulop_data.h" @@ -7,9 +7,10 @@ #define T _Float16 #define NAME add -DEF_VF_MULOP_CASE_0_WRAP(T, +, NAME) +DEF_VF_MULOP_CASE_0_WRAP (T, +, +, NAME) #define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) #define TEST_RUN(T, NAME, out, in, x, n) RUN_VF_MULOP_CASE_0_WRAP(T, NAME, out, in, x, n) +#define TEST_OUT c #include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f32.c index 199b9adc738f..ed9bd36c620e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f32.c @@ -7,9 +7,10 @@ #define T float #define NAME add -DEF_VF_MULOP_CASE_0_WRAP(T, +, NAME) +DEF_VF_MULOP_CASE_0_WRAP (T, +, +, NAME) #define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) #define TEST_RUN(T, NAME, out, in, x, n) RUN_VF_MULOP_CASE_0_WRAP(T, NAME, out, in, x, n) +#define TEST_OUT c #include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f64.c index 3857f586cc9f..b0883df36a46 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f64.c @@ -7,9 +7,10 @@ #define T double #define NAME add -DEF_VF_MULOP_CASE_0_WRAP(T, +, NAME) +DEF_VF_MULOP_CASE_0_WRAP (T, +, +, NAME) #define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) #define TEST_RUN(T, NAME, out, in, x, n) RUN_VF_MULOP_CASE_0_WRAP(T, NAME, out, in, x, n) +#define TEST_OUT c #include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsac-run-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsac-run-1-f16.c new file mode 100644 index 000000000000..21c1860c0f1c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsac-run-1-f16.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-march=rv64gcv_zvfh --param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T _Float16 +#define NAME sub + +DEF_VF_MULOP_ACC_CASE_0_WRAP (T, -, +, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, c, b, x, n) RUN_VF_MULOP_ACC_CASE_0_WRAP(T, NAME, b, c, x, n) +#define TEST_OUT b + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsac-run-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsac-run-1-f32.c new file mode 100644 index 000000000000..3f03e110ddd8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsac-run-1-f32.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T float +#define NAME sub + +DEF_VF_MULOP_ACC_CASE_0_WRAP (T, -, +, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, c, b, x, n) RUN_VF_MULOP_ACC_CASE_0_WRAP(T, NAME, b, c, x, n) +#define TEST_OUT b + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsac-run-1-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsac-run-1-f64.c new file mode 100644 index 000000000000..0df8d3aa1567 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsac-run-1-f64.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T double +#define NAME sub + +DEF_VF_MULOP_ACC_CASE_0_WRAP (T, -, +, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, c, b, x, n) RUN_VF_MULOP_ACC_CASE_0_WRAP(T, NAME, b, c, x, n) +#define TEST_OUT b + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f16.c index 671c7d83d9c7..163b5bd21b42 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f16.c @@ -1,5 +1,5 @@ /* { dg-do run { target { riscv_v } } } */ -/* { dg-additional-options "--param=fpr2vr-cost=0" } */ +/* { dg-additional-options "-march=rv64gcv_zvfh --param=fpr2vr-cost=0" } */ #include "vf_mulop.h" #include "vf_mulop_data.h" @@ -7,9 +7,10 @@ #define T _Float16 #define NAME sub -DEF_VF_MULOP_CASE_0_WRAP(T, -, NAME) +DEF_VF_MULOP_CASE_0_WRAP (T, -, +, NAME) #define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) #define TEST_RUN(T, NAME, out, in, x, n) RUN_VF_MULOP_CASE_0_WRAP(T, NAME, out, in, x, n) +#define TEST_OUT c #include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f32.c index f89696373c3e..d3cd3c19e2af 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f32.c @@ -7,9 +7,10 @@ #define T float #define NAME sub -DEF_VF_MULOP_CASE_0_WRAP(T, -, NAME) +DEF_VF_MULOP_CASE_0_WRAP (T, -, +, NAME) #define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) #define TEST_RUN(T, NAME, out, in, x, n) RUN_VF_MULOP_CASE_0_WRAP(T, NAME, out, in, x, n) +#define TEST_OUT c #include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f64.c index b42ab1eff7d0..0d615da91402 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f64.c @@ -7,9 +7,10 @@ #define T double #define NAME sub -DEF_VF_MULOP_CASE_0_WRAP(T, -, NAME) +DEF_VF_MULOP_CASE_0_WRAP (T, -, +, NAME) #define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) #define TEST_RUN(T, NAME, out, in, x, n) RUN_VF_MULOP_CASE_0_WRAP(T, NAME, out, in, x, n) +#define TEST_OUT c #include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmacc-run-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmacc-run-1-f16.c new file mode 100644 index 000000000000..71f350f74e22 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmacc-run-1-f16.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-march=rv64gcv_zvfh --param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T _Float16 +#define NAME nadd + +DEF_VF_MULOP_ACC_CASE_0_WRAP (T, +, -, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, c, b, x, n) RUN_VF_MULOP_ACC_CASE_0_WRAP(T, NAME, b, c, x, n) +#define TEST_OUT b + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmacc-run-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmacc-run-1-f32.c new file mode 100644 index 000000000000..b97cdc226a67 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmacc-run-1-f32.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T float +#define NAME nadd + +DEF_VF_MULOP_ACC_CASE_0_WRAP (T, +, -, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, c, b, x, n) RUN_VF_MULOP_ACC_CASE_0_WRAP(T, NAME, b, c, x, n) +#define TEST_OUT b + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmacc-run-1-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmacc-run-1-f64.c new file mode 100644 index 000000000000..8da279f187c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmacc-run-1-f64.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T double +#define NAME nadd + +DEF_VF_MULOP_ACC_CASE_0_WRAP (T, +, -, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, c, b, x, n) RUN_VF_MULOP_ACC_CASE_0_WRAP(T, NAME, b, c, x, n) +#define TEST_OUT b + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f16.c new file mode 100644 index 000000000000..e252e0dc21a3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f16.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-march=rv64gcv_zvfh --param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T _Float16 +#define NAME nadd + +DEF_VF_MULOP_CASE_0_WRAP(T, +, -, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VF_MULOP_CASE_0_WRAP(T, NAME, out, in, x, n) +#define TEST_OUT c + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f32.c new file mode 100644 index 000000000000..38d4f7da3bc1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f32.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T float +#define NAME nadd + +DEF_VF_MULOP_CASE_0_WRAP (T, +, -, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VF_MULOP_CASE_0_WRAP(T, NAME, out, in, x, n) +#define TEST_OUT c + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f64.c new file mode 100644 index 000000000000..dc9d3a0560d6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f64.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T double +#define NAME nadd + +DEF_VF_MULOP_CASE_0_WRAP (T, +, -, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VF_MULOP_CASE_0_WRAP(T, NAME, out, in, x, n) +#define TEST_OUT c + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsac-run-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsac-run-1-f16.c new file mode 100644 index 000000000000..439fd3e50560 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsac-run-1-f16.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-march=rv64gcv_zvfh --param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T _Float16 +#define NAME nsub + +DEF_VF_MULOP_ACC_CASE_0_WRAP (T, -, -, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, c, b, x, n) RUN_VF_MULOP_ACC_CASE_0_WRAP(T, NAME, b, c, x, n) +#define TEST_OUT b + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsac-run-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsac-run-1-f32.c new file mode 100644 index 000000000000..be1084afa009 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsac-run-1-f32.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T float +#define NAME nsub + +DEF_VF_MULOP_ACC_CASE_0_WRAP (T, -, -, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, c, b, x, n) RUN_VF_MULOP_ACC_CASE_0_WRAP(T, NAME, b, c, x, n) +#define TEST_OUT b + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsac-run-1-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsac-run-1-f64.c new file mode 100644 index 000000000000..73b5a6e873ba --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsac-run-1-f64.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T double +#define NAME nsub + +DEF_VF_MULOP_ACC_CASE_0_WRAP (T, -, -, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, c, b, x, n) RUN_VF_MULOP_ACC_CASE_0_WRAP(T, NAME, b, c, x, n) +#define TEST_OUT b + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsub-run-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsub-run-1-f16.c new file mode 100644 index 000000000000..b9d66bafeadc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsub-run-1-f16.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-march=rv64gcv_zvfh --param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T _Float16 +#define NAME nsub + +DEF_VF_MULOP_CASE_0_WRAP (T, -, -, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VF_MULOP_CASE_0_WRAP(T, NAME, out, in, x, n) +#define TEST_OUT c + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsub-run-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsub-run-1-f32.c new file mode 100644 index 000000000000..3cbeea9da686 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsub-run-1-f32.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T float +#define NAME nsub + +DEF_VF_MULOP_CASE_0_WRAP (T, -, -, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VF_MULOP_CASE_0_WRAP(T, NAME, out, in, x, n) +#define TEST_OUT c + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsub-run-1-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsub-run-1-f64.c new file mode 100644 index 000000000000..00ead93493c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsub-run-1-f64.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" +#include "vf_mulop_data.h" + +#define T double +#define NAME nsub + +DEF_VF_MULOP_CASE_0_WRAP (T, -, -, NAME) + +#define TEST_DATA TEST_MULOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VF_MULOP_CASE_0_WRAP(T, NAME, out, in, x, n) +#define TEST_OUT c + +#include "vf_mulop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwmacc-run-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwmacc-run-1-f16.c new file mode 100644 index 000000000000..d78cf7384a43 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwmacc-run-1-f16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-march=rv64gcv_zvfh --param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" + +#define T1 _Float16 +#define T2 float +#define NAME acc +#define OP + +#define NEG + + +DEF_VF_MULOP_WIDEN_CASE_0_WRAP (T1, T2, OP, NEG, NAME) + +#define TEST_RUN(T1, T2, NAME, out, in, f, n) RUN_VF_MULOP_WIDEN_CASE_0_WRAP(T1, T2, NAME, out, in, f, n) +#define LIMIT -32768 + +#include "vf_mulop_widen_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwmacc-run-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwmacc-run-1-f32.c new file mode 100644 index 000000000000..1af5240b2857 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwmacc-run-1-f32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" + +#define T1 float +#define T2 double +#define NAME acc +#define OP + +#define NEG + + +DEF_VF_MULOP_WIDEN_CASE_0_WRAP (T1, T2, OP, NEG, NAME) + +#define TEST_RUN(T1, T2, NAME, out, in, f, n) RUN_VF_MULOP_WIDEN_CASE_0_WRAP(T1, T2, NAME, out, in, f, n) +#define LIMIT -2147483648 + +#include "vf_mulop_widen_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwmsac-run-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwmsac-run-1-f16.c new file mode 100644 index 000000000000..6422bbaa4963 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwmsac-run-1-f16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-march=rv64gcv_zvfh --param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" + +#define T1 _Float16 +#define T2 float +#define NAME sac +#define OP - +#define NEG + + +DEF_VF_MULOP_WIDEN_CASE_0_WRAP (T1, T2, OP, NEG, NAME) + +#define TEST_RUN(T1, T2, NAME, out, in, f, n) RUN_VF_MULOP_WIDEN_CASE_0_WRAP(T1, T2, NAME, out, in, f, n) +#define LIMIT -32768 + +#include "vf_mulop_widen_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwmsac-run-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwmsac-run-1-f32.c new file mode 100644 index 000000000000..13617a090d7b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwmsac-run-1-f32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" + +#define T1 float +#define T2 double +#define NAME sac +#define OP - +#define NEG + + +DEF_VF_MULOP_WIDEN_CASE_0_WRAP (T1, T2, OP, NEG, NAME) + +#define TEST_RUN(T1, T2, NAME, out, in, f, n) RUN_VF_MULOP_WIDEN_CASE_0_WRAP(T1, T2, NAME, out, in, f, n) +#define LIMIT -2147483648 + +#include "vf_mulop_widen_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwnmacc-run-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwnmacc-run-1-f16.c new file mode 100644 index 000000000000..6be7d720603d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwnmacc-run-1-f16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-march=rv64gcv_zvfh --param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" + +#define T1 _Float16 +#define T2 float +#define NAME nacc +#define OP + +#define NEG - + +DEF_VF_MULOP_WIDEN_CASE_0_WRAP (T1, T2, OP, NEG, NAME) + +#define TEST_RUN(T1, T2, NAME, out, in, f, n) RUN_VF_MULOP_WIDEN_CASE_0_WRAP(T1, T2, NAME, out, in, f, n) +#define LIMIT -32768 + +#include "vf_mulop_widen_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwnmacc-run-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwnmacc-run-1-f32.c new file mode 100644 index 000000000000..851c335d64d1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwnmacc-run-1-f32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" + +#define T1 float +#define T2 double +#define NAME nacc +#define OP + +#define NEG - + +DEF_VF_MULOP_WIDEN_CASE_0_WRAP (T1, T2, OP, NEG, NAME) + +#define TEST_RUN(T1, T2, NAME, out, in, f, n) RUN_VF_MULOP_WIDEN_CASE_0_WRAP(T1, T2, NAME, out, in, f, n) +#define LIMIT -2147483648 + +#include "vf_mulop_widen_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwnmsac-run-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwnmsac-run-1-f16.c new file mode 100644 index 000000000000..dd28234b6e0e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwnmsac-run-1-f16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-march=rv64gcv_zvfh --param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" + +#define T1 _Float16 +#define T2 float +#define NAME nsac +#define OP - +#define NEG - + +DEF_VF_MULOP_WIDEN_CASE_0_WRAP (T1, T2, OP, NEG, NAME) + +#define TEST_RUN(T1, T2, NAME, out, in, f, n) RUN_VF_MULOP_WIDEN_CASE_0_WRAP(T1, T2, NAME, out, in, f, n) +#define LIMIT -32768 + +#include "vf_mulop_widen_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwnmsac-run-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwnmsac-run-1-f32.c new file mode 100644 index 000000000000..9eacacea44be --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwnmsac-run-1-f32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_mulop.h" + +#define T1 float +#define T2 double +#define NAME nsac +#define OP - +#define NEG - + +DEF_VF_MULOP_WIDEN_CASE_0_WRAP (T1, T2, OP, NEG, NAME) + +#define TEST_RUN(T1, T2, NAME, out, in, f, n) RUN_VF_MULOP_WIDEN_CASE_0_WRAP(T1, T2, NAME, out, in, f, n) +#define LIMIT -2147483648 + +#include "vf_mulop_widen_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i16.c index d88e76b5d99c..83515eebe3c1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i16.c @@ -5,14 +5,7 @@ #define T int16_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub); -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) -DEF_VX_BINARY_CASE_0_WRAP(T, *, mul) -DEF_VX_BINARY_CASE_0_WRAP(T, /, div) +TEST_BINARY_VX_SIGNED_0(T) /* { dg-final { scan-assembler-times {vadd.vx} 1 } } */ /* { dg-final { scan-assembler-times {vsub.vx} 1 } } */ @@ -22,3 +15,8 @@ DEF_VX_BINARY_CASE_0_WRAP(T, /, div) /* { dg-final { scan-assembler-times {vxor.vx} 1 } } */ /* { dg-final { scan-assembler-times {vmul.vx} 1 } } */ /* { dg-final { scan-assembler-times {vdiv.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vrem.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vmax.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vmin.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vsadd.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vssub.vx} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i32.c index 53189c21d041..1488fe1fa176 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i32.c @@ -5,14 +5,7 @@ #define T int32_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub); -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) -DEF_VX_BINARY_CASE_0_WRAP(T, *, mul) -DEF_VX_BINARY_CASE_0_WRAP(T, /, div) +TEST_BINARY_VX_SIGNED_0(T) /* { dg-final { scan-assembler-times {vadd.vx} 1 } } */ /* { dg-final { scan-assembler-times {vsub.vx} 1 } } */ @@ -22,3 +15,8 @@ DEF_VX_BINARY_CASE_0_WRAP(T, /, div) /* { dg-final { scan-assembler-times {vxor.vx} 1 } } */ /* { dg-final { scan-assembler-times {vmul.vx} 1 } } */ /* { dg-final { scan-assembler-times {vdiv.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vrem.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vmax.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vmin.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vsadd.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vssub.vx} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i64.c index 5059beb4c6de..342ea18d59f7 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i64.c @@ -5,14 +5,7 @@ #define T int64_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub); -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) -DEF_VX_BINARY_CASE_0_WRAP(T, *, mul) -DEF_VX_BINARY_CASE_0_WRAP(T, /, div) +TEST_BINARY_VX_SIGNED_0(T) /* { dg-final { scan-assembler-times {vadd.vx} 1 } } */ /* { dg-final { scan-assembler-times {vsub.vx} 1 } } */ @@ -22,3 +15,8 @@ DEF_VX_BINARY_CASE_0_WRAP(T, /, div) /* { dg-final { scan-assembler-times {vxor.vx} 1 } } */ /* { dg-final { scan-assembler-times {vmul.vx} 1 } } */ /* { dg-final { scan-assembler-times {vdiv.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vrem.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vmax.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vmin.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vsadd.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vssub.vx} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i8.c index 4bbe5a40ee0e..583f917bc7ec 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i8.c @@ -5,14 +5,7 @@ #define T int8_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub); -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) -DEF_VX_BINARY_CASE_0_WRAP(T, *, mul) -DEF_VX_BINARY_CASE_0_WRAP(T, /, div) +TEST_BINARY_VX_SIGNED_0(T) /* { dg-final { scan-assembler-times {vadd.vx} 1 } } */ /* { dg-final { scan-assembler-times {vsub.vx} 1 } } */ @@ -22,3 +15,8 @@ DEF_VX_BINARY_CASE_0_WRAP(T, /, div) /* { dg-final { scan-assembler-times {vxor.vx} 1 } } */ /* { dg-final { scan-assembler-times {vmul.vx} 1 } } */ /* { dg-final { scan-assembler-times {vdiv.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vrem.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vmax.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vmin.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vsadd.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vssub.vx} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u16.c index 7e107d30191d..cb62e0f96199 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u16.c @@ -5,12 +5,7 @@ #define T uint16_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub); -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) +TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-times {vadd.vx} 1 } } */ /* { dg-final { scan-assembler-times {vsub.vx} 1 } } */ @@ -18,3 +13,10 @@ DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) /* { dg-final { scan-assembler-times {vand.vx} 1 } } */ /* { dg-final { scan-assembler-times {vor.vx} 1 } } */ /* { dg-final { scan-assembler-times {vxor.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vdivu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vremu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vmaxu.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vminu.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vsaddu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vssubu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vaaddu.vx} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u32.c index f8ffab78067a..e2a5dbbc8599 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u32.c @@ -5,12 +5,7 @@ #define T uint32_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub); -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) +TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-times {vadd.vx} 1 } } */ /* { dg-final { scan-assembler-times {vsub.vx} 1 } } */ @@ -18,3 +13,10 @@ DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) /* { dg-final { scan-assembler-times {vand.vx} 1 } } */ /* { dg-final { scan-assembler-times {vor.vx} 1 } } */ /* { dg-final { scan-assembler-times {vxor.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vdivu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vremu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vmaxu.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vminu.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vsaddu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vssubu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vaaddu.vx} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c index 31d294567e83..e7b1ef077950 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c @@ -5,12 +5,7 @@ #define T uint64_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub); -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) +TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-times {vadd.vx} 1 } } */ /* { dg-final { scan-assembler-times {vsub.vx} 1 } } */ @@ -18,3 +13,10 @@ DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) /* { dg-final { scan-assembler-times {vand.vx} 1 } } */ /* { dg-final { scan-assembler-times {vor.vx} 1 } } */ /* { dg-final { scan-assembler-times {vxor.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vdivu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vremu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vmaxu.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vminu.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vsaddu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vssubu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vaaddu.vx} 1 { target { no-opts "-O3 -mrvv-vector-bits=zvl -mrvv-max-lmul=m2" "-O3 -mrvv-vector-bits=zvl -mrvv-max-lmul=m4" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c index 59e033401b21..559887e69b0e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c @@ -5,12 +5,7 @@ #define T uint8_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub); -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) +TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-times {vadd.vx} 1 } } */ /* { dg-final { scan-assembler-times {vsub.vx} 1 } } */ @@ -18,3 +13,10 @@ DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) /* { dg-final { scan-assembler-times {vand.vx} 1 } } */ /* { dg-final { scan-assembler-times {vor.vx} 1 } } */ /* { dg-final { scan-assembler-times {vxor.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vdivu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vremu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vmaxu.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vminu.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vsaddu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vssubu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vaaddu.vx} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i16.c index 0437db48f59f..78d3e0b933e5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i16.c @@ -5,14 +5,7 @@ #define T int16_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) -DEF_VX_BINARY_CASE_0_WRAP(T, *, mul) -DEF_VX_BINARY_CASE_0_WRAP(T, /, div) +TEST_BINARY_VX_SIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -22,3 +15,8 @@ DEF_VX_BINARY_CASE_0_WRAP(T, /, div) /* { dg-final { scan-assembler-not {vxor.vx} } } */ /* { dg-final { scan-assembler-not {vmul.vx} } } */ /* { dg-final { scan-assembler-not {vdiv.vx} } } */ +/* { dg-final { scan-assembler-not {vrem.vx} } } */ +/* { dg-final { scan-assembler-not {vmax.vx} } } */ +/* { dg-final { scan-assembler-not {vmin.vx} } } */ +/* { dg-final { scan-assembler-not {vsadd.vx} } } */ +/* { dg-final { scan-assembler-not {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i32.c index 95ed403e1eef..e7bcfe59294f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i32.c @@ -5,14 +5,7 @@ #define T int32_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) -DEF_VX_BINARY_CASE_0_WRAP(T, *, mul) -DEF_VX_BINARY_CASE_0_WRAP(T, /, div) +TEST_BINARY_VX_SIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -22,3 +15,8 @@ DEF_VX_BINARY_CASE_0_WRAP(T, /, div) /* { dg-final { scan-assembler-not {vxor.vx} } } */ /* { dg-final { scan-assembler-not {vmul.vx} } } */ /* { dg-final { scan-assembler-not {vdiv.vx} } } */ +/* { dg-final { scan-assembler-not {vrem.vx} } } */ +/* { dg-final { scan-assembler-not {vmax.vx} } } */ +/* { dg-final { scan-assembler-not {vmin.vx} } } */ +/* { dg-final { scan-assembler-not {vsadd.vx} } } */ +/* { dg-final { scan-assembler-not {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i64.c index f8912a0bac6c..f9f1e39a1d23 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i64.c @@ -5,14 +5,7 @@ #define T int64_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) -DEF_VX_BINARY_CASE_0_WRAP(T, *, mul) -DEF_VX_BINARY_CASE_0_WRAP(T, /, div) +TEST_BINARY_VX_SIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -22,3 +15,8 @@ DEF_VX_BINARY_CASE_0_WRAP(T, /, div) /* { dg-final { scan-assembler-not {vxor.vx} } } */ /* { dg-final { scan-assembler-not {vmul.vx} } } */ /* { dg-final { scan-assembler-not {vdiv.vx} } } */ +/* { dg-final { scan-assembler-not {vrem.vx} } } */ +/* { dg-final { scan-assembler-not {vmax.vx} } } */ +/* { dg-final { scan-assembler-not {vmin.vx} } } */ +/* { dg-final { scan-assembler-not {vsadd.vx} } } */ +/* { dg-final { scan-assembler-not {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i8.c index 3c8f9154a247..80d6aaaf8f7a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i8.c @@ -5,14 +5,7 @@ #define T int8_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) -DEF_VX_BINARY_CASE_0_WRAP(T, *, mul) -DEF_VX_BINARY_CASE_0_WRAP(T, /, div) +TEST_BINARY_VX_SIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -22,3 +15,8 @@ DEF_VX_BINARY_CASE_0_WRAP(T, /, div) /* { dg-final { scan-assembler-not {vxor.vx} } } */ /* { dg-final { scan-assembler-not {vmul.vx} } } */ /* { dg-final { scan-assembler-not {vdiv.vx} } } */ +/* { dg-final { scan-assembler-not {vrem.vx} } } */ +/* { dg-final { scan-assembler-not {vmax.vx} } } */ +/* { dg-final { scan-assembler-not {vmin.vx} } } */ +/* { dg-final { scan-assembler-not {vsadd.vx} } } */ +/* { dg-final { scan-assembler-not {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u16.c index 9612e3f66cc4..365e650ef12b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u16.c @@ -5,12 +5,7 @@ #define T uint16_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) +TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -18,3 +13,10 @@ DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) /* { dg-final { scan-assembler-not {vand.vx} } } */ /* { dg-final { scan-assembler-not {vor.vx} } } */ /* { dg-final { scan-assembler-not {vxor.vx} } } */ +/* { dg-final { scan-assembler-not {vdivu.vx} } } */ +/* { dg-final { scan-assembler-not {vremu.vx} } } */ +/* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ +/* { dg-final { scan-assembler-not {vsaddu.vx} } } */ +/* { dg-final { scan-assembler-not {vssubu.vx} } } */ +/* { dg-final { scan-assembler-not {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u32.c index 964180243b47..c8fd42a52c46 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u32.c @@ -5,12 +5,7 @@ #define T uint32_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) +TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -18,3 +13,10 @@ DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) /* { dg-final { scan-assembler-not {vand.vx} } } */ /* { dg-final { scan-assembler-not {vor.vx} } } */ /* { dg-final { scan-assembler-not {vxor.vx} } } */ +/* { dg-final { scan-assembler-not {vdivu.vx} } } */ +/* { dg-final { scan-assembler-not {vremu.vx} } } */ +/* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ +/* { dg-final { scan-assembler-not {vsaddu.vx} } } */ +/* { dg-final { scan-assembler-not {vssubu.vx} } } */ +/* { dg-final { scan-assembler-not {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u64.c index 0d173e0dbbb9..bdb76b471c0c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u64.c @@ -5,12 +5,7 @@ #define T uint64_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) +TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -18,3 +13,10 @@ DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) /* { dg-final { scan-assembler-not {vand.vx} } } */ /* { dg-final { scan-assembler-not {vor.vx} } } */ /* { dg-final { scan-assembler-not {vxor.vx} } } */ +/* { dg-final { scan-assembler-not {vdivu.vx} } } */ +/* { dg-final { scan-assembler-not {vremu.vx} } } */ +/* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ +/* { dg-final { scan-assembler-not {vsaddu.vx} } } */ +/* { dg-final { scan-assembler-not {vssubu.vx} } } */ +/* { dg-final { scan-assembler-not {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u8.c index 931295ec0fb3..fc9c10125a87 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u8.c @@ -5,12 +5,7 @@ #define T uint8_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) +TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -18,3 +13,10 @@ DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) /* { dg-final { scan-assembler-not {vand.vx} } } */ /* { dg-final { scan-assembler-not {vor.vx} } } */ /* { dg-final { scan-assembler-not {vxor.vx} } } */ +/* { dg-final { scan-assembler-not {vdivu.vx} } } */ +/* { dg-final { scan-assembler-not {vremu.vx} } } */ +/* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ +/* { dg-final { scan-assembler-not {vsaddu.vx} } } */ +/* { dg-final { scan-assembler-not {vssubu.vx} } } */ +/* { dg-final { scan-assembler-not {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i16.c index f49dae498bf2..6bf2a3520625 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i16.c @@ -5,14 +5,7 @@ #define T int16_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) -DEF_VX_BINARY_CASE_0_WRAP(T, *, mul) -DEF_VX_BINARY_CASE_0_WRAP(T, /, div) +TEST_BINARY_VX_SIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -22,3 +15,8 @@ DEF_VX_BINARY_CASE_0_WRAP(T, /, div) /* { dg-final { scan-assembler-not {vxor.vx} } } */ /* { dg-final { scan-assembler-not {vmul.vx} } } */ /* { dg-final { scan-assembler-not {vdiv.vx} } } */ +/* { dg-final { scan-assembler-not {vrem.vx} } } */ +/* { dg-final { scan-assembler-not {vmax.vx} } } */ +/* { dg-final { scan-assembler-not {vmin.vx} } } */ +/* { dg-final { scan-assembler-not {vsadd.vx} } } */ +/* { dg-final { scan-assembler-not {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i32.c index 8f502a31c6cc..5432706944b1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i32.c @@ -5,14 +5,7 @@ #define T int32_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) -DEF_VX_BINARY_CASE_0_WRAP(T, *, mul) -DEF_VX_BINARY_CASE_0_WRAP(T, /, div) +TEST_BINARY_VX_SIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -22,3 +15,8 @@ DEF_VX_BINARY_CASE_0_WRAP(T, /, div) /* { dg-final { scan-assembler-not {vxor.vx} } } */ /* { dg-final { scan-assembler-not {vmul.vx} } } */ /* { dg-final { scan-assembler-not {vdiv.vx} } } */ +/* { dg-final { scan-assembler-not {vrem.vx} } } */ +/* { dg-final { scan-assembler-not {vmax.vx} } } */ +/* { dg-final { scan-assembler-not {vmin.vx} } } */ +/* { dg-final { scan-assembler-not {vsadd.vx} } } */ +/* { dg-final { scan-assembler-not {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i64.c index 3277bf24453a..a2099fd8647c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i64.c @@ -5,14 +5,7 @@ #define T int64_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) -DEF_VX_BINARY_CASE_0_WRAP(T, *, mul) -DEF_VX_BINARY_CASE_0_WRAP(T, /, div) +TEST_BINARY_VX_SIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -22,3 +15,8 @@ DEF_VX_BINARY_CASE_0_WRAP(T, /, div) /* { dg-final { scan-assembler-not {vxor.vx} } } */ /* { dg-final { scan-assembler-not {vmul.vx} } } */ /* { dg-final { scan-assembler-not {vdiv.vx} } } */ +/* { dg-final { scan-assembler-not {vrem.vx} } } */ +/* { dg-final { scan-assembler-not {vmax.vx} } } */ +/* { dg-final { scan-assembler-not {vmin.vx} } } */ +/* { dg-final { scan-assembler-not {vsadd.vx} } } */ +/* { dg-final { scan-assembler-not {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i8.c index 25ed2ad18ce8..1daede95888d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i8.c @@ -5,14 +5,7 @@ #define T int8_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) -DEF_VX_BINARY_CASE_0_WRAP(T, *, mul) -DEF_VX_BINARY_CASE_0_WRAP(T, /, div) +TEST_BINARY_VX_SIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -22,3 +15,8 @@ DEF_VX_BINARY_CASE_0_WRAP(T, /, div) /* { dg-final { scan-assembler-not {vxor.vx} } } */ /* { dg-final { scan-assembler-not {vmul.vx} } } */ /* { dg-final { scan-assembler-not {vdiv.vx} } } */ +/* { dg-final { scan-assembler-not {vrem.vx} } } */ +/* { dg-final { scan-assembler-not {vmax.vx} } } */ +/* { dg-final { scan-assembler-not {vmin.vx} } } */ +/* { dg-final { scan-assembler-not {vsadd.vx} } } */ +/* { dg-final { scan-assembler-not {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u16.c index 24b4aa7efba1..121daebcf552 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u16.c @@ -5,12 +5,7 @@ #define T uint16_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) +TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -18,3 +13,10 @@ DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) /* { dg-final { scan-assembler-not {vand.vx} } } */ /* { dg-final { scan-assembler-not {vor.vx} } } */ /* { dg-final { scan-assembler-not {vxor.vx} } } */ +/* { dg-final { scan-assembler-not {vdivu.vx} } } */ +/* { dg-final { scan-assembler-not {vremu.vx} } } */ +/* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ +/* { dg-final { scan-assembler-not {vsaddu.vx} } } */ +/* { dg-final { scan-assembler-not {vssubu.vx} } } */ +/* { dg-final { scan-assembler-not {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u32.c index 0c1552a20541..9616e7f2fe45 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u32.c @@ -5,12 +5,7 @@ #define T uint32_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) +TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -18,3 +13,10 @@ DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) /* { dg-final { scan-assembler-not {vand.vx} } } */ /* { dg-final { scan-assembler-not {vor.vx} } } */ /* { dg-final { scan-assembler-not {vxor.vx} } } */ +/* { dg-final { scan-assembler-not {vdivu.vx} } } */ +/* { dg-final { scan-assembler-not {vremu.vx} } } */ +/* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ +/* { dg-final { scan-assembler-not {vsaddu.vx} } } */ +/* { dg-final { scan-assembler-not {vssubu.vx} } } */ +/* { dg-final { scan-assembler-not {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u64.c index 8364f19b1787..cf985f0ba269 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u64.c @@ -5,12 +5,7 @@ #define T uint64_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) +TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -18,3 +13,10 @@ DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) /* { dg-final { scan-assembler-not {vand.vx} } } */ /* { dg-final { scan-assembler-not {vor.vx} } } */ /* { dg-final { scan-assembler-not {vxor.vx} } } */ +/* { dg-final { scan-assembler-not {vdivu.vx} } } */ +/* { dg-final { scan-assembler-not {vremu.vx} } } */ +/* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ +/* { dg-final { scan-assembler-not {vsaddu.vx} } } */ +/* { dg-final { scan-assembler-not {vssubu.vx} } } */ +/* { dg-final { scan-assembler-not {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u8.c index 8a3111157ffe..3bb382dd395e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u8.c @@ -5,12 +5,7 @@ #define T uint8_t -DEF_VX_BINARY_CASE_0_WRAP(T, +, add) -DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) -DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) -DEF_VX_BINARY_CASE_0_WRAP(T, &, and) -DEF_VX_BINARY_CASE_0_WRAP(T, |, or) -DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) +TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -18,3 +13,10 @@ DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) /* { dg-final { scan-assembler-not {vand.vx} } } */ /* { dg-final { scan-assembler-not {vor.vx} } } */ /* { dg-final { scan-assembler-not {vxor.vx} } } */ +/* { dg-final { scan-assembler-not {vdivu.vx} } } */ +/* { dg-final { scan-assembler-not {vremu.vx} } } */ +/* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ +/* { dg-final { scan-assembler-not {vsaddu.vx} } } */ +/* { dg-final { scan-assembler-not {vssubu.vx} } } */ +/* { dg-final { scan-assembler-not {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c index 1e409dea08b7..d79a9f21af62 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c @@ -13,6 +13,13 @@ DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, *, mul, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -22,3 +29,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16) /* { dg-final { scan-assembler {vxor.vx} } } */ /* { dg-final { scan-assembler {vmul.vx} } } */ /* { dg-final { scan-assembler {vdiv.vx} } } */ +/* { dg-final { scan-assembler {vrem.vx} } } */ +/* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ +/* { dg-final { scan-assembler {vsadd.vx} } } */ +/* { dg-final { scan-assembler {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c index 2f242c73717e..940f59654381 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c @@ -13,6 +13,13 @@ DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, *, mul, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -22,3 +29,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) /* { dg-final { scan-assembler {vxor.vx} } } */ /* { dg-final { scan-assembler {vmul.vx} } } */ /* { dg-final { scan-assembler {vdiv.vx} } } */ +/* { dg-final { scan-assembler {vrem.vx} } } */ +/* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ +/* { dg-final { scan-assembler {vsadd.vx} } } */ +/* { dg-final { scan-assembler {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c index f027bd8129e4..22a64f6c5c02 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c @@ -13,6 +13,13 @@ DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, *, mul, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -22,3 +29,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) /* { dg-final { scan-assembler {vxor.vx} } } */ /* { dg-final { scan-assembler {vmul.vx} } } */ /* { dg-final { scan-assembler {vdiv.vx} } } */ +/* { dg-final { scan-assembler {vrem.vx} } } */ +/* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ +/* { dg-final { scan-assembler-not {vsadd.vx} } } */ +/* { dg-final { scan-assembler-not {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c index c4f55b0228eb..3286b1a3c4ad 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c @@ -13,6 +13,13 @@ DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, *, mul, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -22,3 +29,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) /* { dg-final { scan-assembler {vxor.vx} } } */ /* { dg-final { scan-assembler {vmul.vx} } } */ /* { dg-final { scan-assembler {vdiv.vx} } } */ +/* { dg-final { scan-assembler {vrem.vx} } } */ +/* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ +/* { dg-final { scan-assembler {vsadd.vx} } } */ +/* { dg-final { scan-assembler {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c index 4bc0850f6737..c851f237e01e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c @@ -11,6 +11,15 @@ DEF_VX_BINARY_REVERSE_CASE_1_WRAP(T, -, rsub, VX_BINARY_REVERSE_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, &, and, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X16) +DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, AVG_FLOOR_FUNC_WRAP(T), avg_floor, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -18,3 +27,10 @@ DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X16) /* { dg-final { scan-assembler {vand.vx} } } */ /* { dg-final { scan-assembler {vor.vx} } } */ /* { dg-final { scan-assembler {vxor.vx} } } */ +/* { dg-final { scan-assembler {vdivu.vx} } } */ +/* { dg-final { scan-assembler {vremu.vx} } } */ +/* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ +/* { dg-final { scan-assembler {vsaddu.vx} } } */ +/* { dg-final { scan-assembler {vssubu.vx} } } */ +/* { dg-final { scan-assembler {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c index 255273d767f0..b7805c1a5868 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c @@ -11,6 +11,15 @@ DEF_VX_BINARY_REVERSE_CASE_1_WRAP(T, -, rsub, VX_BINARY_REVERSE_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, &, and, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, AVG_FLOOR_FUNC_WRAP(T), avg_floor, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -18,3 +27,9 @@ DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X4) /* { dg-final { scan-assembler {vand.vx} } } */ /* { dg-final { scan-assembler {vor.vx} } } */ /* { dg-final { scan-assembler {vxor.vx} } } */ +/* { dg-final { scan-assembler {vdivu.vx} } } */ +/* { dg-final { scan-assembler {vremu.vx} } } */ +/* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ +/* { dg-final { scan-assembler {vssubu.vx} } } */ +/* { dg-final { scan-assembler {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c index d21f61b49e73..8295dc29117e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c @@ -11,6 +11,15 @@ DEF_VX_BINARY_REVERSE_CASE_1_WRAP(T, -, rsub, VX_BINARY_REVERSE_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, &, and, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, AVG_FLOOR_FUNC_WRAP(T), avg_floor, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -18,3 +27,10 @@ DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY) /* { dg-final { scan-assembler {vand.vx} } } */ /* { dg-final { scan-assembler {vor.vx} } } */ /* { dg-final { scan-assembler {vxor.vx} } } */ +/* { dg-final { scan-assembler {vdivu.vx} } } */ +/* { dg-final { scan-assembler {vremu.vx} } } */ +/* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ +/* { dg-final { scan-assembler-not {vsaddu.vx} } } */ +/* { dg-final { scan-assembler-not {vssubu.vx} } } */ +/* { dg-final { scan-assembler {vaaddu.vx} { target { no-opts "-O3 -mrvv-vector-bits=zvl -mrvv-max-lmul=m2" "-O3 -mrvv-vector-bits=zvl -mrvv-max-lmul=m4" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c index 51492ae43114..d214da97a9fc 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c @@ -11,6 +11,15 @@ DEF_VX_BINARY_REVERSE_CASE_1_WRAP(T, -, rsub, VX_BINARY_REVERSE_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, &, and, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X16) +DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, AVG_FLOOR_FUNC_WRAP(T), avg_floor, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -18,3 +27,10 @@ DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X16) /* { dg-final { scan-assembler {vand.vx} } } */ /* { dg-final { scan-assembler {vor.vx} } } */ /* { dg-final { scan-assembler {vxor.vx} } } */ +/* { dg-final { scan-assembler {vdivu.vx} } } */ +/* { dg-final { scan-assembler {vremu.vx} } } */ +/* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ +/* { dg-final { scan-assembler {vsaddu.vx} } } */ +/* { dg-final { scan-assembler {vssubu.vx} } } */ +/* { dg-final { scan-assembler {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c index d6b05bc875c0..b92db1096b85 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c @@ -13,6 +13,13 @@ DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, *, mul, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -22,3 +29,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) /* { dg-final { scan-assembler {vxor.vx} } } */ /* { dg-final { scan-assembler-not {vmul.vx} } } */ /* { dg-final { scan-assembler {vdiv.vx} } } */ +/* { dg-final { scan-assembler {vrem.vx} } } */ +/* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ +/* { dg-final { scan-assembler {vsadd.vx} } } */ +/* { dg-final { scan-assembler {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c index e1c043fbb458..0870cde26d6f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c @@ -13,6 +13,13 @@ DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, *, mul, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -22,3 +29,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) /* { dg-final { scan-assembler {vxor.vx} } } */ /* { dg-final { scan-assembler {vmul.vx} } } */ /* { dg-final { scan-assembler {vdiv.vx} } } */ +/* { dg-final { scan-assembler {vrem.vx} } } */ +/* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ +/* { dg-final { scan-assembler-not {vsadd.vx} } } */ +/* { dg-final { scan-assembler-not {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c index 1beb9146d049..a4d60e962038 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c @@ -13,6 +13,13 @@ DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, *, mul, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -22,3 +29,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) /* { dg-final { scan-assembler {vxor.vx} } } */ /* { dg-final { scan-assembler {vmul.vx} } } */ /* { dg-final { scan-assembler {vdiv.vx} } } */ +/* { dg-final { scan-assembler {vrem.vx} } } */ +/* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ +/* { dg-final { scan-assembler-not {vsadd.vx} } } */ +/* { dg-final { scan-assembler-not {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c index 0291517d727e..ec069a3c7789 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c @@ -13,6 +13,13 @@ DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, *, mul, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -22,3 +29,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) /* { dg-final { scan-assembler {vxor.vx} } } */ /* { dg-final { scan-assembler-not {vmul.vx} } } */ /* { dg-final { scan-assembler {vdiv.vx} } } */ +/* { dg-final { scan-assembler {vrem.vx} } } */ +/* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ +/* { dg-final { scan-assembler {vsadd.vx} } } */ +/* { dg-final { scan-assembler {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c index 2ab096709ccd..b7c7ad491e9d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c @@ -11,6 +11,15 @@ DEF_VX_BINARY_REVERSE_CASE_1_WRAP(T, -, rsub, VX_BINARY_REVERSE_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, &, and, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, AVG_FLOOR_FUNC_WRAP(T), avg_floor, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -18,3 +27,10 @@ DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X8) /* { dg-final { scan-assembler {vand.vx} } } */ /* { dg-final { scan-assembler {vor.vx} } } */ /* { dg-final { scan-assembler {vxor.vx} } } */ +/* { dg-final { scan-assembler {vdivu.vx} } } */ +/* { dg-final { scan-assembler {vremu.vx} } } */ +/* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ +/* { dg-final { scan-assembler {vsaddu.vx} } } */ +/* { dg-final { scan-assembler {vssubu.vx} } } */ +/* { dg-final { scan-assembler {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c index 799c5db51c27..dd9c845568fa 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c @@ -11,6 +11,15 @@ DEF_VX_BINARY_REVERSE_CASE_1_WRAP(T, -, rsub, VX_BINARY_REVERSE_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, &, and, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, AVG_FLOOR_FUNC_WRAP(T), avg_floor, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -18,3 +27,10 @@ DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X4) /* { dg-final { scan-assembler {vand.vx} } } */ /* { dg-final { scan-assembler {vor.vx} } } */ /* { dg-final { scan-assembler {vxor.vx} } } */ +/* { dg-final { scan-assembler {vdivu.vx} } } */ +/* { dg-final { scan-assembler {vremu.vx} } } */ +/* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ +/* { dg-final { scan-assembler-not {vsaddu.vx} } } */ +/* { dg-final { scan-assembler {vssubu.vx} } } */ +/* { dg-final { scan-assembler {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c index a5d25d218f94..1fda062c2b95 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c @@ -11,6 +11,15 @@ DEF_VX_BINARY_REVERSE_CASE_1_WRAP(T, -, rsub, VX_BINARY_REVERSE_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, &, and, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, AVG_FLOOR_FUNC_WRAP(T), avg_floor, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -18,3 +27,10 @@ DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY) /* { dg-final { scan-assembler {vand.vx} } } */ /* { dg-final { scan-assembler {vor.vx} } } */ /* { dg-final { scan-assembler {vxor.vx} } } */ +/* { dg-final { scan-assembler {vdivu.vx} } } */ +/* { dg-final { scan-assembler {vremu.vx} } } */ +/* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ +/* { dg-final { scan-assembler-not {vsaddu.vx} } } */ +/* { dg-final { scan-assembler-not {vssubu.vx} } } */ +/* { dg-final { scan-assembler-not {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c index 61d2b245a722..ee6d6aaf2bcf 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c @@ -11,6 +11,15 @@ DEF_VX_BINARY_REVERSE_CASE_1_WRAP(T, -, rsub, VX_BINARY_REVERSE_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, &, and, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X16) +DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_SUB_FUNC_WRAP(T), avg_floor, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -18,3 +27,10 @@ DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X16) /* { dg-final { scan-assembler {vand.vx} } } */ /* { dg-final { scan-assembler {vor.vx} } } */ /* { dg-final { scan-assembler {vxor.vx} } } */ +/* { dg-final { scan-assembler {vdivu.vx} } } */ +/* { dg-final { scan-assembler {vremu.vx} } } */ +/* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ +/* { dg-final { scan-assembler {vsaddu.vx} } } */ +/* { dg-final { scan-assembler {vssubu.vx} } } */ +/* { dg-final { scan-assembler-not {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c index c22c82dce1b4..473c31bca5be 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c @@ -13,6 +13,13 @@ DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, *, mul, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -22,3 +29,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) /* { dg-final { scan-assembler {vxor.vx} } } */ /* { dg-final { scan-assembler-not {vmul.vx} } } */ /* { dg-final { scan-assembler {vdiv.vx} } } */ +/* { dg-final { scan-assembler {vrem.vx} } } */ +/* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ +/* { dg-final { scan-assembler {vsadd.vx} } } */ +/* { dg-final { scan-assembler {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c index dc3560070afd..6ae84c1f8b7b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c @@ -13,6 +13,13 @@ DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, *, mul, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -22,3 +29,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) /* { dg-final { scan-assembler {vxor.vx} } } */ /* { dg-final { scan-assembler {vmul.vx} } } */ /* { dg-final { scan-assembler {vdiv.vx} } } */ +/* { dg-final { scan-assembler {vrem.vx} } } */ +/* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ +/* { dg-final { scan-assembler-not {vsadd.vx} } } */ +/* { dg-final { scan-assembler-not {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c index cee1e3a819bf..794f5062905a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c @@ -13,6 +13,13 @@ DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, *, mul, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -22,3 +29,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) /* { dg-final { scan-assembler-not {vxor.vx} } } */ /* { dg-final { scan-assembler-not {vmul.vx} } } */ /* { dg-final { scan-assembler-not {vdiv.vx} } } */ +/* { dg-final { scan-assembler-not {vrem.vx} } } */ +/* { dg-final { scan-assembler-not {vmax.vx} } } */ +/* { dg-final { scan-assembler-not {vmin.vx} } } */ +/* { dg-final { scan-assembler-not {vsadd.vx} } } */ +/* { dg-final { scan-assembler-not {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c index 74fd2fb9a579..77bcdeb6ad85 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c @@ -13,6 +13,13 @@ DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, *, mul, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_S_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -22,3 +29,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) /* { dg-final { scan-assembler {vxor.vx} } } */ /* { dg-final { scan-assembler-not {vmul.vx} } } */ /* { dg-final { scan-assembler {vdiv.vx} } } */ +/* { dg-final { scan-assembler {vrem.vx} } } */ +/* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ +/* { dg-final { scan-assembler {vsadd.vx} } } */ +/* { dg-final { scan-assembler {vssub.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c index 57220f2ea64d..3a215ea7d2f2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c @@ -11,6 +11,15 @@ DEF_VX_BINARY_REVERSE_CASE_1_WRAP(T, -, rsub, VX_BINARY_REVERSE_BODY_X8); DEF_VX_BINARY_CASE_1_WRAP(T, &, and, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, AVG_FLOOR_FUNC_WRAP(T), avg_floor, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -18,3 +27,10 @@ DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X8) /* { dg-final { scan-assembler {vand.vx} } } */ /* { dg-final { scan-assembler {vor.vx} } } */ /* { dg-final { scan-assembler {vxor.vx} } } */ +/* { dg-final { scan-assembler {vdivu.vx} } } */ +/* { dg-final { scan-assembler {vremu.vx} } } */ +/* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ +/* { dg-final { scan-assembler {vsaddu.vx} } } */ +/* { dg-final { scan-assembler {vssubu.vx} } } */ +/* { dg-final { scan-assembler {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c index 45244a0ee11c..ac4d100e1e6a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c @@ -11,6 +11,15 @@ DEF_VX_BINARY_REVERSE_CASE_1_WRAP(T, -, rsub, VX_BINARY_REVERSE_BODY_X4); DEF_VX_BINARY_CASE_1_WRAP(T, &, and, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, AVG_FLOOR_FUNC_WRAP(T), avg_floor, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -18,3 +27,10 @@ DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X4) /* { dg-final { scan-assembler {vand.vx} } } */ /* { dg-final { scan-assembler {vor.vx} } } */ /* { dg-final { scan-assembler {vxor.vx} } } */ +/* { dg-final { scan-assembler {vdivu.vx} } } */ +/* { dg-final { scan-assembler {vremu.vx} } } */ +/* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ +/* { dg-final { scan-assembler-not {vsaddu.vx} } } */ +/* { dg-final { scan-assembler {vssubu.vx} } } */ +/* { dg-final { scan-assembler {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c index 3bad1305fc99..5eb0ed6cd96e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c @@ -11,6 +11,15 @@ DEF_VX_BINARY_REVERSE_CASE_1_WRAP(T, -, rsub, VX_BINARY_REVERSE_BODY); DEF_VX_BINARY_CASE_1_WRAP(T, &, and, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, AVG_FLOOR_FUNC_WRAP(T), avg_floor, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -18,3 +27,10 @@ DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY) /* { dg-final { scan-assembler-not {vand.vx} } } */ /* { dg-final { scan-assembler-not {vor.vx} } } */ /* { dg-final { scan-assembler-not {vxor.vx} } } */ +/* { dg-final { scan-assembler-not {vdivu.vx} } } */ +/* { dg-final { scan-assembler-not {vremu.vx} } } */ +/* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ +/* { dg-final { scan-assembler-not {vsaddu.vx} } } */ +/* { dg-final { scan-assembler-not {vssubu.vx} } } */ +/* { dg-final { scan-assembler-not {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c index bb860dd9e7ce..8b404b64bd6b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c @@ -11,6 +11,15 @@ DEF_VX_BINARY_REVERSE_CASE_1_WRAP(T, -, rsub, VX_BINARY_REVERSE_BODY_X16); DEF_VX_BINARY_CASE_1_WRAP(T, &, and, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, |, or, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X16) +DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16) +DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_ADD_FUNC_WRAP(T), sat_add, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, SAT_U_SUB_FUNC_WRAP(T), sat_sub, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, AVG_FLOOR_FUNC_WRAP(T), avg_floor, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -18,3 +27,10 @@ DEF_VX_BINARY_CASE_1_WRAP(T, ^, xor, VX_BINARY_BODY_X16) /* { dg-final { scan-assembler {vand.vx} } } */ /* { dg-final { scan-assembler {vor.vx} } } */ /* { dg-final { scan-assembler {vxor.vx} } } */ +/* { dg-final { scan-assembler {vdivu.vx} } } */ +/* { dg-final { scan-assembler {vremu.vx} } } */ +/* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ +/* { dg-final { scan-assembler {vsaddu.vx} } } */ +/* { dg-final { scan-assembler {vssubu.vx} } } */ +/* { dg-final { scan-assembler {vaaddu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h index 66e238c903a3..38f2f72ed011 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h @@ -3,6 +3,13 @@ #include +#undef HAS_UINT128 + +#if __riscv_xlen == 64 +#define HAS_UINT128 +typedef unsigned __int128 uint128_t; +#endif + #define DEF_VX_BINARY_CASE_0(T, OP, NAME) \ void \ test_vx_binary_##NAME##_##T##_case_0 (T * restrict out, T * restrict in, \ @@ -127,4 +134,269 @@ test_vx_binary_reverse_##NAME##_##T##_case_1 (T * restrict out, \ #define DEF_VX_BINARY_REVERSE_CASE_1_WRAP(T, OP, NAME, BODY) \ DEF_VX_BINARY_REVERSE_CASE_1(T, OP, NAME, BODY) +#define DEF_MAX_0(T) \ +static inline T \ +test_##T##_max_0 (T a, T b) \ +{ \ + return a > b ? a : b; \ +} + +#define DEF_MAX_1(T) \ +static inline T \ +test_##T##_max_1 (T a, T b) \ +{ \ + return a >= b ? a : b; \ +} + +DEF_MAX_0(int8_t) +DEF_MAX_0(int16_t) +DEF_MAX_0(int32_t) +DEF_MAX_0(int64_t) + +DEF_MAX_1(int8_t) +DEF_MAX_1(int16_t) +DEF_MAX_1(int32_t) +DEF_MAX_1(int64_t) + +DEF_MAX_0(uint8_t) +DEF_MAX_0(uint16_t) +DEF_MAX_0(uint32_t) +DEF_MAX_0(uint64_t) + +DEF_MAX_1(uint8_t) +DEF_MAX_1(uint16_t) +DEF_MAX_1(uint32_t) +DEF_MAX_1(uint64_t) + +#define MAX_FUNC_0(T) test_##T##_max_0 +#define MAX_FUNC_0_WARP(T) MAX_FUNC_0(T) + +#define MAX_FUNC_1(T) test_##T##_max_1 +#define MAX_FUNC_1_WARP(T) MAX_FUNC_1(T) + +#define DEF_MIN_0(T) \ +static inline T \ +test_##T##_min_0 (T a, T b) \ +{ \ + return a > b ? b : a; \ +} + +#define DEF_MIN_1(T) \ +static inline T \ +test_##T##_min_1 (T a, T b) \ +{ \ + return a >= b ? b : a; \ +} + +DEF_MIN_0(int8_t) +DEF_MIN_0(int16_t) +DEF_MIN_0(int32_t) +DEF_MIN_0(int64_t) + +DEF_MIN_1(int8_t) +DEF_MIN_1(int16_t) +DEF_MIN_1(int32_t) +DEF_MIN_1(int64_t) + +DEF_MIN_0(uint8_t) +DEF_MIN_0(uint16_t) +DEF_MIN_0(uint32_t) +DEF_MIN_0(uint64_t) + +DEF_MIN_1(uint8_t) +DEF_MIN_1(uint16_t) +DEF_MIN_1(uint32_t) +DEF_MIN_1(uint64_t) + +#define MIN_FUNC_0(T) test_##T##_min_0 +#define MIN_FUNC_0_WARP(T) MIN_FUNC_0(T) + +#define MIN_FUNC_1(T) test_##T##_min_1 +#define MIN_FUNC_1_WARP(T) MIN_FUNC_1(T) + +#define DEF_VX_BINARY_CASE_2(T, FUNC, NAME) \ +void \ +test_vx_binary_##NAME##_##FUNC##_##T##_case_2 (T * restrict out, \ + T * restrict in, \ + T x, unsigned n) \ +{ \ + for (unsigned i = 0; i < n; i++) \ + out[i] = FUNC (in[i], x); \ +} +#define DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) \ + DEF_VX_BINARY_CASE_2(T, FUNC, NAME) +#define RUN_VX_BINARY_CASE_2(T, NAME, FUNC, out, in, x, n) \ + test_vx_binary_##NAME##_##FUNC##_##T##_case_2(out, in, x, n) +#define RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) \ + RUN_VX_BINARY_CASE_2(T, NAME, FUNC, out, in, x, n) + +#define DEF_VX_BINARY_CASE_3(T, FUNC, NAME, BODY) \ +void \ +test_vx_binary_##NAME##_##FUNC##_##T##_case_3 (T * restrict out, \ + T * restrict in, \ + T x, unsigned n) \ +{ \ + unsigned k = 0; \ + T tmp = x + 3; \ + \ + while (k < n) \ + { \ + tmp = tmp ^ 0x82; \ + BODY(FUNC) \ + } \ +} +#define DEF_VX_BINARY_CASE_3_WRAP(T, FUNC, NAME, BODY) \ + DEF_VX_BINARY_CASE_3(T, FUNC, NAME, BODY) + +#define VX_BINARY_FUNC_BODY(func) \ + out[k + 0] = func (in[k + 0], tmp); \ + out[k + 1] = func (in[k + 1], tmp); \ + k += 2; + +#define VX_BINARY_FUNC_BODY_X4(op) \ + VX_BINARY_FUNC_BODY(op) \ + VX_BINARY_FUNC_BODY(op) + +#define VX_BINARY_FUNC_BODY_X8(op) \ + VX_BINARY_FUNC_BODY_X4(op) \ + VX_BINARY_FUNC_BODY_X4(op) + +#define VX_BINARY_FUNC_BODY_X16(op) \ + VX_BINARY_FUNC_BODY_X8(op) \ + VX_BINARY_FUNC_BODY_X8(op) + +#define VX_BINARY_FUNC_BODY_X32(op) \ + VX_BINARY_FUNC_BODY_X16(op) \ + VX_BINARY_FUNC_BODY_X16(op) + +#define VX_BINARY_FUNC_BODY_X64(op) \ + VX_BINARY_FUNC_BODY_X32(op) \ + VX_BINARY_FUNC_BODY_X32(op) + +#define VX_BINARY_FUNC_BODY_X128(op) \ + VX_BINARY_FUNC_BODY_X64(op) \ + VX_BINARY_FUNC_BODY_X64(op) + +#define DEF_SAT_U_ADD(T) \ +T \ +test_##T##_sat_add (T a, T b) \ +{ \ + return (a + b) | (-(T)((T)(a + b) < a)); \ +} + +DEF_SAT_U_ADD(uint8_t) +DEF_SAT_U_ADD(uint16_t) +DEF_SAT_U_ADD(uint32_t) +DEF_SAT_U_ADD(uint64_t) + +#define DEF_SAT_U_SUB(T) \ +T \ +test_##T##_sat_sub (T a, T b) \ +{ \ + return (a - b) & (-(T)(a >= b)); \ +} + +DEF_SAT_U_SUB(uint8_t) +DEF_SAT_U_SUB(uint16_t) +DEF_SAT_U_SUB(uint32_t) +DEF_SAT_U_SUB(uint64_t) + +#define DEF_SAT_S_ADD(T, UT, MIN, MAX) \ +T \ +test_##T##_sat_add (T x, T y) \ +{ \ + T sum = (UT)x + (UT)y; \ + return (x ^ y) < 0 \ + ? sum \ + : (sum ^ x) >= 0 \ + ? sum \ + : x < 0 ? MIN : MAX; \ +} + +DEF_SAT_S_ADD(int8_t, uint8_t, INT8_MIN, INT8_MAX) +DEF_SAT_S_ADD(int16_t, uint16_t, INT16_MIN, INT16_MAX) +DEF_SAT_S_ADD(int32_t, uint32_t, INT32_MIN, INT32_MAX) +DEF_SAT_S_ADD(int64_t, uint64_t, INT64_MIN, INT64_MAX) + +#define DEF_SAT_S_SUB(T, UT, MIN, MAX) \ +T \ +test_##T##_sat_sub (T x, T y) \ +{ \ + T minus = (UT)x - (UT)y; \ + return (x ^ y) >= 0 \ + ? minus \ + : (minus ^ x) >= 0 \ + ? minus \ + : x < 0 ? MIN : MAX; \ +} + +DEF_SAT_S_SUB(int8_t, uint8_t, INT8_MIN, INT8_MAX) +DEF_SAT_S_SUB(int16_t, uint16_t, INT16_MIN, INT16_MAX) +DEF_SAT_S_SUB(int32_t, uint32_t, INT32_MIN, INT32_MAX) +DEF_SAT_S_SUB(int64_t, uint64_t, INT64_MIN, INT64_MAX) + +#define SAT_U_ADD_FUNC(T) test_##T##_sat_add +#define SAT_U_ADD_FUNC_WRAP(T) SAT_U_ADD_FUNC(T) + +#define SAT_U_SUB_FUNC(T) test_##T##_sat_sub +#define SAT_U_SUB_FUNC_WRAP(T) SAT_U_SUB_FUNC(T) + +#define SAT_S_ADD_FUNC(T) test_##T##_sat_add +#define SAT_S_ADD_FUNC_WRAP(T) SAT_S_ADD_FUNC(T) + +#define SAT_S_SUB_FUNC(T) test_##T##_sat_sub +#define SAT_S_SUB_FUNC_WRAP(T) SAT_S_SUB_FUNC(T) + +#define DEF_AVG_FLOOR(NT, WT) \ +NT \ +test_##NT##_avg_floor(NT x, NT y) \ +{ \ + return (NT)(((WT)x + (WT)y) >> 1); \ +} + +DEF_AVG_FLOOR(uint8_t, uint16_t) +DEF_AVG_FLOOR(uint16_t, uint32_t) +DEF_AVG_FLOOR(uint32_t, uint64_t) + +#ifdef HAS_UINT128 + DEF_AVG_FLOOR(uint64_t, uint128_t) +#endif + +#define AVG_FLOOR_FUNC(T) test_##T##_avg_floor +#define AVG_FLOOR_FUNC_WRAP(T) AVG_FLOOR_FUNC(T) + +#define TEST_BINARY_VX_SIGNED_0(T) \ + DEF_VX_BINARY_CASE_0_WRAP(T, +, add) \ + DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) \ + DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) \ + DEF_VX_BINARY_CASE_0_WRAP(T, &, and) \ + DEF_VX_BINARY_CASE_0_WRAP(T, |, or) \ + DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) \ + DEF_VX_BINARY_CASE_0_WRAP(T, *, mul) \ + DEF_VX_BINARY_CASE_0_WRAP(T, /, div) \ + DEF_VX_BINARY_CASE_0_WRAP(T, %, rem) \ + DEF_VX_BINARY_CASE_2_WRAP(T, MAX_FUNC_0_WARP(T), max) \ + DEF_VX_BINARY_CASE_2_WRAP(T, MAX_FUNC_1_WARP(T), max) \ + DEF_VX_BINARY_CASE_2_WRAP(T, MIN_FUNC_0_WARP(T), min) \ + DEF_VX_BINARY_CASE_2_WRAP(T, MIN_FUNC_1_WARP(T), min) \ + DEF_VX_BINARY_CASE_2_WRAP(T, SAT_S_ADD_FUNC(T), sat_add) \ + DEF_VX_BINARY_CASE_2_WRAP(T, SAT_S_SUB_FUNC(T), sat_sub) \ + +#define TEST_BINARY_VX_UNSIGNED_0(T) \ + DEF_VX_BINARY_CASE_0_WRAP(T, +, add) \ + DEF_VX_BINARY_CASE_0_WRAP(T, -, sub) \ + DEF_VX_BINARY_REVERSE_CASE_0_WRAP(T, -, rsub) \ + DEF_VX_BINARY_CASE_0_WRAP(T, &, and) \ + DEF_VX_BINARY_CASE_0_WRAP(T, |, or) \ + DEF_VX_BINARY_CASE_0_WRAP(T, ^, xor) \ + DEF_VX_BINARY_CASE_0_WRAP(T, /, div) \ + DEF_VX_BINARY_CASE_0_WRAP(T, %, rem) \ + DEF_VX_BINARY_CASE_2_WRAP(T, MAX_FUNC_0_WARP(T), max) \ + DEF_VX_BINARY_CASE_2_WRAP(T, MAX_FUNC_1_WARP(T), max) \ + DEF_VX_BINARY_CASE_2_WRAP(T, MIN_FUNC_0_WARP(T), min) \ + DEF_VX_BINARY_CASE_2_WRAP(T, MIN_FUNC_1_WARP(T), min) \ + DEF_VX_BINARY_CASE_2_WRAP(T, SAT_U_ADD_FUNC(T), sat_add) \ + DEF_VX_BINARY_CASE_2_WRAP(T, SAT_U_SUB_FUNC(T), sat_sub) \ + DEF_VX_BINARY_CASE_2_WRAP(T, AVG_FLOOR_FUNC_WRAP(T), avg_floor) \ + #endif diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h index ed8c56252dfd..b742856bbb40 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h @@ -2750,4 +2750,2356 @@ int64_t TEST_BINARY_DATA(int64_t, div)[][3][N] = }, }; +uint8_t TEST_BINARY_DATA(uint8_t, div)[][3][N] = +{ + { + { 2 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 4, 4, 4, 4, + 7, 7, 7, 7, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + 2, 2, 2, 2, + 3, 3, 3, 3, + }, + }, + { + { 127 }, + { + 127, 127, 127, 127, + 1, 1, 1, 1, + 128, 128, 128, 128, + 2, 2, 2, 2, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0, + }, + }, + { + { 128 }, + { + 127, 127, 127, 127, + 255, 255, 255, 255, + 128, 128, 128, 128, + 1, 1, 1, 1, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 1, 1, 1, 1, + 0, 0, 0, 0, + }, + }, +}; + +uint16_t TEST_BINARY_DATA(uint16_t, div)[][3][N] = +{ + { + { 2 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 4, 4, 4, 4, + 7, 7, 7, 7, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + 2, 2, 2, 2, + 3, 3, 3, 3, + }, + }, + { + { 32767 }, + { + 32767, 32767, 32767, 32767, + 1, 1, 1, 1, + 32768, 32768, 32768, 32768, + 2, 2, 2, 2, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0, + }, + }, + { + { 32768 }, + { + 32767, 32767, 32767, 32767, + 65535, 65535, 65535, 65535, + 32768, 32768, 32768, 32768, + 1, 1, 1, 1, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 1, 1, 1, 1, + 0, 0, 0, 0, + }, + }, +}; + +uint32_t TEST_BINARY_DATA(uint32_t, div)[][3][N] = +{ + { + { 2 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 4, 4, 4, 4, + 7, 7, 7, 7, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + 2, 2, 2, 2, + 3, 3, 3, 3, + }, + }, + { + { 2147483647 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 1, 1, 1, 1, + 2147483648, 2147483648, 2147483648, 2147483648, + 2, 2, 2, 2, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0, + }, + }, + { + { 2147483648 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 4294967295, 4294967295, 4294967295, 4294967295, + 2147483648, 2147483648, 2147483648, 2147483648, + 1, 1, 1, 1, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 1, 1, 1, 1, + 0, 0, 0, 0, + }, + }, +}; + +uint64_t TEST_BINARY_DATA(uint64_t, div)[][3][N] = +{ + { + { 2 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 4, 4, 4, 4, + 7, 7, 7, 7, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + 2, 2, 2, 2, + 3, 3, 3, 3, + }, + }, + { + { 9223372036854775807ull }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 1, 1, 1, 1, + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 2, 2, 2, 2, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0, + }, + }, + { + { 9223372036854775808ull }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 1, 1, 1, 1, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 1, 1, 1, 1, + 0, 0, 0, 0, + }, + }, +}; + +int8_t TEST_BINARY_DATA(int8_t, rem)[][3][N] = +{ + { + { 2 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + -1, -1, -1, -1, + 0, 0, 0, 0, + }, + }, + { + { 127 }, + { + 127, 127, 127, 127, + -1, -1, -1, -1, + -128, -128, -128, -128, + -2, -2, -2, -2, + }, + { + 0, 0, 0, 0, + -1, -1, -1, -1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + }, + { + { -128 }, + { + -128, -128, -128, -128, + 1, 1, 1, 1, + 127, 127, 127, 127, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 127, 127, 127, 127, + 2, 2, 2, 2, + }, + }, +}; + +int16_t TEST_BINARY_DATA(int16_t, rem)[][3][N] = +{ + { + { 2 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + -1, -1, -1, -1, + 0, 0, 0, 0, + }, + }, + { + { 32767 }, + { + 32767, 32767, 32767, 32767, + -1, -1, -1, -1, + -32768, -32768, -32768, -32768, + -2, -2, -2, -2, + }, + { + 0, 0, 0, 0, + -1, -1, -1, -1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + }, + { + { -32768 }, + { + -32768, -32768, -32768, -32768, + 1, 1, 1, 1, + 32767, 32767, 32767, 32767, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 32767, 32767, 32767, 32767, + 2, 2, 2, 2, + }, + }, +}; + +int32_t TEST_BINARY_DATA(int32_t, rem)[][3][N] = +{ + { + { 2 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + -1, -1, -1, -1, + 0, 0, 0, 0, + }, + }, + { + { 2147483647 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + -1, -1, -1, -1, + -2147483648, -2147483648, -2147483648, -2147483648, + -2, -2, -2, -2, + }, + { + 0, 0, 0, 0, + -1, -1, -1, -1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + }, + { + { -2147483648 }, + { + -2147483648, -2147483648, -2147483648, -2147483648, + 1, 1, 1, 1, + 2147483647, 2147483647, 2147483647, 2147483647, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 2147483647, 2147483647, 2147483647, 2147483647, + 2, 2, 2, 2, + }, + }, +}; + +int64_t TEST_BINARY_DATA(int64_t, rem)[][3][N] = +{ + { + { 2 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + -1, -1, -1, -1, + 0, 0, 0, 0, + }, + }, + { + { 9223372036854775807ll }, + { + 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, + -1, -1, -1, -1, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + -2, -2, -2, -2, + }, + { + 0, 0, 0, 0, + -1, -1, -1, -1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + }, + { + { -9223372036854775808ull }, + { + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + 1, 1, 1, 1, + 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, + 2, 2, 2, 2, + }, + }, +}; + +uint8_t TEST_BINARY_DATA(uint8_t, rem)[][3][N] = +{ + { + { 2 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 8, 8, 8, 8, + 7, 7, 7, 7, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0, + 1, 1, 1, 1, + }, + }, + { + { 127 }, + { + 127, 127, 127, 127, + 1, 1, 1, 1, + 128, 128, 128, 128, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 1, 1, 1, 1, + 2, 2, 2, 2, + }, + }, + { + { 128 }, + { + 128, 128, 128, 128, + 255, 255, 255, 255, + 127, 127, 127, 127, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 127, 127, 127, 127, + 127, 127, 127, 127, + 2, 2, 2, 2, + }, + }, +}; + +uint16_t TEST_BINARY_DATA(uint16_t, rem)[][3][N] = +{ + { + { 2 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 8, 8, 8, 8, + 7, 7, 7, 7, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0, + 1, 1, 1, 1, + }, + }, + { + { 32767 }, + { + 32767, 32767, 32767, 32767, + 1, 1, 1, 1, + 32768, 32768, 32768, 32768, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 1, 1, 1, 1, + 2, 2, 2, 2, + }, + }, + { + { 32768 }, + { + 32768, 32768, 32768, 32768, + 65535, 65535, 65535, 65535, + 32767, 32767, 32767, 32767, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, + 2, 2, 2, 2, + }, + }, +}; + +uint32_t TEST_BINARY_DATA(uint32_t, rem)[][3][N] = +{ + { + { 2 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 8, 8, 8, 8, + 7, 7, 7, 7, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0, + 1, 1, 1, 1, + }, + }, + { + { 2147483647 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 1, 1, 1, 1, + 2147483648, 2147483648, 2147483648, 2147483648, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 1, 1, 1, 1, + 2, 2, 2, 2, + }, + }, + { + { 2147483648 }, + { + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967295, 4294967295, 4294967295, 4294967295, + 2147483647, 2147483647, 2147483647, 2147483647, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483647, 2147483647, 2147483647, 2147483647, + 2, 2, 2, 2, + }, + }, +}; + +uint64_t TEST_BINARY_DATA(uint64_t, rem)[][3][N] = +{ + { + { 2 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 8, 8, 8, 8, + 7, 7, 7, 7, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0, + 1, 1, 1, 1, + }, + }, + { + { 9223372036854775807ull }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 1, 1, 1, 1, + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 1, 1, 1, 1, + 2, 2, 2, 2, + }, + }, + { + { 9223372036854775808ull }, + { + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 2, 2, 2, 2, + }, + }, +}; + +int8_t TEST_BINARY_DATA(int8_t, max)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, + { + { 127 }, + { + 127, 127, 127, 127, + -1, -1, -1, -1, + -128, -128, -128, -128, + -2, -2, -2, -2, + }, + { + 127, 127, 127, 127, + 127, 127, 127, 127, + 127, 127, 127, 127, + 127, 127, 127, 127, + }, + }, + { + { -128 }, + { + -128, -128, -128, -128, + 1, 1, 1, 1, + 127, 127, 127, 127, + 2, 2, 2, 2, + }, + { + -128, -128, -128, -128, + 1, 1, 1, 1, + 127, 127, 127, 127, + 2, 2, 2, 2, + }, + }, +}; + +int16_t TEST_BINARY_DATA(int16_t, max)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, + { + { 32767 }, + { + 32767, 32767, 32767, 32767, + -1, -1, -1, -1, + -32768, -32768, -32768, -32768, + -2, -2, -2, -2, + }, + { + 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, + }, + }, + { + { -32768 }, + { + -32768, -32768, -32768, -32768, + 1, 1, 1, 1, + 32767, 32767, 32767, 32767, + 2, 2, 2, 2, + }, + { + -32768, -32768, -32768, -32768, + 1, 1, 1, 1, + 32767, 32767, 32767, 32767, + 2, 2, 2, 2, + }, + }, +}; + +int32_t TEST_BINARY_DATA(int32_t, max)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, + { + { 2147483647 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + -1, -1, -1, -1, + -2147483648, -2147483648, -2147483648, -2147483648, + -2, -2, -2, -2, + }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483647, 2147483647, 2147483647, 2147483647, + }, + }, + { + { -2147483648 }, + { + -2147483648, -2147483648, -2147483648, -2147483648, + 1, 1, 1, 1, + 2147483647, 2147483647, 2147483647, 2147483647, + 2, 2, 2, 2, + }, + { + -2147483648, -2147483648, -2147483648, -2147483648, + 1, 1, 1, 1, + 2147483647, 2147483647, 2147483647, 2147483647, + 2, 2, 2, 2, + }, + }, +}; + +int64_t TEST_BINARY_DATA(int64_t, max)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, + { + { 9223372036854775807ll }, + { + 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, + -1, -1, -1, -1, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + -2, -2, -2, -2, + }, + { + 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, + 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, + 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, + 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, + }, + }, + { + { -9223372036854775808ull }, + { + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + 1, 1, 1, 1, + 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, + 2, 2, 2, 2, + }, + { + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + 1, 1, 1, 1, + 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, + 2, 2, 2, 2, + }, + }, +}; + +uint8_t TEST_BINARY_DATA(uint8_t, max)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 127 }, + { + 127, 127, 127, 127, + 128, 128, 128, 128, + 255, 255, 255, 255, + 1, 1, 1, 1, + }, + { + 127, 127, 127, 127, + 128, 128, 128, 128, + 255, 255, 255, 255, + 127, 127, 127, 127, + }, + }, + { + { 254 }, + { + 128, 128, 128, 128, + 255, 255, 255, 255, + 127, 127, 127, 127, + 2, 2, 2, 2, + }, + { + 254, 254, 254, 254, + 255, 255, 255, 255, + 254, 254, 254, 254, + 254, 254, 254, 254, + }, + }, +}; + +uint16_t TEST_BINARY_DATA(uint16_t, max)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 32767 }, + { + 32767, 32767, 32767, 32767, + 32768, 32768, 32768, 32768, + 65535, 65535, 65535, 65535, + 1, 1, 1, 1, + }, + { + 32767, 32767, 32767, 32767, + 32768, 32768, 32768, 32768, + 65535, 65535, 65535, 65535, + 32767, 32767, 32767, 32767, + }, + }, + { + { 65534 }, + { + 32768, 32768, 32768, 32768, + 65535, 65535, 65535, 65535, + 32767, 32767, 32767, 32767, + 2, 2, 2, 2, + }, + { + 65534, 65534, 65534, 65534, + 65535, 65535, 65535, 65535, + 65534, 65534, 65534, 65534, + 65534, 65534, 65534, 65534, + }, + }, +}; + +uint32_t TEST_BINARY_DATA(uint32_t, max)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 2147483647 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967295, 4294967295, 4294967295, 4294967295, + 1, 1, 1, 1, + }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967295, 4294967295, 4294967295, 4294967295, + 2147483647, 2147483647, 2147483647, 2147483647, + }, + }, + { + { 4294967294 }, + { + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967295, 4294967295, 4294967295, 4294967295, + 2147483647, 2147483647, 2147483647, 2147483647, + 2, 2, 2, 2, + }, + { + 4294967294, 4294967294, 4294967294, 4294967294, + 4294967295, 4294967295, 4294967295, 4294967295, + 4294967294, 4294967294, 4294967294, 4294967294, + 4294967294, 4294967294, 4294967294, 4294967294, + }, + }, +}; + +uint64_t TEST_BINARY_DATA(uint64_t, max)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 9223372036854775807ull }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 1, 1, 1, 1, + }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + }, + }, + { + { 18446744073709551614ull }, + { + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 2, 2, 2, 2, + }, + { + 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, + 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, + }, + }, +}; + +int8_t TEST_BINARY_DATA(int8_t, min)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + }, + { + { 127 }, + { + 127, 127, 127, 127, + -1, -1, -1, -1, + -128, -128, -128, -128, + -2, -2, -2, -2, + }, + { + 127, 127, 127, 127, + -1, -1, -1, -1, + -128, -128, -128, -128, + -2, -2, -2, -2, + }, + }, + { + { -128 }, + { + -128, -128, -128, -128, + 1, 1, 1, 1, + 127, 127, 127, 127, + 2, 2, 2, 2, + }, + { + -128, -128, -128, -128, + -128, -128, -128, -128, + -128, -128, -128, -128, + -128, -128, -128, -128, + }, + }, +}; + +int16_t TEST_BINARY_DATA(int16_t, min)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + }, + { + { 32767 }, + { + 32767, 32767, 32767, 32767, + -1, -1, -1, -1, + -32768, -32768, -32768, -32768, + -2, -2, -2, -2, + }, + { + 32767, 32767, 32767, 32767, + -1, -1, -1, -1, + -32768, -32768, -32768, -32768, + -2, -2, -2, -2, + }, + }, + { + { -32768 }, + { + -32768, -32768, -32768, -32768, + 1, 1, 1, 1, + 32767, 32767, 32767, 32767, + 2, 2, 2, 2, + }, + { + -32768, -32768, -32768, -32768, + -32768, -32768, -32768, -32768, + -32768, -32768, -32768, -32768, + -32768, -32768, -32768, -32768, + }, + }, +}; + +int32_t TEST_BINARY_DATA(int32_t, min)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + }, + { + { 2147483647 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + -1, -1, -1, -1, + -2147483648, -2147483648, -2147483648, -2147483648, + -2, -2, -2, -2, + }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + -1, -1, -1, -1, + -2147483648, -2147483648, -2147483648, -2147483648, + -2, -2, -2, -2, + }, + }, + { + { -2147483648 }, + { + -2147483648, -2147483648, -2147483648, -2147483648, + 1, 1, 1, 1, + 2147483647, 2147483647, 2147483647, 2147483647, + 2, 2, 2, 2, + }, + { + -2147483648, -2147483648, -2147483648, -2147483648, + -2147483648, -2147483648, -2147483648, -2147483648, + -2147483648, -2147483648, -2147483648, -2147483648, + -2147483648, -2147483648, -2147483648, -2147483648, + }, + }, +}; + +int64_t TEST_BINARY_DATA(int64_t, min)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + -1, -1, -1, -1, + -2, -2, -2, -2, + }, + }, + { + { 9223372036854775807ll }, + { + 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, + -1, -1, -1, -1, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + -2, -2, -2, -2, + }, + { + 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, + -1, -1, -1, -1, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + -2, -2, -2, -2, + }, + }, + { + { -9223372036854775808ull }, + { + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + 1, 1, 1, 1, + 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll, + 2, 2, 2, 2, + }, + { + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + }, + }, +}; + +uint8_t TEST_BINARY_DATA(uint8_t, min)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, + { + { 127 }, + { + 127, 127, 127, 127, + 128, 128, 128, 128, + 255, 255, 255, 255, + 1, 1, 1, 1, + }, + { + 127, 127, 127, 127, + 127, 127, 127, 127, + 127, 127, 127, 127, + 1, 1, 1, 1, + }, + }, + { + { 254 }, + { + 128, 128, 128, 128, + 255, 255, 255, 255, + 127, 127, 127, 127, + 2, 2, 2, 2, + }, + { + 128, 128, 128, 128, + 254, 254, 254, 254, + 127, 127, 127, 127, + 2, 2, 2, 2, + }, + }, +}; + +uint16_t TEST_BINARY_DATA(uint16_t, min)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, + { + { 32767 }, + { + 32767, 32767, 32767, 32767, + 32768, 32768, 32768, 32768, + 65535, 65535, 65535, 65535, + 1, 1, 1, 1, + }, + { + 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, + 1, 1, 1, 1, + }, + }, + { + { 65534 }, + { + 32768, 32768, 32768, 32768, + 65535, 65535, 65535, 65535, + 32767, 32767, 32767, 32767, + 2, 2, 2, 2, + }, + { + 32768, 32768, 32768, 32768, + 65534, 65534, 65534, 65534, + 32767, 32767, 32767, 32767, + 2, 2, 2, 2, + }, + }, +}; + +uint32_t TEST_BINARY_DATA(uint32_t, min)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, + { + { 2147483647 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967295, 4294967295, 4294967295, 4294967295, + 1, 1, 1, 1, + }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483647, 2147483647, 2147483647, 2147483647, + 1, 1, 1, 1, + }, + }, + { + { 4294967294 }, + { + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967295, 4294967295, 4294967295, 4294967295, + 2147483647, 2147483647, 2147483647, 2147483647, + 2, 2, 2, 2, + }, + { + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967294, 4294967294, 4294967294, 4294967294, + 2147483647, 2147483647, 2147483647, 2147483647, + 2, 2, 2, 2, + }, + }, +}; + +uint64_t TEST_BINARY_DATA(uint64_t, min)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, + { + { 9223372036854775807ull }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 1, 1, 1, 1, + }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 1, 1, 1, 1, + }, + }, + { + { 18446744073709551614ull }, + { + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 2, 2, 2, 2, + }, + { + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 2, 2, 2, 2, + }, + }, +}; + +uint8_t TEST_BINARY_DATA(uint8_t, sat_add)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 127 }, + { + 127, 127, 127, 127, + 128, 128, 128, 128, + 255, 255, 255, 255, + 1, 1, 1, 1, + }, + { + 254, 254, 254, 254, + 255, 255, 255, 255, + 255, 255, 255, 255, + 128, 128, 128, 128, + }, + }, + { + { 254 }, + { + 128, 128, 128, 128, + 255, 255, 255, 255, + 127, 127, 127, 127, + 2, 2, 2, 2, + }, + { + 255, 255, 255, 255, + 255, 255, 255, 255, + 255, 255, 255, 255, + 255, 255, 255, 255, + }, + }, +}; + +uint16_t TEST_BINARY_DATA(uint16_t, sat_add)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 32767 }, + { + 32767, 32767, 32767, 32767, + 32768, 32768, 32768, 32768, + 65535, 65535, 65535, 65535, + 1, 1, 1, 1, + }, + { + 65534, 65534, 65534, 65534, + 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, + 32768, 32768, 32768, 32768, + }, + }, + { + { 65534 }, + { + 32768, 32768, 32768, 32768, + 65535, 65535, 65535, 65535, + 32767, 32767, 32767, 32767, + 2, 2, 2, 2, + }, + { + 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, + }, + }, +}; + +uint32_t TEST_BINARY_DATA(uint32_t, sat_add)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 2147483647 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967295, 4294967295, 4294967295, 4294967295, + 1, 1, 1, 1, + }, + { + 4294967294, 4294967294, 4294967294, 4294967294, + 4294967295, 4294967295, 4294967295, 4294967295, + 4294967295, 4294967295, 4294967295, 4294967295, + 2147483648, 2147483648, 2147483648, 2147483648, + }, + }, + { + { 4294967294 }, + { + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967295, 4294967295, 4294967295, 4294967295, + 2147483647, 2147483647, 2147483647, 2147483647, + 2, 2, 2, 2, + }, + { + 4294967295, 4294967295, 4294967295, 4294967295, + 4294967295, 4294967295, 4294967295, 4294967295, + 4294967295, 4294967295, 4294967295, 4294967295, + 4294967295, 4294967295, 4294967295, 4294967295, + }, + }, +}; + +uint64_t TEST_BINARY_DATA(uint64_t, sat_add)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 9223372036854775807ull }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 1, 1, 1, 1, + }, + { + 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + }, + }, + { + { 18446744073709551614ull }, + { + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 2, 2, 2, 2, + }, + { + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + }, + }, +}; + +uint8_t TEST_BINARY_DATA(uint8_t, sat_sub)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 127 }, + { + 127, 127, 127, 127, + 128, 128, 128, 128, + 255, 255, 255, 255, + 1, 1, 1, 1, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 128, 128, 128, 128, + 0, 0, 0, 0, + }, + }, + { + { 254 }, + { + 128, 128, 128, 128, + 255, 255, 255, 255, + 127, 127, 127, 127, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, +}; + +uint16_t TEST_BINARY_DATA(uint16_t, sat_sub)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 32767 }, + { + 32767, 32767, 32767, 32767, + 32768, 32768, 32768, 32768, + 65535, 65535, 65535, 65535, + 1, 1, 1, 1, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 32768, 32768, 32768, 32768, + 0, 0, 0, 0, + }, + }, + { + { 65534 }, + { + 32768, 32768, 32768, 32768, + 65535, 65535, 65535, 65535, + 32767, 32767, 32767, 32767, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, +}; + +uint32_t TEST_BINARY_DATA(uint32_t, sat_sub)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 2147483647 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967295, 4294967295, 4294967295, 4294967295, + 1, 1, 1, 1, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 2147483648, 2147483648, 2147483648, 2147483648, + 0, 0, 0, 0, + }, + }, + { + { 4294967294 }, + { + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967295, 4294967295, 4294967295, 4294967295, + 2147483647, 2147483647, 2147483647, 2147483647, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, +}; + +uint64_t TEST_BINARY_DATA(uint64_t, sat_sub)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 9223372036854775807ull }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 1, 1, 1, 1, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 0, 0, 0, 0, + }, + }, + { + { 18446744073709551614ull }, + { + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 2, 2, 2, 2, + }, + { + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, +}; + +int8_t TEST_BINARY_DATA(int8_t, sat_add)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 127 }, + { + 127, 127, 127, 127, + -128, -128, -128, -128, + -127, -127, -127, -127, + 1, 1, 1, 1, + }, + { + 127, 127, 127, 127, + -1, -1, -1, -1, + 0, 0, 0, 0, + 127, 127, 127, 127, + }, + }, + { + { -128 }, + { + 127, 127, 127, 127, + -1, -1, -1, -1, + -128, -128, -128, -128, + 1, 1, 1, 1, + }, + { + -1, -1, -1, -1, + -128, -128, -128, -128, + -128, -128, -128, -128, + -127, -127, -127, -127, + }, + }, +}; + +int16_t TEST_BINARY_DATA(int16_t, sat_add)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 32767 }, + { + 32767, 32767, 32767, 32767, + -32768, -32768, -32768, -32768, + -32767, -32767, -32767, -32767, + 1, 1, 1, 1, + }, + { + 32767, 32767, 32767, 32767, + -1, -1, -1, -1, + 0, 0, 0, 0, + 32767, 32767, 32767, 32767, + }, + }, + { + { -32768 }, + { + 32767, 32767, 32767, 32767, + -1, -1, -1, -1, + -32768, -32768, -32768, -32768, + 1, 1, 1, 1, + }, + { + -1, -1, -1, -1, + -32768, -32768, -32768, -32768, + -32768, -32768, -32768, -32768, + -32767, -32767, -32767, -32767, + }, + }, +}; + +int32_t TEST_BINARY_DATA(int32_t, sat_add)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 2147483647 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + -2147483648, -2147483648, -2147483648, -2147483648, + -2147483647, -2147483647, -2147483647, -2147483647, + 1, 1, 1, 1, + }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + -1, -1, -1, -1, + 0, 0, 0, 0, + 2147483647, 2147483647, 2147483647, 2147483647, + }, + }, + { + { -2147483648 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + -1, -1, -1, -1, + -2147483648, -2147483648, -2147483648, -2147483648, + 1, 1, 1, 1, + }, + { + -1, -1, -1, -1, + -2147483648, -2147483648, -2147483648, -2147483648, + -2147483648, -2147483648, -2147483648, -2147483648, + -2147483647, -2147483647, -2147483647, -2147483647, + }, + }, +}; + +int64_t TEST_BINARY_DATA(int64_t, sat_add)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + }, + { + { 9223372036854775807ull }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + -9223372036854775807ull, -9223372036854775807ull, -9223372036854775807ull, -9223372036854775807ull, + 1, 1, 1, 1, + }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + -1, -1, -1, -1, + 0, 0, 0, 0, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + }, + }, + { + { -9223372036854775808ull }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + -1, -1, -1, -1, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + 1, 1, 1, 1, + }, + { + -1, -1, -1, -1, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + -9223372036854775807ull, -9223372036854775807ull, -9223372036854775807ull, -9223372036854775807ull, + }, + }, +}; + +int8_t TEST_BINARY_DATA(int8_t, sat_sub)[][3][N] = +{ + { + { 1 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + -1, -1, -1, -1, + 3, 3, 3, 3, + }, + }, + { + { 127 }, + { + 127, 127, 127, 127, + -128, -128, -128, -128, + -127, -127, -127, -127, + 1, 1, 1, 1, + }, + { + 0, 0, 0, 0, + -128, -128, -128, -128, + -128, -128, -128, -128, + -126, -126, -126, -126, + }, + }, + { + { -128 }, + { + 127, 127, 127, 127, + -1, -1, -1, -1, + -128, -128, -128, -128, + 1, 1, 1, 1, + }, + { + 127, 127, 127, 127, + 127, 127, 127, 127, + 0, 0, 0, 0, + 127, 127, 127, 127, + }, + }, +}; + +int16_t TEST_BINARY_DATA(int16_t, sat_sub)[][3][N] = +{ + { + { 1 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + -1, -1, -1, -1, + 3, 3, 3, 3, + }, + }, + { + { 32767 }, + { + 32767, 32767, 32767, 32767, + -32768, -32768, -32768, -32768, + -32767, -32767, -32767, -32767, + 1, 1, 1, 1, + }, + { + 0, 0, 0, 0, + -32768, -32768, -32768, -32768, + -32768, -32768, -32768, -32768, + -32766, -32766, -32766, -32766, + }, + }, + { + { -32768 }, + { + 32767, 32767, 32767, 32767, + -1, -1, -1, -1, + -32768, -32768, -32768, -32768, + 1, 1, 1, 1, + }, + { + 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, + 0, 0, 0, 0, + 32767, 32767, 32767, 32767, + }, + }, +}; + +int32_t TEST_BINARY_DATA(int32_t, sat_sub)[][3][N] = +{ + { + { 1 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + -1, -1, -1, -1, + 3, 3, 3, 3, + }, + }, + { + { 2147483647 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + -2147483648, -2147483648, -2147483648, -2147483648, + -2147483647, -2147483647, -2147483647, -2147483647, + 1, 1, 1, 1, + }, + { + 0, 0, 0, 0, + -2147483648, -2147483648, -2147483648, -2147483648, + -2147483648, -2147483648, -2147483648, -2147483648, + -2147483646, -2147483646, -2147483646, -2147483646, + }, + }, + { + { -2147483648 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + -1, -1, -1, -1, + -2147483648, -2147483648, -2147483648, -2147483648, + 1, 1, 1, 1, + }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483647, 2147483647, 2147483647, 2147483647, + 0, 0, 0, 0, + 2147483647, 2147483647, 2147483647, 2147483647, + }, + }, +}; + +int64_t TEST_BINARY_DATA(int64_t, sat_sub)[][3][N] = +{ + { + { 1 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + -1, -1, -1, -1, + 3, 3, 3, 3, + }, + }, + { + { 9223372036854775807ull }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + -9223372036854775807ull, -9223372036854775807ull, -9223372036854775807ull, -9223372036854775807ull, + 1, 1, 1, 1, + }, + { + 0, 0, 0, 0, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + -9223372036854775806ull, -9223372036854775806ull, -9223372036854775806ull, -9223372036854775806ull, + }, + }, + { + { -9223372036854775808ull }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + -1, -1, -1, -1, + -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull, + 1, 1, 1, 1, + }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 0, 0, 0, 0, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + }, + }, +}; + +uint8_t TEST_BINARY_DATA(uint8_t, avg_floor)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + 0, 0, 0, 0, + 2, 2, 2, 2, + }, + }, + { + { 127 }, + { + 127, 127, 127, 127, + 128, 128, 128, 128, + 255, 255, 255, 255, + 1, 1, 1, 1, + }, + { + 127, 127, 127, 127, + 127, 127, 127, 127, + 191, 191, 191, 191, + 64, 64, 64, 64, + }, + }, + { + { 255 }, + { + 0, 0, 0, 0, + 255, 255, 255, 255, + 254, 254, 254, 254, + 1, 1, 1, 1, + }, + { + 127, 127, 127, 127, + 255, 255, 255, 255, + 254, 254, 254, 254, + 128, 128, 128, 128, + }, + }, +}; + +uint16_t TEST_BINARY_DATA(uint16_t, avg_floor)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + 0, 0, 0, 0, + 2, 2, 2, 2, + }, + }, + { + { 32767 }, + { + 32767, 32767, 32767, 32767, + 32768, 32768, 32768, 32768, + 65535, 65535, 65535, 65535, + 1, 1, 1, 1, + }, + { + 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, + 49151, 49151, 49151, 49151, + 16384, 16384, 16384, 16384, + }, + }, + { + { 65535 }, + { + 0, 0, 0, 0, + 65535, 65535, 65535, 65535, + 65534, 65534, 65534, 65534, + 1, 1, 1, 1, + }, + { + 32767, 32767, 32767, 32767, + 65535, 65535, 65535, 65535, + 65534, 65534, 65534, 65534, + 32768, 32768, 32768, 32768, + }, + }, +}; + +uint32_t TEST_BINARY_DATA(uint32_t, avg_floor)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + 0, 0, 0, 0, + 2, 2, 2, 2, + }, + }, + { + { 2147483647 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967295, 4294967295, 4294967295, 4294967295, + 1, 1, 1, 1, + }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483647, 2147483647, 2147483647, 2147483647, + 3221225471, 3221225471, 3221225471, 3221225471, + 1073741824, 1073741824, 1073741824, 1073741824, + }, + }, + { + { 4294967295 }, + { + 0, 0, 0, 0, + 4294967295, 4294967295, 4294967295, 4294967295, + 4294967294, 4294967294, 4294967294, 4294967294, + 1, 1, 1, 1, + }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 4294967295, 4294967295, 4294967295, 4294967295, + 4294967294, 4294967294, 4294967294, 4294967294, + 2147483648, 2147483648, 2147483648, 2147483648, + }, + }, +}; + +uint64_t TEST_BINARY_DATA(uint64_t, avg_floor)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 1, 1, 1, 1, + 0, 0, 0, 0, + 0, 0, 0, 0, + 2, 2, 2, 2, + }, + }, + { + { 9223372036854775807ull }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 1, 1, 1, 1, + }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 13835058055282163711ull, 13835058055282163711ull, 13835058055282163711ull, 13835058055282163711ull, + 4611686018427387904ull, 4611686018427387904ull, 4611686018427387904ull, 4611686018427387904ull, + }, + }, + { + { 18446744073709551615ull }, + { + 0, 0, 0, 0, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, + 1, 1, 1, 1, + }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + }, + }, +}; + #endif diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-1-u16.c new file mode 100644 index 000000000000..73d1a57bae6b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-1-u16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint16_t +#define NAME avg_floor +#define FUNC AVG_FLOOR_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-1-u32.c new file mode 100644 index 000000000000..60a7aa4ccb7d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-1-u32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint32_t +#define NAME avg_floor +#define FUNC AVG_FLOOR_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-1-u64.c new file mode 100644 index 000000000000..803bcbab080b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-1-u64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v && rv64 } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint64_t +#define NAME avg_floor +#define FUNC AVG_FLOOR_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-1-u8.c new file mode 100644 index 000000000000..f28147bfc3bc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-1-u8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint8_t +#define NAME avg_floor +#define FUNC AVG_FLOOR_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vdiv-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vdiv-run-1-u16.c new file mode 100644 index 000000000000..afb848d9da84 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vdiv-run-1-u16.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint16_t +#define NAME div + +DEF_VX_BINARY_CASE_0_WRAP(T, /, NAME) + +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VX_BINARY_CASE_0_WRAP(T, NAME, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vdiv-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vdiv-run-1-u32.c new file mode 100644 index 000000000000..4acaa5b3b5ba --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vdiv-run-1-u32.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint32_t +#define NAME div + +DEF_VX_BINARY_CASE_0_WRAP(T, /, NAME) + +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VX_BINARY_CASE_0_WRAP(T, NAME, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vdiv-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vdiv-run-1-u64.c new file mode 100644 index 000000000000..335a90979e0a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vdiv-run-1-u64.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint64_t +#define NAME div + +DEF_VX_BINARY_CASE_0_WRAP(T, /, NAME) + +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VX_BINARY_CASE_0_WRAP(T, NAME, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vdiv-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vdiv-run-1-u8.c new file mode 100644 index 000000000000..160d362a23d2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vdiv-run-1-u8.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint8_t +#define NAME div + +DEF_VX_BINARY_CASE_0_WRAP(T, /, NAME) + +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VX_BINARY_CASE_0_WRAP(T, NAME, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-i16.c new file mode 100644 index 000000000000..d36495c14c90 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-i16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int16_t +#define NAME max +#define FUNC MAX_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-i32.c new file mode 100644 index 000000000000..acd8aeb2dc5e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-i32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int32_t +#define NAME max +#define FUNC MAX_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-i64.c new file mode 100644 index 000000000000..5ecc206b0108 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-i64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int64_t +#define NAME max +#define FUNC MAX_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-i8.c new file mode 100644 index 000000000000..5ac63e132c3b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-i8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int8_t +#define NAME max +#define FUNC MAX_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-u16.c new file mode 100644 index 000000000000..ebe3f09d666c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-u16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint16_t +#define NAME max +#define FUNC MAX_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-u32.c new file mode 100644 index 000000000000..ceec03b7ddd2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-u32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint32_t +#define NAME max +#define FUNC MAX_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-u64.c new file mode 100644 index 000000000000..8657253ccb1b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-u64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint64_t +#define NAME max +#define FUNC MAX_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-u8.c new file mode 100644 index 000000000000..aefc72adb5d3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-1-u8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint8_t +#define NAME max +#define FUNC MAX_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-i16.c new file mode 100644 index 000000000000..77445b23cf0f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-i16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int16_t +#define NAME max +#define FUNC MAX_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-i32.c new file mode 100644 index 000000000000..fc4fb5545418 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-i32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int32_t +#define NAME max +#define FUNC MAX_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-i64.c new file mode 100644 index 000000000000..1afa12eb4118 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-i64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int64_t +#define NAME max +#define FUNC MAX_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-i8.c new file mode 100644 index 000000000000..9c1222b9fa1e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-i8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int8_t +#define NAME max +#define FUNC MAX_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-u16.c new file mode 100644 index 000000000000..4617f078560c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-u16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint16_t +#define NAME max +#define FUNC MAX_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-u32.c new file mode 100644 index 000000000000..f0302e8d2118 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-u32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint32_t +#define NAME max +#define FUNC MAX_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-u64.c new file mode 100644 index 000000000000..a82cfc583a6d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-u64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint64_t +#define NAME max +#define FUNC MAX_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-u8.c new file mode 100644 index 000000000000..8199ccd0c388 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmax-run-2-u8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint8_t +#define NAME max +#define FUNC MAX_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, max) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i16.c new file mode 100644 index 000000000000..180c82bc854e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int16_t +#define NAME min +#define FUNC MIN_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i32.c new file mode 100644 index 000000000000..980b63cb0d24 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int32_t +#define NAME min +#define FUNC MIN_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i64.c new file mode 100644 index 000000000000..26fae235c999 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int64_t +#define NAME min +#define FUNC MIN_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i8.c new file mode 100644 index 000000000000..c5c14a45fed4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int8_t +#define NAME min +#define FUNC MIN_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u16.c new file mode 100644 index 000000000000..5295bb84c5ed --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint16_t +#define NAME min +#define FUNC MIN_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u32.c new file mode 100644 index 000000000000..1e09610eea02 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint32_t +#define NAME min +#define FUNC MIN_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u64.c new file mode 100644 index 000000000000..ed757e61f7f1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint64_t +#define NAME min +#define FUNC MIN_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u8.c new file mode 100644 index 000000000000..dd4b93ae0271 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint8_t +#define NAME min +#define FUNC MIN_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i16.c new file mode 100644 index 000000000000..bfdabebf2f87 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int16_t +#define NAME min +#define FUNC MIN_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i32.c new file mode 100644 index 000000000000..af3404943c17 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int32_t +#define NAME min +#define FUNC MIN_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i64.c new file mode 100644 index 000000000000..013bd8356af7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int64_t +#define NAME min +#define FUNC MIN_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i8.c new file mode 100644 index 000000000000..0f4fd2d6da7f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int8_t +#define NAME min +#define FUNC MIN_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u16.c new file mode 100644 index 000000000000..5e450d85d4b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint16_t +#define NAME min +#define FUNC MIN_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u32.c new file mode 100644 index 000000000000..45bfd1230dd3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint32_t +#define NAME min +#define FUNC MIN_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u64.c new file mode 100644 index 000000000000..46f00314cec6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint64_t +#define NAME min +#define FUNC MIN_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u8.c new file mode 100644 index 000000000000..971404b2e677 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint8_t +#define NAME min +#define FUNC MIN_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-i16.c new file mode 100644 index 000000000000..4320789a57a0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-i16.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int16_t +#define NAME rem + +DEF_VX_BINARY_CASE_0_WRAP(T, %, NAME) + +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VX_BINARY_CASE_0_WRAP(T, NAME, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-i32.c new file mode 100644 index 000000000000..43a001b41910 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-i32.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int32_t +#define NAME rem + +DEF_VX_BINARY_CASE_0_WRAP(T, %, NAME) + +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VX_BINARY_CASE_0_WRAP(T, NAME, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-i64.c new file mode 100644 index 000000000000..2e9b43af0fa0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-i64.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int64_t +#define NAME rem + +DEF_VX_BINARY_CASE_0_WRAP(T, %, NAME) + +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VX_BINARY_CASE_0_WRAP(T, NAME, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-i8.c new file mode 100644 index 000000000000..d4185c74417c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-i8.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int8_t +#define NAME rem + +DEF_VX_BINARY_CASE_0_WRAP(T, %, NAME) + +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VX_BINARY_CASE_0_WRAP(T, NAME, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-u16.c new file mode 100644 index 000000000000..46e74f5a4474 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-u16.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint16_t +#define NAME rem + +DEF_VX_BINARY_CASE_0_WRAP(T, %, NAME) + +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VX_BINARY_CASE_0_WRAP(T, NAME, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-u32.c new file mode 100644 index 000000000000..94e3613f2c07 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-u32.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint32_t +#define NAME rem + +DEF_VX_BINARY_CASE_0_WRAP(T, %, NAME) + +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VX_BINARY_CASE_0_WRAP(T, NAME, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-u64.c new file mode 100644 index 000000000000..566a1a18b10c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-u64.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint64_t +#define NAME rem + +DEF_VX_BINARY_CASE_0_WRAP(T, %, NAME) + +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VX_BINARY_CASE_0_WRAP(T, NAME, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-u8.c new file mode 100644 index 000000000000..1532079c9efd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vrem-run-1-u8.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint8_t +#define NAME rem + +DEF_VX_BINARY_CASE_0_WRAP(T, %, NAME) + +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, x, n) RUN_VX_BINARY_CASE_0_WRAP(T, NAME, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-i16.c new file mode 100644 index 000000000000..1f0fd463be9b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-i16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int16_t +#define NAME sat_add +#define FUNC SAT_S_ADD_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-i32.c new file mode 100644 index 000000000000..4a8df0c6d486 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-i32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int32_t +#define NAME sat_add +#define FUNC SAT_S_ADD_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-i64.c new file mode 100644 index 000000000000..534cd2572158 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-i64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int64_t +#define NAME sat_add +#define FUNC SAT_S_ADD_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-i8.c new file mode 100644 index 000000000000..de2a9b678fad --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-i8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int8_t +#define NAME sat_add +#define FUNC SAT_S_ADD_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-u16.c new file mode 100644 index 000000000000..e1531b0b99be --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-u16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint16_t +#define NAME sat_add +#define FUNC SAT_U_ADD_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-u32.c new file mode 100644 index 000000000000..4aa71432a04a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-u32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint32_t +#define NAME sat_add +#define FUNC SAT_U_ADD_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-u64.c new file mode 100644 index 000000000000..30992c226f70 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-u64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint64_t +#define NAME sat_add +#define FUNC SAT_U_ADD_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-u8.c new file mode 100644 index 000000000000..c6852a549f9a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vsadd-run-1-u8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint8_t +#define NAME sat_add +#define FUNC SAT_U_ADD_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-i16.c new file mode 100644 index 000000000000..bd985c22082f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-i16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int16_t +#define NAME sat_sub +#define FUNC SAT_S_SUB_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-i32.c new file mode 100644 index 000000000000..c510ea0e9822 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-i32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int32_t +#define NAME sat_sub +#define FUNC SAT_S_SUB_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-i64.c new file mode 100644 index 000000000000..b82278dd4747 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-i64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int64_t +#define NAME sat_sub +#define FUNC SAT_S_SUB_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-i8.c new file mode 100644 index 000000000000..5fae70459e18 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-i8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T int8_t +#define NAME sat_sub +#define FUNC SAT_S_SUB_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-u16.c new file mode 100644 index 000000000000..f0293a120204 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-u16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint16_t +#define NAME sat_sub +#define FUNC SAT_U_SUB_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-u32.c new file mode 100644 index 000000000000..34e1493e532e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-u32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint32_t +#define NAME sat_sub +#define FUNC SAT_U_SUB_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-u64.c new file mode 100644 index 000000000000..65800b832dd3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-u64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint64_t +#define NAME sat_sub +#define FUNC SAT_U_SUB_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-u8.c new file mode 100644 index 000000000000..f09843aba2e0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vssub-run-1-u8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint8_t +#define NAME sat_sub +#define FUNC SAT_U_SUB_FUNC_WRAP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-74.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-74.c index c8a580038ec9..15284828044d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-74.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-74.c @@ -33,7 +33,7 @@ test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, } /* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ -/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 3 } } */ /* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ /* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ /* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113829.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113829.c new file mode 100644 index 000000000000..48c291a92026 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113829.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gcv -mabi=lp64d" } */ + +#pragma riscv intrinsic "vector" +void +foo (void) +{ + __riscv_vfredosum_tu (X); /* { dg-error "undeclared" } */ + /* { dg-error "too many arguments" "" { target *-*-* } .-1 } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr119164.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr119164.c new file mode 100644 index 000000000000..266e9485880c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr119164.c @@ -0,0 +1,22 @@ +/* Reduced from SPEC2017 blender: node_texture_util.c. + The conditional function call was tripping mode switching state machine */ + +/* { dg-do compile { target { rv64 && { ! riscv_abi_e } } } } */ +/* { dg-options " -Ofast -march=rv64gcv_zvl256b -ftree-vectorize -mrvv-vector-bits=zvl" } */ + +void *a; +float *b; +short c; +void d(); +void e() { + if (a) + d(); + if (c) { + b[0] = b[0] * 0.5f + 0.5f; + b[1] = b[1] * 0.5f + 0.5f; + } +} + +/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */ +/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */ +/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/pr120297.c b/gcc/testsuite/gcc.target/riscv/rvv/pr120297.c new file mode 100644 index 000000000000..3d1845d0fe66 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/pr120297.c @@ -0,0 +1,50 @@ +/* { dg-do run } */ +/* { dg-require-effective-target riscv_v_ok } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -fwhole-program" } */ + +unsigned a; +short c; +char d; +unsigned long e; +_Bool f[10][10]; +unsigned g[10]; +long long ak; +char i = 7; +long long t[10]; +short x[10][10][10][10]; +short y[10][10][10][10]; + +void +h (char i, long long t[], short x[][10][10][10], short y[][10][10][10], + _Bool aa) +{ + for (int j = 2; j < 8; j += 2) + { + for (short k = 0; k < 10; k++) + { + for (int l = 3; l < 8; l += 2) + a = x[1][j][k][l]; + c = x[c][1][1][c]; + } + for (int k = 0; k < 10; k++) + { + f[2][k] |= (_Bool) t[c]; + g[c] = t[c + 1]; + d += y[j][1][k][k]; + e = e > i ? e : i; + } + } +} + +int +main () +{ + t[c] = 1; + h (i, t, x, y, a); + for (int j = 0; j < 10; ++j) + for (int k = 0; k < 10; ++k) + ak ^= f[j][k] + 238516665 + (ak >> 2); + ak ^= g[c] + 238516665 + (ak >> 2); + if (ak != 234635118ull) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-21.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-21.c index 3a64b3b226de..e0bd0fe71ae1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-21.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-21.c @@ -29,4 +29,4 @@ void f (int8_t * restrict in, int8_t * restrict out, int n, int m, int cond) } /* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e32,\s*mf2,\s*tu,\s*mu} 1 { target { no-opts "-O0" no-opts "-g" no-opts "-funroll-loops" } } } } */ -/* { dg-final { scan-assembler-times {vsetvli} 3 { target { no-opts "-O0" no-opts "-Os" no-opts "-O1" no-opts "-g" no-opts "-funroll-loops" } } } } */ +/* { dg-final { scan-assembler-times {vsetvli} 3 { target { no-opts "-O0" no-opts "-Os" no-opts "-O1" no-opts "-g" no-opts "-funroll-loops" no-opts "-Oz" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-26.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-26.c index cd9a5c8a93ef..0ff7f3b3c90f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-26.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-26.c @@ -32,4 +32,4 @@ void f (int8_t * restrict in, int8_t * restrict out, int n, int m, int cond) } /* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e32,\s*mf2,\s*tu,\s*mu} 1 { target { no-opts "-O0" no-opts "-g" no-opts "-funroll-loops" } } } } */ -/* { dg-final { scan-assembler-times {vsetvli} 3 { target { no-opts "-O0" no-opts "-O1" no-opts "-Os" no-opts "-g" no-opts "-funroll-loops" } } } } */ +/* { dg-final { scan-assembler-times {vsetvli} 3 { target { no-opts "-O0" no-opts "-O1" no-opts "-Os" no-opts "-g" no-opts "-funroll-loops" no-opts "-Oz" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-36.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-36.c index 35cad2df2d26..bd1585c5d06f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-36.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-36.c @@ -22,4 +22,4 @@ void f (int8_t * restrict in, int8_t * restrict out, int n, int cond) } /* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*tu,\s*m[au]} 1 { target { no-opts "-O0" no-opts "-g" no-opts "-funroll-loops" } } } } */ -/* { dg-final { scan-assembler-times {vsetvli} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-g" no-opts "-funroll-loops" } } } } */ +/* { dg-final { scan-assembler-times {vsetvli} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-g" no-opts "-funroll-loops" no-opts "-Oz" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-37.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-37.c index cd3e961cefe1..9bade063f17e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-37.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-37.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-schedule-insns -fno-schedule-insns2 -fno-tree-vectorize" } */ +/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-schedule-insns -fno-schedule-insns2 -fno-tree-vectorize -mtune=rocket" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-39.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-39.c index fa5f3c610177..55740ba9610e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-39.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-39.c @@ -16,4 +16,4 @@ void f (int8_t *base, int8_t *out, size_t m, size_t n) { } /* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*tu,\s*m[au]} 1 { target { no-opts "-O0" no-opts "-O1" no-opts "-g" no-opts "-funroll-loops" } } } } */ -/* { dg-final { scan-assembler-times {vsetvli} 2 { target { no-opts "-O0" no-opts "-Os" no-opts "-O1" no-opts "-g" no-opts "-funroll-loops" } } } } */ +/* { dg-final { scan-assembler-times {vsetvli} 2 { target { no-opts "-O0" no-opts "-Os" no-opts "-O1" no-opts "-g" no-opts "-funroll-loops" no-opts "-Oz" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-41.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-41.c index 99c1722875e1..91102acdc67a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-41.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-41.c @@ -16,4 +16,4 @@ void f (int8_t *base, int8_t *out, size_t m, size_t n) { } /* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*tu,\s*m[au]} 1 { target { no-opts "-O0" no-opts "-O1" no-opts "-Os" no-opts "-Oz" no-opts "-g" no-opts "-funroll-loops" } } } } */ -/* { dg-final { scan-assembler-times {vsetvli} 2 { target { no-opts "-O0" no-opts "-Os" no-opts "-O1" no-opts "-g" no-opts "-funroll-loops" } } } } */ +/* { dg-final { scan-assembler-times {vsetvli} 2 { target { no-opts "-O0" no-opts "-Os" no-opts "-O1" no-opts "-g" no-opts "-funroll-loops" no-opts "-Oz" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr117974.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr117974.c new file mode 100644 index 000000000000..bf99240d15f9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr117974.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -mrvv-vector-bits=zvl -Ofast" } */ + +float g(float q[], int N){ + float dqnorm = 0.0; + + #pragma GCC unroll 4 + + for (int i=0; i < N; i++) { + dqnorm = dqnorm + q[i] * q[i]; + } + return dqnorm; +} + +/* need slightly different test for when -funroll-loops is enabled to keep + test output stable. Otherwise test may be flakey. */ +/* { dg-final { scan-assembler-times {beq\s+[a-x0-9]+,zero,.L12\s+vsetvli} 3 { target { no-opts "-funroll-loops" } } } } */ +/* { dg-final { scan-assembler-times {beq\s+[a-x0-9]+,[a-x0-9]+,.L12\s+vsetvli} 3 { target { any-opts "-funroll-loops" } } } } */ + diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-17.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-17.c index d7f6d18d1d61..321eb3b9f298 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-17.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-17.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize" } */ +/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize -mtune=rocket" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-18.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-18.c index 1354c5e46d02..29dcfefbd0cf 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-18.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-18.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize" } */ +/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize -mtune=rocket" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-19.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-19.c index 6366dd9db44f..8b6299e99d1f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-19.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-19.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize" } */ +/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize -mtune=rocket" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-20.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-20.c index bbff028dad16..3b836f927d20 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-20.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-20.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize" } */ +/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize -mtune=rocket" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl-22.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl-22.c index be143658bad2..47eb43ea8b7d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl-22.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl-22.c @@ -18,4 +18,4 @@ void f(int8_t *base, int8_t *out, size_t vl, size_t m, size_t k) { /* { dg-final { scan-assembler-times {slli\s+[a-x0-9]+,\s*[a-x0-9]+,\s*4} 1 { target { no-opts "-O0" no-opts "-g" no-opts "-funroll-loops" } } } } */ /* { dg-final { scan-assembler-times {vsetvli} 2 { target { no-opts "-O0" no-opts "-Os" no-opts "-Oz" no-opts "-g" no-opts "-funroll-loops" } } } } */ -/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*t[au],\s*m[au]} 2 { target { no-opts "-O0" no-opts "-Os" no-opts "-g" no-opts "-funroll-loops" } } } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*t[au],\s*m[au]} 2 { target { no-opts "-O0" no-opts "-Os" no-opts "-Oz" no-opts "-g" no-opts "-funroll-loops" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvlmax-15.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvlmax-15.c index 23042460885a..45c8a4d0e329 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvlmax-15.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvlmax-15.c @@ -18,6 +18,6 @@ void foo(int32_t *in1, int32_t *in2, int32_t *in3, int32_t *out, size_t n, int c } } -/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e32,\s*m1,\s*t[au],\s*m[au]} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-g" no-opts "-funroll-loops" } } } } */ -/* { dg-final { scan-assembler-times {vsetvli} 3 { target { no-opts "-O0" no-opts "-Os" no-opts "-g" no-opts "-funroll-loops" } } } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e32,\s*m1,\s*t[au],\s*m[au]} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-Oz" no-opts "-g" no-opts "-funroll-loops" } } } } */ +/* { dg-final { scan-assembler-times {vsetvli} 3 { target { no-opts "-O0" no-opts "-Os" no-opts "-Oz" no-opts "-g" no-opts "-funroll-loops" } } } } */ /* { dg-final { scan-assembler-times {slli\s+[a-x0-9]+,\s*[a-x0-9]+,\s*5} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-g" no-opts "-funroll-loops" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvlmax-2.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvlmax-2.c index 3df00d627d6d..9bef7dd4ddfa 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvlmax-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvlmax-2.c @@ -17,5 +17,5 @@ void foo(int32_t *in1, int32_t *in2, int32_t *in3, int32_t *out, size_t n) { } } -/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e32,\s*m1,\s*tu,\s*m[au]} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-g" no-opts "-funroll-loops" } } } } */ -/* { dg-final { scan-assembler-times {vsetvli} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-g" no-opts "-funroll-loops" } } } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e32,\s*m1,\s*tu,\s*m[au]} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-Oz" no-opts "-g" no-opts "-funroll-loops" } } } } */ +/* { dg-final { scan-assembler-times {vsetvli} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-Oz" no-opts "-g" no-opts "-funroll-loops" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvlmax-4.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvlmax-4.c index 3228a7540576..28c3dd005cce 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvlmax-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvlmax-4.c @@ -17,5 +17,5 @@ void foo(int32_t *in1, int32_t *in2, int32_t *in3, int32_t *out, size_t n) { } } -/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e32,\s*m1,\s*tu,\s*m[au]} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-g" no-opts "-funroll-loops" } } } } */ -/* { dg-final { scan-assembler-times {vsetvli} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-g" no-opts "-funroll-loops" } } } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e32,\s*m1,\s*tu,\s*m[au]} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-Oz" no-opts "-g" no-opts "-funroll-loops" } } } } */ +/* { dg-final { scan-assembler-times {vsetvli} 1 { target { no-opts "-O0" no-opts "-Os" no-opts "-Oz" no-opts "-g" no-opts "-funroll-loops" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vtype-call-clobbered.c b/gcc/testsuite/gcc.target/riscv/rvv/vtype-call-clobbered.c index be9f312aa508..78c8a4af8166 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vtype-call-clobbered.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vtype-call-clobbered.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gcv -mabi=lp64 -O2" } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O2" } */ /* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr120461.c b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr120461.c new file mode 100644 index 000000000000..69391570970f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr120461.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=xt-c920 -mrvv-vector-bits=zvl -fzero-call-used-regs=all" */ + +void +foo () +{} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr120642.c b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr120642.c new file mode 100644 index 000000000000..1a72580ad605 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr120642.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=xt-c920 -mrvv-vector-bits=zvl" } */ +int __attribute__((__vector_size__(4 * sizeof(int)))) v; +void foo() { v /= 3; } diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_arith.h b/gcc/testsuite/gcc.target/riscv/sat/sat_arith.h index 6e97cae96e6e..e40902a1bca5 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_arith.h +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_arith.h @@ -4,6 +4,10 @@ #include #include +#if __riscv_xlen == 64 +typedef unsigned __int128 uint128_t; +#endif + /******************************************************************************/ /* Saturation Add (unsigned and signed) */ /******************************************************************************/ @@ -69,6 +73,22 @@ sat_u_add_##WT##_##T##_fmt_7(T x, T y) \ } #define DEF_SAT_U_ADD_FMT_7_WRAP(WT, T) DEF_SAT_U_ADD_FMT_7(WT, T) +#define DEF_SAT_U_ADD_FMT_8(T) \ +T __attribute__((noinline)) \ +sat_u_add_##T##_fmt_8(T x, T y) \ +{ \ + return x <= (T)(x + y) ? (x + y) : -1; \ +} +#define DEF_SAT_U_ADD_FMT_8_WRAP(T) DEF_SAT_U_ADD_FMT_8(T) + +#define DEF_SAT_U_ADD_FMT_9(T) \ +T __attribute__((noinline)) \ +sat_u_add_##T##_fmt_9(T x, T y) \ +{ \ + return x > (T)(x + y) ? -1 : (x + y); \ +} +#define DEF_SAT_U_ADD_FMT_9_WRAP(T) DEF_SAT_U_ADD_FMT_9(T) + #define RUN_SAT_U_ADD_FMT_1(T, x, y) sat_u_add_##T##_fmt_1(x, y) #define RUN_SAT_U_ADD_FMT_1_WRAP(T, x, y) RUN_SAT_U_ADD_FMT_1(T, x, y) #define RUN_SAT_U_ADD_FMT_2(T, x, y) sat_u_add_##T##_fmt_2(x, y) @@ -93,6 +113,10 @@ sat_u_add_##WT##_##T##_fmt_7(T x, T y) \ sat_u_add_uint64_t_##T##_fmt_7(x, y) #define RUN_SAT_U_ADD_FMT_7_FROM_U64_WRAP(T, x, y) \ RUN_SAT_U_ADD_FMT_7_FROM_U64(T, x, y) +#define RUN_SAT_U_ADD_FMT_8(T, x, y) sat_u_add_##T##_fmt_8(x, y) +#define RUN_SAT_U_ADD_FMT_8_WRAP(T, x, y) RUN_SAT_U_ADD_FMT_8(T, x, y) +#define RUN_SAT_U_ADD_FMT_9(T, x, y) sat_u_add_##T##_fmt_9(x, y) +#define RUN_SAT_U_ADD_FMT_9_WRAP(T, x, y) RUN_SAT_U_ADD_FMT_9(T, x, y) #define DEF_SAT_U_ADD_IMM_FMT_1(T, IMM) \ T __attribute__((noinline)) \ @@ -227,6 +251,18 @@ sat_s_add_imm_##T##_fmt_1##_##INDEX (T x) \ #define RUN_SAT_S_ADD_IMM_FMT_1(INDEX, T, x, expect) \ if (sat_s_add_imm##_##T##_fmt_1##_##INDEX(x) != expect) __builtin_abort () +#define DEF_SAT_S_ADD_IMM_FMT_2(INDEX, T, UT, IMM, MIN, MAX) \ +T __attribute__((noinline)) \ +sat_s_add_imm_##T##_fmt_2##_##INDEX (T x) \ +{ \ + T sum = (T)((UT)x + (UT)IMM); \ + return ((x ^ sum) < 0 && (x ^ IMM) >= 0) ? \ + (-(T)(x < 0) ^ MAX) : sum; \ +} + +#define RUN_SAT_S_ADD_IMM_FMT_2(INDEX, T, x, expect) \ + if (sat_s_add_imm##_##T##_fmt_2##_##INDEX(x) != expect) __builtin_abort () + /******************************************************************************/ /* Saturation Sub (Unsigned and Signed) */ /******************************************************************************/ @@ -636,4 +672,25 @@ sat_s_trunc_##WT##_to_##NT##_fmt_8 (WT x) \ #define RUN_SAT_S_TRUNC_FMT_8(NT, WT, x) sat_s_trunc_##WT##_to_##NT##_fmt_8 (x) #define RUN_SAT_S_TRUNC_FMT_8_WRAP(NT, WT, x) RUN_SAT_S_TRUNC_FMT_8(NT, WT, x) +/******************************************************************************/ +/* Saturation Mult (unsigned and signed) */ +/******************************************************************************/ + +#define DEF_SAT_U_MUL_FMT_1(NT, WT) \ +NT __attribute__((noinline)) \ +sat_u_mul_##NT##_from_##WT##_fmt_1 (NT a, NT b) \ +{ \ + WT x = (WT)a * (WT)b; \ + NT max = -1; \ + if (x > (WT)(max)) \ + return max; \ + else \ + return (NT)x; \ +} + +#define DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) DEF_SAT_U_MUL_FMT_1(NT, WT) +#define RUN_SAT_U_MUL_FMT_1(NT, WT, a, b) \ + sat_u_mul_##NT##_from_##WT##_fmt_1 (a, b) +#define RUN_SAT_U_MUL_FMT_1_WRAP(NT, WT, a, b) RUN_SAT_U_MUL_FMT_1(NT, WT, a, b) + #endif diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_arith_data.h b/gcc/testsuite/gcc.target/riscv/sat/sat_arith_data.h index f1006889d212..bd33ff1769a4 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_arith_data.h +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_arith_data.h @@ -12,6 +12,7 @@ #define TEST_BINARY_STRUCT_NAME(T, NAME) test_##T##_##NAME##_s #define TEST_BINARY_STRUCT_DECL(T, NAME) struct TEST_BINARY_STRUCT_NAME(T, NAME) +#define TEST_BINARY_STRUCT_DECL_WRAP(T, NAME) TEST_BINARY_STRUCT_DECL(T, NAME) #define TEST_BINARY_STRUCT(T, NAME) \ struct TEST_BINARY_STRUCT_NAME(T, NAME) \ { \ @@ -37,6 +38,11 @@ TEST_BINARY_STRUCT (uint16_t, usadd) TEST_BINARY_STRUCT (uint32_t, usadd) TEST_BINARY_STRUCT (uint64_t, usadd) +TEST_BINARY_STRUCT (uint8_t, usmul) +TEST_BINARY_STRUCT (uint16_t, usmul) +TEST_BINARY_STRUCT (uint32_t, usmul) +TEST_BINARY_STRUCT (uint64_t, usmul) + TEST_BINARY_STRUCT (int8_t, ssadd) TEST_BINARY_STRUCT (int16_t, ssadd) TEST_BINARY_STRUCT (int32_t, ssadd) @@ -433,4 +439,60 @@ TEST_BINARY_STRUCT_DECL(int64_t, sssub) TEST_BINARY_DATA(int64_t, sssub)[] = { 9223372036854775806ll, 9223372036854775800ll, 6}, }; +TEST_BINARY_STRUCT_DECL(uint8_t, usmul) TEST_BINARY_DATA(uint8_t, usmul)[] = +{ + { 0, 0, 0, }, + { 0, 1, 0, }, + { 1, 1, 1, }, + { 1, 127, 127, }, + { 2, 127, 254, }, + { 3, 127, 255, }, + { 127, 127, 255, }, + { 1, 255, 255, }, + { 127, 255, 255, }, + { 255, 255, 255, }, +}; + +TEST_BINARY_STRUCT_DECL(uint16_t, usmul) TEST_BINARY_DATA(uint16_t, usmul)[] = +{ + { 0, 0, 0, }, + { 0, 1, 0, }, + { 1, 1, 1, }, + { 1, 32767, 32767, }, + { 2, 32767, 65534, }, + { 3, 32767, 65535, }, + { 32767, 32767, 65535, }, + { 1, 65535, 65535, }, + { 32767, 65535, 65535, }, + { 65535, 65535, 65535, }, +}; + +TEST_BINARY_STRUCT_DECL(uint32_t, usmul) TEST_BINARY_DATA(uint32_t, usmul)[] = +{ + { 0, 0, 0, }, + { 0, 1, 0, }, + { 1, 1, 1, }, + { 1, 2147483647, 2147483647, }, + { 2, 2147483647, 4294967294, }, + { 3, 2147483647, 4294967295, }, + { 2147483647, 2147483647, 4294967295, }, + { 1, 4294967295, 4294967295, }, + { 2147483647, 4294967295, 4294967295, }, + { 4294967295, 4294967295, 4294967295, }, +}; + +TEST_BINARY_STRUCT_DECL(uint64_t, usmul) TEST_BINARY_DATA(uint64_t, usmul)[] = +{ + { 0, 0, 0, }, + { 0, 1, 0, }, + { 1, 1, 1, }, + { 1, 9223372036854775807ull, 9223372036854775807ull, }, + { 2, 9223372036854775807ull, 18446744073709551614ull, }, + { 3, 9223372036854775807ull, 18446744073709551615ull, }, + { 9223372036854775807ull, 9223372036854775807ull, 18446744073709551615ull, }, + { 1, 18446744073709551615ull, 18446744073709551615ull, }, + { 9223372036854775807ull, 18446744073709551615ull, 18446744073709551615ull, }, + { 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, }, +}; + #endif diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i16.c index 55890d8487ce..50f0f1f06310 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i16.c @@ -1,32 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int16_t_fmt_1: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_ADD_FMT_1(int16_t, uint16_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i32.c index 29e843f3c7be..dc6581736357 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i32.c @@ -1,31 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int32_t_fmt_1: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_S_ADD_FMT_1(int32_t, uint32_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i64.c index 7f29d21d1037..9995bc7b9cf1 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i64.c @@ -1,29 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int64_t_fmt_1: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-1 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_S_ADD_FMT_1(int64_t, uint64_t, INT64_MIN, INT64_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i8.c index 3ad7bdd9164e..caf745a6f9ef 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-1-i8.c @@ -1,30 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int8_t_fmt_1: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_ADD_FMT_1(int8_t, uint8_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i16.c index 07d31015c132..f19187dce498 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i16.c @@ -1,32 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int16_t_fmt_2: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_ADD_FMT_2(int16_t, uint16_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i32.c index 81b85b4ab6ef..88dc37d42f74 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i32.c @@ -1,31 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int32_t_fmt_2: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_S_ADD_FMT_2(int32_t, uint32_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i64.c index 9a3d83e8edc8..891d6cfaace6 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i64.c @@ -1,29 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int64_t_fmt_2: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-1 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_S_ADD_FMT_2(int64_t, uint64_t, INT64_MIN, INT64_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i8.c index ecc9a0f733c4..a07172bea801 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-2-i8.c @@ -1,30 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int8_t_fmt_2: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_ADD_FMT_2(int8_t, uint8_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i16.c index 7e933856e717..507719887250 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i16.c @@ -1,32 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int16_t_fmt_3: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_ADD_FMT_3(int16_t, uint16_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i32.c index 09bf497cc10a..07af4e1a75b8 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i32.c @@ -1,31 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int32_t_fmt_3: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_S_ADD_FMT_3(int32_t, uint32_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i64.c index 5652cdb9aea7..7c4be5b19265 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i64.c @@ -1,29 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int64_t_fmt_3: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-1 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_S_ADD_FMT_3(int64_t, uint64_t, INT64_MIN, INT64_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i8.c index 0eb0c8496496..fc0e1b7bc381 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-3-i8.c @@ -1,30 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int8_t_fmt_3: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_ADD_FMT_3(int8_t, uint8_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i16.c index 9dfdb9eba9af..4c0b38a87c39 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i16.c @@ -1,32 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int16_t_fmt_4: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_ADD_FMT_4(int16_t, uint16_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i32.c index 74df576b5319..45b4638d8dd2 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i32.c @@ -1,31 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int32_t_fmt_4: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_S_ADD_FMT_4(int32_t, uint32_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i64.c index 5937699766f3..294eb52b290e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i64.c @@ -1,29 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int64_t_fmt_4: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-1 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_S_ADD_FMT_4(int64_t, uint64_t, INT64_MIN, INT64_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i8.c index af850d0d1558..143fa3ccd4c1 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-4-i8.c @@ -1,30 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_int8_t_fmt_4: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_ADD_FMT_4(int8_t, uint8_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i16.c index 34459b85e2b2..102393463a38 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i32.c index 4d4841f40661..bccb7683fbaa 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i64.c index df818879628f..34de52042a04 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i8.c index 9a4ce338d0ce..6d136ec705bc 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-1-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i16.c index cdac5bdb883e..ee8e439b9448 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i32.c index 4ac952e27fa4..8996dd2b87af 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i64.c index 4d25e7f171d5..155c8e94b662 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i8.c index d57e0a0d1959..4502ed35a4ec 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-2-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i16.c index 08b961a66891..21289c9c9405 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i32.c index 3611b6e2788b..3d4a6fa1a5f4 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i64.c index 3eaa6c2d7ca7..b55d22171c01 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i8.c index 6d38e5f10929..9fef8b03552e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-3-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i16.c index 2e7345022737..fd135e5aa4b5 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i32.c index ec3022dab8ef..38ade404ab16 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i64.c index 911856ed60bb..04ba746eae0e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i8.c index 94d48ef24f66..32aea5c97b63 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add-run-4-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i16.c index 2e23af5d86b7..414cb6188c36 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i16.c @@ -1,57 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_imm_int16_t_fmt_1_0: -** addi\s+[atx][0-9]+,\s*a0,\s*-7 -** xori\s+[atx][0-9]+,\s*a0,\s*-7 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+a0,\s*a0,\s*63 -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** neg\s+a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*a0,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_ADD_IMM_FMT_1(0, int16_t, uint16_t, -7, INT16_MIN, INT16_MAX) - -/* -** sat_s_add_imm_int16_t_fmt_1_1: -** addi\s+[atx][0-9]+,\s*a0,\s*-1 -** not\s+[atx][0-9]+,\s*a0 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+a0,\s*a0,\s*63 -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** neg\s+a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*a0,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_ADD_IMM_FMT_1(1, int16_t, uint16_t, -1, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 2 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i32.c index e63211ffc1d3..adf5b39ad326 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i32.c @@ -1,54 +1,11 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_imm_int32_t_fmt_1_0: -** addi\s+[atx][0-9]+,\s*a0,\s*10 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** srli\s+[atx][0-9]+,\s*a0,\s*31 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+a0,\s*a0,\s*63 -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** neg\s+a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,a0,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_S_ADD_IMM_FMT_1(0, int32_t, uint32_t, 10, INT32_MIN, INT32_MAX) -/* -** sat_s_add_imm_int32_t_fmt_1_1: -** addi\s+[atx][0-9]+,\s*a0,\s*-1 -** not\s+[atx][0-9]+,\s*a0 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+a0,\s*a0,\s*63 -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** neg\s+a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*a0,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_S_ADD_IMM_FMT_1(1, int32_t, uint32_t, -1, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 2 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i64.c index 3843b711da85..b88e064a4262 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i64.c @@ -1,48 +1,11 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_imm_int64_t_fmt_1_0: -** addi\s+[atx][0-9]+,\s*a0,\s*10 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** srli\s+[atx][0-9]+,\s*a0,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*a0,\s*63 -** li\s+[atx][0-9]+,\s*-1 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*a0,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_S_ADD_IMM_FMT_1(0, int64_t, uint64_t, 10, INT64_MIN, INT64_MAX) -/* -** sat_s_add_imm_int64_t_fmt_1_1: -** addi\s+[atx][0-9]+,\s*a0,\s*-1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** slti\s+[atx][0-9]+,\s*a0,\s*0 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*a0,\s*63 -** li\s+[atx][0-9]+,\s*-1 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*a0,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_S_ADD_IMM_FMT_1(1, int64_t, uint64_t, -1, INT64_MIN, INT64_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 2 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i8.c index ceae1ea2f364..0e337efd1fa1 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i8.c @@ -1,49 +1,11 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_add_imm_int8_t_fmt_1_0: -** addi\s+[atx][0-9]+,\s*a0,\s*9 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 -** srli\s+[atx][0-9]+,\s*a0,\s*7 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+a0,\s*a0,\s*63 -** xori\s+[atx][0-9]+,\s*a0,\s*127 -** neg\s+a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*a0,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_ADD_IMM_FMT_1(0, int8_t, uint8_t, 9, INT8_MIN, INT8_MAX) -/* -** sat_s_add_imm_int8_t_fmt_1_1: -** addi\s+[atx][0-9]+,\s*a0,\s*-1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*56 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** srai\s+a0,\s*a0,\s*63 -** xori\s+[atx][0-9]+,\s*a0,\s*127 -** neg\s+a0,\s*a5 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*a0,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_ADD_IMM_FMT_1(1, int8_t, uint8_t, -1, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 2 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2-i16.c new file mode 100644 index 000000000000..f217fe1863de --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2-i16.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_S_ADD_IMM_FMT_2(0, int16_t, uint16_t, -7, INT16_MIN, INT16_MAX) + +DEF_SAT_S_ADD_IMM_FMT_2(1, int16_t, uint16_t, -1, INT16_MIN, INT16_MAX) + +/* { dg-final { scan-tree-dump-times ".SAT_ADD " 2 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2-i32.c new file mode 100644 index 000000000000..4025b5ae5349 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2-i32.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_S_ADD_IMM_FMT_2(0, int32_t, uint32_t, 10, INT32_MIN, INT32_MAX) + +DEF_SAT_S_ADD_IMM_FMT_2(1, int32_t, uint32_t, -1, INT32_MIN, INT32_MAX) + +/* { dg-final { scan-tree-dump-times ".SAT_ADD " 2 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2-i64.c new file mode 100644 index 000000000000..3fc2514e6ab7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2-i64.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_S_ADD_IMM_FMT_2(0, int64_t, uint64_t, 10, INT64_MIN, INT64_MAX) + +DEF_SAT_S_ADD_IMM_FMT_2(1, int64_t, uint64_t, -1, INT64_MIN, INT64_MAX) + +/* { dg-final { scan-tree-dump-times ".SAT_ADD " 2 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2-i8.c new file mode 100644 index 000000000000..a0e15cfbe4c8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2-i8.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_S_ADD_IMM_FMT_2(0, int8_t, uint8_t, 9, INT8_MIN, INT8_MAX) + +DEF_SAT_S_ADD_IMM_FMT_2(1, int8_t, uint8_t, -1, INT8_MIN, INT8_MAX) + +/* { dg-final { scan-tree-dump-times ".SAT_ADD " 2 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-run-2-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-run-2-i16.c new file mode 100644 index 000000000000..4f24624eb196 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-run-2-i16.c @@ -0,0 +1,48 @@ +/* { dg-do run } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" + +DEF_SAT_S_ADD_IMM_FMT_2(0, int16_t, uint16_t, -32768, INT16_MIN, INT16_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(1, int16_t, uint16_t, 32767, INT16_MIN, INT16_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(2, int16_t, uint16_t, 100, INT16_MIN, INT16_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(3, int16_t, uint16_t, -100, INT16_MIN, INT16_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(4, int16_t, uint16_t, -1, INT16_MIN, INT16_MAX) + +#define T int16_t +#define RUN(INDEX,T, x, expect) RUN_SAT_S_ADD_IMM_FMT_2(INDEX, T, x, expect) + +T d[][2] = { + /* arg_0, expect */ + { -1, -32768, }, + { 2, -32766, }, + { 1, 32767, }, + { -10, 32757, }, + { 32669, 32767, }, + { -32768, -32668, }, + { -32768, -32768, }, + { 0, -100, }, + { -32768, -32768, }, + { 0, -1, }, +}; + +int +main () +{ + RUN (0, T, d[0][0], d[0][1]); + RUN (0, T, d[1][0], d[1][1]); + + RUN (1, T, d[2][0], d[2][1]); + RUN (1, T, d[3][0], d[3][1]); + + RUN (2, T, d[4][0], d[4][1]); + RUN (2, T, d[5][0], d[5][1]); + + RUN (3, T, d[6][0], d[6][1]); + RUN (3, T, d[7][0], d[7][1]); + + RUN (4, T, d[8][0], d[8][1]); + RUN (4, T, d[9][0], d[9][1]); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-run-2-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-run-2-i32.c new file mode 100644 index 000000000000..8d9ddebfa906 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-run-2-i32.c @@ -0,0 +1,48 @@ +/* { dg-do run } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" + +DEF_SAT_S_ADD_IMM_FMT_2(0, int32_t, uint32_t, -2147483648, INT32_MIN, INT32_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(1, int32_t, uint32_t, 2147483647, INT32_MIN, INT32_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(2, int32_t, uint32_t, 100, INT32_MIN, INT32_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(3, int32_t, uint32_t, -100, INT32_MIN, INT32_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(4, int32_t, uint32_t, -1, INT32_MIN, INT32_MAX) + +#define T int32_t +#define RUN(INDEX,T, x, expect) RUN_SAT_S_ADD_IMM_FMT_2(INDEX, T, x, expect) + +T d[][2] = { + /* arg_0, expect */ + { -1, -2147483648, }, + { 2, -2147483646, }, + { 1, 2147483647, }, + { -10, 2147483637, }, + { 300, 400, }, + { -300, -200, }, + { 100, 0, }, + { 0, -100, }, + { 100, 99, }, + { 0, -1, }, +}; + +int +main () +{ + RUN (0, T, d[0][0], d[0][1]); + RUN (0, T, d[1][0], d[1][1]); + + RUN (1, T, d[2][0], d[2][1]); + RUN (1, T, d[3][0], d[3][1]); + + RUN (2, T, d[4][0], d[4][1]); + RUN (2, T, d[5][0], d[5][1]); + + RUN (3, T, d[6][0], d[6][1]); + RUN (3, T, d[7][0], d[7][1]); + + RUN (4, T, d[8][0], d[8][1]); + RUN (4, T, d[9][0], d[9][1]); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-run-2-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-run-2-i64.c new file mode 100644 index 000000000000..4523f9a86432 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-run-2-i64.c @@ -0,0 +1,48 @@ +/* { dg-do run } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" + +DEF_SAT_S_ADD_IMM_FMT_2(0, int64_t, uint64_t, (-9223372036854775807ll - 1), INT64_MIN, INT64_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(1, int64_t, uint64_t, 9223372036854775807ll, INT64_MIN, INT64_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(2, int64_t, uint64_t, 100, INT64_MIN, INT64_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(3, int64_t, uint64_t, -100, INT64_MIN, INT64_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(4, int64_t, uint64_t, -1, INT64_MIN, INT64_MAX) + +#define T int64_t +#define RUN(INDEX,T, x, expect) RUN_SAT_S_ADD_IMM_FMT_2(INDEX, T, x, expect) + +T d[][2] = { + /* arg_0, expect */ + { -1, (-9223372036854775807ll - 1), }, + { 2, -9223372036854775806ll, }, + { 1, 9223372036854775807ll, }, + { -7, 9223372036854775800ll, }, + { 0, 100, }, + { -1, 99, }, + { 0, -100, }, + { 100, 0, }, + { 0, -1, }, + { 100, 99, }, +}; + +int +main () +{ + RUN (0, T, d[0][0], d[0][1]); + RUN (0, T, d[1][0], d[1][1]); + + RUN (1, T, d[2][0], d[2][1]); + RUN (1, T, d[3][0], d[3][1]); + + RUN (2, T, d[4][0], d[4][1]); + RUN (2, T, d[5][0], d[5][1]); + + RUN (3, T, d[6][0], d[6][1]); + RUN (3, T, d[7][0], d[7][1]); + + RUN (4, T, d[8][0], d[8][1]); + RUN (4, T, d[9][0], d[9][1]); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-run-2-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-run-2-i8.c new file mode 100644 index 000000000000..96445aee3eb7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-run-2-i8.c @@ -0,0 +1,49 @@ +/* { dg-do run } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" + +DEF_SAT_S_ADD_IMM_FMT_2(0, int8_t, uint8_t, -128, INT8_MIN, INT8_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(1, int8_t, uint8_t, 127, INT8_MIN, INT8_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(2, int8_t, uint8_t, 6, INT8_MIN, INT8_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(3, int8_t, uint8_t, -6, INT8_MIN, INT8_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(4, int8_t, uint8_t, -1, INT8_MIN, INT8_MAX) + +#define T int8_t +#define RUN(INDEX,T, x, expect) RUN_SAT_S_ADD_IMM_FMT_2(INDEX, T, x, expect) + +T d[][2] = { + /* arg_0, expect */ + { -1, -128, }, + { 2, -126, }, + { 1, 127, }, + { -10, 117, }, + { 122, 127, }, + { -10, -4, }, + { -128, -128, }, + { 127, 121, }, + { -128, -128, }, + { 1, 0, }, +}; + +int +main () +{ + RUN (0, T, d[0][0], d[0][1]); + RUN (0, T, d[1][0], d[1][1]); + + RUN (1, T, d[2][0], d[2][1]); + RUN (1, T, d[3][0], d[3][1]); + + RUN (2, T, d[4][0], d[4][1]); + RUN (2, T, d[5][0], d[5][1]); + + RUN (3, T, d[6][0], d[6][1]); + RUN (3, T, d[7][0], d[7][1]); + + RUN (4, T, d[8][0], d[8][1]); + RUN (4, T, d[9][0], d[9][1]); + + return 0; +} + diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm_type_check-2-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm_type_check-2-i16.c new file mode 100644 index 000000000000..a73a77fafd74 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm_type_check-2-i16.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_S_ADD_IMM_FMT_2(0, int16_t, uint16_t, -32769, INT16_MIN, INT16_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(1, int16_t, uint16_t, 32768, INT16_MIN, INT16_MAX) + +/* { dg-final { scan-tree-dump-not ".SAT_ADD " "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm_type_check-2-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm_type_check-2-i32.c new file mode 100644 index 000000000000..9dae4254d317 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm_type_check-2-i32.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_S_ADD_IMM_FMT_1(0, int32_t, uint32_t, -2147483649, INT32_MIN, INT32_MAX) +DEF_SAT_S_ADD_IMM_FMT_1(1, int32_t, uint32_t, 2147483648, INT32_MIN, INT32_MAX) + +/* { dg-final { scan-tree-dump-not ".SAT_ADD " "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm_type_check-2-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm_type_check-2-i8.c new file mode 100644 index 000000000000..a9cd4b9cd20b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm_type_check-2-i8.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_S_ADD_IMM_FMT_2(0, int8_t, uint8_t, -129, INT8_MIN, INT8_MAX) +DEF_SAT_S_ADD_IMM_FMT_2(1, int8_t, uint8_t, 128, INT8_MIN, INT8_MAX) + +/* { dg-final { scan-tree-dump-not ".SAT_ADD " "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i16.c index c244eb40947e..734e8bec0362 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i16.c @@ -1,30 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int16_t_fmt_1: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_SUB_FMT_1(int16_t, uint16_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i32.c index 9d8245d49979..3aa4c583c2c5 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i32.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int32_t_fmt_1: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srliw\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-7] -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_S_SUB_FMT_1(int32_t, uint32_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i64.c index 929de162d574..4c0caa14b96c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i64.c @@ -1,27 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int64_t_fmt_1: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-1 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_S_SUB_FMT_1(int64_t, uint64_t, INT64_MIN, INT64_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i8.c index a918d5ca0f44..6c1441b2e486 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-1-i8.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int8_t_fmt_1: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_SUB_FMT_1(int8_t, uint8_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i16.c index 2da1c0d35010..57a43276bf17 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i16.c @@ -1,30 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int16_t_fmt_2: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_SUB_FMT_2(int16_t, uint16_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i32.c index 20b28e75f2d5..28582fbaa12f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i32.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int32_t_fmt_2: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srliw\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-7] -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_S_SUB_FMT_2(int32_t, uint32_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i64.c index a5401983e7d9..130ca46fc550 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i64.c @@ -1,27 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int64_t_fmt_2: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-1 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_S_SUB_FMT_2(int64_t, uint64_t, INT64_MIN, INT64_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i8.c index c54057d14c96..cd407b2f71a3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-2-i8.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int8_t_fmt_2: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_SUB_FMT_2(int8_t, uint8_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i16.c index 469a11394bd8..748d61a4f209 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i16.c @@ -1,30 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int16_t_fmt_3: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_SUB_FMT_3(int16_t, uint16_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i32.c index b2c03f682a29..be7869ae6330 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i32.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int32_t_fmt_3: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srliw\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-7] -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_S_SUB_FMT_3(int32_t, uint32_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i64.c index e3fe6c78ca6a..d16a7fbc7e86 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i64.c @@ -1,27 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int64_t_fmt_3: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-1 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_S_SUB_FMT_3(int64_t, uint64_t, INT64_MIN, INT64_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i8.c index 150cde1bf66a..14a245442436 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-3-i8.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int8_t_fmt_3: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_SUB_FMT_3(int8_t, uint8_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i16.c index 26d159ca0b51..614d1ec1de12 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i16.c @@ -1,30 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int16_t_fmt_4: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_SUB_FMT_4(int16_t, uint16_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i32.c index d576c38cf328..2f52bd70f291 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i32.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int32_t_fmt_4: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srliw\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-7] -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_S_SUB_FMT_4(int32_t, uint32_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i64.c index f42ffea5f9f6..cef478b2861a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i64.c @@ -1,27 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int64_t_fmt_4: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** li\s+[atx][0-9]+,\s*-1 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_S_SUB_FMT_4(int64_t, uint64_t, INT64_MIN, INT64_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i8.c index ee510a6340b3..3ed7790ea2ff 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-4-i8.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_sub_int8_t_fmt_4: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*a1 -** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_SUB_FMT_4(int8_t, uint8_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i16.c index e248b73f74c3..b2c5735f2f38 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i32.c index bebb4be86832..6d1518eb7b5e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i64.c index f31eb2994aaf..adcd1bb779cb 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i8.c index e165e3954851..31fa0a6008c5 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-1-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i16.c index 08a9b5ca4b08..0c5ad8cddaf0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i32.c index fc799696e5d7..5e8953945dd6 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i64.c index 8d5f745327db..199e204ba362 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i8.c index 9f6ef300677f..4cfe78707d93 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-2-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i16.c index 0523d1307d93..3cf4ecd04c87 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i32.c index e720964bca6b..ce2151cde17b 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i64.c index 49ed0511f97d..158eeaa77f36 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i8.c index 99b413f79c4d..8eb7ab5bf3a9 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-3-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i16.c index c7056ed27e58..339a403294ac 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i32.c index 7168f948cb6d..285733a07ec5 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i64.c index 29b2b54ec26b..546bac10687c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i8.c index 65027b7a3066..dafc86f1b0a2 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_sub-run-4-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i16-to-i8.c index 451a3754c4fc..6d1fbc4fa5a0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i16-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int16_t_to_int8_t_fmt_1: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_1(int8_t, int16_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i32-to-i16.c index 2aafb94cfe87..56a66990676b 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i32-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int16_t_fmt_1: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_1(int16_t, int32_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i32-to-i8.c index 6e21ee3dbe38..10c3320b58c0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i32-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int8_t_fmt_1: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_1(int8_t, int32_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i64-to-i16.c index 5e971e402cb0..558d704331c1 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i64-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int16_t_fmt_1: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_1(int16_t, int64_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i64-to-i32.c index 87e5a52570cc..02bef462f1a4 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i64-to-i32.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int32_t_fmt_1: -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_S_TRUNC_FMT_1(int32_t, int64_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i64-to-i8.c index 22a0dd4ad843..da04904fa6ba 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-1-i64-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int8_t_fmt_1: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_1(int8_t, int64_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i16-to-i8.c index cb307acd9851..41391e2eefa3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i16-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int16_t_to_int8_t_fmt_2: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_2(int8_t, int16_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i32-to-i16.c index b4bee212ddc7..3e5f9e1fb64a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i32-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int16_t_fmt_2: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_2(int16_t, int32_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i32-to-i8.c index c467c8d49d4e..228eeab9cdf2 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i32-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int8_t_fmt_2: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_2(int8_t, int32_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i64-to-i16.c index 883b77b62b88..78542ca0c97e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i64-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int16_t_fmt_2: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_2(int16_t, int64_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i64-to-i32.c index bb9ffcec332e..556e8ea3ea01 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i64-to-i32.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int32_t_fmt_2: -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_S_TRUNC_FMT_2(int32_t, int64_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i64-to-i8.c index a54db487c38d..918a8c3b8bca 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-2-i64-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int8_t_fmt_2: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_2(int8_t, int64_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i16-to-i8.c index 219156c1bafe..13c0291e61bb 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i16-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int16_t_to_int8_t_fmt_3: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_3(int8_t, int16_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i32-to-i16.c index 87b8a70bc299..03077b722748 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i32-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int16_t_fmt_3: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_3(int16_t, int32_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i32-to-i8.c index 7acd515b7120..e09a88d95bce 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i32-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int8_t_fmt_3: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_3(int8_t, int32_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i64-to-i16.c index 9141f08d2f24..ca071d154416 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i64-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int16_t_fmt_3: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_3(int16_t, int64_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i64-to-i32.c index 839a6f764b1c..4acd93ce0640 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i64-to-i32.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int32_t_fmt_3: -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_S_TRUNC_FMT_3(int32_t, int64_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i64-to-i8.c index 5d13f093356c..362970cb95eb 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-3-i64-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int8_t_fmt_3: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_3(int8_t, int64_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i16-to-i8.c index 34dc80413624..94d9cc47783d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i16-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int16_t_to_int8_t_fmt_4: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_4(int8_t, int16_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i32-to-i16.c index 89c476ee2c25..51a6e7b9e083 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i32-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int16_t_fmt_4: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_4(int16_t, int32_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i32-to-i8.c index 03ca7b7aadfc..9101b40fc840 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i32-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int8_t_fmt_4: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_4(int8_t, int32_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i64-to-i16.c index aafe167a964a..48452e3617a8 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i64-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int16_t_fmt_4: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_4(int16_t, int64_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i64-to-i32.c index 08e5eb3201a5..6757913b1409 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i64-to-i32.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int32_t_fmt_4: -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_S_TRUNC_FMT_4(int32_t, int64_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i64-to-i8.c index b0e71fec47ab..9c6558288c6a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-4-i64-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int8_t_fmt_4: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_4(int8_t, int64_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i16-to-i8.c index b42c75923bfd..f02f8665af07 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i16-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int16_t_to_int8_t_fmt_5: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_5(int8_t, int16_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i32-to-i16.c index 625372e22627..6753c03399f0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i32-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int16_t_fmt_5: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_5(int16_t, int32_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i32-to-i8.c index 250e174fea56..3fd17fa817f4 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i32-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int8_t_fmt_5: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_5(int8_t, int32_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i64-to-i16.c index 4a6ac6d2c3e5..fba761a56686 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i64-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int16_t_fmt_5: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_5(int16_t, int64_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i64-to-i32.c index 02aa6dbde017..8872f7fd4173 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i64-to-i32.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int32_t_fmt_5: -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_S_TRUNC_FMT_5(int32_t, int64_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i64-to-i8.c index ae1bcb989105..13539aa5412f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-5-i64-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int8_t_fmt_5: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_5(int8_t, int64_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i16-to-i8.c index 9a740d71c67d..4aa9a8f56dfc 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i16-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int16_t_to_int8_t_fmt_6: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_6(int8_t, int16_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i32-to-i16.c index 1e42bfd749fa..a772ee8d081a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i32-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int16_t_fmt_6: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_6(int16_t, int32_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i32-to-i8.c index c3bd46dc5b4a..9c5d88b46c28 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i32-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int8_t_fmt_6: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_6(int8_t, int32_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i64-to-i16.c index a6575f5e127e..f9f18e982eca 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i64-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int16_t_fmt_6: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_6(int16_t, int64_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i64-to-i32.c index fd7b72e3cb8b..3658fbb32d3d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i64-to-i32.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int32_t_fmt_6: -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_S_TRUNC_FMT_6(int32_t, int64_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i64-to-i8.c index 242d2d028b19..f1a7eb808ac5 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-6-i64-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int8_t_fmt_6: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_6(int8_t, int64_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i16-to-i8.c index 3f258b877f0c..50b06d54a307 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i16-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int16_t_to_int8_t_fmt_7: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_7(int8_t, int16_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i32-to-i16.c index f37a57e4cc24..12be22079c43 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i32-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int16_t_fmt_7: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_7(int16_t, int32_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i32-to-i8.c index 4e4a7eb50edc..cb7353149335 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i32-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int8_t_fmt_7: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_7(int8_t, int32_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i64-to-i16.c index 29b64b460081..d52394c7d35d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i64-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int16_t_fmt_7: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_7(int16_t, int64_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i64-to-i32.c index 2bfe898f6800..cf797788cae9 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i64-to-i32.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int32_t_fmt_7: -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_S_TRUNC_FMT_7(int32_t, int64_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i64-to-i8.c index 494a3147bbb8..67485a37068c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-7-i64-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int8_t_fmt_7: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_7(int8_t, int64_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i16-to-i8.c index 678dec661173..a34bf4ae80f6 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i16-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int16_t_to_int8_t_fmt_8: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_8(int8_t, int16_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i32-to-i16.c index 4acc78994755..9c25ff081a7e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i32-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int16_t_fmt_8: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_8(int16_t, int32_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i32-to-i8.c index 34a992b4f627..9ee75e2aaee6 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i32-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int32_t_to_int8_t_fmt_8: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_8(int8_t, int32_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i64-to-i16.c index 1919ba5431ce..8cd361e1c0a0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i64-to-i16.c @@ -1,28 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int16_t_fmt_8: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** li\s+[atx][0-9]+,\s*-32768 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*16 -** sraiw\s+a0,\s*a0,\s*16 -** ret -*/ DEF_SAT_S_TRUNC_FMT_8(int16_t, int64_t, INT16_MIN, INT16_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i64-to-i32.c index 541e55cd9836..ace064b2f5fd 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i64-to-i32.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int32_t_fmt_8: -** li\s+[atx][0-9]+,\s*-2147483648 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_S_TRUNC_FMT_8(int32_t, int64_t, INT32_MIN, INT32_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i64-to-i8.c index 36a00857145d..e9a4d3bdbdf0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-8-i64-to-i8.c @@ -1,26 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_s_trunc_int64_t_to_int8_t_fmt_8: -** slti\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** li\s+[atx][0-9]+,\s*-128 -** slt\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 -** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slliw\s+a0,\s*a0,\s*24 -** sraiw\s+a0,\s*a0,\s*24 -** ret -*/ DEF_SAT_S_TRUNC_FMT_8(int8_t, int64_t, INT8_MIN, INT8_MAX) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i16-to-i8.c index 1f230c592a8c..7ed6809ba735 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i16-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i32-to-i16.c index 563760beff54..82e420132600 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i32-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i32-to-i8.c index af50d3e9990c..78be831a1c83 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i32-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i64-to-i16.c index 4ac7025fa941..e8a497fb8779 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i64-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i64-to-i32.c index ca6d31cadfce..142054175198 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i64-to-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i64-to-i8.c index 697e1bce4044..31fecc7b3548 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-1-i64-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i16-to-i8.c index 0d9da40581b0..333bb92ead07 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i16-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i32-to-i16.c index 2e183ef0c113..f494909bf5e1 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i32-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i32-to-i8.c index 1950092ef6f0..d8a619b1b7cc 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i32-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i64-to-i16.c index b11b09739a5d..348832d16167 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i64-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i64-to-i32.c index 419e90979b86..fc183cf5e141 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i64-to-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i64-to-i8.c index de3d9f1936c9..dec54d306cf7 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-2-i64-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i16-to-i8.c index 032c83b7afb5..2b8700ac9167 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i16-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i32-to-i16.c index 51f4946a5362..cf3f76363b7d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i32-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i32-to-i8.c index b959bce41014..20a68bbd8275 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i32-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i64-to-i16.c index ddfb522b5005..5159ab1223b9 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i64-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i64-to-i32.c index 22965e2077d8..edeff902ad39 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i64-to-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i64-to-i8.c index 7cba40860543..7a22637df308 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-3-i64-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i16-to-i8.c index 6dfdd4bd633e..65f9aea56049 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i16-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i32-to-i16.c index fcf8e477bab9..ab32e5dc164e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i32-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i32-to-i8.c index 9d911a4515e0..eecfc49d9e18 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i32-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i64-to-i16.c index 3cc2498a1a8d..410d202b2eb7 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i64-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i64-to-i32.c index b9abf50fdf49..17518ba60a9d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i64-to-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i64-to-i8.c index d90682f0248b..bf0c43e5cfcc 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-4-i64-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i16-to-i8.c index 191116695dd3..bac1fdab9cb4 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i16-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i32-to-i16.c index 28116eb3cd75..3a82ea0a9202 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i32-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i32-to-i8.c index 54b1ffbbaed3..26a89e743bf6 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i32-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i64-to-i16.c index 633417ba3836..a8bfeef6df8b 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i64-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i64-to-i32.c index c5e4e4a0b64a..f79a049eb20d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i64-to-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i64-to-i8.c index 9acbee073a31..eea31af73ce6 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-5-i64-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i16-to-i8.c index db1a6985732f..0ea32f06a5f1 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i16-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i32-to-i16.c index e6b52d4cab1c..39e44d893495 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i32-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i32-to-i8.c index d83836db406d..cb42b7ef3fd6 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i32-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i64-to-i16.c index e910edff0f87..f64a46b74959 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i64-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i64-to-i32.c index 98dd0c2cce18..18e9029f79bc 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i64-to-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i64-to-i8.c index b843300728e3..d8cda79e2ab3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-6-i64-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i16-to-i8.c index ab51ad5edba9..894d5f56a8f1 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i16-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i32-to-i16.c index 9b2c52589429..1ced757931a0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i32-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i32-to-i8.c index ab409f2bc182..ab41a84fa065 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i32-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i64-to-i16.c index 90139529f1ef..c0781367b49a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i64-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i64-to-i32.c index 67e19e713bc9..af86e69224c4 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i64-to-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i64-to-i8.c index a573706caeb1..4a2532dcc803 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-7-i64-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i16-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i16-to-i8.c index dbd70de25690..65c82ad60737 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i16-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i16-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i32-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i32-to-i16.c index 25bb42fb0ab4..a8cb8e113c9f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i32-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i32-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i32-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i32-to-i8.c index 7c71b3d42aa8..5b5f8f4b2a8e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i32-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i32-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i64-to-i16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i64-to-i16.c index 61392b569e57..f48984623dda 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i64-to-i16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i64-to-i16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i64-to-i32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i64-to-i32.c index b47e5da0a29b..a3f3ae5b4b60 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i64-to-i32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i64-to-i32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i64-to-i8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i64-to-i8.c index 1cd7f8049b03..aafe96b0eca4 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i64-to-i8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_trunc-run-8-i64-to-i8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u16.c index 3c916bcb9950..8f1b5c0e2d01 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u16.c @@ -1,21 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint16_t_fmt_1: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_ADD_FMT_1(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u32.c index edded3ebc0e8..2c66eee95af3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint32_t_fmt_1: -** slli\s+[atx][0-9]+,\s*a0,\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** add\s+[atx][0-9]+,\s*a[01],\s*a[01] -** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_ADD_FMT_1(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u64.c index 821e4bc5afea..28d7b7c0d356 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint64_t_fmt_1: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_ADD_FMT_1(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u8.c index fd73c3a5f7a7..ab183362b26a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-1-u8.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint8_t_fmt_1: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_ADD_FMT_1(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u16.c index a166d2888bb7..c03b15d38b2c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u16.c @@ -1,21 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint16_t_fmt_2: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_ADD_FMT_2(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u32.c index c06731b130ce..f753c014a0a5 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint32_t_fmt_2: -** slli\s+[atx][0-9]+,\s*a0,\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** add\s+[atx][0-9]+,\s*a[01],\s*a[01] -** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_ADD_FMT_2(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u64.c index ae10dffb53f2..cad539c02d89 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint64_t_fmt_2: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_ADD_FMT_2(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u8.c index f3977be6edd1..b595241629ec 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-2-u8.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint8_t_fmt_2: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_ADD_FMT_2(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u16.c index 5898c3b75de7..08cd82094bbf 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u16.c @@ -1,21 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint16_t_fmt_3: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_ADD_FMT_3(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u32.c index a1017c9c0a4d..e0b73748c304 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint32_t_fmt_3: -** slli\s+[atx][0-9]+,\s*a0,\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** add\s+[atx][0-9]+,\s*a[01],\s*a[01] -** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_ADD_FMT_3(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u64.c index 83fcb602a8ba..7ce0121e0c43 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint64_t_fmt_3: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_ADD_FMT_3(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u8.c index 2c398e0c1f77..48f61c123790 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-3-u8.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint8_t_fmt_3: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_ADD_FMT_3(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u16.c index c18a5d5939ac..49d5af1e3a1a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u16.c @@ -1,21 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint16_t_fmt_4: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_ADD_FMT_4(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u32.c index fa2e55dc4ccd..20ad476d71da 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint32_t_fmt_4: -** slli\s+[atx][0-9]+,\s*a0,\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** add\s+[atx][0-9]+,\s*a[01],\s*a[01] -** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_ADD_FMT_4(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u64.c index 6818c0c2059a..6d2c9a7f0003 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint64_t_fmt_4: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_ADD_FMT_4(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u8.c index 1096de849f00..15e613bceff1 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-4-u8.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint8_t_fmt_4: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_ADD_FMT_4(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u16.c index fd4be5c46284..225ba0c68c89 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u16.c @@ -1,21 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint16_t_fmt_5: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_ADD_FMT_5(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u32.c index 4fbc80780c59..106baf7bb021 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint32_t_fmt_5: -** slli\s+[atx][0-9]+,\s*a0,\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** add\s+[atx][0-9]+,\s*a[01],\s*a[01] -** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_ADD_FMT_5(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u64.c index 5bc29487442a..48e84f63fe35 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint64_t_fmt_5: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_ADD_FMT_5(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u8.c index 74109c3b5042..9c0d42a652e5 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-5-u8.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint8_t_fmt_5: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_ADD_FMT_5(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u16.c index 3cb9cbe7895d..0b541e0805d7 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u16.c @@ -1,21 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint16_t_fmt_6: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_ADD_FMT_6(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u32.c index fd1cb1ae33f8..ee791566c246 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint32_t_fmt_6: -** slli\s+[atx][0-9]+,\s*a0,\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** add\s+[atx][0-9]+,\s*a[01],\s*a[01] -** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_ADD_FMT_6(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u64.c index c968f3358ed0..fd79139242fd 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint64_t_fmt_6: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_ADD_FMT_6(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u8.c index 9cd95ad6337d..f826aa402518 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-6-u8.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint8_t_fmt_6: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_ADD_FMT_6(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u16-from-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u16-from-u32.c index 527f8de63517..446a951e310f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u16-from-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u16-from-u32.c @@ -1,21 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint32_t_uint16_t_fmt_7: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_ADD_FMT_7(uint32_t, uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u16-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u16-from-u64.c index e9031dedfd1e..626effc2cd83 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u16-from-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u16-from-u64.c @@ -1,21 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint64_t_uint16_t_fmt_7: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_ADD_FMT_7(uint64_t, uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u32-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u32-from-u64.c index a71bd2f479a4..301463437433 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u32-from-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u32-from-u64.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint64_t_uint32_t_fmt_7: -** slli\s+[atx][0-9]+,\s*a0,\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** add\s+[atx][0-9]+,\s*a[01],\s*a[01] -** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_ADD_FMT_7(uint64_t, uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u8-from-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u8-from-u16.c index 589298643fa9..541a1d8791bb 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u8-from-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u8-from-u16.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint16_t_uint8_t_fmt_7: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_ADD_FMT_7(uint16_t, uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u8-from-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u8-from-u32.c index a42a712739e4..26749a8a3ed3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u8-from-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u8-from-u32.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint32_t_uint8_t_fmt_7: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_ADD_FMT_7(uint32_t, uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u8-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u8-from-u64.c index f37ef1c4543d..321f6622b6c6 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u8-from-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-7-u8-from-u64.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_uint64_t_uint8_t_fmt_7: -** add\s+[atx][0-9]+,\s*a0,\s*a1 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_ADD_FMT_7(uint64_t, uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-8-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-8-u16.c new file mode 100644 index 000000000000..a7062b5ff612 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-8-u16.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_U_ADD_FMT_8(uint16_t) + +/* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-8-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-8-u32.c new file mode 100644 index 000000000000..2e43c7f3890c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-8-u32.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_U_ADD_FMT_8(uint32_t) + +/* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-8-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-8-u64.c new file mode 100644 index 000000000000..4ad18c15924e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-8-u64.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_U_ADD_FMT_8(uint64_t) + +/* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-8-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-8-u8.c new file mode 100644 index 000000000000..608d31b7c89e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-8-u8.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_U_ADD_FMT_8(uint8_t) + +/* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-9-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-9-u16.c new file mode 100644 index 000000000000..b9766d1f3999 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-9-u16.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_U_ADD_FMT_9(uint16_t) + +/* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-9-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-9-u32.c new file mode 100644 index 000000000000..2456d39565e0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-9-u32.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_U_ADD_FMT_9(uint32_t) + +/* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-9-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-9-u64.c new file mode 100644 index 000000000000..0a0ff2463865 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-9-u64.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_U_ADD_FMT_9(uint64_t) + +/* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-9-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-9-u8.c new file mode 100644 index 000000000000..53879dd8490d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-9-u8.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +DEF_SAT_U_ADD_FMT_9(uint8_t) + +/* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u16.c index fe015cc9d1ca..548fae390547 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u32.c index 8ee650197383..e76b63687b48 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u64.c index d2c6af0d432d..0ea65092d715 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u8.c index 154edde17943..3aa7441451fe 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-1-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u16.c index 1fc08bd1eb96..f6f8b9d89c32 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u32.c index a52a230f629b..da8c3eb60967 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u64.c index d05ed332d841..03f596042b57 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u8.c index fd393353b569..af898e55e3ba 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-2-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u16.c index 7084272442c6..7862a48db32c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u32.c index 82de67db75a1..d2fbcf201a79 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u64.c index d73f3056e760..23b5488fc894 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u8.c index f572c440c0e5..b5931d4b95e2 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-3-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u16.c index 65c431f8b893..a9937a787790 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u32.c index 8a73fcde64e5..966831aa1662 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u64.c index 0903e107955b..08db7a1dd2b8 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u8.c index ffdd390efd6b..f7bbb5a01bb0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-4-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u16.c index 72ccd2f776a7..da1782de27aa 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u32.c index 34d1a4ef5491..524106a91c43 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u64.c index d502a58a6809..62fdd2579418 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u8.c index f6113763b889..334eb04ec2c9 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-5-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u16.c index 5ef250d19663..28a2fb8f5238 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u32.c index ba95dbf0545e..3b19af380a6c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u64.c index d0e9dfda28b9..f35334a128d0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u8.c index b3d00df16d73..e04fbf0e1087 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-6-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u16-from-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u16-from-u32.c index 26c27783ae04..3363220a6ba4 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u16-from-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u16-from-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u16-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u16-from-u64.c index 1f3e2f3ff957..bc4ca2f95bab 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u16-from-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u16-from-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u32-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u32-from-u64.c index 558f6ce155d1..04abd952c5dd 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u32-from-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u32-from-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u8-from-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u8-from-u16.c index ec5ac70bd84a..c514a86ad9d9 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u8-from-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u8-from-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u8-from-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u8-from-u32.c index aa94eef6c329..b1a644b15699 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u8-from-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u8-from-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u8-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u8-from-u64.c index 6ac38bae0b2b..8664ffaa777e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u8-from-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-7-u8-from-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-8-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-8-u16.c new file mode 100644 index 000000000000..aaf13be7ab68 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-8-u16.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { rv32 || rv64 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 uint16_t +#define DATA TEST_BINARY_DATA_WRAP(T1, usadd) +#define T TEST_BINARY_STRUCT_DECL(T1, usadd) + +DEF_SAT_U_ADD_FMT_8_WRAP(T1) + +#define RUN_BINARY(x, y) RUN_SAT_U_ADD_FMT_8_WRAP(T1, x, y) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-8-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-8-u32.c new file mode 100644 index 000000000000..0ec8d905662a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-8-u32.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { rv32 || rv64 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 uint32_t +#define DATA TEST_BINARY_DATA_WRAP(T1, usadd) +#define T TEST_BINARY_STRUCT_DECL(T1, usadd) + +DEF_SAT_U_ADD_FMT_8_WRAP(T1) + +#define RUN_BINARY(x, y) RUN_SAT_U_ADD_FMT_8_WRAP(T1, x, y) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-8-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-8-u64.c new file mode 100644 index 000000000000..f367f67103a1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-8-u64.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { rv32 || rv64 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 uint64_t +#define DATA TEST_BINARY_DATA_WRAP(T1, usadd) +#define T TEST_BINARY_STRUCT_DECL(T1, usadd) + +DEF_SAT_U_ADD_FMT_8_WRAP(T1) + +#define RUN_BINARY(x, y) RUN_SAT_U_ADD_FMT_8_WRAP(T1, x, y) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-8-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-8-u8.c new file mode 100644 index 000000000000..0fd403614569 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-8-u8.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { rv32 || rv64 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 uint8_t +#define DATA TEST_BINARY_DATA_WRAP(T1, usadd) +#define T TEST_BINARY_STRUCT_DECL(T1, usadd) + +DEF_SAT_U_ADD_FMT_8_WRAP(T1) + +#define RUN_BINARY(x, y) RUN_SAT_U_ADD_FMT_8_WRAP(T1, x, y) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-9-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-9-u16.c new file mode 100644 index 000000000000..4289e2a0a44c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-9-u16.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { rv32 || rv64 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 uint16_t +#define DATA TEST_BINARY_DATA_WRAP(T1, usadd) +#define T TEST_BINARY_STRUCT_DECL(T1, usadd) + +DEF_SAT_U_ADD_FMT_9_WRAP(T1) + +#define RUN_BINARY(x, y) RUN_SAT_U_ADD_FMT_9_WRAP(T1, x, y) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-9-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-9-u32.c new file mode 100644 index 000000000000..d3dd52e0a8d7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-9-u32.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { rv32 || rv64 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 uint32_t +#define DATA TEST_BINARY_DATA_WRAP(T1, usadd) +#define T TEST_BINARY_STRUCT_DECL(T1, usadd) + +DEF_SAT_U_ADD_FMT_9_WRAP(T1) + +#define RUN_BINARY(x, y) RUN_SAT_U_ADD_FMT_9_WRAP(T1, x, y) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-9-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-9-u64.c new file mode 100644 index 000000000000..a9f09643953e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-9-u64.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { rv32 || rv64 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 uint64_t +#define DATA TEST_BINARY_DATA_WRAP(T1, usadd) +#define T TEST_BINARY_STRUCT_DECL(T1, usadd) + +DEF_SAT_U_ADD_FMT_9_WRAP(T1) + +#define RUN_BINARY(x, y) RUN_SAT_U_ADD_FMT_9_WRAP(T1, x, y) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-9-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-9-u8.c new file mode 100644 index 000000000000..91cdb7e82241 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add-run-9-u8.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { rv32 || rv64 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 uint8_t +#define DATA TEST_BINARY_DATA_WRAP(T1, usadd) +#define T TEST_BINARY_STRUCT_DECL(T1, usadd) + +DEF_SAT_U_ADD_FMT_9_WRAP(T1) + +#define RUN_BINARY(x, y) RUN_SAT_U_ADD_FMT_9_WRAP(T1, x, y) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u16.c index 3c31ac3b650d..b6388dce16f3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u16.c @@ -1,21 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm3_uint16_t_fmt_1: -** addi\s+[atx][0-9]+,\s*a0,\s*3 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_1(uint16_t, 3) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u32.c index c6b352c21e48..cae67960785b 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm7_uint32_t_fmt_1: -** slli\s+[atx][0-9]+,\s*a0,\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** addi\s+[atx][0-9]+,\s*a0,\s*7 -** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_1(uint32_t, 7) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u64.c index 1d9df3c3045c..f9d6939f8d90 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm8_uint64_t_fmt_1: -** addi\s+[atx][0-9]+,\s*a0,\s*8 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_1(uint64_t, 8) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u8.c index 101acd88d38c..d90209a14272 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-1-u8.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm9_uint8_t_fmt_1: -** addi\s+[atx][0-9]+,\s*a0,\s*9 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_1(uint8_t, 9) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u16.c index ac57cc92fe49..a34194d636ec 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u16.c @@ -1,21 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm3_uint16_t_fmt_2: -** addi\s+[atx][0-9]+,\s*a0,\s*3 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_2(uint16_t, 3) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u32.c index 6aca60ca7096..9a801d24d901 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm7_uint32_t_fmt_2: -** slli\s+[atx][0-9]+,\s*a0,\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** addi\s+[atx][0-9]+,\s*a0,\s*7 -** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_2(uint32_t, 7) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u64.c index d0417243ff0a..2eb57a3f3d4c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm8_uint64_t_fmt_2: -** addi\s+[atx][0-9]+,\s*a0,\s*8 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_2(uint64_t, 8) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u8.c index 7baeb8d603d1..363b2df8f664 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-2-u8.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm9_uint8_t_fmt_2: -** addi\s+[atx][0-9]+,\s*a0,\s*9 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_2(uint8_t, 9) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u16.c index 6dbabf6f5143..aaf1209f043f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u16.c @@ -1,21 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm3_uint16_t_fmt_3: -** addi\s+[atx][0-9]+,\s*a0,\s*3 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_3(uint16_t, 3) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u32.c index 1c52b219cef0..e430b37995ee 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm7u_uint32_t_fmt_3: -** slli\s+[atx][0-9]+,\s*a0,\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** addi\s+[atx][0-9]+,\s*a0,\s*7 -** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_3(uint32_t, 7u) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u64.c index ef60ce24ec82..aef5c5832f35 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm8ull_uint64_t_fmt_3: -** addi\s+[atx][0-9]+,\s*a0,\s*8 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_3(uint64_t, 8ull) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u8.c index 81a4b217af62..039d982f070e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-3-u8.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm9_uint8_t_fmt_3: -** addi\s+[atx][0-9]+,\s*a0,\s*9 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_3(uint8_t, 9) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u16.c index 2f6c04601f3c..baf70c3cd612 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u16.c @@ -1,21 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm3_uint16_t_fmt_4: -** addi\s+[atx][0-9]+,\s*a0,\s*3 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_4(uint16_t, 3) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u32.c index 1fc9a50a8a2a..a4bfe50ba4f0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm7u_uint32_t_fmt_4: -** slli\s+[atx][0-9]+,\s*a0,\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** addi\s+[atx][0-9]+,\s*a0,\s*7 -** slli\s+[atx][0-9]+,\s*[atx][0-9],\s*32 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_4(uint32_t, 7u) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u64.c index 0ca423c0f01f..f355de60d953 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm8ull_uint64_t_fmt_4: -** addi\s+[atx][0-9]+,\s*a0,\s*8 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_4(uint64_t, 8ull) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u8.c index c8a43fa2c5a6..54880d7f1d07 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-4-u8.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_add_imm9_uint8_t_fmt_4: -** addi\s+[atx][0-9]+,\s*a0,\s*9 -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** neg\s+[atx][0-9]+,\s*[atx][0-9]+ -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_ADD_IMM_FMT_4(uint8_t, 9) /* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u16.c index 090c76565eab..e715bb084690 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u32.c index 8dade742625e..8b8b475a97b0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u64.c index ace2df88e91d..f6f640896633 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u8.c index 0ce546f8f849..f2154fc0984a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-1-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u16.c index 7b6bd7312341..8e3aa83713c9 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u32.c index 80241527ee9f..403cf1461767 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u64.c index 4a76dbb6dde2..17eca5ee6e87 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u8.c index 8e8759c98259..9a277a1aa58c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-2-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u16.c index 64924a665a9a..2068037a91fc 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u32.c index 04f321720656..5f8f1e603e51 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u64.c index 8ef6c14a367e..c5745215e63a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u8.c index 88673610454f..6b9439ab92ad 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-3-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u16.c index 0b75206bedeb..224c3aed8536 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u32.c index e548d0c06b14..5c03e1b7dc9f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u64.c index 4335d827d137..1ceacd2823cd 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u8.c index 872923ec5b9c..aef253c513e2 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_add_imm-run-4-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u16-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u16-from-u128.c new file mode 100644 index 000000000000..cd6f2f8f9e9e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u16-from-u128.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +#define NT uint16_t +#define WT uint128_t + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u16-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u16-from-u64.c new file mode 100644 index 000000000000..43ab563e65b0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u16-from-u64.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc -mabi=ilp32d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +#define NT uint16_t +#define WT uint64_t + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u32-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u32-from-u128.c new file mode 100644 index 000000000000..dea9f6d83168 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u32-from-u128.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +#define NT uint32_t +#define WT uint128_t + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u32-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u32-from-u64.c new file mode 100644 index 000000000000..8d5449bf3493 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u32-from-u64.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc -mabi=ilp32d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +#define NT uint32_t +#define WT uint64_t + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u64-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u64-from-u128.c new file mode 100644 index 000000000000..d8a01d1a06fa --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u64-from-u128.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +#define NT uint64_t +#define WT uint128_t + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u8-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u8-from-u128.c new file mode 100644 index 000000000000..dfc9d2e2abb0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u8-from-u128.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +#define NT uint8_t +#define WT uint128_t + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u8-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u8-from-u64.c new file mode 100644 index 000000000000..ee4159337bad --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u8-from-u64.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc -mabi=ilp32d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +#define NT uint8_t +#define WT uint64_t + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u16-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u16-from-u128.c new file mode 100644 index 000000000000..79f62973af3d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u16-from-u128.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { rv64 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define NT uint16_t +#define WT uint128_t +#define NAME usmul +#define DATA TEST_BINARY_DATA_WRAP(NT, NAME) +#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME) +#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_1_WRAP(NT, WT, x, y) + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u16-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u16-from-u64.c new file mode 100644 index 000000000000..065afb84f1d9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u16-from-u64.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { rv32 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define NT uint16_t +#define WT uint64_t +#define NAME usmul +#define DATA TEST_BINARY_DATA_WRAP(NT, NAME) +#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME) +#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_1_WRAP(NT, WT, x, y) + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u32-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u32-from-u128.c new file mode 100644 index 000000000000..e5a94627fa00 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u32-from-u128.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { rv64 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define NT uint32_t +#define WT uint128_t +#define NAME usmul +#define DATA TEST_BINARY_DATA_WRAP(NT, NAME) +#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME) +#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_1_WRAP(NT, WT, x, y) + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u32-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u32-from-u64.c new file mode 100644 index 000000000000..062bbc954305 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u32-from-u64.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { rv32 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define NT uint32_t +#define WT uint64_t +#define NAME usmul +#define DATA TEST_BINARY_DATA_WRAP(NT, NAME) +#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME) +#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_1_WRAP(NT, WT, x, y) + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u64-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u64-from-u128.c new file mode 100644 index 000000000000..cbe2a221791d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u64-from-u128.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { rv64 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define NT uint64_t +#define WT uint128_t +#define NAME usmul +#define DATA TEST_BINARY_DATA_WRAP(NT, NAME) +#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME) +#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_1_WRAP(NT, WT, x, y) + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u128.c new file mode 100644 index 000000000000..1f54c303fbb2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u128.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { rv64 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define NT uint8_t +#define WT uint128_t +#define NAME usmul +#define DATA TEST_BINARY_DATA_WRAP(NT, NAME) +#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME) +#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_1_WRAP(NT, WT, x, y) + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u64.c new file mode 100644 index 000000000000..e6f632bab0f5 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u64.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { rv32 } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define NT uint8_t +#define WT uint64_t +#define NAME usmul +#define DATA TEST_BINARY_DATA_WRAP(NT, NAME) +#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME) +#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_1_WRAP(NT, WT, x, y) + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u16.c index eb140ae4ca9d..66a439ecc028 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u16.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint16_t_fmt_1: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_FMT_1(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u32.c index 59ad242c9b3b..6f40907a87ae 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint32_t_fmt_1: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** slli\s+a1,\s*a1,\s*32 -** srli\s+a1,\s*a1,\s*32 -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_FMT_1(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u64.c index 47a83823bf05..647fc6dc63d9 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint64_t_fmt_1: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+a0,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_FMT_1(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u8.c index f01317ba257a..a344c58fff3e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-1-u8.c @@ -1,18 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint8_t_fmt_1: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_FMT_1(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u16.c index 4b7bd3a95136..87fb1fc2211b 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u16.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint16_t_fmt_10: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_FMT_10(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u32.c index a28213f44a55..280236a1d68f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint32_t_fmt_10: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** slli\s+a1,\s*a1,\s*32 -** srli\s+a1,\s*a1,\s*32 -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_FMT_10(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u64.c index 432da0cbddc6..4b7d339f7509 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint64_t_fmt_10: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+a0,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_FMT_10(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u8.c index 0658d38bc844..191c3a59fbba 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-10-u8.c @@ -1,18 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint8_t_fmt_10: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_FMT_10(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u16.c index 2e4b875f1f92..9dc41e12b0fb 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u16.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint16_t_fmt_11: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_FMT_11(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u32.c index 61fb80f03203..475f94468ceb 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint32_t_fmt_11: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** slli\s+a1,\s*a1,\s*32 -** srli\s+a1,\s*a1,\s*32 -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_FMT_11(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u64.c index 2a28b1f9a604..61e3584f6106 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint64_t_fmt_11: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+a0,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_FMT_11(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u8.c index 3033844bb629..7a610556c247 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-11-u8.c @@ -1,18 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint8_t_fmt_11: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_FMT_11(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u16.c index 9cb86dfe7a1c..c4d21cb81019 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u16.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint16_t_fmt_12: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_FMT_12(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u32.c index babe768f80a1..56beb836df6a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint32_t_fmt_12: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** slli\s+a1,\s*a1,\s*32 -** srli\s+a1,\s*a1,\s*32 -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_FMT_12(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u64.c index 294ef5a15024..1bef3fe28414 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint64_t_fmt_12: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+a0,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_FMT_12(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u8.c index 8b8f924ffba4..9004281c8431 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-12-u8.c @@ -1,18 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint8_t_fmt_12: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_FMT_12(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u16.c index e724752009a8..7b85582e99db 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u16.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint16_t_fmt_2: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_FMT_2(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u32.c index 9240406ae500..cfdf66c0d6ee 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint32_t_fmt_2: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** slli\s+a1,\s*a1,\s*32 -** srli\s+a1,\s*a1,\s*32 -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_FMT_2(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u64.c index 3e1efba779cf..38988176158e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint64_t_fmt_2: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+a0,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_FMT_2(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u8.c index 600688a75ba0..33182114a193 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-2-u8.c @@ -1,18 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint8_t_fmt_2: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_FMT_2(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u16.c index bb2d0b703d13..61bb5e5136fd 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u16.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint16_t_fmt_3: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_FMT_3(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u32.c index 06635df2393d..73bfa99a2727 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint32_t_fmt_3: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** slli\s+a1,\s*a1,\s*32 -** srli\s+a1,\s*a1,\s*32 -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_FMT_3(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u64.c index ac485daea732..24d1e6958447 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint64_t_fmt_3: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+a0,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_FMT_3(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u8.c index cdc8776d8e68..5523112f96f4 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-3-u8.c @@ -1,18 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint8_t_fmt_3: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_FMT_3(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u16.c index 407ff8f9787e..fb6a604164a2 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u16.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint16_t_fmt_4: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_FMT_4(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u32.c index cb2cd057441c..0f7e2d30b44e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint32_t_fmt_4: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** slli\s+a1,\s*a1,\s*32 -** srli\s+a1,\s*a1,\s*32 -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_FMT_4(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u64.c index 0ce6269bbdfa..c762647d543e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint64_t_fmt_4: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+a0,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_FMT_4(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u8.c index 302206ae1c80..3e5d2e61a899 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-4-u8.c @@ -1,18 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint8_t_fmt_4: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_FMT_4(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u16.c index ce2758f473d9..ab1b375fac09 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u16.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint16_t_fmt_5: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_FMT_5(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u32.c index d33cef3b633d..1b8ce8451020 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint32_t_fmt_5: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** slli\s+a1,\s*a1,\s*32 -** srli\s+a1,\s*a1,\s*32 -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_FMT_5(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u64.c index 1bf1e97968cc..3fc4e7acbdb8 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint64_t_fmt_5: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+a0,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_FMT_5(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u8.c index b2ed732f2ad0..5c34ead2d109 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-5-u8.c @@ -1,18 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint8_t_fmt_5: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_FMT_5(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u16.c index 20614eccf0b9..70dc6ecafffa 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u16.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint16_t_fmt_6: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_FMT_6(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u32.c index 5d7adfdd011f..cc360362695e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint32_t_fmt_6: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** slli\s+a1,\s*a1,\s*32 -** srli\s+a1,\s*a1,\s*32 -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_FMT_6(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u64.c index b3c6f8db4589..ea633ff6f25b 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint64_t_fmt_6: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+a0,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_FMT_6(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u8.c index a4f92a8d048e..7c4747a68a17 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-6-u8.c @@ -1,18 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint8_t_fmt_6: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_FMT_6(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u16.c index ebfe6739f163..cac84714fada 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u16.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint16_t_fmt_7: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_FMT_7(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u32.c index 98841234dd2c..18b8e5f03b9f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint32_t_fmt_7: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** slli\s+a1,\s*a1,\s*32 -** srli\s+a1,\s*a1,\s*32 -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_FMT_7(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u64.c index 67236d584e88..f5ade61c45d0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint64_t_fmt_7: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+a0,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_FMT_7(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u8.c index 549d9d2ffa07..9b528a45b93d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-7-u8.c @@ -1,18 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint8_t_fmt_7: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_FMT_7(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u16.c index aa5aec7fd12d..0d093c3ac9bc 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u16.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint16_t_fmt_8: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_FMT_8(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u32.c index 89a8cc957f48..f04ea1d36db0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint32_t_fmt_8: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** slli\s+a1,\s*a1,\s*32 -** srli\s+a1,\s*a1,\s*32 -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_FMT_8(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u64.c index a52948d3e426..17dd8f38d99b 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint64_t_fmt_8: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+a0,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_FMT_8(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u8.c index 5606733b2ae2..b043207cddc8 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-8-u8.c @@ -1,18 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint8_t_fmt_8: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_FMT_8(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u16.c index 984867ae1d77..19b1a5bba714 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u16.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint16_t_fmt_9: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_FMT_9(uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u32.c index d1109a4ea341..a0026a1fc891 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u32.c @@ -1,22 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint32_t_fmt_9: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** slli\s+a1,\s*a1,\s*32 -** srli\s+a1,\s*a1,\s*32 -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_FMT_9(uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u64.c index a9acf151079d..01c155ea6e32 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint64_t_fmt_9: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*a0,\s*a1 -** addi\s+a0,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_FMT_9(uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u8.c index 47551fae5214..7b94d40f567b 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-9-u8.c @@ -1,18 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_uint8_t_fmt_9: -** sub\s+[atx][0-9]+,\s*a0,\s*a1 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_FMT_9(uint8_t) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u16.c index 1534cf998277..20e14d6960a2 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u32.c index 5c60d28997f9..1a0c3949942e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u64.c index 403764c85687..ee348b317db3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u8.c index 931420a30987..216af8620b67 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-1-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u16.c index ae87544c9c4b..109539d33ff3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u32.c index 43414ae2d84d..9e35fa2cc77f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u64.c index 3ef70a19c581..3c7c8dbe15ae 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u8.c index 2a157f027da5..df291e2c6690 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-10-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u16.c index 534795cdd8fa..88dded4ac4b9 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u32.c index 4d0a34fff3b4..239b42263a5d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u64.c index d74d10dc4e0d..9a524fddf7fe 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u8.c index 949bd0d6f48c..b9b84ea7318a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-11-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u16.c index 80cce95188c6..91bd9deb12aa 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u32.c index 3ecd19c472f9..eaaa256165d3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u64.c index 2d7bfc47a31a..04d2a2026ba3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u8.c index 209965cb8bdb..caedfe71a74e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-12-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u16.c index 7deaae9a5fdc..06a44f1a4a93 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u32.c index d9b1d5cbfe29..9d38c9c57f9a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u64.c index 2774c235cc37..5c10409ed544 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u8.c index 6fa44ca323bd..0ff98276de90 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-2-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u16.c index ea52ff4573eb..aab99ca3964c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u32.c index fdea8916ab3c..5231d6fff727 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u64.c index 164ee77fb761..d7462a85538c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u8.c index 724adf92d3e1..5da783833701 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-3-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u16.c index 9b57861b578d..8e69888e292f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u32.c index df2eecef6fb4..9b22dda9166c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u64.c index 09e9ac38a83f..abd0a958a7dc 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u8.c index c8ae7a6680d2..d92c0e1e974c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-4-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u16.c index 9f575a47bfe8..b404bfdef7c1 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u32.c index c370455c3d41..b74671298dc9 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u64.c index 22d82f973d44..da90b7a30338 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u8.c index b2823112b62b..38dcabe7a023 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-5-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u16.c index e0dda451775f..fd55bec0e67e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u32.c index dfd95ef58c39..2e810dd4d40f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u64.c index 7cac446aa336..e86eebc9868e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u8.c index 0b4cbdbf5993..e749bb5407a4 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-6-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u16.c index 10c65fec97db..eb57d553c3df 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u32.c index e3b4dde683da..c1a5bcffec1c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u64.c index 6e93fcff032d..27d4b827d91e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u8.c index d101d2897c9e..feb56e11e448 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-7-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u16.c index 4e50e3f804ed..a22f1df74080 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u32.c index 3c8f78d7ed31..b98931db96bd 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u64.c index 932596a28e71..dff3c0a9f43c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u8.c index 1f74562125bc..d2f312696607 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-8-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u16.c index 66a82f20ca5e..3740099964f1 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u32.c index a54b5c33bc12..b6ae459348a0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u64.c index 97943b3e3b60..55198d68dde8 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u8.c index ab8b4750d012..ce73d26f4c44 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub-run-9-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-1.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-1.c index 573ef110bf9f..475b31eb8ea9 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-1.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-1.c @@ -1,21 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm32768_uint16_t_fmt_1: -** li\s+[atx][0-9]+,\s*32768 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint16_t, 32768) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-2.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-2.c index 0fefbe71d026..a984f84bf824 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-2.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-2.c @@ -1,22 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm65533_uint16_t_fmt_1: -** li\s+[atx][0-9]+,\s*65536 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-3 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint16_t, 65533) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-3.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-3.c index ad6d4f9693e3..b2930d4fa8e5 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-3.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-3.c @@ -1,22 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm65534_uint16_t_fmt_1: -** li\s+[atx][0-9]+,\s*65536 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-2 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint16_t, 65534) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-4.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-4.c index 02dcbc5ba3a8..362cf48823d3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-4.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16-4.c @@ -1,21 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm1_uint16_t_fmt_1: -** li\s+[atx][0-9]+,\s*1 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint16_t, 1) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16.c index 7346fbb2a9ae..9f17082b63ab 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u16.c @@ -1,21 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm6_uint16_t_fmt_1: -** li\s+[atx][0-9]+,\s*6 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint16_t, 6) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-1.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-1.c index c7dac8ad86f1..801a86eb9e65 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-1.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-1.c @@ -1,23 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm2147483648_uint32_t_fmt_1: -** li\s+[atx][0-9]+,\s*1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint32_t, 2147483648) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-2.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-2.c index 4320db3c6f6f..e04476817402 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-2.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-2.c @@ -1,24 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm68719476732_uint32_t_fmt_1: -** li\s+[atx][0-9]+,\s*1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-4 -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint32_t, 68719476732) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-3.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-3.c index 765d13cde645..5518064a1a11 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-3.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-3.c @@ -1,24 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm4294967294_uint32_t_fmt_1: -** li\s+[atx][0-9]+,\s*1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-2 -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint32_t, 4294967294) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-4.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-4.c index ca11cf14008f..a4cb49bbf800 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-4.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32-4.c @@ -1,22 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm1_uint32_t_fmt_1: -** li\s+[atx][0-9]+,\s*1 -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint32_t, 1) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32.c index 371193002353..64808bfc33f2 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u32.c @@ -1,22 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm255_uint32_t_fmt_1: -** li\s+[atx][0-9]+,\s*255 -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint32_t, 255) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u64-1.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u64-1.c index 2e490f05de6d..493a14d4cf2f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u64-1.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u64-1.c @@ -1,19 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm18446744073709551614u_uint64_t_fmt_1: -** li\s+[atx][0-9]+,\s*-2 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint64_t, 18446744073709551614u) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u64-2.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u64-2.c index 45baa8fc32e5..4faae52395ca 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u64-2.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u64-2.c @@ -1,19 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm1_uint64_t_fmt_1: -** li\s+[atx][0-9]+,\s*1 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint64_t, 1) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u64.c index a29a6e95d7af..3f993fdf6a30 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u64.c @@ -1,19 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm82_uint64_t_fmt_1: -** li\s+[atx][0-9]+,\s*82 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint64_t, 82) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-1.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-1.c index d1c6e942e485..a0d9235cd25f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-1.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-1.c @@ -1,20 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm128_uint8_t_fmt_1: -** li\s+[atx][0-9]+,\s*128 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint8_t, 128) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-2.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-2.c index 4c8cf90e7630..67dae03dfc00 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-2.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-2.c @@ -1,20 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm253_uint8_t_fmt_1: -** li\s+[atx][0-9]+,\s*253 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint8_t, 253) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-3.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-3.c index b958f5e1582a..005453264f2b 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-3.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-3.c @@ -1,20 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm254_uint8_t_fmt_1: -** li\s+[atx][0-9]+,\s*254 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint8_t, 254) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-4.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-4.c index 1951ec5d64c3..c12b5605832b 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-4.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8-4.c @@ -1,20 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm1_uint8_t_fmt_1: -** li\s+[atx][0-9]+,\s*1 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint8_t, 1) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8.c index 86d0b39eb6f9..ce9f495946eb 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-1-u8.c @@ -1,20 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm11_uint8_t_fmt_1: -** li\s+[atx][0-9]+,\s*11 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_1(uint8_t, 11) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16-1.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16-1.c index 31c1bb81969d..93d716983d85 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16-1.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16-1.c @@ -1,21 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm32768_uint16_t_fmt_2: -** li\s+[atx][0-9]+,\s*32768 -** sub\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_2(uint16_t, 32768) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16-2.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16-2.c index 68807b947cc7..8ac2ce898b58 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16-2.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16-2.c @@ -1,22 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm65533_uint16_t_fmt_2: -** li\s+[atx][0-9]+,\s*65536 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-3 -** sub\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_2(uint16_t, 65533) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16-3.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16-3.c index 62deec103f6d..740d6acabf76 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16-3.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16-3.c @@ -1,18 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm1_uint16_t_fmt_2: -** snez\s+[atx][0-9]+,\s*a0 -** subw\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_2(uint16_t, 1) /* { dg-final { scan-tree-dump-not ".SAT_SUB" "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16.c index f789feecc6c8..c82c47856489 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u16.c @@ -1,20 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm6_uint16_t_fmt_2: -** addi\s+[atx][0-9]+,\s*a0,\s*-6 -** sltiu\s+a0,\s*[atx][0-9]+,\s*6 -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_2(uint16_t, 6) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32-1.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32-1.c index 2f4a4395d3bf..b2f690a773a5 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32-1.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32-1.c @@ -1,23 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm2147483648_uint32_t_fmt_2: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** li\s+[atx][0-9]+,\s*1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** sub\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_2(uint32_t, 2147483648) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32-2.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32-2.c index dcfba62e2207..e62010b0ef5d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32-2.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32-2.c @@ -1,24 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm68719476732_uint32_t_fmt_2: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** li\s+[atx][0-9]+,\s*1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-4 -** sub\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_2(uint32_t, 68719476732) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32-3.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32-3.c index a3f48f7bb2fe..dd063d89d54d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32-3.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32-3.c @@ -1,16 +1,8 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm1_uint32_t_fmt_2: -** snez\s+[atx][0-9]+,\s*a0 -** subw\s+a0,\s*a0,\s*[atx][0-9]+ -** ret -*/ - DEF_SAT_U_SUB_IMM_FMT_2(uint32_t, 1) /* { dg-final { scan-tree-dump-not ".SAT_SUB" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32.c index 0bd8ddcdd78f..c0eb8a7b9569 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u32.c @@ -1,21 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm255_uint32_t_fmt_2: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** addi\s+[atx][0-9]+,\s*a0,\s*-255 -** sltiu\s+a0,\s*[atx][0-9]+,\s*255 -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_2(uint32_t, 255) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u64-1.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u64-1.c index 7b6d857a173f..ed6931373273 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u64-1.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u64-1.c @@ -1,16 +1,8 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm1_uint64_t_fmt_2: -** snez\s+[atx][0-9]+,\s*a0 -** sub\s+a0,\s*a0,\s*[atx][0-9]+ -** ret -*/ - DEF_SAT_U_SUB_IMM_FMT_2(uint64_t, 1) /* { dg-final { scan-tree-dump-not ".SAT_SUB" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u64.c index c334665a1dc7..fb7db13a4712 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u64.c @@ -1,18 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm82_uint64_t_fmt_2: -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-82 -** sltiu\s+a0,\s*[atx][0-9]+,\s*82 -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_2(uint64_t, 82) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8-1.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8-1.c index 26e77f0d1ac4..efe6c005bf27 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8-1.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8-1.c @@ -1,19 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm128_uint8_t_fmt_2: -** addi\s+[atx][0-9]+,\s*a0,\s*-128 -** sltiu\s+a0,\s*[atx][0-9]+,\s*128 -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_2(uint8_t, 128) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8-2.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8-2.c index c5ac1b080187..126264897f47 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8-2.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8-2.c @@ -1,19 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm253_uint8_t_fmt_2: -** addi\s+[atx][0-9]+,\s*a0,\s*-253 -** sltiu\s+a0,\s*[atx][0-9]+,\s*253 -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_2(uint8_t, 253) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8-3.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8-3.c index ee59b5adfb86..108daf2ffe23 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8-3.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8-3.c @@ -1,17 +1,8 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm1_uint8_t_fmt_2: -** snez\s+[atx][0-9]+,\s*a0 -** subw\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ - DEF_SAT_U_SUB_IMM_FMT_2(uint8_t, 1) /* { dg-final { scan-tree-dump-not ".SAT_SUB" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8.c index 69dcc2a4a93b..784a97bef421 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-2-u8.c @@ -1,19 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm11_uint8_t_fmt_2: -** addi\s+[atx][0-9]+,\s*a0,\s*-11 -** sltiu\s+a0,\s*[atx][0-9]+,\s*11 -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_2(uint8_t, 11) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u16-1.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u16-1.c index f31236253eca..0f16f9cb2ec0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u16-1.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u16-1.c @@ -1,22 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm32769_uint16_t_fmt_3: -** li\s+[atx][0-9]+,\s*32768 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_3(uint16_t, 32769) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u16-2.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u16-2.c index fa9a9eff1801..49daab566ce4 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u16-2.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u16-2.c @@ -1,22 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm65533_uint16_t_fmt_3: -** li\s+[atx][0-9]+,\s*65536 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-3 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_3(uint16_t, 65533) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u16.c index b98de41711e7..30fc2bf87b0f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u16.c @@ -1,21 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm6_uint16_t_fmt_3: -** li\s+[atx][0-9]+,\s*6 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_3(uint16_t, 6) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u32-1.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u32-1.c index 79457a3b41d4..2d3c63dca52d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u32-1.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u32-1.c @@ -1,24 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm2147483649_uint32_t_fmt_3: -** li\s+[atx][0-9]+,\s*1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_3(uint32_t, 2147483649) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u32-2.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u32-2.c index 2e8426e1f2da..8d96c0062e43 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u32-2.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u32-2.c @@ -1,24 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm68719476732_uint32_t_fmt_3: -** li\s+[atx][0-9]+,\s*1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-4 -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_3(uint32_t, 68719476732) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u32.c index 845218c1d2e5..c06c441bfe31 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u32.c @@ -1,22 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm255_uint32_t_fmt_3: -** li\s+[atx][0-9]+,\s*255 -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_3(uint32_t, 255) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u64.c index ee2fbf846da7..4d2b96d5c0d3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u64.c @@ -1,19 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm82_uint64_t_fmt_3: -** li\s+[atx][0-9]+,\s*82 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_3(uint64_t, 82) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u8-1.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u8-1.c index 8cc81e2253bb..8c3eb148e6d7 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u8-1.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u8-1.c @@ -1,20 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm134_uint8_t_fmt_3: -** li\s+[atx][0-9]+,\s*134 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_3(uint8_t, 134) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u8-2.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u8-2.c index 8d8c70bf3e60..b02d832b0001 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u8-2.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u8-2.c @@ -1,20 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm253_uint8_t_fmt_3: -** li\s+[atx][0-9]+,\s*253 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_3(uint8_t, 253) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u8.c index 348d75b82d8a..d8e0a6959d24 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-3-u8.c @@ -1,20 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm11_uint8_t_fmt_3: -** li\s+[atx][0-9]+,\s*11 -** sub\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_3(uint8_t, 11) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u16-1.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u16-1.c index 089c1683b041..8f3726f0b9b8 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u16-1.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u16-1.c @@ -1,21 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm32768_uint16_t_fmt_4: -** li\s+[atx][0-9]+,\s*32768 -** sub\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_4(uint16_t, 32768) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u16-2.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u16-2.c index b96e3f3da843..56c377eb1c76 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u16-2.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u16-2.c @@ -1,22 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm65533_uint16_t_fmt_4: -** li\s+[atx][0-9]+,\s*65536 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-3 -** sub\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_4(uint16_t, 65533) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u16.c index 5c209bcf1062..29c6b8611041 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u16.c @@ -1,20 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm6_uint16_t_fmt_4: -** addi\s+[atx][0-9]+,\s*a0,\s*-6 -** sltiu\s+a0,\s*[atx][0-9]+,\s*6 -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_4(uint16_t, 6) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u32-1.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u32-1.c index 2f4a4395d3bf..b2f690a773a5 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u32-1.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u32-1.c @@ -1,23 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm2147483648_uint32_t_fmt_2: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** li\s+[atx][0-9]+,\s*1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 -** sub\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_2(uint32_t, 2147483648) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u32-2.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u32-2.c index dcfba62e2207..e62010b0ef5d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u32-2.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u32-2.c @@ -1,24 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm68719476732_uint32_t_fmt_2: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** li\s+[atx][0-9]+,\s*1 -** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-4 -** sub\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_2(uint32_t, 68719476732) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u32.c index ee1ad9abae07..6cfb1e4ca58a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u32.c @@ -1,21 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm255_uint32_t_fmt_4: -** slli\s+a0,\s*a0,\s*32 -** srli\s+a0,\s*a0,\s*32 -** addi\s+[atx][0-9]+,\s*a0,\s*-255 -** sltiu\s+a0,\s*[atx][0-9]+,\s*255 -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** sext\.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_4(uint32_t, 255) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u64.c index c334665a1dc7..fb7db13a4712 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u64.c @@ -1,18 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm82_uint64_t_fmt_2: -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-82 -** sltiu\s+a0,\s*[atx][0-9]+,\s*82 -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_2(uint64_t, 82) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u8-1.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u8-1.c index 3fe4103a8c95..49a4150898a1 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u8-1.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u8-1.c @@ -1,19 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm128_uint8_t_fmt_4: -** addi\s+[atx][0-9]+,\s*a0,\s*-128 -** sltiu\s+a0,\s*[atx][0-9]+,\s*128 -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_4(uint8_t, 128) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u8-2.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u8-2.c index 18dc5050e2b7..1022de2b7dc6 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u8-2.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u8-2.c @@ -1,19 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm253_uint8_t_fmt_4: -** addi\s+[atx][0-9]+,\s*a0,\s*-253 -** sltiu\s+a0,\s*[atx][0-9]+,\s*253 -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_4(uint8_t, 253) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u8.c index 5c40f3270d16..48aaeb25d443 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-4-u8.c @@ -1,19 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_sub_imm11_uint8_t_fmt_4: -** addi\s+[atx][0-9]+,\s*a0,\s*-11 -** sltiu\s+a0,\s*[atx][0-9]+,\s*11 -** addi\s+a0,\s*a0,\s*-1 -** and\s+a0,\s*a0,\s*[atx][0-9]+ -** andi\s+a0,\s*a0,\s*0xff -** ret -*/ DEF_SAT_U_SUB_IMM_FMT_4(uint8_t, 11) /* { dg-final { scan-tree-dump-times ".SAT_SUB " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u16.c index 2bc3be3efc5e..a193d88385f0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u32.c index b1d1ee331351..e1dd81c5b488 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u64.c index 2539d753c112..a71526c37bae 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u8.c index 5091872d208e..4fedf96cc079 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-1-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u16.c index 0f4f9e40f1f4..f990c439799e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u32.c index ea15d85782d2..44d5e88f1c1c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u64.c index 612da9212cd4..91ea98677568 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u8.c index fc3809590dee..7da49ebe7c14 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-2-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u16.c index 150ab2a490d3..8c44ee0b78da 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u32.c index c7d2850c0bef..f5c4e5aa95ae 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u64.c index 6bf5cd2445af..393f7f634196 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u8.c index dfef1f24a9ec..e46463bd1bfc 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-3-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u16.c index 610e02124cf1..3062e0f4ab14 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u32.c index 1d9e0cbbbfc3..e621cd201466 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u64.c index f864a67220cf..cfc96bfcf0f3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u8.c index 603f2eeab847..771ec4ad758f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_sub_imm-run-4-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u16.c index b73290af8e3c..d36862160160 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u16.c @@ -1,20 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint32_t_to_uint16_t_fmt_1: -** li\s+[atx][0-9]+,\s*65536 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** sltu\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_TRUNC_FMT_1(uint16_t, uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u32.c index 8af803ffea3f..02ca992f3102 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u32.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint64_t_to_uint32_t_fmt_1: -** li\s+[atx][0-9]+,\s*-1 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_TRUNC_FMT_1(uint32_t, uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u64.c index 1c887d4ce72d..cc01abd0c29d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint32_t_to_uint8_t_fmt_1: -** sltiu\s+[atx][0-9]+,\s*a0,\s*255 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** ret -*/ DEF_SAT_U_TRUNC_FMT_1(uint8_t, uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u8.c index 6bcf64bfe616..e28ee5cec9f0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-1-u8.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint16_t_to_uint8_t_fmt_1: -** sltiu\s+[atx][0-9]+,\s*a0,\s*255 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** ret -*/ DEF_SAT_U_TRUNC_FMT_1(uint8_t, uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u16.c index 8a35e72424b0..59302cb77b17 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u16.c @@ -1,20 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint64_t_to_uint16_t_fmt_1: -** li\s+[atx][0-9]+,\s*65536 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** sltu\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_TRUNC_FMT_1(uint16_t, uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u32.c index a3b52de44523..735ea7e34c87 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u32.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint16_t_to_uint8_t_fmt_2: -** sltiu\s+[atx][0-9]+,\s*a0,\s*255 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** ret -*/ DEF_SAT_U_TRUNC_FMT_2(uint8_t, uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u64.c index b9b43f14c0b1..8fd3f437e8b6 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u64.c @@ -1,20 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint32_t_to_uint16_t_fmt_2: -** li\s+[atx][0-9]+,\s*65536 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** sltu\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_TRUNC_FMT_2(uint16_t, uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u8.c index 7ed3623b872b..bb4ecc5cac13 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-2-u8.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint64_t_to_uint8_t_fmt_1: -** sltiu\s+[atx][0-9]+,\s*a0,\s*255 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** ret -*/ DEF_SAT_U_TRUNC_FMT_1(uint8_t, uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u16.c index 7572c9e3404f..e476897f46ef 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u16.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint32_t_to_uint8_t_fmt_2: -** sltiu\s+[atx][0-9]+,\s*a0,\s*255 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** ret -*/ DEF_SAT_U_TRUNC_FMT_2(uint8_t, uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u32.c index d83b5dd6caa4..524d62560bdb 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u32.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint64_t_to_uint8_t_fmt_2: -** sltiu\s+[atx][0-9]+,\s*a0,\s*255 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** ret -*/ DEF_SAT_U_TRUNC_FMT_2(uint8_t, uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u64.c index b7202f971a72..ba8b2380f116 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u64.c @@ -1,20 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint64_t_to_uint16_t_fmt_2: -** li\s+[atx][0-9]+,\s*65536 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** sltu\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_TRUNC_FMT_2(uint16_t, uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u8.c index e90b853516ae..cba85733634b 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-3-u8.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint64_t_to_uint32_t_fmt_2: -** li\s+[atx][0-9]+,\s*-1 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_TRUNC_FMT_2(uint32_t, uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u16.c index e8655b98db6e..58520280496a 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u16.c @@ -1,20 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint32_t_to_uint16_t_fmt_3: -** li\s+[atx][0-9]+,\s*65536 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** sltu\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_TRUNC_FMT_3(uint16_t, uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u32.c index 41e676a14548..5d5cf973a851 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u32.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint64_t_to_uint32_t_fmt_3: -** li\s+[atx][0-9]+,\s*-1 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_TRUNC_FMT_3(uint32_t, uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u64.c index 32eeb884cbf2..866e240e9667 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u64.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint32_t_to_uint8_t_fmt_3: -** sltiu\s+[atx][0-9]+,\s*a0,\s*255 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** ret -*/ DEF_SAT_U_TRUNC_FMT_3(uint8_t, uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u8.c index 5d043ce05854..f3adfb6fd48d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-4-u8.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint16_t_to_uint8_t_fmt_3: -** sltiu\s+[atx][0-9]+,\s*a0,\s*255 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** ret -*/ DEF_SAT_U_TRUNC_FMT_3(uint8_t, uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u16.c index 7e5906b5073f..4e132a9370da 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u16.c @@ -1,20 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint64_t_to_uint16_t_fmt_3: -** li\s+[atx][0-9]+,\s*65536 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** sltu\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_TRUNC_FMT_3(uint16_t, uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u32.c index e1b0acdba7e7..893f43e3b828 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u32.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint16_t_to_uint8_t_fmt_4: -** sltiu\s+[atx][0-9]+,\s*a0,\s*255 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** ret -*/ DEF_SAT_U_TRUNC_FMT_4(uint8_t, uint16_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u64.c index 618d50bdbe9c..5c0c7a7eaeef 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u64.c @@ -1,20 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint32_t_to_uint16_t_fmt_4: -** li\s+[atx][0-9]+,\s*65536 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** sltu\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_TRUNC_FMT_4(uint16_t, uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u8.c index c9a9a4cad6b5..395bb1bda2d3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-5-u8.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint64_t_to_uint8_t_fmt_3: -** sltiu\s+[atx][0-9]+,\s*a0,\s*255 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** ret -*/ DEF_SAT_U_TRUNC_FMT_3(uint8_t, uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u16.c index 418cdc8c4816..8f20c8ffeff7 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u16.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint32_t_to_uint8_t_fmt_4: -** sltiu\s+[atx][0-9]+,\s*a0,\s*255 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** ret -*/ DEF_SAT_U_TRUNC_FMT_4(uint8_t, uint32_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u32.c index 4903a046fde7..f7e7ff236213 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u32.c @@ -1,17 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint64_t_to_uint8_t_fmt_4: -** sltiu\s+[atx][0-9]+,\s*a0,\s*255 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff -** ret -*/ DEF_SAT_U_TRUNC_FMT_4(uint8_t, uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u64.c index 6f8191c6e7c6..2d9b6a6caae8 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u64.c @@ -1,20 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint64_t_to_uint16_t_fmt_4: -** li\s+[atx][0-9]+,\s*65536 -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** sltu\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** slli\s+a0,\s*a0,\s*48 -** srli\s+a0,\s*a0,\s*48 -** ret -*/ DEF_SAT_U_TRUNC_FMT_4(uint16_t, uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u8.c index 24bb846a0493..4fa81fec0580 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-6-u8.c @@ -1,19 +1,9 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized -fno-schedule-insns -fno-schedule-insns2" } */ -/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ #include "sat_arith.h" -/* -** sat_u_trunc_uint64_t_to_uint32_t_fmt_4: -** li\s+[atx][0-9]+,\s*-1 -** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*32 -** sltu\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ -** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 -** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ -** sext.w\s+a0,\s*a0 -** ret -*/ DEF_SAT_U_TRUNC_FMT_4(uint32_t, uint64_t) /* { dg-final { scan-tree-dump-times ".SAT_TRUNC " 1 "optimized" } } */ +/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u16.c index a5f43e93a8d7..72c175c54338 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u32.c index a76ae0848da2..aef195a7f858 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u64.c index d05ea792409c..4517418e9310 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u8.c index adaa421b2391..2e510232fbd2 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-1-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u16.c index 38fcba3749ca..8ea83d60089c 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u32.c index 93705f97293a..1d0dd5bf9d07 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u64.c index c1164843df9e..f69968c509ee 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u8.c index 4fbdc9159cda..dcff0b467cb8 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-2-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u16.c index 2281610f3353..33f46eca54af 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u32.c index 126c97c855ac..b9c46172e0f9 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u64.c index 61ad79d506b2..21755a7a1569 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u8.c index 4142e8727bdd..bcf20815f185 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-3-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u16.c index 8952c06fcc90..69f53526396f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u32.c index 8952c06fcc90..69f53526396f 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u64.c index 20ceda6852e9..f001c39c7610 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u8.c index 7011e5040c58..1394d9f59fdc 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-4-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u16.c index e868da152b36..de5d723867a5 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u32.c index 7f52283fbeb3..c345bfa07f36 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u64.c index ee13f0abb9bc..8ca8cc788eb0 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u8.c index 8471c76a4aa8..54e00e86b19d 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-5-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u16.c index f056bd42e91f..a957cc337048 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u16.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u16.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u32.c index 96c06ebcd12d..9691b4d0e590 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u32.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u32.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u64.c index 1623e521fcec..ff2c2a55d516 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u64.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u64.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u8.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u8.c index a1b8a5f19d2e..918eabb401f3 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u8.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_trunc-run-6-u8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv32 || rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/ventana-16122.c b/gcc/testsuite/gcc.target/riscv/ventana-16122.c new file mode 100644 index 000000000000..59e6467b57c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/ventana-16122.c @@ -0,0 +1,19 @@ +/* { dg-do compile { target { rv64 } } } */ + +extern void NG (void); +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +void f74(void) { + int16_t x309 = 0x7fff; + volatile int32_t x310 = 0x7fffffff; + int8_t x311 = 59; + int16_t x312 = -0x8000; + static volatile int32_t t74 = 614992577; + + t74 = (x309==((x310^x311)%x312)); + + if (t74 != 0) { NG(); } else { ; } + +} + diff --git a/gcc/testsuite/gcc.target/riscv/zalrsc.c b/gcc/testsuite/gcc.target/riscv/zalrsc.c new file mode 100644 index 000000000000..19a26bfb47ce --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zalrsc.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64imfd_zalrsc -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } {"-O0"} } */ + +/* lr.w/sc.w */ +int *i; +int lr_sc(int v) +{ + return __atomic_exchange_4(i, v, __ATOMIC_RELAXED); +} + +/* { dg-final { scan-assembler-times {\mlr.w} 1 } } */ +/* { dg-final { scan-assembler-times {\msc.w} 1 } } */ +/* { dg-final { scan-assembler-not {"mv\t"} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c new file mode 100644 index 000000000000..1ad1b77a2e65 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mtune=generic" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mtune=generic" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" "-O3" } } */ + +#define N 10000 + +int primitiveSemantics_compare_reg_reg_return_reg_reg_00(int *a, int min_v) +{ + int last = 0; + + for (int i = 0; i < N; i++) + { + if (a[i] < min_v) + last = a[i]; + } + return last; +} + +/* { dg-final { scan-assembler-times {\mczero\.nez\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mczero\.eqz\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-1.c b/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-1.c new file mode 100644 index 000000000000..36026269c13a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_zilsd -mabi=ilp32" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ + +long long y; +long long foo(long long x) +{ + return y + x; +} + +/* { dg-final { scan-assembler-times "ld\t" 1 } } */ +/* { dg-final { scan-assembler-not "lw\t" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-2.c b/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-2.c new file mode 100644 index 000000000000..3adcd21ea061 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_zilsd -mabi=ilp32" } */ + +long long y; +long long foo(long long x) +{ + return y >> x; +} +/* TODO: We should not split that 64 bit load into two 32 bit load if we have + zilsd, but we split that during the expand time, so it's hard to fix via cost + model turning, we could either fix that for expander, or...combine those two + 32 bit load back later. */ +/* { dg-final { scan-assembler-times "ld\t" 1 { xfail riscv*-*-* } } } */ + +/* Os and Oz will use libcall, so the 64 bit load won't be split. */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Oz" } } */ diff --git a/gcc/testsuite/gcc.target/s390/asm-hard-reg-1.c b/gcc/testsuite/gcc.target/s390/asm-hard-reg-1.c new file mode 100644 index 000000000000..671c0ede6efa --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/asm-hard-reg-1.c @@ -0,0 +1,103 @@ +/* { dg-do compile { target { lp64 } } } */ +/* { dg-options "-O2 -march=z13 -mzarch" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +** test_in_1: +** foo %r2 +** br %r14 +*/ + +int +test_in_1 (int x) +{ + asm ("foo %0" :: "{r2}" (x)); + return x; +} + +/* +** test_in_2: +** lgr (%r[0-9]+),%r2 +** lr %r2,%r3 +** foo %r2 +** lgr %r2,\1 +** br %r14 +*/ + +int +test_in_2 (int x, int y) +{ + asm ("foo %0" :: "{r2}" (y)); + return x; +} + +/* +** test_in_3: +** stmg %r12,%r15,96\(%r15\) +** lay %r15,-160\(%r15\) +** lgr (%r[0-9]+),%r2 +** ahi %r2,1 +** lgfr %r2,%r2 +** brasl %r14,foo@PLT +** lr %r3,%r2 +** lr %r2,\1 +** foo %r3,%r2 +** lgr %r2,\1 +** lmg %r12,%r15,256\(%r15\) +** br %r14 +*/ + +extern int foo (int); + +int +test_in_3 (int x) +{ + asm ("foo %0,%1\n" :: "{r3}" (foo (x + 1)), "{r2}" (x)); + return x; +} + +/* +** test_out_1: +** foo %r3 +** lgfr %r2,%r3 +** br %r14 +*/ + +int +test_out_1 (void) +{ + int x; + asm ("foo %0" : "={r3}" (x)); + return x; +} + +/* +** test_out_2: +** lgr (%r[0-9]+),%r2 +** foo %r2 +** ark (%r[0-9]+),\1,%r2 +** lgfr %r2,\2 +** br %r14 +*/ + +int +test_out_2 (int x) +{ + int y; + asm ("foo %0" : "={r2}" (y)); + return x + y; +} + +/* +** test_inout_1: +** foo %r2 +** lgfr %r2,%r2 +** br %r14 +*/ + +int +test_inout_1 (int x) +{ + asm ("foo %0" : "+{r2}" (x)); + return x; +} diff --git a/gcc/testsuite/gcc.target/s390/asm-hard-reg-2.c b/gcc/testsuite/gcc.target/s390/asm-hard-reg-2.c new file mode 100644 index 000000000000..a892fe8f0aaa --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/asm-hard-reg-2.c @@ -0,0 +1,43 @@ +/* { dg-do compile { target { lp64 } } } */ +/* { dg-options "-O2 -march=z13 -mzarch" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ +/* { dg-final { scan-assembler {\.LC0:\n\t\.long\t1078523331\n} } } */ + + +/* +** test_float_into_gpr: +** lrl %r4,.LC0 +** foo %r4 +** br %r14 +*/ + +void +test_float_into_gpr (void) +{ + // This is the counterpart to + // register float x asm ("r4") = 3.14f; + // asm ("foo %0" :: "r" (x)); + // where the bit-pattern of 3.14f is loaded into GPR. + asm ("foo %0" :: "{r4}" (3.14f)); +} + +/* +** test_float: +** ( +** ldr %f4,%f0 +** ldr %f5,%f2 +** | +** ldr %f5,%f2 +** ldr %f4,%f0 +** ) +** aebr %f5,%f4 +** ldr %f0,%f5 +** br %r14 +*/ + +float +test_float (float x, float y) +{ + asm ("aebr %0,%1" : "+{f5}" (y) : "{f4}" (x)); + return y; +} diff --git a/gcc/testsuite/gcc.target/s390/asm-hard-reg-3.c b/gcc/testsuite/gcc.target/s390/asm-hard-reg-3.c new file mode 100644 index 000000000000..5df37b5b7174 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/asm-hard-reg-3.c @@ -0,0 +1,42 @@ +/* { dg-do compile { target lp64 } } */ +/* { dg-options "-O2 -march=z13 -mzarch" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ +/* { dg-final { scan-assembler {\.LC0:\n\t\.long\t1074339512\n\t\.long\t1374389535\n} } } */ + +/* +** test_double_into_gpr: +** lgrl %r4,.LC0 +** foo %r4 +** br %r14 +*/ + +void +test_double_into_gpr (void) +{ + // This is the counterpart to + // register double x asm ("r4") = 3.14; + // asm ("foo %0" :: "r" (x)); + // where the bit-pattern of 3.14 is loaded into GPR. + asm ("foo %0" :: "{r4}" (3.14)); +} + +/* +** test_double: +** ( +** ldr %f4,%f0 +** ldr %f5,%f2 +** | +** ldr %f5,%f2 +** ldr %f4,%f0 +** ) +** adbr %f5,%f4 +** ldr %f0,%f5 +** br %r14 +*/ + +double +test_double (double x, double y) +{ + asm ("adbr %0,%1" : "+{f5}" (y) : "{f4}" (x)); + return y; +} diff --git a/gcc/testsuite/gcc.target/s390/asm-hard-reg-4.c b/gcc/testsuite/gcc.target/s390/asm-hard-reg-4.c new file mode 100644 index 000000000000..29927ce18215 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/asm-hard-reg-4.c @@ -0,0 +1,6 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-options "-O2 -march=z13 -mzarch" } */ + +/* Test TARGET_MD_ASM_ADJUST for z13 and long double. */ + +#include "asm-hard-reg-longdouble.h" diff --git a/gcc/testsuite/gcc.target/s390/asm-hard-reg-5.c b/gcc/testsuite/gcc.target/s390/asm-hard-reg-5.c new file mode 100644 index 000000000000..eaf34d943797 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/asm-hard-reg-5.c @@ -0,0 +1,6 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-options "-O2 -march=z14 -mzarch" } */ + +/* Test TARGET_MD_ASM_ADJUST for z14 and long double. */ + +#include "asm-hard-reg-longdouble.h" diff --git a/gcc/testsuite/gcc.target/s390/asm-hard-reg-6.c b/gcc/testsuite/gcc.target/s390/asm-hard-reg-6.c new file mode 100644 index 000000000000..d0129667d5c5 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/asm-hard-reg-6.c @@ -0,0 +1,152 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void +test (void) +{ + // GPRs + { + int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p; + __asm__ __volatile__ ("%0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14" + : "=r" (a), + "=r" (b), + "=r" (c), + "=r" (d), + "=r" (e), + "=r" (f), + "=r" (g), + "=r" (h), + "=r" (i), + "=r" (j), + "=r" (k), + "=r" (l), + "=r" (m), + "=r" (n), + "=r" (o)); + __asm__ __volatile__ ("%0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14" + : "={r0}" (a), + "={r1}" (b), + "={r2}" (c), + "={r3}" (d), + "={r4}" (e), + "={r5}" (f), + "={r6}" (g), + "={r7}" (h), + "={r8}" (i), + "={r9}" (j), + "={r10}" (k), + "={r11}" (l), + "={r12}" (m), + "={r13}" (n), + "={r14}" (o)); + __asm__ __volatile__ ("%0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15" /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + : "=r" (a), + "=r" (b), + "=r" (c), + "=r" (d), + "=r" (e), + "=r" (f), + "=r" (g), + "=r" (h), + "=r" (i), + "=r" (j), + "=r" (k), + "=r" (l), + "=r" (m), + "=r" (n), + "=r" (o), + "=r" (p)); + __asm__ __volatile__ ("%0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15" /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + : "=r" (a), + "=r" (b), + "=r" (c), + "=r" (d), + "=r" (e), + "=r" (f), + "=r" (g), + "=r" (h), + "=r" (i), + "=r" (j), + "=r" (k), + "=r" (l), + "=r" (m), + "=r" (n), + "=r" (o), + "={r4}" (p)); + } + + // FPRs + { + float a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q; + __asm__ __volatile__ ("%0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15" + : "=f" (a), + "=f" (b), + "=f" (c), + "=f" (d), + "=f" (e), + "=f" (f), + "=f" (g), + "=f" (h), + "=f" (i), + "=f" (j), + "=f" (k), + "=f" (l), + "=f" (m), + "=f" (n), + "=f" (o), + "=f" (p)); + __asm__ __volatile__ ("%0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15" + : "={f0}" (a), + "={f1}" (b), + "={f2}" (c), + "={f3}" (d), + "={f4}" (e), + "={f5}" (f), + "={f6}" (g), + "={f7}" (h), + "={f8}" (i), + "={f9}" (j), + "={f10}" (k), + "={f11}" (l), + "={f12}" (m), + "={f13}" (n), + "={f14}" (o), + "={f15}" (p)); + __asm__ __volatile__ ("%0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16" /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + : "=f" (a), + "=f" (b), + "=f" (c), + "=f" (d), + "=f" (e), + "=f" (f), + "=f" (g), + "=f" (h), + "=f" (i), + "=f" (j), + "=f" (k), + "=f" (l), + "=f" (m), + "=f" (n), + "=f" (o), + "=f" (p), + "=f" (q)); + __asm__ __volatile__ ("%0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16" /* { dg-error "'asm' operand has impossible constraints or there are not enough registers" } */ + : "=f" (a), + "=f" (b), + "=f" (c), + "=f" (d), + "=f" (e), + "=f" (f), + "=f" (g), + "=f" (h), + "=f" (i), + "=f" (j), + "=f" (k), + "=f" (l), + "=f" (m), + "=f" (n), + "=f" (o), + "=f" (p), + "={f4}" (q)); + } +} diff --git a/gcc/testsuite/gcc.target/s390/asm-hard-reg-7.c b/gcc/testsuite/gcc.target/s390/asm-hard-reg-7.c new file mode 100644 index 000000000000..923c9d2aaa39 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/asm-hard-reg-7.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-march=z13" } */ + +/* Test register pairs. */ + +void +test (void) +{ + register double f0 __asm__ ("f0"); + register double f2 __asm__ ("f2"); + register long double f0f2 __asm__ ("f0"); + double x; + long double y; + + /* Outputs */ + __asm__ __volatile__ ("" : "=r" (f0), "=r" (f0f2)); + __asm__ __volatile__ ("" : "=r" (f0f2), "={f0}" (y)); /* { dg-error "multiple outputs to hard register: %f0" } */ + __asm__ __volatile__ ("" : "={f0}" (x), "=r" (f0f2)); /* { dg-error "multiple outputs to hard register: %f0" } */ + + __asm__ __volatile__ ("" : "=r" (f2), "=r" (f0f2)); + __asm__ __volatile__ ("" : "={f2}" (x), "={f0}" (y)); /* { dg-error "multiple outputs to hard register: %f2" } */ + __asm__ __volatile__ ("" : "=r" (f2), "={f0}" (y)); /* { dg-error "multiple outputs to hard register: %f2" } */ + __asm__ __volatile__ ("" : "={f2}" (x), "=r" (f0f2)); /* { dg-error "multiple outputs to hard register: %f2" } */ + + /* Inputs */ + __asm__ __volatile__ ("" :: "r" (f0), "r" (f0f2)); + __asm__ __volatile__ ("" :: "r" (f0f2), "{f0}" (y)); /* { dg-error "multiple inputs to hard register: %f0" } */ + __asm__ __volatile__ ("" :: "{f0}" (x), "r" (f0f2)); /* { dg-error "multiple inputs to hard register: %f0" } */ + + __asm__ __volatile__ ("" :: "r" (f2), "r" (f0f2)); + __asm__ __volatile__ ("" :: "{f2}" (x), "{f0}" (y)); /* { dg-error "multiple inputs to hard register: %f2" } */ + __asm__ __volatile__ ("" :: "r" (f2), "{f0}" (y)); /* { dg-error "multiple inputs to hard register: %f2" } */ + __asm__ __volatile__ ("" :: "{f2}" (x), "r" (f0f2)); /* { dg-error "multiple inputs to hard register: %f2" } */ +} diff --git a/gcc/testsuite/gcc.target/s390/asm-hard-reg-longdouble.h b/gcc/testsuite/gcc.target/s390/asm-hard-reg-longdouble.h new file mode 100644 index 000000000000..9f4adad2acc6 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/asm-hard-reg-longdouble.h @@ -0,0 +1,18 @@ +__attribute__ ((noipa)) +long double +test_longdouble (long double x) +{ + long double y; + asm ("sqxbr\t%0,%1" : "={f4}" (y) : "{f5}" (x)); + return y; +} + +int +main (void) +{ + long double x = test_longdouble (42.L); + long double y = 6.48074069840786023096596743608799656681773277430814773408787249757445105002862106857719481922686100006103515625L; + if (x != y) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/s390/fminmax-1.c b/gcc/testsuite/gcc.target/s390/fminmax-1.c new file mode 100644 index 000000000000..df10905f037a --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/fminmax-1.c @@ -0,0 +1,77 @@ +/* Check fmin/fmax expanders for scalars on VXE targets. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -march=z14 -mzarch" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +/* +** dofmaxl: +** vl (%v.),0\(%r3\),3 +** vl (%v.),0\(%r4\),3 +** wfmaxxb (%v.),\1,\2,4 +** vst \3,0\(%r2\),3 +** br %r14 +*/ +long double +dofmaxl (long double d1, long double d2) +{ + return __builtin_fmaxl (d1, d2); +} + +/* +** dofminl: +** vl (%v.),0\(%r3\),3 +** vl (%v.),0\(%r4\),3 +** wfminxb (%v.),\1,\2,4 +** vst \3,0\(%r2\),3 +** br %r14 +*/ +long double +dofminl (long double d1, long double d2) +{ + return __builtin_fminl (d1, d2); +} + +/* +** dofmax: +** wfmaxdb %v0,%v0,%v2,4 +** br %r14 +*/ +double +dofmax (double d1, double d2) +{ + return __builtin_fmax (d1, d2); +} + +/* +** dofmin: +** wfmindb %v0,%v0,%v2,4 +** br %r14 +*/ +double +dofmin (double d1, double d2) +{ + return __builtin_fmin (d1, d2); +} + +/* +** dofmaxf: +** wfmaxsb %v0,%v0,%v2,4 +** br %r14 +*/ +float +dofmaxf (float f1, float f2) +{ + return __builtin_fmaxf (f1, f2); +} + +/* +** dofminf: +** wfminsb %v0,%v0,%v2,4 +** br %r14 +*/ +float +dofminf (float f1, float f2) +{ + return __builtin_fminf (f1, f2); +} diff --git a/gcc/testsuite/gcc.target/s390/fminmax-2.c b/gcc/testsuite/gcc.target/s390/fminmax-2.c new file mode 100644 index 000000000000..ea37a0a821de --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/fminmax-2.c @@ -0,0 +1,29 @@ +/* Check fmin/fmax expanders for scalars on non-VXE targets. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -march=z13 -mzarch" } */ +/* { dg-final { scan-assembler-times "jg" 4 } } */ + +double +dofmax (double d1, double d2) +{ + return __builtin_fmax (d1, d2); +} + +double +dofmin (double d1, double d2) +{ + return __builtin_fmin (d1, d2); +} + +float +dofmaxf (float f1, float f2) +{ + return __builtin_fmaxf (f1, f2); +} + +float +dofminf (float f1, float f2) +{ + return __builtin_fminf (f1, f2); +} diff --git a/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-2.c b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-2.c index 2ff5a37c0f0a..e1c7806ad96f 100644 --- a/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-2.c +++ b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-2.c @@ -3,8 +3,10 @@ #include "isfinite-isinf-isnormal-signbit.h" -/* { dg-final { scan-assembler-times {tcxb\t%f[0-9]+,1365} 1 } } SIGNBIT long double */ -/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,1365} 1 } } SIGNBIT _Decimal128 */ +/* { dg-final { scan-assembler-times {tcxb\t%f[0-9]+,1365} 0 { target lp64 } } } SIGNBIT long double */ +/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,1365} 0 { target lp64 } } } SIGNBIT _Decimal128 */ +/* { dg-final { scan-assembler-times {tcxb\t%f[0-9]+,1365} 1 { target { ! lp64 } } } } SIGNBIT long double */ +/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,1365} 1 { target { ! lp64 } } } } SIGNBIT _Decimal128 */ /* { dg-final { scan-assembler-times {tcxb\t%f[0-9]+,4032} 1 } } ISFINITE long double */ /* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,4032} 1 } } ISFINITE _Decimal128 */ /* { dg-final { scan-assembler-times {tcxb\t%f[0-9]+,48} 1 } } ISINF long double */ diff --git a/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-3.c b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-3.c index 8f67553c7dac..5c9986d06006 100644 --- a/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-3.c +++ b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-3.c @@ -3,8 +3,10 @@ #include "isfinite-isinf-isnormal-signbit.h" -/* { dg-final { scan-assembler-times {wftcixb\t%v[0-9]+,%v[0-9]+,1365} 1 } } */ -/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,1365} 1 } } */ +/* { dg-final { scan-assembler-times {wftcixb\t%v[0-9]+,%v[0-9]+,1365} 0 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,1365} 0 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {wftcixb\t%v[0-9]+,%v[0-9]+,1365} 1 { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,1365} 1 { target { ! lp64 } } } } */ /* { dg-final { scan-assembler-times {wftcixb\t%v[0-9]+,%v[0-9]+,4032} 1 } } */ /* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,4032} 1 } } */ /* { dg-final { scan-assembler-times {wftcixb\t%v[0-9]+,%v[0-9]+,48} 1 } } */ diff --git a/gcc/testsuite/gcc.target/s390/signbit-1.c b/gcc/testsuite/gcc.target/s390/signbit-1.c new file mode 100644 index 000000000000..45f608a3f289 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/signbit-1.c @@ -0,0 +1,40 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -march=z900 -save-temps" } */ +/* { dg-final { scan-assembler-times {\ttceb\t} 2 } } */ +/* { dg-final { scan-assembler-times {\ttcdb\t} 2 } } */ +/* { dg-final { scan-assembler-times {\ttcxb\t} 2 } } */ + +/* Binary Floating-Point */ + +__attribute__ ((noipa)) +int signbit_float_reg (float x) { return __builtin_signbit (x); } +__attribute__ ((noipa)) +int signbit_float_mem (float *x) { return __builtin_signbit (*x); } +__attribute__ ((noipa)) +int signbit_double_reg (double x) { return __builtin_signbit (x); } +__attribute__ ((noipa)) +int signbit_double_mem (double *x) { return __builtin_signbit (*x); } + +__attribute__ ((noipa)) +int +signbit_longdouble_reg (long double x) +{ + __asm__ ("" : "+f" (x)); + return __builtin_signbit (x); +} + +__attribute__ ((noipa)) +int signbit_longdouble_mem (long double *x) { return __builtin_signbit (*x); } + +#include "signbit.h" +TEST (float, float, __builtin_inff(), __builtin_nanf("42"), 0.f, 42.f) +TEST (double, double, __builtin_inf(), __builtin_nan("42"), 0., 42.) +TEST (longdouble, long double, __builtin_infl(), __builtin_nanl("42"), 0.L, 42.L) + +int +main (void) +{ + test_float (); + test_double (); + test_longdouble (); +} diff --git a/gcc/testsuite/gcc.target/s390/signbit-2.c b/gcc/testsuite/gcc.target/s390/signbit-2.c new file mode 100644 index 000000000000..488c477c891a --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/signbit-2.c @@ -0,0 +1,40 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -march=z9-ec -mzarch -save-temps" } */ +/* { dg-final { scan-assembler-times {\ttdcet\t} 2 } } */ +/* { dg-final { scan-assembler-times {\ttdcdt\t} 2 } } */ +/* { dg-final { scan-assembler-times {\ttdcxt\t} 2 } } */ + +/* Decimal Floating-Point */ + +__attribute__ ((noipa)) +int signbit_dec32_reg (_Decimal32 x) { return __builtin_signbit (x); } +__attribute__ ((noipa)) +int signbit_dec32_mem (_Decimal32 *x) { return __builtin_signbit (*x); } +__attribute__ ((noipa)) +int signbit_dec64_reg (_Decimal64 x) { return __builtin_signbit (x); } +__attribute__ ((noipa)) +int signbit_dec64_mem (_Decimal64 *x) { return __builtin_signbit (*x); } + +__attribute__ ((noipa)) +int +signbit_dec128_reg (_Decimal128 x) +{ + __asm__ ("" : "+f" (x)); + return __builtin_signbit (x); +} + +__attribute__ ((noipa)) +int signbit_dec128_mem (_Decimal128 *x) { return __builtin_signbit (*x); } + +#include "signbit.h" +TEST (dec32, _Decimal32, __builtin_infd32(), __builtin_nand32("42"), 0.df, 42.df) +TEST (dec64, _Decimal64, __builtin_infd64(), __builtin_nand64("42"), 0.dd, 42.dd) +TEST (dec128, _Decimal128, __builtin_infd128(), __builtin_nand128("42"), 0.dl, 42.dl) + +int +main (void) +{ + test_dec32 (); + test_dec64 (); + test_dec128 (); +} diff --git a/gcc/testsuite/gcc.target/s390/signbit-3.c b/gcc/testsuite/gcc.target/s390/signbit-3.c new file mode 100644 index 000000000000..2fad58bf3be7 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/signbit-3.c @@ -0,0 +1,152 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-options "-O2 -march=z10 -save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* Binary Floating-Point */ + +/* +** signbit_float_reg: +** lgdr (%r[0-9]+),%f0 +** srlg (%r[0-9]+),\1,63 +** lgfr %r2,\2 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_float_reg (float x) { return __builtin_signbit (x); } + +/* +** signbit_float_mem: +** l (%r[0-9]+),0\(%r2\) +** srl \1,31 +** lgfr %r2,\1 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_float_mem (float *x) { return __builtin_signbit (*x); } + +/* +** signbit_double_reg: +** lgdr (%r[0-9]+),%f0 +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_double_reg (double x) { return __builtin_signbit (x); } + +/* +** signbit_double_mem: +** lg (%r[0-9]+),0\(%r2\) +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_double_mem (double *x) { return __builtin_signbit (*x); } + +/* +** signbit_longdouble_reg: +** ld %f0,0\(%r2\) +** ld %f2,8\(%r2\) +** lgdr (%r[0-9]+),%f0 +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int +signbit_longdouble_reg (long double x) +{ + __asm__ ("" : "+f" (x)); + return __builtin_signbit (x); +} + +/* +** signbit_longdouble_mem: +** lg (%r[0-9]+),0\(%r2\) +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_longdouble_mem (long double *x) { return __builtin_signbit (*x); } + +/* Decimal Floating-Point */ + +/* +** signbit_dec32_reg: +** lgdr (%r[0-9]+),%f0 +** srlg (%r[0-9]+),\1,63 +** lgfr %r2,\2 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_dec32_reg (_Decimal32 x) { return __builtin_signbit (x); } + +/* +** signbit_dec32_mem: +** l (%r[0-9]+),0\(%r2\) +** srl \1,31 +** lgfr %r2,\1 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_dec32_mem (_Decimal32 *x) { return __builtin_signbit (*x); } + +/* +** signbit_dec64_reg: +** lgdr (%r[0-9]+),%f0 +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_dec64_reg (_Decimal64 x) { return __builtin_signbit (x); } + +/* +** signbit_dec64_mem: +** lg (%r[0-9]+),0\(%r2\) +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_dec64_mem (_Decimal64 *x) { return __builtin_signbit (*x); } + +/* +** signbit_dec128_reg: +** ld %f0,0\(%r2\) +** ld %f2,8\(%r2\) +** lgdr (%r[0-9]+),%f0 +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int +signbit_dec128_reg (_Decimal128 x) +{ + __asm__ ("" : "+f" (x)); + return __builtin_signbit (x); +} + +/* +** signbit_dec128_mem: +** lg (%r[0-9]+),0\(%r2\) +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_dec128_mem (_Decimal128 *x) { return __builtin_signbit (*x); } + +#include "signbit.h" +TEST (float, float, __builtin_inff(), __builtin_nanf("42"), 0.f, 42.f) +TEST (double, double, __builtin_inf(), __builtin_nan("42"), 0., 42.) +TEST (longdouble, long double, __builtin_infl(), __builtin_nanl("42"), 0.L, 42.L) +TEST (dec32, _Decimal32, __builtin_infd32(), __builtin_nand32("42"), 0.df, 42.df) +TEST (dec64, _Decimal64, __builtin_infd64(), __builtin_nand64("42"), 0.dd, 42.dd) +TEST (dec128, _Decimal128, __builtin_infd128(), __builtin_nand128("42"), 0.dl, 42.dl) + +int +main (void) +{ + test_float (); + test_double (); + test_longdouble (); + test_dec32 (); + test_dec64 (); + test_dec128 (); +} diff --git a/gcc/testsuite/gcc.target/s390/signbit-4.c b/gcc/testsuite/gcc.target/s390/signbit-4.c new file mode 100644 index 000000000000..2cb743edc3ac --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/signbit-4.c @@ -0,0 +1,55 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-require-effective-target s390_vx } */ +/* { dg-options "-O2 -march=z13 -save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* Binary Floating-Point */ + +/* +** signbit_float_reg: +** vlgvf (%r[0-9]+),%v0,0 +** risbgn %r2,\1,64-1,128\+63,32\+1 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_float_reg (float x) { return __builtin_signbit (x); } + +/* +** signbit_float_mem: +** l (%r[0-9]+),0\(%r2\) +** risbgn %r2,\1,64-1,128\+63,32\+1 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_float_mem (float *x) { return __builtin_signbit (*x); } + +/* Decimal Floating-Point */ + +/* +** signbit_dec32_reg: +** vlgvf (%r[0-9]+),%v0,0 +** risbgn %r2,\1,64-1,128\+63,32\+1 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_dec32_reg (_Decimal32 x) { return __builtin_signbit (x); } + +/* +** signbit_dec32_mem: +** l (%r[0-9]+),0\(%r2\) +** risbgn %r2,\1,64-1,128\+63,32\+1 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_dec32_mem (_Decimal32 *x) { return __builtin_signbit (*x); } + +#include "signbit.h" +TEST (float, float, __builtin_inff(), __builtin_nanf("42"), 0.f, 42.f) +TEST (dec32, _Decimal32, __builtin_infd32(), __builtin_nand32("42"), 0.df, 42.df) + +int +main (void) +{ + test_float (); + test_dec32 (); +} diff --git a/gcc/testsuite/gcc.target/s390/signbit-5.c b/gcc/testsuite/gcc.target/s390/signbit-5.c new file mode 100644 index 000000000000..68403275f7ca --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/signbit-5.c @@ -0,0 +1,35 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-options "-O2 -march=z14 -save-temps" } */ + +/* +** signbit_longdouble_reg: +** ld %f0,0(%r2);ld %f2,8+0(%r2) +** lgdr (%r[0-9]+),%f0 +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int +signbit_longdouble_reg (long double x) +{ + __asm__ ("" : "+f" (x)); + return __builtin_signbit (x); +} + +/* +** signbit_longdouble_mem: +** lg (%r[0-9]+),0\(%r2\) +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_longdouble_mem (long double *x) { return __builtin_signbit (*x); } + +#include "signbit.h" +TEST (longdouble, long double, __builtin_infl(), __builtin_nanl("42"), 0.L, 42.L) + +int +main (void) +{ + test_longdouble (); +} diff --git a/gcc/testsuite/gcc.target/s390/signbit.h b/gcc/testsuite/gcc.target/s390/signbit.h new file mode 100644 index 000000000000..730e387752c4 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/signbit.h @@ -0,0 +1,36 @@ +#define TEST(T, U, I, N, C0, C42) \ + void test_##T (void) \ + { \ + U tmp; \ + int x; \ + \ + x = signbit_##T##_reg(C42); \ + x += signbit_##T##_reg(C0); \ + x += signbit_##T##_reg(I); \ + x += signbit_##T##_reg(N); \ + tmp = C42; \ + x += signbit_##T##_mem(&tmp); \ + tmp = C0; \ + x += signbit_##T##_mem(&tmp); \ + tmp = I; \ + x += signbit_##T##_mem(&tmp); \ + tmp = N; \ + x += signbit_##T##_mem(&tmp); \ + if (x != 0) \ + __builtin_abort(); \ + \ + x = signbit_##T##_reg(-C42); \ + x += signbit_##T##_reg(-C0); \ + x += signbit_##T##_reg(-I); \ + x += signbit_##T##_reg(-N); \ + tmp = -C42; \ + x += signbit_##T##_mem(&tmp); \ + tmp = -C0; \ + x += signbit_##T##_mem(&tmp); \ + tmp = -I; \ + x += signbit_##T##_mem(&tmp); \ + tmp = -N; \ + x += signbit_##T##_mem(&tmp); \ + if (x != 8) \ + __builtin_abort(); \ + } diff --git a/gcc/testsuite/gcc.target/s390/stack-protector-guard-tls-1.c b/gcc/testsuite/gcc.target/s390/stack-protector-guard-tls-1.c new file mode 100644 index 000000000000..1efd24551443 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/stack-protector-guard-tls-1.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fstack-protector-all" } */ +/* { dg-final { scan-assembler-times {\tear\t%r[0-9]+,%a[01]} 8 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {\tsllg\t%r[0-9]+,%r[0-9]+,32} 4 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {\tear\t%r[0-9]+,%a[01]} 3 { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler-times {\tmvc\t160\(8,%r15\),40\(%r[0-9]+\)} 2 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {\tmvc\t100\(4,%r15\),20\(%r[0-9]+\)} 2 { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler-times {\tclc\t160\(8,%r15\),40\(%r[0-9]+\)} 2 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {\tclc\t100\(4,%r15\),20\(%r[0-9]+\)} 2 { target { ! lp64 } } } } */ + +/* Computing the address of the thread pointer on s390 involves multiple + instructions and therefore bears the risk that the address of the canary or + intermediate values of it are spilled and reloaded. Therefore, as a + precaution compute the address always twice, i.e., one time for the prologue + and one time for the epilogue. */ + +void test_0 (void) { } + +void test_1 (void) +{ + __asm__ __volatile ("" ::: + "r0", + "r1", + "r2", + "r3", + "r4", + "r5", + "r6", + "r7", + "r8", + "r9", + "r10", + "r11", +#ifndef __PIC__ + "r12", +#endif + "r13", + "r14"); +} diff --git a/gcc/testsuite/gcc.target/s390/vector/pattern-avg-1.c b/gcc/testsuite/gcc.target/s390/vector/pattern-avg-1.c new file mode 100644 index 000000000000..285ebc9a3a56 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/pattern-avg-1.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -march=z16 -ftree-vectorize -fdump-tree-optimized" } */ + +#define TEST(T1,T2,N) \ + void \ + avg##T1 (signed T1 *__restrict res, signed T1 *__restrict a, \ + signed T1 *__restrict b) \ + { \ + for (int i = 0; i < N; ++i) \ + res[i] = ((signed T2)a[i] + b[i] + 1) >> 1; \ + } \ + \ + void \ + uavg##T1 (unsigned T1 *__restrict res, unsigned T1 *__restrict a, \ + unsigned T1 *__restrict b) \ + { \ + for (int i = 0; i < N; ++i) \ + res[i] = ((unsigned T2)a[i] + b[i] + 1) >> 1; \ + } + +TEST(char,short,16) +TEST(short,int,8) +TEST(int,long,4) + +/* { dg-final { scan-tree-dump-times "\.AVG_CEIL" 6 "optimized" { target lp64 } } } */ +/* { dg-final { scan-tree-dump-times "\.AVG_CEIL" 4 "optimized" { target { ! lp64 } } } } */ diff --git a/gcc/testsuite/gcc.target/s390/vector/pattern-avg-2.c b/gcc/testsuite/gcc.target/s390/vector/pattern-avg-2.c new file mode 100644 index 000000000000..1cc614eb1dea --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/pattern-avg-2.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O3 -mzarch -march=z16 -ftree-vectorize -fdump-tree-optimized" } */ + +#define TEST(T1,T2,N) \ + void \ + avg##T1 (signed T1 *__restrict res, signed T1 *__restrict a, \ + signed T1 *__restrict b) \ + { \ + for (int i = 0; i < N; ++i) \ + res[i] = ((signed T2)a[i] + b[i] + 1) >> 1; \ + } \ + \ + void \ + uavg##T1 (unsigned T1 *__restrict res, unsigned T1 *__restrict a, \ + unsigned T1 *__restrict b) \ + { \ + for (int i = 0; i < N; ++i) \ + res[i] = ((unsigned T2)a[i] + b[i] + 1) >> 1; \ + } + +TEST(long,__int128,2) + +/* { dg-final { scan-tree-dump-times "\.AVG_CEIL" 2 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/s390/vector/pattern-mulh-1.c b/gcc/testsuite/gcc.target/s390/vector/pattern-mulh-1.c new file mode 100644 index 000000000000..f0b37d63847c --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/pattern-mulh-1.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -march=arch15 -ftree-vectorize -fdump-tree-optimized" } */ + +#define TEST(T1,T2,N,S) \ + void \ + mulh##T1 (signed T1 *__restrict res, \ + signed T1 *__restrict l, \ + signed T1 *__restrict r) \ + { \ + for (int i = 0; i < N; ++i) \ + res[i] = (signed T1) (((signed T2)l[i] * (signed T2)r[i]) >> S); \ + } \ + \ + void \ + umulh##T1 (unsigned T1 *__restrict res, \ + unsigned T1 *__restrict l, \ + unsigned T1 *__restrict r) \ + { \ + for (int i = 0; i < N; ++i) \ + res[i] = (unsigned T1) \ + (((unsigned T2)l[i] * (unsigned T2)r[i]) >> S); \ + } + +TEST(char,short,16,8) +TEST(short,int,8,16) + +/* { dg-final { scan-tree-dump-times "\.MULH" 4 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/s390/vector/pattern-mulh-2.c b/gcc/testsuite/gcc.target/s390/vector/pattern-mulh-2.c new file mode 100644 index 000000000000..2ff66b7ffaad --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/pattern-mulh-2.c @@ -0,0 +1,27 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O3 -mzarch -march=arch15 -ftree-vectorize -fdump-tree-optimized" } */ + +#define TEST(T1,T2,N,S) \ + void \ + mulh##T1 (signed T1 *__restrict res, \ + signed T1 *__restrict l, \ + signed T1 *__restrict r) \ + { \ + for (int i = 0; i < N; ++i) \ + res[i] = (signed T1) (((signed T2)l[i] * (signed T2)r[i]) >> S); \ + } \ + \ + void \ + umulh##T1 (unsigned T1 *__restrict res, \ + unsigned T1 *__restrict l, \ + unsigned T1 *__restrict r) \ + { \ + for (int i = 0; i < N; ++i) \ + res[i] = (unsigned T1) \ + (((unsigned T2)l[i] * (unsigned T2)r[i]) >> S); \ + } + +TEST(int,long,4,32) +TEST(long,__int128,2,64) + +/* { dg-final { scan-tree-dump-times "\.MULH" 4 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/s390/vector/reduc-binops-1.c b/gcc/testsuite/gcc.target/s390/vector/reduc-binops-1.c new file mode 100644 index 000000000000..efd3294a7350 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/reduc-binops-1.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -march=z13 -ftree-vectorize -fdump-tree-optimized" } */ + +#define T(X,N) \ + unsigned X \ + reduce_and_##X (unsigned X *in) \ + { \ + unsigned X acc = (unsigned X)-1; \ + for (int i = 0; i < N; i++) \ + acc &= in[i]; \ + return acc; \ + } \ + unsigned X \ + reduce_ior_##X (unsigned X *in) \ + { \ + unsigned X acc = 0; \ + for (int i = 0; i < N; i++) \ + acc |= in[i]; \ + return acc; \ + } \ + unsigned X \ + redue_xor_##X (unsigned X *in) \ + { \ + unsigned X acc = 0; \ + for (int i = 0; i < N; i++) \ + acc ^= in[i]; \ + return acc; \ + } + +T(char,16) + +T(short, 8) + +T(int,4) + +T(long,4) + +/* { dg-final { scan-tree-dump-times "\.REDUC_AND" 4 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.REDUC_IOR" 4 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.REDUC_XOR" 4 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/s390/vector/reduc-minmax-1.c b/gcc/testsuite/gcc.target/s390/vector/reduc-minmax-1.c new file mode 100644 index 000000000000..5295250dcb74 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/reduc-minmax-1.c @@ -0,0 +1,234 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -march=z14 -ftree-vectorize -fdump-tree-optimized" } */ + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) > (b) ? (b) : (a)) + +/* unsigned integers */ + +unsigned char +reduce_umax_char (unsigned char *p) +{ + unsigned char res = p[0]; + for (int i = 0; i < 16; i++) + res = MAX (res, p[i]); + return res; +} + +unsigned char +reduce_umin_char (unsigned char *p) +{ + unsigned char res = p[0]; + for (int i = 0; i < 16; i++) + res = MIN (res, p[i]); + return res; +} + +unsigned short +reduce_umax_short (unsigned short *p) +{ + unsigned short res = p[0]; + for (int i = 0; i < 8; i++) + res = MAX (res, p[i]); + return res; +} + +unsigned short +reduce_umin_short (unsigned short *p) +{ + unsigned short res = p[0]; + for (int i = 0; i < 8; i++) + res = MIN (res, p[i]); + return res; +} + +unsigned int +reduce_umax_int (unsigned int* p) +{ + unsigned int res = p[0]; + for (int i = 0; i != 4; i++) + res = MAX (res, p[i]); + return res; +} + +unsigned int +reduce_umin_int (unsigned int* p) +{ + unsigned int res = p[0]; + for (int i = 0; i != 4; i++) + res = MIN(res, p[i]); + return res; +} + +unsigned long +reduce_umax_long (unsigned long* p) +{ + unsigned long res = p[0]; + for (int i = 0; i != 4; i++) + res = MAX (res, p[i]); + return res; +} + +unsigned long +reduce_umin_long (unsigned long* p) +{ + unsigned long res = p[0]; + for (int i = 0; i != 4; i++) + res = MIN(res, p[i]); + return res; +} + +/* signed integers */ + +signed char +reduce_smax_char (signed char *p) +{ + signed char res = p[0]; + for (int i = 0; i < 16; i++) + res = MAX (res, p[i]); + return res; +} + +signed char +reduce_smin_char (signed char *p) +{ + signed char res = p[0]; + for (int i = 0; i < 16; i++) + res = MIN (res, p[i]); + return res; +} + +signed short +reduce_smax_short (signed short *p) +{ + signed short res = p[0]; + for (int i = 0; i < 8; i++) + res = MAX (res, p[i]); + return res; +} + +signed short +reduce_smin_short (signed short *p) +{ + signed short res = p[0]; + for (int i = 0; i < 8; i++) + res = MIN (res, p[i]); + return res; +} + +signed int +reduce_smax_int (signed int* p) +{ + signed int res = p[0]; + for (int i = 0; i != 4; i++) + res = MAX (res, p[i]); + return res; +} + +signed int +reduce_smin_int (signed int* p) +{ + signed int res = p[0]; + for (int i = 0; i != 4; i++) + res = MIN(res, p[i]); + return res; +} + +signed long +reduce_smax_long (signed long* p) +{ + signed long res = p[0]; + for (int i = 0; i != 4; i++) + res = MAX (res, p[i]); + return res; +} + +signed long +reduce_smin_long (signed long* p) +{ + signed long res = p[0]; + for (int i = 0; i != 4; i++) + res = MIN(res, p[i]); + return res; +} + +float +__attribute__((optimize("Ofast"))) +reduce_smax_float (float* p) +{ + float res = p[0]; + for (int i = 0; i != 4; i++) + res = MAX (res, p[i]); + return res; +} + +float +__attribute__((optimize("Ofast"))) +reduce_smin_float (float* p) +{ + float res = p[0]; + for (int i = 0; i != 4; i++) + res = MIN (res, p[i]); + return res; +} + +double +__attribute__((optimize("Ofast"))) +reduce_smax_double (double* p) +{ + double res = p[0]; + for (int i = 0; i != 4; i++) + res = MAX (res, p[i]); + return res; +} + +double +__attribute__((optimize("Ofast"))) +reduce_smin_double (double* p) +{ + double res = p[0]; + for (int i = 0; i != 4; i++) + res = MIN (res, p[i]); + return res; +} + +float +reduce_fmax_float (float* p) +{ + float res = p[0]; + for (int i = 0; i != 4; i++) + res = __builtin_fmaxf (res, p[i]); + return res; +} + +float +reduce_fmin_float (float* p) +{ + float res = p[0]; + for (int i = 0; i != 4; i++) + res = __builtin_fminf (res, p[i]); + return res; +} + +double +reduce_fmax_double (double* p) +{ + double res = p[0]; + for (int i = 0; i != 4; i++) + res = __builtin_fmax (res, p[i]); + return res; +} + +double +reduce_fmin_double (double* p) +{ + double res = p[0]; + for (int i = 0; i != 4; i++) + res = __builtin_fmin (res, p[i]); + return res; +} + +/* { dg-final { scan-tree-dump-times "\.REDUC_MAX" 10 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.REDUC_MIN" 10 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.REDUC_FMAX" 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.REDUC_FMIN" 2 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/s390/vector/reduc-plus-1.c b/gcc/testsuite/gcc.target/s390/vector/reduc-plus-1.c new file mode 100644 index 000000000000..12cdd5f0ee1e --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/reduc-plus-1.c @@ -0,0 +1,152 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -march=z14 -ftree-vectorize -fdump-tree-optimized" } */ +/* { dg-do run { target { s390_z14_hw } } } */ + +/* signed integers */ + +signed char +__attribute__((noipa, optimize("Ofast"))) +reduce_add_char (signed char* p) +{ + signed char sum = 0; + for (int i = 0; i != 16; i++) + sum += p[i]; + return sum; +} + +short +__attribute__((noipa, optimize("Ofast"))) +reduce_add_short (short* p) +{ + short sum = 0; + for (int i = 0; i != 16; i++) + sum += p[i]; + return sum; +} + +int +__attribute__((noipa, optimize("Ofast"))) +reduce_add_int (int* p) +{ + int sum = 0; + for (int i = 0; i != 16; i++) + sum += p[i]; + return sum; +} + +long +__attribute__((noipa, optimize("Ofast"))) +reduce_add_long (long* p) +{ + long sum = 0; + for (int i = 0; i != 16; i++) + sum += p[i]; + return sum; +} + +/* unsigned integers */ + +unsigned char +__attribute__((noipa, optimize("Ofast"))) +reduce_add_uchar (unsigned char* p) +{ + unsigned char sum = 0; + for (int i = 0; i != 16; i++) + sum += p[i]; + return sum; +} + +unsigned short +__attribute__((noipa, optimize("Ofast"))) +reduce_add_ushort (unsigned short* p) +{ + unsigned short sum = 0; + for (int i = 0; i != 16; i++) + sum += p[i]; + return sum; +} + +unsigned int +__attribute__((noipa, optimize("Ofast"))) +reduce_add_uint (unsigned int* p) +{ + unsigned int sum = 0; + for (int i = 0; i != 16; i++) + sum += p[i]; + return sum; +} + +unsigned long +__attribute__((noipa, optimize("Ofast"))) +reduce_add_ulong (unsigned long* p) +{ + unsigned long sum = 0; + for (int i = 0; i != 16; i++) + sum += p[i]; + return sum; +} + +/* floating point */ + +float +__attribute__((noipa, optimize("Ofast"))) +reduce_add_float (float* p) +{ + float sum = 0; + for (int i = 0; i != 16; i++) + sum += p[i]; + return sum; +} + +double +__attribute__((noipa, optimize("Ofast"))) +reduce_add_double (double* p) +{ + double sum = 0; + for (int i = 0; i != 16; i++) + sum += p[i]; + return sum; +} + +int +main() +{ + signed char chararr[] = {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16}; + signed short shortarr[] = {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16}; + signed int intarr[] = {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16}; + signed long longarr[] = {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16}; + + unsigned char uchararr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; + unsigned short ushortarr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; + unsigned int uintarr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; + unsigned long ulongarr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; + + float floatarr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; + double doublearr[] = {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16}; + + if (reduce_add_char (chararr) != (-136 & 0xff)) + __builtin_abort(); + if (reduce_add_short (shortarr) != -136) + __builtin_abort(); + if (reduce_add_int (intarr) != -136) + __builtin_abort(); + if (reduce_add_long (longarr) != -136) + __builtin_abort(); + + if (reduce_add_uchar (uchararr) != 136) + __builtin_abort(); + if (reduce_add_ushort (ushortarr) != 136) + __builtin_abort(); + if (reduce_add_uint (uintarr) != 136) + __builtin_abort(); + if (reduce_add_ulong (ulongarr) != 136) + __builtin_abort(); + + if (reduce_add_float (floatarr) != 136) + __builtin_abort(); + if (reduce_add_double (doublearr) != -136) + __builtin_abort(); + return 0; +} + +/* { dg-final { scan-tree-dump-times "\.REDUC_PLUS" 10 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c b/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c index e0dd222e62c7..2fcaa959828c 100644 --- a/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c +++ b/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O3 -mzarch -march=z13 -save-temps" } */ +/* { dg-options "-O3 -mzarch -march=z13 -save-temps -fno-stack-protector" } */ /* { dg-require-effective-target int128 } */ /* { dg-final { check-function-bodies "**" "" "" } } */ /* { dg-final { scan-assembler-not {\tvlpq\t} } } */ diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-extract-1.c b/gcc/testsuite/gcc.target/s390/vector/vec-extract-1.c index 9df7909a3ea8..83af839963be 100644 --- a/gcc/testsuite/gcc.target/s390/vector/vec-extract-1.c +++ b/gcc/testsuite/gcc.target/s390/vector/vec-extract-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -march=z14 -mzarch" } */ +/* { dg-options "-O2 -march=arch11 -mzarch" } */ /* { dg-final { check-function-bodies "**" "" } } */ typedef double V2DF __attribute__((vector_size(16))); @@ -110,17 +110,6 @@ extractnthfloat (V4SF x, int n) return x[n]; } -/* -** sumfirstfloat: -** vfasb %v0,%v24,%v26 -** br %r14 -*/ -float -sumfirstfloat (V4SF x, V4SF y) -{ - return (x + y)[0]; -} - /* ** extractfirst2: ** vlr %v0,%v24 @@ -179,8 +168,7 @@ extractsingled (V1DF x) /* ** extractsingleld: -** vlr (%v.),%v24 -** vst \1,0\(%r2\),3 +** vst %v24,0\(%r2\),3 ** br %r14 */ long double diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-extract-2.c b/gcc/testsuite/gcc.target/s390/vector/vec-extract-2.c new file mode 100644 index 000000000000..640ac0c8c766 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/vec-extract-2.c @@ -0,0 +1,168 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=arch11 -mzarch" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +typedef double V2DF __attribute__((vector_size(16))); +typedef float V4SF __attribute__((vector_size(16))); +typedef float V2SF __attribute__((vector_size(8))); +typedef double V1DF __attribute__((vector_size(8))); +typedef float V1SF __attribute__((vector_size(4))); +typedef long double V1TF __attribute__((vector_size(16))); + +/* +** extractfirstdouble: +** vsteg %v24,0\(%r2\),0 +** br %r14 +*/ +void +extractfirstdouble (double *res, V2DF x) +{ + *res = x[0]; +} + +/* +** extractseconddouble: +** vsteg %v24,0\(%r2\),1 +** br %r14 +*/ +void +extractseconddouble (double *res, V2DF x) +{ + *res = x[1]; +} + +/* +** extractnthdouble: +** vlgvg (%r.),%v24,0\(%r3\) +** stg \1,0\(%r2\) +** br %r14 +*/ +void +extractnthdouble (double *res, V2DF x, int n) +{ + *res = x[n]; +} + +/* +** extractfirstfloat: +** vstef %v24,0\(%r2\),0 +** br %r14 +*/ +void +extractfirstfloat (float *res, V4SF x) +{ + *res = x[0]; +} + +/* +** extractsecondfloat: +** vstef %v24,0\(%r2\),1 +** br %r14 +*/ +void +extractsecondfloat (float *res, V4SF x) +{ + *res = x[1]; +} + +/* +** extractthirdfloat: +** vstef %v24,0\(%r2\),2 +** br %r14 +*/ +void +extractthirdfloat (float *res, V4SF x) +{ + *res = x[2]; +} + +/* +** extractfourthfloat: +** vstef %v24,0\(%r2\),3 +** br %r14 +*/ +void +extractfourthfloat (float *res, V4SF x) +{ + *res = x[3]; +} + +/* +** extractnthfloat: +** vlgvf (%r.),%v24,0\(%r3\) +** st \1,0\(%r2\) +** br %r14 +*/ +void +extractnthfloat (float *res, V4SF x, int n) +{ + *res = x[n]; +} + +/* +** extractfirst2: +** vstef %v24,0\(%r2\),0 +** br %r14 +*/ +void +extractfirst2 (float *res, V2SF x) +{ + *res = x[0]; +} + +/* +** extractsecond2: +** vstef %v24,0\(%r2\),1 +** br %r14 +*/ +void +extractsecond2 (float *res, V2SF x) +{ + *res = x[1]; +} + +/* +** extractnth2: +** vlgvf (%r.),%v24,0\(%r3\) +** st \1,0\(%r2\) +** br %r14 +*/ +void +extractnth2 (float *res, V2SF x, int n) +{ + *res = x[n]; +} + +/* +** extractsinglef: +** vlr %v(.),%v24 +** ste %f\1,0\(%r2\) +** br %r14 +*/ +void +extractsinglef (float *res, V1SF x) +{ + *res = x[0]; +} + +/* +** extractsingled: +** vsteg %v24,0\(%r2\),0 +** br %r14 +*/ +void +extractsingled (double *res, V1DF x) +{ + *res = x[0]; +} + +/* +** extractsingleld: +** vst %v24,0\(%r2\),3 +** br %r14 +*/ +void +extractsingleld (long double *res, V1TF x) +{ + *res = x[0]; +} diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c b/gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c index 12c7e76edc19..16afd1d72d31 100644 --- a/gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c +++ b/gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O3 -mzarch -march=z13 -save-temps" } */ +/* { dg-options "-O3 -mzarch -march=z13 -save-temps -fno-stack-protector" } */ /* { dg-require-effective-target int128 } */ /* { dg-final { check-function-bodies "**" "" "" } } */ /* { dg-final { scan-assembler-not {\tvmxq\t} } } */ diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c b/gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c index a9bcba39e224..0eb09169cc84 100644 --- a/gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c +++ b/gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O3 -mzarch -march=z13 -save-temps" } */ +/* { dg-options "-O3 -mzarch -march=z13 -save-temps -fno-stack-protector" } */ /* { dg-require-effective-target int128 } */ /* { dg-final { check-function-bodies "**" "" "" } } */ /* { dg-final { scan-assembler-not {\tvmnq\t} } } */ diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-perm-merge-1.c b/gcc/testsuite/gcc.target/s390/vector/vec-perm-merge-1.c new file mode 100644 index 000000000000..79f8a882ef92 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/vec-perm-merge-1.c @@ -0,0 +1,242 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -march=z14 -mzvector --save-temps -fno-stack-protector" } */ +/* { dg-do run { target { s390_z14_hw } } } */ +/* { dg-final {check-function-bodies "**" "" } } */ + +#include "vec-types.h" + +/* +** qi_via_hi_hi: +** vmrhh %v24,%v24,%v26 +** br %r14 +*/ +v16qi __attribute__((noinline,noipa)) +qi_via_hi_hi (v16qi a, v16qi b) +{ + return (v16qi){a[0], a[1], b[0], b[1], a[2], a[3], b[2], b[3], + a[4], a[5], b[4], b[5], a[6], a[7], b[6], b[7]}; +} + +/* +** qi_via_hi_lo: +** vmrlh %v24,%v24,%v26 +** br %r14 +*/ +v16qi __attribute__((noinline,noipa)) +qi_via_hi_lo (v16qi a, v16qi b) +{ + return (v16qi){a[8], a[9], b[8], b[9], a[10], a[11], b[10], b[11], + a[12], a[13], b[12], b[13], a[14], a[15], b[14], b[15]}; +} + +/* +** qi_via_si_hi: +** vmrhf %v24,%v24,%v26 +** br %r14 +*/ +v16qi __attribute__((noinline,noipa)) +qi_via_si_hi (v16qi a, v16qi b) +{ + return (v16qi){a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3], + a[4], a[5], a[6], a[7], b[4], b[5], b[6], b[7]}; +} + +/* +** qi_via_si_lo: +** vmrlf %v24,%v24,%v26 +** br %r14 +*/ +v16qi __attribute__((noinline,noipa)) +qi_via_si_lo (v16qi a, v16qi b) +{ + return (v16qi){a[8], a[9], a[10], a[11], b[8], b[9], b[10], b[11], + a[12], a[13], a[14], a[15], b[12], b[13], b[14], b[15]}; +} + +/* +** qi_via_di_hi: +** vmrhg %v24,%v24,%v26 +** br %r14 +*/ +v16qi __attribute__((noinline,noipa)) +qi_via_di_hi (v16qi a, v16qi b) +{ + return (v16qi){a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]}; +} + +/* +** qi_via_di_lo: +** vmrlg %v24,%v24,%v26 +** br %r14 +*/ +v16qi __attribute__((noinline,noipa)) +qi_via_di_lo (v16qi a, v16qi b) +{ + return (v16qi){a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], + b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]}; +} + +/* +** hi_via_si_hi: +** vmrhf %v24,%v24,%v26 +** br %r14 +*/ +v8hi __attribute__((noinline,noipa)) +hi_via_si_hi (v8hi a, v8hi b) +{ + return (v8hi){a[0], a[1], b[0], b[1], a[2], a[3], b[2], b[3]}; +} + +/* +** hi_via_si_lo: +** vmrlf %v24,%v24,%v26 +** br %r14 +*/ +v8hi __attribute__((noinline,noipa)) +hi_via_si_lo (v8hi a, v8hi b) +{ + return (v8hi){a[4], a[5], b[4], b[5], a[6], a[7], b[6], b[7]}; +} + +/* +** hi_via_di_hi: +** vmrhg %v24,%v24,%v26 +** br %r14 +*/ +v8hi __attribute__((noinline,noipa)) +hi_via_di_hi (v8hi a, v8hi b) +{ + return (v8hi){a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]}; +} + +/* +** hi_via_di_lo: +** vmrlg %v24,%v24,%v26 +** br %r14 +*/ +v8hi __attribute__((noinline,noipa)) +hi_via_di_lo (v8hi a, v8hi b) +{ + return (v8hi){a[4], a[5], a[6], a[7], b[4], b[5], b[6], b[7]}; +} + +/* +** si_via_di_hi: +** vmrhg %v24,%v24,%v26 +** br %r14 +*/ +v4si __attribute__((noinline,noipa)) +si_via_di_hi (v4si a, v4si b) +{ + return (v4si){a[0], a[1], b[0], b[1]}; +} + +/* +** si_via_di_lo: +** vmrlg %v24,%v24,%v26 +** br %r14 +*/ +v4si __attribute__((noinline,noipa)) +si_via_di_lo (v4si a, v4si b) +{ + return (v4si){a[2], a[3], b[2], b[3]}; +} + +int +main () +{ + static const signed char e_qi_via_hi_hi[16] + = {0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23}; + static const signed char e_qi_via_hi_lo[16] + = {8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31}; + static const signed char e_qi_via_si_hi[16] + = {0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23}; + static const signed char e_qi_via_si_lo[16] + = {8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31}; + static const signed char e_qi_via_di_hi[16] + = {0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}; + static const signed char e_qi_via_di_lo[16] + = {8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}; + + static const short e_hi_via_si_hi[8] = {0, 1, 8, 9, 2, 3, 10, 11}; + static const short e_hi_via_si_lo[8] = {4, 5, 12, 13, 6, 7, 14, 15}; + static const short e_hi_via_di_hi[8] = {0, 1, 2, 3, 8, 9, 10, 11}; + static const short e_hi_via_di_lo[8] = {4, 5, 6, 7, 12, 13, 14, 15}; + + static const int e_si_via_di_hi[4] = {0, 1, 4, 5}; + static const int e_si_via_di_lo[4] = {2, 3, 6, 7}; + + v16qi a_qi = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + v16qi b_qi = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + v8hi a_hi = {0, 1, 2, 3, 4, 5, 6, 7}; + v8hi b_hi = {8, 9, 10, 11, 12, 13, 14, 15}; + v4si a_si = {0, 1, 2, 3}; + v4si b_si = {4, 5, 6, 7}; + v16qi r_qi; + v8hi r_hi; + v4si r_si; + int i; + + r_qi = qi_via_hi_hi (a_qi, b_qi); + for (i = 0; i < 16; ++i) + if (r_qi[i] != e_qi_via_hi_hi[i]) + __builtin_abort (); + + r_qi = qi_via_hi_lo (a_qi, b_qi); + for (i = 0; i < 16; ++i) + if (r_qi[i] != e_qi_via_hi_lo[i]) + __builtin_abort (); + + r_qi = qi_via_si_hi (a_qi, b_qi); + for (i = 0; i < 16; ++i) + if (r_qi[i] != e_qi_via_si_hi[i]) + __builtin_abort (); + + r_qi = qi_via_si_lo (a_qi, b_qi); + for (i = 0; i < 16; ++i) + if (r_qi[i] != e_qi_via_si_lo[i]) + __builtin_abort (); + + r_qi = qi_via_di_hi (a_qi, b_qi); + for (i = 0; i < 16; ++i) + if (r_qi[i] != e_qi_via_di_hi[i]) + __builtin_abort (); + + r_qi = qi_via_di_lo (a_qi, b_qi); + for (i = 0; i < 16; ++i) + if (r_qi[i] != e_qi_via_di_lo[i]) + __builtin_abort (); + + r_hi = hi_via_si_hi (a_hi, b_hi); + for (i = 0; i < 8; ++i) + if (r_hi[i] != e_hi_via_si_hi[i]) + __builtin_abort (); + + r_hi = hi_via_si_lo (a_hi, b_hi); + for (i = 0; i < 8; ++i) + if (r_hi[i] != e_hi_via_si_lo[i]) + __builtin_abort (); + + r_hi = hi_via_di_hi (a_hi, b_hi); + for (i = 0; i < 8; ++i) + if (r_hi[i] != e_hi_via_di_hi[i]) + __builtin_abort (); + + r_hi = hi_via_di_lo (a_hi, b_hi); + for (i = 0; i < 8; ++i) + if (r_hi[i] != e_hi_via_di_lo[i]) + __builtin_abort (); + + r_si = si_via_di_hi (a_si, b_si); + for (i = 0; i < 4; ++i) + if (r_si[i] != e_si_via_di_hi[i]) + __builtin_abort (); + + r_si = si_via_di_lo (a_si, b_si); + for (i = 0; i < 4; ++i) + if (r_si[i] != e_si_via_di_lo[i]) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-perm-pack-1.c b/gcc/testsuite/gcc.target/s390/vector/vec-perm-pack-1.c new file mode 100644 index 000000000000..6590c9298cf5 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/vec-perm-pack-1.c @@ -0,0 +1,133 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -march=z14 -mzvector --save-temps -fno-stack-protector" } */ +/* { dg-do run { target { s390_z14_hw } } } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include "vec-types.h" + +/* +** qi_via_hi: +** vpkh %v24,%v24,%v26 +** br %r14 +*/ +v16qi __attribute__((noinline,noipa)) +qi_via_hi (v16qi a, v16qi b) +{ + return (v16qi){a[1], a[3], a[5], a[7], a[9], a[11], a[13], a[15], + b[1], b[3], b[5], b[7], b[9], b[11], b[13], b[15]}; +} + +/* +** qi_via_si: +** vpkf %v24,%v24,%v26 +** br %r14 +*/ +v16qi __attribute__((noinline,noipa)) +qi_via_si (v16qi a, v16qi b) +{ + return (v16qi){a[2], a[3], a[6], a[7], a[10], a[11], a[14], a[15], + b[2], b[3], b[6], b[7], b[10], b[11], b[14], b[15]}; +} + +/* +** qi_via_di: +** vpkg %v24,%v24,%v26 +** br %r14 +*/ +v16qi __attribute__((noinline,noipa)) +qi_via_di (v16qi a, v16qi b) +{ + return (v16qi){a[4], a[5], a[6], a[7], a[12], a[13], a[14], a[15], + b[4], b[5], b[6], b[7], b[12], b[13], b[14], b[15]}; +} + +/* +** hi_via_si: +** vpkf %v24,%v24,%v26 +** br %r14 +*/ +v8hi __attribute__((noinline,noipa)) +hi_via_si (v8hi a, v8hi b) +{ + return (v8hi){a[1], a[3], a[5], a[7], b[1], b[3], b[5], b[7]}; +} + +/* +** hi_via_di: +** vpkg %v24,%v24,%v26 +** br %r14 +*/ +v8hi __attribute__((noinline,noipa)) +hi_via_di (v8hi a, v8hi b) +{ + return (v8hi){a[2], a[3], a[6], a[7], b[2], b[3], b[6], b[7]}; +} + +/* +** si_via_di: +** vpkg %v24,%v24,%v26 +** br %r14 +*/ +v4si __attribute__((noinline,noipa)) +si_via_di (v4si a, v4si b) +{ + return (v4si){a[1], a[3], b[1], b[3]}; +} + +int +main () +{ + static const signed char e_qi_via_hi[16] + = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}; + static const signed char e_qi_via_si[16] + = {2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31}; + static const signed char e_qi_via_di[16] + = {4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31}; + + static const short e_hi_via_si[8] = {1, 3, 5, 7, 9, 11, 13, 15}; + static const short e_hi_via_di[8] = {2, 3, 6, 7, 10, 11, 14, 15}; + + static const int e_si_via_di[4] = {1, 3, 5, 7}; + + v16qi a_qi = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + v16qi b_qi = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + v8hi a_hi = {0, 1, 2, 3, 4, 5, 6, 7}; + v8hi b_hi = {8, 9, 10, 11, 12, 13, 14, 15}; + v4si a_si = {0, 1, 2, 3}; + v4si b_si = {4, 5, 6, 7}; + v16qi r_qi; + v8hi r_hi; + v4si r_si; + int i; + + r_qi = qi_via_hi (a_qi, b_qi); + for (i = 0; i < 16; ++i) + if (r_qi[i] != e_qi_via_hi[i]) + __builtin_abort (); + + r_qi = qi_via_si (a_qi, b_qi); + for (i = 0; i < 16; ++i) + if (r_qi[i] != e_qi_via_si[i]) + __builtin_abort (); + + r_qi = qi_via_di (a_qi, b_qi); + for (i = 0; i < 16; ++i) + if (r_qi[i] != e_qi_via_di[i]) + __builtin_abort (); + + r_hi = hi_via_si (a_hi, b_hi); + for (i = 0; i < 8; ++i) + if (r_hi[i] != e_hi_via_si[i]) + __builtin_abort (); + + r_hi = hi_via_di (a_hi, b_hi); + for (i = 0; i < 8; ++i) + if (r_hi[i] != e_hi_via_di[i]) + __builtin_abort (); + + r_si = si_via_di (a_si, b_si); + for (i = 0; i < 4; ++i) + if (r_si[i] != e_si_via_di[i]) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-set-1.c b/gcc/testsuite/gcc.target/s390/vector/vec-set-1.c index 021a5b9a0b7b..c03963e63af1 100644 --- a/gcc/testsuite/gcc.target/s390/vector/vec-set-1.c +++ b/gcc/testsuite/gcc.target/s390/vector/vec-set-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -march=z14 -mzarch" } */ +/* { dg-options "-O2 -march=arch11 -mzarch" } */ /* { dg-final { check-function-bodies "**" "" } } */ typedef double V2DF __attribute__((vector_size(16))); @@ -69,7 +69,7 @@ set1dfn (V1DF x, double y, int n) /* ** setsf0: -** lgdr (%r.),%f0 +** vlgvf (%r.),%v0,0 ** vlvgf %v24,\1,0 ** br %r14 */ @@ -82,7 +82,7 @@ setsf0 (V4SF x, float y) /* ** setsf1: -** lgdr (%r.),%f0 +** vlgvf (%r.),%v0,0 ** vlvgf %v24,\1,1 ** br %r14 */ @@ -94,8 +94,8 @@ setsf1 (V4SF x, float y) } /* -** setsf0: -** lgdr (%r.),%f0 +** setsf2: +** vlgvf (%r.),%v0,0 ** vlvgf %v24,\1,2 ** br %r14 */ @@ -107,8 +107,8 @@ setsf2 (V4SF x, float y) } /* -** setsf1: -** lgdr (%r.),%f0 +** setsf3: +** vlgvf (%r.),%v0,0 ** vlvgf %v24,\1,3 ** br %r14 */ @@ -121,7 +121,7 @@ setsf3 (V4SF x, float y) /* ** setsfn: -** lgdr (%r.),%f0 +** vlgvf (%r.),%v0,0 ** vlvgf %v24,\1,0\(%r2\) ** br %r14 */ @@ -129,5 +129,12 @@ V4SF setsfn (V4SF x, float y, int n) { x[n] = y; + /* Make sure to read all FPRs such that the "save GPRs in FPRs" optimization + cannot be used. That optimization has a memory clobber on SP restore + causing DSE to fail to eliminate dead stores in leaf functions using this + optimization. */ + asm volatile ("" : : "f" (y), "f" (y), "f" (y), "f" (y), "f" (y), "f" (y), + "f" (y), "f" (y), "f" (y), "f" (y), "f" (y), "f" (y), + "f" (y), "f" (y), "f" (y), "f" (y)); return x; } diff --git a/gcc/testsuite/gcc.target/s390/vector/vlgv-zero-extend-1.c b/gcc/testsuite/gcc.target/s390/vector/vlgv-zero-extend-1.c new file mode 100644 index 000000000000..11df6c1869a8 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/vlgv-zero-extend-1.c @@ -0,0 +1,71 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target s390_vx } */ +/* { dg-additional-options "-O2" } */ +/* { dg-final { scan-assembler-not {\tllg?[fhc]r\t} } } */ + +typedef unsigned char __attribute__ ((vector_size (1))) V1QI; +typedef unsigned char __attribute__ ((vector_size (2))) V2QI; +typedef unsigned char __attribute__ ((vector_size (4))) V4QI; +typedef unsigned char __attribute__ ((vector_size (8))) V8QI; +typedef unsigned char __attribute__ ((vector_size (16))) V16QI; + +typedef unsigned short __attribute__ ((vector_size (2))) V1HI; +typedef unsigned short __attribute__ ((vector_size (4))) V2HI; +typedef unsigned short __attribute__ ((vector_size (8))) V4HI; +typedef unsigned short __attribute__ ((vector_size (16))) V8HI; + +typedef unsigned int __attribute__ ((vector_size (4))) V1SI; +typedef unsigned int __attribute__ ((vector_size (8))) V2SI; +typedef unsigned int __attribute__ ((vector_size (16))) V4SI; + +unsigned short ushort; +unsigned int uint; + +#define TEST(T, U, I) \ + unsigned T test_ ## I ## _ ## U (U x) { return x[I]; } \ + void test_ ## I ## _ ## U ## _ushort (U x) { ushort = x[I]; } \ + void test_ ## I ## _ ## U ## _uint (U x) { uint = x[I]; } + +#define TEST1(T, U) \ + TEST(T, U, 0) + +#define TEST2(T, U) \ + TEST1 (T, U) \ + TEST(T, U, 1) + +#define TEST4(T, U) \ + TEST2 (T, U) \ + TEST(T, U, 2) \ + TEST(T, U, 3) + +#define TEST8(T, U) \ + TEST4 (T, U) \ + TEST(T, U, 4) \ + TEST(T, U, 5) \ + TEST(T, U, 6) \ + TEST(T, U, 7) + +#define TEST16(T, U) \ + TEST8 (T, U) \ + TEST(T, U, 9) \ + TEST(T, U, 10) \ + TEST(T, U, 11) \ + TEST(T, U, 12) \ + TEST(T, U, 13) \ + TEST(T, U, 14) \ + TEST(T, U, 15) + +TEST1 (char, V1QI) +TEST2 (char, V2QI) +TEST4 (char, V4QI) +TEST8 (char, V8QI) +TEST16 (char, V16QI) + +TEST1 (short, V1HI) +TEST2 (short, V2HI) +TEST4 (short, V4HI) +TEST8 (short, V8HI) + +TEST1 (int, V1SI) +TEST2 (int, V2SI) +TEST4 (int, V4SI) diff --git a/gcc/testsuite/gcc.target/sh/pr54236-2.c b/gcc/testsuite/gcc.target/sh/pr54236-2.c index 1e2f3bbcb56c..78befe437701 100644 --- a/gcc/testsuite/gcc.target/sh/pr54236-2.c +++ b/gcc/testsuite/gcc.target/sh/pr54236-2.c @@ -4,10 +4,10 @@ /* { dg-do compile } */ /* { dg-options "-O1" } */ -/* { dg-final { scan-assembler-times "addc" 36 } } */ +/* { dg-final { scan-assembler-times "addc" 32 } } */ /* { dg-final { scan-assembler-times "shll" 14 } } */ -/* { dg-final { scan-assembler-times "add\tr" 12 } } */ -/* { dg-final { scan-assembler-not "movt" } } */ +/* { dg-final { scan-assembler-times "add\tr" 16 } } */ +/* { dg-final { scan-assembler-times "movt" 4 } } */ /* { dg-final { scan-assembler-times "add\t#1" 1 } } */ @@ -184,28 +184,28 @@ test_022 (int a, int b, int c, int d) int test_023 (int a, int b, int c, int d) { - // 1x shll, 1x addc + // 1x shll, 1x add return a + ((b >> 31) & 1); } int test_024 (int a, int b, int c, int d) { - // 1x shll, 1x addc + // 1x shll, 1x add return ((b >> 31) & 1) + a; } int test_025 (int a, int b, int c, int d) { - // 1x shll, 1x addc + // 1x shll, 1x add return ((a >> 31) & 1) + a; } int test_026 (int a, int b, int c, int d) { - // 1x shll, 1x addc + // 1x shll, 1x add return a + ((a >> 31) & 1); } diff --git a/gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-2.c b/gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-2.c index 5f3d3e166afb..46fc4648dbd7 100644 --- a/gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-2.c +++ b/gcc/testsuite/gcc.target/x86_64/abi/callabi/leaf-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-tree-vectorize -mabi=sysv" } */ +/* { dg-options "-O2 -fno-tree-vectorize -mabi=sysv -fno-shrink-wrap-separate" } */ extern int glb1, gbl2, gbl3; diff --git a/gcc/testsuite/gcc.target/xtensa/BGEUI-BLTUI-32k-64k.c b/gcc/testsuite/gcc.target/xtensa/BGEUI-BLTUI-32k-64k.c new file mode 100644 index 000000000000..05873b896896 --- /dev/null +++ b/gcc/testsuite/gcc.target/xtensa/BGEUI-BLTUI-32k-64k.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern void foo(void); + +void BGEUI_test(unsigned int a) +{ + if (a < 32768U) + foo(); +} + +void BLTUI_test(unsigned int a) +{ + if (a >= 65536U) + foo(); +} + +/* { dg-final { scan-assembler-times "bgeui" 1 } } */ +/* { dg-final { scan-assembler-times "bltui" 1 } } */ diff --git a/gcc/testsuite/gcc.target/xtensa/elim_GP_regmove_0.c b/gcc/testsuite/gcc.target/xtensa/elim_GP_regmove_0.c deleted file mode 100644 index 5c195c357dc6..000000000000 --- a/gcc/testsuite/gcc.target/xtensa/elim_GP_regmove_0.c +++ /dev/null @@ -1,23 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -fpeephole2" } */ - -/* can be processed */ -double test0(double a, double b) { - return __builtin_copysign(a, b); -} - -/* cannot be processed: due to violate '0' constraint of the 2nd source operand. */ -int test1(int a, int b) { - int c; - asm volatile ("" : "=a"(c) : "r"(a), "0"(b)); - return c; -} - -/* cannot be processed: due to violate '&' constraint of the destination operand. */ -int test2(int a) { - int b; - asm volatile ("" : "=&a"(b) : "r"(a)); - return b; -} - -/* { dg-final { scan-assembler-times "mov\t|mov.n\t" 2 } } */ diff --git a/gcc/testsuite/gcc.target/xtensa/elim_GP_regmove_1.c b/gcc/testsuite/gcc.target/xtensa/elim_GP_regmove_1.c deleted file mode 100644 index a13ef818827e..000000000000 --- a/gcc/testsuite/gcc.target/xtensa/elim_GP_regmove_1.c +++ /dev/null @@ -1,10 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -fpeephole2 -mabi=windowed" } */ - -/* cannot be processed: due to violate 'a' constraint of the destination operand of the stack adjustment instruction. */ -void test(void) { - int buffer[8192]; - asm volatile ("" : : "m"(buffer)); -} - -/* { dg-final { scan-assembler-times "movsp" 1 } } */ diff --git a/gcc/testsuite/gcc.target/xtensa/pr120888-1.c b/gcc/testsuite/gcc.target/xtensa/pr120888-1.c new file mode 100644 index 000000000000..f438e4c676cb --- /dev/null +++ b/gcc/testsuite/gcc.target/xtensa/pr120888-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-rtl-expand" } */ + +void u8(unsigned char c); +void cu8(unsigned char *p) +{ + u8(*p); +} + +/* { dg-final { scan-rtl-dump "zero_extend" "expand" } } */ +/* { dg-final { scan-rtl-dump-not "sign_extend" "expand" } } */ diff --git a/gcc/testsuite/gcc.target/xtensa/pr120888-2.c b/gcc/testsuite/gcc.target/xtensa/pr120888-2.c new file mode 100644 index 000000000000..9b5caad83298 --- /dev/null +++ b/gcc/testsuite/gcc.target/xtensa/pr120888-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-rtl-expand" } */ + +void s8(signed char c); +void cs8(signed char *p) +{ + s8(*p); +} + +/* { dg-final { scan-rtl-dump "sign_extend" "expand" } } */ +/* { dg-final { scan-rtl-dump-not "zero_extend" "expand" } } */ diff --git a/gcc/testsuite/gfortran.dg/allocate_with_mold_5.f90 b/gcc/testsuite/gfortran.dg/allocate_with_mold_5.f90 new file mode 100644 index 000000000000..f5e2fc93d0a4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/allocate_with_mold_5.f90 @@ -0,0 +1,51 @@ +! { dg-do compile } +! { dg-additional-options "-Wsurprising" } +! +! PR fortran/51961 - fix checking of MOLD= in ALLOCATE statements +! +! Contributed by Tobias Burnus + +program p + implicit none + type t + end type t + type u + class(t), allocatable :: a(:), b(:,:), c + end type u + class(T), allocatable :: a(:), b(:,:), c + type(u) :: z + + allocate (b(2,2)) + allocate (z% b(2,2)) + + allocate (a(2), mold=b(:,1)) + allocate (a(1:2), mold=b(1,:)) + allocate (a(2), mold=b) ! { dg-warning "but MOLD= expression at" } + allocate (a(1:2), mold=b) ! { dg-warning "but MOLD= expression at" } + allocate (z% a(2), mold=b(:,1)) + allocate (z% a(1:2), mold=b(1,:)) + allocate (z% a(2), mold=b) ! { dg-warning "but MOLD= expression at" } + allocate (z% a(1:2), mold=b) ! { dg-warning "but MOLD= expression at" } + allocate (z% a(2), mold=z% b(:,1)) + allocate (z% a(1:2), mold=z% b(1,:)) + allocate (z% a(2), mold=z% b) ! { dg-warning "but MOLD= expression at" } + allocate (z% a(1:2), mold=z% b) ! { dg-warning "but MOLD= expression at" } + + allocate (c, mold=b(1,1)) + allocate (c, mold=b) ! { dg-warning "but MOLD= expression at" } + allocate (z% c, mold=b(1,1)) + allocate (z% c, mold=b) ! { dg-warning "but MOLD= expression at" } + allocate (z% c, mold=z% b(1,1)) + allocate (z% c, mold=z% b) ! { dg-warning "but MOLD= expression at" } + + allocate (a, mold=b(:,1)) + allocate (a, mold=b(1,:)) + allocate (z% a, mold=b(:,1)) + allocate (z% a, mold=b(1,:)) + allocate (z% a, mold=z% b(:,1)) + allocate (z% a, mold=z% b(1,:)) + + allocate (a, mold=b) ! { dg-error "or have the same rank" } + allocate (z% a, mold=b) ! { dg-error "or have the same rank" } + allocate (z% a, mold=z% b) ! { dg-error "or have the same rank" } +end diff --git a/gcc/testsuite/gfortran.dg/array_constructor_58.f90 b/gcc/testsuite/gfortran.dg/array_constructor_58.f90 new file mode 100644 index 000000000000..1473be0da015 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/array_constructor_58.f90 @@ -0,0 +1,17 @@ +!{ dg-do run } + +! Contributed by Federico Perini +! Check that PR fortran/119106 is fixed. + +program char_param_array +implicit none +character, parameter :: p(5) = ['1','2','3','4','5'] +character, save :: n(5) = ['1','2','3','4','5'] +integer :: i(10), j + +i = 4 +if (any([(n(i(j)),j=1,10)] /= '4')) stop 1 ! OK +if (any([(p(i(j)),j=1,10)] /= '4')) stop 2 ! used to runtime out-of-bounds error + +end program char_param_array + diff --git a/gcc/testsuite/gfortran.dg/asan/array_constructor_1.f90 b/gcc/testsuite/gfortran.dg/asan/array_constructor_1.f90 new file mode 100644 index 000000000000..a0c55076a9ae --- /dev/null +++ b/gcc/testsuite/gfortran.dg/asan/array_constructor_1.f90 @@ -0,0 +1,25 @@ +!{ dg-do run } + +! Contributed by Christopher Albert + +program grow_type_array + type :: container + integer, allocatable :: arr(:) + end type container + + type(container), allocatable :: list(:) + + allocate(list(0)) + + list = [list, new_elem(5)] + + deallocate(list) + +contains + + type(container) function new_elem(s) result(out) + integer :: s + allocate(out%arr(s)) + end function new_elem + +end program grow_type_array diff --git a/gcc/testsuite/gfortran.dg/asan/finalize_1.f90 b/gcc/testsuite/gfortran.dg/asan/finalize_1.f90 new file mode 100644 index 000000000000..ab53a9ecf2be --- /dev/null +++ b/gcc/testsuite/gfortran.dg/asan/finalize_1.f90 @@ -0,0 +1,67 @@ +!{ dg-do run } + +! PR fortran/120637 + +! Contributed by Antony Lewis +! The unused module is needed to trigger the issue of not freeing the +! memory of second module. + + module MiscUtils + implicit none + + contains + + logical function isFloat0(R) + class(*), intent(in) :: R + + select type(R) + type is (real) + isFloat0 = .true. + end select + end function isFloat0 + + end module MiscUtils + + module results3 + implicit none + public + + Type ClTransferData2 + real, dimension(:,:,:), allocatable :: Delta_p_l_k + end type ClTransferData2 + + type TCLdata2 + Type(ClTransferData2) :: CTransScal, CTransTens, CTransVec + end type TCLdata2 + + type :: CAMBdata2 + Type(TClData2) :: CLdata2 + end type + + end module results3 + +program driver + use results3 + integer i + do i=1, 2 + call test() + end do + + contains + + subroutine test + implicit none + class(CAMBdata2), pointer :: Data + + allocate(CAMBdata2::Data) + + allocate(Data%ClData2%CTransScal%Delta_p_l_k(3, 1000, 1000)) + allocate(Data%ClData2%CTransVec%Delta_p_l_k(3, 1000, 1000)) + deallocate(Data) + + end subroutine test + + end program driver + +!{ dg-final { cleanup-modules "miscutils results3" } } + diff --git a/gcc/testsuite/gfortran.dg/associate_75.f90 b/gcc/testsuite/gfortran.dg/associate_75.f90 new file mode 100644 index 000000000000..c7c461a5cb65 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/associate_75.f90 @@ -0,0 +1,50 @@ +! { dg-do run } +! +! Test fix for PR121060. +! +! Contributed by Damian Rouson +! +module subdomain_m + implicit none + + type subdomain_t + real :: s_ = 99. + contains + generic :: operator(.laplacian.) => laplacian + procedure laplacian + end type + +contains + + function laplacian(rhs) + class(subdomain_t), intent(in) :: rhs + type(subdomain_t) laplacian + laplacian%s_ = rhs%s_ + 42 + end function + +end module + + use subdomain_m + implicit none + + type operands_t + real :: s_ + end type + + type(subdomain_t) phi + type(operands_t) operands + + associate(laplacian_phi => .laplacian. phi) ! ICE because specific not found. + operands = approximates(laplacian_phi%s_) + end associate + + if (int (operands%s_) /= 42) stop 1 +contains + + function approximates(actual) + real actual + type(operands_t) approximates + approximates%s_ = actual - 99 + end function + +end diff --git a/gcc/testsuite/gfortran.dg/coarray/coindexed_6.f90 b/gcc/testsuite/gfortran.dg/coarray/coindexed_6.f90 new file mode 100644 index 000000000000..d566c504134f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/coarray/coindexed_6.f90 @@ -0,0 +1,24 @@ +!{ dg-do compile } + +! Check PR120843 is fixed + +program p + implicit none + + type T + integer, allocatable :: arr(:,:) [:,:] + end type + + type(T) :: o + integer, allocatable :: vec(:)[:,:] + integer :: c[*] + + c = 7 + + allocate(o%arr(4,3)[2,*], source=6) + allocate(vec(10)[1,*], source=7) + + if (vec(3) * c /= 49) stop 1 + if (o%arr(2,2)* c /= 42) stop 2 + +end program p diff --git a/gcc/testsuite/gfortran.dg/coarray/coindexed_7.f90 b/gcc/testsuite/gfortran.dg/coarray/coindexed_7.f90 new file mode 100644 index 000000000000..066397024f47 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/coarray/coindexed_7.f90 @@ -0,0 +1,24 @@ +!{ dg-do compile } + +! Check PR120847 is fixed. + +program p + implicit none + + type T + integer, allocatable :: i(:, :) [:] + end type T + + type(T) :: o + integer, allocatable :: c[:] + integer :: i + + c = 7 + + allocate(o%i(4, 5)[*], source=6) + + do i = 1, 4 + c = o%i(mod(i, 2), mod(i, 3))[1] + end do + +end program p diff --git a/gcc/testsuite/gfortran.dg/diagnostic-format-json-1.F90 b/gcc/testsuite/gfortran.dg/diagnostic-format-json-1.F90 deleted file mode 100644 index b8cd61cff23a..000000000000 --- a/gcc/testsuite/gfortran.dg/diagnostic-format-json-1.F90 +++ /dev/null @@ -1,24 +0,0 @@ -! { dg-do compile } -! { dg-options "-fdiagnostics-format=json" } - -#error message - -#if 0 -{ dg-begin-multiline-output "" } -[{"kind": "error", - "message": "#error message", - "children": [], - "column-origin": 1, - "locations": [{"caret": {"file": - "line": 4, - "display-column": 2, - "byte-column": 2, - "column": 2}, - "finish": {"file": - "line": 4, - "display-column": 6, - "byte-column": 6, - "column": 6}}], - "escape-source": false}] -{ dg-end-multiline-output "" } -#endif diff --git a/gcc/testsuite/gfortran.dg/diagnostic-format-json-2.F90 b/gcc/testsuite/gfortran.dg/diagnostic-format-json-2.F90 deleted file mode 100644 index 9ff1ef59b343..000000000000 --- a/gcc/testsuite/gfortran.dg/diagnostic-format-json-2.F90 +++ /dev/null @@ -1,26 +0,0 @@ -! { dg-do compile } -! { dg-options "-fdiagnostics-format=json" } - -#warning message - -#if 0 -{ dg-begin-multiline-output "" } -[{"kind": "warning", - "message": "#warning message", - "option": "-Wcpp", - "option_url": - "children": [], - "column-origin": 1, - "locations": [{"caret": {"file": - "line": 4, - "display-column": 2, - "byte-column": 2, - "column": 2}, - "finish": {"file": - "line": 4, - "display-column": 8, - "byte-column": 8, - "column": 8}}], - "escape-source": false}] -{ dg-end-multiline-output "" } -#endif diff --git a/gcc/testsuite/gfortran.dg/diagnostic-format-json-3.F90 b/gcc/testsuite/gfortran.dg/diagnostic-format-json-3.F90 deleted file mode 100644 index 750e186c8acf..000000000000 --- a/gcc/testsuite/gfortran.dg/diagnostic-format-json-3.F90 +++ /dev/null @@ -1,26 +0,0 @@ -! { dg-do compile } -! { dg-options "-fdiagnostics-format=json -Werror" } - -#warning message - -#if 0 -{ dg-begin-multiline-output "" } -[{"kind": "error", - "message": "#warning message", - "option": "-Werror=cpp", - "option_url": - "children": [], - "column-origin": 1, - "locations": [{"caret": {"file": - "line": 4, - "display-column": 2, - "byte-column": 2, - "column": 2}, - "finish": {"file": - "line": 4, - "display-column": 8, - "byte-column": 8, - "column": 8}}], - "escape-source": false}] -{ dg-end-multiline-output "" } -#endif diff --git a/gcc/testsuite/gfortran.dg/diagnostic-format-json-pr105916.F90 b/gcc/testsuite/gfortran.dg/diagnostic-format-json-pr105916.F90 deleted file mode 100644 index bf22a86867bc..000000000000 --- a/gcc/testsuite/gfortran.dg/diagnostic-format-json-pr105916.F90 +++ /dev/null @@ -1,14 +0,0 @@ -! { dg-do compile } -! { dg-options "-fdiagnostics-format=json-stderr -fmax-errors=1 -Wfatal-errors" } - -program main - implicit none - print*, "Hello World!" -end program main - -! We expect an empty array as the JSON output. -#if 0 -{ dg-begin-multiline-output "" } -[] -{ dg-end-multiline-output "" } -#endif diff --git a/gcc/testsuite/gfortran.dg/g77/980310-3.f b/gcc/testsuite/gfortran.dg/g77/980310-3.f index 39bd86c80365..4bf4d91092f3 100644 --- a/gcc/testsuite/gfortran.dg/g77/980310-3.f +++ b/gcc/testsuite/gfortran.dg/g77/980310-3.f @@ -12,7 +12,7 @@ C From: Joao Cardoso C To: egcs-bugs@cygnus.com C Subject: egcs-1.0 f77 bug on OSR5 -C When trying to compile the Fortran file that I enclose bellow, +C When trying to compile the Fortran file that I enclose below, C I got an assembler error: C C ./g77 -B./ -fpic -O -c scaleg.f diff --git a/gcc/testsuite/gfortran.dg/goacc/acc-wait-1.f90 b/gcc/testsuite/gfortran.dg/goacc/acc-wait-1.f90 new file mode 100644 index 000000000000..dd19b4156637 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/acc-wait-1.f90 @@ -0,0 +1,47 @@ +! { dg-do compile } +! { dg-additional-options "-fdump-tree-original" } + +subroutine f0(x) + implicit none + integer, value :: x + !$acc wait(x) if(.false.) async +end + +subroutine f1(y, ia) + implicit none + integer, value :: y, ia + !$acc wait(y) if(.true.) async(ia) +end + +subroutine fl(z, ll) + implicit none + integer, value :: z + logical, value :: ll + !$acc wait(z) if(ll) async(3) +end + +subroutine a0(a) + implicit none + integer, value :: a + !$acc wait(a) if(.false.) +end + +subroutine a1(b) + implicit none + integer, value :: b + !$acc wait(b) if(.true.) +end + +subroutine al(c, qq) + implicit none + integer, value :: c + logical, value :: qq + !$acc wait(c) if(qq) +end + +! { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = x;\[\\n\\r\]+ *if \\(0\\)\[\\n\\r\]+ *\{\[\\n\\r\]+ *__builtin_GOACC_wait \\(-1, 1, D\.\[0-9\]+\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = ia;\[\\n\\r\]+ *D\.\[0-9\]+ = y;\[\\n\\r\]+ *if \\(1\\)\[\\n\\r\]+ *\{\[\\n\\r\]+ *__builtin_GOACC_wait \\(D\.\[0-9\]+, 1, D\.\[0-9\]+\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = z;\[\\n\\r\]+ *D\.\[0-9\]+ = ll;\[\\n\\r\]+ *if \\(D\.\[0-9\]+\\)\[\\n\\r\]+ *\{\[\\n\\r\]+ *__builtin_GOACC_wait \\(3, 1, D\.\[0-9\]+\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = a;\[\\n\\r\]+ *if \\(0\\)\[\\n\\r\]+ *\{\[\\n\\r\]+ *__builtin_GOACC_wait \\(-2, 1, D\.\[0-9\]+\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = b;\[\\n\\r\]+ *if \\(1\\)\[\\n\\r\]+ *\{\[\\n\\r\]+ *__builtin_GOACC_wait \\(-2, 1, D\.\[0-9\]+\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = c;\[\\n\\r\]+ *D\.\[0-9\]+ = qq;\[\\n\\r\]+ *if \\(D\.\[0-9\]+\\)\[\\n\\r\]+ *\{\[\\n\\r\]+ *__builtin_GOACC_wait \\(-2, 1, D\.\[0-9\]+\\);" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/goacc/parameter-3.f90 b/gcc/testsuite/gfortran.dg/goacc/parameter-3.f90 new file mode 100644 index 000000000000..2c8aa618cc22 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/parameter-3.f90 @@ -0,0 +1,16 @@ +! { dg-do compile } + +subroutine x + integer :: var + integer, parameter :: ilog = 0 + integer, parameter :: array(*) = [11,22,33] + !$ACC DECLARE COPYIN(ilog, array, var, array) ! { dg-error "Symbol 'array' present on multiple clauses" } +end subroutine x + +integer :: a +integer, parameter :: b = 4 +integer, parameter :: c(*) = [1,2,3] + +!$acc parallel copy(a,c,b,c) ! { dg-error "Symbol 'c' present on multiple clauses" } +!$acc end parallel +end diff --git a/gcc/testsuite/gfortran.dg/goacc/parameter-4.f90 b/gcc/testsuite/gfortran.dg/goacc/parameter-4.f90 new file mode 100644 index 000000000000..aadd7cffe810 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/parameter-4.f90 @@ -0,0 +1,26 @@ +! { dg-do compile } +! { dg-additional-options "-fdump-tree-original" } + +subroutine x + integer :: var + integer, parameter :: ilog = 0 + integer, parameter :: array(*) = [11,22,33] + !$ACC DECLARE COPYIN(ilog, array, var) +end subroutine x + +integer :: a +integer, parameter :: b = 4 +integer, parameter :: c(*) = [1,2,3] + +!$acc parallel copy(a,c,b) + a = c(2) + b +!$acc end parallel + +!$acc parallel firstprivate(a,c,b) + a = c(2) + b +!$acc end parallel +end + +! { dg-final { scan-tree-dump-times "#pragma acc data map\\(to:var\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma acc parallel map\\(tofrom:a\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma acc parallel firstprivate\\(a\\)" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/goacc/parameter.f95 b/gcc/testsuite/gfortran.dg/goacc/parameter.f95 index b58133867217..a9bde4a67ec1 100644 --- a/gcc/testsuite/gfortran.dg/goacc/parameter.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/parameter.f95 @@ -1,4 +1,5 @@ ! { dg-do compile } +! { dg-additional-options "-Wsurprising" } module test contains @@ -6,37 +7,37 @@ subroutine oacc1 implicit none integer :: i integer, parameter :: a = 1 - !$acc declare device_resident (a) ! { dg-error "is not a variable" } - !$acc data copy (a) ! { dg-error "not a variable" } + !$acc declare device_resident (a) ! (no warning here - for semi-good reasons) + !$acc data copy (a) ! { dg-warning "Clause for object 'a' at .1. is ignored as parameters need not be copied \\\[-Wsurprising\\\]" } !$acc end data - !$acc data deviceptr (a) ! { dg-error "not a variable" } + !$acc data deviceptr (a) ! { dg-warning "Clause for object 'a' at .1. is ignored as parameters need not be copied \\\[-Wsurprising\\\]" } !$acc end data - !$acc parallel private (a) ! { dg-error "not a variable" } + !$acc parallel private (a) ! { dg-warning "Clause for object 'a' at .1. is ignored as it is a parameter \\\[-Wsurprising\\\]" } !$acc end parallel - !$acc serial private (a) ! { dg-error "not a variable" } + !$acc serial private (a) ! { dg-warning "Clause for object 'a' at .1. is ignored as it is a parameter \\\[-Wsurprising\\\]" } !$acc end serial - !$acc host_data use_device (a) ! { dg-error "not a variable" } + !$acc host_data use_device (a) ! { dg-warning "Clause for object 'a' at .1. is ignored as it is a parameter \\\[-Wsurprising\\\]" } !$acc end host_data - !$acc parallel loop reduction(+:a) ! { dg-error "not a variable" } + !$acc parallel loop reduction(+:a) ! { dg-warning "Clause for object 'a' at .1. is ignored as it is a parameter \\\[-Wsurprising\\\]" } do i = 1,5 enddo !$acc end parallel loop - !$acc serial loop reduction(+:a) ! { dg-error "not a variable" } + !$acc serial loop reduction(+:a) ! { dg-warning "Clause for object 'a' at .1. is ignored as it is a parameter \\\[-Wsurprising\\\]" } do i = 1,5 enddo !$acc end serial loop !$acc parallel loop do i = 1,5 - !$acc cache (a) ! { dg-error "not a variable" } + !$acc cache (a) ! { dg-warning "Clause for object 'a' at .1. is ignored as it is a parameter \\\[-Wsurprising\\\]" } enddo !$acc end parallel loop !$acc serial loop do i = 1,5 - !$acc cache (a) ! { dg-error "not a variable" } + !$acc cache (a) ! { dg-warning "Clause for object 'a' at .1. is ignored as it is a parameter \\\[-Wsurprising\\\]" } enddo !$acc end serial loop - !$acc update device (a) ! { dg-error "not a variable" } - !$acc update host (a) ! { dg-error "not a variable" } - !$acc update self (a) ! { dg-error "not a variable" } + !$acc update device (a) ! { dg-warning "Clause for object 'a' at .1. is ignored as parameters need not be copied \\\[-Wsurprising\\\]" } + !$acc update host (a) ! { dg-warning "Clause for object 'a' at .1. is ignored as parameters need not be copied \\\[-Wsurprising\\\]" } + !$acc update self (a) ! { dg-warning "Clause for object 'a' at .1. is ignored as parameters need not be copied \\\[-Wsurprising\\\]" } end subroutine oacc1 end module test diff --git a/gcc/testsuite/gfortran.dg/gomp/omp_get_num_devices_initial_device-2.f90 b/gcc/testsuite/gfortran.dg/gomp/omp_get_num_devices_initial_device-2.f90 new file mode 100644 index 000000000000..18613d458b1b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/omp_get_num_devices_initial_device-2.f90 @@ -0,0 +1,21 @@ +! { dg-do compile } +! { dg-additional-options "-O1 -fdump-tree-optimized -fno-builtin-omp_get_num_devices -fno-builtin-omp_get_initial_device" } +integer function f() result(ret) + interface + integer function omp_get_initial_device (); end + integer function omp_get_num_devices (); end + end interface + + if (omp_get_initial_device () /= omp_get_num_devices ()) error stop + + if (omp_get_num_devices () /= omp_get_num_devices ()) error stop + + if (omp_get_initial_device () /= omp_get_initial_device ()) error stop + + ret = omp_get_num_devices () +end + +! { dg-final { scan-tree-dump-times "error_stop" 3 "optimized" } } + +! { dg-final { scan-tree-dump-times "omp_get_num_devices" 4 "optimized" } } +! { dg-final { scan-tree-dump-times "omp_get_initial_device" 3 "optimized" } } diff --git a/gcc/testsuite/gfortran.dg/gomp/omp_get_num_devices_initial_device.f90 b/gcc/testsuite/gfortran.dg/gomp/omp_get_num_devices_initial_device.f90 new file mode 100644 index 000000000000..279656bdd840 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/omp_get_num_devices_initial_device.f90 @@ -0,0 +1,24 @@ +! { dg-do compile } +! { dg-additional-options "-O1 -fdump-tree-optimized" } +integer function f() result(ret) + interface + integer function omp_get_initial_device (); end + integer function omp_get_num_devices (); end + end interface + + if (omp_get_initial_device () /= omp_get_num_devices ()) error stop + + if (omp_get_num_devices () /= omp_get_num_devices ()) error stop + + if (omp_get_initial_device () /= omp_get_initial_device ()) error stop + + ret = omp_get_num_devices () +end + +! { dg-final { scan-tree-dump-not "error_stop" "optimized" } } + +! { dg-final { scan-tree-dump-not "omp_get_num_devices" "optimized" { target { ! offloading_enabled } } } } +! { dg-final { scan-tree-dump "return 0;" "optimized" { target { ! offloading_enabled } } } } + +! { dg-final { scan-tree-dump-times "omp_get_num_devices" 1 "optimized" { target offloading_enabled } } } +! { dg-final { scan-tree-dump "_1 = __builtin_omp_get_num_devices \\(\\);\[\\r\\n\]+\[ \]+return _1;" "optimized" { target offloading_enabled } } } diff --git a/gcc/testsuite/gfortran.dg/gomp/pr104428.f90 b/gcc/testsuite/gfortran.dg/gomp/pr104428.f90 new file mode 100644 index 000000000000..639b331ff5b6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr104428.f90 @@ -0,0 +1,15 @@ +! { dg-do compile } + +program p + interface + subroutine x + end subroutine x + end interface +contains + subroutine foo + !$omp declare variant(x) match(construct={do}) + end + subroutine bar + !$omp declare variant(y) match(construct={do}) ! { dg-error "Cannot find symbol 'y'" } + end +end diff --git a/gcc/testsuite/gfortran.dg/guality/arg1.f90 b/gcc/testsuite/gfortran.dg/guality/arg1.f90 index 332a4ed1d872..775b7bb304f1 100644 --- a/gcc/testsuite/gfortran.dg/guality/arg1.f90 +++ b/gcc/testsuite/gfortran.dg/guality/arg1.f90 @@ -1,5 +1,5 @@ ! { dg-do run } -! { dg-options "-g" } +! { dg-options "-fno-shrink-wrap -g" } integer :: a(10), b(12) call sub (a, 10) call sub (b, 12) diff --git a/gcc/testsuite/gfortran.dg/import12.f90 b/gcc/testsuite/gfortran.dg/import12.f90 new file mode 100644 index 000000000000..df1aae6d0d25 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/import12.f90 @@ -0,0 +1,302 @@ +! { dg-do compile } +! +! Tests the variants of IMPORT introduced in F2018 +! +! Contributed by Paul Thomas +! +MODULE M + import, none ! { dg-error "F2018: C897 IMPORT statement" } + IMPLICIT NONE + integer :: z +end module + +MODULE N + IMPLICIT NONE + integer :: z +end module + +! Taken from gfortran.dg/pr103312.f90. These F2008-style invocations should +! be accepted. +module example + type, abstract :: foo + integer :: i + contains + procedure(foo_size), deferred :: size + procedure(foo_func), deferred :: func + end type + abstract interface + pure integer function foo_size (this) + import :: foo + class(foo), intent(in) :: this + end function + function foo_func (this) result (string) + import :: foo + class(foo) :: this + character(this%size()) :: string + end function + end interface +end module + +block data blk + import, all ! { dg-error "F2018: C897 IMPORT statement" } + integer a(2) + common /my_common/a + data a/1,2/ +end + +subroutine extern_sub1 + import ! { dg-error "F2018: C897 IMPORT statement" } +end + +subroutine extern_sub2 (arg1, arg2, arg3) + implicit none + integer :: arg1, arg2, arg3 + arg1 = int_fcn () +contains + integer function int_fcn () + import, only : arg2, arg3 + int_fcn = arg2 * arg3 + end +end + +program p + import, all ! { dg-error "F2018: C897 IMPORT statement" } + implicit none + integer :: x, y + type :: t + integer :: i + end type + type(t) :: progtype + type, extends(t) :: s + integer :: j + end type + class(t), allocatable :: progclass +contains + +! OK because arg is just that and x is declared in scope of sub1. + subroutine sub1 (arg) + import, none + implicit none + real :: arg, x + end + +! IMPORT, ALL must be the only IMPORT statement in the scope. + subroutine sub2 (arg) + import, none + import, all ! { dg-error "F2018: C8100 IMPORT statement" } + implicit none + real :: arg, x + end + +! Error message says it all. + subroutine sub3 (arg) + import, none + implicit none + integer :: arg + print *, arg + x = 1 ! { dg-error "F2018: C8102" } + end + +! Error messages say it all. + subroutine sub4 (arg) + import, only : y + implicit none + integer :: arg + print *, arg + x = 1 ! { dg-error "F2018: C8102" } + y = 2 + print *, x ! { dg-error "F2018: C8102" } + end + +! IMPORT eos and IMPORT, ALL must be unique in the scope. + subroutine sub5a (arg) + import, all + import ! { dg-error "F2018: C8100" } + implicit none + real :: arg + real :: x ! { dg-error "F2018: C8102" } + end + + subroutine sub5b (arg) + import, only : x + implicit none + real :: arg + real :: x ! { dg-error "F2018: C8102" } + end + +! Error message says it all. + integer function func1 () + import, only : x + func1 = x * y ! { dg-error "F2018: C8102" } + end + +! Error messages say it all. + subroutine sub6 (arg) + import, only : func1 + import, only : func2 + import, only : foobar ! { dg-error "has no IMPLICIT type" } + implicit none + integer :: arg + arg = func1 () * func2 () * func3 () ! { dg-error "F2018: C8102" } + end + +! Error message says it all. + integer function func2 () + use N + import, none + implicit none + func2 = y ! { dg-error "F2018: C8102" } + end + +! OK + integer function func3 () + func3 = 42 + end + + subroutine sub7 (arg) + implicit none + integer :: arg +! OK + block + import, only : arg, func1, func2, func3 + arg = func1 () * func2 () * func3 () + end block + block + arg = func1 () + import, only : arg, func1 ! { dg-error "Unexpected IMPORT statement" } + end block + end + +! Error messages say it all. + subroutine sub8 (arg) + implicit none + integer :: arg + block + import, only : func1 + import, only : func2 + import, only : foobar ! { dg-error "has no IMPLICIT type" } + arg = func1 () * func2 () * func3 () ! { dg-error "F2018: C8102" } + end block + end + +! ASSOCIATE does not have a specification part so IMPORT cannot appear. + subroutine sub9 (arg) + implicit none + integer :: arg + associate (f3 => func3 ()) ! { dg-error "F2018: C8102" } + import, only : arg, func1 ! { dg-error "Unexpected IMPORT statement" } + arg = func1 () * func2 () * f3 ! { dg-error "F2018: C8102" } + end associate + end + +! OK + subroutine sub10 (arg) + import, only : t + implicit none + type(t) :: arg, mytype + mytype%i = 1 + arg = mytype + end + +! TYPE t does not appear in the IMPORT list + subroutine sub11 (arg) + import, only : progtype + implicit none + type(t) :: arg + progtype%i = 1 ! { dg-error "F2018: C8102" } + arg = progtype ! { dg-error "F2018: C8102" } + end + +! TYPE t is excluded by IMPORT, NONE + subroutine sub12 (arg) + import, none + implicit none + type(t) :: arg, mytype + mytype%i = 1 ! { dg-error "F2018: C8102" } + arg = mytype ! { dg-error "F2018: C8102" } + end + +! TYPE t does not appear in the IMPORT list + subroutine sub13 (arg) + import, only : progclass + implicit none + class(t) :: arg + type(t) :: ca(2) = [t(1), t(2)] ! { dg-error "F2018: C8102" } + progclass%i = t(1) ! { dg-error "F2018: C8102" } + arg = progclass ! { dg-error "F2018: C8102" } + ca = [t(1), t(2)] ! { dg-error "has no IMPLICIT type|F2018: C8102" } + arg = ca(2) ! Note: The preceeding line catches 'ca' having no implicit type. + end + +! TYPE t is excluded by IMPORT, NONE + subroutine sub14 (arg) + import, none + implicit none + class(t) :: arg + class(t), allocatable :: myclass + myclass%i = t(1) ! { dg-error "F2018: C8102" } + arg%i = myclass%i ! { dg-error "F2018: C8102" } + select type (arg) ! { dg-error "F2018: C8102" } + type is (t) + arg%i = arg%i + 1 + type is (s) + arg%j = -1 + end select + end + +! TYPE s does not appear in the IMPORT, ONLY list + subroutine sub15 (arg) + import, only : t + implicit none + class(t) :: arg + class(t), allocatable :: myclass + myclass = t(1) + arg%i = myclass%i + select type (arg) ! { dg-error "F2018: C8102" } + type is (t) + arg%i = arg%i + 1 + type is (s) + arg%j = -1 ! s is caught at the SELECT TYPE statement + end select + end + +! This is OK + subroutine sub16 (arg) + import, only : t, s + implicit none + class(t) :: arg + class(t), allocatable :: myclass + myclass = t(1) + arg%i = myclass%i + select type (arg) + type is (t) + arg%i = arg%i + 1 + type is (s) + arg%j = -1 + end select + end + + subroutine sub17 (arg) + import, only : t + implicit none + class(t) :: arg + call sub16 (arg) ! { dg-error "F2018: C8102" } + end + +! Make sure that recursive procedures do not require the procedure itself to be imported. + recursive subroutine sub18 (arg) + import, none + implicit none + integer :: arg + if (arg <= 0) call sub18 (arg) + arg = 1 + end + + recursive integer function func4 (arg) result (res) + import, none + implicit none + integer :: arg + if (arg <= 0) arg = func4 (arg) + res = 1 + end +end diff --git a/gcc/testsuite/gfortran.dg/import13.f90 b/gcc/testsuite/gfortran.dg/import13.f90 new file mode 100644 index 000000000000..3bcfec33723d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/import13.f90 @@ -0,0 +1,21 @@ +! { dg-do compile } +! +! Contributed by Steve Kargl +! +program foo + implicit none + integer i + i = 42 + if (i /= 42) stop 1 + call bah + contains + subroutine bah ! { dg-error "is already defined at" } + i = 43 + if (i /= 43) stop 2 + end subroutine bah + subroutine bah ! { dg-error "is already defined at" } + ! import statement missing a comma + import none ! { dg-error "Unexpected IMPORT statement" } + i = 44 ! { dg-error "Unexpected assignment" } + end subroutine bah ! { dg-error "Expecting END PROGRAM" } +end program foo diff --git a/gcc/testsuite/gfortran.dg/import3.f90 b/gcc/testsuite/gfortran.dg/import3.f90 index 74cd5279b1fe..9288c6b63a2c 100644 --- a/gcc/testsuite/gfortran.dg/import3.f90 +++ b/gcc/testsuite/gfortran.dg/import3.f90 @@ -1,6 +1,8 @@ ! { dg-do compile } +! { dg-options "-std=f2008" } ! { dg-shouldfail "Invalid use of IMPORT" } ! Test invalid uses of import +! Wording of some error messages change for -std>=F2018 but all are caught. ! PR fortran/29601 subroutine test() diff --git a/gcc/testsuite/gfortran.dg/inline_matmul_16.f90 b/gcc/testsuite/gfortran.dg/inline_matmul_16.f90 index 580cb1ac9393..bb1a3cb48ab4 100644 --- a/gcc/testsuite/gfortran.dg/inline_matmul_16.f90 +++ b/gcc/testsuite/gfortran.dg/inline_matmul_16.f90 @@ -58,4 +58,4 @@ program main end do end do end program main -! { dg-final { scan-tree-dump-times "_gfortran_matmul" 1 "optimized" } } +! { dg-final { scan-tree-dump-not "_gfortran_matmul" "optimized" } } diff --git a/gcc/testsuite/gfortran.dg/inline_matmul_26.f90 b/gcc/testsuite/gfortran.dg/inline_matmul_26.f90 new file mode 100644 index 000000000000..0876941ad4cd --- /dev/null +++ b/gcc/testsuite/gfortran.dg/inline_matmul_26.f90 @@ -0,0 +1,36 @@ +! { dg-do run } +! { dg-options "-ffrontend-optimize -fdump-tree-optimized -Wrealloc-lhs -finline-matmul-limit=1000 -O" } +! PR 66094: Check functionality for MATMUL(TRANSPOSE(A),B)) for two-dimensional arrays +program main + implicit none + integer :: in, im, icnt + integer, volatile :: ten + + ten = 10 + ! cycle through a few test cases... + do in = 2,ten + do im = 2,ten + do icnt = 2,ten + block + real, dimension(icnt,in) :: a2 + real, dimension(icnt,im) :: b2 + real, dimension(in,im) :: c2,cr + integer :: i,j,k + call random_number(a2) + call random_number(b2) + c2 = 0 + do i=1,size(a2,2) + do j=1, size(b2,2) + do k=1, size(a2,1) + c2(i,j) = c2(i,j) + a2(k,i) * b2(k,j) + end do + end do + end do + cr = matmul(transpose(a2), b2) + if (any(abs(c2-cr) > 1e-4)) STOP 7 + end block + end do + end do + end do +end program main +! { dg-final { scan-tree-dump-times "_gfortran_matmul" 1 "optimized" } } diff --git a/gcc/testsuite/gfortran.dg/interface_63.f90 b/gcc/testsuite/gfortran.dg/interface_63.f90 new file mode 100644 index 000000000000..56c1644ed822 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/interface_63.f90 @@ -0,0 +1,97 @@ +! { dg-do compile } +! PR fortran/120784 - fix checking of renamed-on-use interface name +! +! Contributed by Matt Thompson + +module A_mod + implicit none + + interface Get + procedure :: get_1 + procedure :: get_2 + end interface Get + +contains + + subroutine get_1(i) + integer :: i + i = 5 + end subroutine get_1 + + subroutine get_2(x) + real :: x + x = 4 + end subroutine get_2 +end module A_mod + +module B_mod + use A_mod, only : MyGet => Get + implicit none + + interface MyGet + procedure :: other_get + end interface MyGet + +contains + + subroutine other_get(c) + character(1) :: c + c = 'a' + end subroutine other_get + + subroutine check_get () + character :: c + integer :: i + real :: r + call myget (c) + call myget (i) + call myget (r) + end subroutine check_get + +end module B_MOD + +program p + use b_mod, only: myget + implicit none + character :: c + integer :: i + real :: r + call myget (c) + call myget (i) + call myget (r) +end + +! Check that we do not regress on the following: + +module mod1 + implicit none + + interface local + module procedure local_data + end interface local + +contains + + logical function local_data (data) result (local) + real, intent(in) :: data + local = .true. + end function local_data + +end module mod1 + +module mod2 + use mod1, only: local + implicit none + + interface local + module procedure local_invt + end interface local + +contains + + logical function local_invt (invt) result (local) + integer, intent(in) :: invt + local = .true. + end function local_invt + +end module mod2 diff --git a/gcc/testsuite/gfortran.dg/move_alloc_20.f03 b/gcc/testsuite/gfortran.dg/move_alloc_20.f03 new file mode 100644 index 000000000000..20403c300287 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/move_alloc_20.f03 @@ -0,0 +1,151 @@ +! { dg-do run } +! +! Check the presence of the pre and post code of the FROM and TO arguments +! of the MOVE_ALLOC intrinsic subroutine. + +module m + implicit none + type :: t + integer, allocatable :: a(:) + end type +end module + +module pre + use m + implicit none + private + public :: check_pre + +contains + + subroutine check_pre + integer, parameter :: n = 5 + type(t) :: x(n) + integer, allocatable :: tmp(:) + integer :: array(4) = [ -1, 0, 1, 2 ] + integer :: i + + if (allocated(tmp)) error stop 1 + + tmp = [17] + + if (.not. allocated(tmp)) error stop 11 + if (any(shape(tmp) /= [1])) error stop 12 + if (any(tmp /= [17])) error stop 13 + do i=1,n + if (allocated(x(i)%a)) error stop 14 + end do + + ! Check that the index of X is properly computed for the evaluation of TO. + call move_alloc(tmp, x(sum(array))%a) + + do i=1,n + if (i == 2) cycle + if (allocated(x(i)%a)) error stop 21 + end do + if (.not. allocated(x(2)%a)) error stop 22 + if (any(shape(x(2)%a) /= [1])) error stop 23 + if (any(x(2)%a /= [17])) error stop 24 + if (allocated(tmp)) error stop 25 + + ! Check that the index of X is properly computed for the evaluation of FROM. + call move_alloc(x(sum(array))%a, tmp) + + if (.not. allocated(tmp)) error stop 31 + if (any(shape(tmp) /= [1])) error stop 32 + if (any(tmp /= [17])) error stop 33 + do i=1,n + if (allocated(x(i)%a)) error stop 34 + end do + end subroutine + +end module + +module post + use m + implicit none + private + public :: check_post + integer, parameter :: n = 5 + type(t), target :: x(n) + type :: u + integer :: a + contains + final :: finalize + end type + integer :: finalization_count = 0 + +contains + + function idx(arg) + type(u) :: arg + integer :: idx + idx = mod(arg%a, n) + end function + + subroutine check_post + type(u) :: y + integer, allocatable :: tmp(:) + integer, target :: array(4) = [ -1, 0, 1, 2 ] + integer :: i + + y%a = 12 + + if (allocated(tmp)) error stop 1 + + tmp = [37] + + if (.not. allocated(tmp)) error stop 11 + if (any(shape(tmp) /= [1])) error stop 12 + if (any(tmp /= [37])) error stop 13 + if (finalization_count /= 0) error stop 14 + do i=1,n + if (allocated(x(i)%a)) error stop 15 + end do + + ! Check that the cleanup code for the evaluation of TO is properly + ! executed after MOVE_ALLOC: the result of GET_U should be finalized. + call move_alloc(tmp, x(idx(get_u(y)))%a) + + do i=1,n + if (i == 2) cycle + if (allocated(x(i)%a)) error stop 21 + end do + if (.not. allocated(x(2)%a)) error stop 22 + if (any(shape(x(2)%a) /= [1])) error stop 23 + if (any(x(2)%a /= [37])) error stop 24 + if (allocated(tmp)) error stop 25 + if (finalization_count /= 1) error stop 26 + + ! Check that the cleanup code for the evaluation of FROM is properly + ! executed after MOVE_ALLOC: the result of GET_U should be finalized. + call move_alloc(x(idx(get_u(y)))%a, tmp) + + if (.not. allocated(tmp)) error stop 31 + if (any(shape(tmp) /= [1])) error stop 32 + if (any(tmp /= [37])) error stop 33 + if (finalization_count /= 2) error stop 34 + do i=1,n + if (allocated(x(i)%a)) error stop 35 + end do + end subroutine + + function get_u(arg) + type(u) :: arg, get_u + get_u = arg + end function get_u + + subroutine finalize(obj) + type(u) :: obj + finalization_count = finalization_count + 1 + end subroutine + +end module + +program p + use pre + use post + implicit none + call check_pre + call check_post +end program diff --git a/gcc/testsuite/gfortran.dg/non_lvalue_1.f90 b/gcc/testsuite/gfortran.dg/non_lvalue_1.f90 new file mode 100644 index 000000000000..61dad5a2ce1b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/non_lvalue_1.f90 @@ -0,0 +1,32 @@ +! { dg-do compile } +! { dg-additional-options "-fdump-tree-original" } +! +! Check the generation of NON_LVALUE_EXPR expressions in cases where a unary +! operator expression would simplify to a bare data reference. + +! A NON_LVALUE_EXPR is generated for a double negation that would simplify to +! a bare data reference. +function f1 (f1_arg1) + integer, value :: f1_arg1 + integer :: f1 + f1 = -(-f1_arg1) +end function +! { dg-final { scan-tree-dump "__result_f1 = NON_LVALUE_EXPR ;" "original" } } + +! A NON_LVALUE_EXPR is generated for a double complement that would simplify to +! a bare data reference. +function f2 (f2_arg1) + integer, value :: f2_arg1 + integer :: f2 + f2 = not(not(f2_arg1)) +end function +! { dg-final { scan-tree-dump "__result_f2 = NON_LVALUE_EXPR ;" "original" } } + +! A NON_LVALUE_EXPR is generated for a double complex conjugate that would +! simplify to a bare data reference. +function f3 (f3_arg1) + complex, value :: f3_arg1 + complex :: f3 + f3 = conjg(conjg(f3_arg1)) +end function +! { dg-final { scan-tree-dump "__result_f3 = NON_LVALUE_EXPR ;" "original" } } diff --git a/gcc/testsuite/gfortran.dg/pointer_check_15.f90 b/gcc/testsuite/gfortran.dg/pointer_check_15.f90 new file mode 100644 index 000000000000..13c6820be0e3 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pointer_check_15.f90 @@ -0,0 +1,46 @@ +! { dg-do run } +! { dg-additional-options "-O -fcheck=pointer -fdump-tree-original" } +! +! PR fortran/121145 +! Erroneous runtime error: Proc-pointer actual argument 'ptr' is not associated +! +! Contributed by Federico Perini. + +module m + implicit none + + abstract interface + subroutine fun(x) + real, intent(in) :: x + end subroutine fun + end interface + +contains + + subroutine with_fun(sub) + procedure(fun), optional :: sub + if (present(sub)) stop 1 + end subroutine + + subroutine with_non_optional(sub) + procedure(fun) :: sub + end subroutine + +end module m + +program p + use m + implicit none + + procedure(fun), pointer :: ptr1 => null() + procedure(fun), pointer :: ptr2 => null() + + call with_fun() + call with_fun(sub=ptr1) ! no runtime check here + + if (associated (ptr2)) then + call with_non_optional(sub=ptr2) ! runtime check here + end if +end + +! { dg-final { scan-tree-dump-times "Proc-pointer actual argument .'ptr2.'" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/pr120743.f90 b/gcc/testsuite/gfortran.dg/pr120743.f90 new file mode 100644 index 000000000000..8682d0c8859e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr120743.f90 @@ -0,0 +1,38 @@ +! { dg-do compile } +! PR fortran/120743 - ICE in verify_gimple_in_seq with substrings +! +! Testcase as reduced by Jerry DeLisle + +module what + implicit none + CHARACTER(LEN=:), ALLOCATABLE :: attrlist +contains + SUBROUTINE get_c_attr ( attrname, attrval_c ) + ! + ! returns attrval_c='' if not found + ! + IMPLICIT NONE + CHARACTER(LEN=*), INTENT(IN) :: attrname + CHARACTER(LEN=*), INTENT(OUT) :: attrval_c + ! + CHARACTER(LEN=1) :: quote + INTEGER :: j0, j1 + LOGICAL :: found + ! + ! search for attribute name in attrlist: attr1="val1" attr2="val2" ... + ! + attrval_c = '' + if ( .not. allocated(attrlist) ) return + if ( len_trim(attrlist) < 1 ) return + ! + j0 = 1 + do while ( j0 < len_trim(attrlist) ) + ! locate = and first quote + j1 = index ( attrlist(j0:), '=' ) + quote = attrlist(j0+j1:j0+j1) + ! next line: something is not right + if ( quote /= '"' .and. quote /= "'" ) return + end do + ! + END SUBROUTINE get_c_attr +end module what diff --git a/gcc/testsuite/gfortran.dg/save_alloc_character_1.f90 b/gcc/testsuite/gfortran.dg/save_alloc_character_1.f90 new file mode 100644 index 000000000000..e26919f83bea --- /dev/null +++ b/gcc/testsuite/gfortran.dg/save_alloc_character_1.f90 @@ -0,0 +1,23 @@ +! { dg-do run } +! +! PR fortran/120713 +! Check that the length variable of SAVEd allocatable character arrays are +! not initialized at function entry. + +program p + implicit none + call s(1) + call s(2) +contains + subroutine s(i) + integer, intent(in) :: i + character(len=:), allocatable, save :: a(:) + integer :: j + if (i == 1) then + allocate(a, source= [ ('x' // achar(ichar('0') + j), j=1,7) ]) + else + if (len(a) /= 2) error stop 1 + if (any(a /= ['x1','x2','x3','x4','x5','x6','x7'])) error stop 2 + end if + end subroutine s +end program p diff --git a/gcc/testsuite/gfortran.dg/select_type_51.f90 b/gcc/testsuite/gfortran.dg/select_type_51.f90 new file mode 100644 index 000000000000..6099be1c7622 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/select_type_51.f90 @@ -0,0 +1,37 @@ +! { dg-do compile } +! +! Check the support by the compiler of very long symbol names in SELECT TYPE +! and TYPE IS statements. +! +! Original testcase by Harald Anlauf. + +module m + implicit none + type t2345678901234567890123456789012345678901234567890123456789_123 + integer :: i + end type t2345678901234567890123456789012345678901234567890123456789_123 + class(*), allocatable :: a, & + c2345678901234567890123456789012345678901234567890123456789_123 +contains + subroutine check_type_is_intrinsic() + select type (s2345678901234567890123456789012345678901234567890123456789_123 & + => c2345678901234567890123456789012345678901234567890123456789_123) + type is (integer(kind=4)) + print *, s2345678901234567890123456789012345678901234567890123456789_123 + end select + end subroutine + subroutine check_type_is_derived() + select type (s2345678901234567890123456789012345678901234567890123456789_123 & + => c2345678901234567890123456789012345678901234567890123456789_123) + type is (t2345678901234567890123456789012345678901234567890123456789_123) + print *, s2345678901234567890123456789012345678901234567890123456789_123%i + end select + end subroutine + subroutine check_type_is_class() + select type (s2345678901234567890123456789012345678901234567890123456789_123 & + => c2345678901234567890123456789012345678901234567890123456789_123) + class is (t2345678901234567890123456789012345678901234567890123456789_123) + print *, s2345678901234567890123456789012345678901234567890123456789_123%i + end select + end subroutine +end module m diff --git a/gcc/testsuite/gfortran.dg/stat_3.f90 b/gcc/testsuite/gfortran.dg/stat_3.f90 new file mode 100644 index 000000000000..93ec1836a9a9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/stat_3.f90 @@ -0,0 +1,46 @@ +! { dg-do compile } +! PR fortran/82480 - checking of arguments to STAT/LSTAT/FSTAT + +subroutine sub1 () + integer, parameter :: ik = kind(1) + integer(ik) :: buff12(12) + integer(ik) :: buff13(13) + integer(ik) :: unit = 10 + integer(ik) :: ierr + character(len=64) :: name = "/etc/passwd" + ierr = stat (name, values= buff12) ! { dg-error "too small" } + ierr = stat (name, values= buff13) + ierr = lstat (name, values= buff12) ! { dg-error "too small" } + ierr = lstat (name, values= buff13) + ierr = fstat (unit, values= buff12) ! { dg-error "too small" } + ierr = fstat (unit, values= buff13) + ierr = stat (name, values=(buff13)) ! { dg-error "must be a variable" } + ierr = lstat (name, values=(buff13)) ! { dg-error "must be a variable" } + ierr = fstat (unit, values=(buff13)) ! { dg-error "must be a variable" } +end + +subroutine sub2 () + integer, parameter :: ik = kind(1) + integer(ik) :: buff12(12) + integer(ik), target :: buff13(13) = 0 + integer(ik) :: unit = 10 + integer(ik), target :: ierr = 0 + character(len=64) :: name = "/etc/passwd" + integer(ik),pointer :: pbuf(:) => buff13 + integer(ik),pointer :: perr => ierr + call stat (name, status=ierr, values= buff12) ! { dg-error "too small" } + call stat (name, status=ierr, values= buff13) + call lstat (name, status=ierr, values= buff12) ! { dg-error "too small" } + call lstat (name, status=ierr, values= buff13) + call fstat (unit, status=ierr, values= buff12) ! { dg-error "too small" } + call fstat (unit, status=ierr, values= buff13) + call stat (name, status=ierr, values=(buff13)) ! { dg-error "must be a variable" } + call lstat (name, status=ierr, values=(buff13)) ! { dg-error "must be a variable" } + call fstat (unit, status=ierr, values=(buff13)) ! { dg-error "must be a variable" } + call stat (name, status=(ierr),values=buff13) ! { dg-error "must be a variable" } + call lstat (name, status=(ierr),values=buff13) ! { dg-error "must be a variable" } + call fstat (unit, status=(ierr),values=buff13) ! { dg-error "must be a variable" } + call stat (name, status=perr, values= pbuf) + call lstat (name, status=perr, values= pbuf) + call fstat (unit, status=perr, values= pbuf) +end diff --git a/gcc/testsuite/gm2.dg/doc/examples/run/pass/doc-examples-run-pass.exp b/gcc/testsuite/gm2.dg/doc/examples/run/pass/doc-examples-run-pass.exp new file mode 100644 index 000000000000..6fb7d6e2cf37 --- /dev/null +++ b/gcc/testsuite/gm2.dg/doc/examples/run/pass/doc-examples-run-pass.exp @@ -0,0 +1,17 @@ +# Compile tests, no torture testing. +# +# These tests should all pass. + +# Load support procs. +load_lib gm2-dg.exp + +gm2_init_pim4 $srcdir/$subdir -masm=intel + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] "" "" + +# All done. +dg-finish diff --git a/gcc/testsuite/gm2.dg/doc/examples/run/pass/exampleadd2.mod b/gcc/testsuite/gm2.dg/doc/examples/run/pass/exampleadd2.mod new file mode 100644 index 000000000000..8bab2994c226 --- /dev/null +++ b/gcc/testsuite/gm2.dg/doc/examples/run/pass/exampleadd2.mod @@ -0,0 +1,35 @@ +(* { dg-do assemble { target { x86_64-*-gnu* } } } *) +(* { dg-options "-masm=intel" } *) +(* { dg-do run { target x86_64-*-gnu* } } *) + +MODULE exampleadd2 ; + +FROM libc IMPORT printf, exit ; + + +PROCEDURE Example (foo, bar: LONGCARD) : CARDINAL ; +VAR + myout: LONGCARD ; +BEGIN + ASM VOLATILE ( + "mov rax, %[left]; add rax, %[right]; mov %[output], rax;" + : [output] "=rm" (myout) (* outputs *) + : [left] "rm" (foo), [right] "rm" (bar) (* inputs *) + : "rax") ; (* we trash *) + RETURN( myout ) +END Example ; + +VAR + a, b, c: CARDINAL ; +BEGIN + a := 1 ; + b := 2 ; + c := Example (a, b) ; + IF c = 3 + THEN + printf ("success result from function is %d\n", c) ; + ELSE + printf ("example failed to return 3, seen %d\n" , c) ; + exit (1) + END +END exampleadd2. \ No newline at end of file diff --git a/gcc/testsuite/gm2/iso/fail/CHAR.mod b/gcc/testsuite/gm2/iso/fail/CHAR.mod new file mode 100644 index 000000000000..0e7d43e24251 --- /dev/null +++ b/gcc/testsuite/gm2/iso/fail/CHAR.mod @@ -0,0 +1,7 @@ +MODULE CHAR ; + +IMPORT CHAR ; + +BEGIN + CHAR.Write ("h") +END CHAR. diff --git a/gcc/testsuite/gm2/iso/fail/badreturn.mod b/gcc/testsuite/gm2/iso/fail/badreturn.mod new file mode 100644 index 000000000000..54179611eccd --- /dev/null +++ b/gcc/testsuite/gm2/iso/fail/badreturn.mod @@ -0,0 +1,5 @@ +MODULE badreturn ; + +BEGIN + RETURN 0 +END badreturn. \ No newline at end of file diff --git a/gcc/testsuite/gm2/iso/fail/badreturn2.mod b/gcc/testsuite/gm2/iso/fail/badreturn2.mod new file mode 100644 index 000000000000..a4b90085f1f3 --- /dev/null +++ b/gcc/testsuite/gm2/iso/fail/badreturn2.mod @@ -0,0 +1,12 @@ +MODULE badreturn2 ; + + +PROCEDURE foo ; +BEGIN + RETURN 0 +END foo ; + + +BEGIN + foo +END badreturn2. diff --git a/gcc/testsuite/gm2/iso/pass/modulereturn.mod b/gcc/testsuite/gm2/iso/pass/modulereturn.mod new file mode 100644 index 000000000000..b39947d37200 --- /dev/null +++ b/gcc/testsuite/gm2/iso/pass/modulereturn.mod @@ -0,0 +1,5 @@ +MODULE modulereturn ; + +BEGIN + RETURN +END modulereturn. diff --git a/gcc/testsuite/gm2/iso/pass/modulereturn2.mod b/gcc/testsuite/gm2/iso/pass/modulereturn2.mod new file mode 100644 index 000000000000..934cfae79020 --- /dev/null +++ b/gcc/testsuite/gm2/iso/pass/modulereturn2.mod @@ -0,0 +1,10 @@ +MODULE modulereturn2 ; + + +BEGIN + RETURN +EXCEPT + RETURN +FINALLY + RETURN +END modulereturn2. diff --git a/gcc/testsuite/gm2/iso/run/pass/CHAR.mod b/gcc/testsuite/gm2/iso/run/pass/CHAR.mod new file mode 100644 index 000000000000..4ca86b8ad326 --- /dev/null +++ b/gcc/testsuite/gm2/iso/run/pass/CHAR.mod @@ -0,0 +1,7 @@ +MODULE CHAR ; + +FROM libc IMPORT printf ; + +BEGIN + printf ("hello world\n") +END CHAR. diff --git a/gcc/testsuite/gm2/iso/run/pass/importself.mod b/gcc/testsuite/gm2/iso/run/pass/importself.mod new file mode 100644 index 000000000000..06cf7176af59 --- /dev/null +++ b/gcc/testsuite/gm2/iso/run/pass/importself.mod @@ -0,0 +1,14 @@ +MODULE importself ; + +IMPORT importself ; + + +PROCEDURE foo ; +BEGIN + +END foo ; + +BEGIN + foo ; + importself.foo +END importself. diff --git a/gcc/testsuite/gm2/isolib/run/pass/testdelete2.mod b/gcc/testsuite/gm2/isolib/run/pass/testdelete2.mod new file mode 100644 index 000000000000..386b49d51a86 --- /dev/null +++ b/gcc/testsuite/gm2/isolib/run/pass/testdelete2.mod @@ -0,0 +1,107 @@ +MODULE testdelete2 ; + +(* A test module to test file creation and deletion using ISO + libraries. *) + + +IMPORT DynamicStrings, StringFileSysOp, + FileSysOp, SeqFile, TextIO, Strings, + IOChanUtils ; + +FROM libc IMPORT printf, exit ; +FROM FormatStrings IMPORT Sprintf1 ; + + +CONST + MaxFile = 10 ; + +VAR + files: ARRAY [0..MaxFile] OF SeqFile.ChanId ; + + +PROCEDURE Assert (condition: BOOLEAN; line: CARDINAL) ; +BEGIN + IF NOT condition + THEN + printf ("%s:%d: assert failed\n", __FILE__, line) ; + exit (1) + END +END Assert ; + + +(* + CreateFiles - create MaxFile files saving the file handle + into files. +*) + +PROCEDURE CreateFiles ; +VAR + i : CARDINAL ; + name: ARRAY [0..10] OF CHAR ; + ch : CHAR ; + res : SeqFile.OpenResults ; +BEGIN + FOR i := 1 TO HIGH (files) DO + Strings.Assign ('file', name) ; + ch := CHR (ORD ('0')+i-1) ; + name[4] := ch ; + name[5] := 0C ; + SeqFile.OpenWrite (files[i], name, + SeqFile.text+SeqFile.write, res) ; + TextIO.WriteString (files[i], "some text inside file ") ; + TextIO.WriteLn (files[i]) ; + SeqFile.Close (files[i]) + END +END CreateFiles ; + + +(* + DeleteFiles - delete every file in files. +*) + +PROCEDURE DeleteFiles ; +VAR + i : CARDINAL ; + name: ARRAY [0..10] OF CHAR ; + s : DynamicStrings.String ; + ch : CHAR ; + res : SeqFile.OpenResults ; +BEGIN + (* Open the files first. *) + FOR i := 1 TO HIGH (files) DO + Strings.Assign ('file', name) ; + ch := CHR (ORD ('0')+i-1) ; + name[4] := ch ; + name[5] := 0C ; + SeqFile.OpenRead (files[i], name, SeqFile.text, res) ; + Assert (FileSysOp.Exists (name), __LINE__) ; + Assert (FileSysOp.IsFile (name), __LINE__) + END ; + (* Now delete them. *) + FOR i := 1 TO HIGH (files) DO + s := IOChanUtils.GetFileName (files[i]) ; + Assert (StringFileSysOp.Exists (s), __LINE__) ; + Assert (StringFileSysOp.IsFile (s), __LINE__) ; + Assert (StringFileSysOp.Unlink (s), __LINE__) ; + Assert (NOT StringFileSysOp.Exists (s), __LINE__) ; + SeqFile.Close (files[i]) ; + s := DynamicStrings.KillString (s) + END +END DeleteFiles ; + + +(* + Init - +*) + +PROCEDURE Init ; +BEGIN + CreateFiles ; + DeleteFiles ; + printf ("all tests passed\n") +END Init ; + + +BEGIN + Init +END testdelete2. diff --git a/gcc/testsuite/gm2/pim/fail/badmodvar.mod b/gcc/testsuite/gm2/pim/fail/badmodvar.mod new file mode 100644 index 000000000000..dd90920af71f --- /dev/null +++ b/gcc/testsuite/gm2/pim/fail/badmodvar.mod @@ -0,0 +1,7 @@ +MODULE badmodvar ; + +VAR + x: y ; +BEGIN + +END badmodvar. diff --git a/gcc/testsuite/gm2/pim/fail/cyclictypes.mod b/gcc/testsuite/gm2/pim/fail/cyclictypes.mod new file mode 100644 index 000000000000..f2adb49c9082 --- /dev/null +++ b/gcc/testsuite/gm2/pim/fail/cyclictypes.mod @@ -0,0 +1,13 @@ +MODULE cyclictypes ; + +TYPE + A = B; + B = A; + +PROCEDURE foo ; +VAR + bar: A ; +END foo ; + + +END cyclictypes. diff --git a/gcc/testsuite/gm2/pim/fail/cyclictypes2.mod b/gcc/testsuite/gm2/pim/fail/cyclictypes2.mod new file mode 100644 index 000000000000..a5630c86ff6a --- /dev/null +++ b/gcc/testsuite/gm2/pim/fail/cyclictypes2.mod @@ -0,0 +1,9 @@ +MODULE cyclictypes2 ; + +TYPE + A = B; + B = A; + +VAR + bar: A ; +END cyclictypes2. diff --git a/gcc/testsuite/gm2/pim/fail/cyclictypes4.mod b/gcc/testsuite/gm2/pim/fail/cyclictypes4.mod new file mode 100644 index 000000000000..69f061b6ebb1 --- /dev/null +++ b/gcc/testsuite/gm2/pim/fail/cyclictypes4.mod @@ -0,0 +1,13 @@ +MODULE cyclictypes4 ; + +TYPE + A = B ; + B = C ; + C = D ; + D = A ; + +VAR + v: A ; +BEGIN + +END cyclictypes4. diff --git a/gcc/testsuite/gm2/pim/pass/forarray.mod b/gcc/testsuite/gm2/pim/pass/forarray.mod new file mode 100644 index 000000000000..e1b41e793bc0 --- /dev/null +++ b/gcc/testsuite/gm2/pim/pass/forarray.mod @@ -0,0 +1,21 @@ +MODULE forarray ; + + +VAR + array: ARRAY [0..10] OF CARDINAL ; + + +PROCEDURE Init ; +VAR + i, n: CARDINAL ; +BEGIN + array[0] := 10 ; + n := 0 ; + FOR i := 1 TO array[n] DO + END +END Init ; + + +BEGIN + Init +END forarray. diff --git a/gcc/testsuite/gm2/pimlib/logitech/run/pass/testdelete2.mod b/gcc/testsuite/gm2/pimlib/logitech/run/pass/testdelete2.mod new file mode 100644 index 000000000000..977d498e656c --- /dev/null +++ b/gcc/testsuite/gm2/pimlib/logitech/run/pass/testdelete2.mod @@ -0,0 +1,104 @@ +MODULE testdelete2 ; + +(* A test module to test file creation and deletion using log + libraries. *) + + +IMPORT FIO, SFIO, DynamicStrings, StringFileSysOp, + FileSysOp, FileSystem, StrLib ; + +FROM libc IMPORT printf, exit ; +FROM FormatStrings IMPORT Sprintf1 ; + + +CONST + MaxFile = 10 ; + +VAR + files: ARRAY [0..MaxFile] OF FileSystem.File ; + + +PROCEDURE Assert (condition: BOOLEAN; line: CARDINAL) ; +BEGIN + IF NOT condition + THEN + printf ("%s:%d: assert failed\n", __FILE__, line) ; + exit (1) + END +END Assert ; + + +(* + CreateFiles - create MaxFile files saving the file handle + into files. +*) + +PROCEDURE CreateFiles ; +VAR + i : CARDINAL ; + name: ARRAY [0..10] OF CHAR ; + ch : CHAR ; +BEGIN + FOR i := 1 TO HIGH (files) DO + StrLib.StrCopy ('file', name) ; + ch := CHR (ORD ('0')+i-1) ; + name[4] := ch ; + name[5] := 0C ; + FileSystem.Lookup (files[i], name, TRUE) ; + FileSystem.WriteString (files[i], "some text inside file ") ; + FileSystem.WriteChar (files[i], ch) ; + FileSystem.WriteString (files[i], "\n") ; + FileSystem.Close (files[i]) + END +END CreateFiles ; + + +(* + DeleteFiles - delete every file in files. +*) + +PROCEDURE DeleteFiles ; +VAR + i : CARDINAL ; + name: ARRAY [0..10] OF CHAR ; + s : DynamicStrings.String ; + ch : CHAR ; +BEGIN + (* Open the files first. *) + FOR i := 1 TO HIGH (files) DO + StrLib.StrCopy ('file', name) ; + ch := CHR (ORD ('0')+i-1) ; + name[4] := ch ; + name[5] := 0C ; + FileSystem.Lookup (files[i], name, FALSE) ; + Assert (FileSysOp.Exists (name), __LINE__) ; + Assert (FileSysOp.IsFile (name), __LINE__) + END ; + (* Now delete them. *) + FOR i := 1 TO HIGH (files) DO + s := FileSystem.GetFileName (files[i]) ; + Assert (StringFileSysOp.Exists (s), __LINE__) ; + Assert (StringFileSysOp.IsFile (s), __LINE__) ; + Assert (StringFileSysOp.Unlink (s), __LINE__) ; + Assert (NOT StringFileSysOp.Exists (s), __LINE__) ; + FileSystem.Close (files[i]) ; + s := DynamicStrings.KillString (s) + END +END DeleteFiles ; + + +(* + Init - +*) + +PROCEDURE Init ; +BEGIN + CreateFiles ; + DeleteFiles ; + printf ("all tests passed\n") +END Init ; + + +BEGIN + Init +END testdelete2. diff --git a/gcc/testsuite/gm2/pimlib/logitech/run/pass/teststrings.mod b/gcc/testsuite/gm2/pimlib/logitech/run/pass/teststrings.mod new file mode 100644 index 000000000000..1085d9cf4ecc --- /dev/null +++ b/gcc/testsuite/gm2/pimlib/logitech/run/pass/teststrings.mod @@ -0,0 +1,16 @@ +MODULE teststrings ; + +IMPORT InOut,Strings; + +VAR + content : ARRAY[1..256] OF CHAR; + position: CARDINAL; + +(* the content is just random text. *) + +BEGIN + content := "erreur: In program module « essai3 »: attempting to pass (1) parameters to procedure"; + InOut.WriteString(content); + InOut.WriteLn; + position := Strings.Pos ("IMPORT", content); +END teststrings . diff --git a/gcc/testsuite/gm2/pimlib/run/pass/testdelete.mod b/gcc/testsuite/gm2/pimlib/run/pass/testdelete.mod new file mode 100644 index 000000000000..8afdc445cae2 --- /dev/null +++ b/gcc/testsuite/gm2/pimlib/run/pass/testdelete.mod @@ -0,0 +1,97 @@ +MODULE testdelete ; + +(* A test module to test file creation and deletion using base + PIM libraries. *) + + +IMPORT FIO, SFIO, DynamicStrings, StringFileSysOp ; +FROM libc IMPORT printf, exit ; +FROM FormatStrings IMPORT Sprintf1 ; + + +CONST + MaxFile = 10 ; + +VAR + files: ARRAY [0..MaxFile] OF FIO.File ; + + +PROCEDURE Assert (condition: BOOLEAN; line: CARDINAL) ; +BEGIN + IF NOT condition + THEN + printf ("%s:%d: assert failed\n", __FILE__, line) ; + exit (1) + END +END Assert ; + + +(* + CreateFiles - create MaxFile files saving the file handle + into files. +*) + +PROCEDURE CreateFiles ; +VAR + i: CARDINAL ; + s: DynamicStrings.String ; +BEGIN + FOR i := 1 TO HIGH (files) DO + s := DynamicStrings.InitString ("file%03d") ; + s := Sprintf1 (s, i) ; + files[i] := SFIO.OpenToWrite (s) ; + s := DynamicStrings.KillString (s) ; + s := DynamicStrings.InitString ("some text inside file %d\n") ; + s := Sprintf1 (s, i) ; + s := DynamicStrings.KillString (SFIO.WriteS (files[i], s)) ; + FIO.Close (files[i]) + END +END CreateFiles ; + + +(* + DeleteFiles - delete every file in files. +*) + +PROCEDURE DeleteFiles ; +VAR + i: CARDINAL ; + s: DynamicStrings.String ; +BEGIN + (* Open the files first. *) + FOR i := 1 TO HIGH (files) DO + s := DynamicStrings.InitString ("file%03d") ; + s := Sprintf1 (s, i) ; + files[i] := SFIO.OpenToRead (s) ; + Assert (StringFileSysOp.Exists (s), __LINE__) ; + Assert (StringFileSysOp.IsFile (s), __LINE__) ; + s := DynamicStrings.KillString (s) + END ; + (* Now delete them. *) + FOR i := 1 TO HIGH (files) DO + s := SFIO.GetFileName (files[i]) ; + Assert (StringFileSysOp.Exists (s), __LINE__) ; + Assert (StringFileSysOp.IsFile (s), __LINE__) ; + Assert (StringFileSysOp.Unlink (s), __LINE__) ; + Assert (NOT StringFileSysOp.Exists (s), __LINE__) ; + FIO.Close (files[i]) ; + s := DynamicStrings.KillString (s) + END +END DeleteFiles ; + + +(* + Init - +*) + +PROCEDURE Init ; +BEGIN + CreateFiles ; + DeleteFiles ; + printf ("all tests passed\n") +END Init ; + + +BEGIN + Init +END testdelete. diff --git a/gcc/testsuite/gm2/pimlib/run/pass/testwrite.mod b/gcc/testsuite/gm2/pimlib/run/pass/testwrite.mod new file mode 100644 index 000000000000..ce1f0351a051 --- /dev/null +++ b/gcc/testsuite/gm2/pimlib/run/pass/testwrite.mod @@ -0,0 +1,8 @@ +MODULE testwrite ; + +IMPORT ARRAYOFCHAR ; +FROM FIO IMPORT StdOut ; + +BEGIN + ARRAYOFCHAR.Write (StdOut, "hello world") ; ARRAYOFCHAR.WriteLn (StdOut) +END testwrite. diff --git a/gcc/testsuite/gm2/pimlib/run/pass/testwritechar.mod b/gcc/testsuite/gm2/pimlib/run/pass/testwritechar.mod new file mode 100644 index 000000000000..c2f739de6449 --- /dev/null +++ b/gcc/testsuite/gm2/pimlib/run/pass/testwritechar.mod @@ -0,0 +1,13 @@ +MODULE testwritechar ; + +IMPORT CHAR ; +FROM FIO IMPORT StdOut ; + +BEGIN + CHAR.Write (StdOut, 'h') ; + CHAR.Write (StdOut, 'e') ; + CHAR.Write (StdOut, 'l') ; + CHAR.Write (StdOut, 'l') ; + CHAR.Write (StdOut, 'o') ; + CHAR.WriteLn (StdOut) +END testwritechar. diff --git a/gcc/testsuite/gnat.dg/concat6.adb b/gcc/testsuite/gnat.dg/concat6.adb new file mode 100644 index 000000000000..015be56bcb2b --- /dev/null +++ b/gcc/testsuite/gnat.dg/concat6.adb @@ -0,0 +1,9 @@ +-- { dg-do compile } + +with Ada.Text_IO; use Ada.Text_IO; + +procedure Concat6 is + C : constant character := 16#00#; -- { dg-error "expected type|found type" } +begin + Put_Line ("Test " & C); +end; diff --git a/gcc/testsuite/gnat.dg/deref4.adb b/gcc/testsuite/gnat.dg/deref4.adb new file mode 100644 index 000000000000..586a61869eae --- /dev/null +++ b/gcc/testsuite/gnat.dg/deref4.adb @@ -0,0 +1,9 @@ +-- { dg-do compile } +-- { dg-options "-gnatX" } + +with Deref4_Pkg; use Deref4_Pkg; + +procedure Deref4 is +begin + Obj.Proc (null); +end; diff --git a/gcc/testsuite/gnat.dg/deref4_pkg.ads b/gcc/testsuite/gnat.dg/deref4_pkg.ads new file mode 100644 index 000000000000..9410d0d22bc3 --- /dev/null +++ b/gcc/testsuite/gnat.dg/deref4_pkg.ads @@ -0,0 +1,8 @@ +package Deref4_Pkg is + + type A is tagged null record; + type A_Ptr is access A; + procedure Proc (This : in out A'Class; Some_Parameter : A_Ptr) is null; + Obj : A_Ptr; + +end Deref4_Pkg; diff --git a/gcc/testsuite/gnat.dg/specs/aggr7.ads b/gcc/testsuite/gnat.dg/specs/aggr7.ads new file mode 100644 index 000000000000..06980b317b35 --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/aggr7.ads @@ -0,0 +1,11 @@ +-- { dg-do compile } + +package Aggr7 is + + type Arr is array (Integer range <>) of Boolean; + + Data : constant Arr := (False, True); + + function Get_Data return Arr is (Data); + +end Aggr7; diff --git a/gcc/testsuite/gnat.dg/specs/aggr8.ads b/gcc/testsuite/gnat.dg/specs/aggr8.ads new file mode 100644 index 000000000000..3847c4e4e9f9 --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/aggr8.ads @@ -0,0 +1,14 @@ +-- PR ada/120665 +-- { dg-do compile } +-- { dg-options "-gnat2022" } + +package Aggr8 is + + type T is null record + with Aggregate => (Empty => Empty, Add_Named => Add_Named); + + function Empty return T is ([]); -- { dg-warning "empty|infinite" } + + procedure Add_Named (this : in out T; k : Integer; v : Integer) is null; + +end Aggr8; diff --git a/gcc/testsuite/gnat.dg/specs/finalizable2.ads b/gcc/testsuite/gnat.dg/specs/finalizable2.ads new file mode 100644 index 000000000000..b4a6bb1b6ee4 --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/finalizable2.ads @@ -0,0 +1,21 @@ +-- { dg-do compile } +-- { dg-options "-gnatX0" } + +package Finalizable2 is + + type Root is abstract tagged limited null record + with Finalizable => (Initialize => Initialize); + + procedure Initialize (this : in out Root) is abstract; + + type Ext (L : Natural) is new Root with record + A : String (1 .. L); + end record; + + overriding procedure Initialize (this : in out Ext) is null; + + function Make return Ext is (L => 3, A => "asd"); + + Obj : Ext := Make; + +end Finalizable2; diff --git a/gcc/testsuite/gnat.dg/specs/opt7.ads b/gcc/testsuite/gnat.dg/specs/opt7.ads new file mode 100644 index 000000000000..ee151f082a88 --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/opt7.ads @@ -0,0 +1,15 @@ +-- { dg-do compile } +-- { dg-options "-O2 -gnatn" } + +with Opt7_Pkg; use Opt7_Pkg; + +package Opt7 is + + type Rec is record + E : Enum; + end record; + + function Image (R : Rec) return String is + (if R.E = A then Image (R.E) else ""); + +end Opt7; diff --git a/gcc/testsuite/gnat.dg/specs/opt7_pkg.adb b/gcc/testsuite/gnat.dg/specs/opt7_pkg.adb new file mode 100644 index 000000000000..1c9d79bb8721 --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/opt7_pkg.adb @@ -0,0 +1,15 @@ +package body Opt7_Pkg is + + type Constant_String_Access is access constant String; + + type Enum_Name is array (Enum) of Constant_String_Access; + + Enum_Name_Table : constant Enum_Name := + (A => new String'("A"), B => new String'("B")); + + function Image (E : Enum) return String is + begin + return Enum_Name_Table (E).all; + end Image; + +end Opt7_Pkg; diff --git a/gcc/testsuite/gnat.dg/specs/opt7_pkg.ads b/gcc/testsuite/gnat.dg/specs/opt7_pkg.ads new file mode 100644 index 000000000000..2dd271b63adb --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/opt7_pkg.ads @@ -0,0 +1,9 @@ +-- { dg-excess-errors "no code generated" } + +package Opt7_Pkg is + + type Enum is (A, B); + + function Image (E : Enum) return String with Inline; + +end Opt7_Pkg; diff --git a/gcc/testsuite/gnat.dg/sso20.adb b/gcc/testsuite/gnat.dg/sso20.adb new file mode 100644 index 000000000000..34980d35d874 --- /dev/null +++ b/gcc/testsuite/gnat.dg/sso20.adb @@ -0,0 +1,29 @@ +-- { dg-do run } +-- { dg-options "-O" } + +with Ada.Unchecked_Conversion; +with Interfaces; use Interfaces; +with System; use System; + +procedure SSO20 is + + type Bytes_Ref is array (1 .. 4) of Unsigned_8 + with Convention => Ada_Pass_By_Reference; + + type U32_BE is record + Value : Unsigned_32; + end record + with + Pack, + Bit_Order => High_Order_First, + Scalar_Storage_Order => High_Order_First; + + function Conv is new Ada.Unchecked_Conversion (Bytes_Ref, U32_BE); + + function Value (B : Bytes_Ref) return Unsigned_32 is (Conv (B).Value); + +begin + if Value ((16#11#, 16#22#, 16#33#, 16#44#)) /= 16#11223344# then + raise Program_Error; + end if; +end; diff --git a/gcc/testsuite/jit.dg/test-debuginfo.c b/gcc/testsuite/jit.dg/test-debuginfo.c index 49e8834a0ba1..e0d6f2df0240 100644 --- a/gcc/testsuite/jit.dg/test-debuginfo.c +++ b/gcc/testsuite/jit.dg/test-debuginfo.c @@ -1,5 +1,5 @@ /* Essentially this test checks that debug info are generated for globals - locals and functions, including type info. The comment bellow is used + locals and functions, including type info. The comment below is used as fake code (does not affect the test, use for manual debugging). */ /* int a_global_for_test_debuginfo; diff --git a/gcc/testsuite/lib/htmltest.py b/gcc/testsuite/lib/htmltest.py index 8e42a8c2a17e..35f524c8d55c 100644 --- a/gcc/testsuite/lib/htmltest.py +++ b/gcc/testsuite/lib/htmltest.py @@ -9,7 +9,9 @@ def html_tree_from_env(): return ET.parse(html_filename) XHTML = 'http://www.w3.org/1999/xhtml' -ns = {'xhtml': XHTML} +SVG = 'http://www.w3.org/2000/svg' +ns = {'xhtml': XHTML, + 'svg' : SVG} def make_tag(local_name): return f'{{{XHTML}}}' + local_name @@ -83,14 +85,11 @@ def get_diag_by_index(html_tree, index): assert diag_list is not None assert_class(diag_list, 'gcc-diagnostic-list') - diags = diag_list.findall('xhtml:div', ns) - diag = diags[index] - assert_class(diag, 'gcc-diagnostic') + diag = diag_list.find(f"xhtml:div[@id='gcc-diag-{index}']", ns) return diag def get_message_within_diag(diag_element): - msg = diag_element.find('xhtml:span', ns) - assert_class(msg, 'gcc-message') + msg = diag_element.find("xhtml:div[@class='gcc-message']", ns) return msg def get_locus_within_diag(diag_element): diff --git a/gcc/testsuite/lib/sarif.py b/gcc/testsuite/lib/sarif.py index 7daf35b58190..06d05c027a43 100644 --- a/gcc/testsuite/lib/sarif.py +++ b/gcc/testsuite/lib/sarif.py @@ -1,5 +1,6 @@ import json import os +import xml.etree.ElementTree as ET def sarif_from_env(): # return parsed JSON content a SARIF_PATH file @@ -21,3 +22,31 @@ def get_location_snippet_text(location): def get_location_relationships(location): return location['relationships'] + +def get_result_by_index(sarif, idx): + runs = sarif['runs'] + run = runs[0] + results = run['results'] + return results[idx] + +def get_state_graph(events, event_idx): + graph = events[event_idx]['properties']['gcc/diagnostic_event/state_graph'] + if 0: + print(graph) + assert graph is not None + return graph + +def get_state_node_attr(obj, attr_name): + return obj['properties']['gcc/diagnostic_state_node/%s' % attr_name] + +def get_state_node_kind(obj): + return get_state_node_attr(obj, 'kind') + +def get_state_node_name(obj): + return get_state_node_attr(obj, 'name') + +def get_state_node_type(obj): + return get_state_node_attr(obj, 'type') + +def get_state_node_value(obj): + return get_state_node_attr(obj, 'value') diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp index 97935cb23c3c..51952a6a7f45 100644 --- a/gcc/testsuite/lib/scanasm.exp +++ b/gcc/testsuite/lib/scanasm.exp @@ -896,6 +896,10 @@ proc configure_check-function-bodies { config } { set up_config(fluff) {^\s*(?://)} } elseif { [istarget *-*-darwin*] } { set up_config(fluff) {^\s*(?:\.|//|@)|^L[0-9ABCESV]} + } elseif { [istarget s390*-*-*] } { + # Additionally to the defaults skip lines beginning with a # resulting + # from inline asm. + set up_config(fluff) {^\s*(?:\.|//|@|$|#)} } else { # Skip lines beginning with labels ('.L[...]:') or other directives # ('.align', '.cfi_startproc', '.quad [...]', '.text', etc.), '//' or @@ -1109,6 +1113,8 @@ proc check-function-bodies { args } { append function_regexp ".*" } elseif { [regexp {^\.L} $line] } { append function_regexp $line "\n" + } elseif { [regexp {^[0-9]+:} $line] } { + append function_regexp $line "\n" } else { append function_regexp $config(line_prefix) $line "\n" } diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index dfffe3adfbdd..65d2e67a85b7 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -5800,6 +5800,13 @@ proc add_options_for_aarch64_sve { flags } { return "$flags -march=armv8.2-a+sve" } +proc add_options_for_aarch64_sme { flags } { + if { ![istarget aarch64*-*-*] || [check_effective_target_aarch64_sme] } { + return "$flags" + } + return "$flags -march=armv9-a+sme" +} + # Return 1 if this is an ARM target supporting the FP16 alternative # format. Some multilibs may be incompatible with the options needed. Also # set et_arm_fp16_alternative_flags to the best options to add. @@ -6491,6 +6498,23 @@ proc check_effective_target_aarch64_sve2_hw { } { }] } +# Return true if this is an AArch64 target that can run SVE2.1 code. + +proc check_effective_target_aarch64_sve2p1_hw { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + return [check_runtime aarch64_sve2p1_hw_available { + #pragma GCC target "+sve2p1" + int + main (void) + { + asm volatile ("dupq z0.b, z0.b[0]"); + return 0; + } + }] +} + # Return true if this is an AArch64 target that can run SVE code and # if its SVE vectors have exactly BITS bits. @@ -6522,6 +6546,22 @@ foreach N { 128 256 512 1024 2048 } { }] } +# Return true if this is an AArch64 target that can run SME code. + +proc check_effective_target_aarch64_sme_hw { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + return [check_runtime aarch64_sme_hw_available { + int + main (void) + { + asm volatile ("rdsvl x0, #1"); + return 0; + } + } [add_options_for_aarch64_sme ""]] +} + proc check_effective_target_arm_neonv2_hw { } { return [check_runtime arm_neon_hwv2_available { #include "arm_neon.h" @@ -9944,7 +9984,8 @@ proc check_effective_target_vect_logical_reduc { } { || [istarget amdgcn-*-*] || [check_effective_target_riscv_v] || [check_effective_target_loongarch_sx] - || [check_effective_target_x86]}] + || [check_effective_target_x86] + || [check_effective_target_s390_vx]}] } # Return 1 if the target supports the fold_extract_last optab. @@ -12442,15 +12483,32 @@ proc check_effective_target_aarch64_tiny { } { } } +# Return 1 if Gas supports AEABI build attributes on AArch64 target +proc check_effective_target_aarch64_gas_has_build_attributes { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + + return [check_no_compiler_messages aarch64_gas_has_build_attributes object { + /* Assembly */ + .aeabi_subsection aeabi_feature_and_bits, optional, ULEB128 + .aeabi_attribute Tag_Feature_BTI, 1 + .aeabi_attribute Tag_Feature_PAC, 1 + .aeabi_attribute Tag_Feature_GCS, 1 + }] +} + # Create functions to check that the AArch64 assembler supports the # various architecture extensions via the .arch_extension pseudo-op. -foreach { aarch64_ext } { "fp" "simd" "crypto" "crc" "lse" "dotprod" "sve" - "i8mm" "f32mm" "f64mm" "bf16" "sb" "sve2" "ls64" - "lut" "sme" "sme-i16i64" "sme2" "sve-b16b16" - "sme-b16b16" "sme-f16f16" "sme2p1" "fp8" "fp8fma" - "ssve-fp8fma" "fp8dot2" "ssve-fp8dot2" "fp8dot4" - "ssve-fp8dot4"} { +set exts { + "bf16" "cmpbr" "crc" "crypto" "dotprod" "f32mm" "f64mm" "fp" "fp8" + "fp8dot2" "fp8dot4" "fp8fma" "i8mm" "ls64" "lse" "lut" "sb" "simd" + "sme-b16b16" "sme-f16f16" "sme-i16i64" "sme" "sme2" "sme2p1" "ssve-fp8dot2" + "ssve-fp8dot4" "ssve-fp8fma" "sve-b16b16" "sve" "sve2" +} + +foreach { aarch64_ext } $exts { eval [string map [list FUNC $aarch64_ext] { proc check_effective_target_aarch64_asm_FUNC_ok { } { if { [istarget aarch64*-*-*] } { @@ -14480,3 +14538,65 @@ proc check_effective_target_xtensa_atomic { } { #endif }] } + +# Return 1 if pi-based trigonometry function is foldable +# We should remove this after bumping the minimum mpfr version to 4.2.0. +proc check_effective_target_foldable_pi_based_trigonometry { } { + return [check_runtime foldable_pi_based_trigonometry { + int + main () + { + if (!__builtin_constant_p (__builtin_acospi (0.5))) + __builtin_abort (); + return 0; + } + }] +} +# +# Return 1 if the x86-64 target enables -mfentry by default, 0 +# otherwise. Cache the result. + +proc check_effective_target_fentry { } { + global tool + global GCC_UNDER_TEST + + if { ![check_effective_target_x86] } { + return 0 + } + + # Need auto-host.h to check linker support. + if { ![file exists ../../auto-host.h ] } { + return 0 + } + + return [check_cached_effective_target fentry { + # Set up and compile to see if ENABLE_X86_64_MFENTRY is + # non-zero. Include the current process ID in the file + # names to prevent conflicts with invocations for multiple + # testsuites. + + set src pie[pid].c + set obj pie[pid].o + + set f [open $src "w"] + puts $f "#include \"../../auto-host.h\"" + puts $f "#if ENABLE_X86_64_MFENTRY == 0 || !defined __x86_64__" + puts $f "# error -mfentry is not enabled by default." + puts $f "#endif" + close $f + + verbose "check_effective_target_fentry compiling testfile $src" 2 + set lines [${tool}_target_compile $src $obj object ""] + + file delete $src + file delete $obj + + if [string match "" $lines] then { + verbose "check_effective_target_fentry testfile compilation passed" 2 + return 1 + } else { + verbose "check_effective_target_fentry testfile compilation failed" 2 + return 0 + } + }] +} diff --git a/gcc/testsuite/libgdiagnostics.dg/sarif.py b/gcc/testsuite/libgdiagnostics.dg/sarif.py deleted file mode 100644 index 7daf35b58190..000000000000 --- a/gcc/testsuite/libgdiagnostics.dg/sarif.py +++ /dev/null @@ -1,23 +0,0 @@ -import json -import os - -def sarif_from_env(): - # return parsed JSON content a SARIF_PATH file - json_filename = os.environ['SARIF_PATH'] - json_filename += '.sarif' - print('json_filename: %r' % json_filename) - with open(json_filename) as f: - json_data = f.read() - return json.loads(json_data) - -def get_location_artifact_uri(location): - return location['physicalLocation']['artifactLocation']['uri'] - -def get_location_physical_region(location): - return location['physicalLocation']['region'] - -def get_location_snippet_text(location): - return location['physicalLocation']['contextRegion']['snippet']['text'] - -def get_location_relationships(location): - return location['relationships'] diff --git a/gcc/testsuite/libgdiagnostics.dg/test-message-buffer-c.py b/gcc/testsuite/libgdiagnostics.dg/test-message-buffer-c.py new file mode 100644 index 000000000000..9d14b9a7bda9 --- /dev/null +++ b/gcc/testsuite/libgdiagnostics.dg/test-message-buffer-c.py @@ -0,0 +1,12 @@ +from sarif import * + +import pytest + +@pytest.fixture(scope='function', autouse=True) +def sarif(): + return sarif_from_env() + +def test_message_in_generated_sarif(sarif): + result = get_result_by_index(sarif, 0) + assert result['level'] == 'error' + assert result['message']['text'] == "this is a string; foo; int: 42 str: mostly harmless; [this is a link](https://example.com/) 'this is quoted' highlight A highlight B (1)." diff --git a/gcc/testsuite/libgdiagnostics.dg/test-message-buffer.c b/gcc/testsuite/libgdiagnostics.dg/test-message-buffer.c new file mode 100644 index 000000000000..a958fc577036 --- /dev/null +++ b/gcc/testsuite/libgdiagnostics.dg/test-message-buffer.c @@ -0,0 +1,80 @@ +/* Example of using a message buffer to build the text of a diagnostic + in pieces before emitting it. */ + +#include "libgdiagnostics.h" +#include "test-helpers.h" + +int +main () +{ + begin_test ("test-message-buffer.c.exe", + "test-message-buffer.c.sarif", + __FILE__, "c"); + + diagnostic_event_id event_id = 0; + + /* begin quoted source */ + diagnostic *d = diagnostic_begin (diag_mgr, + DIAGNOSTIC_LEVEL_ERROR); + + diagnostic_message_buffer *msg_buf = diagnostic_message_buffer_new (); + + /* Add a null-terminated string. */ + diagnostic_message_buffer_append_str (msg_buf, "this is a string; "); + + /* Add a length-specified string. */ + diagnostic_message_buffer_append_text (msg_buf, "foobar", 3); + + /* "printf"-formatting. */ + diagnostic_message_buffer_append_printf (msg_buf, + "; int: %i str: %s; ", + 42, "mostly harmless"); + + /* Adding a URL. */ + diagnostic_message_buffer_begin_url (msg_buf, "https://example.com/"); + diagnostic_message_buffer_append_str (msg_buf, "this is a link"); + diagnostic_message_buffer_end_url (msg_buf); + + diagnostic_message_buffer_append_str (msg_buf, " "); + + /* Add quoted text. */ + diagnostic_message_buffer_begin_quote (msg_buf); + diagnostic_message_buffer_append_str (msg_buf, "this is quoted"); + diagnostic_message_buffer_end_quote (msg_buf); + + diagnostic_message_buffer_append_str (msg_buf, " "); + + /* Add colorized text. */ + diagnostic_message_buffer_begin_color (msg_buf, "highlight-a"); + diagnostic_message_buffer_append_str (msg_buf, "highlight A"); + diagnostic_message_buffer_end_color (msg_buf); + + diagnostic_message_buffer_append_str (msg_buf, " "); + + diagnostic_message_buffer_begin_color (msg_buf, "highlight-b"); + diagnostic_message_buffer_append_str (msg_buf, "highlight B"); + diagnostic_message_buffer_end_color (msg_buf); + + diagnostic_message_buffer_append_str (msg_buf, " "); + + /* Add an event ID. This will be printed as "(1)". */ + diagnostic_message_buffer_append_event_id (msg_buf, event_id); + + /* Add an ASCII char. */ + diagnostic_message_buffer_append_byte (msg_buf, '.'); + + diagnostic_finish_via_msg_buf (d, msg_buf); + /* end quoted source */ + + return end_test (); +}; + +/* Verify the output from the text sink. + { dg-regexp "test-message-buffer.c.exe: error: this is a string; foo; int: 42 str: mostly harmless; this is a link 'this is quoted' highlight A highlight B \\(1\\)." } */ + +/* Verify that some JSON was written to a file with the expected name: + { dg-final { verify-sarif-file } } */ + +/* Use a Python script to verify various properties about the generated + .sarif file: + { dg-final { run-sarif-pytest test-message-buffer.c "test-message-buffer-c.py" } } */ diff --git a/gcc/testsuite/libgdiagnostics.dg/test-warning-with-path-c.py b/gcc/testsuite/libgdiagnostics.dg/test-warning-with-path-c.py index af1e7b980fa9..61ccb93336a9 100644 --- a/gcc/testsuite/libgdiagnostics.dg/test-warning-with-path-c.py +++ b/gcc/testsuite/libgdiagnostics.dg/test-warning-with-path-c.py @@ -101,7 +101,7 @@ def test_sarif_output_for_warning_with_path(sarif): == ' PyList_Append(list, item);\n' assert tfl_2_loc['logicalLocations'] == location['logicalLocations'] assert tfl_2_loc['message']['text'] \ - == "when calling 'PyList_Append', passing NULL from (1) as argument 1" + == "when calling 'PyList_Append', passing NULL from [(1)](sarif:/runs/0/results/0/codeFlows/0/threadFlows/0/locations/0) as argument 1" assert tfl_2['nestingLevel'] == 0 assert tfl_2['executionOrder'] == 3 diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-invalid/3.40.2-duplicate-node-id.sarif b/gcc/testsuite/sarif-replay.dg/2.1.0-invalid/3.40.2-duplicate-node-id.sarif new file mode 100644 index 000000000000..a4eb9d4fba68 --- /dev/null +++ b/gcc/testsuite/sarif-replay.dg/2.1.0-invalid/3.40.2-duplicate-node-id.sarif @@ -0,0 +1,23 @@ +{"$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json", + "version": "2.1.0", + "runs": [{"tool": { "driver": { "name": "example" } }, + "results": [], + "graphs": [{"nodes": [{"id": "a", /* { dg-message "'a' already used as node id within graph here" } */ + "children": [{"id": "a"}]}], /* { dg-error "duplicate node id 'a' within graph \\\[SARIF v2.1.0 §3.40.2\\\]" } */ + "edges": []}]}]} + +/* { dg-begin-multiline-output "" } +In JSON property '/runs/0/graphs/0/nodes/0/children/0/id': + { dg-end-multiline-output "" } */ +/* { dg-begin-multiline-output "" } + 6 | "children": [{"id": "a"}]}], + | ^~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } +In JSON property '/runs/0/graphs/0/nodes/0/id': + { dg-end-multiline-output "" } */ +/* { dg-begin-multiline-output "" } + 5 | "graphs": [{"nodes": [{"id": "a", + | ^~~ + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-invalid/3.41.4-unrecognized-node-id.sarif b/gcc/testsuite/sarif-replay.dg/2.1.0-invalid/3.41.4-unrecognized-node-id.sarif new file mode 100644 index 000000000000..b483346d1442 --- /dev/null +++ b/gcc/testsuite/sarif-replay.dg/2.1.0-invalid/3.41.4-unrecognized-node-id.sarif @@ -0,0 +1,16 @@ +{"$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json", + "version": "2.1.0", + "runs": [{"tool": { "driver": { "name": "example" } }, + "results": [], + "graphs": [{"nodes": [], + "edges": [{"id": "edge0", + "sourceNodeId": "this-does-not-exist", /* { dg-error "no node with id 'this-does-not-exist' in graph \\\[SARIF v2.1.0 §3.41.4\\\]" } */ + "targetNodeId": "neither-does-this"}]}]}]} + +/* { dg-begin-multiline-output "" } +In JSON property '/runs/0/graphs/0/edges/0/sourceNodeId': + { dg-end-multiline-output "" } */ +/* { dg-begin-multiline-output "" } + 7 | "sourceNodeId": "this-does-not-exist", + | ^~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/3.11.6-embedded-links.sarif b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/3.11.6-embedded-links.sarif index bc64521716c6..cd7b8228742f 100644 --- a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/3.11.6-embedded-links.sarif +++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/3.11.6-embedded-links.sarif @@ -1,3 +1,6 @@ +/* { dg-additional-options "-fdiagnostics-add-output=experimental-html:file=3.11.6-embedded-links.sarif.html,javascript=no" } */ +/* { dg-additional-options "-fdiagnostics-add-output=sarif:file=3.11.6-embedded-links.sarif.roundtrip.sarif" } */ + {"$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json", "version": "2.1.0", "runs": [{"tool": {"driver": {"name": "hand-written"}}, @@ -16,10 +19,24 @@ hand-written: warning: 002: Prohibited term used in [para\[0\]\\spans\[2\](1). /* With the fix from https://github.com/oasis-tcs/sarif-spec/issues/656 */ {"message": {"text": "003: Prohibited term used in [para\\[0\\]\\\\spans\\[2\\]](1)."}, - "locations": []} + "locations": []}, /* { dg-begin-multiline-output "" } hand-written: warning: 003: Prohibited term used in para[0]\spans[2]. + { dg-end-multiline-output "" } */ + + {"message": {"text": "004: This is a [link](http://www.example.com)."}, + "locations": []} +/* { dg-begin-multiline-output "" } +hand-written: warning: 004: This is a link. { dg-end-multiline-output "" } */ ]}]} +/* Use a Python script to verify various properties about the generated + .html file: + { dg-final { run-html-pytest 3.11.6-embedded-links.sarif "2.1.0-valid/embedded-links-check-html.py" } } */ + +/* Use a Python script to verify various properties about the *generated* + .sarif file: + { dg-final { run-sarif-pytest 3.11.6-embedded-links.sarif.roundtrip "2.1.0-valid/embedded-links-check-sarif-roundtrip.py" } } */ + diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/embedded-links-check-html.py b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/embedded-links-check-html.py new file mode 100644 index 000000000000..ff1c2f261853 --- /dev/null +++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/embedded-links-check-html.py @@ -0,0 +1,28 @@ +from htmltest import * + +import pytest + +@pytest.fixture(scope='function', autouse=True) +def html_tree(): + return html_tree_from_env() + +def test_generated_html(html_tree): + root = html_tree.getroot () + assert root.tag == make_tag('html') + + head = root.find('xhtml:head', ns) + assert head is not None + + # Get "warning: 004: This is a link." + diag = get_diag_by_index(html_tree, 3) + + msg = get_message_within_diag(diag) + assert msg is not None + + assert_tag(msg[0], 'strong') + assert msg[0].text == 'warning: ' + assert msg[0].tail == ' 004: This is a ' + assert_tag(msg[1], 'a') + assert msg[1].text == 'link' + assert msg[1].get('href') == 'http://www.example.com' + assert msg[1].tail == '. ' diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/embedded-links-check-sarif-roundtrip.py b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/embedded-links-check-sarif-roundtrip.py new file mode 100644 index 000000000000..171339e37571 --- /dev/null +++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/embedded-links-check-sarif-roundtrip.py @@ -0,0 +1,13 @@ +from sarif import * + +import pytest + +@pytest.fixture(scope='function', autouse=True) +def sarif(): + return sarif_from_env() + +def test_roundtrip_of_url_in_generated_sarif(sarif): + # Get "warning: 004: This is a link." + result = get_result_by_index(sarif, 3) + assert result['level'] == 'warning' + assert result['message']['text'] == "004: This is a [link](http://www.example.com)." diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/graphs-check-html.py b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/graphs-check-html.py new file mode 100644 index 000000000000..63b80c98738f --- /dev/null +++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/graphs-check-html.py @@ -0,0 +1,46 @@ +from htmltest import * + +import pytest + +@pytest.fixture(scope='function', autouse=True) +def html_tree(): + return html_tree_from_env() + +def test_result_graph(html_tree): + root = html_tree.getroot () + assert root.tag == make_tag('html') + + body = root.find('xhtml:body', ns) + assert body is not None + + diag_list = body.find('xhtml:div', ns) + assert diag_list is not None + assert diag_list.attrib['class'] == 'gcc-diagnostic-list' + + diag = diag_list.find('xhtml:div', ns) + assert diag is not None + + message = diag.find("./xhtml:div[@class='gcc-message']", ns) + assert message.attrib['id'] == 'gcc-diag-0-message' + + assert message[0].tag == make_tag('strong') + assert message[0].tail == ' this is a placeholder error, with graphs ' + + graph = diag.find("./xhtml:div[@class='gcc-directed-graph']", ns) + assert graph is not None + + header = graph.find("./xhtml:h2", ns) + assert header.text == 'foo' + +def test_run_graph(html_tree): + root = html_tree.getroot () + assert root.tag == make_tag('html') + + body = root.find('xhtml:body', ns) + assert body is not None + + graph = body.find("./xhtml:div[@class='gcc-directed-graph']", ns) + assert graph is not None + + header = graph.find("./xhtml:h2", ns) + assert header.text == 'Optimization Passes' diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/graphs-check-sarif-roundtrip.py b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/graphs-check-sarif-roundtrip.py new file mode 100644 index 000000000000..4bb7535cc64a --- /dev/null +++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/graphs-check-sarif-roundtrip.py @@ -0,0 +1,55 @@ +from sarif import * + +import pytest + +@pytest.fixture(scope='function', autouse=True) +def sarif(): + return sarif_from_env() + +def test_basics(sarif): + schema = sarif['$schema'] + assert schema == "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json" + + version = sarif['version'] + assert version == "2.1.0" + +def test_result_graph(sarif): + runs = sarif['runs'] + run = runs[0] + results = run['results'] + + assert len(results) == 1 + + result = results[0] + assert result['level'] == 'error' + assert result['message']['text'] == "this is a placeholder error, with graphs" + + assert len(result['graphs']) == 2 + + assert result['graphs'][0]['description']['text'] == 'foo' + + assert len(result['graphs'][0]['nodes']) == 2 + assert result['graphs'][0]['nodes'][0]['id'] == 'a' + assert result['graphs'][0]['nodes'][1]['id'] == 'b' + assert result['graphs'][0]['nodes'][1]['properties']['/placeholder-prefix/color'] == 'red' + assert len(result['graphs'][0]['nodes'][1]['children']) == 1 + assert result['graphs'][0]['nodes'][1]['children'][0]['id'] == 'c' + assert result['graphs'][0]['nodes'][1]['children'][0]['label']['text'] == 'I am a node label' + + assert len(result['graphs'][0]['edges']) == 1 + result['graphs'][0]['edges'][0]['id'] == 'my-edge' + assert result['graphs'][0]['edges'][0]['label']['text'] == 'I am an edge label' + assert result['graphs'][0]['edges'][0]['sourceNodeId'] == 'a' + assert result['graphs'][0]['edges'][0]['targetNodeId'] == 'c' + + assert result['graphs'][1]['description']['text'] == 'bar' + +def test_run_graph(sarif): + runs = sarif['runs'] + run = runs[0] + + assert len(run['graphs']) == 1 + + assert run['graphs'][0]['description']['text'] == 'Optimization Passes' + assert run['graphs'][0]['nodes'][0]['id'] == 'all_lowering_passes' + assert run['graphs'][0]['edges'][0]['id'] == 'edge0' diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/graphs.sarif b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/graphs.sarif new file mode 100644 index 000000000000..da236ba02dd0 --- /dev/null +++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/graphs.sarif @@ -0,0 +1,2445 @@ +/* Test a replay of a .sarif file generated from GCC testsuite. + + The dg directives were stripped out from the generated .sarif + to avoid confusing DejaGnu for this test. */ +/* { dg-additional-options "-fdiagnostics-add-output=experimental-html:file=graphs.sarif.html,javascript=no" } */ +/* { dg-additional-options "-fdiagnostics-add-output=sarif:file=graphs.roundtrip.sarif" } */ + +{"$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json", + "version": "2.1.0", + "runs": [{"tool": {"driver": {"name": "GNU C23", + "fullName": "GNU C23 (GCC) version 16.0.0 20250702 (experimental) (x86_64-pc-linux-gnu)", + "version": "16.0.0 20250702 (experimental)", + "informationUri": "https://gcc.gnu.org/gcc-16/", + "rules": []}, + "extensions": [{"name": "diagnostic_plugin_test_graphs", + "fullName": "./diagnostic_plugin_test_graphs.so"}]}, + "invocations": [{"arguments": ["/home/david/gcc-newgit-gcc16/build/gcc/cc1", + "-quiet", + "-iprefix", + "/usr/local/lib/gcc/x86_64-pc-linux-gnu/16.0.0/", + "-isystem", + "/home/david/gcc-newgit-gcc16/build/gcc/include", + "-isystem", + "/home/david/gcc-newgit-gcc16/build/gcc/include-fixed", + "-iplugindir=/home/david/gcc-newgit-gcc16/build/gcc/plugin", + "/home/david/gcc-newgit-gcc16/src/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-sarif.c", + "-iplugindir=/home/david/gcc-newgit-gcc16/build/gcc/plugin", + "-quiet", + "-dumpbase", + "diagnostic-test-graphs-sarif.c", + "-dumpbase-ext", + ".c", + "-mtune=generic", + "-march=x86-64", + "-fdiagnostics-color=never", + "-fdiagnostics-urls=never", + "-fno-diagnostics-show-caret", + "-fno-diagnostics-show-line-numbers", + "-fdiagnostics-path-format=separate-events", + "-fdiagnostics-text-art-charset=none", + "-fno-diagnostics-show-event-links", + "-fplugin=./diagnostic_plugin_test_graphs.so", + "-fdiagnostics-add-output=sarif", + "-o", + "diagnostic-test-graphs-sarif.s"], + "workingDirectory": {"uri": "/home/david/gcc-newgit-gcc16/build/gcc/testsuite/gcc"}, + "startTimeUtc": "2025-07-09T22:43:31Z", + "executionSuccessful": false, + "toolExecutionNotifications": [], + "endTimeUtc": "2025-07-09T22:43:31Z"}], + "artifacts": [{"location": {"uri": "/home/david/gcc-newgit-gcc16/src/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-sarif.c"}, + "sourceLanguage": "c", + "roles": ["analysisTarget"]}], + "results": [{"ruleId": "error", + "level": "error", + "message": {"text": "this is a placeholder error, with graphs"}, + "locations": [{"physicalLocation": {"artifactLocation": {"uri": "/home/david/gcc-newgit-gcc16/src/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-sarif.c"}, + "region": {"startLine": 8, + "startColumn": 3, + "endColumn": 10}, + "contextRegion": {"startLine": 8, + "snippet": {"text": " here ();"}}}, + "logicalLocations": [{"index": 0, + "fullyQualifiedName": "test_graphs"}]}], + "graphs": [{"description": {"text": "foo"}, + "nodes": [{"id": "a"}, + {"id": "b", + "properties": {"/placeholder-prefix/color": "red"}, + "children": [{"id": "c", + "label": {"text": "I am a node label"}}]}], + "edges": [{"id": "my-edge", + "label": {"text": "I am an edge label"}, + "sourceNodeId": "a", + "targetNodeId": "c"}]}, + {"description": {"text": "bar"}, + "nodes": [{"id": "a"}, + {"id": "b", + "properties": {"/placeholder-prefix/color": "red"}, + "children": [{"id": "c", + "label": {"text": "I am a node label"}}]}], + "edges": [{"id": "my-edge", + "label": {"text": "I am an edge label"}, + "sourceNodeId": "a", + "targetNodeId": "c"}]}]}], + "logicalLocations": [{"name": "test_graphs", + "fullyQualifiedName": "test_graphs", + "decoratedName": "test_graphs", + "kind": "function", + "index": 0}], + "graphs": [{"description": {"text": "Optimization Passes"}, + "nodes": [{"id": "all_lowering_passes", + "label": {"text": "all_lowering_passes"}, + "children": [{"id": "*warn_unused_result_0x101ef3d0", + "label": {"text": "*warn_unused_result"}}, + {"id": "*diagnose_omp_blocks_0x101ef430", + "label": {"text": "*diagnose_omp_blocks"}}, + {"id": "*diagnose_tm_blocks_0x101ef490", + "label": {"text": "*diagnose_tm_blocks"}}, + {"id": "13_omp_oacc_kernels_decompose", + "label": {"text": "13_omp_oacc_kernels_decompose"}}, + {"id": "14_omplower", + "label": {"text": "14_omplower"}}, + {"id": "15_lower", + "label": {"text": "15_lower"}}, + {"id": "16_tmlower", + "label": {"text": "16_tmlower"}}, + {"id": "17_ehopt", + "label": {"text": "17_ehopt"}}, + {"id": "18_eh", + "label": {"text": "18_eh"}}, + {"id": "19_coro-lower-builtins", + "label": {"text": "19_coro-lower-builtins"}}, + {"id": "20_cfg", + "label": {"text": "20_cfg"}}, + {"id": "*warn_function_return_0x101ef7f0", + "label": {"text": "*warn_function_return"}}, + {"id": "21_coro-early-expand-ifns", + "label": {"text": "21_coro-early-expand-ifns"}}, + {"id": "22_ompexp", + "label": {"text": "22_ompexp"}}, + {"id": "*build_cgraph_edges_0x101ef910", + "label": {"text": "*build_cgraph_edges"}}]}, + {"id": "all_small_ipa_passes", + "label": {"text": "all_small_ipa_passes"}, + "children": [{"id": "23_afdo_offline", + "label": {"text": "23_afdo_offline"}}, + {"id": "*free_lang_data_0x101ef9d0", + "label": {"text": "*free_lang_data"}}, + {"id": "24_visibility", + "label": {"text": "24_visibility"}}, + {"id": "25_strubm", + "label": {"text": "25_strubm"}}, + {"id": "26_build_ssa_passes", + "label": {"text": "26_build_ssa_passes"}}, + {"id": "27_fixup_cfg", + "label": {"text": "27_fixup_cfg"}}, + {"id": "28_ssa", + "label": {"text": "28_ssa"}}, + {"id": "376_test_graph_emission", + "label": {"text": "376_test_graph_emission"}}, + {"id": "29_walloca", + "label": {"text": "29_walloca"}}, + {"id": "30_warn-printf", + "label": {"text": "30_warn-printf"}}, + {"id": "*nonnullcmp_0x101efce0", + "label": {"text": "*nonnullcmp"}}, + {"id": "31_early_uninit", + "label": {"text": "31_early_uninit"}}, + {"id": "32_waccess", + "label": {"text": "32_waccess"}}, + {"id": "33_ubsan", + "label": {"text": "33_ubsan"}}, + {"id": "34_nothrow", + "label": {"text": "34_nothrow"}}, + {"id": "*rebuild_cgraph_edges_0x101f0020", + "label": {"text": "*rebuild_cgraph_edges"}}, + {"id": "35_opt_local_passes", + "label": {"text": "35_opt_local_passes"}}, + {"id": "36_fixup_cfg", + "label": {"text": "36_fixup_cfg"}}, + {"id": "*rebuild_cgraph_edges_0x101f0140", + "label": {"text": "*rebuild_cgraph_edges"}}, + {"id": "37_local-fnsummary", + "label": {"text": "37_local-fnsummary"}}, + {"id": "38_einline", + "label": {"text": "38_einline"}}, + {"id": "*infinite-recursion_0x101f0260", + "label": {"text": "*infinite-recursion"}}, + {"id": "39_early_optimizations", + "label": {"text": "39_early_optimizations"}}, + {"id": "*remove_cgraph_callee_edges_0x101f0340", + "label": {"text": "*remove_cgraph_callee_edges"}}, + {"id": "40_early_objsz", + "label": {"text": "40_early_objsz"}}, + {"id": "41_ccp", + "label": {"text": "41_ccp"}}, + {"id": "42_forwprop", + "label": {"text": "42_forwprop"}}, + {"id": "43_ethread", + "label": {"text": "43_ethread"}}, + {"id": "44_esra", + "label": {"text": "44_esra"}}, + {"id": "45_ealias", + "label": {"text": "45_ealias"}}, + {"id": "46_phiprop", + "label": {"text": "46_phiprop"}}, + {"id": "47_fre", + "label": {"text": "47_fre"}}, + {"id": "48_evrp", + "label": {"text": "48_evrp"}}, + {"id": "49_mergephi", + "label": {"text": "49_mergephi"}}, + {"id": "50_dse", + "label": {"text": "50_dse"}}, + {"id": "51_cddce", + "label": {"text": "51_cddce"}}, + {"id": "52_phiopt", + "label": {"text": "52_phiopt"}}, + {"id": "53_tailr", + "label": {"text": "53_tailr"}}, + {"id": "54_iftoswitch", + "label": {"text": "54_iftoswitch"}}, + {"id": "55_switchconv", + "label": {"text": "55_switchconv"}}, + {"id": "56_ehcleanup", + "label": {"text": "56_ehcleanup"}}, + {"id": "57_sccopy", + "label": {"text": "57_sccopy"}}, + {"id": "58_profile_estimate", + "label": {"text": "58_profile_estimate"}}, + {"id": "59_local-pure-const", + "label": {"text": "59_local-pure-const"}}, + {"id": "60_modref", + "label": {"text": "60_modref"}}, + {"id": "61_fnsplit", + "label": {"text": "61_fnsplit"}}, + {"id": "*strip_predict_hints_0x101f0c60", + "label": {"text": "*strip_predict_hints"}}, + {"id": "62_release_ssa", + "label": {"text": "62_release_ssa"}}, + {"id": "*rebuild_cgraph_edges_0x101f0d30", + "label": {"text": "*rebuild_cgraph_edges"}}, + {"id": "63_local-fnsummary", + "label": {"text": "63_local-fnsummary"}}, + {"id": "64_remove_symbols", + "label": {"text": "64_remove_symbols"}}, + {"id": "65_strub", + "label": {"text": "65_strub"}}, + {"id": "66_ipa_oacc", + "label": {"text": "66_ipa_oacc"}}, + {"id": "67_pta", + "label": {"text": "67_pta"}}, + {"id": "68_ipa_oacc_kernels", + "label": {"text": "68_ipa_oacc_kernels"}}, + {"id": "69_oacc_kernels", + "label": {"text": "69_oacc_kernels"}}, + {"id": "70_ch", + "label": {"text": "70_ch"}}, + {"id": "71_fre", + "label": {"text": "71_fre"}}, + {"id": "72_lim", + "label": {"text": "72_lim"}}, + {"id": "73_dom", + "label": {"text": "73_dom"}}, + {"id": "74_dce", + "label": {"text": "74_dce"}}, + {"id": "75_parloops", + "label": {"text": "75_parloops"}}, + {"id": "76_ompexpssa", + "label": {"text": "76_ompexpssa"}}, + {"id": "*rebuild_cgraph_edges_0x101f1310", + "label": {"text": "*rebuild_cgraph_edges"}}, + {"id": "77_targetclone", + "label": {"text": "77_targetclone"}}, + {"id": "78_afdo", + "label": {"text": "78_afdo"}}, + {"id": "79_feedback_fnsplit", + "label": {"text": "79_feedback_fnsplit"}}, + {"id": "80_profile", + "label": {"text": "80_profile"}}, + {"id": "81_feedback_fnsplit", + "label": {"text": "81_feedback_fnsplit"}}, + {"id": "82_free-fnsummary", + "label": {"text": "82_free-fnsummary"}}, + {"id": "83_increase_alignment", + "label": {"text": "83_increase_alignment"}}, + {"id": "84_tmipa", + "label": {"text": "84_tmipa"}}, + {"id": "85_emutls", + "label": {"text": "85_emutls"}}]}, + {"id": "all_regular_ipa_passes", + "label": {"text": "all_regular_ipa_passes"}, + "children": [{"id": "86_analyzer", + "label": {"text": "86_analyzer"}}, + {"id": "87_odr", + "label": {"text": "87_odr"}}, + {"id": "88_whole-program", + "label": {"text": "88_whole-program"}}, + {"id": "89_profile_estimate", + "label": {"text": "89_profile_estimate"}}, + {"id": "90_icf", + "label": {"text": "90_icf"}}, + {"id": "91_devirt", + "label": {"text": "91_devirt"}}, + {"id": "92_cdtor", + "label": {"text": "92_cdtor"}}, + {"id": "93_cp", + "label": {"text": "93_cp"}}, + {"id": "94_sra", + "label": {"text": "94_sra"}}, + {"id": "95_fnsummary", + "label": {"text": "95_fnsummary"}}, + {"id": "96_inline", + "label": {"text": "96_inline"}}, + {"id": "97_locality-clone", + "label": {"text": "97_locality-clone"}}, + {"id": "98_pure-const", + "label": {"text": "98_pure-const"}}, + {"id": "99_modref", + "label": {"text": "99_modref"}}, + {"id": "100_free-fnsummary", + "label": {"text": "100_free-fnsummary"}}, + {"id": "101_static-var", + "label": {"text": "101_static-var"}}, + {"id": "102_single-use", + "label": {"text": "102_single-use"}}, + {"id": "103_comdats", + "label": {"text": "103_comdats"}}]}, + {"id": "all_late_ipa_passes", + "label": {"text": "all_late_ipa_passes"}, + "children": [{"id": "104_pta", + "label": {"text": "104_pta"}}, + {"id": "105_simdclone", + "label": {"text": "105_simdclone"}}]}, + {"id": "all_passes", + "label": {"text": "all_passes"}, + "children": [{"id": "106_fixup_cfg", + "label": {"text": "106_fixup_cfg"}}, + {"id": "107_ehdisp", + "label": {"text": "107_ehdisp"}}, + {"id": "108_oaccloops", + "label": {"text": "108_oaccloops"}}, + {"id": "109_omp_oacc_neuter_broadcast", + "label": {"text": "109_omp_oacc_neuter_broadcast"}}, + {"id": "110_oaccdevlow", + "label": {"text": "110_oaccdevlow"}}, + {"id": "111_ompdevlow", + "label": {"text": "111_ompdevlow"}}, + {"id": "112_omptargetlink", + "label": {"text": "112_omptargetlink"}}, + {"id": "113_adjust_alignment", + "label": {"text": "113_adjust_alignment"}}, + {"id": "114_hardcfr", + "label": {"text": "114_hardcfr"}}, + {"id": "*all_optimizations_0x101f2720", + "label": {"text": "*all_optimizations"}}, + {"id": "*remove_cgraph_callee_edges_0x101f2780", + "label": {"text": "*remove_cgraph_callee_edges"}}, + {"id": "*strip_predict_hints_0x101f27e0", + "label": {"text": "*strip_predict_hints"}}, + {"id": "115_ccp", + "label": {"text": "115_ccp"}}, + {"id": "116_objsz", + "label": {"text": "116_objsz"}}, + {"id": "117_post_ipa_warn", + "label": {"text": "117_post_ipa_warn"}}, + {"id": "118_waccess", + "label": {"text": "118_waccess"}}, + {"id": "119_rebuild_frequencies", + "label": {"text": "119_rebuild_frequencies"}}, + {"id": "120_cunrolli", + "label": {"text": "120_cunrolli"}}, + {"id": "121_backprop", + "label": {"text": "121_backprop"}}, + {"id": "122_phiprop", + "label": {"text": "122_phiprop"}}, + {"id": "123_forwprop", + "label": {"text": "123_forwprop"}}, + {"id": "124_alias", + "label": {"text": "124_alias"}}, + {"id": "125_retslot", + "label": {"text": "125_retslot"}}, + {"id": "126_fre", + "label": {"text": "126_fre"}}, + {"id": "127_mergephi", + "label": {"text": "127_mergephi"}}, + {"id": "128_threadfull", + "label": {"text": "128_threadfull"}}, + {"id": "129_vrp", + "label": {"text": "129_vrp"}}, + {"id": "130_bounds", + "label": {"text": "130_bounds"}}, + {"id": "131_dse", + "label": {"text": "131_dse"}}, + {"id": "132_dce", + "label": {"text": "132_dce"}}, + {"id": "133_stdarg", + "label": {"text": "133_stdarg"}}, + {"id": "134_cdce", + "label": {"text": "134_cdce"}}, + {"id": "135_cselim", + "label": {"text": "135_cselim"}}, + {"id": "136_copyprop", + "label": {"text": "136_copyprop"}}, + {"id": "137_ifcombine", + "label": {"text": "137_ifcombine"}}, + {"id": "138_mergephi", + "label": {"text": "138_mergephi"}}, + {"id": "139_phiopt", + "label": {"text": "139_phiopt"}}, + {"id": "140_tailr", + "label": {"text": "140_tailr"}}, + {"id": "141_ch", + "label": {"text": "141_ch"}}, + {"id": "142_cplxlower", + "label": {"text": "142_cplxlower"}}, + {"id": "143_bitintlower", + "label": {"text": "143_bitintlower"}}, + {"id": "144_sra", + "label": {"text": "144_sra"}}, + {"id": "145_thread", + "label": {"text": "145_thread"}}, + {"id": "146_dom", + "label": {"text": "146_dom"}}, + {"id": "147_copyprop", + "label": {"text": "147_copyprop"}}, + {"id": "148_isolate-paths", + "label": {"text": "148_isolate-paths"}}, + {"id": "149_reassoc", + "label": {"text": "149_reassoc"}}, + {"id": "150_dce", + "label": {"text": "150_dce"}}, + {"id": "151_forwprop", + "label": {"text": "151_forwprop"}}, + {"id": "152_phiopt", + "label": {"text": "152_phiopt"}}, + {"id": "153_ccp", + "label": {"text": "153_ccp"}}, + {"id": "154_pow", + "label": {"text": "154_pow"}}, + {"id": "155_bswap", + "label": {"text": "155_bswap"}}, + {"id": "156_laddress", + "label": {"text": "156_laddress"}}, + {"id": "157_lim", + "label": {"text": "157_lim"}}, + {"id": "158_walloca", + "label": {"text": "158_walloca"}}, + {"id": "159_pre", + "label": {"text": "159_pre"}}, + {"id": "160_sink", + "label": {"text": "160_sink"}}, + {"id": "161_sancov", + "label": {"text": "161_sancov"}}, + {"id": "162_asan", + "label": {"text": "162_asan"}}, + {"id": "163_tsan", + "label": {"text": "163_tsan"}}, + {"id": "164_dse", + "label": {"text": "164_dse"}}, + {"id": "165_dce", + "label": {"text": "165_dce"}}, + {"id": "166_fix_loops", + "label": {"text": "166_fix_loops"}}, + {"id": "167_loop", + "label": {"text": "167_loop"}}, + {"id": "168_loopinit", + "label": {"text": "168_loopinit"}}, + {"id": "169_unswitch", + "label": {"text": "169_unswitch"}}, + {"id": "170_lsplit", + "label": {"text": "170_lsplit"}}, + {"id": "171_sccp", + "label": {"text": "171_sccp"}}, + {"id": "172_lversion", + "label": {"text": "172_lversion"}}, + {"id": "173_unrolljam", + "label": {"text": "173_unrolljam"}}, + {"id": "174_cddce", + "label": {"text": "174_cddce"}}, + {"id": "175_ivcanon", + "label": {"text": "175_ivcanon"}}, + {"id": "176_ldist", + "label": {"text": "176_ldist"}}, + {"id": "177_crc", + "label": {"text": "177_crc"}}, + {"id": "178_linterchange", + "label": {"text": "178_linterchange"}}, + {"id": "179_copyprop", + "label": {"text": "179_copyprop"}}, + {"id": "180_graphite0", + "label": {"text": "180_graphite0"}}, + {"id": "181_graphite", + "label": {"text": "181_graphite"}}, + {"id": "182_lim", + "label": {"text": "182_lim"}}, + {"id": "183_copyprop", + "label": {"text": "183_copyprop"}}, + {"id": "184_dce", + "label": {"text": "184_dce"}}, + {"id": "185_parloops", + "label": {"text": "185_parloops"}}, + {"id": "186_ompexpssa", + "label": {"text": "186_ompexpssa"}}, + {"id": "187_ch_vect", + "label": {"text": "187_ch_vect"}}, + {"id": "188_ifcvt", + "label": {"text": "188_ifcvt"}}, + {"id": "189_vect", + "label": {"text": "189_vect"}}, + {"id": "190_dce", + "label": {"text": "190_dce"}}, + {"id": "191_pcom", + "label": {"text": "191_pcom"}}, + {"id": "192_cunroll", + "label": {"text": "192_cunroll"}}, + {"id": "*pre_slp_scalar_cleanup_0x101f4880", + "label": {"text": "*pre_slp_scalar_cleanup"}}, + {"id": "193_fre", + "label": {"text": "193_fre"}}, + {"id": "194_dse", + "label": {"text": "194_dse"}}, + {"id": "195_slp", + "label": {"text": "195_slp"}}, + {"id": "196_aprefetch", + "label": {"text": "196_aprefetch"}}, + {"id": "197_ivopts", + "label": {"text": "197_ivopts"}}, + {"id": "198_lim", + "label": {"text": "198_lim"}}, + {"id": "199_loopdone", + "label": {"text": "199_loopdone"}}, + {"id": "200_no_loop", + "label": {"text": "200_no_loop"}}, + {"id": "201_slp", + "label": {"text": "201_slp"}}, + {"id": "202_simduid", + "label": {"text": "202_simduid"}}, + {"id": "203_veclower2", + "label": {"text": "203_veclower2"}}, + {"id": "204_switchlower", + "label": {"text": "204_switchlower"}}, + {"id": "205_sincos", + "label": {"text": "205_sincos"}}, + {"id": "206_recip", + "label": {"text": "206_recip"}}, + {"id": "207_reassoc", + "label": {"text": "207_reassoc"}}, + {"id": "208_slsr", + "label": {"text": "208_slsr"}}, + {"id": "209_split-paths", + "label": {"text": "209_split-paths"}}, + {"id": "210_tracer", + "label": {"text": "210_tracer"}}, + {"id": "211_fre", + "label": {"text": "211_fre"}}, + {"id": "212_thread", + "label": {"text": "212_thread"}}, + {"id": "213_dom", + "label": {"text": "213_dom"}}, + {"id": "214_strlen", + "label": {"text": "214_strlen"}}, + {"id": "215_threadfull", + "label": {"text": "215_threadfull"}}, + {"id": "216_vrp", + "label": {"text": "216_vrp"}}, + {"id": "217_ccp", + "label": {"text": "217_ccp"}}, + {"id": "218_wrestrict", + "label": {"text": "218_wrestrict"}}, + {"id": "219_dse", + "label": {"text": "219_dse"}}, + {"id": "220_dce", + "label": {"text": "220_dce"}}, + {"id": "221_forwprop", + "label": {"text": "221_forwprop"}}, + {"id": "222_sink", + "label": {"text": "222_sink"}}, + {"id": "223_phiopt", + "label": {"text": "223_phiopt"}}, + {"id": "224_fab", + "label": {"text": "224_fab"}}, + {"id": "225_widening_mul", + "label": {"text": "225_widening_mul"}}, + {"id": "226_store-merging", + "label": {"text": "226_store-merging"}}, + {"id": "227_cddce", + "label": {"text": "227_cddce"}}, + {"id": "228_sccopy", + "label": {"text": "228_sccopy"}}, + {"id": "229_tailc", + "label": {"text": "229_tailc"}}, + {"id": "230_crited", + "label": {"text": "230_crited"}}, + {"id": "231_uninit", + "label": {"text": "231_uninit"}}, + {"id": "232_local-pure-const", + "label": {"text": "232_local-pure-const"}}, + {"id": "233_modref", + "label": {"text": "233_modref"}}, + {"id": "234_uncprop", + "label": {"text": "234_uncprop"}}, + {"id": "*all_optimizations_g_0x101f5af0", + "label": {"text": "*all_optimizations_g"}}, + {"id": "*remove_cgraph_callee_edges_0x101f5b50", + "label": {"text": "*remove_cgraph_callee_edges"}}, + {"id": "*strip_predict_hints_0x101f5bb0", + "label": {"text": "*strip_predict_hints"}}, + {"id": "235_cplxlower", + "label": {"text": "235_cplxlower"}}, + {"id": "236_bitintlower", + "label": {"text": "236_bitintlower"}}, + {"id": "237_veclower2", + "label": {"text": "237_veclower2"}}, + {"id": "238_switchlower", + "label": {"text": "238_switchlower"}}, + {"id": "239_ccp", + "label": {"text": "239_ccp"}}, + {"id": "240_post_ipa_warn", + "label": {"text": "240_post_ipa_warn"}}, + {"id": "241_objsz", + "label": {"text": "241_objsz"}}, + {"id": "242_fab", + "label": {"text": "242_fab"}}, + {"id": "243_strlen", + "label": {"text": "243_strlen"}}, + {"id": "244_copyprop", + "label": {"text": "244_copyprop"}}, + {"id": "245_dce", + "label": {"text": "245_dce"}}, + {"id": "246_rebuild_frequencies", + "label": {"text": "246_rebuild_frequencies"}}, + {"id": "247_sancov", + "label": {"text": "247_sancov"}}, + {"id": "248_asan", + "label": {"text": "248_asan"}}, + {"id": "249_tsan", + "label": {"text": "249_tsan"}}, + {"id": "250_crited", + "label": {"text": "250_crited"}}, + {"id": "251_uninit", + "label": {"text": "251_uninit"}}, + {"id": "252_uncprop", + "label": {"text": "252_uncprop"}}, + {"id": "253_assumptions", + "label": {"text": "253_assumptions"}}, + {"id": "*tminit_0x101f6370", + "label": {"text": "*tminit"}}, + {"id": "254_tmmark", + "label": {"text": "254_tmmark"}}, + {"id": "255_tmmemopt", + "label": {"text": "255_tmmemopt"}}, + {"id": "256_tmedge", + "label": {"text": "256_tmedge"}}, + {"id": "257_simduid", + "label": {"text": "257_simduid"}}, + {"id": "258_vtable-verify", + "label": {"text": "258_vtable-verify"}}, + {"id": "259_lower_vaarg", + "label": {"text": "259_lower_vaarg"}}, + {"id": "260_veclower", + "label": {"text": "260_veclower"}}, + {"id": "261_cplxlower0", + "label": {"text": "261_cplxlower0"}}, + {"id": "262_bitintlower0", + "label": {"text": "262_bitintlower0"}}, + {"id": "263_sancov_O0", + "label": {"text": "263_sancov_O0"}}, + {"id": "264_switchlower_O0", + "label": {"text": "264_switchlower_O0"}}, + {"id": "265_asan0", + "label": {"text": "265_asan0"}}, + {"id": "266_tsan0", + "label": {"text": "266_tsan0"}}, + {"id": "267_musttail", + "label": {"text": "267_musttail"}}, + {"id": "268_sanopt", + "label": {"text": "268_sanopt"}}, + {"id": "269_ehcleanup", + "label": {"text": "269_ehcleanup"}}, + {"id": "270_resx", + "label": {"text": "270_resx"}}, + {"id": "271_nrv", + "label": {"text": "271_nrv"}}, + {"id": "272_isel", + "label": {"text": "272_isel"}}, + {"id": "273_hardcbr", + "label": {"text": "273_hardcbr"}}, + {"id": "274_hardcmp", + "label": {"text": "274_hardcmp"}}, + {"id": "275_waccess", + "label": {"text": "275_waccess"}}, + {"id": "276_optimized", + "label": {"text": "276_optimized"}}, + {"id": "*warn_function_noreturn_0x101f6dd0", + "label": {"text": "*warn_function_noreturn"}}, + {"id": "277_expand", + "label": {"text": "277_expand"}}, + {"id": "*rest_of_compilation_0x101f6e90", + "label": {"text": "*rest_of_compilation"}}, + {"id": "278_vregs", + "label": {"text": "278_vregs"}}, + {"id": "279_into_cfglayout", + "label": {"text": "279_into_cfglayout"}}, + {"id": "280_jump", + "label": {"text": "280_jump"}}, + {"id": "281_subreg1", + "label": {"text": "281_subreg1"}}, + {"id": "282_dfinit", + "label": {"text": "282_dfinit"}}, + {"id": "283_cse1", + "label": {"text": "283_cse1"}}, + {"id": "284_fwprop1", + "label": {"text": "284_fwprop1"}}, + {"id": "285_cprop", + "label": {"text": "285_cprop"}}, + {"id": "286_rtl pre", + "label": {"text": "286_rtl pre"}}, + {"id": "287_hoist", + "label": {"text": "287_hoist"}}, + {"id": "288_hardreg_pre", + "label": {"text": "288_hardreg_pre"}}, + {"id": "289_cprop", + "label": {"text": "289_cprop"}}, + {"id": "290_store_motion", + "label": {"text": "290_store_motion"}}, + {"id": "291_cse_local", + "label": {"text": "291_cse_local"}}, + {"id": "292_ce1", + "label": {"text": "292_ce1"}}, + {"id": "293_apx_nfcvt", + "label": {"text": "293_apx_nfcvt"}}, + {"id": "294_reginfo", + "label": {"text": "294_reginfo"}}, + {"id": "295_loop2", + "label": {"text": "295_loop2"}}, + {"id": "296_loop2_init", + "label": {"text": "296_loop2_init"}}, + {"id": "297_loop2_invariant", + "label": {"text": "297_loop2_invariant"}}, + {"id": "298_loop2_unroll", + "label": {"text": "298_loop2_unroll"}}, + {"id": "299_loop2_doloop", + "label": {"text": "299_loop2_doloop"}}, + {"id": "300_loop2_done", + "label": {"text": "300_loop2_done"}}, + {"id": "301_subreg2", + "label": {"text": "301_subreg2"}}, + {"id": "302_web", + "label": {"text": "302_web"}}, + {"id": "303_cprop", + "label": {"text": "303_cprop"}}, + {"id": "304_stv", + "label": {"text": "304_stv"}}, + {"id": "305_cse2", + "label": {"text": "305_cse2"}}, + {"id": "306_dse1", + "label": {"text": "306_dse1"}}, + {"id": "307_fwprop2", + "label": {"text": "307_fwprop2"}}, + {"id": "308_auto_inc_dec", + "label": {"text": "308_auto_inc_dec"}}, + {"id": "309_init-regs", + "label": {"text": "309_init-regs"}}, + {"id": "310_ud_dce", + "label": {"text": "310_ud_dce"}}, + {"id": "311_ext_dce", + "label": {"text": "311_ext_dce"}}, + {"id": "312_combine", + "label": {"text": "312_combine"}}, + {"id": "313_late_combine", + "label": {"text": "313_late_combine"}}, + {"id": "314_rpad", + "label": {"text": "314_rpad"}}, + {"id": "315_rrvl", + "label": {"text": "315_rrvl"}}, + {"id": "316_stv", + "label": {"text": "316_stv"}}, + {"id": "317_ce2", + "label": {"text": "317_ce2"}}, + {"id": "318_jump_after_combine", + "label": {"text": "318_jump_after_combine"}}, + {"id": "319_bbpart", + "label": {"text": "319_bbpart"}}, + {"id": "320_outof_cfglayout", + "label": {"text": "320_outof_cfglayout"}}, + {"id": "321_split1", + "label": {"text": "321_split1"}}, + {"id": "322_subreg3", + "label": {"text": "322_subreg3"}}, + {"id": "323_no-opt dfinit", + "label": {"text": "323_no-opt dfinit"}}, + {"id": "*stack_ptr_mod_0x101f8050", + "label": {"text": "*stack_ptr_mod"}}, + {"id": "324_mode_sw", + "label": {"text": "324_mode_sw"}}, + {"id": "325_asmcons", + "label": {"text": "325_asmcons"}}, + {"id": "326_sms", + "label": {"text": "326_sms"}}, + {"id": "327_lr_shrinkage", + "label": {"text": "327_lr_shrinkage"}}, + {"id": "328_sched1", + "label": {"text": "328_sched1"}}, + {"id": "329_avoid_store_forwarding", + "label": {"text": "329_avoid_store_forwarding"}}, + {"id": "330_early_remat", + "label": {"text": "330_early_remat"}}, + {"id": "331_ira", + "label": {"text": "331_ira"}}, + {"id": "332_reload", + "label": {"text": "332_reload"}}, + {"id": "*all-postreload_0x101f8410", + "label": {"text": "*all-postreload"}}, + {"id": "333_postreload", + "label": {"text": "333_postreload"}}, + {"id": "334_vzeroupper", + "label": {"text": "334_vzeroupper"}}, + {"id": "335_late_combine", + "label": {"text": "335_late_combine"}}, + {"id": "336_gcse2", + "label": {"text": "336_gcse2"}}, + {"id": "337_split2", + "label": {"text": "337_split2"}}, + {"id": "338_ree", + "label": {"text": "338_ree"}}, + {"id": "339_cmpelim", + "label": {"text": "339_cmpelim"}}, + {"id": "340_pro_and_epilogue", + "label": {"text": "340_pro_and_epilogue"}}, + {"id": "341_dse2", + "label": {"text": "341_dse2"}}, + {"id": "342_csa", + "label": {"text": "342_csa"}}, + {"id": "343_jump2", + "label": {"text": "343_jump2"}}, + {"id": "344_compgotos", + "label": {"text": "344_compgotos"}}, + {"id": "345_sched_fusion", + "label": {"text": "345_sched_fusion"}}, + {"id": "346_peephole2", + "label": {"text": "346_peephole2"}}, + {"id": "347_ce3", + "label": {"text": "347_ce3"}}, + {"id": "348_rnreg", + "label": {"text": "348_rnreg"}}, + {"id": "349_fold_mem_offsets", + "label": {"text": "349_fold_mem_offsets"}}, + {"id": "350_cprop_hardreg", + "label": {"text": "350_cprop_hardreg"}}, + {"id": "351_rtl_dce", + "label": {"text": "351_rtl_dce"}}, + {"id": "352_bbro", + "label": {"text": "352_bbro"}}, + {"id": "*leaf_regs_0x101f8bf0", + "label": {"text": "*leaf_regs"}}, + {"id": "353_split3", + "label": {"text": "353_split3"}}, + {"id": "354_sched2", + "label": {"text": "354_sched2"}}, + {"id": "*stack_regs_0x101f8d10", + "label": {"text": "*stack_regs"}}, + {"id": "355_split4", + "label": {"text": "355_split4"}}, + {"id": "356_stack", + "label": {"text": "356_stack"}}, + {"id": "357_late_pro_and_epilogue", + "label": {"text": "357_late_pro_and_epilogue"}}, + {"id": "*all-late_compilation_0x101f8e90", + "label": {"text": "*all-late_compilation"}}, + {"id": "358_zero_call_used_regs", + "label": {"text": "358_zero_call_used_regs"}}, + {"id": "359_alignments", + "label": {"text": "359_alignments"}}, + {"id": "360_vartrack", + "label": {"text": "360_vartrack"}}, + {"id": "*free_cfg_0x101f9010", + "label": {"text": "*free_cfg"}}, + {"id": "361_mach", + "label": {"text": "361_mach"}}, + {"id": "362_barriers", + "label": {"text": "362_barriers"}}, + {"id": "363_dbr", + "label": {"text": "363_dbr"}}, + {"id": "364_split5", + "label": {"text": "364_split5"}}, + {"id": "365_eh_ranges", + "label": {"text": "365_eh_ranges"}}, + {"id": "366_endbr_and_patchable_area", + "label": {"text": "366_endbr_and_patchable_area"}}, + {"id": "367_align_tight_loops", + "label": {"text": "367_align_tight_loops"}}, + {"id": "368_shorten", + "label": {"text": "368_shorten"}}, + {"id": "369_nothrow", + "label": {"text": "369_nothrow"}}, + {"id": "370_dwarf2", + "label": {"text": "370_dwarf2"}}, + {"id": "371_final", + "label": {"text": "371_final"}}, + {"id": "372_dfinish", + "label": {"text": "372_dfinish"}}, + {"id": "*clean_state_0x101f9500", + "label": {"text": "*clean_state"}}]}], + "edges": [{"id": "edge0", + "label": {"text": "next"}, + "sourceNodeId": "22_ompexp", + "targetNodeId": "*build_cgraph_edges_0x101ef910"}, + {"id": "edge1", + "label": {"text": "next"}, + "sourceNodeId": "21_coro-early-expand-ifns", + "targetNodeId": "22_ompexp"}, + {"id": "edge2", + "label": {"text": "next"}, + "sourceNodeId": "*warn_function_return_0x101ef7f0", + "targetNodeId": "21_coro-early-expand-ifns"}, + {"id": "edge3", + "label": {"text": "next"}, + "sourceNodeId": "20_cfg", + "targetNodeId": "*warn_function_return_0x101ef7f0"}, + {"id": "edge4", + "label": {"text": "next"}, + "sourceNodeId": "19_coro-lower-builtins", + "targetNodeId": "20_cfg"}, + {"id": "edge5", + "label": {"text": "next"}, + "sourceNodeId": "18_eh", + "targetNodeId": "19_coro-lower-builtins"}, + {"id": "edge6", + "label": {"text": "next"}, + "sourceNodeId": "17_ehopt", + "targetNodeId": "18_eh"}, + {"id": "edge7", + "label": {"text": "next"}, + "sourceNodeId": "16_tmlower", + "targetNodeId": "17_ehopt"}, + {"id": "edge8", + "label": {"text": "next"}, + "sourceNodeId": "15_lower", + "targetNodeId": "16_tmlower"}, + {"id": "edge9", + "label": {"text": "next"}, + "sourceNodeId": "14_omplower", + "targetNodeId": "15_lower"}, + {"id": "edge10", + "label": {"text": "next"}, + "sourceNodeId": "13_omp_oacc_kernels_decompose", + "targetNodeId": "14_omplower"}, + {"id": "edge11", + "label": {"text": "next"}, + "sourceNodeId": "*diagnose_tm_blocks_0x101ef490", + "targetNodeId": "13_omp_oacc_kernels_decompose"}, + {"id": "edge12", + "label": {"text": "next"}, + "sourceNodeId": "*diagnose_omp_blocks_0x101ef430", + "targetNodeId": "*diagnose_tm_blocks_0x101ef490"}, + {"id": "edge13", + "label": {"text": "next"}, + "sourceNodeId": "*warn_unused_result_0x101ef3d0", + "targetNodeId": "*diagnose_omp_blocks_0x101ef430"}, + {"id": "edge14", + "label": {"text": "next"}, + "sourceNodeId": "34_nothrow", + "targetNodeId": "*rebuild_cgraph_edges_0x101f0020"}, + {"id": "edge15", + "label": {"text": "next"}, + "sourceNodeId": "33_ubsan", + "targetNodeId": "34_nothrow"}, + {"id": "edge16", + "label": {"text": "next"}, + "sourceNodeId": "32_waccess", + "targetNodeId": "33_ubsan"}, + {"id": "edge17", + "label": {"text": "next"}, + "sourceNodeId": "31_early_uninit", + "targetNodeId": "32_waccess"}, + {"id": "edge18", + "label": {"text": "next"}, + "sourceNodeId": "*nonnullcmp_0x101efce0", + "targetNodeId": "31_early_uninit"}, + {"id": "edge19", + "label": {"text": "next"}, + "sourceNodeId": "30_warn-printf", + "targetNodeId": "*nonnullcmp_0x101efce0"}, + {"id": "edge20", + "label": {"text": "next"}, + "sourceNodeId": "29_walloca", + "targetNodeId": "30_warn-printf"}, + {"id": "edge21", + "label": {"text": "next"}, + "sourceNodeId": "376_test_graph_emission", + "targetNodeId": "29_walloca"}, + {"id": "edge22", + "label": {"text": "next"}, + "sourceNodeId": "28_ssa", + "targetNodeId": "376_test_graph_emission"}, + {"id": "edge23", + "label": {"text": "next"}, + "sourceNodeId": "27_fixup_cfg", + "targetNodeId": "28_ssa"}, + {"id": "edge24", + "label": {"text": "sub"}, + "sourceNodeId": "26_build_ssa_passes", + "targetNodeId": "27_fixup_cfg"}, + {"id": "edge25", + "label": {"text": "next"}, + "sourceNodeId": "61_fnsplit", + "targetNodeId": "*strip_predict_hints_0x101f0c60"}, + {"id": "edge26", + "label": {"text": "next"}, + "sourceNodeId": "60_modref", + "targetNodeId": "61_fnsplit"}, + {"id": "edge27", + "label": {"text": "next"}, + "sourceNodeId": "59_local-pure-const", + "targetNodeId": "60_modref"}, + {"id": "edge28", + "label": {"text": "next"}, + "sourceNodeId": "58_profile_estimate", + "targetNodeId": "59_local-pure-const"}, + {"id": "edge29", + "label": {"text": "next"}, + "sourceNodeId": "57_sccopy", + "targetNodeId": "58_profile_estimate"}, + {"id": "edge30", + "label": {"text": "next"}, + "sourceNodeId": "56_ehcleanup", + "targetNodeId": "57_sccopy"}, + {"id": "edge31", + "label": {"text": "next"}, + "sourceNodeId": "55_switchconv", + "targetNodeId": "56_ehcleanup"}, + {"id": "edge32", + "label": {"text": "next"}, + "sourceNodeId": "54_iftoswitch", + "targetNodeId": "55_switchconv"}, + {"id": "edge33", + "label": {"text": "next"}, + "sourceNodeId": "53_tailr", + "targetNodeId": "54_iftoswitch"}, + {"id": "edge34", + "label": {"text": "next"}, + "sourceNodeId": "52_phiopt", + "targetNodeId": "53_tailr"}, + {"id": "edge35", + "label": {"text": "next"}, + "sourceNodeId": "51_cddce", + "targetNodeId": "52_phiopt"}, + {"id": "edge36", + "label": {"text": "next"}, + "sourceNodeId": "50_dse", + "targetNodeId": "51_cddce"}, + {"id": "edge37", + "label": {"text": "next"}, + "sourceNodeId": "49_mergephi", + "targetNodeId": "50_dse"}, + {"id": "edge38", + "label": {"text": "next"}, + "sourceNodeId": "48_evrp", + "targetNodeId": "49_mergephi"}, + {"id": "edge39", + "label": {"text": "next"}, + "sourceNodeId": "47_fre", + "targetNodeId": "48_evrp"}, + {"id": "edge40", + "label": {"text": "next"}, + "sourceNodeId": "46_phiprop", + "targetNodeId": "47_fre"}, + {"id": "edge41", + "label": {"text": "next"}, + "sourceNodeId": "45_ealias", + "targetNodeId": "46_phiprop"}, + {"id": "edge42", + "label": {"text": "next"}, + "sourceNodeId": "44_esra", + "targetNodeId": "45_ealias"}, + {"id": "edge43", + "label": {"text": "next"}, + "sourceNodeId": "43_ethread", + "targetNodeId": "44_esra"}, + {"id": "edge44", + "label": {"text": "next"}, + "sourceNodeId": "42_forwprop", + "targetNodeId": "43_ethread"}, + {"id": "edge45", + "label": {"text": "next"}, + "sourceNodeId": "41_ccp", + "targetNodeId": "42_forwprop"}, + {"id": "edge46", + "label": {"text": "next"}, + "sourceNodeId": "40_early_objsz", + "targetNodeId": "41_ccp"}, + {"id": "edge47", + "label": {"text": "next"}, + "sourceNodeId": "*remove_cgraph_callee_edges_0x101f0340", + "targetNodeId": "40_early_objsz"}, + {"id": "edge48", + "label": {"text": "sub"}, + "sourceNodeId": "39_early_optimizations", + "targetNodeId": "*remove_cgraph_callee_edges_0x101f0340"}, + {"id": "edge49", + "label": {"text": "next"}, + "sourceNodeId": "*rebuild_cgraph_edges_0x101f0d30", + "targetNodeId": "63_local-fnsummary"}, + {"id": "edge50", + "label": {"text": "next"}, + "sourceNodeId": "62_release_ssa", + "targetNodeId": "*rebuild_cgraph_edges_0x101f0d30"}, + {"id": "edge51", + "label": {"text": "next"}, + "sourceNodeId": "39_early_optimizations", + "targetNodeId": "62_release_ssa"}, + {"id": "edge52", + "label": {"text": "next"}, + "sourceNodeId": "*infinite-recursion_0x101f0260", + "targetNodeId": "39_early_optimizations"}, + {"id": "edge53", + "label": {"text": "next"}, + "sourceNodeId": "38_einline", + "targetNodeId": "*infinite-recursion_0x101f0260"}, + {"id": "edge54", + "label": {"text": "next"}, + "sourceNodeId": "37_local-fnsummary", + "targetNodeId": "38_einline"}, + {"id": "edge55", + "label": {"text": "next"}, + "sourceNodeId": "*rebuild_cgraph_edges_0x101f0140", + "targetNodeId": "37_local-fnsummary"}, + {"id": "edge56", + "label": {"text": "next"}, + "sourceNodeId": "36_fixup_cfg", + "targetNodeId": "*rebuild_cgraph_edges_0x101f0140"}, + {"id": "edge57", + "label": {"text": "sub"}, + "sourceNodeId": "35_opt_local_passes", + "targetNodeId": "36_fixup_cfg"}, + {"id": "edge58", + "label": {"text": "next"}, + "sourceNodeId": "76_ompexpssa", + "targetNodeId": "*rebuild_cgraph_edges_0x101f1310"}, + {"id": "edge59", + "label": {"text": "next"}, + "sourceNodeId": "75_parloops", + "targetNodeId": "76_ompexpssa"}, + {"id": "edge60", + "label": {"text": "next"}, + "sourceNodeId": "74_dce", + "targetNodeId": "75_parloops"}, + {"id": "edge61", + "label": {"text": "next"}, + "sourceNodeId": "73_dom", + "targetNodeId": "74_dce"}, + {"id": "edge62", + "label": {"text": "next"}, + "sourceNodeId": "72_lim", + "targetNodeId": "73_dom"}, + {"id": "edge63", + "label": {"text": "next"}, + "sourceNodeId": "71_fre", + "targetNodeId": "72_lim"}, + {"id": "edge64", + "label": {"text": "next"}, + "sourceNodeId": "70_ch", + "targetNodeId": "71_fre"}, + {"id": "edge65", + "label": {"text": "sub"}, + "sourceNodeId": "69_oacc_kernels", + "targetNodeId": "70_ch"}, + {"id": "edge66", + "label": {"text": "sub"}, + "sourceNodeId": "68_ipa_oacc_kernels", + "targetNodeId": "69_oacc_kernels"}, + {"id": "edge67", + "label": {"text": "next"}, + "sourceNodeId": "67_pta", + "targetNodeId": "68_ipa_oacc_kernels"}, + {"id": "edge68", + "label": {"text": "sub"}, + "sourceNodeId": "66_ipa_oacc", + "targetNodeId": "67_pta"}, + {"id": "edge69", + "label": {"text": "sub"}, + "sourceNodeId": "78_afdo", + "targetNodeId": "79_feedback_fnsplit"}, + {"id": "edge70", + "label": {"text": "sub"}, + "sourceNodeId": "80_profile", + "targetNodeId": "81_feedback_fnsplit"}, + {"id": "edge71", + "label": {"text": "next"}, + "sourceNodeId": "84_tmipa", + "targetNodeId": "85_emutls"}, + {"id": "edge72", + "label": {"text": "next"}, + "sourceNodeId": "83_increase_alignment", + "targetNodeId": "84_tmipa"}, + {"id": "edge73", + "label": {"text": "next"}, + "sourceNodeId": "82_free-fnsummary", + "targetNodeId": "83_increase_alignment"}, + {"id": "edge74", + "label": {"text": "next"}, + "sourceNodeId": "80_profile", + "targetNodeId": "82_free-fnsummary"}, + {"id": "edge75", + "label": {"text": "next"}, + "sourceNodeId": "78_afdo", + "targetNodeId": "80_profile"}, + {"id": "edge76", + "label": {"text": "next"}, + "sourceNodeId": "77_targetclone", + "targetNodeId": "78_afdo"}, + {"id": "edge77", + "label": {"text": "next"}, + "sourceNodeId": "66_ipa_oacc", + "targetNodeId": "77_targetclone"}, + {"id": "edge78", + "label": {"text": "next"}, + "sourceNodeId": "65_strub", + "targetNodeId": "66_ipa_oacc"}, + {"id": "edge79", + "label": {"text": "next"}, + "sourceNodeId": "64_remove_symbols", + "targetNodeId": "65_strub"}, + {"id": "edge80", + "label": {"text": "next"}, + "sourceNodeId": "35_opt_local_passes", + "targetNodeId": "64_remove_symbols"}, + {"id": "edge81", + "label": {"text": "next"}, + "sourceNodeId": "26_build_ssa_passes", + "targetNodeId": "35_opt_local_passes"}, + {"id": "edge82", + "label": {"text": "next"}, + "sourceNodeId": "25_strubm", + "targetNodeId": "26_build_ssa_passes"}, + {"id": "edge83", + "label": {"text": "next"}, + "sourceNodeId": "24_visibility", + "targetNodeId": "25_strubm"}, + {"id": "edge84", + "label": {"text": "next"}, + "sourceNodeId": "*free_lang_data_0x101ef9d0", + "targetNodeId": "24_visibility"}, + {"id": "edge85", + "label": {"text": "next"}, + "sourceNodeId": "23_afdo_offline", + "targetNodeId": "*free_lang_data_0x101ef9d0"}, + {"id": "edge86", + "label": {"text": "next"}, + "sourceNodeId": "102_single-use", + "targetNodeId": "103_comdats"}, + {"id": "edge87", + "label": {"text": "next"}, + "sourceNodeId": "101_static-var", + "targetNodeId": "102_single-use"}, + {"id": "edge88", + "label": {"text": "next"}, + "sourceNodeId": "100_free-fnsummary", + "targetNodeId": "101_static-var"}, + {"id": "edge89", + "label": {"text": "next"}, + "sourceNodeId": "99_modref", + "targetNodeId": "100_free-fnsummary"}, + {"id": "edge90", + "label": {"text": "next"}, + "sourceNodeId": "98_pure-const", + "targetNodeId": "99_modref"}, + {"id": "edge91", + "label": {"text": "next"}, + "sourceNodeId": "97_locality-clone", + "targetNodeId": "98_pure-const"}, + {"id": "edge92", + "label": {"text": "next"}, + "sourceNodeId": "96_inline", + "targetNodeId": "97_locality-clone"}, + {"id": "edge93", + "label": {"text": "next"}, + "sourceNodeId": "95_fnsummary", + "targetNodeId": "96_inline"}, + {"id": "edge94", + "label": {"text": "next"}, + "sourceNodeId": "94_sra", + "targetNodeId": "95_fnsummary"}, + {"id": "edge95", + "label": {"text": "next"}, + "sourceNodeId": "93_cp", + "targetNodeId": "94_sra"}, + {"id": "edge96", + "label": {"text": "next"}, + "sourceNodeId": "92_cdtor", + "targetNodeId": "93_cp"}, + {"id": "edge97", + "label": {"text": "next"}, + "sourceNodeId": "91_devirt", + "targetNodeId": "92_cdtor"}, + {"id": "edge98", + "label": {"text": "next"}, + "sourceNodeId": "90_icf", + "targetNodeId": "91_devirt"}, + {"id": "edge99", + "label": {"text": "next"}, + "sourceNodeId": "89_profile_estimate", + "targetNodeId": "90_icf"}, + {"id": "edge100", + "label": {"text": "next"}, + "sourceNodeId": "88_whole-program", + "targetNodeId": "89_profile_estimate"}, + {"id": "edge101", + "label": {"text": "next"}, + "sourceNodeId": "87_odr", + "targetNodeId": "88_whole-program"}, + {"id": "edge102", + "label": {"text": "next"}, + "sourceNodeId": "86_analyzer", + "targetNodeId": "87_odr"}, + {"id": "edge103", + "label": {"text": "next"}, + "sourceNodeId": "104_pta", + "targetNodeId": "105_simdclone"}, + {"id": "edge104", + "label": {"text": "next"}, + "sourceNodeId": "183_copyprop", + "targetNodeId": "184_dce"}, + {"id": "edge105", + "label": {"text": "next"}, + "sourceNodeId": "182_lim", + "targetNodeId": "183_copyprop"}, + {"id": "edge106", + "label": {"text": "next"}, + "sourceNodeId": "181_graphite", + "targetNodeId": "182_lim"}, + {"id": "edge107", + "label": {"text": "sub"}, + "sourceNodeId": "180_graphite0", + "targetNodeId": "181_graphite"}, + {"id": "edge108", + "label": {"text": "sub"}, + "sourceNodeId": "189_vect", + "targetNodeId": "190_dce"}, + {"id": "edge109", + "label": {"text": "next"}, + "sourceNodeId": "193_fre", + "targetNodeId": "194_dse"}, + {"id": "edge110", + "label": {"text": "sub"}, + "sourceNodeId": "*pre_slp_scalar_cleanup_0x101f4880", + "targetNodeId": "193_fre"}, + {"id": "edge111", + "label": {"text": "next"}, + "sourceNodeId": "198_lim", + "targetNodeId": "199_loopdone"}, + {"id": "edge112", + "label": {"text": "next"}, + "sourceNodeId": "197_ivopts", + "targetNodeId": "198_lim"}, + {"id": "edge113", + "label": {"text": "next"}, + "sourceNodeId": "196_aprefetch", + "targetNodeId": "197_ivopts"}, + {"id": "edge114", + "label": {"text": "next"}, + "sourceNodeId": "195_slp", + "targetNodeId": "196_aprefetch"}, + {"id": "edge115", + "label": {"text": "next"}, + "sourceNodeId": "*pre_slp_scalar_cleanup_0x101f4880", + "targetNodeId": "195_slp"}, + {"id": "edge116", + "label": {"text": "next"}, + "sourceNodeId": "192_cunroll", + "targetNodeId": "*pre_slp_scalar_cleanup_0x101f4880"}, + {"id": "edge117", + "label": {"text": "next"}, + "sourceNodeId": "191_pcom", + "targetNodeId": "192_cunroll"}, + {"id": "edge118", + "label": {"text": "next"}, + "sourceNodeId": "189_vect", + "targetNodeId": "191_pcom"}, + {"id": "edge119", + "label": {"text": "next"}, + "sourceNodeId": "188_ifcvt", + "targetNodeId": "189_vect"}, + {"id": "edge120", + "label": {"text": "next"}, + "sourceNodeId": "187_ch_vect", + "targetNodeId": "188_ifcvt"}, + {"id": "edge121", + "label": {"text": "next"}, + "sourceNodeId": "186_ompexpssa", + "targetNodeId": "187_ch_vect"}, + {"id": "edge122", + "label": {"text": "next"}, + "sourceNodeId": "185_parloops", + "targetNodeId": "186_ompexpssa"}, + {"id": "edge123", + "label": {"text": "next"}, + "sourceNodeId": "180_graphite0", + "targetNodeId": "185_parloops"}, + {"id": "edge124", + "label": {"text": "next"}, + "sourceNodeId": "179_copyprop", + "targetNodeId": "180_graphite0"}, + {"id": "edge125", + "label": {"text": "next"}, + "sourceNodeId": "178_linterchange", + "targetNodeId": "179_copyprop"}, + {"id": "edge126", + "label": {"text": "next"}, + "sourceNodeId": "177_crc", + "targetNodeId": "178_linterchange"}, + {"id": "edge127", + "label": {"text": "next"}, + "sourceNodeId": "176_ldist", + "targetNodeId": "177_crc"}, + {"id": "edge128", + "label": {"text": "next"}, + "sourceNodeId": "175_ivcanon", + "targetNodeId": "176_ldist"}, + {"id": "edge129", + "label": {"text": "next"}, + "sourceNodeId": "174_cddce", + "targetNodeId": "175_ivcanon"}, + {"id": "edge130", + "label": {"text": "next"}, + "sourceNodeId": "173_unrolljam", + "targetNodeId": "174_cddce"}, + {"id": "edge131", + "label": {"text": "next"}, + "sourceNodeId": "172_lversion", + "targetNodeId": "173_unrolljam"}, + {"id": "edge132", + "label": {"text": "next"}, + "sourceNodeId": "171_sccp", + "targetNodeId": "172_lversion"}, + {"id": "edge133", + "label": {"text": "next"}, + "sourceNodeId": "170_lsplit", + "targetNodeId": "171_sccp"}, + {"id": "edge134", + "label": {"text": "next"}, + "sourceNodeId": "169_unswitch", + "targetNodeId": "170_lsplit"}, + {"id": "edge135", + "label": {"text": "next"}, + "sourceNodeId": "168_loopinit", + "targetNodeId": "169_unswitch"}, + {"id": "edge136", + "label": {"text": "sub"}, + "sourceNodeId": "167_loop", + "targetNodeId": "168_loopinit"}, + {"id": "edge137", + "label": {"text": "sub"}, + "sourceNodeId": "200_no_loop", + "targetNodeId": "201_slp"}, + {"id": "edge138", + "label": {"text": "next"}, + "sourceNodeId": "233_modref", + "targetNodeId": "234_uncprop"}, + {"id": "edge139", + "label": {"text": "next"}, + "sourceNodeId": "232_local-pure-const", + "targetNodeId": "233_modref"}, + {"id": "edge140", + "label": {"text": "next"}, + "sourceNodeId": "231_uninit", + "targetNodeId": "232_local-pure-const"}, + {"id": "edge141", + "label": {"text": "next"}, + "sourceNodeId": "230_crited", + "targetNodeId": "231_uninit"}, + {"id": "edge142", + "label": {"text": "next"}, + "sourceNodeId": "229_tailc", + "targetNodeId": "230_crited"}, + {"id": "edge143", + "label": {"text": "next"}, + "sourceNodeId": "228_sccopy", + "targetNodeId": "229_tailc"}, + {"id": "edge144", + "label": {"text": "next"}, + "sourceNodeId": "227_cddce", + "targetNodeId": "228_sccopy"}, + {"id": "edge145", + "label": {"text": "next"}, + "sourceNodeId": "226_store-merging", + "targetNodeId": "227_cddce"}, + {"id": "edge146", + "label": {"text": "next"}, + "sourceNodeId": "225_widening_mul", + "targetNodeId": "226_store-merging"}, + {"id": "edge147", + "label": {"text": "next"}, + "sourceNodeId": "224_fab", + "targetNodeId": "225_widening_mul"}, + {"id": "edge148", + "label": {"text": "next"}, + "sourceNodeId": "223_phiopt", + "targetNodeId": "224_fab"}, + {"id": "edge149", + "label": {"text": "next"}, + "sourceNodeId": "222_sink", + "targetNodeId": "223_phiopt"}, + {"id": "edge150", + "label": {"text": "next"}, + "sourceNodeId": "221_forwprop", + "targetNodeId": "222_sink"}, + {"id": "edge151", + "label": {"text": "next"}, + "sourceNodeId": "220_dce", + "targetNodeId": "221_forwprop"}, + {"id": "edge152", + "label": {"text": "next"}, + "sourceNodeId": "219_dse", + "targetNodeId": "220_dce"}, + {"id": "edge153", + "label": {"text": "next"}, + "sourceNodeId": "218_wrestrict", + "targetNodeId": "219_dse"}, + {"id": "edge154", + "label": {"text": "next"}, + "sourceNodeId": "217_ccp", + "targetNodeId": "218_wrestrict"}, + {"id": "edge155", + "label": {"text": "next"}, + "sourceNodeId": "216_vrp", + "targetNodeId": "217_ccp"}, + {"id": "edge156", + "label": {"text": "next"}, + "sourceNodeId": "215_threadfull", + "targetNodeId": "216_vrp"}, + {"id": "edge157", + "label": {"text": "next"}, + "sourceNodeId": "214_strlen", + "targetNodeId": "215_threadfull"}, + {"id": "edge158", + "label": {"text": "next"}, + "sourceNodeId": "213_dom", + "targetNodeId": "214_strlen"}, + {"id": "edge159", + "label": {"text": "next"}, + "sourceNodeId": "212_thread", + "targetNodeId": "213_dom"}, + {"id": "edge160", + "label": {"text": "next"}, + "sourceNodeId": "211_fre", + "targetNodeId": "212_thread"}, + {"id": "edge161", + "label": {"text": "next"}, + "sourceNodeId": "210_tracer", + "targetNodeId": "211_fre"}, + {"id": "edge162", + "label": {"text": "next"}, + "sourceNodeId": "209_split-paths", + "targetNodeId": "210_tracer"}, + {"id": "edge163", + "label": {"text": "next"}, + "sourceNodeId": "208_slsr", + "targetNodeId": "209_split-paths"}, + {"id": "edge164", + "label": {"text": "next"}, + "sourceNodeId": "207_reassoc", + "targetNodeId": "208_slsr"}, + {"id": "edge165", + "label": {"text": "next"}, + "sourceNodeId": "206_recip", + "targetNodeId": "207_reassoc"}, + {"id": "edge166", + "label": {"text": "next"}, + "sourceNodeId": "205_sincos", + "targetNodeId": "206_recip"}, + {"id": "edge167", + "label": {"text": "next"}, + "sourceNodeId": "204_switchlower", + "targetNodeId": "205_sincos"}, + {"id": "edge168", + "label": {"text": "next"}, + "sourceNodeId": "203_veclower2", + "targetNodeId": "204_switchlower"}, + {"id": "edge169", + "label": {"text": "next"}, + "sourceNodeId": "202_simduid", + "targetNodeId": "203_veclower2"}, + {"id": "edge170", + "label": {"text": "next"}, + "sourceNodeId": "200_no_loop", + "targetNodeId": "202_simduid"}, + {"id": "edge171", + "label": {"text": "next"}, + "sourceNodeId": "167_loop", + "targetNodeId": "200_no_loop"}, + {"id": "edge172", + "label": {"text": "next"}, + "sourceNodeId": "166_fix_loops", + "targetNodeId": "167_loop"}, + {"id": "edge173", + "label": {"text": "next"}, + "sourceNodeId": "165_dce", + "targetNodeId": "166_fix_loops"}, + {"id": "edge174", + "label": {"text": "next"}, + "sourceNodeId": "164_dse", + "targetNodeId": "165_dce"}, + {"id": "edge175", + "label": {"text": "next"}, + "sourceNodeId": "163_tsan", + "targetNodeId": "164_dse"}, + {"id": "edge176", + "label": {"text": "next"}, + "sourceNodeId": "162_asan", + "targetNodeId": "163_tsan"}, + {"id": "edge177", + "label": {"text": "next"}, + "sourceNodeId": "161_sancov", + "targetNodeId": "162_asan"}, + {"id": "edge178", + "label": {"text": "next"}, + "sourceNodeId": "160_sink", + "targetNodeId": "161_sancov"}, + {"id": "edge179", + "label": {"text": "next"}, + "sourceNodeId": "159_pre", + "targetNodeId": "160_sink"}, + {"id": "edge180", + "label": {"text": "next"}, + "sourceNodeId": "158_walloca", + "targetNodeId": "159_pre"}, + {"id": "edge181", + "label": {"text": "next"}, + "sourceNodeId": "157_lim", + "targetNodeId": "158_walloca"}, + {"id": "edge182", + "label": {"text": "next"}, + "sourceNodeId": "156_laddress", + "targetNodeId": "157_lim"}, + {"id": "edge183", + "label": {"text": "next"}, + "sourceNodeId": "155_bswap", + "targetNodeId": "156_laddress"}, + {"id": "edge184", + "label": {"text": "next"}, + "sourceNodeId": "154_pow", + "targetNodeId": "155_bswap"}, + {"id": "edge185", + "label": {"text": "next"}, + "sourceNodeId": "153_ccp", + "targetNodeId": "154_pow"}, + {"id": "edge186", + "label": {"text": "next"}, + "sourceNodeId": "152_phiopt", + "targetNodeId": "153_ccp"}, + {"id": "edge187", + "label": {"text": "next"}, + "sourceNodeId": "151_forwprop", + "targetNodeId": "152_phiopt"}, + {"id": "edge188", + "label": {"text": "next"}, + "sourceNodeId": "150_dce", + "targetNodeId": "151_forwprop"}, + {"id": "edge189", + "label": {"text": "next"}, + "sourceNodeId": "149_reassoc", + "targetNodeId": "150_dce"}, + {"id": "edge190", + "label": {"text": "next"}, + "sourceNodeId": "148_isolate-paths", + "targetNodeId": "149_reassoc"}, + {"id": "edge191", + "label": {"text": "next"}, + "sourceNodeId": "147_copyprop", + "targetNodeId": "148_isolate-paths"}, + {"id": "edge192", + "label": {"text": "next"}, + "sourceNodeId": "146_dom", + "targetNodeId": "147_copyprop"}, + {"id": "edge193", + "label": {"text": "next"}, + "sourceNodeId": "145_thread", + "targetNodeId": "146_dom"}, + {"id": "edge194", + "label": {"text": "next"}, + "sourceNodeId": "144_sra", + "targetNodeId": "145_thread"}, + {"id": "edge195", + "label": {"text": "next"}, + "sourceNodeId": "143_bitintlower", + "targetNodeId": "144_sra"}, + {"id": "edge196", + "label": {"text": "next"}, + "sourceNodeId": "142_cplxlower", + "targetNodeId": "143_bitintlower"}, + {"id": "edge197", + "label": {"text": "next"}, + "sourceNodeId": "141_ch", + "targetNodeId": "142_cplxlower"}, + {"id": "edge198", + "label": {"text": "next"}, + "sourceNodeId": "140_tailr", + "targetNodeId": "141_ch"}, + {"id": "edge199", + "label": {"text": "next"}, + "sourceNodeId": "139_phiopt", + "targetNodeId": "140_tailr"}, + {"id": "edge200", + "label": {"text": "next"}, + "sourceNodeId": "138_mergephi", + "targetNodeId": "139_phiopt"}, + {"id": "edge201", + "label": {"text": "next"}, + "sourceNodeId": "137_ifcombine", + "targetNodeId": "138_mergephi"}, + {"id": "edge202", + "label": {"text": "next"}, + "sourceNodeId": "136_copyprop", + "targetNodeId": "137_ifcombine"}, + {"id": "edge203", + "label": {"text": "next"}, + "sourceNodeId": "135_cselim", + "targetNodeId": "136_copyprop"}, + {"id": "edge204", + "label": {"text": "next"}, + "sourceNodeId": "134_cdce", + "targetNodeId": "135_cselim"}, + {"id": "edge205", + "label": {"text": "next"}, + "sourceNodeId": "133_stdarg", + "targetNodeId": "134_cdce"}, + {"id": "edge206", + "label": {"text": "next"}, + "sourceNodeId": "132_dce", + "targetNodeId": "133_stdarg"}, + {"id": "edge207", + "label": {"text": "next"}, + "sourceNodeId": "131_dse", + "targetNodeId": "132_dce"}, + {"id": "edge208", + "label": {"text": "next"}, + "sourceNodeId": "130_bounds", + "targetNodeId": "131_dse"}, + {"id": "edge209", + "label": {"text": "next"}, + "sourceNodeId": "129_vrp", + "targetNodeId": "130_bounds"}, + {"id": "edge210", + "label": {"text": "next"}, + "sourceNodeId": "128_threadfull", + "targetNodeId": "129_vrp"}, + {"id": "edge211", + "label": {"text": "next"}, + "sourceNodeId": "127_mergephi", + "targetNodeId": "128_threadfull"}, + {"id": "edge212", + "label": {"text": "next"}, + "sourceNodeId": "126_fre", + "targetNodeId": "127_mergephi"}, + {"id": "edge213", + "label": {"text": "next"}, + "sourceNodeId": "125_retslot", + "targetNodeId": "126_fre"}, + {"id": "edge214", + "label": {"text": "next"}, + "sourceNodeId": "124_alias", + "targetNodeId": "125_retslot"}, + {"id": "edge215", + "label": {"text": "next"}, + "sourceNodeId": "123_forwprop", + "targetNodeId": "124_alias"}, + {"id": "edge216", + "label": {"text": "next"}, + "sourceNodeId": "122_phiprop", + "targetNodeId": "123_forwprop"}, + {"id": "edge217", + "label": {"text": "next"}, + "sourceNodeId": "121_backprop", + "targetNodeId": "122_phiprop"}, + {"id": "edge218", + "label": {"text": "next"}, + "sourceNodeId": "120_cunrolli", + "targetNodeId": "121_backprop"}, + {"id": "edge219", + "label": {"text": "next"}, + "sourceNodeId": "119_rebuild_frequencies", + "targetNodeId": "120_cunrolli"}, + {"id": "edge220", + "label": {"text": "next"}, + "sourceNodeId": "118_waccess", + "targetNodeId": "119_rebuild_frequencies"}, + {"id": "edge221", + "label": {"text": "next"}, + "sourceNodeId": "117_post_ipa_warn", + "targetNodeId": "118_waccess"}, + {"id": "edge222", + "label": {"text": "next"}, + "sourceNodeId": "116_objsz", + "targetNodeId": "117_post_ipa_warn"}, + {"id": "edge223", + "label": {"text": "next"}, + "sourceNodeId": "115_ccp", + "targetNodeId": "116_objsz"}, + {"id": "edge224", + "label": {"text": "next"}, + "sourceNodeId": "*strip_predict_hints_0x101f27e0", + "targetNodeId": "115_ccp"}, + {"id": "edge225", + "label": {"text": "next"}, + "sourceNodeId": "*remove_cgraph_callee_edges_0x101f2780", + "targetNodeId": "*strip_predict_hints_0x101f27e0"}, + {"id": "edge226", + "label": {"text": "sub"}, + "sourceNodeId": "*all_optimizations_0x101f2720", + "targetNodeId": "*remove_cgraph_callee_edges_0x101f2780"}, + {"id": "edge227", + "label": {"text": "next"}, + "sourceNodeId": "251_uninit", + "targetNodeId": "252_uncprop"}, + {"id": "edge228", + "label": {"text": "next"}, + "sourceNodeId": "250_crited", + "targetNodeId": "251_uninit"}, + {"id": "edge229", + "label": {"text": "next"}, + "sourceNodeId": "249_tsan", + "targetNodeId": "250_crited"}, + {"id": "edge230", + "label": {"text": "next"}, + "sourceNodeId": "248_asan", + "targetNodeId": "249_tsan"}, + {"id": "edge231", + "label": {"text": "next"}, + "sourceNodeId": "247_sancov", + "targetNodeId": "248_asan"}, + {"id": "edge232", + "label": {"text": "next"}, + "sourceNodeId": "246_rebuild_frequencies", + "targetNodeId": "247_sancov"}, + {"id": "edge233", + "label": {"text": "next"}, + "sourceNodeId": "245_dce", + "targetNodeId": "246_rebuild_frequencies"}, + {"id": "edge234", + "label": {"text": "next"}, + "sourceNodeId": "244_copyprop", + "targetNodeId": "245_dce"}, + {"id": "edge235", + "label": {"text": "next"}, + "sourceNodeId": "243_strlen", + "targetNodeId": "244_copyprop"}, + {"id": "edge236", + "label": {"text": "next"}, + "sourceNodeId": "242_fab", + "targetNodeId": "243_strlen"}, + {"id": "edge237", + "label": {"text": "next"}, + "sourceNodeId": "241_objsz", + "targetNodeId": "242_fab"}, + {"id": "edge238", + "label": {"text": "next"}, + "sourceNodeId": "240_post_ipa_warn", + "targetNodeId": "241_objsz"}, + {"id": "edge239", + "label": {"text": "next"}, + "sourceNodeId": "239_ccp", + "targetNodeId": "240_post_ipa_warn"}, + {"id": "edge240", + "label": {"text": "next"}, + "sourceNodeId": "238_switchlower", + "targetNodeId": "239_ccp"}, + {"id": "edge241", + "label": {"text": "next"}, + "sourceNodeId": "237_veclower2", + "targetNodeId": "238_switchlower"}, + {"id": "edge242", + "label": {"text": "next"}, + "sourceNodeId": "236_bitintlower", + "targetNodeId": "237_veclower2"}, + {"id": "edge243", + "label": {"text": "next"}, + "sourceNodeId": "235_cplxlower", + "targetNodeId": "236_bitintlower"}, + {"id": "edge244", + "label": {"text": "next"}, + "sourceNodeId": "*strip_predict_hints_0x101f5bb0", + "targetNodeId": "235_cplxlower"}, + {"id": "edge245", + "label": {"text": "next"}, + "sourceNodeId": "*remove_cgraph_callee_edges_0x101f5b50", + "targetNodeId": "*strip_predict_hints_0x101f5bb0"}, + {"id": "edge246", + "label": {"text": "sub"}, + "sourceNodeId": "*all_optimizations_g_0x101f5af0", + "targetNodeId": "*remove_cgraph_callee_edges_0x101f5b50"}, + {"id": "edge247", + "label": {"text": "next"}, + "sourceNodeId": "255_tmmemopt", + "targetNodeId": "256_tmedge"}, + {"id": "edge248", + "label": {"text": "next"}, + "sourceNodeId": "254_tmmark", + "targetNodeId": "255_tmmemopt"}, + {"id": "edge249", + "label": {"text": "sub"}, + "sourceNodeId": "*tminit_0x101f6370", + "targetNodeId": "254_tmmark"}, + {"id": "edge250", + "label": {"text": "next"}, + "sourceNodeId": "299_loop2_doloop", + "targetNodeId": "300_loop2_done"}, + {"id": "edge251", + "label": {"text": "next"}, + "sourceNodeId": "298_loop2_unroll", + "targetNodeId": "299_loop2_doloop"}, + {"id": "edge252", + "label": {"text": "next"}, + "sourceNodeId": "297_loop2_invariant", + "targetNodeId": "298_loop2_unroll"}, + {"id": "edge253", + "label": {"text": "next"}, + "sourceNodeId": "296_loop2_init", + "targetNodeId": "297_loop2_invariant"}, + {"id": "edge254", + "label": {"text": "sub"}, + "sourceNodeId": "295_loop2", + "targetNodeId": "296_loop2_init"}, + {"id": "edge255", + "label": {"text": "next"}, + "sourceNodeId": "355_split4", + "targetNodeId": "356_stack"}, + {"id": "edge256", + "label": {"text": "sub"}, + "sourceNodeId": "*stack_regs_0x101f8d10", + "targetNodeId": "355_split4"}, + {"id": "edge257", + "label": {"text": "next"}, + "sourceNodeId": "354_sched2", + "targetNodeId": "*stack_regs_0x101f8d10"}, + {"id": "edge258", + "label": {"text": "next"}, + "sourceNodeId": "353_split3", + "targetNodeId": "354_sched2"}, + {"id": "edge259", + "label": {"text": "next"}, + "sourceNodeId": "*leaf_regs_0x101f8bf0", + "targetNodeId": "353_split3"}, + {"id": "edge260", + "label": {"text": "next"}, + "sourceNodeId": "352_bbro", + "targetNodeId": "*leaf_regs_0x101f8bf0"}, + {"id": "edge261", + "label": {"text": "next"}, + "sourceNodeId": "351_rtl_dce", + "targetNodeId": "352_bbro"}, + {"id": "edge262", + "label": {"text": "next"}, + "sourceNodeId": "350_cprop_hardreg", + "targetNodeId": "351_rtl_dce"}, + {"id": "edge263", + "label": {"text": "next"}, + "sourceNodeId": "349_fold_mem_offsets", + "targetNodeId": "350_cprop_hardreg"}, + {"id": "edge264", + "label": {"text": "next"}, + "sourceNodeId": "348_rnreg", + "targetNodeId": "349_fold_mem_offsets"}, + {"id": "edge265", + "label": {"text": "next"}, + "sourceNodeId": "347_ce3", + "targetNodeId": "348_rnreg"}, + {"id": "edge266", + "label": {"text": "next"}, + "sourceNodeId": "346_peephole2", + "targetNodeId": "347_ce3"}, + {"id": "edge267", + "label": {"text": "next"}, + "sourceNodeId": "345_sched_fusion", + "targetNodeId": "346_peephole2"}, + {"id": "edge268", + "label": {"text": "next"}, + "sourceNodeId": "344_compgotos", + "targetNodeId": "345_sched_fusion"}, + {"id": "edge269", + "label": {"text": "next"}, + "sourceNodeId": "343_jump2", + "targetNodeId": "344_compgotos"}, + {"id": "edge270", + "label": {"text": "next"}, + "sourceNodeId": "342_csa", + "targetNodeId": "343_jump2"}, + {"id": "edge271", + "label": {"text": "next"}, + "sourceNodeId": "341_dse2", + "targetNodeId": "342_csa"}, + {"id": "edge272", + "label": {"text": "next"}, + "sourceNodeId": "340_pro_and_epilogue", + "targetNodeId": "341_dse2"}, + {"id": "edge273", + "label": {"text": "next"}, + "sourceNodeId": "339_cmpelim", + "targetNodeId": "340_pro_and_epilogue"}, + {"id": "edge274", + "label": {"text": "next"}, + "sourceNodeId": "338_ree", + "targetNodeId": "339_cmpelim"}, + {"id": "edge275", + "label": {"text": "next"}, + "sourceNodeId": "337_split2", + "targetNodeId": "338_ree"}, + {"id": "edge276", + "label": {"text": "next"}, + "sourceNodeId": "336_gcse2", + "targetNodeId": "337_split2"}, + {"id": "edge277", + "label": {"text": "next"}, + "sourceNodeId": "335_late_combine", + "targetNodeId": "336_gcse2"}, + {"id": "edge278", + "label": {"text": "next"}, + "sourceNodeId": "334_vzeroupper", + "targetNodeId": "335_late_combine"}, + {"id": "edge279", + "label": {"text": "next"}, + "sourceNodeId": "333_postreload", + "targetNodeId": "334_vzeroupper"}, + {"id": "edge280", + "label": {"text": "sub"}, + "sourceNodeId": "*all-postreload_0x101f8410", + "targetNodeId": "333_postreload"}, + {"id": "edge281", + "label": {"text": "next"}, + "sourceNodeId": "370_dwarf2", + "targetNodeId": "371_final"}, + {"id": "edge282", + "label": {"text": "next"}, + "sourceNodeId": "369_nothrow", + "targetNodeId": "370_dwarf2"}, + {"id": "edge283", + "label": {"text": "next"}, + "sourceNodeId": "368_shorten", + "targetNodeId": "369_nothrow"}, + {"id": "edge284", + "label": {"text": "next"}, + "sourceNodeId": "367_align_tight_loops", + "targetNodeId": "368_shorten"}, + {"id": "edge285", + "label": {"text": "next"}, + "sourceNodeId": "366_endbr_and_patchable_area", + "targetNodeId": "367_align_tight_loops"}, + {"id": "edge286", + "label": {"text": "next"}, + "sourceNodeId": "365_eh_ranges", + "targetNodeId": "366_endbr_and_patchable_area"}, + {"id": "edge287", + "label": {"text": "next"}, + "sourceNodeId": "364_split5", + "targetNodeId": "365_eh_ranges"}, + {"id": "edge288", + "label": {"text": "next"}, + "sourceNodeId": "363_dbr", + "targetNodeId": "364_split5"}, + {"id": "edge289", + "label": {"text": "next"}, + "sourceNodeId": "362_barriers", + "targetNodeId": "363_dbr"}, + {"id": "edge290", + "label": {"text": "next"}, + "sourceNodeId": "361_mach", + "targetNodeId": "362_barriers"}, + {"id": "edge291", + "label": {"text": "next"}, + "sourceNodeId": "*free_cfg_0x101f9010", + "targetNodeId": "361_mach"}, + {"id": "edge292", + "label": {"text": "next"}, + "sourceNodeId": "360_vartrack", + "targetNodeId": "*free_cfg_0x101f9010"}, + {"id": "edge293", + "label": {"text": "next"}, + "sourceNodeId": "359_alignments", + "targetNodeId": "360_vartrack"}, + {"id": "edge294", + "label": {"text": "next"}, + "sourceNodeId": "358_zero_call_used_regs", + "targetNodeId": "359_alignments"}, + {"id": "edge295", + "label": {"text": "sub"}, + "sourceNodeId": "*all-late_compilation_0x101f8e90", + "targetNodeId": "358_zero_call_used_regs"}, + {"id": "edge296", + "label": {"text": "next"}, + "sourceNodeId": "*all-late_compilation_0x101f8e90", + "targetNodeId": "372_dfinish"}, + {"id": "edge297", + "label": {"text": "next"}, + "sourceNodeId": "357_late_pro_and_epilogue", + "targetNodeId": "*all-late_compilation_0x101f8e90"}, + {"id": "edge298", + "label": {"text": "next"}, + "sourceNodeId": "*all-postreload_0x101f8410", + "targetNodeId": "357_late_pro_and_epilogue"}, + {"id": "edge299", + "label": {"text": "next"}, + "sourceNodeId": "332_reload", + "targetNodeId": "*all-postreload_0x101f8410"}, + {"id": "edge300", + "label": {"text": "next"}, + "sourceNodeId": "331_ira", + "targetNodeId": "332_reload"}, + {"id": "edge301", + "label": {"text": "next"}, + "sourceNodeId": "330_early_remat", + "targetNodeId": "331_ira"}, + {"id": "edge302", + "label": {"text": "next"}, + "sourceNodeId": "329_avoid_store_forwarding", + "targetNodeId": "330_early_remat"}, + {"id": "edge303", + "label": {"text": "next"}, + "sourceNodeId": "328_sched1", + "targetNodeId": "329_avoid_store_forwarding"}, + {"id": "edge304", + "label": {"text": "next"}, + "sourceNodeId": "327_lr_shrinkage", + "targetNodeId": "328_sched1"}, + {"id": "edge305", + "label": {"text": "next"}, + "sourceNodeId": "326_sms", + "targetNodeId": "327_lr_shrinkage"}, + {"id": "edge306", + "label": {"text": "next"}, + "sourceNodeId": "325_asmcons", + "targetNodeId": "326_sms"}, + {"id": "edge307", + "label": {"text": "next"}, + "sourceNodeId": "324_mode_sw", + "targetNodeId": "325_asmcons"}, + {"id": "edge308", + "label": {"text": "next"}, + "sourceNodeId": "*stack_ptr_mod_0x101f8050", + "targetNodeId": "324_mode_sw"}, + {"id": "edge309", + "label": {"text": "next"}, + "sourceNodeId": "323_no-opt dfinit", + "targetNodeId": "*stack_ptr_mod_0x101f8050"}, + {"id": "edge310", + "label": {"text": "next"}, + "sourceNodeId": "322_subreg3", + "targetNodeId": "323_no-opt dfinit"}, + {"id": "edge311", + "label": {"text": "next"}, + "sourceNodeId": "321_split1", + "targetNodeId": "322_subreg3"}, + {"id": "edge312", + "label": {"text": "next"}, + "sourceNodeId": "320_outof_cfglayout", + "targetNodeId": "321_split1"}, + {"id": "edge313", + "label": {"text": "next"}, + "sourceNodeId": "319_bbpart", + "targetNodeId": "320_outof_cfglayout"}, + {"id": "edge314", + "label": {"text": "next"}, + "sourceNodeId": "318_jump_after_combine", + "targetNodeId": "319_bbpart"}, + {"id": "edge315", + "label": {"text": "next"}, + "sourceNodeId": "317_ce2", + "targetNodeId": "318_jump_after_combine"}, + {"id": "edge316", + "label": {"text": "next"}, + "sourceNodeId": "316_stv", + "targetNodeId": "317_ce2"}, + {"id": "edge317", + "label": {"text": "next"}, + "sourceNodeId": "315_rrvl", + "targetNodeId": "316_stv"}, + {"id": "edge318", + "label": {"text": "next"}, + "sourceNodeId": "314_rpad", + "targetNodeId": "315_rrvl"}, + {"id": "edge319", + "label": {"text": "next"}, + "sourceNodeId": "313_late_combine", + "targetNodeId": "314_rpad"}, + {"id": "edge320", + "label": {"text": "next"}, + "sourceNodeId": "312_combine", + "targetNodeId": "313_late_combine"}, + {"id": "edge321", + "label": {"text": "next"}, + "sourceNodeId": "311_ext_dce", + "targetNodeId": "312_combine"}, + {"id": "edge322", + "label": {"text": "next"}, + "sourceNodeId": "310_ud_dce", + "targetNodeId": "311_ext_dce"}, + {"id": "edge323", + "label": {"text": "next"}, + "sourceNodeId": "309_init-regs", + "targetNodeId": "310_ud_dce"}, + {"id": "edge324", + "label": {"text": "next"}, + "sourceNodeId": "308_auto_inc_dec", + "targetNodeId": "309_init-regs"}, + {"id": "edge325", + "label": {"text": "next"}, + "sourceNodeId": "307_fwprop2", + "targetNodeId": "308_auto_inc_dec"}, + {"id": "edge326", + "label": {"text": "next"}, + "sourceNodeId": "306_dse1", + "targetNodeId": "307_fwprop2"}, + {"id": "edge327", + "label": {"text": "next"}, + "sourceNodeId": "305_cse2", + "targetNodeId": "306_dse1"}, + {"id": "edge328", + "label": {"text": "next"}, + "sourceNodeId": "304_stv", + "targetNodeId": "305_cse2"}, + {"id": "edge329", + "label": {"text": "next"}, + "sourceNodeId": "303_cprop", + "targetNodeId": "304_stv"}, + {"id": "edge330", + "label": {"text": "next"}, + "sourceNodeId": "302_web", + "targetNodeId": "303_cprop"}, + {"id": "edge331", + "label": {"text": "next"}, + "sourceNodeId": "301_subreg2", + "targetNodeId": "302_web"}, + {"id": "edge332", + "label": {"text": "next"}, + "sourceNodeId": "295_loop2", + "targetNodeId": "301_subreg2"}, + {"id": "edge333", + "label": {"text": "next"}, + "sourceNodeId": "294_reginfo", + "targetNodeId": "295_loop2"}, + {"id": "edge334", + "label": {"text": "next"}, + "sourceNodeId": "293_apx_nfcvt", + "targetNodeId": "294_reginfo"}, + {"id": "edge335", + "label": {"text": "next"}, + "sourceNodeId": "292_ce1", + "targetNodeId": "293_apx_nfcvt"}, + {"id": "edge336", + "label": {"text": "next"}, + "sourceNodeId": "291_cse_local", + "targetNodeId": "292_ce1"}, + {"id": "edge337", + "label": {"text": "next"}, + "sourceNodeId": "290_store_motion", + "targetNodeId": "291_cse_local"}, + {"id": "edge338", + "label": {"text": "next"}, + "sourceNodeId": "289_cprop", + "targetNodeId": "290_store_motion"}, + {"id": "edge339", + "label": {"text": "next"}, + "sourceNodeId": "288_hardreg_pre", + "targetNodeId": "289_cprop"}, + {"id": "edge340", + "label": {"text": "next"}, + "sourceNodeId": "287_hoist", + "targetNodeId": "288_hardreg_pre"}, + {"id": "edge341", + "label": {"text": "next"}, + "sourceNodeId": "286_rtl pre", + "targetNodeId": "287_hoist"}, + {"id": "edge342", + "label": {"text": "next"}, + "sourceNodeId": "285_cprop", + "targetNodeId": "286_rtl pre"}, + {"id": "edge343", + "label": {"text": "next"}, + "sourceNodeId": "284_fwprop1", + "targetNodeId": "285_cprop"}, + {"id": "edge344", + "label": {"text": "next"}, + "sourceNodeId": "283_cse1", + "targetNodeId": "284_fwprop1"}, + {"id": "edge345", + "label": {"text": "next"}, + "sourceNodeId": "282_dfinit", + "targetNodeId": "283_cse1"}, + {"id": "edge346", + "label": {"text": "next"}, + "sourceNodeId": "281_subreg1", + "targetNodeId": "282_dfinit"}, + {"id": "edge347", + "label": {"text": "next"}, + "sourceNodeId": "280_jump", + "targetNodeId": "281_subreg1"}, + {"id": "edge348", + "label": {"text": "next"}, + "sourceNodeId": "279_into_cfglayout", + "targetNodeId": "280_jump"}, + {"id": "edge349", + "label": {"text": "next"}, + "sourceNodeId": "278_vregs", + "targetNodeId": "279_into_cfglayout"}, + {"id": "edge350", + "label": {"text": "sub"}, + "sourceNodeId": "*rest_of_compilation_0x101f6e90", + "targetNodeId": "278_vregs"}, + {"id": "edge351", + "label": {"text": "next"}, + "sourceNodeId": "*rest_of_compilation_0x101f6e90", + "targetNodeId": "*clean_state_0x101f9500"}, + {"id": "edge352", + "label": {"text": "next"}, + "sourceNodeId": "277_expand", + "targetNodeId": "*rest_of_compilation_0x101f6e90"}, + {"id": "edge353", + "label": {"text": "next"}, + "sourceNodeId": "*warn_function_noreturn_0x101f6dd0", + "targetNodeId": "277_expand"}, + {"id": "edge354", + "label": {"text": "next"}, + "sourceNodeId": "276_optimized", + "targetNodeId": "*warn_function_noreturn_0x101f6dd0"}, + {"id": "edge355", + "label": {"text": "next"}, + "sourceNodeId": "275_waccess", + "targetNodeId": "276_optimized"}, + {"id": "edge356", + "label": {"text": "next"}, + "sourceNodeId": "274_hardcmp", + "targetNodeId": "275_waccess"}, + {"id": "edge357", + "label": {"text": "next"}, + "sourceNodeId": "273_hardcbr", + "targetNodeId": "274_hardcmp"}, + {"id": "edge358", + "label": {"text": "next"}, + "sourceNodeId": "272_isel", + "targetNodeId": "273_hardcbr"}, + {"id": "edge359", + "label": {"text": "next"}, + "sourceNodeId": "271_nrv", + "targetNodeId": "272_isel"}, + {"id": "edge360", + "label": {"text": "next"}, + "sourceNodeId": "270_resx", + "targetNodeId": "271_nrv"}, + {"id": "edge361", + "label": {"text": "next"}, + "sourceNodeId": "269_ehcleanup", + "targetNodeId": "270_resx"}, + {"id": "edge362", + "label": {"text": "next"}, + "sourceNodeId": "268_sanopt", + "targetNodeId": "269_ehcleanup"}, + {"id": "edge363", + "label": {"text": "next"}, + "sourceNodeId": "267_musttail", + "targetNodeId": "268_sanopt"}, + {"id": "edge364", + "label": {"text": "next"}, + "sourceNodeId": "266_tsan0", + "targetNodeId": "267_musttail"}, + {"id": "edge365", + "label": {"text": "next"}, + "sourceNodeId": "265_asan0", + "targetNodeId": "266_tsan0"}, + {"id": "edge366", + "label": {"text": "next"}, + "sourceNodeId": "264_switchlower_O0", + "targetNodeId": "265_asan0"}, + {"id": "edge367", + "label": {"text": "next"}, + "sourceNodeId": "263_sancov_O0", + "targetNodeId": "264_switchlower_O0"}, + {"id": "edge368", + "label": {"text": "next"}, + "sourceNodeId": "262_bitintlower0", + "targetNodeId": "263_sancov_O0"}, + {"id": "edge369", + "label": {"text": "next"}, + "sourceNodeId": "261_cplxlower0", + "targetNodeId": "262_bitintlower0"}, + {"id": "edge370", + "label": {"text": "next"}, + "sourceNodeId": "260_veclower", + "targetNodeId": "261_cplxlower0"}, + {"id": "edge371", + "label": {"text": "next"}, + "sourceNodeId": "259_lower_vaarg", + "targetNodeId": "260_veclower"}, + {"id": "edge372", + "label": {"text": "next"}, + "sourceNodeId": "258_vtable-verify", + "targetNodeId": "259_lower_vaarg"}, + {"id": "edge373", + "label": {"text": "next"}, + "sourceNodeId": "257_simduid", + "targetNodeId": "258_vtable-verify"}, + {"id": "edge374", + "label": {"text": "next"}, + "sourceNodeId": "*tminit_0x101f6370", + "targetNodeId": "257_simduid"}, + {"id": "edge375", + "label": {"text": "next"}, + "sourceNodeId": "253_assumptions", + "targetNodeId": "*tminit_0x101f6370"}, + {"id": "edge376", + "label": {"text": "next"}, + "sourceNodeId": "*all_optimizations_g_0x101f5af0", + "targetNodeId": "253_assumptions"}, + {"id": "edge377", + "label": {"text": "next"}, + "sourceNodeId": "*all_optimizations_0x101f2720", + "targetNodeId": "*all_optimizations_g_0x101f5af0"}, + {"id": "edge378", + "label": {"text": "next"}, + "sourceNodeId": "114_hardcfr", + "targetNodeId": "*all_optimizations_0x101f2720"}, + {"id": "edge379", + "label": {"text": "next"}, + "sourceNodeId": "113_adjust_alignment", + "targetNodeId": "114_hardcfr"}, + {"id": "edge380", + "label": {"text": "next"}, + "sourceNodeId": "112_omptargetlink", + "targetNodeId": "113_adjust_alignment"}, + {"id": "edge381", + "label": {"text": "next"}, + "sourceNodeId": "111_ompdevlow", + "targetNodeId": "112_omptargetlink"}, + {"id": "edge382", + "label": {"text": "next"}, + "sourceNodeId": "110_oaccdevlow", + "targetNodeId": "111_ompdevlow"}, + {"id": "edge383", + "label": {"text": "next"}, + "sourceNodeId": "109_omp_oacc_neuter_broadcast", + "targetNodeId": "110_oaccdevlow"}, + {"id": "edge384", + "label": {"text": "next"}, + "sourceNodeId": "108_oaccloops", + "targetNodeId": "109_omp_oacc_neuter_broadcast"}, + {"id": "edge385", + "label": {"text": "next"}, + "sourceNodeId": "107_ehdisp", + "targetNodeId": "108_oaccloops"}, + {"id": "edge386", + "label": {"text": "next"}, + "sourceNodeId": "106_fixup_cfg", + "targetNodeId": "107_ehdisp"}]}]}]} + +/* { dg-begin-multiline-output "" } +In function 'test_graphs': +/home/david/gcc-newgit-gcc16/src/gcc/testsuite/gcc.dg/plugin/diagnostic-test-graphs-sarif.c:8:3: error: this is a placeholder error, with graphs + { dg-end-multiline-output "" } */ + +/* Use a Python script to verify various properties about the generated + .html file: + { dg-final { run-html-pytest graphs.sarif "2.1.0-valid/graphs-check-html.py" } } */ + +/* Use a Python script to verify various properties about the *generated* + .sarif file: + { dg-final { run-sarif-pytest graphs.roundtrip "2.1.0-valid/graphs-check-sarif-roundtrip.py" } } */ diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1-check-html.py b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1-check-html.py new file mode 100644 index 000000000000..a0978da048b6 --- /dev/null +++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1-check-html.py @@ -0,0 +1,26 @@ +from htmltest import * + +import pytest + +@pytest.fixture(scope='function', autouse=True) +def html_tree(): + return html_tree_from_env() + +def test_generated_html(html_tree): + root = html_tree.getroot () + assert root.tag == make_tag('html') + + head = root.find('xhtml:head', ns) + assert head is not None + + title = head.find('xhtml:title', ns) + assert title.text == '../../src/gcc/testsuite/gcc.dg/analyzer/signal-1.c' + + diag = get_diag_by_index(html_tree, 0) + + msg = get_message_within_diag(diag) + assert msg is not None + + assert_tag(msg[0], 'strong') + assert msg[0].text == 'warning: ' + assert msg[0].tail == " call to ‘fprintf’ from within signal handler " diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1-check-sarif-roundtrip.py b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1-check-sarif-roundtrip.py new file mode 100644 index 000000000000..ea93b039e8f4 --- /dev/null +++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1-check-sarif-roundtrip.py @@ -0,0 +1,41 @@ +from sarif import * + +import pytest + +@pytest.fixture(scope='function', autouse=True) +def sarif(): + return sarif_from_env() + +def test_basics(sarif): + schema = sarif['$schema'] + assert schema == "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json" + + version = sarif['version'] + assert version == "2.1.0" + +def test_execution_successful(sarif): + runs = sarif['runs'] + run = runs[0] + + invocations = run['invocations'] + assert len(invocations) == 1 + invocation = invocations[0] + + assert invocation['executionSuccessful'] == True + +def test_warning(sarif): + result = get_result_by_index(sarif, 0) + + assert result['level'] == 'warning' + + # TODO: this should be "-Wanalyzer-unsafe-call-within-signal-handler" and have a URL + assert result['ruleId'] == 'warning' + + # TODO: check code flow + events = result["codeFlows"][0]["threadFlows"][0]['locations'] + + # Event "(1)": "entry to 'main'" (index == 0) + assert events[0]['location']['message']['text'] == "entry to ‘main’" + + # Final event: + assert events[-1]['location']['message']['text'].startswith("call to ‘fprintf’ from within signal handler") diff --git a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1.c.sarif b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1.c.sarif index 54fa0b83f1d8..3b88af95f93b 100644 --- a/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1.c.sarif +++ b/gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1.c.sarif @@ -2,6 +2,8 @@ The dg directives were stripped out from the generated .sarif to avoid confusing DejaGnu for this test. */ +/* { dg-additional-options "-fdiagnostics-add-output=experimental-html:file=signal-1.c.sarif.html,javascript=no" } */ +/* { dg-additional-options "-fdiagnostics-add-output=sarif:file=signal-1.c.roundtrip.sarif" } */ {"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", "version": "2.1.0", @@ -211,3 +213,11 @@ In function 'custom_logger': | | (7) call to ‘fprintf’ from within signal handler | { dg-end-multiline-output "" } */ + +/* Use a Python script to verify various properties about the generated + .html file: + { dg-final { run-html-pytest signal-1.c.sarif "2.1.0-valid/signal-1-check-html.py" } } */ + +/* Use a Python script to verify various properties about the *generated* + .sarif file: + { dg-final { run-sarif-pytest signal-1.c.roundtrip "2.1.0-valid/signal-1-check-sarif-roundtrip.py" } } */ diff --git a/gcc/text-art/widget.cc b/gcc/text-art/widget.cc index 3c68018c3b54..5d3e5178484c 100644 --- a/gcc/text-art/widget.cc +++ b/gcc/text-art/widget.cc @@ -199,6 +199,15 @@ test_wrapper_widget () "BBB\n")); } +static void +test_empty_wrapper_widget () +{ + style_manager sm; + wrapper_widget w (nullptr); + canvas c (w.to_canvas (sm)); + ASSERT_CANVAS_STREQ (c, false, ""); +} + static void test_vbox_1 () { @@ -263,6 +272,7 @@ text_art_widget_cc_tests () test_test_widget (); test_text_widget (); test_wrapper_widget (); + test_empty_wrapper_widget (); test_vbox_1 (); test_vbox_2 (); test_canvas_widget (); diff --git a/gcc/text-art/widget.h b/gcc/text-art/widget.h index 55655ebfd62a..ab7b1d3c4ecc 100644 --- a/gcc/text-art/widget.h +++ b/gcc/text-art/widget.h @@ -146,15 +146,20 @@ class wrapper_widget : public widget } canvas::size_t calc_req_size () override { - return m_child->get_req_size (); + if (m_child) + return m_child->get_req_size (); + else + return canvas::size_t (0,0); } void update_child_alloc_rects () override { - m_child->set_alloc_rect (get_alloc_rect ()); + if (m_child) + m_child->set_alloc_rect (get_alloc_rect ()); } void paint_to_canvas (canvas &canvas) override { - m_child->paint_to_canvas (canvas); + if (m_child) + m_child->paint_to_canvas (canvas); } private: std::unique_ptr m_child; diff --git a/gcc/timevar.def b/gcc/timevar.def index 02ace466da59..4f60f04baa11 100644 --- a/gcc/timevar.def +++ b/gcc/timevar.def @@ -101,6 +101,7 @@ DEFTIMEVAR (TV_WHOPR_LTRANS , "whopr ltrans") DEFTIMEVAR (TV_IPA_REFERENCE , "ipa reference") DEFTIMEVAR (TV_IPA_PROFILE , "ipa profile") DEFTIMEVAR (TV_IPA_AUTOFDO , "auto profile") +DEFTIMEVAR (TV_IPA_AUTOFDO_OFFLINE , "auto profile offline") DEFTIMEVAR (TV_IPA_PURE_CONST , "ipa pure const") DEFTIMEVAR (TV_IPA_ICF , "ipa icf") DEFTIMEVAR (TV_IPA_PTA , "ipa points-to") diff --git a/gcc/toplev.cc b/gcc/toplev.cc index 7e457b5168b4..931466ca6324 100644 --- a/gcc/toplev.cc +++ b/gcc/toplev.cc @@ -1029,7 +1029,7 @@ internal_error_reentered (diagnostic_context *, const char *, va_list *) static void internal_error_function (diagnostic_context *, const char *, va_list *) { - global_dc->m_internal_error = internal_error_reentered; + global_dc->set_internal_error_callback (internal_error_reentered); warn_if_plugins (); emergency_dump_function (); } @@ -1091,7 +1091,7 @@ general_init (const char *argv0, bool init_signals, unique_argv original_argv) = global_options_init.x_flag_show_column; global_dc->set_show_highlight_colors (global_options_init.x_flag_diagnostics_show_highlight_colors); - global_dc->m_internal_error = internal_error_function; + global_dc->set_internal_error_callback (internal_error_function); const unsigned lang_mask = lang_hooks.option_lang_mask (); global_dc->set_option_manager (std::make_unique (*global_dc, @@ -1289,7 +1289,7 @@ process_options () /* Avoid any informative notes in the second run of -fcompare-debug. */ if (flag_compare_debug) - diagnostic_inhibit_notes (global_dc); + global_dc->inhibit_notes (); if (flag_section_anchors && !target_supports_section_anchors_p ()) { @@ -1815,6 +1815,10 @@ backend_init_target (void) static void backend_init (void) { +#if CHECKING_P + verify_reg_names_in_constraints (); +#endif + init_emit_once (); init_rtlanal (); diff --git a/gcc/tree-call-cdce.cc b/gcc/tree-call-cdce.cc index 9ca5fda5126d..3edea754ee4d 100644 --- a/gcc/tree-call-cdce.cc +++ b/gcc/tree-call-cdce.cc @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "builtins.h" #include "internal-fn.h" #include "tree-dfa.h" +#include "tree-eh.h" /* This pass serves two closely-related purposes: @@ -296,8 +297,12 @@ can_test_argument_range (gcall *call) /* Trig functions. */ CASE_FLT_FN (BUILT_IN_ACOS): CASE_FLT_FN_FLOATN_NX (BUILT_IN_ACOS): + CASE_FLT_FN (BUILT_IN_ACOSPI): + CASE_FLT_FN_FLOATN_NX (BUILT_IN_ACOSPI): CASE_FLT_FN (BUILT_IN_ASIN): CASE_FLT_FN_FLOATN_NX (BUILT_IN_ASIN): + CASE_FLT_FN (BUILT_IN_ASINPI): + CASE_FLT_FN_FLOATN_NX (BUILT_IN_ASINPI): /* Hyperbolic functions. */ CASE_FLT_FN (BUILT_IN_ACOSH): CASE_FLT_FN_FLOATN_NX (BUILT_IN_ACOSH): @@ -351,15 +356,21 @@ edom_only_function (gcall *call) { CASE_FLT_FN (BUILT_IN_ACOS): CASE_FLT_FN_FLOATN_NX (BUILT_IN_ACOS): + CASE_FLT_FN (BUILT_IN_ACOSPI): + CASE_FLT_FN_FLOATN_NX (BUILT_IN_ACOSPI): CASE_FLT_FN (BUILT_IN_ASIN): CASE_FLT_FN_FLOATN_NX (BUILT_IN_ASIN): - CASE_FLT_FN (BUILT_IN_ATAN): - CASE_FLT_FN_FLOATN_NX (BUILT_IN_ATAN): + CASE_FLT_FN (BUILT_IN_ASINPI): + CASE_FLT_FN_FLOATN_NX (BUILT_IN_ASINPI): CASE_FLT_FN (BUILT_IN_COS): CASE_FLT_FN_FLOATN_NX (BUILT_IN_COS): + CASE_FLT_FN (BUILT_IN_COSPI): + CASE_FLT_FN_FLOATN_NX (BUILT_IN_COSPI): CASE_FLT_FN (BUILT_IN_SIGNIFICAND): CASE_FLT_FN (BUILT_IN_SIN): CASE_FLT_FN_FLOATN_NX (BUILT_IN_SIN): + CASE_FLT_FN (BUILT_IN_SINPI): + CASE_FLT_FN_FLOATN_NX (BUILT_IN_SINPI): CASE_FLT_FN (BUILT_IN_SQRT): CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT): CASE_FLT_FN (BUILT_IN_FMOD): @@ -694,8 +705,12 @@ get_no_error_domain (enum built_in_function fnc) /* Trig functions: return [-1, +1] */ CASE_FLT_FN (BUILT_IN_ACOS): CASE_FLT_FN_FLOATN_NX (BUILT_IN_ACOS): + CASE_FLT_FN (BUILT_IN_ACOSPI): + CASE_FLT_FN_FLOATN_NX (BUILT_IN_ACOSPI): CASE_FLT_FN (BUILT_IN_ASIN): CASE_FLT_FN_FLOATN_NX (BUILT_IN_ASIN): + CASE_FLT_FN (BUILT_IN_ASINPI): + CASE_FLT_FN_FLOATN_NX (BUILT_IN_ASINPI): return get_domain (-1, true, true, 1, true, true); /* Hyperbolic functions. */ @@ -1208,8 +1223,20 @@ use_internal_fn (gcall *call) { /* Skip the call if LHS == LHS. If we reach here, EDOM is the only valid errno value and it is used iff the result is NaN. */ - conds.quick_push (gimple_build_cond (EQ_EXPR, lhs, lhs, - NULL_TREE, NULL_TREE)); + /* In the case of non call exceptions, with signaling NaNs, EQ_EXPR + can throw an exception and that can't be part of the GIMPLE_COND. */ + if (flag_exceptions + && cfun->can_throw_non_call_exceptions + && operation_could_trap_p (EQ_EXPR, true, false, NULL_TREE)) + { + tree b = make_ssa_name (boolean_type_node); + conds.quick_push (gimple_build_assign (b, EQ_EXPR, lhs, lhs)); + conds.quick_push (gimple_build_cond (NE_EXPR, b, boolean_false_node, + NULL_TREE, NULL_TREE)); + } + else + conds.quick_push (gimple_build_cond (EQ_EXPR, lhs, lhs, + NULL_TREE, NULL_TREE)); nconds++; /* Try replacing the original call with a direct assignment to diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index b342b147716a..275fc436d135 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -114,43 +114,6 @@ struct replace_decls_d tree to_context; }; -/* Hash table to store last discriminator assigned for each locus. */ -struct locus_discrim_map -{ - int location_line; - int discriminator; -}; - -/* Hashtable helpers. */ - -struct locus_discrim_hasher : free_ptr_hash -{ - static inline hashval_t hash (const locus_discrim_map *); - static inline bool equal (const locus_discrim_map *, - const locus_discrim_map *); -}; - -/* Trivial hash function for a location_t. ITEM is a pointer to - a hash table entry that maps a location_t to a discriminator. */ - -inline hashval_t -locus_discrim_hasher::hash (const locus_discrim_map *item) -{ - return item->location_line; -} - -/* Equality function for the locus-to-discriminator map. A and B - point to the two hash table entries to compare. */ - -inline bool -locus_discrim_hasher::equal (const locus_discrim_map *a, - const locus_discrim_map *b) -{ - return a->location_line == b->location_line; -} - -static hash_table *discriminator_per_locus; - /* Basic blocks and flowgraphs. */ static void make_blocks (gimple_seq); @@ -168,7 +131,6 @@ static edge gimple_try_redirect_by_replacing_jump (edge, basic_block); static inline bool stmt_starts_bb_p (gimple *, gimple *); static bool gimple_verify_flow_info (void); static void gimple_make_forwarder_block (edge); -static gimple *first_non_label_nondebug_stmt (basic_block); static bool verify_gimple_transaction (gtransaction *); static bool call_can_make_abnormal_goto (gimple *); @@ -247,12 +209,9 @@ build_gimple_cfg (gimple_seq seq) group_case_labels (); /* Create the edges of the flowgraph. */ - discriminator_per_locus = new hash_table (13); make_edges (); assign_discriminators (); cleanup_dead_labels (); - delete discriminator_per_locus; - discriminator_per_locus = NULL; } /* Look for ANNOTATE calls with loop annotation kind in BB; if found, remove @@ -1120,77 +1079,41 @@ gimple_find_sub_bbs (gimple_seq seq, gimple_stmt_iterator *gsi) return true; } -/* Find the next available discriminator value for LOCUS. The - discriminator distinguishes among several basic blocks that - share a common locus, allowing for more accurate sample-based - profiling. */ - -static int -next_discriminator_for_locus (int line) +/* Auto-profile needs discriminator to distinguish statements with same line + number (file name is ignored) which are in different basic block. This + map keeps track of current discriminator for a given line number. */ +struct discrim_entry { - struct locus_discrim_map item; - struct locus_discrim_map **slot; - - item.location_line = line; - item.discriminator = 0; - slot = discriminator_per_locus->find_slot_with_hash (&item, line, INSERT); - gcc_assert (slot); - if (*slot == HTAB_EMPTY_ENTRY) - { - *slot = XNEW (struct locus_discrim_map); - gcc_assert (*slot); - (*slot)->location_line = line; - (*slot)->discriminator = 0; - } - (*slot)->discriminator++; - return (*slot)->discriminator; -} - -/* Return TRUE if LOCUS1 and LOCUS2 refer to the same source line. */ - -static bool -same_line_p (location_t locus1, expanded_location *from, location_t locus2) -{ - expanded_location to; - - if (locus1 == locus2) - return true; - - to = expand_location (locus2); - - if (from->line != to.line) - return false; - if (from->file == to.file) - return true; - return (from->file != NULL - && to.file != NULL - && filename_cmp (from->file, to.file) == 0); -} + /* ID of basic block we saw line number last time. */ + unsigned int bb_id; + /* Discriminator we used. */ + unsigned int discrim; +}; -/* Assign a unique discriminator value to all statements in block bb that - have the same line number as locus. */ +/* Return updated LOC with discriminator for use in basic block BB_ID. + MAP keeps track of current values. */ -static void -assign_discriminator (location_t locus, basic_block bb) +location_t +assign_discriminator (location_t loc, unsigned int bb_id, + hash_map, discrim_entry> &map) { - gimple_stmt_iterator gsi; - int discriminator; - - if (locus == UNKNOWN_LOCATION) - return; - - expanded_location locus_e = expand_location (locus); - - discriminator = next_discriminator_for_locus (locus_e.line); - - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + bool existed; + discrim_entry &e = map.get_or_insert (LOCATION_LINE (loc), &existed); + gcc_checking_assert (!has_discriminator (loc)); + if (!existed) { - gimple *stmt = gsi_stmt (gsi); - location_t stmt_locus = gimple_location (stmt); - if (same_line_p (locus, &locus_e, stmt_locus)) - gimple_set_location (stmt, - location_with_discriminator (stmt_locus, discriminator)); + e.bb_id = bb_id; + e.discrim = 0; + return loc; + } + if (e.bb_id != bb_id) + { + e.bb_id = bb_id; + e.discrim++; } + if (e.discrim) + return location_with_discriminator (loc, e.discrim); + return loc; } /* Assign discriminators to statement locations. */ @@ -1198,92 +1121,54 @@ assign_discriminator (location_t locus, basic_block bb) static void assign_discriminators (void) { + hash_map, discrim_entry> map (13); + unsigned int bb_id = 0; basic_block bb; - FOR_EACH_BB_FN (bb, cfun) { - edge e; - edge_iterator ei; - gimple_stmt_iterator gsi; - location_t curr_locus = UNKNOWN_LOCATION; - expanded_location curr_locus_e = {}; - int curr_discr = 0; - + location_t prev_loc = UNKNOWN_LOCATION, prev_replacement = UNKNOWN_LOCATION; /* Traverse the basic block, if two function calls within a basic block are mapped to the same line, assign a new discriminator because a call stmt could be a split point of a basic block. */ - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + for (gimple_stmt_iterator gsi = gsi_start_bb (bb); + !gsi_end_p (gsi); gsi_next (&gsi)) { gimple *stmt = gsi_stmt (gsi); - - /* Don't allow debug stmts to affect discriminators, but - allow them to take discriminators when they're on the - same line as the preceding nondebug stmt. */ - if (is_gimple_debug (stmt)) - { - if (curr_locus != UNKNOWN_LOCATION - && same_line_p (curr_locus, &curr_locus_e, - gimple_location (stmt))) - { - location_t loc = gimple_location (stmt); - location_t dloc = location_with_discriminator (loc, - curr_discr); - gimple_set_location (stmt, dloc); - } - continue; - } - if (curr_locus == UNKNOWN_LOCATION) - { - curr_locus = gimple_location (stmt); - curr_locus_e = expand_location (curr_locus); - } - else if (!same_line_p (curr_locus, &curr_locus_e, gimple_location (stmt))) - { - curr_locus = gimple_location (stmt); - curr_locus_e = expand_location (curr_locus); - curr_discr = 0; - } - else if (curr_discr != 0) + location_t loc = gimple_location (stmt); + if (loc == UNKNOWN_LOCATION) + continue; + if (loc == prev_loc) + gimple_set_location (stmt, prev_replacement); + else { - location_t loc = gimple_location (stmt); - location_t dloc = location_with_discriminator (loc, curr_discr); - gimple_set_location (stmt, dloc); + prev_loc = loc; + prev_replacement = assign_discriminator (loc, bb_id, map); + gimple_set_location (stmt, prev_replacement); } - /* Allocate a new discriminator for CALL stmt. */ + /* Break basic blocks after each call. This is requires so each + call site has unque discriminator. + More correctly, we can break after each statement that can possibly + terinate execution of the basic block, but for auto-profile this + precision is probably not useful. */ if (gimple_code (stmt) == GIMPLE_CALL) - curr_discr = next_discriminator_for_locus (curr_locus_e.line); - } - - gimple *last = last_nondebug_stmt (bb); - location_t locus = last ? gimple_location (last) : UNKNOWN_LOCATION; - if (locus == UNKNOWN_LOCATION) - continue; - - expanded_location locus_e = expand_location (locus); - - FOR_EACH_EDGE (e, ei, bb->succs) - { - gimple *first = first_non_label_nondebug_stmt (e->dest); - gimple *last = last_nondebug_stmt (e->dest); - - gimple *stmt_on_same_line = NULL; - if (first && same_line_p (locus, &locus_e, - gimple_location (first))) - stmt_on_same_line = first; - else if (last && same_line_p (locus, &locus_e, - gimple_location (last))) - stmt_on_same_line = last; - - if (stmt_on_same_line) { - if (has_discriminator (gimple_location (stmt_on_same_line)) - && !has_discriminator (locus)) - assign_discriminator (locus, bb); - else - assign_discriminator (locus, e->dest); + prev_loc = UNKNOWN_LOCATION; + bb_id++; } } + /* IF basic block has multiple sucessors, consdier every edge as a separate + block. */ + if (!single_succ_p (bb)) + bb_id++; + for (edge e : bb->succs) + if (e->goto_locus != UNKNOWN_LOCATION) + { + e->goto_locus = assign_discriminator (e->goto_locus, bb_id, map); + bb_id++; + } + bb_id++; } + } /* Create the edges for a GIMPLE_COND starting at block BB. */ @@ -2948,16 +2833,6 @@ first_stmt (basic_block bb) return stmt; } -/* Return the first non-label/non-debug statement in basic block BB. */ - -static gimple * -first_non_label_nondebug_stmt (basic_block bb) -{ - gimple_stmt_iterator i; - i = gsi_start_nondebug_after_labels_bb (bb); - return !gsi_end_p (i) ? gsi_stmt (i) : NULL; -} - /* Return the last statement in basic block BB. */ gimple * @@ -4623,6 +4498,14 @@ verify_gimple_assign_single (gassign *stmt) return true; } + /* LHS can't be a constant or an address expression. */ + if (CONSTANT_CLASS_P (lhs)|| TREE_CODE (lhs) == ADDR_EXPR) + { + error ("invalid LHS (%qs) for assignment: %qs", + get_tree_code_name (TREE_CODE (lhs)), code_name); + return true; + } + if (gimple_clobber_p (stmt) && !(DECL_P (lhs) || TREE_CODE (lhs) == MEM_REF)) { @@ -4745,6 +4628,11 @@ verify_gimple_assign_single (gassign *stmt) if (CONSTRUCTOR_NELTS (rhs1) == 0) return res; + if (!is_gimple_reg (lhs)) + { + error ("non-register as LHS with vector constructor"); + return true; + } /* For vector CONSTRUCTORs we require that either it is empty CONSTRUCTOR, or it is a CONSTRUCTOR of smaller vector elements (then the element count must be correct to cover the whole @@ -5757,6 +5645,12 @@ gimple_verify_flow_info (void) error ("probability of edge from entry block not initialized"); err = true; } + if (!EXIT_BLOCK_PTR_FOR_FN (cfun) + ->count.compatible_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count)) + { + error ("exit block count is not compatible with entry block count"); + err = true; + } FOR_EACH_BB_FN (bb, cfun) @@ -5780,6 +5674,12 @@ gimple_verify_flow_info (void) err = true; } } + if (!bb->count.compatible_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count)) + { + error ("count of bb %d is not compatible with entry block count", + bb->index); + err = true; + } /* Skip labels on the start of basic block. */ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) @@ -8327,7 +8227,7 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags) fprintf (file, ", "); tree name = get_attribute_name (chain); - print_generic_expr (file, name, dump_flags); + print_generic_expr (file, name, flags); if (TREE_VALUE (chain) != NULL_TREE) { fprintf (file, " ("); @@ -8338,13 +8238,13 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags) "omp declare variant base")) { tree a = TREE_VALUE (chain); - print_generic_expr (file, TREE_PURPOSE (a), dump_flags); + print_generic_expr (file, TREE_PURPOSE (a), flags); fprintf (file, " match "); print_omp_context_selector (file, TREE_VALUE (a), - dump_flags); + flags); } else - print_generic_expr (file, TREE_VALUE (chain), dump_flags); + print_generic_expr (file, TREE_VALUE (chain), flags); fprintf (file, ")"); } } @@ -8366,7 +8266,7 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags) } print_generic_expr (file, TREE_TYPE (TREE_TYPE (fndecl)), - dump_flags | TDF_SLIM); + flags | TDF_SLIM); fprintf (file, " __GIMPLE (%s", (fun->curr_properties & PROP_ssa) ? "ssa" : (fun->curr_properties & PROP_cfg) ? "cfg" @@ -8379,7 +8279,7 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags) fprintf (file, ",%s(%" PRIu64 ")", profile_quality_as_string (bb->count.quality ()), bb->count.value ()); - if (dump_flags & TDF_UID) + if (flags & TDF_UID) fprintf (file, ")\n%sD_%u (", function_name (fun), DECL_UID (fndecl)); else @@ -8388,8 +8288,8 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags) } else { - print_generic_expr (file, TREE_TYPE (fntype), dump_flags); - if (dump_flags & TDF_UID) + print_generic_expr (file, TREE_TYPE (fntype), flags); + if (flags & TDF_UID) fprintf (file, " %sD.%u %s(", function_name (fun), DECL_UID (fndecl), tmclone ? "[tm-clone] " : ""); else @@ -8400,9 +8300,9 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags) arg = DECL_ARGUMENTS (fndecl); while (arg) { - print_generic_expr (file, TREE_TYPE (arg), dump_flags); + print_generic_expr (file, TREE_TYPE (arg), flags); fprintf (file, " "); - print_generic_expr (file, arg, dump_flags); + print_generic_expr (file, arg, flags); if (DECL_CHAIN (arg)) fprintf (file, ", "); arg = DECL_CHAIN (arg); @@ -9949,6 +9849,8 @@ do_warn_unused_result (gimple_seq seq) break; if (gimple_call_internal_p (g)) break; + if (warning_suppressed_p (g, OPT_Wunused_result)) + break; /* This is a naked call, as opposed to a GIMPLE_CALL with an LHS. All calls whose value is ignored should be diff --git a/gcc/tree-diagnostic-client-data-hooks.cc b/gcc/tree-diagnostic-client-data-hooks.cc index 06a089425f00..84bd4b53fe76 100644 --- a/gcc/tree-diagnostic-client-data-hooks.cc +++ b/gcc/tree-diagnostic-client-data-hooks.cc @@ -155,7 +155,7 @@ class compiler_data_hooks : public diagnostic_client_data_hooks stderr. Implement this by cleaning up the global timer instance now. */ delete g_timer; - g_timer = NULL; + g_timer = nullptr; } } diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index a4d59954c059..8cc81ebcf5e9 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -2538,6 +2538,13 @@ operation_could_trap_helper_p (enum tree_code op, /* Constructing an object cannot trap. */ return false; + case FIX_TRUNC_EXPR: + case VEC_PACK_FIX_TRUNC_EXPR: + case VEC_UNPACK_FIX_TRUNC_HI_EXPR: + case VEC_UNPACK_FIX_TRUNC_LO_EXPR: + /* The FIX_TRUNC family are always potentially trapping. */ + return flag_trapping_math; + case COND_EXPR: case VEC_COND_EXPR: /* Whether *COND_EXPR can trap depends on whether the diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc index 636361e7c360..ba25c19c50ce 100644 --- a/gcc/tree-if-conv.cc +++ b/gcc/tree-if-conv.cc @@ -494,6 +494,10 @@ fold_or_predicates (location_t loc, tree c1, tree c2) static tree fold_build_cond_expr (tree type, tree cond, tree rhs, tree lhs) { + /* Short cut the case where both rhs and lhs are the same. */ + if (operand_equal_p (rhs, lhs)) + return rhs; + /* If COND is comparison r != 0 and r has boolean type, convert COND to SSA_NAME to accept by vect bool pattern. */ if (TREE_CODE (cond) == NE_EXPR) @@ -2110,6 +2114,187 @@ gen_phi_arg_condition (gphi *phi, ifcvt_arg_entry_t &arg, return cond; } +/* Find the operand which is different between ARG0_OP and ARG1_OP. + Returns the operand num where the difference is. + Set NEWARG0 and NEWARG1 from the different argument. + Returns -1 if none is found. + If ARG0_OP/ARG1_OP is commutative also try swapping the + two commutative operands and return the operand number where + the difference happens in ARG0_OP. */ + +static int +find_different_opnum (const gimple_match_op &arg0_op, + const gimple_match_op &arg1_op, + tree *new_arg0, tree *new_arg1) +{ + unsigned opnum = -1; + unsigned first; + first = first_commutative_argument (arg1_op.code, arg1_op.type); + for (unsigned i = 0; i < arg0_op.num_ops; i++) + { + if (!operand_equal_for_phi_arg_p (arg0_op.ops[i], + arg1_op.ops[i])) + { + /* Can handle only one non equal operand. */ + if (opnum != -1u) + { + /* Though if opnum is right before i and opnum is equal + to the first communtative argument, handle communtative + specially. */ + if (i == opnum + 1 && opnum == first) + goto commutative; + return -1; + } + opnum = i; + } + } + /* If all operands are equal only do this is there was single + operand. */ + if (opnum == -1u) + { + if (arg0_op.num_ops != 1) + return -1; + opnum = 0; + } + *new_arg0 = arg0_op.ops[opnum]; + *new_arg1 = arg1_op.ops[opnum]; + return opnum; + +/* Handle commutative operations. */ +commutative: + gcc_assert (first != -1u); + + /* Check the rest of the arguments to make sure they are the same. */ + for (unsigned i = first + 2; i < arg0_op.num_ops; i++) + if (!operand_equal_for_phi_arg_p (arg0_op.ops[i], + arg1_op.ops[i])) + return -1; + + /* If the arg0[first+1] and arg1[first] are the same + then the one which is different is arg0[first] and arg1[first+1] + return first since this is based on arg0. */ + if (operand_equal_for_phi_arg_p (arg0_op.ops[first + 1], + arg1_op.ops[first])) + { + *new_arg0 = arg0_op.ops[first]; + *new_arg1 = arg1_op.ops[first + 1]; + return first; + } + /* If the arg0[first] and arg1[first+1] are the same + then the one which is different is arg0[first+1] and arg1[first] + return first+1 since this is based on arg0. */ + if (operand_equal_for_phi_arg_p (arg0_op.ops[first], + arg1_op.ops[first + 1])) + { + *new_arg0 = arg0_op.ops[first + 1]; + *new_arg1 = arg1_op.ops[first]; + return first + 1; + } + return -1; +} + +/* Factors out an operation from *ARG0 and *ARG1 and + create the new statement at GSI. *RES is the + result of that new statement. Update *ARG0 and *ARG1 + and *RES to the new values if the factoring happened. + Loops until all of the factoring is completed. */ + +static void +factor_out_operators (tree *res, gimple_stmt_iterator *gsi, + tree *arg0, tree *arg1, gphi *phi) +{ + gimple_match_op arg0_op, arg1_op; + bool repeated = false; + +again: + if (TREE_CODE (*arg0) != SSA_NAME || TREE_CODE (*arg1) != SSA_NAME) + return; + + if (operand_equal_p (*arg0, *arg1)) + return; + + /* If either args have > 1 use, then this transformation actually + increases the number of expressions evaluated at runtime. */ + if (repeated + ? (!has_zero_uses (*arg0) || !has_zero_uses (*arg1)) + : (!has_single_use (*arg0) || !has_single_use (*arg1))) + return; + + gimple *arg0_def_stmt = SSA_NAME_DEF_STMT (*arg0); + if (!gimple_extract_op (arg0_def_stmt, &arg0_op)) + return; + + /* At this point there should be no ssa names occuring in abnormals. */ + gcc_assert (!arg0_op.operands_occurs_in_abnormal_phi ()); + + gimple *arg1_def_stmt = SSA_NAME_DEF_STMT (*arg1); + if (!gimple_extract_op (arg1_def_stmt, &arg1_op)) + return; + + /* At this point there should be no ssa names occuring in abnormals. */ + gcc_assert (!arg1_op.operands_occurs_in_abnormal_phi ()); + + /* No factoring can happen if the codes are different + or the number operands. */ + if (arg1_op.code != arg0_op.code + || arg1_op.num_ops != arg0_op.num_ops) + return; + + tree new_arg0, new_arg1; + int opnum = find_different_opnum (arg0_op, arg1_op, &new_arg0, &new_arg1); + if (opnum == -1) + return; + + if (!types_compatible_p (TREE_TYPE (new_arg0), TREE_TYPE (new_arg1))) + return; + tree new_res = make_ssa_name (TREE_TYPE (new_arg0), NULL); + + /* Create the operation stmt if possible and insert it. */ + + gimple_match_op new_op = arg0_op; + new_op.ops[opnum] = new_res; + gimple_seq seq = NULL; + tree result = *res; + result = maybe_push_res_to_seq (&new_op, &seq, result); + + /* If we can't create the new statement, release the temp name + and return back. */ + if (!result) + { + release_ssa_name (new_res); + return; + } + gsi_insert_seq_before (gsi, seq, GSI_CONTINUE_LINKING); + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "PHI "); + print_generic_expr (dump_file, gimple_phi_result (phi)); + fprintf (dump_file, + " changed to factor operation out from COND_EXPR.\n"); + fprintf (dump_file, "New stmt with OPERATION that defines "); + print_generic_expr (dump_file, result); + fprintf (dump_file, ".\n"); + } + + /* Remove the old operation(s) that has single use. */ + gimple_stmt_iterator gsi_for_def; + + gsi_for_def = gsi_for_stmt (arg0_def_stmt); + gsi_remove (&gsi_for_def, true); + release_defs (arg0_def_stmt); + gsi_for_def = gsi_for_stmt (arg1_def_stmt); + gsi_remove (&gsi_for_def, true); + release_defs (arg1_def_stmt); + + /* Update the arguments and try again. */ + *arg0 = new_arg0; + *arg1 = new_arg1; + *res = new_res; + repeated = true; + goto again; +} + /* Create the smallest nested conditional possible. On pre-order we record which conditionals are live, and on post-order rewrite the chain by removing already active conditions. @@ -2289,6 +2474,11 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi, bool loop_versioned) arg0 = gimple_phi_arg_def (phi, 0); arg1 = gimple_phi_arg_def (phi, 1); } + + /* Factor out operand if possible. This can only be done easily + for PHI with 2 elements. */ + factor_out_operators (&res, gsi, &arg0, &arg1, phi); + if (is_cond_scalar_reduction (phi, &reduc, arg0, arg1, &op0, &op1, false, &has_nop, &nop_reduc)) @@ -3004,12 +3194,10 @@ combine_blocks (class loop *loop, bool loop_versioned) /* Reset flow-sensitive info before predicating stmts or PHIs we might fold. */ - bool *predicated = XNEWVEC (bool, orig_loop_num_nodes); for (i = 0; i < orig_loop_num_nodes; i++) { bb = ifc_bbs[i]; - predicated[i] = is_predicated (bb); - if (predicated[i]) + if (is_predicated (bb)) { for (auto gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) @@ -3211,7 +3399,6 @@ combine_blocks (class loop *loop, bool loop_versioned) free (ifc_bbs); ifc_bbs = NULL; - free (predicated); } /* Version LOOP before if-converting it; the original loop diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc index 1a72e31b06cd..08e642178ba5 100644 --- a/gcc/tree-inline.cc +++ b/gcc/tree-inline.cc @@ -1460,10 +1460,7 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data) || OMP_CLAUSE_CODE (*tp) == OMP_CLAUSE_DEPEND)) { tree t = OMP_CLAUSE_DECL (*tp); - if (t - && TREE_CODE (t) == TREE_LIST - && TREE_PURPOSE (t) - && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) + if (t && OMP_ITERATOR_DECL_P (t)) { *walk_subtrees = 0; OMP_CLAUSE_DECL (*tp) = copy_node (t); @@ -2239,7 +2236,7 @@ copy_bb (copy_body_data *id, basic_block bb, } else if (nargs != 0) { - tree newlhs = create_tmp_reg_or_ssa_name (integer_type_node); + tree newlhs = make_ssa_name (integer_type_node); count = build_int_cst (integer_type_node, nargs); new_stmt = gimple_build_assign (gimple_call_lhs (stmt), PLUS_EXPR, newlhs, count); @@ -2888,11 +2885,9 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, profile_count count) profile_count::adjust_for_ipa_scaling (&num, &den); ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = - ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count.apply_scale (count, - ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count); + ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count.apply_scale (num, den); EXIT_BLOCK_PTR_FOR_FN (cfun)->count = - EXIT_BLOCK_PTR_FOR_FN (src_cfun)->count.apply_scale (count, - ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count); + EXIT_BLOCK_PTR_FOR_FN (src_cfun)->count.apply_scale (num, den); if (src_cfun->eh) init_eh_for_function (); @@ -3084,7 +3079,7 @@ copy_cfg_body (copy_body_data * id, /* Register specific tree functions. */ gimple_register_cfg_hooks (); - /* If we are inlining just region of the function, make sure to connect + /* If we are offlining region of the function, make sure to connect new entry to ENTRY_BLOCK_PTR_FOR_FN (cfun). Since new entry can be part of loop, we must compute frequency and probability of ENTRY_BLOCK_PTR_FOR_FN (cfun) based on the frequencies and @@ -3093,12 +3088,14 @@ copy_cfg_body (copy_body_data * id, { edge e; edge_iterator ei; - den = profile_count::zero (); + ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = profile_count::zero (); FOR_EACH_EDGE (e, ei, new_entry->preds) if (!e->src->aux) - den += e->count (); - ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = den; + ENTRY_BLOCK_PTR_FOR_FN (cfun)->count += e->count (); + /* Do not scale - the profile of offlined region should + remain unchanged. */ + num = den = profile_count::one (); } profile_count::adjust_for_ipa_scaling (&num, &den); @@ -4846,7 +4843,9 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id, goto egress; cg_edge = id->dst_node->get_edge (stmt); - gcc_checking_assert (cg_edge); + /* Edge should exist and speculations should be resolved at this + stage. */ + gcc_checking_assert (cg_edge && !cg_edge->speculative); /* First, see if we can figure out what function is being called. If we cannot, then there is no hope of inlining the function. */ if (cg_edge->indirect_unknown_callee) @@ -5014,6 +5013,9 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id, loc = LOCATION_LOCUS (DECL_SOURCE_LOCATION (fn)); if (loc == UNKNOWN_LOCATION) loc = BUILTINS_LOCATION; + if (has_discriminator (gimple_location (stmt))) + loc = location_with_discriminator + (loc, get_discriminator_from_loc (gimple_location (stmt))); id->block = make_node (BLOCK); BLOCK_ABSTRACT_ORIGIN (id->block) = DECL_ORIGIN (fn); BLOCK_SOURCE_LOCATION (id->block) = loc; diff --git a/gcc/tree-logical-location.cc b/gcc/tree-logical-location.cc index 1b2702fdb8a0..1d0cc5803dd7 100644 --- a/gcc/tree-logical-location.cc +++ b/gcc/tree-logical-location.cc @@ -90,18 +90,18 @@ tree_logical_location_manager::get_kind (key k) const switch (TREE_CODE (node)) { default: - return LOGICAL_LOCATION_KIND_UNKNOWN; + return logical_location_kind::unknown; case FUNCTION_DECL: - return LOGICAL_LOCATION_KIND_FUNCTION; + return logical_location_kind::function; case PARM_DECL: - return LOGICAL_LOCATION_KIND_PARAMETER; + return logical_location_kind::parameter; case VAR_DECL: - return LOGICAL_LOCATION_KIND_VARIABLE; + return logical_location_kind::variable; case NAMESPACE_DECL: - return LOGICAL_LOCATION_KIND_NAMESPACE; + return logical_location_kind::namespace_; case RECORD_TYPE: - return LOGICAL_LOCATION_KIND_TYPE; + return logical_location_kind::type; } } diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc index f348673ae758..8545eff61a3e 100644 --- a/gcc/tree-object-size.cc +++ b/gcc/tree-object-size.cc @@ -464,6 +464,93 @@ compute_object_offset (tree expr, const_tree var) return size_binop (code, base, off); } +/* Return true if CONTAINER has a field of type INNER at OFFSET. */ + +static bool +inner_at_offset (tree container, tree inner, tree offset) +{ + gcc_assert (RECORD_OR_UNION_TYPE_P (container)); + + for (tree t = TYPE_FIELDS (container); t; t = DECL_CHAIN (t)) + { + if (TREE_CODE (t) != FIELD_DECL) + continue; + + /* Skip over fields at bit offsets that are not BITS_PER_UNIT aligned + to avoid an accidental truncated match with BYTE_POSITION below since + the address of such fields cannot be taken. */ + if (wi::bit_and (wi::to_offset (DECL_FIELD_BIT_OFFSET (t)), + BITS_PER_UNIT - 1) != 0) + continue; + + tree byte_offset = byte_position (t); + if (TREE_CODE (byte_offset) != INTEGER_CST + || tree_int_cst_lt (offset, byte_offset)) + return false; + + /* For an array, check the element type, otherwise the actual type. This + deliberately does not support the case of jumping from a pointer to + the middle of an array to its containing struct. */ + tree t_type = TREE_TYPE (t); + if (((TREE_CODE (t_type) == ARRAY_TYPE && TREE_TYPE (t_type) == inner) + || t_type == inner) + && tree_int_cst_equal (byte_offset, offset)) + return true; + + /* Nested structure or union, adjust the expected offset and dive in. */ + if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)) + && inner_at_offset (TREE_TYPE (t), inner, + fold_build2 (MINUS_EXPR, sizetype, offset, + byte_offset))) + return true; + } + + return false; +} + +/* For the input MEMREF of type MEMREF_TYPE, look for the presence of a field + of BASE_TYPE at OFFSET and return an adjusted WHOLESIZE if found. */ + +static tree +get_wholesize_for_memref (tree memref, tree wholesize) +{ + tree base = TREE_OPERAND (memref, 0); + tree offset = fold_convert (sizetype, TREE_OPERAND (memref, 1)); + tree memref_type = TREE_TYPE (memref); + tree base_type = TREE_TYPE (base); + + if (POINTER_TYPE_P (base_type)) + base_type = TREE_TYPE ((base_type)); + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "wholesize_for_memref: "); + print_generic_expr (dump_file, wholesize, dump_flags); + fprintf (dump_file, ", offset: "); + print_generic_expr (dump_file, offset, dump_flags); + fprintf (dump_file, "\n"); + } + + if (TREE_CODE (offset) != INTEGER_CST + || compare_tree_int (offset, offset_limit) < 0 + || !RECORD_OR_UNION_TYPE_P (memref_type)) + return wholesize; + + offset = fold_build1 (NEGATE_EXPR, sizetype, offset); + + if (inner_at_offset (memref_type, base_type, offset)) + wholesize = size_binop (PLUS_EXPR, wholesize, offset); + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, " new wholesize: "); + print_generic_expr (dump_file, wholesize, dump_flags); + fprintf (dump_file, "\n"); + } + + return wholesize; +} + /* Returns the size of the object designated by DECL considering its initializer if it either has one or if it would not affect its size, otherwise the size of the object without the initializer when MIN @@ -536,7 +623,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, { compute_builtin_object_size (TREE_OPERAND (pt_var, 0), object_size_type & ~OST_SUBOBJECT, &sz); - wholesize = sz; + wholesize = get_wholesize_for_memref (pt_var, sz); } else { @@ -548,6 +635,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, { sz = object_sizes_get (osi, SSA_NAME_VERSION (var)); wholesize = object_sizes_get (osi, SSA_NAME_VERSION (var), true); + wholesize = get_wholesize_for_memref (pt_var, wholesize); } else sz = wholesize = size_unknown (object_size_type); @@ -763,37 +851,32 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, /* Compute __builtin_object_size for a CALL to .ACCESS_WITH_SIZE, OBJECT_SIZE_TYPE is the second argument from __builtin_object_size. - The 2nd, 3rd, and the 4th parameters of the call determine the size of + + The 2nd, 3rd, and 4th parameters of the call determine the size of the CALL: 2nd argument REF_TO_SIZE: The reference to the size of the object, - 3rd argument CLASS_OF_SIZE: The size referenced by the REF_TO_SIZE represents - 0: the number of bytes; - 1: the number of the elements of the object type; - 4th argument TYPE_OF_SIZE: A constant 0 with its TYPE being the same as the TYPE - of the object referenced by REF_TO_SIZE - 6th argument: A constant 0 with the pointer TYPE to the original flexible - array type. - - The size of the element can be retrived from the TYPE of the 6th argument - of the call, which is the pointer to the array type. */ + 3rd argument TYPE_OF_SIZE + ACCESS_MODE: An integer constant with a pointer + TYPE. + The pointee TYPE of this pointer TYPE is the TYPE of the object referenced + by REF_TO_SIZE. + + 4th argument: The TYPE_SIZE_UNIT of the element TYPE of the array. */ + static tree access_with_size_object_size (const gcall *call, int object_size_type) { /* If not for dynamic object size, return. */ if ((object_size_type & OST_DYNAMIC) == 0) return size_unknown (object_size_type); - gcc_assert (gimple_call_internal_p (call, IFN_ACCESS_WITH_SIZE)); - /* The type of the 6th argument type is the pointer TYPE to the original - flexible array type. */ - tree pointer_to_array_type = TREE_TYPE (gimple_call_arg (call, 5)); - gcc_assert (POINTER_TYPE_P (pointer_to_array_type)); - tree element_type = TREE_TYPE (TREE_TYPE (pointer_to_array_type)); - tree element_size = TYPE_SIZE_UNIT (element_type); + tree ref_to_size = gimple_call_arg (call, 1); - unsigned int class_of_size = TREE_INT_CST_LOW (gimple_call_arg (call, 2)); - tree type = TREE_TYPE (gimple_call_arg (call, 3)); + tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (call, 2))); + + /* The 4th argument is the TYPE_SIZE_UNIT for the element of the original + flexible array. */ + tree element_size = gimple_call_arg (call, 3); tree size = fold_build2 (MEM_REF, type, ref_to_size, build_int_cst (ptr_type_node, 0)); @@ -807,12 +890,9 @@ access_with_size_object_size (const gcall *call, int object_size_type) build_zero_cst (type), size); } - if (class_of_size == 1) - size = size_binop (MULT_EXPR, - fold_convert (sizetype, size), - fold_convert (sizetype, element_size)); - else - size = fold_convert (sizetype, size); + size = size_binop (MULT_EXPR, + fold_convert (sizetype, size), + fold_convert (sizetype, element_size)); if (!todo) todo = TODO_update_ssa_only_virtuals; diff --git a/gcc/tree-outof-ssa.cc b/gcc/tree-outof-ssa.cc index bdf474dbd936..b71f32028dfe 100644 --- a/gcc/tree-outof-ssa.cc +++ b/gcc/tree-outof-ssa.cc @@ -1005,9 +1005,8 @@ get_undefined_value_partitions (var_map map) } /* Given the out-of-ssa info object SA (with prepared partitions) - eliminate all phi nodes in all basic blocks. Afterwards no - basic block will have phi nodes anymore and there are possibly - some RTL instructions inserted on edges. */ + eliminate all phi nodes in all basic blocks. Afterwards there + are possibly some RTL instructions inserted on edges. */ void expand_phi_nodes (struct ssaexpand *sa) @@ -1023,7 +1022,6 @@ expand_phi_nodes (struct ssaexpand *sa) edge_iterator ei; FOR_EACH_EDGE (e, ei, bb->preds) eliminate_phi (e, &g); - set_phi_nodes (bb, NULL); /* We can't redirect EH edges in RTL land, so we need to do this here. Redirection happens only when splitting is necessary, which it is only for critical edges, normally. For EH edges diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 4139f6d8eace..1c68a69350df 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -520,6 +520,8 @@ extern simple_ipa_opt_pass *make_pass_ipa_strub_mode (gcc::context *ctxt); extern simple_ipa_opt_pass *make_pass_ipa_strub (gcc::context *ctxt); extern simple_ipa_opt_pass *make_pass_ipa_tree_profile (gcc::context *ctxt); extern simple_ipa_opt_pass *make_pass_ipa_auto_profile (gcc::context *ctxt); +extern simple_ipa_opt_pass *make_pass_ipa_auto_profile_offline + (gcc::context *ctxt); extern simple_ipa_opt_pass *make_pass_build_ssa_passes (gcc::context *ctxt); extern simple_ipa_opt_pass *make_pass_local_optimization_passes (gcc::context *ctxt); diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc index fadafd6d24bc..50d08516746e 100644 --- a/gcc/tree-pretty-print.cc +++ b/gcc/tree-pretty-print.cc @@ -902,9 +902,7 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags) pp_string (pp, "affinity("); { tree t = OMP_CLAUSE_DECL (clause); - if (TREE_CODE (t) == TREE_LIST - && TREE_PURPOSE (t) - && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) + if (OMP_ITERATOR_DECL_P (t)) { dump_omp_iterators (pp, TREE_PURPOSE (t), spc, flags); pp_colon (pp); @@ -944,9 +942,7 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags) } { tree t = OMP_CLAUSE_DECL (clause); - if (TREE_CODE (t) == TREE_LIST - && TREE_PURPOSE (t) - && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) + if (OMP_ITERATOR_DECL_P (t)) { dump_omp_iterators (pp, TREE_PURPOSE (t), spc, flags); pp_colon (pp); diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc index fed218eb60bc..fe20e84838d8 100644 --- a/gcc/tree-profile.cc +++ b/gcc/tree-profile.cc @@ -2031,6 +2031,7 @@ tree_profiling (void) handle_missing_profiles (); del_node_map (); + end_branch_prob (); return 0; } @@ -2065,10 +2066,8 @@ class pass_ipa_tree_profile : public simple_ipa_opt_pass bool pass_ipa_tree_profile::gate (function *) { - /* When profile instrumentation, use or test coverage shall be performed. - But for AutoFDO, this there is no instrumentation, thus this pass is - disabled. */ - return (!in_lto_p && !flag_auto_profile + /* When profile instrumentation, use or test coverage shall be performed. */ + return (!in_lto_p && (flag_branch_probabilities || flag_test_coverage || coverage_instrumentation_p ()) && !seen_error ()); diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc index 43311e52f94c..413ca49cb926 100644 --- a/gcc/tree-scalar-evolution.cc +++ b/gcc/tree-scalar-evolution.cc @@ -3088,7 +3088,7 @@ iv_can_overflow_p (class loop *loop, tree type, tree base, tree step) type_max = wi::max_value (type); /* Just sanity check that we don't see values out of the range of the type. - In this case the arithmetics bellow would overflow. */ + In this case the arithmetics below would overflow. */ gcc_checking_assert (wi::ge_p (base_min, type_min, sgn) && wi::le_p (base_max, type_max, sgn)); diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc index 4b6daf772841..240af676ea33 100644 --- a/gcc/tree-sra.cc +++ b/gcc/tree-sra.cc @@ -2889,7 +2889,10 @@ analyze_access_subtree (struct access *root, struct access *parent, for (child = root->first_child; child; child = child->next_sibling) { - hole |= covered_to < child->offset; + if (totally) + covered_to = child->offset; + else + hole |= covered_to < child->offset; sth_created |= analyze_access_subtree (child, root, allow_replacements && !scalar && !root->grp_partial_lhs, @@ -2900,6 +2903,8 @@ analyze_access_subtree (struct access *root, struct access *parent, covered_to += child->size; else hole = true; + if (totally && !hole) + covered_to = limit; } if (allow_replacements && scalar && !root->first_child @@ -2972,7 +2977,7 @@ analyze_access_subtree (struct access *root, struct access *parent, root->grp_total_scalarization = 0; } - if (!hole || totally) + if (!hole) root->grp_covered = 1; else if (root->grp_write || comes_initialized_p (root->base)) root->grp_unscalarized_data = 1; /* not covered and written to */ @@ -3760,7 +3765,7 @@ sra_get_max_scalarization_size (void) /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>, fall back to a target default. */ unsigned HOST_WIDE_INT max_scalarization_size - = get_move_ratio (optimize_speed_p) * UNITS_PER_WORD; + = get_move_ratio (optimize_speed_p) * MOVE_MAX; if (optimize_speed_p) { diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc index 9dd1780867d4..41193432cc10 100644 --- a/gcc/tree-ssa-alias.cc +++ b/gcc/tree-ssa-alias.cc @@ -4376,7 +4376,7 @@ ao_compare::compare_ao_refs (ao_ref *ref1, ao_ref *ref2, i++; } - /* For variable accesses we can not rely on offset match bellow. + /* For variable accesses we can not rely on offset match below. We know that paths are struturally same, so only check that starts of TBAA paths did not diverge. */ if (!known_eq (ref1->size, ref1->max_size) diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc index 3e0c75cf2be8..f33cc042e9fb 100644 --- a/gcc/tree-ssa-ccp.cc +++ b/gcc/tree-ssa-ccp.cc @@ -2567,7 +2567,12 @@ insert_clobber_before_stack_restore (tree saved_val, tree var, { clobber = build_clobber (TREE_TYPE (var), CLOBBER_STORAGE_END); clobber_stmt = gimple_build_assign (var, clobber); - + /* Manually update the vdef/vuse here. */ + gimple_set_vuse (clobber_stmt, gimple_vuse (stmt)); + gimple_set_vdef (clobber_stmt, make_ssa_name (gimple_vop (cfun))); + gimple_set_vuse (stmt, gimple_vdef (clobber_stmt)); + SSA_NAME_DEF_STMT (gimple_vdef (clobber_stmt)) = clobber_stmt; + update_stmt (stmt); i = gsi_for_stmt (stmt); gsi_insert_before (&i, clobber_stmt, GSI_SAME_STMT); } @@ -3020,7 +3025,7 @@ do_ssa_ccp (bool nonzero_p) ccp_propagate.ssa_propagate (); if (ccp_finalize (nonzero_p || flag_ipa_bit_cp)) { - todo = (TODO_cleanup_cfg | TODO_update_ssa); + todo = TODO_cleanup_cfg; /* ccp_finalize does not preserve loop-closed ssa. */ loops_state_clear (LOOP_CLOSED_SSA); @@ -4624,17 +4629,24 @@ pass_post_ipa_warn::execute (function *fun) unsigned int idx = TREE_INT_CST_LOW (TREE_VALUE (args)) - 1; unsigned int idx2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args))) - 1; + unsigned int idx3 = idx2; + if (tree chain2 = TREE_CHAIN (TREE_CHAIN (args))) + idx3 = TREE_INT_CST_LOW (TREE_VALUE (chain2)) - 1; if (idx < gimple_call_num_args (stmt) - && idx2 < gimple_call_num_args (stmt)) + && idx2 < gimple_call_num_args (stmt) + && idx3 < gimple_call_num_args (stmt)) { tree arg = gimple_call_arg (stmt, idx); tree arg2 = gimple_call_arg (stmt, idx2); + tree arg3 = gimple_call_arg (stmt, idx3); if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE || !integer_zerop (arg) || !INTEGRAL_TYPE_P (TREE_TYPE (arg2)) + || !INTEGRAL_TYPE_P (TREE_TYPE (arg3)) || integer_zerop (arg2) + || integer_zerop (arg3) || ((TREE_CODE (fntype) == METHOD_TYPE || closure) - && (idx == 0 || idx2 == 0))) + && (idx == 0 || idx2 == 0 || idx3 == 0))) continue; if (!integer_nonzerop (arg2) && !tree_expr_nonzero_p (arg2)) @@ -4649,17 +4661,40 @@ pass_post_ipa_warn::execute (function *fun) if (range_includes_zero_p (vr)) continue; } + if (idx2 != idx3 + && !integer_nonzerop (arg3) + && !tree_expr_nonzero_p (arg3)) + { + if (TREE_CODE (arg3) != SSA_NAME || optimize < 2) + continue; + if (!ranger) + ranger = enable_ranger (cfun); + + int_range_max vr; + get_range_query (cfun)->range_of_expr (vr, arg3, stmt); + if (range_includes_zero_p (vr)) + continue; + } unsigned argno = idx + 1; unsigned argno2 = idx2 + 1; + unsigned argno3 = idx3 + 1; location_t loc = (EXPR_HAS_LOCATION (arg) ? EXPR_LOCATION (arg) : gimple_location (stmt)); auto_diagnostic_group d; - if (!warning_at (loc, OPT_Wnonnull, - "argument %u null where non-null " - "expected because argument %u is " - "nonzero", argno, argno2)) + if (idx2 != idx3) + { + if (!warning_at (loc, OPT_Wnonnull, + "argument %u null where non-null " + "expected because arguments %u and %u " + "are nonzero", argno, argno2, argno3)) + continue; + } + else if (!warning_at (loc, OPT_Wnonnull, + "argument %u null where non-null " + "expected because argument %u is " + "nonzero", argno, argno2)) continue; tree fndecl = gimple_call_fndecl (stmt); diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc index 5ac4280ee361..51a572316cdc 100644 --- a/gcc/tree-ssa-dse.cc +++ b/gcc/tree-ssa-dse.cc @@ -181,10 +181,10 @@ initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write, bool may_def_ok = false) can provide a may-def variant. */ if (may_def_ok) { - ao_ref_init_from_ptr_and_size ( - write, gimple_call_arg (stmt, 0), - TYPE_SIZE_UNIT ( - TREE_TYPE (gimple_call_arg (stmt, stored_value_index)))); + ao_ref_init_from_ptr_and_range ( + write, gimple_call_arg (stmt, 0), true, 0, -1, + tree_to_poly_int64 (TYPE_SIZE ( + TREE_TYPE (gimple_call_arg (stmt, stored_value_index))))); return true; } break; diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc index 27197bbc0769..43b1c9d696fd 100644 --- a/gcc/tree-ssa-forwprop.cc +++ b/gcc/tree-ssa-forwprop.cc @@ -2508,17 +2508,16 @@ simplify_rotate (gimple_stmt_iterator *gsi) } -/* Check whether an array contains a valid ctz table. */ +/* Check whether an array contains a valid table according to VALIDATE_FN. */ +template static bool -check_ctz_array (tree ctor, unsigned HOST_WIDE_INT mulc, - HOST_WIDE_INT &zero_val, unsigned shift, unsigned bits) +check_table_array (tree ctor, HOST_WIDE_INT &zero_val, unsigned bits, + ValidateFn validate_fn) { tree elt, idx; - unsigned HOST_WIDE_INT i, mask, raw_idx = 0; + unsigned HOST_WIDE_INT i, raw_idx = 0; unsigned matched = 0; - mask = ((HOST_WIDE_INT_1U << (bits - shift)) - 1) << shift; - zero_val = 0; FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, idx, elt) @@ -2558,7 +2557,7 @@ check_ctz_array (tree ctor, unsigned HOST_WIDE_INT mulc, matched++; } - if (val >= 0 && val < bits && (((mulc << val) & mask) >> shift) == index) + if (val >= 0 && val < bits && validate_fn (val, index)) matched++; if (matched > bits) @@ -2568,48 +2567,86 @@ check_ctz_array (tree ctor, unsigned HOST_WIDE_INT mulc, return false; } -/* Check whether a string contains a valid ctz table. */ +/* Check whether a string contains a valid table according to VALIDATE_FN. */ +template static bool -check_ctz_string (tree string, unsigned HOST_WIDE_INT mulc, - HOST_WIDE_INT &zero_val, unsigned shift, unsigned bits) +check_table_string (tree string, HOST_WIDE_INT &zero_val,unsigned bits, + ValidateFn validate_fn) { unsigned HOST_WIDE_INT len = TREE_STRING_LENGTH (string); - unsigned HOST_WIDE_INT mask; unsigned matched = 0; const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (string); if (len < bits || len > bits * 2) return false; - mask = ((HOST_WIDE_INT_1U << (bits - shift)) - 1) << shift; - zero_val = p[0]; for (unsigned i = 0; i < len; i++) - if (p[i] < bits && (((mulc << p[i]) & mask) >> shift) == i) + if (p[i] < bits && validate_fn (p[i], i)) matched++; return matched == bits; } -/* Recognize count trailing zeroes idiom. +/* Check whether CTOR contains a valid table according to VALIDATE_FN. */ +template +static bool +check_table (tree ctor, tree type, HOST_WIDE_INT &zero_val, unsigned bits, + ValidateFn validate_fn) +{ + if (TREE_CODE (ctor) == CONSTRUCTOR) + return check_table_array (ctor, zero_val, bits, validate_fn); + else if (TREE_CODE (ctor) == STRING_CST + && TYPE_PRECISION (type) == CHAR_TYPE_SIZE) + return check_table_string (ctor, zero_val, bits, validate_fn); + return false; +} + +/* Match.pd function to match the ctz expression. */ +extern bool gimple_ctz_table_index (tree, tree *, tree (*)(tree)); +extern bool gimple_clz_table_index (tree, tree *, tree (*)(tree)); + +/* Recognize count leading and trailing zeroes idioms. The canonical form is array[((x & -x) * C) >> SHIFT] where C is a magic constant which when multiplied by a power of 2 creates a unique value in the top 5 or 6 bits. This is then indexed into a table which maps it to the number of trailing zeroes. Array[0] is returned so the caller can emit an appropriate sequence depending on whether ctz (0) is defined on the target. */ + static bool -optimize_count_trailing_zeroes (tree array_ref, tree x, tree mulc, - tree tshift, HOST_WIDE_INT &zero_val) +simplify_count_zeroes (gimple_stmt_iterator *gsi) { - tree type = TREE_TYPE (array_ref); - tree array = TREE_OPERAND (array_ref, 0); + gimple *stmt = gsi_stmt (*gsi); + tree array_ref = gimple_assign_rhs1 (stmt); + tree res_ops[3]; - gcc_assert (TREE_CODE (mulc) == INTEGER_CST); - gcc_assert (TREE_CODE (tshift) == INTEGER_CST); + gcc_checking_assert (TREE_CODE (array_ref) == ARRAY_REF); - tree input_type = TREE_TYPE (x); + internal_fn fn = IFN_LAST; + /* For CTZ we recognize ((x & -x) * C) >> SHIFT where the array data + represents the number of trailing zeros. */ + if (gimple_ctz_table_index (TREE_OPERAND (array_ref, 1), &res_ops[0], NULL)) + fn = IFN_CTZ; + /* For CLZ we recognize + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + (x * C) >> SHIFT + where 31 minus the array data represents the number of leading zeros. */ + else if (gimple_clz_table_index (TREE_OPERAND (array_ref, 1), &res_ops[0], + NULL)) + fn = IFN_CLZ; + else + return false; + + HOST_WIDE_INT zero_val; + tree type = TREE_TYPE (array_ref); + tree array = TREE_OPERAND (array_ref, 0); + tree input_type = TREE_TYPE (res_ops[0]); unsigned input_bits = tree_to_shwi (TYPE_SIZE (input_type)); /* Check the array element type is not wider than 32 bits and the input is @@ -2619,7 +2656,7 @@ optimize_count_trailing_zeroes (tree array_ref, tree x, tree mulc, if (input_bits != 32 && input_bits != 64) return false; - if (!direct_internal_fn_supported_p (IFN_CTZ, input_type, OPTIMIZE_FOR_BOTH)) + if (!direct_internal_fn_supported_p (fn, input_type, OPTIMIZE_FOR_BOTH)) return false; /* Check the lower bound of the array is zero. */ @@ -2627,102 +2664,127 @@ optimize_count_trailing_zeroes (tree array_ref, tree x, tree mulc, if (!low || !integer_zerop (low)) return false; - unsigned shiftval = tree_to_shwi (tshift); - /* Check the shift extracts the top 5..7 bits. */ + unsigned shiftval = tree_to_shwi (res_ops[2]); if (shiftval < input_bits - 7 || shiftval > input_bits - 5) return false; tree ctor = ctor_for_folding (array); if (!ctor) return false; - - unsigned HOST_WIDE_INT val = tree_to_uhwi (mulc); - - if (TREE_CODE (ctor) == CONSTRUCTOR) - return check_ctz_array (ctor, val, zero_val, shiftval, input_bits); - - if (TREE_CODE (ctor) == STRING_CST - && TYPE_PRECISION (type) == CHAR_TYPE_SIZE) - return check_ctz_string (ctor, val, zero_val, shiftval, input_bits); - - return false; -} - -/* Match.pd function to match the ctz expression. */ -extern bool gimple_ctz_table_index (tree, tree *, tree (*)(tree)); - -static bool -simplify_count_trailing_zeroes (gimple_stmt_iterator *gsi) -{ - gimple *stmt = gsi_stmt (*gsi); - tree array_ref = gimple_assign_rhs1 (stmt); - tree res_ops[3]; - HOST_WIDE_INT zero_val; - - gcc_checking_assert (TREE_CODE (array_ref) == ARRAY_REF); - - if (!gimple_ctz_table_index (TREE_OPERAND (array_ref, 1), &res_ops[0], NULL)) - return false; - - if (optimize_count_trailing_zeroes (array_ref, res_ops[0], - res_ops[1], res_ops[2], zero_val)) + unsigned HOST_WIDE_INT mulval = tree_to_uhwi (res_ops[1]); + if (fn == IFN_CTZ) { - tree type = TREE_TYPE (res_ops[0]); - HOST_WIDE_INT ctz_val = 0; - HOST_WIDE_INT type_size = tree_to_shwi (TYPE_SIZE (type)); - bool zero_ok - = CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (type), ctz_val) == 2; - int nargs = 2; - - /* If the input value can't be zero, don't special case ctz (0). */ - if (tree_expr_nonzero_p (res_ops[0])) + auto checkfn = [&](unsigned data, unsigned i) -> bool { - zero_ok = true; - zero_val = 0; - ctz_val = 0; - nargs = 1; - } - - /* Skip if there is no value defined at zero, or if we can't easily - return the correct value for zero. */ - if (!zero_ok) + unsigned HOST_WIDE_INT mask + = ((HOST_WIDE_INT_1U << (input_bits - shiftval)) - 1) << shiftval; + return (((mulval << data) & mask) >> shiftval) == i; + }; + if (!check_table (ctor, type, zero_val, input_bits, checkfn)) return false; - if (zero_val != ctz_val && !(zero_val == 0 && ctz_val == type_size)) - return false; - - gimple_seq seq = NULL; - gimple *g; - gcall *call - = gimple_build_call_internal (IFN_CTZ, nargs, res_ops[0], - nargs == 1 ? NULL_TREE - : build_int_cst (integer_type_node, - ctz_val)); - gimple_set_location (call, gimple_location (stmt)); - gimple_set_lhs (call, make_ssa_name (integer_type_node)); - gimple_seq_add_stmt (&seq, call); - - tree prev_lhs = gimple_call_lhs (call); - - /* Emit ctz (x) & 31 if ctz (0) is 32 but we need to return 0. */ - if (zero_val == 0 && ctz_val == type_size) + } + else if (fn == IFN_CLZ) + { + auto checkfn = [&](unsigned data, unsigned i) -> bool { - g = gimple_build_assign (make_ssa_name (integer_type_node), - BIT_AND_EXPR, prev_lhs, - build_int_cst (integer_type_node, - type_size - 1)); - gimple_set_location (g, gimple_location (stmt)); - gimple_seq_add_stmt (&seq, g); - prev_lhs = gimple_assign_lhs (g); - } + unsigned HOST_WIDE_INT mask + = ((HOST_WIDE_INT_1U << (input_bits - shiftval)) - 1) << shiftval; + return (((((HOST_WIDE_INT_1U << (data + 1)) - 1) * mulval) & mask) + >> shiftval) == i; + }; + if (!check_table (ctor, type, zero_val, input_bits, checkfn)) + return false; + } + + HOST_WIDE_INT ctz_val = -1; + bool zero_ok; + if (fn == IFN_CTZ) + { + ctz_val = 0; + zero_ok = CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (input_type), + ctz_val) == 2; + } + else if (fn == IFN_CLZ) + { + ctz_val = 32; + zero_ok = CLZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (input_type), + ctz_val) == 2; + zero_val = input_bits - 1 - zero_val; + } + int nargs = 2; + + /* If the input value can't be zero, don't special case ctz (0). */ + range_query *q = get_range_query (cfun); + if (q == get_global_range_query ()) + q = enable_ranger (cfun); + int_range_max vr; + if (q->range_of_expr (vr, res_ops[0], stmt) + && !range_includes_zero_p (vr)) + { + zero_ok = true; + zero_val = 0; + ctz_val = 0; + nargs = 1; + } - g = gimple_build_assign (gimple_assign_lhs (stmt), NOP_EXPR, prev_lhs); + gimple_seq seq = NULL; + gimple *g; + gcall *call = gimple_build_call_internal (fn, nargs, res_ops[0], + nargs == 1 ? NULL_TREE + : build_int_cst (integer_type_node, + ctz_val)); + gimple_set_location (call, gimple_location (stmt)); + gimple_set_lhs (call, make_ssa_name (integer_type_node)); + gimple_seq_add_stmt (&seq, call); + + tree prev_lhs = gimple_call_lhs (call); + if (fn == IFN_CLZ) + { + g = gimple_build_assign (make_ssa_name (integer_type_node), + MINUS_EXPR, + build_int_cst (integer_type_node, + input_bits - 1), + prev_lhs); + gimple_set_location (g, gimple_location (stmt)); gimple_seq_add_stmt (&seq, g); - gsi_replace_with_seq (gsi, seq, true); - return true; + prev_lhs = gimple_assign_lhs (g); } - return false; + if (zero_ok && zero_val == ctz_val) + ; + /* Emit ctz (x) & 31 if ctz (0) is 32 but we need to return 0. */ + else if (zero_ok && zero_val == 0 && ctz_val == input_bits) + { + g = gimple_build_assign (make_ssa_name (integer_type_node), + BIT_AND_EXPR, prev_lhs, + build_int_cst (integer_type_node, + input_bits - 1)); + gimple_set_location (g, gimple_location (stmt)); + gimple_seq_add_stmt (&seq, g); + prev_lhs = gimple_assign_lhs (g); + } + /* As fallback emit a conditional move. */ + else + { + g = gimple_build_assign (make_ssa_name (boolean_type_node), EQ_EXPR, + res_ops[0], build_zero_cst (input_type)); + gimple_set_location (g, gimple_location (stmt)); + gimple_seq_add_stmt (&seq, g); + tree cond = gimple_assign_lhs (g); + g = gimple_build_assign (make_ssa_name (integer_type_node), + COND_EXPR, cond, + build_int_cst (integer_type_node, zero_val), + prev_lhs); + gimple_set_location (g, gimple_location (stmt)); + gimple_seq_add_stmt (&seq, g); + prev_lhs = gimple_assign_lhs (g); + } + + g = gimple_build_assign (gimple_assign_lhs (stmt), NOP_EXPR, prev_lhs); + gimple_seq_add_stmt (&seq, g); + gsi_replace_with_seq (gsi, seq, true); + return true; } @@ -4837,7 +4899,7 @@ pass_forwprop::execute (function *fun) && TREE_CODE (TREE_TYPE (rhs1)) == VECTOR_TYPE) changed |= simplify_vector_constructor (&gsi); else if (code == ARRAY_REF) - changed |= simplify_count_trailing_zeroes (&gsi); + changed |= simplify_count_zeroes (&gsi); break; } diff --git a/gcc/tree-ssa-live.cc b/gcc/tree-ssa-live.cc index 5b8bfd06bec1..5e0891361dc7 100644 --- a/gcc/tree-ssa-live.cc +++ b/gcc/tree-ssa-live.cc @@ -702,7 +702,10 @@ dump_scope_block (FILE *file, int indent, tree scope, dump_flags_t flags) if (LOCATION_LOCUS (BLOCK_SOURCE_LOCATION (scope)) != UNKNOWN_LOCATION) { expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (scope)); - fprintf (file, " %s:%i", s.file, s.line); + fprintf (file, " %s:%i:%i", s.file, s.line, s.column); + if (has_discriminator (BLOCK_SOURCE_LOCATION (scope))) + fprintf (file, " discrim %i", + get_discriminator_from_loc (BLOCK_SOURCE_LOCATION (scope))); } if (BLOCK_ABSTRACT_ORIGIN (scope)) { diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc index a2150818a43f..544a946ff890 100644 --- a/gcc/tree-ssa-loop-ivopts.cc +++ b/gcc/tree-ssa-loop-ivopts.cc @@ -2117,11 +2117,15 @@ idx_record_use (tree base, tree *idx, signedness of TOP and BOT. */ static bool -constant_multiple_of (tree top, tree bot, widest_int *mul) +constant_multiple_of (tree top, tree bot, widest_int *mul, + struct ivopts_data *data) { aff_tree aff_top, aff_bot; - tree_to_aff_combination (top, TREE_TYPE (top), &aff_top); - tree_to_aff_combination (bot, TREE_TYPE (bot), &aff_bot); + tree_to_aff_combination_expand (top, TREE_TYPE (top), &aff_top, + &data->name_expansion_cache); + tree_to_aff_combination_expand (bot, TREE_TYPE (bot), &aff_bot, + &data->name_expansion_cache); + poly_widest_int poly_mul; if (aff_combination_constant_multiple_p (&aff_top, &aff_bot, &poly_mul) && poly_mul.is_constant (mul)) @@ -3945,13 +3949,14 @@ determine_common_wider_type (tree *a, tree *b) } /* Determines the expression by that USE is expressed from induction variable - CAND at statement AT in LOOP. The expression is stored in two parts in a - decomposed form. The invariant part is stored in AFF_INV; while variant - part in AFF_VAR. Store ratio of CAND.step over USE.step in PRAT if it's - non-null. Returns false if USE cannot be expressed using CAND. */ + CAND at statement AT in DATA's current loop. The expression is stored in + two parts in a decomposed form. The invariant part is stored in AFF_INV; + while variant part in AFF_VAR. Store ratio of CAND.step over USE.step in + PRAT if it's non-null. Returns false if USE cannot be expressed using + CAND. */ static bool -get_computation_aff_1 (class loop *loop, gimple *at, struct iv_use *use, +get_computation_aff_1 (struct ivopts_data *data, gimple *at, struct iv_use *use, struct iv_cand *cand, class aff_tree *aff_inv, class aff_tree *aff_var, widest_int *prat = NULL) { @@ -3966,7 +3971,7 @@ get_computation_aff_1 (class loop *loop, gimple *at, struct iv_use *use, if (TYPE_PRECISION (utype) > TYPE_PRECISION (ctype)) return false; - var = var_at_stmt (loop, cand, at); + var = var_at_stmt (data->current_loop, cand, at); uutype = unsigned_type_for (utype); /* If the conversion is not noop, perform it. */ @@ -4011,7 +4016,7 @@ get_computation_aff_1 (class loop *loop, gimple *at, struct iv_use *use, gcc_assert (gimple_assign_lhs (use->stmt) == cand->var_after); rat = 1; } - else if (!constant_multiple_of (ustep, cstep, &rat)) + else if (!constant_multiple_of (ustep, cstep, &rat, data)) return false; if (prat) @@ -4030,7 +4035,7 @@ get_computation_aff_1 (class loop *loop, gimple *at, struct iv_use *use, tree_to_aff_combination (var, uutype, aff_var); /* We need to shift the value if we are after the increment. */ - if (stmt_after_increment (loop, cand, at)) + if (stmt_after_increment (data->current_loop, cand, at)) { aff_tree cstep_aff; @@ -4053,16 +4058,17 @@ get_computation_aff_1 (class loop *loop, gimple *at, struct iv_use *use, } /* Determines the expression by that USE is expressed from induction variable - CAND at statement AT in LOOP. The expression is stored in a decomposed - form into AFF. Returns false if USE cannot be expressed using CAND. */ + CAND at statement AT in DATA's current loop. The expression is stored in a + decomposed form into AFF. Returns false if USE cannot be expressed using + CAND. */ static bool -get_computation_aff (class loop *loop, gimple *at, struct iv_use *use, +get_computation_aff (struct ivopts_data *data, gimple *at, struct iv_use *use, struct iv_cand *cand, class aff_tree *aff) { aff_tree aff_var; - if (!get_computation_aff_1 (loop, at, use, cand, aff, &aff_var)) + if (!get_computation_aff_1 (data, at, use, cand, aff, &aff_var)) return false; aff_combination_add (aff, &aff_var); @@ -4092,16 +4098,17 @@ get_use_type (struct iv_use *use) } /* Determines the expression by that USE is expressed from induction variable - CAND at statement AT in LOOP. The computation is unshared. */ + CAND at statement AT in DATA's current loop. The computation is + unshared. */ static tree -get_computation_at (class loop *loop, gimple *at, +get_computation_at (struct ivopts_data *data, gimple *at, struct iv_use *use, struct iv_cand *cand) { aff_tree aff; tree type = get_use_type (use); - if (!get_computation_aff (loop, at, use, cand, &aff)) + if (!get_computation_aff (data, at, use, cand, &aff)) return NULL_TREE; unshare_aff_combination (&aff); return fold_convert (type, aff_combination_to_tree (&aff)); @@ -4111,10 +4118,10 @@ get_computation_at (class loop *loop, gimple *at, is more expensive. Intended for debug stmts. */ static tree -get_debug_computation_at (class loop *loop, gimple *at, +get_debug_computation_at (struct ivopts_data *data, gimple *at, struct iv_use *use, struct iv_cand *cand) { - if (tree ret = get_computation_at (loop, at, use, cand)) + if (tree ret = get_computation_at (data, at, use, cand)) return ret; tree ubase = use->iv->base, ustep = use->iv->step; @@ -4131,7 +4138,7 @@ get_debug_computation_at (class loop *loop, gimple *at, try to express use = ubase + (var - cbase) / ratio. */ if (!constant_multiple_of (cstep, fold_convert (TREE_TYPE (cstep), ustep), - &rat)) + &rat, data)) return NULL_TREE; bool neg_p = false; @@ -4160,7 +4167,7 @@ get_debug_computation_at (class loop *loop, gimple *at, && TYPE_PRECISION (utype) + bits > TYPE_PRECISION (ctype)) return NULL_TREE; - var = var_at_stmt (loop, cand, at); + var = var_at_stmt (data->current_loop, cand, at); if (POINTER_TYPE_P (ctype)) { @@ -4170,7 +4177,7 @@ get_debug_computation_at (class loop *loop, gimple *at, var = fold_convert (ctype, var); } - if (stmt_after_increment (loop, cand, at)) + if (stmt_after_increment (data->current_loop, cand, at)) var = fold_build2 (MINUS_EXPR, TREE_TYPE (var), var, unshare_expr (cstep)); @@ -4873,8 +4880,7 @@ get_computation_cost (struct ivopts_data *data, struct iv_use *use, return infinite_cost; } - if (!get_computation_aff_1 (data->current_loop, at, use, - cand, &aff_inv, &aff_var, &rat) + if (!get_computation_aff_1 (data, at, use, cand, &aff_inv, &aff_var, &rat) || !wi::fits_shwi_p (rat)) return infinite_cost; @@ -5015,8 +5021,6 @@ determine_group_iv_cost_address (struct ivopts_data *data, sum_cost = infinite_cost; } - /* Uses in a group can share setup code, so only add setup cost once. */ - cost -= cost.scratch; /* Compute and add costs for rest uses of this group. */ for (i = 1; i < group->vuses.length () && !sum_cost.infinite_cost_p (); i++) { @@ -5032,7 +5036,12 @@ determine_group_iv_cost_address (struct ivopts_data *data, if (!inv_exprs) inv_exprs = BITMAP_ALLOC (NULL); - bitmap_set_bit (inv_exprs, inv_expr->id); + /* Uses in a group can share setup code, + so only add setup cost once. */ + if (bitmap_bit_p (inv_exprs, inv_expr->id)) + cost -= cost.scratch; + else + bitmap_set_bit (inv_exprs, inv_expr->id); } sum_cost += cost; } @@ -7355,8 +7364,7 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data, } aff_tree aff_inv, aff_var; - if (!get_computation_aff_1 (data->current_loop, use->stmt, - use, cand, &aff_inv, &aff_var)) + if (!get_computation_aff_1 (data, use->stmt, use, cand, &aff_inv, &aff_var)) gcc_unreachable (); unshare_aff_combination (&aff_inv); @@ -7553,7 +7561,7 @@ rewrite_use_address (struct ivopts_data *data, bool ok; adjust_iv_update_pos (cand, use); - ok = get_computation_aff (data->current_loop, use->stmt, use, cand, &aff); + ok = get_computation_aff (data, use->stmt, use, cand, &aff); gcc_assert (ok); unshare_aff_combination (&aff); @@ -7656,7 +7664,7 @@ rewrite_use_compare (struct ivopts_data *data, /* The induction variable elimination failed; just express the original giv. */ - comp = get_computation_at (data->current_loop, use->stmt, use, cand); + comp = get_computation_at (data, use->stmt, use, cand); gcc_assert (comp != NULL_TREE); gcc_assert (use->op_p != NULL); *use->op_p = force_gimple_operand_gsi (&bsi, comp, true, @@ -7787,7 +7795,7 @@ remove_unused_ivs (struct ivopts_data *data, bitmap toremove) if (best_cand == NULL || best_pref < cand_pref) { tree this_comp - = get_debug_computation_at (data->current_loop, + = get_debug_computation_at (data, SSA_NAME_DEF_STMT (def), &dummy_use, cand); if (this_comp) diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc index 9ce881344142..6e1308625491 100644 --- a/gcc/tree-ssa-loop-niter.cc +++ b/gcc/tree-ssa-loop-niter.cc @@ -4701,7 +4701,7 @@ maybe_lower_iteration_bound (class loop *loop) TODO: Due to the way record_estimate choose estimates to store, the bounds will be always nb_iterations_upper_bound-1. We can change this to record - also statements not dominating the loop latch and update the walk bellow + also statements not dominating the loop latch and update the walk below to the shortest path algorithm. */ for (elt = loop->bounds; elt; elt = elt->next) { diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc index 7e819f37446c..ca98205d58f8 100644 --- a/gcc/tree-ssa-math-opts.cc +++ b/gcc/tree-ssa-math-opts.cc @@ -1053,6 +1053,7 @@ pass_cse_reciprocals::execute (function *fun) continue; gimple_replace_ssa_lhs (call, arg1); + reset_flow_sensitive_info (arg1); if (gimple_call_internal_p (call) != (ifn != IFN_LAST)) { auto_vec args; @@ -4063,6 +4064,7 @@ arith_overflow_check_p (gimple *stmt, gimple *cast_stmt, gimple *&use_stmt, extern bool gimple_unsigned_integer_sat_add (tree, tree*, tree (*)(tree)); extern bool gimple_unsigned_integer_sat_sub (tree, tree*, tree (*)(tree)); extern bool gimple_unsigned_integer_sat_trunc (tree, tree*, tree (*)(tree)); +extern bool gimple_unsigned_integer_sat_mul (tree, tree*, tree (*)(tree)); extern bool gimple_signed_integer_sat_add (tree, tree*, tree (*)(tree)); extern bool gimple_signed_integer_sat_sub (tree, tree*, tree (*)(tree)); @@ -4215,6 +4217,30 @@ match_unsigned_saturation_sub (gimple_stmt_iterator *gsi, gassign *stmt) ops[0], ops[1]); } +/* + * Try to match saturation unsigned mul. + * _1 = (unsigned int) a_6(D); + * _2 = (unsigned int) b_7(D); + * x_8 = _1 * _2; + * overflow_9 = x_8 > 255; + * _3 = (unsigned char) overflow_9; + * _4 = -_3; + * _5 = (unsigned char) x_8; + * _10 = _4 | _5; + * => + * _10 = .SAT_SUB (a_6, b_7); */ + +static void +match_unsigned_saturation_mul (gimple_stmt_iterator *gsi, gassign *stmt) +{ + tree ops[2]; + tree lhs = gimple_assign_lhs (stmt); + + if (gimple_unsigned_integer_sat_mul (lhs, ops, NULL)) + build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_MUL, lhs, + ops[0], ops[1]); +} + /* * Try to match saturation unsigned sub. * [local count: 1073741824]: @@ -6468,6 +6494,7 @@ math_opts_dom_walker::after_dom_children (basic_block bb) break; case NOP_EXPR: + match_unsigned_saturation_mul (&gsi, as_a (stmt)); match_unsigned_saturation_trunc (&gsi, as_a (stmt)); match_saturation_add_with_assign (&gsi, as_a (stmt)); break; diff --git a/gcc/tree-ssa-operands.cc b/gcc/tree-ssa-operands.cc index 4eb9673a0856..a5970ac7b717 100644 --- a/gcc/tree-ssa-operands.cc +++ b/gcc/tree-ssa-operands.cc @@ -721,7 +721,7 @@ operands_scanner::get_asm_stmt_operands (gasm *stmt) constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); oconstraints[i] = constraint; parse_output_constraint (&constraint, i, 0, 0, &allows_mem, - &allows_reg, &is_inout); + &allows_reg, &is_inout, nullptr); /* This should have been split in gimplify_asm_expr. */ gcc_assert (!allows_reg || !is_inout); @@ -740,7 +740,7 @@ operands_scanner::get_asm_stmt_operands (gasm *stmt) tree link = gimple_asm_input_op (stmt, i); constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints, - &allows_mem, &allows_reg); + &allows_mem, &allows_reg, nullptr); /* Memory operands are addressable. Note that STMT needs the address of this operand. */ diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc index bf493e129878..faecab6ab7aa 100644 --- a/gcc/tree-ssa-phiopt.cc +++ b/gcc/tree-ssa-phiopt.cc @@ -3605,7 +3605,8 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, static bool cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb, basic_block join_bb, gimple *then_assign, - gimple *else_assign) + gimple *else_assign, + gphi *vphi) { tree lhs_base, lhs, then_rhs, else_rhs, name; location_t then_locus, else_locus; @@ -3672,6 +3673,14 @@ cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb, add_phi_arg (newphi, else_rhs, EDGE_SUCC (else_bb, 0), else_locus); new_stmt = gimple_build_assign (lhs, gimple_phi_result (newphi)); + /* Update the vdef for the new store statement. */ + tree newvphilhs = make_ssa_name (gimple_vop (cfun)); + tree vdef = gimple_phi_result (vphi); + gimple_set_vuse (new_stmt, newvphilhs); + gimple_set_vdef (new_stmt, vdef); + gimple_phi_set_result (vphi, newvphilhs); + SSA_NAME_DEF_STMT (vdef) = new_stmt; + update_stmt (vphi); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf(dump_file, "to use phi:\n"); @@ -3699,10 +3708,11 @@ cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb, } /* Return the single store in BB with VDEF or NULL if there are - other stores in the BB or loads following the store. */ + other stores in the BB or loads following the store. VPHI is + where the only use of the vdef should be. */ static gimple * -single_trailing_store_in_bb (basic_block bb, tree vdef) +single_trailing_store_in_bb (basic_block bb, tree vdef, gphi *vphi) { if (SSA_NAME_IS_DEFAULT_DEF (vdef)) return NULL; @@ -3717,17 +3727,62 @@ single_trailing_store_in_bb (basic_block bb, tree vdef) && gimple_code (SSA_NAME_DEF_STMT (gimple_vuse (store))) != GIMPLE_PHI) return NULL; - /* Verify there is no load or store after the store. */ + /* Verify there is no load or store after the store, the vdef of the store + should only be used by the vphi joining the 2 bbs. */ use_operand_p use_p; - imm_use_iterator imm_iter; - FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_vdef (store)) - if (USE_STMT (use_p) != store - && gimple_bb (USE_STMT (use_p)) == bb) - return NULL; + gimple *use_stmt; + if (!single_imm_use (gimple_vdef (store), &use_p, &use_stmt)) + return NULL; + if (use_stmt != vphi) + return NULL; return store; } +/* Limited Conditional store replacement. We already know + that the recognized pattern looks like so: + + split: + if (cond) goto THEN_BB; else goto ELSE_BB (edge E1) + THEN_BB: + ... + ONLY_STORE = Y; + ... + goto JOIN_BB; + ELSE_BB: + ... + ONLY_STORE = Z; + ... + fallthrough (edge E0) + JOIN_BB: + some more + + Handles only the case with single store in THEN_BB and ELSE_BB. That is + cheap enough due to in phiopt and not worry about heurstics. Moving the store + out might provide an opportunity for a phiopt to happen. */ + +static bool +cond_if_else_store_replacement_limited (basic_block then_bb, basic_block else_bb, + basic_block join_bb) +{ + gphi *vphi = get_virtual_phi (join_bb); + if (!vphi) + return false; + + tree then_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (then_bb)); + gimple *then_assign = single_trailing_store_in_bb (then_bb, then_vdef, vphi); + if (!then_assign) + return false; + + tree else_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (else_bb)); + gimple *else_assign = single_trailing_store_in_bb (else_bb, else_vdef, vphi); + if (!else_assign) + return false; + + return cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb, + then_assign, else_assign, vphi); +} + /* Conditional store replacement. We already know that the recognized pattern looks like so: @@ -3764,25 +3819,20 @@ cond_if_else_store_replacement (basic_block then_bb, basic_block else_bb, /* Handle the case with single store in THEN_BB and ELSE_BB. That is cheap enough to always handle as it allows us to elide dependence checking. */ - gphi *vphi = NULL; - for (gphi_iterator si = gsi_start_phis (join_bb); !gsi_end_p (si); - gsi_next (&si)) - if (virtual_operand_p (gimple_phi_result (si.phi ()))) - { - vphi = si.phi (); - break; - } + gphi *vphi = get_virtual_phi (join_bb); if (!vphi) return false; tree then_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (then_bb)); - tree else_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (else_bb)); - gimple *then_assign = single_trailing_store_in_bb (then_bb, then_vdef); + gimple *then_assign = single_trailing_store_in_bb (then_bb, then_vdef, vphi); if (then_assign) { - gimple *else_assign = single_trailing_store_in_bb (else_bb, else_vdef); + tree else_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (else_bb)); + gimple *else_assign = single_trailing_store_in_bb (else_bb, else_vdef, + vphi); if (else_assign) return cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb, - then_assign, else_assign); + then_assign, else_assign, + vphi); } /* If either vectorization or if-conversion is disabled then do @@ -3921,7 +3971,7 @@ cond_if_else_store_replacement (basic_block then_bb, basic_block else_bb, then_store = store_pair.first; else_store = store_pair.second; res = cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb, - then_store, else_store); + then_store, else_store, vphi); ok = ok || res; } @@ -4456,6 +4506,11 @@ pass_phiopt::execute (function *) && !predictable_edge_p (EDGE_SUCC (bb, 0)) && !predictable_edge_p (EDGE_SUCC (bb, 1))) hoist_adjacent_loads (bb, bb1, bb2, bb3); + + /* Try to see if there are only one store in each side of the if + and try to remove that. */ + if (EDGE_COUNT (bb3->preds) == 2) + cond_if_else_store_replacement_limited (bb1, bb2, bb3); } gimple_stmt_iterator gsi; diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc index f6c531e4892d..99331730bc2e 100644 --- a/gcc/tree-ssa-pre.cc +++ b/gcc/tree-ssa-pre.cc @@ -2773,16 +2773,17 @@ find_or_generate_expression (basic_block block, tree op, gimple_seq *stmts) bitmap exprset = value_expressions[lookfor]; bitmap_iterator bi; unsigned int i; - EXECUTE_IF_SET_IN_BITMAP (exprset, 0, i, bi) - { - pre_expr temp = expression_for_id (i); - /* We cannot insert random REFERENCE expressions at arbitrary - places. We can insert NARYs which eventually re-materializes - its operand values. */ - if (temp->kind == NARY) - return create_expression_by_pieces (block, temp, stmts, - TREE_TYPE (op)); - } + if (exprset) + EXECUTE_IF_SET_IN_BITMAP (exprset, 0, i, bi) + { + pre_expr temp = expression_for_id (i); + /* We cannot insert random REFERENCE expressions at arbitrary + places. We can insert NARYs which eventually re-materializes + its operand values. */ + if (temp->kind == NARY) + return create_expression_by_pieces (block, temp, stmts, + TREE_TYPE (op)); + } /* Defer. */ return NULL_TREE; diff --git a/gcc/tree-ssa-propagate.h b/gcc/tree-ssa-propagate.h index 8429e38f40e4..200fc7320796 100644 --- a/gcc/tree-ssa-propagate.h +++ b/gcc/tree-ssa-propagate.h @@ -102,10 +102,10 @@ class substitute_and_fold_engine : public range_query substitute_and_fold_engine (bool fold_all_stmts = false) : fold_all_stmts (fold_all_stmts) { } - virtual tree value_of_expr (tree expr, gimple * = NULL) = 0; + virtual tree value_of_expr (tree expr, gimple * = NULL) override = 0; virtual tree value_on_edge (edge, tree expr) override; virtual tree value_of_stmt (gimple *, tree name = NULL) override; - virtual bool range_of_expr (vrange &r, tree expr, gimple * = NULL); + virtual bool range_of_expr (vrange &r, tree expr, gimple * = NULL) override; virtual ~substitute_and_fold_engine (void) { } virtual bool fold_stmt (gimple_stmt_iterator *) { return false; } diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc index f7f50c3de994..45fb79cd8a1f 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -1615,6 +1615,8 @@ fully_constant_vn_reference_p (vn_reference_t ref) ++i; break; } + if (operands[i].reverse) + return NULL_TREE; if (known_eq (operands[i].off, -1)) return NULL_TREE; off += operands[i].off; @@ -2807,7 +2809,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, we find a VN result with exactly the same value as the possible clobber. In this case we can ignore the clobber and return the found value. */ - if (is_gimple_reg_type (TREE_TYPE (lhs)) + if (!gimple_has_volatile_ops (def_stmt) + && is_gimple_reg_type (TREE_TYPE (lhs)) && types_compatible_p (TREE_TYPE (lhs), vr->type) && (ref->ref || data->orig_ref.ref) && !data->mask @@ -3091,7 +3094,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, else if (is_gimple_reg_type (vr->type) && gimple_assign_single_p (def_stmt) && gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR - && CONSTRUCTOR_NELTS (gimple_assign_rhs1 (def_stmt)) == 0) + && CONSTRUCTOR_NELTS (gimple_assign_rhs1 (def_stmt)) == 0 + && !TREE_THIS_VOLATILE (gimple_assign_lhs (def_stmt))) { tree base2; poly_int64 offset2, size2, maxsize2; @@ -3147,6 +3151,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, && !reverse_storage_order_for_component_p (vr->operands) && !contains_storage_order_barrier_p (vr->operands) && gimple_assign_single_p (def_stmt) + && !TREE_THIS_VOLATILE (gimple_assign_lhs (def_stmt)) && CHAR_BIT == 8 && BITS_PER_UNIT == 8 && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN @@ -3305,6 +3310,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, && !reverse_storage_order_for_component_p (vr->operands) && !contains_storage_order_barrier_p (vr->operands) && gimple_assign_single_p (def_stmt) + && !TREE_THIS_VOLATILE (gimple_assign_lhs (def_stmt)) && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME) { tree lhs = gimple_assign_lhs (def_stmt); @@ -3516,6 +3522,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, the copy kills ref. */ else if (data->vn_walk_kind == VN_WALKREWRITE && gimple_assign_single_p (def_stmt) + && !gimple_has_volatile_ops (def_stmt) && (DECL_P (gimple_assign_rhs1 (def_stmt)) || TREE_CODE (gimple_assign_rhs1 (def_stmt)) == MEM_REF || handled_component_p (gimple_assign_rhs1 (def_stmt)))) diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc index deca44ae0bf3..0035e50c62c7 100644 --- a/gcc/tree-ssa-structalias.cc +++ b/gcc/tree-ssa-structalias.cc @@ -48,6 +48,9 @@ #include "ipa-modref.h" #include "attr-fnspec.h" +#include "tree-ssa-structalias.h" +#include "pta-andersen.h" + /* The idea behind this analyzer is to generate set constraints from the program, then solve the resulting constraints in order to generate the points-to sets. @@ -201,2785 +204,513 @@ And probably more. */ -static bool use_field_sensitive = true; -static int in_ipa_mode = 0; - -/* Used for predecessor bitmaps. */ -static bitmap_obstack predbitmap_obstack; +namespace pointer_analysis { /* Used for points-to sets. */ -static bitmap_obstack pta_obstack; - -/* Used for oldsolution members of variables. */ -static bitmap_obstack oldpta_obstack; - -/* Used for per-solver-iteration bitmaps. */ -static bitmap_obstack iteration_obstack; - -static unsigned int create_variable_info_for (tree, const char *, bool); -typedef struct constraint_graph *constraint_graph_t; -static void unify_nodes (constraint_graph_t, unsigned int, unsigned int, bool); +bitmap_obstack pta_obstack; -struct constraint; -typedef struct constraint *constraint_t; +/* Used for oldsolution members of variables. */ +bitmap_obstack oldpta_obstack; +/* Table of variable info structures for constraint variables. + Indexed directly by variable info id. */ +vec varmap; -#define EXECUTE_IF_IN_NONNULL_BITMAP(a, b, c, d) \ - if (a) \ - EXECUTE_IF_SET_IN_BITMAP (a, b, c, d) - -static struct constraint_stats -{ - unsigned int total_vars; - unsigned int nonpointer_vars; - unsigned int unified_vars_static; - unsigned int unified_vars_dynamic; - unsigned int iterations; - unsigned int num_edges; - unsigned int num_implicit_edges; - unsigned int num_avoided_edges; - unsigned int points_to_sets_created; -} stats; - -struct variable_info -{ - /* ID of this variable */ - unsigned int id; - - /* True if this is a variable created by the constraint analysis, such as - heap variables and constraints we had to break up. */ - unsigned int is_artificial_var : 1; +/* List of constraints that we use to build the constraint graph from. */ +vec constraints; - /* True if this is a special variable whose solution set should not be - changed. */ - unsigned int is_special_var : 1; +/* Map from trees to variable infos. */ +static hash_map *vi_for_tree; - /* True for variables whose size is not known or variable. */ - unsigned int is_unknown_size_var : 1; +/* The representative variable for a variable. The points-to solution for a + var can be found in its rep. Trivially, a var can be its own rep. - /* True for (sub-)fields that represent a whole variable. */ - unsigned int is_full_var : 1; + The solver provides this array once it is done solving. */ +unsigned int *var_rep; - /* True if this is a heap variable. */ - unsigned int is_heap_var : 1; +struct constraint_stats stats; - /* True if this is a register variable. */ - unsigned int is_reg_var : 1; +/* Find the first varinfo in the same variable as START that overlaps with + OFFSET. Return NULL if we can't find one. */ - /* True if this field may contain pointers. */ - unsigned int may_have_pointers : 1; +varinfo_t +first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset) +{ + /* If the offset is outside of the variable, bail out. */ + if (offset >= start->fullsize) + return NULL; - /* True if this field has only restrict qualified pointers. */ - unsigned int only_restrict_pointers : 1; + /* If we cannot reach offset from start, lookup the first field + and start from there. */ + if (start->offset > offset) + start = get_varinfo (start->head); - /* True if this represents a heap var created for a restrict qualified - pointer. */ - unsigned int is_restrict_var : 1; + while (start) + { + /* We may not find a variable in the field list with the actual + offset when we have glommed a structure to a variable. + In that case, however, offset should still be within the size + of the variable. */ + if (offset >= start->offset + && (offset - start->offset) < start->size) + return start; - /* True if this represents a global variable. */ - unsigned int is_global_var : 1; + start = vi_next (start); + } - /* True if this represents a module escape point for IPA analysis. */ - unsigned int is_ipa_escape_point : 1; + return NULL; +} - /* True if this represents a IPA function info. */ - unsigned int is_fn_info : 1; +/* Find the first varinfo in the same variable as START that overlaps with + OFFSET. If there is no such varinfo the varinfo directly preceding + OFFSET is returned. */ - /* True if this appears as RHS in a ADDRESSOF constraint. */ - unsigned int address_taken : 1; +varinfo_t +first_or_preceding_vi_for_offset (varinfo_t start, + unsigned HOST_WIDE_INT offset) +{ + /* If we cannot reach offset from start, lookup the first field + and start from there. */ + if (start->offset > offset) + start = get_varinfo (start->head); - /* ??? Store somewhere better. */ - unsigned short ruid; + /* We may not find a variable in the field list with the actual + offset when we have glommed a structure to a variable. + In that case, however, offset should still be within the size + of the variable. + If we got beyond the offset we look for return the field + directly preceding offset which may be the last field. */ + while (start->next + && offset >= start->offset + && !((offset - start->offset) < start->size)) + start = vi_next (start); - /* The ID of the variable for the next field in this structure - or zero for the last field in this structure. */ - unsigned next; + return start; +} - /* The ID of the variable for the first field in this structure. */ - unsigned head; +/* Print out constraint C to FILE. */ - /* Offset of this variable, in bits, from the base variable */ - unsigned HOST_WIDE_INT offset; +void +dump_constraint (FILE *file, constraint_t c) +{ + if (c->lhs.type == ADDRESSOF) + fprintf (file, "&"); + else if (c->lhs.type == DEREF) + fprintf (file, "*"); + if (dump_file) + fprintf (file, "%s", get_varinfo (c->lhs.var)->name); + else + fprintf (file, "V%d", c->lhs.var); + if (c->lhs.offset == UNKNOWN_OFFSET) + fprintf (file, " + UNKNOWN"); + else if (c->lhs.offset != 0) + fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->lhs.offset); + fprintf (file, " = "); + if (c->rhs.type == ADDRESSOF) + fprintf (file, "&"); + else if (c->rhs.type == DEREF) + fprintf (file, "*"); + if (dump_file) + fprintf (file, "%s", get_varinfo (c->rhs.var)->name); + else + fprintf (file, "V%d", c->rhs.var); + if (c->rhs.offset == UNKNOWN_OFFSET) + fprintf (file, " + UNKNOWN"); + else if (c->rhs.offset != 0) + fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset); +} - /* Size of the variable, in bits. */ - unsigned HOST_WIDE_INT size; +/* Print out constraint C to stderr. */ - /* Full size of the base variable, in bits. */ - unsigned HOST_WIDE_INT fullsize; +DEBUG_FUNCTION void +debug_constraint (constraint_t c) +{ + dump_constraint (stderr, c); + fprintf (stderr, "\n"); +} - /* In IPA mode the shadow UID in case the variable needs to be duplicated in - the final points-to solution because it reaches its containing - function recursively. Zero if none is needed. */ - unsigned int shadow_var_uid; +/* Print out all constraints to FILE. */ - /* Name of this variable */ - const char *name; +void +dump_constraints (FILE *file, int from) +{ + int i; + constraint_t c; + for (i = from; constraints.iterate (i, &c); i++) + if (c) + { + dump_constraint (file, c); + fprintf (file, "\n"); + } +} - /* Tree that this variable is associated with. */ - tree decl; +/* Print out all constraints to stderr. */ - /* Points-to set for this variable. */ - bitmap solution; +DEBUG_FUNCTION void +debug_constraints (void) +{ + dump_constraints (stderr, 0); +} - /* Old points-to set for this variable. */ - bitmap oldsolution; -}; -typedef struct variable_info *varinfo_t; +/* Print out the points-to solution for VAR to FILE. */ -static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT); -static varinfo_t first_or_preceding_vi_for_offset (varinfo_t, - unsigned HOST_WIDE_INT); -static varinfo_t lookup_vi_for_tree (tree); -static inline bool type_can_have_subvars (const_tree); -static void make_param_constraints (varinfo_t); +void +dump_solution_for_var (FILE *file, unsigned int var) +{ + varinfo_t vi = get_varinfo (var); + unsigned int i; + bitmap_iterator bi; -/* Pool of variable info structures. */ -static object_allocator variable_info_pool - ("Variable info pool"); + /* Dump the solution for unified vars anyway, this avoids difficulties + in scanning dumps in the testsuite. */ + fprintf (file, "%s = { ", vi->name); + vi = get_varinfo (var_rep[var]); + EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi) + fprintf (file, "%s ", get_varinfo (i)->name); + fprintf (file, "}"); -/* Map varinfo to final pt_solution. */ -static hash_map *final_solutions; -struct obstack final_solutions_obstack; + /* But note when the variable was unified. */ + if (vi->id != var) + fprintf (file, " same as %s", vi->name); -/* Table of variable info structures for constraint variables. - Indexed directly by variable info id. */ -static vec varmap; + fprintf (file, "\n"); +} -/* Return the varmap element N */ +/* Print the points-to solution for VAR to stderr. */ -static inline varinfo_t -get_varinfo (unsigned int n) +DEBUG_FUNCTION void +debug_solution_for_var (unsigned int var) { - return varmap[n]; + dump_solution_for_var (stderr, var); } -/* Return the next variable in the list of sub-variables of VI - or NULL if VI is the last sub-variable. */ +/* Dump stats information to OUTFILE. */ -static inline varinfo_t -vi_next (varinfo_t vi) +void +dump_sa_stats (FILE *outfile) { - return get_varinfo (vi->next); + fprintf (outfile, "Points-to Stats:\n"); + fprintf (outfile, "Total vars: %d\n", stats.total_vars); + fprintf (outfile, "Non-pointer vars: %d\n", + stats.nonpointer_vars); + fprintf (outfile, "Statically unified vars: %d\n", + stats.unified_vars_static); + fprintf (outfile, "Dynamically unified vars: %d\n", + stats.unified_vars_dynamic); + fprintf (outfile, "Iterations: %d\n", stats.iterations); + fprintf (outfile, "Number of edges: %d\n", stats.num_edges); + fprintf (outfile, "Number of implicit edges: %d\n", + stats.num_implicit_edges); + fprintf (outfile, "Number of avoided edges: %d\n", + stats.num_avoided_edges); } -/* Static IDs for the special variables. Variable ID zero is unused - and used as terminator for the sub-variable chain. */ -enum { nothing_id = 1, anything_id = 2, string_id = 3, - escaped_id = 4, nonlocal_id = 5, escaped_return_id = 6, - storedanything_id = 7, integer_id = 8 }; - -/* Return a new variable info structure consisting for a variable - named NAME, and using constraint graph node NODE. Append it - to the vector of variable info structures. */ +/* Dump points-to information to OUTFILE. */ -static varinfo_t -new_var_info (tree t, const char *name, bool add_id) +void +dump_sa_points_to_info (FILE *outfile) { - unsigned index = varmap.length (); - varinfo_t ret = variable_info_pool.allocate (); + fprintf (outfile, "\nPoints-to sets\n\n"); - if (dump_file && add_id) + for (unsigned i = 1; i < varmap.length (); i++) { - char *tempname = xasprintf ("%s(%d)", name, index); - name = ggc_strdup (tempname); - free (tempname); + varinfo_t vi = get_varinfo (i); + if (!vi->may_have_pointers) + continue; + dump_solution_for_var (outfile, i); } +} - ret->id = index; - ret->name = name; - ret->decl = t; - /* Vars without decl are artificial and do not have sub-variables. */ - ret->is_artificial_var = (t == NULL_TREE); - ret->is_special_var = false; - ret->is_unknown_size_var = false; - ret->is_full_var = (t == NULL_TREE); - ret->is_heap_var = false; - ret->may_have_pointers = true; - ret->only_restrict_pointers = false; - ret->is_restrict_var = false; - ret->ruid = 0; - ret->is_global_var = (t == NULL_TREE); - ret->is_ipa_escape_point = false; - ret->is_fn_info = false; - ret->address_taken = false; - if (t && DECL_P (t)) - ret->is_global_var = (is_global_var (t) - /* We have to treat even local register variables - as escape points. */ - || (VAR_P (t) && DECL_HARD_REGISTER (t))); - ret->is_reg_var = (t && TREE_CODE (t) == SSA_NAME); - ret->solution = BITMAP_ALLOC (&pta_obstack); - ret->oldsolution = NULL; - ret->next = 0; - ret->shadow_var_uid = 0; - ret->head = ret->id; - - stats.total_vars++; - varmap.safe_push (ret); +/* Debug points-to information to stderr. */ - return ret; +DEBUG_FUNCTION void +debug_sa_points_to_info (void) +{ + dump_sa_points_to_info (stderr); } -/* A map mapping call statements to per-stmt variables for uses - and clobbers specific to the call. */ -static hash_map *call_stmt_vars; - -/* Lookup or create the variable for the call statement CALL. */ +/* Dump varinfo VI to FILE. */ -static varinfo_t -get_call_vi (gcall *call) +void +dump_varinfo (FILE *file, varinfo_t vi) { - varinfo_t vi, vi2; - - bool existed; - varinfo_t *slot_p = &call_stmt_vars->get_or_insert (call, &existed); - if (existed) - return *slot_p; + if (vi == NULL) + return; - vi = new_var_info (NULL_TREE, "CALLUSED", true); - vi->offset = 0; - vi->size = 1; - vi->fullsize = 2; - vi->is_full_var = true; - vi->is_reg_var = true; + fprintf (file, "%u: %s\n", vi->id, vi->name); - vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true); - vi2->offset = 1; - vi2->size = 1; - vi2->fullsize = 2; - vi2->is_full_var = true; - vi2->is_reg_var = true; - - vi->next = vi2->id; - - *slot_p = vi; - return vi; -} - -/* Lookup the variable for the call statement CALL representing - the uses. Returns NULL if there is nothing special about this call. */ - -static varinfo_t -lookup_call_use_vi (gcall *call) -{ - varinfo_t *slot_p = call_stmt_vars->get (call); - if (slot_p) - return *slot_p; - - return NULL; -} - -/* Lookup the variable for the call statement CALL representing - the clobbers. Returns NULL if there is nothing special about this call. */ - -static varinfo_t -lookup_call_clobber_vi (gcall *call) -{ - varinfo_t uses = lookup_call_use_vi (call); - if (!uses) - return NULL; - - return vi_next (uses); -} - -/* Lookup or create the variable for the call statement CALL representing - the uses. */ - -static varinfo_t -get_call_use_vi (gcall *call) -{ - return get_call_vi (call); -} - -/* Lookup or create the variable for the call statement CALL representing - the clobbers. */ - -static varinfo_t ATTRIBUTE_UNUSED -get_call_clobber_vi (gcall *call) -{ - return vi_next (get_call_vi (call)); -} - - -enum constraint_expr_type {SCALAR, DEREF, ADDRESSOF}; - -/* An expression that appears in a constraint. */ - -struct constraint_expr -{ - /* Constraint type. */ - constraint_expr_type type; - - /* Variable we are referring to in the constraint. */ - unsigned int var; - - /* Offset, in bits, of this constraint from the beginning of - variables it ends up referring to. - - IOW, in a deref constraint, we would deref, get the result set, - then add OFFSET to each member. */ - HOST_WIDE_INT offset; -}; - -/* Use 0x8000... as special unknown offset. */ -#define UNKNOWN_OFFSET HOST_WIDE_INT_MIN - -typedef struct constraint_expr ce_s; -static void get_constraint_for_1 (tree, vec *, bool, bool); -static void get_constraint_for (tree, vec *); -static void get_constraint_for_rhs (tree, vec *); -static void do_deref (vec *); - -/* Our set constraints are made up of two constraint expressions, one - LHS, and one RHS. - - As described in the introduction, our set constraints each represent an - operation between set valued variables. -*/ -struct constraint -{ - struct constraint_expr lhs; - struct constraint_expr rhs; -}; - -/* List of constraints that we use to build the constraint graph from. */ - -static vec constraints; -static object_allocator constraint_pool ("Constraint pool"); - -/* The constraint graph is represented as an array of bitmaps - containing successor nodes. */ - -struct constraint_graph -{ - /* Size of this graph, which may be different than the number of - nodes in the variable map. */ - unsigned int size; - - /* Explicit successors of each node. */ - bitmap *succs; - - /* Implicit predecessors of each node (Used for variable - substitution). */ - bitmap *implicit_preds; - - /* Explicit predecessors of each node (Used for variable substitution). */ - bitmap *preds; - - /* Indirect cycle representatives, or -1 if the node has no indirect - cycles. */ - int *indirect_cycles; - - /* Representative node for a node. rep[a] == a unless the node has - been unified. */ - unsigned int *rep; - - /* Equivalence class representative for a label. This is used for - variable substitution. */ - int *eq_rep; - - /* Pointer equivalence label for a node. All nodes with the same - pointer equivalence label can be unified together at some point - (either during constraint optimization or after the constraint - graph is built). */ - unsigned int *pe; - - /* Pointer equivalence representative for a label. This is used to - handle nodes that are pointer equivalent but not location - equivalent. We can unite these once the addressof constraints - are transformed into initial points-to sets. */ - int *pe_rep; - - /* Pointer equivalence label for each node, used during variable - substitution. */ - unsigned int *pointer_label; - - /* Location equivalence label for each node, used during location - equivalence finding. */ - unsigned int *loc_label; - - /* Pointed-by set for each node, used during location equivalence - finding. This is pointed-by rather than pointed-to, because it - is constructed using the predecessor graph. */ - bitmap *pointed_by; - - /* Points to sets for pointer equivalence. This is *not* the actual - points-to sets for nodes. */ - bitmap *points_to; - - /* Bitmap of nodes where the bit is set if the node is a direct - node. Used for variable substitution. */ - sbitmap direct_nodes; - - /* Bitmap of nodes where the bit is set if the node is address - taken. Used for variable substitution. */ - bitmap address_taken; - - /* Vector of complex constraints for each graph node. Complex - constraints are those involving dereferences or offsets that are - not 0. */ - vec *complex; -}; - -static constraint_graph_t graph; - -/* During variable substitution and the offline version of indirect - cycle finding, we create nodes to represent dereferences and - address taken constraints. These represent where these start and - end. */ -#define FIRST_REF_NODE (varmap).length () -#define LAST_REF_NODE (FIRST_REF_NODE + (FIRST_REF_NODE - 1)) - -/* Return the representative node for NODE, if NODE has been unioned - with another NODE. - This function performs path compression along the way to finding - the representative. */ - -static unsigned int -find (unsigned int node) -{ - gcc_checking_assert (node < graph->size); - if (graph->rep[node] != node) - return graph->rep[node] = find (graph->rep[node]); - return node; -} - -/* Union the TO and FROM nodes to the TO nodes. - Note that at some point in the future, we may want to do - union-by-rank, in which case we are going to have to return the - node we unified to. */ - -static bool -unite (unsigned int to, unsigned int from) -{ - gcc_checking_assert (to < graph->size && from < graph->size); - if (to != from && graph->rep[from] != to) - { - graph->rep[from] = to; - return true; - } - return false; -} - -/* Create a new constraint consisting of LHS and RHS expressions. */ - -static constraint_t -new_constraint (const struct constraint_expr lhs, - const struct constraint_expr rhs) -{ - constraint_t ret = constraint_pool.allocate (); - ret->lhs = lhs; - ret->rhs = rhs; - return ret; -} - -/* Print out constraint C to FILE. */ - -static void -dump_constraint (FILE *file, constraint_t c) -{ - if (c->lhs.type == ADDRESSOF) - fprintf (file, "&"); - else if (c->lhs.type == DEREF) - fprintf (file, "*"); - if (dump_file) - fprintf (file, "%s", get_varinfo (c->lhs.var)->name); - else - fprintf (file, "V%d", c->lhs.var); - if (c->lhs.offset == UNKNOWN_OFFSET) - fprintf (file, " + UNKNOWN"); - else if (c->lhs.offset != 0) - fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->lhs.offset); - fprintf (file, " = "); - if (c->rhs.type == ADDRESSOF) - fprintf (file, "&"); - else if (c->rhs.type == DEREF) - fprintf (file, "*"); - if (dump_file) - fprintf (file, "%s", get_varinfo (c->rhs.var)->name); - else - fprintf (file, "V%d", c->rhs.var); - if (c->rhs.offset == UNKNOWN_OFFSET) - fprintf (file, " + UNKNOWN"); - else if (c->rhs.offset != 0) - fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset); -} - - -void debug_constraint (constraint_t); -void debug_constraints (void); -void debug_constraint_graph (void); -void debug_solution_for_var (unsigned int); -void debug_sa_points_to_info (void); -void debug_varinfo (varinfo_t); -void debug_varmap (void); - -/* Print out constraint C to stderr. */ - -DEBUG_FUNCTION void -debug_constraint (constraint_t c) -{ - dump_constraint (stderr, c); - fprintf (stderr, "\n"); -} - -/* Print out all constraints to FILE */ - -static void -dump_constraints (FILE *file, int from) -{ - int i; - constraint_t c; - for (i = from; constraints.iterate (i, &c); i++) - if (c) - { - dump_constraint (file, c); - fprintf (file, "\n"); - } -} - -/* Print out all constraints to stderr. */ - -DEBUG_FUNCTION void -debug_constraints (void) -{ - dump_constraints (stderr, 0); -} - -/* Print the constraint graph in dot format. */ - -static void -dump_constraint_graph (FILE *file) -{ - unsigned int i; - - /* Only print the graph if it has already been initialized: */ - if (!graph) - return; - - /* Prints the header of the dot file: */ - fprintf (file, "strict digraph {\n"); - fprintf (file, " node [\n shape = box\n ]\n"); - fprintf (file, " edge [\n fontsize = \"12\"\n ]\n"); - fprintf (file, "\n // List of nodes and complex constraints in " - "the constraint graph:\n"); - - /* The next lines print the nodes in the graph together with the - complex constraints attached to them. */ - for (i = 1; i < graph->size; i++) - { - if (i == FIRST_REF_NODE) - continue; - if (find (i) != i) - continue; - if (i < FIRST_REF_NODE) - fprintf (file, "\"%s\"", get_varinfo (i)->name); - else - fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name); - if (graph->complex[i].exists ()) - { - unsigned j; - constraint_t c; - fprintf (file, " [label=\"\\N\\n"); - for (j = 0; graph->complex[i].iterate (j, &c); ++j) - { - dump_constraint (file, c); - fprintf (file, "\\l"); - } - fprintf (file, "\"]"); - } - fprintf (file, ";\n"); - } - - /* Go over the edges. */ - fprintf (file, "\n // Edges in the constraint graph:\n"); - for (i = 1; i < graph->size; i++) - { - unsigned j; - bitmap_iterator bi; - if (find (i) != i) - continue; - EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i], 0, j, bi) - { - unsigned to = find (j); - if (i == to) - continue; - if (i < FIRST_REF_NODE) - fprintf (file, "\"%s\"", get_varinfo (i)->name); - else - fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name); - fprintf (file, " -> "); - if (to < FIRST_REF_NODE) - fprintf (file, "\"%s\"", get_varinfo (to)->name); - else - fprintf (file, "\"*%s\"", get_varinfo (to - FIRST_REF_NODE)->name); - fprintf (file, ";\n"); - } - } - - /* Prints the tail of the dot file. */ - fprintf (file, "}\n"); -} - -/* Print out the constraint graph to stderr. */ - -DEBUG_FUNCTION void -debug_constraint_graph (void) -{ - dump_constraint_graph (stderr); -} - -/* SOLVER FUNCTIONS - - The solver is a simple worklist solver, that works on the following - algorithm: - - sbitmap changed_nodes = all zeroes; - changed_count = 0; - For each node that is not already collapsed: - changed_count++; - set bit in changed nodes - - while (changed_count > 0) - { - compute topological ordering for constraint graph - - find and collapse cycles in the constraint graph (updating - changed if necessary) - - for each node (n) in the graph in topological order: - changed_count--; - - Process each complex constraint associated with the node, - updating changed if necessary. - - For each outgoing edge from n, propagate the solution from n to - the destination of the edge, updating changed as necessary. - - } */ - -/* Return true if two constraint expressions A and B are equal. */ - -static bool -constraint_expr_equal (struct constraint_expr a, struct constraint_expr b) -{ - return a.type == b.type && a.var == b.var && a.offset == b.offset; -} - -/* Return true if constraint expression A is less than constraint expression - B. This is just arbitrary, but consistent, in order to give them an - ordering. */ - -static bool -constraint_expr_less (struct constraint_expr a, struct constraint_expr b) -{ - if (a.type == b.type) - { - if (a.var == b.var) - return a.offset < b.offset; - else - return a.var < b.var; - } - else - return a.type < b.type; -} - -/* Return true if constraint A is less than constraint B. This is just - arbitrary, but consistent, in order to give them an ordering. */ - -static bool -constraint_less (const constraint_t &a, const constraint_t &b) -{ - if (constraint_expr_less (a->lhs, b->lhs)) - return true; - else if (constraint_expr_less (b->lhs, a->lhs)) - return false; - else - return constraint_expr_less (a->rhs, b->rhs); -} - -/* Return true if two constraints A and B are equal. */ - -static bool -constraint_equal (const constraint &a, const constraint &b) -{ - return constraint_expr_equal (a.lhs, b.lhs) - && constraint_expr_equal (a.rhs, b.rhs); -} - - -/* Find a constraint LOOKFOR in the sorted constraint vector VEC */ - -static constraint_t -constraint_vec_find (vec vec, - constraint &lookfor) -{ - unsigned int place; - constraint_t found; - - if (!vec.exists ()) - return NULL; - - place = vec.lower_bound (&lookfor, constraint_less); - if (place >= vec.length ()) - return NULL; - found = vec[place]; - if (!constraint_equal (*found, lookfor)) - return NULL; - return found; -} - -/* Union two constraint vectors, TO and FROM. Put the result in TO. - Returns true of TO set is changed. */ - -static bool -constraint_set_union (vec *to, - vec *from) -{ - int i; - constraint_t c; - bool any_change = false; - - FOR_EACH_VEC_ELT (*from, i, c) - { - if (constraint_vec_find (*to, *c) == NULL) - { - unsigned int place = to->lower_bound (c, constraint_less); - to->safe_insert (place, c); - any_change = true; - } - } - return any_change; -} - -/* Expands the solution in SET to all sub-fields of variables included. */ - -static bitmap -solution_set_expand (bitmap set, bitmap *expanded) -{ - bitmap_iterator bi; - unsigned j; - - if (*expanded) - return *expanded; - - *expanded = BITMAP_ALLOC (&iteration_obstack); - - /* In a first pass expand variables, once for each head to avoid - quadratic behavior, to include all sub-fields. */ - unsigned prev_head = 0; - EXECUTE_IF_SET_IN_BITMAP (set, 0, j, bi) - { - varinfo_t v = get_varinfo (j); - if (v->is_artificial_var - || v->is_full_var) - continue; - if (v->head != prev_head) - { - varinfo_t head = get_varinfo (v->head); - unsigned num = 1; - for (varinfo_t n = vi_next (head); n != NULL; n = vi_next (n)) - { - if (n->id != head->id + num) - { - /* Usually sub variables are adjacent but since we - create pointed-to restrict representatives there - can be gaps as well. */ - bitmap_set_range (*expanded, head->id, num); - head = n; - num = 1; - } - else - num++; - } - - bitmap_set_range (*expanded, head->id, num); - prev_head = v->head; - } - } - - /* And finally set the rest of the bits from SET in an efficient way. */ - bitmap_ior_into (*expanded, set); - - return *expanded; -} - -/* Union solution sets TO and DELTA, and add INC to each member of DELTA in the - process. */ - -static bool -set_union_with_increment (bitmap to, bitmap delta, HOST_WIDE_INT inc, - bitmap *expanded_delta) -{ - bool changed = false; - bitmap_iterator bi; - unsigned int i; - - /* If the solution of DELTA contains anything it is good enough to transfer - this to TO. */ - if (bitmap_bit_p (delta, anything_id)) - return bitmap_set_bit (to, anything_id); - - /* If the offset is unknown we have to expand the solution to - all subfields. */ - if (inc == UNKNOWN_OFFSET) - { - delta = solution_set_expand (delta, expanded_delta); - changed |= bitmap_ior_into (to, delta); - return changed; - } - - /* For non-zero offset union the offsetted solution into the destination. */ - EXECUTE_IF_SET_IN_BITMAP (delta, 0, i, bi) - { - varinfo_t vi = get_varinfo (i); - - /* If this is a variable with just one field just set its bit - in the result. */ - if (vi->is_artificial_var - || vi->is_unknown_size_var - || vi->is_full_var) - changed |= bitmap_set_bit (to, i); - else - { - HOST_WIDE_INT fieldoffset = vi->offset + inc; - unsigned HOST_WIDE_INT size = vi->size; - - /* If the offset makes the pointer point to before the - variable use offset zero for the field lookup. */ - if (fieldoffset < 0) - vi = get_varinfo (vi->head); - else - vi = first_or_preceding_vi_for_offset (vi, fieldoffset); - - do - { - changed |= bitmap_set_bit (to, vi->id); - if (vi->is_full_var - || vi->next == 0) - break; - - /* We have to include all fields that overlap the current field - shifted by inc. */ - vi = vi_next (vi); - } - while (vi->offset < fieldoffset + size); - } - } - - return changed; -} - -/* Insert constraint C into the list of complex constraints for graph - node VAR. */ - -static void -insert_into_complex (constraint_graph_t graph, - unsigned int var, constraint_t c) -{ - vec complex = graph->complex[var]; - unsigned int place = complex.lower_bound (c, constraint_less); - - /* Only insert constraints that do not already exist. */ - if (place >= complex.length () - || !constraint_equal (*c, *complex[place])) - graph->complex[var].safe_insert (place, c); -} - - -/* Condense two variable nodes into a single variable node, by moving - all associated info from FROM to TO. Returns true if TO node's - constraint set changes after the merge. */ - -static bool -merge_node_constraints (constraint_graph_t graph, unsigned int to, - unsigned int from) -{ - unsigned int i; - constraint_t c; - bool any_change = false; - - gcc_checking_assert (find (from) == to); - - /* Move all complex constraints from src node into to node */ - FOR_EACH_VEC_ELT (graph->complex[from], i, c) - { - /* In complex constraints for node FROM, we may have either - a = *FROM, and *FROM = a, or an offseted constraint which are - always added to the rhs node's constraints. */ - - if (c->rhs.type == DEREF) - c->rhs.var = to; - else if (c->lhs.type == DEREF) - c->lhs.var = to; - else - c->rhs.var = to; - - } - any_change = constraint_set_union (&graph->complex[to], - &graph->complex[from]); - graph->complex[from].release (); - return any_change; -} - - -/* Remove edges involving NODE from GRAPH. */ - -static void -clear_edges_for_node (constraint_graph_t graph, unsigned int node) -{ - if (graph->succs[node]) - BITMAP_FREE (graph->succs[node]); -} - -/* Merge GRAPH nodes FROM and TO into node TO. */ - -static void -merge_graph_nodes (constraint_graph_t graph, unsigned int to, - unsigned int from) -{ - if (graph->indirect_cycles[from] != -1) - { - /* If we have indirect cycles with the from node, and we have - none on the to node, the to node has indirect cycles from the - from node now that they are unified. - If indirect cycles exist on both, unify the nodes that they - are in a cycle with, since we know they are in a cycle with - each other. */ - if (graph->indirect_cycles[to] == -1) - graph->indirect_cycles[to] = graph->indirect_cycles[from]; - } - - /* Merge all the successor edges. */ - if (graph->succs[from]) - { - if (!graph->succs[to]) - graph->succs[to] = BITMAP_ALLOC (&pta_obstack); - bitmap_ior_into (graph->succs[to], - graph->succs[from]); - } - - clear_edges_for_node (graph, from); -} - - -/* Add an indirect graph edge to GRAPH, going from TO to FROM if - it doesn't exist in the graph already. */ - -static void -add_implicit_graph_edge (constraint_graph_t graph, unsigned int to, - unsigned int from) -{ - if (to == from) - return; - - if (!graph->implicit_preds[to]) - graph->implicit_preds[to] = BITMAP_ALLOC (&predbitmap_obstack); - - if (bitmap_set_bit (graph->implicit_preds[to], from)) - stats.num_implicit_edges++; -} - -/* Add a predecessor graph edge to GRAPH, going from TO to FROM if - it doesn't exist in the graph already. - Return false if the edge already existed, true otherwise. */ - -static void -add_pred_graph_edge (constraint_graph_t graph, unsigned int to, - unsigned int from) -{ - if (!graph->preds[to]) - graph->preds[to] = BITMAP_ALLOC (&predbitmap_obstack); - bitmap_set_bit (graph->preds[to], from); -} - -/* Add a graph edge to GRAPH, going from FROM to TO if - it doesn't exist in the graph already. - Return false if the edge already existed, true otherwise. */ - -static bool -add_graph_edge (constraint_graph_t graph, unsigned int to, - unsigned int from) -{ - if (to == from) - { - return false; - } - else - { - bool r = false; - - if (!graph->succs[from]) - graph->succs[from] = BITMAP_ALLOC (&pta_obstack); - - /* The graph solving process does not avoid "triangles", thus - there can be multiple paths from a node to another involving - intermediate other nodes. That causes extra copying which is - most difficult to avoid when the intermediate node is ESCAPED - because there are no edges added from ESCAPED. Avoid - adding the direct edge FROM -> TO when we have FROM -> ESCAPED - and TO contains ESCAPED. - ??? Note this is only a heuristic, it does not prevent the - situation from occuring. The heuristic helps PR38474 and - PR99912 significantly. */ - if (to < FIRST_REF_NODE - && bitmap_bit_p (graph->succs[from], find (escaped_id)) - && bitmap_bit_p (get_varinfo (find (to))->solution, escaped_id)) - { - stats.num_avoided_edges++; - return false; - } - - if (bitmap_set_bit (graph->succs[from], to)) - { - r = true; - if (to < FIRST_REF_NODE && from < FIRST_REF_NODE) - stats.num_edges++; - } - return r; - } -} - - -/* Initialize the constraint graph structure to contain SIZE nodes. */ - -static void -init_graph (unsigned int size) -{ - unsigned int j; - - graph = XCNEW (struct constraint_graph); - graph->size = size; - graph->succs = XCNEWVEC (bitmap, graph->size); - graph->indirect_cycles = XNEWVEC (int, graph->size); - graph->rep = XNEWVEC (unsigned int, graph->size); - /* ??? Macros do not support template types with multiple arguments, - so we use a typedef to work around it. */ - typedef vec vec_constraint_t_heap; - graph->complex = XCNEWVEC (vec_constraint_t_heap, size); - graph->pe = XCNEWVEC (unsigned int, graph->size); - graph->pe_rep = XNEWVEC (int, graph->size); - - for (j = 0; j < graph->size; j++) - { - graph->rep[j] = j; - graph->pe_rep[j] = -1; - graph->indirect_cycles[j] = -1; - } -} - -/* Build the constraint graph, adding only predecessor edges right now. */ - -static void -build_pred_graph (void) -{ - int i; - constraint_t c; - unsigned int j; - - graph->implicit_preds = XCNEWVEC (bitmap, graph->size); - graph->preds = XCNEWVEC (bitmap, graph->size); - graph->pointer_label = XCNEWVEC (unsigned int, graph->size); - graph->loc_label = XCNEWVEC (unsigned int, graph->size); - graph->pointed_by = XCNEWVEC (bitmap, graph->size); - graph->points_to = XCNEWVEC (bitmap, graph->size); - graph->eq_rep = XNEWVEC (int, graph->size); - graph->direct_nodes = sbitmap_alloc (graph->size); - graph->address_taken = BITMAP_ALLOC (&predbitmap_obstack); - bitmap_clear (graph->direct_nodes); - - for (j = 1; j < FIRST_REF_NODE; j++) - { - if (!get_varinfo (j)->is_special_var) - bitmap_set_bit (graph->direct_nodes, j); - } - - for (j = 0; j < graph->size; j++) - graph->eq_rep[j] = -1; - - for (j = 0; j < varmap.length (); j++) - graph->indirect_cycles[j] = -1; - - FOR_EACH_VEC_ELT (constraints, i, c) - { - struct constraint_expr lhs = c->lhs; - struct constraint_expr rhs = c->rhs; - unsigned int lhsvar = lhs.var; - unsigned int rhsvar = rhs.var; - - if (lhs.type == DEREF) - { - /* *x = y. */ - if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR) - { - if (lhs.var == anything_id) - add_pred_graph_edge (graph, storedanything_id, rhsvar); - else - add_pred_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar); - } - } - else if (rhs.type == DEREF) - { - /* x = *y */ - if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR) - add_pred_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar); - else - bitmap_clear_bit (graph->direct_nodes, lhsvar); - } - else if (rhs.type == ADDRESSOF) - { - varinfo_t v; - - /* x = &y */ - if (graph->points_to[lhsvar] == NULL) - graph->points_to[lhsvar] = BITMAP_ALLOC (&predbitmap_obstack); - bitmap_set_bit (graph->points_to[lhsvar], rhsvar); - - if (graph->pointed_by[rhsvar] == NULL) - graph->pointed_by[rhsvar] = BITMAP_ALLOC (&predbitmap_obstack); - bitmap_set_bit (graph->pointed_by[rhsvar], lhsvar); - - /* Implicitly, *x = y */ - add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar); - - /* All related variables are no longer direct nodes. */ - bitmap_clear_bit (graph->direct_nodes, rhsvar); - v = get_varinfo (rhsvar); - if (!v->is_full_var) - { - v = get_varinfo (v->head); - do - { - bitmap_clear_bit (graph->direct_nodes, v->id); - v = vi_next (v); - } - while (v != NULL); - } - bitmap_set_bit (graph->address_taken, rhsvar); - } - else if (lhsvar > anything_id - && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0) - { - /* x = y */ - add_pred_graph_edge (graph, lhsvar, rhsvar); - /* Implicitly, *x = *y */ - add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar, - FIRST_REF_NODE + rhsvar); - } - else if (lhs.offset != 0 || rhs.offset != 0) - { - if (rhs.offset != 0) - bitmap_clear_bit (graph->direct_nodes, lhs.var); - else if (lhs.offset != 0) - bitmap_clear_bit (graph->direct_nodes, rhs.var); - } - } -} - -/* Build the constraint graph, adding successor edges. */ - -static void -build_succ_graph (void) -{ - unsigned i, t; - constraint_t c; - - FOR_EACH_VEC_ELT (constraints, i, c) - { - struct constraint_expr lhs; - struct constraint_expr rhs; - unsigned int lhsvar; - unsigned int rhsvar; - - if (!c) - continue; - - lhs = c->lhs; - rhs = c->rhs; - lhsvar = find (lhs.var); - rhsvar = find (rhs.var); - - if (lhs.type == DEREF) - { - if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR) - { - if (lhs.var == anything_id) - add_graph_edge (graph, storedanything_id, rhsvar); - else - add_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar); - } - } - else if (rhs.type == DEREF) - { - if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR) - add_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar); - } - else if (rhs.type == ADDRESSOF) - { - /* x = &y */ - gcc_checking_assert (find (rhs.var) == rhs.var); - bitmap_set_bit (get_varinfo (lhsvar)->solution, rhsvar); - } - else if (lhsvar > anything_id - && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0) - { - add_graph_edge (graph, lhsvar, rhsvar); - } - } - - /* Add edges from STOREDANYTHING to all nodes that can receive pointers. */ - t = find (storedanything_id); - for (i = integer_id + 1; i < FIRST_REF_NODE; ++i) - { - if (get_varinfo (i)->may_have_pointers) - add_graph_edge (graph, find (i), t); - } - - /* Everything stored to ANYTHING also potentially escapes. */ - add_graph_edge (graph, find (escaped_id), t); -} - - -/* Changed variables on the last iteration. */ -static bitmap changed; - -/* Strongly Connected Component visitation info. */ - -class scc_info -{ -public: - scc_info (size_t size); - ~scc_info (); - - auto_sbitmap visited; - auto_sbitmap deleted; - unsigned int *dfs; - unsigned int *node_mapping; - int current_index; - auto_vec scc_stack; -}; - - -/* Recursive routine to find strongly connected components in GRAPH. - SI is the SCC info to store the information in, and N is the id of current - graph node we are processing. - - This is Tarjan's strongly connected component finding algorithm, as - modified by Nuutila to keep only non-root nodes on the stack. - The algorithm can be found in "On finding the strongly connected - connected components in a directed graph" by Esko Nuutila and Eljas - Soisalon-Soininen, in Information Processing Letters volume 49, - number 1, pages 9-14. */ - -static void -scc_visit (constraint_graph_t graph, class scc_info *si, unsigned int n) -{ - unsigned int i; - bitmap_iterator bi; - unsigned int my_dfs; - - bitmap_set_bit (si->visited, n); - si->dfs[n] = si->current_index ++; - my_dfs = si->dfs[n]; - - /* Visit all the successors. */ - EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[n], 0, i, bi) - { - unsigned int w; - - if (i > LAST_REF_NODE) - break; - - w = find (i); - if (bitmap_bit_p (si->deleted, w)) - continue; - - if (!bitmap_bit_p (si->visited, w)) - scc_visit (graph, si, w); - - unsigned int t = find (w); - gcc_checking_assert (find (n) == n); - if (si->dfs[t] < si->dfs[n]) - si->dfs[n] = si->dfs[t]; - } - - /* See if any components have been identified. */ - if (si->dfs[n] == my_dfs) - { - if (si->scc_stack.length () > 0 - && si->dfs[si->scc_stack.last ()] >= my_dfs) - { - bitmap scc = BITMAP_ALLOC (NULL); - unsigned int lowest_node; - bitmap_iterator bi; - - bitmap_set_bit (scc, n); - - while (si->scc_stack.length () != 0 - && si->dfs[si->scc_stack.last ()] >= my_dfs) - { - unsigned int w = si->scc_stack.pop (); - - bitmap_set_bit (scc, w); - } - - lowest_node = bitmap_first_set_bit (scc); - gcc_assert (lowest_node < FIRST_REF_NODE); - - /* Collapse the SCC nodes into a single node, and mark the - indirect cycles. */ - EXECUTE_IF_SET_IN_BITMAP (scc, 0, i, bi) - { - if (i < FIRST_REF_NODE) - { - if (unite (lowest_node, i)) - unify_nodes (graph, lowest_node, i, false); - } - else - { - unite (lowest_node, i); - graph->indirect_cycles[i - FIRST_REF_NODE] = lowest_node; - } - } - bitmap_set_bit (si->deleted, lowest_node); - } - else - bitmap_set_bit (si->deleted, n); - } - else - si->scc_stack.safe_push (n); -} - -/* Unify node FROM into node TO, updating the changed count if - necessary when UPDATE_CHANGED is true. */ - -static void -unify_nodes (constraint_graph_t graph, unsigned int to, unsigned int from, - bool update_changed) -{ - gcc_checking_assert (to != from && find (to) == to); - - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Unifying %s to %s\n", - get_varinfo (from)->name, - get_varinfo (to)->name); - - if (update_changed) - stats.unified_vars_dynamic++; - else - stats.unified_vars_static++; - - merge_graph_nodes (graph, to, from); - if (merge_node_constraints (graph, to, from)) - { - if (update_changed) - bitmap_set_bit (changed, to); - } - - /* Mark TO as changed if FROM was changed. If TO was already marked - as changed, decrease the changed count. */ - - if (update_changed - && bitmap_clear_bit (changed, from)) - bitmap_set_bit (changed, to); - varinfo_t fromvi = get_varinfo (from); - if (fromvi->solution) - { - /* If the solution changes because of the merging, we need to mark - the variable as changed. */ - varinfo_t tovi = get_varinfo (to); - if (bitmap_ior_into (tovi->solution, fromvi->solution)) - { - if (update_changed) - bitmap_set_bit (changed, to); - } - - BITMAP_FREE (fromvi->solution); - if (fromvi->oldsolution) - BITMAP_FREE (fromvi->oldsolution); - - if (stats.iterations > 0 - && tovi->oldsolution) - BITMAP_FREE (tovi->oldsolution); - } - if (graph->succs[to]) - bitmap_clear_bit (graph->succs[to], to); -} - -/* Add a copy edge FROM -> TO, optimizing special cases. Returns TRUE - if the solution of TO changed. */ - -static bool -solve_add_graph_edge (constraint_graph_t graph, unsigned int to, - unsigned int from) -{ - /* Adding edges from the special vars is pointless. - They don't have sets that can change. */ - if (get_varinfo (from)->is_special_var) - return bitmap_ior_into (get_varinfo (to)->solution, - get_varinfo (from)->solution); - /* Merging the solution from ESCAPED needlessly increases - the set. Use ESCAPED as representative instead. */ - else if (from == find (escaped_id)) - return bitmap_set_bit (get_varinfo (to)->solution, escaped_id); - else if (get_varinfo (from)->may_have_pointers - && add_graph_edge (graph, to, from)) - return bitmap_ior_into (get_varinfo (to)->solution, - get_varinfo (from)->solution); - return false; -} - -/* Process a constraint C that represents x = *(y + off), using DELTA as the - starting solution for y. */ - -static void -do_sd_constraint (constraint_graph_t graph, constraint_t c, - bitmap delta, bitmap *expanded_delta) -{ - unsigned int lhs = c->lhs.var; - bool flag = false; - bitmap sol = get_varinfo (lhs)->solution; - unsigned int j; - bitmap_iterator bi; - HOST_WIDE_INT roffset = c->rhs.offset; - - /* Our IL does not allow this. */ - gcc_checking_assert (c->lhs.offset == 0); - - /* If the solution of Y contains anything it is good enough to transfer - this to the LHS. */ - if (bitmap_bit_p (delta, anything_id)) - { - flag |= bitmap_set_bit (sol, anything_id); - goto done; - } - - /* If we do not know at with offset the rhs is dereferenced compute - the reachability set of DELTA, conservatively assuming it is - dereferenced at all valid offsets. */ - if (roffset == UNKNOWN_OFFSET) - { - delta = solution_set_expand (delta, expanded_delta); - /* No further offset processing is necessary. */ - roffset = 0; - } - - /* For each variable j in delta (Sol(y)), add - an edge in the graph from j to x, and union Sol(j) into Sol(x). */ - EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi) - { - varinfo_t v = get_varinfo (j); - HOST_WIDE_INT fieldoffset = v->offset + roffset; - unsigned HOST_WIDE_INT size = v->size; - unsigned int t; - - if (v->is_full_var) - ; - else if (roffset != 0) - { - if (fieldoffset < 0) - v = get_varinfo (v->head); - else - v = first_or_preceding_vi_for_offset (v, fieldoffset); - } - - /* We have to include all fields that overlap the current field - shifted by roffset. */ - do - { - t = find (v->id); - - flag |= solve_add_graph_edge (graph, lhs, t); - - if (v->is_full_var - || v->next == 0) - break; - - v = vi_next (v); - } - while (v->offset < fieldoffset + size); - } - -done: - /* If the LHS solution changed, mark the var as changed. */ - if (flag) - bitmap_set_bit (changed, lhs); -} - -/* Process a constraint C that represents *(x + off) = y using DELTA - as the starting solution for x. */ - -static void -do_ds_constraint (constraint_t c, bitmap delta, bitmap *expanded_delta) -{ - unsigned int rhs = c->rhs.var; - bitmap sol = get_varinfo (rhs)->solution; - unsigned int j; - bitmap_iterator bi; - HOST_WIDE_INT loff = c->lhs.offset; - bool escaped_p = false; - - /* Our IL does not allow this. */ - gcc_checking_assert (c->rhs.offset == 0); - - /* If the solution of y contains ANYTHING simply use the ANYTHING - solution. This avoids needlessly increasing the points-to sets. */ - if (bitmap_bit_p (sol, anything_id)) - sol = get_varinfo (find (anything_id))->solution; - - /* If the solution for x contains ANYTHING we have to merge the - solution of y into all pointer variables which we do via - STOREDANYTHING. */ - if (bitmap_bit_p (delta, anything_id)) - { - unsigned t = find (storedanything_id); - if (solve_add_graph_edge (graph, t, rhs)) - bitmap_set_bit (changed, t); - return; - } - - /* If we do not know at with offset the rhs is dereferenced compute - the reachability set of DELTA, conservatively assuming it is - dereferenced at all valid offsets. */ - if (loff == UNKNOWN_OFFSET) - { - delta = solution_set_expand (delta, expanded_delta); - loff = 0; - } - - /* For each member j of delta (Sol(x)), add an edge from y to j and - union Sol(y) into Sol(j) */ - EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi) - { - varinfo_t v = get_varinfo (j); - unsigned int t; - HOST_WIDE_INT fieldoffset = v->offset + loff; - unsigned HOST_WIDE_INT size = v->size; - - if (v->is_full_var) - ; - else if (loff != 0) - { - if (fieldoffset < 0) - v = get_varinfo (v->head); - else - v = first_or_preceding_vi_for_offset (v, fieldoffset); - } - - /* We have to include all fields that overlap the current field - shifted by loff. */ - do - { - if (v->may_have_pointers) - { - /* If v is a global variable then this is an escape point. */ - if (v->is_global_var - && !escaped_p) - { - t = find (escaped_id); - if (add_graph_edge (graph, t, rhs) - && bitmap_ior_into (get_varinfo (t)->solution, sol)) - bitmap_set_bit (changed, t); - /* Enough to let rhs escape once. */ - escaped_p = true; - } - - if (v->is_special_var) - break; - - t = find (v->id); - - if (solve_add_graph_edge (graph, t, rhs)) - bitmap_set_bit (changed, t); - } - - if (v->is_full_var - || v->next == 0) - break; - - v = vi_next (v); - } - while (v->offset < fieldoffset + size); - } -} - -/* Handle a non-simple (simple meaning requires no iteration), - constraint (IE *x = &y, x = *y, *x = y, and x = y with offsets involved). */ - -static void -do_complex_constraint (constraint_graph_t graph, constraint_t c, bitmap delta, - bitmap *expanded_delta) -{ - if (c->lhs.type == DEREF) - { - if (c->rhs.type == ADDRESSOF) - { - gcc_unreachable (); - } - else - { - /* *x = y */ - do_ds_constraint (c, delta, expanded_delta); - } - } - else if (c->rhs.type == DEREF) - { - /* x = *y */ - if (!(get_varinfo (c->lhs.var)->is_special_var)) - do_sd_constraint (graph, c, delta, expanded_delta); - } - else - { - bitmap tmp; - bool flag = false; - - gcc_checking_assert (c->rhs.type == SCALAR && c->lhs.type == SCALAR - && c->rhs.offset != 0 && c->lhs.offset == 0); - tmp = get_varinfo (c->lhs.var)->solution; - - flag = set_union_with_increment (tmp, delta, c->rhs.offset, - expanded_delta); - - if (flag) - bitmap_set_bit (changed, c->lhs.var); - } -} - -/* Initialize and return a new SCC info structure. */ - -scc_info::scc_info (size_t size) : - visited (size), deleted (size), current_index (0), scc_stack (1) -{ - bitmap_clear (visited); - bitmap_clear (deleted); - node_mapping = XNEWVEC (unsigned int, size); - dfs = XCNEWVEC (unsigned int, size); - - for (size_t i = 0; i < size; i++) - node_mapping[i] = i; -} - -/* Free an SCC info structure pointed to by SI */ - -scc_info::~scc_info () -{ - free (node_mapping); - free (dfs); -} - - -/* Find indirect cycles in GRAPH that occur, using strongly connected - components, and note them in the indirect cycles map. - - This technique comes from Ben Hardekopf and Calvin Lin, - "It Pays to be Lazy: Fast and Accurate Pointer Analysis for Millions of - Lines of Code", submitted to PLDI 2007. */ - -static void -find_indirect_cycles (constraint_graph_t graph) -{ - unsigned int i; - unsigned int size = graph->size; - scc_info si (size); - - for (i = 0; i < MIN (LAST_REF_NODE, size); i ++ ) - if (!bitmap_bit_p (si.visited, i) && find (i) == i) - scc_visit (graph, &si, i); -} - -/* Visit the graph in topological order starting at node N, and store the - order in TOPO_ORDER using VISITED to indicate visited nodes. */ - -static void -topo_visit (constraint_graph_t graph, vec &topo_order, - sbitmap visited, unsigned int n) -{ - bitmap_iterator bi; - unsigned int j; - - bitmap_set_bit (visited, n); - - if (graph->succs[n]) - EXECUTE_IF_SET_IN_BITMAP (graph->succs[n], 0, j, bi) - { - unsigned k = find (j); - if (!bitmap_bit_p (visited, k)) - topo_visit (graph, topo_order, visited, k); - } - - /* Also consider copy with offset complex constraints as implicit edges. */ - for (auto c : graph->complex[n]) - { - /* Constraints are ordered so that SCALAR = SCALAR appear first. */ - if (c->lhs.type != SCALAR || c->rhs.type != SCALAR) - break; - gcc_checking_assert (c->rhs.var == n); - unsigned k = find (c->lhs.var); - if (!bitmap_bit_p (visited, k)) - topo_visit (graph, topo_order, visited, k); - } - - topo_order.quick_push (n); -} - -/* Compute a topological ordering for GRAPH, and return the result. */ - -static auto_vec -compute_topo_order (constraint_graph_t graph) -{ - unsigned int i; - unsigned int size = graph->size; - - auto_sbitmap visited (size); - bitmap_clear (visited); - - /* For the heuristic in add_graph_edge to work optimally make sure to - first visit the connected component of the graph containing - ESCAPED. Do this by extracting the connected component - with ESCAPED and append that to all other components as solve_graph - pops from the order. */ - auto_vec tail (size); - topo_visit (graph, tail, visited, find (escaped_id)); - - auto_vec topo_order (size); - - for (i = 0; i != size; ++i) - if (!bitmap_bit_p (visited, i) && find (i) == i) - topo_visit (graph, topo_order, visited, i); - - topo_order.splice (tail); - return topo_order; -} - -/* Structure used to for hash value numbering of pointer equivalence - classes. */ - -typedef struct equiv_class_label -{ - hashval_t hashcode; - unsigned int equivalence_class; - bitmap labels; -} *equiv_class_label_t; -typedef const struct equiv_class_label *const_equiv_class_label_t; - -/* Equiv_class_label hashtable helpers. */ - -struct equiv_class_hasher : nofree_ptr_hash -{ - static inline hashval_t hash (const equiv_class_label *); - static inline bool equal (const equiv_class_label *, - const equiv_class_label *); -}; - -/* Hash function for a equiv_class_label_t */ - -inline hashval_t -equiv_class_hasher::hash (const equiv_class_label *ecl) -{ - return ecl->hashcode; -} - -/* Equality function for two equiv_class_label_t's. */ - -inline bool -equiv_class_hasher::equal (const equiv_class_label *eql1, - const equiv_class_label *eql2) -{ - return (eql1->hashcode == eql2->hashcode - && bitmap_equal_p (eql1->labels, eql2->labels)); -} - -/* A hashtable for mapping a bitmap of labels->pointer equivalence - classes. */ -static hash_table *pointer_equiv_class_table; - -/* A hashtable for mapping a bitmap of labels->location equivalence - classes. */ -static hash_table *location_equiv_class_table; - -struct obstack equiv_class_obstack; - -/* Lookup a equivalence class in TABLE by the bitmap of LABELS with - hash HAS it contains. Sets *REF_LABELS to the bitmap LABELS - is equivalent to. */ - -static equiv_class_label * -equiv_class_lookup_or_add (hash_table *table, - bitmap labels) -{ - equiv_class_label **slot; - equiv_class_label ecl; - - ecl.labels = labels; - ecl.hashcode = bitmap_hash (labels); - slot = table->find_slot (&ecl, INSERT); - if (!*slot) - { - *slot = XOBNEW (&equiv_class_obstack, struct equiv_class_label); - (*slot)->labels = labels; - (*slot)->hashcode = ecl.hashcode; - (*slot)->equivalence_class = 0; - } - - return *slot; -} - -/* Perform offline variable substitution. - - This is a worst case quadratic time way of identifying variables - that must have equivalent points-to sets, including those caused by - static cycles, and single entry subgraphs, in the constraint graph. - - The technique is described in "Exploiting Pointer and Location - Equivalence to Optimize Pointer Analysis. In the 14th International - Static Analysis Symposium (SAS), August 2007." It is known as the - "HU" algorithm, and is equivalent to value numbering the collapsed - constraint graph including evaluating unions. - - The general method of finding equivalence classes is as follows: - Add fake nodes (REF nodes) and edges for *a = b and a = *b constraints. - Initialize all non-REF nodes to be direct nodes. - For each constraint a = a U {b}, we set pts(a) = pts(a) u {fresh - variable} - For each constraint containing the dereference, we also do the same - thing. - - We then compute SCC's in the graph and unify nodes in the same SCC, - including pts sets. - - For each non-collapsed node x: - Visit all unvisited explicit incoming edges. - Ignoring all non-pointers, set pts(x) = Union of pts(a) for y - where y->x. - Lookup the equivalence class for pts(x). - If we found one, equivalence_class(x) = found class. - Otherwise, equivalence_class(x) = new class, and new_class is - added to the lookup table. - - All direct nodes with the same equivalence class can be replaced - with a single representative node. - All unlabeled nodes (label == 0) are not pointers and all edges - involving them can be eliminated. - We perform these optimizations during rewrite_constraints - - In addition to pointer equivalence class finding, we also perform - location equivalence class finding. This is the set of variables - that always appear together in points-to sets. We use this to - compress the size of the points-to sets. */ - -/* Current maximum pointer equivalence class id. */ -static int pointer_equiv_class; - -/* Current maximum location equivalence class id. */ -static int location_equiv_class; - -/* Recursive routine to find strongly connected components in GRAPH, - and label it's nodes with DFS numbers. */ - -static void -condense_visit (constraint_graph_t graph, class scc_info *si, unsigned int n) -{ - unsigned int i; - bitmap_iterator bi; - unsigned int my_dfs; - - gcc_checking_assert (si->node_mapping[n] == n); - bitmap_set_bit (si->visited, n); - si->dfs[n] = si->current_index ++; - my_dfs = si->dfs[n]; - - /* Visit all the successors. */ - EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi) - { - unsigned int w = si->node_mapping[i]; - - if (bitmap_bit_p (si->deleted, w)) - continue; - - if (!bitmap_bit_p (si->visited, w)) - condense_visit (graph, si, w); - - unsigned int t = si->node_mapping[w]; - gcc_checking_assert (si->node_mapping[n] == n); - if (si->dfs[t] < si->dfs[n]) - si->dfs[n] = si->dfs[t]; - } + const char *sep = " "; + if (vi->is_artificial_var) + fprintf (file, "%sartificial", sep); + if (vi->is_special_var) + fprintf (file, "%sspecial", sep); + if (vi->is_unknown_size_var) + fprintf (file, "%sunknown-size", sep); + if (vi->is_full_var) + fprintf (file, "%sfull", sep); + if (vi->is_heap_var) + fprintf (file, "%sheap", sep); + if (vi->may_have_pointers) + fprintf (file, "%smay-have-pointers", sep); + if (vi->only_restrict_pointers) + fprintf (file, "%sonly-restrict-pointers", sep); + if (vi->is_restrict_var) + fprintf (file, "%sis-restrict-var", sep); + if (vi->is_global_var) + fprintf (file, "%sglobal", sep); + if (vi->is_ipa_escape_point) + fprintf (file, "%sipa-escape-point", sep); + if (vi->is_fn_info) + fprintf (file, "%sfn-info", sep); + if (vi->ruid) + fprintf (file, "%srestrict-uid:%u", sep, vi->ruid); + if (vi->next) + fprintf (file, "%snext:%u", sep, vi->next); + if (vi->head != vi->id) + fprintf (file, "%shead:%u", sep, vi->head); + if (vi->offset) + fprintf (file, "%soffset:" HOST_WIDE_INT_PRINT_DEC, sep, vi->offset); + if (vi->size != ~HOST_WIDE_INT_0U) + fprintf (file, "%ssize:" HOST_WIDE_INT_PRINT_DEC, sep, vi->size); + if (vi->fullsize != ~HOST_WIDE_INT_0U && vi->fullsize != vi->size) + fprintf (file, "%sfullsize:" HOST_WIDE_INT_PRINT_DEC, sep, + vi->fullsize); + fprintf (file, "\n"); - /* Visit all the implicit predecessors. */ - EXECUTE_IF_IN_NONNULL_BITMAP (graph->implicit_preds[n], 0, i, bi) + if (vi->solution && !bitmap_empty_p (vi->solution)) { - unsigned int w = si->node_mapping[i]; - - if (bitmap_bit_p (si->deleted, w)) - continue; - - if (!bitmap_bit_p (si->visited, w)) - condense_visit (graph, si, w); - - unsigned int t = si->node_mapping[w]; - gcc_assert (si->node_mapping[n] == n); - if (si->dfs[t] < si->dfs[n]) - si->dfs[n] = si->dfs[t]; + bitmap_iterator bi; + unsigned i; + fprintf (file, " solution: {"); + EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi) + fprintf (file, " %u", i); + fprintf (file, " }\n"); } - /* See if any components have been identified. */ - if (si->dfs[n] == my_dfs) + if (vi->oldsolution && !bitmap_empty_p (vi->oldsolution) + && !bitmap_equal_p (vi->solution, vi->oldsolution)) { - if (si->scc_stack.length () != 0 - && si->dfs[si->scc_stack.last ()] >= my_dfs) - { - /* Find the first node of the SCC and do non-bitmap work. */ - bool direct_p = true; - unsigned first = si->scc_stack.length (); - do - { - --first; - unsigned int w = si->scc_stack[first]; - si->node_mapping[w] = n; - if (!bitmap_bit_p (graph->direct_nodes, w)) - direct_p = false; - } - while (first > 0 - && si->dfs[si->scc_stack[first - 1]] >= my_dfs); - if (!direct_p) - bitmap_clear_bit (graph->direct_nodes, n); - - /* Want to reduce to node n, push that first. */ - si->scc_stack.reserve (1); - si->scc_stack.quick_push (si->scc_stack[first]); - si->scc_stack[first] = n; - - unsigned scc_size = si->scc_stack.length () - first; - unsigned split = scc_size / 2; - unsigned carry = scc_size - split * 2; - while (split > 0) - { - for (unsigned i = 0; i < split; ++i) - { - unsigned a = si->scc_stack[first + i]; - unsigned b = si->scc_stack[first + split + carry + i]; - - /* Unify our nodes. */ - if (graph->preds[b]) - { - if (!graph->preds[a]) - std::swap (graph->preds[a], graph->preds[b]); - else - bitmap_ior_into_and_free (graph->preds[a], - &graph->preds[b]); - } - if (graph->implicit_preds[b]) - { - if (!graph->implicit_preds[a]) - std::swap (graph->implicit_preds[a], - graph->implicit_preds[b]); - else - bitmap_ior_into_and_free (graph->implicit_preds[a], - &graph->implicit_preds[b]); - } - if (graph->points_to[b]) - { - if (!graph->points_to[a]) - std::swap (graph->points_to[a], graph->points_to[b]); - else - bitmap_ior_into_and_free (graph->points_to[a], - &graph->points_to[b]); - } - } - unsigned remain = split + carry; - split = remain / 2; - carry = remain - split * 2; - } - /* Actually pop the SCC. */ - si->scc_stack.truncate (first); - } - bitmap_set_bit (si->deleted, n); + bitmap_iterator bi; + unsigned i; + fprintf (file, " oldsolution: {"); + EXECUTE_IF_SET_IN_BITMAP (vi->oldsolution, 0, i, bi) + fprintf (file, " %u", i); + fprintf (file, " }\n"); } - else - si->scc_stack.safe_push (n); } -/* Label pointer equivalences. - - This performs a value numbering of the constraint graph to - discover which variables will always have the same points-to sets - under the current set of constraints. - - The way it value numbers is to store the set of points-to bits - generated by the constraints and graph edges. This is just used as a - hash and equality comparison. The *actual set of points-to bits* is - completely irrelevant, in that we don't care about being able to - extract them later. - - The equality values (currently bitmaps) just have to satisfy a few - constraints, the main ones being: - 1. The combining operation must be order independent. - 2. The end result of a given set of operations must be unique iff the - combination of input values is unique - 3. Hashable. */ +/* Dump varinfo VI to stderr. */ -static void -label_visit (constraint_graph_t graph, class scc_info *si, unsigned int n) +DEBUG_FUNCTION void +debug_varinfo (varinfo_t vi) { - unsigned int i, first_pred; - bitmap_iterator bi; - - bitmap_set_bit (si->visited, n); - - /* Label and union our incoming edges's points to sets. */ - first_pred = -1U; - EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi) - { - unsigned int w = si->node_mapping[i]; - if (!bitmap_bit_p (si->visited, w)) - label_visit (graph, si, w); - - /* Skip unused edges */ - if (w == n || graph->pointer_label[w] == 0) - continue; - - if (graph->points_to[w]) - { - if (!graph->points_to[n]) - { - if (first_pred == -1U) - first_pred = w; - else - { - graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack); - bitmap_ior (graph->points_to[n], - graph->points_to[first_pred], - graph->points_to[w]); - } - } - else - bitmap_ior_into (graph->points_to[n], graph->points_to[w]); - } - } - - /* Indirect nodes get fresh variables and a new pointer equiv class. */ - if (!bitmap_bit_p (graph->direct_nodes, n)) - { - if (!graph->points_to[n]) - { - graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack); - if (first_pred != -1U) - bitmap_copy (graph->points_to[n], graph->points_to[first_pred]); - } - bitmap_set_bit (graph->points_to[n], FIRST_REF_NODE + n); - graph->pointer_label[n] = pointer_equiv_class++; - equiv_class_label_t ecl; - ecl = equiv_class_lookup_or_add (pointer_equiv_class_table, - graph->points_to[n]); - ecl->equivalence_class = graph->pointer_label[n]; - return; - } - - /* If there was only a single non-empty predecessor the pointer equiv - class is the same. */ - if (!graph->points_to[n]) - { - if (first_pred != -1U) - { - graph->pointer_label[n] = graph->pointer_label[first_pred]; - graph->points_to[n] = graph->points_to[first_pred]; - } - return; - } - - if (!bitmap_empty_p (graph->points_to[n])) - { - equiv_class_label_t ecl; - ecl = equiv_class_lookup_or_add (pointer_equiv_class_table, - graph->points_to[n]); - if (ecl->equivalence_class == 0) - ecl->equivalence_class = pointer_equiv_class++; - else - { - BITMAP_FREE (graph->points_to[n]); - graph->points_to[n] = ecl->labels; - } - graph->pointer_label[n] = ecl->equivalence_class; - } + dump_varinfo (stderr, vi); } -/* Print the pred graph in dot format. */ +/* Dump varmap to FILE. */ -static void -dump_pred_graph (class scc_info *si, FILE *file) +void +dump_varmap (FILE *file) { - unsigned int i; - - /* Only print the graph if it has already been initialized: */ - if (!graph) + if (varmap.length () == 0) return; - /* Prints the header of the dot file: */ - fprintf (file, "strict digraph {\n"); - fprintf (file, " node [\n shape = box\n ]\n"); - fprintf (file, " edge [\n fontsize = \"12\"\n ]\n"); - fprintf (file, "\n // List of nodes and complex constraints in " - "the constraint graph:\n"); - - /* The next lines print the nodes in the graph together with the - complex constraints attached to them. */ - for (i = 1; i < graph->size; i++) - { - if (i == FIRST_REF_NODE) - continue; - if (si->node_mapping[i] != i) - continue; - if (i < FIRST_REF_NODE) - fprintf (file, "\"%s\"", get_varinfo (i)->name); - else - fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name); - if (graph->points_to[i] - && !bitmap_empty_p (graph->points_to[i])) - { - if (i < FIRST_REF_NODE) - fprintf (file, "[label=\"%s = {", get_varinfo (i)->name); - else - fprintf (file, "[label=\"*%s = {", - get_varinfo (i - FIRST_REF_NODE)->name); - unsigned j; - bitmap_iterator bi; - EXECUTE_IF_SET_IN_BITMAP (graph->points_to[i], 0, j, bi) - fprintf (file, " %d", j); - fprintf (file, " }\"]"); - } - fprintf (file, ";\n"); - } + fprintf (file, "variables:\n"); - /* Go over the edges. */ - fprintf (file, "\n // Edges in the constraint graph:\n"); - for (i = 1; i < graph->size; i++) + for (unsigned int i = 0; i < varmap.length (); ++i) { - unsigned j; - bitmap_iterator bi; - if (si->node_mapping[i] != i) - continue; - EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[i], 0, j, bi) - { - unsigned from = si->node_mapping[j]; - if (from < FIRST_REF_NODE) - fprintf (file, "\"%s\"", get_varinfo (from)->name); - else - fprintf (file, "\"*%s\"", get_varinfo (from - FIRST_REF_NODE)->name); - fprintf (file, " -> "); - if (i < FIRST_REF_NODE) - fprintf (file, "\"%s\"", get_varinfo (i)->name); - else - fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name); - fprintf (file, ";\n"); - } + varinfo_t vi = get_varinfo (i); + dump_varinfo (file, vi); } - /* Prints the tail of the dot file. */ - fprintf (file, "}\n"); + fprintf (file, "\n"); } -/* Perform offline variable substitution, discovering equivalence - classes, and eliminating non-pointer variables. */ +/* Dump varmap to stderr. */ -static class scc_info * -perform_var_substitution (constraint_graph_t graph) +DEBUG_FUNCTION void +debug_varmap (void) { - unsigned int i; - unsigned int size = graph->size; - scc_info *si = new scc_info (size); - - bitmap_obstack_initialize (&iteration_obstack); - gcc_obstack_init (&equiv_class_obstack); - pointer_equiv_class_table = new hash_table (511); - location_equiv_class_table - = new hash_table (511); - pointer_equiv_class = 1; - location_equiv_class = 1; - - /* Condense the nodes, which means to find SCC's, count incoming - predecessors, and unite nodes in SCC's. */ - for (i = 1; i < FIRST_REF_NODE; i++) - if (!bitmap_bit_p (si->visited, si->node_mapping[i])) - condense_visit (graph, si, si->node_mapping[i]); - - if (dump_file && (dump_flags & TDF_GRAPH)) - { - fprintf (dump_file, "\n\n// The constraint graph before var-substitution " - "in dot format:\n"); - dump_pred_graph (si, dump_file); - fprintf (dump_file, "\n\n"); - } - - bitmap_clear (si->visited); - /* Actually the label the nodes for pointer equivalences */ - for (i = 1; i < FIRST_REF_NODE; i++) - if (!bitmap_bit_p (si->visited, si->node_mapping[i])) - label_visit (graph, si, si->node_mapping[i]); - - /* Calculate location equivalence labels. */ - for (i = 1; i < FIRST_REF_NODE; i++) - { - bitmap pointed_by; - bitmap_iterator bi; - unsigned int j; - - if (!graph->pointed_by[i]) - continue; - pointed_by = BITMAP_ALLOC (&iteration_obstack); - - /* Translate the pointed-by mapping for pointer equivalence - labels. */ - EXECUTE_IF_SET_IN_BITMAP (graph->pointed_by[i], 0, j, bi) - { - bitmap_set_bit (pointed_by, - graph->pointer_label[si->node_mapping[j]]); - } - /* The original pointed_by is now dead. */ - BITMAP_FREE (graph->pointed_by[i]); - - /* Look up the location equivalence label if one exists, or make - one otherwise. */ - equiv_class_label_t ecl; - ecl = equiv_class_lookup_or_add (location_equiv_class_table, pointed_by); - if (ecl->equivalence_class == 0) - ecl->equivalence_class = location_equiv_class++; - else - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Found location equivalence for node %s\n", - get_varinfo (i)->name); - BITMAP_FREE (pointed_by); - } - graph->loc_label[i] = ecl->equivalence_class; - - } - - if (dump_file && (dump_flags & TDF_DETAILS)) - for (i = 1; i < FIRST_REF_NODE; i++) - { - unsigned j = si->node_mapping[i]; - if (j != i) - { - fprintf (dump_file, "%s node id %d ", - bitmap_bit_p (graph->direct_nodes, i) - ? "Direct" : "Indirect", i); - if (i < FIRST_REF_NODE) - fprintf (dump_file, "\"%s\"", get_varinfo (i)->name); - else - fprintf (dump_file, "\"*%s\"", - get_varinfo (i - FIRST_REF_NODE)->name); - fprintf (dump_file, " mapped to SCC leader node id %d ", j); - if (j < FIRST_REF_NODE) - fprintf (dump_file, "\"%s\"\n", get_varinfo (j)->name); - else - fprintf (dump_file, "\"*%s\"\n", - get_varinfo (j - FIRST_REF_NODE)->name); - } - else - { - fprintf (dump_file, - "Equivalence classes for %s node id %d ", - bitmap_bit_p (graph->direct_nodes, i) - ? "direct" : "indirect", i); - if (i < FIRST_REF_NODE) - fprintf (dump_file, "\"%s\"", get_varinfo (i)->name); - else - fprintf (dump_file, "\"*%s\"", - get_varinfo (i - FIRST_REF_NODE)->name); - fprintf (dump_file, - ": pointer %d, location %d\n", - graph->pointer_label[i], graph->loc_label[i]); - } - } - - /* Quickly eliminate our non-pointer variables. */ - - for (i = 1; i < FIRST_REF_NODE; i++) - { - unsigned int node = si->node_mapping[i]; - - if (graph->pointer_label[node] == 0) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - "%s is a non-pointer variable, eliminating edges.\n", - get_varinfo (node)->name); - stats.nonpointer_vars++; - clear_edges_for_node (graph, node); - } - } - - return si; + dump_varmap (stderr); } -/* Free information that was only necessary for variable - substitution. */ +} // namespace pointer_analysis -static void -free_var_substitution_info (class scc_info *si) -{ - delete si; - free (graph->pointer_label); - free (graph->loc_label); - free (graph->pointed_by); - free (graph->points_to); - free (graph->eq_rep); - sbitmap_free (graph->direct_nodes); - delete pointer_equiv_class_table; - pointer_equiv_class_table = NULL; - delete location_equiv_class_table; - location_equiv_class_table = NULL; - obstack_free (&equiv_class_obstack, NULL); - bitmap_obstack_release (&iteration_obstack); -} -/* Return an existing node that is equivalent to NODE, which has - equivalence class LABEL, if one exists. Return NODE otherwise. */ +using namespace pointer_analysis; -static unsigned int -find_equivalent_node (constraint_graph_t graph, - unsigned int node, unsigned int label) -{ - /* If the address version of this variable is unused, we can - substitute it for anything else with the same label. - Otherwise, we know the pointers are equivalent, but not the - locations, and we can unite them later. */ +static bool use_field_sensitive = true; +static int in_ipa_mode = 0; - if (!bitmap_bit_p (graph->address_taken, node)) - { - gcc_checking_assert (label < graph->size); +static unsigned int create_variable_info_for (tree, const char *, bool); +static varinfo_t lookup_vi_for_tree (tree); +static inline bool type_can_have_subvars (const_tree); +static void make_param_constraints (varinfo_t); - if (graph->eq_rep[label] != -1) - { - /* Unify the two variables since we know they are equivalent. */ - if (unite (graph->eq_rep[label], node)) - unify_nodes (graph, graph->eq_rep[label], node, false); - return graph->eq_rep[label]; - } - else - { - graph->eq_rep[label] = node; - graph->pe_rep[label] = node; - } - } - else - { - gcc_checking_assert (label < graph->size); - graph->pe[node] = label; - if (graph->pe_rep[label] == -1) - graph->pe_rep[label] = node; - } +/* Pool of variable info structures. */ +static object_allocator variable_info_pool + ("Variable info pool"); - return node; -} +/* Map varinfo to final pt_solution. */ +static hash_map *final_solutions; +static struct obstack final_solutions_obstack; -/* Unite pointer equivalent but not location equivalent nodes in - GRAPH. This may only be performed once variable substitution is - finished. */ +/* Return a new variable info structure consisting for a variable + named NAME, and using constraint graph node NODE. Append it + to the vector of variable info structures. */ -static void -unite_pointer_equivalences (constraint_graph_t graph) +static varinfo_t +new_var_info (tree t, const char *name, bool add_id) { - unsigned int i; + unsigned index = varmap.length (); + varinfo_t ret = variable_info_pool.allocate (); - /* Go through the pointer equivalences and unite them to their - representative, if they aren't already. */ - for (i = 1; i < FIRST_REF_NODE; i++) + if (dump_file && add_id) { - unsigned int label = graph->pe[i]; - if (label) - { - int label_rep = graph->pe_rep[label]; - - if (label_rep == -1) - continue; - - label_rep = find (label_rep); - if (label_rep >= 0 && unite (label_rep, find (i))) - unify_nodes (graph, label_rep, i, false); - } + char *tempname = xasprintf ("%s(%d)", name, index); + name = ggc_strdup (tempname); + free (tempname); } -} -/* Move complex constraints to the GRAPH nodes they belong to. */ + ret->id = index; + ret->name = name; + ret->decl = t; + /* Vars without decl are artificial and do not have sub-variables. */ + ret->is_artificial_var = (t == NULL_TREE); + ret->is_special_var = false; + ret->is_unknown_size_var = false; + ret->is_full_var = (t == NULL_TREE); + ret->is_heap_var = false; + ret->may_have_pointers = true; + ret->only_restrict_pointers = false; + ret->is_restrict_var = false; + ret->ruid = 0; + ret->is_global_var = (t == NULL_TREE); + ret->is_ipa_escape_point = false; + ret->is_fn_info = false; + ret->address_taken = false; + if (t && DECL_P (t)) + ret->is_global_var = (is_global_var (t) + /* We have to treat even local register variables + as escape points. */ + || (VAR_P (t) && DECL_HARD_REGISTER (t))); + ret->is_reg_var = (t && TREE_CODE (t) == SSA_NAME); + ret->solution = BITMAP_ALLOC (&pta_obstack); + ret->oldsolution = NULL; + ret->next = 0; + ret->shadow_var_uid = 0; + ret->head = ret->id; -static void -move_complex_constraints (constraint_graph_t graph) -{ - int i; - constraint_t c; + stats.total_vars++; - FOR_EACH_VEC_ELT (constraints, i, c) - { - if (c) - { - struct constraint_expr lhs = c->lhs; - struct constraint_expr rhs = c->rhs; + varmap.safe_push (ret); - if (lhs.type == DEREF) - { - insert_into_complex (graph, lhs.var, c); - } - else if (rhs.type == DEREF) - { - if (!(get_varinfo (lhs.var)->is_special_var)) - insert_into_complex (graph, rhs.var, c); - } - else if (rhs.type != ADDRESSOF && lhs.var > anything_id - && (lhs.offset != 0 || rhs.offset != 0)) - { - insert_into_complex (graph, rhs.var, c); - } - } - } + return ret; } +/* A map mapping call statements to per-stmt variables for uses + and clobbers specific to the call. */ +static hash_map *call_stmt_vars; -/* Optimize and rewrite complex constraints while performing - collapsing of equivalent nodes. SI is the SCC_INFO that is the - result of perform_variable_substitution. */ +/* Lookup or create the variable for the call statement CALL. */ -static void -rewrite_constraints (constraint_graph_t graph, - class scc_info *si) +static varinfo_t +get_call_vi (gcall *call) { - int i; - constraint_t c; - - if (flag_checking) - { - for (unsigned int j = 0; j < graph->size; j++) - gcc_assert (find (j) == j); - } + varinfo_t vi, vi2; - FOR_EACH_VEC_ELT (constraints, i, c) - { - struct constraint_expr lhs = c->lhs; - struct constraint_expr rhs = c->rhs; - unsigned int lhsvar = find (lhs.var); - unsigned int rhsvar = find (rhs.var); - unsigned int lhsnode, rhsnode; - unsigned int lhslabel, rhslabel; - - lhsnode = si->node_mapping[lhsvar]; - rhsnode = si->node_mapping[rhsvar]; - lhslabel = graph->pointer_label[lhsnode]; - rhslabel = graph->pointer_label[rhsnode]; - - /* See if it is really a non-pointer variable, and if so, ignore - the constraint. */ - if (lhslabel == 0) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - { + bool existed; + varinfo_t *slot_p = &call_stmt_vars->get_or_insert (call, &existed); + if (existed) + return *slot_p; - fprintf (dump_file, "%s is a non-pointer variable, " - "ignoring constraint:", - get_varinfo (lhs.var)->name); - dump_constraint (dump_file, c); - fprintf (dump_file, "\n"); - } - constraints[i] = NULL; - continue; - } + vi = new_var_info (NULL_TREE, "CALLUSED", true); + vi->offset = 0; + vi->size = 1; + vi->fullsize = 2; + vi->is_full_var = true; + vi->is_reg_var = true; - if (rhslabel == 0) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - { + vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true); + vi2->offset = 1; + vi2->size = 1; + vi2->fullsize = 2; + vi2->is_full_var = true; + vi2->is_reg_var = true; - fprintf (dump_file, "%s is a non-pointer variable, " - "ignoring constraint:", - get_varinfo (rhs.var)->name); - dump_constraint (dump_file, c); - fprintf (dump_file, "\n"); - } - constraints[i] = NULL; - continue; - } + vi->next = vi2->id; - lhsvar = find_equivalent_node (graph, lhsvar, lhslabel); - rhsvar = find_equivalent_node (graph, rhsvar, rhslabel); - c->lhs.var = lhsvar; - c->rhs.var = rhsvar; - } + *slot_p = vi; + return vi; } -/* Eliminate indirect cycles involving NODE. Return true if NODE was - part of an SCC, false otherwise. */ +/* Lookup the variable for the call statement CALL representing + the uses. Returns NULL if there is nothing special about this call. */ -static bool -eliminate_indirect_cycles (unsigned int node) +static varinfo_t +lookup_call_use_vi (gcall *call) { - if (graph->indirect_cycles[node] != -1 - && !bitmap_empty_p (get_varinfo (node)->solution)) - { - unsigned int i; - auto_vec queue; - int queuepos; - unsigned int to = find (graph->indirect_cycles[node]); - bitmap_iterator bi; - - /* We can't touch the solution set and call unify_nodes - at the same time, because unify_nodes is going to do - bitmap unions into it. */ - - EXECUTE_IF_SET_IN_BITMAP (get_varinfo (node)->solution, 0, i, bi) - { - if (find (i) == i && i != to) - { - if (unite (to, i)) - queue.safe_push (i); - } - } + varinfo_t *slot_p = call_stmt_vars->get (call); + if (slot_p) + return *slot_p; - for (queuepos = 0; - queue.iterate (queuepos, &i); - queuepos++) - { - unify_nodes (graph, to, i, true); - } - return true; - } - return false; + return NULL; } -/* Solve the constraint graph GRAPH using our worklist solver. - This is based on the PW* family of solvers from the "Efficient Field - Sensitive Pointer Analysis for C" paper. - It works by iterating over all the graph nodes, processing the complex - constraints and propagating the copy constraints, until everything stops - changed. This corresponds to steps 6-8 in the solving list given above. */ +/* Lookup the variable for the call statement CALL representing + the clobbers. Returns NULL if there is nothing special about this call. */ -static void -solve_graph (constraint_graph_t graph) +static varinfo_t +lookup_call_clobber_vi (gcall *call) { - unsigned int size = graph->size; - unsigned int i; - bitmap pts; - - changed = BITMAP_ALLOC (NULL); - - /* Mark all initial non-collapsed nodes as changed. */ - for (i = 1; i < size; i++) - { - varinfo_t ivi = get_varinfo (i); - if (find (i) == i && !bitmap_empty_p (ivi->solution) - && ((graph->succs[i] && !bitmap_empty_p (graph->succs[i])) - || graph->complex[i].length () > 0)) - bitmap_set_bit (changed, i); - } - - /* Allocate a bitmap to be used to store the changed bits. */ - pts = BITMAP_ALLOC (&pta_obstack); - - while (!bitmap_empty_p (changed)) - { - unsigned int i; - stats.iterations++; - - bitmap_obstack_initialize (&iteration_obstack); - - auto_vec topo_order = compute_topo_order (graph); - while (topo_order.length () != 0) - { - i = topo_order.pop (); - - /* If this variable is not a representative, skip it. */ - if (find (i) != i) - continue; - - /* In certain indirect cycle cases, we may merge this - variable to another. */ - if (eliminate_indirect_cycles (i) && find (i) != i) - continue; + varinfo_t uses = lookup_call_use_vi (call); + if (!uses) + return NULL; - /* If the node has changed, we need to process the - complex constraints and outgoing edges again. For complex - constraints that modify i itself, like the common group of - callarg = callarg + UNKNOWN; - callarg = *callarg + UNKNOWN; - *callarg = callescape; - make sure to iterate immediately because that maximizes - cache reuse and expands the graph quickest, leading to - better visitation order in the next iteration. */ - while (bitmap_clear_bit (changed, i)) - { - bitmap solution; - vec &complex = graph->complex[i]; - varinfo_t vi = get_varinfo (i); - bool solution_empty; - - /* Compute the changed set of solution bits. If anything - is in the solution just propagate that. */ - if (bitmap_bit_p (vi->solution, anything_id)) - { - /* If anything is also in the old solution there is - nothing to do. - ??? But we shouldn't ended up with "changed" set ... */ - if (vi->oldsolution - && bitmap_bit_p (vi->oldsolution, anything_id)) - break; - bitmap_copy (pts, get_varinfo (find (anything_id))->solution); - } - else if (vi->oldsolution) - bitmap_and_compl (pts, vi->solution, vi->oldsolution); - else - bitmap_copy (pts, vi->solution); + return vi_next (uses); +} - if (bitmap_empty_p (pts)) - break; +/* Lookup or create the variable for the call statement CALL representing + the uses. */ - if (vi->oldsolution) - bitmap_ior_into (vi->oldsolution, pts); - else - { - vi->oldsolution = BITMAP_ALLOC (&oldpta_obstack); - bitmap_copy (vi->oldsolution, pts); - } +static varinfo_t +get_call_use_vi (gcall *call) +{ + return get_call_vi (call); +} - solution = vi->solution; - solution_empty = bitmap_empty_p (solution); +/* Lookup or create the variable for the call statement CALL representing + the clobbers. */ - /* Process the complex constraints */ - hash_set *cvisited = nullptr; - if (flag_checking) - cvisited = new hash_set; - bitmap expanded_pts = NULL; - for (unsigned j = 0; j < complex.length (); ++j) - { - constraint_t c = complex[j]; - /* At unification time only the directly involved nodes - will get their complex constraints updated. Update - our complex constraints now but keep the constraint - vector sorted and clear of duplicates. Also make - sure to evaluate each prevailing constraint only once. */ - unsigned int new_lhs = find (c->lhs.var); - unsigned int new_rhs = find (c->rhs.var); - if (c->lhs.var != new_lhs || c->rhs.var != new_rhs) - { - constraint tem = *c; - tem.lhs.var = new_lhs; - tem.rhs.var = new_rhs; - unsigned int place - = complex.lower_bound (&tem, constraint_less); - c->lhs.var = new_lhs; - c->rhs.var = new_rhs; - if (place != j) - { - complex.ordered_remove (j); - if (j < place) - --place; - if (place < complex.length ()) - { - if (constraint_equal (*complex[place], *c)) - { - j--; - continue; - } - else - complex.safe_insert (place, c); - } - else - complex.quick_push (c); - if (place > j) - { - j--; - continue; - } - } - } +static varinfo_t ATTRIBUTE_UNUSED +get_call_clobber_vi (gcall *call) +{ + return vi_next (get_call_vi (call)); +} - /* The only complex constraint that can change our - solution to non-empty, given an empty solution, - is a constraint where the lhs side is receiving - some set from elsewhere. */ - if (cvisited && cvisited->add (c)) - gcc_unreachable (); - if (!solution_empty || c->lhs.type != DEREF) - do_complex_constraint (graph, c, pts, &expanded_pts); - } - if (cvisited) - { - /* When checking, verify the order of constraints is - maintained and each constraint is evaluated exactly - once. */ - for (unsigned j = 1; j < complex.length (); ++j) - gcc_assert (constraint_less (complex[j-1], complex[j])); - gcc_assert (cvisited->elements () == complex.length ()); - delete cvisited; - } - BITMAP_FREE (expanded_pts); - solution_empty = bitmap_empty_p (solution); +static void get_constraint_for_1 (tree, vec *, bool, bool); +static void get_constraint_for (tree, vec *); +static void get_constraint_for_rhs (tree, vec *); +static void do_deref (vec *); - if (!solution_empty) - { - bitmap_iterator bi; - unsigned eff_escaped_id = find (escaped_id); - unsigned j; +/* Allocator for 'constraints' vector. */ - /* Propagate solution to all successors. */ - unsigned to_remove = ~0U; - EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i], - 0, j, bi) - { - if (to_remove != ~0U) - { - bitmap_clear_bit (graph->succs[i], to_remove); - to_remove = ~0U; - } - unsigned int to = find (j); - if (to != j) - { - /* Update the succ graph, avoiding duplicate - work. */ - to_remove = j; - if (! bitmap_set_bit (graph->succs[i], to)) - continue; - /* We eventually end up processing 'to' twice - as it is undefined whether bitmap iteration - iterates over bits set during iteration. - Play safe instead of doing tricks. */ - } - /* Don't try to propagate to ourselves. */ - if (to == i) - { - to_remove = j; - continue; - } - /* Early node unification can lead to edges from - escaped - remove them. */ - if (i == eff_escaped_id) - { - to_remove = j; - if (bitmap_set_bit (get_varinfo (to)->solution, - escaped_id)) - bitmap_set_bit (changed, to); - continue; - } +static object_allocator constraint_pool ("Constraint pool"); - if (bitmap_ior_into (get_varinfo (to)->solution, pts)) - bitmap_set_bit (changed, to); - } - if (to_remove != ~0U) - bitmap_clear_bit (graph->succs[i], to_remove); - } - } - } - bitmap_obstack_release (&iteration_obstack); - } +/* Create a new constraint consisting of LHS and RHS expressions. */ - BITMAP_FREE (pts); - BITMAP_FREE (changed); - bitmap_obstack_release (&oldpta_obstack); +static constraint_t +new_constraint (const struct constraint_expr lhs, + const struct constraint_expr rhs) +{ + constraint_t ret = constraint_pool.allocate (); + ret->lhs = lhs; + ret->rhs = rhs; + return ret; } -/* Map from trees to variable infos. */ -static hash_map *vi_for_tree; - - /* Insert ID as the variable id for tree T in the vi_for_tree map. */ static void @@ -3003,7 +734,7 @@ lookup_vi_for_tree (tree t) return *slot; } -/* Return a printable name for DECL */ +/* Return a printable name for DECL. */ static const char * alias_get_name (tree decl) @@ -3191,10 +922,10 @@ process_constraint (constraint_t t) if (!get_varinfo (lhs.var)->may_have_pointers) return; - /* This can happen in our IR with things like n->a = *p */ + /* This can happen in our IR with things like n->a = *p. */ if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id) { - /* Split into tmp = *rhs, *lhs = tmp */ + /* Split into tmp = *rhs, *lhs = tmp. */ struct constraint_expr tmplhs; tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp", true); process_constraint (new_constraint (tmplhs, rhs)); @@ -3202,7 +933,7 @@ process_constraint (constraint_t t) } else if ((rhs.type != SCALAR || rhs.offset != 0) && lhs.type == DEREF) { - /* Split into tmp = &rhs, *lhs = tmp */ + /* Split into tmp = &rhs, *lhs = tmp. */ struct constraint_expr tmplhs; tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp", true); process_constraint (new_constraint (tmplhs, rhs)); @@ -3370,7 +1101,7 @@ get_constraint_for_component_ref (tree t, vec *results, tree forzero; /* Some people like to do cute things like take the address of - &0->a.b */ + &0->a.b. */ forzero = t; while (handled_component_p (forzero) || INDIRECT_REF_P (forzero) @@ -3444,7 +1175,7 @@ get_constraint_for_component_ref (tree t, vec *results, { /* In languages like C, you can access one past the end of an array. You aren't allowed to dereference it, so we can - ignore this constraint. When we handle pointer subtraction, + ignore this constraint. When we handle pointer subtraction, we may have to do something cute here. */ if (maybe_lt (poly_uint64 (bitpos), get_varinfo (result.var)->fullsize) @@ -3481,7 +1212,7 @@ get_constraint_for_component_ref (tree t, vec *results, results->safe_push (cexpr); } else if (results->length () == 0) - /* Assert that we found *some* field there. The user couldn't be + /* Assert that we found *some* field there. The user couldn't be accessing *only* padding. */ /* Still the user could access one past the end of an array embedded in a struct resulting in accessing *only* padding. */ @@ -3535,7 +1266,7 @@ get_constraint_for_component_ref (tree t, vec *results, /* Dereference the constraint expression CONS, and return the result. DEREF (ADDRESSOF) = SCALAR DEREF (SCALAR) = DEREF - DEREF (DEREF) = (temp = DEREF1; result = DEREF(temp)) + DEREF (DEREF) = (temp = DEREF1; result = DEREF (temp)) This is needed so that we can handle dereferencing DEREF constraints. */ static void @@ -3594,7 +1325,7 @@ get_constraint_for_1 (tree t, vec *results, bool address_p, point to anything by itself. That is, of course, unless it is an integer constant being treated as a pointer, in which case, we will return that this is really the addressof anything. This - happens below, since it will fall into the default case. The only + happens below, since it will fall into the default case. The only case we know something about an integer treated like a pointer is when it is the NULL pointer, and then we just say it points to NULL. @@ -3690,7 +1421,10 @@ get_constraint_for_1 (tree t, vec *results, bool address_p, size = -1; for (; curr; curr = vi_next (curr)) { - if (curr->offset - vi->offset < size) + /* The start of the access might happen anywhere + within vi, so conservatively assume it was + at its end. */ + if (curr->offset - (vi->offset + vi->size - 1) < size) { cs.var = curr->id; results->safe_push (cs); @@ -3742,7 +1476,7 @@ get_constraint_for_1 (tree t, vec *results, bool address_p, tmp.truncate (0); } /* We do not know whether the constructor was complete, - so technically we have to add &NOTHING or &ANYTHING + so technically we have to add &NOTHING or &ANYTHING like we do for an empty constructor as well. */ return; } @@ -4141,7 +1875,7 @@ get_function_part_constraint (varinfo_t fi, unsigned part) /* Produce constraints for argument ARG of call STMT with eaf flags FLAGS. RESULTS is array holding constraints for return value. CALLESCAPE_ID is variable where call loocal escapes are added. - WRITES_GLOVEL_MEMORY is true if callee may write global memory. */ + WRITES_GLOVEL_MEMORY is true if callee may write global memory. */ static void handle_call_arg (gcall *stmt, tree arg, vec *results, int flags, @@ -4507,7 +2241,7 @@ handle_lhs_call (gcall *stmt, tree lhs, int flags, vec &rhsc, rhsc.truncate (0); vi = make_heapvar ("HEAP", true); /* We are marking allocated storage local, we deal with it becoming - global by escaping and setting of vars_contains_escaped_heap. */ + global by escaping and setting of vars_contains_escaped_heap. */ DECL_EXTERNAL (vi->decl) = 0; vi->is_global_var = 0; /* If this is not a real malloc call assume the memory was @@ -4695,8 +2429,8 @@ find_func_aliases_for_builtin_call (struct function *fn, gcall *t) } case BUILT_IN_STACK_SAVE: case BUILT_IN_STACK_RESTORE: - /* Nothing interesting happens. */ - return true; + /* Nothing interesting happens. */ + return true; case BUILT_IN_ALLOCA: case BUILT_IN_ALLOCA_WITH_ALIGN: case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX: @@ -4720,7 +2454,7 @@ find_func_aliases_for_builtin_call (struct function *fn, gcall *t) return true; } case BUILT_IN_POSIX_MEMALIGN: - { + { tree ptrptr = gimple_call_arg (t, 0); get_constraint_for (ptrptr, &lhsc); do_deref (&lhsc); @@ -4803,7 +2537,7 @@ find_func_aliases_for_builtin_call (struct function *fn, gcall *t) } break; /* String / character search functions return a pointer into the - source string or NULL. */ + source string or NULL. */ case BUILT_IN_INDEX: case BUILT_IN_STRCHR: case BUILT_IN_STRRCHR: @@ -4824,7 +2558,7 @@ find_func_aliases_for_builtin_call (struct function *fn, gcall *t) } return true; /* Pure functions that return something not based on any object and - that use the memory pointed to by their arguments (but not + that use the memory pointed to by their arguments (but not transitively). */ case BUILT_IN_STRCMP: case BUILT_IN_STRCMP_EQ: @@ -5189,7 +2923,7 @@ find_func_aliases (struct function *fn, gimple *origt) } } /* In IPA mode, we need to generate constraints to pass call - arguments through their calls. There are two cases, + arguments through their calls. There are two cases, either a GIMPLE_CALL returning a value, or just a plain GIMPLE_CALL when we are not. @@ -5334,7 +3068,7 @@ find_func_aliases (struct function *fn, gimple *origt) constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); oconstraints[i] = constraint; parse_output_constraint (&constraint, i, 0, 0, &allows_mem, - &allows_reg, &is_inout); + &allows_reg, &is_inout, nullptr); /* A memory constraint makes the address of the operand escape. */ if (!allows_reg && allows_mem) @@ -5367,7 +3101,7 @@ find_func_aliases (struct function *fn, gimple *origt) constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints, - &allows_mem, &allows_reg); + &allows_mem, &allows_reg, nullptr); /* A memory constraint makes the address of the operand escape. */ if (!allows_reg && allows_mem) @@ -5442,7 +3176,7 @@ find_func_clobbers (struct function *fn, gimple *origt) || (TREE_CODE (tem) == MEM_REF && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR && auto_var_in_fn_p - (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl)))) + (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl)))) { struct constraint_expr lhsc, *rhsp; unsigned i; @@ -5471,7 +3205,7 @@ find_func_clobbers (struct function *fn, gimple *origt) || (TREE_CODE (tem) == MEM_REF && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR && auto_var_in_fn_p - (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl)))) + (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl)))) { struct constraint_expr lhs, *rhsp; unsigned i; @@ -5758,87 +3492,28 @@ find_func_clobbers (struct function *fn, gimple *origt) return; } - /* Otherwise the caller clobbers and uses what the callee does. - ??? This should use a new complex constraint that filters - local variables of the callee. */ - if (gimple_vdef (t)) - { - lhs = get_function_part_constraint (fi, fi_clobbers); - rhs = get_function_part_constraint (cfi, fi_clobbers); - process_constraint (new_constraint (lhs, rhs)); - } - lhs = get_function_part_constraint (fi, fi_uses); - rhs = get_function_part_constraint (cfi, fi_uses); - process_constraint (new_constraint (lhs, rhs)); - } - else if (gimple_code (t) == GIMPLE_ASM) - { - /* ??? Ick. We can do better. */ - if (gimple_vdef (t)) - make_constraint_from (first_vi_for_offset (fi, fi_clobbers), - anything_id); - make_constraint_from (first_vi_for_offset (fi, fi_uses), - anything_id); - } -} - - -/* Find the first varinfo in the same variable as START that overlaps with - OFFSET. Return NULL if we can't find one. */ - -static varinfo_t -first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset) -{ - /* If the offset is outside of the variable, bail out. */ - if (offset >= start->fullsize) - return NULL; - - /* If we cannot reach offset from start, lookup the first field - and start from there. */ - if (start->offset > offset) - start = get_varinfo (start->head); - - while (start) - { - /* We may not find a variable in the field list with the actual - offset when we have glommed a structure to a variable. - In that case, however, offset should still be within the size - of the variable. */ - if (offset >= start->offset - && (offset - start->offset) < start->size) - return start; - - start = vi_next (start); - } - - return NULL; -} - -/* Find the first varinfo in the same variable as START that overlaps with - OFFSET. If there is no such varinfo the varinfo directly preceding - OFFSET is returned. */ - -static varinfo_t -first_or_preceding_vi_for_offset (varinfo_t start, - unsigned HOST_WIDE_INT offset) -{ - /* If we cannot reach offset from start, lookup the first field - and start from there. */ - if (start->offset > offset) - start = get_varinfo (start->head); - - /* We may not find a variable in the field list with the actual - offset when we have glommed a structure to a variable. - In that case, however, offset should still be within the size - of the variable. - If we got beyond the offset we look for return the field - directly preceding offset which may be the last field. */ - while (start->next - && offset >= start->offset - && !((offset - start->offset) < start->size)) - start = vi_next (start); - - return start; + /* Otherwise the caller clobbers and uses what the callee does. + ??? This should use a new complex constraint that filters + local variables of the callee. */ + if (gimple_vdef (t)) + { + lhs = get_function_part_constraint (fi, fi_clobbers); + rhs = get_function_part_constraint (cfi, fi_clobbers); + process_constraint (new_constraint (lhs, rhs)); + } + lhs = get_function_part_constraint (fi, fi_uses); + rhs = get_function_part_constraint (cfi, fi_uses); + process_constraint (new_constraint (lhs, rhs)); + } + else if (gimple_code (t) == GIMPLE_ASM) + { + /* ??? Ick. We can do better. */ + if (gimple_vdef (t)) + make_constraint_from (first_vi_for_offset (fi, fi_clobbers), + anything_id); + make_constraint_from (first_vi_for_offset (fi, fi_uses), + anything_id); + } } @@ -5868,7 +3543,7 @@ struct fieldoff typedef struct fieldoff fieldoff_s; -/* qsort comparison function for two fieldoff's PA and PB */ +/* qsort comparison function for two fieldoff's PA and PB. */ static int fieldoff_compare (const void *pa, const void *pb) @@ -6596,38 +4271,6 @@ create_variable_info_for (tree decl, const char *name, bool add_id) return id; } -/* Print out the points-to solution for VAR to FILE. */ - -static void -dump_solution_for_var (FILE *file, unsigned int var) -{ - varinfo_t vi = get_varinfo (var); - unsigned int i; - bitmap_iterator bi; - - /* Dump the solution for unified vars anyway, this avoids difficulties - in scanning dumps in the testsuite. */ - fprintf (file, "%s = { ", vi->name); - vi = get_varinfo (find (var)); - EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi) - fprintf (file, "%s ", get_varinfo (i)->name); - fprintf (file, "}"); - - /* But note when the variable was unified. */ - if (vi->id != var) - fprintf (file, " same as %s", vi->name); - - fprintf (file, "\n"); -} - -/* Print the points-to solution for VAR to stderr. */ - -DEBUG_FUNCTION void -debug_solution_for_var (unsigned int var) -{ - dump_solution_for_var (stderr, var); -} - /* Register the constraints for function parameter related VI. */ static void @@ -6715,7 +4358,7 @@ struct shared_bitmap_hasher : free_ptr_hash const shared_bitmap_info *); }; -/* Hash function for a shared_bitmap_info_t */ +/* Hash function for a shared_bitmap_info_t. */ inline hashval_t shared_bitmap_hasher::hash (const shared_bitmap_info *bi) @@ -6723,7 +4366,7 @@ shared_bitmap_hasher::hash (const shared_bitmap_info *bi) return bi->hashcode; } -/* Equality function for two shared_bitmap_info_t's. */ +/* Equality function for two shared_bitmap_info_t's. */ inline bool shared_bitmap_hasher::equal (const shared_bitmap_info *sbi1, @@ -6781,8 +4424,8 @@ set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt, { unsigned int i; bitmap_iterator bi; - varinfo_t escaped_vi = get_varinfo (find (escaped_id)); - varinfo_t escaped_return_vi = get_varinfo (find (escaped_return_id)); + varinfo_t escaped_vi = get_varinfo (var_rep[escaped_id]); + varinfo_t escaped_return_vi = get_varinfo (var_rep[escaped_return_id]); bool everything_escaped = escaped_vi->solution && bitmap_bit_p (escaped_vi->solution, anything_id); @@ -6880,7 +4523,7 @@ find_what_var_points_to (tree fndecl, varinfo_t orig_vi) /* This variable may have been collapsed, let's get the real variable. */ - vi = get_varinfo (find (orig_vi->id)); + vi = get_varinfo (var_rep[orig_vi->id]); /* See if we have already computed the solution and return it. */ pt_solution **slot = &final_solutions->get_or_insert (vi); @@ -6907,7 +4550,7 @@ find_what_var_points_to (tree fndecl, varinfo_t orig_vi) else pt->escaped = 1; /* Expand some special vars of ESCAPED in-place here. */ - varinfo_t evi = get_varinfo (find (escaped_id)); + varinfo_t evi = get_varinfo (var_rep[escaped_id]); if (bitmap_bit_p (evi->solution, nonlocal_id)) pt->nonlocal = 1; } @@ -7134,7 +4777,7 @@ pt_solution_includes_global (struct pt_solution *pt, bool escaped_local_p) || pt->nonlocal || pt->vars_contains_nonlocal /* The following is a hack to make the malloc escape hack work. - In reality we'd need different sets for escaped-through-return + In reality we'd need different sets for escaped-through-return and escaped-to-callees and passes would need to be updated. */ || pt->vars_contains_escaped_heap) return true; @@ -7270,52 +4913,6 @@ pt_solutions_intersect (struct pt_solution *pt1, struct pt_solution *pt2) return res; } -/* Dump stats information to OUTFILE. */ - -static void -dump_sa_stats (FILE *outfile) -{ - fprintf (outfile, "Points-to Stats:\n"); - fprintf (outfile, "Total vars: %d\n", stats.total_vars); - fprintf (outfile, "Non-pointer vars: %d\n", - stats.nonpointer_vars); - fprintf (outfile, "Statically unified vars: %d\n", - stats.unified_vars_static); - fprintf (outfile, "Dynamically unified vars: %d\n", - stats.unified_vars_dynamic); - fprintf (outfile, "Iterations: %d\n", stats.iterations); - fprintf (outfile, "Number of edges: %d\n", stats.num_edges); - fprintf (outfile, "Number of implicit edges: %d\n", - stats.num_implicit_edges); - fprintf (outfile, "Number of avoided edges: %d\n", - stats.num_avoided_edges); -} - -/* Dump points-to information to OUTFILE. */ - -static void -dump_sa_points_to_info (FILE *outfile) -{ - fprintf (outfile, "\nPoints-to sets\n\n"); - - for (unsigned i = 1; i < varmap.length (); i++) - { - varinfo_t vi = get_varinfo (i); - if (!vi->may_have_pointers) - continue; - dump_solution_for_var (outfile, i); - } -} - - -/* Debug points-to information to stderr. */ - -DEBUG_FUNCTION void -debug_sa_points_to_info (void) -{ - dump_sa_points_to_info (stderr); -} - /* Initialize the always-existing constraint variables for NULL ANYTHING, READONLY, and INTEGER */ @@ -7508,7 +5105,7 @@ init_base_vars (void) process_constraint (new_constraint (lhs, rhs)); } -/* Initialize things necessary to perform PTA */ +/* Initialize things necessary to perform PTA. */ static void init_alias_vars (void) @@ -7517,7 +5114,6 @@ init_alias_vars (void) bitmap_obstack_initialize (&pta_obstack); bitmap_obstack_initialize (&oldpta_obstack); - bitmap_obstack_initialize (&predbitmap_obstack); constraints.create (8); varmap.create (8); @@ -7534,144 +5130,6 @@ init_alias_vars (void) gcc_obstack_init (&final_solutions_obstack); } -/* Remove the REF and ADDRESS edges from GRAPH, as well as all the - predecessor edges. */ - -static void -remove_preds_and_fake_succs (constraint_graph_t graph) -{ - unsigned int i; - - /* Clear the implicit ref and address nodes from the successor - lists. */ - for (i = 1; i < FIRST_REF_NODE; i++) - { - if (graph->succs[i]) - bitmap_clear_range (graph->succs[i], FIRST_REF_NODE, - FIRST_REF_NODE * 2); - } - - /* Free the successor list for the non-ref nodes. */ - for (i = FIRST_REF_NODE + 1; i < graph->size; i++) - { - if (graph->succs[i]) - BITMAP_FREE (graph->succs[i]); - } - - /* Now reallocate the size of the successor list as, and blow away - the predecessor bitmaps. */ - graph->size = varmap.length (); - graph->succs = XRESIZEVEC (bitmap, graph->succs, graph->size); - - free (graph->implicit_preds); - graph->implicit_preds = NULL; - free (graph->preds); - graph->preds = NULL; - bitmap_obstack_release (&predbitmap_obstack); -} - -/* Solve the constraint set. */ - -static void -solve_constraints (void) -{ - class scc_info *si; - - /* Sort varinfos so that ones that cannot be pointed to are last. - This makes bitmaps more efficient. */ - unsigned int *map = XNEWVEC (unsigned int, varmap.length ()); - for (unsigned i = 0; i < integer_id + 1; ++i) - map[i] = i; - /* Start with address-taken vars, followed by not address-taken vars - to move vars never appearing in the points-to solution bitmaps last. */ - unsigned j = integer_id + 1; - for (unsigned i = integer_id + 1; i < varmap.length (); ++i) - if (varmap[varmap[i]->head]->address_taken) - map[i] = j++; - for (unsigned i = integer_id + 1; i < varmap.length (); ++i) - if (! varmap[varmap[i]->head]->address_taken) - map[i] = j++; - /* Shuffle varmap according to map. */ - for (unsigned i = integer_id + 1; i < varmap.length (); ++i) - { - while (map[varmap[i]->id] != i) - std::swap (varmap[i], varmap[map[varmap[i]->id]]); - gcc_assert (bitmap_empty_p (varmap[i]->solution)); - varmap[i]->id = i; - varmap[i]->next = map[varmap[i]->next]; - varmap[i]->head = map[varmap[i]->head]; - } - /* Finally rewrite constraints. */ - for (unsigned i = 0; i < constraints.length (); ++i) - { - constraints[i]->lhs.var = map[constraints[i]->lhs.var]; - constraints[i]->rhs.var = map[constraints[i]->rhs.var]; - } - free (map); - - if (dump_file) - fprintf (dump_file, - "\nCollapsing static cycles and doing variable " - "substitution\n"); - - init_graph (varmap.length () * 2); - - if (dump_file) - fprintf (dump_file, "Building predecessor graph\n"); - build_pred_graph (); - - if (dump_file) - fprintf (dump_file, "Detecting pointer and location " - "equivalences\n"); - si = perform_var_substitution (graph); - - if (dump_file) - fprintf (dump_file, "Rewriting constraints and unifying " - "variables\n"); - rewrite_constraints (graph, si); - - build_succ_graph (); - - free_var_substitution_info (si); - - /* Attach complex constraints to graph nodes. */ - move_complex_constraints (graph); - - if (dump_file) - fprintf (dump_file, "Uniting pointer but not location equivalent " - "variables\n"); - unite_pointer_equivalences (graph); - - if (dump_file) - fprintf (dump_file, "Finding indirect cycles\n"); - find_indirect_cycles (graph); - - /* Implicit nodes and predecessors are no longer necessary at this - point. */ - remove_preds_and_fake_succs (graph); - - if (dump_file && (dump_flags & TDF_GRAPH)) - { - fprintf (dump_file, "\n\n// The constraint graph before solve-graph " - "in dot format:\n"); - dump_constraint_graph (dump_file); - fprintf (dump_file, "\n\n"); - } - - if (dump_file) - fprintf (dump_file, "Solving graph\n"); - - solve_graph (graph); - - if (dump_file && (dump_flags & TDF_GRAPH)) - { - fprintf (dump_file, "\n\n// The constraint graph after solve-graph " - "in dot format:\n"); - dump_constraint_graph (dump_file); - fprintf (dump_file, "\n\n"); - } -} - /* Create points-to sets for the current function. See the comments at the start of the file for an algorithmic overview. */ @@ -7842,8 +5300,6 @@ compute_points_to_sets (void) static void delete_points_to_sets (void) { - unsigned int i; - delete shared_bitmap_table; shared_bitmap_table = NULL; if (dump_file && (dump_flags & TDF_STATS)) @@ -7855,16 +5311,7 @@ delete_points_to_sets (void) bitmap_obstack_release (&pta_obstack); constraints.release (); - for (i = 0; i < graph->size; i++) - graph->complex[i].release (); - free (graph->complex); - - free (graph->rep); - free (graph->succs); - free (graph->pe); - free (graph->pe_rep); - free (graph->indirect_cycles); - free (graph); + free (var_rep); varmap.release (); variable_info_pool.release (); @@ -7911,14 +5358,14 @@ visit_loadstore (gimple *, tree base, tree ref, void *data) if (! vi) return false; - vi = get_varinfo (find (vi->id)); + vi = get_varinfo (var_rep[vi->id]); if (bitmap_intersect_p (rvars, vi->solution) || (escaped_p && bitmap_bit_p (vi->solution, escaped_id))) return false; } /* Do not overwrite existing cliques (that includes clique, base - pairs we just set). */ + pairs we just set). */ if (MR_DEPENDENCE_CLIQUE (base) == 0) { MR_DEPENDENCE_CLIQUE (base) = clique; @@ -8047,7 +5494,7 @@ compute_dependence_clique (void) varinfo_t vi = lookup_vi_for_tree (p); if (!vi) continue; - vi = get_varinfo (find (vi->id)); + vi = get_varinfo (var_rep[vi->id]); bitmap_iterator bi; unsigned j; varinfo_t restrict_var = NULL; @@ -8098,11 +5545,11 @@ compute_dependence_clique (void) maybe_set_dependence_info); if (used) { - /* Add all subvars to the set of restrict pointed-to set. */ + /* Add all subvars to the set of restrict pointed-to set. */ for (unsigned sv = restrict_var->head; sv != 0; sv = get_varinfo (sv)->next) bitmap_set_bit (rvars, sv); - varinfo_t escaped = get_varinfo (find (escaped_id)); + varinfo_t escaped = get_varinfo (var_rep[escaped_id]); if (bitmap_bit_p (escaped->solution, restrict_var->id)) escaped_p = true; } @@ -8258,7 +5705,7 @@ struct pt_solution ipa_escaped_pt = { true, false, false, false, false, false, false, false, false, false, false, NULL }; -/* Associate node with varinfo DATA. Worker for +/* Associate node with varinfo DATA. Worker for cgraph_for_symbol_thunks_and_aliases. */ static bool associate_varinfo_to_alias (struct cgraph_node *node, void *data) @@ -8272,111 +5719,6 @@ associate_varinfo_to_alias (struct cgraph_node *node, void *data) return false; } -/* Dump varinfo VI to FILE. */ - -static void -dump_varinfo (FILE *file, varinfo_t vi) -{ - if (vi == NULL) - return; - - fprintf (file, "%u: %s\n", vi->id, vi->name); - - const char *sep = " "; - if (vi->is_artificial_var) - fprintf (file, "%sartificial", sep); - if (vi->is_special_var) - fprintf (file, "%sspecial", sep); - if (vi->is_unknown_size_var) - fprintf (file, "%sunknown-size", sep); - if (vi->is_full_var) - fprintf (file, "%sfull", sep); - if (vi->is_heap_var) - fprintf (file, "%sheap", sep); - if (vi->may_have_pointers) - fprintf (file, "%smay-have-pointers", sep); - if (vi->only_restrict_pointers) - fprintf (file, "%sonly-restrict-pointers", sep); - if (vi->is_restrict_var) - fprintf (file, "%sis-restrict-var", sep); - if (vi->is_global_var) - fprintf (file, "%sglobal", sep); - if (vi->is_ipa_escape_point) - fprintf (file, "%sipa-escape-point", sep); - if (vi->is_fn_info) - fprintf (file, "%sfn-info", sep); - if (vi->ruid) - fprintf (file, "%srestrict-uid:%u", sep, vi->ruid); - if (vi->next) - fprintf (file, "%snext:%u", sep, vi->next); - if (vi->head != vi->id) - fprintf (file, "%shead:%u", sep, vi->head); - if (vi->offset) - fprintf (file, "%soffset:" HOST_WIDE_INT_PRINT_DEC, sep, vi->offset); - if (vi->size != ~HOST_WIDE_INT_0U) - fprintf (file, "%ssize:" HOST_WIDE_INT_PRINT_DEC, sep, vi->size); - if (vi->fullsize != ~HOST_WIDE_INT_0U && vi->fullsize != vi->size) - fprintf (file, "%sfullsize:" HOST_WIDE_INT_PRINT_DEC, sep, - vi->fullsize); - fprintf (file, "\n"); - - if (vi->solution && !bitmap_empty_p (vi->solution)) - { - bitmap_iterator bi; - unsigned i; - fprintf (file, " solution: {"); - EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi) - fprintf (file, " %u", i); - fprintf (file, " }\n"); - } - - if (vi->oldsolution && !bitmap_empty_p (vi->oldsolution) - && !bitmap_equal_p (vi->solution, vi->oldsolution)) - { - bitmap_iterator bi; - unsigned i; - fprintf (file, " oldsolution: {"); - EXECUTE_IF_SET_IN_BITMAP (vi->oldsolution, 0, i, bi) - fprintf (file, " %u", i); - fprintf (file, " }\n"); - } -} - -/* Dump varinfo VI to stderr. */ - -DEBUG_FUNCTION void -debug_varinfo (varinfo_t vi) -{ - dump_varinfo (stderr, vi); -} - -/* Dump varmap to FILE. */ - -static void -dump_varmap (FILE *file) -{ - if (varmap.length () == 0) - return; - - fprintf (file, "variables:\n"); - - for (unsigned int i = 0; i < varmap.length (); ++i) - { - varinfo_t vi = get_varinfo (i); - dump_varinfo (file, vi); - } - - fprintf (file, "\n"); -} - -/* Dump varmap to stderr. */ - -DEBUG_FUNCTION void -debug_varmap (void) -{ - dump_varmap (stderr); -} - /* Compute whether node is refered to non-locally. Worker for cgraph_for_symbol_thunks_and_aliases. */ static bool @@ -8490,7 +5832,7 @@ ipa_pta_execute (void) varinfo_t vi = get_vi_for_tree (var->decl); /* For the purpose of IPA PTA unit-local globals are not - escape points. */ + escape points. */ bool nonlocal_p = (DECL_EXTERNAL (var->decl) || TREE_PUBLIC (var->decl) || var->used_from_other_partition @@ -8589,7 +5931,7 @@ ipa_pta_execute (void) for (varinfo_t ai = first_vi_for_offset (fi, fi_parm_base); ai; ai = vi_next (ai)) { - varinfo_t vi = get_varinfo (find (ai->id)); + varinfo_t vi = get_varinfo (var_rep[ai->id]); bitmap_iterator bi; unsigned j; EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi) @@ -8605,12 +5947,12 @@ ipa_pta_execute (void) } } /* As well as global variables which are another way of passing - arguments to recursive invocations. */ + arguments to recursive invocations. */ else if (fi->is_global_var) { for (varinfo_t ai = fi; ai; ai = vi_next (ai)) { - varinfo_t vi = get_varinfo (find (ai->id)); + varinfo_t vi = get_varinfo (var_rep[ai->id]); bitmap_iterator bi; unsigned j; EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi) @@ -8705,10 +6047,10 @@ ipa_pta_execute (void) { *gimple_call_clobber_set (stmt) = find_what_var_points_to - (node->decl, first_vi_for_offset (fi, fi_clobbers)); + (node->decl, first_vi_for_offset (fi, fi_clobbers)); *gimple_call_use_set (stmt) = find_what_var_points_to - (node->decl, first_vi_for_offset (fi, fi_uses)); + (node->decl, first_vi_for_offset (fi, fi_uses)); } /* Handle direct calls to external functions. */ else if (decl && (!fi || fi->decl)) @@ -8735,7 +6077,8 @@ ipa_pta_execute (void) } pt = gimple_call_clobber_set (stmt); - if (gimple_call_flags (stmt) & (ECF_CONST|ECF_PURE|ECF_NOVOPS)) + if (gimple_call_flags (stmt) & + (ECF_CONST|ECF_PURE|ECF_NOVOPS)) memset (pt, 0, sizeof (struct pt_solution)); else if ((vi = lookup_call_clobber_vi (stmt)) != NULL) { @@ -8760,7 +6103,7 @@ ipa_pta_execute (void) { /* We need to accumulate all clobbers/uses of all possible callees. */ - fi = get_varinfo (find (fi->id)); + fi = get_varinfo (var_rep[fi->id]); /* If we cannot constrain the set of functions we'll end up calling we end up using/clobbering everything. */ if (bitmap_bit_p (fi->solution, anything_id) @@ -8820,7 +6163,7 @@ ipa_pta_execute (void) fn->gimple_df->ipa_pta = true; /* We have to re-set the final-solution cache after each function - because what is a "global" is dependent on function context. */ + because what is a "global" is dependent on function context. */ final_solutions->empty (); obstack_free (&final_solutions_obstack, NULL); gcc_obstack_init (&final_solutions_obstack); diff --git a/gcc/tree-ssa-structalias.h b/gcc/tree-ssa-structalias.h new file mode 100644 index 000000000000..4104bad3499f --- /dev/null +++ b/gcc/tree-ssa-structalias.h @@ -0,0 +1,217 @@ +/* Tree based points-to analysis + Copyright (C) 2005-2025 Free Software Foundation, Inc. + Contributed by Daniel Berlin + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* NOTE: This file declares the internal interface of the points-to analyzer. + Outward-facing function declarations can be found in tree-ssa-alias.h. */ + +#ifndef TREE_SSA_STRUCTALIAS_H +#define TREE_SSA_STRUCTALIAS_H + +namespace pointer_analysis { + +enum constraint_expr_type {SCALAR, DEREF, ADDRESSOF}; + +/* Static IDs for the special variables. Variable ID zero is unused + and used as terminator for the sub-variable chain. */ +enum { nothing_id = 1, anything_id = 2, string_id = 3, + escaped_id = 4, nonlocal_id = 5, escaped_return_id = 6, + storedanything_id = 7, integer_id = 8 }; + +/* Use 0x8000... as special unknown offset. */ +#define UNKNOWN_OFFSET HOST_WIDE_INT_MIN + +/* An expression that appears in a constraint. */ + +struct constraint_expr +{ + /* Constraint type. */ + constraint_expr_type type; + + /* Variable we are referring to in the constraint. */ + unsigned int var; + + /* Offset, in bits, of this constraint from the beginning of + variables it ends up referring to. + + IOW, in a deref constraint, we would deref, get the result set, + then add OFFSET to each member. */ + HOST_WIDE_INT offset; +}; +typedef struct constraint_expr ce_s; + +/* Our set constraints are made up of two constraint expressions, one + LHS, and one RHS. + + As described in the introduction in tree-ssa-structalias.cc, our set + constraints each represent an operation between set valued variables. +*/ +struct constraint +{ + struct constraint_expr lhs; + struct constraint_expr rhs; +}; +typedef struct constraint *constraint_t; + +struct variable_info +{ + /* ID of this variable. */ + unsigned int id; + + /* True if this is a variable created by the constraint analysis, such as + heap variables and constraints we had to break up. */ + unsigned int is_artificial_var : 1; + + /* True if this is a special variable whose solution set should not be + changed. */ + unsigned int is_special_var : 1; + + /* True for variables whose size is not known or variable. */ + unsigned int is_unknown_size_var : 1; + + /* True for (sub-)fields that represent a whole variable. */ + unsigned int is_full_var : 1; + + /* True if this is a heap variable. */ + unsigned int is_heap_var : 1; + + /* True if this is a register variable. */ + unsigned int is_reg_var : 1; + + /* True if this field may contain pointers. */ + unsigned int may_have_pointers : 1; + + /* True if this field has only restrict qualified pointers. */ + unsigned int only_restrict_pointers : 1; + + /* True if this represents a heap var created for a restrict qualified + pointer. */ + unsigned int is_restrict_var : 1; + + /* True if this represents a global variable. */ + unsigned int is_global_var : 1; + + /* True if this represents a module escape point for IPA analysis. */ + unsigned int is_ipa_escape_point : 1; + + /* True if this represents a IPA function info. */ + unsigned int is_fn_info : 1; + + /* True if this appears as RHS in a ADDRESSOF constraint. */ + unsigned int address_taken : 1; + + /* ??? Store somewhere better. */ + unsigned short ruid; + + /* The ID of the variable for the next field in this structure + or zero for the last field in this structure. */ + unsigned next; + + /* The ID of the variable for the first field in this structure. */ + unsigned head; + + /* Offset of this variable, in bits, from the base variable. */ + unsigned HOST_WIDE_INT offset; + + /* Size of the variable, in bits. */ + unsigned HOST_WIDE_INT size; + + /* Full size of the base variable, in bits. */ + unsigned HOST_WIDE_INT fullsize; + + /* In IPA mode the shadow UID in case the variable needs to be duplicated in + the final points-to solution because it reaches its containing + function recursively. Zero if none is needed. */ + unsigned int shadow_var_uid; + + /* Name of this variable. */ + const char *name; + + /* Tree that this variable is associated with. */ + tree decl; + + /* Points-to set for this variable. */ + bitmap solution; + + /* Old points-to set for this variable. */ + bitmap oldsolution; +}; +typedef struct variable_info *varinfo_t; + +struct constraint_stats +{ + unsigned int total_vars; + unsigned int nonpointer_vars; + unsigned int unified_vars_static; + unsigned int unified_vars_dynamic; + unsigned int iterations; + unsigned int num_edges; + unsigned int num_implicit_edges; + unsigned int num_avoided_edges; + unsigned int points_to_sets_created; +}; + +extern struct constraint_stats stats; + +extern bitmap_obstack pta_obstack; +extern bitmap_obstack oldpta_obstack; + +extern vec varmap; +extern vec constraints; +extern unsigned int *var_rep; + + +/* Return the varmap element N. */ + +inline varinfo_t +get_varinfo (unsigned int n) +{ + return varmap[n]; +} + +/* Return the next variable in the list of sub-variables of VI + or NULL if VI is the last sub-variable. */ + +inline varinfo_t +vi_next (varinfo_t vi) +{ + return get_varinfo (vi->next); +} + +varinfo_t first_vi_for_offset (varinfo_t start, + unsigned HOST_WIDE_INT offset); +varinfo_t first_or_preceding_vi_for_offset (varinfo_t start, + unsigned HOST_WIDE_INT offset); +void dump_constraint (FILE *file, constraint_t c); +void dump_constraints (FILE *file, int from); +void dump_solution_for_var (FILE *file, unsigned int var); +void dump_sa_stats (FILE *outfile); +void dump_sa_points_to_info (FILE *outfile); +void dump_varinfo (FILE *file, varinfo_t vi); +void dump_varmap (FILE *file); +void debug_constraint (constraint_t); +void debug_constraints (void); +void debug_solution_for_var (unsigned int); +void debug_sa_points_to_info (void); +void debug_varinfo (varinfo_t); +void debug_varmap (void); + +} // namespace pointer_analysis + +#endif /* TREE_SSA_STRUCTALIAS_H */ diff --git a/gcc/tree-tailcall.cc b/gcc/tree-tailcall.cc index 10e88d9c8292..c80145d23e4e 100644 --- a/gcc/tree-tailcall.cc +++ b/gcc/tree-tailcall.cc @@ -528,8 +528,20 @@ empty_eh_cleanup (basic_block bb, int *eh_has_tsan_func_exit, int cnt) *eh_has_tsan_func_exit = 1; continue; } - if (is_gimple_resx (g) && stmt_can_throw_external (cfun, g)) - return true; + if (eh_has_tsan_func_exit + && sanitize_flags_p (SANITIZE_ADDRESS) + && asan_mark_p (g, ASAN_MARK_POISON)) + continue; + if (is_gimple_resx (g)) + { + if (stmt_can_throw_external (cfun, g)) + return true; + if (single_succ_p (bb) + && (single_succ_edge (bb)->flags & EDGE_EH) + && cnt > 1) + return empty_eh_cleanup (single_succ (bb), eh_has_tsan_func_exit, + cnt - 1); + } return false; } if (!single_succ_p (bb)) @@ -544,8 +556,9 @@ empty_eh_cleanup (basic_block bb, int *eh_has_tsan_func_exit, int cnt) static live_vars_map *live_vars; static vec live_vars_vec; -/* Finds tailcalls falling into basic block BB. The list of found tailcalls is - added to the start of RET. When ONLY_MUSTTAIL is set only handle musttail. +/* Finds tailcalls falling into basic block BB when coming from edge ESUCC (or + NULL). The list of found tailcalls is added to the start of RET. + When ONLY_MUSTTAIL is set only handle musttail. Update OPT_TAILCALLS as output parameter. If DIAG_MUSTTAIL, diagnose failures for musttail calls. RETRY_TSAN_FUNC_EXIT is initially 0 and in that case the last call is attempted to be tail called, including @@ -554,12 +567,15 @@ static vec live_vars_vec; will retry with it set to 1 (regardless of whether turning the __tsan_func_exit was successfully detected as tail call or not) and that will allow turning musttail calls before that call into tail calls as well - by adding __tsan_func_exit call before the call. */ + by adding __tsan_func_exit call before the call. + IGNORED_EDGES and MUST_SEE_BBS are used in recursive calls when handling + GIMPLE_CONDs for cleanups. */ static void -find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail, - bool &opt_tailcalls, bool diag_musttail, - int &retry_tsan_func_exit) +find_tail_calls (basic_block bb, edge esucc, struct tailcall **ret, + bool only_musttail, bool &opt_tailcalls, bool diag_musttail, + int &retry_tsan_func_exit, hash_set *ignored_edges, + hash_set *must_see_bbs) { tree ass_var = NULL_TREE, ret_var, func, param; gimple *stmt; @@ -575,14 +591,24 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail, bool only_tailr = false; bool has_tsan_func_exit = false; int eh_has_tsan_func_exit = -1; + bool delete_ignored_edges = false; if (!single_succ_p (bb) && (EDGE_COUNT (bb->succs) || !cfun->has_musttail || !diag_musttail)) { + if (EDGE_COUNT (bb->succs) == 2 + && esucc + && cfun->has_musttail + && diag_musttail + && (EDGE_SUCC (bb, 0)->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)) + && (EDGE_SUCC (bb, 1)->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)) + && (stmt = last_nondebug_stmt (bb)) + && gimple_code (stmt) == GIMPLE_COND) + ; /* If there is an abnormal edge assume it's the only extra one. Tolerate that case so that we can give better error messages for musttail later. */ - if (!has_abnormal_or_eh_outgoing_edge_p (bb)) + else if (!has_abnormal_or_eh_outgoing_edge_p (bb)) { if (dump_file) fprintf (dump_file, "Basic block %d has extra exit edges\n", @@ -619,6 +645,85 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail, continue; } + if (cfun->has_musttail + && sanitize_flags_p (SANITIZE_ADDRESS) + && asan_mark_p (stmt, ASAN_MARK_POISON) + && diag_musttail) + continue; + + /* Especially at -O0 with -fsanitize=address we can end up with + code like + _26 = foo (x_24(D)); [must tail call] + finally_tmp.3_27 = 0; + goto ; [INV] + + ... + + : + # _6 = PHI <_26(3), _23(D)(4)> + # finally_tmp.3_8 = PHI + .ASAN_MARK (POISON, &c, 4); + if (finally_tmp.3_8 == 1) + goto ; [INV] + else + goto ; [INV] + When walking backwards, ESUCC is the edge we are coming from, + depending on its EDGE_TRUE_FLAG, == vs. != for the comparison + and value compared against try to find out through which edge + we need to go and which edge should be ignored. The code handles + both INTEGER_CST PHI arguments and SSA_NAMEs set to constants + (for -O0 where those aren't propagated). */ + if (cfun->has_musttail + && diag_musttail + && esucc + && gimple_code (stmt) == GIMPLE_COND + && (gimple_cond_code (stmt) == EQ_EXPR + || gimple_cond_code (stmt) == NE_EXPR) + && TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME + && TREE_CODE (gimple_cond_rhs (stmt)) == INTEGER_CST + && INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt))) + && (integer_zerop (gimple_cond_rhs (stmt)) + || integer_onep (gimple_cond_rhs (stmt)))) + { + tree lhs = gimple_cond_lhs (stmt); + bool rhsv = integer_onep (gimple_cond_rhs (stmt)); + if (((esucc->flags & EDGE_TRUE_VALUE) != 0) + ^ (gimple_cond_code (stmt) == EQ_EXPR)) + rhsv = !rhsv; + if (!ignored_edges) + { + ignored_edges = new hash_set; + must_see_bbs = new hash_set; + delete_ignored_edges = true; + } + if (is_gimple_assign (SSA_NAME_DEF_STMT (lhs)) + && (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (lhs)) + == INTEGER_CST)) + { + tree rhs = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (lhs)); + if (rhsv ? integer_onep (rhs) : integer_zerop (rhs)) + continue; + } + else if (gimple_code (SSA_NAME_DEF_STMT (lhs)) == GIMPLE_PHI) + { + gimple *phi = SSA_NAME_DEF_STMT (lhs); + basic_block pbb = gimple_bb (phi); + must_see_bbs->add (pbb); + edge_iterator ei; + FOR_EACH_EDGE (e, ei, pbb->preds) + { + tree rhs = gimple_phi_arg_def_from_edge (phi, e); + if (TREE_CODE (rhs) == SSA_NAME + && is_gimple_assign (SSA_NAME_DEF_STMT (rhs)) + && (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (rhs)) + == INTEGER_CST)) + rhs = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs)); + if (!(rhsv ? integer_onep (rhs) : integer_zerop (rhs))) + ignored_edges->add (e); + } + } + } + if (!last_stmt) last_stmt = stmt; /* Check for a call. */ @@ -627,12 +732,20 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail, call = as_a (stmt); /* Handle only musttail calls when not optimizing. */ if (only_musttail && !gimple_call_must_tail_p (call)) - return; + { + maybe_delete_ignored_edges: + if (delete_ignored_edges) + { + delete ignored_edges; + delete must_see_bbs; + } + return; + } if (bad_stmt) { maybe_error_musttail (call, _("memory reference or volatile " "after call"), diag_musttail); - return; + goto maybe_delete_ignored_edges; } ass_var = gimple_call_lhs (call); break; @@ -661,17 +774,34 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail, } if (bad_stmt) - return; + goto maybe_delete_ignored_edges; if (gsi_end_p (gsi)) { + if (must_see_bbs) + must_see_bbs->remove (bb); + edge_iterator ei; /* Recurse to the predecessors. */ FOR_EACH_EDGE (e, ei, bb->preds) - find_tail_calls (e->src, ret, only_musttail, opt_tailcalls, - diag_musttail, retry_tsan_func_exit); + { + if (ignored_edges && ignored_edges->contains (e)) + continue; + find_tail_calls (e->src, e, ret, only_musttail, opt_tailcalls, + diag_musttail, retry_tsan_func_exit, ignored_edges, + must_see_bbs); + } - return; + goto maybe_delete_ignored_edges; + } + + if (must_see_bbs && !must_see_bbs->is_empty ()) + goto maybe_delete_ignored_edges; + + if (delete_ignored_edges) + { + delete ignored_edges; + delete must_see_bbs; } if (!suitable_for_tail_opt_p (call, diag_musttail)) @@ -963,11 +1093,12 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail, tree tmp_m = NULL_TREE; gsi_next (&agsi); + new_bb: while (gsi_end_p (agsi)) { edge e = single_non_eh_succ_edge (abb); ass_var = propagate_through_phis (ass_var, e); - if (!ass_var) + if (!ass_var || ignored_edges) edges.safe_push (e); abb = e->dest; agsi = gsi_start_bb (abb); @@ -995,6 +1126,94 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail, continue; } + if (cfun->has_musttail + && sanitize_flags_p (SANITIZE_ADDRESS) + && asan_mark_p (stmt, ASAN_MARK_POISON) + && diag_musttail) + continue; + + /* See earlier comment on GIMPLE_CONDs. Here we need to propagate + through on the forward walk, so based on the edges vector we've + walked through determine which edge to follow. */ + if (ignored_edges) + { + if (is_gimple_assign (stmt) + && gimple_assign_rhs_code (stmt) == INTEGER_CST) + { + use_operand_p use_p; + gimple *use_stmt; + if ((integer_zerop (gimple_assign_rhs1 (stmt)) + || integer_onep (gimple_assign_rhs1 (stmt))) + && single_imm_use (gimple_assign_lhs (stmt), &use_p, + &use_stmt)) + { + if (gimple_code (use_stmt) == GIMPLE_COND) + continue; + if (gimple_code (use_stmt) == GIMPLE_PHI + && single_imm_use (gimple_phi_result (use_stmt), + &use_p, &use_stmt) + && gimple_code (use_stmt) == GIMPLE_COND) + continue; + } + } + if (gimple_code (stmt) == GIMPLE_COND + && (gimple_cond_code (stmt) == EQ_EXPR + || gimple_cond_code (stmt) == NE_EXPR) + && TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME + && TREE_CODE (gimple_cond_rhs (stmt)) == INTEGER_CST + && INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt))) + && (integer_zerop (gimple_cond_rhs (stmt)) + || integer_onep (gimple_cond_rhs (stmt)))) + { + edge e = NULL, et, ef; + tree lhs = gimple_cond_lhs (stmt); + bool rhsv = integer_onep (gimple_cond_rhs (stmt)); + if (gimple_cond_code (stmt) == NE_EXPR) + rhsv = !rhsv; + extract_true_false_edges_from_block (gimple_bb (stmt), &et, &ef); + if (is_gimple_assign (SSA_NAME_DEF_STMT (lhs)) + && (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (lhs)) + == INTEGER_CST)) + { + tree rhs = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (lhs)); + if (rhsv ? integer_onep (rhs) : integer_zerop (rhs)) + e = et; + else if (rhsv ? integer_zerop (rhs) : integer_onep (rhs)) + e = ef; + } + else if (gimple_code (SSA_NAME_DEF_STMT (lhs)) == GIMPLE_PHI) + { + gimple *phi = SSA_NAME_DEF_STMT (lhs); + basic_block pbb = gimple_bb (phi); + for (edge e2 : edges) + if (e2->dest == pbb) + { + tree rhs = gimple_phi_arg_def_from_edge (phi, e2); + if (TREE_CODE (rhs) == SSA_NAME) + if (gimple *g = SSA_NAME_DEF_STMT (rhs)) + if (is_gimple_assign (g) + && gimple_assign_rhs_code (g) == INTEGER_CST) + rhs = gimple_assign_rhs1 (g); + if (rhsv ? integer_onep (rhs) : integer_zerop (rhs)) + e = et; + else if (rhsv ? integer_zerop (rhs) + : integer_onep (rhs)) + e = ef; + break; + } + } + if (e) + { + ass_var = propagate_through_phis (ass_var, e); + if (!ass_var || ignored_edges) + edges.safe_push (e); + abb = e->dest; + agsi = gsi_start_bb (abb); + goto new_bb; + } + } + } + if (gimple_code (stmt) != GIMPLE_ASSIGN) { maybe_error_musttail (call, _("unhandled code after call"), @@ -1629,14 +1848,14 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls, bool only_musttail, if (safe_is_a (*gsi_last_bb (e->src))) { int retry_tsan_func_exit = 0; - find_tail_calls (e->src, &tailcalls, only_musttail, opt_tailcalls, - diag_musttail, retry_tsan_func_exit); + find_tail_calls (e->src, e, &tailcalls, only_musttail, opt_tailcalls, + diag_musttail, retry_tsan_func_exit, NULL, NULL); if (retry_tsan_func_exit == -1) { retry_tsan_func_exit = 1; - find_tail_calls (e->src, &tailcalls, only_musttail, + find_tail_calls (e->src, e, &tailcalls, only_musttail, opt_tailcalls, diag_musttail, - retry_tsan_func_exit); + retry_tsan_func_exit, NULL, NULL); } } } @@ -1652,8 +1871,9 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls, bool only_musttail, if (is_gimple_call (c) && gimple_call_must_tail_p (as_a (c)) && gimple_call_noreturn_p (as_a (c))) - find_tail_calls (bb, &tailcalls, only_musttail, opt_tailcalls, - diag_musttail, retry_tsan_func_exit); + find_tail_calls (bb, NULL, &tailcalls, only_musttail, + opt_tailcalls, diag_musttail, + retry_tsan_func_exit, NULL, NULL); } if (live_vars) diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc index 1792ee4ea05f..460a48db2e60 100644 --- a/gcc/tree-vect-data-refs.cc +++ b/gcc/tree-vect-data-refs.cc @@ -1501,10 +1501,17 @@ vect_compute_data_ref_alignment (vec_info *vinfo, dr_vec_info *dr_info, /* We can only use base and misalignment information relative to an innermost loop if the misalignment stays the same throughout the execution of the loop. As above, this is the case if the stride of - the dataref evenly divides by the alignment. */ - poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); - step_preserves_misalignment_p - = multiple_p (drb->step_alignment * vf, vect_align_c); + the dataref evenly divides by the alignment. Make sure to check + previous epilogues and the main loop. */ + step_preserves_misalignment_p = true; + auto lvinfo = loop_vinfo; + while (lvinfo) + { + poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (lvinfo); + step_preserves_misalignment_p + &= multiple_p (drb->step_alignment * vf, vect_align_c); + lvinfo = LOOP_VINFO_ORIG_LOOP_INFO (lvinfo); + } if (!step_preserves_misalignment_p && dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -1571,6 +1578,7 @@ vect_compute_data_ref_alignment (vec_info *vinfo, dr_vec_info *dr_info, unsigned int max_alignment; tree base = get_base_for_alignment (drb->base_address, &max_alignment); if (max_alignment < vect_align_c + || (loop_vinfo && LOOP_VINFO_EPILOGUE_P (loop_vinfo)) || !vect_can_force_dr_alignment_p (base, vect_align_c * BITS_PER_UNIT)) { @@ -2111,9 +2119,10 @@ vect_peeling_hash_choose_best_peeling (hash_table *peeling_hta return res; } -/* Return true if the new peeling NPEEL is supported. */ +/* Return if vectorization is definitely, possibly, or unlikely to be + supportable after loop peeling. */ -static bool +static enum peeling_support vect_peeling_supportable (loop_vec_info loop_vinfo, dr_vec_info *dr0_info, unsigned npeel) { @@ -2123,8 +2132,11 @@ vect_peeling_supportable (loop_vec_info loop_vinfo, dr_vec_info *dr0_info, bool dr0_alignment_known_p = known_alignment_for_access_p (dr0_info, STMT_VINFO_VECTYPE (dr0_info->stmt)); + bool has_unsupported_dr_p = false; + unsigned int dr0_step = tree_to_shwi (DR_STEP (dr0_info->dr)); + int known_unsupported_misalignment = DR_MISALIGNMENT_UNKNOWN; - /* Ensure that all data refs can be vectorized after the peel. */ + /* Check if each data ref can be vectorized after peeling. */ for (data_reference *dr : datarefs) { if (dr == dr0_info->dr) @@ -2152,10 +2164,44 @@ vect_peeling_supportable (loop_vec_info loop_vinfo, dr_vec_info *dr0_info, = vect_supportable_dr_alignment (loop_vinfo, dr_info, vectype, misalignment); if (supportable_dr_alignment == dr_unaligned_unsupported) - return false; + { + has_unsupported_dr_p = true; + + /* If unaligned unsupported DRs exist, we do following checks to see + if they can be mutually aligned to support vectorization. If yes, + we can try peeling and create a runtime (mutual alignment) check + to guard the peeled loop. If no, return PEELING_UNSUPPORTED. */ + + /* 1) If unaligned unsupported DRs have different alignment steps, the + probability of DRs being mutually aligned is very low, and it's + quite complex to check mutual alignment at runtime. We return + PEELING_UNSUPPORTED in this case. */ + if (tree_to_shwi (DR_STEP (dr)) != dr0_step) + return peeling_unsupported; + + /* 2) Based on above same alignment step condition, if one known + misaligned DR has zero misalignment, or different misalignment + amount from another known misaligned DR, peeling is unable to + help make all these DRs aligned together. We won't try peeling + with versioning anymore. */ + int curr_dr_misalignment = dr_misalignment (dr_info, vectype); + if (curr_dr_misalignment == 0) + return peeling_unsupported; + if (known_unsupported_misalignment != DR_MISALIGNMENT_UNKNOWN) + { + if (curr_dr_misalignment != DR_MISALIGNMENT_UNKNOWN + && curr_dr_misalignment != known_unsupported_misalignment) + return peeling_unsupported; + } + else + known_unsupported_misalignment = curr_dr_misalignment; + } } - return true; + /* Vectorization is known to be supportable with peeling alone when there is + no unsupported DR. */ + return has_unsupported_dr_p ? peeling_maybe_supported + : peeling_known_supported; } /* Compare two data-references DRA and DRB to group them into chunks @@ -2264,20 +2310,20 @@ dr_align_group_sort_cmp (const void *dra_, const void *drb_) } -- Possibility 3: combination of loop peeling and versioning: - for (i = 0; i < 3; i++){ # (scalar loop, not to be vectorized). - x = q[i]; - p[i] = y; - } - if (p is aligned) { - for (i = 3; i &may_misalign_stmts @@ -2958,12 +3040,28 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) "Alignment of access forced using versioning.\n"); } - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "Versioning for alignment will be applied.\n"); - - /* Peeling and versioning can't be done together at this time. */ - gcc_assert (! (do_peeling && do_versioning)); + if (do_peeling) + { + /* This point is reached if peeling and versioning are used together + to ensure alignment. Update data structures to make sure the loop + is correctly peeled and a right runtime check is added for loop + versioning. */ + gcc_assert (try_peeling_with_versioning); + LOOP_VINFO_UNALIGNED_DR (loop_vinfo) = dr0_info; + LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) = -1; + LOOP_VINFO_ALLOW_MUTUAL_ALIGNMENT (loop_vinfo) = true; + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "Both peeling and versioning will be applied.\n"); + } + else + { + /* This point is reached if versioning is used alone. */ + LOOP_VINFO_ALLOW_MUTUAL_ALIGNMENT (loop_vinfo) = false; + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "Versioning for alignment will be applied.\n"); + } return opt_result::success (); } @@ -4569,26 +4667,19 @@ vect_check_gather_scatter (stmt_vec_info stmt_info, loop_vec_info loop_vinfo, if (off == NULL_TREE) off = size_zero_node; - /* If base is not loop invariant, either off is 0, then we start with just - the constant offset in the loop invariant BASE and continue with base - as OFF, otherwise give up. - We could handle that case by gimplifying the addition of base + off - into some SSA_NAME and use that as off, but for now punt. */ + /* BASE must be loop invariant. If it is not invariant, but OFF is, then we + * can fix that by swapping BASE and OFF. */ if (!expr_invariant_in_loop_p (loop, base)) { - if (!integer_zerop (off)) + if (!expr_invariant_in_loop_p (loop, off)) return false; - off = base; - base = size_int (pbytepos); - } - /* Otherwise put base + constant offset into the loop invariant BASE - and continue with OFF. */ - else - { - base = fold_convert (sizetype, base); - base = size_binop (PLUS_EXPR, base, size_int (pbytepos)); + + std::swap (base, off); } + base = fold_convert (sizetype, base); + base = size_binop (PLUS_EXPR, base, size_int (pbytepos)); + /* OFF at this point may be either a SSA_NAME or some tree expression from get_inner_reference. Try to peel off loop invariants from it into BASE as long as possible. */ @@ -4766,6 +4857,9 @@ vect_check_gather_scatter (stmt_vec_info stmt_info, loop_vec_info loop_vinfo, offset_vectype = NULL_TREE; } + gcc_checking_assert (expr_invariant_in_loop_p (loop, base)); + gcc_checking_assert (!expr_invariant_in_loop_p (loop, off)); + info->ifn = ifn; info->decl = decl; info->base = base; @@ -4958,7 +5052,7 @@ vect_find_stmt_data_reference (loop_p loop, gimple *stmt, */ opt_result -vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf, bool *fatal) +vect_analyze_data_refs (vec_info *vinfo, bool *fatal) { class loop *loop = NULL; unsigned int i; @@ -4977,7 +5071,6 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf, bool *fatal) FOR_EACH_VEC_ELT (datarefs, i, dr) { enum { SG_NONE, GATHER, SCATTER } gatherscatter = SG_NONE; - poly_uint64 vf; gcc_assert (DR_REF (dr)); stmt_vec_info stmt_info = vinfo->lookup_stmt (DR_STMT (dr)); @@ -5169,11 +5262,6 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf, bool *fatal) stmt_info->stmt, vectype); } - /* Adjust the minimal vectorization factor according to the - vector type. */ - vf = TYPE_VECTOR_SUBPARTS (vectype); - *min_vf = upper_bound (*min_vf, vf); - /* Leave the BB vectorizer to pick the vector type later, based on the final dataref group size and SLP node size. */ if (is_a (vinfo)) @@ -7249,7 +7337,8 @@ vect_can_force_dr_alignment_p (const_tree decl, poly_uint64 alignment) return false; if (decl_in_symtab_p (decl) - && !symtab_node::get (decl)->can_increase_alignment_p ()) + && (!symtab_node::get (decl) + || !symtab_node::get (decl)->can_increase_alignment_p ())) return false; if (TREE_STATIC (decl)) diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc index 56a4e9a8b63f..2d01a4b0ed1c 100644 --- a/gcc/tree-vect-loop-manip.cc +++ b/gcc/tree-vect-loop-manip.cc @@ -2794,7 +2794,6 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters, tree niters_vector, step_vector, type = TREE_TYPE (niters); poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); edge pe = loop_preheader_edge (LOOP_VINFO_LOOP (loop_vinfo)); - tree log_vf = NULL_TREE; /* If epilogue loop is required because of data accesses with gaps, we subtract one iteration from the total number of iterations here for @@ -2820,22 +2819,25 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters, if (vf.is_constant (&const_vf) && !LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) { - /* Create: niters >> log2(vf) */ + /* Create: niters / vf, which is equivalent to niters >> log2(vf) when + vf is a power of two, and when not we approximate using a + truncating division. */ /* If it's known that niters == number of latch executions + 1 doesn't - overflow, we can generate niters >> log2(vf); otherwise we generate - (niters - vf) >> log2(vf) + 1 by using the fact that we know ratio + overflow, we can generate niters / vf; otherwise we generate + (niters - vf) / vf + 1 by using the fact that we know ratio will be at least one. */ - log_vf = build_int_cst (type, exact_log2 (const_vf)); + tree var_vf = build_int_cst (type, const_vf); if (niters_no_overflow) - niters_vector = fold_build2 (RSHIFT_EXPR, type, ni_minus_gap, log_vf); + niters_vector = fold_build2 (TRUNC_DIV_EXPR, type, ni_minus_gap, + var_vf); else niters_vector = fold_build2 (PLUS_EXPR, type, - fold_build2 (RSHIFT_EXPR, type, + fold_build2 (TRUNC_DIV_EXPR, type, fold_build2 (MINUS_EXPR, type, ni_minus_gap, - build_int_cst (type, vf)), - log_vf), + var_vf), + var_vf), build_int_cst (type, 1)); step_vector = build_one_cst (type); } @@ -2854,16 +2856,29 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters, /* Peeling algorithm guarantees that vector loop bound is at least ONE, we set range information to make niters analyzer's life easier. Note the number of latch iteration value can be TYPE_MAX_VALUE so - we have to represent the vector niter TYPE_MAX_VALUE + 1 >> log_vf. */ - if (stmts != NULL && log_vf) + we have to represent the vector niter TYPE_MAX_VALUE + 1 / vf. */ + if (stmts != NULL && const_vf > 0) { - if (niters_no_overflow) + if (niters_no_overflow + && LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) { int_range<1> vr (type, wi::one (TYPE_PRECISION (type)), - wi::rshift (wi::max_value (TYPE_PRECISION (type), - TYPE_SIGN (type)), - exact_log2 (const_vf), + wi::div_ceil (wi::max_value + (TYPE_PRECISION (type), + TYPE_SIGN (type)), + const_vf, + TYPE_SIGN (type))); + set_range_info (niters_vector, vr); + } + else if (niters_no_overflow) + { + int_range<1> vr (type, + wi::one (TYPE_PRECISION (type)), + wi::div_trunc (wi::max_value + (TYPE_PRECISION (type), + TYPE_SIGN (type)), + const_vf, TYPE_SIGN (type))); set_range_info (niters_vector, vr); } @@ -2901,13 +2916,12 @@ vect_gen_vector_loop_niters_mult_vf (loop_vec_info loop_vinfo, /* We should be using a step_vector of VF if VF is variable. */ int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant (); tree type = TREE_TYPE (niters_vector); - tree log_vf = build_int_cst (type, exact_log2 (vf)); tree tree_vf = build_int_cst (type, vf); basic_block exit_bb = LOOP_VINFO_IV_EXIT (loop_vinfo)->dest; gcc_assert (niters_vector_mult_vf_ptr != NULL); - tree niters_vector_mult_vf = fold_build2 (LSHIFT_EXPR, type, - niters_vector, log_vf); + tree niters_vector_mult_vf = fold_build2 (MULT_EXPR, type, + niters_vector, tree_vf); /* If we've peeled a vector iteration then subtract one full vector iteration. */ @@ -3787,10 +3801,11 @@ chain_cond_expr (tree *cond_expr, tree part_cond_expr) Input: COND_EXPR - input conditional expression. New conditions will be chained - with logical AND operation. - LOOP_VINFO - two fields of the loop information are used. - LOOP_VINFO_PTR_MASK is the mask used to check the alignment. - LOOP_VINFO_MAY_MISALIGN_STMTS contains the refs to be checked. + with logical AND operation. + LOOP_VINFO - three fields of the loop information are used. + LOOP_VINFO_PTR_MASK is the mask used to check the alignment. + LOOP_VINFO_MAY_MISALIGN_STMTS contains the refs to be checked. + LOOP_VINFO_ALLOW_MUTUAL_ALIGNMENT indicates which check applies. Output: COND_EXPR_STMT_LIST - statements needed to construct the conditional @@ -3798,7 +3813,20 @@ chain_cond_expr (tree *cond_expr, tree part_cond_expr) The returned value is the conditional expression to be used in the if statement that controls which version of the loop gets executed at runtime. - The algorithm makes two assumptions: + Based on the boolean value of LOOP_VINFO_ALLOW_MUTUAL_ALIGNMENT, we decide + which type of check should be applied and create two different expressions + accordingly. + 1) When LOOP_VINFO_ALLOW_MUTUAL_ALIGNMENT is false, we see if all data refs + to be checked are already aligned to an alignment boundary. We create + an expression of "(a_1 | a_2 | a_3 | ... | a_n) & mask", where "a_i" is + the address of i'th data reference. + 2) When LOOP_VINFO_ALLOW_MUTUAL_ALIGNMENT is true, we see if all data refs + can be aligned to a boundary after a certain amount of peeling, in other + words, their addresses have the same bottom bits according to the mask. + We create "((a_1 ^ a_2) | (a_2 ^ a_3) | ... | (a_n-1 ^ a_n)) & mask", + where "a_i" is the address of i'th data reference. + + Both algorithms make two assumptions: 1) The number of bytes "n" in a vector is a power of 2. 2) An address "a" is aligned if a%n is zero and that this test can be done as a&(n-1) == 0. For example, for 16 @@ -3816,8 +3844,9 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo, tree mask_cst; unsigned int i; tree int_ptrsize_type; - char tmp_name[20]; + char tmp_name[30]; tree or_tmp_name = NULL_TREE; + tree prev_addr_tmp_name = NULL_TREE; tree and_tmp_name; gimple *and_stmt; tree ptrsize_zero; @@ -3829,16 +3858,19 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo, int_ptrsize_type = signed_type_for (ptr_type_node); - /* Create expression (mask & (dr_1 || ... || dr_n)) where dr_i is the address - of the first vector of the i'th data reference. */ + /* If LOOP_VINFO_ALLOW_MUTUAL_ALIGNMENT is true, we should have at least two + datarefs to check the mutual alignment. */ + gcc_assert (may_misalign_stmts.length () > 1 + || !LOOP_VINFO_ALLOW_MUTUAL_ALIGNMENT (loop_vinfo)); FOR_EACH_VEC_ELT (may_misalign_stmts, i, stmt_info) { gimple_seq new_stmt_list = NULL; tree addr_base; tree addr_tmp_name; + tree xor_tmp_name; tree new_or_tmp_name; - gimple *addr_stmt, *or_stmt; + gimple *addr_stmt, *or_stmt, *xor_stmt; tree vectype = STMT_VINFO_VECTYPE (stmt_info); bool negative = tree_int_cst_compare (DR_STEP (STMT_VINFO_DATA_REF (stmt_info)), size_zero_node) < 0; @@ -3860,20 +3892,56 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo, addr_stmt = gimple_build_assign (addr_tmp_name, NOP_EXPR, addr_base); gimple_seq_add_stmt (cond_expr_stmt_list, addr_stmt); - /* The addresses are OR together. */ - - if (or_tmp_name != NULL_TREE) - { - /* create: or_tmp = or_tmp | addr_tmp */ - sprintf (tmp_name, "orptrs%d", i); - new_or_tmp_name = make_temp_ssa_name (int_ptrsize_type, NULL, tmp_name); - or_stmt = gimple_build_assign (new_or_tmp_name, BIT_IOR_EXPR, - or_tmp_name, addr_tmp_name); - gimple_seq_add_stmt (cond_expr_stmt_list, or_stmt); - or_tmp_name = new_or_tmp_name; - } + if (LOOP_VINFO_ALLOW_MUTUAL_ALIGNMENT (loop_vinfo)) + { + /* Create "((a_1 ^ a_2) | (a_2 ^ a_3) | ... | (a_n-1 ^ a_n)) & mask" + to check mutual alignment. */ + if (prev_addr_tmp_name != NULL_TREE) + { + sprintf (tmp_name, "xorptrs%d_%d", i - 1, i); + xor_tmp_name = make_temp_ssa_name (int_ptrsize_type, NULL, + tmp_name); + xor_stmt = gimple_build_assign (xor_tmp_name, BIT_XOR_EXPR, + prev_addr_tmp_name, + addr_tmp_name); + gimple_seq_add_stmt (cond_expr_stmt_list, xor_stmt); + if (or_tmp_name == NULL_TREE) + { + /* Create the 1st XOR when the 2nd data ref is seen. */ + or_tmp_name = xor_tmp_name; + } + else + { + /* Create: or_tmp = or_tmp | new_xor_tmp. */ + sprintf (tmp_name, "orxors%d", i - 1); + new_or_tmp_name = make_temp_ssa_name (int_ptrsize_type, NULL, + tmp_name); + or_stmt = gimple_build_assign (new_or_tmp_name, BIT_IOR_EXPR, + or_tmp_name, xor_tmp_name); + gimple_seq_add_stmt (cond_expr_stmt_list, or_stmt); + or_tmp_name = new_or_tmp_name; + } + } + prev_addr_tmp_name = addr_tmp_name; + } else - or_tmp_name = addr_tmp_name; + { + /* Create: "(a_1 | a_2 | a_3 | ... | a_n) & mask" to check if all + addresses are already aligned. */ + if (or_tmp_name != NULL_TREE) + { + /* Create: or_tmp = or_tmp | addr_tmp. */ + sprintf (tmp_name, "orptrs%d", i); + new_or_tmp_name = make_temp_ssa_name (int_ptrsize_type, NULL, + tmp_name); + or_stmt = gimple_build_assign (new_or_tmp_name, BIT_IOR_EXPR, + or_tmp_name, addr_tmp_name); + gimple_seq_add_stmt (cond_expr_stmt_list, or_stmt); + or_tmp_name = new_or_tmp_name; + } + else + or_tmp_name = addr_tmp_name; + } } /* end for i */ diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 8c5761d3c55d..899e09dd659b 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-eh.h" #include "case-cfn-macros.h" #include "langhooks.h" +#include "opts.h" /* Loop Vectorization Pass. @@ -167,9 +168,8 @@ static stmt_vec_info vect_is_simple_reduction (loop_vec_info, stmt_vec_info, may already be set for general statements (not just data refs). */ static opt_result -vect_determine_vf_for_stmt_1 (vec_info *vinfo, stmt_vec_info stmt_info, - bool vectype_maybe_set_p, - poly_uint64 *vf) +vect_determine_vectype_for_stmt_1 (vec_info *vinfo, stmt_vec_info stmt_info, + bool vectype_maybe_set_p) { gimple *stmt = stmt_info->stmt; @@ -202,9 +202,6 @@ vect_determine_vf_for_stmt_1 (vec_info *vinfo, stmt_vec_info stmt_info, STMT_VINFO_VECTYPE (stmt_info) = stmt_vectype; } - if (nunits_vectype) - vect_update_max_nunits (vf, nunits_vectype); - return opt_result::success (); } @@ -214,13 +211,12 @@ vect_determine_vf_for_stmt_1 (vec_info *vinfo, stmt_vec_info stmt_info, or false if something prevented vectorization. */ static opt_result -vect_determine_vf_for_stmt (vec_info *vinfo, - stmt_vec_info stmt_info, poly_uint64 *vf) +vect_determine_vectype_for_stmt (vec_info *vinfo, stmt_vec_info stmt_info) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "==> examining statement: %G", stmt_info->stmt); - opt_result res = vect_determine_vf_for_stmt_1 (vinfo, stmt_info, false, vf); + opt_result res = vect_determine_vectype_for_stmt_1 (vinfo, stmt_info, false); if (!res) return res; @@ -239,7 +235,7 @@ vect_determine_vf_for_stmt (vec_info *vinfo, dump_printf_loc (MSG_NOTE, vect_location, "==> examining pattern def stmt: %G", def_stmt_info->stmt); - res = vect_determine_vf_for_stmt_1 (vinfo, def_stmt_info, true, vf); + res = vect_determine_vectype_for_stmt_1 (vinfo, def_stmt_info, true); if (!res) return res; } @@ -248,7 +244,7 @@ vect_determine_vf_for_stmt (vec_info *vinfo, dump_printf_loc (MSG_NOTE, vect_location, "==> examining pattern statement: %G", stmt_info->stmt); - res = vect_determine_vf_for_stmt_1 (vinfo, stmt_info, true, vf); + res = vect_determine_vectype_for_stmt_1 (vinfo, stmt_info, true); if (!res) return res; } @@ -256,45 +252,23 @@ vect_determine_vf_for_stmt (vec_info *vinfo, return opt_result::success (); } -/* Function vect_determine_vectorization_factor - - Determine the vectorization factor (VF). VF is the number of data elements - that are operated upon in parallel in a single iteration of the vectorized - loop. For example, when vectorizing a loop that operates on 4byte elements, - on a target with vector size (VS) 16byte, the VF is set to 4, since 4 - elements can fit in a single vector register. - - We currently support vectorization of loops in which all types operated upon - are of the same size. Therefore this function currently sets VF according to - the size of the types operated upon, and fails if there are multiple sizes - in the loop. - - VF is also the factor by which the loop iterations are strip-mined, e.g.: - original loop: - for (i=0; inum_nodes; - poly_uint64 vectorization_factor = 1; tree scalar_type = NULL_TREE; gphi *phi; tree vectype; stmt_vec_info stmt_info; unsigned i; - DUMP_VECT_SCOPE ("vect_determine_vectorization_factor"); + DUMP_VECT_SCOPE ("vect_set_stmts_vectype"); for (i = 0; i < nbbs; i++) { @@ -333,15 +307,6 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "vectype: %T\n", vectype); - - if (dump_enabled_p ()) - { - dump_printf_loc (MSG_NOTE, vect_location, "nunits = "); - dump_dec (MSG_NOTE, TYPE_VECTOR_SUBPARTS (vectype)); - dump_printf (MSG_NOTE, "\n"); - } - - vect_update_max_nunits (&vectorization_factor, vectype); } } @@ -352,25 +317,12 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) continue; stmt_info = loop_vinfo->lookup_stmt (gsi_stmt (si)); opt_result res - = vect_determine_vf_for_stmt (loop_vinfo, - stmt_info, &vectorization_factor); + = vect_determine_vectype_for_stmt (loop_vinfo, stmt_info); if (!res) return res; } } - /* TODO: Analyze cost. Decide if worth while to vectorize. */ - if (dump_enabled_p ()) - { - dump_printf_loc (MSG_NOTE, vect_location, "vectorization factor = "); - dump_dec (MSG_NOTE, vectorization_factor); - dump_printf (MSG_NOTE, "\n"); - } - - if (known_le (vectorization_factor, 1U)) - return opt_result::failure_at (vect_location, - "not vectorized: unsupported data-type\n"); - LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor; return opt_result::success (); } @@ -1069,10 +1021,12 @@ _loop_vec_info::_loop_vec_info (class loop *loop_in, vec_info_shared *shared) using_decrementing_iv_p (false), using_select_vl_p (false), epil_using_partial_vectors_p (false), + allow_mutual_alignment (false), partial_load_store_bias (0), peeling_for_gaps (false), peeling_for_niter (false), early_breaks (false), + user_unroll (false), no_data_dependencies (false), has_mask_store (false), scalar_loop_scaling (profile_probability::uninitialized ()), @@ -1999,234 +1953,6 @@ vect_create_loop_vinfo (class loop *loop, vec_info_shared *shared, -/* Scan the loop stmts and dependent on whether there are any (non-)SLP - statements update the vectorization factor. */ - -static void -vect_update_vf_for_slp (loop_vec_info loop_vinfo) -{ - class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); - basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo); - int nbbs = loop->num_nodes; - poly_uint64 vectorization_factor; - int i; - - DUMP_VECT_SCOPE ("vect_update_vf_for_slp"); - - vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo); - gcc_assert (known_ne (vectorization_factor, 0U)); - - /* If all the stmts in the loop can be SLPed, we perform only SLP, and - vectorization factor of the loop is the unrolling factor required by - the SLP instances. If that unrolling factor is 1, we say, that we - perform pure SLP on loop - cross iteration parallelism is not - exploited. */ - bool only_slp_in_loop = true; - for (i = 0; i < nbbs; i++) - { - basic_block bb = bbs[i]; - for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si); - gsi_next (&si)) - { - stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (si.phi ()); - if (!stmt_info) - continue; - if ((STMT_VINFO_RELEVANT_P (stmt_info) - || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))) - && !PURE_SLP_STMT (stmt_info)) - /* STMT needs both SLP and loop-based vectorization. */ - only_slp_in_loop = false; - } - for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); - gsi_next (&si)) - { - if (is_gimple_debug (gsi_stmt (si))) - continue; - stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (gsi_stmt (si)); - stmt_info = vect_stmt_to_vectorize (stmt_info); - if ((STMT_VINFO_RELEVANT_P (stmt_info) - || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))) - && !PURE_SLP_STMT (stmt_info)) - /* STMT needs both SLP and loop-based vectorization. */ - only_slp_in_loop = false; - } - } - - if (only_slp_in_loop) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "Loop contains only SLP stmts\n"); - vectorization_factor = LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo); - } - else - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "Loop contains SLP and non-SLP stmts\n"); - /* Both the vectorization factor and unroll factor have the form - GET_MODE_SIZE (loop_vinfo->vector_mode) * X for some rational X, - so they must have a common multiple. */ - vectorization_factor - = force_common_multiple (vectorization_factor, - LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo)); - } - - LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor; - if (dump_enabled_p ()) - { - dump_printf_loc (MSG_NOTE, vect_location, - "Updating vectorization factor to "); - dump_dec (MSG_NOTE, vectorization_factor); - dump_printf (MSG_NOTE, ".\n"); - } -} - -/* Return true if STMT_INFO describes a double reduction phi and if - the other phi in the reduction is also relevant for vectorization. - This rejects cases such as: - - outer1: - x_1 = PHI ; - ... - - inner: - x_2 = ...; - ... - - outer2: - x_3 = PHI ; - - if nothing in x_2 or elsewhere makes x_1 relevant. */ - -static bool -vect_active_double_reduction_p (stmt_vec_info stmt_info) -{ - if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_double_reduction_def) - return false; - - return STMT_VINFO_RELEVANT_P (STMT_VINFO_REDUC_DEF (stmt_info)); -} - -/* Function vect_analyze_loop_operations. - - Scan the loop stmts and make sure they are all vectorizable. */ - -static opt_result -vect_analyze_loop_operations (loop_vec_info loop_vinfo) -{ - class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); - basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo); - int nbbs = loop->num_nodes; - int i; - stmt_vec_info stmt_info; - - DUMP_VECT_SCOPE ("vect_analyze_loop_operations"); - - for (i = 0; i < nbbs; i++) - { - basic_block bb = bbs[i]; - - for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si); - gsi_next (&si)) - { - gphi *phi = si.phi (); - - stmt_info = loop_vinfo->lookup_stmt (phi); - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "examining phi: %G", - (gimple *) phi); - if (virtual_operand_p (gimple_phi_result (phi))) - continue; - - /* ??? All of the below unconditional FAILs should be in - done earlier after analyzing cycles, possibly when - determining stmt relevancy? */ - - /* Inner-loop loop-closed exit phi in outer-loop vectorization - (i.e., a phi in the tail of the outer-loop). */ - if (! is_loop_header_bb_p (bb)) - { - /* FORNOW: we currently don't support the case that these phis - are not used in the outerloop (unless it is double reduction, - i.e., this phi is vect_reduction_def), cause this case - requires to actually do something here. */ - if (STMT_VINFO_LIVE_P (stmt_info) - && !vect_active_double_reduction_p (stmt_info)) - return opt_result::failure_at (phi, - "Unsupported loop-closed phi" - " in outer-loop.\n"); - - /* If PHI is used in the outer loop, we check that its operand - is defined in the inner loop. */ - if (STMT_VINFO_RELEVANT_P (stmt_info)) - { - tree phi_op; - - if (gimple_phi_num_args (phi) != 1) - return opt_result::failure_at (phi, "unsupported phi"); - - phi_op = PHI_ARG_DEF (phi, 0); - stmt_vec_info op_def_info = loop_vinfo->lookup_def (phi_op); - if (!op_def_info) - return opt_result::failure_at (phi, "unsupported phi\n"); - - if (STMT_VINFO_RELEVANT (op_def_info) != vect_used_in_outer - && (STMT_VINFO_RELEVANT (op_def_info) - != vect_used_in_outer_by_reduction)) - return opt_result::failure_at (phi, "unsupported phi\n"); - - if ((STMT_VINFO_DEF_TYPE (stmt_info) == vect_internal_def - || (STMT_VINFO_DEF_TYPE (stmt_info) - == vect_double_reduction_def)) - && ! PURE_SLP_STMT (stmt_info)) - return opt_result::failure_at (phi, "unsupported phi\n"); - } - - continue; - } - - gcc_assert (stmt_info); - - if ((STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_scope - || STMT_VINFO_LIVE_P (stmt_info)) - && STMT_VINFO_DEF_TYPE (stmt_info) != vect_induction_def - && STMT_VINFO_DEF_TYPE (stmt_info) != vect_first_order_recurrence) - /* A scalar-dependence cycle that we don't support. */ - return opt_result::failure_at (phi, - "not vectorized:" - " scalar dependence cycle.\n"); - - if (STMT_VINFO_RELEVANT_P (stmt_info) - && ! PURE_SLP_STMT (stmt_info)) - return opt_result::failure_at (phi, - "not vectorized: relevant phi not " - "supported: %G", - static_cast (phi)); - } - - for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); - gsi_next (&si)) - { - gimple *stmt = gsi_stmt (si); - if (!gimple_clobber_p (stmt) - && !is_gimple_debug (stmt)) - { - bool need_to_vectorize = false; - opt_result res - = vect_analyze_stmt (loop_vinfo, - loop_vinfo->lookup_stmt (stmt), - &need_to_vectorize, - NULL, NULL, NULL); - if (!res) - return res; - } - } - } /* bbs */ - - return opt_result::success (); -} - /* Return true if we know that the iteration count is smaller than the vectorization factor. Return false if it isn't, or if we can't be sure either way. */ @@ -2527,78 +2253,6 @@ vect_get_datarefs_in_loop (loop_p loop, basic_block *bbs, return opt_result::success (); } -/* Look for SLP-only access groups and turn each individual access into its own - group. */ -static void -vect_dissolve_slp_only_groups (loop_vec_info loop_vinfo) -{ - unsigned int i; - struct data_reference *dr; - - DUMP_VECT_SCOPE ("vect_dissolve_slp_only_groups"); - - vec datarefs = LOOP_VINFO_DATAREFS (loop_vinfo); - FOR_EACH_VEC_ELT (datarefs, i, dr) - { - gcc_assert (DR_REF (dr)); - stmt_vec_info stmt_info - = vect_stmt_to_vectorize (loop_vinfo->lookup_stmt (DR_STMT (dr))); - - /* Check if the load is a part of an interleaving chain. */ - if (STMT_VINFO_GROUPED_ACCESS (stmt_info)) - { - stmt_vec_info first_element = DR_GROUP_FIRST_ELEMENT (stmt_info); - dr_vec_info *dr_info = STMT_VINFO_DR_INFO (first_element); - unsigned int group_size = DR_GROUP_SIZE (first_element); - - /* Check if SLP-only groups. */ - if (!STMT_SLP_TYPE (stmt_info) - && STMT_VINFO_SLP_VECT_ONLY (first_element)) - { - /* Dissolve the group. */ - STMT_VINFO_SLP_VECT_ONLY (first_element) = false; - - stmt_vec_info vinfo = first_element; - while (vinfo) - { - stmt_vec_info next = DR_GROUP_NEXT_ELEMENT (vinfo); - DR_GROUP_FIRST_ELEMENT (vinfo) = vinfo; - DR_GROUP_NEXT_ELEMENT (vinfo) = NULL; - DR_GROUP_SIZE (vinfo) = 1; - if (STMT_VINFO_STRIDED_P (first_element) - /* We cannot handle stores with gaps. */ - || DR_IS_WRITE (dr_info->dr)) - { - STMT_VINFO_STRIDED_P (vinfo) = true; - DR_GROUP_GAP (vinfo) = 0; - } - else - DR_GROUP_GAP (vinfo) = group_size - 1; - /* Duplicate and adjust alignment info, it needs to - be present on each group leader, see dr_misalignment. */ - if (vinfo != first_element) - { - dr_vec_info *dr_info2 = STMT_VINFO_DR_INFO (vinfo); - dr_info2->target_alignment = dr_info->target_alignment; - int misalignment = dr_info->misalignment; - if (misalignment != DR_MISALIGNMENT_UNKNOWN) - { - HOST_WIDE_INT diff - = (TREE_INT_CST_LOW (DR_INIT (dr_info2->dr)) - - TREE_INT_CST_LOW (DR_INIT (dr_info->dr))); - unsigned HOST_WIDE_INT align_c - = dr_info->target_alignment.to_constant (); - misalignment = (misalignment + diff) % align_c; - } - dr_info2->misalignment = misalignment; - } - vinfo = next; - } - } - } - } -} - /* Determine if operating on full vectors for LOOP_VINFO might leave some scalar iterations still to do. If so, decide how we should handle those scalar iterations. The possibilities are: @@ -2719,7 +2373,6 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo, bool &fatal, opt_result ok = opt_result::success (); int res; unsigned int max_vf = MAX_VECTORIZATION_FACTOR; - poly_uint64 min_vf = 2; loop_vec_info orig_loop_vinfo = NULL; /* If we are dealing with an epilogue then orig_loop_vinfo points to the @@ -2766,7 +2419,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo, bool &fatal, /* Analyze the data references and also adjust the minimal vectorization factor according to the loads and stores. */ - ok = vect_analyze_data_refs (loop_vinfo, &min_vf, &fatal); + ok = vect_analyze_data_refs (loop_vinfo, &fatal); if (!ok) { if (dump_enabled_p ()) @@ -2831,24 +2484,20 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo, bool &fatal, "bad data dependence.\n"); return ok; } - if (max_vf != MAX_VECTORIZATION_FACTOR - && maybe_lt (max_vf, min_vf)) - return opt_result::failure_at (vect_location, "bad data dependence.\n"); LOOP_VINFO_MAX_VECT_FACTOR (loop_vinfo) = max_vf; - ok = vect_determine_vectorization_factor (loop_vinfo); + ok = vect_set_stmts_vectype (loop_vinfo); if (!ok) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "can't determine vectorization factor.\n"); + "cannot determine vector types.\n"); return ok; } /* Compute the scalar iteration cost. */ vect_compute_single_scalar_iteration_cost (loop_vinfo); - poly_uint64 saved_vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo); bool saved_can_use_partial_vectors_p = LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo); @@ -2864,21 +2513,29 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo, bool &fatal, return ok; /* If there are any SLP instances mark them as pure_slp. */ - if (vect_make_slp_decision (loop_vinfo)) - { - /* Find stmts that need to be both vectorized and SLPed. */ - vect_detect_hybrid_slp (loop_vinfo); + if (!vect_make_slp_decision (loop_vinfo)) + return opt_result::failure_at (vect_location, "no stmts to vectorize.\n"); - /* Update the vectorization factor based on the SLP decision. */ - vect_update_vf_for_slp (loop_vinfo); + /* Find stmts that need to be both vectorized and SLPed. */ + if (!vect_detect_hybrid_slp (loop_vinfo)) + return opt_result::failure_at (vect_location, "needs non-SLP handling\n"); - /* Optimize the SLP graph with the vectorization factor fixed. */ - vect_optimize_slp (loop_vinfo); - - /* Gather the loads reachable from the SLP graph entries. */ - vect_gather_slp_loads (loop_vinfo); + /* Determine the vectorization factor from the SLP decision. */ + LOOP_VINFO_VECT_FACTOR (loop_vinfo) + = LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo); + if (dump_enabled_p ()) + { + dump_printf_loc (MSG_NOTE, vect_location, "vectorization factor = "); + dump_dec (MSG_NOTE, LOOP_VINFO_VECT_FACTOR (loop_vinfo)); + dump_printf (MSG_NOTE, "\n"); } + /* Optimize the SLP graph with the vectorization factor fixed. */ + vect_optimize_slp (loop_vinfo); + + /* Gather the loads reachable from the SLP graph entries. */ + vect_gather_slp_loads (loop_vinfo); + /* We don't expect to have to roll back to anything other than an empty set of rgroups. */ gcc_assert (LOOP_VINFO_MASKS (loop_vinfo).is_empty ()); @@ -2947,19 +2604,6 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo, bool &fatal, goto again; } - /* Dissolve SLP-only groups. */ - vect_dissolve_slp_only_groups (loop_vinfo); - - /* Scan all the remaining operations in the loop that we did not catch - during SLP build and make sure we fail. */ - ok = vect_analyze_loop_operations (loop_vinfo); - if (!ok) - { - ok = opt_result::failure_at (vect_location, - "bad operation or unsupported loop bound\n"); - goto again; - } - /* For now, we don't expect to mix both masking and length approaches for one loop, disable it if both are recorded. */ if (LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) @@ -3269,8 +2913,8 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo, bool &fatal, dump_printf_loc (MSG_NOTE, vect_location, "re-trying with single-lane SLP\n"); - /* Restore vectorization factor as it were without SLP. */ - LOOP_VINFO_VECT_FACTOR (loop_vinfo) = saved_vectorization_factor; + /* Reset the vectorization factor. */ + LOOP_VINFO_VECT_FACTOR (loop_vinfo) = 0; /* Free the SLP instances. */ FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (loop_vinfo), j, instance) vect_free_slp_instance (instance); @@ -3398,8 +3042,10 @@ vect_joust_loop_vinfos (loop_vec_info new_loop_vinfo, } /* Analyze LOOP with VECTOR_MODES[MODE_I] and as epilogue if ORIG_LOOP_VINFO is - not NULL. Set AUTODETECTED_VECTOR_MODE if VOIDmode and advance - MODE_I to the next mode useful to analyze. + not NULL. When MASKED_P is not -1 override the default + LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P with it. + Set AUTODETECTED_VECTOR_MODE if VOIDmode and advance MODE_I to the next + mode useful to analyze. Return the loop_vinfo on success and wrapped null on failure. */ static opt_loop_vec_info @@ -3407,6 +3053,7 @@ vect_analyze_loop_1 (class loop *loop, vec_info_shared *shared, const vect_loop_form_info *loop_form_info, loop_vec_info orig_loop_vinfo, const vector_modes &vector_modes, unsigned &mode_i, + int masked_p, machine_mode &autodetected_vector_mode, bool &fatal) { @@ -3415,6 +3062,8 @@ vect_analyze_loop_1 (class loop *loop, vec_info_shared *shared, machine_mode vector_mode = vector_modes[mode_i]; loop_vinfo->vector_mode = vector_mode; + if (masked_p != -1) + loop_vinfo->can_use_partial_vectors_p = masked_p; unsigned int suggested_unroll_factor = 1; unsigned slp_done_for_suggested_uf = 0; @@ -3428,27 +3077,50 @@ vect_analyze_loop_1 (class loop *loop, vec_info_shared *shared, res ? "succeeded" : "failed", GET_MODE_NAME (loop_vinfo->vector_mode)); - if (res && !LOOP_VINFO_EPILOGUE_P (loop_vinfo) && suggested_unroll_factor > 1) + auto user_unroll = LOOP_VINFO_LOOP (loop_vinfo)->unroll; + if (res && !LOOP_VINFO_EPILOGUE_P (loop_vinfo) + /* Check to see if the user wants to unroll or if the target wants to. */ + && (suggested_unroll_factor > 1 || user_unroll > 1)) { - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, + if (suggested_unroll_factor == 1) + { + int assumed_vf = vect_vf_for_cost (loop_vinfo); + suggested_unroll_factor = user_unroll / assumed_vf; + if (suggested_unroll_factor > 1) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "setting unroll factor to %d based on user requested " + "unroll factor %d and suggested vectorization " + "factor: %d\n", + suggested_unroll_factor, user_unroll, assumed_vf); + } + } + + if (suggested_unroll_factor > 1) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, "***** Re-trying analysis for unrolling" " with unroll factor %d and slp %s.\n", suggested_unroll_factor, slp_done_for_suggested_uf ? "on" : "off"); - loop_vec_info unroll_vinfo - = vect_create_loop_vinfo (loop, shared, loop_form_info, NULL); - unroll_vinfo->vector_mode = vector_mode; - unroll_vinfo->suggested_unroll_factor = suggested_unroll_factor; - opt_result new_res = vect_analyze_loop_2 (unroll_vinfo, fatal, NULL, - slp_done_for_suggested_uf); - if (new_res) - { - delete loop_vinfo; - loop_vinfo = unroll_vinfo; - } - else - delete unroll_vinfo; + loop_vec_info unroll_vinfo + = vect_create_loop_vinfo (loop, shared, loop_form_info, NULL); + unroll_vinfo->vector_mode = vector_mode; + unroll_vinfo->suggested_unroll_factor = suggested_unroll_factor; + opt_result new_res + = vect_analyze_loop_2 (unroll_vinfo, fatal, NULL, + slp_done_for_suggested_uf); + if (new_res) + { + delete loop_vinfo; + loop_vinfo = unroll_vinfo; + LOOP_VINFO_USER_UNROLL (loop_vinfo) = user_unroll > 1; + } + else + delete unroll_vinfo; + } } /* Remember the autodetected vector mode. */ @@ -3469,13 +3141,8 @@ vect_analyze_loop_1 (class loop *loop, vec_info_shared *shared, mode_i += 1; } if (mode_i + 1 < vector_modes.length () - && VECTOR_MODE_P (autodetected_vector_mode) - && (related_vector_mode (vector_modes[mode_i + 1], - GET_MODE_INNER (autodetected_vector_mode)) - == autodetected_vector_mode) - && (related_vector_mode (autodetected_vector_mode, - GET_MODE_INNER (vector_modes[mode_i + 1])) - == vector_modes[mode_i + 1])) + && vect_chooses_same_modes_p (autodetected_vector_mode, + vector_modes[mode_i + 1])) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, @@ -3580,7 +3247,7 @@ vect_analyze_loop (class loop *loop, gimple *loop_vectorized_call, cached_vf_per_mode[last_mode_i] = -1; opt_loop_vec_info loop_vinfo = vect_analyze_loop_1 (loop, shared, &loop_form_info, - NULL, vector_modes, mode_i, + NULL, vector_modes, mode_i, -1, autodetected_vector_mode, fatal); if (fatal) break; @@ -3665,24 +3332,38 @@ vect_analyze_loop (class loop *loop, gimple *loop_vectorized_call, array may contain length-agnostic and length-specific modes. Their ordering is not guaranteed, so we could end up picking a mode for the main loop that is after the epilogue's optimal mode. */ + int masked_p = -1; if (!unlimited_cost_model (loop) - && first_loop_vinfo->vector_costs->suggested_epilogue_mode () != VOIDmode) + && (first_loop_vinfo->vector_costs->suggested_epilogue_mode (masked_p) + != VOIDmode)) { vector_modes[0] - = first_loop_vinfo->vector_costs->suggested_epilogue_mode (); + = first_loop_vinfo->vector_costs->suggested_epilogue_mode (masked_p); cached_vf_per_mode[0] = 0; } else vector_modes[0] = autodetected_vector_mode; mode_i = 0; - bool supports_partial_vectors = - partial_vectors_supported_p () && param_vect_partial_vector_usage != 0; + bool supports_partial_vectors = (param_vect_partial_vector_usage != 0 + || masked_p == 1); + machine_mode mask_mode; + if (supports_partial_vectors + && !partial_vectors_supported_p () + && !(VECTOR_MODE_P (first_loop_vinfo->vector_mode) + && targetm.vectorize.get_mask_mode + (first_loop_vinfo->vector_mode).exists (&mask_mode) + && SCALAR_INT_MODE_P (mask_mode))) + supports_partial_vectors = false; poly_uint64 first_vinfo_vf = LOOP_VINFO_VECT_FACTOR (first_loop_vinfo); loop_vec_info orig_loop_vinfo = first_loop_vinfo; do { + /* Let the user override what the target suggests. */ + if (OPTION_SET_P (param_vect_partial_vector_usage)) + masked_p = -1; + while (1) { /* If the target does not support partial vectors we can shorten the @@ -3697,6 +3378,22 @@ vect_analyze_loop (class loop *loop, gimple *loop_vectorized_call, break; continue; } + /* We would need an exhaustive search to find all modes we + skipped but that would lead to the same result as the + analysis it was skipped for and where we'd could check + cached_vf_per_mode against. + Check for the autodetected mode, which is the common + situation on x86 which does not perform cost comparison. */ + if (!supports_partial_vectors + && maybe_ge (cached_vf_per_mode[0], first_vinfo_vf) + && vect_chooses_same_modes_p (autodetected_vector_mode, + vector_modes[mode_i])) + { + mode_i++; + if (mode_i == vector_modes.length ()) + break; + continue; + } if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, @@ -3707,7 +3404,7 @@ vect_analyze_loop (class loop *loop, gimple *loop_vectorized_call, opt_loop_vec_info loop_vinfo = vect_analyze_loop_1 (loop, shared, &loop_form_info, orig_loop_vinfo, - vector_modes, mode_i, + vector_modes, mode_i, masked_p, autodetected_vector_mode, fatal); if (fatal) break; @@ -3738,6 +3435,9 @@ vect_analyze_loop (class loop *loop, gimple *loop_vectorized_call, break; } + /* Revert back to the default from the suggested prefered + epilogue vectorization mode. */ + masked_p = -1; if (mode_i == vector_modes.length ()) break; } @@ -3748,12 +3448,14 @@ vect_analyze_loop (class loop *loop, gimple *loop_vectorized_call, /* When we selected a first vectorized epilogue, see if the target suggests to have another one. */ + masked_p = -1; if (!unlimited_cost_model (loop) - && (orig_loop_vinfo->vector_costs->suggested_epilogue_mode () + && !LOOP_VINFO_USING_PARTIAL_VECTORS_P (orig_loop_vinfo) + && (orig_loop_vinfo->vector_costs->suggested_epilogue_mode (masked_p) != VOIDmode)) { vector_modes[0] - = orig_loop_vinfo->vector_costs->suggested_epilogue_mode (); + = orig_loop_vinfo->vector_costs->suggested_epilogue_mode (masked_p); cached_vf_per_mode[0] = 0; mode_i = 0; } @@ -4101,6 +3803,10 @@ check_reduction_path (dump_user_location_t loc, loop_p loop, gphi *phi, if (op.ops[2] == op.ops[opi]) neg = ! neg; } + /* For an FMA the reduction code is the PLUS if the addition chain + is the reduction. */ + else if (op.code == IFN_FMA && opi == 2) + op.code = PLUS_EXPR; if (CONVERT_EXPR_CODE_P (op.code) && tree_nop_conversion_p (op.type, TREE_TYPE (op.ops[0]))) ; @@ -4646,7 +4352,8 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, TODO: Consider assigning different costs to different scalar statements. */ - scalar_single_iter_cost = loop_vinfo->scalar_costs->total_cost (); + scalar_single_iter_cost = (loop_vinfo->scalar_costs->total_cost () + * param_vect_scalar_cost_multiplier) / 100; /* Add additional cost for the peeled instructions in prologue and epilogue loop. (For fully-masked loops there will be no peeling.) @@ -5283,7 +4990,7 @@ vect_is_emulated_mixed_dot_prod (stmt_vec_info stmt_info) static void vect_model_reduction_cost (loop_vec_info loop_vinfo, - stmt_vec_info stmt_info, internal_fn reduc_fn, + slp_tree node, internal_fn reduc_fn, vect_reduction_type reduction_type, int ncopies, stmt_vector_for_cost *cost_vec) { @@ -5299,9 +5006,10 @@ vect_model_reduction_cost (loop_vec_info loop_vinfo, if (reduction_type == COND_REDUCTION) ncopies *= 2; - vectype = STMT_VINFO_VECTYPE (stmt_info); + vectype = SLP_TREE_VECTYPE (node); mode = TYPE_MODE (vectype); - stmt_vec_info orig_stmt_info = vect_orig_stmt (stmt_info); + stmt_vec_info orig_stmt_info + = vect_orig_stmt (SLP_TREE_REPRESENTATIVE (node)); gimple_match_op op; if (!gimple_extract_op (orig_stmt_info->stmt, &op)) @@ -5319,16 +5027,16 @@ vect_model_reduction_cost (loop_vec_info loop_vinfo, if (reduc_fn != IFN_LAST) /* Count one reduction-like operation per vector. */ inside_cost = record_stmt_cost (cost_vec, ncopies, vec_to_scalar, - stmt_info, 0, vect_body); + node, 0, vect_body); else { /* Use NELEMENTS extracts and NELEMENTS scalar ops. */ unsigned int nelements = ncopies * vect_nunits_for_cost (vectype); inside_cost = record_stmt_cost (cost_vec, nelements, - vec_to_scalar, stmt_info, 0, + vec_to_scalar, node, 0, vect_body); inside_cost += record_stmt_cost (cost_vec, nelements, - scalar_stmt, stmt_info, 0, + scalar_stmt, node, 0, vect_body); } } @@ -5345,7 +5053,7 @@ vect_model_reduction_cost (loop_vec_info loop_vinfo, /* We need the initial reduction value. */ prologue_stmts = 1; prologue_cost += record_stmt_cost (cost_vec, prologue_stmts, - scalar_to_vec, stmt_info, 0, + scalar_to_vec, node, 0, vect_prologue); } @@ -5362,24 +5070,24 @@ vect_model_reduction_cost (loop_vec_info loop_vinfo, { /* An EQ stmt and an COND_EXPR stmt. */ epilogue_cost += record_stmt_cost (cost_vec, 2, - vector_stmt, stmt_info, 0, + vector_stmt, node, 0, vect_epilogue); /* Reduction of the max index and a reduction of the found values. */ epilogue_cost += record_stmt_cost (cost_vec, 2, - vec_to_scalar, stmt_info, 0, + vec_to_scalar, node, 0, vect_epilogue); /* A broadcast of the max value. */ epilogue_cost += record_stmt_cost (cost_vec, 1, - scalar_to_vec, stmt_info, 0, + scalar_to_vec, node, 0, vect_epilogue); } else { epilogue_cost += record_stmt_cost (cost_vec, 1, vector_stmt, - stmt_info, 0, vect_epilogue); + node, 0, vect_epilogue); epilogue_cost += record_stmt_cost (cost_vec, 1, - vec_to_scalar, stmt_info, 0, + vec_to_scalar, node, 0, vect_epilogue); } } @@ -5389,12 +5097,12 @@ vect_model_reduction_cost (loop_vec_info loop_vinfo, /* Extraction of scalar elements. */ epilogue_cost += record_stmt_cost (cost_vec, 2 * estimated_nunits, - vec_to_scalar, stmt_info, 0, + vec_to_scalar, node, 0, vect_epilogue); /* Scalar max reductions via COND_EXPR / MAX_EXPR. */ epilogue_cost += record_stmt_cost (cost_vec, 2 * estimated_nunits - 3, - scalar_stmt, stmt_info, 0, + scalar_stmt, node, 0, vect_epilogue); } else if (reduction_type == EXTRACT_LAST_REDUCTION @@ -5420,10 +5128,10 @@ vect_model_reduction_cost (loop_vec_info loop_vinfo, Also requires scalar extract. */ epilogue_cost += record_stmt_cost (cost_vec, exact_log2 (nelements) * 2, - vector_stmt, stmt_info, 0, + vector_stmt, node, 0, vect_epilogue); epilogue_cost += record_stmt_cost (cost_vec, 1, - vec_to_scalar, stmt_info, 0, + vec_to_scalar, node, 0, vect_epilogue); } else @@ -5431,7 +5139,7 @@ vect_model_reduction_cost (loop_vec_info loop_vinfo, elements, we have N extracts and N-1 reduction ops. */ epilogue_cost += record_stmt_cost (cost_vec, nelements + nelements - 1, - vector_stmt, stmt_info, 0, + vector_stmt, node, 0, vect_epilogue); } } @@ -7597,17 +7305,17 @@ vectorizable_reduction (loop_vec_info loop_vinfo, unsigned reduc_chain_length = 0; bool only_slp_reduc_chain = true; stmt_info = NULL; - slp_tree slp_for_stmt_info = slp_node_instance->root; + slp_tree slp_for_stmt_info = NULL; + slp_tree vdef_slp = slp_node_instance->root; /* For double-reductions we start SLP analysis at the inner loop LC PHI which is the def of the outer loop live stmt. */ if (STMT_VINFO_DEF_TYPE (reduc_info) == vect_double_reduction_def) - slp_for_stmt_info = SLP_TREE_CHILDREN (slp_for_stmt_info)[0]; + vdef_slp = SLP_TREE_CHILDREN (vdef_slp)[0]; while (reduc_def != PHI_RESULT (reduc_def_phi)) { stmt_vec_info def = loop_vinfo->lookup_def (reduc_def); stmt_vec_info vdef = vect_stmt_to_vectorize (def); int reduc_idx = STMT_VINFO_REDUC_IDX (vdef); - if (reduc_idx == -1) { if (dump_enabled_p ()) @@ -7624,14 +7332,9 @@ vectorizable_reduction (loop_vec_info loop_vinfo, the SLP node with live lane zero the other live lanes also need to be identified as part of a reduction to be able to skip code generation for them. */ - if (slp_for_stmt_info) - { - for (auto s : SLP_TREE_SCALAR_STMTS (slp_for_stmt_info)) - if (STMT_VINFO_LIVE_P (s)) - STMT_VINFO_REDUC_DEF (vect_orig_stmt (s)) = phi_info; - } - else if (STMT_VINFO_LIVE_P (vdef)) - STMT_VINFO_REDUC_DEF (def) = phi_info; + for (auto s : SLP_TREE_SCALAR_STMTS (vdef_slp)) + if (STMT_VINFO_LIVE_P (s)) + STMT_VINFO_REDUC_DEF (vect_orig_stmt (s)) = phi_info; gimple_match_op op; if (!gimple_extract_op (vdef->stmt, &op)) { @@ -7650,32 +7353,33 @@ vectorizable_reduction (loop_vec_info loop_vinfo, "conversion in the reduction chain.\n"); return false; } + vdef_slp = SLP_TREE_CHILDREN (vdef_slp)[0]; } else { /* First non-conversion stmt. */ if (!stmt_info) - stmt_info = vdef; + { + stmt_info = vdef; + slp_for_stmt_info = vdef_slp; + } if (lane_reducing_op_p (op.code)) { - enum vect_def_type dt; - tree vectype_op; - /* The last operand of lane-reducing operation is for reduction. */ gcc_assert (reduc_idx > 0 && reduc_idx == (int) op.num_ops - 1); - if (!vect_is_simple_use (op.ops[0], loop_vinfo, &dt, &vectype_op)) - return false; - + slp_tree op_node = SLP_TREE_CHILDREN (vdef_slp)[0]; + tree vectype_op = SLP_TREE_VECTYPE (op_node); tree type_op = TREE_TYPE (op.ops[0]); - if (!vectype_op) { vectype_op = get_vectype_for_scalar_type (loop_vinfo, type_op); - if (!vectype_op) + if (!vectype_op + || !vect_maybe_update_slp_op_vectype (op_node, + vectype_op)) return false; } @@ -7697,14 +7401,14 @@ vectorizable_reduction (loop_vec_info loop_vinfo, < GET_MODE_SIZE (SCALAR_TYPE_MODE (type_op)))) vectype_in = vectype_op; } - else + else if (!vectype_in) vectype_in = STMT_VINFO_VECTYPE (phi_info); + if (!REDUC_GROUP_FIRST_ELEMENT (vdef)) + vdef_slp = SLP_TREE_CHILDREN (vdef_slp)[reduc_idx]; } reduc_def = op.ops[reduc_idx]; reduc_chain_length++; - if (!stmt_info) - slp_for_stmt_info = SLP_TREE_CHILDREN (slp_for_stmt_info)[0]; } /* PHIs should not participate in patterns. */ gcc_assert (!STMT_VINFO_RELATED_STMT (phi_info)); @@ -7756,7 +7460,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo, inside the loop body. The last operand is the reduction variable, which is defined by the loop-header-phi. */ - tree vectype_out = STMT_VINFO_VECTYPE (stmt_info); + tree vectype_out = SLP_TREE_VECTYPE (slp_for_stmt_info); STMT_VINFO_REDUC_VECTYPE (reduc_info) = vectype_out; STMT_VINFO_REDUC_VECTYPE_IN (reduc_info) = vectype_in; @@ -8044,6 +7748,19 @@ vectorizable_reduction (loop_vec_info loop_vinfo, "in-order reduction chain without SLP.\n"); return false; } + /* Code generation doesn't support function calls other + than .COND_*. */ + if (!op.code.is_tree_code () + && !(op.code.is_internal_fn () + && conditional_internal_fn_code (internal_fn (op.code)) + != ERROR_MARK)) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "in-order reduction chain operation not " + "supported.\n"); + return false; + } STMT_VINFO_REDUC_TYPE (reduc_info) = reduction_type = FOLD_LEFT_REDUCTION; } @@ -8346,7 +8063,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo, return false; } - vect_model_reduction_cost (loop_vinfo, stmt_info, reduc_fn, + vect_model_reduction_cost (loop_vinfo, slp_for_stmt_info, reduc_fn, reduction_type, ncopies, cost_vec); /* Cost the reduction op inside the loop if transformed via vect_transform_reduction for non-lane-reducing operation. Otherwise @@ -9042,6 +8759,18 @@ vectorizable_lc_phi (loop_vec_info loop_vinfo, "incompatible vector types for invariants\n"); return false; } + + /* ??? This can happen with data vs. mask uses of boolean. */ + if (!useless_type_conversion_p (SLP_TREE_VECTYPE (slp_node), + SLP_TREE_VECTYPE + (SLP_TREE_CHILDREN (slp_node)[0]))) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "missed mask promotion\n"); + return false; + } + STMT_VINFO_TYPE (stmt_info) = lc_phi_info_type; return true; } @@ -10103,6 +9832,7 @@ vectorizable_induction (loop_vec_info loop_vinfo, } tree stept = TREE_TYPE (step_expr); tree step_vectype = get_same_sized_vectype (stept, vectype); + stept = TREE_TYPE (step_vectype); /* Check for target support of the vectorized arithmetic used here. */ if (!target_supports_op_p (step_vectype, PLUS_EXPR, optab_default) @@ -10557,9 +10287,8 @@ vectorizable_induction (loop_vec_info loop_vinfo, helper function for vectorizable_live_operation. */ static tree -vectorizable_live_operation_1 (loop_vec_info loop_vinfo, - stmt_vec_info stmt_info, basic_block exit_bb, - tree vectype, int ncopies, slp_tree slp_node, +vectorizable_live_operation_1 (loop_vec_info loop_vinfo, basic_block exit_bb, + tree vectype, slp_tree slp_node, tree bitsize, tree bitstart, tree vec_lhs, tree lhs_type, gimple_stmt_iterator *exit_gsi) { @@ -10590,8 +10319,7 @@ vectorizable_live_operation_1 (loop_vec_info loop_vinfo, where VEC_LHS is the vectorized live-out result and MASK is the loop mask for the final iteration. */ - gcc_assert (ncopies == 1 - && (!slp_node || SLP_TREE_LANES (slp_node) == 1)); + gcc_assert (SLP_TREE_LANES (slp_node) == 1); gimple_seq tem = NULL; gimple_stmt_iterator gsi = gsi_last (tem); tree len = vect_get_loop_len (loop_vinfo, &gsi, @@ -10626,8 +10354,8 @@ vectorizable_live_operation_1 (loop_vec_info loop_vinfo, where VEC_LHS is the vectorized live-out result and MASK is the loop mask for the final iteration. */ - gcc_assert (!slp_node || SLP_TREE_LANES (slp_node) == 1); - tree scalar_type = TREE_TYPE (STMT_VINFO_VECTYPE (stmt_info)); + gcc_assert (SLP_TREE_LANES (slp_node) == 1); + tree scalar_type = TREE_TYPE (vectype); gimple_seq tem = NULL; gimple_stmt_iterator gsi = gsi_last (tem); tree mask = vect_get_loop_mask (loop_vinfo, &gsi, @@ -10673,11 +10401,8 @@ vectorizable_live_operation (vec_info *vinfo, stmt_vec_info stmt_info, loop_vec_info loop_vinfo = dyn_cast (vinfo); imm_use_iterator imm_iter; tree lhs, lhs_type, bitsize; - tree vectype = (slp_node - ? SLP_TREE_VECTYPE (slp_node) - : STMT_VINFO_VECTYPE (stmt_info)); + tree vectype = SLP_TREE_VECTYPE (slp_node); poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); - int ncopies; gimple *use_stmt; use_operand_p use_p; auto_vec vec_oprnds; @@ -10696,7 +10421,7 @@ vectorizable_live_operation (vec_info *vinfo, stmt_vec_info stmt_info, return true; /* For SLP reductions we vectorize the epilogue for all involved stmts together. */ - if (slp_node && !REDUC_GROUP_FIRST_ELEMENT (stmt_info) && slp_index != 0) + if (!REDUC_GROUP_FIRST_ELEMENT (stmt_info) && slp_index != 0) return true; stmt_vec_info reduc_info = info_for_reduction (loop_vinfo, stmt_info); gcc_assert (reduc_info->is_reduc_info); @@ -10714,7 +10439,7 @@ vectorizable_live_operation (vec_info *vinfo, stmt_vec_info stmt_info, block, but we have to find an alternate exit first. */ if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo)) { - slp_tree phis_node = slp_node ? slp_node_instance->reduc_phis : NULL; + slp_tree phis_node = slp_node_instance->reduc_phis; for (auto exit : get_loop_exit_edges (LOOP_VINFO_LOOP (loop_vinfo))) if (exit != LOOP_VINFO_IV_EXIT (loop_vinfo)) { @@ -10745,32 +10470,24 @@ vectorizable_live_operation (vec_info *vinfo, stmt_vec_info stmt_info, return true; } - if (slp_node) - ncopies = 1; - else - ncopies = vect_get_num_copies (loop_vinfo, vectype); - - if (slp_node) - { - gcc_assert (slp_index >= 0); + gcc_assert (slp_index >= 0); - /* Get the last occurrence of the scalar index from the concatenation of - all the slp vectors. Calculate which slp vector it is and the index - within. */ - int num_scalar = SLP_TREE_LANES (slp_node); - int num_vec = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); - poly_uint64 pos = (num_vec * nunits) - num_scalar + slp_index; + /* Get the last occurrence of the scalar index from the concatenation of + all the slp vectors. Calculate which slp vector it is and the index + within. */ + int num_scalar = SLP_TREE_LANES (slp_node); + int num_vec = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); + poly_uint64 pos = (num_vec * nunits) - num_scalar + slp_index; - /* Calculate which vector contains the result, and which lane of - that vector we need. */ - if (!can_div_trunc_p (pos, nunits, &vec_entry, &vec_index)) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Cannot determine which vector holds the" - " final result.\n"); - return false; - } + /* Calculate which vector contains the result, and which lane of + that vector we need. */ + if (!can_div_trunc_p (pos, nunits, &vec_entry, &vec_index)) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Cannot determine which vector holds the" + " final result.\n"); + return false; } if (!vec_stmt_p) @@ -10778,7 +10495,7 @@ vectorizable_live_operation (vec_info *vinfo, stmt_vec_info stmt_info, /* No transformation required. */ if (loop_vinfo && LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo)) { - if (slp_node && SLP_TREE_LANES (slp_node) != 1) + if (SLP_TREE_LANES (slp_node) != 1) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -10787,8 +10504,7 @@ vectorizable_live_operation (vec_info *vinfo, stmt_vec_info stmt_info, "the loop.\n"); LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; } - else if (ncopies > 1 - || (slp_node && SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node) > 1)) + else if (SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node) > 1) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -10798,8 +10514,6 @@ vectorizable_live_operation (vec_info *vinfo, stmt_vec_info stmt_info, } else { - gcc_assert (ncopies == 1 - && (!slp_node || SLP_TREE_LANES (slp_node) == 1)); if (direct_internal_fn_supported_p (IFN_EXTRACT_LAST, vectype, OPTIMIZE_FOR_SPEED)) vect_record_loop_mask (loop_vinfo, @@ -10841,40 +10555,21 @@ vectorizable_live_operation (vec_info *vinfo, stmt_vec_info stmt_info, bitsize = vector_element_bits_tree (vectype); /* Get the vectorized lhs of STMT and the lane to use (counted in bits). */ - tree vec_lhs, vec_lhs0, bitstart; - gimple *vec_stmt, *vec_stmt0; - if (slp_node) - { - gcc_assert (!loop_vinfo - || ((!LOOP_VINFO_FULLY_MASKED_P (loop_vinfo) - && !LOOP_VINFO_FULLY_WITH_LENGTH_P (loop_vinfo)) - || SLP_TREE_LANES (slp_node) == 1)); + gcc_assert (!loop_vinfo + || ((!LOOP_VINFO_FULLY_MASKED_P (loop_vinfo) + && !LOOP_VINFO_FULLY_WITH_LENGTH_P (loop_vinfo)) + || SLP_TREE_LANES (slp_node) == 1)); - /* Get the correct slp vectorized stmt. */ - vec_lhs = SLP_TREE_VEC_DEFS (slp_node)[vec_entry]; - vec_stmt = SSA_NAME_DEF_STMT (vec_lhs); + /* Get the correct slp vectorized stmt. */ + tree vec_lhs = SLP_TREE_VEC_DEFS (slp_node)[vec_entry]; + gimple *vec_stmt = SSA_NAME_DEF_STMT (vec_lhs); - /* In case we need to early break vectorize also get the first stmt. */ - vec_lhs0 = SLP_TREE_VEC_DEFS (slp_node)[0]; - vec_stmt0 = SSA_NAME_DEF_STMT (vec_lhs0); + /* In case we need to early break vectorize also get the first stmt. */ + tree vec_lhs0 = SLP_TREE_VEC_DEFS (slp_node)[0]; - /* Get entry to use. */ - bitstart = bitsize_int (vec_index); - bitstart = int_const_binop (MULT_EXPR, bitsize, bitstart); - } - else - { - /* For multiple copies, get the last copy. */ - vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info).last (); - vec_lhs = gimple_get_lhs (vec_stmt); - - /* In case we need to early break vectorize also get the first stmt. */ - vec_stmt0 = STMT_VINFO_VEC_STMTS (stmt_info)[0]; - vec_lhs0 = gimple_get_lhs (vec_stmt0); - - /* Get the last lane in the vector. */ - bitstart = int_const_binop (MULT_EXPR, bitsize, bitsize_int (nunits - 1)); - } + /* Get entry to use. */ + tree bitstart = bitsize_int (vec_index); + bitstart = int_const_binop (MULT_EXPR, bitsize, bitstart); if (loop_vinfo) { @@ -10923,8 +10618,8 @@ vectorizable_live_operation (vec_info *vinfo, stmt_vec_info stmt_info, gimple_stmt_iterator exit_gsi; tree new_tree - = vectorizable_live_operation_1 (loop_vinfo, stmt_info, - e->dest, vectype, ncopies, + = vectorizable_live_operation_1 (loop_vinfo, + e->dest, vectype, slp_node, bitsize, tmp_bitstart, tmp_vec_lhs, lhs_type, &exit_gsi); @@ -11350,7 +11045,7 @@ vect_get_loop_len (loop_vec_info loop_vinfo, gimple_stmt_iterator *gsi, factor = exact_div (nunits1, nunits2).to_constant (); tree iv_type = LOOP_VINFO_RGROUP_IV_TYPE (loop_vinfo); gimple_seq seq = NULL; - loop_len = gimple_build (&seq, RDIV_EXPR, iv_type, loop_len, + loop_len = gimple_build (&seq, EXACT_DIV_EXPR, iv_type, loop_len, build_int_cst (iv_type, factor)); if (seq) gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT); @@ -11410,7 +11105,7 @@ scale_profile_for_vect_loop (class loop *loop, edge exit_e, unsigned vf, bool fl profile_count entry_count = loop_preheader_edge (loop)->count (); /* If we have unreliable loop profile avoid dropping entry - count bellow header count. This can happen since loops + count below header count. This can happen since loops has unrealistically low trip counts. */ while (vf > 1 && loop->header->count > entry_count @@ -12040,6 +11735,13 @@ vect_transform_loop (loop_vec_info loop_vinfo, gimple *loop_vectorized_call) dump_printf_loc (MSG_NOTE, vect_location, "Disabling unrolling due to" " variable-length vectorization factor\n"); } + + /* When we have unrolled the loop due to a user requested value we should + leave it up to the RTL unroll heuristics to determine if it's still worth + while to unroll more. */ + if (LOOP_VINFO_USER_UNROLL (loop_vinfo)) + loop->unroll = 0; + /* Free SLP instances here because otherwise stmt reference counting won't work. */ slp_instance instance; diff --git a/gcc/tree-vect-slp-patterns.cc b/gcc/tree-vect-slp-patterns.cc index c0dff90d9baf..95319bc09ff6 100644 --- a/gcc/tree-vect-slp-patterns.cc +++ b/gcc/tree-vect-slp-patterns.cc @@ -299,18 +299,23 @@ vect_build_swap_evenodd_node (slp_tree node) code CODE. */ static inline bool -vect_match_expression_p (slp_tree node, tree_code code) +vect_match_expression_p (slp_tree node, code_helper code) { if (!node || !SLP_TREE_REPRESENTATIVE (node)) return false; gimple* expr = STMT_VINFO_STMT (SLP_TREE_REPRESENTATIVE (node)); - if (!is_gimple_assign (expr) - || gimple_assign_rhs_code (expr) != code) - return false; - - return true; + if (is_gimple_assign (expr) + && code.is_tree_code () + && gimple_assign_rhs_code (expr) == (tree_code) code) + return true; + if (is_a (expr) + && !code.is_tree_code () + && gimple_call_combined_fn (expr) == (combined_fn) code) + return true; + + return false; } /* Check if the given lane permute in PERMUTES matches an alternating sequence @@ -786,7 +791,7 @@ compatible_complex_nodes_p (slp_compat_nodes_map_t *compat_cache, if (is_gimple_call (a_stmt)) { if (!compatible_calls_p (dyn_cast (a_stmt), - dyn_cast (b_stmt))) + dyn_cast (b_stmt), false)) return false; } else if (!is_gimple_assign (a_stmt)) @@ -1494,15 +1499,33 @@ addsub_pattern::recognize (slp_tree_to_load_perm_map_t *, unsigned l1 = SLP_TREE_LANE_PERMUTATION (node)[1].first; if (l0 == l1) return NULL; + bool fma_p = false; bool l0add_p = vect_match_expression_p (SLP_TREE_CHILDREN (node)[l0], PLUS_EXPR); if (!l0add_p && !vect_match_expression_p (SLP_TREE_CHILDREN (node)[l0], MINUS_EXPR)) - return NULL; + { + l0add_p = vect_match_expression_p (SLP_TREE_CHILDREN (node)[l0], CFN_FMA); + if (!l0add_p + && !vect_match_expression_p (SLP_TREE_CHILDREN (node)[l0], CFN_FMS)) + return NULL; + fma_p = true; + } bool l1add_p = vect_match_expression_p (SLP_TREE_CHILDREN (node)[l1], PLUS_EXPR); + if (l1add_p && fma_p) + return NULL; if (!l1add_p && !vect_match_expression_p (SLP_TREE_CHILDREN (node)[l1], MINUS_EXPR)) + { + if (!fma_p) + return NULL; + l1add_p = vect_match_expression_p (SLP_TREE_CHILDREN (node)[l1], CFN_FMA); + if (!l1add_p + && !vect_match_expression_p (SLP_TREE_CHILDREN (node)[l1], CFN_FMS)) + return NULL; + } + else if (!l1add_p && fma_p) return NULL; slp_tree l0node = SLP_TREE_CHILDREN (node)[l0]; @@ -1527,26 +1550,31 @@ addsub_pattern::recognize (slp_tree_to_load_perm_map_t *, /* Now we have either { -, +, -, + ... } (!l0add_p) or { +, -, +, - ... } (l0add_p), see whether we have FMA variants. We can only form FMAs - if allowed via -ffp-contract=fast. */ - if (flag_fp_contract_mode != FP_CONTRACT_FAST + if allowed via -ffp-contract=fast or if they were FMA before. */ + if (!fma_p + && flag_fp_contract_mode != FP_CONTRACT_FAST && FLOAT_TYPE_P (SLP_TREE_VECTYPE (l0node))) ; else if (!l0add_p - && vect_match_expression_p (SLP_TREE_CHILDREN (l0node)[0], MULT_EXPR)) + && (fma_p + || vect_match_expression_p (SLP_TREE_CHILDREN (l0node)[0], + MULT_EXPR))) { /* (c * d) -+ a */ if (vect_pattern_validate_optab (IFN_VEC_FMADDSUB, node)) return new addsub_pattern (node_, IFN_VEC_FMADDSUB); } else if (l0add_p - && vect_match_expression_p (SLP_TREE_CHILDREN (l1node)[0], MULT_EXPR)) + && (fma_p + || vect_match_expression_p (SLP_TREE_CHILDREN (l1node)[0], + MULT_EXPR))) { /* (c * d) +- a */ if (vect_pattern_validate_optab (IFN_VEC_FMSUBADD, node)) return new addsub_pattern (node_, IFN_VEC_FMSUBADD); } - if (!l0add_p && vect_pattern_validate_optab (IFN_VEC_ADDSUB, node)) + if (!fma_p && !l0add_p && vect_pattern_validate_optab (IFN_VEC_ADDSUB, node)) return new addsub_pattern (node_, IFN_VEC_ADDSUB); return NULL; @@ -1610,25 +1638,42 @@ addsub_pattern::build (vec_info *vinfo) sub = SLP_TREE_CHILDREN (node)[l1]; add = SLP_TREE_CHILDREN (node)[l0]; } - slp_tree mul = SLP_TREE_CHILDREN (sub)[0]; /* Modify the blend node in-place. */ SLP_TREE_CHILDREN (node).safe_grow (3, true); - SLP_TREE_CHILDREN (node)[0] = SLP_TREE_CHILDREN (mul)[0]; - SLP_TREE_CHILDREN (node)[1] = SLP_TREE_CHILDREN (mul)[1]; - SLP_TREE_CHILDREN (node)[2] = SLP_TREE_CHILDREN (sub)[1]; + gcall *call; + stmt_vec_info srep = SLP_TREE_REPRESENTATIVE (sub); + if (vect_match_expression_p (add, CFN_FMA)) + { + SLP_TREE_CHILDREN (node)[0] = SLP_TREE_CHILDREN (add)[0]; + SLP_TREE_CHILDREN (node)[1] = SLP_TREE_CHILDREN (add)[1]; + SLP_TREE_CHILDREN (node)[2] = SLP_TREE_CHILDREN (add)[2]; + /* Build IFN_VEC_FMADDSUB from the fms representative + operands. */ + call = gimple_build_call_internal (m_ifn, 3, + gimple_call_arg (srep->stmt, 0), + gimple_call_arg (srep->stmt, 1), + gimple_call_arg (srep->stmt, 2)); + } + else + { + slp_tree mul = SLP_TREE_CHILDREN (sub)[0]; + SLP_TREE_CHILDREN (node)[0] = SLP_TREE_CHILDREN (mul)[0]; + SLP_TREE_CHILDREN (node)[1] = SLP_TREE_CHILDREN (mul)[1]; + SLP_TREE_CHILDREN (node)[2] = SLP_TREE_CHILDREN (sub)[1]; + /* Build IFN_VEC_FMADDSUB from the mul/sub representative + operands. */ + stmt_vec_info mrep = SLP_TREE_REPRESENTATIVE (mul); + call = gimple_build_call_internal (m_ifn, 3, + gimple_assign_rhs1 (mrep->stmt), + gimple_assign_rhs2 (mrep->stmt), + gimple_assign_rhs2 (srep->stmt)); + } SLP_TREE_REF_COUNT (SLP_TREE_CHILDREN (node)[0])++; SLP_TREE_REF_COUNT (SLP_TREE_CHILDREN (node)[1])++; SLP_TREE_REF_COUNT (SLP_TREE_CHILDREN (node)[2])++; - /* Build IFN_VEC_FMADDSUB from the mul/sub representative operands. */ - stmt_vec_info srep = SLP_TREE_REPRESENTATIVE (sub); - stmt_vec_info mrep = SLP_TREE_REPRESENTATIVE (mul); - gcall *call = gimple_build_call_internal (m_ifn, 3, - gimple_assign_rhs1 (mrep->stmt), - gimple_assign_rhs2 (mrep->stmt), - gimple_assign_rhs2 (srep->stmt)); gimple_call_set_lhs (call, make_ssa_name - (TREE_TYPE (gimple_assign_lhs (srep->stmt)))); + (TREE_TYPE (gimple_get_lhs (srep->stmt)))); gimple_call_set_nothrow (call, true); gimple_set_bb (call, gimple_bb (srep->stmt)); stmt_vec_info new_rep = vinfo->add_pattern_stmt (call, srep); diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index dc89da3bf177..7776b2f1d8e6 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -507,11 +507,6 @@ vect_def_types_match (enum vect_def_type dta, enum vect_def_type dtb) && (dtb == vect_external_def || dtb == vect_constant_def))); } -static const int cond_expr_maps[3][5] = { - { 4, -1, -2, 1, 2 }, - { 4, -2, -1, 1, 2 }, - { 4, -1, -2, 2, 1 } -}; static const int no_arg_map[] = { 0 }; static const int arg0_map[] = { 1, 0 }; static const int arg1_map[] = { 1, 1 }; @@ -986,13 +981,18 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned char swap, to be combined into the same SLP group. */ bool -compatible_calls_p (gcall *call1, gcall *call2) +compatible_calls_p (gcall *call1, gcall *call2, bool allow_two_operators) { unsigned int nargs = gimple_call_num_args (call1); if (nargs != gimple_call_num_args (call2)) return false; - if (gimple_call_combined_fn (call1) != gimple_call_combined_fn (call2)) + auto cfn1 = gimple_call_combined_fn (call1); + auto cfn2 = gimple_call_combined_fn (call2); + if (cfn1 != cfn2 + && (!allow_two_operators + || !((cfn1 == CFN_FMA || cfn1 == CFN_FMS) + && (cfn2 == CFN_FMA || cfn2 == CFN_FMS)))) return false; if (gimple_call_internal_p (call1)) @@ -1114,6 +1114,16 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap, matches[0] = false; return false; } + if (is_a (vinfo) + && known_le (TYPE_VECTOR_SUBPARTS (vectype), 1U)) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Build SLP failed: not using single lane " + "vector type %T\n", vectype); + matches[0] = false; + return false; + } /* Record nunits required but continue analysis, producing matches[] as if nunits was not an issue. This allows splitting of groups to happen. */ @@ -1354,10 +1364,14 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap, || rhs_code != IMAGPART_EXPR) /* Handle mismatches in plus/minus by computing both and merging the results. */ - && !((first_stmt_code == PLUS_EXPR - || first_stmt_code == MINUS_EXPR) - && (alt_stmt_code == PLUS_EXPR - || alt_stmt_code == MINUS_EXPR) + && !((((first_stmt_code == PLUS_EXPR + || first_stmt_code == MINUS_EXPR) + && (alt_stmt_code == PLUS_EXPR + || alt_stmt_code == MINUS_EXPR)) + || ((first_stmt_code == CFN_FMA + || first_stmt_code == CFN_FMS) + && (alt_stmt_code == CFN_FMA + || alt_stmt_code == CFN_FMS))) && rhs_code == alt_stmt_code) && !(first_stmt_code.is_tree_code () && rhs_code.is_tree_code () @@ -1406,7 +1420,7 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap, { if (!is_a (stmts[0]->stmt) || !compatible_calls_p (as_a (stmts[0]->stmt), - call_stmt)) + call_stmt, true)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -2845,9 +2859,10 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node, && matches[0] /* ??? For COND_EXPRs we can swap the comparison operands as well as the arms under some constraints. */ - && nops == 2 + && (nops == 2 || nops == 3) && oprnds_info[1]->first_dt == vect_internal_def - && is_gimple_assign (stmt_info->stmt) + && (is_gimple_assign (stmt_info->stmt) + || is_gimple_call (stmt_info->stmt)) /* Swapping operands for reductions breaks assumptions later on. */ && STMT_VINFO_REDUC_IDX (stmt_info) == -1) { @@ -2862,14 +2877,32 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node, continue; stmt_vec_info stmt_info = stmts[j]; /* Verify if we can swap operands of this stmt. */ - gassign *stmt = dyn_cast (stmt_info->stmt); - if (!stmt - || !commutative_tree_code (gimple_assign_rhs_code (stmt))) + if (gassign *stmt = dyn_cast (stmt_info->stmt)) { - if (!swap_not_matching) - goto fail; - swap_not_matching = false; - break; + tree_code code = gimple_assign_rhs_code (stmt); + if (! commutative_tree_code (code) + && ! commutative_ternary_tree_code (code)) + { + if (!swap_not_matching) + goto fail; + swap_not_matching = false; + break; + } + } + else if (gcall *call = dyn_cast (stmt_info->stmt)) + { + internal_fn fn = (gimple_call_internal_p (call) + ? gimple_call_internal_fn (call) + : IFN_LAST); + if ((! commutative_binary_fn_p (fn) + && ! commutative_ternary_fn_p (fn)) + || first_commutative_argument (fn) != 0) + { + if (!swap_not_matching) + goto fail; + swap_not_matching = false; + break; + } } } } @@ -3055,24 +3088,35 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node, SLP_TREE_CODE (node) = VEC_PERM_EXPR; SLP_TREE_CHILDREN (node).quick_push (one); SLP_TREE_CHILDREN (node).quick_push (two); - gassign *stmt = as_a (stmts[0]->stmt); - enum tree_code code0 = gimple_assign_rhs_code (stmt); + enum tree_code code0 = ERROR_MARK; enum tree_code ocode = ERROR_MARK; + if (gassign *stmt = dyn_cast (stmts[0]->stmt)) + code0 = gimple_assign_rhs_code (stmt); stmt_vec_info ostmt_info; unsigned j = 0; FOR_EACH_VEC_ELT (stmts, i, ostmt_info) { - gassign *ostmt = as_a (ostmt_info->stmt); - if (gimple_assign_rhs_code (ostmt) != code0) + int op = 0; + if (gassign *ostmt = dyn_cast (ostmt_info->stmt)) { - SLP_TREE_LANE_PERMUTATION (node).safe_push (std::make_pair (1, i)); - ocode = gimple_assign_rhs_code (ostmt); - j = i; + if (gimple_assign_rhs_code (ostmt) != code0) + { + ocode = gimple_assign_rhs_code (ostmt); + op = 1; + j = i; + } } else - SLP_TREE_LANE_PERMUTATION (node).safe_push (std::make_pair (0, i)); + { + if (gimple_call_combined_fn (stmts[0]->stmt) + != gimple_call_combined_fn (ostmt_info->stmt)) + { + op = 1; + j = i; + } + } + SLP_TREE_LANE_PERMUTATION (node).safe_push (std::make_pair (op, i)); } - SLP_TREE_CODE (one) = code0; SLP_TREE_CODE (two) = ocode; SLP_TREE_LANES (one) = stmts.length (); @@ -4033,7 +4077,12 @@ vect_build_slp_instance (vec_info *vinfo, for (unsigned i = 0; i < group_size; ++i) scalar_stmts.quick_push (next_info); slp_tree conv = vect_create_new_slp_node (scalar_stmts, 1); - SLP_TREE_VECTYPE (conv) = STMT_VINFO_VECTYPE (next_info); + SLP_TREE_VECTYPE (conv) + = get_vectype_for_scalar_type (vinfo, + TREE_TYPE + (gimple_assign_lhs + (scalar_def)), + group_size); SLP_TREE_CHILDREN (conv).quick_push (node); SLP_INSTANCE_TREE (new_instance) = conv; /* We also have to fake this conversion stmt as SLP reduction @@ -5029,9 +5078,15 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size, tree args0 = gimple_cond_lhs (stmt); tree args1 = gimple_cond_rhs (stmt); - /* These should be enforced by cond lowering. */ - gcc_assert (gimple_cond_code (stmt) == NE_EXPR); - gcc_assert (zerop (args1)); + /* These should be enforced by cond lowering, but if it failed + bail. */ + if (gimple_cond_code (stmt) != NE_EXPR + || TREE_TYPE (args0) != boolean_type_node + || !integer_zerop (args1)) + { + roots.release (); + continue; + } /* An argument without a loop def will be codegened from vectorizing the root gcond itself. As such we don't need to try to build an SLP tree @@ -7531,20 +7586,25 @@ vect_make_slp_decision (loop_vec_info loop_vinfo) hash_set visited; FOR_EACH_VEC_ELT (slp_instances, i, instance) { - /* FORNOW: SLP if you can. */ + slp_tree root = SLP_INSTANCE_TREE (instance); + /* All unroll factors have the form: GET_MODE_SIZE (vinfo->vector_mode) * X for some rational X, so they must have a common multiple. */ - vect_update_slp_vf_for_node (SLP_INSTANCE_TREE (instance), - unrolling_factor, visited); + vect_update_slp_vf_for_node (root, unrolling_factor, visited); /* Mark all the stmts that belong to INSTANCE as PURE_SLP stmts. Later we call vect_detect_hybrid_slp () to find stmts that need hybrid SLP and loop-based vectorization. Such stmts will be marked as HYBRID. */ - vect_mark_slp_stmts (loop_vinfo, SLP_INSTANCE_TREE (instance)); - decided_to_slp++; + vect_mark_slp_stmts (loop_vinfo, root); + + /* If all instances ended up with vector(1) T roots make sure to + not vectorize. RVV for example relies on loop vectorization + when some instances are essentially kept scalar. See PR121048. */ + if (known_gt (TYPE_VECTOR_SUBPARTS (SLP_TREE_VECTYPE (root)), 1U)) + decided_to_slp++; } LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo) = unrolling_factor; @@ -7657,7 +7717,7 @@ maybe_push_to_hybrid_worklist (vec_info *vinfo, /* Find stmts that must be both vectorized and SLPed. */ -void +bool vect_detect_hybrid_slp (loop_vec_info loop_vinfo) { DUMP_VECT_SCOPE ("vect_detect_hybrid_slp"); @@ -7738,6 +7798,52 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo) vect_detect_hybrid_slp (&gs_info.offset, &dummy, &wi); } } + + /* Determine if all the stmts in the loop can be SLPed. */ + for (unsigned i = 0; i < LOOP_VINFO_LOOP (loop_vinfo)->num_nodes; i++) + { + basic_block bb = LOOP_VINFO_BBS (loop_vinfo)[i]; + for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si); + gsi_next (&si)) + { + stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (si.phi ()); + if (!stmt_info) + continue; + if ((STMT_VINFO_RELEVANT_P (stmt_info) + || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))) + && !PURE_SLP_STMT (stmt_info)) + { + /* STMT needs both SLP and loop-based vectorization. */ + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "Loop contains SLP and non-SLP stmts\n"); + return false; + } + } + for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); + gsi_next (&si)) + { + if (is_gimple_debug (gsi_stmt (si))) + continue; + stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (gsi_stmt (si)); + stmt_info = vect_stmt_to_vectorize (stmt_info); + if ((STMT_VINFO_RELEVANT_P (stmt_info) + || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))) + && !PURE_SLP_STMT (stmt_info)) + { + /* STMT needs both SLP and loop-based vectorization. */ + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "Loop contains SLP and non-SLP stmts\n"); + return false; + } + } + } + + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "Loop contains only SLP stmts\n"); + return true; } @@ -7818,8 +7924,6 @@ vect_slp_analyze_node_operations_1 (vec_info *vinfo, slp_tree node, slp_instance node_instance, stmt_vector_for_cost *cost_vec) { - stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node); - /* Calculate the number of vector statements to be created for the scalar stmts in this node. It is the number of scalar elements in one scalar iteration (DR_GROUP_SIZE) multiplied by VF divided by the number of @@ -7848,9 +7952,7 @@ vect_slp_analyze_node_operations_1 (vec_info *vinfo, slp_tree node, return true; } - bool dummy; - return vect_analyze_stmt (vinfo, stmt_info, &dummy, - node, node_instance, cost_vec); + return vect_analyze_stmt (vinfo, node, node_instance, cost_vec); } static int @@ -9468,14 +9570,13 @@ vect_slp_analyze_bb_1 (bb_vec_info bb_vinfo, int n_stmts, bool &fatal, slp_instance instance; int i; - poly_uint64 min_vf = 2; /* The first group of checks is independent of the vector size. */ fatal = true; /* Analyze the data references. */ - if (!vect_analyze_data_refs (bb_vinfo, &min_vf, NULL)) + if (!vect_analyze_data_refs (bb_vinfo, NULL)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -11269,7 +11370,11 @@ vect_schedule_slp_node (vec_info *vinfo, && !SSA_NAME_IS_DEFAULT_DEF (def)) { gimple *stmt = SSA_NAME_DEF_STMT (def); - if (!last_stmt) + if (gimple_uid (stmt) == -1u) + /* If the stmt is not inside the region do not + use it as possible insertion point. */ + ; + else if (!last_stmt) last_stmt = stmt; else if (vect_stmt_dominates_stmt_p (last_stmt, stmt)) last_stmt = stmt; diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 3710694ac75d..2e9b3d2e6863 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -2097,310 +2097,246 @@ get_group_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info, known at compile time. */ gcc_assert (!STMT_VINFO_STRIDED_P (first_stmt_info) || gap == 0); - /* Stores can't yet have gaps. */ - gcc_assert (slp_node || vls_type == VLS_LOAD || gap == 0); - - if (slp_node) + /* For SLP vectorization we directly vectorize a subchain + without permutation. */ + if (! SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()) + first_dr_info = STMT_VINFO_DR_INFO (SLP_TREE_SCALAR_STMTS (slp_node)[0]); + if (STMT_VINFO_STRIDED_P (first_stmt_info)) + /* Try to use consecutive accesses of as many elements as possible, + separated by the stride, until we have a complete vector. + Fall back to scalar accesses if that isn't possible. */ + *memory_access_type = VMAT_STRIDED_SLP; + else { - /* For SLP vectorization we directly vectorize a subchain - without permutation. */ - if (! SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()) - first_dr_info - = STMT_VINFO_DR_INFO (SLP_TREE_SCALAR_STMTS (slp_node)[0]); - if (STMT_VINFO_STRIDED_P (first_stmt_info)) - /* Try to use consecutive accesses of as many elements as possible, - separated by the stride, until we have a complete vector. - Fall back to scalar accesses if that isn't possible. */ - *memory_access_type = VMAT_STRIDED_SLP; - else + int cmp = compare_step_with_zero (vinfo, stmt_info); + if (cmp < 0) { - int cmp = compare_step_with_zero (vinfo, stmt_info); - if (cmp < 0) + if (single_element_p) + /* ??? The VMAT_CONTIGUOUS_REVERSE code generation is + only correct for single element "interleaving" SLP. */ + *memory_access_type = get_negative_load_store_type + (vinfo, stmt_info, vectype, vls_type, 1, + &neg_ldst_offset); + else { - if (single_element_p) - /* ??? The VMAT_CONTIGUOUS_REVERSE code generation is - only correct for single element "interleaving" SLP. */ - *memory_access_type = get_negative_load_store_type - (vinfo, stmt_info, vectype, vls_type, 1, - &neg_ldst_offset); + /* Try to use consecutive accesses of DR_GROUP_SIZE elements, + separated by the stride, until we have a complete vector. + Fall back to scalar accesses if that isn't possible. */ + if (multiple_p (nunits, group_size)) + *memory_access_type = VMAT_STRIDED_SLP; else - { - /* Try to use consecutive accesses of DR_GROUP_SIZE elements, - separated by the stride, until we have a complete vector. - Fall back to scalar accesses if that isn't possible. */ - if (multiple_p (nunits, group_size)) - *memory_access_type = VMAT_STRIDED_SLP; - else - *memory_access_type = VMAT_ELEMENTWISE; - } + *memory_access_type = VMAT_ELEMENTWISE; } - else if (cmp == 0 && loop_vinfo) - { - gcc_assert (vls_type == VLS_LOAD); - *memory_access_type = VMAT_INVARIANT; - } - /* Try using LOAD/STORE_LANES. */ - else if (slp_node->ldst_lanes - && (*lanes_ifn - = (vls_type == VLS_LOAD - ? vect_load_lanes_supported (vectype, group_size, - masked_p, elsvals) - : vect_store_lanes_supported (vectype, group_size, - masked_p))) != IFN_LAST) - *memory_access_type = VMAT_LOAD_STORE_LANES; - else if (!loop_vinfo && slp_node->avoid_stlf_fail) + } + else if (cmp == 0 && loop_vinfo) + { + gcc_assert (vls_type == VLS_LOAD); + *memory_access_type = VMAT_INVARIANT; + } + /* Try using LOAD/STORE_LANES. */ + else if (slp_node->ldst_lanes + && (*lanes_ifn + = (vls_type == VLS_LOAD + ? vect_load_lanes_supported (vectype, group_size, + masked_p, elsvals) + : vect_store_lanes_supported (vectype, group_size, + masked_p))) != IFN_LAST) + *memory_access_type = VMAT_LOAD_STORE_LANES; + else if (!loop_vinfo && slp_node->avoid_stlf_fail) + { + *memory_access_type = VMAT_ELEMENTWISE; + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "using element-wise load to avoid disrupting " + "cross iteration store-to-load forwarding\n"); + } + else + *memory_access_type = VMAT_CONTIGUOUS; + + /* If this is single-element interleaving with an element + distance that leaves unused vector loads around fall back + to elementwise access if possible - we otherwise least + create very sub-optimal code in that case (and + blow up memory, see PR65518). */ + if (loop_vinfo + && single_element_p + && (*memory_access_type == VMAT_CONTIGUOUS + || *memory_access_type == VMAT_CONTIGUOUS_REVERSE) + && maybe_gt (group_size, TYPE_VECTOR_SUBPARTS (vectype))) + { + if (SLP_TREE_LANES (slp_node) == 1) { *memory_access_type = VMAT_ELEMENTWISE; if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "using element-wise load to avoid disrupting " - "cross iteration store-to-load forwarding\n"); + "single-element interleaving not supported " + "for not adjacent vector loads, using " + "elementwise access\n"); } else - *memory_access_type = VMAT_CONTIGUOUS; - - /* If this is single-element interleaving with an element - distance that leaves unused vector loads around fall back - to elementwise access if possible - we otherwise least - create very sub-optimal code in that case (and - blow up memory, see PR65518). */ - if (loop_vinfo - && single_element_p - && (*memory_access_type == VMAT_CONTIGUOUS - || *memory_access_type == VMAT_CONTIGUOUS_REVERSE) - && maybe_gt (group_size, TYPE_VECTOR_SUBPARTS (vectype))) - { - if (SLP_TREE_LANES (slp_node) == 1) - { - *memory_access_type = VMAT_ELEMENTWISE; - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "single-element interleaving not supported " - "for not adjacent vector loads, using " - "elementwise access\n"); - } - else - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "single-element interleaving not supported " - "for not adjacent vector loads\n"); - return false; - } - } - - /* For single-element interleaving also fall back to elementwise - access in case we did not lower a permutation and cannot - code generate it. */ - auto_vec temv; - unsigned n_perms; - if (loop_vinfo - && single_element_p - && SLP_TREE_LANES (slp_node) == 1 - && (*memory_access_type == VMAT_CONTIGUOUS - || *memory_access_type == VMAT_CONTIGUOUS_REVERSE) - && SLP_TREE_LOAD_PERMUTATION (slp_node).exists () - && !vect_transform_slp_perm_load - (loop_vinfo, slp_node, temv, NULL, - LOOP_VINFO_VECT_FACTOR (loop_vinfo), true, &n_perms)) { - *memory_access_type = VMAT_ELEMENTWISE; if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "single-element interleaving permutation not " - "supported, using elementwise access\n"); - } - - overrun_p = (loop_vinfo && gap != 0 - && *memory_access_type != VMAT_ELEMENTWISE); - if (overrun_p && vls_type != VLS_LOAD) - { - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Grouped store with gaps requires" - " non-consecutive accesses\n"); + "single-element interleaving not supported " + "for not adjacent vector loads\n"); return false; } + } - unsigned HOST_WIDE_INT dr_size - = vect_get_scalar_dr_size (first_dr_info); - poly_int64 off = 0; - if (*memory_access_type == VMAT_CONTIGUOUS_REVERSE) - off = (TYPE_VECTOR_SUBPARTS (vectype) - 1) * -dr_size; - - /* An overrun is fine if the trailing elements are smaller - than the alignment boundary B. Every vector access will - be a multiple of B and so we are guaranteed to access a - non-gap element in the same B-sized block. */ - if (overrun_p - && gap < (vect_known_alignment_in_bytes (first_dr_info, - vectype, off) / dr_size)) - overrun_p = false; - - /* When we have a contiguous access across loop iterations - but the access in the loop doesn't cover the full vector - we can end up with no gap recorded but still excess - elements accessed, see PR103116. Make sure we peel for - gaps if necessary and sufficient and give up if not. - - If there is a combination of the access not covering the full - vector and a gap recorded then we may need to peel twice. */ - bool large_vector_overrun_p = false; - if (loop_vinfo - && (*memory_access_type == VMAT_CONTIGUOUS - || *memory_access_type == VMAT_CONTIGUOUS_REVERSE) - && SLP_TREE_LOAD_PERMUTATION (slp_node).exists () - && !multiple_p (group_size * LOOP_VINFO_VECT_FACTOR (loop_vinfo), - nunits)) - large_vector_overrun_p = overrun_p = true; - - /* If the gap splits the vector in half and the target - can do half-vector operations avoid the epilogue peeling - by simply loading half of the vector only. Usually - the construction with an upper zero half will be elided. */ - dr_alignment_support alss; - int misalign = dr_misalignment (first_dr_info, vectype, off); - tree half_vtype; - poly_uint64 remain; - unsigned HOST_WIDE_INT tem, num; - if (overrun_p - && !masked_p - && *memory_access_type != VMAT_LOAD_STORE_LANES - && (((alss = vect_supportable_dr_alignment (vinfo, first_dr_info, - vectype, misalign))) - == dr_aligned - || alss == dr_unaligned_supported) - && can_div_trunc_p (group_size - * LOOP_VINFO_VECT_FACTOR (loop_vinfo) - gap, - nunits, &tem, &remain) - && (known_eq (remain, 0u) - || (known_ne (remain, 0u) - && constant_multiple_p (nunits, remain, &num) - && (vector_vector_composition_type (vectype, num, - &half_vtype) - != NULL_TREE)))) - overrun_p = false; - - if (overrun_p && !can_overrun_p) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Peeling for outer loop is not supported\n"); - return false; - } + /* For single-element interleaving also fall back to elementwise + access in case we did not lower a permutation and cannot + code generate it. */ + auto_vec temv; + unsigned n_perms; + if (loop_vinfo + && single_element_p + && SLP_TREE_LANES (slp_node) == 1 + && (*memory_access_type == VMAT_CONTIGUOUS + || *memory_access_type == VMAT_CONTIGUOUS_REVERSE) + && SLP_TREE_LOAD_PERMUTATION (slp_node).exists () + && !vect_transform_slp_perm_load + (loop_vinfo, slp_node, temv, NULL, + LOOP_VINFO_VECT_FACTOR (loop_vinfo), true, &n_perms)) + { + *memory_access_type = VMAT_ELEMENTWISE; + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "single-element interleaving permutation not " + "supported, using elementwise access\n"); + } - /* Peeling for gaps assumes that a single scalar iteration - is enough to make sure the last vector iteration doesn't - access excess elements. */ - if (overrun_p - && (!can_div_trunc_p (group_size - * LOOP_VINFO_VECT_FACTOR (loop_vinfo) - gap, - nunits, &tem, &remain) - || maybe_lt (remain + group_size, nunits))) - { - /* But peeling a single scalar iteration is enough if - we can use the next power-of-two sized partial - access and that is sufficiently small to be covered - by the single scalar iteration. */ - unsigned HOST_WIDE_INT cnunits, cvf, cremain, cpart_size; - if (masked_p - || !nunits.is_constant (&cnunits) - || !LOOP_VINFO_VECT_FACTOR (loop_vinfo).is_constant (&cvf) - || (((cremain = (group_size * cvf - gap) % cnunits), true) - && ((cpart_size = (1 << ceil_log2 (cremain))), true) - && (cremain + group_size < cpart_size - || vector_vector_composition_type - (vectype, cnunits / cpart_size, - &half_vtype) == NULL_TREE))) - { - /* If all fails we can still resort to niter masking unless - the vectors used are too big, so enforce the use of - partial vectors. */ - if (LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) - && !large_vector_overrun_p) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "peeling for gaps insufficient for " - "access unless using partial " - "vectors\n"); - LOOP_VINFO_MUST_USE_PARTIAL_VECTORS_P (loop_vinfo) = true; - } - else - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "peeling for gaps insufficient for " - "access\n"); - return false; - } - } - else if (large_vector_overrun_p) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "can't operate on partial vectors because " - "only unmasked loads handle access " - "shortening required because of gaps at " - "the end of the access\n"); - LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; - } - } + overrun_p = (loop_vinfo && gap != 0 + && *memory_access_type != VMAT_ELEMENTWISE); + if (overrun_p && vls_type != VLS_LOAD) + { + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Grouped store with gaps requires" + " non-consecutive accesses\n"); + return false; } - } - else - { - /* We can always handle this case using elementwise accesses, - but see if something more efficient is available. */ - *memory_access_type = VMAT_ELEMENTWISE; - - /* If there is a gap at the end of the group then these optimizations - would access excess elements in the last iteration. */ - bool would_overrun_p = (gap != 0); - /* An overrun is fine if the trailing elements are smaller than the - alignment boundary B. Every vector access will be a multiple of B - and so we are guaranteed to access a non-gap element in the - same B-sized block. */ - if (would_overrun_p - && !masked_p - && gap < (vect_known_alignment_in_bytes (first_dr_info, vectype) - / vect_get_scalar_dr_size (first_dr_info))) - would_overrun_p = false; - if (!STMT_VINFO_STRIDED_P (first_stmt_info) - && (can_overrun_p || !would_overrun_p) - && compare_step_with_zero (vinfo, stmt_info) > 0) + unsigned HOST_WIDE_INT dr_size = vect_get_scalar_dr_size (first_dr_info); + poly_int64 off = 0; + if (*memory_access_type == VMAT_CONTIGUOUS_REVERSE) + off = (TYPE_VECTOR_SUBPARTS (vectype) - 1) * -dr_size; + + /* An overrun is fine if the trailing elements are smaller + than the alignment boundary B. Every vector access will + be a multiple of B and so we are guaranteed to access a + non-gap element in the same B-sized block. */ + if (overrun_p + && gap < (vect_known_alignment_in_bytes (first_dr_info, + vectype, off) / dr_size)) + overrun_p = false; + + /* When we have a contiguous access across loop iterations + but the access in the loop doesn't cover the full vector + we can end up with no gap recorded but still excess + elements accessed, see PR103116. Make sure we peel for + gaps if necessary and sufficient and give up if not. + + If there is a combination of the access not covering the full + vector and a gap recorded then we may need to peel twice. */ + bool large_vector_overrun_p = false; + if (loop_vinfo + && (*memory_access_type == VMAT_CONTIGUOUS + || *memory_access_type == VMAT_CONTIGUOUS_REVERSE) + && SLP_TREE_LOAD_PERMUTATION (slp_node).exists () + && !multiple_p (group_size * LOOP_VINFO_VECT_FACTOR (loop_vinfo), + nunits)) + large_vector_overrun_p = overrun_p = true; + + /* If the gap splits the vector in half and the target + can do half-vector operations avoid the epilogue peeling + by simply loading half of the vector only. Usually + the construction with an upper zero half will be elided. */ + dr_alignment_support alss; + int misalign = dr_misalignment (first_dr_info, vectype, off); + tree half_vtype; + poly_uint64 remain; + unsigned HOST_WIDE_INT tem, num; + if (overrun_p + && !masked_p + && *memory_access_type != VMAT_LOAD_STORE_LANES + && (((alss = vect_supportable_dr_alignment (vinfo, first_dr_info, + vectype, misalign))) + == dr_aligned + || alss == dr_unaligned_supported) + && can_div_trunc_p (group_size + * LOOP_VINFO_VECT_FACTOR (loop_vinfo) - gap, + nunits, &tem, &remain) + && (known_eq (remain, 0u) + || (known_ne (remain, 0u) + && constant_multiple_p (nunits, remain, &num) + && (vector_vector_composition_type (vectype, num, &half_vtype) + != NULL_TREE)))) + overrun_p = false; + + if (overrun_p && !can_overrun_p) { - /* First cope with the degenerate case of a single-element - vector. */ - if (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 1U)) - ; + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Peeling for outer loop is not supported\n"); + return false; + } - else - { - /* Otherwise try using LOAD/STORE_LANES. */ - *lanes_ifn - = vls_type == VLS_LOAD - ? vect_load_lanes_supported (vectype, group_size, masked_p, - elsvals) - : vect_store_lanes_supported (vectype, group_size, - masked_p); - if (*lanes_ifn != IFN_LAST) + /* Peeling for gaps assumes that a single scalar iteration + is enough to make sure the last vector iteration doesn't + access excess elements. */ + if (overrun_p + && (!can_div_trunc_p (group_size + * LOOP_VINFO_VECT_FACTOR (loop_vinfo) - gap, + nunits, &tem, &remain) + || maybe_lt (remain + group_size, nunits))) + { + /* But peeling a single scalar iteration is enough if + we can use the next power-of-two sized partial + access and that is sufficiently small to be covered + by the single scalar iteration. */ + unsigned HOST_WIDE_INT cnunits, cvf, cremain, cpart_size; + if (masked_p + || !nunits.is_constant (&cnunits) + || !LOOP_VINFO_VECT_FACTOR (loop_vinfo).is_constant (&cvf) + || (((cremain = (group_size * cvf - gap) % cnunits), true) + && ((cpart_size = (1 << ceil_log2 (cremain))), true) + && (cremain + group_size < cpart_size + || (vector_vector_composition_type (vectype, + cnunits / cpart_size, + &half_vtype) + == NULL_TREE)))) + { + /* If all fails we can still resort to niter masking unless + the vectors used are too big, so enforce the use of + partial vectors. */ + if (LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) + && !large_vector_overrun_p) { - *memory_access_type = VMAT_LOAD_STORE_LANES; - overrun_p = would_overrun_p; + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "peeling for gaps insufficient for " + "access unless using partial " + "vectors\n"); + LOOP_VINFO_MUST_USE_PARTIAL_VECTORS_P (loop_vinfo) = true; } - - /* If that fails, try using permuting loads. */ - else if (vls_type == VLS_LOAD - ? vect_grouped_load_supported (vectype, - single_element_p, - group_size) - : vect_grouped_store_supported (vectype, group_size)) + else { - *memory_access_type = VMAT_CONTIGUOUS_PERMUTE; - overrun_p = would_overrun_p; + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "peeling for gaps insufficient for " + "access\n"); + return false; } } + else if (large_vector_overrun_p) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "can't operate on partial vectors because " + "only unmasked loads handle access " + "shortening required because of gaps at " + "the end of the access\n"); + LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; + } } } @@ -2414,7 +2350,7 @@ get_group_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info, if ((*memory_access_type == VMAT_ELEMENTWISE || *memory_access_type == VMAT_STRIDED_SLP) && single_element_p - && (!slp_node || SLP_TREE_LANES (slp_node) == 1) + && SLP_TREE_LANES (slp_node) == 1 && loop_vinfo && vect_use_strided_gather_scatters_p (stmt_info, loop_vinfo, masked_p, gs_info, elsvals)) @@ -2494,7 +2430,7 @@ static bool get_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info, tree vectype, slp_tree slp_node, bool masked_p, vec_load_store_type vls_type, - unsigned int ncopies, + unsigned int, vect_memory_access_type *memory_access_type, poly_int64 *poffset, dr_alignment_support *alignment_support_scheme, @@ -2530,17 +2466,10 @@ get_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info, vls_type == VLS_LOAD ? "gather" : "scatter"); return false; } - else if (!vect_is_simple_use (gs_info->offset, vinfo, - &gs_info->offset_dt, - &gs_info->offset_vectype)) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "%s index use not simple.\n", - vls_type == VLS_LOAD ? "gather" : "scatter"); - return false; - } - else if (gs_info->ifn == IFN_LAST && !gs_info->decl) + slp_tree offset_node = SLP_TREE_CHILDREN (slp_node)[0]; + gs_info->offset_dt = SLP_TREE_DEF_TYPE (offset_node); + gs_info->offset_vectype = SLP_TREE_VECTYPE (offset_node); + if (gs_info->ifn == IFN_LAST && !gs_info->decl) { if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant () || !TYPE_VECTOR_SUBPARTS (gs_info->offset_vectype).is_constant () @@ -2560,54 +2489,13 @@ get_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info, is irrelevant for them. */ *alignment_support_scheme = dr_unaligned_supported; } - else if (STMT_VINFO_GROUPED_ACCESS (stmt_info) || slp_node) - { - if (!get_group_load_store_type (vinfo, stmt_info, vectype, slp_node, - masked_p, - vls_type, memory_access_type, poffset, - alignment_support_scheme, - misalignment, gs_info, lanes_ifn, - elsvals)) - return false; - } - else if (STMT_VINFO_STRIDED_P (stmt_info)) - { - gcc_assert (!slp_node); - if (loop_vinfo - && vect_use_strided_gather_scatters_p (stmt_info, loop_vinfo, - masked_p, gs_info, elsvals)) - *memory_access_type = VMAT_GATHER_SCATTER; - else - *memory_access_type = VMAT_ELEMENTWISE; - /* Alignment is irrelevant here. */ - *alignment_support_scheme = dr_unaligned_supported; - } - else - { - int cmp = compare_step_with_zero (vinfo, stmt_info); - if (cmp == 0) - { - gcc_assert (vls_type == VLS_LOAD); - *memory_access_type = VMAT_INVARIANT; - /* Invariant accesses perform only component accesses, alignment - is irrelevant for them. */ - *alignment_support_scheme = dr_unaligned_supported; - } - else - { - if (cmp < 0) - *memory_access_type = get_negative_load_store_type - (vinfo, stmt_info, vectype, vls_type, ncopies, poffset); - else - *memory_access_type = VMAT_CONTIGUOUS; - *misalignment = dr_misalignment (STMT_VINFO_DR_INFO (stmt_info), - vectype, *poffset); - *alignment_support_scheme - = vect_supportable_dr_alignment (vinfo, - STMT_VINFO_DR_INFO (stmt_info), - vectype, *misalignment); - } - } + else if (!get_group_load_store_type (vinfo, stmt_info, vectype, slp_node, + masked_p, + vls_type, memory_access_type, poffset, + alignment_support_scheme, + misalignment, gs_info, lanes_ifn, + elsvals)) + return false; if ((*memory_access_type == VMAT_ELEMENTWISE || *memory_access_type == VMAT_STRIDED_SLP) @@ -2731,7 +2619,7 @@ get_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info, such only the first load in the group is aligned, the rest are not. Because of this the permutes may break the alignment requirements that have been set, and as such we should for now, reject them. */ - if (slp_node && SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()) + if (SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -5572,6 +5460,7 @@ vectorizable_conversion (vec_info *vinfo, vec vec_oprnds1 = vNULL; tree vop0; bb_vec_info bb_vinfo = dyn_cast (vinfo); + loop_vec_info loop_vinfo = dyn_cast (vinfo); int multi_step_cvt = 0; vec interm_types = vNULL; tree intermediate_type, cvt_type = NULL_TREE; @@ -5914,6 +5803,20 @@ vectorizable_conversion (vec_info *vinfo, gcc_unreachable (); } + if (modifier == WIDEN + && loop_vinfo + && LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) + && (code1 == VEC_WIDEN_MULT_EVEN_EXPR + || widening_evenodd_fn_p (code1))) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "can't use a fully-masked loop because" + " widening operation on even/odd elements" + " mixes up lanes.\n"); + LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; + } + if (!vec_stmt) /* transformation not required. */ { if (!vect_maybe_update_slp_op_vectype (slp_op0, vectype_in) @@ -6817,7 +6720,6 @@ vectorizable_operation (vec_info *vinfo, poly_uint64 nunits_in; poly_uint64 nunits_out; tree vectype_out; - int vec_num; int i; vec vec_oprnds0 = vNULL; vec vec_oprnds1 = vNULL; @@ -6989,7 +6891,7 @@ vectorizable_operation (vec_info *vinfo, /* Multiple types in SLP are handled by creating the appropriate number of vectorized stmts for each SLP node. */ - vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); + auto vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); /* Reject attempts to combine mask types with nonmask types, e.g. if we have an AND between a (nonmask) boolean loaded from memory and @@ -7341,7 +7243,7 @@ vectorizable_operation (vec_info *vinfo, && code == BIT_AND_EXPR && VECTOR_BOOLEAN_TYPE_P (vectype)) { - if (loop_vinfo->scalar_cond_masked_set.contains ({ op0, 1 })) + if (loop_vinfo->scalar_cond_masked_set.contains ({ op0, vec_num })) { mask = vect_get_loop_mask (loop_vinfo, gsi, masks, vec_num, vectype, i); @@ -7350,7 +7252,7 @@ vectorizable_operation (vec_info *vinfo, vop0, gsi); } - if (loop_vinfo->scalar_cond_masked_set.contains ({ op1, 1 })) + if (loop_vinfo->scalar_cond_masked_set.contains ({ op1, vec_num })) { mask = vect_get_loop_mask (loop_vinfo, gsi, masks, vec_num, vectype, i); @@ -8352,12 +8254,10 @@ vectorizable_store (vec_info *vinfo, tree dataref_ptr = NULL_TREE; tree dataref_offset = NULL_TREE; gimple *ptr_incr = NULL; - int ncopies; int j; stmt_vec_info first_stmt_info; bool grouped_store; unsigned int group_size, i; - bool slp = (slp_node != NULL); unsigned int vec_num; bb_vec_info bb_vinfo = dyn_cast (vinfo); tree aggr_type; @@ -8403,7 +8303,7 @@ vectorizable_store (vec_info *vinfo, return false; int mask_index = internal_fn_mask_index (ifn); - if (mask_index >= 0 && slp_node) + if (mask_index >= 0) mask_index = vect_slp_child_index_for_operand (call, mask_index, STMT_VINFO_GATHER_SCATTER_P (stmt_info)); if (mask_index >= 0 @@ -8415,9 +8315,9 @@ vectorizable_store (vec_info *vinfo, /* Cannot have hybrid store SLP -- that would mean storing to the same location twice. */ - gcc_assert (slp == PURE_SLP_STMT (stmt_info)); + gcc_assert (PURE_SLP_STMT (stmt_info)); - tree vectype = STMT_VINFO_VECTYPE (stmt_info), rhs_vectype = NULL_TREE; + tree vectype = SLP_TREE_VECTYPE (stmt_info), rhs_vectype = NULL_TREE; poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); if (loop_vinfo) @@ -8428,20 +8328,10 @@ vectorizable_store (vec_info *vinfo, else vf = 1; - /* Multiple types in SLP are handled by creating the appropriate number of - vectorized stmts for each SLP node. Hence, NCOPIES is always 1 in - case of SLP. */ - if (slp) - ncopies = 1; - else - ncopies = vect_get_num_copies (loop_vinfo, vectype); - - gcc_assert (ncopies >= 1); - /* FORNOW. This restriction should be relaxed. */ if (loop && nested_in_vect_loop_p (loop, stmt_info) - && (ncopies > 1 || (slp && SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node) > 1))) + && SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node) > 1) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -8467,13 +8357,12 @@ vectorizable_store (vec_info *vinfo, poly_int64 poffset; internal_fn lanes_ifn; if (!get_load_store_type (vinfo, stmt_info, vectype, slp_node, mask, vls_type, - ncopies, &memory_access_type, &poffset, + 1, &memory_access_type, &poffset, &alignment_support_scheme, &misalignment, &gs_info, &lanes_ifn)) return false; - if (slp_node - && slp_node->ldst_lanes + if (slp_node->ldst_lanes && memory_access_type != VMAT_LOAD_STORE_LANES) { if (dump_enabled_p ()) @@ -8520,8 +8409,7 @@ vectorizable_store (vec_info *vinfo, dr_vec_info *dr_info = STMT_VINFO_DR_INFO (stmt_info), *first_dr_info = NULL; grouped_store = (STMT_VINFO_GROUPED_ACCESS (stmt_info) - && memory_access_type != VMAT_GATHER_SCATTER - && (slp || memory_access_type != VMAT_CONTIGUOUS)); + && memory_access_type != VMAT_GATHER_SCATTER); if (grouped_store) { first_stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info); @@ -8546,8 +8434,7 @@ vectorizable_store (vec_info *vinfo, if (costing_p) /* transformation not required. */ { STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) = memory_access_type; - if (slp_node) - SLP_TREE_MEMORY_ACCESS_TYPE (slp_node) = memory_access_type; + SLP_TREE_MEMORY_ACCESS_TYPE (slp_node) = memory_access_type; if (loop_vinfo && LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo)) @@ -8556,11 +8443,10 @@ vectorizable_store (vec_info *vinfo, memory_access_type, &gs_info, mask); - if (slp_node - && (!vect_maybe_update_slp_op_vectype (op_node, vectype) - || (mask - && !vect_maybe_update_slp_op_vectype (mask_node, - mask_vectype)))) + if (!vect_maybe_update_slp_op_vectype (op_node, vectype) + || (mask + && !vect_maybe_update_slp_op_vectype (mask_node, + mask_vectype))) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -8578,22 +8464,8 @@ vectorizable_store (vec_info *vinfo, "Vectorizing an unaligned access.\n"); STMT_VINFO_TYPE (stmt_info) = store_vec_info_type; - - /* As function vect_transform_stmt shows, for interleaving stores - the whole chain is vectorized when the last store in the chain - is reached, the other stores in the group are skipped. So we - want to only cost the last one here, but it's not trivial to - get the last, as it's equivalent to use the first one for - costing, use the first one instead. */ - if (grouped_store - && !slp - && first_stmt_info != stmt_info) - return true; } - if (slp_node) - gcc_assert (memory_access_type == SLP_TREE_MEMORY_ACCESS_TYPE (stmt_info)); - else - gcc_assert (memory_access_type == STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info)); + gcc_assert (memory_access_type == SLP_TREE_MEMORY_ACCESS_TYPE (stmt_info)); /* Transform. */ @@ -8602,14 +8474,14 @@ vectorizable_store (vec_info *vinfo, if (STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info) >= 3) { gcc_assert (memory_access_type == VMAT_CONTIGUOUS); - gcc_assert (!slp || SLP_TREE_LANES (slp_node) == 1); + gcc_assert (SLP_TREE_LANES (slp_node) == 1); if (costing_p) { unsigned int inside_cost = 0, prologue_cost = 0; if (vls_type == VLS_STORE_INVARIANT) prologue_cost += record_stmt_cost (cost_vec, 1, scalar_to_vec, stmt_info, 0, vect_prologue); - vect_get_store_cost (vinfo, stmt_info, slp_node, ncopies, + vect_get_store_cost (vinfo, stmt_info, slp_node, 1, alignment_support_scheme, misalignment, &inside_cost, cost_vec); @@ -8622,67 +8494,28 @@ vectorizable_store (vec_info *vinfo, return true; } return vectorizable_scan_store (vinfo, stmt_info, slp_node, - gsi, vec_stmt, ncopies); + gsi, vec_stmt, 1); } - if (grouped_store || slp) - { - /* FORNOW */ - gcc_assert (!grouped_store - || !loop - || !nested_in_vect_loop_p (loop, stmt_info)); + /* FORNOW */ + gcc_assert (!grouped_store + || !loop + || !nested_in_vect_loop_p (loop, stmt_info)); - if (slp) - { - grouped_store = false; - /* VEC_NUM is the number of vect stmts to be created for this - group. */ - vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); - first_stmt_info = SLP_TREE_SCALAR_STMTS (slp_node)[0]; - gcc_assert (!STMT_VINFO_GROUPED_ACCESS (first_stmt_info) - || (DR_GROUP_FIRST_ELEMENT (first_stmt_info) - == first_stmt_info)); - first_dr_info = STMT_VINFO_DR_INFO (first_stmt_info); - op = vect_get_store_rhs (first_stmt_info); - } - else - /* VEC_NUM is the number of vect stmts to be created for this - group. */ - vec_num = group_size; + grouped_store = false; + /* VEC_NUM is the number of vect stmts to be created for this + group. */ + vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); + first_stmt_info = SLP_TREE_SCALAR_STMTS (slp_node)[0]; + gcc_assert (!STMT_VINFO_GROUPED_ACCESS (first_stmt_info) + || (DR_GROUP_FIRST_ELEMENT (first_stmt_info) == first_stmt_info)); + first_dr_info = STMT_VINFO_DR_INFO (first_stmt_info); + op = vect_get_store_rhs (first_stmt_info); - ref_type = get_group_alias_ptr_type (first_stmt_info); - } - else - ref_type = reference_alias_ptr_type (DR_REF (first_dr_info->dr)); + ref_type = get_group_alias_ptr_type (first_stmt_info); if (!costing_p && dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "transform store. ncopies = %d\n", - ncopies); - - /* Check if we need to update prologue cost for invariant, - and update it accordingly if so. If it's not for - interleaving store, we can just check vls_type; but if - it's for interleaving store, need to check the def_type - of the stored value since the current vls_type is just - for first_stmt_info. */ - auto update_prologue_cost = [&](unsigned *prologue_cost, tree store_rhs) - { - gcc_assert (costing_p); - if (slp) - return; - if (grouped_store) - { - gcc_assert (store_rhs); - enum vect_def_type cdt; - gcc_assert (vect_is_simple_use (store_rhs, vinfo, &cdt)); - if (cdt != vect_constant_def && cdt != vect_external_def) - return; - } - else if (vls_type != VLS_STORE_INVARIANT) - return; - *prologue_cost += record_stmt_cost (cost_vec, 1, scalar_to_vec, - slp_node, 0, vect_prologue); - }; + dump_printf_loc (MSG_NOTE, vect_location, "transform store.\n"); if (memory_access_type == VMAT_ELEMENTWISE || memory_access_type == VMAT_STRIDED_SLP) @@ -8690,14 +8523,12 @@ vectorizable_store (vec_info *vinfo, unsigned inside_cost = 0, prologue_cost = 0; gimple_stmt_iterator incr_gsi; bool insert_after; - gimple *incr; tree offvar = NULL_TREE; tree ivstep; tree running_off; tree stride_base, stride_step, alias_off; tree vec_oprnd = NULL_TREE; tree dr_offset; - unsigned int g; /* Checked by get_load_store_type. */ unsigned int const_nunits = nunits.to_constant (); @@ -8735,116 +8566,112 @@ vectorizable_store (vec_info *vinfo, unsigned lnel = 1; tree ltype = elem_type; tree lvectype = vectype; - if (slp) - { - HOST_WIDE_INT n = gcd (group_size, const_nunits); - if (n == const_nunits) - { - int mis_align = dr_misalignment (first_dr_info, vectype); - /* With VF > 1 we advance the DR by step, if that is constant - and only aligned when performed VF times, DR alignment - analysis can analyze this as aligned since it assumes - contiguous accesses. But that is not how we code generate - here, so adjust for this. */ - if (maybe_gt (vf, 1u) - && !multiple_p (DR_STEP_ALIGNMENT (first_dr_info->dr), - DR_TARGET_ALIGNMENT (first_dr_info))) - mis_align = -1; - dr_alignment_support dr_align - = vect_supportable_dr_alignment (vinfo, dr_info, vectype, - mis_align); - if (dr_align == dr_aligned - || dr_align == dr_unaligned_supported) - { - nstores = 1; - lnel = const_nunits; - ltype = vectype; - lvectype = vectype; - alignment_support_scheme = dr_align; - misalignment = mis_align; - } - } - else if (n > 1) - { - nstores = const_nunits / n; - lnel = n; - ltype = build_vector_type (elem_type, n); + HOST_WIDE_INT n = gcd (group_size, const_nunits); + if (n == const_nunits) + { + int mis_align = dr_misalignment (first_dr_info, vectype); + /* With VF > 1 we advance the DR by step, if that is constant + and only aligned when performed VF times, DR alignment + analysis can analyze this as aligned since it assumes + contiguous accesses. But that is not how we code generate + here, so adjust for this. */ + if (maybe_gt (vf, 1u) + && !multiple_p (DR_STEP_ALIGNMENT (first_dr_info->dr), + DR_TARGET_ALIGNMENT (first_dr_info))) + mis_align = -1; + dr_alignment_support dr_align + = vect_supportable_dr_alignment (vinfo, dr_info, vectype, + mis_align); + if (dr_align == dr_aligned + || dr_align == dr_unaligned_supported) + { + nstores = 1; + lnel = const_nunits; + ltype = vectype; lvectype = vectype; - int mis_align = dr_misalignment (first_dr_info, ltype); - if (maybe_gt (vf, 1u) - && !multiple_p (DR_STEP_ALIGNMENT (first_dr_info->dr), - DR_TARGET_ALIGNMENT (first_dr_info))) - mis_align = -1; - dr_alignment_support dr_align - = vect_supportable_dr_alignment (vinfo, dr_info, ltype, - mis_align); alignment_support_scheme = dr_align; misalignment = mis_align; - - /* First check if vec_extract optab doesn't support extraction - of vector elts directly. */ - scalar_mode elmode = SCALAR_TYPE_MODE (elem_type); - machine_mode vmode; - if (!VECTOR_MODE_P (TYPE_MODE (vectype)) - || !related_vector_mode (TYPE_MODE (vectype), elmode, - n).exists (&vmode) - || (convert_optab_handler (vec_extract_optab, - TYPE_MODE (vectype), vmode) - == CODE_FOR_nothing) - || !(dr_align == dr_aligned - || dr_align == dr_unaligned_supported)) - { - /* Try to avoid emitting an extract of vector elements - by performing the extracts using an integer type of the - same size, extracting from a vector of those and then - re-interpreting it as the original vector type if - supported. */ - unsigned lsize - = n * GET_MODE_BITSIZE (elmode); - unsigned int lnunits = const_nunits / n; - /* If we can't construct such a vector fall back to - element extracts from the original vector type and - element size stores. */ - if (int_mode_for_size (lsize, 0).exists (&elmode) - && VECTOR_MODE_P (TYPE_MODE (vectype)) - && related_vector_mode (TYPE_MODE (vectype), elmode, - lnunits).exists (&vmode) - && (convert_optab_handler (vec_extract_optab, - vmode, elmode) - != CODE_FOR_nothing)) - { - nstores = lnunits; - lnel = n; - ltype = build_nonstandard_integer_type (lsize, 1); - lvectype = build_vector_type (ltype, nstores); - } - /* Else fall back to vector extraction anyway. - Fewer stores are more important than avoiding spilling - of the vector we extract from. Compared to the - construction case in vectorizable_load no store-forwarding - issue exists here for reasonable archs. But only - if the store is supported. */ - else if (!(dr_align == dr_aligned - || dr_align == dr_unaligned_supported)) - { - nstores = const_nunits; - lnel = 1; - ltype = elem_type; - lvectype = vectype; - } - } } - unsigned align; - if (alignment_support_scheme == dr_aligned) - align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info)); - else - align = dr_alignment (vect_dr_behavior (vinfo, first_dr_info)); - /* Alignment is at most the access size if we do multiple stores. */ - if (nstores > 1) - align = MIN (tree_to_uhwi (TYPE_SIZE_UNIT (ltype)), align); - ltype = build_aligned_type (ltype, align * BITS_PER_UNIT); - ncopies = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); } + else if (n > 1) + { + nstores = const_nunits / n; + lnel = n; + ltype = build_vector_type (elem_type, n); + lvectype = vectype; + int mis_align = dr_misalignment (first_dr_info, ltype); + if (maybe_gt (vf, 1u) + && !multiple_p (DR_STEP_ALIGNMENT (first_dr_info->dr), + DR_TARGET_ALIGNMENT (first_dr_info))) + mis_align = -1; + dr_alignment_support dr_align + = vect_supportable_dr_alignment (vinfo, dr_info, ltype, + mis_align); + alignment_support_scheme = dr_align; + misalignment = mis_align; + + /* First check if vec_extract optab doesn't support extraction + of vector elts directly. */ + scalar_mode elmode = SCALAR_TYPE_MODE (elem_type); + machine_mode vmode; + if (!VECTOR_MODE_P (TYPE_MODE (vectype)) + || !related_vector_mode (TYPE_MODE (vectype), elmode, + n).exists (&vmode) + || (convert_optab_handler (vec_extract_optab, + TYPE_MODE (vectype), vmode) + == CODE_FOR_nothing) + || !(dr_align == dr_aligned + || dr_align == dr_unaligned_supported)) + { + /* Try to avoid emitting an extract of vector elements + by performing the extracts using an integer type of the + same size, extracting from a vector of those and then + re-interpreting it as the original vector type if + supported. */ + unsigned lsize = n * GET_MODE_BITSIZE (elmode); + unsigned int lnunits = const_nunits / n; + /* If we can't construct such a vector fall back to + element extracts from the original vector type and + element size stores. */ + if (int_mode_for_size (lsize, 0).exists (&elmode) + && VECTOR_MODE_P (TYPE_MODE (vectype)) + && related_vector_mode (TYPE_MODE (vectype), elmode, + lnunits).exists (&vmode) + && (convert_optab_handler (vec_extract_optab, + vmode, elmode) + != CODE_FOR_nothing)) + { + nstores = lnunits; + lnel = n; + ltype = build_nonstandard_integer_type (lsize, 1); + lvectype = build_vector_type (ltype, nstores); + } + /* Else fall back to vector extraction anyway. + Fewer stores are more important than avoiding spilling + of the vector we extract from. Compared to the + construction case in vectorizable_load no store-forwarding + issue exists here for reasonable archs. But only + if the store is supported. */ + else if (!(dr_align == dr_aligned + || dr_align == dr_unaligned_supported)) + { + nstores = const_nunits; + lnel = 1; + ltype = elem_type; + lvectype = vectype; + } + } + } + unsigned align; + if (alignment_support_scheme == dr_aligned) + align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info)); + else + align = dr_alignment (vect_dr_behavior (vinfo, first_dr_info)); + /* Alignment is at most the access size if we do multiple stores. */ + if (nstores > 1) + align = MIN (tree_to_uhwi (TYPE_SIZE_UNIT (ltype)), align); + ltype = build_aligned_type (ltype, align * BITS_PER_UNIT); + int ncopies = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); if (!costing_p) { @@ -8858,7 +8685,6 @@ vectorizable_store (vec_info *vinfo, ivstep = cse_and_gimplify_to_preheader (loop_vinfo, ivstep); create_iv (stride_base, PLUS_EXPR, ivstep, NULL, loop, &incr_gsi, insert_after, &offvar, NULL); - incr = gsi_stmt (incr_gsi); stride_step = cse_and_gimplify_to_preheader (loop_vinfo, stride_step); } @@ -8869,104 +8695,68 @@ vectorizable_store (vec_info *vinfo, /* For costing some adjacent vector stores, we'd like to cost with the total number of them once instead of cost each one by one. */ unsigned int n_adjacent_stores = 0; - for (g = 0; g < group_size; g++) + running_off = offvar; + if (!costing_p) + vect_get_vec_defs (vinfo, next_stmt_info, slp_node, ncopies, op, + &vec_oprnds); + unsigned int group_el = 0; + unsigned HOST_WIDE_INT elsz + = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (vectype))); + for (j = 0; j < ncopies; j++) { - running_off = offvar; if (!costing_p) { - if (g) + vec_oprnd = vec_oprnds[j]; + /* Pun the vector to extract from if necessary. */ + if (lvectype != vectype) { - tree size = TYPE_SIZE_UNIT (ltype); - tree pos - = fold_build2 (MULT_EXPR, sizetype, size_int (g), size); - tree newoff = copy_ssa_name (running_off, NULL); - incr = gimple_build_assign (newoff, POINTER_PLUS_EXPR, - running_off, pos); - vect_finish_stmt_generation (vinfo, stmt_info, incr, gsi); - running_off = newoff; + tree tem = make_ssa_name (lvectype); + tree cvt = build1 (VIEW_CONVERT_EXPR, lvectype, vec_oprnd); + gimple *pun = gimple_build_assign (tem, cvt); + vect_finish_stmt_generation (vinfo, stmt_info, pun, gsi); + vec_oprnd = tem; } } - if (!slp) - op = vect_get_store_rhs (next_stmt_info); - if (!costing_p) - vect_get_vec_defs (vinfo, next_stmt_info, slp_node, ncopies, op, - &vec_oprnds); - else - update_prologue_cost (&prologue_cost, op); - unsigned int group_el = 0; - unsigned HOST_WIDE_INT - elsz = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (vectype))); - for (j = 0; j < ncopies; j++) + for (i = 0; i < nstores; i++) { - if (!costing_p) + if (costing_p) { - vec_oprnd = vec_oprnds[j]; - /* Pun the vector to extract from if necessary. */ - if (lvectype != vectype) - { - tree tem = make_ssa_name (lvectype); - tree cvt - = build1 (VIEW_CONVERT_EXPR, lvectype, vec_oprnd); - gimple *pun = gimple_build_assign (tem, cvt); - vect_finish_stmt_generation (vinfo, stmt_info, pun, gsi); - vec_oprnd = tem; - } + n_adjacent_stores++; + continue; } - for (i = 0; i < nstores; i++) + tree newref, newoff; + gimple *incr, *assign; + tree size = TYPE_SIZE (ltype); + /* Extract the i'th component. */ + tree pos = fold_build2 (MULT_EXPR, bitsizetype, + bitsize_int (i), size); + tree elem = fold_build3 (BIT_FIELD_REF, ltype, vec_oprnd, + size, pos); + + elem = force_gimple_operand_gsi (gsi, elem, true, NULL_TREE, true, + GSI_SAME_STMT); + + tree this_off = build_int_cst (TREE_TYPE (alias_off), + group_el * elsz); + newref = build2 (MEM_REF, ltype, running_off, this_off); + vect_copy_ref_info (newref, DR_REF (first_dr_info->dr)); + + /* And store it to *running_off. */ + assign = gimple_build_assign (newref, elem); + vect_finish_stmt_generation (vinfo, stmt_info, assign, gsi); + + group_el += lnel; + if (group_el == group_size) { - if (costing_p) - { - n_adjacent_stores++; - continue; - } - tree newref, newoff; - gimple *incr, *assign; - tree size = TYPE_SIZE (ltype); - /* Extract the i'th component. */ - tree pos = fold_build2 (MULT_EXPR, bitsizetype, - bitsize_int (i), size); - tree elem = fold_build3 (BIT_FIELD_REF, ltype, vec_oprnd, - size, pos); - - elem = force_gimple_operand_gsi (gsi, elem, true, - NULL_TREE, true, - GSI_SAME_STMT); - - tree this_off = build_int_cst (TREE_TYPE (alias_off), - group_el * elsz); - newref = build2 (MEM_REF, ltype, - running_off, this_off); - vect_copy_ref_info (newref, DR_REF (first_dr_info->dr)); - - /* And store it to *running_off. */ - assign = gimple_build_assign (newref, elem); - vect_finish_stmt_generation (vinfo, stmt_info, assign, gsi); - - group_el += lnel; - if (! slp - || group_el == group_size) - { - newoff = copy_ssa_name (running_off, NULL); - incr = gimple_build_assign (newoff, POINTER_PLUS_EXPR, - running_off, stride_step); - vect_finish_stmt_generation (vinfo, stmt_info, incr, gsi); + newoff = copy_ssa_name (running_off, NULL); + incr = gimple_build_assign (newoff, POINTER_PLUS_EXPR, + running_off, stride_step); + vect_finish_stmt_generation (vinfo, stmt_info, incr, gsi); - running_off = newoff; - group_el = 0; - } - if (g == group_size - 1 - && !slp) - { - if (j == 0 && i == 0) - *vec_stmt = assign; - STMT_VINFO_VEC_STMTS (stmt_info).safe_push (assign); - } + running_off = newoff; + group_el = 0; } } - next_stmt_info = DR_GROUP_NEXT_ELEMENT (next_stmt_info); - vec_oprnds.truncate(0); - if (slp) - break; } if (costing_p) @@ -9107,7 +8897,7 @@ vectorizable_store (vec_info *vinfo, if (memory_access_type == VMAT_LOAD_STORE_LANES) { - if (costing_p && slp_node) + if (costing_p) /* Update all incoming store operand nodes, the general handling above only handles the mask and the first store operand node. */ for (slp_tree child : SLP_TREE_CHILDREN (slp_node)) @@ -9123,49 +8913,18 @@ vectorizable_store (vec_info *vinfo, /* For costing some adjacent vector stores, we'd like to cost with the total number of them once instead of cost each one by one. */ unsigned int n_adjacent_stores = 0; - if (slp) - ncopies = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node) / group_size; + int ncopies = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node) / group_size; for (j = 0; j < ncopies; j++) { - gimple *new_stmt; if (j == 0) { - /* For interleaved stores we collect vectorized defs for all - the stores in the group in DR_CHAIN. DR_CHAIN is then used - as an input to vect_permute_store_chain(). */ - stmt_vec_info next_stmt_info = first_stmt_info; - for (i = 0; i < group_size; i++) - { - /* Since gaps are not supported for interleaved stores, - DR_GROUP_SIZE is the exact number of stmts in the - chain. Therefore, NEXT_STMT_INFO can't be NULL_TREE. */ - op = vect_get_store_rhs (next_stmt_info); - if (costing_p) - update_prologue_cost (&prologue_cost, op); - else if (!slp) - { - vect_get_vec_defs_for_operand (vinfo, next_stmt_info, - ncopies, op, - gvec_oprnds[i]); - vec_oprnd = (*gvec_oprnds[i])[0]; - dr_chain.quick_push (vec_oprnd); - } - next_stmt_info = DR_GROUP_NEXT_ELEMENT (next_stmt_info); - } - if (!costing_p) { if (mask) { - if (slp_node) - vect_get_slp_defs (mask_node, &vec_masks); - else - vect_get_vec_defs_for_operand (vinfo, stmt_info, ncopies, - mask, &vec_masks, - mask_vectype); + vect_get_slp_defs (mask_node, &vec_masks); vec_mask = vec_masks[0]; } - dataref_ptr = vect_create_data_ref_ptr (vinfo, first_stmt_info, aggr_type, NULL, offset, &dummy, @@ -9175,19 +8934,6 @@ vectorizable_store (vec_info *vinfo, else if (!costing_p) { gcc_assert (!LOOP_VINFO_USING_SELECT_VL_P (loop_vinfo)); - /* DR_CHAIN is then used as an input to - vect_permute_store_chain(). */ - if (!slp) - { - /* We should have caught mismatched types earlier. */ - gcc_assert ( - useless_type_conversion_p (vectype, TREE_TYPE (vec_oprnd))); - for (i = 0; i < group_size; i++) - { - vec_oprnd = (*gvec_oprnds[i])[j]; - dr_chain[i] = vec_oprnd; - } - } if (mask) vec_mask = vec_masks[j]; dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, gsi, @@ -9211,17 +8957,12 @@ vectorizable_store (vec_info *vinfo, /* Store the individual vectors into the array. */ for (i = 0; i < group_size; i++) { - if (slp) - { - slp_tree child; - if (i == 0 || !mask_node) - child = SLP_TREE_CHILDREN (slp_node)[i]; - else - child = SLP_TREE_CHILDREN (slp_node)[i + 1]; - vec_oprnd = SLP_TREE_VEC_DEFS (child)[j]; - } + slp_tree child; + if (i == 0 || !mask_node) + child = SLP_TREE_CHILDREN (slp_node)[i]; else - vec_oprnd = dr_chain[i]; + child = SLP_TREE_CHILDREN (slp_node)[i + 1]; + vec_oprnd = SLP_TREE_VEC_DEFS (child)[j]; write_vector_array (vinfo, stmt_info, gsi, vec_oprnd, vec_array, i); } @@ -9287,14 +9028,9 @@ vectorizable_store (vec_info *vinfo, } gimple_call_set_nothrow (call, true); vect_finish_stmt_generation (vinfo, stmt_info, call, gsi); - new_stmt = call; /* Record that VEC_ARRAY is now dead. */ vect_clobber_variable (vinfo, stmt_info, gsi, vec_array); - if (j == 0 && !slp) - *vec_stmt = new_stmt; - if (!slp) - STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); } if (costing_p) @@ -9318,7 +9054,7 @@ vectorizable_store (vec_info *vinfo, gcc_assert (!grouped_store); auto_vec vec_offsets; unsigned int inside_cost = 0, prologue_cost = 0; - int num_stmts = ncopies * vec_num; + int num_stmts = vec_num; for (j = 0; j < num_stmts; j++) { gimple *new_stmt; @@ -9332,21 +9068,9 @@ vectorizable_store (vec_info *vinfo, /* Since the store is not grouped, DR_GROUP_SIZE is 1, and DR_CHAIN is of size 1. */ gcc_assert (group_size == 1); - if (slp_node) - vect_get_slp_defs (op_node, gvec_oprnds[0]); - else - vect_get_vec_defs_for_operand (vinfo, first_stmt_info, - num_stmts, op, gvec_oprnds[0]); + vect_get_slp_defs (op_node, gvec_oprnds[0]); if (mask) - { - if (slp_node) - vect_get_slp_defs (mask_node, &vec_masks); - else - vect_get_vec_defs_for_operand (vinfo, stmt_info, - num_stmts, - mask, &vec_masks, - mask_vectype); - } + vect_get_slp_defs (mask_node, &vec_masks); if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)) vect_get_gather_scatter_ops (loop_vinfo, loop, stmt_info, @@ -9638,17 +9362,10 @@ vectorizable_store (vec_info *vinfo, vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); } - if (slp) - slp_node->push_vec_def (new_stmt); + slp_node->push_vec_def (new_stmt); } - - if (!slp && !costing_p) - STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); } - if (!slp && !costing_p) - *vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info)[0]; - if (costing_p && dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "vect_model_store_cost: inside_cost = %d, " @@ -9669,330 +9386,263 @@ vectorizable_store (vec_info *vinfo, unsigned int n_adjacent_stores = 0; auto_vec result_chain (group_size); auto_vec vec_oprnds; - for (j = 0; j < ncopies; j++) + gimple *new_stmt; + if (!costing_p) { - gimple *new_stmt; - if (j == 0) - { - if (slp && !costing_p) - { - /* Get vectorized arguments for SLP_NODE. */ - vect_get_vec_defs (vinfo, stmt_info, slp_node, 1, op, - &vec_oprnds, mask, &vec_masks); - vec_oprnd = vec_oprnds[0]; - if (mask) - vec_mask = vec_masks[0]; - } - else - { - /* For interleaved stores we collect vectorized defs for all the - stores in the group in DR_CHAIN. DR_CHAIN is then used as an - input to vect_permute_store_chain(). - - If the store is not grouped, DR_GROUP_SIZE is 1, and DR_CHAIN - is of size 1. */ - stmt_vec_info next_stmt_info = first_stmt_info; - for (i = 0; i < group_size; i++) - { - /* Since gaps are not supported for interleaved stores, - DR_GROUP_SIZE is the exact number of stmts in the chain. - Therefore, NEXT_STMT_INFO can't be NULL_TREE. In case - that there is no interleaving, DR_GROUP_SIZE is 1, - and only one iteration of the loop will be executed. */ - op = vect_get_store_rhs (next_stmt_info); - if (costing_p) - update_prologue_cost (&prologue_cost, op); - else - { - vect_get_vec_defs_for_operand (vinfo, next_stmt_info, - ncopies, op, - gvec_oprnds[i]); - vec_oprnd = (*gvec_oprnds[i])[0]; - dr_chain.quick_push (vec_oprnd); - } - next_stmt_info = DR_GROUP_NEXT_ELEMENT (next_stmt_info); - } - if (mask && !costing_p) - { - vect_get_vec_defs_for_operand (vinfo, stmt_info, ncopies, - mask, &vec_masks, - mask_vectype); - vec_mask = vec_masks[0]; - } - } + /* Get vectorized arguments for SLP_NODE. */ + vect_get_vec_defs (vinfo, stmt_info, slp_node, 1, op, + &vec_oprnds, mask, &vec_masks); + vec_oprnd = vec_oprnds[0]; + if (mask) + vec_mask = vec_masks[0]; + } + else + { + /* For interleaved stores we collect vectorized defs for all the + stores in the group in DR_CHAIN. DR_CHAIN is then used as an + input to vect_permute_store_chain(). - /* We should have catched mismatched types earlier. */ - gcc_assert (costing_p - || useless_type_conversion_p (vectype, - TREE_TYPE (vec_oprnd))); - bool simd_lane_access_p - = STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info) != 0; - if (!costing_p - && simd_lane_access_p - && !loop_masks - && TREE_CODE (DR_BASE_ADDRESS (first_dr_info->dr)) == ADDR_EXPR - && VAR_P (TREE_OPERAND (DR_BASE_ADDRESS (first_dr_info->dr), 0)) - && integer_zerop (get_dr_vinfo_offset (vinfo, first_dr_info)) - && integer_zerop (DR_INIT (first_dr_info->dr)) - && alias_sets_conflict_p (get_alias_set (aggr_type), - get_alias_set (TREE_TYPE (ref_type)))) - { - dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr_info->dr)); - dataref_offset = build_int_cst (ref_type, 0); - } - else if (!costing_p) - dataref_ptr - = vect_create_data_ref_ptr (vinfo, first_stmt_info, aggr_type, - simd_lane_access_p ? loop : NULL, - offset, &dummy, gsi, &ptr_incr, - simd_lane_access_p, bump); - } - else if (!costing_p) - { - gcc_assert (!LOOP_VINFO_USING_SELECT_VL_P (loop_vinfo)); - /* DR_CHAIN is then used as an input to vect_permute_store_chain(). - If the store is not grouped, DR_GROUP_SIZE is 1, and DR_CHAIN is - of size 1. */ - for (i = 0; i < group_size; i++) + If the store is not grouped, DR_GROUP_SIZE is 1, and DR_CHAIN + is of size 1. */ + stmt_vec_info next_stmt_info = first_stmt_info; + for (i = 0; i < group_size; i++) + { + /* Since gaps are not supported for interleaved stores, + DR_GROUP_SIZE is the exact number of stmts in the chain. + Therefore, NEXT_STMT_INFO can't be NULL_TREE. In case + that there is no interleaving, DR_GROUP_SIZE is 1, + and only one iteration of the loop will be executed. */ + op = vect_get_store_rhs (next_stmt_info); + if (!costing_p) { - vec_oprnd = (*gvec_oprnds[i])[j]; - dr_chain[i] = vec_oprnd; + vect_get_vec_defs_for_operand (vinfo, next_stmt_info, + 1, op, gvec_oprnds[i]); + vec_oprnd = (*gvec_oprnds[i])[0]; + dr_chain.quick_push (vec_oprnd); } - if (mask) - vec_mask = vec_masks[j]; - if (dataref_offset) - dataref_offset = int_const_binop (PLUS_EXPR, dataref_offset, bump); - else - dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, gsi, - stmt_info, bump); + next_stmt_info = DR_GROUP_NEXT_ELEMENT (next_stmt_info); } - - new_stmt = NULL; - if (grouped_store) + if (mask && !costing_p) { - /* Permute. */ - gcc_assert (memory_access_type == VMAT_CONTIGUOUS_PERMUTE); - if (costing_p) - { - int group_size = DR_GROUP_SIZE (first_stmt_info); - int nstmts = ceil_log2 (group_size) * group_size; - inside_cost += record_stmt_cost (cost_vec, nstmts, vec_perm, - slp_node, 0, vect_body); - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "vect_model_store_cost: " - "strided group_size = %d .\n", - group_size); - } - else - vect_permute_store_chain (vinfo, dr_chain, group_size, stmt_info, - gsi, &result_chain); + vect_get_vec_defs_for_operand (vinfo, stmt_info, 1, + mask, &vec_masks, mask_vectype); + vec_mask = vec_masks[0]; } + } - stmt_vec_info next_stmt_info = first_stmt_info; - for (i = 0; i < vec_num; i++) + /* We should have catched mismatched types earlier. */ + gcc_assert (costing_p + || useless_type_conversion_p (vectype, TREE_TYPE (vec_oprnd))); + bool simd_lane_access_p + = STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info) != 0; + if (!costing_p + && simd_lane_access_p + && !loop_masks + && TREE_CODE (DR_BASE_ADDRESS (first_dr_info->dr)) == ADDR_EXPR + && VAR_P (TREE_OPERAND (DR_BASE_ADDRESS (first_dr_info->dr), 0)) + && integer_zerop (get_dr_vinfo_offset (vinfo, first_dr_info)) + && integer_zerop (DR_INIT (first_dr_info->dr)) + && alias_sets_conflict_p (get_alias_set (aggr_type), + get_alias_set (TREE_TYPE (ref_type)))) + { + dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr_info->dr)); + dataref_offset = build_int_cst (ref_type, 0); + } + else if (!costing_p) + dataref_ptr = vect_create_data_ref_ptr (vinfo, first_stmt_info, aggr_type, + simd_lane_access_p ? loop : NULL, + offset, &dummy, gsi, &ptr_incr, + simd_lane_access_p, bump); + + new_stmt = NULL; + if (grouped_store) + { + /* Permute. */ + gcc_assert (memory_access_type == VMAT_CONTIGUOUS_PERMUTE); + if (costing_p) { - if (!costing_p) - { - if (slp) - vec_oprnd = vec_oprnds[i]; - else if (grouped_store) - /* For grouped stores vectorized defs are interleaved in - vect_permute_store_chain(). */ - vec_oprnd = result_chain[i]; - } + int group_size = DR_GROUP_SIZE (first_stmt_info); + int nstmts = ceil_log2 (group_size) * group_size; + inside_cost += record_stmt_cost (cost_vec, nstmts, vec_perm, + slp_node, 0, vect_body); + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, "vect_model_store_cost: " + "strided group_size = %d .\n", group_size); + } + else + vect_permute_store_chain (vinfo, dr_chain, group_size, stmt_info, + gsi, &result_chain); + } - if (memory_access_type == VMAT_CONTIGUOUS_REVERSE) - { - if (costing_p) - inside_cost += record_stmt_cost (cost_vec, 1, vec_perm, - slp_node, 0, vect_body); - else - { - tree perm_mask = perm_mask_for_reverse (vectype); - tree perm_dest = vect_create_destination_var ( - vect_get_store_rhs (stmt_info), vectype); - tree new_temp = make_ssa_name (perm_dest); - - /* Generate the permute statement. */ - gimple *perm_stmt - = gimple_build_assign (new_temp, VEC_PERM_EXPR, vec_oprnd, - vec_oprnd, perm_mask); - vect_finish_stmt_generation (vinfo, stmt_info, perm_stmt, - gsi); - - perm_stmt = SSA_NAME_DEF_STMT (new_temp); - vec_oprnd = new_temp; - } - } + for (i = 0; i < vec_num; i++) + { + if (!costing_p) + vec_oprnd = vec_oprnds[i]; + if (memory_access_type == VMAT_CONTIGUOUS_REVERSE) + { if (costing_p) + inside_cost += record_stmt_cost (cost_vec, 1, vec_perm, + slp_node, 0, vect_body); + else { - n_adjacent_stores++; + tree perm_mask = perm_mask_for_reverse (vectype); + tree perm_dest + = vect_create_destination_var (vect_get_store_rhs (stmt_info), + vectype); + tree new_temp = make_ssa_name (perm_dest); - if (!slp) - { - next_stmt_info = DR_GROUP_NEXT_ELEMENT (next_stmt_info); - if (!next_stmt_info) - break; - } + /* Generate the permute statement. */ + gimple *perm_stmt + = gimple_build_assign (new_temp, VEC_PERM_EXPR, vec_oprnd, + vec_oprnd, perm_mask); + vect_finish_stmt_generation (vinfo, stmt_info, perm_stmt, gsi); - continue; + perm_stmt = SSA_NAME_DEF_STMT (new_temp); + vec_oprnd = new_temp; } + } - tree final_mask = NULL_TREE; - tree final_len = NULL_TREE; - tree bias = NULL_TREE; - if (loop_masks) - final_mask = vect_get_loop_mask (loop_vinfo, gsi, loop_masks, - vec_num * ncopies, vectype, - vec_num * j + i); - if (slp && vec_mask) - vec_mask = vec_masks[i]; - if (vec_mask) - final_mask = prepare_vec_mask (loop_vinfo, mask_vectype, final_mask, - vec_mask, gsi); - - if (i > 0) - /* Bump the vector pointer. */ - dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, gsi, - stmt_info, bump); + if (costing_p) + { + n_adjacent_stores++; + continue; + } - unsigned misalign; - unsigned HOST_WIDE_INT align; - align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info)); - if (alignment_support_scheme == dr_aligned) - misalign = 0; - else if (misalignment == DR_MISALIGNMENT_UNKNOWN) - { - align = dr_alignment (vect_dr_behavior (vinfo, first_dr_info)); - misalign = 0; - } - else - misalign = misalignment; - if (dataref_offset == NULL_TREE - && TREE_CODE (dataref_ptr) == SSA_NAME) - set_ptr_info_alignment (get_ptr_info (dataref_ptr), align, - misalign); - align = least_bit_hwi (misalign | align); - - /* Compute IFN when LOOP_LENS or final_mask valid. */ - machine_mode vmode = TYPE_MODE (vectype); - machine_mode new_vmode = vmode; - internal_fn partial_ifn = IFN_LAST; - if (loop_lens) - { - opt_machine_mode new_ovmode - = get_len_load_store_mode (vmode, false, &partial_ifn); - new_vmode = new_ovmode.require (); - unsigned factor - = (new_ovmode == vmode) ? 1 : GET_MODE_UNIT_SIZE (vmode); - final_len = vect_get_loop_len (loop_vinfo, gsi, loop_lens, - vec_num * ncopies, vectype, - vec_num * j + i, factor); - } - else if (final_mask) - { - if (!can_vec_mask_load_store_p ( - vmode, TYPE_MODE (TREE_TYPE (final_mask)), false, - &partial_ifn)) - gcc_unreachable (); - } + tree final_mask = NULL_TREE; + tree final_len = NULL_TREE; + tree bias = NULL_TREE; + if (loop_masks) + final_mask = vect_get_loop_mask (loop_vinfo, gsi, loop_masks, + vec_num, vectype, i); + if (vec_mask) + vec_mask = vec_masks[i]; + if (vec_mask) + final_mask = prepare_vec_mask (loop_vinfo, mask_vectype, final_mask, + vec_mask, gsi); + + if (i > 0) + /* Bump the vector pointer. */ + dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, gsi, + stmt_info, bump); + + unsigned misalign; + unsigned HOST_WIDE_INT align; + align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info)); + if (alignment_support_scheme == dr_aligned) + misalign = 0; + else if (misalignment == DR_MISALIGNMENT_UNKNOWN) + { + align = dr_alignment (vect_dr_behavior (vinfo, first_dr_info)); + misalign = 0; + } + else + misalign = misalignment; + if (dataref_offset == NULL_TREE + && TREE_CODE (dataref_ptr) == SSA_NAME) + set_ptr_info_alignment (get_ptr_info (dataref_ptr), align, misalign); + align = least_bit_hwi (misalign | align); + + /* Compute IFN when LOOP_LENS or final_mask valid. */ + machine_mode vmode = TYPE_MODE (vectype); + machine_mode new_vmode = vmode; + internal_fn partial_ifn = IFN_LAST; + if (loop_lens) + { + opt_machine_mode new_ovmode + = get_len_load_store_mode (vmode, false, &partial_ifn); + new_vmode = new_ovmode.require (); + unsigned factor + = (new_ovmode == vmode) ? 1 : GET_MODE_UNIT_SIZE (vmode); + final_len = vect_get_loop_len (loop_vinfo, gsi, loop_lens, + vec_num, vectype, i, factor); + } + else if (final_mask) + { + if (!can_vec_mask_load_store_p (vmode, + TYPE_MODE (TREE_TYPE (final_mask)), + false, &partial_ifn)) + gcc_unreachable (); + } - if (partial_ifn == IFN_MASK_LEN_STORE) + if (partial_ifn == IFN_MASK_LEN_STORE) + { + if (!final_len) { - if (!final_len) - { - /* Pass VF value to 'len' argument of - MASK_LEN_STORE if LOOP_LENS is invalid. */ - final_len = size_int (TYPE_VECTOR_SUBPARTS (vectype)); - } - if (!final_mask) - { - /* Pass all ones value to 'mask' argument of - MASK_LEN_STORE if final_mask is invalid. */ - mask_vectype = truth_type_for (vectype); - final_mask = build_minus_one_cst (mask_vectype); - } + /* Pass VF value to 'len' argument of + MASK_LEN_STORE if LOOP_LENS is invalid. */ + final_len = size_int (TYPE_VECTOR_SUBPARTS (vectype)); } - if (final_len) + if (!final_mask) { - signed char biasval - = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo); - - bias = build_int_cst (intQI_type_node, biasval); + /* Pass all ones value to 'mask' argument of + MASK_LEN_STORE if final_mask is invalid. */ + mask_vectype = truth_type_for (vectype); + final_mask = build_minus_one_cst (mask_vectype); } + } + if (final_len) + { + signed char biasval = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo); + bias = build_int_cst (intQI_type_node, biasval); + } - /* Arguments are ready. Create the new vector stmt. */ - if (final_len) - { - gcall *call; - tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT); - /* Need conversion if it's wrapped with VnQI. */ - if (vmode != new_vmode) - { - tree new_vtype - = build_vector_type_for_mode (unsigned_intQI_type_node, - new_vmode); - tree var = vect_get_new_ssa_name (new_vtype, vect_simple_var); - vec_oprnd = build1 (VIEW_CONVERT_EXPR, new_vtype, vec_oprnd); - gassign *new_stmt - = gimple_build_assign (var, VIEW_CONVERT_EXPR, vec_oprnd); - vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); - vec_oprnd = var; - } - - if (partial_ifn == IFN_MASK_LEN_STORE) - call = gimple_build_call_internal (IFN_MASK_LEN_STORE, 6, - dataref_ptr, ptr, final_mask, - final_len, bias, vec_oprnd); - else - call = gimple_build_call_internal (IFN_LEN_STORE, 5, - dataref_ptr, ptr, final_len, - bias, vec_oprnd); - gimple_call_set_nothrow (call, true); - vect_finish_stmt_generation (vinfo, stmt_info, call, gsi); - new_stmt = call; - } - else if (final_mask) - { - tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT); - gcall *call - = gimple_build_call_internal (IFN_MASK_STORE, 4, dataref_ptr, - ptr, final_mask, vec_oprnd); - gimple_call_set_nothrow (call, true); - vect_finish_stmt_generation (vinfo, stmt_info, call, gsi); - new_stmt = call; - } - else - { - data_ref - = fold_build2 (MEM_REF, vectype, dataref_ptr, - dataref_offset ? dataref_offset - : build_int_cst (ref_type, 0)); - if (alignment_support_scheme == dr_aligned) - ; - else - TREE_TYPE (data_ref) - = build_aligned_type (TREE_TYPE (data_ref), - align * BITS_PER_UNIT); - vect_copy_ref_info (data_ref, DR_REF (first_dr_info->dr)); - new_stmt = gimple_build_assign (data_ref, vec_oprnd); + /* Arguments are ready. Create the new vector stmt. */ + if (final_len) + { + gcall *call; + tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT); + /* Need conversion if it's wrapped with VnQI. */ + if (vmode != new_vmode) + { + tree new_vtype + = build_vector_type_for_mode (unsigned_intQI_type_node, + new_vmode); + tree var = vect_get_new_ssa_name (new_vtype, vect_simple_var); + vec_oprnd = build1 (VIEW_CONVERT_EXPR, new_vtype, vec_oprnd); + gassign *new_stmt + = gimple_build_assign (var, VIEW_CONVERT_EXPR, vec_oprnd); vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); + vec_oprnd = var; } - if (slp) - continue; - - next_stmt_info = DR_GROUP_NEXT_ELEMENT (next_stmt_info); - if (!next_stmt_info) - break; + if (partial_ifn == IFN_MASK_LEN_STORE) + call = gimple_build_call_internal (IFN_MASK_LEN_STORE, 6, + dataref_ptr, ptr, final_mask, + final_len, bias, vec_oprnd); + else + call = gimple_build_call_internal (IFN_LEN_STORE, 5, + dataref_ptr, ptr, final_len, + bias, vec_oprnd); + gimple_call_set_nothrow (call, true); + vect_finish_stmt_generation (vinfo, stmt_info, call, gsi); + new_stmt = call; } - if (!slp && !costing_p) + else if (final_mask) { - if (j == 0) - *vec_stmt = new_stmt; - STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); + tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT); + gcall *call + = gimple_build_call_internal (IFN_MASK_STORE, 4, dataref_ptr, + ptr, final_mask, vec_oprnd); + gimple_call_set_nothrow (call, true); + vect_finish_stmt_generation (vinfo, stmt_info, call, gsi); + new_stmt = call; + } + else + { + data_ref = fold_build2 (MEM_REF, vectype, dataref_ptr, + dataref_offset ? dataref_offset + : build_int_cst (ref_type, 0)); + if (alignment_support_scheme == dr_aligned + && align >= TYPE_ALIGN_UNIT (vectype)) + ; + else + TREE_TYPE (data_ref) + = build_aligned_type (TREE_TYPE (data_ref), + align * BITS_PER_UNIT); + vect_copy_ref_info (data_ref, DR_REF (first_dr_info->dr)); + new_stmt = gimple_build_assign (data_ref, vec_oprnd); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); } } @@ -10024,11 +9674,11 @@ vectorizable_store (vec_info *vinfo, { /* Spill. */ prologue_cost - += record_stmt_cost (cost_vec, ncopies, vector_store, + += record_stmt_cost (cost_vec, 1, vector_store, slp_node, 0, vect_epilogue); /* Loads. */ prologue_cost - += record_stmt_cost (cost_vec, ncopies * nregs, scalar_load, + += record_stmt_cost (cost_vec, nregs, scalar_load, slp_node, 0, vect_epilogue); } } @@ -10194,7 +9844,6 @@ vectorizable_load (vec_info *vinfo, tree dataref_ptr = NULL_TREE; tree dataref_offset = NULL_TREE; gimple *ptr_incr = NULL; - int ncopies; int i, j; unsigned int group_size; poly_uint64 group_gap_adj; @@ -10208,7 +9857,6 @@ vectorizable_load (vec_info *vinfo, bool compute_in_loop = false; class loop *at_loop; int vec_num; - bool slp = (slp_node != NULL); bool slp_perm = false; bb_vec_info bb_vinfo = dyn_cast (vinfo); poly_uint64 vf; @@ -10267,7 +9915,7 @@ vectorizable_load (vec_info *vinfo, return false; mask_index = internal_fn_mask_index (ifn); - if (mask_index >= 0 && slp_node) + if (mask_index >= 0) mask_index = vect_slp_child_index_for_operand (call, mask_index, STMT_VINFO_GATHER_SCATTER_P (stmt_info)); if (mask_index >= 0 @@ -10276,7 +9924,7 @@ vectorizable_load (vec_info *vinfo, return false; els_index = internal_fn_else_index (ifn); - if (els_index >= 0 && slp_node) + if (els_index >= 0) els_index = vect_slp_child_index_for_operand (call, els_index, STMT_VINFO_GATHER_SCATTER_P (stmt_info)); if (els_index >= 0 @@ -10297,19 +9945,9 @@ vectorizable_load (vec_info *vinfo, else vf = 1; - /* Multiple types in SLP are handled by creating the appropriate number of - vectorized stmts for each SLP node. Hence, NCOPIES is always 1 in - case of SLP. */ - if (slp) - ncopies = 1; - else - ncopies = vect_get_num_copies (loop_vinfo, vectype); - - gcc_assert (ncopies >= 1); - /* FORNOW. This restriction should be relaxed. */ if (nested_in_vect_loop - && (ncopies > 1 || (slp && SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node) > 1))) + && SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node) > 1) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -10317,20 +9955,6 @@ vectorizable_load (vec_info *vinfo, return false; } - /* Invalidate assumptions made by dependence analysis when vectorization - on the unrolled body effectively re-orders stmts. */ - if (ncopies > 1 - && STMT_VINFO_MIN_NEG_DIST (stmt_info) != 0 - && maybe_gt (LOOP_VINFO_VECT_FACTOR (loop_vinfo), - STMT_VINFO_MIN_NEG_DIST (stmt_info))) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "cannot perform implicit CSE when unrolling " - "with negative dependence distance\n"); - return false; - } - elem_type = TREE_TYPE (vectype); mode = TYPE_MODE (vectype); @@ -10355,15 +9979,6 @@ vectorizable_load (vec_info *vinfo, first_stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info); group_size = DR_GROUP_SIZE (first_stmt_info); - /* Refuse non-SLP vectorization of SLP-only groups. */ - if (!slp && STMT_VINFO_SLP_VECT_ONLY (first_stmt_info)) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "cannot vectorize load in non-SLP mode.\n"); - return false; - } - /* Invalidate assumptions made by dependence analysis when vectorization on the unrolled body effectively re-orders stmts. */ if (STMT_VINFO_MIN_NEG_DIST (stmt_info) != 0 @@ -10389,7 +10004,7 @@ vectorizable_load (vec_info *vinfo, int maskload_elsval = 0; bool need_zeroing = false; if (!get_load_store_type (vinfo, stmt_info, vectype, slp_node, mask, VLS_LOAD, - ncopies, &memory_access_type, &poffset, + 1, &memory_access_type, &poffset, &alignment_support_scheme, &misalignment, &gs_info, &lanes_ifn, &elsvals)) return false; @@ -10404,8 +10019,7 @@ vectorizable_load (vec_info *vinfo, /* ??? The following checks should really be part of get_group_load_store_type. */ - if (slp - && SLP_TREE_LOAD_PERMUTATION (slp_node).exists () + if (SLP_TREE_LOAD_PERMUTATION (slp_node).exists () && !((memory_access_type == VMAT_ELEMENTWISE || memory_access_type == VMAT_GATHER_SCATTER) && SLP_TREE_LANES (slp_node) == 1)) @@ -10448,8 +10062,7 @@ vectorizable_load (vec_info *vinfo, } } - if (slp_node - && slp_node->ldst_lanes + if (slp_node->ldst_lanes && memory_access_type != VMAT_LOAD_STORE_LANES) { if (dump_enabled_p ()) @@ -10500,8 +10113,7 @@ vectorizable_load (vec_info *vinfo, if (costing_p) /* transformation not required. */ { - if (slp_node - && mask + if (mask && !vect_maybe_update_slp_op_vectype (slp_op, mask_vectype)) { @@ -10511,10 +10123,7 @@ vectorizable_load (vec_info *vinfo, return false; } - if (!slp) - STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) = memory_access_type; - else - SLP_TREE_MEMORY_ACCESS_TYPE (slp_node) = memory_access_type; + SLP_TREE_MEMORY_ACCESS_TYPE (slp_node) = memory_access_type; if (loop_vinfo && LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo)) @@ -10568,16 +10177,10 @@ vectorizable_load (vec_info *vinfo, if (elsvals.length ()) maskload_elsval = *elsvals.begin (); - if (!slp) - gcc_assert (memory_access_type - == STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info)); - else - gcc_assert (memory_access_type - == SLP_TREE_MEMORY_ACCESS_TYPE (slp_node)); + gcc_assert (memory_access_type == SLP_TREE_MEMORY_ACCESS_TYPE (slp_node)); if (dump_enabled_p () && !costing_p) - dump_printf_loc (MSG_NOTE, vect_location, - "transform load. ncopies = %d\n", ncopies); + dump_printf_loc (MSG_NOTE, vect_location, "transform load.\n"); /* Transform. */ @@ -10647,15 +10250,8 @@ vectorizable_load (vec_info *vinfo, vectype, &gsi2); } gimple *new_stmt = SSA_NAME_DEF_STMT (new_temp); - if (slp) - for (j = 0; j < (int) SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); ++j) - slp_node->push_vec_def (new_stmt); - else - { - for (j = 0; j < ncopies; ++j) - STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); - *vec_stmt = new_stmt; - } + for (j = 0; j < (int) SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); ++j) + slp_node->push_vec_def (new_stmt); return true; } @@ -10832,6 +10428,7 @@ vectorizable_load (vec_info *vinfo, /* For SLP permutation support we need to load the whole group, not only the number of vector stmts the permutation result fits in. */ + int ncopies; if (slp_perm) { /* We don't yet generate SLP_TREE_LOAD_PERMUTATIONs for @@ -10973,12 +10570,11 @@ vectorizable_load (vec_info *vinfo, return true; } - if (memory_access_type == VMAT_GATHER_SCATTER - || (!slp && memory_access_type == VMAT_CONTIGUOUS)) + if (memory_access_type == VMAT_GATHER_SCATTER) grouped_load = false; if (grouped_load - || (slp && SLP_TREE_LOAD_PERMUTATION (slp_node).exists ())) + || SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()) { if (grouped_load) { @@ -10992,7 +10588,7 @@ vectorizable_load (vec_info *vinfo, } /* For SLP vectorization we directly vectorize a subchain without permutation. */ - if (slp && ! SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()) + if (! SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()) first_stmt_info = SLP_TREE_SCALAR_STMTS (slp_node)[0]; /* For BB vectorization always use the first stmt to base the data ref pointer on. */ @@ -11000,60 +10596,39 @@ vectorizable_load (vec_info *vinfo, first_stmt_info_for_drptr = vect_find_first_scalar_stmt_in_slp (slp_node); - /* Check if the chain of loads is already vectorized. */ - if (STMT_VINFO_VEC_STMTS (first_stmt_info).exists () - /* For SLP we would need to copy over SLP_TREE_VEC_DEFS. - ??? But we can only do so if there is exactly one - as we have no way to get at the rest. Leave the CSE - opportunity alone. - ??? With the group load eventually participating - in multiple different permutations (having multiple - slp nodes which refer to the same group) the CSE - is even wrong code. See PR56270. */ - && !slp) - { - *vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info)[0]; - return true; - } first_dr_info = STMT_VINFO_DR_INFO (first_stmt_info); group_gap_adj = 0; /* VEC_NUM is the number of vect stmts to be created for this group. */ - if (slp) - { - grouped_load = false; - /* If an SLP permutation is from N elements to N elements, - and if one vector holds a whole number of N, we can load - the inputs to the permutation in the same way as an - unpermuted sequence. In other cases we need to load the - whole group, not only the number of vector stmts the - permutation result fits in. */ - unsigned scalar_lanes = SLP_TREE_LANES (slp_node); - if (nested_in_vect_loop) - /* We do not support grouped accesses in a nested loop, - instead the access is contiguous but it might be - permuted. No gap adjustment is needed though. */ - vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); - else if (slp_perm - && (group_size != scalar_lanes - || !multiple_p (nunits, group_size))) - { - /* We don't yet generate such SLP_TREE_LOAD_PERMUTATIONs for - variable VF; see vect_transform_slp_perm_load. */ - unsigned int const_vf = vf.to_constant (); - unsigned int const_nunits = nunits.to_constant (); - vec_num = CEIL (group_size * const_vf, const_nunits); - group_gap_adj = vf * group_size - nunits * vec_num; - } - else - { - vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); - group_gap_adj - = group_size - scalar_lanes; - } - } + grouped_load = false; + /* If an SLP permutation is from N elements to N elements, + and if one vector holds a whole number of N, we can load + the inputs to the permutation in the same way as an + unpermuted sequence. In other cases we need to load the + whole group, not only the number of vector stmts the + permutation result fits in. */ + unsigned scalar_lanes = SLP_TREE_LANES (slp_node); + if (nested_in_vect_loop) + /* We do not support grouped accesses in a nested loop, + instead the access is contiguous but it might be + permuted. No gap adjustment is needed though. */ + vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); + else if (slp_perm + && (group_size != scalar_lanes + || !multiple_p (nunits, group_size))) + { + /* We don't yet generate such SLP_TREE_LOAD_PERMUTATIONs for + variable VF; see vect_transform_slp_perm_load. */ + unsigned int const_vf = vf.to_constant (); + unsigned int const_nunits = nunits.to_constant (); + vec_num = CEIL (group_size * const_vf, const_nunits); + group_gap_adj = vf * group_size - nunits * vec_num; + } else - vec_num = group_size; + { + vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); + group_gap_adj = group_size - scalar_lanes; + } ref_type = get_group_alias_ptr_type (first_stmt_info); } @@ -11064,8 +10639,7 @@ vectorizable_load (vec_info *vinfo, group_size = vec_num = 1; group_gap_adj = 0; ref_type = reference_alias_ptr_type (DR_REF (first_dr_info->dr)); - if (slp) - vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); + vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); } gcc_assert (alignment_support_scheme); @@ -11267,14 +10841,8 @@ vectorizable_load (vec_info *vinfo, auto_vec vec_offsets; auto_vec vec_masks; if (mask && !costing_p) - { - if (slp_node) - vect_get_slp_defs (SLP_TREE_CHILDREN (slp_node)[mask_index], - &vec_masks); - else - vect_get_vec_defs_for_operand (vinfo, stmt_info, ncopies, mask, - &vec_masks, mask_vectype); - } + vect_get_slp_defs (SLP_TREE_CHILDREN (slp_node)[mask_index], + &vec_masks); tree vec_mask = NULL_TREE; tree vec_els = NULL_TREE; @@ -11287,8 +10855,7 @@ vectorizable_load (vec_info *vinfo, /* For costing some adjacent vector loads, we'd like to cost with the total number of them once instead of cost each one by one. */ unsigned int n_adjacent_loads = 0; - if (slp_node) - ncopies = slp_node->vec_stmts_size / group_size; + int ncopies = slp_node->vec_stmts_size / group_size; for (j = 0; j < ncopies; j++) { if (costing_p) @@ -11411,33 +10978,18 @@ vectorizable_load (vec_info *vinfo, gimple_call_set_nothrow (call, true); vect_finish_stmt_generation (vinfo, stmt_info, call, gsi); - if (!slp) - dr_chain.create (group_size); /* Extract each vector into an SSA_NAME. */ for (unsigned i = 0; i < group_size; i++) { new_temp = read_vector_array (vinfo, stmt_info, gsi, scalar_dest, vec_array, i, need_zeroing, final_mask); - if (slp) - slp_node->push_vec_def (new_temp); - else - dr_chain.quick_push (new_temp); + slp_node->push_vec_def (new_temp); } - if (!slp) - /* Record the mapping between SSA_NAMEs and statements. */ - vect_record_grouped_load_vectors (vinfo, stmt_info, dr_chain); - /* Record that VEC_ARRAY is now dead. */ vect_clobber_variable (vinfo, stmt_info, gsi, vec_array); - - if (!slp) - dr_chain.release (); - - if (!slp_node) - *vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info)[0]; - } + } if (costing_p) { @@ -11463,365 +11015,329 @@ vectorizable_load (vec_info *vinfo, gcc_assert (!grouped_load && !slp_perm); unsigned int inside_cost = 0, prologue_cost = 0; - for (j = 0; j < ncopies; j++) + + /* 1. Create the vector or array pointer update chain. */ + if (!costing_p) { - /* 1. Create the vector or array pointer update chain. */ - if (j == 0 && !costing_p) - { - if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)) - vect_get_gather_scatter_ops (loop_vinfo, loop, stmt_info, - slp_node, &gs_info, &dataref_ptr, - &vec_offsets); - else - dataref_ptr - = vect_create_data_ref_ptr (vinfo, first_stmt_info, aggr_type, - at_loop, offset, &dummy, gsi, - &ptr_incr, false, bump); - } - else if (!costing_p) + if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)) + vect_get_gather_scatter_ops (loop_vinfo, loop, stmt_info, + slp_node, &gs_info, &dataref_ptr, + &vec_offsets); + else + dataref_ptr + = vect_create_data_ref_ptr (vinfo, first_stmt_info, aggr_type, + at_loop, offset, &dummy, gsi, + &ptr_incr, false, bump); + } + + gimple *new_stmt = NULL; + for (i = 0; i < vec_num; i++) + { + tree final_mask = NULL_TREE; + tree final_len = NULL_TREE; + tree bias = NULL_TREE; + if (!costing_p) { - gcc_assert (!LOOP_VINFO_USING_SELECT_VL_P (loop_vinfo)); - if (!STMT_VINFO_GATHER_SCATTER_P (stmt_info)) + if (mask) + vec_mask = vec_masks[i]; + if (loop_masks) + final_mask = vect_get_loop_mask (loop_vinfo, gsi, loop_masks, + vec_num, vectype, i); + if (vec_mask) + final_mask = prepare_vec_mask (loop_vinfo, mask_vectype, + final_mask, vec_mask, gsi); + + if (i > 0 && !STMT_VINFO_GATHER_SCATTER_P (stmt_info)) dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, gsi, stmt_info, bump); } - gimple *new_stmt = NULL; - for (i = 0; i < vec_num; i++) + /* 2. Create the vector-load in the loop. */ + unsigned HOST_WIDE_INT align; + if (gs_info.ifn != IFN_LAST) { - tree final_mask = NULL_TREE; - tree final_len = NULL_TREE; - tree bias = NULL_TREE; - if (!costing_p) + if (costing_p) { - if (mask) - vec_mask = vec_masks[vec_num * j + i]; - if (loop_masks) - final_mask - = vect_get_loop_mask (loop_vinfo, gsi, loop_masks, - vec_num * ncopies, vectype, - vec_num * j + i); - if (vec_mask) - final_mask = prepare_vec_mask (loop_vinfo, mask_vectype, - final_mask, vec_mask, gsi); - - if (i > 0 && !STMT_VINFO_GATHER_SCATTER_P (stmt_info)) - dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, - gsi, stmt_info, bump); + unsigned int cnunits = vect_nunits_for_cost (vectype); + inside_cost + = record_stmt_cost (cost_vec, cnunits, scalar_load, + slp_node, 0, vect_body); + continue; } + if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)) + vec_offset = vec_offsets[i]; + tree zero = build_zero_cst (vectype); + tree scale = size_int (gs_info.scale); - /* 2. Create the vector-load in the loop. */ - unsigned HOST_WIDE_INT align; - if (gs_info.ifn != IFN_LAST) + if (gs_info.ifn == IFN_MASK_LEN_GATHER_LOAD) { - if (costing_p) - { - unsigned int cnunits = vect_nunits_for_cost (vectype); - inside_cost - = record_stmt_cost (cost_vec, cnunits, scalar_load, - slp_node, 0, vect_body); - continue; - } - if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)) - vec_offset = vec_offsets[vec_num * j + i]; - tree zero = build_zero_cst (vectype); - tree scale = size_int (gs_info.scale); - - if (gs_info.ifn == IFN_MASK_LEN_GATHER_LOAD) + if (loop_lens) + final_len = vect_get_loop_len (loop_vinfo, gsi, loop_lens, + vec_num, vectype, i, 1); + else + final_len = build_int_cst (sizetype, + TYPE_VECTOR_SUBPARTS (vectype)); + signed char biasval + = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo); + bias = build_int_cst (intQI_type_node, biasval); + if (!final_mask) { - if (loop_lens) - final_len - = vect_get_loop_len (loop_vinfo, gsi, loop_lens, - vec_num * ncopies, vectype, - vec_num * j + i, 1); - else - final_len - = build_int_cst (sizetype, - TYPE_VECTOR_SUBPARTS (vectype)); - signed char biasval - = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo); - bias = build_int_cst (intQI_type_node, biasval); - if (!final_mask) - { - mask_vectype = truth_type_for (vectype); - final_mask = build_minus_one_cst (mask_vectype); - } + mask_vectype = truth_type_for (vectype); + final_mask = build_minus_one_cst (mask_vectype); } + } - if (final_mask) - { - vec_els = vect_get_mask_load_else - (maskload_elsval, vectype); - if (type_mode_padding_p - && maskload_elsval != MASK_LOAD_ELSE_ZERO) - need_zeroing = true; - } + if (final_mask) + { + vec_els = vect_get_mask_load_else (maskload_elsval, vectype); + if (type_mode_padding_p + && maskload_elsval != MASK_LOAD_ELSE_ZERO) + need_zeroing = true; + } - gcall *call; - if (final_len && final_mask) - { - if (VECTOR_TYPE_P (TREE_TYPE (vec_offset))) - call = gimple_build_call_internal ( - IFN_MASK_LEN_GATHER_LOAD, 8, dataref_ptr, vec_offset, - scale, zero, final_mask, vec_els, final_len, bias); - else - /* Non-vector offset indicates that prefer to take - MASK_LEN_STRIDED_LOAD instead of the - MASK_LEN_GATHER_LOAD with direct stride arg. */ - call = gimple_build_call_internal ( - IFN_MASK_LEN_STRIDED_LOAD, 7, dataref_ptr, vec_offset, - zero, final_mask, vec_els, final_len, bias); - } - else if (final_mask) - call = gimple_build_call_internal (IFN_MASK_GATHER_LOAD, - 6, dataref_ptr, - vec_offset, scale, - zero, final_mask, - vec_els); + gcall *call; + if (final_len && final_mask) + { + if (VECTOR_TYPE_P (TREE_TYPE (vec_offset))) + call = gimple_build_call_internal (IFN_MASK_LEN_GATHER_LOAD, + 8, dataref_ptr, + vec_offset, scale, zero, + final_mask, vec_els, + final_len, bias); else - call = gimple_build_call_internal (IFN_GATHER_LOAD, 4, - dataref_ptr, vec_offset, - scale, zero); - gimple_call_set_nothrow (call, true); - new_stmt = call; + /* Non-vector offset indicates that prefer to take + MASK_LEN_STRIDED_LOAD instead of the + MASK_LEN_GATHER_LOAD with direct stride arg. */ + call = gimple_build_call_internal + (IFN_MASK_LEN_STRIDED_LOAD, 7, dataref_ptr, + vec_offset, zero, final_mask, vec_els, final_len, + bias); + } + else if (final_mask) + call = gimple_build_call_internal (IFN_MASK_GATHER_LOAD, + 6, dataref_ptr, + vec_offset, scale, + zero, final_mask, vec_els); + else + call = gimple_build_call_internal (IFN_GATHER_LOAD, 4, + dataref_ptr, vec_offset, + scale, zero); + gimple_call_set_nothrow (call, true); + new_stmt = call; + data_ref = NULL_TREE; + } + else if (gs_info.decl) + { + /* The builtin decls path for gather is legacy, x86 only. */ + gcc_assert (!final_len && nunits.is_constant ()); + if (costing_p) + { + unsigned int cnunits = vect_nunits_for_cost (vectype); + inside_cost + = record_stmt_cost (cost_vec, cnunits, scalar_load, + slp_node, 0, vect_body); + continue; + } + poly_uint64 offset_nunits + = TYPE_VECTOR_SUBPARTS (gs_info.offset_vectype); + if (known_eq (nunits, offset_nunits)) + { + new_stmt = vect_build_one_gather_load_call + (vinfo, stmt_info, gsi, &gs_info, + dataref_ptr, vec_offsets[i], final_mask); data_ref = NULL_TREE; } - else if (gs_info.decl) + else if (known_eq (nunits, offset_nunits * 2)) { - /* The builtin decls path for gather is legacy, x86 only. */ - gcc_assert (!final_len && nunits.is_constant ()); - if (costing_p) - { - unsigned int cnunits = vect_nunits_for_cost (vectype); - inside_cost - = record_stmt_cost (cost_vec, cnunits, scalar_load, - slp_node, 0, vect_body); - continue; - } - poly_uint64 offset_nunits - = TYPE_VECTOR_SUBPARTS (gs_info.offset_vectype); - if (known_eq (nunits, offset_nunits)) + /* We have a offset vector with half the number of + lanes but the builtins will produce full vectype + data with just the lower lanes filled. */ + new_stmt = vect_build_one_gather_load_call + (vinfo, stmt_info, gsi, &gs_info, + dataref_ptr, vec_offsets[2 * i], final_mask); + tree low = make_ssa_name (vectype); + gimple_set_lhs (new_stmt, low); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); + + /* now put upper half of final_mask in final_mask low. */ + if (final_mask + && !SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (final_mask)))) { - new_stmt = vect_build_one_gather_load_call - (vinfo, stmt_info, gsi, &gs_info, - dataref_ptr, vec_offsets[vec_num * j + i], - final_mask); - data_ref = NULL_TREE; + int count = nunits.to_constant (); + vec_perm_builder sel (count, count, 1); + sel.quick_grow (count); + for (int i = 0; i < count; ++i) + sel[i] = i | (count / 2); + vec_perm_indices indices (sel, 2, count); + tree perm_mask = vect_gen_perm_mask_checked + (TREE_TYPE (final_mask), indices); + new_stmt = gimple_build_assign (NULL_TREE, VEC_PERM_EXPR, + final_mask, final_mask, + perm_mask); + final_mask = make_ssa_name (TREE_TYPE (final_mask)); + gimple_set_lhs (new_stmt, final_mask); + vect_finish_stmt_generation (vinfo, stmt_info, + new_stmt, gsi); } - else if (known_eq (nunits, offset_nunits * 2)) + else if (final_mask) { - /* We have a offset vector with half the number of - lanes but the builtins will produce full vectype - data with just the lower lanes filled. */ - new_stmt = vect_build_one_gather_load_call - (vinfo, stmt_info, gsi, &gs_info, - dataref_ptr, vec_offsets[2 * vec_num * j + 2 * i], - final_mask); - tree low = make_ssa_name (vectype); - gimple_set_lhs (new_stmt, low); + new_stmt = gimple_build_assign (NULL_TREE, + VEC_UNPACK_HI_EXPR, + final_mask); + final_mask = make_ssa_name + (truth_type_for (gs_info.offset_vectype)); + gimple_set_lhs (new_stmt, final_mask); vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); + } - /* now put upper half of final_mask in final_mask low. */ - if (final_mask - && !SCALAR_INT_MODE_P - (TYPE_MODE (TREE_TYPE (final_mask)))) - { - int count = nunits.to_constant (); - vec_perm_builder sel (count, count, 1); - sel.quick_grow (count); - for (int i = 0; i < count; ++i) - sel[i] = i | (count / 2); - vec_perm_indices indices (sel, 2, count); - tree perm_mask = vect_gen_perm_mask_checked - (TREE_TYPE (final_mask), indices); - new_stmt = gimple_build_assign (NULL_TREE, - VEC_PERM_EXPR, - final_mask, - final_mask, - perm_mask); - final_mask = make_ssa_name (TREE_TYPE (final_mask)); - gimple_set_lhs (new_stmt, final_mask); - vect_finish_stmt_generation (vinfo, stmt_info, - new_stmt, gsi); - } - else if (final_mask) - { - new_stmt = gimple_build_assign (NULL_TREE, - VEC_UNPACK_HI_EXPR, - final_mask); - final_mask = make_ssa_name - (truth_type_for (gs_info.offset_vectype)); - gimple_set_lhs (new_stmt, final_mask); - vect_finish_stmt_generation (vinfo, stmt_info, - new_stmt, gsi); - } - - new_stmt = vect_build_one_gather_load_call - (vinfo, stmt_info, gsi, &gs_info, - dataref_ptr, - vec_offsets[2 * vec_num * j + 2 * i + 1], - final_mask); - tree high = make_ssa_name (vectype); - gimple_set_lhs (new_stmt, high); - vect_finish_stmt_generation (vinfo, stmt_info, - new_stmt, gsi); + new_stmt = vect_build_one_gather_load_call + (vinfo, stmt_info, gsi, &gs_info, dataref_ptr, + vec_offsets[2 * i + 1], final_mask); + tree high = make_ssa_name (vectype); + gimple_set_lhs (new_stmt, high); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); - /* compose low + high. */ - int count = nunits.to_constant (); + /* compose low + high. */ + int count = nunits.to_constant (); + vec_perm_builder sel (count, count, 1); + sel.quick_grow (count); + for (int i = 0; i < count; ++i) + sel[i] = i < count / 2 ? i : i + count / 2; + vec_perm_indices indices (sel, 2, count); + tree perm_mask + = vect_gen_perm_mask_checked (vectype, indices); + new_stmt = gimple_build_assign (NULL_TREE, VEC_PERM_EXPR, + low, high, perm_mask); + data_ref = NULL_TREE; + } + else if (known_eq (nunits * 2, offset_nunits)) + { + /* We have a offset vector with double the number of + lanes. Select the low/high part accordingly. */ + vec_offset = vec_offsets[i / 2]; + if (i & 1) + { + int count = offset_nunits.to_constant (); vec_perm_builder sel (count, count, 1); sel.quick_grow (count); for (int i = 0; i < count; ++i) - sel[i] = i < count / 2 ? i : i + count / 2; + sel[i] = i | (count / 2); vec_perm_indices indices (sel, 2, count); - tree perm_mask - = vect_gen_perm_mask_checked (vectype, indices); - new_stmt = gimple_build_assign (NULL_TREE, - VEC_PERM_EXPR, - low, high, perm_mask); - data_ref = NULL_TREE; - } - else if (known_eq (nunits * 2, offset_nunits)) - { - /* We have a offset vector with double the number of - lanes. Select the low/high part accordingly. */ - vec_offset = vec_offsets[(vec_num * j + i) / 2]; - if ((vec_num * j + i) & 1) - { - int count = offset_nunits.to_constant (); - vec_perm_builder sel (count, count, 1); - sel.quick_grow (count); - for (int i = 0; i < count; ++i) - sel[i] = i | (count / 2); - vec_perm_indices indices (sel, 2, count); - tree perm_mask = vect_gen_perm_mask_checked - (TREE_TYPE (vec_offset), indices); - new_stmt = gimple_build_assign (NULL_TREE, - VEC_PERM_EXPR, - vec_offset, - vec_offset, - perm_mask); - vec_offset = make_ssa_name (TREE_TYPE (vec_offset)); - gimple_set_lhs (new_stmt, vec_offset); - vect_finish_stmt_generation (vinfo, stmt_info, - new_stmt, gsi); - } - new_stmt = vect_build_one_gather_load_call - (vinfo, stmt_info, gsi, &gs_info, - dataref_ptr, vec_offset, final_mask); - data_ref = NULL_TREE; + tree perm_mask = vect_gen_perm_mask_checked + (TREE_TYPE (vec_offset), indices); + new_stmt = gimple_build_assign (NULL_TREE, VEC_PERM_EXPR, + vec_offset, vec_offset, + perm_mask); + vec_offset = make_ssa_name (TREE_TYPE (vec_offset)); + gimple_set_lhs (new_stmt, vec_offset); + vect_finish_stmt_generation (vinfo, stmt_info, + new_stmt, gsi); } - else - gcc_unreachable (); + new_stmt = vect_build_one_gather_load_call + (vinfo, stmt_info, gsi, &gs_info, + dataref_ptr, vec_offset, final_mask); + data_ref = NULL_TREE; } else + gcc_unreachable (); + } + else + { + /* Emulated gather-scatter. */ + gcc_assert (!final_mask); + unsigned HOST_WIDE_INT const_nunits = nunits.to_constant (); + if (costing_p) { - /* Emulated gather-scatter. */ - gcc_assert (!final_mask); - unsigned HOST_WIDE_INT const_nunits = nunits.to_constant (); - if (costing_p) - { - /* For emulated gathers N offset vector element - offset add is consumed by the load). */ - inside_cost = record_stmt_cost (cost_vec, const_nunits, - vec_to_scalar, - slp_node, 0, vect_body); - /* N scalar loads plus gathering them into a - vector. */ - inside_cost - = record_stmt_cost (cost_vec, const_nunits, scalar_load, - slp_node, 0, vect_body); - inside_cost - = record_stmt_cost (cost_vec, 1, vec_construct, - slp_node, 0, vect_body); - continue; - } - unsigned HOST_WIDE_INT const_offset_nunits - = TYPE_VECTOR_SUBPARTS (gs_info.offset_vectype) - .to_constant (); - vec *ctor_elts; - vec_alloc (ctor_elts, const_nunits); - gimple_seq stmts = NULL; - /* We support offset vectors with more elements - than the data vector for now. */ - unsigned HOST_WIDE_INT factor - = const_offset_nunits / const_nunits; - vec_offset = vec_offsets[(vec_num * j + i) / factor]; - unsigned elt_offset - = ((vec_num * j + i) % factor) * const_nunits; - tree idx_type = TREE_TYPE (TREE_TYPE (vec_offset)); - tree scale = size_int (gs_info.scale); - align = get_object_alignment (DR_REF (first_dr_info->dr)); - tree ltype = build_aligned_type (TREE_TYPE (vectype), align); - for (unsigned k = 0; k < const_nunits; ++k) - { - tree boff = size_binop (MULT_EXPR, TYPE_SIZE (idx_type), - bitsize_int (k + elt_offset)); - tree idx - = gimple_build (&stmts, BIT_FIELD_REF, idx_type, - vec_offset, TYPE_SIZE (idx_type), boff); - idx = gimple_convert (&stmts, sizetype, idx); - idx = gimple_build (&stmts, MULT_EXPR, sizetype, idx, - scale); - tree ptr = gimple_build (&stmts, PLUS_EXPR, - TREE_TYPE (dataref_ptr), - dataref_ptr, idx); - ptr = gimple_convert (&stmts, ptr_type_node, ptr); - tree elt = make_ssa_name (TREE_TYPE (vectype)); - tree ref = build2 (MEM_REF, ltype, ptr, - build_int_cst (ref_type, 0)); - new_stmt = gimple_build_assign (elt, ref); - gimple_set_vuse (new_stmt, gimple_vuse (gsi_stmt (*gsi))); - gimple_seq_add_stmt (&stmts, new_stmt); - CONSTRUCTOR_APPEND_ELT (ctor_elts, NULL_TREE, elt); - } - gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); - new_stmt = gimple_build_assign ( - NULL_TREE, build_constructor (vectype, ctor_elts)); - data_ref = NULL_TREE; + /* For emulated gathers N offset vector element + offset add is consumed by the load). */ + inside_cost = record_stmt_cost (cost_vec, const_nunits, + vec_to_scalar, + slp_node, 0, vect_body); + /* N scalar loads plus gathering them into a + vector. */ + inside_cost + = record_stmt_cost (cost_vec, const_nunits, scalar_load, + slp_node, 0, vect_body); + inside_cost + = record_stmt_cost (cost_vec, 1, vec_construct, + slp_node, 0, vect_body); + continue; } - - vec_dest = vect_create_destination_var (scalar_dest, vectype); - /* DATA_REF is null if we've already built the statement. */ - if (data_ref) + unsigned HOST_WIDE_INT const_offset_nunits + = TYPE_VECTOR_SUBPARTS (gs_info.offset_vectype) .to_constant (); + vec *ctor_elts; + vec_alloc (ctor_elts, const_nunits); + gimple_seq stmts = NULL; + /* We support offset vectors with more elements + than the data vector for now. */ + unsigned HOST_WIDE_INT factor + = const_offset_nunits / const_nunits; + vec_offset = vec_offsets[i / factor]; + unsigned elt_offset = (i % factor) * const_nunits; + tree idx_type = TREE_TYPE (TREE_TYPE (vec_offset)); + tree scale = size_int (gs_info.scale); + align = get_object_alignment (DR_REF (first_dr_info->dr)); + tree ltype = build_aligned_type (TREE_TYPE (vectype), align); + for (unsigned k = 0; k < const_nunits; ++k) { - vect_copy_ref_info (data_ref, DR_REF (first_dr_info->dr)); - new_stmt = gimple_build_assign (vec_dest, data_ref); + tree boff = size_binop (MULT_EXPR, TYPE_SIZE (idx_type), + bitsize_int (k + elt_offset)); + tree idx = gimple_build (&stmts, BIT_FIELD_REF, idx_type, + vec_offset, TYPE_SIZE (idx_type), + boff); + idx = gimple_convert (&stmts, sizetype, idx); + idx = gimple_build (&stmts, MULT_EXPR, sizetype, idx, scale); + tree ptr = gimple_build (&stmts, PLUS_EXPR, + TREE_TYPE (dataref_ptr), + dataref_ptr, idx); + ptr = gimple_convert (&stmts, ptr_type_node, ptr); + tree elt = make_ssa_name (TREE_TYPE (vectype)); + tree ref = build2 (MEM_REF, ltype, ptr, + build_int_cst (ref_type, 0)); + new_stmt = gimple_build_assign (elt, ref); + gimple_set_vuse (new_stmt, gimple_vuse (gsi_stmt (*gsi))); + gimple_seq_add_stmt (&stmts, new_stmt); + CONSTRUCTOR_APPEND_ELT (ctor_elts, NULL_TREE, elt); } - new_temp = need_zeroing - ? make_ssa_name (vectype) - : make_ssa_name (vec_dest, new_stmt); - gimple_set_lhs (new_stmt, new_temp); - vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); + gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); + new_stmt = gimple_build_assign (NULL_TREE, + build_constructor (vectype, + ctor_elts)); + data_ref = NULL_TREE; + } - /* If we need to explicitly zero inactive elements emit a - VEC_COND_EXPR that does so. */ - if (need_zeroing) - { - vec_els = vect_get_mask_load_else (MASK_LOAD_ELSE_ZERO, - vectype); + vec_dest = vect_create_destination_var (scalar_dest, vectype); + /* DATA_REF is null if we've already built the statement. */ + if (data_ref) + { + vect_copy_ref_info (data_ref, DR_REF (first_dr_info->dr)); + new_stmt = gimple_build_assign (vec_dest, data_ref); + } + new_temp = (need_zeroing + ? make_ssa_name (vectype) + : make_ssa_name (vec_dest, new_stmt)); + gimple_set_lhs (new_stmt, new_temp); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); - tree new_temp2 = make_ssa_name (vec_dest, new_stmt); - new_stmt - = gimple_build_assign (new_temp2, VEC_COND_EXPR, - final_mask, new_temp, vec_els); - vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, - gsi); - new_temp = new_temp2; - } + /* If we need to explicitly zero inactive elements emit a + VEC_COND_EXPR that does so. */ + if (need_zeroing) + { + vec_els = vect_get_mask_load_else (MASK_LOAD_ELSE_ZERO, + vectype); - /* Store vector loads in the corresponding SLP_NODE. */ - if (slp) - slp_node->push_vec_def (new_stmt); + tree new_temp2 = make_ssa_name (vec_dest, new_stmt); + new_stmt = gimple_build_assign (new_temp2, VEC_COND_EXPR, + final_mask, new_temp, vec_els); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); + new_temp = new_temp2; } - if (!slp && !costing_p) - STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); + /* Store vector loads in the corresponding SLP_NODE. */ + slp_node->push_vec_def (new_stmt); } - if (!slp && !costing_p) - *vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info)[0]; - if (costing_p && dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "vect_model_load_cost: inside_cost = %u, " @@ -11835,273 +11351,293 @@ vectorizable_load (vec_info *vinfo, /* For costing some adjacent vector loads, we'd like to cost with the total number of them once instead of cost each one by one. */ unsigned int n_adjacent_loads = 0; - for (j = 0; j < ncopies; j++) - { - /* 1. Create the vector or array pointer update chain. */ - if (j == 0 && !costing_p) - { - bool simd_lane_access_p - = STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info) != 0; - if (simd_lane_access_p - && TREE_CODE (DR_BASE_ADDRESS (first_dr_info->dr)) == ADDR_EXPR - && VAR_P (TREE_OPERAND (DR_BASE_ADDRESS (first_dr_info->dr), 0)) - && integer_zerop (get_dr_vinfo_offset (vinfo, first_dr_info)) - && integer_zerop (DR_INIT (first_dr_info->dr)) - && alias_sets_conflict_p (get_alias_set (aggr_type), - get_alias_set (TREE_TYPE (ref_type))) - && (alignment_support_scheme == dr_aligned - || alignment_support_scheme == dr_unaligned_supported)) - { - dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr_info->dr)); - dataref_offset = build_int_cst (ref_type, 0); - } - else if (diff_first_stmt_info) - { - dataref_ptr - = vect_create_data_ref_ptr (vinfo, first_stmt_info_for_drptr, - aggr_type, at_loop, offset, &dummy, - gsi, &ptr_incr, simd_lane_access_p, - bump); - /* Adjust the pointer by the difference to first_stmt. */ - data_reference_p ptrdr - = STMT_VINFO_DATA_REF (first_stmt_info_for_drptr); - tree diff - = fold_convert (sizetype, - size_binop (MINUS_EXPR, - DR_INIT (first_dr_info->dr), - DR_INIT (ptrdr))); - dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, gsi, - stmt_info, diff); - if (alignment_support_scheme == dr_explicit_realign) - { - msq = vect_setup_realignment (vinfo, - first_stmt_info_for_drptr, gsi, - &realignment_token, - alignment_support_scheme, - dataref_ptr, &at_loop); - gcc_assert (!compute_in_loop); - } + + /* 1. Create the vector or array pointer update chain. */ + if (!costing_p) + { + bool simd_lane_access_p + = STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info) != 0; + if (simd_lane_access_p + && TREE_CODE (DR_BASE_ADDRESS (first_dr_info->dr)) == ADDR_EXPR + && VAR_P (TREE_OPERAND (DR_BASE_ADDRESS (first_dr_info->dr), 0)) + && integer_zerop (get_dr_vinfo_offset (vinfo, first_dr_info)) + && integer_zerop (DR_INIT (first_dr_info->dr)) + && alias_sets_conflict_p (get_alias_set (aggr_type), + get_alias_set (TREE_TYPE (ref_type))) + && (alignment_support_scheme == dr_aligned + || alignment_support_scheme == dr_unaligned_supported)) + { + dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr_info->dr)); + dataref_offset = build_int_cst (ref_type, 0); + } + else if (diff_first_stmt_info) + { + dataref_ptr + = vect_create_data_ref_ptr (vinfo, first_stmt_info_for_drptr, + aggr_type, at_loop, offset, &dummy, + gsi, &ptr_incr, simd_lane_access_p, + bump); + /* Adjust the pointer by the difference to first_stmt. */ + data_reference_p ptrdr + = STMT_VINFO_DATA_REF (first_stmt_info_for_drptr); + tree diff = fold_convert (sizetype, + size_binop (MINUS_EXPR, + DR_INIT (first_dr_info->dr), + DR_INIT (ptrdr))); + dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, gsi, + stmt_info, diff); + if (alignment_support_scheme == dr_explicit_realign) + { + msq = vect_setup_realignment (vinfo, + first_stmt_info_for_drptr, gsi, + &realignment_token, + alignment_support_scheme, + dataref_ptr, &at_loop); + gcc_assert (!compute_in_loop); } - else - dataref_ptr - = vect_create_data_ref_ptr (vinfo, first_stmt_info, aggr_type, - at_loop, - offset, &dummy, gsi, &ptr_incr, - simd_lane_access_p, bump); - } - else if (!costing_p) - { - gcc_assert (!LOOP_VINFO_USING_SELECT_VL_P (loop_vinfo)); - if (dataref_offset) - dataref_offset = int_const_binop (PLUS_EXPR, dataref_offset, - bump); - else - dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, gsi, - stmt_info, bump); } + else + dataref_ptr + = vect_create_data_ref_ptr (vinfo, first_stmt_info, aggr_type, + at_loop, + offset, &dummy, gsi, &ptr_incr, + simd_lane_access_p, bump); + } + else if (!costing_p) + { + gcc_assert (!LOOP_VINFO_USING_SELECT_VL_P (loop_vinfo)); + if (dataref_offset) + dataref_offset = int_const_binop (PLUS_EXPR, dataref_offset, bump); + else + dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, gsi, + stmt_info, bump); + } - if (grouped_load || slp_perm) - dr_chain.create (vec_num); + if (grouped_load || slp_perm) + dr_chain.create (vec_num); - gimple *new_stmt = NULL; - for (i = 0; i < vec_num; i++) + gimple *new_stmt = NULL; + for (i = 0; i < vec_num; i++) + { + tree final_mask = NULL_TREE; + tree final_len = NULL_TREE; + tree bias = NULL_TREE; + + if (!costing_p) { - tree final_mask = NULL_TREE; - tree final_len = NULL_TREE; - tree bias = NULL_TREE; + if (mask) + vec_mask = vec_masks[i]; + if (loop_masks) + final_mask = vect_get_loop_mask (loop_vinfo, gsi, loop_masks, + vec_num, vectype, i); + if (vec_mask) + final_mask = prepare_vec_mask (loop_vinfo, mask_vectype, + final_mask, vec_mask, gsi); - if (!costing_p) - { - if (mask) - vec_mask = vec_masks[vec_num * j + i]; - if (loop_masks) - final_mask = vect_get_loop_mask (loop_vinfo, gsi, loop_masks, - vec_num * ncopies, vectype, - vec_num * j + i); - if (vec_mask) - final_mask = prepare_vec_mask (loop_vinfo, mask_vectype, - final_mask, vec_mask, gsi); + if (i > 0) + dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, + gsi, stmt_info, bump); + } - if (i > 0) - dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, - gsi, stmt_info, bump); - } + /* 2. Create the vector-load in the loop. */ + switch (alignment_support_scheme) + { + case dr_aligned: + case dr_unaligned_supported: + { + if (costing_p) + break; - /* 2. Create the vector-load in the loop. */ - switch (alignment_support_scheme) - { - case dr_aligned: - case dr_unaligned_supported: + unsigned int misalign; + unsigned HOST_WIDE_INT align; + align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info)); + if (alignment_support_scheme == dr_aligned) + misalign = 0; + else if (misalignment == DR_MISALIGNMENT_UNKNOWN) { - if (costing_p) - break; - - unsigned int misalign; - unsigned HOST_WIDE_INT align; - align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info)); - if (alignment_support_scheme == dr_aligned) - misalign = 0; - else if (misalignment == DR_MISALIGNMENT_UNKNOWN) - { - align - = dr_alignment (vect_dr_behavior (vinfo, first_dr_info)); - misalign = 0; - } - else - misalign = misalignment; - if (dataref_offset == NULL_TREE - && TREE_CODE (dataref_ptr) == SSA_NAME) - set_ptr_info_alignment (get_ptr_info (dataref_ptr), align, - misalign); - align = least_bit_hwi (misalign | align); - - /* Compute IFN when LOOP_LENS or final_mask valid. */ - machine_mode vmode = TYPE_MODE (vectype); - machine_mode new_vmode = vmode; - internal_fn partial_ifn = IFN_LAST; - if (loop_lens) - { - opt_machine_mode new_ovmode - = get_len_load_store_mode (vmode, true, &partial_ifn); - new_vmode = new_ovmode.require (); - unsigned factor - = (new_ovmode == vmode) ? 1 : GET_MODE_UNIT_SIZE (vmode); - final_len = vect_get_loop_len (loop_vinfo, gsi, loop_lens, - vec_num * ncopies, vectype, - vec_num * j + i, factor); - } - else if (final_mask) - { - if (!can_vec_mask_load_store_p ( - vmode, TYPE_MODE (TREE_TYPE (final_mask)), true, - &partial_ifn)) - gcc_unreachable (); - } + align = dr_alignment (vect_dr_behavior (vinfo, first_dr_info)); + misalign = 0; + } + else + misalign = misalignment; + if (dataref_offset == NULL_TREE + && TREE_CODE (dataref_ptr) == SSA_NAME) + set_ptr_info_alignment (get_ptr_info (dataref_ptr), align, + misalign); + align = least_bit_hwi (misalign | align); + + /* Compute IFN when LOOP_LENS or final_mask valid. */ + machine_mode vmode = TYPE_MODE (vectype); + machine_mode new_vmode = vmode; + internal_fn partial_ifn = IFN_LAST; + if (loop_lens) + { + opt_machine_mode new_ovmode + = get_len_load_store_mode (vmode, true, &partial_ifn); + new_vmode = new_ovmode.require (); + unsigned factor + = (new_ovmode == vmode) ? 1 : GET_MODE_UNIT_SIZE (vmode); + final_len = vect_get_loop_len (loop_vinfo, gsi, loop_lens, + vec_num, vectype, i, factor); + } + else if (final_mask) + { + if (!can_vec_mask_load_store_p (vmode, + TYPE_MODE + (TREE_TYPE (final_mask)), + true, &partial_ifn)) + gcc_unreachable (); + } - if (partial_ifn == IFN_MASK_LEN_LOAD) + if (partial_ifn == IFN_MASK_LEN_LOAD) + { + if (!final_len) { - if (!final_len) - { - /* Pass VF value to 'len' argument of - MASK_LEN_LOAD if LOOP_LENS is invalid. */ - final_len = size_int (TYPE_VECTOR_SUBPARTS (vectype)); - } - if (!final_mask) - { - /* Pass all ones value to 'mask' argument of - MASK_LEN_LOAD if final_mask is invalid. */ - mask_vectype = truth_type_for (vectype); - final_mask = build_minus_one_cst (mask_vectype); - } + /* Pass VF value to 'len' argument of + MASK_LEN_LOAD if LOOP_LENS is invalid. */ + final_len = size_int (TYPE_VECTOR_SUBPARTS (vectype)); } - if (final_len) + if (!final_mask) { - signed char biasval - = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo); - - bias = build_int_cst (intQI_type_node, biasval); + /* Pass all ones value to 'mask' argument of + MASK_LEN_LOAD if final_mask is invalid. */ + mask_vectype = truth_type_for (vectype); + final_mask = build_minus_one_cst (mask_vectype); } + } + if (final_len) + { + signed char biasval + = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo); + bias = build_int_cst (intQI_type_node, biasval); + } - tree vec_els; + tree vec_els; - if (final_len) - { - tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT); - gcall *call; - if (partial_ifn == IFN_MASK_LEN_LOAD) - { - vec_els = vect_get_mask_load_else - (maskload_elsval, vectype); - if (type_mode_padding_p - && maskload_elsval != MASK_LOAD_ELSE_ZERO) - need_zeroing = true; - call = gimple_build_call_internal (IFN_MASK_LEN_LOAD, - 6, dataref_ptr, ptr, - final_mask, vec_els, - final_len, bias); - } - else - call = gimple_build_call_internal (IFN_LEN_LOAD, 4, - dataref_ptr, ptr, - final_len, bias); - gimple_call_set_nothrow (call, true); - new_stmt = call; - data_ref = NULL_TREE; - - /* Need conversion if it's wrapped with VnQI. */ - if (vmode != new_vmode) - { - tree new_vtype = build_vector_type_for_mode ( - unsigned_intQI_type_node, new_vmode); - tree var - = vect_get_new_ssa_name (new_vtype, vect_simple_var); - gimple_set_lhs (call, var); - vect_finish_stmt_generation (vinfo, stmt_info, call, - gsi); - tree op = build1 (VIEW_CONVERT_EXPR, vectype, var); - new_stmt = gimple_build_assign (vec_dest, - VIEW_CONVERT_EXPR, op); - } - } - else if (final_mask) + if (final_len) + { + tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT); + gcall *call; + if (partial_ifn == IFN_MASK_LEN_LOAD) { - tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT); - vec_els = vect_get_mask_load_else - (maskload_elsval, vectype); + vec_els = vect_get_mask_load_else (maskload_elsval, + vectype); if (type_mode_padding_p && maskload_elsval != MASK_LOAD_ELSE_ZERO) need_zeroing = true; - gcall *call = gimple_build_call_internal (IFN_MASK_LOAD, 4, - dataref_ptr, ptr, - final_mask, - vec_els); - gimple_call_set_nothrow (call, true); - new_stmt = call; - data_ref = NULL_TREE; + call = gimple_build_call_internal (IFN_MASK_LEN_LOAD, + 6, dataref_ptr, ptr, + final_mask, vec_els, + final_len, bias); } else + call = gimple_build_call_internal (IFN_LEN_LOAD, 4, + dataref_ptr, ptr, + final_len, bias); + gimple_call_set_nothrow (call, true); + new_stmt = call; + data_ref = NULL_TREE; + + /* Need conversion if it's wrapped with VnQI. */ + if (vmode != new_vmode) { - tree ltype = vectype; - tree new_vtype = NULL_TREE; - unsigned HOST_WIDE_INT gap = DR_GROUP_GAP (first_stmt_info); - unsigned HOST_WIDE_INT dr_size - = vect_get_scalar_dr_size (first_dr_info); - poly_int64 off = 0; - if (memory_access_type == VMAT_CONTIGUOUS_REVERSE) - off = (TYPE_VECTOR_SUBPARTS (vectype) - 1) * -dr_size; - unsigned int vect_align - = vect_known_alignment_in_bytes (first_dr_info, vectype, - off); - /* Try to use a single smaller load when we are about - to load excess elements compared to the unrolled - scalar loop. */ - if (known_gt ((vec_num * j + i + 1) * nunits, - (group_size * vf - gap))) + tree new_vtype + = build_vector_type_for_mode (unsigned_intQI_type_node, + new_vmode); + tree var = vect_get_new_ssa_name (new_vtype, + vect_simple_var); + gimple_set_lhs (call, var); + vect_finish_stmt_generation (vinfo, stmt_info, call, + gsi); + tree op = build1 (VIEW_CONVERT_EXPR, vectype, var); + new_stmt = gimple_build_assign (vec_dest, + VIEW_CONVERT_EXPR, op); + } + } + else if (final_mask) + { + tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT); + vec_els = vect_get_mask_load_else (maskload_elsval, vectype); + if (type_mode_padding_p + && maskload_elsval != MASK_LOAD_ELSE_ZERO) + need_zeroing = true; + gcall *call = gimple_build_call_internal (IFN_MASK_LOAD, 4, + dataref_ptr, ptr, + final_mask, + vec_els); + gimple_call_set_nothrow (call, true); + new_stmt = call; + data_ref = NULL_TREE; + } + else + { + tree ltype = vectype; + tree new_vtype = NULL_TREE; + unsigned HOST_WIDE_INT gap = DR_GROUP_GAP (first_stmt_info); + unsigned HOST_WIDE_INT dr_size + = vect_get_scalar_dr_size (first_dr_info); + poly_int64 off = 0; + if (memory_access_type == VMAT_CONTIGUOUS_REVERSE) + off = (TYPE_VECTOR_SUBPARTS (vectype) - 1) * -dr_size; + unsigned int vect_align + = vect_known_alignment_in_bytes (first_dr_info, vectype, + off); + /* Try to use a single smaller load when we are about + to load excess elements compared to the unrolled + scalar loop. */ + if (known_gt ((i + 1) * nunits, + (group_size * vf - gap))) + { + poly_uint64 remain = ((group_size * vf - gap) - i * nunits); + if (known_ge ((i + 1) * nunits - (group_size * vf - gap), + nunits)) + /* DR will be unused. */ + ltype = NULL_TREE; + else if (known_ge (vect_align, + tree_to_poly_uint64 + (TYPE_SIZE_UNIT (vectype)))) + /* Aligned access to excess elements is OK if + at least one element is accessed in the + scalar loop. */ + ; + else if (known_gt (vect_align, + ((nunits - remain) * dr_size))) + /* Aligned access to the gap area when there's + at least one element in it is OK. */ + ; + else { - poly_uint64 remain = ((group_size * vf - gap) - - (vec_num * j + i) * nunits); - if (known_ge ((vec_num * j + i + 1) * nunits - - (group_size * vf - gap), nunits)) - /* DR will be unused. */ - ltype = NULL_TREE; - else if (known_ge (vect_align, - tree_to_poly_uint64 - (TYPE_SIZE_UNIT (vectype)))) - /* Aligned access to excess elements is OK if - at least one element is accessed in the - scalar loop. */ - ; - else if (known_gt (vect_align, - ((nunits - remain) * dr_size))) - /* Aligned access to the gap area when there's - at least one element in it is OK. */ - ; - else + /* remain should now be > 0 and < nunits. */ + unsigned num; + if (known_ne (remain, 0u) + && constant_multiple_p (nunits, remain, &num)) + { + tree ptype; + new_vtype + = vector_vector_composition_type (vectype, num, + &ptype); + if (new_vtype) + ltype = ptype; + } + /* Else use multiple loads or a masked load? */ + /* For loop vectorization we now should have + an alternate type or LOOP_VINFO_PEELING_FOR_GAPS + set. */ + if (loop_vinfo) + gcc_assert (new_vtype + || LOOP_VINFO_PEELING_FOR_GAPS + (loop_vinfo)); + /* But still reduce the access size to the next + required power-of-two so peeling a single + scalar iteration is sufficient. */ + unsigned HOST_WIDE_INT cremain; + if (remain.is_constant (&cremain)) { - /* remain should now be > 0 and < nunits. */ - unsigned num; - if (known_ne (remain, 0u) - && constant_multiple_p (nunits, remain, &num)) + unsigned HOST_WIDE_INT cpart_size + = 1 << ceil_log2 (cremain); + if (known_gt (nunits, cpart_size) + && constant_multiple_p (nunits, cpart_size, + &num)) { tree ptype; new_vtype @@ -12111,333 +11647,290 @@ vectorizable_load (vec_info *vinfo, if (new_vtype) ltype = ptype; } - /* Else use multiple loads or a masked load? */ - /* For loop vectorization we now should have - an alternate type or LOOP_VINFO_PEELING_FOR_GAPS - set. */ - if (loop_vinfo) - gcc_assert (new_vtype - || LOOP_VINFO_PEELING_FOR_GAPS - (loop_vinfo)); - /* But still reduce the access size to the next - required power-of-two so peeling a single - scalar iteration is sufficient. */ - unsigned HOST_WIDE_INT cremain; - if (remain.is_constant (&cremain)) - { - unsigned HOST_WIDE_INT cpart_size - = 1 << ceil_log2 (cremain); - if (known_gt (nunits, cpart_size) - && constant_multiple_p (nunits, cpart_size, - &num)) - { - tree ptype; - new_vtype - = vector_vector_composition_type (vectype, - num, - &ptype); - if (new_vtype) - ltype = ptype; - } - } } } - tree offset - = (dataref_offset ? dataref_offset - : build_int_cst (ref_type, 0)); - if (!ltype) + } + tree offset = (dataref_offset ? dataref_offset + : build_int_cst (ref_type, 0)); + if (!ltype) + ; + else if (ltype != vectype + && memory_access_type == VMAT_CONTIGUOUS_REVERSE) + { + poly_uint64 gap_offset + = (tree_to_poly_uint64 (TYPE_SIZE_UNIT (vectype)) + - tree_to_poly_uint64 (TYPE_SIZE_UNIT (ltype))); + tree gapcst = build_int_cstu (ref_type, gap_offset); + offset = size_binop (PLUS_EXPR, offset, gapcst); + } + if (ltype) + { + data_ref = fold_build2 (MEM_REF, ltype, + dataref_ptr, offset); + if (alignment_support_scheme == dr_aligned + && align >= TYPE_ALIGN_UNIT (ltype)) ; - else if (ltype != vectype - && memory_access_type == VMAT_CONTIGUOUS_REVERSE) + else + TREE_TYPE (data_ref) + = build_aligned_type (TREE_TYPE (data_ref), + align * BITS_PER_UNIT); + } + if (!ltype) + data_ref = build_constructor (vectype, NULL); + else if (ltype != vectype) + { + vect_copy_ref_info (data_ref, + DR_REF (first_dr_info->dr)); + tree tem = make_ssa_name (ltype); + new_stmt = gimple_build_assign (tem, data_ref); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, + gsi); + data_ref = NULL; + vec *v; + /* We've computed 'num' above to statically two + or via constant_multiple_p. */ + unsigned num + = (exact_div (tree_to_poly_uint64 + (TYPE_SIZE_UNIT (vectype)), + tree_to_poly_uint64 + (TYPE_SIZE_UNIT (ltype))) + .to_constant ()); + vec_alloc (v, num); + if (memory_access_type == VMAT_CONTIGUOUS_REVERSE) { - poly_uint64 gap_offset - = (tree_to_poly_uint64 (TYPE_SIZE_UNIT (vectype)) - - tree_to_poly_uint64 (TYPE_SIZE_UNIT (ltype))); - tree gapcst = build_int_cstu (ref_type, gap_offset); - offset = size_binop (PLUS_EXPR, offset, gapcst); + while (--num) + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + build_zero_cst (ltype)); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, tem); } - if (ltype) + else { - data_ref - = fold_build2 (MEM_REF, ltype, dataref_ptr, offset); - if (alignment_support_scheme == dr_aligned) - ; - else - TREE_TYPE (data_ref) - = build_aligned_type (TREE_TYPE (data_ref), - align * BITS_PER_UNIT); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, tem); + while (--num) + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, + build_zero_cst (ltype)); } - if (!ltype) - data_ref = build_constructor (vectype, NULL); - else if (ltype != vectype) + gcc_assert (new_vtype != NULL_TREE); + if (new_vtype == vectype) + new_stmt + = gimple_build_assign (vec_dest, + build_constructor (vectype, v)); + else { - vect_copy_ref_info (data_ref, - DR_REF (first_dr_info->dr)); - tree tem = make_ssa_name (ltype); - new_stmt = gimple_build_assign (tem, data_ref); - vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, - gsi); - data_ref = NULL; - vec *v; - /* We've computed 'num' above to statically two - or via constant_multiple_p. */ - unsigned num - = (exact_div (tree_to_poly_uint64 - (TYPE_SIZE_UNIT (vectype)), - tree_to_poly_uint64 - (TYPE_SIZE_UNIT (ltype))) - .to_constant ()); - vec_alloc (v, num); - if (memory_access_type == VMAT_CONTIGUOUS_REVERSE) - { - while (--num) - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, - build_zero_cst (ltype)); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, tem); - } - else - { - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, tem); - while (--num) - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, - build_zero_cst (ltype)); - } - gcc_assert (new_vtype != NULL_TREE); - if (new_vtype == vectype) - new_stmt = gimple_build_assign ( - vec_dest, build_constructor (vectype, v)); - else - { - tree new_vname = make_ssa_name (new_vtype); - new_stmt = gimple_build_assign ( - new_vname, build_constructor (new_vtype, v)); - vect_finish_stmt_generation (vinfo, stmt_info, - new_stmt, gsi); - new_stmt = gimple_build_assign ( - vec_dest, - build1 (VIEW_CONVERT_EXPR, vectype, new_vname)); - } + tree new_vname = make_ssa_name (new_vtype); + new_stmt + = gimple_build_assign (new_vname, + build_constructor (new_vtype, + v)); + vect_finish_stmt_generation (vinfo, stmt_info, + new_stmt, gsi); + new_stmt + = gimple_build_assign (vec_dest, + build1 (VIEW_CONVERT_EXPR, + vectype, new_vname)); } } - break; } - case dr_explicit_realign: - { - if (costing_p) - break; - tree ptr, bump; - - tree vs = size_int (TYPE_VECTOR_SUBPARTS (vectype)); - - if (compute_in_loop) - msq = vect_setup_realignment (vinfo, first_stmt_info, gsi, - &realignment_token, - dr_explicit_realign, - dataref_ptr, NULL); + break; + } + case dr_explicit_realign: + { + if (costing_p) + break; + tree ptr, bump; + + tree vs = size_int (TYPE_VECTOR_SUBPARTS (vectype)); + + if (compute_in_loop) + msq = vect_setup_realignment (vinfo, first_stmt_info, gsi, + &realignment_token, + dr_explicit_realign, + dataref_ptr, NULL); + + if (TREE_CODE (dataref_ptr) == SSA_NAME) + ptr = copy_ssa_name (dataref_ptr); + else + ptr = make_ssa_name (TREE_TYPE (dataref_ptr)); + // For explicit realign the target alignment should be + // known at compile time. + unsigned HOST_WIDE_INT align + = DR_TARGET_ALIGNMENT (first_dr_info).to_constant (); + new_stmt = gimple_build_assign (ptr, BIT_AND_EXPR, dataref_ptr, + build_int_cst + (TREE_TYPE (dataref_ptr), + -(HOST_WIDE_INT) align)); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); + data_ref = build2 (MEM_REF, vectype, + ptr, build_int_cst (ref_type, 0)); + vect_copy_ref_info (data_ref, DR_REF (first_dr_info->dr)); + vec_dest = vect_create_destination_var (scalar_dest, vectype); + new_stmt = gimple_build_assign (vec_dest, data_ref); + new_temp = make_ssa_name (vec_dest, new_stmt); + gimple_assign_set_lhs (new_stmt, new_temp); + gimple_move_vops (new_stmt, stmt_info->stmt); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); + msq = new_temp; + + bump = size_binop (MULT_EXPR, vs, TYPE_SIZE_UNIT (elem_type)); + bump = size_binop (MINUS_EXPR, bump, size_one_node); + ptr = bump_vector_ptr (vinfo, dataref_ptr, NULL, gsi, stmt_info, + bump); + new_stmt = gimple_build_assign (NULL_TREE, BIT_AND_EXPR, ptr, + build_int_cst (TREE_TYPE (ptr), + -(HOST_WIDE_INT) align)); + if (TREE_CODE (ptr) == SSA_NAME) + ptr = copy_ssa_name (ptr, new_stmt); + else + ptr = make_ssa_name (TREE_TYPE (ptr), new_stmt); + gimple_assign_set_lhs (new_stmt, ptr); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); + data_ref = build2 (MEM_REF, vectype, + ptr, build_int_cst (ref_type, 0)); + break; + } + case dr_explicit_realign_optimized: + { + if (costing_p) + break; + if (TREE_CODE (dataref_ptr) == SSA_NAME) + new_temp = copy_ssa_name (dataref_ptr); + else + new_temp = make_ssa_name (TREE_TYPE (dataref_ptr)); + // We should only be doing this if we know the target + // alignment at compile time. + unsigned HOST_WIDE_INT align + = DR_TARGET_ALIGNMENT (first_dr_info).to_constant (); + new_stmt = gimple_build_assign (new_temp, BIT_AND_EXPR, dataref_ptr, + build_int_cst (TREE_TYPE (dataref_ptr), + -(HOST_WIDE_INT) align)); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); + data_ref = build2 (MEM_REF, vectype, new_temp, + build_int_cst (ref_type, 0)); + break; + } + default: + gcc_unreachable (); + } - if (TREE_CODE (dataref_ptr) == SSA_NAME) - ptr = copy_ssa_name (dataref_ptr); - else - ptr = make_ssa_name (TREE_TYPE (dataref_ptr)); - // For explicit realign the target alignment should be - // known at compile time. - unsigned HOST_WIDE_INT align - = DR_TARGET_ALIGNMENT (first_dr_info).to_constant (); - new_stmt = gimple_build_assign ( - ptr, BIT_AND_EXPR, dataref_ptr, - build_int_cst (TREE_TYPE (dataref_ptr), - -(HOST_WIDE_INT) align)); - vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); - data_ref - = build2 (MEM_REF, vectype, ptr, build_int_cst (ref_type, 0)); - vect_copy_ref_info (data_ref, DR_REF (first_dr_info->dr)); - vec_dest = vect_create_destination_var (scalar_dest, vectype); - new_stmt = gimple_build_assign (vec_dest, data_ref); - new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_assign_set_lhs (new_stmt, new_temp); - gimple_move_vops (new_stmt, stmt_info->stmt); - vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); - msq = new_temp; - - bump = size_binop (MULT_EXPR, vs, TYPE_SIZE_UNIT (elem_type)); - bump = size_binop (MINUS_EXPR, bump, size_one_node); - ptr = bump_vector_ptr (vinfo, dataref_ptr, NULL, gsi, stmt_info, - bump); - new_stmt = gimple_build_assign ( - NULL_TREE, BIT_AND_EXPR, ptr, - build_int_cst (TREE_TYPE (ptr), -(HOST_WIDE_INT) align)); - if (TREE_CODE (ptr) == SSA_NAME) - ptr = copy_ssa_name (ptr, new_stmt); - else - ptr = make_ssa_name (TREE_TYPE (ptr), new_stmt); - gimple_assign_set_lhs (new_stmt, ptr); - vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); - data_ref - = build2 (MEM_REF, vectype, ptr, build_int_cst (ref_type, 0)); - break; - } - case dr_explicit_realign_optimized: - { - if (costing_p) - break; - if (TREE_CODE (dataref_ptr) == SSA_NAME) - new_temp = copy_ssa_name (dataref_ptr); - else - new_temp = make_ssa_name (TREE_TYPE (dataref_ptr)); - // We should only be doing this if we know the target - // alignment at compile time. - unsigned HOST_WIDE_INT align - = DR_TARGET_ALIGNMENT (first_dr_info).to_constant (); - new_stmt = gimple_build_assign ( - new_temp, BIT_AND_EXPR, dataref_ptr, - build_int_cst (TREE_TYPE (dataref_ptr), - -(HOST_WIDE_INT) align)); - vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); - data_ref = build2 (MEM_REF, vectype, new_temp, - build_int_cst (ref_type, 0)); - break; - } - default: - gcc_unreachable (); + /* One common place to cost the above vect load for different + alignment support schemes. */ + if (costing_p) + { + /* For VMAT_CONTIGUOUS_PERMUTE if it's grouped load, we + only need to take care of the first stmt, whose + stmt_info is first_stmt_info, vec_num iterating on it + will cover the cost for the remaining, it's consistent + with transforming. For the prologue cost for realign, + we only need to count it once for the whole group. */ + bool first_stmt_info_p = first_stmt_info == stmt_info; + bool add_realign_cost = first_stmt_info_p && i == 0; + if (memory_access_type == VMAT_CONTIGUOUS + || memory_access_type == VMAT_CONTIGUOUS_REVERSE + || (memory_access_type == VMAT_CONTIGUOUS_PERMUTE + && (!grouped_load || first_stmt_info_p))) + { + /* Leave realign cases alone to keep them simple. */ + if (alignment_support_scheme == dr_explicit_realign_optimized + || alignment_support_scheme == dr_explicit_realign) + vect_get_load_cost (vinfo, stmt_info, slp_node, 1, + alignment_support_scheme, misalignment, + add_realign_cost, &inside_cost, + &prologue_cost, cost_vec, cost_vec, + true); + else + n_adjacent_loads++; } - - /* One common place to cost the above vect load for different - alignment support schemes. */ - if (costing_p) + } + else + { + vec_dest = vect_create_destination_var (scalar_dest, vectype); + /* DATA_REF is null if we've already built the statement. */ + if (data_ref) { - /* For VMAT_CONTIGUOUS_PERMUTE if it's grouped load, we - only need to take care of the first stmt, whose - stmt_info is first_stmt_info, vec_num iterating on it - will cover the cost for the remaining, it's consistent - with transforming. For the prologue cost for realign, - we only need to count it once for the whole group. */ - bool first_stmt_info_p = first_stmt_info == stmt_info; - bool add_realign_cost = first_stmt_info_p && i == 0; - if (memory_access_type == VMAT_CONTIGUOUS - || memory_access_type == VMAT_CONTIGUOUS_REVERSE - || (memory_access_type == VMAT_CONTIGUOUS_PERMUTE - && (!grouped_load || first_stmt_info_p))) - { - /* Leave realign cases alone to keep them simple. */ - if (alignment_support_scheme == dr_explicit_realign_optimized - || alignment_support_scheme == dr_explicit_realign) - vect_get_load_cost (vinfo, stmt_info, slp_node, 1, - alignment_support_scheme, misalignment, - add_realign_cost, &inside_cost, - &prologue_cost, cost_vec, cost_vec, - true); - else - n_adjacent_loads++; - } + vect_copy_ref_info (data_ref, DR_REF (first_dr_info->dr)); + new_stmt = gimple_build_assign (vec_dest, data_ref); } - else - { - vec_dest = vect_create_destination_var (scalar_dest, vectype); - /* DATA_REF is null if we've already built the statement. */ - if (data_ref) - { - vect_copy_ref_info (data_ref, DR_REF (first_dr_info->dr)); - new_stmt = gimple_build_assign (vec_dest, data_ref); - } - new_temp = need_zeroing - ? make_ssa_name (vectype) - : make_ssa_name (vec_dest, new_stmt); - gimple_set_lhs (new_stmt, new_temp); - vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); + new_temp = (need_zeroing + ? make_ssa_name (vectype) + : make_ssa_name (vec_dest, new_stmt)); + gimple_set_lhs (new_stmt, new_temp); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); - /* If we need to explicitly zero inactive elements emit a - VEC_COND_EXPR that does so. */ - if (need_zeroing) - { - vec_els = vect_get_mask_load_else (MASK_LOAD_ELSE_ZERO, - vectype); + /* If we need to explicitly zero inactive elements emit a + VEC_COND_EXPR that does so. */ + if (need_zeroing) + { + vec_els = vect_get_mask_load_else (MASK_LOAD_ELSE_ZERO, + vectype); - tree new_temp2 = make_ssa_name (vec_dest, new_stmt); - new_stmt - = gimple_build_assign (new_temp2, VEC_COND_EXPR, - final_mask, new_temp, vec_els); - vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, - gsi); - new_temp = new_temp2; - } + tree new_temp2 = make_ssa_name (vec_dest, new_stmt); + new_stmt = gimple_build_assign (new_temp2, VEC_COND_EXPR, + final_mask, new_temp, vec_els); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, + gsi); + new_temp = new_temp2; } + } - /* 3. Handle explicit realignment if necessary/supported. - Create in loop: - vec_dest = realign_load (msq, lsq, realignment_token) */ - if (!costing_p - && (alignment_support_scheme == dr_explicit_realign_optimized - || alignment_support_scheme == dr_explicit_realign)) - { - lsq = gimple_assign_lhs (new_stmt); - if (!realignment_token) - realignment_token = dataref_ptr; - vec_dest = vect_create_destination_var (scalar_dest, vectype); - new_stmt = gimple_build_assign (vec_dest, REALIGN_LOAD_EXPR, msq, - lsq, realignment_token); - new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_assign_set_lhs (new_stmt, new_temp); - vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); + /* 3. Handle explicit realignment if necessary/supported. + Create in loop: + vec_dest = realign_load (msq, lsq, realignment_token) */ + if (!costing_p + && (alignment_support_scheme == dr_explicit_realign_optimized + || alignment_support_scheme == dr_explicit_realign)) + { + lsq = gimple_assign_lhs (new_stmt); + if (!realignment_token) + realignment_token = dataref_ptr; + vec_dest = vect_create_destination_var (scalar_dest, vectype); + new_stmt = gimple_build_assign (vec_dest, REALIGN_LOAD_EXPR, msq, + lsq, realignment_token); + new_temp = make_ssa_name (vec_dest, new_stmt); + gimple_assign_set_lhs (new_stmt, new_temp); + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); - if (alignment_support_scheme == dr_explicit_realign_optimized) - { - gcc_assert (phi); - if (i == vec_num - 1 && j == ncopies - 1) - add_phi_arg (phi, lsq, loop_latch_edge (containing_loop), - UNKNOWN_LOCATION); - msq = lsq; - } + if (alignment_support_scheme == dr_explicit_realign_optimized) + { + gcc_assert (phi); + if (i == vec_num - 1) + add_phi_arg (phi, lsq, loop_latch_edge (containing_loop), + UNKNOWN_LOCATION); + msq = lsq; } + } - if (memory_access_type == VMAT_CONTIGUOUS_REVERSE) + if (memory_access_type == VMAT_CONTIGUOUS_REVERSE) + { + if (costing_p) + inside_cost = record_stmt_cost (cost_vec, 1, vec_perm, + slp_node, 0, vect_body); + else { - if (costing_p) - inside_cost = record_stmt_cost (cost_vec, 1, vec_perm, - slp_node, 0, vect_body); - else - { - tree perm_mask = perm_mask_for_reverse (vectype); - new_temp = permute_vec_elements (vinfo, new_temp, new_temp, - perm_mask, stmt_info, gsi); - new_stmt = SSA_NAME_DEF_STMT (new_temp); - } + tree perm_mask = perm_mask_for_reverse (vectype); + new_temp = permute_vec_elements (vinfo, new_temp, new_temp, + perm_mask, stmt_info, gsi); + new_stmt = SSA_NAME_DEF_STMT (new_temp); } + } - /* Collect vector loads and later create their permutation in - vect_transform_grouped_load (). */ - if (!costing_p && (grouped_load || slp_perm)) - dr_chain.quick_push (new_temp); + /* Collect vector loads and later create their permutation in + vect_transform_grouped_load (). */ + if (!costing_p && (grouped_load || slp_perm)) + dr_chain.quick_push (new_temp); - /* Store vector loads in the corresponding SLP_NODE. */ - if (!costing_p && slp && !slp_perm) - slp_node->push_vec_def (new_stmt); + /* Store vector loads in the corresponding SLP_NODE. */ + if (!costing_p && !slp_perm) + slp_node->push_vec_def (new_stmt); - /* With SLP permutation we load the gaps as well, without - we need to skip the gaps after we manage to fully load - all elements. group_gap_adj is DR_GROUP_SIZE here. */ - group_elt += nunits; - if (!costing_p - && maybe_ne (group_gap_adj, 0U) - && !slp_perm - && known_eq (group_elt, group_size - group_gap_adj)) - { - poly_wide_int bump_val - = (wi::to_wide (TYPE_SIZE_UNIT (elem_type)) * group_gap_adj); - if (tree_int_cst_sgn (vect_dr_behavior (vinfo, dr_info)->step) - == -1) - bump_val = -bump_val; - tree bump = wide_int_to_tree (sizetype, bump_val); - dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, gsi, - stmt_info, bump); - group_elt = 0; - } - } - /* Bump the vector pointer to account for a gap or for excess - elements loaded for a permuted SLP load. */ + /* With SLP permutation we load the gaps as well, without + we need to skip the gaps after we manage to fully load + all elements. group_gap_adj is DR_GROUP_SIZE here. */ + group_elt += nunits; if (!costing_p && maybe_ne (group_gap_adj, 0U) - && slp_perm) + && !slp_perm + && known_eq (group_elt, group_size - group_gap_adj)) { poly_wide_int bump_val = (wi::to_wide (TYPE_SIZE_UNIT (elem_type)) * group_gap_adj); @@ -12446,72 +11939,47 @@ vectorizable_load (vec_info *vinfo, tree bump = wide_int_to_tree (sizetype, bump_val); dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, gsi, stmt_info, bump); + group_elt = 0; } + } + /* Bump the vector pointer to account for a gap or for excess + elements loaded for a permuted SLP load. */ + if (!costing_p + && maybe_ne (group_gap_adj, 0U) + && slp_perm) + { + poly_wide_int bump_val + = (wi::to_wide (TYPE_SIZE_UNIT (elem_type)) * group_gap_adj); + if (tree_int_cst_sgn (vect_dr_behavior (vinfo, dr_info)->step) == -1) + bump_val = -bump_val; + tree bump = wide_int_to_tree (sizetype, bump_val); + dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, gsi, + stmt_info, bump); + } - if (slp && !slp_perm) - continue; - - if (slp_perm) + if (slp_perm) + { + unsigned n_perms; + /* For SLP we know we've seen all possible uses of dr_chain so + direct vect_transform_slp_perm_load to DCE the unused parts. + ??? This is a hack to prevent compile-time issues as seen + in PR101120 and friends. */ + if (costing_p) { - unsigned n_perms; - /* For SLP we know we've seen all possible uses of dr_chain so - direct vect_transform_slp_perm_load to DCE the unused parts. - ??? This is a hack to prevent compile-time issues as seen - in PR101120 and friends. */ - if (costing_p) - { - vect_transform_slp_perm_load (vinfo, slp_node, vNULL, nullptr, vf, - true, &n_perms, nullptr); - inside_cost = record_stmt_cost (cost_vec, n_perms, vec_perm, - slp_node, 0, vect_body); - } - else - { - bool ok = vect_transform_slp_perm_load (vinfo, slp_node, dr_chain, - gsi, vf, false, &n_perms, - nullptr, true); - gcc_assert (ok); - } + vect_transform_slp_perm_load (vinfo, slp_node, vNULL, nullptr, vf, + true, &n_perms, nullptr); + inside_cost = record_stmt_cost (cost_vec, n_perms, vec_perm, + slp_node, 0, vect_body); } else { - if (grouped_load) - { - gcc_assert (memory_access_type == VMAT_CONTIGUOUS_PERMUTE); - /* We assume that the cost of a single load-lanes instruction - is equivalent to the cost of DR_GROUP_SIZE separate loads. - If a grouped access is instead being provided by a - load-and-permute operation, include the cost of the - permutes. */ - if (costing_p && first_stmt_info == stmt_info) - { - /* Uses an even and odd extract operations or shuffle - operations for each needed permute. */ - int group_size = DR_GROUP_SIZE (first_stmt_info); - int nstmts = ceil_log2 (group_size) * group_size; - inside_cost += record_stmt_cost (cost_vec, nstmts, vec_perm, - slp_node, 0, vect_body); - - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "vect_model_load_cost: " - "strided group_size = %d .\n", - group_size); - } - else if (!costing_p) - { - vect_transform_grouped_load (vinfo, stmt_info, dr_chain, - group_size, gsi); - *vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info)[0]; - } - } - else if (!costing_p) - STMT_VINFO_VEC_STMTS (stmt_info).safe_push (new_stmt); + bool ok = vect_transform_slp_perm_load (vinfo, slp_node, dr_chain, + gsi, vf, false, &n_perms, + nullptr, true); + gcc_assert (ok); } dr_chain.release (); } - if (!slp && !costing_p) - *vec_stmt = STMT_VINFO_VEC_STMTS (stmt_info)[0]; if (costing_p) { @@ -13725,37 +13193,27 @@ vectorizable_early_exit (vec_info *vinfo, stmt_vec_info stmt_info, VEC_STMT_P is as for vectorizable_live_operation. */ static bool -can_vectorize_live_stmts (vec_info *vinfo, stmt_vec_info stmt_info, +can_vectorize_live_stmts (vec_info *vinfo, slp_tree slp_node, slp_instance slp_node_instance, bool vec_stmt_p, stmt_vector_for_cost *cost_vec) { loop_vec_info loop_vinfo = dyn_cast (vinfo); - if (slp_node) - { - stmt_vec_info slp_stmt_info; - unsigned int i; - FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (slp_node), i, slp_stmt_info) - { - if (slp_stmt_info - && (STMT_VINFO_LIVE_P (slp_stmt_info) - || (loop_vinfo - && LOOP_VINFO_EARLY_BREAKS (loop_vinfo) - && STMT_VINFO_DEF_TYPE (slp_stmt_info) - == vect_induction_def)) - && !vectorizable_live_operation (vinfo, slp_stmt_info, slp_node, - slp_node_instance, i, - vec_stmt_p, cost_vec)) - return false; - } + stmt_vec_info slp_stmt_info; + unsigned int i; + FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (slp_node), i, slp_stmt_info) + { + if (slp_stmt_info + && (STMT_VINFO_LIVE_P (slp_stmt_info) + || (loop_vinfo + && LOOP_VINFO_EARLY_BREAKS (loop_vinfo) + && STMT_VINFO_DEF_TYPE (slp_stmt_info) + == vect_induction_def)) + && !vectorizable_live_operation (vinfo, slp_stmt_info, slp_node, + slp_node_instance, i, + vec_stmt_p, cost_vec)) + return false; } - else if ((STMT_VINFO_LIVE_P (stmt_info) - || (LOOP_VINFO_EARLY_BREAKS (loop_vinfo) - && STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)) - && !vectorizable_live_operation (vinfo, stmt_info, - slp_node, slp_node_instance, -1, - vec_stmt_p, cost_vec)) - return false; return true; } @@ -13764,115 +13222,42 @@ can_vectorize_live_stmts (vec_info *vinfo, stmt_vec_info stmt_info, opt_result vect_analyze_stmt (vec_info *vinfo, - stmt_vec_info stmt_info, bool *need_to_vectorize, slp_tree node, slp_instance node_instance, stmt_vector_for_cost *cost_vec) { + stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node); bb_vec_info bb_vinfo = dyn_cast (vinfo); enum vect_relevant relevance = STMT_VINFO_RELEVANT (stmt_info); bool ok; - gimple_seq pattern_def_seq; if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "==> examining statement: %G", stmt_info->stmt); if (gimple_has_volatile_ops (stmt_info->stmt)) - return opt_result::failure_at (stmt_info->stmt, - "not vectorized:" - " stmt has volatile operands: %G\n", - stmt_info->stmt); - - if (STMT_VINFO_IN_PATTERN_P (stmt_info) - && node == NULL - && (pattern_def_seq = STMT_VINFO_PATTERN_DEF_SEQ (stmt_info))) { - gimple_stmt_iterator si; - - for (si = gsi_start (pattern_def_seq); !gsi_end_p (si); gsi_next (&si)) - { - stmt_vec_info pattern_def_stmt_info - = vinfo->lookup_stmt (gsi_stmt (si)); - if (STMT_VINFO_RELEVANT_P (pattern_def_stmt_info) - || STMT_VINFO_LIVE_P (pattern_def_stmt_info)) - { - /* Analyze def stmt of STMT if it's a pattern stmt. */ - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "==> examining pattern def statement: %G", - pattern_def_stmt_info->stmt); - - opt_result res - = vect_analyze_stmt (vinfo, pattern_def_stmt_info, - need_to_vectorize, node, node_instance, - cost_vec); - if (!res) - return res; - } - } + /* ??? This shouldn't really happen, volatile stmts should + not end up in the SLP graph. */ + return opt_result::failure_at (stmt_info->stmt, + "not vectorized:" + " stmt has volatile operands: %G\n", + stmt_info->stmt); } - /* Skip stmts that do not need to be vectorized. In loops this is expected - to include: - - the COND_EXPR which is the loop exit condition - - any LABEL_EXPRs in the loop - - computations that are used only for array indexing or loop control. - In basic blocks we only analyze statements that are a part of some SLP - instance, therefore, all the statements are relevant. - - Pattern statement needs to be analyzed instead of the original statement - if the original statement is not relevant. Otherwise, we analyze both - statements. In basic blocks we are called from some SLP instance - traversal, don't analyze pattern stmts instead, the pattern stmts - already will be part of SLP instance. */ - - stmt_vec_info pattern_stmt_info = STMT_VINFO_RELATED_STMT (stmt_info); + /* Skip stmts that do not need to be vectorized. */ if (!STMT_VINFO_RELEVANT_P (stmt_info) && !STMT_VINFO_LIVE_P (stmt_info)) { - if (STMT_VINFO_IN_PATTERN_P (stmt_info) - && pattern_stmt_info - && (STMT_VINFO_RELEVANT_P (pattern_stmt_info) - || STMT_VINFO_LIVE_P (pattern_stmt_info))) - { - /* Analyze PATTERN_STMT instead of the original stmt. */ - stmt_info = pattern_stmt_info; - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "==> examining pattern statement: %G", - stmt_info->stmt); - } - else - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "irrelevant.\n"); - - if (node) - return opt_result::failure_at (stmt_info->stmt, - "not vectorized:" - " irrelevant stmt as SLP node %p " - "representative.\n", - (void *)node); - return opt_result::success (); - } - } - else if (STMT_VINFO_IN_PATTERN_P (stmt_info) - && node == NULL - && pattern_stmt_info - && (STMT_VINFO_RELEVANT_P (pattern_stmt_info) - || STMT_VINFO_LIVE_P (pattern_stmt_info))) - { - /* Analyze PATTERN_STMT too. */ if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "==> examining pattern statement: %G", - pattern_stmt_info->stmt); + dump_printf_loc (MSG_NOTE, vect_location, "irrelevant.\n"); - opt_result res - = vect_analyze_stmt (vinfo, pattern_stmt_info, need_to_vectorize, node, - node_instance, cost_vec); - if (!res) - return res; + /* ??? This shouldn't really happen, irrelevant stmts should + not end up in the SLP graph. */ + return opt_result::failure_at (stmt_info->stmt, + "not vectorized:" + " irrelevant stmt as SLP node %p " + "representative.\n", + (void *)node); } switch (STMT_VINFO_DEF_TYPE (stmt_info)) @@ -13908,8 +13293,7 @@ vect_analyze_stmt (vec_info *vinfo, } tree saved_vectype = STMT_VINFO_VECTYPE (stmt_info); - if (node) - STMT_VINFO_VECTYPE (stmt_info) = SLP_TREE_VECTYPE (node); + STMT_VINFO_VECTYPE (stmt_info) = SLP_TREE_VECTYPE (node); if (STMT_VINFO_RELEVANT_P (stmt_info)) { @@ -13917,23 +13301,8 @@ vect_analyze_stmt (vec_info *vinfo, gcc_assert (STMT_VINFO_VECTYPE (stmt_info) || gimple_code (stmt_info->stmt) == GIMPLE_COND || (call && gimple_call_lhs (call) == NULL_TREE)); - *need_to_vectorize = true; } - if (PURE_SLP_STMT (stmt_info) && !node) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "handled only by SLP analysis\n"); - return opt_result::success (); - } - - /* When we arrive here with a non-SLP statement and we are supposed - to use SLP for everything fail vectorization. */ - if (!node) - return opt_result::failure_at (stmt_info->stmt, - "needs non-SLP handling\n"); - ok = true; if (!bb_vinfo && (STMT_VINFO_RELEVANT_P (stmt_info) @@ -13997,8 +13366,7 @@ vect_analyze_stmt (vec_info *vinfo, } - if (node) - STMT_VINFO_VECTYPE (stmt_info) = saved_vectype; + STMT_VINFO_VECTYPE (stmt_info) = saved_vectype; if (!ok) return opt_result::failure_at (stmt_info->stmt, @@ -14010,10 +13378,11 @@ vect_analyze_stmt (vec_info *vinfo, need extra handling, except for vectorizable reductions. */ if (!bb_vinfo && STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type - && STMT_VINFO_TYPE (stmt_info) != lc_phi_info_type - && (!node || !node->ldst_lanes || SLP_TREE_CODE (node) == VEC_PERM_EXPR) + && (STMT_VINFO_TYPE (stmt_info) != lc_phi_info_type + || STMT_VINFO_DEF_TYPE (stmt_info) == vect_internal_def) + && (!node->ldst_lanes || SLP_TREE_CODE (node) == VEC_PERM_EXPR) && !can_vectorize_live_stmts (as_a (vinfo), - stmt_info, node, node_instance, + node, node_instance, false, cost_vec)) return opt_result::failure_at (stmt_info->stmt, "not vectorized:" @@ -14185,7 +13554,7 @@ vect_transform_stmt (vec_info *vinfo, { /* Handle stmts whose DEF is used outside the loop-nest that is being vectorized. */ - done = can_vectorize_live_stmts (vinfo, stmt_info, slp_node, + done = can_vectorize_live_stmts (vinfo, slp_node, slp_node_instance, true, NULL); gcc_assert (done); } @@ -14488,6 +13857,23 @@ vect_chooses_same_modes_p (vec_info *vinfo, machine_mode vector_mode) return true; } +/* Return true if replacing VECTOR_MODE with ALT_VECTOR_MODE would not + change the chosen vector modes for analysis of a loop. */ + +bool +vect_chooses_same_modes_p (machine_mode vector_mode, + machine_mode alt_vector_mode) +{ + return (VECTOR_MODE_P (vector_mode) + && VECTOR_MODE_P (alt_vector_mode) + && (related_vector_mode (vector_mode, + GET_MODE_INNER (alt_vector_mode)) + == alt_vector_mode) + && (related_vector_mode (alt_vector_mode, + GET_MODE_INNER (vector_mode)) + == vector_mode)); +} + /* Function vect_is_simple_use. Input: @@ -14932,6 +14318,8 @@ supportable_widening_operation (vec_info *vinfo, internal_fn lo, hi, even, odd; lookup_hilo_internal_fn (ifn, &lo, &hi); + if (BYTES_BIG_ENDIAN) + std::swap (lo, hi); *code1 = as_combined_fn (lo); *code2 = as_combined_fn (hi); optab1 = direct_internal_fn_optab (lo, {vectype, vectype}); @@ -15285,7 +14673,6 @@ supportable_indirect_convert_operation (code_helper code, bool found_mode = false; scalar_mode lhs_mode = GET_MODE_INNER (TYPE_MODE (vectype_out)); scalar_mode rhs_mode = GET_MODE_INNER (TYPE_MODE (vectype_in)); - opt_scalar_mode mode_iter; tree_code tc1, tc2, code1, code2; tree cvt_type = NULL_TREE; diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 7aa2b02b63cb..80f8853733de 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -56,6 +56,14 @@ enum dr_alignment_support { dr_aligned }; +/* Define type of peeling support to indicate how peeling for alignment can help + make vectorization supported. */ +enum peeling_support { + peeling_known_supported, + peeling_maybe_supported, + peeling_unsupported +}; + /* Define type of def-use cross-iteration cycle. */ enum vect_def_type { vect_uninitialized_def = 0, @@ -946,6 +954,13 @@ typedef class _loop_vec_info : public vec_info { epilogue of loop. */ bool epil_using_partial_vectors_p; + /* True if we've decided to use peeling with versioning together, which allows + unaligned unsupported data refs to be uniformly aligned after a certain + amount of peeling (mutual alignment). Otherwise, we use versioning alone + so these data refs must be already aligned to a power-of-two boundary + without peeling. */ + bool allow_mutual_alignment; + /* The bias for len_load and len_store. For now, only 0 and -1 are supported. -1 must be used when a backend does not support len_load/len_store with a length of zero. */ @@ -970,6 +985,10 @@ typedef class _loop_vec_info : public vec_info { /* Main loop IV cond. */ gcond* loop_iv_cond; + /* True if we have an unroll factor requested by the user through pragma GCC + unroll. */ + bool user_unroll; + /* True if there are no loop carried data dependencies in the loop. If loop->safelen <= 1, then this is always true, either the loop didn't have any loop carried data dependencies, or the loop is being @@ -1070,6 +1089,7 @@ typedef class _loop_vec_info : public vec_info { #define LOOP_VINFO_USING_SELECT_VL_P(L) (L)->using_select_vl_p #define LOOP_VINFO_EPIL_USING_PARTIAL_VECTORS_P(L) \ (L)->epil_using_partial_vectors_p +#define LOOP_VINFO_ALLOW_MUTUAL_ALIGNMENT(L) (L)->allow_mutual_alignment #define LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS(L) (L)->partial_load_store_bias #define LOOP_VINFO_VECT_FACTOR(L) (L)->vectorization_factor #define LOOP_VINFO_MAX_VECT_FACTOR(L) (L)->max_vectorization_factor @@ -1094,6 +1114,7 @@ typedef class _loop_vec_info : public vec_info { #define LOOP_VINFO_CHECK_UNEQUAL_ADDRS(L) (L)->check_unequal_addrs #define LOOP_VINFO_CHECK_NONZERO(L) (L)->check_nonzero #define LOOP_VINFO_LOWER_BOUNDS(L) (L)->lower_bounds +#define LOOP_VINFO_USER_UNROLL(L) (L)->user_unroll #define LOOP_VINFO_GROUPED_STORES(L) (L)->grouped_stores #define LOOP_VINFO_SLP_INSTANCES(L) (L)->slp_instances #define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor @@ -1693,7 +1714,7 @@ class vector_costs unsigned int outside_cost () const; unsigned int total_cost () const; unsigned int suggested_unroll_factor () const; - machine_mode suggested_epilogue_mode () const; + machine_mode suggested_epilogue_mode (int &masked) const; protected: unsigned int record_stmt_cost (stmt_vec_info, vect_cost_model_location, @@ -1717,8 +1738,13 @@ class vector_costs unsigned int m_suggested_unroll_factor; /* The suggested mode to be used for a vectorized epilogue or VOIDmode, - determined at finish_cost. */ + determined at finish_cost. m_masked_epilogue specifies whether the + epilogue should use masked vectorization, regardless of the + --param vect-partial-vector-usage default. If -1 then the + --param setting takes precedence. If the user explicitly specified + --param vect-partial-vector-usage then that takes precedence. */ machine_mode m_suggested_epilogue_mode; + int m_masked_epilogue; /* True if finish_cost has been called. */ bool m_finished; @@ -1734,6 +1760,7 @@ vector_costs::vector_costs (vec_info *vinfo, bool costing_for_scalar) m_costs (), m_suggested_unroll_factor(1), m_suggested_epilogue_mode(VOIDmode), + m_masked_epilogue (-1), m_finished (false) { } @@ -1794,9 +1821,10 @@ vector_costs::suggested_unroll_factor () const /* Return the suggested epilogue mode. */ inline machine_mode -vector_costs::suggested_epilogue_mode () const +vector_costs::suggested_epilogue_mode (int &masked_p) const { gcc_checking_assert (m_finished); + masked_p = m_masked_epilogue; return m_suggested_epilogue_mode; } @@ -2390,6 +2418,7 @@ extern tree get_mask_type_for_scalar_type (vec_info *, tree, unsigned int = 0); extern tree get_mask_type_for_scalar_type (vec_info *, tree, slp_tree); extern tree get_same_sized_vectype (tree, tree); extern bool vect_chooses_same_modes_p (vec_info *, machine_mode); +extern bool vect_chooses_same_modes_p (machine_mode, machine_mode); extern bool vect_get_loop_mask_type (loop_vec_info); extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *, stmt_vec_info * = NULL, gimple ** = NULL); @@ -2477,8 +2506,7 @@ extern bool vect_transform_stmt (vec_info *, stmt_vec_info, slp_tree, slp_instance); extern void vect_remove_stores (vec_info *, stmt_vec_info); extern bool vect_nop_conversion_p (stmt_vec_info); -extern opt_result vect_analyze_stmt (vec_info *, stmt_vec_info, bool *, - slp_tree, +extern opt_result vect_analyze_stmt (vec_info *, slp_tree, slp_instance, stmt_vector_for_cost *); extern void vect_get_load_cost (vec_info *, stmt_vec_info, slp_tree, int, dr_alignment_support, int, bool, @@ -2524,7 +2552,7 @@ extern bool vect_check_gather_scatter (stmt_vec_info, loop_vec_info, extern opt_result vect_find_stmt_data_reference (loop_p, gimple *, vec *, vec *, int); -extern opt_result vect_analyze_data_refs (vec_info *, poly_uint64 *, bool *); +extern opt_result vect_analyze_data_refs (vec_info *, bool *); extern void vect_record_base_alignments (vec_info *); extern tree vect_create_data_ref_ptr (vec_info *, stmt_vec_info, tree, class loop *, tree, @@ -2660,7 +2688,7 @@ extern bool vect_slp_analyze_operations (vec_info *); extern void vect_schedule_slp (vec_info *, const vec &); extern opt_result vect_analyze_slp (vec_info *, unsigned, bool); extern bool vect_make_slp_decision (loop_vec_info); -extern void vect_detect_hybrid_slp (loop_vec_info); +extern bool vect_detect_hybrid_slp (loop_vec_info); extern void vect_optimize_slp (vec_info *); extern void vect_gather_slp_loads (vec_info *); extern tree vect_get_slp_scalar_def (slp_tree, unsigned); @@ -2680,7 +2708,7 @@ extern void duplicate_and_interleave (vec_info *, gimple_seq *, tree, extern int vect_get_place_in_interleaving_chain (stmt_vec_info, stmt_vec_info); extern slp_tree vect_create_new_slp_node (unsigned, tree_code); extern void vect_free_slp_tree (slp_tree); -extern bool compatible_calls_p (gcall *, gcall *); +extern bool compatible_calls_p (gcall *, gcall *, bool); extern int vect_slp_child_index_for_operand (const gimple *, int op, bool); extern tree prepare_vec_mask (loop_vec_info, tree, tree, tree, diff --git a/gcc/tree.cc b/gcc/tree.cc index 9759c6b36a6e..0f02924763ff 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -32,6 +32,8 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "backend.h" #include "target.h" +#include "memmodel.h" +#include "tm_p.h" #include "tree.h" #include "gimple.h" #include "tree-pass.h" @@ -788,6 +790,57 @@ init_ttree (void) } +/* Mapping from prefix to label number. */ + +struct identifier_hash : ggc_ptr_hash +{ + static inline hashval_t hash (tree t) + { + return IDENTIFIER_HASH_VALUE (t); + } +}; +struct identifier_count_traits + : simple_hashmap_traits {}; +typedef hash_map internal_label_map; +static GTY(()) internal_label_map *internal_label_nums; + +/* Generates an identifier intended to be used internally with the + given PREFIX. This is intended to be used by the frontend so that + C++ modules can regenerate appropriate (non-clashing) identifiers on + stream-in. */ + +tree +generate_internal_label (const char *prefix) +{ + tree prefix_id = get_identifier (prefix); + if (!internal_label_nums) + internal_label_nums = internal_label_map::create_ggc(); + long &num = internal_label_nums->get_or_insert (prefix_id); + + char tmp[32]; + ASM_GENERATE_INTERNAL_LABEL (tmp, prefix, num++); + + tree id = get_identifier (tmp); + IDENTIFIER_INTERNAL_P (id) = true; + + /* Cache the prefix on the identifier so we can retrieve it later. */ + TREE_CHAIN (id) = prefix_id; + + return id; +} + +/* Get the PREFIX we created the internal identifier LABEL with. */ + +const char * +prefix_for_internal_label (tree label) +{ + gcc_assert (IDENTIFIER_INTERNAL_P (label) + && !IDENTIFIER_TRANSPARENT_ALIAS (label) + && TREE_CHAIN (label) + && TREE_CODE (TREE_CHAIN (label)) == IDENTIFIER_NODE); + return IDENTIFIER_POINTER (TREE_CHAIN (label)); +} + /* The name of the object as the assembler will see it (but before any translations made by ASM_OUTPUT_LABELREF). Often this is the same as DECL_NAME. It is an IDENTIFIER_NODE. */ @@ -3964,6 +4017,38 @@ decl_address_ip_invariant_p (const_tree op) return false; } +/* Return true if T is an object with invariant address. */ + +bool +address_invariant_p (tree t) +{ + while (handled_component_p (t)) + { + switch (TREE_CODE (t)) + { + case ARRAY_REF: + case ARRAY_RANGE_REF: + if (!tree_invariant_p (TREE_OPERAND (t, 1)) + || TREE_OPERAND (t, 2) != NULL_TREE + || TREE_OPERAND (t, 3) != NULL_TREE) + return false; + break; + + case COMPONENT_REF: + if (TREE_OPERAND (t, 2) != NULL_TREE) + return false; + break; + + default: + break; + } + t = TREE_OPERAND (t, 0); + } + + STRIP_ANY_LOCATION_WRAPPER (t); + return CONSTANT_CLASS_P (t) || decl_address_invariant_p (t); +} + /* Return true if T is function-invariant (internal function, does not handle arithmetic; that's handled in skip_simple_arithmetic and @@ -3972,10 +4057,7 @@ decl_address_ip_invariant_p (const_tree op) static bool tree_invariant_p_1 (tree t) { - tree op; - - if (TREE_CONSTANT (t) - || (TREE_READONLY (t) && !TREE_SIDE_EFFECTS (t))) + if (TREE_CONSTANT (t) || (TREE_READONLY (t) && !TREE_SIDE_EFFECTS (t))) return true; switch (TREE_CODE (t)) @@ -3985,30 +4067,7 @@ tree_invariant_p_1 (tree t) return true; case ADDR_EXPR: - op = TREE_OPERAND (t, 0); - while (handled_component_p (op)) - { - switch (TREE_CODE (op)) - { - case ARRAY_REF: - case ARRAY_RANGE_REF: - if (!tree_invariant_p (TREE_OPERAND (op, 1)) - || TREE_OPERAND (op, 2) != NULL_TREE - || TREE_OPERAND (op, 3) != NULL_TREE) - return false; - break; - - case COMPONENT_REF: - if (TREE_OPERAND (op, 2) != NULL_TREE) - return false; - break; - - default:; - } - op = TREE_OPERAND (op, 0); - } - - return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op); + return address_invariant_p (TREE_OPERAND (t, 0)); default: break; @@ -14613,10 +14672,11 @@ verify_type (const_tree t) /* Return 1 if ARG interpreted as signed in its precision is known to be always non-negative or 2 if ARG is known to be always negative, or 3 if - ARG may be non-negative or negative. */ + ARG may be non-negative or negative. STMT if specified is the statement + on which it is being tested. */ int -get_range_pos_neg (tree arg) +get_range_pos_neg (tree arg, gimple *stmt) { if (arg == error_mark_node) return 3; @@ -14649,7 +14709,7 @@ get_range_pos_neg (tree arg) if (TREE_CODE (arg) != SSA_NAME) return 3; int_range_max r; - while (!get_global_range_query ()->range_of_expr (r, arg) + while (!get_range_query (cfun)->range_of_expr (r, arg, stmt) || r.undefined_p () || r.varying_p ()) { gimple *g = SSA_NAME_DEF_STMT (arg); @@ -15360,6 +15420,65 @@ get_target_clone_attr_len (tree arglist) return str_len_sum; } +/* Returns an auto_vec of string_slices containing the version strings from + ARGLIST. DEFAULT_COUNT is incremented for each default version found. */ + +auto_vec +get_clone_attr_versions (const tree arglist, int *default_count) +{ + gcc_assert (TREE_CODE (arglist) == TREE_LIST); + auto_vec versions; + + static const char separator_str[] = {TARGET_CLONES_ATTR_SEPARATOR, 0}; + string_slice separators = string_slice (separator_str); + + for (tree arg = arglist; arg; arg = TREE_CHAIN (arg)) + { + string_slice str = string_slice (TREE_STRING_POINTER (TREE_VALUE (arg))); + while (str.is_valid ()) + { + string_slice attr = string_slice::tokenize (&str, separators); + attr = attr.strip (); + + if (attr == "default" && default_count) + (*default_count)++; + versions.safe_push (attr); + } + } + return versions; +} + +/* Returns an auto_vec of string_slices containing the version strings from + the target_clone attribute from DECL. DEFAULT_COUNT is incremented for each + default version found. */ +auto_vec +get_clone_versions (const tree decl, int *default_count) +{ + tree attr = lookup_attribute ("target_clones", DECL_ATTRIBUTES (decl)); + if (!attr) + return auto_vec (); + tree arglist = TREE_VALUE (attr); + return get_clone_attr_versions (arglist, default_count); +} + +/* If DECL has a target_version attribute, returns a string_slice containing the + attribute value. Otherwise, returns string_slice::invalid. + Only works for target_version due to target attributes allowing multiple + string arguments to specify one target. */ +string_slice +get_target_version (const tree decl) +{ + gcc_assert (!TARGET_HAS_FMV_TARGET_ATTRIBUTE); + + tree attr = lookup_attribute ("target_version", DECL_ATTRIBUTES (decl)); + + if (!attr) + return string_slice::invalid (); + + return string_slice (TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)))) + .strip (); +} + void tree_cc_finalize (void) { diff --git a/gcc/tree.h b/gcc/tree.h index 7e4008e8fb41..c0e434ba8977 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-core.h" #include "options.h" +#include "vec.h" /* Convert a target-independent built-in function code to a combined_fn. */ @@ -1078,6 +1079,11 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, #define IDENTIFIER_ANON_P(NODE) \ (IDENTIFIER_NODE_CHECK (NODE)->base.private_flag) +/* Nonzero indicates an IDENTIFIER_NODE that names an internal label. + The prefix used to generate the label can be found on the TREE_CHAIN. */ +#define IDENTIFIER_INTERNAL_P(NODE) \ + (IDENTIFIER_NODE_CHECK (NODE)->base.volatile_flag) + /* Nonzero in an IDENTIFIER_NODE if the name is a local alias, whose uses are to be substituted for uses of the TREE_CHAINed identifier. */ #define IDENTIFIER_TRANSPARENT_ALIAS(NODE) \ @@ -2227,6 +2233,12 @@ class auto_suppress_location_wrappers #define OMP_CLAUSE_OPERAND(NODE, I) \ OMP_CLAUSE_ELT_CHECK (NODE, I) +/* True if the clause decl NODE contains an OpenMP iterator. */ +#define OMP_ITERATOR_DECL_P(NODE) \ + (TREE_CODE (NODE) == TREE_LIST \ + && TREE_PURPOSE (NODE) \ + && TREE_CODE (TREE_PURPOSE (NODE)) == TREE_VEC) + /* In a BLOCK (scope) node: Variables declared in the scope NODE. */ #define BLOCK_VARS(NODE) (BLOCK_CHECK (NODE)->block.vars) @@ -4744,6 +4756,8 @@ vector_cst_encoded_nelts (const_tree t) return VECTOR_CST_NPATTERNS (t) * VECTOR_CST_NELTS_PER_PATTERN (t); } +extern tree generate_internal_label (const char *); +extern const char *prefix_for_internal_label (tree label); extern tree decl_assembler_name (tree); extern void overwrite_decl_assembler_name (tree decl, tree name); extern tree decl_comdat_group (const_tree); @@ -5340,6 +5354,10 @@ extern tree staticp (tree); extern tree save_expr (tree); +/* Return true if T is an object with invariant address. */ + +extern bool address_invariant_p (tree); + /* Return true if T is function-invariant. */ extern bool tree_invariant_p (tree); @@ -5900,7 +5918,7 @@ extern bool gimple_canonical_types_compatible_p (const_tree, const_tree, bool trust_type_canonical = true); extern bool type_with_interoperable_signedness (const_tree); extern bitmap get_nonnull_args (const_tree); -extern int get_range_pos_neg (tree); +extern int get_range_pos_neg (tree, gimple * = NULL); /* Return true for a valid pair of new and delete operators. */ extern bool valid_new_delete_pair_p (tree, tree, bool * = NULL); @@ -7071,4 +7089,14 @@ extern tree get_attr_nonstring_decl (tree, tree * = NULL); extern int get_target_clone_attr_len (tree); +/* Returns the version string for a decl with target_version attribute. + Returns an invalid string_slice if no attribute is present. */ +extern string_slice get_target_version (const tree); +/* Returns a vector of the version strings from a target_clones attribute on + a decl. Can also record the number of default versions found. */ +extern auto_vec get_clone_versions (const tree, int * = NULL); +/* Returns a vector of the version strings from a target_clones attribute + directly. */ +extern auto_vec get_clone_attr_versions (const tree, int *); + #endif /* GCC_TREE_H */ diff --git a/gcc/ubsan.cc b/gcc/ubsan.cc index 35a7dbd011ee..6d748258b1e3 100644 --- a/gcc/ubsan.cc +++ b/gcc/ubsan.cc @@ -358,10 +358,6 @@ get_ubsan_type_info_for_type (tree type) return 0; } -/* Counters for internal labels. ubsan_ids[0] for Lubsan_type, - ubsan_ids[1] for Lubsan_data labels. */ -static GTY(()) unsigned int ubsan_ids[2]; - /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type descriptor. It first looks into the hash table; if not found, create the VAR_DECL, put it into the hash table and return the @@ -552,10 +548,8 @@ ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle) TREE_READONLY (str) = 1; TREE_STATIC (str) = 1; - char tmp_name[32]; - ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", ubsan_ids[0]++); - decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name), - dtype); + decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, + generate_internal_label ("Lubsan_type"), dtype); TREE_STATIC (decl) = 1; TREE_PUBLIC (decl) = 0; DECL_ARTIFICIAL (decl) = 1; @@ -659,10 +653,8 @@ ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...) layout_type (ret); /* Now, fill in the type. */ - char tmp_name[32]; - ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_ids[1]++); - tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name), - ret); + tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, + generate_internal_label ("Lubsan_data"), ret); TREE_STATIC (var) = 1; TREE_PUBLIC (var) = 0; DECL_ARTIFICIAL (var) = 1; @@ -2046,9 +2038,9 @@ instrument_nonnull_arg (gimple_stmt_iterator *gsi) for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++) { tree arg = gimple_call_arg (stmt, i); - tree arg2; + tree arg2, arg3; if (POINTER_TYPE_P (TREE_TYPE (arg)) - && infer_nonnull_range_by_attribute (stmt, arg, &arg2)) + && infer_nonnull_range_by_attribute (stmt, arg, &arg2, &arg3)) { gimple *g; if (!is_gimple_val (arg)) @@ -2058,6 +2050,8 @@ instrument_nonnull_arg (gimple_stmt_iterator *gsi) gsi_safe_insert_before (gsi, g); arg = gimple_assign_lhs (g); } + if (arg2 == arg3) + arg3 = NULL_TREE; if (arg2 && !is_gimple_val (arg2)) { g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg2)), arg2); @@ -2065,6 +2059,13 @@ instrument_nonnull_arg (gimple_stmt_iterator *gsi) gsi_safe_insert_before (gsi, g); arg2 = gimple_assign_lhs (g); } + if (arg3 && !is_gimple_val (arg3)) + { + g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg3)), arg3); + gimple_set_location (g, loc[0]); + gsi_safe_insert_before (gsi, g); + arg3 = gimple_assign_lhs (g); + } basic_block then_bb, fallthru_bb; *gsi = create_cond_insert_point (gsi, true, false, true, @@ -2086,6 +2087,18 @@ instrument_nonnull_arg (gimple_stmt_iterator *gsi) gimple_set_location (g, loc[0]); gsi_insert_after (gsi, g, GSI_NEW_STMT); + *gsi = gsi_after_labels (then_bb); + } + if (arg3) + { + *gsi = create_cond_insert_point (gsi, true, false, true, + &then_bb, &fallthru_bb); + g = gimple_build_cond (NE_EXPR, arg3, + build_zero_cst (TREE_TYPE (arg3)), + NULL_TREE, NULL_TREE); + gimple_set_location (g, loc[0]); + gsi_insert_after (gsi, g, GSI_NEW_STMT); + *gsi = gsi_after_labels (then_bb); } if (flag_sanitize_trap & SANITIZE_NONNULL_ATTRIBUTE) diff --git a/gcc/value-range.cc b/gcc/value-range.cc index ed3760fa6ff6..dc6909e77c54 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -1205,7 +1205,7 @@ frange::supports_type_p (const_tree type) const } void -frange::verify_range () +frange::verify_range () const { if (!undefined_p ()) gcc_checking_assert (HONOR_NANS (m_type) || !maybe_isnan ()); @@ -1515,7 +1515,7 @@ irange::set (tree min, tree max, value_range_kind kind) // Check the validity of the range. void -irange::verify_range () +irange::verify_range () const { gcc_checking_assert (m_discriminator == VR_IRANGE); if (m_kind == VR_UNDEFINED) @@ -1552,6 +1552,11 @@ irange::verify_range () gcc_checking_assert (ub.get_precision () == prec); int c = wi::cmp (lb, ub, TYPE_SIGN (m_type)); gcc_checking_assert (c == 0 || c == -1); + // Previous UB should be lower than LB + if (i > 0) + gcc_checking_assert (wi::lt_p (upper_bound (i - 1), + lb, + TYPE_SIGN (m_type))); } m_bitmask.verify_mask (); } @@ -1628,10 +1633,8 @@ irange::contains_p (const wide_int &cst) const if (undefined_p ()) return false; - // See if we can exclude CST based on the known 0 bits. - if (!m_bitmask.unknown_p () - && cst != 0 - && wi::bit_and (m_bitmask.get_nonzero_bits (), cst) == 0) + // Check if the known bits in bitmask exclude CST. + if (!m_bitmask.member_p (cst)) return false; signop sign = TYPE_SIGN (type ()); @@ -1899,12 +1902,17 @@ irange::irange_contains_p (const irange &r) const gcc_checking_assert (!undefined_p () && !varying_p ()); gcc_checking_assert (!r.undefined_p () && !varying_p ()); + // Check singletons directly which will include any bitmasks. + wide_int rl; + if (r.singleton_p (rl)) + return contains_p (rl); + // In order for THIS to fully contain R, all of the pairs within R must // be fully contained by the pairs in this object. signop sign = TYPE_SIGN (m_type); unsigned ri = 0; unsigned i = 0; - wide_int rl = r.m_base[0]; + rl = r.m_base[0]; wide_int ru = r.m_base[1]; wide_int l = m_base[0]; wide_int u = m_base[1]; @@ -1973,6 +1981,16 @@ irange::intersect (const vrange &v) return res; } + // If either range is a singleton and the other range does not contain + // it, the result is undefined. + wide_int val; + if ((singleton_p (val) && !r.contains_p (val)) + || (r.singleton_p (val) && !contains_p (val))) + { + set_undefined (); + return true; + } + // If R fully contains this, then intersection will change nothing. if (r.irange_contains_p (*this)) return intersect_bitmask (r); @@ -2254,6 +2272,93 @@ irange::invert () verify_range (); } +// This routine will take the bounds [LB, UB], and apply the bitmask to those +// values such that both bounds satisfy the bitmask. TRUE is returned +// if either bound changes, and they are returned as [NEW_LB, NEW_UB]. +// if NEW_UB < NEW_LB, then the entire bound is to be removed as none of +// the values are valid. +// ie, [4, 14] MASK 0xFFFE VALUE 0x1 +// means all values must be odd, the new bounds returned will be [5, 13]. +// ie, [4, 4] MASK 0xFFFE VALUE 0x1 +// would return [1, 0] and as the LB < UB, the entire subrange is invalid +// and should be removed. + +bool +irange::snap (const wide_int &lb, const wide_int &ub, + wide_int &new_lb, wide_int &new_ub) +{ + int z = wi::ctz (m_bitmask.mask ()); + if (z == 0) + return false; + + const wide_int step = (wi::one (TYPE_PRECISION (type ())) << z); + const wide_int match_mask = step - 1; + const wide_int value = m_bitmask.value () & match_mask; + + bool ovf = false; + + wide_int rem_lb = lb & match_mask; + wide_int offset = (value - rem_lb) & match_mask; + new_lb = lb + offset; + // Check for overflows at +INF + if (wi::lt_p (new_lb, lb, TYPE_SIGN (type ()))) + ovf = true; + + wide_int rem_ub = ub & match_mask; + wide_int offset_ub = (rem_ub - value) & match_mask; + new_ub = ub - offset_ub; + // Check for underflows at -INF + if (wi::gt_p (new_ub, ub, TYPE_SIGN (type ()))) + ovf = true; + + // Overflow or inverted range = invalid + if (ovf || wi::lt_p (new_ub, new_lb, TYPE_SIGN (type ()))) + { + new_lb = wi::one (lb.get_precision ()); + new_ub = wi::zero (ub.get_precision ()); + return true; + } + return (new_lb != lb) || (new_ub != ub); +} + +// This method loops through the subranges in THIS, and adjusts any bounds +// to satisfy the contraints of the BITMASK. If a subrange is invalid, +// it is removed. TRUE is returned if there were any changes. + +bool +irange::snap_subranges () +{ + bool changed = false; + int_range_max invalid; + unsigned x; + wide_int lb, ub; + for (x = 0; x < m_num_ranges; x++) + { + if (snap (lower_bound (x), upper_bound (x), lb, ub)) + { + changed = true; + // This subrange is to be completely removed. + if (wi::lt_p (ub, lb, TYPE_SIGN (type ()))) + { + int_range<1> tmp (type (), lower_bound (x), upper_bound (x)); + invalid.union_ (tmp); + continue; + } + if (lower_bound (x) != lb) + m_base[x * 2] = lb; + if (upper_bound (x) != ub) + m_base[x * 2 + 1] = ub; + } + } + // Remove any subranges which are no invalid. + if (!invalid.undefined_p ()) + { + invalid.invert (); + intersect (invalid); + } + return changed; +} + // If the mask can be trivially converted to a range, do so. // Otherwise attempt to remove the lower bits from the range. // Return true if the range changed in any way. @@ -2268,7 +2373,11 @@ irange::set_range_from_bitmask () // If all the bits are known, this is a singleton. if (m_bitmask.mask () == 0) { - set (m_type, m_bitmask.value (), m_bitmask.value ()); + // Make sure the singleton is within the range. + if (contains_p (m_bitmask.value ())) + set (m_type, m_bitmask.value (), m_bitmask.value ()); + else + set_undefined (); return true; } @@ -2349,6 +2458,9 @@ irange::set_range_from_bitmask () // Make sure we call intersect, so do it first. changed = intersect (mask_range) | changed; + // Now make sure each subrange endpoint matches the bitmask. + changed |= snap_subranges (); + return changed; } @@ -2401,7 +2513,13 @@ irange::get_bitmask () const // See also the note in irange_bitmask::intersect. irange_bitmask bm (type (), lower_bound (), upper_bound ()); if (!m_bitmask.unknown_p ()) - bm.intersect (m_bitmask); + { + bm.intersect (m_bitmask); + // If the new intersection is unknown, it means there are inconstent + // bits, so simply return the original bitmask. + if (bm.unknown_p ()) + return m_bitmask; + } return bm; } @@ -2440,15 +2558,14 @@ irange::intersect_bitmask (const irange &r) irange_bitmask bm = get_bitmask (); irange_bitmask save = bm; bm.intersect (r.get_bitmask ()); - if (save == bm) - return false; - + // Use ths opportunity to make sure mask always reflects the + // best mask we have. m_bitmask = bm; // Updating m_bitmask may still yield a semantic bitmask (as // returned by get_bitmask) which is functionally equivalent to what // we originally had. In which case, there's still no change. - if (save == get_bitmask ()) + if (save == bm || save == get_bitmask ()) return false; if (!set_range_from_bitmask ()) @@ -2768,6 +2885,112 @@ range_tests_strict_enum () ASSERT_FALSE (ir1.varying_p ()); } +// Test that range bounds are "snapped" to where they are expected to be. + +static void +assert_snap_result (int lb_val, int ub_val, + int expected_lb, int expected_ub, + unsigned mask_val, unsigned value_val, + tree type) +{ + wide_int lb = wi::shwi (lb_val, TYPE_PRECISION (type)); + wide_int ub = wi::shwi (ub_val, TYPE_PRECISION (type)); + wide_int new_lb, new_ub; + + irange_bitmask bm (wi::uhwi (value_val, TYPE_PRECISION (type)), + wi::uhwi (mask_val, TYPE_PRECISION (type))); + + int_range_max r (type); + r.set (type, lb, ub); + r.update_bitmask (bm); + + if (TYPE_SIGN (type) == SIGNED && expected_ub < expected_lb) + gcc_checking_assert (r.undefined_p ()); + else if (TYPE_SIGN (type) == UNSIGNED + && ((unsigned)expected_ub < (unsigned)expected_lb)) + gcc_checking_assert (r.undefined_p ()); + else + { + gcc_checking_assert (wi::eq_p (r.lower_bound (), + wi::shwi (expected_lb, + TYPE_PRECISION (type)))); + gcc_checking_assert (wi::eq_p (r.upper_bound (), + wi::shwi (expected_ub, + TYPE_PRECISION (type)))); + } +} + + +// Run a selection of tests that confirm, bounds are snapped as expected. +// We only test individual pairs, multiple pairs use the same snapping +// routine as single pairs. + +static void +test_irange_snap_bounds () +{ + tree u32 = unsigned_type_node; + tree s32 = integer_type_node; + tree s8 = build_nonstandard_integer_type (8, /*unsigned=*/ 0); + tree s1 = build_nonstandard_integer_type (1, /*unsigned=*/ 0); + tree u1 = build_nonstandard_integer_type (1, /*unsigned=*/ 1); + + // Basic aligned range: even-only + assert_snap_result (5, 15, 6, 14, 0xFFFFFFFE, 0x0, u32); + // Singleton that doesn't match mask: undefined. + assert_snap_result (7, 7, 1, 0, 0xFFFFFFFE, 0x0, u32); + // 8-bit signed char, mask 0xF0 (i.e. step of 16). + assert_snap_result (-100, 100, -96, 96, 0xF0, 0x00, s8); + // Already aligned range: no change. + assert_snap_result (0, 240, 0, 240, 0xF0, 0x00, u32); + // Negative range, step 16 alignment (s32). + assert_snap_result (-123, -17, -112, -32, 0xFFFFFFF0, 0x00, s32); + // Negative range, step 16 alignment (trailing-zero aligned mask). + assert_snap_result (-123, -17, -112, -32, 0xFFFFFFF0, 0x00, s32); + // s8, 16-alignment mask, value = 0 (valid). + assert_snap_result (-50, 10, -48, 0, 0xF0, 0x00, s8); + // No values in range [-3,2] match alignment except 0. + assert_snap_result (-3, 2, 0, 0, 0xF8, 0x00, s8); + // No values in range [-3,2] match alignment — undefined. + assert_snap_result (-3, 2, 1, 0, 0xF8, 0x04, s8); + // Already aligned range: no change. + assert_snap_result (0, 240, 0, 240, 0xF0, 0x00, s32); + // 1-bit signed: only -1 allowed (0b1). + assert_snap_result (-1, 0, -1, -1, 0x00, 0x01, s1); + // 1-bit signed: only 0 allowed (0b0). + assert_snap_result (-1, 0, 0, 0, 0x00, 0x00, s1); + // 1-bit signed: no match (invalid case). + assert_snap_result (-1, -1, 1, 0, 0x00, 0x00, s1); + // 1-bit signed: no match (invalid case). + assert_snap_result (0, 0, 1, 0, 0x00, 0x01, s1); + // 1-bit unsigned: only 1 allowed. + assert_snap_result (0, 1, 1, 1, 0x00, 0x01, u1); + // 1-bit unsigned: only 0 allowed. + assert_snap_result (0, 1, 0, 0, 0x00, 0x00, u1); + // 1-bit unsigned: no match (invalid case). + assert_snap_result (1, 1, 1, 0, 0x00, 0x00, u1); + // 1-bit unsigned: no match (invalid case). + assert_snap_result (0, 0, 1, 0, 0x00, 0x01, u1); + // Unsigned: Near overflow, even alignment. + assert_snap_result (UINT_MAX - 6, UINT_MAX, UINT_MAX - 5, UINT_MAX - 1, + 0xFFFFFFFE, 0x00, u32); + // Unsigned: Wraparound-like range — no valid snapped values. + assert_snap_result (UINT_MAX - 5, UINT_MAX, 1, 0, 0xFFFFFFF0, 0x00, u32); + // Signed: Near INT_MAX, 8-aligned. + assert_snap_result (INT_MAX - 18, INT_MAX, INT_MAX - 15, INT_MAX - 7, + 0xFFFFFFF8, 0x00, s32); + // Signed: Near INT_MIN, 16-aligned. + assert_snap_result (INT_MIN, INT_MIN + 30, INT_MIN, INT_MIN + 16, + 0xFFFFFFF0, 0x00, s32); + // Signed: Full domain, 4-aligned. + assert_snap_result (-128, 127, -128, 124, 0xFC, 0x00, s8); + // Singleton at INT_MIN that doesn’t match alignment — undefined + assert_snap_result (INT_MIN, INT_MIN, 1, 0, 0xFFFFFFFE, 0x01, s32); + // Range at INT_MIN that doesn’t match alignment — undefined. + assert_snap_result (INT_MIN, INT_MIN + 10, 1, 0, 0xFFFFFFF0, 0x0F, s32); + // Unsigned: Full domain, 256-aligned. + assert_snap_result (0, UINT_MAX, 0, UINT_MAX & ~255, 0xFFFFFF00, 0x00, u32); +} + static void range_tests_misc () { @@ -3039,6 +3262,9 @@ range_tests_nonzero_bits () r0.set_zero (integer_type_node); r0.set_nonzero_bits (INT (1)); ASSERT_TRUE (r0.zero_p ()); + + // Now test that range bounds are snapped to match bitmask alignments. + test_irange_snap_bounds (); } // Build an frange from string endpoints. diff --git a/gcc/value-range.h b/gcc/value-range.h index 74cdf29ddcb3..3bc02db43a50 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -111,6 +111,7 @@ class vrange bool operator== (const vrange &) const; bool operator!= (const vrange &r) const { return !(*this == r); } void dump (FILE *) const; + virtual void verify_range () const { } protected: vrange (enum value_range_discriminator d) : m_discriminator (d) { } ENUM_BITFIELD(value_range_kind) m_kind : 8; @@ -323,6 +324,7 @@ class irange : public vrange virtual void update_bitmask (const class irange_bitmask &) override; virtual irange_bitmask get_bitmask () const override; + virtual void verify_range () const override; protected: void maybe_resize (int needed); virtual void set (tree, tree, value_range_kind = VR_RANGE) override; @@ -335,7 +337,6 @@ class irange : public vrange void normalize_kind (); - void verify_range (); // Hard limit on max ranges allowed. static const int HARD_MAX_RANGES = 255; @@ -344,6 +345,8 @@ class irange : public vrange bool intersect_bitmask (const irange &r); bool union_bitmask (const irange &r); bool set_range_from_bitmask (); + bool snap_subranges (); + bool snap (const wide_int &, const wide_int &, wide_int &, wide_int &); bool intersect (const wide_int& lb, const wide_int& ub); bool union_append (const irange &r); @@ -419,7 +422,7 @@ class prange final : public vrange bool contains_p (const wide_int &) const; wide_int lower_bound () const; wide_int upper_bound () const; - void verify_range () const; + virtual void verify_range () const final override; irange_bitmask get_bitmask () const final override; void update_bitmask (const irange_bitmask &) final override; protected: @@ -591,14 +594,13 @@ class frange final : public vrange bool nan_signbit_p (bool &signbit) const; bool known_isnormal () const; bool known_isdenormal_or_zero () const; - + virtual void verify_range () const override; protected: virtual bool contains_p (tree cst) const override; virtual void set (tree, tree, value_range_kind = VR_RANGE) override; private: bool internal_singleton_p (REAL_VALUE_TYPE * = NULL) const; - void verify_range (); bool normalize_kind (); bool union_nans (const frange &); bool intersect_nans (const frange &); @@ -796,6 +798,7 @@ class value_range void update_bitmask (const class irange_bitmask &bm) { return m_vrange->update_bitmask (bm); } void accept (const vrange_visitor &v) const { m_vrange->accept (v); } + void verify_range () const { m_vrange->verify_range (); } private: void init (tree type); void init (const vrange &); diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc index c7ced445ad76..2ac7650fe5b4 100644 --- a/gcc/value-relation.cc +++ b/gcc/value-relation.cc @@ -202,12 +202,6 @@ adjust_equivalence_range (vrange &range) } } -// This vector maps a relation to the equivalent tree code. - -static const tree_code relation_to_code [VREL_LAST] = { - ERROR_MARK, ERROR_MARK, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EQ_EXPR, - NE_EXPR }; - // Given an equivalence set EQUIV, set all the bits in B that are still valid // members of EQUIV in basic block BB. diff --git a/gcc/value-relation.h b/gcc/value-relation.h index 1081877ccca7..87f0d856fabd 100644 --- a/gcc/value-relation.h +++ b/gcc/value-relation.h @@ -235,7 +235,7 @@ class dom_oracle : public equiv_oracle void dump (FILE *f) const final override; protected: virtual relation_chain *next_relation (basic_block, relation_chain *, - tree) const; + tree) const override; bool m_do_trans_p; bitmap m_tmp, m_tmp2; bitmap m_relation_set; // Index by ssa-name. True if a relation exists diff --git a/gcc/varasm.cc b/gcc/varasm.cc index 10c1d2e31371..8384e8b635c7 100644 --- a/gcc/varasm.cc +++ b/gcc/varasm.cc @@ -1734,7 +1734,8 @@ assemble_asm (tree asm_str) constraints[i] = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail))); if (!parse_output_constraint (&constraints[i], i, ninputs, noutputs, - &allows_mem, &allows_reg, &is_inout)) + &allows_mem, &allows_reg, &is_inout, + nullptr)) goto done; if (is_inout) { @@ -1776,7 +1777,7 @@ assemble_asm (tree asm_str) = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail))); if (!parse_input_constraint (&constraints[i + noutputs], i, ninputs, noutputs, 0, constraints, - &allows_mem, &allows_reg)) + &allows_mem, &allows_reg, nullptr)) goto done; if (strchr (constraints[i], '%')) { diff --git a/gcc/vec.cc b/gcc/vec.cc index 55f5f3dd447c..38314d7360c4 100644 --- a/gcc/vec.cc +++ b/gcc/vec.cc @@ -176,6 +176,74 @@ dump_vec_loc_statistics (void) vec_mem_desc.dump (VEC_ORIGIN); } +/* Gets the next token from STR delimited by DELIMS (deliminator not included + in returned string). + + Updates STR to be the remaining string after the given token. + + STR and DELIMS must both be valid string_slices. + + If there aren't any of the chars in DELIM in STR (ie no more tokens in STR) + then returns the string, and updates STR to be invalid. */ +string_slice +string_slice::tokenize (string_slice *str, string_slice delims) +{ + const char *ptr = str->begin (); + + gcc_assert (str->is_valid () && delims.is_valid ()); + + for (; ptr < str->end (); ptr++) + for (char c : delims) + if (*ptr == c) + { + /* Update the input string to be the remaining string. */ + const char *str_begin = str->begin (); + *str = string_slice (ptr + 1, str->end ()); + return string_slice (str_begin, ptr); + } + + /* If no deliminators between the start and end, return the whole string. */ + string_slice res = *str; + *str = string_slice::invalid (); + return res; +} + +/* Compares the string_slices STR1 and STR2 giving a lexograpical ordering. + Returns -1 if STR1 comes before STR2, 1 if STR1 comes after, and 0 if the + string_slices have the same contents. */ + +int +string_slice::strcmp (string_slice str1, string_slice str2) +{ + for (unsigned int i = 0; i < str1.size () && i < str2.size (); i++) + { + if (str1[i] < str2[i]) + return -1; + if (str1[i] > str2[i]) + return 1; + } + + if (str1.size () < str2.size ()) + return -1; + if (str1.size () > str2.size ()) + return 1; + return 0; +} + +string_slice +string_slice::strip () +{ + const char *start = this->begin (); + const char *end = this->end (); + + while (start < end && ISSPACE (*start)) + start++; + while (end > start && ISSPACE (*(end-1))) + end--; + + return string_slice (start, end); +} + #if CHECKING_P /* Report qsort comparator CMP consistency check failure with P1, P2, P3 as witness elements. */ @@ -584,6 +652,159 @@ test_auto_alias () ASSERT_EQ (val, 0); } +static void +test_string_slice_initializers () +{ + string_slice str1 = string_slice (); + ASSERT_TRUE (str1.is_valid ()); + ASSERT_EQ (str1.size (), 0); + + string_slice str2 = string_slice ("Test string"); + ASSERT_TRUE (str2.is_valid ()); + ASSERT_EQ (str2.size (), 11); + + string_slice str3 = "Test string the second"; + ASSERT_TRUE (str3.is_valid ()); + ASSERT_EQ (str3.size (), 22); + + string_slice str4 = string_slice ("Test string", 4); + ASSERT_TRUE (str4.is_valid ()); + ASSERT_EQ (str4.size (), 4); +} + +static void +test_string_slice_tokenize () +{ + string_slice test_string_slice = ""; + string_slice test_delims = ","; + + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), ""); + ASSERT_FALSE (test_string_slice.is_valid ()); + + test_string_slice = ","; + test_delims = ","; + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), + string_slice ("")); + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), + string_slice ("")); + ASSERT_FALSE (test_string_slice.is_valid ()); + + test_string_slice = ",test.,.test, , test "; + test_delims = ",."; + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), ""); + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), "test"); + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), ""); + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), ""); + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), "test"); + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), " "); + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), + " test "); + ASSERT_FALSE (test_string_slice.is_valid ()); + + const char *test_string + = "This is the test string, it \0 is for testing, 123 ,,"; + test_string_slice = string_slice (test_string, 52); + test_delims = string_slice (",\0", 2); + + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), + "This is the test string"); + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), + " it "); + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), + " is for testing"); + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), + " 123 "); + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), + ""); + ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), + ""); + ASSERT_FALSE (test_string_slice.is_valid ()); +} + +static void +test_string_slice_strcmp () +{ + ASSERT_EQ (string_slice::strcmp (string_slice (), + string_slice ()), 0); + ASSERT_EQ (string_slice::strcmp (string_slice ("test"), + string_slice ()), 1); + ASSERT_EQ (string_slice::strcmp (string_slice (), + string_slice ("test")), -1); + ASSERT_EQ (string_slice::strcmp (string_slice ("test"), + string_slice ("test")), 0); + ASSERT_EQ (string_slice::strcmp (string_slice ("a"), + string_slice ("b")), -1); + ASSERT_EQ (string_slice::strcmp (string_slice ("b"), + string_slice ("a")), 1); + ASSERT_EQ (string_slice::strcmp (string_slice ("ab", 1), + string_slice ("a")), 0); + ASSERT_EQ (string_slice::strcmp (string_slice ("ab", 2), + string_slice ("a")), 1); +} + +static void +test_string_slice_equality () +{ + ASSERT_TRUE (string_slice () == string_slice ()); + ASSERT_FALSE (string_slice ("test") == string_slice ()); + ASSERT_FALSE ("test" == string_slice ()); + ASSERT_FALSE (string_slice () == string_slice ("test")); + ASSERT_FALSE (string_slice () == "test"); + ASSERT_TRUE (string_slice ("test") == string_slice ("test")); + ASSERT_TRUE ("test" == string_slice ("test")); + ASSERT_TRUE (string_slice ("test") == "test"); + ASSERT_FALSE (string_slice ("a") == string_slice ("b")); + ASSERT_FALSE ("a" == string_slice ("b")); + ASSERT_FALSE (string_slice ("a") == "b"); + ASSERT_FALSE (string_slice ("b") == string_slice ("a")); + ASSERT_TRUE (string_slice ("ab", 1) == string_slice ("a")); + ASSERT_TRUE (string_slice ("ab", 1) == "a"); + ASSERT_FALSE (string_slice ("ab", 2) == string_slice ("a")); + ASSERT_FALSE (string_slice ("ab", 2) == "a"); +} + +static void +test_string_slice_inequality () +{ + ASSERT_FALSE (string_slice () != string_slice ()); + ASSERT_TRUE (string_slice ("test") != string_slice ()); + ASSERT_TRUE ("test" != string_slice ()); + ASSERT_TRUE (string_slice () != string_slice ("test")); + ASSERT_TRUE (string_slice () != "test"); + ASSERT_FALSE (string_slice ("test") != string_slice ("test")); + ASSERT_FALSE ("test" != string_slice ("test")); + ASSERT_FALSE (string_slice ("test") != "test"); + ASSERT_TRUE (string_slice ("a") != string_slice ("b")); + ASSERT_TRUE ("a" != string_slice ("b")); + ASSERT_TRUE (string_slice ("a") != "b"); + ASSERT_TRUE (string_slice ("b") != string_slice ("a")); + ASSERT_FALSE (string_slice ("ab", 1) != string_slice ("a")); + ASSERT_FALSE (string_slice ("ab", 1) != "a"); + ASSERT_TRUE (string_slice ("ab", 2) != string_slice ("a")); + ASSERT_TRUE (string_slice ("ab", 2) != "a"); +} + +static void +test_string_slice_invalid () +{ + ASSERT_FALSE (string_slice::invalid ().is_valid ()); + ASSERT_FALSE (string_slice (NULL, 1).is_valid ()); + ASSERT_TRUE (string_slice (NULL, (size_t) 0).is_valid ()); + ASSERT_TRUE (string_slice ("Test", (size_t) 0).is_valid ()); + ASSERT_TRUE (string_slice ().is_valid ()); +} + +static void +test_string_slice_strip () +{ + ASSERT_EQ (string_slice (" test ").strip (), string_slice ("test")); + ASSERT_EQ (string_slice ("\t test string\t \n ").strip (), + string_slice ("test string")); + ASSERT_EQ (string_slice ("test").strip (), string_slice ("test")); + ASSERT_EQ (string_slice ().strip (), string_slice ()); + ASSERT_EQ (string_slice ("\t \n \t ").strip (), string_slice ()); +} + /* Run all of the selftests within this file. */ void @@ -604,6 +825,13 @@ vec_cc_tests () test_reverse (); test_auto_delete_vec (); test_auto_alias (); + test_string_slice_initializers (); + test_string_slice_tokenize (); + test_string_slice_strcmp (); + test_string_slice_equality (); + test_string_slice_inequality (); + test_string_slice_invalid (); + test_string_slice_strip (); } } // namespace selftest diff --git a/gcc/vec.h b/gcc/vec.h index 7e112d1a80a6..9604edb1c3cf 100644 --- a/gcc/vec.h +++ b/gcc/vec.h @@ -2495,4 +2495,50 @@ make_array_slice (T *base, unsigned int size) # pragma GCC poison m_vec m_vecpfx m_vecdata #endif +/* string_slice inherits from array_slice, specifically to refer to a substring + of a character array. + It includes some string like helpers. */ +class string_slice : public array_slice +{ +public: + string_slice () : array_slice () {} + string_slice (const char *str) : array_slice (str, strlen (str)) {} + explicit string_slice (const char *str, size_t len) + : array_slice (str, len) {} + explicit string_slice (const char *start, const char *end) + : array_slice (start, end - start) {} + + friend bool operator== (const string_slice &lhs, const string_slice &rhs) + { + if (!lhs.is_valid () || !rhs.is_valid ()) + return false; + if (lhs.size () != rhs.size ()) + return false; + return memcmp (lhs.begin (), rhs.begin (), lhs.size ()) == 0; + } + + friend bool operator!= (const string_slice &lhs, const string_slice &rhs) + { + return !(lhs == rhs); + } + + /* Returns an invalid string_slice. */ + static string_slice invalid () + { + return string_slice (nullptr, ~0U); + } + + /* tokenize is used to split a string by some deliminator into + string_slice's. Similarly to the posix strtok_r.but without modifying the + input string, and returning all tokens which may be empty in the case + of an empty input string of consecutive deliminators. */ + static string_slice tokenize (string_slice *str, string_slice delims); + + /* Removes white space from the front and back of the string_slice. */ + string_slice strip (); + + /* Compares two string_slices in lexographical ordering. */ + static int strcmp (string_slice str1, string_slice str2); +}; + #endif // GCC_VEC_H diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc index 4c787593b95a..ff11656559bf 100644 --- a/gcc/vr-values.cc +++ b/gcc/vr-values.cc @@ -513,85 +513,6 @@ simplify_using_ranges::legacy_fold_cond (gcond *stmt, edge *taken_edge_p) } } -/* Searches the case label vector VEC for the ranges of CASE_LABELs that are - used in range VR. The indices are placed in MIN_IDX1, MAX_IDX, MIN_IDX2 and - MAX_IDX2. If the ranges of CASE_LABELs are empty then MAX_IDX1 < MIN_IDX1. - Returns true if the default label is not needed. */ - -static bool -find_case_label_ranges (gswitch *stmt, const irange *vr, - size_t *min_idx1, size_t *max_idx1, - size_t *min_idx2, size_t *max_idx2) -{ - size_t i, j, k, l; - unsigned int n = gimple_switch_num_labels (stmt); - bool take_default; - tree case_low, case_high; - tree min, max; - value_range_kind kind = get_legacy_range (*vr, min, max); - - gcc_checking_assert (!vr->varying_p () && !vr->undefined_p ()); - - take_default = !find_case_label_range (stmt, min, max, &i, &j); - - /* Set second range to empty. */ - *min_idx2 = 1; - *max_idx2 = 0; - - if (kind == VR_RANGE) - { - *min_idx1 = i; - *max_idx1 = j; - return !take_default; - } - - /* Set first range to all case labels. */ - *min_idx1 = 1; - *max_idx1 = n - 1; - - if (i > j) - return false; - - /* Make sure all the values of case labels [i , j] are contained in - range [MIN, MAX]. */ - case_low = CASE_LOW (gimple_switch_label (stmt, i)); - case_high = CASE_HIGH (gimple_switch_label (stmt, j)); - if (tree_int_cst_compare (case_low, min) < 0) - i += 1; - if (case_high != NULL_TREE - && tree_int_cst_compare (max, case_high) < 0) - j -= 1; - - if (i > j) - return false; - - /* If the range spans case labels [i, j], the corresponding anti-range spans - the labels [1, i - 1] and [j + 1, n - 1]. */ - k = j + 1; - l = n - 1; - if (k > l) - { - k = 1; - l = 0; - } - - j = i - 1; - i = 1; - if (i > j) - { - i = k; - j = l; - k = 1; - l = 0; - } - - *min_idx1 = i; - *max_idx1 = j; - *min_idx2 = k; - *max_idx2 = l; - return false; -} - /* Simplify boolean operations if the source is known to be already a boolean. */ bool @@ -1023,6 +944,10 @@ range_fits_type_p (const irange *vr, widest_int tem; signop src_sgn; + /* Now we can only handle ranges with constant bounds. */ + if (vr->undefined_p () || vr->varying_p ()) + return false; + /* We can only handle integral and pointer types. */ src_type = vr->type (); if (!INTEGRAL_TYPE_P (src_type) @@ -1031,17 +956,13 @@ range_fits_type_p (const irange *vr, /* An extension is fine unless VR is SIGNED and dest_sgn is UNSIGNED, and so is an identity transform. */ - src_precision = TYPE_PRECISION (vr->type ()); + src_precision = TYPE_PRECISION (src_type); src_sgn = TYPE_SIGN (src_type); if ((src_precision < dest_precision && !(dest_sgn == UNSIGNED && src_sgn == SIGNED)) || (src_precision == dest_precision && src_sgn == dest_sgn)) return true; - /* Now we can only handle ranges with constant bounds. */ - if (vr->undefined_p () || vr->varying_p ()) - return false; - wide_int vrmin = vr->lower_bound (); wide_int vrmax = vr->upper_bound (); @@ -1374,157 +1295,99 @@ bool simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt) { tree op = gimple_switch_index (stmt); - int_range_max vr; - bool take_default; + tree type = TREE_TYPE (op); + int_range_max op_range (type); + int_range_max default_range (type); + auto_vec cases; + cases.truncate (0); edge e; - edge_iterator ei; - size_t i = 0, j = 0, n, n2; - tree vec2; switch_update su; - size_t k = 1, l = 0; - - if (TREE_CODE (op) == SSA_NAME) - { - if (!query->range_of_expr (vr, op, stmt) - || vr.varying_p () || vr.undefined_p ()) - return false; - /* Find case label for min/max of the value range. */ - take_default = !find_case_label_ranges (stmt, &vr, &i, &j, &k, &l); - } - else if (TREE_CODE (op) == INTEGER_CST) - { - take_default = !find_case_label_index (stmt, 1, op, &i); - if (take_default) - { - i = 1; - j = 0; - } - else - { - j = i; - } - } - else + // Abort if we don't have a useful range for the switch index. + if (!query->range_of_expr (op_range, op, stmt) + || op_range.varying_p () || op_range.undefined_p ()) return false; - n = gimple_switch_num_labels (stmt); + // Default range starts with full known range of op. + default_range = op_range; + edge default_edge = gimple_switch_default_edge (cfun, stmt); - /* We can truncate the case label ranges that partially overlap with OP's - value range. */ - size_t min_idx = 1, max_idx = 0; - tree min, max; - value_range_kind kind = get_legacy_range (vr, min, max); - if (!vr.undefined_p ()) - find_case_label_range (stmt, min, max, &min_idx, &max_idx); - if (min_idx <= max_idx) + unsigned x, lim = gimple_switch_num_labels (stmt); + for (x = 1; x < lim; x++) { - tree min_label = gimple_switch_label (stmt, min_idx); - tree max_label = gimple_switch_label (stmt, max_idx); + e = gimple_switch_edge (cfun, stmt, x); + tree label = gimple_switch_label (stmt, x); + + // If this edge is the same as the default edge, do nothing else. + if (e == default_edge) + continue; + // Ada sometimes has mismatched labels and index. Just bail. + if (TREE_TYPE (CASE_LOW (label)) != type) + return false; - /* Avoid changing the type of the case labels when truncating. */ - tree case_label_type = TREE_TYPE (CASE_LOW (min_label)); - tree vr_min = fold_convert (case_label_type, min); - tree vr_max = fold_convert (case_label_type, max); + wide_int low = wi::to_wide (CASE_LOW (label)); + wide_int high; + // Singleton cases have no CASE_HIGH. + tree tree_high = CASE_HIGH (label); + if (tree_high) + high = wi::to_wide (tree_high); + else + high = low; - if (kind == VR_RANGE) + // If the case range is fully contained in op_range, leave the + // case as it is, otherwise adjust the labels. + int_range_max case_range (type, low, high); + if (case_range.intersect (op_range)) { - /* If OP's value range is [2,8] and the low label range is - 0 ... 3, truncate the label's range to 2 .. 3. */ - if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0 - && CASE_HIGH (min_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (min_label), vr_min) >= 0) - CASE_LOW (min_label) = vr_min; - - /* If OP's value range is [2,8] and the high label range is - 7 ... 10, truncate the label's range to 7 .. 8. */ - if (tree_int_cst_compare (CASE_LOW (max_label), vr_max) <= 0 - && CASE_HIGH (max_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0) - CASE_HIGH (max_label) = vr_max; - } - else if (kind == VR_ANTI_RANGE) - { - tree one_cst = build_one_cst (case_label_type); - - if (min_label == max_label) - { - /* If OP's value range is ~[7,8] and the label's range is - 7 ... 10, truncate the label's range to 9 ... 10. */ - if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) == 0 - && CASE_HIGH (min_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (min_label), vr_max) > 0) - CASE_LOW (min_label) - = int_const_binop (PLUS_EXPR, vr_max, one_cst); - - /* If OP's value range is ~[7,8] and the label's range is - 5 ... 8, truncate the label's range to 5 ... 6. */ - if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0 - && CASE_HIGH (min_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (min_label), vr_max) == 0) - CASE_HIGH (min_label) - = int_const_binop (MINUS_EXPR, vr_min, one_cst); - } + // If none of the label is in op_range, skip this label. + if (case_range.undefined_p ()) + continue; + + // Part of the label is in op_range, but not all of it. CASE_RANGE + // contains the part that is. Adjust the case range to + // the new min/max. + if (case_range.lower_bound () != low) + CASE_LOW (label) = wide_int_to_tree (type, + case_range.lower_bound ()); + if (case_range.singleton_p ()) + CASE_HIGH (label) = NULL_TREE; else - { - /* If OP's value range is ~[2,8] and the low label range is - 0 ... 3, truncate the label's range to 0 ... 1. */ - if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0 - && CASE_HIGH (min_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (min_label), vr_min) >= 0) - CASE_HIGH (min_label) - = int_const_binop (MINUS_EXPR, vr_min, one_cst); - - /* If OP's value range is ~[2,8] and the high label range is - 7 ... 10, truncate the label's range to 9 ... 10. */ - if (tree_int_cst_compare (CASE_LOW (max_label), vr_max) <= 0 - && CASE_HIGH (max_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0) - CASE_LOW (max_label) - = int_const_binop (PLUS_EXPR, vr_max, one_cst); - } + if (case_range.upper_bound () != high) + CASE_HIGH (label) = wide_int_to_tree (type, + case_range.upper_bound ()); } - - /* Canonicalize singleton case ranges. */ - if (tree_int_cst_equal (CASE_LOW (min_label), CASE_HIGH (min_label))) - CASE_HIGH (min_label) = NULL_TREE; - if (tree_int_cst_equal (CASE_LOW (max_label), CASE_HIGH (max_label))) - CASE_HIGH (max_label) = NULL_TREE; + // Add case label to the keep list. + cases.safe_push (x); + // Remove case_range from needing to be handled by the default. + case_range.invert (); + default_range.intersect (case_range); } - /* We can also eliminate case labels that lie completely outside OP's value - range. */ - - /* Bail out if this is just all edges taken. */ - if (i == 1 - && j == n - 1 - && take_default) + // An undefined DEFAULT range means the current default case is not needed. + unsigned idx = default_range.undefined_p () ? 0 : 1; + unsigned vec_size = cases.length () + idx; + if (vec_size == lim) return false; - /* Build a new vector of taken case labels. */ - vec2 = make_tree_vec (j - i + 1 + l - k + 1 + (int)take_default); - n2 = 0; - - /* Add the default edge, if necessary. */ - if (take_default) - TREE_VEC_ELT (vec2, n2++) = gimple_switch_default_label (stmt); - - for (; i <= j; ++i, ++n2) - TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, i); - - for (; k <= l; ++k, ++n2) - TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, k); + tree vec2 = make_tree_vec (vec_size); + // Add default label if there is one. + if (idx) + { + TREE_VEC_ELT (vec2, 0) = gimple_switch_default_label (stmt); + e = gimple_switch_edge (cfun, stmt, 0); + e->aux = (void *)-1; + } - /* Mark needed edges. */ - for (i = 0; i < n2; ++i) + for (x = 0; x < cases.length (); x++) { - e = find_edge (gimple_bb (stmt), - label_to_block (cfun, - CASE_LABEL (TREE_VEC_ELT (vec2, i)))); - e->aux = (void *)-1; + unsigned swi = cases[x]; + TREE_VEC_ELT (vec2, idx++) = gimple_switch_label (stmt, swi); + e = gimple_switch_edge (cfun, stmt, swi); + e->aux = (void *)-1; } /* Queue not needed edges for later removal. */ + edge_iterator ei; FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs) { if (e->aux == (void *)-1) diff --git a/gcc/xml-printer.h b/gcc/xml-printer.h index b90390cb0f6e..428da0a4245d 100644 --- a/gcc/xml-printer.h +++ b/gcc/xml-printer.h @@ -32,18 +32,19 @@ class node; class printer { public: - printer (element &insertion_point); + printer (element &insertion_point, bool check_popped_tags = true); void push_tag (std::string name, bool preserve_whitespace = false); void push_tag_with_class (std::string name, std::string class_, bool preserve_whitespace = false); - void pop_tag (); + void pop_tag (const char *expected_name); void set_attr (const char *name, std::string value); void add_text (std::string text); + void add_text_from_pp (pretty_printer &pp); void add_raw (std::string text); @@ -53,9 +54,38 @@ class printer element *get_insertion_point () const; + size_t get_num_open_tags () const { return m_open_tags.size (); } + + void DEBUG_FUNCTION dump () const; + private: // borrowed ptrs: std::vector m_open_tags; + bool m_check_popped_tags; +}; + +/* RAII class for ensuring that the tags nested correctly. + Verify that within an instance's lifetime that any pushes + to the printer's insertion point have been popped by the end. */ + +class auto_check_tag_nesting +{ +public: + auto_check_tag_nesting (const printer &xp) + : m_xp (xp), + m_initial_insertion_element (xp.get_insertion_point ()) + { + } + ~auto_check_tag_nesting () + { + /* Verify that we didn't pop too many tags within the printer, + or leave any tags open. */ + gcc_assert (m_initial_insertion_element == m_xp.get_insertion_point ()); + } + +private: + const printer &m_xp; + const element *m_initial_insertion_element; }; // RAII for push/pop element on xml::printer @@ -66,17 +96,19 @@ class auto_print_element auto_print_element (printer &printer, std::string name, bool preserve_whitespace = false) - : m_printer (printer) + : m_printer (printer), + m_name (std::move (name)) { - m_printer.push_tag (name, preserve_whitespace); + m_printer.push_tag (m_name, preserve_whitespace); } ~auto_print_element () { - m_printer.pop_tag (); + m_printer.pop_tag (m_name.c_str ()); } private: printer &m_printer; + std::string m_name; }; } // namespace xml diff --git a/gcc/xml.cc b/gcc/xml.cc new file mode 100644 index 000000000000..8e11c6783425 --- /dev/null +++ b/gcc/xml.cc @@ -0,0 +1,476 @@ +/* XML support for diagnostics. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + Contributed by David Malcolm . + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#define INCLUDE_MAP +#define INCLUDE_STRING +#define INCLUDE_VECTOR +#include "system.h" +#include "coretypes.h" +#include "xml.h" +#include "xml-printer.h" +#include "pretty-print.h" +#include "selftest.h" +#include "selftest-xml.h" + +namespace xml { + +/* Disable warnings about quoting issues in the pp_xxx calls below + that (intentionally) don't follow GCC diagnostic conventions. */ +#if __GNUC__ >= 10 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wformat-diag" +#endif + + +/* Implementation. */ + +static void +write_escaped_text (pretty_printer *pp, const char *text) +{ + gcc_assert (text); + + for (const char *p = text; *p; ++p) + { + char ch = *p; + switch (ch) + { + default: + pp_character (pp, ch); + break; + case '\'': + pp_string (pp, "'"); + break; + case '"': + pp_string (pp, """); + break; + case '&': + pp_string (pp, "&"); + break; + case '<': + pp_string (pp, "<"); + break; + case '>': + pp_string (pp, ">"); + break; + } + } +} + +/* struct node. */ + +void +node::dump (FILE *out) const +{ + pretty_printer pp; + pp.set_output_stream (out); + write_as_xml (&pp, 0, true); + pp_flush (&pp); +} + +/* struct text : public node. */ + +void +text::write_as_xml (pretty_printer *pp, int depth, bool indent) const +{ + if (indent) + { + for (int i = 0; i < depth; ++i) + pp_string (pp, " "); + } + write_escaped_text (pp, m_str.c_str ()); + if (indent) + pp_newline (pp); +} + +/* struct node_with_children : public node. */ + +void +node_with_children::add_child (std::unique_ptr node) +{ + gcc_assert (node.get ()); + m_children.push_back (std::move (node)); +} + +void +node_with_children::add_text (std::string str) +{ + // Consolidate runs of text + if (!m_children.empty ()) + if (text *t = m_children.back ()->dyn_cast_text ()) + { + t->m_str += std::move (str); + return; + } + add_child (std::make_unique (std::move (str))); +} + +void +node_with_children::add_text_from_pp (pretty_printer &pp) +{ + add_text (pp_formatted_text (&pp)); +} + +void +node_with_children::add_comment (std::string str) +{ + add_child (std::make_unique (std::move (str))); +} + +element * +node_with_children::find_child_element (std::string kind) const +{ + for (auto &iter : m_children) + if (element *e = iter->dyn_cast_element ()) + if (e->m_kind == kind) + return e; + return nullptr; +} + +/* struct document : public node_with_children. */ + +void +document::write_as_xml (pretty_printer *pp, int depth, bool indent) const +{ + pp_string (pp, "\n"); + if (m_doctypedecl) + m_doctypedecl->write_as_xml (pp, depth, indent); + for (auto &iter : m_children) + iter->write_as_xml (pp, depth, indent); +} + +/* struct element : public node_with_children. */ + +void +element::write_as_xml (pretty_printer *pp, int depth, bool indent) const +{ + if (indent) + { + for (int i = 0; i < depth; ++i) + pp_string (pp, " "); + } + + pp_printf (pp, "<%s", m_kind.c_str ()); + for (auto &key : m_key_insertion_order) + { + auto iter = m_attributes.find (key); + if (iter != m_attributes.end ()) + { + pp_printf (pp, " %s=\"", key.c_str ()); + write_escaped_text (pp, iter->second.c_str ()); + pp_string (pp, "\""); + } + } + if (m_children.empty ()) + pp_string (pp, "/>"); + else + { + const bool indent_children = m_preserve_whitespace ? false : indent; + pp_string (pp, ">"); + if (indent_children) + pp_newline (pp); + for (auto &child : m_children) + child->write_as_xml (pp, depth + 1, indent_children); + if (indent_children) + { + for (int i = 0; i < depth; ++i) + pp_string (pp, " "); + } + pp_printf (pp, "", m_kind.c_str ()); + } + + if (indent) + pp_newline (pp); +} + +void +element::set_attr (const char *name, std::string value) +{ + auto iter = m_attributes.find (name); + if (iter == m_attributes.end ()) + m_key_insertion_order.push_back (name); + m_attributes[name] = std::move (value); +} + +const char * +element::get_attr (const char *name) const +{ + auto iter = m_attributes.find (name); + if (iter == m_attributes.end ()) + return nullptr; + return iter->second.c_str (); +} + +// struct comment : public node + +void +comment::write_as_xml (pretty_printer *pp, + int depth, bool indent) const +{ + if (indent) + { + for (int i = 0; i < depth; ++i) + pp_string (pp, " "); + } + pp_string (pp, ""); + if (indent) + pp_newline (pp); +} + +// struct raw : public node + +void +raw::write_as_xml (pretty_printer *pp, + int /*depth*/, bool /*indent*/) const +{ + pp_string (pp, m_xml_src.c_str ()); +} + +// class printer + +printer::printer (element &insertion_point, + bool check_popped_tags) +: m_check_popped_tags (check_popped_tags) +{ + m_open_tags.push_back (&insertion_point); +} + +void +printer::push_tag (std::string name, + bool preserve_whitespace) +{ + push_element + (std::make_unique (std::move (name), + preserve_whitespace)); +} + +void +printer::push_tag_with_class (std::string name, std::string class_, + bool preserve_whitespace) +{ + auto new_element + = std::make_unique (std::move (name), + preserve_whitespace); + new_element->set_attr ("class", class_); + push_element (std::move (new_element)); +} + +/* Pop the current topmost tag. + If m_check_popped_tags, assert that the tag we're popping is + EXPECTED_NAME. */ + +void +printer::pop_tag (const char *expected_name ATTRIBUTE_UNUSED) +{ + gcc_assert (!m_open_tags.empty ()); + if (m_check_popped_tags) + gcc_assert (expected_name == get_insertion_point ()->m_kind); + m_open_tags.pop_back (); +} + +void +printer::set_attr (const char *name, std::string value) +{ + m_open_tags.back ()->set_attr (name, value); +} + +void +printer::add_text (std::string text) +{ + element *parent = m_open_tags.back (); + parent->add_text (std::move (text)); +} + +void +printer::add_text_from_pp (pretty_printer &pp) +{ + element *parent = m_open_tags.back (); + parent->add_text_from_pp (pp); +} + +void +printer::add_raw (std::string text) +{ + element *parent = m_open_tags.back (); + parent->add_child (std::make_unique (std::move (text))); +} + +void +printer::push_element (std::unique_ptr new_element) +{ + gcc_assert (new_element.get ()); + element *parent = m_open_tags.back (); + m_open_tags.push_back (new_element.get ()); + parent->add_child (std::move (new_element)); +} + +void +printer::append (std::unique_ptr new_node) +{ + gcc_assert (new_node.get ()); + element *parent = m_open_tags.back (); + parent->add_child (std::move (new_node)); +} + +element * +printer::get_insertion_point () const +{ + return m_open_tags.back (); +} + +void +printer::dump () const +{ + pretty_printer pp; + pp.set_output_stream (stderr); + pp_printf (&pp, "open tags: %i:", (int)m_open_tags.size ()); + for (auto iter : m_open_tags) + pp_printf (&pp, " <%s>", iter->m_kind.c_str ()); + pp_newline (&pp); + pp_printf (&pp, "xml:"); + pp_newline (&pp); + m_open_tags[0]->write_as_xml (&pp, 1, true); + pp_flush (&pp); +} + +#if __GNUC__ >= 10 +# pragma GCC diagnostic pop +#endif + +} // namespace xml + +#if CHECKING_P + +namespace selftest { + +void +assert_xml_print_eq (const location &loc, + const xml::node &node, + const char *expected_value) +{ + pretty_printer pp; + node.write_as_xml (&pp, 0, true); + ASSERT_STREQ_AT (loc, pp_formatted_text (&pp), expected_value); +} + +static void +test_no_dtd () +{ + xml::document doc; + ASSERT_XML_PRINT_EQ + (doc, + "\n"); +} + +static void +test_printer () +{ + xml::element top ("top", false); + xml::printer xp (top); + xp.push_tag ("foo"); + xp.add_text ("hello"); + xp.push_tag ("bar"); + xp.set_attr ("size", "3"); + xp.set_attr ("color", "red"); + xp.add_text ("world"); + xp.push_tag ("baz"); + xp.pop_tag ("baz"); + xp.pop_tag ("bar"); + xp.pop_tag ("foo"); + + ASSERT_XML_PRINT_EQ + (top, + "\n" + " \n" + " hello\n" + " \n" + " world\n" + " \n" + " \n" + " \n" + "\n"); + + xml::element *foo = top.find_child_element ("foo"); + ASSERT_TRUE (foo); + ASSERT_EQ (top.find_child_element ("not-foo"), nullptr); + xml::element *bar = foo->find_child_element ("bar"); + ASSERT_TRUE (bar); + ASSERT_STREQ (bar->get_attr ("size"), "3"); + ASSERT_STREQ (bar->get_attr ("color"), "red"); + ASSERT_EQ (bar->get_attr ("airspeed-velocity"), nullptr); +} + +// Verify that element attributes preserve insertion order. + +static void +test_attribute_ordering () +{ + xml::element top ("top", false); + xml::printer xp (top); + xp.push_tag ("chronological"); + xp.set_attr ("maldon", "991"); + xp.set_attr ("hastings", "1066"); + xp.set_attr ("edgehill", "1642"); + xp.set_attr ("naseby", "1645"); + xp.pop_tag ("chronological"); + xp.push_tag ("alphabetical"); + xp.set_attr ("edgehill", "1642"); + xp.set_attr ("hastings", "1066"); + xp.set_attr ("maldon", "991"); + xp.set_attr ("naseby", "1645"); + xp.pop_tag ("alphabetical"); + + ASSERT_XML_PRINT_EQ + (top, + "\n" + " \n" + " \n" + "\n"); +} + +static void +test_comment () +{ + xml::document doc; + doc.add_comment ("hello"); + doc.add_comment ("world"); + ASSERT_XML_PRINT_EQ + (doc, + "\n" + "\n" + "\n"); + +} +/* Run all of the selftests within this file. */ + +void +xml_cc_tests () +{ + test_no_dtd (); + test_printer (); + test_attribute_ordering (); + test_comment (); +} + +} // namespace selftest + +#endif /* CHECKING_P */ diff --git a/gcc/xml.h b/gcc/xml.h index 523a44dd146f..15591290c7d7 100644 --- a/gcc/xml.h +++ b/gcc/xml.h @@ -29,6 +29,9 @@ struct node; struct node_with_children; struct document; struct element; + struct doctypedecl; + struct comment; + struct raw; struct node { @@ -37,7 +40,11 @@ struct node int depth, bool indent) const = 0; virtual text *dyn_cast_text () { - return 0; + return nullptr; + } + virtual element *dyn_cast_element () + { + return nullptr; } void dump (FILE *out) const; void DEBUG_FUNCTION dump () const { dump (stderr); } @@ -64,6 +71,10 @@ struct node_with_children : public node { void add_child (std::unique_ptr node); void add_text (std::string str); + void add_text_from_pp (pretty_printer &pp); + void add_comment (std::string str); + + element *find_child_element (std::string kind) const; std::vector> m_children; }; @@ -72,6 +83,13 @@ struct document : public node_with_children { void write_as_xml (pretty_printer *pp, int depth, bool indent) const final override; + + std::unique_ptr m_doctypedecl; +}; + +struct doctypedecl : public node +{ + // still abstract }; struct element : public node_with_children @@ -81,10 +99,16 @@ struct element : public node_with_children m_preserve_whitespace (preserve_whitespace) {} + element *dyn_cast_element () final override + { + return this; + } + void write_as_xml (pretty_printer *pp, int depth, bool indent) const final override; void set_attr (const char *name, std::string value); + const char *get_attr (const char *name) const; std::string m_kind; bool m_preserve_whitespace; @@ -92,6 +116,21 @@ struct element : public node_with_children std::vector m_key_insertion_order; }; +/* An XML comment. */ + +struct comment : public node +{ + comment (std::string text) + : m_text (std::move (text)) + { + } + + void write_as_xml (pretty_printer *pp, + int depth, bool indent) const final override; + + std::string m_text; +}; + /* A fragment of raw XML source, to be spliced in directly. Use sparingly. */ diff --git a/gnattools/ChangeLog b/gnattools/ChangeLog index d7e28ab48c8a..0e5efb89193b 100644 --- a/gnattools/ChangeLog +++ b/gnattools/ChangeLog @@ -1,3 +1,13 @@ +2025-06-22 Nicolas Boulenguez + + PR ada/120106 + * configure.ac: Remove ACX_NONCANONICAL_HOST and add ACX_PROG_GNAT. + * configure: Regenerate. + * Makefile.in: Do not substitute host_noncanonical but substitute + GNATMAKE and GNATBIND. + Set GNAT{MAKE,BIND,LINK_LS}_FOR_HOST from GNAT{MAKE,BIND} instead + of using hardcoded commands. + 2025-04-01 Eric Botcazou PR ada/119440 diff --git a/gnattools/Makefile.in b/gnattools/Makefile.in index 996e600c196e..98f1f75bdcca 100644 --- a/gnattools/Makefile.in +++ b/gnattools/Makefile.in @@ -33,7 +33,8 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ # Nonstandard autoconf-set variables. LN_S=@LN_S@ target_noncanonical=@target_noncanonical@ -host_noncanonical=@host_noncanonical@ +GNATMAKE=@GNATMAKE@ +GNATBIND=@GNATBIND@ # Variables for the user (or the top level) to override. exeext = @EXEEXT@ @@ -115,17 +116,11 @@ TOOLS_FLAGS_TO_PASS_RE= \ "TOOLSCASE=cross" # Variables for gnattools, cross -ifeq ($(build), $(host)) - GNATMAKE_FOR_HOST=gnatmake - GNATLINK_FOR_HOST=gnatlink - GNATBIND_FOR_HOST=gnatbind - GNATLS_FOR_HOST=gnatls -else - GNATMAKE_FOR_HOST=$(host_noncanonical)-gnatmake - GNATLINK_FOR_HOST=$(host_noncanonical)-gnatlink - GNATBIND_FOR_HOST=$(host_noncanonical)-gnatbind - GNATLS_FOR_HOST=$(host_noncanonical)-gnatls -endif +# See configure.ac for what "cross" means here. +GNATMAKE_FOR_HOST = $(GNATMAKE) +GNATBIND_FOR_HOST = $(GNATBIND) +GNATLINK_FOR_HOST = $(subst gnatmake,gnatlink,$(GNATMAKE)) +GNATLS_FOR_HOST = $(subst gnatmake,gnatls,$(GNATMAKE)) # Put the host RTS dir first in the PATH to hide the default runtime # files that are among the sources diff --git a/gnattools/configure b/gnattools/configure index 1eb0debc2ce7..b3b6aab1b72e 100755 --- a/gnattools/configure +++ b/gnattools/configure @@ -588,6 +588,13 @@ default_gnattools_target LD_PICFLAG PICFLAG warn_cflags +ADA_CFLAGS +EXTRA_GNATTOOLS +TOOLS_TARGET_PAIRS +LN_S +target_noncanonical +GNATMAKE +GNATBIND OBJEXT EXEEXT ac_ct_CC @@ -595,12 +602,6 @@ CPPFLAGS LDFLAGS CFLAGS CC -ADA_CFLAGS -EXTRA_GNATTOOLS -TOOLS_TARGET_PAIRS -LN_S -target_noncanonical -host_noncanonical target_os target_vendor target_cpu @@ -2023,78 +2024,7 @@ test -n "$target_alias" && NONENONEs,x,x, && program_prefix=${target_alias}- - case ${build_alias} in - "") build_noncanonical=${build} ;; - *) build_noncanonical=${build_alias} ;; -esac - - case ${host_alias} in - "") host_noncanonical=${build_noncanonical} ;; - *) host_noncanonical=${host_alias} ;; -esac - - - - case ${target_alias} in - "") target_noncanonical=${host_noncanonical} ;; - *) target_noncanonical=${target_alias} ;; -esac - - - - -# Need to pass this down for now :-P -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } -fi - - -# Target-specific stuff (defaults) -TOOLS_TARGET_PAIRS= -EXTRA_GNATTOOLS= - -# Per-target case statement -# ------------------------- -case "${target}" in - *-*-aix*) - TOOLS_TARGET_PAIRS="indepsw.adb&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_GNATBIND+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$GNATBIND"; then + ac_cv_prog_GNATBIND="$GNATBIND" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_GNATBIND="${ac_tool_prefix}gnatbind" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +GNATBIND=$ac_cv_prog_GNATBIND +if test -n "$GNATBIND"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GNATBIND" >&5 +$as_echo "$GNATBIND" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_GNATBIND"; then + ac_ct_GNATBIND=$GNATBIND + # Extract the first word of "gnatbind", so it can be a program name with args. +set dummy gnatbind; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_GNATBIND+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_GNATBIND"; then + ac_cv_prog_ac_ct_GNATBIND="$ac_ct_GNATBIND" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_GNATBIND="gnatbind" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_GNATBIND=$ac_cv_prog_ac_ct_GNATBIND +if test -n "$ac_ct_GNATBIND"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_GNATBIND" >&5 +$as_echo "$ac_ct_GNATBIND" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_GNATBIND" = x; then + GNATBIND="no" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + GNATBIND=$ac_ct_GNATBIND + fi +else + GNATBIND="$ac_cv_prog_GNATBIND" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gnatmake", so it can be a program name with args. +set dummy ${ac_tool_prefix}gnatmake; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_GNATMAKE+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$GNATMAKE"; then + ac_cv_prog_GNATMAKE="$GNATMAKE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_GNATMAKE="${ac_tool_prefix}gnatmake" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +GNATMAKE=$ac_cv_prog_GNATMAKE +if test -n "$GNATMAKE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GNATMAKE" >&5 +$as_echo "$GNATMAKE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_GNATMAKE"; then + ac_ct_GNATMAKE=$GNATMAKE + # Extract the first word of "gnatmake", so it can be a program name with args. +set dummy gnatmake; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_GNATMAKE+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_GNATMAKE"; then + ac_cv_prog_ac_ct_GNATMAKE="$ac_ct_GNATMAKE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_GNATMAKE="gnatmake" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_GNATMAKE=$ac_cv_prog_ac_ct_GNATMAKE +if test -n "$ac_ct_GNATMAKE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_GNATMAKE" >&5 +$as_echo "$ac_ct_GNATMAKE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_GNATMAKE" = x; then + GNATMAKE="no" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + GNATMAKE=$ac_ct_GNATMAKE + fi +else + GNATMAKE="$ac_cv_prog_GNATMAKE" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler driver understands Ada and is recent enough" >&5 +$as_echo_n "checking whether compiler driver understands Ada and is recent enough... " >&6; } +if ${acx_cv_cc_gcc_supports_ada+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.adb <&1 || echo failure` +if test x"$errors" = x && test -f conftest.$ac_objext; then + acx_cv_cc_gcc_supports_ada=yes +fi +rm -f conftest.* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_cc_gcc_supports_ada" >&5 +$as_echo "$acx_cv_cc_gcc_supports_ada" >&6; } + +if test "x$GNATBIND" != xno && test "x$GNATMAKE" != xno && test x$acx_cv_cc_gcc_supports_ada != xno; then + have_gnat=yes +else + have_gnat=no +fi + + case ${build_alias} in + "") build_noncanonical=${build} ;; + *) build_noncanonical=${build_alias} ;; +esac + + case ${host_alias} in + "") host_noncanonical=${build_noncanonical} ;; + *) host_noncanonical=${host_alias} ;; +esac + + case ${target_alias} in + "") target_noncanonical=${host_noncanonical} ;; + *) target_noncanonical=${target_alias} ;; +esac + + + + +# Need to pass this down for now :-P +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + + +# Target-specific stuff (defaults) +TOOLS_TARGET_PAIRS= +EXTRA_GNATTOOLS= + +# Per-target case statement +# ------------------------- +case "${target}" in + *-*-aix*) + TOOLS_TARGET_PAIRS="indepsw.adb&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + warn_cflags= if test "x$GCC" = "xyes"; then warn_cflags='$(GCC_WARN_CFLAGS)' diff --git a/gnattools/configure.ac b/gnattools/configure.ac index 776530aee524..ff07179b3ba8 100644 --- a/gnattools/configure.ac +++ b/gnattools/configure.ac @@ -45,7 +45,7 @@ AC_CANONICAL_BUILD AC_CANONICAL_HOST AC_CANONICAL_TARGET -ACX_NONCANONICAL_HOST +ACX_PROG_GNAT ACX_NONCANONICAL_TARGET # Need to pass this down for now :-P diff --git a/include/ChangeLog b/include/ChangeLog index 886dab6c69cd..b3fdd3ce045d 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,14 @@ +2025-07-09 Matthieu Longo + + * doubly-linked-list.h: New file. + +2025-06-20 Sosutha Sethuramapandian + + PR target/110181 + * longlong.h [__riscv] (count_leading_zeros): Define. + [__riscv] (count_trailing_zeros): Likewise. + [__riscv] (COUNT_LEADING_ZEROS_0): Likewise. + 2025-06-02 Tobias Burnus PR libgomp/120444 diff --git a/include/doubly-linked-list.h b/include/doubly-linked-list.h new file mode 100644 index 000000000000..3f5ea2808f99 --- /dev/null +++ b/include/doubly-linked-list.h @@ -0,0 +1,447 @@ +/* Manipulate doubly linked lists. + Copyright (C) 2025 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + + +#ifndef _DOUBLY_LINKED_LIST_H +#define _DOUBLY_LINKED_LIST_H + +/* Doubly linked list implementation enforcing typing. + + This implementation of doubly linked list tries to achieve the enforcement of + typing similarly to C++ templates, but without encapsulation. + + All the functions are prefixed with the type of the value: "AType_xxx". + Some functions are prefixed with "_AType_xxx" and are not part of the public + API, so should not be used, except for _##LTYPE##_merge_sort with a caveat + (see note above its definition). + + Each function (### is a placeholder for method name) has a macro for: + (1) its invocation LINKED_LIST_###(LTYPE). + (2) its prototype LINKED_LIST_DECL_###(A, A2, scope). To add in a header + file, or a source file for forward declaration. 'scope' should be set + respectively to 'extern', or 'static'. + (3) its definition LINKED_LIST_DEFN_###(A, A2, scope). To add in a source + file with the 'scope' set respectively to nothing, or 'static' depending + on (2). + + Data structures requirements: + - LTYPE corresponds to the node of a doubly linked list. It needs to define + attributes 'prev' and 'next' which are pointers on the type of a node. + For instance: + struct my_list_node + { + T value; + struct my_list_node *prev; + struct my_list_node *next; + }; + - LWRAPPERTYPE is a structure wrapping the nodes and others metadata (first, + last, size). + */ + + +/* Mutative operations: + - append + - prepend + - insert_before + - pop_front + - pop_back + - remove + - swap + The header and body of each of those operation can be declared individually, + or as a whole via LINKED_LIST_MUTATIVE_OPS_PROTOTYPE for the prototypes, and + LINKED_LIST_MUTATIVE_OPS_DECL for the implementations. */ + +/* Append the given node new_ to the exising list. + Precondition: prev and next of new_ must be NULL. */ +#define LINKED_LIST_APPEND(LTYPE) LTYPE##_append + +#define LINKED_LIST_DECL_APPEND(LWRAPPERTYPE, LTYPE, EXPORT) \ + EXPORT void \ + LTYPE##_append (LWRAPPERTYPE *wrapper, LTYPE *new_) + +#define LINKED_LIST_DEFN_APPEND(LWRAPPERTYPE, LTYPE, EXPORT) \ +EXPORT void \ +LTYPE##_append (LWRAPPERTYPE *wrapper, LTYPE *new_) \ +{ \ + if (wrapper->last == NULL) \ + wrapper->first = new_; \ + else \ + { \ + new_->prev = wrapper->last; \ + wrapper->last->next = new_; \ + } \ + wrapper->last = new_; \ + ++wrapper->size; \ +} + +/* Prepend the given node new_ to the existing list. + Precondition: prev and next of new_ must be NULL. */ +#define LINKED_LIST_PREPEND(LTYPE) LTYPE##_prepend + +#define LINKED_LIST_DECL_PREPEND(LWRAPPERTYPE, LTYPE, EXPORT) \ + EXPORT void \ + LTYPE##_prepend (LWRAPPERTYPE *wrapper, LTYPE *new_) + +#define LINKED_LIST_DEFN_PREPEND(LWRAPPERTYPE, LTYPE, EXPORT) \ +EXPORT void \ +LTYPE##_prepend (LWRAPPERTYPE *wrapper, LTYPE *new_) \ +{ \ + if (wrapper->first == NULL) \ + wrapper->last = new_; \ + else \ + { \ + new_->next = wrapper->first; \ + wrapper->first->prev = new_; \ + } \ + wrapper->first = new_; \ + ++wrapper->size; \ +} + +/* Insert the given node new_ before 'where' in the existing list. + If where == NULL, the insertion is equivalent to an append. + If where == first, the insertion is equivalent to a prepend. */ +#define LINKED_LIST_INSERT_BEFORE(LTYPE) LTYPE##_insert_before + +#define LINKED_LIST_DECL_INSERT_BEFORE(LWRAPPERTYPE, LTYPE, EXPORT) \ + EXPORT void \ + LTYPE##_insert_before (LWRAPPERTYPE *wrapper, \ + LTYPE *new_, \ + LTYPE *where) + +#define LINKED_LIST_DEFN_INSERT_BEFORE(LWRAPPERTYPE, LTYPE, EXPORT) \ +EXPORT void \ +LTYPE##_insert_before (LWRAPPERTYPE *wrapper, \ + LTYPE *new_, \ + LTYPE *where) \ +{ \ + if (where == wrapper->first) \ + LTYPE##_prepend (wrapper, new_); \ + else if (where == NULL) \ + LTYPE##_append (wrapper, new_); \ + else \ + { \ + where->prev->next = new_; \ + new_->prev = where->prev; \ + where->prev = new_; \ + new_->next = where; \ + ++wrapper->size; \ + } \ +} + +/* Pop the first node of the list. */ +#define LINKED_LIST_POP_FRONT(LTYPE) LTYPE##_pop_front + +#define LINKED_LIST_DECL_POP_FRONT(LWRAPPERTYPE, LTYPE, EXPORT) \ + EXPORT LTYPE * \ + LTYPE##_pop_front (LWRAPPERTYPE *wrapper) + +#define LINKED_LIST_DEFN_POP_FRONT(LWRAPPERTYPE, LTYPE, EXPORT) \ +EXPORT LTYPE * \ +LTYPE##_pop_front (LWRAPPERTYPE *wrapper) \ +{ \ + LTYPE *front_node = wrapper->first; \ + if (front_node != NULL) \ + { \ + wrapper->first = front_node->next; \ + if (wrapper->last == front_node) \ + wrapper->last = NULL; \ + else \ + { \ + front_node->next->prev = NULL; \ + front_node->next = NULL; \ + } \ + front_node->next = NULL; \ + --wrapper->size; \ + } \ + return front_node; \ +} + +/* Pop the last node of the list. */ +#define LINKED_LIST_POP_BACK(LTYPE) LTYPE##_pop_back + +#define LINKED_LIST_DECL_POP_BACK(LWRAPPERTYPE, LTYPE, EXPORT) \ + EXPORT LTYPE * \ + LTYPE##_pop_back (LWRAPPERTYPE *wrapper) + +#define LINKED_LIST_DEFN_POP_BACK(LWRAPPERTYPE, LTYPE, EXPORT) \ +EXPORT LTYPE * \ +LTYPE##_pop_back (LWRAPPERTYPE *wrapper) \ +{ \ + LTYPE *back_node = wrapper->last; \ + if (back_node != NULL) \ + { \ + wrapper->last = back_node->prev; \ + if (wrapper->first == back_node) \ + wrapper->first = NULL; \ + else \ + { \ + back_node->prev->next = NULL; \ + back_node->prev = NULL; \ + } \ + back_node->prev = NULL; \ + --wrapper->size; \ + } \ + return back_node; \ +} + +/* Remove the given node from the existing list, and return the previous + node. */ +#define LINKED_LIST_REMOVE(LTYPE) LTYPE##_remove + +#define LINKED_LIST_DECL_REMOVE(LWRAPPERTYPE, LTYPE, EXPORT) \ + EXPORT LTYPE * \ + LTYPE##_remove (LWRAPPERTYPE *wrapper, LTYPE *node) + +#define LINKED_LIST_DEFN_REMOVE(LWRAPPERTYPE, LTYPE, EXPORT) \ +EXPORT LTYPE * \ +LTYPE##_remove (LWRAPPERTYPE *wrapper, LTYPE *node) \ +{ \ + LTYPE *previous = NULL; \ + \ + if (node->prev != NULL) \ + { \ + node->prev->next = node->next; \ + if (node->next == NULL) \ + wrapper->last = node->prev; \ + else \ + node->next->prev = node->prev; \ + previous = node->prev; \ + node->next = NULL; \ + node->prev = NULL; \ + --wrapper->size; \ + } \ + else \ + LTYPE##_pop_front (wrapper); \ + \ + return previous; \ +} + +/* Generic swap. */ +#define LINKED_LIST_SWAP(LTYPE) LTYPE##_swap + +#define LINKED_LIST_DECL_SWAP(LWRAPPERTYPE, LTYPE, EXPORT) \ + EXPORT void \ + LTYPE##_swap (LWRAPPERTYPE *wrapper, LTYPE *node1, LTYPE *node2) + +/* Swap two nodes in a list. */ +#define LINKED_LIST_DEFN_SWAP(LWRAPPERTYPE, LTYPE, EXPORT) \ +EXPORT void \ +LTYPE##_swap (LWRAPPERTYPE *wrapper, LTYPE *node1, LTYPE *node2) \ +{ \ + LTYPE *prev1 = node1->prev; \ + LTYPE *next1 = node1->next; \ + LTYPE *prev2 = node2->prev; \ + LTYPE *next2 = node2->next; \ + \ + if (prev1 != NULL) \ + prev1->next = node2; \ + else \ + wrapper->first = node2; \ + if (prev2 != NULL) \ + prev2->next = node1; \ + else \ + wrapper->first = node1; \ + \ + if (next1 != NULL) \ + next1->prev = node2; \ + else \ + wrapper->last = node2; \ + if (next2 != NULL) \ + next2->prev = node1; \ + else \ + wrapper->last = node1; \ + \ + { \ + LTYPE *temp = node1->next; \ + node1->next = node2->next; \ + node2->next = temp; \ + } \ + { \ + LTYPE *temp = node1->prev; \ + node1->prev = node2->prev; \ + node2->prev = temp; \ + } \ +} + +/* Note: all the mutative operations below also update the data in the wrapper, + i.e. first, last and size. */ +#define LINKED_LIST_MUTATIVE_OPS_PROTOTYPE(LWRAPPERTYPE, LTYPE, EXPORT) \ + LINKED_LIST_DECL_APPEND(LWRAPPERTYPE, LTYPE, EXPORT); \ + LINKED_LIST_DECL_PREPEND(LWRAPPERTYPE, LTYPE, EXPORT); \ + LINKED_LIST_DECL_INSERT_BEFORE(LWRAPPERTYPE, LTYPE, EXPORT); \ + LINKED_LIST_DECL_POP_FRONT(LWRAPPERTYPE, LTYPE, EXPORT); \ + LINKED_LIST_DECL_POP_BACK(LWRAPPERTYPE, LTYPE, EXPORT); \ + LINKED_LIST_DECL_REMOVE(LWRAPPERTYPE, LTYPE, EXPORT); \ + LINKED_LIST_DECL_SWAP(LWRAPPERTYPE, LTYPE, EXPORT) + +#define LINKED_LIST_MUTATIVE_OPS_DECL(LWRAPPERTYPE, LTYPE, EXPORT) \ + LINKED_LIST_DEFN_APPEND(LWRAPPERTYPE, LTYPE, EXPORT) \ + LINKED_LIST_DEFN_PREPEND(LWRAPPERTYPE, LTYPE, EXPORT) \ + LINKED_LIST_DEFN_INSERT_BEFORE(LWRAPPERTYPE, LTYPE, EXPORT) \ + LINKED_LIST_DEFN_POP_FRONT(LWRAPPERTYPE, LTYPE, EXPORT) \ + LINKED_LIST_DEFN_POP_BACK(LWRAPPERTYPE, LTYPE, EXPORT) \ + LINKED_LIST_DEFN_REMOVE(LWRAPPERTYPE, LTYPE, EXPORT) \ + LINKED_LIST_DEFN_SWAP(LWRAPPERTYPE, LTYPE, EXPORT) + + +/* Sorting. */ + +#define LINKED_LIST_MERGE_SORT_(LTYPE) LTYPE##_merge_sort_ + +#define LINKED_LIST_MERGE_SORT(LTYPE) LTYPE##_merge_sort + +#define LINKED_LIST_MERGE_SORT_PROTOTYPE_(LTYPE, EXPORT) \ + EXPORT LTYPE * \ + LTYPE##_merge_sort_ (LTYPE *node, \ + int (*fn_cmp) (const LTYPE *, const LTYPE *)) + +#define LINKED_LIST_MERGE_SORT_PROTOTYPE(LWRAPPERTYPE, LTYPE, EXPORT) \ + EXPORT void \ + LTYPE##_merge_sort (LWRAPPERTYPE *wrapper, \ + int (*fn_cmp) (const LTYPE *, const LTYPE *)) + +/* Note: all the functions and macros below starting with "_" should be + considered private. */ + +/* Compute the middle element of the list based on the turtle and hare + approach, i.e. the hare runs twice faster than the turtle. */ +#define _MERGE_SORT_IMPL_COMPUTE_TURTLE(LTYPE) \ +static inline LTYPE * \ +LTYPE##_merge_sort_compute_turtle_ (LTYPE *node) \ +{ \ + if (node == NULL) \ + return node; \ + \ + LTYPE *turtle = node, *hare = node->next; \ + while (hare != NULL && hare->next != NULL) \ + { \ + turtle = turtle->next; \ + hare = hare->next->next; \ + } \ + return turtle; \ +} + +/* Append n at the end of l_out, and return the next node after n. + l_out and l_last should be ideally encapsulated into a list structure + but this is overkill for what we need here. */ +#define _MERGE_SORT_IMPL_OUT_APPEND(LTYPE) \ +static inline LTYPE * \ +LTYPE##_merge_sort_out_append_ (LTYPE **l_out, LTYPE **l_last, \ + LTYPE *n) \ +{ \ + if (*l_last == NULL) \ + { \ + *l_last = n; \ + *l_out = n; \ + n->prev = NULL; \ + } \ + else \ + { \ + (*l_last)->next = n; \ + n->prev = *l_last; \ + *l_last = n; \ + } \ + \ + return n->next; \ +} + +/* Merge two sorted lists together. + The returned value corresponds to the first element of the list. + Note: both input lists are invalidated after the call. */ +#define _MERGE_SORT_IMPL_MERGE(LTYPE) \ +static inline LTYPE * \ +LTYPE##_merge_sort_merge_ (LTYPE *l_left, LTYPE *l_right, \ + int (*fn_cmp) (const LTYPE *, const LTYPE *))\ +{ \ + if (l_left == NULL) \ + return l_right; \ + else if (l_right == NULL) \ + return l_left; \ + \ + LTYPE *l_out = NULL, *l_last = NULL; \ + \ + LTYPE *l_l = l_left, *l_r = l_right; \ + while (l_l != NULL && l_r != NULL) \ + { \ + int cmp = fn_cmp (l_l, l_r); \ + if (cmp <= 0) \ + l_l = LTYPE##_merge_sort_out_append_ (&l_out, &l_last, l_l); \ + else \ + l_r = LTYPE##_merge_sort_out_append_ (&l_out, &l_last, l_r); \ + } \ + \ + LTYPE *l_remaining = (l_l != NULL) ? l_l : l_r; \ + while (l_remaining != NULL) \ + l_remaining = \ + LTYPE##_merge_sort_out_append_ (&l_out, &l_last, l_remaining); \ + \ + return l_out; \ +} + +/* Merge sort implementation taking the first node of the list to sort, + and the comparison function. Returns the first node of the sorted list. + Note: use this if you don't care about updating the information in the + wrapper. */ +#define _MERGE_SORT_DEFN_SORT(LTYPE, EXPORT) \ +EXPORT LTYPE * \ +LTYPE##_merge_sort_ (LTYPE *node, \ + int (*fn_cmp)(const LTYPE *, const LTYPE *)) \ +{ \ + if (node == NULL) \ + return NULL; \ + else if (node->next == NULL) \ + return node; \ + \ + LTYPE *left_end = LTYPE##_merge_sort_compute_turtle_ (node); \ + LTYPE *left_begin = node; \ + LTYPE *right_begin = left_end->next; \ + /* break the list. */ \ + left_end->next = NULL; \ + right_begin->prev = NULL; \ + \ + left_begin = LTYPE##_merge_sort_ (left_begin, fn_cmp); \ + right_begin = LTYPE##_merge_sort_ (right_begin, fn_cmp); \ + return LTYPE##_merge_sort_merge_ (left_begin, right_begin, fn_cmp); \ +} + +/* Merge sort wrapper that the end-user should be using as it updates the + first and last metadata of the list in wrapper as well. + If the user does not want to pay the cost of the update of the data, + it can directly use _##LTYPE##_merge_sort_merge. */ +#define _MERGE_SORT_DEFN_WRAPPER_SORT(LWRAPPERTYPE, LTYPE, EXPORT) \ +EXPORT void \ +LTYPE##_merge_sort (LWRAPPERTYPE *wrapper, \ + int (*fn_cmp) (const LTYPE *, const LTYPE *)) \ +{ \ + wrapper->first = LTYPE##_merge_sort_ (wrapper->first, fn_cmp); \ + \ + if (wrapper->first == NULL || wrapper->first->next == NULL) \ + wrapper->last = wrapper->first; \ + else \ + for (LTYPE *node = wrapper->first; \ + node != NULL; \ + node = node->next) \ + wrapper->last = node; \ +} + +#define LINKED_LIST_MERGE_SORT_DECL(LWRAPPERTYPE, LTYPE, EXPORT) \ + _MERGE_SORT_IMPL_COMPUTE_TURTLE(LTYPE) \ + _MERGE_SORT_IMPL_OUT_APPEND(LTYPE) \ + _MERGE_SORT_IMPL_MERGE(LTYPE) \ + _MERGE_SORT_DEFN_SORT(LTYPE, EXPORT) \ + _MERGE_SORT_DEFN_WRAPPER_SORT(LWRAPPERTYPE, LTYPE, EXPORT) + +#endif /* _DOUBLY_LINKED_LIST_H */ diff --git a/include/longlong.h b/include/longlong.h index 40f94243a1af..5ae250f7192d 100644 --- a/include/longlong.h +++ b/include/longlong.h @@ -1065,6 +1065,20 @@ extern UDItype __umulsidi3 (USItype, USItype); #endif #if defined(__riscv) + +#ifdef __riscv_zbb +#if W_TYPE_SIZE == 32 +#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) +#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) +#define COUNT_LEADING_ZEROS_0 32 +#endif /* W_TYPE_SIZE == 32 */ +#if W_TYPE_SIZE == 64 +#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clzll (X)) +#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctzll (X)) +#define COUNT_LEADING_ZEROS_0 64 +#endif /* W_TYPE_SIZE == 64 */ +#endif /* __riscv_zbb */ + #ifdef __riscv_mul #define __umulsidi3(u,v) ((UDWtype)(UWtype)(u) * (UWtype)(v)) #define __muluw3(a, b) ((UWtype)(a) * (UWtype)(b)) diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index eef6ec7a48ca..3c5bae1e9d0c 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,17 @@ +2025-06-17 Jason Merrill + + * line-map.cc (linemap_location_from_module_p): Add. + * include/line-map.h: Declare it. + +2025-06-11 David Malcolm + + PR other/116792 + * include/line-map.h (typedef expanded_location): Convert to... + (struct expanded_location): ...this. + (operator==): New decl, for expanded_location. + (operator!=): Likewise. + * line-map.cc (operator==): New decl, for expanded_location. + 2025-05-07 Jakub Jelinek PR preprocessor/108900 diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h index 75cc1ad2c275..21a59af22369 100644 --- a/libcpp/include/line-map.h +++ b/libcpp/include/line-map.h @@ -1111,6 +1111,10 @@ extern location_t linemap_module_loc extern void linemap_module_reparent (line_maps *, location_t loc, location_t new_parent); +/* TRUE iff the location comes from a module import. */ +extern bool linemap_location_from_module_p + (const line_maps *, location_t); + /* Restore the linemap state such that the map at LWM-1 continues. Return start location of the new map. */ extern location_t linemap_module_restore @@ -1280,7 +1284,7 @@ linemap_location_before_p (const line_maps *set, return linemap_compare_locations (set, loc_a, loc_b) >= 0; } -typedef struct +struct expanded_location { /* The name of the source file involved. */ const char *file; @@ -1294,7 +1298,18 @@ typedef struct /* In a system header?. */ bool sysp; -} expanded_location; +}; + +extern bool +operator== (const expanded_location &a, + const expanded_location &b); +inline bool +operator!= (const expanded_location &a, + const expanded_location &b) +{ + return !(a == b); +} + /* This is enum is used by the function linemap_resolve_location below. The meaning of the values is explained in the comment of diff --git a/libcpp/line-map.cc b/libcpp/line-map.cc index cf6557117c81..33701b519e1f 100644 --- a/libcpp/line-map.cc +++ b/libcpp/line-map.cc @@ -767,6 +767,17 @@ linemap_module_restore (line_maps *set, line_map_uint_t lwm) return 0; } +/* TRUE iff the location comes from a module import. */ + +bool +linemap_location_from_module_p (const line_maps *set, location_t loc) +{ + const line_map_ordinary *map = linemap_ordinary_map_lookup (set, loc); + while (map && map->reason != LC_MODULE) + map = linemap_included_from_linemap (set, map); + return !!map; +} + /* Returns TRUE if the line table set tracks token locations across macro expansion, FALSE otherwise. */ @@ -1949,6 +1960,28 @@ linemap_expand_location (const line_maps *set, return xloc; } +bool +operator== (const expanded_location &a, + const expanded_location &b) +{ + /* "file" can be null; for them to be equal they must both + have either null or nonnull values, and if non-null + they must compare as equal. */ + if ((a.file == nullptr) != (b.file == nullptr)) + return false; + if (a.file && strcmp (a.file, b.file)) + return false; + + if (a.line != b.line) + return false; + if (a.column != b.column) + return false; + if (a.data != b.data) + return false; + if (a.sysp != b.sysp) + return false; + return true; +} /* Dump line map at index IX in line table SET to STREAM. If STREAM is NULL, use stderr. IS_MACRO is true if the caller wants to diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 7e907b665800..055e7ca371a6 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,20 @@ +2025-07-17 Richard Sandiford + Yury Khrustalev + + * config/aarch64/linux-unwind.h (aarch64_fallback_frame_state): + If a signal was raised while there was an uncommitted lazy save, + commit the save as part of the unwind process. + +2025-07-16 John Ericson + + * Makefile.in: Delete dead `MACHMODE_H` variable + +2025-07-10 Jan Dubiec + + PR target/116363 + * libgcc2.c (__fixunssfDI): Fix SFtype to UDWtype conversion for targets + without LIBGCC2_HAS_DF_MODE defined + 2025-05-27 Jakub Jelinek * config/t-softfp (softfp_bid_list): Don't guard with diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in index 0719fd0615d3..f7b48dceb064 100644 --- a/libgcc/Makefile.in +++ b/libgcc/Makefile.in @@ -193,7 +193,6 @@ AWK = @AWK@ GCC_FOR_TARGET = $(CC) LIPO = @LIPO@ LIPO_FOR_TARGET = $(LIPO) -MACHMODE_H = machmode.h mode-classes.def insn-modes.h NM = @NM@ NM_FOR_TARGET = $(NM) RANLIB_FOR_TARGET = $(RANLIB) @@ -220,7 +219,6 @@ export INSTALL_DATA export LIB1ASMSRC export LIBGCC2_CFLAGS export LIPO_FOR_TARGET -export MACHMODE_H export NM_FOR_TARGET export STRIP_FOR_TARGET export RANLIB_FOR_TARGET diff --git a/libgcc/config/aarch64/linux-unwind.h b/libgcc/config/aarch64/linux-unwind.h index e41ca6a6a6e6..f5b73a0777f6 100644 --- a/libgcc/config/aarch64/linux-unwind.h +++ b/libgcc/config/aarch64/linux-unwind.h @@ -27,7 +27,7 @@ #include #include - +#include /* Since insns are always stored LE, on a BE system the opcodes will be loaded byte-reversed. Therefore, define two sets of opcodes, @@ -43,6 +43,22 @@ #define MD_FALLBACK_FRAME_STATE_FOR aarch64_fallback_frame_state +#ifndef FPSIMD_MAGIC +#define FPSIMD_MAGIC 0x46508001 +#endif + +#ifndef TPIDR2_MAGIC +#define TPIDR2_MAGIC 0x54504902 +#endif + +#ifndef ZA_MAGIC +#define ZA_MAGIC 0x54366345 +#endif + +#ifndef EXTRA_MAGIC +#define EXTRA_MAGIC 0x45585401 +#endif + static _Unwind_Reason_Code aarch64_fallback_frame_state (struct _Unwind_Context *context, _Unwind_FrameState * fs) @@ -58,6 +74,21 @@ aarch64_fallback_frame_state (struct _Unwind_Context *context, ucontext_t uc; }; + struct tpidr2_block + { + uint64_t za_save_buffer; + uint16_t num_za_save_slices; + uint8_t reserved[6]; + }; + + struct za_block + { + struct _aarch64_ctx head; + uint16_t vl; + uint16_t reserved[3]; + uint64_t data; + }; + struct rt_sigframe *rt_; _Unwind_Ptr new_cfa; unsigned *pc = context->ra; @@ -103,11 +134,15 @@ aarch64_fallback_frame_state (struct _Unwind_Context *context, field can be used to skip over unrecognized context extensions. The end of the context sequence is marked by a context with magic 0 or size 0. */ + struct tpidr2_block *tpidr2 = 0; + struct za_block *za_ctx = 0; + for (extension_marker = (struct _aarch64_ctx *) &sc->__reserved; extension_marker->magic; extension_marker = (struct _aarch64_ctx *) ((unsigned char *) extension_marker + extension_marker->size)) { + restart: if (extension_marker->magic == FPSIMD_MAGIC) { struct fpsimd_context *ctx = @@ -139,12 +174,83 @@ aarch64_fallback_frame_state (struct _Unwind_Context *context, fs->regs.reg[AARCH64_DWARF_V0 + i].loc.offset = offset; } } + else if (extension_marker->magic == TPIDR2_MAGIC) + { + /* A TPIDR2 context. + + All the casting is to support big-endian ILP32. We could read + directly into TPIDR2 otherwise. */ + struct { struct _aarch64_ctx h; uint64_t tpidr2; } *ctx + = (void *)extension_marker; +#if defined (__ILP32__) + tpidr2 = (struct tpidr2_block *) (uintptr_t) ctx->tpidr2; +#else + tpidr2 = (struct tpidr2_block *) ctx->tpidr2; +#endif + } + else if (extension_marker->magic == ZA_MAGIC) + /* A ZA context. We interpret this later. */ + za_ctx = (void *)extension_marker; + else if (extension_marker->magic == EXTRA_MAGIC) + { + /* Extra context. The ABI guarantees that the next _aarch64_ctx + in the current list will be the zero terminator, so we can simply + switch to the new list and continue from there. The new list is + also zero-terminated. + + As above, the casting is to support big-endian ILP32. */ + struct { struct _aarch64_ctx h; uint64_t next; } *ctx + = (void *)extension_marker; +#if defined (__ILP32__) + extension_marker = (struct _aarch64_ctx *) (uintptr_t) ctx->next; +#else + extension_marker = (struct _aarch64_ctx *) ctx->next; +#endif + goto restart; + } else { /* There is context provided that we do not recognize! */ } } + /* Signal handlers are entered with ZA in the off state (TPIDR2_ELO==0 and + PSTATE.ZA==0). The normal process when transitioning from ZA being + dormant to ZA being off is to commit the lazy save; see the AAPCS64 + for details. However, this is not done when entering a signal handler. + Instead, linux saves the old contents of ZA and TPIDR2_EL0 to the + sigcontext without interpreting them further. + + Therefore, if a signal handler throws an exception to code outside the + signal handler, the unwinder must commit the lazy save after the fact. + Committing a lazy save means: + + (1) Storing the contents of ZA into the buffer provided by TPIDR2_EL0. + (2) Setting TPIDR2_EL0 to zero. + (3) Turning ZA off. + + (2) and (3) have already been done by the call to __libgcc_arm_za_disable. + (1) involves copying data from the ZA sigcontext entry to the + corresponding lazy save buffer. */ + if (tpidr2 && za_ctx && tpidr2->za_save_buffer) + { + /* There is a 16-bit vector length (measured in bytes) at ZA_CTX + 8. + The data itself starts at ZA_CTX + 16. + As above, the casting is to support big-endian ILP32. */ + uint16_t vl = za_ctx->vl; +#if defined (__ILP32__) + void *save_buffer = (void *) (uintptr_t) tpidr2->za_save_buffer; + const void *za_buffer = (void *) (uintptr_t) &za_ctx->data; +#else + void *save_buffer = (void *) tpidr2->za_save_buffer; + const void *za_buffer = (void *) &za_ctx->data; +#endif + uint64_t num_slices = tpidr2->num_za_save_slices; + if (num_slices > vl) + num_slices = vl; + memcpy (save_buffer, za_buffer, num_slices * vl); + } + fs->regs.how[31] = REG_SAVED_OFFSET; fs->regs.reg[31].loc.offset = (_Unwind_Ptr) & (sc->sp) - new_cfa; diff --git a/libgcc/config/libbid/ChangeLog b/libgcc/config/libbid/ChangeLog index 9bc4518a9fa0..fd82d6edf06a 100644 --- a/libgcc/config/libbid/ChangeLog +++ b/libgcc/config/libbid/ChangeLog @@ -1,3 +1,8 @@ +2025-07-15 Andrew Pinski + + * bid_binarydecimal.c (__mul_10x256_to_256): Mark c3 as being + used. + 2025-05-15 liuhongt * bid128_string.c (MIN_DIGITS): New macro. diff --git a/libgcc/config/libbid/bid_binarydecimal.c b/libgcc/config/libbid/bid_binarydecimal.c index daca2ffe306f..12e32b9667aa 100644 --- a/libgcc/config/libbid/bid_binarydecimal.c +++ b/libgcc/config/libbid/bid_binarydecimal.c @@ -132,6 +132,7 @@ UINT64 CY; \ __mul_10x64(p1,c1,a1,c0); \ __mul_10x64(p2,c2,a2,c1); \ __mul_10x64(p3,c3,a3,c2); \ + (void)c3; \ } // Set up indices for low and high parts, depending on the endian-ness. diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c index faefff3730ca..df99c78eb204 100644 --- a/libgcc/libgcc2.c +++ b/libgcc/libgcc2.c @@ -2187,36 +2187,21 @@ __fixunssfDI (SFtype a) if (a < 1) return 0; if (a < Wtype_MAXp1_F) - return (UWtype)a; + return (UWtype) a; if (a < Wtype_MAXp1_F * Wtype_MAXp1_F) { - /* Since we know that there are fewer significant bits in the SFmode - quantity than in a word, we know that we can convert out all the - significant bits in one step, and thus avoid losing bits. */ - - /* ??? This following loop essentially performs frexpf. If we could - use the real libm function, or poke at the actual bits of the fp - format, it would be significantly faster. */ - - UWtype shift = 0, counter; - SFtype msb; - - a /= Wtype_MAXp1_F; - for (counter = W_TYPE_SIZE / 2; counter != 0; counter >>= 1) - { - SFtype counterf = (UWtype)1 << counter; - if (a >= counterf) - { - shift |= counter; - a /= counterf; - } - } - - /* Rescale into the range of one word, extract the bits of that - one word, and shift the result into position. */ - a *= Wtype_MAXp1_F; - counter = a; - return (DWtype)counter << shift; + /* We assume that SFtype -> UWtype and UWtype -> UDWtype casts work + properly. Obviously, we *cannot* assume that SFtype -> UDWtype + works as expected. */ + SFtype a_hi, a_lo; + + a_hi = a / Wtype_MAXp1_F; + a_lo = a - a_hi * Wtype_MAXp1_F; + + /* A lot of parentheses. This is to make it very clear what is + the sequence of operations. */ + return ((UDWtype) ((UWtype) a_hi)) << W_TYPE_SIZE + | (UDWtype) ((UWtype) a_lo); } return -1; #else diff --git a/libgcobol/ChangeLog b/libgcobol/ChangeLog index 4293598050a9..91a3b86c481b 100644 --- a/libgcobol/ChangeLog +++ b/libgcobol/ChangeLog @@ -1,3 +1,345 @@ +2025-07-13 Robert Dubner + + * common-defs.h (PTRCAST): Moved here from libgcobol.h. + * libgcobol.h (PTRCAST): Deleted. + +2025-07-10 James K. Lowden + + * common-defs.h (cdf_enabled_exceptions): Use new CDF state. + +2025-07-09 Robert Dubner + James K. Lowden + + * libgcobol.cc (__gg__accept_envar): ACCEPT/DISPLAY environment variables. + (accept_envar): Likewise. + (default_exception_handler): Refine system log entries. + (open_syslog): Likewise. + (__gg__set_env_name): ACCEPT/DISPLAY environment variables. + (__gg__get_env_name): ACCEPT/DISPLAY environment variables. + (__gg__get_env_value): ACCEPT/DISPLAY environment variables. + (__gg__set_env_value): ACCEPT/DISPLAY environment variables. + (__gg__fprintf_stderr): Adjust __attribute__ for printf. + (__gg__set_arg_num): ACCEPT/DISPLAY command-line arguments. + (__gg__accept_arg_value): ACCEPT/DISPLAY command-line arguments. + (__gg__get_file_descriptor): DISPLAY on os_filename[] /dev device. + +2025-06-20 James K. Lowden + + * LICENSE: New file. + +2025-06-16 James K. Lowden + + PR cobol/120621 + * common-defs.h (class cbl_enabled_exceptions_t): Const parameter. + +2025-06-11 Robert Dubner + + PR cobol/119975 + * intrinsic.cc (__gg__current_date): Eliminate CLOCK_REALTIME. + (__gg__seconds_past_midnight): Likewise. + (__gg__formatted_current_date): Likewise. + (__gg__random): Likewise. + (__gg__random_next): Likewise. + * libgcobol.cc: include . + (__gg__abort): Eliminate CLOCK_REALTIME. + (cobol_time): Likewise. + (get_time_nanoseconds): Rename. + (get_time_nanoseconds_local): Comment; Eliminate CLOCK_REALTIME. + (__gg__clock_gettime): Likewise. + (__gg__get_date_hhmmssff): Likewise. + * libgcobol.h (__gg__clock_gettime): Eliminate clockid_t from declaration. + +2025-06-06 Robert Dubner + James K. Lowden + + * common-defs.h (enum cbl_file_mode_t): Whitespace. + (enum file_stmt_t): Likewise. + (ec_cmp): Likewise. + (struct cbl_declarative_t): Add "explicit" keyword. + (class cbl_enabled_exceptions_t): Whitespace. + * gfileio.cc: Remove cppcheck comment. + * libgcobol.cc (class ec_status_t): Add "explicit" keyword. + (match_declarative): Remove %zu. + (default_exception_handler): Likwise. + (__gg__check_fatal_exception): Exception overhead. + (__gg__exception_push): Remove %zu. + (__gg__exception_pop): Likewise. + (cbl_enabled_exception_t::dump): Likewise. + (__gg__match_exception): Exception overhead; remove %zu. + (cbl_enabled_exceptions_t::dump): Remove %zu. + (__gg__set_exception_environment): Likewise. + +2025-06-05 Robert Dubner + + PR cobol/119975 + * configure.ac: AC_CHECK_LIB(rt, clock_gettime). + * config.h.in: Likewise. + * configure: Likewise. + * gfileio.cc: Remove in-line cppcheck-suppress. + * intrinsic.cc (timespec_to_string): Use guarded clock_gettime(). + (__gg__current_date): Likewise. + (__gg__seconds_past_midnight): Likewise. + (__gg__formatted_current_date): Likewise. + (__gg__random): Likewise. + (__gg__random_next): Likewise. + (__gg__when_compiled): Likewise. + * libgcobol.cc (cobol_time): Likewise. + (get_time_nanoseconds): Likewise. + (__gg__clock_gettime): Likewise. + (__gg__get_date_hhmmssff): Likewise. + * libgcobol.h (__gg__clock_gettime): Likewise. + (struct cbl_timespec): Likewise. + +2025-06-04 Robert Dubner + + PR cobol/119323 + * charmaps.cc (__gg__raw_to_ascii): Eliminate cppcheck warnings. + (__gg__raw_to_ebcdic): Likewise. + (__gg__ebcdic_to_console): Likewise. + (__gg__console_to_ascii): Likewise. + (__gg__console_to_ebcdic): Likewise. + * common-defs.h (struct cbl_declarative_t): Likewise. + * gfileio.cc (get_filename): Likewise. + (max_value): Likewise. + (relative_file_delete_varying): Likewise. + (relative_file_delete): Likewise. + (read_an_indexed_record): Likewise. + (position_state_restore): Likewise. + (indexed_file_delete): Likewise. + (indexed_file_start): Likewise. + (sequential_file_rewrite): Likewise. + (relative_file_write_varying): Likewise. + (relative_file_write): Likewise. + (sequential_file_write): Likewise. + (indexed_file_write): Likewise. + (__io__file_write): Likewise. + (line_sequential_file_read): Likewise. + (indexed_file_read): Likewise. + (file_indexed_open): Likewise. + (__gg__file_reopen): Likewise. + * gmath.cc (conditional_stash): Likewise. + (__gg__pow): Likewise. + (multiply_int256_by_int64): Likewise. + (add_int256_to_int256): Likewise. + (divide_int256_by_int64): Likewise. + (squeeze_int256): Likewise. + (get_int256_from_qualified_field): Likewise. + (__gg__add_fixed_phase1): Likewise. + (__gg__addf1_fixed_phase2): Likewise. + (__gg__fixed_phase2_assign_to_c): Likewise. + (__gg__add_float_phase1): Likewise. + (__gg__addf1_float_phase2): Likewise. + (__gg__float_phase2_assign_to_c): Likewise. + (__gg__addf3): Likewise. + (__gg__subtractf1_fixed_phase2): Likewise. + (__gg__subtractf2_fixed_phase1): Likewise. + (__gg__subtractf1_float_phase2): Likewise. + (__gg__subtractf2_float_phase1): Likewise. + (__gg__subtractf3): Likewise. + (__gg__multiplyf1_phase1): Likewise. + (multiply_int128_by_int128): Likewise. + (__gg__multiplyf1_phase2): Likewise. + (__gg__multiplyf2): Likewise. + (shift_in_place128): Likewise. + (divide_int128_by_int128): Likewise. + (__gg__dividef1_phase2): Likewise. + (__gg__dividef23): Likewise. + (__gg__dividef45): Likewise. + * intrinsic.cc (struct input_state): Likewise. + (get_value_as_double_from_qualified_field): Likewise. + (kahan_summation): Likewise. + (variance): Likewise. + (get_all_time): Likewise. + (populate_ctm_from_date): Likewise. + (populate_ctm_from_time): Likewise. + (ftime_replace): Likewise. + (__gg__abs): Likewise. + (__gg__acos): Likewise. + (__gg__annuity): Likewise. + (__gg__asin): Likewise. + (__gg__atan): Likewise. + (__gg__byte_length): Likewise. + (__gg__char): Likewise. + (__gg__combined_datetime): Likewise. + (__gg__cos): Likewise. + (__gg__date_of_integer): Likewise. + (__gg__date_to_yyyymmdd): Likewise. + (__gg__day_of_integer): Likewise. + (__gg__day_to_yyyyddd): Likewise. + (__gg__exp): Likewise. + (__gg__exp10): Likewise. + (__gg__factorial): Likewise. + (__gg__formatted_current_date): Likewise. + (__gg__formatted_date): Likewise. + (__gg__formatted_datetime): Likewise. + (__gg__formatted_time): Likewise. + (__gg__integer): Likewise. + (__gg__integer_of_date): Likewise. + (__gg__integer_of_day): Likewise. + (__gg__integer_part): Likewise. + (__gg__fraction_part): Likewise. + (__gg__log): Likewise. + (__gg__log10): Likewise. + (__gg__max): Likewise. + (__gg__lower_case): Likewise. + (__gg__median): Likewise. + (__gg__min): Likewise. + (numval): Likewise. + (numval_c): Likewise. + (__gg__numval): Likewise. + (__gg__test_numval): Likewise. + (__gg__numval_c): Likewise. + (__gg__test_numval_c): Likewise. + (__gg__ord): Likewise. + (__gg__rem): Likewise. + (__gg__trim): Likewise. + (__gg__random): Likewise. + (__gg__reverse): Likewise. + (__gg__sign): Likewise. + (__gg__sin): Likewise. + (__gg__sqrt): Likewise. + (__gg__tan): Likewise. + (__gg__test_date_yyyymmdd): Likewise. + (__gg__test_day_yyyyddd): Likewise. + (__gg__upper_case): Likewise. + (__gg__year_to_yyyy): Likewise. + (gets_int): Likewise. + (gets_year): Likewise. + (gets_month): Likewise. + (gets_day): Likewise. + (gets_day_of_week): Likewise. + (gets_day_of_year): Likewise. + (gets_week): Likewise. + (gets_hours): Likewise. + (gets_minutes): Likewise. + (gets_seconds): Likewise. + (gets_nanoseconds): Likewise. + (fill_cobol_tm): Likewise. + (__gg__test_formatted_datetime): Likewise. + (__gg__integer_of_formatted_date): Likewise. + (__gg__seconds_from_formatted_time): Likewise. + (__gg__hex_of): Likewise. + (__gg__highest_algebraic): Likewise. + (__gg__lowest_algebraic): Likewise. + (floating_format_tester): Likewise. + (__gg__numval_f): Likewise. + (__gg__test_numval_f): Likewise. + (ismatch): Likewise. + (iscasematch): Likewise. + (strstr): Likewise. + (strcasestr): Likewise. + (strlaststr): Likewise. + (strcaselaststr): Likewise. + (__gg__substitute): Likewise. + (__gg__locale_compare): Likewise. + (__gg__locale_date): Likewise. + (__gg__locale_time): Likewise. + (__gg__locale_time_from_seconds): Likewise. + * libgcobol.cc (class ec_status_t): Likewise. + (__gg__set_truncation_mode): Likewise. + (malloc): Likewise. + (__gg__mabort): Likewise. + (__gg__resize_int_p): Likewise. + (__gg__resize_treeplet): Likewise. + (var_is_refmod): Likewise. + (value_is_too_big): Likewise. + (__gg__string_to_alpha_edited_ascii): Likewise. + (int128_to_field): Likewise. + (edited_to_binary): Likewise. + (get_binary_value_local): Likewise. + (__gg__get_date_yymmdd): Likewise. + (__gg__get_date_yyyymmdd): Likewise. + (__gg__get_date_yyddd): Likewise. + (__gg__get_yyyyddd): Likewise. + (__gg__get_date_dow): Likewise. + (get_scaled_rdigits): Likewise. + (format_for_display_internal): Likewise. + (compare_88): Likewise. + (get_float128): Likewise. + (compare_field_class): Likewise. + (compare_strings): Likewise. + (__gg__compare_2): Likewise. + (__gg__sort_table): Likewise. + (init_var_both): Likewise. + (alpha_to_alpha_move_from_location): Likewise. + (alpha_to_alpha_move): Likewise. + (__gg__move): Likewise. + (__gg__move_literala): Likewise. + (__gg__sort_workfile): Likewise. + (__gg__merge_files): Likewise. + (normalize_id): Likewise. + (inspect_backward_format_1): Likewise. + (__gg__inspect_format_1): Likewise. + (inspect_backward_format_2): Likewise. + (__gg__inspect_format_2): Likewise. + (__gg__inspect_format_4): Likewise. + (move_string): Likewise. + (__gg__string): Likewise. + (display_both): Likewise. + (__gg__display_string): Likewise. + (__gg__accept): Likewise. + (__gg__binary_value_from_qualified_field): Likewise. + (__gg__float128_from_qualified_field): Likewise. + (float128_to_int128): Likewise. + (float128_to_location): Likewise. + (__gg__set_initial_switch_value): Likewise. + (is_numeric_display_numeric): Likewise. + (is_packed_numeric): Likewise. + (is_alpha_a_number): Likewise. + (__gg__classify): Likewise. + (__gg__accept_envar): Likewise. + (__gg__set_envar): Likewise. + (command_line_plan_b): Likewise. + (__gg__get_command_line): Likewise. + (__gg__set_pointer): Likewise. + (__gg__ascii_to_internal_field): Likewise. + (__gg__internal_to_console_in_place): Likewise. + (__gg__routine_to_call): Likewise. + (__gg__fetch_call_by_value_value): Likewise. + (__gg__assign_value_from_stack): Likewise. + (__gg__literaln_alpha_compare): Likewise. + (string_in): Likewise. + (__gg__unstring): Likewise. + (local_ec_type_of): Likewise. + (struct exception_descr_t): Likewise. + (struct cbl_exception_t): Likewise. + (cbl_enabled_exception_t: Likewise.: Likewise.dump): Likewise. + (__gg__match_exception): Likewise. + (__gg__float128_from_location): Likewise. + (__gg__integer_from_float128): Likewise. + (__gg__set_exception_file): Likewise. + (__gg__func_exception_file): Likewise. + (__gg__set_exception_code): Likewise. + (__gg__is_float_infinite): Likewise. + (__gg__float32_from_128): Likewise. + (__gg__float32_from_64): Likewise. + (__gg__float64_from_128): Likewise. + (__gg__copy_as_big_endian): Likewise. + (__gg__get_figconst_data): Likewise. + (find_in_dirs): Likewise. + (__gg__function_handle_from_cobpath): Likewise. + (__gg__just_mangle_name): Likewise. + (__gg__function_handle_from_literal): Likewise. + (__gg__function_handle_from_name): Likewise. + (__gg__mirror_range): Likewise. + (__gg__deallocate): Likewise. + (__gg__allocate): Likewise. + (__gg__module_name): Likewise. + (__gg__set_env_name): Likewise. + (__gg__set_env_value): Likewise. + * libgcobol.h (__gg__mabort): Likewise. + (massert): Likewise. + (PTRCAST): Likewise. + (__gg__float128_from_location): Likewise. + (__gg__set_exception_file): Likewise. + (__gg__binary_value_from_qualified_field): Likewise. + (__gg__float128_from_qualified_field): Likewise. + * valconv.cc (__gg__realloc_if_necessary): Likewise. + (__gg__alphabet_create): Likewise. + (__gg__string_to_numeric_edited): Likewise. + (__gg__string_to_alpha_edited): Likewise. + * valconv.h: Likewise. + 2025-06-01 Robert Dubner PR cobol/119524 diff --git a/libgcobol/LICENSE b/libgcobol/LICENSE new file mode 100644 index 000000000000..3937993c56a2 --- /dev/null +++ b/libgcobol/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2021-2025 Symas Corporation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. +* Neither the name of the Symas Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libgcobol/common-defs.h b/libgcobol/common-defs.h index 764d9f813d0a..15d06831be74 100644 --- a/libgcobol/common-defs.h +++ b/libgcobol/common-defs.h @@ -84,6 +84,14 @@ #define MINIMUM_ALLOCATION_SIZE 16 +// This was part of an exercise to make cppcheck shut up about invalid +// pointer type conversions. +// It was also to avoid having reinterpret_cast<> all over the place. +// So, instead of reinterpret_cast(VALUE) +// I sometimes use PTRCAST(char, VALUE) +// Note that "(char *)" is implied by "PTRCAST(char, VALUE)" +#define PTRCAST(TYPE, VALUE) static_cast(static_cast(VALUE)) + /* * User-defined names in IBM COBOL can have at most 30 characters. * For DBCS, the maximum is 14. @@ -237,7 +245,7 @@ enum cbl_file_mode_t { file_mode_output_e = 'w', file_mode_extend_e = 'a', file_mode_io_e = '+', - file_mode_any_e, + file_mode_any_e, }; enum cbl_round_t { @@ -288,15 +296,15 @@ enum bitop_t { }; enum file_stmt_t { - file_stmt_delete_e, - file_stmt_merge_e, - file_stmt_read_e, - file_stmt_rewrite_e, - file_stmt_sort_e, - file_stmt_start_e, - file_stmt_write_e, + file_stmt_delete_e, + file_stmt_merge_e, + file_stmt_read_e, + file_stmt_rewrite_e, + file_stmt_sort_e, + file_stmt_start_e, + file_stmt_write_e, }; - + enum file_close_how_t { file_close_no_how_e = 0x00, file_close_removal_e = 0x01, @@ -412,14 +420,14 @@ ec_cmp( ec_type_t raised, ec_type_t ec ) { if( raised == ec ) return true; - // If both low bytes are nonzero, we had to match exactly, above. + // If both low bytes are nonzero, we had to match exactly, above. if( (~EC_ALL_E & static_cast(raised)) && (~EC_ALL_E & static_cast(ec)) ) { return false; } - // Level 1 and 2 have low byte of zero. + // Level 1 and 2 have low byte of zero. // If one low byte is zero, see if they're the same kind. return 0xFF < ( static_cast(raised) & @@ -464,8 +472,7 @@ struct cbl_declarative_t { uint32_t nfile, files[files_max]; cbl_file_mode_t mode; - // cppcheck-suppress noExplicitConstructor - cbl_declarative_t( cbl_file_mode_t mode = file_mode_none_e ) + explicit cbl_declarative_t( cbl_file_mode_t mode = file_mode_none_e ) : section(0) , global(false) , type(ec_none_e) @@ -474,8 +481,7 @@ struct cbl_declarative_t { { std::fill(files, files + COUNT_OF(files), 0); } - // cppcheck-suppress noExplicitConstructor - cbl_declarative_t( ec_type_t type ) + explicit cbl_declarative_t( ec_type_t type ) : section(0) , global(false) , type(type) @@ -512,7 +518,7 @@ struct cbl_declarative_t { std::copy( that.files, that.files + nfile, this->files ); } } - constexpr cbl_declarative_t& operator=(const cbl_declarative_t&) = default; + cbl_declarative_t& operator=(const cbl_declarative_t&) = default; std::vector encode() const; @@ -539,7 +545,7 @@ struct cbl_declarative_t { // TRUE if there are no files to match, or the provided file is in the list. bool match_file( size_t file ) const { - static const auto pend = files + nfile; // cppcheck-suppress constVariablePointer + static const uint32_t * pend = files + nfile; return nfile == 0 || pend != std::find(files, files + nfile, file); } @@ -568,11 +574,11 @@ class cbl_enabled_exceptions_t : protected std::set public: cbl_enabled_exceptions_t() {} - cbl_enabled_exceptions_t( size_t nec, const cbl_enabled_exception_t *ecs ) + cbl_enabled_exceptions_t( size_t nec, const cbl_enabled_exception_t *ecs ) : std::set(ecs, ecs + nec) {} void turn_on_off( bool enabled, bool location, ec_type_t type, - std::set files ); + const std::set& files ); const cbl_enabled_exception_t * match( ec_type_t ec, size_t file = 0 ) const; @@ -591,7 +597,7 @@ class cbl_enabled_exceptions_t : protected std::set cbl_enabled_exceptions_t& operator=( const cbl_enabled_exceptions_t& ) = default; }; -extern cbl_enabled_exceptions_t enabled_exceptions; +cbl_enabled_exceptions_t& cdf_enabled_exceptions(); template T enabled_exception_match( T beg, T end, ec_type_t type, size_t file ) { diff --git a/libgcobol/config.h.in b/libgcobol/config.h.in index ee3dd6b21514..1b511d0330d5 100644 --- a/libgcobol/config.h.in +++ b/libgcobol/config.h.in @@ -3,6 +3,9 @@ /* Define to 1 if the target assembler supports thread-local storage. */ #undef HAVE_CC_TLS +/* Define to 1 if you have the `clock_gettime' function. */ +#undef HAVE_CLOCK_GETTIME + /* Define to 1 if you have the header file. */ #undef HAVE_COMPLEX_H diff --git a/libgcobol/configure b/libgcobol/configure index 5f319eedf538..72715177c230 100755 --- a/libgcobol/configure +++ b/libgcobol/configure @@ -17275,6 +17275,59 @@ if test "$ac_res" != no; then : fi +# Copied from gcc/configure.ac. 2025-06-05 R.J.Dubner +# At least for glibc, clock_gettime is in librt. But don't pull that +# in if it still doesn't give us the function we want. +ac_cv_func_clock_gettime=no +if test $ac_cv_func_clock_gettime = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 +$as_echo_n "checking for clock_gettime in -lrt... " >&6; } +if ${ac_cv_lib_rt_clock_gettime+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char clock_gettime (); +int +main () +{ +return clock_gettime (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_rt_clock_gettime=yes +else + ac_cv_lib_rt_clock_gettime=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5 +$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; } +if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then : + LIBS="-lrt $LIBS" + +$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h + +fi + +fi + have_iec_60559_libc_support=no if test "x$ac_cv_func_strtof128$ac_cv_func_strfromf128" = xyesyes \ && test "x$libgcobol_have_sinf128$libgcobol_have_cacosf128" = xyesyes; then diff --git a/libgcobol/configure.ac b/libgcobol/configure.ac index 13326960515a..acfca7e68e43 100644 --- a/libgcobol/configure.ac +++ b/libgcobol/configure.ac @@ -232,6 +232,17 @@ AC_SEARCH_LIBS([sinf128], [c m], libgcobol_have_sinf128=yes) libgcobol_have_cacosf128=no AC_SEARCH_LIBS([cacosf128], [c m], libgcobol_have_cacosf128=yes) +# Copied from gcc/configure.ac. 2025-06-05 R.J.Dubner +# At least for glibc, clock_gettime is in librt. But don't pull that +# in if it still doesn't give us the function we want. +ac_cv_func_clock_gettime=no +if test $ac_cv_func_clock_gettime = no; then + AC_CHECK_LIB(rt, clock_gettime, + [LIBS="-lrt $LIBS" + AC_DEFINE(HAVE_CLOCK_GETTIME, 1, + [Define to 1 if you have the `clock_gettime' function.])]) +fi + have_iec_60559_libc_support=no if test "x$ac_cv_func_strtof128$ac_cv_func_strfromf128" = xyesyes \ && test "x$libgcobol_have_sinf128$libgcobol_have_cacosf128" = xyesyes; then diff --git a/libgcobol/gfileio.cc b/libgcobol/gfileio.cc index c09102168e46..51a73cd5315c 100644 --- a/libgcobol/gfileio.cc +++ b/libgcobol/gfileio.cc @@ -28,8 +28,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// cppcheck-suppress-file postfixOperator - #include #include #include @@ -107,11 +105,6 @@ */ -/* cppcheck has its opinions about ++iterator being superior to iterator++. - however, can't abide by the prefix notation; it just looks dumb to me. - And I have to believe that in the year of our Lord 2025 that the - optimizing algorithms in modern compilers have sorted this out by now. */ - extern "C" void __gg__handle_error(const char *function, const char *msg) @@ -1814,7 +1807,7 @@ relative_file_rewrite_varying( cblc_file_t *file, bool is_random ) done: // Per the standard, return the file location pointer back to whence it came: fseek(file->file_pointer, starting_position, SEEK_SET); - handle_ferror(file, __func__, "fseek() error"); + handle_ferror(file, __func__, "fseek() error"); file->prior_op = file_op_rewrite; establish_status(file, starting_position); } @@ -1915,7 +1908,7 @@ relative_file_rewrite( cblc_file_t *file, size_t length, bool is_random ) done: // Per the standard, return the file location pointer back to whence it came: fseek(file->file_pointer, starting_position, SEEK_SET); - handle_ferror(file, __func__, "fseek() error"); + handle_ferror(file, __func__, "fseek() error"); file->prior_op = file_op_rewrite; establish_status(file, starting_position); } diff --git a/libgcobol/intrinsic.cc b/libgcobol/intrinsic.cc index 1053bf627435..81ae638630f1 100644 --- a/libgcobol/intrinsic.cc +++ b/libgcobol/intrinsic.cc @@ -167,7 +167,7 @@ JD_to_DOW(double JD) static char * -timespec_to_string(char *retval, struct timespec &tp) +timespec_to_string(char *retval, struct cbl_timespec &tp) { /* Returns a 21-character string: @@ -1218,8 +1218,8 @@ void __gg__current_date(cblc_field_t *dest) { // FUNCTION CURRENT-DATE - struct timespec tp = {}; - __gg__clock_gettime(CLOCK_REALTIME, &tp); // time_t tv_sec; long tv_nsec + struct cbl_timespec tp = {}; + __gg__clock_gettime(&tp); // time_t tv_sec; long tv_nsec char retval[DATE_STRING_BUFFER_SIZE]; timespec_to_string(retval, tp); @@ -1232,11 +1232,11 @@ void __gg__seconds_past_midnight(cblc_field_t *dest) { // SECONDS-PAST-MIDNIGHT - struct timespec tp = {}; + struct cbl_timespec tp = {}; struct tm tm; __int128 retval=0; - __gg__clock_gettime(CLOCK_REALTIME, &tp); // time_t tv_sec; long tv_nsec + __gg__clock_gettime(&tp); // time_t tv_sec; long tv_nsec localtime_r(&tp.tv_sec, &tm); retval += tm.tm_hour; @@ -1460,7 +1460,7 @@ __gg__formatted_current_date( cblc_field_t *dest, // Destination string size_t input_offset, size_t input_size) { - // FUNCTION CURRENT-DATE + // FUNCTION FORMATTED-CURRENT-DATE // Establish the destination, and set it to spaces char *d = PTRCAST(char, dest->data); @@ -1484,8 +1484,8 @@ __gg__formatted_current_date( cblc_field_t *dest, // Destination string } } - struct timespec ts = {}; - __gg__clock_gettime(CLOCK_REALTIME, &ts); + struct cbl_timespec ts = {}; + __gg__clock_gettime(&ts); struct tm tm = {}; #ifdef HAVE_STRUCT_TM_TM_ZONE @@ -3432,8 +3432,8 @@ __gg__random( cblc_field_t *dest, buf->state = NULL; state = (char *)malloc(state_len); - struct timespec ts; - __gg__clock_gettime(CLOCK_REALTIME, &ts); + struct cbl_timespec ts; + __gg__clock_gettime(&ts); initstate_r( ts.tv_nsec, state, state_len, buf); } int seed = (int)__gg__binary_value_from_qualified_field(&rdigits, @@ -3472,8 +3472,8 @@ __gg__random_next(cblc_field_t *dest) buf = (random_data *)malloc(sizeof(struct random_data)); buf->state = NULL; state = (char *)malloc(state_len); - struct timespec ts; - __gg__clock_gettime(CLOCK_REALTIME, &ts); + struct cbl_timespec ts; + __gg__clock_gettime(&ts); initstate_r( ts.tv_nsec, state, state_len, buf); } random_r(buf, &retval_31); @@ -3776,7 +3776,7 @@ extern "C" void __gg__when_compiled(cblc_field_t *dest, size_t tv_sec, long tv_nsec) { - struct timespec tp = {}; + struct cbl_timespec tp = {}; tp.tv_sec = tv_sec; tp.tv_nsec = tv_nsec; char retval[DATE_STRING_BUFFER_SIZE]; diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc index f17c659bdd50..c3d78d465b77 100644 --- a/libgcobol/libgcobol.cc +++ b/libgcobol/libgcobol.cc @@ -69,6 +69,7 @@ #include #include #include +#include #include #include "exceptl.h" @@ -264,10 +265,9 @@ class ec_status_t { , operation(file_op_none) , mode(file_mode_none_e) , user_status(nullptr) - , filename(nullptr) + , filename(nullptr) {} -// cppcheck-suppress noExplicitConstructor - file_status_t( const cblc_file_t *file ) + explicit file_status_t( const cblc_file_t *file ) : ifile(file->symbol_table_index) , operation(file->prior_op) , mode(cbl_file_mode_t(file->mode_char)) @@ -296,7 +296,7 @@ class ec_status_t { cbl_declaratives_t declaratives; struct file_status_t file; public: - size_t lineno; + int lineno; const char *source_file; cbl_name_t statement; // e.g., "ADD" @@ -325,7 +325,8 @@ class ec_status_t { } ec_status_t& clear() { handled = type = ec_none_e; - isection = lineno = 0; + isection = 0; + lineno = 0; msg[0] = statement[0] = '\0'; return *this; } @@ -345,7 +346,7 @@ class ec_status_t { const file_status_t& file_status() const { return file; } const char * exception_location() { - snprintf(msg, sizeof(msg), "%s:%zu: '%s'", source_file, lineno, statement); + snprintf(msg, sizeof(msg), "%s:%d: '%s'", source_file, lineno, statement); return msg; } }; @@ -558,7 +559,7 @@ __gg__abort(const char *msg) abort(); } -void +void __gg__mabort() { __gg__abort("Memory allocation error\n"); @@ -2289,8 +2290,8 @@ get_binary_value_local( int *rdigits, static time_t cobol_time() { - struct timespec tp; - __gg__clock_gettime(CLOCK_REALTIME, &tp); + struct cbl_timespec tp; + __gg__clock_gettime(&tp); return tp.tv_sec; } @@ -2402,10 +2403,49 @@ int_from_digits(const char * &p, int ndigits) return retval; } +// For testing purposes, this undef causes the use of gettimeofday(). +// #undef HAVE_CLOCK_GETTIME + +static uint64_t +get_time_nanoseconds_local() +{ + // This code was unabashedly stolen from gcc/timevar.cc. + // It returns the Unix epoch with nine decimal places. + + /* Note: I am perplexed. I have been examining the gcc Makefiles and + configure.ac files, and I am unable to locate where HAVE_GETTIMEOFDAY + is established. There have been issues compiling on MacOS, where + apparently clock_gettime() is not available. But I don't see exactly + how gettimeofday() gets used, instead. But without the ability to + compile on a MacOS system, I am fumbling along as best I can. + + I decided to simply replace clock_gettime() with getttimeofday() when + clock_gettime() isn't available, even though gcc/timevar.cc handles + the situation differently. + + -- Bob Dubner, 2025-06-11*/ + + uint64_t retval = 0; + +#ifdef HAVE_CLOCK_GETTIME + struct timespec ts; + clock_gettime (CLOCK_REALTIME, &ts); + retval = ts.tv_sec * 1000000000 + ts.tv_nsec; + return retval; +//#endif +//#ifdef HAVE_GETTIMEOFDAY +#else + struct timeval tv; + gettimeofday (&tv, NULL); + retval = tv.tv_sec * 1000000000 + tv.tv_usec * 1000; + return retval; +#endif + return retval; +} extern "C" void -__gg__clock_gettime(clockid_t clk_id, struct timespec *tp) +__gg__clock_gettime(struct cbl_timespec *tp) { const char *p = getenv("GCOBOL_CURRENT_DATE"); @@ -2435,7 +2475,9 @@ __gg__clock_gettime(clockid_t clk_id, struct timespec *tp) } else { - clock_gettime(clk_id, tp); + uint64_t ns = get_time_nanoseconds_local(); + tp->tv_sec = ns/1000000000; + tp->tv_nsec = ns%1000000000; } } @@ -2445,8 +2487,8 @@ __gg__get_date_hhmmssff() { char ach[32]; - struct timespec tv; - __gg__clock_gettime(CLOCK_REALTIME, &tv); + struct cbl_timespec tv; + __gg__clock_gettime(&tv); struct tm tm; localtime_r(&tv.tv_sec, &tm); @@ -3665,7 +3707,7 @@ compare_88( const char *list, } else { - cmpval = cstrncmp (test, + cmpval = cstrncmp (test, PTRCAST(char, conditional_location), conditional_length); if( cmpval == 0 && (int)strlen(test) != conditional_length ) @@ -4547,7 +4589,7 @@ __gg__compare_2(cblc_field_t *left_side, } static size_t right_string_size = MINIMUM_ALLOCATION_SIZE; - static char *right_string + static char *right_string = static_cast(malloc(right_string_size)); right_string = format_for_display_internal( @@ -10090,55 +10132,73 @@ __gg__classify( classify_t type, return retval; } -extern "C" +static int -__gg__accept_envar( cblc_field_t *tgt, - size_t tgt_offset, - size_t tgt_length, - cblc_field_t *name, - size_t name_offset, - size_t name_length) +accept_envar( cblc_field_t *tgt, + size_t tgt_offset, + size_t tgt_length, + const char *psz_name) { - int retval; - tgt_length = tgt_length ? tgt_length : tgt->capacity; - name_length = name_length ? name_length : name->capacity; - - // Pick up the environment variable name, which is in teh internal codeset - static char *env = NULL; - static size_t env_length = 0; - if( env_length < name_length+1 ) + int retval = 1; // 1 means we couldn't find it + if( psz_name ) { - env_length = name_length+1; - env = static_cast(realloc(env, env_length)); - } - memcpy(env, name->data + name_offset, name_length); - env[name_length] = '\0'; + tgt_length = tgt_length ? tgt_length : tgt->capacity; - // Get rid of leading and trailing internal_space characters: - char *trimmed_env = brute_force_trim(env); + // Pick up the environment variable name, which is in the internal codeset + char *env = strdup(psz_name); + massert(env); - // Convert the name to the console codeset: - __gg__internal_to_console_in_place(trimmed_env, strlen(trimmed_env)); + // Get rid of leading and trailing internal_space characters: + char *trimmed_env = brute_force_trim(env); - // Pick up the environment variable, and convert it to the internal codeset - const char *p = getenv(trimmed_env); - if(p) - { - char *pp = strdup(p); - console_to_internal(pp, strlen(pp)); - retval = 0; // Okay - move_string(tgt, tgt_offset, tgt_length, pp); - free(pp); + // Convert the name to the console codeset: + __gg__internal_to_console_in_place(trimmed_env, strlen(trimmed_env)); + + // Pick up the environment variable, and convert it to the internal codeset + const char *p = getenv(trimmed_env); + if(p) + { + char *pp = strdup(p); + massert(pp); + console_to_internal(pp, strlen(pp)); + retval = 0; // Okay + move_string(tgt, tgt_offset, tgt_length, pp); + free(pp); + } + free(env); } - else + + if( retval == 1 ) { - retval = 1; // Could't find it + // Could't find it exception_raise(ec_argument_imp_environment_e); } return retval; } +extern "C" +int +__gg__accept_envar( cblc_field_t *tgt, + size_t tgt_offset, + size_t tgt_length, + const cblc_field_t *name, + size_t name_offset, + size_t name_length) + { + // We need the name to be nul-terminated: + char *p = static_cast(malloc(name_length + 1)); + massert(p); + memcpy(p, name->data+name_offset, name_length); + p[name_length] = '\0'; + int retval = accept_envar(tgt, + tgt_offset, + tgt_length, + p); + free(p); + return retval; + } + extern "C" bool __gg__set_envar(cblc_field_t *name, @@ -11196,44 +11256,51 @@ match_declarative( bool enabled, } if( matches && MATCH_DECLARATIVE ) { - warnx(" matches exception %s (file %zu mode %s)", + warnx(" matches exception %s (file %u mode %s)", local_ec_type_str(raised.type), - raised.file, + static_cast(raised.file), cbl_file_mode_str(raised.mode)); } } return matches; } -/* - * The default exception handler is called if: - * 1. The EC is enabled and was not handled by a Declarative, or - * 2. The EC is EC-I-O and was not handled by a Format-1 Declarative, or - * 3. The EC is EC-I-O, associated with a file, and is not OPEN or CLOSE. - */ -static void -default_exception_handler( ec_type_t ec ) +static +void open_syslog(int option, int facility) { + static bool first_time = true; + if( first_time ) { #if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME /* Declared in errno.h, when available. */ - static const char * const ident = program_invocation_short_name; + static const char * const ident = program_invocation_short_name; #elif defined (HAVE_GETPROGNAME) /* Declared in stdlib.h. */ - static const char * const ident = getprogname(); + static const char * const ident = getprogname(); #else /* Avoid a NULL entry. */ - static const char * const ident = "unnamed_COBOL_program"; + static const char * const ident = "unnamed_COBOL_program"; #endif - static bool first_time = true; - static const int priority = LOG_INFO, option = LOG_PERROR, facility = LOG_USER; - ec_disposition_t disposition = ec_category_fatal_e; - - if( first_time ) { // TODO: Program to set option in library via command-line and/or environment. // Library listens to program, not to the environment. openlog(ident, option, facility); first_time = false; } +} + +/* + * The default exception handler is called if: + * 1. The EC is enabled and was not handled by a Declarative, or + * 2. The EC is EC-I-O and was not handled by a Format-1 Declarative, or + * 3. The EC is EC-I-O, associated with a file, and is not OPEN or CLOSE. + */ +static void +default_exception_handler( ec_type_t ec ) +{ + static const int priority = LOG_INFO, option = LOG_PERROR, facility = LOG_USER; + open_syslog(option, facility); + + ec_disposition_t disposition = ec_category_fatal_e; + if( ec != ec_none_e ) { auto pec = std::find_if( __gg__exception_table, __gg__exception_table_end, @@ -11286,7 +11353,7 @@ default_exception_handler( ec_type_t ec ) case ec_category_fatal_e: case uc_category_fatal_e: if( filename ) { - syslog(priority, "fatal exception: %s:%zu: %s %s: %s (%s)", + syslog(priority, "fatal exception: %s:%d: %s %s: %s (%s)", program_name, ec_status.lineno, ec_status.statement, @@ -11294,7 +11361,7 @@ default_exception_handler( ec_type_t ec ) pec->name, pec->description); } else { - syslog(priority, "fatal exception: %s:%zu: %s: %s (%s)", + syslog(priority, "fatal exception: %s:%d: %s: %s (%s)", program_name, ec_status.lineno, ec_status.statement, @@ -11305,7 +11372,7 @@ default_exception_handler( ec_type_t ec ) break; case ec_category_nonfatal_e: case uc_category_nonfatal_e: - syslog(priority, "%s:%zu: %s: %s (%s)", + syslog(priority, "%s:%d: %s: %s (%s)", program_name, ec_status.lineno, ec_status.statement, @@ -11367,7 +11434,11 @@ __gg__check_fatal_exception() warnx("%s: ec_status is %s", __func__, ec_status.unset()? "unset" : "set"); if( ec_status.copy_environment().unset() ) + { ec_status.update(); // __gg__match_exception was not called first + // This is a good time to set the exception code back to zero + __gg__exception_code = 0; + } if( ec_status.done() ) { // false for part-handled fatal if( MATCH_DECLARATIVE ) @@ -11434,8 +11505,10 @@ __gg__exception_push() { ec_stack.push(ec_status); if( MATCH_DECLARATIVE ) - warnx("%s: %s: %zu ECs, %zu declaratives", __func__, - __gg__exception_statement, enabled_ECs.size(), declaratives.size()); + warnx("%s: %s: %u ECs, %u declaratives", __func__, + __gg__exception_statement, + static_cast(enabled_ECs.size()), + static_cast(declaratives.size())); } /* @@ -11449,8 +11522,10 @@ __gg__exception_pop() ec_stack.pop(); ec_status.reset_environment(); if( MATCH_DECLARATIVE ) - warnx("%s: %s: %zu ECs, %zu declaratives", __func__, - __gg__exception_statement, enabled_ECs.size(), declaratives.size()); + warnx("%s: %s: %u ECs, %u declaratives", __func__, + __gg__exception_statement, + static_cast(enabled_ECs.size()), + static_cast(declaratives.size())); __gg__check_fatal_exception(); } @@ -11464,11 +11539,11 @@ __gg__clear_exception() void cbl_enabled_exception_t::dump( int i ) const { - warnx("cbl_enabled_exception_t: %2d {%s, %s, %zu}", + warnx("cbl_enabled_exception_t: %2d {%s, %s, %u}", i, location? "location" : " none", local_ec_type_str(ec), - file ); + static_cast(file) ); } /* @@ -11504,6 +11579,10 @@ __gg__match_exception( cblc_field_t *index ) * Format 1 may be restricted to a particular mode (for all files). * Format 1 and 3 may be restricted to a set of files. */ + + // This is a good time to set the actual exception code back to zero. + __gg__exception_code = 0; + auto f = ec_status.file_status(); cbl_exception_t raised = { /*0,*/ f.ifile, ec, f.mode }; bool enabled = enabled_ECs.match(ec); @@ -11518,8 +11597,9 @@ __gg__match_exception( cblc_field_t *index ) if( p == declaratives.end() ) { if( MATCH_DECLARATIVE ) { warnx("__gg__match_exception:%d: raised exception " - "%s not matched (%zu enabled)", __LINE__, - local_ec_type_str(ec), enabled_ECs.size()); + "%s not matched (%u enabled)", __LINE__, + local_ec_type_str(ec), + static_cast(enabled_ECs.size())); } } else { isection = p->section; @@ -11527,11 +11607,11 @@ __gg__match_exception( cblc_field_t *index ) if( MATCH_DECLARATIVE ) { warnx("__gg__match_exception:%d: matched " - "%s against mask %s for section #%zu", + "%s against mask %s for section #%u", __LINE__, local_ec_type_str(ec), local_ec_type_str(p->type), - p->section); + static_cast(p->section)); } } assert(ec != ec_none_e); @@ -13056,12 +13136,12 @@ cbl_enabled_exceptions_t::dump( const char tag[] ) const { } int i = 1; for( auto& elem : *this ) { - warnx("%s: %2d {%s, %04x %s, %ld}", tag, - i++, - elem.location? "with location" : " no location", - elem.ec, - local_ec_type_str(elem.ec), - elem.file ); + warnx("%s: %2d {%s, %04x %s, %u}", tag, + i++, + elem.location? "with location" : " no location", + elem.ec, + local_ec_type_str(elem.ec), + static_cast(elem.file) ); } } @@ -13093,6 +13173,7 @@ operator<<( std::vector& dcls, return decode( dcls, encoded ); } +// The first element of each array is the number of elements that follow // The first element of each array is the number of elements that follow extern "C" void @@ -13111,7 +13192,9 @@ __gg__set_exception_environment( uint64_t *ecs, uint64_t *dcls ) if( prior.ecs != ecs ) { uint64_t *ecs_begin = ecs + 1, *ecs_end = ecs_begin + ecs[0]; if( MATCH_DECLARATIVE ) { - warnx("%zu elements implies %zu ECs", ecs[0], ecs[0] / 3); + warnx("%u elements implies %u ECs", + static_cast(ecs[0]), + static_cast(ecs[0] / 3)); } cbl_enabled_exceptions_t enabled; enabled_ECs = enabled.decode( std::vector(ecs_begin, ecs_end) ); @@ -13125,7 +13208,9 @@ __gg__set_exception_environment( uint64_t *ecs, uint64_t *dcls ) if( prior.dcls != dcls ) { uint64_t *dcls_begin = dcls + 1, *dcls_end = dcls_begin + dcls[0]; if( MATCH_DECLARATIVE ) { - warnx("%zu elements implies %zu declaratives", dcls[0], dcls[0] / 21); + warnx("%u elements implies %u declaratives", + static_cast(dcls[0]), + static_cast(dcls[0] / 21)); } declaratives.clear(); declaratives << std::vector( dcls_begin, dcls_end ); @@ -13148,6 +13233,7 @@ __gg__set_env_name( const cblc_field_t *var, size_t offset, size_t length ) { + // implements DISPLAY UPON ENVIRONMENT-NAME free(sv_envname); sv_envname = static_cast(malloc(length+1)); massert(sv_envname); @@ -13155,12 +13241,41 @@ __gg__set_env_name( const cblc_field_t *var, sv_envname[length] = '\0'; } + +extern "C" +void +__gg__get_env_name( cblc_field_t *dest, + size_t dest_offset, + size_t dest_length) + { + // Implements ACCEPT FROM ENVIRONMENT-NAME + // It returns the value previously established by __gg__set_env_name. + if( sv_envname ) + { + sv_envname = strdup(""); + } + move_string(dest, dest_offset, dest_length, sv_envname); + } + +extern "C" +int +__gg__get_env_value(cblc_field_t *dest, + size_t dest_offset, + size_t dest_length) + { + return accept_envar(dest, + dest_offset, + dest_length, + sv_envname); + } + extern "C" void __gg__set_env_value(const cblc_field_t *value, size_t offset, size_t length ) { + // implements DISPLAY UPON ENVIRONMENT-VALUE size_t name_length = strlen(sv_envname); size_t value_length = length; @@ -13199,6 +13314,11 @@ __gg__set_env_value(const cblc_field_t *value, setenv(trimmed_env, trimmed_val, 1); } +extern "C" +void +__gg__fprintf_stderr(const char *format_string, ...) + __attribute__ ((__format__ (__printf__, 1, 2))); + extern "C" void __gg__fprintf_stderr(const char *format_string, ...) @@ -13211,3 +13331,81 @@ __gg__fprintf_stderr(const char *format_string, ...) va_end(ap); } + +static int sv_argument_number = 0; + +extern "C" +void +__gg__set_arg_num( const cblc_field_t *index, + size_t index_offset, + size_t index_size ) + { + // Implements DISPLAY UPON ARGUMENT-NUMBER. + int rdigits; + __int128 N = get_binary_value_local(&rdigits, + index, + index->data + index_offset, + index_size); + // If he gives us fractional digits, just truncate + N /= __gg__power_of_ten(rdigits); + + // N is 1-based, per normal COBOL. We have to decrement it here: + N -= 1; + sv_argument_number = static_cast(N); + } + +extern "C" +int +__gg__accept_arg_value( cblc_field_t *dest, + size_t dest_offset, + size_t dest_length) + { + // Implements ACCEPT FROM ARGUMENT-VALUE + int retcode; + command_line_plan_b(); + if( sv_argument_number >= stashed_argc || sv_argument_number < 0 ) + { + exception_raise(ec_argument_imp_command_e); + retcode = 1; // Error + } + else + { + char *retval = strdup(stashed_argv[sv_argument_number]); + console_to_internal(retval, strlen(retval)); + move_string(dest, dest_offset, dest_length, retval); + free(retval); + retcode = 0; // Okay + + // The Fujitsu spec says bump this value by one. + sv_argument_number += 1; + } + return retcode; + } + +extern "C" +int +__gg__get_file_descriptor(const char *device) + { + int retval = open(device, O_WRONLY); + + if( retval == -1 ) + { + char *msg; + int ec = asprintf(&msg, + "Trying to open %s. Got error %s", + device, + strerror(errno)); + if( ec != -1 ) + { + static const int priority = LOG_INFO, + option = LOG_PERROR, + facility = LOG_USER; + open_syslog(option, facility); + syslog(priority, "%s", msg); + } + + // Open a new handle to /dev/stdout, since our caller will be closing it + retval = open("/dev/stdout", O_WRONLY); + } + return retval; + } diff --git a/libgcobol/libgcobol.h b/libgcobol/libgcobol.h index ace321d20e41..2f5c8b0e63c2 100644 --- a/libgcobol/libgcobol.h +++ b/libgcobol/libgcobol.h @@ -47,13 +47,6 @@ extern void __gg__mabort(); // malloc(). #define massert(p) if(!p){__gg__mabort();abort();} -// This was part of an exercise to make cppcheck shut up about invalid -// pointer type conversions. -// It was also to avoid having reinterpret_cast<> all over the place. -// So, instead of reinterpret_cast(VALUE) -// I sometimes use PTRCAST(char, VALUE) -#define PTRCAST(TYPE, VALUE) static_cast(static_cast(VALUE)) - extern "C" __int128 __gg__power_of_ten(int n); extern "C" __int128 __gg__dirty_to_binary_source( const char *dirty, @@ -104,7 +97,15 @@ extern "C" char __gg__get_decimal_separator(); extern "C" char __gg__get_decimal_point(); extern "C" char * __gg__get_default_currency_string(); -extern "C" void __gg__clock_gettime(clockid_t clk_id, struct timespec *tp); +struct cbl_timespec + { + /* You keep using that word "portability". I do not think it means what + you think it means. */ + time_t tv_sec; // Seconds. + long tv_nsec; // Nanoseconds. + } ; + +extern "C" void __gg__clock_gettime(struct cbl_timespec *tp); extern "C" GCOB_FP128 __gg__float128_from_location( const cblc_field_t *var, diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 1f658d5d3d2e..057b850c7374 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,162 @@ +2025-06-18 Harald Anlauf + + PR fortran/82480 + * intrinsics/stat.c (stat_i4_sub_0): Fix argument names. Rename + SARRAY to VALUES also in error message. When array VALUES is + KIND=4, get only stat components that do not overflow INT32_MAX, + otherwise set the corresponding VALUES elements to -1. + (stat_i4_sub): Fix argument names. + (lstat_i4_sub): Likewise. + (stat_i8_sub_0): Likewise. + (stat_i8_sub): Likewise. + (lstat_i8_sub): Likewise. + (stat_i4): Likewise. + (stat_i8): Likewise. + (lstat_i4): Likewise. + (lstat_i8): Likewise. + (fstat_i4_sub): Likewise. + (fstat_i8_sub): Likewise. + (fstat_i4): Likewise. + (fstat_i8): Likewise. + +2025-06-11 François-Xavier Coudert + + PR libfortran/116400 + * Makefile.am: Simplify logic. + * Makefile.in: Regenerate. + * regenerate.sh: Add some checks. + +2025-06-10 François-Xavier Coudert + + PR libfortran/116400 + * Makefile.am: Remove source file regeneration rules. + * Makefile.in: Regenerate. + * regenerate.sh: New file. + +2025-06-07 François-Xavier Coudert + + PR libfortran/116400 + * generated/iall_i1.c: Regenerate. + * generated/iall_i16.c: Regenerate. + * generated/iall_i2.c: Regenerate. + * generated/iall_i4.c: Regenerate. + * generated/iall_i8.c: Regenerate. + * generated/iany_i1.c: Regenerate. + * generated/iany_i16.c: Regenerate. + * generated/iany_i2.c: Regenerate. + * generated/iany_i4.c: Regenerate. + * generated/iany_i8.c: Regenerate. + * generated/iparity_i1.c: Regenerate. + * generated/iparity_i16.c: Regenerate. + * generated/iparity_i2.c: Regenerate. + * generated/iparity_i4.c: Regenerate. + * generated/iparity_i8.c: Regenerate. + * generated/matmulavx128_c10.c: Regenerate. + * generated/matmulavx128_c16.c: Regenerate. + * generated/matmulavx128_c17.c: Regenerate. + * generated/matmulavx128_c4.c: Regenerate. + * generated/matmulavx128_c8.c: Regenerate. + * generated/matmulavx128_i1.c: Regenerate. + * generated/matmulavx128_i16.c: Regenerate. + * generated/matmulavx128_i2.c: Regenerate. + * generated/matmulavx128_i4.c: Regenerate. + * generated/matmulavx128_i8.c: Regenerate. + * generated/matmulavx128_r10.c: Regenerate. + * generated/matmulavx128_r16.c: Regenerate. + * generated/matmulavx128_r17.c: Regenerate. + * generated/matmulavx128_r4.c: Regenerate. + * generated/matmulavx128_r8.c: Regenerate. + * generated/maxloc1_16_i1.c: Regenerate. + * generated/maxloc1_16_i16.c: Regenerate. + * generated/maxloc1_16_i2.c: Regenerate. + * generated/maxloc1_16_i4.c: Regenerate. + * generated/maxloc1_16_i8.c: Regenerate. + * generated/maxloc1_16_r10.c: Regenerate. + * generated/maxloc1_16_r16.c: Regenerate. + * generated/maxloc1_16_r17.c: Regenerate. + * generated/maxloc1_16_r4.c: Regenerate. + * generated/maxloc1_16_r8.c: Regenerate. + * generated/maxloc1_4_i1.c: Regenerate. + * generated/maxloc1_4_i16.c: Regenerate. + * generated/maxloc1_4_i2.c: Regenerate. + * generated/maxloc1_4_i4.c: Regenerate. + * generated/maxloc1_4_i8.c: Regenerate. + * generated/maxloc1_4_r10.c: Regenerate. + * generated/maxloc1_4_r16.c: Regenerate. + * generated/maxloc1_4_r17.c: Regenerate. + * generated/maxloc1_4_r4.c: Regenerate. + * generated/maxloc1_4_r8.c: Regenerate. + * generated/maxloc1_8_i1.c: Regenerate. + * generated/maxloc1_8_i16.c: Regenerate. + * generated/maxloc1_8_i2.c: Regenerate. + * generated/maxloc1_8_i4.c: Regenerate. + * generated/maxloc1_8_i8.c: Regenerate. + * generated/maxloc1_8_r10.c: Regenerate. + * generated/maxloc1_8_r16.c: Regenerate. + * generated/maxloc1_8_r17.c: Regenerate. + * generated/maxloc1_8_r4.c: Regenerate. + * generated/maxloc1_8_r8.c: Regenerate. + * generated/maxval_i1.c: Regenerate. + * generated/maxval_i16.c: Regenerate. + * generated/maxval_i2.c: Regenerate. + * generated/maxval_i4.c: Regenerate. + * generated/maxval_i8.c: Regenerate. + * generated/maxval_r10.c: Regenerate. + * generated/maxval_r16.c: Regenerate. + * generated/maxval_r17.c: Regenerate. + * generated/maxval_r4.c: Regenerate. + * generated/maxval_r8.c: Regenerate. + * generated/minloc1_16_i1.c: Regenerate. + * generated/minloc1_16_i16.c: Regenerate. + * generated/minloc1_16_i2.c: Regenerate. + * generated/minloc1_16_i4.c: Regenerate. + * generated/minloc1_16_i8.c: Regenerate. + * generated/minloc1_16_r10.c: Regenerate. + * generated/minloc1_16_r16.c: Regenerate. + * generated/minloc1_16_r17.c: Regenerate. + * generated/minloc1_16_r4.c: Regenerate. + * generated/minloc1_16_r8.c: Regenerate. + * generated/minloc1_4_i1.c: Regenerate. + * generated/minloc1_4_i16.c: Regenerate. + * generated/minloc1_4_i2.c: Regenerate. + * generated/minloc1_4_i4.c: Regenerate. + * generated/minloc1_4_i8.c: Regenerate. + * generated/minloc1_4_r10.c: Regenerate. + * generated/minloc1_4_r16.c: Regenerate. + * generated/minloc1_4_r17.c: Regenerate. + * generated/minloc1_4_r4.c: Regenerate. + * generated/minloc1_4_r8.c: Regenerate. + * generated/minloc1_8_i1.c: Regenerate. + * generated/minloc1_8_i16.c: Regenerate. + * generated/minloc1_8_i2.c: Regenerate. + * generated/minloc1_8_i4.c: Regenerate. + * generated/minloc1_8_i8.c: Regenerate. + * generated/minloc1_8_r10.c: Regenerate. + * generated/minloc1_8_r16.c: Regenerate. + * generated/minloc1_8_r17.c: Regenerate. + * generated/minloc1_8_r4.c: Regenerate. + * generated/minloc1_8_r8.c: Regenerate. + * generated/minval_i1.c: Regenerate. + * generated/minval_i16.c: Regenerate. + * generated/minval_i2.c: Regenerate. + * generated/minval_i4.c: Regenerate. + * generated/minval_i8.c: Regenerate. + * generated/minval_r10.c: Regenerate. + * generated/minval_r16.c: Regenerate. + * generated/minval_r17.c: Regenerate. + * generated/minval_r4.c: Regenerate. + * generated/minval_r8.c: Regenerate. + * generated/norm2_r10.c: Regenerate. + * generated/norm2_r16.c: Regenerate. + * generated/norm2_r17.c: Regenerate. + * generated/norm2_r4.c: Regenerate. + * generated/norm2_r8.c: Regenerate. + * generated/parity_l1.c: Regenerate. + * generated/parity_l16.c: Regenerate. + * generated/parity_l2.c: Regenerate. + * generated/parity_l4.c: Regenerate. + * generated/parity_l8.c: Regenerate. + 2025-06-01 Jerry DeLisle PR libfortran/119856 diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am index 60aa949fb629..4f3b30332245 100644 --- a/libgfortran/Makefile.am +++ b/libgfortran/Makefile.am @@ -240,102 +240,61 @@ runtime/stop.c endif -i_all_c= \ +i_matmul_c= \ +generated/matmul_i1.c \ +generated/matmul_i2.c \ +generated/matmul_i4.c \ +generated/matmul_i8.c \ +generated/matmul_i16.c \ +generated/matmul_r4.c \ +generated/matmul_r8.c \ +generated/matmul_r10.c \ +generated/matmul_r16.c \ +generated/matmul_r17.c \ +generated/matmul_c4.c \ +generated/matmul_c8.c \ +generated/matmul_c10.c \ +generated/matmul_c16.c \ +generated/matmul_c17.c + +i_matmulavx128_c= \ +generated/matmulavx128_i1.c \ +generated/matmulavx128_i2.c \ +generated/matmulavx128_i4.c \ +generated/matmulavx128_i8.c \ +generated/matmulavx128_i16.c \ +generated/matmulavx128_r4.c \ +generated/matmulavx128_r8.c \ +generated/matmulavx128_r10.c \ +generated/matmulavx128_r16.c \ +generated/matmulavx128_r17.c \ +generated/matmulavx128_c4.c \ +generated/matmulavx128_c8.c \ +generated/matmulavx128_c10.c \ +generated/matmulavx128_c16.c \ +generated/matmulavx128_c17.c + +i_matmull_c= \ +generated/matmul_l4.c \ +generated/matmul_l8.c \ +generated/matmul_l16.c + +gfor_built_src= \ generated/all_l1.c \ generated/all_l2.c \ generated/all_l4.c \ generated/all_l8.c \ -generated/all_l16.c - -i_any_c= \ +generated/all_l16.c \ generated/any_l1.c \ generated/any_l2.c \ generated/any_l4.c \ generated/any_l8.c \ -generated/any_l16.c - -i_bessel_c= \ -generated/bessel_r4.c \ -generated/bessel_r8.c \ -generated/bessel_r10.c \ -generated/bessel_r16.c \ -generated/bessel_r17.c - -i_count_c= \ +generated/any_l16.c \ generated/count_1_l.c \ generated/count_2_l.c \ generated/count_4_l.c \ generated/count_8_l.c \ -generated/count_16_l.c - -i_iall_c= \ -generated/iall_i1.c \ -generated/iall_i2.c \ -generated/iall_i4.c \ -generated/iall_i8.c \ -generated/iall_i16.c - -i_iany_c= \ -generated/iany_i1.c \ -generated/iany_i2.c \ -generated/iany_i4.c \ -generated/iany_i8.c \ -generated/iany_i16.c - -i_iparity_c= \ -generated/iparity_i1.c \ -generated/iparity_i2.c \ -generated/iparity_i4.c \ -generated/iparity_i8.c \ -generated/iparity_i16.c - -i_findloc0_c= \ -generated/findloc0_i1.c \ -generated/findloc0_i2.c \ -generated/findloc0_i4.c \ -generated/findloc0_i8.c \ -generated/findloc0_i16.c \ -generated/findloc0_r4.c \ -generated/findloc0_r8.c \ -generated/findloc0_r10.c \ -generated/findloc0_r16.c \ -generated/findloc0_r17.c \ -generated/findloc0_c4.c \ -generated/findloc0_c8.c \ -generated/findloc0_c10.c \ -generated/findloc0_c16.c \ -generated/findloc0_c17.c - -i_findloc0s_c= \ -generated/findloc0_s1.c \ -generated/findloc0_s4.c - -i_findloc1_c= \ -generated/findloc1_i1.c \ -generated/findloc1_i2.c \ -generated/findloc1_i4.c \ -generated/findloc1_i8.c \ -generated/findloc1_i16.c \ -generated/findloc1_r4.c \ -generated/findloc1_r8.c \ -generated/findloc1_r10.c \ -generated/findloc1_r16.c \ -generated/findloc1_r17.c \ -generated/findloc1_c4.c \ -generated/findloc1_c8.c \ -generated/findloc1_c10.c \ -generated/findloc1_c16.c \ -generated/findloc1_c17.c - -i_findloc1s_c= \ -generated/findloc1_s1.c \ -generated/findloc1_s4.c - -i_findloc2s_c= \ -generated/findloc2_s1.c \ -generated/findloc2_s4.c - -i_maxloc0_c= \ +generated/count_16_l.c \ generated/maxloc0_4_i1.c \ generated/maxloc0_8_i1.c \ generated/maxloc0_16_i1.c \ @@ -380,17 +339,7 @@ generated/maxloc0_8_r16.c \ generated/maxloc0_16_r16.c \ generated/maxloc0_4_r17.c \ generated/maxloc0_8_r17.c \ -generated/maxloc0_16_r17.c - -i_maxloc0s_c = \ -generated/maxloc0_4_s1.c \ -generated/maxloc0_4_s4.c \ -generated/maxloc0_8_s1.c \ -generated/maxloc0_8_s4.c \ -generated/maxloc0_16_s1.c \ -generated/maxloc0_16_s4.c - -i_maxloc1_c= \ +generated/maxloc0_16_r17.c \ generated/maxloc1_4_i1.c \ generated/maxloc1_8_i1.c \ generated/maxloc1_16_i1.c \ @@ -435,25 +384,7 @@ generated/maxloc1_8_r16.c \ generated/maxloc1_16_r16.c \ generated/maxloc1_4_r17.c \ generated/maxloc1_8_r17.c \ -generated/maxloc1_16_r17.c - -i_maxloc1s_c= \ -generated/maxloc1_4_s1.c \ -generated/maxloc1_4_s4.c \ -generated/maxloc1_8_s1.c \ -generated/maxloc1_8_s4.c \ -generated/maxloc1_16_s1.c \ -generated/maxloc1_16_s4.c - -i_maxloc2s_c= \ -generated/maxloc2_4_s1.c \ -generated/maxloc2_4_s4.c \ -generated/maxloc2_8_s1.c \ -generated/maxloc2_8_s4.c \ -generated/maxloc2_16_s1.c \ -generated/maxloc2_16_s4.c - -i_maxval_c= \ +generated/maxloc1_16_r17.c \ generated/maxval_i1.c \ generated/maxval_i2.c \ generated/maxval_i4.c \ @@ -468,17 +399,7 @@ generated/maxval_r4.c \ generated/maxval_r8.c \ generated/maxval_r10.c \ generated/maxval_r16.c \ -generated/maxval_r17.c - -i_maxval0s_c=\ -generated/maxval0_s1.c \ -generated/maxval0_s4.c - -i_maxval1s_c=\ -generated/maxval1_s1.c \ -generated/maxval1_s4.c - -i_minloc0_c= \ +generated/maxval_r17.c \ generated/minloc0_4_i1.c \ generated/minloc0_8_i1.c \ generated/minloc0_16_i1.c \ @@ -523,17 +444,7 @@ generated/minloc0_8_r16.c \ generated/minloc0_16_r16.c \ generated/minloc0_4_r17.c \ generated/minloc0_8_r17.c \ -generated/minloc0_16_r17.c - -i_minloc0s_c = \ -generated/minloc0_4_s1.c \ -generated/minloc0_4_s4.c \ -generated/minloc0_8_s1.c \ -generated/minloc0_8_s4.c \ -generated/minloc0_16_s1.c \ -generated/minloc0_16_s4.c - -i_minloc1_c= \ +generated/minloc0_16_r17.c \ generated/minloc1_4_i1.c \ generated/minloc1_8_i1.c \ generated/minloc1_16_i1.c \ @@ -578,25 +489,7 @@ generated/minloc1_8_r16.c \ generated/minloc1_16_r16.c \ generated/minloc1_4_r17.c \ generated/minloc1_8_r17.c \ -generated/minloc1_16_r17.c - -i_minloc1s_c= \ -generated/minloc1_4_s1.c \ -generated/minloc1_4_s4.c \ -generated/minloc1_8_s1.c \ -generated/minloc1_8_s4.c \ -generated/minloc1_16_s1.c \ -generated/minloc1_16_s4.c - -i_minloc2s_c= \ -generated/minloc2_4_s1.c \ -generated/minloc2_4_s4.c \ -generated/minloc2_8_s1.c \ -generated/minloc2_8_s4.c \ -generated/minloc2_16_s1.c \ -generated/minloc2_16_s4.c - -i_minval_c= \ +generated/minloc1_16_r17.c \ generated/minval_i1.c \ generated/minval_i2.c \ generated/minval_i4.c \ @@ -611,48 +504,7 @@ generated/minval_r4.c \ generated/minval_r8.c \ generated/minval_r10.c \ generated/minval_r16.c \ -generated/minval_r17.c - -i_minval0s_c=\ -generated/minval0_s1.c \ -generated/minval0_s4.c - -i_minval1s_c=\ -generated/minval1_s1.c \ -generated/minval1_s4.c - -i_norm2_c= \ -generated/norm2_r4.c \ -generated/norm2_r8.c \ -generated/norm2_r10.c \ -generated/norm2_r16.c \ -generated/norm2_r17.c - -i_parity_c = \ -generated/parity_l1.c \ -generated/parity_l2.c \ -generated/parity_l4.c \ -generated/parity_l8.c \ -generated/parity_l16.c - -i_sum_c= \ -generated/sum_i1.c \ -generated/sum_i2.c \ -generated/sum_i4.c \ -generated/sum_i8.c \ -generated/sum_i16.c \ -generated/sum_r4.c \ -generated/sum_r8.c \ -generated/sum_r10.c \ -generated/sum_r16.c \ -generated/sum_r17.c \ -generated/sum_c4.c \ -generated/sum_c8.c \ -generated/sum_c10.c \ -generated/sum_c16.c \ -generated/sum_c17.c - -i_product_c= \ +generated/minval_r17.c \ generated/product_i1.c \ generated/product_i2.c \ generated/product_i4.c \ @@ -667,149 +519,79 @@ generated/product_c4.c \ generated/product_c8.c \ generated/product_c10.c \ generated/product_c16.c \ -generated/product_c17.c - -i_matmul_c= \ -generated/matmul_i1.c \ -generated/matmul_i2.c \ -generated/matmul_i4.c \ -generated/matmul_i8.c \ -generated/matmul_i16.c \ -generated/matmul_r4.c \ -generated/matmul_r8.c \ -generated/matmul_r10.c \ -generated/matmul_r16.c \ -generated/matmul_r17.c \ -generated/matmul_c4.c \ -generated/matmul_c8.c \ -generated/matmul_c10.c \ -generated/matmul_c16.c \ -generated/matmul_c17.c - -i_matmulavx128_c= \ -generated/matmulavx128_i1.c \ -generated/matmulavx128_i2.c \ -generated/matmulavx128_i4.c \ -generated/matmulavx128_i8.c \ -generated/matmulavx128_i16.c \ -generated/matmulavx128_r4.c \ -generated/matmulavx128_r8.c \ -generated/matmulavx128_r10.c \ -generated/matmulavx128_r16.c \ -generated/matmulavx128_r17.c \ -generated/matmulavx128_c4.c \ -generated/matmulavx128_c8.c \ -generated/matmulavx128_c10.c \ -generated/matmulavx128_c16.c \ -generated/matmulavx128_c17.c - -i_matmull_c= \ -generated/matmul_l4.c \ -generated/matmul_l8.c \ -generated/matmul_l16.c - -i_shape_c= \ +generated/product_c17.c \ +generated/sum_i1.c \ +generated/sum_i2.c \ +generated/sum_i4.c \ +generated/sum_i8.c \ +generated/sum_i16.c \ +generated/sum_r4.c \ +generated/sum_r8.c \ +generated/sum_r10.c \ +generated/sum_r16.c \ +generated/sum_r17.c \ +generated/sum_c4.c \ +generated/sum_c8.c \ +generated/sum_c10.c \ +generated/sum_c16.c \ +generated/sum_c17.c \ +generated/bessel_r4.c \ +generated/bessel_r8.c \ +generated/bessel_r10.c \ +generated/bessel_r16.c \ +generated/bessel_r17.c \ +generated/iall_i1.c \ +generated/iall_i2.c \ +generated/iall_i4.c \ +generated/iall_i8.c \ +generated/iall_i16.c \ +generated/iany_i1.c \ +generated/iany_i2.c \ +generated/iany_i4.c \ +generated/iany_i8.c \ +generated/iany_i16.c \ +generated/iparity_i1.c \ +generated/iparity_i2.c \ +generated/iparity_i4.c \ +generated/iparity_i8.c \ +generated/iparity_i16.c \ +generated/norm2_r4.c \ +generated/norm2_r8.c \ +generated/norm2_r10.c \ +generated/norm2_r16.c \ +generated/norm2_r17.c \ +generated/parity_l1.c \ +generated/parity_l2.c \ +generated/parity_l4.c \ +generated/parity_l8.c \ +generated/parity_l16.c \ generated/shape_i1.c \ generated/shape_i2.c \ generated/shape_i4.c \ generated/shape_i8.c \ -generated/shape_i16.c - -i_reshape_c= \ -generated/reshape_i4.c \ -generated/reshape_i8.c \ -generated/reshape_i16.c \ -generated/reshape_r4.c \ -generated/reshape_r8.c \ -generated/reshape_r10.c \ -generated/reshape_r16.c \ -generated/reshape_r17.c \ -generated/reshape_c4.c \ -generated/reshape_c8.c \ -generated/reshape_c10.c \ -generated/reshape_c16.c \ -generated/reshape_c17.c - -i_eoshift1_c= \ -generated/eoshift1_4.c \ -generated/eoshift1_8.c \ -generated/eoshift1_16.c - -i_eoshift3_c= \ -generated/eoshift3_4.c \ -generated/eoshift3_8.c \ -generated/eoshift3_16.c - -i_cshift0_c= \ -generated/cshift0_i1.c \ -generated/cshift0_i2.c \ -generated/cshift0_i4.c \ -generated/cshift0_i8.c \ -generated/cshift0_i16.c \ -generated/cshift0_r4.c \ -generated/cshift0_r8.c \ -generated/cshift0_r10.c \ -generated/cshift0_r16.c \ -generated/cshift0_r17.c \ -generated/cshift0_c4.c \ -generated/cshift0_c8.c \ -generated/cshift0_c10.c \ -generated/cshift0_c16.c \ -generated/cshift0_c17.c - -i_cshift1_c= \ -generated/cshift1_4.c \ -generated/cshift1_8.c \ -generated/cshift1_16.c - -i_cshift1a_c = \ -generated/cshift1_4_i1.c \ -generated/cshift1_4_i2.c \ -generated/cshift1_4_i4.c \ -generated/cshift1_4_i8.c \ -generated/cshift1_4_i16.c \ -generated/cshift1_4_r4.c \ -generated/cshift1_4_r8.c \ -generated/cshift1_4_r10.c \ -generated/cshift1_4_r16.c \ -generated/cshift1_4_r17.c \ -generated/cshift1_4_c4.c \ -generated/cshift1_4_c8.c \ -generated/cshift1_4_c10.c \ -generated/cshift1_4_c16.c \ -generated/cshift1_4_c17.c \ -generated/cshift1_8_i1.c \ -generated/cshift1_8_i2.c \ -generated/cshift1_8_i4.c \ -generated/cshift1_8_i8.c \ -generated/cshift1_8_i16.c \ -generated/cshift1_8_r4.c \ -generated/cshift1_8_r8.c \ -generated/cshift1_8_r10.c \ -generated/cshift1_8_r16.c \ -generated/cshift1_8_r17.c \ -generated/cshift1_8_c4.c \ -generated/cshift1_8_c8.c \ -generated/cshift1_8_c10.c \ -generated/cshift1_8_c16.c \ -generated/cshift1_8_c17.c \ -generated/cshift1_16_i1.c \ -generated/cshift1_16_i2.c \ -generated/cshift1_16_i4.c \ -generated/cshift1_16_i8.c \ -generated/cshift1_16_i16.c \ -generated/cshift1_16_r4.c \ -generated/cshift1_16_r8.c \ -generated/cshift1_16_r10.c \ -generated/cshift1_16_r16.c \ -generated/cshift1_16_r17.c \ -generated/cshift1_16_c4.c \ -generated/cshift1_16_c8.c \ -generated/cshift1_16_c10.c \ -generated/cshift1_16_c16.c \ -generated/cshift1_16_c17.c - -in_pack_c = \ +generated/shape_i16.c \ +generated/eoshift1_4.c \ +generated/eoshift1_8.c \ +generated/eoshift1_16.c \ +generated/eoshift3_4.c \ +generated/eoshift3_8.c \ +generated/eoshift3_16.c \ +generated/cshift1_4.c \ +generated/cshift1_8.c \ +generated/cshift1_16.c \ +generated/reshape_i4.c \ +generated/reshape_i8.c \ +generated/reshape_i16.c \ +generated/reshape_r4.c \ +generated/reshape_r8.c \ +generated/reshape_r10.c \ +generated/reshape_r16.c \ +generated/reshape_r17.c \ +generated/reshape_c4.c \ +generated/reshape_c8.c \ +generated/reshape_c10.c \ +generated/reshape_c16.c \ +generated/reshape_c17.c \ generated/in_pack_i1.c \ generated/in_pack_i2.c \ generated/in_pack_i4.c \ @@ -824,9 +606,7 @@ generated/in_pack_c4.c \ generated/in_pack_c8.c \ generated/in_pack_c10.c \ generated/in_pack_c16.c \ -generated/in_pack_c17.c - -in_unpack_c = \ +generated/in_pack_c17.c \ generated/in_unpack_i1.c \ generated/in_unpack_i2.c \ generated/in_unpack_i4.c \ @@ -841,9 +621,7 @@ generated/in_unpack_c4.c \ generated/in_unpack_c8.c \ generated/in_unpack_c10.c \ generated/in_unpack_c16.c \ -generated/in_unpack_c17.c - -i_pow_c = \ +generated/in_unpack_c17.c \ generated/pow_i4_i4.c \ generated/pow_i8_i4.c \ generated/pow_i16_i4.c \ @@ -879,36 +657,7 @@ generated/pow_c4_i16.c \ generated/pow_c8_i16.c \ generated/pow_c10_i16.c \ generated/pow_c16_i16.c \ -generated/pow_c17_i16.c - -i_powu_c = \ -generated/pow_m1_m1.c \ -generated/pow_m1_m2.c \ -generated/pow_m1_m4.c \ -generated/pow_m1_m8.c \ -generated/pow_m1_m16.c \ -generated/pow_m2_m1.c \ -generated/pow_m2_m2.c \ -generated/pow_m2_m4.c \ -generated/pow_m2_m8.c \ -generated/pow_m2_m16.c \ -generated/pow_m4_m1.c \ -generated/pow_m4_m2.c \ -generated/pow_m4_m4.c \ -generated/pow_m4_m8.c \ -generated/pow_m4_m16.c \ -generated/pow_m8_m1.c \ -generated/pow_m8_m2.c \ -generated/pow_m8_m4.c \ -generated/pow_m8_m8.c \ -generated/pow_m8_m16.c \ -generated/pow_m16_m1.c \ -generated/pow_m16_m2.c \ -generated/pow_m16_m4.c \ -generated/pow_m16_m8.c \ -generated/pow_m16_m16.c - -i_pack_c = \ +generated/pow_c17_i16.c \ generated/pack_i1.c \ generated/pack_i2.c \ generated/pack_i4.c \ @@ -923,9 +672,7 @@ generated/pack_c4.c \ generated/pack_c8.c \ generated/pack_c10.c \ generated/pack_c16.c \ -generated/pack_c17.c - -i_unpack_c = \ +generated/pack_c17.c \ generated/unpack_i1.c \ generated/unpack_i2.c \ generated/unpack_i4.c \ @@ -940,9 +687,7 @@ generated/unpack_c4.c \ generated/unpack_c8.c \ generated/unpack_c10.c \ generated/unpack_c16.c \ -generated/unpack_c17.c - -i_spread_c = \ +generated/unpack_c17.c \ generated/spread_i1.c \ generated/spread_i2.c \ generated/spread_i4.c \ @@ -957,43 +702,179 @@ generated/spread_c4.c \ generated/spread_c8.c \ generated/spread_c10.c \ generated/spread_c16.c \ -generated/spread_c17.c - -i_isobinding_c = \ -runtime/ISO_Fortran_binding.c - -m4_files= m4/iparm.m4 m4/ifunction.m4 m4/iforeach.m4 m4/all.m4 \ - m4/any.m4 m4/count.m4 m4/maxloc0.m4 m4/maxloc1.m4 m4/maxval.m4 \ - m4/minloc0.m4 m4/minloc1.m4 m4/minval.m4 m4/product.m4 m4/sum.m4 \ - m4/matmul.m4 m4/matmull.m4 m4/ifunction_logical.m4 \ - m4/ctrig.m4 m4/cexp.m4 m4/chyp.m4 m4/mtype.m4 \ - m4/specific.m4 m4/specific2.m4 m4/head.m4 m4/shape.m4 m4/reshape.m4 \ - m4/eoshift1.m4 m4/eoshift3.m4 \ - m4/pow.m4 \ - m4/misc_specifics.m4 m4/pack.m4 \ - m4/unpack.m4 m4/spread.m4 m4/bessel.m4 m4/norm2.m4 m4/parity.m4 \ - m4/iall.m4 m4/iany.m4 m4/iparity.m4 m4/iforeach-s.m4 m4/findloc0.m4 \ - m4/findloc0s.m4 m4/ifindloc0.m4 m4/findloc1.m4 m4/ifindloc1.m4 \ - m4/findloc2s.m4 m4/ifindloc2.m4 - -gfor_built_src= $(i_all_c) $(i_any_c) $(i_count_c) $(i_maxloc0_c) \ - $(i_maxloc1_c) $(i_maxval_c) $(i_minloc0_c) $(i_minloc1_c) $(i_minval_c) \ - $(i_product_c) $(i_sum_c) $(i_bessel_c) $(i_iall_c) $(i_iany_c) \ - $(i_iparity_c) $(i_norm2_c) $(i_parity_c) \ - $(i_matmul_c) $(i_matmull_c) $(i_shape_c) $(i_eoshift1_c) \ - $(i_eoshift3_c) $(i_cshift1_c) $(i_reshape_c) $(in_pack_c) $(in_unpack_c) \ - $(i_pow_c) $(i_pack_c) $(i_unpack_c) $(i_matmulavx128_c) \ - $(i_spread_c) selected_int_kind.inc selected_real_kind.inc kinds.h \ - $(i_cshift0_c) kinds.inc c99_protos.inc fpu-target.h fpu-target.inc \ - include/ISO_Fortran_binding.h \ - $(i_cshift1a_c) $(i_maxloc0s_c) $(i_minloc0s_c) $(i_maxloc1s_c) \ - $(i_minloc1s_c) $(i_maxloc2s_c) $(i_minloc2s_c) $(i_maxvals_c) \ - $(i_maxval0s_c) $(i_minval0s_c) $(i_maxval1s_c) $(i_minval1s_c) \ - $(i_findloc0_c) $(i_findloc0s_c) $(i_findloc1_c) $(i_findloc1s_c) \ - $(i_findloc2s_c) $(i_isobinding_c) $(i_powu_c) - -# Machine generated specifics -gfor_built_specific_src= \ +generated/spread_c17.c \ +generated/cshift0_i1.c \ +generated/cshift0_i2.c \ +generated/cshift0_i4.c \ +generated/cshift0_i8.c \ +generated/cshift0_i16.c \ +generated/cshift0_r4.c \ +generated/cshift0_r8.c \ +generated/cshift0_r10.c \ +generated/cshift0_r16.c \ +generated/cshift0_r17.c \ +generated/cshift0_c4.c \ +generated/cshift0_c8.c \ +generated/cshift0_c10.c \ +generated/cshift0_c16.c \ +generated/cshift0_c17.c \ +generated/cshift1_4_i1.c \ +generated/cshift1_4_i2.c \ +generated/cshift1_4_i4.c \ +generated/cshift1_4_i8.c \ +generated/cshift1_4_i16.c \ +generated/cshift1_4_r4.c \ +generated/cshift1_4_r8.c \ +generated/cshift1_4_r10.c \ +generated/cshift1_4_r16.c \ +generated/cshift1_4_r17.c \ +generated/cshift1_4_c4.c \ +generated/cshift1_4_c8.c \ +generated/cshift1_4_c10.c \ +generated/cshift1_4_c16.c \ +generated/cshift1_4_c17.c \ +generated/cshift1_8_i1.c \ +generated/cshift1_8_i2.c \ +generated/cshift1_8_i4.c \ +generated/cshift1_8_i8.c \ +generated/cshift1_8_i16.c \ +generated/cshift1_8_r4.c \ +generated/cshift1_8_r8.c \ +generated/cshift1_8_r10.c \ +generated/cshift1_8_r16.c \ +generated/cshift1_8_r17.c \ +generated/cshift1_8_c4.c \ +generated/cshift1_8_c8.c \ +generated/cshift1_8_c10.c \ +generated/cshift1_8_c16.c \ +generated/cshift1_8_c17.c \ +generated/cshift1_16_i1.c \ +generated/cshift1_16_i2.c \ +generated/cshift1_16_i4.c \ +generated/cshift1_16_i8.c \ +generated/cshift1_16_i16.c \ +generated/cshift1_16_r4.c \ +generated/cshift1_16_r8.c \ +generated/cshift1_16_r10.c \ +generated/cshift1_16_r16.c \ +generated/cshift1_16_r17.c \ +generated/cshift1_16_c4.c \ +generated/cshift1_16_c8.c \ +generated/cshift1_16_c10.c \ +generated/cshift1_16_c16.c \ +generated/cshift1_16_c17.c \ +generated/findloc0_i1.c \ +generated/findloc0_i2.c \ +generated/findloc0_i4.c \ +generated/findloc0_i8.c \ +generated/findloc0_i16.c \ +generated/findloc0_r4.c \ +generated/findloc0_r8.c \ +generated/findloc0_r10.c \ +generated/findloc0_r16.c \ +generated/findloc0_r17.c \ +generated/findloc0_c4.c \ +generated/findloc0_c8.c \ +generated/findloc0_c10.c \ +generated/findloc0_c16.c \ +generated/findloc0_c17.c \ +generated/findloc0_s1.c \ +generated/findloc0_s4.c \ +generated/findloc1_i1.c \ +generated/findloc1_i2.c \ +generated/findloc1_i4.c \ +generated/findloc1_i8.c \ +generated/findloc1_i16.c \ +generated/findloc1_r4.c \ +generated/findloc1_r8.c \ +generated/findloc1_r10.c \ +generated/findloc1_r16.c \ +generated/findloc1_r17.c \ +generated/findloc1_c4.c \ +generated/findloc1_c8.c \ +generated/findloc1_c10.c \ +generated/findloc1_c16.c \ +generated/findloc1_c17.c \ +generated/findloc1_s1.c \ +generated/findloc1_s4.c \ +generated/findloc2_s1.c \ +generated/findloc2_s4.c \ +generated/maxloc0_4_s1.c \ +generated/maxloc0_4_s4.c \ +generated/maxloc0_8_s1.c \ +generated/maxloc0_8_s4.c \ +generated/maxloc0_16_s1.c \ +generated/maxloc0_16_s4.c \ +generated/maxloc1_4_s1.c \ +generated/maxloc1_4_s4.c \ +generated/maxloc1_8_s1.c \ +generated/maxloc1_8_s4.c \ +generated/maxloc1_16_s1.c \ +generated/maxloc1_16_s4.c \ +generated/maxloc2_4_s1.c \ +generated/maxloc2_4_s4.c \ +generated/maxloc2_8_s1.c \ +generated/maxloc2_8_s4.c \ +generated/maxloc2_16_s1.c \ +generated/maxloc2_16_s4.c \ +generated/maxval0_s1.c \ +generated/maxval0_s4.c \ +generated/maxval1_s1.c \ +generated/maxval1_s4.c \ +generated/minloc0_4_s1.c \ +generated/minloc0_4_s4.c \ +generated/minloc0_8_s1.c \ +generated/minloc0_8_s4.c \ +generated/minloc0_16_s1.c \ +generated/minloc0_16_s4.c \ +generated/minloc1_4_s1.c \ +generated/minloc1_4_s4.c \ +generated/minloc1_8_s1.c \ +generated/minloc1_8_s4.c \ +generated/minloc1_16_s1.c \ +generated/minloc1_16_s4.c \ +generated/minloc2_4_s1.c \ +generated/minloc2_4_s4.c \ +generated/minloc2_8_s1.c \ +generated/minloc2_8_s4.c \ +generated/minloc2_16_s1.c \ +generated/minloc2_16_s4.c \ +generated/minval0_s1.c \ +generated/minval0_s4.c \ +generated/minval1_s1.c \ +generated/minval1_s4.c \ +generated/pow_m1_m1.c \ +generated/pow_m1_m2.c \ +generated/pow_m1_m4.c \ +generated/pow_m1_m8.c \ +generated/pow_m1_m16.c \ +generated/pow_m2_m1.c \ +generated/pow_m2_m2.c \ +generated/pow_m2_m4.c \ +generated/pow_m2_m8.c \ +generated/pow_m2_m16.c \ +generated/pow_m4_m1.c \ +generated/pow_m4_m2.c \ +generated/pow_m4_m4.c \ +generated/pow_m4_m8.c \ +generated/pow_m4_m16.c \ +generated/pow_m8_m1.c \ +generated/pow_m8_m2.c \ +generated/pow_m8_m4.c \ +generated/pow_m8_m8.c \ +generated/pow_m8_m16.c \ +generated/pow_m16_m1.c \ +generated/pow_m16_m2.c \ +generated/pow_m16_m4.c \ +generated/pow_m16_m8.c \ +generated/pow_m16_m16.c \ +$(i_matmul_c) $(i_matmull_c) $(i_matmulavx128_c) \ +selected_int_kind.inc selected_real_kind.inc kinds.h \ +kinds.inc c99_protos.inc fpu-target.h fpu-target.inc \ +include/ISO_Fortran_binding.h runtime/ISO_Fortran_binding.c + +# Specifics +gfor_specific_src= \ generated/_abs_c4.F90 \ generated/_abs_c8.F90 \ generated/_abs_c10.F90 \ @@ -1131,9 +1012,7 @@ generated/_anint_r4.F90 \ generated/_anint_r8.F90 \ generated/_anint_r10.F90 \ generated/_anint_r16.F90 \ -generated/_anint_r17.F90 - -gfor_built_specific2_src= \ +generated/_anint_r17.F90 \ generated/_sign_i4.F90 \ generated/_sign_i8.F90 \ generated/_sign_i16.F90 \ @@ -1162,14 +1041,8 @@ generated/_mod_r4.F90 \ generated/_mod_r8.F90 \ generated/_mod_r10.F90 \ generated/_mod_r16.F90 \ -generated/_mod_r17.F90 - -gfor_misc_specifics = generated/misc_specifics.F90 - -gfor_specific_src= \ -$(gfor_built_specific_src) \ -$(gfor_built_specific2_src) \ -$(gfor_misc_specifics) \ +generated/_mod_r17.F90 \ +generated/misc_specifics.F90 \ intrinsics/dprod_r8.f90 \ intrinsics/f2c_specifics.F90 \ intrinsics/random_init.f90 @@ -1221,24 +1094,11 @@ ieee_exceptions.mod: ieee/ieee_exceptions.lo ieee_arithmetic.mod: ieee/ieee_arithmetic.lo : -BUILT_SOURCES=$(gfor_built_src) $(gfor_built_specific_src) \ - $(gfor_built_specific2_src) $(gfor_misc_specifics) +BUILT_SOURCES=$(gfor_built_src) libgfortran_la_SOURCES = $(gfor_src) $(gfor_built_src) $(gfor_io_src) \ $(gfor_helper_src) $(gfor_ieee_src) $(gfor_io_headers) $(gfor_specific_src) -I_M4_DEPS=m4/iparm.m4 m4/mtype.m4 -I_M4_DEPS0=$(I_M4_DEPS) m4/iforeach.m4 -I_M4_DEPS1=$(I_M4_DEPS) m4/ifunction.m4 -I_M4_DEPS2=$(I_M4_DEPS) m4/ifunction_logical.m4 -I_M4_DEPS3=$(I_M4_DEPS) m4/iforeach-s.m4 -I_M4_DEPS4=$(I_M4_DEPS) m4/ifunction-s.m4 -I_M4_DEPS5=$(I_M4_DEPS) m4/iforeach-s2.m4 -I_M4_DEPS6=$(I_M4_DEPS) m4/ifunction-s2.m4 -I_M4_DEPS7=$(I_M4_DEPS) m4/ifindloc0.m4 -I_M4_DEPS8=$(I_M4_DEPS) m4/ifindloc1.m4 -I_M4_DEPS9=$(I_M4_DEPS) m4/ifindloc2.m4 - kinds.h: $(srcdir)/mk-kinds-h.sh $(SHELL) $(srcdir)/mk-kinds-h.sh '@LIBGOMP_CHECKED_INT_KINDS@' \ '@LIBGOMP_CHECKED_REAL_KINDS@' \ @@ -1271,172 +1131,10 @@ include/ISO_Fortran_binding.h: $(srcdir)/ISO_Fortran_binding.h $(MKDIR_P) include cp $(srcdir)/ISO_Fortran_binding.h $@ -## A 'normal' build shouldn't need to regenerate these -## so we only include them in maintainer mode - -if MAINTAINER_MODE -$(i_all_c): m4/all.m4 $(I_M4_DEPS2) - $(M4) -Dfile=$@ -I$(srcdir)/m4 all.m4 > $@ - -$(i_bessel_c): m4/bessel.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 bessel.m4 > $@ - -$(i_any_c): m4/any.m4 $(I_M4_DEPS2) - $(M4) -Dfile=$@ -I$(srcdir)/m4 any.m4 > $@ - -$(i_count_c): m4/count.m4 $(I_M4_DEPS2) - $(M4) -Dfile=$@ -I$(srcdir)/m4 count.m4 > $@ - -$(i_findloc0_c): m4/findloc0.m4 $(I_M4_DEPS7) - $(M4) -Dfile=$@ -I$(srcdir)/m4 findloc0.m4 > $@ - -$(i_findloc0s_c): m4/findloc0s.m4 $(I_M4_DEPS7) - $(M4) -Dfile=$@ -I$(srcdir)/m4 findloc0s.m4 > $@ - -$(i_findloc1_c): m4/findloc1.m4 $(I_M4_DEPS8) - $(M4) -Dfile=$@ -I$(srcdir)/m4 findloc1.m4 > $@ - -$(i_findloc1s_c): m4/findloc1s.m4 $(I_M4_DEPS8) - $(M4) -Dfile=$@ -I$(srcdir)/m4 findloc1s.m4 > $@ - -$(i_findloc2s_c): m4/findloc2s.m4 $(I_M4_DEPS9) - $(M4) -Dfile=$@ -I$(srcdir)/m4 findloc2s.m4 > $@ - -$(i_iall_c): m4/iall.m4 $(I_M4_DEPS1) - $(M4) -Dfile=$@ -I$(srcdir)/m4 iall.m4 > $@ - -$(i_iany_c): m4/iany.m4 $(I_M4_DEPS1) - $(M4) -Dfile=$@ -I$(srcdir)/m4 iany.m4 > $@ - -$(i_iparity_c): m4/iparity.m4 $(I_M4_DEPS1) - $(M4) -Dfile=$@ -I$(srcdir)/m4 iparity.m4 > $@ - -$(i_maxloc0_c): m4/maxloc0.m4 $(I_M4_DEPS0) - $(M4) -Dfile=$@ -I$(srcdir)/m4 maxloc0.m4 > $@ - -$(i_maxloc0s_c) : m4/maxloc0s.m4 $(I_M4_DEPS3) - $(M4) -Dfile=$@ -I$(srcdir)/m4 maxloc0s.m4 > $@ - -$(i_maxloc1_c): m4/maxloc1.m4 $(I_M4_DEPS1) - $(M4) -Dfile=$@ -I$(srcdir)/m4 maxloc1.m4 > $@ - -$(i_maxloc1s_c): m4/maxloc1s.m4 $(I_M4_DEPS4) - $(M4) -Dfile=$@ -I$(srcdir)/m4 maxloc1s.m4 > $@ - -$(i_maxloc2s_c): m4/maxloc2s.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 maxloc2s.m4 > $@ - -$(i_maxval_c): m4/maxval.m4 $(I_M4_DEPS1) - $(M4) -Dfile=$@ -I$(srcdir)/m4 maxval.m4 > $@ - -$(i_maxval0s_c): m4/maxval0s.m4 $(I_M4_DEPS5) - $(M4) -Dfile=$@ -I$(srcdir)/m4 maxval0s.m4 > $@ - -$(i_maxval1s_c): m4/maxval1s.m4 $(I_M4_DEPS6) - $(M4) -Dfile=$@ -I$(srcdir)/m4 maxval1s.m4 > $@ - -$(i_minloc0_c): m4/minloc0.m4 $(I_M4_DEPS0) - $(M4) -Dfile=$@ -I$(srcdir)/m4 minloc0.m4 > $@ - -$(i_minloc0s_c) : m4/minloc0s.m4 $(I_M4_DEPS3) - $(M4) -Dfile=$@ -I$(srcdir)/m4 minloc0s.m4 > $@ - -$(i_minloc1_c): m4/minloc1.m4 $(I_M4_DEPS1) - $(M4) -Dfile=$@ -I$(srcdir)/m4 minloc1.m4 > $@ - -$(i_minloc1s_c): m4/minloc1s.m4 $(I_M4_DEPS4) - $(M4) -Dfile=$@ -I$(srcdir)/m4 minloc1s.m4 > $@ - -$(i_minloc2s_c): m4/minloc2s.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 minloc2s.m4 > $@ - -$(i_minval_c): m4/minval.m4 $(I_M4_DEPS1) - $(M4) -Dfile=$@ -I$(srcdir)/m4 minval.m4 > $@ - -$(i_minval0s_c): m4/minval0s.m4 $(I_M4_DEPS5) - $(M4) -Dfile=$@ -I$(srcdir)/m4 minval0s.m4 > $@ - -$(i_minval1s_c): m4/minval1s.m4 $(I_M4_DEPS6) - $(M4) -Dfile=$@ -I$(srcdir)/m4 minval1s.m4 > $@ - -$(i_product_c): m4/product.m4 $(I_M4_DEPS1) - $(M4) -Dfile=$@ -I$(srcdir)/m4 product.m4 > $@ - -$(i_sum_c): m4/sum.m4 $(I_M4_DEPS1) - $(M4) -Dfile=$@ -I$(srcdir)/m4 sum.m4 > $@ - -$(i_matmul_c): m4/matmul.m4 m4/matmul_internal.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 matmul.m4 > $@ - -$(i_matmulavx128_c): m4/matmulavx128.m4 m4/matmul_internal.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 matmulavx128.m4 > $@ - -$(i_matmull_c): m4/matmull.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 matmull.m4 > $@ - -$(i_norm2_c): m4/norm2.m4 $(I_M4_DEPS1) - $(M4) -Dfile=$@ -I$(srcdir)/m4 norm2.m4 > $@ - -$(i_parity_c): m4/parity.m4 $(I_M4_DEPS1) - $(M4) -Dfile=$@ -I$(srcdir)/m4 parity.m4 > $@ - -$(i_shape_c): m4/shape.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 shape.m4 > $@ - -$(i_reshape_c): m4/reshape.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 reshape.m4 > $@ - -$(i_eoshift1_c): m4/eoshift1.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 eoshift1.m4 > $@ - -$(i_eoshift3_c): m4/eoshift3.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 eoshift3.m4 > $@ - -$(i_cshift0_c): m4/cshift0.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 cshift0.m4 > $@ - -$(i_cshift1_c): m4/cshift1.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 cshift1.m4 > $@ - -$(i_cshift1a_c): m4/cshift1a.m4 $(I_M$_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 cshift1a.m4 > $@ - -$(in_pack_c): m4/in_pack.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 in_pack.m4 > $@ - -$(in_unpack_c): m4/in_unpack.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 in_unpack.m4 > $@ - -$(i_pow_c): m4/pow.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 pow.m4 > $@ - -$(i_powu_c): m4/powu.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 powu.m4 > $@ - -$(i_pack_c): m4/pack.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 pack.m4 > $@ - -$(i_unpack_c): m4/unpack.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 unpack.m4 > $@ - -$(i_spread_c): m4/spread.m4 $(I_M4_DEPS) - $(M4) -Dfile=$@ -I$(srcdir)/m4 spread.m4 > $@ - -$(gfor_built_specific_src): m4/specific.m4 m4/head.m4 - $(M4) -Dfile=$@ -I$(srcdir)/m4 specific.m4 > $@ - -$(gfor_built_specific2_src): m4/specific2.m4 m4/head.m4 - $(M4) -Dfile=$@ -I$(srcdir)/m4 specific2.m4 > $@ - -$(gfor_misc_specifics): m4/misc_specifics.m4 m4/head.m4 - $(M4) -Dfile=$@ -I$(srcdir)/m4 misc_specifics.m4 > $@ -## end of maintainer mode only rules -endif - clean-local: -rm -rf include $(version_dep) -EXTRA_DIST = $(m4_files) +EXTRA_DIST = m4 # target overrides -include $(tmake_file) diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in index c171b3d62192..dd88f8893b7f 100644 --- a/libgfortran/Makefile.in +++ b/libgfortran/Makefile.in @@ -231,37 +231,54 @@ libgfortran_la_LIBADD = am__objects_3 = runtime/bounds.lo runtime/compile_options.lo \ runtime/memory.lo runtime/string.lo runtime/select.lo \ $(am__objects_1) $(am__objects_2) -am__objects_4 = generated/all_l1.lo generated/all_l2.lo \ - generated/all_l4.lo generated/all_l8.lo generated/all_l16.lo -am__objects_5 = generated/any_l1.lo generated/any_l2.lo \ - generated/any_l4.lo generated/any_l8.lo generated/any_l16.lo -am__objects_6 = generated/count_1_l.lo generated/count_2_l.lo \ +am__objects_4 = generated/matmul_i1.lo generated/matmul_i2.lo \ + generated/matmul_i4.lo generated/matmul_i8.lo \ + generated/matmul_i16.lo generated/matmul_r4.lo \ + generated/matmul_r8.lo generated/matmul_r10.lo \ + generated/matmul_r16.lo generated/matmul_r17.lo \ + generated/matmul_c4.lo generated/matmul_c8.lo \ + generated/matmul_c10.lo generated/matmul_c16.lo \ + generated/matmul_c17.lo +am__objects_5 = generated/matmul_l4.lo generated/matmul_l8.lo \ + generated/matmul_l16.lo +am__objects_6 = generated/matmulavx128_i1.lo \ + generated/matmulavx128_i2.lo generated/matmulavx128_i4.lo \ + generated/matmulavx128_i8.lo generated/matmulavx128_i16.lo \ + generated/matmulavx128_r4.lo generated/matmulavx128_r8.lo \ + generated/matmulavx128_r10.lo generated/matmulavx128_r16.lo \ + generated/matmulavx128_r17.lo generated/matmulavx128_c4.lo \ + generated/matmulavx128_c8.lo generated/matmulavx128_c10.lo \ + generated/matmulavx128_c16.lo generated/matmulavx128_c17.lo +am__objects_7 = generated/all_l1.lo generated/all_l2.lo \ + generated/all_l4.lo generated/all_l8.lo generated/all_l16.lo \ + generated/any_l1.lo generated/any_l2.lo generated/any_l4.lo \ + generated/any_l8.lo generated/any_l16.lo \ + generated/count_1_l.lo generated/count_2_l.lo \ generated/count_4_l.lo generated/count_8_l.lo \ - generated/count_16_l.lo -am__objects_7 = generated/maxloc0_4_i1.lo generated/maxloc0_8_i1.lo \ - generated/maxloc0_16_i1.lo generated/maxloc0_4_i2.lo \ - generated/maxloc0_8_i2.lo generated/maxloc0_16_i2.lo \ - generated/maxloc0_4_i4.lo generated/maxloc0_8_i4.lo \ - generated/maxloc0_16_i4.lo generated/maxloc0_4_i8.lo \ - generated/maxloc0_8_i8.lo generated/maxloc0_16_i8.lo \ - generated/maxloc0_4_i16.lo generated/maxloc0_8_i16.lo \ - generated/maxloc0_16_i16.lo generated/maxloc0_4_m1.lo \ - generated/maxloc0_8_m1.lo generated/maxloc0_16_m1.lo \ - generated/maxloc0_4_m2.lo generated/maxloc0_8_m2.lo \ - generated/maxloc0_16_m2.lo generated/maxloc0_4_m4.lo \ - generated/maxloc0_8_m4.lo generated/maxloc0_16_m4.lo \ - generated/maxloc0_4_m8.lo generated/maxloc0_8_m8.lo \ - generated/maxloc0_16_m8.lo generated/maxloc0_4_m16.lo \ - generated/maxloc0_8_m16.lo generated/maxloc0_16_m16.lo \ - generated/maxloc0_4_r4.lo generated/maxloc0_8_r4.lo \ - generated/maxloc0_16_r4.lo generated/maxloc0_4_r8.lo \ - generated/maxloc0_8_r8.lo generated/maxloc0_16_r8.lo \ - generated/maxloc0_4_r10.lo generated/maxloc0_8_r10.lo \ - generated/maxloc0_16_r10.lo generated/maxloc0_4_r16.lo \ - generated/maxloc0_8_r16.lo generated/maxloc0_16_r16.lo \ - generated/maxloc0_4_r17.lo generated/maxloc0_8_r17.lo \ - generated/maxloc0_16_r17.lo -am__objects_8 = generated/maxloc1_4_i1.lo generated/maxloc1_8_i1.lo \ + generated/count_16_l.lo generated/maxloc0_4_i1.lo \ + generated/maxloc0_8_i1.lo generated/maxloc0_16_i1.lo \ + generated/maxloc0_4_i2.lo generated/maxloc0_8_i2.lo \ + generated/maxloc0_16_i2.lo generated/maxloc0_4_i4.lo \ + generated/maxloc0_8_i4.lo generated/maxloc0_16_i4.lo \ + generated/maxloc0_4_i8.lo generated/maxloc0_8_i8.lo \ + generated/maxloc0_16_i8.lo generated/maxloc0_4_i16.lo \ + generated/maxloc0_8_i16.lo generated/maxloc0_16_i16.lo \ + generated/maxloc0_4_m1.lo generated/maxloc0_8_m1.lo \ + generated/maxloc0_16_m1.lo generated/maxloc0_4_m2.lo \ + generated/maxloc0_8_m2.lo generated/maxloc0_16_m2.lo \ + generated/maxloc0_4_m4.lo generated/maxloc0_8_m4.lo \ + generated/maxloc0_16_m4.lo generated/maxloc0_4_m8.lo \ + generated/maxloc0_8_m8.lo generated/maxloc0_16_m8.lo \ + generated/maxloc0_4_m16.lo generated/maxloc0_8_m16.lo \ + generated/maxloc0_16_m16.lo generated/maxloc0_4_r4.lo \ + generated/maxloc0_8_r4.lo generated/maxloc0_16_r4.lo \ + generated/maxloc0_4_r8.lo generated/maxloc0_8_r8.lo \ + generated/maxloc0_16_r8.lo generated/maxloc0_4_r10.lo \ + generated/maxloc0_8_r10.lo generated/maxloc0_16_r10.lo \ + generated/maxloc0_4_r16.lo generated/maxloc0_8_r16.lo \ + generated/maxloc0_16_r16.lo generated/maxloc0_4_r17.lo \ + generated/maxloc0_8_r17.lo generated/maxloc0_16_r17.lo \ + generated/maxloc1_4_i1.lo generated/maxloc1_8_i1.lo \ generated/maxloc1_16_i1.lo generated/maxloc1_4_i2.lo \ generated/maxloc1_8_i2.lo generated/maxloc1_16_i2.lo \ generated/maxloc1_4_i4.lo generated/maxloc1_8_i4.lo \ @@ -283,16 +300,15 @@ am__objects_8 = generated/maxloc1_4_i1.lo generated/maxloc1_8_i1.lo \ generated/maxloc1_16_r10.lo generated/maxloc1_4_r16.lo \ generated/maxloc1_8_r16.lo generated/maxloc1_16_r16.lo \ generated/maxloc1_4_r17.lo generated/maxloc1_8_r17.lo \ - generated/maxloc1_16_r17.lo -am__objects_9 = generated/maxval_i1.lo generated/maxval_i2.lo \ - generated/maxval_i4.lo generated/maxval_i8.lo \ - generated/maxval_i16.lo generated/maxval_m1.lo \ - generated/maxval_m2.lo generated/maxval_m4.lo \ - generated/maxval_m8.lo generated/maxval_m16.lo \ - generated/maxval_r4.lo generated/maxval_r8.lo \ - generated/maxval_r10.lo generated/maxval_r16.lo \ - generated/maxval_r17.lo -am__objects_10 = generated/minloc0_4_i1.lo generated/minloc0_8_i1.lo \ + generated/maxloc1_16_r17.lo generated/maxval_i1.lo \ + generated/maxval_i2.lo generated/maxval_i4.lo \ + generated/maxval_i8.lo generated/maxval_i16.lo \ + generated/maxval_m1.lo generated/maxval_m2.lo \ + generated/maxval_m4.lo generated/maxval_m8.lo \ + generated/maxval_m16.lo generated/maxval_r4.lo \ + generated/maxval_r8.lo generated/maxval_r10.lo \ + generated/maxval_r16.lo generated/maxval_r17.lo \ + generated/minloc0_4_i1.lo generated/minloc0_8_i1.lo \ generated/minloc0_16_i1.lo generated/minloc0_4_i2.lo \ generated/minloc0_8_i2.lo generated/minloc0_16_i2.lo \ generated/minloc0_4_i4.lo generated/minloc0_8_i4.lo \ @@ -314,171 +330,140 @@ am__objects_10 = generated/minloc0_4_i1.lo generated/minloc0_8_i1.lo \ generated/minloc0_16_r10.lo generated/minloc0_4_r16.lo \ generated/minloc0_8_r16.lo generated/minloc0_16_r16.lo \ generated/minloc0_4_r17.lo generated/minloc0_8_r17.lo \ - generated/minloc0_16_r17.lo -am__objects_11 = generated/minloc1_4_i1.lo generated/minloc1_8_i1.lo \ - generated/minloc1_16_i1.lo generated/minloc1_4_i2.lo \ - generated/minloc1_8_i2.lo generated/minloc1_16_i2.lo \ - generated/minloc1_4_i4.lo generated/minloc1_8_i4.lo \ - generated/minloc1_16_i4.lo generated/minloc1_4_i8.lo \ - generated/minloc1_8_i8.lo generated/minloc1_16_i8.lo \ - generated/minloc1_4_i16.lo generated/minloc1_8_i16.lo \ - generated/minloc1_16_i16.lo generated/minloc1_4_m1.lo \ - generated/minloc1_8_m1.lo generated/minloc1_16_m1.lo \ - generated/minloc1_4_m2.lo generated/minloc1_8_m2.lo \ - generated/minloc1_16_m2.lo generated/minloc1_4_m4.lo \ - generated/minloc1_8_m4.lo generated/minloc1_16_m4.lo \ - generated/minloc1_4_m8.lo generated/minloc1_8_m8.lo \ - generated/minloc1_16_m8.lo generated/minloc1_4_m16.lo \ - generated/minloc1_8_m16.lo generated/minloc1_16_m16.lo \ - generated/minloc1_4_r4.lo generated/minloc1_8_r4.lo \ - generated/minloc1_16_r4.lo generated/minloc1_4_r8.lo \ - generated/minloc1_8_r8.lo generated/minloc1_16_r8.lo \ - generated/minloc1_4_r10.lo generated/minloc1_8_r10.lo \ - generated/minloc1_16_r10.lo generated/minloc1_4_r16.lo \ - generated/minloc1_8_r16.lo generated/minloc1_16_r16.lo \ - generated/minloc1_4_r17.lo generated/minloc1_8_r17.lo \ - generated/minloc1_16_r17.lo -am__objects_12 = generated/minval_i1.lo generated/minval_i2.lo \ + generated/minloc0_16_r17.lo generated/minloc1_4_i1.lo \ + generated/minloc1_8_i1.lo generated/minloc1_16_i1.lo \ + generated/minloc1_4_i2.lo generated/minloc1_8_i2.lo \ + generated/minloc1_16_i2.lo generated/minloc1_4_i4.lo \ + generated/minloc1_8_i4.lo generated/minloc1_16_i4.lo \ + generated/minloc1_4_i8.lo generated/minloc1_8_i8.lo \ + generated/minloc1_16_i8.lo generated/minloc1_4_i16.lo \ + generated/minloc1_8_i16.lo generated/minloc1_16_i16.lo \ + generated/minloc1_4_m1.lo generated/minloc1_8_m1.lo \ + generated/minloc1_16_m1.lo generated/minloc1_4_m2.lo \ + generated/minloc1_8_m2.lo generated/minloc1_16_m2.lo \ + generated/minloc1_4_m4.lo generated/minloc1_8_m4.lo \ + generated/minloc1_16_m4.lo generated/minloc1_4_m8.lo \ + generated/minloc1_8_m8.lo generated/minloc1_16_m8.lo \ + generated/minloc1_4_m16.lo generated/minloc1_8_m16.lo \ + generated/minloc1_16_m16.lo generated/minloc1_4_r4.lo \ + generated/minloc1_8_r4.lo generated/minloc1_16_r4.lo \ + generated/minloc1_4_r8.lo generated/minloc1_8_r8.lo \ + generated/minloc1_16_r8.lo generated/minloc1_4_r10.lo \ + generated/minloc1_8_r10.lo generated/minloc1_16_r10.lo \ + generated/minloc1_4_r16.lo generated/minloc1_8_r16.lo \ + generated/minloc1_16_r16.lo generated/minloc1_4_r17.lo \ + generated/minloc1_8_r17.lo generated/minloc1_16_r17.lo \ + generated/minval_i1.lo generated/minval_i2.lo \ generated/minval_i4.lo generated/minval_i8.lo \ generated/minval_i16.lo generated/minval_m1.lo \ generated/minval_m2.lo generated/minval_m4.lo \ generated/minval_m8.lo generated/minval_m16.lo \ generated/minval_r4.lo generated/minval_r8.lo \ generated/minval_r10.lo generated/minval_r16.lo \ - generated/minval_r17.lo -am__objects_13 = generated/product_i1.lo generated/product_i2.lo \ - generated/product_i4.lo generated/product_i8.lo \ - generated/product_i16.lo generated/product_r4.lo \ - generated/product_r8.lo generated/product_r10.lo \ - generated/product_r16.lo generated/product_r17.lo \ - generated/product_c4.lo generated/product_c8.lo \ - generated/product_c10.lo generated/product_c16.lo \ - generated/product_c17.lo -am__objects_14 = generated/sum_i1.lo generated/sum_i2.lo \ - generated/sum_i4.lo generated/sum_i8.lo generated/sum_i16.lo \ - generated/sum_r4.lo generated/sum_r8.lo generated/sum_r10.lo \ - generated/sum_r16.lo generated/sum_r17.lo generated/sum_c4.lo \ - generated/sum_c8.lo generated/sum_c10.lo generated/sum_c16.lo \ - generated/sum_c17.lo -am__objects_15 = generated/bessel_r4.lo generated/bessel_r8.lo \ + generated/minval_r17.lo generated/product_i1.lo \ + generated/product_i2.lo generated/product_i4.lo \ + generated/product_i8.lo generated/product_i16.lo \ + generated/product_r4.lo generated/product_r8.lo \ + generated/product_r10.lo generated/product_r16.lo \ + generated/product_r17.lo generated/product_c4.lo \ + generated/product_c8.lo generated/product_c10.lo \ + generated/product_c16.lo generated/product_c17.lo \ + generated/sum_i1.lo generated/sum_i2.lo generated/sum_i4.lo \ + generated/sum_i8.lo generated/sum_i16.lo generated/sum_r4.lo \ + generated/sum_r8.lo generated/sum_r10.lo generated/sum_r16.lo \ + generated/sum_r17.lo generated/sum_c4.lo generated/sum_c8.lo \ + generated/sum_c10.lo generated/sum_c16.lo generated/sum_c17.lo \ + generated/bessel_r4.lo generated/bessel_r8.lo \ generated/bessel_r10.lo generated/bessel_r16.lo \ - generated/bessel_r17.lo -am__objects_16 = generated/iall_i1.lo generated/iall_i2.lo \ - generated/iall_i4.lo generated/iall_i8.lo \ - generated/iall_i16.lo -am__objects_17 = generated/iany_i1.lo generated/iany_i2.lo \ - generated/iany_i4.lo generated/iany_i8.lo \ - generated/iany_i16.lo -am__objects_18 = generated/iparity_i1.lo generated/iparity_i2.lo \ - generated/iparity_i4.lo generated/iparity_i8.lo \ - generated/iparity_i16.lo -am__objects_19 = generated/norm2_r4.lo generated/norm2_r8.lo \ + generated/bessel_r17.lo generated/iall_i1.lo \ + generated/iall_i2.lo generated/iall_i4.lo generated/iall_i8.lo \ + generated/iall_i16.lo generated/iany_i1.lo \ + generated/iany_i2.lo generated/iany_i4.lo generated/iany_i8.lo \ + generated/iany_i16.lo generated/iparity_i1.lo \ + generated/iparity_i2.lo generated/iparity_i4.lo \ + generated/iparity_i8.lo generated/iparity_i16.lo \ + generated/norm2_r4.lo generated/norm2_r8.lo \ generated/norm2_r10.lo generated/norm2_r16.lo \ - generated/norm2_r17.lo -am__objects_20 = generated/parity_l1.lo generated/parity_l2.lo \ - generated/parity_l4.lo generated/parity_l8.lo \ - generated/parity_l16.lo -am__objects_21 = generated/matmul_i1.lo generated/matmul_i2.lo \ - generated/matmul_i4.lo generated/matmul_i8.lo \ - generated/matmul_i16.lo generated/matmul_r4.lo \ - generated/matmul_r8.lo generated/matmul_r10.lo \ - generated/matmul_r16.lo generated/matmul_r17.lo \ - generated/matmul_c4.lo generated/matmul_c8.lo \ - generated/matmul_c10.lo generated/matmul_c16.lo \ - generated/matmul_c17.lo -am__objects_22 = generated/matmul_l4.lo generated/matmul_l8.lo \ - generated/matmul_l16.lo -am__objects_23 = generated/shape_i1.lo generated/shape_i2.lo \ + generated/norm2_r17.lo generated/parity_l1.lo \ + generated/parity_l2.lo generated/parity_l4.lo \ + generated/parity_l8.lo generated/parity_l16.lo \ + generated/shape_i1.lo generated/shape_i2.lo \ generated/shape_i4.lo generated/shape_i8.lo \ - generated/shape_i16.lo -am__objects_24 = generated/eoshift1_4.lo generated/eoshift1_8.lo \ - generated/eoshift1_16.lo -am__objects_25 = generated/eoshift3_4.lo generated/eoshift3_8.lo \ - generated/eoshift3_16.lo -am__objects_26 = generated/cshift1_4.lo generated/cshift1_8.lo \ - generated/cshift1_16.lo -am__objects_27 = generated/reshape_i4.lo generated/reshape_i8.lo \ + generated/shape_i16.lo generated/eoshift1_4.lo \ + generated/eoshift1_8.lo generated/eoshift1_16.lo \ + generated/eoshift3_4.lo generated/eoshift3_8.lo \ + generated/eoshift3_16.lo generated/cshift1_4.lo \ + generated/cshift1_8.lo generated/cshift1_16.lo \ + generated/reshape_i4.lo generated/reshape_i8.lo \ generated/reshape_i16.lo generated/reshape_r4.lo \ generated/reshape_r8.lo generated/reshape_r10.lo \ generated/reshape_r16.lo generated/reshape_r17.lo \ generated/reshape_c4.lo generated/reshape_c8.lo \ generated/reshape_c10.lo generated/reshape_c16.lo \ - generated/reshape_c17.lo -am__objects_28 = generated/in_pack_i1.lo generated/in_pack_i2.lo \ - generated/in_pack_i4.lo generated/in_pack_i8.lo \ - generated/in_pack_i16.lo generated/in_pack_r4.lo \ - generated/in_pack_r8.lo generated/in_pack_r10.lo \ - generated/in_pack_r16.lo generated/in_pack_r17.lo \ - generated/in_pack_c4.lo generated/in_pack_c8.lo \ - generated/in_pack_c10.lo generated/in_pack_c16.lo \ - generated/in_pack_c17.lo -am__objects_29 = generated/in_unpack_i1.lo generated/in_unpack_i2.lo \ + generated/reshape_c17.lo generated/in_pack_i1.lo \ + generated/in_pack_i2.lo generated/in_pack_i4.lo \ + generated/in_pack_i8.lo generated/in_pack_i16.lo \ + generated/in_pack_r4.lo generated/in_pack_r8.lo \ + generated/in_pack_r10.lo generated/in_pack_r16.lo \ + generated/in_pack_r17.lo generated/in_pack_c4.lo \ + generated/in_pack_c8.lo generated/in_pack_c10.lo \ + generated/in_pack_c16.lo generated/in_pack_c17.lo \ + generated/in_unpack_i1.lo generated/in_unpack_i2.lo \ generated/in_unpack_i4.lo generated/in_unpack_i8.lo \ generated/in_unpack_i16.lo generated/in_unpack_r4.lo \ generated/in_unpack_r8.lo generated/in_unpack_r10.lo \ generated/in_unpack_r16.lo generated/in_unpack_r17.lo \ generated/in_unpack_c4.lo generated/in_unpack_c8.lo \ generated/in_unpack_c10.lo generated/in_unpack_c16.lo \ - generated/in_unpack_c17.lo -am__objects_30 = generated/pow_i4_i4.lo generated/pow_i8_i4.lo \ - generated/pow_i16_i4.lo generated/pow_r16_i4.lo \ - generated/pow_r17_i4.lo generated/pow_c4_i4.lo \ - generated/pow_c8_i4.lo generated/pow_c10_i4.lo \ - generated/pow_c16_i4.lo generated/pow_c17_i4.lo \ - generated/pow_i4_i8.lo generated/pow_i8_i8.lo \ - generated/pow_i16_i8.lo generated/pow_r4_i8.lo \ - generated/pow_r8_i8.lo generated/pow_r10_i8.lo \ - generated/pow_r16_i8.lo generated/pow_r17_i8.lo \ - generated/pow_c4_i8.lo generated/pow_c8_i8.lo \ - generated/pow_c10_i8.lo generated/pow_c16_i8.lo \ - generated/pow_c17_i8.lo generated/pow_i4_i16.lo \ - generated/pow_i8_i16.lo generated/pow_i16_i16.lo \ - generated/pow_r4_i16.lo generated/pow_r8_i16.lo \ - generated/pow_r10_i16.lo generated/pow_r16_i16.lo \ - generated/pow_r17_i16.lo generated/pow_c4_i16.lo \ - generated/pow_c8_i16.lo generated/pow_c10_i16.lo \ - generated/pow_c16_i16.lo generated/pow_c17_i16.lo -am__objects_31 = generated/pack_i1.lo generated/pack_i2.lo \ - generated/pack_i4.lo generated/pack_i8.lo \ + generated/in_unpack_c17.lo generated/pow_i4_i4.lo \ + generated/pow_i8_i4.lo generated/pow_i16_i4.lo \ + generated/pow_r16_i4.lo generated/pow_r17_i4.lo \ + generated/pow_c4_i4.lo generated/pow_c8_i4.lo \ + generated/pow_c10_i4.lo generated/pow_c16_i4.lo \ + generated/pow_c17_i4.lo generated/pow_i4_i8.lo \ + generated/pow_i8_i8.lo generated/pow_i16_i8.lo \ + generated/pow_r4_i8.lo generated/pow_r8_i8.lo \ + generated/pow_r10_i8.lo generated/pow_r16_i8.lo \ + generated/pow_r17_i8.lo generated/pow_c4_i8.lo \ + generated/pow_c8_i8.lo generated/pow_c10_i8.lo \ + generated/pow_c16_i8.lo generated/pow_c17_i8.lo \ + generated/pow_i4_i16.lo generated/pow_i8_i16.lo \ + generated/pow_i16_i16.lo generated/pow_r4_i16.lo \ + generated/pow_r8_i16.lo generated/pow_r10_i16.lo \ + generated/pow_r16_i16.lo generated/pow_r17_i16.lo \ + generated/pow_c4_i16.lo generated/pow_c8_i16.lo \ + generated/pow_c10_i16.lo generated/pow_c16_i16.lo \ + generated/pow_c17_i16.lo generated/pack_i1.lo \ + generated/pack_i2.lo generated/pack_i4.lo generated/pack_i8.lo \ generated/pack_i16.lo generated/pack_r4.lo \ generated/pack_r8.lo generated/pack_r10.lo \ generated/pack_r16.lo generated/pack_r17.lo \ generated/pack_c4.lo generated/pack_c8.lo \ generated/pack_c10.lo generated/pack_c16.lo \ - generated/pack_c17.lo -am__objects_32 = generated/unpack_i1.lo generated/unpack_i2.lo \ - generated/unpack_i4.lo generated/unpack_i8.lo \ - generated/unpack_i16.lo generated/unpack_r4.lo \ - generated/unpack_r8.lo generated/unpack_r10.lo \ - generated/unpack_r16.lo generated/unpack_r17.lo \ - generated/unpack_c4.lo generated/unpack_c8.lo \ - generated/unpack_c10.lo generated/unpack_c16.lo \ - generated/unpack_c17.lo -am__objects_33 = generated/matmulavx128_i1.lo \ - generated/matmulavx128_i2.lo generated/matmulavx128_i4.lo \ - generated/matmulavx128_i8.lo generated/matmulavx128_i16.lo \ - generated/matmulavx128_r4.lo generated/matmulavx128_r8.lo \ - generated/matmulavx128_r10.lo generated/matmulavx128_r16.lo \ - generated/matmulavx128_r17.lo generated/matmulavx128_c4.lo \ - generated/matmulavx128_c8.lo generated/matmulavx128_c10.lo \ - generated/matmulavx128_c16.lo generated/matmulavx128_c17.lo -am__objects_34 = generated/spread_i1.lo generated/spread_i2.lo \ + generated/pack_c17.lo generated/unpack_i1.lo \ + generated/unpack_i2.lo generated/unpack_i4.lo \ + generated/unpack_i8.lo generated/unpack_i16.lo \ + generated/unpack_r4.lo generated/unpack_r8.lo \ + generated/unpack_r10.lo generated/unpack_r16.lo \ + generated/unpack_r17.lo generated/unpack_c4.lo \ + generated/unpack_c8.lo generated/unpack_c10.lo \ + generated/unpack_c16.lo generated/unpack_c17.lo \ + generated/spread_i1.lo generated/spread_i2.lo \ generated/spread_i4.lo generated/spread_i8.lo \ generated/spread_i16.lo generated/spread_r4.lo \ generated/spread_r8.lo generated/spread_r10.lo \ generated/spread_r16.lo generated/spread_r17.lo \ generated/spread_c4.lo generated/spread_c8.lo \ generated/spread_c10.lo generated/spread_c16.lo \ - generated/spread_c17.lo -am__objects_35 = generated/cshift0_i1.lo generated/cshift0_i2.lo \ - generated/cshift0_i4.lo generated/cshift0_i8.lo \ - generated/cshift0_i16.lo generated/cshift0_r4.lo \ - generated/cshift0_r8.lo generated/cshift0_r10.lo \ - generated/cshift0_r16.lo generated/cshift0_r17.lo \ - generated/cshift0_c4.lo generated/cshift0_c8.lo \ - generated/cshift0_c10.lo generated/cshift0_c16.lo \ - generated/cshift0_c17.lo -am__objects_36 = generated/cshift1_4_i1.lo generated/cshift1_4_i2.lo \ + generated/spread_c17.lo generated/cshift0_i1.lo \ + generated/cshift0_i2.lo generated/cshift0_i4.lo \ + generated/cshift0_i8.lo generated/cshift0_i16.lo \ + generated/cshift0_r4.lo generated/cshift0_r8.lo \ + generated/cshift0_r10.lo generated/cshift0_r16.lo \ + generated/cshift0_r17.lo generated/cshift0_c4.lo \ + generated/cshift0_c8.lo generated/cshift0_c10.lo \ + generated/cshift0_c16.lo generated/cshift0_c17.lo \ + generated/cshift1_4_i1.lo generated/cshift1_4_i2.lo \ generated/cshift1_4_i4.lo generated/cshift1_4_i8.lo \ generated/cshift1_4_i16.lo generated/cshift1_4_r4.lo \ generated/cshift1_4_r8.lo generated/cshift1_4_r10.lo \ @@ -500,88 +485,70 @@ am__objects_36 = generated/cshift1_4_i1.lo generated/cshift1_4_i2.lo \ generated/cshift1_16_r16.lo generated/cshift1_16_r17.lo \ generated/cshift1_16_c4.lo generated/cshift1_16_c8.lo \ generated/cshift1_16_c10.lo generated/cshift1_16_c16.lo \ - generated/cshift1_16_c17.lo -am__objects_37 = generated/maxloc0_4_s1.lo generated/maxloc0_4_s4.lo \ - generated/maxloc0_8_s1.lo generated/maxloc0_8_s4.lo \ - generated/maxloc0_16_s1.lo generated/maxloc0_16_s4.lo -am__objects_38 = generated/minloc0_4_s1.lo generated/minloc0_4_s4.lo \ - generated/minloc0_8_s1.lo generated/minloc0_8_s4.lo \ - generated/minloc0_16_s1.lo generated/minloc0_16_s4.lo -am__objects_39 = generated/maxloc1_4_s1.lo generated/maxloc1_4_s4.lo \ - generated/maxloc1_8_s1.lo generated/maxloc1_8_s4.lo \ - generated/maxloc1_16_s1.lo generated/maxloc1_16_s4.lo -am__objects_40 = generated/minloc1_4_s1.lo generated/minloc1_4_s4.lo \ - generated/minloc1_8_s1.lo generated/minloc1_8_s4.lo \ - generated/minloc1_16_s1.lo generated/minloc1_16_s4.lo -am__objects_41 = generated/maxloc2_4_s1.lo generated/maxloc2_4_s4.lo \ - generated/maxloc2_8_s1.lo generated/maxloc2_8_s4.lo \ - generated/maxloc2_16_s1.lo generated/maxloc2_16_s4.lo -am__objects_42 = generated/minloc2_4_s1.lo generated/minloc2_4_s4.lo \ - generated/minloc2_8_s1.lo generated/minloc2_8_s4.lo \ - generated/minloc2_16_s1.lo generated/minloc2_16_s4.lo -am__objects_43 = generated/maxval0_s1.lo generated/maxval0_s4.lo -am__objects_44 = generated/minval0_s1.lo generated/minval0_s4.lo -am__objects_45 = generated/maxval1_s1.lo generated/maxval1_s4.lo -am__objects_46 = generated/minval1_s1.lo generated/minval1_s4.lo -am__objects_47 = generated/findloc0_i1.lo generated/findloc0_i2.lo \ - generated/findloc0_i4.lo generated/findloc0_i8.lo \ - generated/findloc0_i16.lo generated/findloc0_r4.lo \ - generated/findloc0_r8.lo generated/findloc0_r10.lo \ - generated/findloc0_r16.lo generated/findloc0_r17.lo \ - generated/findloc0_c4.lo generated/findloc0_c8.lo \ - generated/findloc0_c10.lo generated/findloc0_c16.lo \ - generated/findloc0_c17.lo -am__objects_48 = generated/findloc0_s1.lo generated/findloc0_s4.lo -am__objects_49 = generated/findloc1_i1.lo generated/findloc1_i2.lo \ + generated/cshift1_16_c17.lo generated/findloc0_i1.lo \ + generated/findloc0_i2.lo generated/findloc0_i4.lo \ + generated/findloc0_i8.lo generated/findloc0_i16.lo \ + generated/findloc0_r4.lo generated/findloc0_r8.lo \ + generated/findloc0_r10.lo generated/findloc0_r16.lo \ + generated/findloc0_r17.lo generated/findloc0_c4.lo \ + generated/findloc0_c8.lo generated/findloc0_c10.lo \ + generated/findloc0_c16.lo generated/findloc0_c17.lo \ + generated/findloc0_s1.lo generated/findloc0_s4.lo \ + generated/findloc1_i1.lo generated/findloc1_i2.lo \ generated/findloc1_i4.lo generated/findloc1_i8.lo \ generated/findloc1_i16.lo generated/findloc1_r4.lo \ generated/findloc1_r8.lo generated/findloc1_r10.lo \ generated/findloc1_r16.lo generated/findloc1_r17.lo \ generated/findloc1_c4.lo generated/findloc1_c8.lo \ generated/findloc1_c10.lo generated/findloc1_c16.lo \ - generated/findloc1_c17.lo -am__objects_50 = generated/findloc1_s1.lo generated/findloc1_s4.lo -am__objects_51 = generated/findloc2_s1.lo generated/findloc2_s4.lo -am__objects_52 = runtime/ISO_Fortran_binding.lo -am__objects_53 = generated/pow_m1_m1.lo generated/pow_m1_m2.lo \ - generated/pow_m1_m4.lo generated/pow_m1_m8.lo \ - generated/pow_m1_m16.lo generated/pow_m2_m1.lo \ - generated/pow_m2_m2.lo generated/pow_m2_m4.lo \ - generated/pow_m2_m8.lo generated/pow_m2_m16.lo \ - generated/pow_m4_m1.lo generated/pow_m4_m2.lo \ - generated/pow_m4_m4.lo generated/pow_m4_m8.lo \ - generated/pow_m4_m16.lo generated/pow_m8_m1.lo \ - generated/pow_m8_m2.lo generated/pow_m8_m4.lo \ - generated/pow_m8_m8.lo generated/pow_m8_m16.lo \ - generated/pow_m16_m1.lo generated/pow_m16_m2.lo \ - generated/pow_m16_m4.lo generated/pow_m16_m8.lo \ - generated/pow_m16_m16.lo -am__objects_54 = $(am__objects_4) $(am__objects_5) $(am__objects_6) \ - $(am__objects_7) $(am__objects_8) $(am__objects_9) \ - $(am__objects_10) $(am__objects_11) $(am__objects_12) \ - $(am__objects_13) $(am__objects_14) $(am__objects_15) \ - $(am__objects_16) $(am__objects_17) $(am__objects_18) \ - $(am__objects_19) $(am__objects_20) $(am__objects_21) \ - $(am__objects_22) $(am__objects_23) $(am__objects_24) \ - $(am__objects_25) $(am__objects_26) $(am__objects_27) \ - $(am__objects_28) $(am__objects_29) $(am__objects_30) \ - $(am__objects_31) $(am__objects_32) $(am__objects_33) \ - $(am__objects_34) $(am__objects_35) $(am__objects_36) \ - $(am__objects_37) $(am__objects_38) $(am__objects_39) \ - $(am__objects_40) $(am__objects_41) $(am__objects_42) \ - $(am__objects_43) $(am__objects_44) $(am__objects_45) \ - $(am__objects_46) $(am__objects_47) $(am__objects_48) \ - $(am__objects_49) $(am__objects_50) $(am__objects_51) \ - $(am__objects_52) $(am__objects_53) -@LIBGFOR_MINIMAL_FALSE@am__objects_55 = io/close.lo io/file_pos.lo \ + generated/findloc1_c17.lo generated/findloc1_s1.lo \ + generated/findloc1_s4.lo generated/findloc2_s1.lo \ + generated/findloc2_s4.lo generated/maxloc0_4_s1.lo \ + generated/maxloc0_4_s4.lo generated/maxloc0_8_s1.lo \ + generated/maxloc0_8_s4.lo generated/maxloc0_16_s1.lo \ + generated/maxloc0_16_s4.lo generated/maxloc1_4_s1.lo \ + generated/maxloc1_4_s4.lo generated/maxloc1_8_s1.lo \ + generated/maxloc1_8_s4.lo generated/maxloc1_16_s1.lo \ + generated/maxloc1_16_s4.lo generated/maxloc2_4_s1.lo \ + generated/maxloc2_4_s4.lo generated/maxloc2_8_s1.lo \ + generated/maxloc2_8_s4.lo generated/maxloc2_16_s1.lo \ + generated/maxloc2_16_s4.lo generated/maxval0_s1.lo \ + generated/maxval0_s4.lo generated/maxval1_s1.lo \ + generated/maxval1_s4.lo generated/minloc0_4_s1.lo \ + generated/minloc0_4_s4.lo generated/minloc0_8_s1.lo \ + generated/minloc0_8_s4.lo generated/minloc0_16_s1.lo \ + generated/minloc0_16_s4.lo generated/minloc1_4_s1.lo \ + generated/minloc1_4_s4.lo generated/minloc1_8_s1.lo \ + generated/minloc1_8_s4.lo generated/minloc1_16_s1.lo \ + generated/minloc1_16_s4.lo generated/minloc2_4_s1.lo \ + generated/minloc2_4_s4.lo generated/minloc2_8_s1.lo \ + generated/minloc2_8_s4.lo generated/minloc2_16_s1.lo \ + generated/minloc2_16_s4.lo generated/minval0_s1.lo \ + generated/minval0_s4.lo generated/minval1_s1.lo \ + generated/minval1_s4.lo generated/pow_m1_m1.lo \ + generated/pow_m1_m2.lo generated/pow_m1_m4.lo \ + generated/pow_m1_m8.lo generated/pow_m1_m16.lo \ + generated/pow_m2_m1.lo generated/pow_m2_m2.lo \ + generated/pow_m2_m4.lo generated/pow_m2_m8.lo \ + generated/pow_m2_m16.lo generated/pow_m4_m1.lo \ + generated/pow_m4_m2.lo generated/pow_m4_m4.lo \ + generated/pow_m4_m8.lo generated/pow_m4_m16.lo \ + generated/pow_m8_m1.lo generated/pow_m8_m2.lo \ + generated/pow_m8_m4.lo generated/pow_m8_m8.lo \ + generated/pow_m8_m16.lo generated/pow_m16_m1.lo \ + generated/pow_m16_m2.lo generated/pow_m16_m4.lo \ + generated/pow_m16_m8.lo generated/pow_m16_m16.lo \ + $(am__objects_4) $(am__objects_5) $(am__objects_6) \ + runtime/ISO_Fortran_binding.lo +@LIBGFOR_MINIMAL_FALSE@am__objects_8 = io/close.lo io/file_pos.lo \ @LIBGFOR_MINIMAL_FALSE@ io/format.lo io/inquire.lo \ @LIBGFOR_MINIMAL_FALSE@ io/intrinsics.lo io/list_read.lo \ @LIBGFOR_MINIMAL_FALSE@ io/lock.lo io/open.lo io/read.lo \ @LIBGFOR_MINIMAL_FALSE@ io/transfer.lo io/transfer128.lo \ @LIBGFOR_MINIMAL_FALSE@ io/unit.lo io/unix.lo io/write.lo \ @LIBGFOR_MINIMAL_FALSE@ io/fbuf.lo io/async.lo -am__objects_56 = io/size_from_kind.lo $(am__objects_55) -@LIBGFOR_MINIMAL_FALSE@am__objects_57 = intrinsics/access.lo \ +am__objects_9 = io/size_from_kind.lo $(am__objects_8) +@LIBGFOR_MINIMAL_FALSE@am__objects_10 = intrinsics/access.lo \ @LIBGFOR_MINIMAL_FALSE@ intrinsics/c99_functions.lo \ @LIBGFOR_MINIMAL_FALSE@ intrinsics/chdir.lo intrinsics/chmod.lo \ @LIBGFOR_MINIMAL_FALSE@ intrinsics/clock.lo \ @@ -605,8 +572,8 @@ am__objects_56 = io/size_from_kind.lo $(am__objects_55) @LIBGFOR_MINIMAL_FALSE@ intrinsics/system_clock.lo \ @LIBGFOR_MINIMAL_FALSE@ intrinsics/time.lo intrinsics/umask.lo \ @LIBGFOR_MINIMAL_FALSE@ intrinsics/unlink.lo -@IEEE_SUPPORT_TRUE@am__objects_58 = ieee/ieee_helper.lo -am__objects_59 = intrinsics/associated.lo intrinsics/abort.lo \ +@IEEE_SUPPORT_TRUE@am__objects_11 = ieee/ieee_helper.lo +am__objects_12 = intrinsics/associated.lo intrinsics/abort.lo \ intrinsics/args.lo intrinsics/cshift0.lo \ intrinsics/eoshift0.lo intrinsics/eoshift2.lo \ intrinsics/erfc_scaled.lo intrinsics/extends_type_of.lo \ @@ -621,12 +588,12 @@ am__objects_59 = intrinsics/associated.lo intrinsics/abort.lo \ intrinsics/selected_real_kind.lo intrinsics/trigd.lo \ intrinsics/unpack_generic.lo runtime/in_pack_generic.lo \ runtime/in_unpack_generic.lo runtime/in_pack_class.lo \ - runtime/in_unpack_class.lo $(am__objects_57) $(am__objects_58) -@IEEE_SUPPORT_TRUE@am__objects_60 = ieee/ieee_arithmetic.lo \ + runtime/in_unpack_class.lo $(am__objects_10) $(am__objects_11) +@IEEE_SUPPORT_TRUE@am__objects_13 = ieee/ieee_arithmetic.lo \ @IEEE_SUPPORT_TRUE@ ieee/ieee_exceptions.lo \ @IEEE_SUPPORT_TRUE@ ieee/ieee_features.lo -am__objects_61 = -am__objects_62 = generated/_abs_c4.lo generated/_abs_c8.lo \ +am__objects_14 = +am__objects_15 = generated/_abs_c4.lo generated/_abs_c8.lo \ generated/_abs_c10.lo generated/_abs_c16.lo \ generated/_abs_c17.lo generated/_abs_i4.lo \ generated/_abs_i8.lo generated/_abs_i16.lo \ @@ -694,8 +661,8 @@ am__objects_62 = generated/_abs_c4.lo generated/_abs_c8.lo \ generated/_aint_r10.lo generated/_aint_r16.lo \ generated/_aint_r17.lo generated/_anint_r4.lo \ generated/_anint_r8.lo generated/_anint_r10.lo \ - generated/_anint_r16.lo generated/_anint_r17.lo -am__objects_63 = generated/_sign_i4.lo generated/_sign_i8.lo \ + generated/_anint_r16.lo generated/_anint_r17.lo \ + generated/_sign_i4.lo generated/_sign_i8.lo \ generated/_sign_i16.lo generated/_sign_r4.lo \ generated/_sign_r8.lo generated/_sign_r10.lo \ generated/_sign_r16.lo generated/_sign_r17.lo \ @@ -709,14 +676,12 @@ am__objects_63 = generated/_sign_i4.lo generated/_sign_i8.lo \ generated/_mod_i8.lo generated/_mod_i16.lo \ generated/_mod_r4.lo generated/_mod_r8.lo \ generated/_mod_r10.lo generated/_mod_r16.lo \ - generated/_mod_r17.lo -am__objects_64 = generated/misc_specifics.lo -am__objects_65 = $(am__objects_62) $(am__objects_63) $(am__objects_64) \ + generated/_mod_r17.lo generated/misc_specifics.lo \ intrinsics/dprod_r8.lo intrinsics/f2c_specifics.lo \ intrinsics/random_init.lo -am_libgfortran_la_OBJECTS = $(am__objects_3) $(am__objects_54) \ - $(am__objects_56) $(am__objects_59) $(am__objects_60) \ - $(am__objects_61) $(am__objects_65) +am_libgfortran_la_OBJECTS = $(am__objects_3) $(am__objects_7) \ + $(am__objects_9) $(am__objects_12) $(am__objects_13) \ + $(am__objects_14) $(am__objects_15) libgfortran_la_OBJECTS = $(am_libgfortran_la_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -1048,102 +1013,61 @@ gfor_helper_src = intrinsics/associated.c intrinsics/abort.c \ gfor_src = runtime/bounds.c runtime/compile_options.c runtime/memory.c \ runtime/string.c runtime/select.c $(am__append_6) \ $(am__append_7) -i_all_c = \ +i_matmul_c = \ +generated/matmul_i1.c \ +generated/matmul_i2.c \ +generated/matmul_i4.c \ +generated/matmul_i8.c \ +generated/matmul_i16.c \ +generated/matmul_r4.c \ +generated/matmul_r8.c \ +generated/matmul_r10.c \ +generated/matmul_r16.c \ +generated/matmul_r17.c \ +generated/matmul_c4.c \ +generated/matmul_c8.c \ +generated/matmul_c10.c \ +generated/matmul_c16.c \ +generated/matmul_c17.c + +i_matmulavx128_c = \ +generated/matmulavx128_i1.c \ +generated/matmulavx128_i2.c \ +generated/matmulavx128_i4.c \ +generated/matmulavx128_i8.c \ +generated/matmulavx128_i16.c \ +generated/matmulavx128_r4.c \ +generated/matmulavx128_r8.c \ +generated/matmulavx128_r10.c \ +generated/matmulavx128_r16.c \ +generated/matmulavx128_r17.c \ +generated/matmulavx128_c4.c \ +generated/matmulavx128_c8.c \ +generated/matmulavx128_c10.c \ +generated/matmulavx128_c16.c \ +generated/matmulavx128_c17.c + +i_matmull_c = \ +generated/matmul_l4.c \ +generated/matmul_l8.c \ +generated/matmul_l16.c + +gfor_built_src = \ generated/all_l1.c \ generated/all_l2.c \ generated/all_l4.c \ generated/all_l8.c \ -generated/all_l16.c - -i_any_c = \ +generated/all_l16.c \ generated/any_l1.c \ generated/any_l2.c \ generated/any_l4.c \ generated/any_l8.c \ -generated/any_l16.c - -i_bessel_c = \ -generated/bessel_r4.c \ -generated/bessel_r8.c \ -generated/bessel_r10.c \ -generated/bessel_r16.c \ -generated/bessel_r17.c - -i_count_c = \ +generated/any_l16.c \ generated/count_1_l.c \ generated/count_2_l.c \ generated/count_4_l.c \ generated/count_8_l.c \ -generated/count_16_l.c - -i_iall_c = \ -generated/iall_i1.c \ -generated/iall_i2.c \ -generated/iall_i4.c \ -generated/iall_i8.c \ -generated/iall_i16.c - -i_iany_c = \ -generated/iany_i1.c \ -generated/iany_i2.c \ -generated/iany_i4.c \ -generated/iany_i8.c \ -generated/iany_i16.c - -i_iparity_c = \ -generated/iparity_i1.c \ -generated/iparity_i2.c \ -generated/iparity_i4.c \ -generated/iparity_i8.c \ -generated/iparity_i16.c - -i_findloc0_c = \ -generated/findloc0_i1.c \ -generated/findloc0_i2.c \ -generated/findloc0_i4.c \ -generated/findloc0_i8.c \ -generated/findloc0_i16.c \ -generated/findloc0_r4.c \ -generated/findloc0_r8.c \ -generated/findloc0_r10.c \ -generated/findloc0_r16.c \ -generated/findloc0_r17.c \ -generated/findloc0_c4.c \ -generated/findloc0_c8.c \ -generated/findloc0_c10.c \ -generated/findloc0_c16.c \ -generated/findloc0_c17.c - -i_findloc0s_c = \ -generated/findloc0_s1.c \ -generated/findloc0_s4.c - -i_findloc1_c = \ -generated/findloc1_i1.c \ -generated/findloc1_i2.c \ -generated/findloc1_i4.c \ -generated/findloc1_i8.c \ -generated/findloc1_i16.c \ -generated/findloc1_r4.c \ -generated/findloc1_r8.c \ -generated/findloc1_r10.c \ -generated/findloc1_r16.c \ -generated/findloc1_r17.c \ -generated/findloc1_c4.c \ -generated/findloc1_c8.c \ -generated/findloc1_c10.c \ -generated/findloc1_c16.c \ -generated/findloc1_c17.c - -i_findloc1s_c = \ -generated/findloc1_s1.c \ -generated/findloc1_s4.c - -i_findloc2s_c = \ -generated/findloc2_s1.c \ -generated/findloc2_s4.c - -i_maxloc0_c = \ +generated/count_16_l.c \ generated/maxloc0_4_i1.c \ generated/maxloc0_8_i1.c \ generated/maxloc0_16_i1.c \ @@ -1188,17 +1112,7 @@ generated/maxloc0_8_r16.c \ generated/maxloc0_16_r16.c \ generated/maxloc0_4_r17.c \ generated/maxloc0_8_r17.c \ -generated/maxloc0_16_r17.c - -i_maxloc0s_c = \ -generated/maxloc0_4_s1.c \ -generated/maxloc0_4_s4.c \ -generated/maxloc0_8_s1.c \ -generated/maxloc0_8_s4.c \ -generated/maxloc0_16_s1.c \ -generated/maxloc0_16_s4.c - -i_maxloc1_c = \ +generated/maxloc0_16_r17.c \ generated/maxloc1_4_i1.c \ generated/maxloc1_8_i1.c \ generated/maxloc1_16_i1.c \ @@ -1243,25 +1157,7 @@ generated/maxloc1_8_r16.c \ generated/maxloc1_16_r16.c \ generated/maxloc1_4_r17.c \ generated/maxloc1_8_r17.c \ -generated/maxloc1_16_r17.c - -i_maxloc1s_c = \ -generated/maxloc1_4_s1.c \ -generated/maxloc1_4_s4.c \ -generated/maxloc1_8_s1.c \ -generated/maxloc1_8_s4.c \ -generated/maxloc1_16_s1.c \ -generated/maxloc1_16_s4.c - -i_maxloc2s_c = \ -generated/maxloc2_4_s1.c \ -generated/maxloc2_4_s4.c \ -generated/maxloc2_8_s1.c \ -generated/maxloc2_8_s4.c \ -generated/maxloc2_16_s1.c \ -generated/maxloc2_16_s4.c - -i_maxval_c = \ +generated/maxloc1_16_r17.c \ generated/maxval_i1.c \ generated/maxval_i2.c \ generated/maxval_i4.c \ @@ -1276,17 +1172,7 @@ generated/maxval_r4.c \ generated/maxval_r8.c \ generated/maxval_r10.c \ generated/maxval_r16.c \ -generated/maxval_r17.c - -i_maxval0s_c = \ -generated/maxval0_s1.c \ -generated/maxval0_s4.c - -i_maxval1s_c = \ -generated/maxval1_s1.c \ -generated/maxval1_s4.c - -i_minloc0_c = \ +generated/maxval_r17.c \ generated/minloc0_4_i1.c \ generated/minloc0_8_i1.c \ generated/minloc0_16_i1.c \ @@ -1331,17 +1217,7 @@ generated/minloc0_8_r16.c \ generated/minloc0_16_r16.c \ generated/minloc0_4_r17.c \ generated/minloc0_8_r17.c \ -generated/minloc0_16_r17.c - -i_minloc0s_c = \ -generated/minloc0_4_s1.c \ -generated/minloc0_4_s4.c \ -generated/minloc0_8_s1.c \ -generated/minloc0_8_s4.c \ -generated/minloc0_16_s1.c \ -generated/minloc0_16_s4.c - -i_minloc1_c = \ +generated/minloc0_16_r17.c \ generated/minloc1_4_i1.c \ generated/minloc1_8_i1.c \ generated/minloc1_16_i1.c \ @@ -1386,25 +1262,7 @@ generated/minloc1_8_r16.c \ generated/minloc1_16_r16.c \ generated/minloc1_4_r17.c \ generated/minloc1_8_r17.c \ -generated/minloc1_16_r17.c - -i_minloc1s_c = \ -generated/minloc1_4_s1.c \ -generated/minloc1_4_s4.c \ -generated/minloc1_8_s1.c \ -generated/minloc1_8_s4.c \ -generated/minloc1_16_s1.c \ -generated/minloc1_16_s4.c - -i_minloc2s_c = \ -generated/minloc2_4_s1.c \ -generated/minloc2_4_s4.c \ -generated/minloc2_8_s1.c \ -generated/minloc2_8_s4.c \ -generated/minloc2_16_s1.c \ -generated/minloc2_16_s4.c - -i_minval_c = \ +generated/minloc1_16_r17.c \ generated/minval_i1.c \ generated/minval_i2.c \ generated/minval_i4.c \ @@ -1419,48 +1277,7 @@ generated/minval_r4.c \ generated/minval_r8.c \ generated/minval_r10.c \ generated/minval_r16.c \ -generated/minval_r17.c - -i_minval0s_c = \ -generated/minval0_s1.c \ -generated/minval0_s4.c - -i_minval1s_c = \ -generated/minval1_s1.c \ -generated/minval1_s4.c - -i_norm2_c = \ -generated/norm2_r4.c \ -generated/norm2_r8.c \ -generated/norm2_r10.c \ -generated/norm2_r16.c \ -generated/norm2_r17.c - -i_parity_c = \ -generated/parity_l1.c \ -generated/parity_l2.c \ -generated/parity_l4.c \ -generated/parity_l8.c \ -generated/parity_l16.c - -i_sum_c = \ -generated/sum_i1.c \ -generated/sum_i2.c \ -generated/sum_i4.c \ -generated/sum_i8.c \ -generated/sum_i16.c \ -generated/sum_r4.c \ -generated/sum_r8.c \ -generated/sum_r10.c \ -generated/sum_r16.c \ -generated/sum_r17.c \ -generated/sum_c4.c \ -generated/sum_c8.c \ -generated/sum_c10.c \ -generated/sum_c16.c \ -generated/sum_c17.c - -i_product_c = \ +generated/minval_r17.c \ generated/product_i1.c \ generated/product_i2.c \ generated/product_i4.c \ @@ -1475,55 +1292,66 @@ generated/product_c4.c \ generated/product_c8.c \ generated/product_c10.c \ generated/product_c16.c \ -generated/product_c17.c - -i_matmul_c = \ -generated/matmul_i1.c \ -generated/matmul_i2.c \ -generated/matmul_i4.c \ -generated/matmul_i8.c \ -generated/matmul_i16.c \ -generated/matmul_r4.c \ -generated/matmul_r8.c \ -generated/matmul_r10.c \ -generated/matmul_r16.c \ -generated/matmul_r17.c \ -generated/matmul_c4.c \ -generated/matmul_c8.c \ -generated/matmul_c10.c \ -generated/matmul_c16.c \ -generated/matmul_c17.c - -i_matmulavx128_c = \ -generated/matmulavx128_i1.c \ -generated/matmulavx128_i2.c \ -generated/matmulavx128_i4.c \ -generated/matmulavx128_i8.c \ -generated/matmulavx128_i16.c \ -generated/matmulavx128_r4.c \ -generated/matmulavx128_r8.c \ -generated/matmulavx128_r10.c \ -generated/matmulavx128_r16.c \ -generated/matmulavx128_r17.c \ -generated/matmulavx128_c4.c \ -generated/matmulavx128_c8.c \ -generated/matmulavx128_c10.c \ -generated/matmulavx128_c16.c \ -generated/matmulavx128_c17.c - -i_matmull_c = \ -generated/matmul_l4.c \ -generated/matmul_l8.c \ -generated/matmul_l16.c - -i_shape_c = \ +generated/product_c17.c \ +generated/sum_i1.c \ +generated/sum_i2.c \ +generated/sum_i4.c \ +generated/sum_i8.c \ +generated/sum_i16.c \ +generated/sum_r4.c \ +generated/sum_r8.c \ +generated/sum_r10.c \ +generated/sum_r16.c \ +generated/sum_r17.c \ +generated/sum_c4.c \ +generated/sum_c8.c \ +generated/sum_c10.c \ +generated/sum_c16.c \ +generated/sum_c17.c \ +generated/bessel_r4.c \ +generated/bessel_r8.c \ +generated/bessel_r10.c \ +generated/bessel_r16.c \ +generated/bessel_r17.c \ +generated/iall_i1.c \ +generated/iall_i2.c \ +generated/iall_i4.c \ +generated/iall_i8.c \ +generated/iall_i16.c \ +generated/iany_i1.c \ +generated/iany_i2.c \ +generated/iany_i4.c \ +generated/iany_i8.c \ +generated/iany_i16.c \ +generated/iparity_i1.c \ +generated/iparity_i2.c \ +generated/iparity_i4.c \ +generated/iparity_i8.c \ +generated/iparity_i16.c \ +generated/norm2_r4.c \ +generated/norm2_r8.c \ +generated/norm2_r10.c \ +generated/norm2_r16.c \ +generated/norm2_r17.c \ +generated/parity_l1.c \ +generated/parity_l2.c \ +generated/parity_l4.c \ +generated/parity_l8.c \ +generated/parity_l16.c \ generated/shape_i1.c \ generated/shape_i2.c \ generated/shape_i4.c \ generated/shape_i8.c \ -generated/shape_i16.c - -i_reshape_c = \ +generated/shape_i16.c \ +generated/eoshift1_4.c \ +generated/eoshift1_8.c \ +generated/eoshift1_16.c \ +generated/eoshift3_4.c \ +generated/eoshift3_8.c \ +generated/eoshift3_16.c \ +generated/cshift1_4.c \ +generated/cshift1_8.c \ +generated/cshift1_16.c \ generated/reshape_i4.c \ generated/reshape_i8.c \ generated/reshape_i16.c \ @@ -1536,88 +1364,7 @@ generated/reshape_c4.c \ generated/reshape_c8.c \ generated/reshape_c10.c \ generated/reshape_c16.c \ -generated/reshape_c17.c - -i_eoshift1_c = \ -generated/eoshift1_4.c \ -generated/eoshift1_8.c \ -generated/eoshift1_16.c - -i_eoshift3_c = \ -generated/eoshift3_4.c \ -generated/eoshift3_8.c \ -generated/eoshift3_16.c - -i_cshift0_c = \ -generated/cshift0_i1.c \ -generated/cshift0_i2.c \ -generated/cshift0_i4.c \ -generated/cshift0_i8.c \ -generated/cshift0_i16.c \ -generated/cshift0_r4.c \ -generated/cshift0_r8.c \ -generated/cshift0_r10.c \ -generated/cshift0_r16.c \ -generated/cshift0_r17.c \ -generated/cshift0_c4.c \ -generated/cshift0_c8.c \ -generated/cshift0_c10.c \ -generated/cshift0_c16.c \ -generated/cshift0_c17.c - -i_cshift1_c = \ -generated/cshift1_4.c \ -generated/cshift1_8.c \ -generated/cshift1_16.c - -i_cshift1a_c = \ -generated/cshift1_4_i1.c \ -generated/cshift1_4_i2.c \ -generated/cshift1_4_i4.c \ -generated/cshift1_4_i8.c \ -generated/cshift1_4_i16.c \ -generated/cshift1_4_r4.c \ -generated/cshift1_4_r8.c \ -generated/cshift1_4_r10.c \ -generated/cshift1_4_r16.c \ -generated/cshift1_4_r17.c \ -generated/cshift1_4_c4.c \ -generated/cshift1_4_c8.c \ -generated/cshift1_4_c10.c \ -generated/cshift1_4_c16.c \ -generated/cshift1_4_c17.c \ -generated/cshift1_8_i1.c \ -generated/cshift1_8_i2.c \ -generated/cshift1_8_i4.c \ -generated/cshift1_8_i8.c \ -generated/cshift1_8_i16.c \ -generated/cshift1_8_r4.c \ -generated/cshift1_8_r8.c \ -generated/cshift1_8_r10.c \ -generated/cshift1_8_r16.c \ -generated/cshift1_8_r17.c \ -generated/cshift1_8_c4.c \ -generated/cshift1_8_c8.c \ -generated/cshift1_8_c10.c \ -generated/cshift1_8_c16.c \ -generated/cshift1_8_c17.c \ -generated/cshift1_16_i1.c \ -generated/cshift1_16_i2.c \ -generated/cshift1_16_i4.c \ -generated/cshift1_16_i8.c \ -generated/cshift1_16_i16.c \ -generated/cshift1_16_r4.c \ -generated/cshift1_16_r8.c \ -generated/cshift1_16_r10.c \ -generated/cshift1_16_r16.c \ -generated/cshift1_16_r17.c \ -generated/cshift1_16_c4.c \ -generated/cshift1_16_c8.c \ -generated/cshift1_16_c10.c \ -generated/cshift1_16_c16.c \ -generated/cshift1_16_c17.c - -in_pack_c = \ +generated/reshape_c17.c \ generated/in_pack_i1.c \ generated/in_pack_i2.c \ generated/in_pack_i4.c \ @@ -1632,9 +1379,7 @@ generated/in_pack_c4.c \ generated/in_pack_c8.c \ generated/in_pack_c10.c \ generated/in_pack_c16.c \ -generated/in_pack_c17.c - -in_unpack_c = \ +generated/in_pack_c17.c \ generated/in_unpack_i1.c \ generated/in_unpack_i2.c \ generated/in_unpack_i4.c \ @@ -1649,9 +1394,7 @@ generated/in_unpack_c4.c \ generated/in_unpack_c8.c \ generated/in_unpack_c10.c \ generated/in_unpack_c16.c \ -generated/in_unpack_c17.c - -i_pow_c = \ +generated/in_unpack_c17.c \ generated/pow_i4_i4.c \ generated/pow_i8_i4.c \ generated/pow_i16_i4.c \ @@ -1687,9 +1430,192 @@ generated/pow_c4_i16.c \ generated/pow_c8_i16.c \ generated/pow_c10_i16.c \ generated/pow_c16_i16.c \ -generated/pow_c17_i16.c - -i_powu_c = \ +generated/pow_c17_i16.c \ +generated/pack_i1.c \ +generated/pack_i2.c \ +generated/pack_i4.c \ +generated/pack_i8.c \ +generated/pack_i16.c \ +generated/pack_r4.c \ +generated/pack_r8.c \ +generated/pack_r10.c \ +generated/pack_r16.c \ +generated/pack_r17.c \ +generated/pack_c4.c \ +generated/pack_c8.c \ +generated/pack_c10.c \ +generated/pack_c16.c \ +generated/pack_c17.c \ +generated/unpack_i1.c \ +generated/unpack_i2.c \ +generated/unpack_i4.c \ +generated/unpack_i8.c \ +generated/unpack_i16.c \ +generated/unpack_r4.c \ +generated/unpack_r8.c \ +generated/unpack_r10.c \ +generated/unpack_r16.c \ +generated/unpack_r17.c \ +generated/unpack_c4.c \ +generated/unpack_c8.c \ +generated/unpack_c10.c \ +generated/unpack_c16.c \ +generated/unpack_c17.c \ +generated/spread_i1.c \ +generated/spread_i2.c \ +generated/spread_i4.c \ +generated/spread_i8.c \ +generated/spread_i16.c \ +generated/spread_r4.c \ +generated/spread_r8.c \ +generated/spread_r10.c \ +generated/spread_r16.c \ +generated/spread_r17.c \ +generated/spread_c4.c \ +generated/spread_c8.c \ +generated/spread_c10.c \ +generated/spread_c16.c \ +generated/spread_c17.c \ +generated/cshift0_i1.c \ +generated/cshift0_i2.c \ +generated/cshift0_i4.c \ +generated/cshift0_i8.c \ +generated/cshift0_i16.c \ +generated/cshift0_r4.c \ +generated/cshift0_r8.c \ +generated/cshift0_r10.c \ +generated/cshift0_r16.c \ +generated/cshift0_r17.c \ +generated/cshift0_c4.c \ +generated/cshift0_c8.c \ +generated/cshift0_c10.c \ +generated/cshift0_c16.c \ +generated/cshift0_c17.c \ +generated/cshift1_4_i1.c \ +generated/cshift1_4_i2.c \ +generated/cshift1_4_i4.c \ +generated/cshift1_4_i8.c \ +generated/cshift1_4_i16.c \ +generated/cshift1_4_r4.c \ +generated/cshift1_4_r8.c \ +generated/cshift1_4_r10.c \ +generated/cshift1_4_r16.c \ +generated/cshift1_4_r17.c \ +generated/cshift1_4_c4.c \ +generated/cshift1_4_c8.c \ +generated/cshift1_4_c10.c \ +generated/cshift1_4_c16.c \ +generated/cshift1_4_c17.c \ +generated/cshift1_8_i1.c \ +generated/cshift1_8_i2.c \ +generated/cshift1_8_i4.c \ +generated/cshift1_8_i8.c \ +generated/cshift1_8_i16.c \ +generated/cshift1_8_r4.c \ +generated/cshift1_8_r8.c \ +generated/cshift1_8_r10.c \ +generated/cshift1_8_r16.c \ +generated/cshift1_8_r17.c \ +generated/cshift1_8_c4.c \ +generated/cshift1_8_c8.c \ +generated/cshift1_8_c10.c \ +generated/cshift1_8_c16.c \ +generated/cshift1_8_c17.c \ +generated/cshift1_16_i1.c \ +generated/cshift1_16_i2.c \ +generated/cshift1_16_i4.c \ +generated/cshift1_16_i8.c \ +generated/cshift1_16_i16.c \ +generated/cshift1_16_r4.c \ +generated/cshift1_16_r8.c \ +generated/cshift1_16_r10.c \ +generated/cshift1_16_r16.c \ +generated/cshift1_16_r17.c \ +generated/cshift1_16_c4.c \ +generated/cshift1_16_c8.c \ +generated/cshift1_16_c10.c \ +generated/cshift1_16_c16.c \ +generated/cshift1_16_c17.c \ +generated/findloc0_i1.c \ +generated/findloc0_i2.c \ +generated/findloc0_i4.c \ +generated/findloc0_i8.c \ +generated/findloc0_i16.c \ +generated/findloc0_r4.c \ +generated/findloc0_r8.c \ +generated/findloc0_r10.c \ +generated/findloc0_r16.c \ +generated/findloc0_r17.c \ +generated/findloc0_c4.c \ +generated/findloc0_c8.c \ +generated/findloc0_c10.c \ +generated/findloc0_c16.c \ +generated/findloc0_c17.c \ +generated/findloc0_s1.c \ +generated/findloc0_s4.c \ +generated/findloc1_i1.c \ +generated/findloc1_i2.c \ +generated/findloc1_i4.c \ +generated/findloc1_i8.c \ +generated/findloc1_i16.c \ +generated/findloc1_r4.c \ +generated/findloc1_r8.c \ +generated/findloc1_r10.c \ +generated/findloc1_r16.c \ +generated/findloc1_r17.c \ +generated/findloc1_c4.c \ +generated/findloc1_c8.c \ +generated/findloc1_c10.c \ +generated/findloc1_c16.c \ +generated/findloc1_c17.c \ +generated/findloc1_s1.c \ +generated/findloc1_s4.c \ +generated/findloc2_s1.c \ +generated/findloc2_s4.c \ +generated/maxloc0_4_s1.c \ +generated/maxloc0_4_s4.c \ +generated/maxloc0_8_s1.c \ +generated/maxloc0_8_s4.c \ +generated/maxloc0_16_s1.c \ +generated/maxloc0_16_s4.c \ +generated/maxloc1_4_s1.c \ +generated/maxloc1_4_s4.c \ +generated/maxloc1_8_s1.c \ +generated/maxloc1_8_s4.c \ +generated/maxloc1_16_s1.c \ +generated/maxloc1_16_s4.c \ +generated/maxloc2_4_s1.c \ +generated/maxloc2_4_s4.c \ +generated/maxloc2_8_s1.c \ +generated/maxloc2_8_s4.c \ +generated/maxloc2_16_s1.c \ +generated/maxloc2_16_s4.c \ +generated/maxval0_s1.c \ +generated/maxval0_s4.c \ +generated/maxval1_s1.c \ +generated/maxval1_s4.c \ +generated/minloc0_4_s1.c \ +generated/minloc0_4_s4.c \ +generated/minloc0_8_s1.c \ +generated/minloc0_8_s4.c \ +generated/minloc0_16_s1.c \ +generated/minloc0_16_s4.c \ +generated/minloc1_4_s1.c \ +generated/minloc1_4_s4.c \ +generated/minloc1_8_s1.c \ +generated/minloc1_8_s4.c \ +generated/minloc1_16_s1.c \ +generated/minloc1_16_s4.c \ +generated/minloc2_4_s1.c \ +generated/minloc2_4_s4.c \ +generated/minloc2_8_s1.c \ +generated/minloc2_8_s4.c \ +generated/minloc2_16_s1.c \ +generated/minloc2_16_s4.c \ +generated/minval0_s1.c \ +generated/minval0_s4.c \ +generated/minval1_s1.c \ +generated/minval1_s4.c \ generated/pow_m1_m1.c \ generated/pow_m1_m2.c \ generated/pow_m1_m4.c \ @@ -1714,95 +1640,15 @@ generated/pow_m16_m1.c \ generated/pow_m16_m2.c \ generated/pow_m16_m4.c \ generated/pow_m16_m8.c \ -generated/pow_m16_m16.c - -i_pack_c = \ -generated/pack_i1.c \ -generated/pack_i2.c \ -generated/pack_i4.c \ -generated/pack_i8.c \ -generated/pack_i16.c \ -generated/pack_r4.c \ -generated/pack_r8.c \ -generated/pack_r10.c \ -generated/pack_r16.c \ -generated/pack_r17.c \ -generated/pack_c4.c \ -generated/pack_c8.c \ -generated/pack_c10.c \ -generated/pack_c16.c \ -generated/pack_c17.c +generated/pow_m16_m16.c \ +$(i_matmul_c) $(i_matmull_c) $(i_matmulavx128_c) \ +selected_int_kind.inc selected_real_kind.inc kinds.h \ +kinds.inc c99_protos.inc fpu-target.h fpu-target.inc \ +include/ISO_Fortran_binding.h runtime/ISO_Fortran_binding.c -i_unpack_c = \ -generated/unpack_i1.c \ -generated/unpack_i2.c \ -generated/unpack_i4.c \ -generated/unpack_i8.c \ -generated/unpack_i16.c \ -generated/unpack_r4.c \ -generated/unpack_r8.c \ -generated/unpack_r10.c \ -generated/unpack_r16.c \ -generated/unpack_r17.c \ -generated/unpack_c4.c \ -generated/unpack_c8.c \ -generated/unpack_c10.c \ -generated/unpack_c16.c \ -generated/unpack_c17.c -i_spread_c = \ -generated/spread_i1.c \ -generated/spread_i2.c \ -generated/spread_i4.c \ -generated/spread_i8.c \ -generated/spread_i16.c \ -generated/spread_r4.c \ -generated/spread_r8.c \ -generated/spread_r10.c \ -generated/spread_r16.c \ -generated/spread_r17.c \ -generated/spread_c4.c \ -generated/spread_c8.c \ -generated/spread_c10.c \ -generated/spread_c16.c \ -generated/spread_c17.c - -i_isobinding_c = \ -runtime/ISO_Fortran_binding.c - -m4_files = m4/iparm.m4 m4/ifunction.m4 m4/iforeach.m4 m4/all.m4 \ - m4/any.m4 m4/count.m4 m4/maxloc0.m4 m4/maxloc1.m4 m4/maxval.m4 \ - m4/minloc0.m4 m4/minloc1.m4 m4/minval.m4 m4/product.m4 m4/sum.m4 \ - m4/matmul.m4 m4/matmull.m4 m4/ifunction_logical.m4 \ - m4/ctrig.m4 m4/cexp.m4 m4/chyp.m4 m4/mtype.m4 \ - m4/specific.m4 m4/specific2.m4 m4/head.m4 m4/shape.m4 m4/reshape.m4 \ - m4/eoshift1.m4 m4/eoshift3.m4 \ - m4/pow.m4 \ - m4/misc_specifics.m4 m4/pack.m4 \ - m4/unpack.m4 m4/spread.m4 m4/bessel.m4 m4/norm2.m4 m4/parity.m4 \ - m4/iall.m4 m4/iany.m4 m4/iparity.m4 m4/iforeach-s.m4 m4/findloc0.m4 \ - m4/findloc0s.m4 m4/ifindloc0.m4 m4/findloc1.m4 m4/ifindloc1.m4 \ - m4/findloc2s.m4 m4/ifindloc2.m4 - -gfor_built_src = $(i_all_c) $(i_any_c) $(i_count_c) $(i_maxloc0_c) \ - $(i_maxloc1_c) $(i_maxval_c) $(i_minloc0_c) $(i_minloc1_c) $(i_minval_c) \ - $(i_product_c) $(i_sum_c) $(i_bessel_c) $(i_iall_c) $(i_iany_c) \ - $(i_iparity_c) $(i_norm2_c) $(i_parity_c) \ - $(i_matmul_c) $(i_matmull_c) $(i_shape_c) $(i_eoshift1_c) \ - $(i_eoshift3_c) $(i_cshift1_c) $(i_reshape_c) $(in_pack_c) $(in_unpack_c) \ - $(i_pow_c) $(i_pack_c) $(i_unpack_c) $(i_matmulavx128_c) \ - $(i_spread_c) selected_int_kind.inc selected_real_kind.inc kinds.h \ - $(i_cshift0_c) kinds.inc c99_protos.inc fpu-target.h fpu-target.inc \ - include/ISO_Fortran_binding.h \ - $(i_cshift1a_c) $(i_maxloc0s_c) $(i_minloc0s_c) $(i_maxloc1s_c) \ - $(i_minloc1s_c) $(i_maxloc2s_c) $(i_minloc2s_c) $(i_maxvals_c) \ - $(i_maxval0s_c) $(i_minval0s_c) $(i_maxval1s_c) $(i_minval1s_c) \ - $(i_findloc0_c) $(i_findloc0s_c) $(i_findloc1_c) $(i_findloc1s_c) \ - $(i_findloc2s_c) $(i_isobinding_c) $(i_powu_c) - - -# Machine generated specifics -gfor_built_specific_src = \ +# Specifics +gfor_specific_src = \ generated/_abs_c4.F90 \ generated/_abs_c8.F90 \ generated/_abs_c10.F90 \ @@ -1940,9 +1786,7 @@ generated/_anint_r4.F90 \ generated/_anint_r8.F90 \ generated/_anint_r10.F90 \ generated/_anint_r16.F90 \ -generated/_anint_r17.F90 - -gfor_built_specific2_src = \ +generated/_anint_r17.F90 \ generated/_sign_i4.F90 \ generated/_sign_i8.F90 \ generated/_sign_i16.F90 \ @@ -1971,35 +1815,17 @@ generated/_mod_r4.F90 \ generated/_mod_r8.F90 \ generated/_mod_r10.F90 \ generated/_mod_r16.F90 \ -generated/_mod_r17.F90 - -gfor_misc_specifics = generated/misc_specifics.F90 -gfor_specific_src = \ -$(gfor_built_specific_src) \ -$(gfor_built_specific2_src) \ -$(gfor_misc_specifics) \ +generated/_mod_r17.F90 \ +generated/misc_specifics.F90 \ intrinsics/dprod_r8.f90 \ intrinsics/f2c_specifics.F90 \ intrinsics/random_init.f90 -BUILT_SOURCES = $(gfor_built_src) $(gfor_built_specific_src) \ - $(gfor_built_specific2_src) $(gfor_misc_specifics) - +BUILT_SOURCES = $(gfor_built_src) libgfortran_la_SOURCES = $(gfor_src) $(gfor_built_src) $(gfor_io_src) \ $(gfor_helper_src) $(gfor_ieee_src) $(gfor_io_headers) $(gfor_specific_src) -I_M4_DEPS = m4/iparm.m4 m4/mtype.m4 -I_M4_DEPS0 = $(I_M4_DEPS) m4/iforeach.m4 -I_M4_DEPS1 = $(I_M4_DEPS) m4/ifunction.m4 -I_M4_DEPS2 = $(I_M4_DEPS) m4/ifunction_logical.m4 -I_M4_DEPS3 = $(I_M4_DEPS) m4/iforeach-s.m4 -I_M4_DEPS4 = $(I_M4_DEPS) m4/ifunction-s.m4 -I_M4_DEPS5 = $(I_M4_DEPS) m4/iforeach-s2.m4 -I_M4_DEPS6 = $(I_M4_DEPS) m4/ifunction-s2.m4 -I_M4_DEPS7 = $(I_M4_DEPS) m4/ifindloc0.m4 -I_M4_DEPS8 = $(I_M4_DEPS) m4/ifindloc1.m4 -I_M4_DEPS9 = $(I_M4_DEPS) m4/ifindloc2.m4 -EXTRA_DIST = $(m4_files) +EXTRA_DIST = m4 MULTISRCTOP = MULTIBUILDTOP = MULTIDIRS = @@ -2752,42 +2578,6 @@ generated/parity_l8.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) generated/parity_l16.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_i1.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_i2.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_i4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_i8.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_i16.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_r4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_r8.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_r10.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_r16.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_r17.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_c4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_c8.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_c10.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_c16.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_c17.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_l4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_l8.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmul_l16.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) generated/shape_i1.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) generated/shape_i2.lo: generated/$(am__dirstamp) \ @@ -3034,36 +2824,6 @@ generated/unpack_c16.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) generated/unpack_c17.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_i1.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_i2.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_i4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_i8.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_i16.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_r4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_r8.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_r10.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_r16.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_r17.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_c4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_c8.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_c10.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_c16.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/matmulavx128_c17.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) generated/spread_i1.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) generated/spread_i2.lo: generated/$(am__dirstamp) \ @@ -3168,139 +2928,51 @@ generated/cshift1_8_r4.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) generated/cshift1_8_r8.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_8_r10.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_8_r16.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_8_r17.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_8_c4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_8_c8.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_8_c10.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_8_c16.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_8_c17.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_i1.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_i2.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_i4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_i8.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_i16.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_r4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_r8.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_r10.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_r16.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_r17.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_c4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_c8.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_c10.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_c16.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/cshift1_16_c17.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc0_4_s1.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc0_4_s4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc0_8_s1.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc0_8_s4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc0_16_s1.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc0_16_s4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc0_4_s1.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc0_4_s4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc0_8_s1.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc0_8_s4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc0_16_s1.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc0_16_s4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc1_4_s1.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc1_4_s4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc1_8_s1.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc1_8_s4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc1_16_s1.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc1_16_s4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc1_4_s1.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc1_4_s4.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc1_8_s1.lo: generated/$(am__dirstamp) \ - generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc1_8_s4.lo: generated/$(am__dirstamp) \ +generated/cshift1_8_r10.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc1_16_s1.lo: generated/$(am__dirstamp) \ +generated/cshift1_8_r16.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc1_16_s4.lo: generated/$(am__dirstamp) \ +generated/cshift1_8_r17.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc2_4_s1.lo: generated/$(am__dirstamp) \ +generated/cshift1_8_c4.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc2_4_s4.lo: generated/$(am__dirstamp) \ +generated/cshift1_8_c8.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc2_8_s1.lo: generated/$(am__dirstamp) \ +generated/cshift1_8_c10.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc2_8_s4.lo: generated/$(am__dirstamp) \ +generated/cshift1_8_c16.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc2_16_s1.lo: generated/$(am__dirstamp) \ +generated/cshift1_8_c17.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/maxloc2_16_s4.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_i1.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc2_4_s1.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_i2.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc2_4_s4.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_i4.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc2_8_s1.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_i8.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc2_8_s4.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_i16.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc2_16_s1.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_r4.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/minloc2_16_s4.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_r8.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/maxval0_s1.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_r10.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/maxval0_s4.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_r16.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/minval0_s1.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_r17.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/minval0_s4.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_c4.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/maxval1_s1.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_c8.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/maxval1_s4.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_c10.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/minval1_s1.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_c16.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -generated/minval1_s4.lo: generated/$(am__dirstamp) \ +generated/cshift1_16_c17.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) generated/findloc0_i1.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) @@ -3374,8 +3046,94 @@ generated/findloc2_s1.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) generated/findloc2_s4.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) -runtime/ISO_Fortran_binding.lo: runtime/$(am__dirstamp) \ - runtime/$(DEPDIR)/$(am__dirstamp) +generated/maxloc0_4_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc0_4_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc0_8_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc0_8_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc0_16_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc0_16_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc1_4_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc1_4_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc1_8_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc1_8_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc1_16_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc1_16_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc2_4_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc2_4_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc2_8_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc2_8_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc2_16_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxloc2_16_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxval0_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxval0_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxval1_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/maxval1_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc0_4_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc0_4_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc0_8_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc0_8_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc0_16_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc0_16_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc1_4_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc1_4_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc1_8_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc1_8_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc1_16_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc1_16_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc2_4_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc2_4_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc2_8_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc2_8_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc2_16_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minloc2_16_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minval0_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minval0_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minval1_s1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/minval1_s4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) generated/pow_m1_m1.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) generated/pow_m1_m2.lo: generated/$(am__dirstamp) \ @@ -3426,6 +3184,74 @@ generated/pow_m16_m8.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) generated/pow_m16_m16.lo: generated/$(am__dirstamp) \ generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_i1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_i2.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_i4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_i8.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_i16.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_r4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_r8.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_r10.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_r16.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_r17.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_c4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_c8.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_c10.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_c16.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_c17.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_l4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_l8.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmul_l16.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_i1.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_i2.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_i4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_i8.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_i16.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_r4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_r8.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_r10.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_r16.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_r17.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_c4.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_c8.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_c10.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_c16.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +generated/matmulavx128_c17.lo: generated/$(am__dirstamp) \ + generated/$(DEPDIR)/$(am__dirstamp) +runtime/ISO_Fortran_binding.lo: runtime/$(am__dirstamp) \ + runtime/$(DEPDIR)/$(am__dirstamp) io/$(am__dirstamp): @$(MKDIR_P) io @: > io/$(am__dirstamp) @@ -5094,162 +4920,6 @@ include/ISO_Fortran_binding.h: $(srcdir)/ISO_Fortran_binding.h $(MKDIR_P) include cp $(srcdir)/ISO_Fortran_binding.h $@ -@MAINTAINER_MODE_TRUE@$(i_all_c): m4/all.m4 $(I_M4_DEPS2) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 all.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_bessel_c): m4/bessel.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 bessel.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_any_c): m4/any.m4 $(I_M4_DEPS2) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 any.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_count_c): m4/count.m4 $(I_M4_DEPS2) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 count.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_findloc0_c): m4/findloc0.m4 $(I_M4_DEPS7) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 findloc0.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_findloc0s_c): m4/findloc0s.m4 $(I_M4_DEPS7) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 findloc0s.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_findloc1_c): m4/findloc1.m4 $(I_M4_DEPS8) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 findloc1.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_findloc1s_c): m4/findloc1s.m4 $(I_M4_DEPS8) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 findloc1s.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_findloc2s_c): m4/findloc2s.m4 $(I_M4_DEPS9) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 findloc2s.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_iall_c): m4/iall.m4 $(I_M4_DEPS1) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 iall.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_iany_c): m4/iany.m4 $(I_M4_DEPS1) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 iany.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_iparity_c): m4/iparity.m4 $(I_M4_DEPS1) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 iparity.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_maxloc0_c): m4/maxloc0.m4 $(I_M4_DEPS0) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 maxloc0.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_maxloc0s_c) : m4/maxloc0s.m4 $(I_M4_DEPS3) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 maxloc0s.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_maxloc1_c): m4/maxloc1.m4 $(I_M4_DEPS1) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 maxloc1.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_maxloc1s_c): m4/maxloc1s.m4 $(I_M4_DEPS4) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 maxloc1s.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_maxloc2s_c): m4/maxloc2s.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 maxloc2s.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_maxval_c): m4/maxval.m4 $(I_M4_DEPS1) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 maxval.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_maxval0s_c): m4/maxval0s.m4 $(I_M4_DEPS5) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 maxval0s.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_maxval1s_c): m4/maxval1s.m4 $(I_M4_DEPS6) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 maxval1s.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_minloc0_c): m4/minloc0.m4 $(I_M4_DEPS0) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 minloc0.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_minloc0s_c) : m4/minloc0s.m4 $(I_M4_DEPS3) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 minloc0s.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_minloc1_c): m4/minloc1.m4 $(I_M4_DEPS1) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 minloc1.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_minloc1s_c): m4/minloc1s.m4 $(I_M4_DEPS4) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 minloc1s.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_minloc2s_c): m4/minloc2s.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 minloc2s.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_minval_c): m4/minval.m4 $(I_M4_DEPS1) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 minval.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_minval0s_c): m4/minval0s.m4 $(I_M4_DEPS5) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 minval0s.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_minval1s_c): m4/minval1s.m4 $(I_M4_DEPS6) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 minval1s.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_product_c): m4/product.m4 $(I_M4_DEPS1) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 product.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_sum_c): m4/sum.m4 $(I_M4_DEPS1) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 sum.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_matmul_c): m4/matmul.m4 m4/matmul_internal.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 matmul.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_matmulavx128_c): m4/matmulavx128.m4 m4/matmul_internal.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 matmulavx128.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_matmull_c): m4/matmull.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 matmull.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_norm2_c): m4/norm2.m4 $(I_M4_DEPS1) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 norm2.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_parity_c): m4/parity.m4 $(I_M4_DEPS1) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 parity.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_shape_c): m4/shape.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 shape.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_reshape_c): m4/reshape.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 reshape.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_eoshift1_c): m4/eoshift1.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 eoshift1.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_eoshift3_c): m4/eoshift3.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 eoshift3.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_cshift0_c): m4/cshift0.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 cshift0.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_cshift1_c): m4/cshift1.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 cshift1.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_cshift1a_c): m4/cshift1a.m4 $(I_M$_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 cshift1a.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(in_pack_c): m4/in_pack.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 in_pack.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(in_unpack_c): m4/in_unpack.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 in_unpack.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_pow_c): m4/pow.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 pow.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_powu_c): m4/powu.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 powu.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_pack_c): m4/pack.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 pack.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_unpack_c): m4/unpack.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 unpack.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(i_spread_c): m4/spread.m4 $(I_M4_DEPS) -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 spread.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(gfor_built_specific_src): m4/specific.m4 m4/head.m4 -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 specific.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(gfor_built_specific2_src): m4/specific2.m4 m4/head.m4 -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 specific2.m4 > $@ - -@MAINTAINER_MODE_TRUE@$(gfor_misc_specifics): m4/misc_specifics.m4 m4/head.m4 -@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 misc_specifics.m4 > $@ - clean-local: -rm -rf include $(version_dep) diff --git a/libgfortran/generated/iall_i1.c b/libgfortran/generated/iall_i1.c index d82d8ba6fc52..2e322c1f1953 100644 --- a/libgfortran/generated/iall_i1.c +++ b/libgfortran/generated/iall_i1.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_1) && defined (HAVE_GFC_INTEGER_1) -extern void iall_i1 (gfc_array_i1 * const restrict, +extern void iall_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict); export_proto(iall_i1); void -iall_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, +iall_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iall_i1 (gfc_array_i1 * const restrict retarray, } -extern void miall_i1 (gfc_array_i1 * const restrict, +extern void miall_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miall_i1); void -miall_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +miall_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miall_i1 (gfc_array_i1 * const restrict retarray, } -extern void siall_i1 (gfc_array_i1 * const restrict, +extern void siall_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siall_i1); void -siall_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +siall_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/iall_i16.c b/libgfortran/generated/iall_i16.c index ee134521c07e..c70b6982315d 100644 --- a/libgfortran/generated/iall_i16.c +++ b/libgfortran/generated/iall_i16.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_16) && defined (HAVE_GFC_INTEGER_16) -extern void iall_i16 (gfc_array_i16 * const restrict, +extern void iall_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict); export_proto(iall_i16); void -iall_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, +iall_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iall_i16 (gfc_array_i16 * const restrict retarray, } -extern void miall_i16 (gfc_array_i16 * const restrict, +extern void miall_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miall_i16); void -miall_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +miall_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miall_i16 (gfc_array_i16 * const restrict retarray, } -extern void siall_i16 (gfc_array_i16 * const restrict, +extern void siall_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siall_i16); void -siall_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +siall_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/iall_i2.c b/libgfortran/generated/iall_i2.c index a57aabdeb281..bede3c37c526 100644 --- a/libgfortran/generated/iall_i2.c +++ b/libgfortran/generated/iall_i2.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_2) && defined (HAVE_GFC_INTEGER_2) -extern void iall_i2 (gfc_array_i2 * const restrict, +extern void iall_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict); export_proto(iall_i2); void -iall_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, +iall_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iall_i2 (gfc_array_i2 * const restrict retarray, } -extern void miall_i2 (gfc_array_i2 * const restrict, +extern void miall_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miall_i2); void -miall_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +miall_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miall_i2 (gfc_array_i2 * const restrict retarray, } -extern void siall_i2 (gfc_array_i2 * const restrict, +extern void siall_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siall_i2); void -siall_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +siall_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/iall_i4.c b/libgfortran/generated/iall_i4.c index 039256d0a942..3e4370be7e35 100644 --- a/libgfortran/generated/iall_i4.c +++ b/libgfortran/generated/iall_i4.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_4) && defined (HAVE_GFC_INTEGER_4) -extern void iall_i4 (gfc_array_i4 * const restrict, +extern void iall_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict); export_proto(iall_i4); void -iall_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, +iall_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iall_i4 (gfc_array_i4 * const restrict retarray, } -extern void miall_i4 (gfc_array_i4 * const restrict, +extern void miall_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miall_i4); void -miall_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +miall_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miall_i4 (gfc_array_i4 * const restrict retarray, } -extern void siall_i4 (gfc_array_i4 * const restrict, +extern void siall_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siall_i4); void -siall_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +siall_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/iall_i8.c b/libgfortran/generated/iall_i8.c index 9f41e6073600..1651a470748a 100644 --- a/libgfortran/generated/iall_i8.c +++ b/libgfortran/generated/iall_i8.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_8) && defined (HAVE_GFC_INTEGER_8) -extern void iall_i8 (gfc_array_i8 * const restrict, +extern void iall_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict); export_proto(iall_i8); void -iall_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, +iall_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iall_i8 (gfc_array_i8 * const restrict retarray, } -extern void miall_i8 (gfc_array_i8 * const restrict, +extern void miall_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miall_i8); void -miall_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +miall_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miall_i8 (gfc_array_i8 * const restrict retarray, } -extern void siall_i8 (gfc_array_i8 * const restrict, +extern void siall_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siall_i8); void -siall_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +siall_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/iany_i1.c b/libgfortran/generated/iany_i1.c index ebe21e44b015..a9b24f208c2b 100644 --- a/libgfortran/generated/iany_i1.c +++ b/libgfortran/generated/iany_i1.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_1) && defined (HAVE_GFC_INTEGER_1) -extern void iany_i1 (gfc_array_i1 * const restrict, +extern void iany_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict); export_proto(iany_i1); void -iany_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, +iany_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iany_i1 (gfc_array_i1 * const restrict retarray, } -extern void miany_i1 (gfc_array_i1 * const restrict, +extern void miany_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miany_i1); void -miany_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +miany_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miany_i1 (gfc_array_i1 * const restrict retarray, } -extern void siany_i1 (gfc_array_i1 * const restrict, +extern void siany_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siany_i1); void -siany_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +siany_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/iany_i16.c b/libgfortran/generated/iany_i16.c index 8cbb439dd51f..34d0954bdf94 100644 --- a/libgfortran/generated/iany_i16.c +++ b/libgfortran/generated/iany_i16.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_16) && defined (HAVE_GFC_INTEGER_16) -extern void iany_i16 (gfc_array_i16 * const restrict, +extern void iany_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict); export_proto(iany_i16); void -iany_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, +iany_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iany_i16 (gfc_array_i16 * const restrict retarray, } -extern void miany_i16 (gfc_array_i16 * const restrict, +extern void miany_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miany_i16); void -miany_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +miany_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miany_i16 (gfc_array_i16 * const restrict retarray, } -extern void siany_i16 (gfc_array_i16 * const restrict, +extern void siany_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siany_i16); void -siany_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +siany_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/iany_i2.c b/libgfortran/generated/iany_i2.c index 01f6f6c2c720..554a0245603f 100644 --- a/libgfortran/generated/iany_i2.c +++ b/libgfortran/generated/iany_i2.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_2) && defined (HAVE_GFC_INTEGER_2) -extern void iany_i2 (gfc_array_i2 * const restrict, +extern void iany_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict); export_proto(iany_i2); void -iany_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, +iany_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iany_i2 (gfc_array_i2 * const restrict retarray, } -extern void miany_i2 (gfc_array_i2 * const restrict, +extern void miany_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miany_i2); void -miany_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +miany_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miany_i2 (gfc_array_i2 * const restrict retarray, } -extern void siany_i2 (gfc_array_i2 * const restrict, +extern void siany_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siany_i2); void -siany_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +siany_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/iany_i4.c b/libgfortran/generated/iany_i4.c index 7bc70d1d5eb3..d4c824f6d145 100644 --- a/libgfortran/generated/iany_i4.c +++ b/libgfortran/generated/iany_i4.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_4) && defined (HAVE_GFC_INTEGER_4) -extern void iany_i4 (gfc_array_i4 * const restrict, +extern void iany_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict); export_proto(iany_i4); void -iany_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, +iany_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iany_i4 (gfc_array_i4 * const restrict retarray, } -extern void miany_i4 (gfc_array_i4 * const restrict, +extern void miany_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miany_i4); void -miany_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +miany_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miany_i4 (gfc_array_i4 * const restrict retarray, } -extern void siany_i4 (gfc_array_i4 * const restrict, +extern void siany_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siany_i4); void -siany_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +siany_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/iany_i8.c b/libgfortran/generated/iany_i8.c index 4165061e689b..cebeec24656d 100644 --- a/libgfortran/generated/iany_i8.c +++ b/libgfortran/generated/iany_i8.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_8) && defined (HAVE_GFC_INTEGER_8) -extern void iany_i8 (gfc_array_i8 * const restrict, +extern void iany_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict); export_proto(iany_i8); void -iany_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, +iany_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iany_i8 (gfc_array_i8 * const restrict retarray, } -extern void miany_i8 (gfc_array_i8 * const restrict, +extern void miany_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miany_i8); void -miany_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +miany_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miany_i8 (gfc_array_i8 * const restrict retarray, } -extern void siany_i8 (gfc_array_i8 * const restrict, +extern void siany_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siany_i8); void -siany_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +siany_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/iparity_i1.c b/libgfortran/generated/iparity_i1.c index f3ec3287fafe..b7cdb3e995f6 100644 --- a/libgfortran/generated/iparity_i1.c +++ b/libgfortran/generated/iparity_i1.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_1) && defined (HAVE_GFC_INTEGER_1) -extern void iparity_i1 (gfc_array_i1 * const restrict, +extern void iparity_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict); export_proto(iparity_i1); void -iparity_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, +iparity_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iparity_i1 (gfc_array_i1 * const restrict retarray, } -extern void miparity_i1 (gfc_array_i1 * const restrict, +extern void miparity_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miparity_i1); void -miparity_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +miparity_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miparity_i1 (gfc_array_i1 * const restrict retarray, } -extern void siparity_i1 (gfc_array_i1 * const restrict, +extern void siparity_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siparity_i1); void -siparity_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +siparity_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/iparity_i16.c b/libgfortran/generated/iparity_i16.c index 1111bbc5c6df..f6272638f2ef 100644 --- a/libgfortran/generated/iparity_i16.c +++ b/libgfortran/generated/iparity_i16.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_16) && defined (HAVE_GFC_INTEGER_16) -extern void iparity_i16 (gfc_array_i16 * const restrict, +extern void iparity_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict); export_proto(iparity_i16); void -iparity_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, +iparity_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iparity_i16 (gfc_array_i16 * const restrict retarray, } -extern void miparity_i16 (gfc_array_i16 * const restrict, +extern void miparity_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miparity_i16); void -miparity_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +miparity_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miparity_i16 (gfc_array_i16 * const restrict retarray, } -extern void siparity_i16 (gfc_array_i16 * const restrict, +extern void siparity_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siparity_i16); void -siparity_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +siparity_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/iparity_i2.c b/libgfortran/generated/iparity_i2.c index ef0a9e7d948b..4481a04c2f88 100644 --- a/libgfortran/generated/iparity_i2.c +++ b/libgfortran/generated/iparity_i2.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_2) && defined (HAVE_GFC_INTEGER_2) -extern void iparity_i2 (gfc_array_i2 * const restrict, +extern void iparity_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict); export_proto(iparity_i2); void -iparity_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, +iparity_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iparity_i2 (gfc_array_i2 * const restrict retarray, } -extern void miparity_i2 (gfc_array_i2 * const restrict, +extern void miparity_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miparity_i2); void -miparity_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +miparity_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miparity_i2 (gfc_array_i2 * const restrict retarray, } -extern void siparity_i2 (gfc_array_i2 * const restrict, +extern void siparity_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siparity_i2); void -siparity_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +siparity_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/iparity_i4.c b/libgfortran/generated/iparity_i4.c index 189d820c2de8..e0c65dd207b0 100644 --- a/libgfortran/generated/iparity_i4.c +++ b/libgfortran/generated/iparity_i4.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_4) && defined (HAVE_GFC_INTEGER_4) -extern void iparity_i4 (gfc_array_i4 * const restrict, +extern void iparity_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict); export_proto(iparity_i4); void -iparity_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, +iparity_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iparity_i4 (gfc_array_i4 * const restrict retarray, } -extern void miparity_i4 (gfc_array_i4 * const restrict, +extern void miparity_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miparity_i4); void -miparity_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +miparity_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miparity_i4 (gfc_array_i4 * const restrict retarray, } -extern void siparity_i4 (gfc_array_i4 * const restrict, +extern void siparity_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siparity_i4); void -siparity_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +siparity_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/iparity_i8.c b/libgfortran/generated/iparity_i8.c index 1d2f33bdfe2e..f2feec9fae8a 100644 --- a/libgfortran/generated/iparity_i8.c +++ b/libgfortran/generated/iparity_i8.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_8) && defined (HAVE_GFC_INTEGER_8) -extern void iparity_i8 (gfc_array_i8 * const restrict, +extern void iparity_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict); export_proto(iparity_i8); void -iparity_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, +iparity_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -188,15 +188,15 @@ iparity_i8 (gfc_array_i8 * const restrict retarray, } -extern void miparity_i8 (gfc_array_i8 * const restrict, +extern void miparity_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(miparity_i8); void -miparity_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +miparity_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -378,15 +378,15 @@ miparity_i8 (gfc_array_i8 * const restrict retarray, } -extern void siparity_i8 (gfc_array_i8 * const restrict, +extern void siparity_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(siparity_i8); void -siparity_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +siparity_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/matmulavx128_c10.c b/libgfortran/generated/matmulavx128_c10.c index 7094a5f80e94..6e084809027d 100644 --- a/libgfortran/generated/matmulavx128_c10.c +++ b/libgfortran/generated/matmulavx128_c10.c @@ -49,7 +49,7 @@ matmul_c10_avx128_fma3 (gfc_array_c10 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_c10_avx128_fma3); void -matmul_c10_avx128_fma3 (gfc_array_c10 * const restrict retarray, +matmul_c10_avx128_fma3 (gfc_array_c10 * const restrict retarray, gfc_array_c10 * const restrict a, gfc_array_c10 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_c10_avx128_fma4 (gfc_array_c10 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_c10_avx128_fma4); void -matmul_c10_avx128_fma4 (gfc_array_c10 * const restrict retarray, +matmul_c10_avx128_fma4 (gfc_array_c10 * const restrict retarray, gfc_array_c10 * const restrict a, gfc_array_c10 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/matmulavx128_c16.c b/libgfortran/generated/matmulavx128_c16.c index 4a1a3408be95..57d24ec0b586 100644 --- a/libgfortran/generated/matmulavx128_c16.c +++ b/libgfortran/generated/matmulavx128_c16.c @@ -49,7 +49,7 @@ matmul_c16_avx128_fma3 (gfc_array_c16 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_c16_avx128_fma3); void -matmul_c16_avx128_fma3 (gfc_array_c16 * const restrict retarray, +matmul_c16_avx128_fma3 (gfc_array_c16 * const restrict retarray, gfc_array_c16 * const restrict a, gfc_array_c16 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_c16_avx128_fma4 (gfc_array_c16 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_c16_avx128_fma4); void -matmul_c16_avx128_fma4 (gfc_array_c16 * const restrict retarray, +matmul_c16_avx128_fma4 (gfc_array_c16 * const restrict retarray, gfc_array_c16 * const restrict a, gfc_array_c16 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/matmulavx128_c17.c b/libgfortran/generated/matmulavx128_c17.c index 52b3c0df62f1..7d54c0dc655f 100644 --- a/libgfortran/generated/matmulavx128_c17.c +++ b/libgfortran/generated/matmulavx128_c17.c @@ -49,7 +49,7 @@ matmul_c17_avx128_fma3 (gfc_array_c17 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_c17_avx128_fma3); void -matmul_c17_avx128_fma3 (gfc_array_c17 * const restrict retarray, +matmul_c17_avx128_fma3 (gfc_array_c17 * const restrict retarray, gfc_array_c17 * const restrict a, gfc_array_c17 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_c17_avx128_fma4 (gfc_array_c17 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_c17_avx128_fma4); void -matmul_c17_avx128_fma4 (gfc_array_c17 * const restrict retarray, +matmul_c17_avx128_fma4 (gfc_array_c17 * const restrict retarray, gfc_array_c17 * const restrict a, gfc_array_c17 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/matmulavx128_c4.c b/libgfortran/generated/matmulavx128_c4.c index f0014cc89e26..a7708c5a1f74 100644 --- a/libgfortran/generated/matmulavx128_c4.c +++ b/libgfortran/generated/matmulavx128_c4.c @@ -49,7 +49,7 @@ matmul_c4_avx128_fma3 (gfc_array_c4 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_c4_avx128_fma3); void -matmul_c4_avx128_fma3 (gfc_array_c4 * const restrict retarray, +matmul_c4_avx128_fma3 (gfc_array_c4 * const restrict retarray, gfc_array_c4 * const restrict a, gfc_array_c4 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_c4_avx128_fma4 (gfc_array_c4 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_c4_avx128_fma4); void -matmul_c4_avx128_fma4 (gfc_array_c4 * const restrict retarray, +matmul_c4_avx128_fma4 (gfc_array_c4 * const restrict retarray, gfc_array_c4 * const restrict a, gfc_array_c4 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/matmulavx128_c8.c b/libgfortran/generated/matmulavx128_c8.c index 94764a9c38b7..b0d325fba595 100644 --- a/libgfortran/generated/matmulavx128_c8.c +++ b/libgfortran/generated/matmulavx128_c8.c @@ -49,7 +49,7 @@ matmul_c8_avx128_fma3 (gfc_array_c8 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_c8_avx128_fma3); void -matmul_c8_avx128_fma3 (gfc_array_c8 * const restrict retarray, +matmul_c8_avx128_fma3 (gfc_array_c8 * const restrict retarray, gfc_array_c8 * const restrict a, gfc_array_c8 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_c8_avx128_fma4 (gfc_array_c8 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_c8_avx128_fma4); void -matmul_c8_avx128_fma4 (gfc_array_c8 * const restrict retarray, +matmul_c8_avx128_fma4 (gfc_array_c8 * const restrict retarray, gfc_array_c8 * const restrict a, gfc_array_c8 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/matmulavx128_i1.c b/libgfortran/generated/matmulavx128_i1.c index 3ab8eda71b3f..f5e5befad90b 100644 --- a/libgfortran/generated/matmulavx128_i1.c +++ b/libgfortran/generated/matmulavx128_i1.c @@ -49,7 +49,7 @@ matmul_i1_avx128_fma3 (gfc_array_i1 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_i1_avx128_fma3); void -matmul_i1_avx128_fma3 (gfc_array_i1 * const restrict retarray, +matmul_i1_avx128_fma3 (gfc_array_i1 * const restrict retarray, gfc_array_i1 * const restrict a, gfc_array_i1 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_i1_avx128_fma4 (gfc_array_i1 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_i1_avx128_fma4); void -matmul_i1_avx128_fma4 (gfc_array_i1 * const restrict retarray, +matmul_i1_avx128_fma4 (gfc_array_i1 * const restrict retarray, gfc_array_i1 * const restrict a, gfc_array_i1 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/matmulavx128_i16.c b/libgfortran/generated/matmulavx128_i16.c index c8ef87e019c2..f686f7ad44cc 100644 --- a/libgfortran/generated/matmulavx128_i16.c +++ b/libgfortran/generated/matmulavx128_i16.c @@ -49,7 +49,7 @@ matmul_i16_avx128_fma3 (gfc_array_i16 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_i16_avx128_fma3); void -matmul_i16_avx128_fma3 (gfc_array_i16 * const restrict retarray, +matmul_i16_avx128_fma3 (gfc_array_i16 * const restrict retarray, gfc_array_i16 * const restrict a, gfc_array_i16 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_i16_avx128_fma4 (gfc_array_i16 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_i16_avx128_fma4); void -matmul_i16_avx128_fma4 (gfc_array_i16 * const restrict retarray, +matmul_i16_avx128_fma4 (gfc_array_i16 * const restrict retarray, gfc_array_i16 * const restrict a, gfc_array_i16 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/matmulavx128_i2.c b/libgfortran/generated/matmulavx128_i2.c index 88f345272498..f6a162d1e416 100644 --- a/libgfortran/generated/matmulavx128_i2.c +++ b/libgfortran/generated/matmulavx128_i2.c @@ -49,7 +49,7 @@ matmul_i2_avx128_fma3 (gfc_array_i2 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_i2_avx128_fma3); void -matmul_i2_avx128_fma3 (gfc_array_i2 * const restrict retarray, +matmul_i2_avx128_fma3 (gfc_array_i2 * const restrict retarray, gfc_array_i2 * const restrict a, gfc_array_i2 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_i2_avx128_fma4 (gfc_array_i2 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_i2_avx128_fma4); void -matmul_i2_avx128_fma4 (gfc_array_i2 * const restrict retarray, +matmul_i2_avx128_fma4 (gfc_array_i2 * const restrict retarray, gfc_array_i2 * const restrict a, gfc_array_i2 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/matmulavx128_i4.c b/libgfortran/generated/matmulavx128_i4.c index 272692e5351f..0a28e4ba0593 100644 --- a/libgfortran/generated/matmulavx128_i4.c +++ b/libgfortran/generated/matmulavx128_i4.c @@ -49,7 +49,7 @@ matmul_i4_avx128_fma3 (gfc_array_i4 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_i4_avx128_fma3); void -matmul_i4_avx128_fma3 (gfc_array_i4 * const restrict retarray, +matmul_i4_avx128_fma3 (gfc_array_i4 * const restrict retarray, gfc_array_i4 * const restrict a, gfc_array_i4 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_i4_avx128_fma4 (gfc_array_i4 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_i4_avx128_fma4); void -matmul_i4_avx128_fma4 (gfc_array_i4 * const restrict retarray, +matmul_i4_avx128_fma4 (gfc_array_i4 * const restrict retarray, gfc_array_i4 * const restrict a, gfc_array_i4 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/matmulavx128_i8.c b/libgfortran/generated/matmulavx128_i8.c index a1db25b30690..a077a26a701d 100644 --- a/libgfortran/generated/matmulavx128_i8.c +++ b/libgfortran/generated/matmulavx128_i8.c @@ -49,7 +49,7 @@ matmul_i8_avx128_fma3 (gfc_array_i8 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_i8_avx128_fma3); void -matmul_i8_avx128_fma3 (gfc_array_i8 * const restrict retarray, +matmul_i8_avx128_fma3 (gfc_array_i8 * const restrict retarray, gfc_array_i8 * const restrict a, gfc_array_i8 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_i8_avx128_fma4 (gfc_array_i8 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_i8_avx128_fma4); void -matmul_i8_avx128_fma4 (gfc_array_i8 * const restrict retarray, +matmul_i8_avx128_fma4 (gfc_array_i8 * const restrict retarray, gfc_array_i8 * const restrict a, gfc_array_i8 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/matmulavx128_r10.c b/libgfortran/generated/matmulavx128_r10.c index 8d164d0049c6..31c62bab4b71 100644 --- a/libgfortran/generated/matmulavx128_r10.c +++ b/libgfortran/generated/matmulavx128_r10.c @@ -49,7 +49,7 @@ matmul_r10_avx128_fma3 (gfc_array_r10 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_r10_avx128_fma3); void -matmul_r10_avx128_fma3 (gfc_array_r10 * const restrict retarray, +matmul_r10_avx128_fma3 (gfc_array_r10 * const restrict retarray, gfc_array_r10 * const restrict a, gfc_array_r10 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_r10_avx128_fma4 (gfc_array_r10 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_r10_avx128_fma4); void -matmul_r10_avx128_fma4 (gfc_array_r10 * const restrict retarray, +matmul_r10_avx128_fma4 (gfc_array_r10 * const restrict retarray, gfc_array_r10 * const restrict a, gfc_array_r10 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/matmulavx128_r16.c b/libgfortran/generated/matmulavx128_r16.c index ee536b53390d..1ed5516d1ed7 100644 --- a/libgfortran/generated/matmulavx128_r16.c +++ b/libgfortran/generated/matmulavx128_r16.c @@ -49,7 +49,7 @@ matmul_r16_avx128_fma3 (gfc_array_r16 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_r16_avx128_fma3); void -matmul_r16_avx128_fma3 (gfc_array_r16 * const restrict retarray, +matmul_r16_avx128_fma3 (gfc_array_r16 * const restrict retarray, gfc_array_r16 * const restrict a, gfc_array_r16 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_r16_avx128_fma4 (gfc_array_r16 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_r16_avx128_fma4); void -matmul_r16_avx128_fma4 (gfc_array_r16 * const restrict retarray, +matmul_r16_avx128_fma4 (gfc_array_r16 * const restrict retarray, gfc_array_r16 * const restrict a, gfc_array_r16 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/matmulavx128_r17.c b/libgfortran/generated/matmulavx128_r17.c index b45f3b36be9f..f1e58521204c 100644 --- a/libgfortran/generated/matmulavx128_r17.c +++ b/libgfortran/generated/matmulavx128_r17.c @@ -49,7 +49,7 @@ matmul_r17_avx128_fma3 (gfc_array_r17 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_r17_avx128_fma3); void -matmul_r17_avx128_fma3 (gfc_array_r17 * const restrict retarray, +matmul_r17_avx128_fma3 (gfc_array_r17 * const restrict retarray, gfc_array_r17 * const restrict a, gfc_array_r17 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_r17_avx128_fma4 (gfc_array_r17 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_r17_avx128_fma4); void -matmul_r17_avx128_fma4 (gfc_array_r17 * const restrict retarray, +matmul_r17_avx128_fma4 (gfc_array_r17 * const restrict retarray, gfc_array_r17 * const restrict a, gfc_array_r17 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/matmulavx128_r4.c b/libgfortran/generated/matmulavx128_r4.c index 104b1df35eb7..5372623c65d3 100644 --- a/libgfortran/generated/matmulavx128_r4.c +++ b/libgfortran/generated/matmulavx128_r4.c @@ -49,7 +49,7 @@ matmul_r4_avx128_fma3 (gfc_array_r4 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_r4_avx128_fma3); void -matmul_r4_avx128_fma3 (gfc_array_r4 * const restrict retarray, +matmul_r4_avx128_fma3 (gfc_array_r4 * const restrict retarray, gfc_array_r4 * const restrict a, gfc_array_r4 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_r4_avx128_fma4 (gfc_array_r4 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_r4_avx128_fma4); void -matmul_r4_avx128_fma4 (gfc_array_r4 * const restrict retarray, +matmul_r4_avx128_fma4 (gfc_array_r4 * const restrict retarray, gfc_array_r4 * const restrict a, gfc_array_r4 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/matmulavx128_r8.c b/libgfortran/generated/matmulavx128_r8.c index f76301dec032..ee7bc4a28ab8 100644 --- a/libgfortran/generated/matmulavx128_r8.c +++ b/libgfortran/generated/matmulavx128_r8.c @@ -49,7 +49,7 @@ matmul_r8_avx128_fma3 (gfc_array_r8 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma"))); internal_proto(matmul_r8_avx128_fma3); void -matmul_r8_avx128_fma3 (gfc_array_r8 * const restrict retarray, +matmul_r8_avx128_fma3 (gfc_array_r8 * const restrict retarray, gfc_array_r8 * const restrict a, gfc_array_r8 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { @@ -619,7 +619,7 @@ matmul_r8_avx128_fma4 (gfc_array_r8 * const restrict retarray, int blas_limit, blas_call gemm) __attribute__((__target__("avx,fma4"))); internal_proto(matmul_r8_avx128_fma4); void -matmul_r8_avx128_fma4 (gfc_array_r8 * const restrict retarray, +matmul_r8_avx128_fma4 (gfc_array_r8 * const restrict retarray, gfc_array_r8 * const restrict a, gfc_array_r8 * const restrict b, int try_blas, int blas_limit, blas_call gemm) { diff --git a/libgfortran/generated/maxloc1_16_i1.c b/libgfortran/generated/maxloc1_16_i1.c index 853fe3fcf43e..31e17c443e8e 100644 --- a/libgfortran/generated/maxloc1_16_i1.c +++ b/libgfortran/generated/maxloc1_16_i1.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_16_i1 (gfc_array_i16 * const restrict, +extern void maxloc1_16_i1 (gfc_array_i16 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_16_i1); void -maxloc1_16_i1 (gfc_array_i16 * const restrict retarray, - gfc_array_i1 * const restrict array, +maxloc1_16_i1 (gfc_array_i16 * const restrict retarray, + gfc_array_i1 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_16_i1 (gfc_array_i16 * const restrict retarray, } -extern void mmaxloc1_16_i1 (gfc_array_i16 * const restrict, +extern void mmaxloc1_16_i1 (gfc_array_i16 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_16_i1); void -mmaxloc1_16_i1 (gfc_array_i16 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_16_i1 (gfc_array_i16 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_16_i1 (gfc_array_i16 * const restrict retarray, } -extern void smaxloc1_16_i1 (gfc_array_i16 * const restrict, +extern void smaxloc1_16_i1 (gfc_array_i16 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_16_i1); void -smaxloc1_16_i1 (gfc_array_i16 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_16_i1 (gfc_array_i16 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_16_i16.c b/libgfortran/generated/maxloc1_16_i16.c index 96f76ac08f66..227ab99fecdf 100644 --- a/libgfortran/generated/maxloc1_16_i16.c +++ b/libgfortran/generated/maxloc1_16_i16.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_16_i16 (gfc_array_i16 * const restrict, +extern void maxloc1_16_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_16_i16); void -maxloc1_16_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, +maxloc1_16_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_16_i16 (gfc_array_i16 * const restrict retarray, } -extern void mmaxloc1_16_i16 (gfc_array_i16 * const restrict, +extern void mmaxloc1_16_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_16_i16); void -mmaxloc1_16_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_16_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_16_i16 (gfc_array_i16 * const restrict retarray, } -extern void smaxloc1_16_i16 (gfc_array_i16 * const restrict, +extern void smaxloc1_16_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_16_i16); void -smaxloc1_16_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_16_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_16_i2.c b/libgfortran/generated/maxloc1_16_i2.c index a2861511b1ec..40fbf8bf153f 100644 --- a/libgfortran/generated/maxloc1_16_i2.c +++ b/libgfortran/generated/maxloc1_16_i2.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_16_i2 (gfc_array_i16 * const restrict, +extern void maxloc1_16_i2 (gfc_array_i16 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_16_i2); void -maxloc1_16_i2 (gfc_array_i16 * const restrict retarray, - gfc_array_i2 * const restrict array, +maxloc1_16_i2 (gfc_array_i16 * const restrict retarray, + gfc_array_i2 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_16_i2 (gfc_array_i16 * const restrict retarray, } -extern void mmaxloc1_16_i2 (gfc_array_i16 * const restrict, +extern void mmaxloc1_16_i2 (gfc_array_i16 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_16_i2); void -mmaxloc1_16_i2 (gfc_array_i16 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_16_i2 (gfc_array_i16 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_16_i2 (gfc_array_i16 * const restrict retarray, } -extern void smaxloc1_16_i2 (gfc_array_i16 * const restrict, +extern void smaxloc1_16_i2 (gfc_array_i16 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_16_i2); void -smaxloc1_16_i2 (gfc_array_i16 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_16_i2 (gfc_array_i16 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_16_i4.c b/libgfortran/generated/maxloc1_16_i4.c index ad9de409f46f..28f1f4f743fd 100644 --- a/libgfortran/generated/maxloc1_16_i4.c +++ b/libgfortran/generated/maxloc1_16_i4.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_16_i4 (gfc_array_i16 * const restrict, +extern void maxloc1_16_i4 (gfc_array_i16 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_16_i4); void -maxloc1_16_i4 (gfc_array_i16 * const restrict retarray, - gfc_array_i4 * const restrict array, +maxloc1_16_i4 (gfc_array_i16 * const restrict retarray, + gfc_array_i4 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_16_i4 (gfc_array_i16 * const restrict retarray, } -extern void mmaxloc1_16_i4 (gfc_array_i16 * const restrict, +extern void mmaxloc1_16_i4 (gfc_array_i16 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_16_i4); void -mmaxloc1_16_i4 (gfc_array_i16 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_16_i4 (gfc_array_i16 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_16_i4 (gfc_array_i16 * const restrict retarray, } -extern void smaxloc1_16_i4 (gfc_array_i16 * const restrict, +extern void smaxloc1_16_i4 (gfc_array_i16 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_16_i4); void -smaxloc1_16_i4 (gfc_array_i16 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_16_i4 (gfc_array_i16 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_16_i8.c b/libgfortran/generated/maxloc1_16_i8.c index 6439eedbd511..ee97c1ac552d 100644 --- a/libgfortran/generated/maxloc1_16_i8.c +++ b/libgfortran/generated/maxloc1_16_i8.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_16_i8 (gfc_array_i16 * const restrict, +extern void maxloc1_16_i8 (gfc_array_i16 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_16_i8); void -maxloc1_16_i8 (gfc_array_i16 * const restrict retarray, - gfc_array_i8 * const restrict array, +maxloc1_16_i8 (gfc_array_i16 * const restrict retarray, + gfc_array_i8 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_16_i8 (gfc_array_i16 * const restrict retarray, } -extern void mmaxloc1_16_i8 (gfc_array_i16 * const restrict, +extern void mmaxloc1_16_i8 (gfc_array_i16 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_16_i8); void -mmaxloc1_16_i8 (gfc_array_i16 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_16_i8 (gfc_array_i16 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_16_i8 (gfc_array_i16 * const restrict retarray, } -extern void smaxloc1_16_i8 (gfc_array_i16 * const restrict, +extern void smaxloc1_16_i8 (gfc_array_i16 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_16_i8); void -smaxloc1_16_i8 (gfc_array_i16 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_16_i8 (gfc_array_i16 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_16_r10.c b/libgfortran/generated/maxloc1_16_r10.c index 246271398255..87b56477149c 100644 --- a/libgfortran/generated/maxloc1_16_r10.c +++ b/libgfortran/generated/maxloc1_16_r10.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_16_r10 (gfc_array_i16 * const restrict, +extern void maxloc1_16_r10 (gfc_array_i16 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_16_r10); void -maxloc1_16_r10 (gfc_array_i16 * const restrict retarray, - gfc_array_r10 * const restrict array, +maxloc1_16_r10 (gfc_array_i16 * const restrict retarray, + gfc_array_r10 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_16_r10 (gfc_array_i16 * const restrict retarray, } -extern void mmaxloc1_16_r10 (gfc_array_i16 * const restrict, +extern void mmaxloc1_16_r10 (gfc_array_i16 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_16_r10); void -mmaxloc1_16_r10 (gfc_array_i16 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_16_r10 (gfc_array_i16 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_16_r10 (gfc_array_i16 * const restrict retarray, } -extern void smaxloc1_16_r10 (gfc_array_i16 * const restrict, +extern void smaxloc1_16_r10 (gfc_array_i16 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_16_r10); void -smaxloc1_16_r10 (gfc_array_i16 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_16_r10 (gfc_array_i16 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_16_r16.c b/libgfortran/generated/maxloc1_16_r16.c index 5ad73be9702d..2bc6edb85bfa 100644 --- a/libgfortran/generated/maxloc1_16_r16.c +++ b/libgfortran/generated/maxloc1_16_r16.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_16_r16 (gfc_array_i16 * const restrict, +extern void maxloc1_16_r16 (gfc_array_i16 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_16_r16); void -maxloc1_16_r16 (gfc_array_i16 * const restrict retarray, - gfc_array_r16 * const restrict array, +maxloc1_16_r16 (gfc_array_i16 * const restrict retarray, + gfc_array_r16 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_16_r16 (gfc_array_i16 * const restrict retarray, } -extern void mmaxloc1_16_r16 (gfc_array_i16 * const restrict, +extern void mmaxloc1_16_r16 (gfc_array_i16 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_16_r16); void -mmaxloc1_16_r16 (gfc_array_i16 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_16_r16 (gfc_array_i16 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_16_r16 (gfc_array_i16 * const restrict retarray, } -extern void smaxloc1_16_r16 (gfc_array_i16 * const restrict, +extern void smaxloc1_16_r16 (gfc_array_i16 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_16_r16); void -smaxloc1_16_r16 (gfc_array_i16 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_16_r16 (gfc_array_i16 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_16_r17.c b/libgfortran/generated/maxloc1_16_r17.c index 4444d41b83a5..ce5259897199 100644 --- a/libgfortran/generated/maxloc1_16_r17.c +++ b/libgfortran/generated/maxloc1_16_r17.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_16_r17 (gfc_array_i16 * const restrict, +extern void maxloc1_16_r17 (gfc_array_i16 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_16_r17); void -maxloc1_16_r17 (gfc_array_i16 * const restrict retarray, - gfc_array_r17 * const restrict array, +maxloc1_16_r17 (gfc_array_i16 * const restrict retarray, + gfc_array_r17 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_16_r17 (gfc_array_i16 * const restrict retarray, } -extern void mmaxloc1_16_r17 (gfc_array_i16 * const restrict, +extern void mmaxloc1_16_r17 (gfc_array_i16 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_16_r17); void -mmaxloc1_16_r17 (gfc_array_i16 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_16_r17 (gfc_array_i16 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_16_r17 (gfc_array_i16 * const restrict retarray, } -extern void smaxloc1_16_r17 (gfc_array_i16 * const restrict, +extern void smaxloc1_16_r17 (gfc_array_i16 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_16_r17); void -smaxloc1_16_r17 (gfc_array_i16 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_16_r17 (gfc_array_i16 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_16_r4.c b/libgfortran/generated/maxloc1_16_r4.c index 0be7ad1b78f3..5ae022f0b34f 100644 --- a/libgfortran/generated/maxloc1_16_r4.c +++ b/libgfortran/generated/maxloc1_16_r4.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_16_r4 (gfc_array_i16 * const restrict, +extern void maxloc1_16_r4 (gfc_array_i16 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_16_r4); void -maxloc1_16_r4 (gfc_array_i16 * const restrict retarray, - gfc_array_r4 * const restrict array, +maxloc1_16_r4 (gfc_array_i16 * const restrict retarray, + gfc_array_r4 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_16_r4 (gfc_array_i16 * const restrict retarray, } -extern void mmaxloc1_16_r4 (gfc_array_i16 * const restrict, +extern void mmaxloc1_16_r4 (gfc_array_i16 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_16_r4); void -mmaxloc1_16_r4 (gfc_array_i16 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_16_r4 (gfc_array_i16 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_16_r4 (gfc_array_i16 * const restrict retarray, } -extern void smaxloc1_16_r4 (gfc_array_i16 * const restrict, +extern void smaxloc1_16_r4 (gfc_array_i16 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_16_r4); void -smaxloc1_16_r4 (gfc_array_i16 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_16_r4 (gfc_array_i16 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_16_r8.c b/libgfortran/generated/maxloc1_16_r8.c index fd3dae933526..cf2e12643be0 100644 --- a/libgfortran/generated/maxloc1_16_r8.c +++ b/libgfortran/generated/maxloc1_16_r8.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_16_r8 (gfc_array_i16 * const restrict, +extern void maxloc1_16_r8 (gfc_array_i16 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_16_r8); void -maxloc1_16_r8 (gfc_array_i16 * const restrict retarray, - gfc_array_r8 * const restrict array, +maxloc1_16_r8 (gfc_array_i16 * const restrict retarray, + gfc_array_r8 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_16_r8 (gfc_array_i16 * const restrict retarray, } -extern void mmaxloc1_16_r8 (gfc_array_i16 * const restrict, +extern void mmaxloc1_16_r8 (gfc_array_i16 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_16_r8); void -mmaxloc1_16_r8 (gfc_array_i16 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_16_r8 (gfc_array_i16 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_16_r8 (gfc_array_i16 * const restrict retarray, } -extern void smaxloc1_16_r8 (gfc_array_i16 * const restrict, +extern void smaxloc1_16_r8 (gfc_array_i16 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_16_r8); void -smaxloc1_16_r8 (gfc_array_i16 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_16_r8 (gfc_array_i16 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_4_i1.c b/libgfortran/generated/maxloc1_4_i1.c index 664c1db63974..a54feb4afbd5 100644 --- a/libgfortran/generated/maxloc1_4_i1.c +++ b/libgfortran/generated/maxloc1_4_i1.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_4_i1 (gfc_array_i4 * const restrict, +extern void maxloc1_4_i1 (gfc_array_i4 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_4_i1); void -maxloc1_4_i1 (gfc_array_i4 * const restrict retarray, - gfc_array_i1 * const restrict array, +maxloc1_4_i1 (gfc_array_i4 * const restrict retarray, + gfc_array_i1 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_4_i1 (gfc_array_i4 * const restrict retarray, } -extern void mmaxloc1_4_i1 (gfc_array_i4 * const restrict, +extern void mmaxloc1_4_i1 (gfc_array_i4 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_4_i1); void -mmaxloc1_4_i1 (gfc_array_i4 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_4_i1 (gfc_array_i4 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_4_i1 (gfc_array_i4 * const restrict retarray, } -extern void smaxloc1_4_i1 (gfc_array_i4 * const restrict, +extern void smaxloc1_4_i1 (gfc_array_i4 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_4_i1); void -smaxloc1_4_i1 (gfc_array_i4 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_4_i1 (gfc_array_i4 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_4_i16.c b/libgfortran/generated/maxloc1_4_i16.c index 1f07aa0c9dd9..cb866c0c4298 100644 --- a/libgfortran/generated/maxloc1_4_i16.c +++ b/libgfortran/generated/maxloc1_4_i16.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_4_i16 (gfc_array_i4 * const restrict, +extern void maxloc1_4_i16 (gfc_array_i4 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_4_i16); void -maxloc1_4_i16 (gfc_array_i4 * const restrict retarray, - gfc_array_i16 * const restrict array, +maxloc1_4_i16 (gfc_array_i4 * const restrict retarray, + gfc_array_i16 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_4_i16 (gfc_array_i4 * const restrict retarray, } -extern void mmaxloc1_4_i16 (gfc_array_i4 * const restrict, +extern void mmaxloc1_4_i16 (gfc_array_i4 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_4_i16); void -mmaxloc1_4_i16 (gfc_array_i4 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_4_i16 (gfc_array_i4 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_4_i16 (gfc_array_i4 * const restrict retarray, } -extern void smaxloc1_4_i16 (gfc_array_i4 * const restrict, +extern void smaxloc1_4_i16 (gfc_array_i4 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_4_i16); void -smaxloc1_4_i16 (gfc_array_i4 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_4_i16 (gfc_array_i4 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_4_i2.c b/libgfortran/generated/maxloc1_4_i2.c index f7152f1b8b1a..45aa9a1e9cd9 100644 --- a/libgfortran/generated/maxloc1_4_i2.c +++ b/libgfortran/generated/maxloc1_4_i2.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_4_i2 (gfc_array_i4 * const restrict, +extern void maxloc1_4_i2 (gfc_array_i4 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_4_i2); void -maxloc1_4_i2 (gfc_array_i4 * const restrict retarray, - gfc_array_i2 * const restrict array, +maxloc1_4_i2 (gfc_array_i4 * const restrict retarray, + gfc_array_i2 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_4_i2 (gfc_array_i4 * const restrict retarray, } -extern void mmaxloc1_4_i2 (gfc_array_i4 * const restrict, +extern void mmaxloc1_4_i2 (gfc_array_i4 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_4_i2); void -mmaxloc1_4_i2 (gfc_array_i4 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_4_i2 (gfc_array_i4 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_4_i2 (gfc_array_i4 * const restrict retarray, } -extern void smaxloc1_4_i2 (gfc_array_i4 * const restrict, +extern void smaxloc1_4_i2 (gfc_array_i4 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_4_i2); void -smaxloc1_4_i2 (gfc_array_i4 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_4_i2 (gfc_array_i4 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_4_i4.c b/libgfortran/generated/maxloc1_4_i4.c index e5d348417f4c..ae966d8f76ad 100644 --- a/libgfortran/generated/maxloc1_4_i4.c +++ b/libgfortran/generated/maxloc1_4_i4.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_4_i4 (gfc_array_i4 * const restrict, +extern void maxloc1_4_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_4_i4); void -maxloc1_4_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, +maxloc1_4_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_4_i4 (gfc_array_i4 * const restrict retarray, } -extern void mmaxloc1_4_i4 (gfc_array_i4 * const restrict, +extern void mmaxloc1_4_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_4_i4); void -mmaxloc1_4_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_4_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_4_i4 (gfc_array_i4 * const restrict retarray, } -extern void smaxloc1_4_i4 (gfc_array_i4 * const restrict, +extern void smaxloc1_4_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_4_i4); void -smaxloc1_4_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_4_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_4_i8.c b/libgfortran/generated/maxloc1_4_i8.c index bcc3445683dc..31bff23b6200 100644 --- a/libgfortran/generated/maxloc1_4_i8.c +++ b/libgfortran/generated/maxloc1_4_i8.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_4_i8 (gfc_array_i4 * const restrict, +extern void maxloc1_4_i8 (gfc_array_i4 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_4_i8); void -maxloc1_4_i8 (gfc_array_i4 * const restrict retarray, - gfc_array_i8 * const restrict array, +maxloc1_4_i8 (gfc_array_i4 * const restrict retarray, + gfc_array_i8 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_4_i8 (gfc_array_i4 * const restrict retarray, } -extern void mmaxloc1_4_i8 (gfc_array_i4 * const restrict, +extern void mmaxloc1_4_i8 (gfc_array_i4 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_4_i8); void -mmaxloc1_4_i8 (gfc_array_i4 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_4_i8 (gfc_array_i4 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_4_i8 (gfc_array_i4 * const restrict retarray, } -extern void smaxloc1_4_i8 (gfc_array_i4 * const restrict, +extern void smaxloc1_4_i8 (gfc_array_i4 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_4_i8); void -smaxloc1_4_i8 (gfc_array_i4 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_4_i8 (gfc_array_i4 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_4_r10.c b/libgfortran/generated/maxloc1_4_r10.c index 0b0ac4bc455d..fdab04271143 100644 --- a/libgfortran/generated/maxloc1_4_r10.c +++ b/libgfortran/generated/maxloc1_4_r10.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_4_r10 (gfc_array_i4 * const restrict, +extern void maxloc1_4_r10 (gfc_array_i4 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_4_r10); void -maxloc1_4_r10 (gfc_array_i4 * const restrict retarray, - gfc_array_r10 * const restrict array, +maxloc1_4_r10 (gfc_array_i4 * const restrict retarray, + gfc_array_r10 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_4_r10 (gfc_array_i4 * const restrict retarray, } -extern void mmaxloc1_4_r10 (gfc_array_i4 * const restrict, +extern void mmaxloc1_4_r10 (gfc_array_i4 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_4_r10); void -mmaxloc1_4_r10 (gfc_array_i4 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_4_r10 (gfc_array_i4 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_4_r10 (gfc_array_i4 * const restrict retarray, } -extern void smaxloc1_4_r10 (gfc_array_i4 * const restrict, +extern void smaxloc1_4_r10 (gfc_array_i4 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_4_r10); void -smaxloc1_4_r10 (gfc_array_i4 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_4_r10 (gfc_array_i4 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_4_r16.c b/libgfortran/generated/maxloc1_4_r16.c index ffc1e4defbca..9eedf782116e 100644 --- a/libgfortran/generated/maxloc1_4_r16.c +++ b/libgfortran/generated/maxloc1_4_r16.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_4_r16 (gfc_array_i4 * const restrict, +extern void maxloc1_4_r16 (gfc_array_i4 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_4_r16); void -maxloc1_4_r16 (gfc_array_i4 * const restrict retarray, - gfc_array_r16 * const restrict array, +maxloc1_4_r16 (gfc_array_i4 * const restrict retarray, + gfc_array_r16 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_4_r16 (gfc_array_i4 * const restrict retarray, } -extern void mmaxloc1_4_r16 (gfc_array_i4 * const restrict, +extern void mmaxloc1_4_r16 (gfc_array_i4 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_4_r16); void -mmaxloc1_4_r16 (gfc_array_i4 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_4_r16 (gfc_array_i4 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_4_r16 (gfc_array_i4 * const restrict retarray, } -extern void smaxloc1_4_r16 (gfc_array_i4 * const restrict, +extern void smaxloc1_4_r16 (gfc_array_i4 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_4_r16); void -smaxloc1_4_r16 (gfc_array_i4 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_4_r16 (gfc_array_i4 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_4_r17.c b/libgfortran/generated/maxloc1_4_r17.c index f59a9eeb47d0..516268e4beb0 100644 --- a/libgfortran/generated/maxloc1_4_r17.c +++ b/libgfortran/generated/maxloc1_4_r17.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_4_r17 (gfc_array_i4 * const restrict, +extern void maxloc1_4_r17 (gfc_array_i4 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_4_r17); void -maxloc1_4_r17 (gfc_array_i4 * const restrict retarray, - gfc_array_r17 * const restrict array, +maxloc1_4_r17 (gfc_array_i4 * const restrict retarray, + gfc_array_r17 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_4_r17 (gfc_array_i4 * const restrict retarray, } -extern void mmaxloc1_4_r17 (gfc_array_i4 * const restrict, +extern void mmaxloc1_4_r17 (gfc_array_i4 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_4_r17); void -mmaxloc1_4_r17 (gfc_array_i4 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_4_r17 (gfc_array_i4 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_4_r17 (gfc_array_i4 * const restrict retarray, } -extern void smaxloc1_4_r17 (gfc_array_i4 * const restrict, +extern void smaxloc1_4_r17 (gfc_array_i4 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_4_r17); void -smaxloc1_4_r17 (gfc_array_i4 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_4_r17 (gfc_array_i4 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_4_r4.c b/libgfortran/generated/maxloc1_4_r4.c index bd9343fdc37d..1ccc30ca4cc8 100644 --- a/libgfortran/generated/maxloc1_4_r4.c +++ b/libgfortran/generated/maxloc1_4_r4.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_4_r4 (gfc_array_i4 * const restrict, +extern void maxloc1_4_r4 (gfc_array_i4 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_4_r4); void -maxloc1_4_r4 (gfc_array_i4 * const restrict retarray, - gfc_array_r4 * const restrict array, +maxloc1_4_r4 (gfc_array_i4 * const restrict retarray, + gfc_array_r4 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_4_r4 (gfc_array_i4 * const restrict retarray, } -extern void mmaxloc1_4_r4 (gfc_array_i4 * const restrict, +extern void mmaxloc1_4_r4 (gfc_array_i4 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_4_r4); void -mmaxloc1_4_r4 (gfc_array_i4 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_4_r4 (gfc_array_i4 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_4_r4 (gfc_array_i4 * const restrict retarray, } -extern void smaxloc1_4_r4 (gfc_array_i4 * const restrict, +extern void smaxloc1_4_r4 (gfc_array_i4 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_4_r4); void -smaxloc1_4_r4 (gfc_array_i4 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_4_r4 (gfc_array_i4 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_4_r8.c b/libgfortran/generated/maxloc1_4_r8.c index a63ae6af463c..86da06456cbc 100644 --- a/libgfortran/generated/maxloc1_4_r8.c +++ b/libgfortran/generated/maxloc1_4_r8.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_4_r8 (gfc_array_i4 * const restrict, +extern void maxloc1_4_r8 (gfc_array_i4 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_4_r8); void -maxloc1_4_r8 (gfc_array_i4 * const restrict retarray, - gfc_array_r8 * const restrict array, +maxloc1_4_r8 (gfc_array_i4 * const restrict retarray, + gfc_array_r8 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_4_r8 (gfc_array_i4 * const restrict retarray, } -extern void mmaxloc1_4_r8 (gfc_array_i4 * const restrict, +extern void mmaxloc1_4_r8 (gfc_array_i4 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_4_r8); void -mmaxloc1_4_r8 (gfc_array_i4 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_4_r8 (gfc_array_i4 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_4_r8 (gfc_array_i4 * const restrict retarray, } -extern void smaxloc1_4_r8 (gfc_array_i4 * const restrict, +extern void smaxloc1_4_r8 (gfc_array_i4 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_4_r8); void -smaxloc1_4_r8 (gfc_array_i4 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_4_r8 (gfc_array_i4 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_8_i1.c b/libgfortran/generated/maxloc1_8_i1.c index 01b30c9194f0..bb745335bc98 100644 --- a/libgfortran/generated/maxloc1_8_i1.c +++ b/libgfortran/generated/maxloc1_8_i1.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_8_i1 (gfc_array_i8 * const restrict, +extern void maxloc1_8_i1 (gfc_array_i8 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_8_i1); void -maxloc1_8_i1 (gfc_array_i8 * const restrict retarray, - gfc_array_i1 * const restrict array, +maxloc1_8_i1 (gfc_array_i8 * const restrict retarray, + gfc_array_i1 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_8_i1 (gfc_array_i8 * const restrict retarray, } -extern void mmaxloc1_8_i1 (gfc_array_i8 * const restrict, +extern void mmaxloc1_8_i1 (gfc_array_i8 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_8_i1); void -mmaxloc1_8_i1 (gfc_array_i8 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_8_i1 (gfc_array_i8 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_8_i1 (gfc_array_i8 * const restrict retarray, } -extern void smaxloc1_8_i1 (gfc_array_i8 * const restrict, +extern void smaxloc1_8_i1 (gfc_array_i8 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_8_i1); void -smaxloc1_8_i1 (gfc_array_i8 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_8_i1 (gfc_array_i8 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_8_i16.c b/libgfortran/generated/maxloc1_8_i16.c index 6fa0ed3659b2..6e8061a18bf6 100644 --- a/libgfortran/generated/maxloc1_8_i16.c +++ b/libgfortran/generated/maxloc1_8_i16.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_8_i16 (gfc_array_i8 * const restrict, +extern void maxloc1_8_i16 (gfc_array_i8 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_8_i16); void -maxloc1_8_i16 (gfc_array_i8 * const restrict retarray, - gfc_array_i16 * const restrict array, +maxloc1_8_i16 (gfc_array_i8 * const restrict retarray, + gfc_array_i16 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_8_i16 (gfc_array_i8 * const restrict retarray, } -extern void mmaxloc1_8_i16 (gfc_array_i8 * const restrict, +extern void mmaxloc1_8_i16 (gfc_array_i8 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_8_i16); void -mmaxloc1_8_i16 (gfc_array_i8 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_8_i16 (gfc_array_i8 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_8_i16 (gfc_array_i8 * const restrict retarray, } -extern void smaxloc1_8_i16 (gfc_array_i8 * const restrict, +extern void smaxloc1_8_i16 (gfc_array_i8 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_8_i16); void -smaxloc1_8_i16 (gfc_array_i8 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_8_i16 (gfc_array_i8 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_8_i2.c b/libgfortran/generated/maxloc1_8_i2.c index 93966137651f..ed4fda52494e 100644 --- a/libgfortran/generated/maxloc1_8_i2.c +++ b/libgfortran/generated/maxloc1_8_i2.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_8_i2 (gfc_array_i8 * const restrict, +extern void maxloc1_8_i2 (gfc_array_i8 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_8_i2); void -maxloc1_8_i2 (gfc_array_i8 * const restrict retarray, - gfc_array_i2 * const restrict array, +maxloc1_8_i2 (gfc_array_i8 * const restrict retarray, + gfc_array_i2 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_8_i2 (gfc_array_i8 * const restrict retarray, } -extern void mmaxloc1_8_i2 (gfc_array_i8 * const restrict, +extern void mmaxloc1_8_i2 (gfc_array_i8 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_8_i2); void -mmaxloc1_8_i2 (gfc_array_i8 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_8_i2 (gfc_array_i8 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_8_i2 (gfc_array_i8 * const restrict retarray, } -extern void smaxloc1_8_i2 (gfc_array_i8 * const restrict, +extern void smaxloc1_8_i2 (gfc_array_i8 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_8_i2); void -smaxloc1_8_i2 (gfc_array_i8 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_8_i2 (gfc_array_i8 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_8_i4.c b/libgfortran/generated/maxloc1_8_i4.c index baf6d9a5b956..4c708311b617 100644 --- a/libgfortran/generated/maxloc1_8_i4.c +++ b/libgfortran/generated/maxloc1_8_i4.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_8_i4 (gfc_array_i8 * const restrict, +extern void maxloc1_8_i4 (gfc_array_i8 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_8_i4); void -maxloc1_8_i4 (gfc_array_i8 * const restrict retarray, - gfc_array_i4 * const restrict array, +maxloc1_8_i4 (gfc_array_i8 * const restrict retarray, + gfc_array_i4 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_8_i4 (gfc_array_i8 * const restrict retarray, } -extern void mmaxloc1_8_i4 (gfc_array_i8 * const restrict, +extern void mmaxloc1_8_i4 (gfc_array_i8 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_8_i4); void -mmaxloc1_8_i4 (gfc_array_i8 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_8_i4 (gfc_array_i8 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_8_i4 (gfc_array_i8 * const restrict retarray, } -extern void smaxloc1_8_i4 (gfc_array_i8 * const restrict, +extern void smaxloc1_8_i4 (gfc_array_i8 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_8_i4); void -smaxloc1_8_i4 (gfc_array_i8 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_8_i4 (gfc_array_i8 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_8_i8.c b/libgfortran/generated/maxloc1_8_i8.c index b72c973b0a25..d0c34950fff4 100644 --- a/libgfortran/generated/maxloc1_8_i8.c +++ b/libgfortran/generated/maxloc1_8_i8.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_8_i8 (gfc_array_i8 * const restrict, +extern void maxloc1_8_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_8_i8); void -maxloc1_8_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, +maxloc1_8_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_8_i8 (gfc_array_i8 * const restrict retarray, } -extern void mmaxloc1_8_i8 (gfc_array_i8 * const restrict, +extern void mmaxloc1_8_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_8_i8); void -mmaxloc1_8_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_8_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_8_i8 (gfc_array_i8 * const restrict retarray, } -extern void smaxloc1_8_i8 (gfc_array_i8 * const restrict, +extern void smaxloc1_8_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_8_i8); void -smaxloc1_8_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_8_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_8_r10.c b/libgfortran/generated/maxloc1_8_r10.c index d593dd6a9409..f67183f72383 100644 --- a/libgfortran/generated/maxloc1_8_r10.c +++ b/libgfortran/generated/maxloc1_8_r10.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_8_r10 (gfc_array_i8 * const restrict, +extern void maxloc1_8_r10 (gfc_array_i8 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_8_r10); void -maxloc1_8_r10 (gfc_array_i8 * const restrict retarray, - gfc_array_r10 * const restrict array, +maxloc1_8_r10 (gfc_array_i8 * const restrict retarray, + gfc_array_r10 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_8_r10 (gfc_array_i8 * const restrict retarray, } -extern void mmaxloc1_8_r10 (gfc_array_i8 * const restrict, +extern void mmaxloc1_8_r10 (gfc_array_i8 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_8_r10); void -mmaxloc1_8_r10 (gfc_array_i8 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_8_r10 (gfc_array_i8 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_8_r10 (gfc_array_i8 * const restrict retarray, } -extern void smaxloc1_8_r10 (gfc_array_i8 * const restrict, +extern void smaxloc1_8_r10 (gfc_array_i8 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_8_r10); void -smaxloc1_8_r10 (gfc_array_i8 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_8_r10 (gfc_array_i8 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_8_r16.c b/libgfortran/generated/maxloc1_8_r16.c index 8a270d8f2dc7..6b2fc5989cd3 100644 --- a/libgfortran/generated/maxloc1_8_r16.c +++ b/libgfortran/generated/maxloc1_8_r16.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_8_r16 (gfc_array_i8 * const restrict, +extern void maxloc1_8_r16 (gfc_array_i8 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_8_r16); void -maxloc1_8_r16 (gfc_array_i8 * const restrict retarray, - gfc_array_r16 * const restrict array, +maxloc1_8_r16 (gfc_array_i8 * const restrict retarray, + gfc_array_r16 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_8_r16 (gfc_array_i8 * const restrict retarray, } -extern void mmaxloc1_8_r16 (gfc_array_i8 * const restrict, +extern void mmaxloc1_8_r16 (gfc_array_i8 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_8_r16); void -mmaxloc1_8_r16 (gfc_array_i8 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_8_r16 (gfc_array_i8 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_8_r16 (gfc_array_i8 * const restrict retarray, } -extern void smaxloc1_8_r16 (gfc_array_i8 * const restrict, +extern void smaxloc1_8_r16 (gfc_array_i8 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_8_r16); void -smaxloc1_8_r16 (gfc_array_i8 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_8_r16 (gfc_array_i8 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_8_r17.c b/libgfortran/generated/maxloc1_8_r17.c index 03a37c54ef96..65b480827dfa 100644 --- a/libgfortran/generated/maxloc1_8_r17.c +++ b/libgfortran/generated/maxloc1_8_r17.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_8_r17 (gfc_array_i8 * const restrict, +extern void maxloc1_8_r17 (gfc_array_i8 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_8_r17); void -maxloc1_8_r17 (gfc_array_i8 * const restrict retarray, - gfc_array_r17 * const restrict array, +maxloc1_8_r17 (gfc_array_i8 * const restrict retarray, + gfc_array_r17 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_8_r17 (gfc_array_i8 * const restrict retarray, } -extern void mmaxloc1_8_r17 (gfc_array_i8 * const restrict, +extern void mmaxloc1_8_r17 (gfc_array_i8 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_8_r17); void -mmaxloc1_8_r17 (gfc_array_i8 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_8_r17 (gfc_array_i8 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_8_r17 (gfc_array_i8 * const restrict retarray, } -extern void smaxloc1_8_r17 (gfc_array_i8 * const restrict, +extern void smaxloc1_8_r17 (gfc_array_i8 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_8_r17); void -smaxloc1_8_r17 (gfc_array_i8 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_8_r17 (gfc_array_i8 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_8_r4.c b/libgfortran/generated/maxloc1_8_r4.c index b4917a3ec4de..844038c88e75 100644 --- a/libgfortran/generated/maxloc1_8_r4.c +++ b/libgfortran/generated/maxloc1_8_r4.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_8_r4 (gfc_array_i8 * const restrict, +extern void maxloc1_8_r4 (gfc_array_i8 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_8_r4); void -maxloc1_8_r4 (gfc_array_i8 * const restrict retarray, - gfc_array_r4 * const restrict array, +maxloc1_8_r4 (gfc_array_i8 * const restrict retarray, + gfc_array_r4 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_8_r4 (gfc_array_i8 * const restrict retarray, } -extern void mmaxloc1_8_r4 (gfc_array_i8 * const restrict, +extern void mmaxloc1_8_r4 (gfc_array_i8 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_8_r4); void -mmaxloc1_8_r4 (gfc_array_i8 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_8_r4 (gfc_array_i8 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_8_r4 (gfc_array_i8 * const restrict retarray, } -extern void smaxloc1_8_r4 (gfc_array_i8 * const restrict, +extern void smaxloc1_8_r4 (gfc_array_i8 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_8_r4); void -smaxloc1_8_r4 (gfc_array_i8 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_8_r4 (gfc_array_i8 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxloc1_8_r8.c b/libgfortran/generated/maxloc1_8_r8.c index ed60a4573832..7e61bfe83a58 100644 --- a/libgfortran/generated/maxloc1_8_r8.c +++ b/libgfortran/generated/maxloc1_8_r8.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void maxloc1_8_r8 (gfc_array_i8 * const restrict, +extern void maxloc1_8_r8 (gfc_array_i8 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(maxloc1_8_r8); void -maxloc1_8_r8 (gfc_array_i8 * const restrict retarray, - gfc_array_r8 * const restrict array, +maxloc1_8_r8 (gfc_array_i8 * const restrict retarray, + gfc_array_r8 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -216,15 +216,15 @@ maxloc1_8_r8 (gfc_array_i8 * const restrict retarray, } -extern void mmaxloc1_8_r8 (gfc_array_i8 * const restrict, +extern void mmaxloc1_8_r8 (gfc_array_i8 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mmaxloc1_8_r8); void -mmaxloc1_8_r8 (gfc_array_i8 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +mmaxloc1_8_r8 (gfc_array_i8 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -449,15 +449,15 @@ mmaxloc1_8_r8 (gfc_array_i8 * const restrict retarray, } -extern void smaxloc1_8_r8 (gfc_array_i8 * const restrict, +extern void smaxloc1_8_r8 (gfc_array_i8 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(smaxloc1_8_r8); void -smaxloc1_8_r8 (gfc_array_i8 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +smaxloc1_8_r8 (gfc_array_i8 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxval_i1.c b/libgfortran/generated/maxval_i1.c index 984f7b04b1ab..a7672ac9c84a 100644 --- a/libgfortran/generated/maxval_i1.c +++ b/libgfortran/generated/maxval_i1.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_1) && defined (HAVE_GFC_INTEGER_1) -extern void maxval_i1 (gfc_array_i1 * const restrict, +extern void maxval_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict); export_proto(maxval_i1); void -maxval_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, +maxval_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ maxval_i1 (gfc_array_i1 * const restrict retarray, } -extern void mmaxval_i1 (gfc_array_i1 * const restrict, +extern void mmaxval_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mmaxval_i1); void -mmaxval_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +mmaxval_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mmaxval_i1 (gfc_array_i1 * const restrict retarray, } -extern void smaxval_i1 (gfc_array_i1 * const restrict, +extern void smaxval_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(smaxval_i1); void -smaxval_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +smaxval_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxval_i16.c b/libgfortran/generated/maxval_i16.c index 7effaa041771..1ab02452e17f 100644 --- a/libgfortran/generated/maxval_i16.c +++ b/libgfortran/generated/maxval_i16.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_16) && defined (HAVE_GFC_INTEGER_16) -extern void maxval_i16 (gfc_array_i16 * const restrict, +extern void maxval_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict); export_proto(maxval_i16); void -maxval_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, +maxval_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ maxval_i16 (gfc_array_i16 * const restrict retarray, } -extern void mmaxval_i16 (gfc_array_i16 * const restrict, +extern void mmaxval_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mmaxval_i16); void -mmaxval_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +mmaxval_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mmaxval_i16 (gfc_array_i16 * const restrict retarray, } -extern void smaxval_i16 (gfc_array_i16 * const restrict, +extern void smaxval_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(smaxval_i16); void -smaxval_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +smaxval_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxval_i2.c b/libgfortran/generated/maxval_i2.c index f39f1e192579..8aa05bb475a7 100644 --- a/libgfortran/generated/maxval_i2.c +++ b/libgfortran/generated/maxval_i2.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_2) && defined (HAVE_GFC_INTEGER_2) -extern void maxval_i2 (gfc_array_i2 * const restrict, +extern void maxval_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict); export_proto(maxval_i2); void -maxval_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, +maxval_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ maxval_i2 (gfc_array_i2 * const restrict retarray, } -extern void mmaxval_i2 (gfc_array_i2 * const restrict, +extern void mmaxval_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mmaxval_i2); void -mmaxval_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +mmaxval_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mmaxval_i2 (gfc_array_i2 * const restrict retarray, } -extern void smaxval_i2 (gfc_array_i2 * const restrict, +extern void smaxval_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(smaxval_i2); void -smaxval_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +smaxval_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxval_i4.c b/libgfortran/generated/maxval_i4.c index 95aff8c68546..a1493032022a 100644 --- a/libgfortran/generated/maxval_i4.c +++ b/libgfortran/generated/maxval_i4.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_4) && defined (HAVE_GFC_INTEGER_4) -extern void maxval_i4 (gfc_array_i4 * const restrict, +extern void maxval_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict); export_proto(maxval_i4); void -maxval_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, +maxval_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ maxval_i4 (gfc_array_i4 * const restrict retarray, } -extern void mmaxval_i4 (gfc_array_i4 * const restrict, +extern void mmaxval_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mmaxval_i4); void -mmaxval_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +mmaxval_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mmaxval_i4 (gfc_array_i4 * const restrict retarray, } -extern void smaxval_i4 (gfc_array_i4 * const restrict, +extern void smaxval_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(smaxval_i4); void -smaxval_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +smaxval_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxval_i8.c b/libgfortran/generated/maxval_i8.c index 17433359d0d0..42746ce53a73 100644 --- a/libgfortran/generated/maxval_i8.c +++ b/libgfortran/generated/maxval_i8.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_8) && defined (HAVE_GFC_INTEGER_8) -extern void maxval_i8 (gfc_array_i8 * const restrict, +extern void maxval_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict); export_proto(maxval_i8); void -maxval_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, +maxval_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ maxval_i8 (gfc_array_i8 * const restrict retarray, } -extern void mmaxval_i8 (gfc_array_i8 * const restrict, +extern void mmaxval_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mmaxval_i8); void -mmaxval_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +mmaxval_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mmaxval_i8 (gfc_array_i8 * const restrict retarray, } -extern void smaxval_i8 (gfc_array_i8 * const restrict, +extern void smaxval_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(smaxval_i8); void -smaxval_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +smaxval_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxval_r10.c b/libgfortran/generated/maxval_r10.c index dbf68993211d..7488db0c50a7 100644 --- a/libgfortran/generated/maxval_r10.c +++ b/libgfortran/generated/maxval_r10.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_REAL_10) && defined (HAVE_GFC_REAL_10) -extern void maxval_r10 (gfc_array_r10 * const restrict, +extern void maxval_r10 (gfc_array_r10 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict); export_proto(maxval_r10); void -maxval_r10 (gfc_array_r10 * const restrict retarray, - gfc_array_r10 * const restrict array, +maxval_r10 (gfc_array_r10 * const restrict retarray, + gfc_array_r10 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ maxval_r10 (gfc_array_r10 * const restrict retarray, } -extern void mmaxval_r10 (gfc_array_r10 * const restrict, +extern void mmaxval_r10 (gfc_array_r10 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mmaxval_r10); void -mmaxval_r10 (gfc_array_r10 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +mmaxval_r10 (gfc_array_r10 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mmaxval_r10 (gfc_array_r10 * const restrict retarray, } -extern void smaxval_r10 (gfc_array_r10 * const restrict, +extern void smaxval_r10 (gfc_array_r10 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(smaxval_r10); void -smaxval_r10 (gfc_array_r10 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +smaxval_r10 (gfc_array_r10 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxval_r16.c b/libgfortran/generated/maxval_r16.c index 73cb64f2ac29..c735944b4dfd 100644 --- a/libgfortran/generated/maxval_r16.c +++ b/libgfortran/generated/maxval_r16.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_REAL_16) && defined (HAVE_GFC_REAL_16) -extern void maxval_r16 (gfc_array_r16 * const restrict, +extern void maxval_r16 (gfc_array_r16 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict); export_proto(maxval_r16); void -maxval_r16 (gfc_array_r16 * const restrict retarray, - gfc_array_r16 * const restrict array, +maxval_r16 (gfc_array_r16 * const restrict retarray, + gfc_array_r16 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ maxval_r16 (gfc_array_r16 * const restrict retarray, } -extern void mmaxval_r16 (gfc_array_r16 * const restrict, +extern void mmaxval_r16 (gfc_array_r16 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mmaxval_r16); void -mmaxval_r16 (gfc_array_r16 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +mmaxval_r16 (gfc_array_r16 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mmaxval_r16 (gfc_array_r16 * const restrict retarray, } -extern void smaxval_r16 (gfc_array_r16 * const restrict, +extern void smaxval_r16 (gfc_array_r16 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(smaxval_r16); void -smaxval_r16 (gfc_array_r16 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +smaxval_r16 (gfc_array_r16 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxval_r17.c b/libgfortran/generated/maxval_r17.c index 07cbbe18088c..9e47d6506887 100644 --- a/libgfortran/generated/maxval_r17.c +++ b/libgfortran/generated/maxval_r17.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_REAL_17) && defined (HAVE_GFC_REAL_17) -extern void maxval_r17 (gfc_array_r17 * const restrict, +extern void maxval_r17 (gfc_array_r17 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict); export_proto(maxval_r17); void -maxval_r17 (gfc_array_r17 * const restrict retarray, - gfc_array_r17 * const restrict array, +maxval_r17 (gfc_array_r17 * const restrict retarray, + gfc_array_r17 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ maxval_r17 (gfc_array_r17 * const restrict retarray, } -extern void mmaxval_r17 (gfc_array_r17 * const restrict, +extern void mmaxval_r17 (gfc_array_r17 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mmaxval_r17); void -mmaxval_r17 (gfc_array_r17 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +mmaxval_r17 (gfc_array_r17 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mmaxval_r17 (gfc_array_r17 * const restrict retarray, } -extern void smaxval_r17 (gfc_array_r17 * const restrict, +extern void smaxval_r17 (gfc_array_r17 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(smaxval_r17); void -smaxval_r17 (gfc_array_r17 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +smaxval_r17 (gfc_array_r17 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxval_r4.c b/libgfortran/generated/maxval_r4.c index d4b895dea46e..c379d2e43205 100644 --- a/libgfortran/generated/maxval_r4.c +++ b/libgfortran/generated/maxval_r4.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_REAL_4) && defined (HAVE_GFC_REAL_4) -extern void maxval_r4 (gfc_array_r4 * const restrict, +extern void maxval_r4 (gfc_array_r4 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict); export_proto(maxval_r4); void -maxval_r4 (gfc_array_r4 * const restrict retarray, - gfc_array_r4 * const restrict array, +maxval_r4 (gfc_array_r4 * const restrict retarray, + gfc_array_r4 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ maxval_r4 (gfc_array_r4 * const restrict retarray, } -extern void mmaxval_r4 (gfc_array_r4 * const restrict, +extern void mmaxval_r4 (gfc_array_r4 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mmaxval_r4); void -mmaxval_r4 (gfc_array_r4 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +mmaxval_r4 (gfc_array_r4 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mmaxval_r4 (gfc_array_r4 * const restrict retarray, } -extern void smaxval_r4 (gfc_array_r4 * const restrict, +extern void smaxval_r4 (gfc_array_r4 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(smaxval_r4); void -smaxval_r4 (gfc_array_r4 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +smaxval_r4 (gfc_array_r4 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/maxval_r8.c b/libgfortran/generated/maxval_r8.c index 2b2b67990cfc..16e09bf3fb1f 100644 --- a/libgfortran/generated/maxval_r8.c +++ b/libgfortran/generated/maxval_r8.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_REAL_8) && defined (HAVE_GFC_REAL_8) -extern void maxval_r8 (gfc_array_r8 * const restrict, +extern void maxval_r8 (gfc_array_r8 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict); export_proto(maxval_r8); void -maxval_r8 (gfc_array_r8 * const restrict retarray, - gfc_array_r8 * const restrict array, +maxval_r8 (gfc_array_r8 * const restrict retarray, + gfc_array_r8 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ maxval_r8 (gfc_array_r8 * const restrict retarray, } -extern void mmaxval_r8 (gfc_array_r8 * const restrict, +extern void mmaxval_r8 (gfc_array_r8 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mmaxval_r8); void -mmaxval_r8 (gfc_array_r8 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +mmaxval_r8 (gfc_array_r8 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mmaxval_r8 (gfc_array_r8 * const restrict retarray, } -extern void smaxval_r8 (gfc_array_r8 * const restrict, +extern void smaxval_r8 (gfc_array_r8 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(smaxval_r8); void -smaxval_r8 (gfc_array_r8 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +smaxval_r8 (gfc_array_r8 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_16_i1.c b/libgfortran/generated/minloc1_16_i1.c index 81006ef30c7a..840139f18dad 100644 --- a/libgfortran/generated/minloc1_16_i1.c +++ b/libgfortran/generated/minloc1_16_i1.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_16_i1 (gfc_array_i16 * const restrict, +extern void minloc1_16_i1 (gfc_array_i16 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_16_i1); void -minloc1_16_i1 (gfc_array_i16 * const restrict retarray, - gfc_array_i1 * const restrict array, +minloc1_16_i1 (gfc_array_i16 * const restrict retarray, + gfc_array_i1 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_16_i1 (gfc_array_i16 * const restrict retarray, } -extern void mminloc1_16_i1 (gfc_array_i16 * const restrict, +extern void mminloc1_16_i1 (gfc_array_i16 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_16_i1); void -mminloc1_16_i1 (gfc_array_i16 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +mminloc1_16_i1 (gfc_array_i16 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_16_i1 (gfc_array_i16 * const restrict retarray, } -extern void sminloc1_16_i1 (gfc_array_i16 * const restrict, +extern void sminloc1_16_i1 (gfc_array_i16 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_16_i1); void -sminloc1_16_i1 (gfc_array_i16 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +sminloc1_16_i1 (gfc_array_i16 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_16_i16.c b/libgfortran/generated/minloc1_16_i16.c index 36ea12ddc9fd..4b6545fd012f 100644 --- a/libgfortran/generated/minloc1_16_i16.c +++ b/libgfortran/generated/minloc1_16_i16.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_16_i16 (gfc_array_i16 * const restrict, +extern void minloc1_16_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_16_i16); void -minloc1_16_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, +minloc1_16_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_16_i16 (gfc_array_i16 * const restrict retarray, } -extern void mminloc1_16_i16 (gfc_array_i16 * const restrict, +extern void mminloc1_16_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_16_i16); void -mminloc1_16_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +mminloc1_16_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_16_i16 (gfc_array_i16 * const restrict retarray, } -extern void sminloc1_16_i16 (gfc_array_i16 * const restrict, +extern void sminloc1_16_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_16_i16); void -sminloc1_16_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +sminloc1_16_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_16_i2.c b/libgfortran/generated/minloc1_16_i2.c index 61c9f97d9320..89f9465b2b1a 100644 --- a/libgfortran/generated/minloc1_16_i2.c +++ b/libgfortran/generated/minloc1_16_i2.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_16_i2 (gfc_array_i16 * const restrict, +extern void minloc1_16_i2 (gfc_array_i16 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_16_i2); void -minloc1_16_i2 (gfc_array_i16 * const restrict retarray, - gfc_array_i2 * const restrict array, +minloc1_16_i2 (gfc_array_i16 * const restrict retarray, + gfc_array_i2 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_16_i2 (gfc_array_i16 * const restrict retarray, } -extern void mminloc1_16_i2 (gfc_array_i16 * const restrict, +extern void mminloc1_16_i2 (gfc_array_i16 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_16_i2); void -mminloc1_16_i2 (gfc_array_i16 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +mminloc1_16_i2 (gfc_array_i16 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_16_i2 (gfc_array_i16 * const restrict retarray, } -extern void sminloc1_16_i2 (gfc_array_i16 * const restrict, +extern void sminloc1_16_i2 (gfc_array_i16 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_16_i2); void -sminloc1_16_i2 (gfc_array_i16 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +sminloc1_16_i2 (gfc_array_i16 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_16_i4.c b/libgfortran/generated/minloc1_16_i4.c index d8a3683ddbb1..4475dfe78e66 100644 --- a/libgfortran/generated/minloc1_16_i4.c +++ b/libgfortran/generated/minloc1_16_i4.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_16_i4 (gfc_array_i16 * const restrict, +extern void minloc1_16_i4 (gfc_array_i16 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_16_i4); void -minloc1_16_i4 (gfc_array_i16 * const restrict retarray, - gfc_array_i4 * const restrict array, +minloc1_16_i4 (gfc_array_i16 * const restrict retarray, + gfc_array_i4 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_16_i4 (gfc_array_i16 * const restrict retarray, } -extern void mminloc1_16_i4 (gfc_array_i16 * const restrict, +extern void mminloc1_16_i4 (gfc_array_i16 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_16_i4); void -mminloc1_16_i4 (gfc_array_i16 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +mminloc1_16_i4 (gfc_array_i16 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_16_i4 (gfc_array_i16 * const restrict retarray, } -extern void sminloc1_16_i4 (gfc_array_i16 * const restrict, +extern void sminloc1_16_i4 (gfc_array_i16 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_16_i4); void -sminloc1_16_i4 (gfc_array_i16 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +sminloc1_16_i4 (gfc_array_i16 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_16_i8.c b/libgfortran/generated/minloc1_16_i8.c index 70bfdec06213..394789861ba5 100644 --- a/libgfortran/generated/minloc1_16_i8.c +++ b/libgfortran/generated/minloc1_16_i8.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_16_i8 (gfc_array_i16 * const restrict, +extern void minloc1_16_i8 (gfc_array_i16 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_16_i8); void -minloc1_16_i8 (gfc_array_i16 * const restrict retarray, - gfc_array_i8 * const restrict array, +minloc1_16_i8 (gfc_array_i16 * const restrict retarray, + gfc_array_i8 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_16_i8 (gfc_array_i16 * const restrict retarray, } -extern void mminloc1_16_i8 (gfc_array_i16 * const restrict, +extern void mminloc1_16_i8 (gfc_array_i16 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_16_i8); void -mminloc1_16_i8 (gfc_array_i16 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +mminloc1_16_i8 (gfc_array_i16 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_16_i8 (gfc_array_i16 * const restrict retarray, } -extern void sminloc1_16_i8 (gfc_array_i16 * const restrict, +extern void sminloc1_16_i8 (gfc_array_i16 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_16_i8); void -sminloc1_16_i8 (gfc_array_i16 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +sminloc1_16_i8 (gfc_array_i16 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_16_r10.c b/libgfortran/generated/minloc1_16_r10.c index 1f16bda32e3e..46fc94e801ff 100644 --- a/libgfortran/generated/minloc1_16_r10.c +++ b/libgfortran/generated/minloc1_16_r10.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_16_r10 (gfc_array_i16 * const restrict, +extern void minloc1_16_r10 (gfc_array_i16 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_16_r10); void -minloc1_16_r10 (gfc_array_i16 * const restrict retarray, - gfc_array_r10 * const restrict array, +minloc1_16_r10 (gfc_array_i16 * const restrict retarray, + gfc_array_r10 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_16_r10 (gfc_array_i16 * const restrict retarray, } -extern void mminloc1_16_r10 (gfc_array_i16 * const restrict, +extern void mminloc1_16_r10 (gfc_array_i16 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_16_r10); void -mminloc1_16_r10 (gfc_array_i16 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +mminloc1_16_r10 (gfc_array_i16 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_16_r10 (gfc_array_i16 * const restrict retarray, } -extern void sminloc1_16_r10 (gfc_array_i16 * const restrict, +extern void sminloc1_16_r10 (gfc_array_i16 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_16_r10); void -sminloc1_16_r10 (gfc_array_i16 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +sminloc1_16_r10 (gfc_array_i16 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_16_r16.c b/libgfortran/generated/minloc1_16_r16.c index 35bf98ad650b..da3b8f2b7b9e 100644 --- a/libgfortran/generated/minloc1_16_r16.c +++ b/libgfortran/generated/minloc1_16_r16.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_16_r16 (gfc_array_i16 * const restrict, +extern void minloc1_16_r16 (gfc_array_i16 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_16_r16); void -minloc1_16_r16 (gfc_array_i16 * const restrict retarray, - gfc_array_r16 * const restrict array, +minloc1_16_r16 (gfc_array_i16 * const restrict retarray, + gfc_array_r16 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_16_r16 (gfc_array_i16 * const restrict retarray, } -extern void mminloc1_16_r16 (gfc_array_i16 * const restrict, +extern void mminloc1_16_r16 (gfc_array_i16 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_16_r16); void -mminloc1_16_r16 (gfc_array_i16 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +mminloc1_16_r16 (gfc_array_i16 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_16_r16 (gfc_array_i16 * const restrict retarray, } -extern void sminloc1_16_r16 (gfc_array_i16 * const restrict, +extern void sminloc1_16_r16 (gfc_array_i16 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_16_r16); void -sminloc1_16_r16 (gfc_array_i16 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +sminloc1_16_r16 (gfc_array_i16 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_16_r17.c b/libgfortran/generated/minloc1_16_r17.c index 31b3bbbfb1d8..8777ecfef3d0 100644 --- a/libgfortran/generated/minloc1_16_r17.c +++ b/libgfortran/generated/minloc1_16_r17.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_16_r17 (gfc_array_i16 * const restrict, +extern void minloc1_16_r17 (gfc_array_i16 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_16_r17); void -minloc1_16_r17 (gfc_array_i16 * const restrict retarray, - gfc_array_r17 * const restrict array, +minloc1_16_r17 (gfc_array_i16 * const restrict retarray, + gfc_array_r17 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_16_r17 (gfc_array_i16 * const restrict retarray, } -extern void mminloc1_16_r17 (gfc_array_i16 * const restrict, +extern void mminloc1_16_r17 (gfc_array_i16 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_16_r17); void -mminloc1_16_r17 (gfc_array_i16 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +mminloc1_16_r17 (gfc_array_i16 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_16_r17 (gfc_array_i16 * const restrict retarray, } -extern void sminloc1_16_r17 (gfc_array_i16 * const restrict, +extern void sminloc1_16_r17 (gfc_array_i16 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_16_r17); void -sminloc1_16_r17 (gfc_array_i16 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +sminloc1_16_r17 (gfc_array_i16 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_16_r4.c b/libgfortran/generated/minloc1_16_r4.c index 845aa035012b..1c550175242f 100644 --- a/libgfortran/generated/minloc1_16_r4.c +++ b/libgfortran/generated/minloc1_16_r4.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_16_r4 (gfc_array_i16 * const restrict, +extern void minloc1_16_r4 (gfc_array_i16 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_16_r4); void -minloc1_16_r4 (gfc_array_i16 * const restrict retarray, - gfc_array_r4 * const restrict array, +minloc1_16_r4 (gfc_array_i16 * const restrict retarray, + gfc_array_r4 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_16_r4 (gfc_array_i16 * const restrict retarray, } -extern void mminloc1_16_r4 (gfc_array_i16 * const restrict, +extern void mminloc1_16_r4 (gfc_array_i16 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_16_r4); void -mminloc1_16_r4 (gfc_array_i16 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +mminloc1_16_r4 (gfc_array_i16 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_16_r4 (gfc_array_i16 * const restrict retarray, } -extern void sminloc1_16_r4 (gfc_array_i16 * const restrict, +extern void sminloc1_16_r4 (gfc_array_i16 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_16_r4); void -sminloc1_16_r4 (gfc_array_i16 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +sminloc1_16_r4 (gfc_array_i16 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_16_r8.c b/libgfortran/generated/minloc1_16_r8.c index d6760091b8fc..e778c4709328 100644 --- a/libgfortran/generated/minloc1_16_r8.c +++ b/libgfortran/generated/minloc1_16_r8.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_16_r8 (gfc_array_i16 * const restrict, +extern void minloc1_16_r8 (gfc_array_i16 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_16_r8); void -minloc1_16_r8 (gfc_array_i16 * const restrict retarray, - gfc_array_r8 * const restrict array, +minloc1_16_r8 (gfc_array_i16 * const restrict retarray, + gfc_array_r8 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_16_r8 (gfc_array_i16 * const restrict retarray, } -extern void mminloc1_16_r8 (gfc_array_i16 * const restrict, +extern void mminloc1_16_r8 (gfc_array_i16 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_16_r8); void -mminloc1_16_r8 (gfc_array_i16 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +mminloc1_16_r8 (gfc_array_i16 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_16_r8 (gfc_array_i16 * const restrict retarray, } -extern void sminloc1_16_r8 (gfc_array_i16 * const restrict, +extern void sminloc1_16_r8 (gfc_array_i16 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_16_r8); void -sminloc1_16_r8 (gfc_array_i16 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +sminloc1_16_r8 (gfc_array_i16 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_4_i1.c b/libgfortran/generated/minloc1_4_i1.c index bd24eafe0176..639838bc5e9a 100644 --- a/libgfortran/generated/minloc1_4_i1.c +++ b/libgfortran/generated/minloc1_4_i1.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_4_i1 (gfc_array_i4 * const restrict, +extern void minloc1_4_i1 (gfc_array_i4 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_4_i1); void -minloc1_4_i1 (gfc_array_i4 * const restrict retarray, - gfc_array_i1 * const restrict array, +minloc1_4_i1 (gfc_array_i4 * const restrict retarray, + gfc_array_i1 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_4_i1 (gfc_array_i4 * const restrict retarray, } -extern void mminloc1_4_i1 (gfc_array_i4 * const restrict, +extern void mminloc1_4_i1 (gfc_array_i4 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_4_i1); void -mminloc1_4_i1 (gfc_array_i4 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +mminloc1_4_i1 (gfc_array_i4 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_4_i1 (gfc_array_i4 * const restrict retarray, } -extern void sminloc1_4_i1 (gfc_array_i4 * const restrict, +extern void sminloc1_4_i1 (gfc_array_i4 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_4_i1); void -sminloc1_4_i1 (gfc_array_i4 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +sminloc1_4_i1 (gfc_array_i4 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_4_i16.c b/libgfortran/generated/minloc1_4_i16.c index 5a735a9029b7..b86e3cc06461 100644 --- a/libgfortran/generated/minloc1_4_i16.c +++ b/libgfortran/generated/minloc1_4_i16.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_4_i16 (gfc_array_i4 * const restrict, +extern void minloc1_4_i16 (gfc_array_i4 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_4_i16); void -minloc1_4_i16 (gfc_array_i4 * const restrict retarray, - gfc_array_i16 * const restrict array, +minloc1_4_i16 (gfc_array_i4 * const restrict retarray, + gfc_array_i16 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_4_i16 (gfc_array_i4 * const restrict retarray, } -extern void mminloc1_4_i16 (gfc_array_i4 * const restrict, +extern void mminloc1_4_i16 (gfc_array_i4 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_4_i16); void -mminloc1_4_i16 (gfc_array_i4 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +mminloc1_4_i16 (gfc_array_i4 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_4_i16 (gfc_array_i4 * const restrict retarray, } -extern void sminloc1_4_i16 (gfc_array_i4 * const restrict, +extern void sminloc1_4_i16 (gfc_array_i4 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_4_i16); void -sminloc1_4_i16 (gfc_array_i4 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +sminloc1_4_i16 (gfc_array_i4 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_4_i2.c b/libgfortran/generated/minloc1_4_i2.c index 5328eefa36b0..8def21c8addb 100644 --- a/libgfortran/generated/minloc1_4_i2.c +++ b/libgfortran/generated/minloc1_4_i2.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_4_i2 (gfc_array_i4 * const restrict, +extern void minloc1_4_i2 (gfc_array_i4 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_4_i2); void -minloc1_4_i2 (gfc_array_i4 * const restrict retarray, - gfc_array_i2 * const restrict array, +minloc1_4_i2 (gfc_array_i4 * const restrict retarray, + gfc_array_i2 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_4_i2 (gfc_array_i4 * const restrict retarray, } -extern void mminloc1_4_i2 (gfc_array_i4 * const restrict, +extern void mminloc1_4_i2 (gfc_array_i4 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_4_i2); void -mminloc1_4_i2 (gfc_array_i4 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +mminloc1_4_i2 (gfc_array_i4 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_4_i2 (gfc_array_i4 * const restrict retarray, } -extern void sminloc1_4_i2 (gfc_array_i4 * const restrict, +extern void sminloc1_4_i2 (gfc_array_i4 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_4_i2); void -sminloc1_4_i2 (gfc_array_i4 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +sminloc1_4_i2 (gfc_array_i4 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_4_i4.c b/libgfortran/generated/minloc1_4_i4.c index 84bd3373d69a..e42b9f8181b9 100644 --- a/libgfortran/generated/minloc1_4_i4.c +++ b/libgfortran/generated/minloc1_4_i4.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_4_i4 (gfc_array_i4 * const restrict, +extern void minloc1_4_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_4_i4); void -minloc1_4_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, +minloc1_4_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_4_i4 (gfc_array_i4 * const restrict retarray, } -extern void mminloc1_4_i4 (gfc_array_i4 * const restrict, +extern void mminloc1_4_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_4_i4); void -mminloc1_4_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +mminloc1_4_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_4_i4 (gfc_array_i4 * const restrict retarray, } -extern void sminloc1_4_i4 (gfc_array_i4 * const restrict, +extern void sminloc1_4_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_4_i4); void -sminloc1_4_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +sminloc1_4_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_4_i8.c b/libgfortran/generated/minloc1_4_i8.c index 1425c39e6dc2..cc9fa4cc78d0 100644 --- a/libgfortran/generated/minloc1_4_i8.c +++ b/libgfortran/generated/minloc1_4_i8.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_4_i8 (gfc_array_i4 * const restrict, +extern void minloc1_4_i8 (gfc_array_i4 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_4_i8); void -minloc1_4_i8 (gfc_array_i4 * const restrict retarray, - gfc_array_i8 * const restrict array, +minloc1_4_i8 (gfc_array_i4 * const restrict retarray, + gfc_array_i8 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_4_i8 (gfc_array_i4 * const restrict retarray, } -extern void mminloc1_4_i8 (gfc_array_i4 * const restrict, +extern void mminloc1_4_i8 (gfc_array_i4 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_4_i8); void -mminloc1_4_i8 (gfc_array_i4 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +mminloc1_4_i8 (gfc_array_i4 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_4_i8 (gfc_array_i4 * const restrict retarray, } -extern void sminloc1_4_i8 (gfc_array_i4 * const restrict, +extern void sminloc1_4_i8 (gfc_array_i4 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_4_i8); void -sminloc1_4_i8 (gfc_array_i4 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +sminloc1_4_i8 (gfc_array_i4 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_4_r10.c b/libgfortran/generated/minloc1_4_r10.c index 6a9eae496e3d..65ce7b9c3f7a 100644 --- a/libgfortran/generated/minloc1_4_r10.c +++ b/libgfortran/generated/minloc1_4_r10.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_4_r10 (gfc_array_i4 * const restrict, +extern void minloc1_4_r10 (gfc_array_i4 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_4_r10); void -minloc1_4_r10 (gfc_array_i4 * const restrict retarray, - gfc_array_r10 * const restrict array, +minloc1_4_r10 (gfc_array_i4 * const restrict retarray, + gfc_array_r10 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_4_r10 (gfc_array_i4 * const restrict retarray, } -extern void mminloc1_4_r10 (gfc_array_i4 * const restrict, +extern void mminloc1_4_r10 (gfc_array_i4 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_4_r10); void -mminloc1_4_r10 (gfc_array_i4 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +mminloc1_4_r10 (gfc_array_i4 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_4_r10 (gfc_array_i4 * const restrict retarray, } -extern void sminloc1_4_r10 (gfc_array_i4 * const restrict, +extern void sminloc1_4_r10 (gfc_array_i4 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_4_r10); void -sminloc1_4_r10 (gfc_array_i4 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +sminloc1_4_r10 (gfc_array_i4 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_4_r16.c b/libgfortran/generated/minloc1_4_r16.c index 66c3017b512d..ddd21c95d76a 100644 --- a/libgfortran/generated/minloc1_4_r16.c +++ b/libgfortran/generated/minloc1_4_r16.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_4_r16 (gfc_array_i4 * const restrict, +extern void minloc1_4_r16 (gfc_array_i4 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_4_r16); void -minloc1_4_r16 (gfc_array_i4 * const restrict retarray, - gfc_array_r16 * const restrict array, +minloc1_4_r16 (gfc_array_i4 * const restrict retarray, + gfc_array_r16 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_4_r16 (gfc_array_i4 * const restrict retarray, } -extern void mminloc1_4_r16 (gfc_array_i4 * const restrict, +extern void mminloc1_4_r16 (gfc_array_i4 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_4_r16); void -mminloc1_4_r16 (gfc_array_i4 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +mminloc1_4_r16 (gfc_array_i4 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_4_r16 (gfc_array_i4 * const restrict retarray, } -extern void sminloc1_4_r16 (gfc_array_i4 * const restrict, +extern void sminloc1_4_r16 (gfc_array_i4 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_4_r16); void -sminloc1_4_r16 (gfc_array_i4 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +sminloc1_4_r16 (gfc_array_i4 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_4_r17.c b/libgfortran/generated/minloc1_4_r17.c index e600a430011c..0b90a10624e8 100644 --- a/libgfortran/generated/minloc1_4_r17.c +++ b/libgfortran/generated/minloc1_4_r17.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_4_r17 (gfc_array_i4 * const restrict, +extern void minloc1_4_r17 (gfc_array_i4 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_4_r17); void -minloc1_4_r17 (gfc_array_i4 * const restrict retarray, - gfc_array_r17 * const restrict array, +minloc1_4_r17 (gfc_array_i4 * const restrict retarray, + gfc_array_r17 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_4_r17 (gfc_array_i4 * const restrict retarray, } -extern void mminloc1_4_r17 (gfc_array_i4 * const restrict, +extern void mminloc1_4_r17 (gfc_array_i4 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_4_r17); void -mminloc1_4_r17 (gfc_array_i4 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +mminloc1_4_r17 (gfc_array_i4 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_4_r17 (gfc_array_i4 * const restrict retarray, } -extern void sminloc1_4_r17 (gfc_array_i4 * const restrict, +extern void sminloc1_4_r17 (gfc_array_i4 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_4_r17); void -sminloc1_4_r17 (gfc_array_i4 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +sminloc1_4_r17 (gfc_array_i4 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_4_r4.c b/libgfortran/generated/minloc1_4_r4.c index a743d8d032c9..0a68f2c1cd27 100644 --- a/libgfortran/generated/minloc1_4_r4.c +++ b/libgfortran/generated/minloc1_4_r4.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_4_r4 (gfc_array_i4 * const restrict, +extern void minloc1_4_r4 (gfc_array_i4 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_4_r4); void -minloc1_4_r4 (gfc_array_i4 * const restrict retarray, - gfc_array_r4 * const restrict array, +minloc1_4_r4 (gfc_array_i4 * const restrict retarray, + gfc_array_r4 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_4_r4 (gfc_array_i4 * const restrict retarray, } -extern void mminloc1_4_r4 (gfc_array_i4 * const restrict, +extern void mminloc1_4_r4 (gfc_array_i4 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_4_r4); void -mminloc1_4_r4 (gfc_array_i4 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +mminloc1_4_r4 (gfc_array_i4 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_4_r4 (gfc_array_i4 * const restrict retarray, } -extern void sminloc1_4_r4 (gfc_array_i4 * const restrict, +extern void sminloc1_4_r4 (gfc_array_i4 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_4_r4); void -sminloc1_4_r4 (gfc_array_i4 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +sminloc1_4_r4 (gfc_array_i4 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_4_r8.c b/libgfortran/generated/minloc1_4_r8.c index a3d399e3050b..b89deb521ea3 100644 --- a/libgfortran/generated/minloc1_4_r8.c +++ b/libgfortran/generated/minloc1_4_r8.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_4_r8 (gfc_array_i4 * const restrict, +extern void minloc1_4_r8 (gfc_array_i4 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_4_r8); void -minloc1_4_r8 (gfc_array_i4 * const restrict retarray, - gfc_array_r8 * const restrict array, +minloc1_4_r8 (gfc_array_i4 * const restrict retarray, + gfc_array_r8 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_4_r8 (gfc_array_i4 * const restrict retarray, } -extern void mminloc1_4_r8 (gfc_array_i4 * const restrict, +extern void mminloc1_4_r8 (gfc_array_i4 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_4_r8); void -mminloc1_4_r8 (gfc_array_i4 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +mminloc1_4_r8 (gfc_array_i4 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_4_r8 (gfc_array_i4 * const restrict retarray, } -extern void sminloc1_4_r8 (gfc_array_i4 * const restrict, +extern void sminloc1_4_r8 (gfc_array_i4 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_4_r8); void -sminloc1_4_r8 (gfc_array_i4 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +sminloc1_4_r8 (gfc_array_i4 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_8_i1.c b/libgfortran/generated/minloc1_8_i1.c index 113725ea9112..f4fa5a091f43 100644 --- a/libgfortran/generated/minloc1_8_i1.c +++ b/libgfortran/generated/minloc1_8_i1.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_8_i1 (gfc_array_i8 * const restrict, +extern void minloc1_8_i1 (gfc_array_i8 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_8_i1); void -minloc1_8_i1 (gfc_array_i8 * const restrict retarray, - gfc_array_i1 * const restrict array, +minloc1_8_i1 (gfc_array_i8 * const restrict retarray, + gfc_array_i1 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_8_i1 (gfc_array_i8 * const restrict retarray, } -extern void mminloc1_8_i1 (gfc_array_i8 * const restrict, +extern void mminloc1_8_i1 (gfc_array_i8 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_8_i1); void -mminloc1_8_i1 (gfc_array_i8 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +mminloc1_8_i1 (gfc_array_i8 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_8_i1 (gfc_array_i8 * const restrict retarray, } -extern void sminloc1_8_i1 (gfc_array_i8 * const restrict, +extern void sminloc1_8_i1 (gfc_array_i8 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_8_i1); void -sminloc1_8_i1 (gfc_array_i8 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +sminloc1_8_i1 (gfc_array_i8 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_8_i16.c b/libgfortran/generated/minloc1_8_i16.c index 70ba7d5c53f3..73edefbf21a9 100644 --- a/libgfortran/generated/minloc1_8_i16.c +++ b/libgfortran/generated/minloc1_8_i16.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_8_i16 (gfc_array_i8 * const restrict, +extern void minloc1_8_i16 (gfc_array_i8 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_8_i16); void -minloc1_8_i16 (gfc_array_i8 * const restrict retarray, - gfc_array_i16 * const restrict array, +minloc1_8_i16 (gfc_array_i8 * const restrict retarray, + gfc_array_i16 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_8_i16 (gfc_array_i8 * const restrict retarray, } -extern void mminloc1_8_i16 (gfc_array_i8 * const restrict, +extern void mminloc1_8_i16 (gfc_array_i8 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_8_i16); void -mminloc1_8_i16 (gfc_array_i8 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +mminloc1_8_i16 (gfc_array_i8 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_8_i16 (gfc_array_i8 * const restrict retarray, } -extern void sminloc1_8_i16 (gfc_array_i8 * const restrict, +extern void sminloc1_8_i16 (gfc_array_i8 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_8_i16); void -sminloc1_8_i16 (gfc_array_i8 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +sminloc1_8_i16 (gfc_array_i8 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_8_i2.c b/libgfortran/generated/minloc1_8_i2.c index ed14464347d2..126587caf771 100644 --- a/libgfortran/generated/minloc1_8_i2.c +++ b/libgfortran/generated/minloc1_8_i2.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_8_i2 (gfc_array_i8 * const restrict, +extern void minloc1_8_i2 (gfc_array_i8 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_8_i2); void -minloc1_8_i2 (gfc_array_i8 * const restrict retarray, - gfc_array_i2 * const restrict array, +minloc1_8_i2 (gfc_array_i8 * const restrict retarray, + gfc_array_i2 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_8_i2 (gfc_array_i8 * const restrict retarray, } -extern void mminloc1_8_i2 (gfc_array_i8 * const restrict, +extern void mminloc1_8_i2 (gfc_array_i8 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_8_i2); void -mminloc1_8_i2 (gfc_array_i8 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +mminloc1_8_i2 (gfc_array_i8 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_8_i2 (gfc_array_i8 * const restrict retarray, } -extern void sminloc1_8_i2 (gfc_array_i8 * const restrict, +extern void sminloc1_8_i2 (gfc_array_i8 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_8_i2); void -sminloc1_8_i2 (gfc_array_i8 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +sminloc1_8_i2 (gfc_array_i8 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_8_i4.c b/libgfortran/generated/minloc1_8_i4.c index 47e0a989147d..eafbbe10dcc0 100644 --- a/libgfortran/generated/minloc1_8_i4.c +++ b/libgfortran/generated/minloc1_8_i4.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_8_i4 (gfc_array_i8 * const restrict, +extern void minloc1_8_i4 (gfc_array_i8 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_8_i4); void -minloc1_8_i4 (gfc_array_i8 * const restrict retarray, - gfc_array_i4 * const restrict array, +minloc1_8_i4 (gfc_array_i8 * const restrict retarray, + gfc_array_i4 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_8_i4 (gfc_array_i8 * const restrict retarray, } -extern void mminloc1_8_i4 (gfc_array_i8 * const restrict, +extern void mminloc1_8_i4 (gfc_array_i8 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_8_i4); void -mminloc1_8_i4 (gfc_array_i8 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +mminloc1_8_i4 (gfc_array_i8 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_8_i4 (gfc_array_i8 * const restrict retarray, } -extern void sminloc1_8_i4 (gfc_array_i8 * const restrict, +extern void sminloc1_8_i4 (gfc_array_i8 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_8_i4); void -sminloc1_8_i4 (gfc_array_i8 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +sminloc1_8_i4 (gfc_array_i8 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_8_i8.c b/libgfortran/generated/minloc1_8_i8.c index 6e2b50342e6c..c806250d7a5b 100644 --- a/libgfortran/generated/minloc1_8_i8.c +++ b/libgfortran/generated/minloc1_8_i8.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_8_i8 (gfc_array_i8 * const restrict, +extern void minloc1_8_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_8_i8); void -minloc1_8_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, +minloc1_8_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_8_i8 (gfc_array_i8 * const restrict retarray, } -extern void mminloc1_8_i8 (gfc_array_i8 * const restrict, +extern void mminloc1_8_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_8_i8); void -mminloc1_8_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +mminloc1_8_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_8_i8 (gfc_array_i8 * const restrict retarray, } -extern void sminloc1_8_i8 (gfc_array_i8 * const restrict, +extern void sminloc1_8_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_8_i8); void -sminloc1_8_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +sminloc1_8_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_8_r10.c b/libgfortran/generated/minloc1_8_r10.c index ef7126156b13..5e87310fb017 100644 --- a/libgfortran/generated/minloc1_8_r10.c +++ b/libgfortran/generated/minloc1_8_r10.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_8_r10 (gfc_array_i8 * const restrict, +extern void minloc1_8_r10 (gfc_array_i8 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_8_r10); void -minloc1_8_r10 (gfc_array_i8 * const restrict retarray, - gfc_array_r10 * const restrict array, +minloc1_8_r10 (gfc_array_i8 * const restrict retarray, + gfc_array_r10 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_8_r10 (gfc_array_i8 * const restrict retarray, } -extern void mminloc1_8_r10 (gfc_array_i8 * const restrict, +extern void mminloc1_8_r10 (gfc_array_i8 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_8_r10); void -mminloc1_8_r10 (gfc_array_i8 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +mminloc1_8_r10 (gfc_array_i8 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_8_r10 (gfc_array_i8 * const restrict retarray, } -extern void sminloc1_8_r10 (gfc_array_i8 * const restrict, +extern void sminloc1_8_r10 (gfc_array_i8 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_8_r10); void -sminloc1_8_r10 (gfc_array_i8 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +sminloc1_8_r10 (gfc_array_i8 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_8_r16.c b/libgfortran/generated/minloc1_8_r16.c index b645a53ef644..a0df1baf7295 100644 --- a/libgfortran/generated/minloc1_8_r16.c +++ b/libgfortran/generated/minloc1_8_r16.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_8_r16 (gfc_array_i8 * const restrict, +extern void minloc1_8_r16 (gfc_array_i8 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_8_r16); void -minloc1_8_r16 (gfc_array_i8 * const restrict retarray, - gfc_array_r16 * const restrict array, +minloc1_8_r16 (gfc_array_i8 * const restrict retarray, + gfc_array_r16 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_8_r16 (gfc_array_i8 * const restrict retarray, } -extern void mminloc1_8_r16 (gfc_array_i8 * const restrict, +extern void mminloc1_8_r16 (gfc_array_i8 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_8_r16); void -mminloc1_8_r16 (gfc_array_i8 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +mminloc1_8_r16 (gfc_array_i8 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_8_r16 (gfc_array_i8 * const restrict retarray, } -extern void sminloc1_8_r16 (gfc_array_i8 * const restrict, +extern void sminloc1_8_r16 (gfc_array_i8 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_8_r16); void -sminloc1_8_r16 (gfc_array_i8 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +sminloc1_8_r16 (gfc_array_i8 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_8_r17.c b/libgfortran/generated/minloc1_8_r17.c index 51ccd09fc144..023ecd39a9a3 100644 --- a/libgfortran/generated/minloc1_8_r17.c +++ b/libgfortran/generated/minloc1_8_r17.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_8_r17 (gfc_array_i8 * const restrict, +extern void minloc1_8_r17 (gfc_array_i8 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_8_r17); void -minloc1_8_r17 (gfc_array_i8 * const restrict retarray, - gfc_array_r17 * const restrict array, +minloc1_8_r17 (gfc_array_i8 * const restrict retarray, + gfc_array_r17 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_8_r17 (gfc_array_i8 * const restrict retarray, } -extern void mminloc1_8_r17 (gfc_array_i8 * const restrict, +extern void mminloc1_8_r17 (gfc_array_i8 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_8_r17); void -mminloc1_8_r17 (gfc_array_i8 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +mminloc1_8_r17 (gfc_array_i8 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_8_r17 (gfc_array_i8 * const restrict retarray, } -extern void sminloc1_8_r17 (gfc_array_i8 * const restrict, +extern void sminloc1_8_r17 (gfc_array_i8 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_8_r17); void -sminloc1_8_r17 (gfc_array_i8 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +sminloc1_8_r17 (gfc_array_i8 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_8_r4.c b/libgfortran/generated/minloc1_8_r4.c index 14e491fc682f..b0d5d151c784 100644 --- a/libgfortran/generated/minloc1_8_r4.c +++ b/libgfortran/generated/minloc1_8_r4.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_8_r4 (gfc_array_i8 * const restrict, +extern void minloc1_8_r4 (gfc_array_i8 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_8_r4); void -minloc1_8_r4 (gfc_array_i8 * const restrict retarray, - gfc_array_r4 * const restrict array, +minloc1_8_r4 (gfc_array_i8 * const restrict retarray, + gfc_array_r4 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_8_r4 (gfc_array_i8 * const restrict retarray, } -extern void mminloc1_8_r4 (gfc_array_i8 * const restrict, +extern void mminloc1_8_r4 (gfc_array_i8 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_8_r4); void -mminloc1_8_r4 (gfc_array_i8 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +mminloc1_8_r4 (gfc_array_i8 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_8_r4 (gfc_array_i8 * const restrict retarray, } -extern void sminloc1_8_r4 (gfc_array_i8 * const restrict, +extern void sminloc1_8_r4 (gfc_array_i8 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_8_r4); void -sminloc1_8_r4 (gfc_array_i8 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +sminloc1_8_r4 (gfc_array_i8 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minloc1_8_r8.c b/libgfortran/generated/minloc1_8_r8.c index 188a0cdf520f..2b12a8ae8d55 100644 --- a/libgfortran/generated/minloc1_8_r8.c +++ b/libgfortran/generated/minloc1_8_r8.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define HAVE_BACK_ARG 1 -extern void minloc1_8_r8 (gfc_array_i8 * const restrict, +extern void minloc1_8_r8 (gfc_array_i8 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 back); export_proto(minloc1_8_r8); void -minloc1_8_r8 (gfc_array_i8 * const restrict retarray, - gfc_array_r8 * const restrict array, +minloc1_8_r8 (gfc_array_i8 * const restrict retarray, + gfc_array_r8 * const restrict array, const index_type * const restrict pdim, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -226,15 +226,15 @@ minloc1_8_r8 (gfc_array_i8 * const restrict retarray, } -extern void mminloc1_8_r8 (gfc_array_i8 * const restrict, +extern void mminloc1_8_r8 (gfc_array_i8 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict, GFC_LOGICAL_4 back); export_proto(mminloc1_8_r8); void -mminloc1_8_r8 (gfc_array_i8 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +mminloc1_8_r8 (gfc_array_i8 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; @@ -459,15 +459,15 @@ mminloc1_8_r8 (gfc_array_i8 * const restrict retarray, } -extern void sminloc1_8_r8 (gfc_array_i8 * const restrict, +extern void sminloc1_8_r8 (gfc_array_i8 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4 back); export_proto(sminloc1_8_r8); void -sminloc1_8_r8 (gfc_array_i8 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +sminloc1_8_r8 (gfc_array_i8 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minval_i1.c b/libgfortran/generated/minval_i1.c index f27dfa1ac85e..fcf70e0e03d1 100644 --- a/libgfortran/generated/minval_i1.c +++ b/libgfortran/generated/minval_i1.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_1) && defined (HAVE_GFC_INTEGER_1) -extern void minval_i1 (gfc_array_i1 * const restrict, +extern void minval_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict); export_proto(minval_i1); void -minval_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, +minval_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ minval_i1 (gfc_array_i1 * const restrict retarray, } -extern void mminval_i1 (gfc_array_i1 * const restrict, +extern void mminval_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mminval_i1); void -mminval_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +mminval_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mminval_i1 (gfc_array_i1 * const restrict retarray, } -extern void sminval_i1 (gfc_array_i1 * const restrict, +extern void sminval_i1 (gfc_array_i1 * const restrict, gfc_array_i1 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(sminval_i1); void -sminval_i1 (gfc_array_i1 * const restrict retarray, - gfc_array_i1 * const restrict array, - const index_type * const restrict pdim, +sminval_i1 (gfc_array_i1 * const restrict retarray, + gfc_array_i1 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minval_i16.c b/libgfortran/generated/minval_i16.c index a1da87483c68..e35fd997629b 100644 --- a/libgfortran/generated/minval_i16.c +++ b/libgfortran/generated/minval_i16.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_16) && defined (HAVE_GFC_INTEGER_16) -extern void minval_i16 (gfc_array_i16 * const restrict, +extern void minval_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict); export_proto(minval_i16); void -minval_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, +minval_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ minval_i16 (gfc_array_i16 * const restrict retarray, } -extern void mminval_i16 (gfc_array_i16 * const restrict, +extern void mminval_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mminval_i16); void -mminval_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +mminval_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mminval_i16 (gfc_array_i16 * const restrict retarray, } -extern void sminval_i16 (gfc_array_i16 * const restrict, +extern void sminval_i16 (gfc_array_i16 * const restrict, gfc_array_i16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(sminval_i16); void -sminval_i16 (gfc_array_i16 * const restrict retarray, - gfc_array_i16 * const restrict array, - const index_type * const restrict pdim, +sminval_i16 (gfc_array_i16 * const restrict retarray, + gfc_array_i16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minval_i2.c b/libgfortran/generated/minval_i2.c index 2ea0e7629d80..ac14b0e44ff6 100644 --- a/libgfortran/generated/minval_i2.c +++ b/libgfortran/generated/minval_i2.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_2) && defined (HAVE_GFC_INTEGER_2) -extern void minval_i2 (gfc_array_i2 * const restrict, +extern void minval_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict); export_proto(minval_i2); void -minval_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, +minval_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ minval_i2 (gfc_array_i2 * const restrict retarray, } -extern void mminval_i2 (gfc_array_i2 * const restrict, +extern void mminval_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mminval_i2); void -mminval_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +mminval_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mminval_i2 (gfc_array_i2 * const restrict retarray, } -extern void sminval_i2 (gfc_array_i2 * const restrict, +extern void sminval_i2 (gfc_array_i2 * const restrict, gfc_array_i2 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(sminval_i2); void -sminval_i2 (gfc_array_i2 * const restrict retarray, - gfc_array_i2 * const restrict array, - const index_type * const restrict pdim, +sminval_i2 (gfc_array_i2 * const restrict retarray, + gfc_array_i2 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minval_i4.c b/libgfortran/generated/minval_i4.c index 30df475d3996..b40edc64c797 100644 --- a/libgfortran/generated/minval_i4.c +++ b/libgfortran/generated/minval_i4.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_4) && defined (HAVE_GFC_INTEGER_4) -extern void minval_i4 (gfc_array_i4 * const restrict, +extern void minval_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict); export_proto(minval_i4); void -minval_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, +minval_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ minval_i4 (gfc_array_i4 * const restrict retarray, } -extern void mminval_i4 (gfc_array_i4 * const restrict, +extern void mminval_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mminval_i4); void -mminval_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +mminval_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mminval_i4 (gfc_array_i4 * const restrict retarray, } -extern void sminval_i4 (gfc_array_i4 * const restrict, +extern void sminval_i4 (gfc_array_i4 * const restrict, gfc_array_i4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(sminval_i4); void -sminval_i4 (gfc_array_i4 * const restrict retarray, - gfc_array_i4 * const restrict array, - const index_type * const restrict pdim, +sminval_i4 (gfc_array_i4 * const restrict retarray, + gfc_array_i4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minval_i8.c b/libgfortran/generated/minval_i8.c index 4da720271a2e..4152132d89ae 100644 --- a/libgfortran/generated/minval_i8.c +++ b/libgfortran/generated/minval_i8.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_INTEGER_8) && defined (HAVE_GFC_INTEGER_8) -extern void minval_i8 (gfc_array_i8 * const restrict, +extern void minval_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict); export_proto(minval_i8); void -minval_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, +minval_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ minval_i8 (gfc_array_i8 * const restrict retarray, } -extern void mminval_i8 (gfc_array_i8 * const restrict, +extern void mminval_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mminval_i8); void -mminval_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +mminval_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mminval_i8 (gfc_array_i8 * const restrict retarray, } -extern void sminval_i8 (gfc_array_i8 * const restrict, +extern void sminval_i8 (gfc_array_i8 * const restrict, gfc_array_i8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(sminval_i8); void -sminval_i8 (gfc_array_i8 * const restrict retarray, - gfc_array_i8 * const restrict array, - const index_type * const restrict pdim, +sminval_i8 (gfc_array_i8 * const restrict retarray, + gfc_array_i8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minval_r10.c b/libgfortran/generated/minval_r10.c index b3b729da9006..0fc412125b94 100644 --- a/libgfortran/generated/minval_r10.c +++ b/libgfortran/generated/minval_r10.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_REAL_10) && defined (HAVE_GFC_REAL_10) -extern void minval_r10 (gfc_array_r10 * const restrict, +extern void minval_r10 (gfc_array_r10 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict); export_proto(minval_r10); void -minval_r10 (gfc_array_r10 * const restrict retarray, - gfc_array_r10 * const restrict array, +minval_r10 (gfc_array_r10 * const restrict retarray, + gfc_array_r10 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ minval_r10 (gfc_array_r10 * const restrict retarray, } -extern void mminval_r10 (gfc_array_r10 * const restrict, +extern void mminval_r10 (gfc_array_r10 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mminval_r10); void -mminval_r10 (gfc_array_r10 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +mminval_r10 (gfc_array_r10 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mminval_r10 (gfc_array_r10 * const restrict retarray, } -extern void sminval_r10 (gfc_array_r10 * const restrict, +extern void sminval_r10 (gfc_array_r10 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(sminval_r10); void -sminval_r10 (gfc_array_r10 * const restrict retarray, - gfc_array_r10 * const restrict array, - const index_type * const restrict pdim, +sminval_r10 (gfc_array_r10 * const restrict retarray, + gfc_array_r10 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minval_r16.c b/libgfortran/generated/minval_r16.c index 3137d054fdf0..4dedffd07934 100644 --- a/libgfortran/generated/minval_r16.c +++ b/libgfortran/generated/minval_r16.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_REAL_16) && defined (HAVE_GFC_REAL_16) -extern void minval_r16 (gfc_array_r16 * const restrict, +extern void minval_r16 (gfc_array_r16 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict); export_proto(minval_r16); void -minval_r16 (gfc_array_r16 * const restrict retarray, - gfc_array_r16 * const restrict array, +minval_r16 (gfc_array_r16 * const restrict retarray, + gfc_array_r16 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ minval_r16 (gfc_array_r16 * const restrict retarray, } -extern void mminval_r16 (gfc_array_r16 * const restrict, +extern void mminval_r16 (gfc_array_r16 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mminval_r16); void -mminval_r16 (gfc_array_r16 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +mminval_r16 (gfc_array_r16 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mminval_r16 (gfc_array_r16 * const restrict retarray, } -extern void sminval_r16 (gfc_array_r16 * const restrict, +extern void sminval_r16 (gfc_array_r16 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(sminval_r16); void -sminval_r16 (gfc_array_r16 * const restrict retarray, - gfc_array_r16 * const restrict array, - const index_type * const restrict pdim, +sminval_r16 (gfc_array_r16 * const restrict retarray, + gfc_array_r16 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minval_r17.c b/libgfortran/generated/minval_r17.c index 3772fbee3ea0..efb4c6513fc2 100644 --- a/libgfortran/generated/minval_r17.c +++ b/libgfortran/generated/minval_r17.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_REAL_17) && defined (HAVE_GFC_REAL_17) -extern void minval_r17 (gfc_array_r17 * const restrict, +extern void minval_r17 (gfc_array_r17 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict); export_proto(minval_r17); void -minval_r17 (gfc_array_r17 * const restrict retarray, - gfc_array_r17 * const restrict array, +minval_r17 (gfc_array_r17 * const restrict retarray, + gfc_array_r17 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ minval_r17 (gfc_array_r17 * const restrict retarray, } -extern void mminval_r17 (gfc_array_r17 * const restrict, +extern void mminval_r17 (gfc_array_r17 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mminval_r17); void -mminval_r17 (gfc_array_r17 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +mminval_r17 (gfc_array_r17 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mminval_r17 (gfc_array_r17 * const restrict retarray, } -extern void sminval_r17 (gfc_array_r17 * const restrict, +extern void sminval_r17 (gfc_array_r17 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(sminval_r17); void -sminval_r17 (gfc_array_r17 * const restrict retarray, - gfc_array_r17 * const restrict array, - const index_type * const restrict pdim, +sminval_r17 (gfc_array_r17 * const restrict retarray, + gfc_array_r17 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minval_r4.c b/libgfortran/generated/minval_r4.c index ecc054a5d6d9..4370f4d13169 100644 --- a/libgfortran/generated/minval_r4.c +++ b/libgfortran/generated/minval_r4.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_REAL_4) && defined (HAVE_GFC_REAL_4) -extern void minval_r4 (gfc_array_r4 * const restrict, +extern void minval_r4 (gfc_array_r4 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict); export_proto(minval_r4); void -minval_r4 (gfc_array_r4 * const restrict retarray, - gfc_array_r4 * const restrict array, +minval_r4 (gfc_array_r4 * const restrict retarray, + gfc_array_r4 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ minval_r4 (gfc_array_r4 * const restrict retarray, } -extern void mminval_r4 (gfc_array_r4 * const restrict, +extern void mminval_r4 (gfc_array_r4 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mminval_r4); void -mminval_r4 (gfc_array_r4 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +mminval_r4 (gfc_array_r4 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mminval_r4 (gfc_array_r4 * const restrict retarray, } -extern void sminval_r4 (gfc_array_r4 * const restrict, +extern void sminval_r4 (gfc_array_r4 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(sminval_r4); void -sminval_r4 (gfc_array_r4 * const restrict retarray, - gfc_array_r4 * const restrict array, - const index_type * const restrict pdim, +sminval_r4 (gfc_array_r4 * const restrict retarray, + gfc_array_r4 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/minval_r8.c b/libgfortran/generated/minval_r8.c index 5e5ca794f57c..bab37af88d79 100644 --- a/libgfortran/generated/minval_r8.c +++ b/libgfortran/generated/minval_r8.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_REAL_8) && defined (HAVE_GFC_REAL_8) -extern void minval_r8 (gfc_array_r8 * const restrict, +extern void minval_r8 (gfc_array_r8 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict); export_proto(minval_r8); void -minval_r8 (gfc_array_r8 * const restrict retarray, - gfc_array_r8 * const restrict array, +minval_r8 (gfc_array_r8 * const restrict retarray, + gfc_array_r8 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; @@ -202,15 +202,15 @@ minval_r8 (gfc_array_r8 * const restrict retarray, } -extern void mminval_r8 (gfc_array_r8 * const restrict, +extern void mminval_r8 (gfc_array_r8 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, gfc_array_l1 * const restrict); export_proto(mminval_r8); void -mminval_r8 (gfc_array_r8 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +mminval_r8 (gfc_array_r8 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, gfc_array_l1 * const restrict mask) { index_type count[GFC_MAX_DIMENSIONS]; @@ -420,15 +420,15 @@ mminval_r8 (gfc_array_r8 * const restrict retarray, } -extern void sminval_r8 (gfc_array_r8 * const restrict, +extern void sminval_r8 (gfc_array_r8 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict, GFC_LOGICAL_4 *); export_proto(sminval_r8); void -sminval_r8 (gfc_array_r8 * const restrict retarray, - gfc_array_r8 * const restrict array, - const index_type * const restrict pdim, +sminval_r8 (gfc_array_r8 * const restrict retarray, + gfc_array_r8 * const restrict array, + const index_type * const restrict pdim, GFC_LOGICAL_4 * mask) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/norm2_r10.c b/libgfortran/generated/norm2_r10.c index 98625a42db7b..c879f54cbfc9 100644 --- a/libgfortran/generated/norm2_r10.c +++ b/libgfortran/generated/norm2_r10.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define MATHFUNC(funcname) funcname ## l -extern void norm2_r10 (gfc_array_r10 * const restrict, +extern void norm2_r10 (gfc_array_r10 * const restrict, gfc_array_r10 * const restrict, const index_type * const restrict); export_proto(norm2_r10); void -norm2_r10 (gfc_array_r10 * const restrict retarray, - gfc_array_r10 * const restrict array, +norm2_r10 (gfc_array_r10 * const restrict retarray, + gfc_array_r10 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/norm2_r16.c b/libgfortran/generated/norm2_r16.c index 62c5a4065dc2..84fbe3b0c932 100644 --- a/libgfortran/generated/norm2_r16.c +++ b/libgfortran/generated/norm2_r16.c @@ -40,13 +40,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #endif -extern void norm2_r16 (gfc_array_r16 * const restrict, +extern void norm2_r16 (gfc_array_r16 * const restrict, gfc_array_r16 * const restrict, const index_type * const restrict); export_proto(norm2_r16); void -norm2_r16 (gfc_array_r16 * const restrict retarray, - gfc_array_r16 * const restrict array, +norm2_r16 (gfc_array_r16 * const restrict retarray, + gfc_array_r16 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/norm2_r17.c b/libgfortran/generated/norm2_r17.c index 91fa70423660..72ad123df17a 100644 --- a/libgfortran/generated/norm2_r17.c +++ b/libgfortran/generated/norm2_r17.c @@ -38,13 +38,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #endif -extern void norm2_r17 (gfc_array_r17 * const restrict, +extern void norm2_r17 (gfc_array_r17 * const restrict, gfc_array_r17 * const restrict, const index_type * const restrict); export_proto(norm2_r17); void -norm2_r17 (gfc_array_r17 * const restrict retarray, - gfc_array_r17 * const restrict array, +norm2_r17 (gfc_array_r17 * const restrict retarray, + gfc_array_r17 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/norm2_r4.c b/libgfortran/generated/norm2_r4.c index 164963af6bd7..65ba9822e4dc 100644 --- a/libgfortran/generated/norm2_r4.c +++ b/libgfortran/generated/norm2_r4.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define MATHFUNC(funcname) funcname ## f -extern void norm2_r4 (gfc_array_r4 * const restrict, +extern void norm2_r4 (gfc_array_r4 * const restrict, gfc_array_r4 * const restrict, const index_type * const restrict); export_proto(norm2_r4); void -norm2_r4 (gfc_array_r4 * const restrict retarray, - gfc_array_r4 * const restrict array, +norm2_r4 (gfc_array_r4 * const restrict retarray, + gfc_array_r4 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/norm2_r8.c b/libgfortran/generated/norm2_r8.c index fecf60ede544..c10e6a046138 100644 --- a/libgfortran/generated/norm2_r8.c +++ b/libgfortran/generated/norm2_r8.c @@ -32,13 +32,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define MATHFUNC(funcname) funcname -extern void norm2_r8 (gfc_array_r8 * const restrict, +extern void norm2_r8 (gfc_array_r8 * const restrict, gfc_array_r8 * const restrict, const index_type * const restrict); export_proto(norm2_r8); void -norm2_r8 (gfc_array_r8 * const restrict retarray, - gfc_array_r8 * const restrict array, +norm2_r8 (gfc_array_r8 * const restrict retarray, + gfc_array_r8 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/parity_l1.c b/libgfortran/generated/parity_l1.c index 0e1007ad3085..7d5bc9128f61 100644 --- a/libgfortran/generated/parity_l1.c +++ b/libgfortran/generated/parity_l1.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_LOGICAL_1) && defined (HAVE_GFC_LOGICAL_1) -extern void parity_l1 (gfc_array_l1 * const restrict, +extern void parity_l1 (gfc_array_l1 * const restrict, gfc_array_l1 * const restrict, const index_type * const restrict); export_proto(parity_l1); void -parity_l1 (gfc_array_l1 * const restrict retarray, - gfc_array_l1 * const restrict array, +parity_l1 (gfc_array_l1 * const restrict retarray, + gfc_array_l1 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/parity_l16.c b/libgfortran/generated/parity_l16.c index d0c1065bac38..3276e1b84892 100644 --- a/libgfortran/generated/parity_l16.c +++ b/libgfortran/generated/parity_l16.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_LOGICAL_16) && defined (HAVE_GFC_LOGICAL_16) -extern void parity_l16 (gfc_array_l16 * const restrict, +extern void parity_l16 (gfc_array_l16 * const restrict, gfc_array_l16 * const restrict, const index_type * const restrict); export_proto(parity_l16); void -parity_l16 (gfc_array_l16 * const restrict retarray, - gfc_array_l16 * const restrict array, +parity_l16 (gfc_array_l16 * const restrict retarray, + gfc_array_l16 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/parity_l2.c b/libgfortran/generated/parity_l2.c index bff60b224c0e..1f1221451f96 100644 --- a/libgfortran/generated/parity_l2.c +++ b/libgfortran/generated/parity_l2.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_LOGICAL_2) && defined (HAVE_GFC_LOGICAL_2) -extern void parity_l2 (gfc_array_l2 * const restrict, +extern void parity_l2 (gfc_array_l2 * const restrict, gfc_array_l2 * const restrict, const index_type * const restrict); export_proto(parity_l2); void -parity_l2 (gfc_array_l2 * const restrict retarray, - gfc_array_l2 * const restrict array, +parity_l2 (gfc_array_l2 * const restrict retarray, + gfc_array_l2 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/parity_l4.c b/libgfortran/generated/parity_l4.c index 3ac03cb9d29a..dcc8cd45e9af 100644 --- a/libgfortran/generated/parity_l4.c +++ b/libgfortran/generated/parity_l4.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_LOGICAL_4) && defined (HAVE_GFC_LOGICAL_4) -extern void parity_l4 (gfc_array_l4 * const restrict, +extern void parity_l4 (gfc_array_l4 * const restrict, gfc_array_l4 * const restrict, const index_type * const restrict); export_proto(parity_l4); void -parity_l4 (gfc_array_l4 * const restrict retarray, - gfc_array_l4 * const restrict array, +parity_l4 (gfc_array_l4 * const restrict retarray, + gfc_array_l4 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/generated/parity_l8.c b/libgfortran/generated/parity_l8.c index 6ce6a8bd6389..dee33acef3ba 100644 --- a/libgfortran/generated/parity_l8.c +++ b/libgfortran/generated/parity_l8.c @@ -29,13 +29,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined (HAVE_GFC_LOGICAL_8) && defined (HAVE_GFC_LOGICAL_8) -extern void parity_l8 (gfc_array_l8 * const restrict, +extern void parity_l8 (gfc_array_l8 * const restrict, gfc_array_l8 * const restrict, const index_type * const restrict); export_proto(parity_l8); void -parity_l8 (gfc_array_l8 * const restrict retarray, - gfc_array_l8 * const restrict array, +parity_l8 (gfc_array_l8 * const restrict retarray, + gfc_array_l8 * const restrict array, const index_type * const restrict pdim) { index_type count[GFC_MAX_DIMENSIONS]; diff --git a/libgfortran/intrinsics/stat.c b/libgfortran/intrinsics/stat.c index 8d32f223b24f..63a57cd05eec 100644 --- a/libgfortran/intrinsics/stat.c +++ b/libgfortran/intrinsics/stat.c @@ -35,22 +35,22 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #ifdef HAVE_STAT -/* SUBROUTINE STAT(FILE, SARRAY, STATUS) +/* SUBROUTINE STAT(NAME, VALUES, STATUS) CHARACTER(len=*), INTENT(IN) :: FILE - INTEGER, INTENT(OUT), :: SARRAY(13) + INTEGER, INTENT(OUT), :: VALUES(13) INTEGER, INTENT(OUT), OPTIONAL :: STATUS - FUNCTION STAT(FILE, SARRAY) + FUNCTION STAT(NAME, VALUES) INTEGER STAT CHARACTER(len=*), INTENT(IN) :: FILE - INTEGER, INTENT(OUT), :: SARRAY(13) */ + INTEGER, INTENT(OUT), :: VALUES(13) */ /*extern void stat_i4_sub_0 (char *, gfc_array_i4 *, GFC_INTEGER_4 *, gfc_charlen_type, int); internal_proto(stat_i4_sub_0);*/ static void -stat_i4_sub_0 (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status, +stat_i4_sub_0 (char *name, gfc_array_i4 *values, GFC_INTEGER_4 *status, gfc_charlen_type name_len, int is_lstat __attribute__ ((unused))) { int val; @@ -58,12 +58,12 @@ stat_i4_sub_0 (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status, struct stat sb; /* If the rank of the array is not 1, abort. */ - if (GFC_DESCRIPTOR_RANK (sarray) != 1) - runtime_error ("Array rank of SARRAY is not 1."); + if (GFC_DESCRIPTOR_RANK (values) != 1) + runtime_error ("Array rank of VALUES is not 1."); /* If the array is too small, abort. */ - if (GFC_DESCRIPTOR_EXTENT(sarray,0) < 13) - runtime_error ("Array size of SARRAY is too small."); + if (GFC_DESCRIPTOR_EXTENT(values,0) < 13) + runtime_error ("Array size of VALUES is too small."); /* Make a null terminated copy of the string. */ str = fc_strdup (name, name_len); @@ -80,57 +80,70 @@ stat_i4_sub_0 (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status, if (val == 0) { - index_type stride = GFC_DESCRIPTOR_STRIDE(sarray,0); + index_type stride = GFC_DESCRIPTOR_STRIDE(values,0); + + /* Return -1 for any value overflowing INT32_MAX. */ + for (int i = 0; i < 13; i++) + values->base_addr[i * stride] = -1; /* Device ID */ - sarray->base_addr[0 * stride] = sb.st_dev; + if (sb.st_dev <= INT32_MAX) + values->base_addr[0 * stride] = sb.st_dev; /* Inode number */ - sarray->base_addr[1 * stride] = sb.st_ino; + if (sb.st_ino <= INT32_MAX) + values->base_addr[1 * stride] = sb.st_ino; /* File mode */ - sarray->base_addr[2 * stride] = sb.st_mode; + if (sb.st_mode <= INT32_MAX) + values->base_addr[2 * stride] = sb.st_mode; /* Number of (hard) links */ - sarray->base_addr[3 * stride] = sb.st_nlink; + if (sb.st_nlink <= INT32_MAX) + values->base_addr[3 * stride] = sb.st_nlink; /* Owner's uid */ - sarray->base_addr[4 * stride] = sb.st_uid; + if (sb.st_uid <= INT32_MAX) + values->base_addr[4 * stride] = sb.st_uid; /* Owner's gid */ - sarray->base_addr[5 * stride] = sb.st_gid; + if (sb.st_gid <= INT32_MAX) + values->base_addr[5 * stride] = sb.st_gid; /* ID of device containing directory entry for file (0 if not available) */ #if HAVE_STRUCT_STAT_ST_RDEV - sarray->base_addr[6 * stride] = sb.st_rdev; + if (sb.st_rdev <= INT32_MAX) + values->base_addr[6 * stride] = sb.st_rdev; #else - sarray->base_addr[6 * stride] = 0; + values->base_addr[6 * stride] = 0; #endif /* File size (bytes) */ - sarray->base_addr[7 * stride] = sb.st_size; + if (sb.st_size <= INT32_MAX) + values->base_addr[7 * stride] = sb.st_size; /* Last access time */ - sarray->base_addr[8 * stride] = sb.st_atime; + if (sb.st_atime <= INT32_MAX) + values->base_addr[8 * stride] = sb.st_atime; /* Last modification time */ - sarray->base_addr[9 * stride] = sb.st_mtime; + if (sb.st_mtime <= INT32_MAX) + values->base_addr[9 * stride] = sb.st_mtime; /* Last file status change time */ - sarray->base_addr[10 * stride] = sb.st_ctime; + if (sb.st_ctime <= INT32_MAX) + values->base_addr[10 * stride] = sb.st_ctime; /* Preferred I/O block size (-1 if not available) */ #if HAVE_STRUCT_STAT_ST_BLKSIZE - sarray->base_addr[11 * stride] = sb.st_blksize; -#else - sarray->base_addr[11 * stride] = -1; + if (sb.st_blksize <= INT32_MAX) + values->base_addr[11 * stride] = sb.st_blksize; #endif /* Number of blocks allocated (-1 if not available) */ #if HAVE_STRUCT_STAT_ST_BLOCKS - sarray->base_addr[12 * stride] = sb.st_blocks; -#else - sarray->base_addr[12 * stride] = -1; + if (sb.st_blocks <= INT32_MAX) + values->base_addr[12 * stride] = sb.st_blocks; #endif } @@ -144,10 +157,10 @@ extern void stat_i4_sub (char *, gfc_array_i4 *, GFC_INTEGER_4 *, iexport_proto(stat_i4_sub); void -stat_i4_sub (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status, +stat_i4_sub (char *name, gfc_array_i4 *values, GFC_INTEGER_4 *status, gfc_charlen_type name_len) { - stat_i4_sub_0 (name, sarray, status, name_len, 0); + stat_i4_sub_0 (name, values, status, name_len, 0); } iexport(stat_i4_sub); @@ -157,17 +170,17 @@ extern void lstat_i4_sub (char *, gfc_array_i4 *, GFC_INTEGER_4 *, iexport_proto(lstat_i4_sub); void -lstat_i4_sub (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status, +lstat_i4_sub (char *name, gfc_array_i4 *values, GFC_INTEGER_4 *status, gfc_charlen_type name_len) { - stat_i4_sub_0 (name, sarray, status, name_len, 1); + stat_i4_sub_0 (name, values, status, name_len, 1); } iexport(lstat_i4_sub); static void -stat_i8_sub_0 (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status, +stat_i8_sub_0 (char *name, gfc_array_i8 *values, GFC_INTEGER_8 *status, gfc_charlen_type name_len, int is_lstat __attribute__ ((unused))) { int val; @@ -175,12 +188,12 @@ stat_i8_sub_0 (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status, struct stat sb; /* If the rank of the array is not 1, abort. */ - if (GFC_DESCRIPTOR_RANK (sarray) != 1) - runtime_error ("Array rank of SARRAY is not 1."); + if (GFC_DESCRIPTOR_RANK (values) != 1) + runtime_error ("Array rank of VALUES is not 1."); /* If the array is too small, abort. */ - if (GFC_DESCRIPTOR_EXTENT(sarray,0) < 13) - runtime_error ("Array size of SARRAY is too small."); + if (GFC_DESCRIPTOR_EXTENT(values,0) < 13) + runtime_error ("Array size of VALUES is too small."); /* Make a null terminated copy of the string. */ str = fc_strdup (name, name_len); @@ -197,57 +210,57 @@ stat_i8_sub_0 (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status, if (val == 0) { - index_type stride = GFC_DESCRIPTOR_STRIDE(sarray,0); + index_type stride = GFC_DESCRIPTOR_STRIDE(values,0); /* Device ID */ - sarray->base_addr[0] = sb.st_dev; + values->base_addr[0] = sb.st_dev; /* Inode number */ - sarray->base_addr[stride] = sb.st_ino; + values->base_addr[stride] = sb.st_ino; /* File mode */ - sarray->base_addr[2 * stride] = sb.st_mode; + values->base_addr[2 * stride] = sb.st_mode; /* Number of (hard) links */ - sarray->base_addr[3 * stride] = sb.st_nlink; + values->base_addr[3 * stride] = sb.st_nlink; /* Owner's uid */ - sarray->base_addr[4 * stride] = sb.st_uid; + values->base_addr[4 * stride] = sb.st_uid; /* Owner's gid */ - sarray->base_addr[5 * stride] = sb.st_gid; + values->base_addr[5 * stride] = sb.st_gid; /* ID of device containing directory entry for file (0 if not available) */ #if HAVE_STRUCT_STAT_ST_RDEV - sarray->base_addr[6 * stride] = sb.st_rdev; + values->base_addr[6 * stride] = sb.st_rdev; #else - sarray->base_addr[6 * stride] = 0; + values->base_addr[6 * stride] = 0; #endif /* File size (bytes) */ - sarray->base_addr[7 * stride] = sb.st_size; + values->base_addr[7 * stride] = sb.st_size; /* Last access time */ - sarray->base_addr[8 * stride] = sb.st_atime; + values->base_addr[8 * stride] = sb.st_atime; /* Last modification time */ - sarray->base_addr[9 * stride] = sb.st_mtime; + values->base_addr[9 * stride] = sb.st_mtime; /* Last file status change time */ - sarray->base_addr[10 * stride] = sb.st_ctime; + values->base_addr[10 * stride] = sb.st_ctime; /* Preferred I/O block size (-1 if not available) */ #if HAVE_STRUCT_STAT_ST_BLKSIZE - sarray->base_addr[11 * stride] = sb.st_blksize; + values->base_addr[11 * stride] = sb.st_blksize; #else - sarray->base_addr[11 * stride] = -1; + values->base_addr[11 * stride] = -1; #endif /* Number of blocks allocated (-1 if not available) */ #if HAVE_STRUCT_STAT_ST_BLOCKS - sarray->base_addr[12 * stride] = sb.st_blocks; + values->base_addr[12 * stride] = sb.st_blocks; #else - sarray->base_addr[12 * stride] = -1; + values->base_addr[12 * stride] = -1; #endif } @@ -261,10 +274,10 @@ extern void stat_i8_sub (char *, gfc_array_i8 *, GFC_INTEGER_8 *, iexport_proto(stat_i8_sub); void -stat_i8_sub (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status, +stat_i8_sub (char *name, gfc_array_i8 *values, GFC_INTEGER_8 *status, gfc_charlen_type name_len) { - stat_i8_sub_0 (name, sarray, status, name_len, 0); + stat_i8_sub_0 (name, values, status, name_len, 0); } iexport(stat_i8_sub); @@ -275,10 +288,10 @@ extern void lstat_i8_sub (char *, gfc_array_i8 *, GFC_INTEGER_8 *, iexport_proto(lstat_i8_sub); void -lstat_i8_sub (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status, +lstat_i8_sub (char *name, gfc_array_i8 *values, GFC_INTEGER_8 *status, gfc_charlen_type name_len) { - stat_i8_sub_0 (name, sarray, status, name_len, 1); + stat_i8_sub_0 (name, values, status, name_len, 1); } iexport(lstat_i8_sub); @@ -288,10 +301,10 @@ extern GFC_INTEGER_4 stat_i4 (char *, gfc_array_i4 *, gfc_charlen_type); export_proto(stat_i4); GFC_INTEGER_4 -stat_i4 (char *name, gfc_array_i4 *sarray, gfc_charlen_type name_len) +stat_i4 (char *name, gfc_array_i4 *values, gfc_charlen_type name_len) { GFC_INTEGER_4 val; - stat_i4_sub (name, sarray, &val, name_len); + stat_i4_sub (name, values, &val, name_len); return val; } @@ -299,32 +312,32 @@ extern GFC_INTEGER_8 stat_i8 (char *, gfc_array_i8 *, gfc_charlen_type); export_proto(stat_i8); GFC_INTEGER_8 -stat_i8 (char *name, gfc_array_i8 *sarray, gfc_charlen_type name_len) +stat_i8 (char *name, gfc_array_i8 *values, gfc_charlen_type name_len) { GFC_INTEGER_8 val; - stat_i8_sub (name, sarray, &val, name_len); + stat_i8_sub (name, values, &val, name_len); return val; } -/* SUBROUTINE LSTAT(FILE, SARRAY, STATUS) +/* SUBROUTINE LSTAT(NAME, VALUES, STATUS) CHARACTER(len=*), INTENT(IN) :: FILE - INTEGER, INTENT(OUT), :: SARRAY(13) + INTEGER, INTENT(OUT), :: VALUES(13) INTEGER, INTENT(OUT), OPTIONAL :: STATUS - FUNCTION LSTAT(FILE, SARRAY) + FUNCTION LSTAT(NAME, VALUES) INTEGER LSTAT CHARACTER(len=*), INTENT(IN) :: FILE - INTEGER, INTENT(OUT), :: SARRAY(13) */ + INTEGER, INTENT(OUT), :: VALUES(13) */ extern GFC_INTEGER_4 lstat_i4 (char *, gfc_array_i4 *, gfc_charlen_type); export_proto(lstat_i4); GFC_INTEGER_4 -lstat_i4 (char *name, gfc_array_i4 *sarray, gfc_charlen_type name_len) +lstat_i4 (char *name, gfc_array_i4 *values, gfc_charlen_type name_len) { GFC_INTEGER_4 val; - lstat_i4_sub (name, sarray, &val, name_len); + lstat_i4_sub (name, values, &val, name_len); return val; } @@ -332,10 +345,10 @@ extern GFC_INTEGER_8 lstat_i8 (char *, gfc_array_i8 *, gfc_charlen_type); export_proto(lstat_i8); GFC_INTEGER_8 -lstat_i8 (char *name, gfc_array_i8 *sarray, gfc_charlen_type name_len) +lstat_i8 (char *name, gfc_array_i8 *values, gfc_charlen_type name_len) { GFC_INTEGER_8 val; - lstat_i8_sub (name, sarray, &val, name_len); + lstat_i8_sub (name, values, &val, name_len); return val; } @@ -344,32 +357,32 @@ lstat_i8 (char *name, gfc_array_i8 *sarray, gfc_charlen_type name_len) #ifdef HAVE_FSTAT -/* SUBROUTINE FSTAT(UNIT, SARRAY, STATUS) +/* SUBROUTINE FSTAT(UNIT, VALUES, STATUS) INTEGER, INTENT(IN) :: UNIT - INTEGER, INTENT(OUT) :: SARRAY(13) + INTEGER, INTENT(OUT) :: VALUES(13) INTEGER, INTENT(OUT), OPTIONAL :: STATUS - FUNCTION FSTAT(UNIT, SARRAY) + FUNCTION FSTAT(UNIT, VALUES) INTEGER FSTAT INTEGER, INTENT(IN) :: UNIT - INTEGER, INTENT(OUT) :: SARRAY(13) */ + INTEGER, INTENT(OUT) :: VALUES(13) */ extern void fstat_i4_sub (GFC_INTEGER_4 *, gfc_array_i4 *, GFC_INTEGER_4 *); iexport_proto(fstat_i4_sub); void -fstat_i4_sub (GFC_INTEGER_4 *unit, gfc_array_i4 *sarray, GFC_INTEGER_4 *status) +fstat_i4_sub (GFC_INTEGER_4 *unit, gfc_array_i4 *values, GFC_INTEGER_4 *status) { int val; struct stat sb; /* If the rank of the array is not 1, abort. */ - if (GFC_DESCRIPTOR_RANK (sarray) != 1) - runtime_error ("Array rank of SARRAY is not 1."); + if (GFC_DESCRIPTOR_RANK (values) != 1) + runtime_error ("Array rank of VALUES is not 1."); /* If the array is too small, abort. */ - if (GFC_DESCRIPTOR_EXTENT(sarray,0) < 13) - runtime_error ("Array size of SARRAY is too small."); + if (GFC_DESCRIPTOR_EXTENT(values,0) < 13) + runtime_error ("Array size of VALUES is too small."); /* Convert Fortran unit number to C file descriptor. */ val = unit_to_fd (*unit); @@ -378,57 +391,70 @@ fstat_i4_sub (GFC_INTEGER_4 *unit, gfc_array_i4 *sarray, GFC_INTEGER_4 *status) if (val == 0) { - index_type stride = GFC_DESCRIPTOR_STRIDE(sarray,0); + index_type stride = GFC_DESCRIPTOR_STRIDE(values,0); + + /* Return -1 for any value overflowing INT32_MAX. */ + for (int i = 0; i < 13; i++) + values->base_addr[i * stride] = -1; /* Device ID */ - sarray->base_addr[0 * stride] = sb.st_dev; + if (sb.st_dev <= INT32_MAX) + values->base_addr[0 * stride] = sb.st_dev; /* Inode number */ - sarray->base_addr[1 * stride] = sb.st_ino; + if (sb.st_ino <= INT32_MAX) + values->base_addr[1 * stride] = sb.st_ino; /* File mode */ - sarray->base_addr[2 * stride] = sb.st_mode; + if (sb.st_mode <= INT32_MAX) + values->base_addr[2 * stride] = sb.st_mode; /* Number of (hard) links */ - sarray->base_addr[3 * stride] = sb.st_nlink; + if (sb.st_nlink <= INT32_MAX) + values->base_addr[3 * stride] = sb.st_nlink; /* Owner's uid */ - sarray->base_addr[4 * stride] = sb.st_uid; + if (sb.st_uid <= INT32_MAX) + values->base_addr[4 * stride] = sb.st_uid; /* Owner's gid */ - sarray->base_addr[5 * stride] = sb.st_gid; + if (sb.st_gid <= INT32_MAX) + values->base_addr[5 * stride] = sb.st_gid; /* ID of device containing directory entry for file (0 if not available) */ #if HAVE_STRUCT_STAT_ST_RDEV - sarray->base_addr[6 * stride] = sb.st_rdev; + if (sb.st_rdev <= INT32_MAX) + values->base_addr[6 * stride] = sb.st_rdev; #else - sarray->base_addr[6 * stride] = 0; + values->base_addr[6 * stride] = 0; #endif /* File size (bytes) */ - sarray->base_addr[7 * stride] = sb.st_size; + if (sb.st_size <= INT32_MAX) + values->base_addr[7 * stride] = sb.st_size; /* Last access time */ - sarray->base_addr[8 * stride] = sb.st_atime; + if (sb.st_atime <= INT32_MAX) + values->base_addr[8 * stride] = sb.st_atime; /* Last modification time */ - sarray->base_addr[9 * stride] = sb.st_mtime; + if (sb.st_mtime <= INT32_MAX) + values->base_addr[9 * stride] = sb.st_mtime; /* Last file status change time */ - sarray->base_addr[10 * stride] = sb.st_ctime; + if (sb.st_ctime <= INT32_MAX) + values->base_addr[10 * stride] = sb.st_ctime; /* Preferred I/O block size (-1 if not available) */ #if HAVE_STRUCT_STAT_ST_BLKSIZE - sarray->base_addr[11 * stride] = sb.st_blksize; -#else - sarray->base_addr[11 * stride] = -1; + if (sb.st_blksize <= INT32_MAX) + values->base_addr[11 * stride] = sb.st_blksize; #endif /* Number of blocks allocated (-1 if not available) */ #if HAVE_STRUCT_STAT_ST_BLOCKS - sarray->base_addr[12 * stride] = sb.st_blocks; -#else - sarray->base_addr[12 * stride] = -1; + if (sb.st_blocks <= INT32_MAX) + values->base_addr[12 * stride] = sb.st_blocks; #endif } @@ -441,18 +467,18 @@ extern void fstat_i8_sub (GFC_INTEGER_8 *, gfc_array_i8 *, GFC_INTEGER_8 *); iexport_proto(fstat_i8_sub); void -fstat_i8_sub (GFC_INTEGER_8 *unit, gfc_array_i8 *sarray, GFC_INTEGER_8 *status) +fstat_i8_sub (GFC_INTEGER_8 *unit, gfc_array_i8 *values, GFC_INTEGER_8 *status) { int val; struct stat sb; /* If the rank of the array is not 1, abort. */ - if (GFC_DESCRIPTOR_RANK (sarray) != 1) - runtime_error ("Array rank of SARRAY is not 1."); + if (GFC_DESCRIPTOR_RANK (values) != 1) + runtime_error ("Array rank of VALUES is not 1."); /* If the array is too small, abort. */ - if (GFC_DESCRIPTOR_EXTENT(sarray,0) < 13) - runtime_error ("Array size of SARRAY is too small."); + if (GFC_DESCRIPTOR_EXTENT(values,0) < 13) + runtime_error ("Array size of VALUES is too small."); /* Convert Fortran unit number to C file descriptor. */ val = unit_to_fd ((int) *unit); @@ -461,57 +487,57 @@ fstat_i8_sub (GFC_INTEGER_8 *unit, gfc_array_i8 *sarray, GFC_INTEGER_8 *status) if (val == 0) { - index_type stride = GFC_DESCRIPTOR_STRIDE(sarray,0); + index_type stride = GFC_DESCRIPTOR_STRIDE(values,0); /* Device ID */ - sarray->base_addr[0] = sb.st_dev; + values->base_addr[0] = sb.st_dev; /* Inode number */ - sarray->base_addr[stride] = sb.st_ino; + values->base_addr[stride] = sb.st_ino; /* File mode */ - sarray->base_addr[2 * stride] = sb.st_mode; + values->base_addr[2 * stride] = sb.st_mode; /* Number of (hard) links */ - sarray->base_addr[3 * stride] = sb.st_nlink; + values->base_addr[3 * stride] = sb.st_nlink; /* Owner's uid */ - sarray->base_addr[4 * stride] = sb.st_uid; + values->base_addr[4 * stride] = sb.st_uid; /* Owner's gid */ - sarray->base_addr[5 * stride] = sb.st_gid; + values->base_addr[5 * stride] = sb.st_gid; /* ID of device containing directory entry for file (0 if not available) */ #if HAVE_STRUCT_STAT_ST_RDEV - sarray->base_addr[6 * stride] = sb.st_rdev; + values->base_addr[6 * stride] = sb.st_rdev; #else - sarray->base_addr[6 * stride] = 0; + values->base_addr[6 * stride] = 0; #endif /* File size (bytes) */ - sarray->base_addr[7 * stride] = sb.st_size; + values->base_addr[7 * stride] = sb.st_size; /* Last access time */ - sarray->base_addr[8 * stride] = sb.st_atime; + values->base_addr[8 * stride] = sb.st_atime; /* Last modification time */ - sarray->base_addr[9 * stride] = sb.st_mtime; + values->base_addr[9 * stride] = sb.st_mtime; /* Last file status change time */ - sarray->base_addr[10 * stride] = sb.st_ctime; + values->base_addr[10 * stride] = sb.st_ctime; /* Preferred I/O block size (-1 if not available) */ #if HAVE_STRUCT_STAT_ST_BLKSIZE - sarray->base_addr[11 * stride] = sb.st_blksize; + values->base_addr[11 * stride] = sb.st_blksize; #else - sarray->base_addr[11 * stride] = -1; + values->base_addr[11 * stride] = -1; #endif /* Number of blocks allocated (-1 if not available) */ #if HAVE_STRUCT_STAT_ST_BLOCKS - sarray->base_addr[12 * stride] = sb.st_blocks; + values->base_addr[12 * stride] = sb.st_blocks; #else - sarray->base_addr[12 * stride] = -1; + values->base_addr[12 * stride] = -1; #endif } @@ -524,10 +550,10 @@ extern GFC_INTEGER_4 fstat_i4 (GFC_INTEGER_4 *, gfc_array_i4 *); export_proto(fstat_i4); GFC_INTEGER_4 -fstat_i4 (GFC_INTEGER_4 *unit, gfc_array_i4 *sarray) +fstat_i4 (GFC_INTEGER_4 *unit, gfc_array_i4 *values) { GFC_INTEGER_4 val; - fstat_i4_sub (unit, sarray, &val); + fstat_i4_sub (unit, values, &val); return val; } @@ -535,10 +561,10 @@ extern GFC_INTEGER_8 fstat_i8 (GFC_INTEGER_8 *, gfc_array_i8 *); export_proto(fstat_i8); GFC_INTEGER_8 -fstat_i8 (GFC_INTEGER_8 *unit, gfc_array_i8 *sarray) +fstat_i8 (GFC_INTEGER_8 *unit, gfc_array_i8 *values) { GFC_INTEGER_8 val; - fstat_i8_sub (unit, sarray, &val); + fstat_i8_sub (unit, values, &val); return val; } diff --git a/libgfortran/regenerate.sh b/libgfortran/regenerate.sh new file mode 100755 index 000000000000..a016034c13e9 --- /dev/null +++ b/libgfortran/regenerate.sh @@ -0,0 +1,1250 @@ +#!/bin/sh + +# Unless the user specified their desired m4 implementation through the +# M4 environment variable, find a GNU M4 in the PATH. + +if [ -z "$M4" ] ; then + for prog in gm4 gnum4 m4 ; do + if $prog --version 2>/dev/null | grep -q 'GNU M4' ; then + M4=${prog} + break + fi + done +fi + +if [ -z "$M4" ] ; then + echo "GNU M4 not found" + exit 1 +else + echo "Found GNU M4: ${M4}" +fi + +# Make sure we run in the correct directory + +if [ ! -e "./m4/pow.m4" ] ; then + echo "This script should be run in the libgfortran/ directory" + exit 1 +fi + + +i_all_c=" +generated/all_l1.c +generated/all_l2.c +generated/all_l4.c +generated/all_l8.c +generated/all_l16.c +" + +i_any_c=" +generated/any_l1.c +generated/any_l2.c +generated/any_l4.c +generated/any_l8.c +generated/any_l16.c +" + +i_bessel_c=" +generated/bessel_r4.c +generated/bessel_r8.c +generated/bessel_r10.c +generated/bessel_r16.c +generated/bessel_r17.c +" + +i_count_c=" +generated/count_1_l.c +generated/count_2_l.c +generated/count_4_l.c +generated/count_8_l.c +generated/count_16_l.c +" + +i_iall_c=" +generated/iall_i1.c +generated/iall_i2.c +generated/iall_i4.c +generated/iall_i8.c +generated/iall_i16.c +" + +i_iany_c=" +generated/iany_i1.c +generated/iany_i2.c +generated/iany_i4.c +generated/iany_i8.c +generated/iany_i16.c +" + +i_iparity_c=" +generated/iparity_i1.c +generated/iparity_i2.c +generated/iparity_i4.c +generated/iparity_i8.c +generated/iparity_i16.c +" + +i_findloc0_c=" +generated/findloc0_i1.c +generated/findloc0_i2.c +generated/findloc0_i4.c +generated/findloc0_i8.c +generated/findloc0_i16.c +generated/findloc0_r4.c +generated/findloc0_r8.c +generated/findloc0_r10.c +generated/findloc0_r16.c +generated/findloc0_r17.c +generated/findloc0_c4.c +generated/findloc0_c8.c +generated/findloc0_c10.c +generated/findloc0_c16.c +generated/findloc0_c17.c +" + +i_findloc0s_c=" +generated/findloc0_s1.c +generated/findloc0_s4.c +" + +i_findloc1_c=" +generated/findloc1_i1.c +generated/findloc1_i2.c +generated/findloc1_i4.c +generated/findloc1_i8.c +generated/findloc1_i16.c +generated/findloc1_r4.c +generated/findloc1_r8.c +generated/findloc1_r10.c +generated/findloc1_r16.c +generated/findloc1_r17.c +generated/findloc1_c4.c +generated/findloc1_c8.c +generated/findloc1_c10.c +generated/findloc1_c16.c +generated/findloc1_c17.c +" + +i_findloc1s_c=" +generated/findloc1_s1.c +generated/findloc1_s4.c +" + +i_findloc2s_c=" +generated/findloc2_s1.c +generated/findloc2_s4.c +" + +i_maxloc0_c=" +generated/maxloc0_4_i1.c +generated/maxloc0_8_i1.c +generated/maxloc0_16_i1.c +generated/maxloc0_4_i2.c +generated/maxloc0_8_i2.c +generated/maxloc0_16_i2.c +generated/maxloc0_4_i4.c +generated/maxloc0_8_i4.c +generated/maxloc0_16_i4.c +generated/maxloc0_4_i8.c +generated/maxloc0_8_i8.c +generated/maxloc0_16_i8.c +generated/maxloc0_4_i16.c +generated/maxloc0_8_i16.c +generated/maxloc0_16_i16.c +generated/maxloc0_4_m1.c +generated/maxloc0_8_m1.c +generated/maxloc0_16_m1.c +generated/maxloc0_4_m2.c +generated/maxloc0_8_m2.c +generated/maxloc0_16_m2.c +generated/maxloc0_4_m4.c +generated/maxloc0_8_m4.c +generated/maxloc0_16_m4.c +generated/maxloc0_4_m8.c +generated/maxloc0_8_m8.c +generated/maxloc0_16_m8.c +generated/maxloc0_4_m16.c +generated/maxloc0_8_m16.c +generated/maxloc0_16_m16.c +generated/maxloc0_4_r4.c +generated/maxloc0_8_r4.c +generated/maxloc0_16_r4.c +generated/maxloc0_4_r8.c +generated/maxloc0_8_r8.c +generated/maxloc0_16_r8.c +generated/maxloc0_4_r10.c +generated/maxloc0_8_r10.c +generated/maxloc0_16_r10.c +generated/maxloc0_4_r16.c +generated/maxloc0_8_r16.c +generated/maxloc0_16_r16.c +generated/maxloc0_4_r17.c +generated/maxloc0_8_r17.c +generated/maxloc0_16_r17.c +" + +i_maxloc0s_c=" +generated/maxloc0_4_s1.c +generated/maxloc0_4_s4.c +generated/maxloc0_8_s1.c +generated/maxloc0_8_s4.c +generated/maxloc0_16_s1.c +generated/maxloc0_16_s4.c +" + +i_maxloc1_c=" +generated/maxloc1_4_i1.c +generated/maxloc1_8_i1.c +generated/maxloc1_16_i1.c +generated/maxloc1_4_i2.c +generated/maxloc1_8_i2.c +generated/maxloc1_16_i2.c +generated/maxloc1_4_i4.c +generated/maxloc1_8_i4.c +generated/maxloc1_16_i4.c +generated/maxloc1_4_i8.c +generated/maxloc1_8_i8.c +generated/maxloc1_16_i8.c +generated/maxloc1_4_i16.c +generated/maxloc1_8_i16.c +generated/maxloc1_16_i16.c +generated/maxloc1_4_m1.c +generated/maxloc1_8_m1.c +generated/maxloc1_16_m1.c +generated/maxloc1_4_m2.c +generated/maxloc1_8_m2.c +generated/maxloc1_16_m2.c +generated/maxloc1_4_m4.c +generated/maxloc1_8_m4.c +generated/maxloc1_16_m4.c +generated/maxloc1_4_m8.c +generated/maxloc1_8_m8.c +generated/maxloc1_16_m8.c +generated/maxloc1_4_m16.c +generated/maxloc1_8_m16.c +generated/maxloc1_16_m16.c +generated/maxloc1_4_r4.c +generated/maxloc1_8_r4.c +generated/maxloc1_16_r4.c +generated/maxloc1_4_r8.c +generated/maxloc1_8_r8.c +generated/maxloc1_16_r8.c +generated/maxloc1_4_r10.c +generated/maxloc1_8_r10.c +generated/maxloc1_16_r10.c +generated/maxloc1_4_r16.c +generated/maxloc1_8_r16.c +generated/maxloc1_16_r16.c +generated/maxloc1_4_r17.c +generated/maxloc1_8_r17.c +generated/maxloc1_16_r17.c +" + +i_maxloc1s_c=" +generated/maxloc1_4_s1.c +generated/maxloc1_4_s4.c +generated/maxloc1_8_s1.c +generated/maxloc1_8_s4.c +generated/maxloc1_16_s1.c +generated/maxloc1_16_s4.c +" + +i_maxloc2s_c=" +generated/maxloc2_4_s1.c +generated/maxloc2_4_s4.c +generated/maxloc2_8_s1.c +generated/maxloc2_8_s4.c +generated/maxloc2_16_s1.c +generated/maxloc2_16_s4.c +" + +i_maxval_c=" +generated/maxval_i1.c +generated/maxval_i2.c +generated/maxval_i4.c +generated/maxval_i8.c +generated/maxval_i16.c +generated/maxval_m1.c +generated/maxval_m2.c +generated/maxval_m4.c +generated/maxval_m8.c +generated/maxval_m16.c +generated/maxval_r4.c +generated/maxval_r8.c +generated/maxval_r10.c +generated/maxval_r16.c +generated/maxval_r17.c +" + +i_maxval0s_c=" +generated/maxval0_s1.c +generated/maxval0_s4.c +" + +i_maxval1s_c=" +generated/maxval1_s1.c +generated/maxval1_s4.c +" + +i_minloc0_c=" +generated/minloc0_4_i1.c +generated/minloc0_8_i1.c +generated/minloc0_16_i1.c +generated/minloc0_4_i2.c +generated/minloc0_8_i2.c +generated/minloc0_16_i2.c +generated/minloc0_4_i4.c +generated/minloc0_8_i4.c +generated/minloc0_16_i4.c +generated/minloc0_4_i8.c +generated/minloc0_8_i8.c +generated/minloc0_16_i8.c +generated/minloc0_4_i16.c +generated/minloc0_8_i16.c +generated/minloc0_16_i16.c +generated/minloc0_4_m1.c +generated/minloc0_8_m1.c +generated/minloc0_16_m1.c +generated/minloc0_4_m2.c +generated/minloc0_8_m2.c +generated/minloc0_16_m2.c +generated/minloc0_4_m4.c +generated/minloc0_8_m4.c +generated/minloc0_16_m4.c +generated/minloc0_4_m8.c +generated/minloc0_8_m8.c +generated/minloc0_16_m8.c +generated/minloc0_4_m16.c +generated/minloc0_8_m16.c +generated/minloc0_16_m16.c +generated/minloc0_4_r4.c +generated/minloc0_8_r4.c +generated/minloc0_16_r4.c +generated/minloc0_4_r8.c +generated/minloc0_8_r8.c +generated/minloc0_16_r8.c +generated/minloc0_4_r10.c +generated/minloc0_8_r10.c +generated/minloc0_16_r10.c +generated/minloc0_4_r16.c +generated/minloc0_8_r16.c +generated/minloc0_16_r16.c +generated/minloc0_4_r17.c +generated/minloc0_8_r17.c +generated/minloc0_16_r17.c +" + +i_minloc0s_c=" +generated/minloc0_4_s1.c +generated/minloc0_4_s4.c +generated/minloc0_8_s1.c +generated/minloc0_8_s4.c +generated/minloc0_16_s1.c +generated/minloc0_16_s4.c +" + +i_minloc1_c=" +generated/minloc1_4_i1.c +generated/minloc1_8_i1.c +generated/minloc1_16_i1.c +generated/minloc1_4_i2.c +generated/minloc1_8_i2.c +generated/minloc1_16_i2.c +generated/minloc1_4_i4.c +generated/minloc1_8_i4.c +generated/minloc1_16_i4.c +generated/minloc1_4_i8.c +generated/minloc1_8_i8.c +generated/minloc1_16_i8.c +generated/minloc1_4_i16.c +generated/minloc1_8_i16.c +generated/minloc1_16_i16.c +generated/minloc1_4_m1.c +generated/minloc1_8_m1.c +generated/minloc1_16_m1.c +generated/minloc1_4_m2.c +generated/minloc1_8_m2.c +generated/minloc1_16_m2.c +generated/minloc1_4_m4.c +generated/minloc1_8_m4.c +generated/minloc1_16_m4.c +generated/minloc1_4_m8.c +generated/minloc1_8_m8.c +generated/minloc1_16_m8.c +generated/minloc1_4_m16.c +generated/minloc1_8_m16.c +generated/minloc1_16_m16.c +generated/minloc1_4_r4.c +generated/minloc1_8_r4.c +generated/minloc1_16_r4.c +generated/minloc1_4_r8.c +generated/minloc1_8_r8.c +generated/minloc1_16_r8.c +generated/minloc1_4_r10.c +generated/minloc1_8_r10.c +generated/minloc1_16_r10.c +generated/minloc1_4_r16.c +generated/minloc1_8_r16.c +generated/minloc1_16_r16.c +generated/minloc1_4_r17.c +generated/minloc1_8_r17.c +generated/minloc1_16_r17.c +" +i_minloc1s_c=" +generated/minloc1_4_s1.c +generated/minloc1_4_s4.c +generated/minloc1_8_s1.c +generated/minloc1_8_s4.c +generated/minloc1_16_s1.c +generated/minloc1_16_s4.c +" + +i_minloc2s_c=" +generated/minloc2_4_s1.c +generated/minloc2_4_s4.c +generated/minloc2_8_s1.c +generated/minloc2_8_s4.c +generated/minloc2_16_s1.c +generated/minloc2_16_s4.c +" + +i_minval_c=" +generated/minval_i1.c +generated/minval_i2.c +generated/minval_i4.c +generated/minval_i8.c +generated/minval_i16.c +generated/minval_m1.c +generated/minval_m2.c +generated/minval_m4.c +generated/minval_m8.c +generated/minval_m16.c +generated/minval_r4.c +generated/minval_r8.c +generated/minval_r10.c +generated/minval_r16.c +generated/minval_r17.c +" + +i_minval0s_c=" +generated/minval0_s1.c +generated/minval0_s4.c +" + +i_minval1s_c=" +generated/minval1_s1.c +generated/minval1_s4.c +" + +i_norm2_c=" +generated/norm2_r4.c +generated/norm2_r8.c +generated/norm2_r10.c +generated/norm2_r16.c +generated/norm2_r17.c +" +i_parity_c=" +generated/parity_l1.c +generated/parity_l2.c +generated/parity_l4.c +generated/parity_l8.c +generated/parity_l16.c +" + +i_sum_c=" +generated/sum_i1.c +generated/sum_i2.c +generated/sum_i4.c +generated/sum_i8.c +generated/sum_i16.c +generated/sum_r4.c +generated/sum_r8.c +generated/sum_r10.c +generated/sum_r16.c +generated/sum_r17.c +generated/sum_c4.c +generated/sum_c8.c +generated/sum_c10.c +generated/sum_c16.c +generated/sum_c17.c +" + +i_product_c=" +generated/product_i1.c +generated/product_i2.c +generated/product_i4.c +generated/product_i8.c +generated/product_i16.c +generated/product_r4.c +generated/product_r8.c +generated/product_r10.c +generated/product_r16.c +generated/product_r17.c +generated/product_c4.c +generated/product_c8.c +generated/product_c10.c +generated/product_c16.c +generated/product_c17.c +" + +i_matmul_c=" +generated/matmul_i1.c +generated/matmul_i2.c +generated/matmul_i4.c +generated/matmul_i8.c +generated/matmul_i16.c +generated/matmul_r4.c +generated/matmul_r8.c +generated/matmul_r10.c +generated/matmul_r16.c +generated/matmul_r17.c +generated/matmul_c4.c +generated/matmul_c8.c +generated/matmul_c10.c +generated/matmul_c16.c +generated/matmul_c17.c +" + +i_matmulavx128_c=" +generated/matmulavx128_i1.c +generated/matmulavx128_i2.c +generated/matmulavx128_i4.c +generated/matmulavx128_i8.c +generated/matmulavx128_i16.c +generated/matmulavx128_r4.c +generated/matmulavx128_r8.c +generated/matmulavx128_r10.c +generated/matmulavx128_r16.c +generated/matmulavx128_r17.c +generated/matmulavx128_c4.c +generated/matmulavx128_c8.c +generated/matmulavx128_c10.c +generated/matmulavx128_c16.c +generated/matmulavx128_c17.c +" + +i_matmull_c=" +generated/matmul_l4.c +generated/matmul_l8.c +generated/matmul_l16.c +" + +i_shape_c=" +generated/shape_i1.c +generated/shape_i2.c +generated/shape_i4.c +generated/shape_i8.c +generated/shape_i16.c +" + +i_reshape_c=" +generated/reshape_i4.c +generated/reshape_i8.c +generated/reshape_i16.c +generated/reshape_r4.c +generated/reshape_r8.c +generated/reshape_r10.c +generated/reshape_r16.c +generated/reshape_r17.c +generated/reshape_c4.c +generated/reshape_c8.c +generated/reshape_c10.c +generated/reshape_c16.c +generated/reshape_c17.c +" + +i_eoshift1_c=" +generated/eoshift1_4.c +generated/eoshift1_8.c +generated/eoshift1_16.c +" + +i_eoshift3_c=" +generated/eoshift3_4.c +generated/eoshift3_8.c +generated/eoshift3_16.c +" + +i_cshift0_c=" +generated/cshift0_i1.c +generated/cshift0_i2.c +generated/cshift0_i4.c +generated/cshift0_i8.c +generated/cshift0_i16.c +generated/cshift0_r4.c +generated/cshift0_r8.c +generated/cshift0_r10.c +generated/cshift0_r16.c +generated/cshift0_r17.c +generated/cshift0_c4.c +generated/cshift0_c8.c +generated/cshift0_c10.c +generated/cshift0_c16.c +generated/cshift0_c17.c +" + +i_cshift1_c=" +generated/cshift1_4.c +generated/cshift1_8.c +generated/cshift1_16.c +" + +i_cshift1a_c=" +generated/cshift1_4_i1.c +generated/cshift1_4_i2.c +generated/cshift1_4_i4.c +generated/cshift1_4_i8.c +generated/cshift1_4_i16.c +generated/cshift1_4_r4.c +generated/cshift1_4_r8.c +generated/cshift1_4_r10.c +generated/cshift1_4_r16.c +generated/cshift1_4_r17.c +generated/cshift1_4_c4.c +generated/cshift1_4_c8.c +generated/cshift1_4_c10.c +generated/cshift1_4_c16.c +generated/cshift1_4_c17.c +generated/cshift1_8_i1.c +generated/cshift1_8_i2.c +generated/cshift1_8_i4.c +generated/cshift1_8_i8.c +generated/cshift1_8_i16.c +generated/cshift1_8_r4.c +generated/cshift1_8_r8.c +generated/cshift1_8_r10.c +generated/cshift1_8_r16.c +generated/cshift1_8_r17.c +generated/cshift1_8_c4.c +generated/cshift1_8_c8.c +generated/cshift1_8_c10.c +generated/cshift1_8_c16.c +generated/cshift1_8_c17.c +generated/cshift1_16_i1.c +generated/cshift1_16_i2.c +generated/cshift1_16_i4.c +generated/cshift1_16_i8.c +generated/cshift1_16_i16.c +generated/cshift1_16_r4.c +generated/cshift1_16_r8.c +generated/cshift1_16_r10.c +generated/cshift1_16_r16.c +generated/cshift1_16_r17.c +generated/cshift1_16_c4.c +generated/cshift1_16_c8.c +generated/cshift1_16_c10.c +generated/cshift1_16_c16.c +generated/cshift1_16_c17.c +" + +in_pack_c=" +generated/in_pack_i1.c +generated/in_pack_i2.c +generated/in_pack_i4.c +generated/in_pack_i8.c +generated/in_pack_i16.c +generated/in_pack_r4.c +generated/in_pack_r8.c +generated/in_pack_r10.c +generated/in_pack_r16.c +generated/in_pack_r17.c +generated/in_pack_c4.c +generated/in_pack_c8.c +generated/in_pack_c10.c +generated/in_pack_c16.c +generated/in_pack_c17.c +" + +in_unpack_c=" +generated/in_unpack_i1.c +generated/in_unpack_i2.c +generated/in_unpack_i4.c +generated/in_unpack_i8.c +generated/in_unpack_i16.c +generated/in_unpack_r4.c +generated/in_unpack_r8.c +generated/in_unpack_r10.c +generated/in_unpack_r16.c +generated/in_unpack_r17.c +generated/in_unpack_c4.c +generated/in_unpack_c8.c +generated/in_unpack_c10.c +generated/in_unpack_c16.c +generated/in_unpack_c17.c +" + +i_pow_c=" +generated/pow_i4_i4.c +generated/pow_i8_i4.c +generated/pow_i16_i4.c +generated/pow_r16_i4.c +generated/pow_r17_i4.c +generated/pow_c4_i4.c +generated/pow_c8_i4.c +generated/pow_c10_i4.c +generated/pow_c16_i4.c +generated/pow_c17_i4.c +generated/pow_i4_i8.c +generated/pow_i8_i8.c +generated/pow_i16_i8.c +generated/pow_r4_i8.c +generated/pow_r8_i8.c +generated/pow_r10_i8.c +generated/pow_r16_i8.c +generated/pow_r17_i8.c +generated/pow_c4_i8.c +generated/pow_c8_i8.c +generated/pow_c10_i8.c +generated/pow_c16_i8.c +generated/pow_c17_i8.c +generated/pow_i4_i16.c +generated/pow_i8_i16.c +generated/pow_i16_i16.c +generated/pow_r4_i16.c +generated/pow_r8_i16.c +generated/pow_r10_i16.c +generated/pow_r16_i16.c +generated/pow_r17_i16.c +generated/pow_c4_i16.c +generated/pow_c8_i16.c +generated/pow_c10_i16.c +generated/pow_c16_i16.c +generated/pow_c17_i16.c +" + +i_powu_c=" +generated/pow_m1_m1.c +generated/pow_m1_m2.c +generated/pow_m1_m4.c +generated/pow_m1_m8.c +generated/pow_m1_m16.c +generated/pow_m2_m1.c +generated/pow_m2_m2.c +generated/pow_m2_m4.c +generated/pow_m2_m8.c +generated/pow_m2_m16.c +generated/pow_m4_m1.c +generated/pow_m4_m2.c +generated/pow_m4_m4.c +generated/pow_m4_m8.c +generated/pow_m4_m16.c +generated/pow_m8_m1.c +generated/pow_m8_m2.c +generated/pow_m8_m4.c +generated/pow_m8_m8.c +generated/pow_m8_m16.c +generated/pow_m16_m1.c +generated/pow_m16_m2.c +generated/pow_m16_m4.c +generated/pow_m16_m8.c +generated/pow_m16_m16.c +" + +i_pack_c=" +generated/pack_i1.c +generated/pack_i2.c +generated/pack_i4.c +generated/pack_i8.c +generated/pack_i16.c +generated/pack_r4.c +generated/pack_r8.c +generated/pack_r10.c +generated/pack_r16.c +generated/pack_r17.c +generated/pack_c4.c +generated/pack_c8.c +generated/pack_c10.c +generated/pack_c16.c +generated/pack_c17.c +" + +i_unpack_c=" +generated/unpack_i1.c +generated/unpack_i2.c +generated/unpack_i4.c +generated/unpack_i8.c +generated/unpack_i16.c +generated/unpack_r4.c +generated/unpack_r8.c +generated/unpack_r10.c +generated/unpack_r16.c +generated/unpack_r17.c +generated/unpack_c4.c +generated/unpack_c8.c +generated/unpack_c10.c +generated/unpack_c16.c +generated/unpack_c17.c +" + +i_spread_c=" +generated/spread_i1.c +generated/spread_i2.c +generated/spread_i4.c +generated/spread_i8.c +generated/spread_i16.c +generated/spread_r4.c +generated/spread_r8.c +generated/spread_r10.c +generated/spread_r16.c +generated/spread_r17.c +generated/spread_c4.c +generated/spread_c8.c +generated/spread_c10.c +generated/spread_c16.c +generated/spread_c17.c +" + +gfor_built_specific_src=" +generated/_abs_c4.F90 +generated/_abs_c8.F90 +generated/_abs_c10.F90 +generated/_abs_c16.F90 +generated/_abs_c17.F90 +generated/_abs_i4.F90 +generated/_abs_i8.F90 +generated/_abs_i16.F90 +generated/_abs_r4.F90 +generated/_abs_r8.F90 +generated/_abs_r10.F90 +generated/_abs_r16.F90 +generated/_abs_r17.F90 +generated/_aimag_c4.F90 +generated/_aimag_c8.F90 +generated/_aimag_c10.F90 +generated/_aimag_c16.F90 +generated/_aimag_c17.F90 +generated/_exp_r4.F90 +generated/_exp_r8.F90 +generated/_exp_r10.F90 +generated/_exp_r16.F90 +generated/_exp_r17.F90 +generated/_exp_c4.F90 +generated/_exp_c8.F90 +generated/_exp_c10.F90 +generated/_exp_c16.F90 +generated/_exp_c17.F90 +generated/_log_r4.F90 +generated/_log_r8.F90 +generated/_log_r10.F90 +generated/_log_r16.F90 +generated/_log_r17.F90 +generated/_log_c4.F90 +generated/_log_c8.F90 +generated/_log_c10.F90 +generated/_log_c16.F90 +generated/_log_c17.F90 +generated/_log10_r4.F90 +generated/_log10_r8.F90 +generated/_log10_r10.F90 +generated/_log10_r16.F90 +generated/_log10_r17.F90 +generated/_sqrt_r4.F90 +generated/_sqrt_r8.F90 +generated/_sqrt_r10.F90 +generated/_sqrt_r16.F90 +generated/_sqrt_r17.F90 +generated/_sqrt_c4.F90 +generated/_sqrt_c8.F90 +generated/_sqrt_c10.F90 +generated/_sqrt_c16.F90 +generated/_sqrt_c17.F90 +generated/_asin_r4.F90 +generated/_asin_r8.F90 +generated/_asin_r10.F90 +generated/_asin_r16.F90 +generated/_asin_r17.F90 +generated/_asinh_r4.F90 +generated/_asinh_r8.F90 +generated/_asinh_r10.F90 +generated/_asinh_r16.F90 +generated/_asinh_r17.F90 +generated/_acos_r4.F90 +generated/_acos_r8.F90 +generated/_acos_r10.F90 +generated/_acos_r16.F90 +generated/_acos_r17.F90 +generated/_acosh_r4.F90 +generated/_acosh_r8.F90 +generated/_acosh_r10.F90 +generated/_acosh_r16.F90 +generated/_acosh_r17.F90 +generated/_atan_r4.F90 +generated/_atan_r8.F90 +generated/_atan_r10.F90 +generated/_atan_r16.F90 +generated/_atan_r17.F90 +generated/_atanh_r4.F90 +generated/_atanh_r8.F90 +generated/_atanh_r10.F90 +generated/_atanh_r16.F90 +generated/_atanh_r17.F90 +generated/_sin_r4.F90 +generated/_sin_r8.F90 +generated/_sin_r10.F90 +generated/_sin_r16.F90 +generated/_sin_r17.F90 +generated/_sin_c4.F90 +generated/_sin_c8.F90 +generated/_sin_c10.F90 +generated/_sin_c16.F90 +generated/_sin_c17.F90 +generated/_cos_r4.F90 +generated/_cos_r8.F90 +generated/_cos_r10.F90 +generated/_cos_r16.F90 +generated/_cos_r17.F90 +generated/_cos_c4.F90 +generated/_cos_c8.F90 +generated/_cos_c10.F90 +generated/_cos_c16.F90 +generated/_cos_c17.F90 +generated/_tan_r4.F90 +generated/_tan_r8.F90 +generated/_tan_r10.F90 +generated/_tan_r16.F90 +generated/_tan_r17.F90 +generated/_sinh_r4.F90 +generated/_sinh_r8.F90 +generated/_sinh_r10.F90 +generated/_sinh_r16.F90 +generated/_sinh_r17.F90 +generated/_cosh_r4.F90 +generated/_cosh_r8.F90 +generated/_cosh_r10.F90 +generated/_cosh_r16.F90 +generated/_cosh_r17.F90 +generated/_tanh_r4.F90 +generated/_tanh_r8.F90 +generated/_tanh_r10.F90 +generated/_tanh_r16.F90 +generated/_tanh_r17.F90 +generated/_conjg_c4.F90 +generated/_conjg_c8.F90 +generated/_conjg_c10.F90 +generated/_conjg_c16.F90 +generated/_conjg_c17.F90 +generated/_aint_r4.F90 +generated/_aint_r8.F90 +generated/_aint_r10.F90 +generated/_aint_r16.F90 +generated/_aint_r17.F90 +generated/_anint_r4.F90 +generated/_anint_r8.F90 +generated/_anint_r10.F90 +generated/_anint_r16.F90 +generated/_anint_r17.F90 +" + +gfor_built_specific2_src=" +generated/_sign_i4.F90 +generated/_sign_i8.F90 +generated/_sign_i16.F90 +generated/_sign_r4.F90 +generated/_sign_r8.F90 +generated/_sign_r10.F90 +generated/_sign_r16.F90 +generated/_sign_r17.F90 +generated/_dim_i4.F90 +generated/_dim_i8.F90 +generated/_dim_i16.F90 +generated/_dim_r4.F90 +generated/_dim_r8.F90 +generated/_dim_r10.F90 +generated/_dim_r16.F90 +generated/_dim_r17.F90 +generated/_atan2_r4.F90 +generated/_atan2_r8.F90 +generated/_atan2_r10.F90 +generated/_atan2_r16.F90 +generated/_atan2_r17.F90 +generated/_mod_i4.F90 +generated/_mod_i8.F90 +generated/_mod_i16.F90 +generated/_mod_r4.F90 +generated/_mod_r8.F90 +generated/_mod_r10.F90 +generated/_mod_r16.F90 +generated/_mod_r17.F90 +" + +gfor_misc_specifics=" +generated/misc_specifics.F90 +" + + +for f in ${i_all_c} ; do + ${M4} -Dfile=$f -I./m4 all.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_bessel_c} ; do + ${M4} -Dfile=$f -I./m4 bessel.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_any_c} ; do + ${M4} -Dfile=$f -I./m4 any.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_count_c} ; do + ${M4} -Dfile=$f -I./m4 count.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_findloc0_c} ; do + ${M4} -Dfile=$f -I./m4 findloc0.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_findloc0s_c} ; do + ${M4} -Dfile=$f -I./m4 findloc0s.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_findloc1_c} ; do + ${M4} -Dfile=$f -I./m4 findloc1.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_findloc1s_c} ; do + ${M4} -Dfile=$f -I./m4 findloc1s.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_findloc2s_c} ; do + ${M4} -Dfile=$f -I./m4 findloc2s.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_iall_c} ; do + ${M4} -Dfile=$f -I./m4 iall.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_iany_c} ; do + ${M4} -Dfile=$f -I./m4 iany.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_iparity_c} ; do + ${M4} -Dfile=$f -I./m4 iparity.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_maxloc0_c} ; do + ${M4} -Dfile=$f -I./m4 maxloc0.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_maxloc0s_c} ; do + ${M4} -Dfile=$f -I./m4 maxloc0s.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_maxloc1_c} ; do + ${M4} -Dfile=$f -I./m4 maxloc1.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_maxloc1s_c} ; do + ${M4} -Dfile=$f -I./m4 maxloc1s.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_maxloc2s_c} ; do + ${M4} -Dfile=$f -I./m4 maxloc2s.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_maxval_c} ; do + ${M4} -Dfile=$f -I./m4 maxval.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_maxval0s_c} ; do + ${M4} -Dfile=$f -I./m4 maxval0s.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_maxval1s_c} ; do + ${M4} -Dfile=$f -I./m4 maxval1s.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_minloc0_c} ; do + ${M4} -Dfile=$f -I./m4 minloc0.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_minloc0s_c} ; do + ${M4} -Dfile=$f -I./m4 minloc0s.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_minloc1_c} ; do + ${M4} -Dfile=$f -I./m4 minloc1.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_minloc1s_c} ; do + ${M4} -Dfile=$f -I./m4 minloc1s.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_minloc2s_c} ; do + ${M4} -Dfile=$f -I./m4 minloc2s.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_minval_c} ; do + ${M4} -Dfile=$f -I./m4 minval.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_minval0s_c} ; do + ${M4} -Dfile=$f -I./m4 minval0s.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_minval1s_c} ; do + ${M4} -Dfile=$f -I./m4 minval1s.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_product_c} ; do + ${M4} -Dfile=$f -I./m4 product.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_sum_c} ; do + ${M4} -Dfile=$f -I./m4 sum.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_matmul_c} ; do + ${M4} -Dfile=$f -I./m4 matmul.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_matmulavx128_c} ; do + ${M4} -Dfile=$f -I./m4 matmulavx128.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_matmull_c} ; do + ${M4} -Dfile=$f -I./m4 matmull.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_norm2_c} ; do + ${M4} -Dfile=$f -I./m4 norm2.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_parity_c} ; do + ${M4} -Dfile=$f -I./m4 parity.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_shape_c} ; do + ${M4} -Dfile=$f -I./m4 shape.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_reshape_c} ; do + ${M4} -Dfile=$f -I./m4 reshape.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_eoshift1_c} ; do + ${M4} -Dfile=$f -I./m4 eoshift1.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_eoshift3_c} ; do + ${M4} -Dfile=$f -I./m4 eoshift3.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_cshift0_c} ; do + ${M4} -Dfile=$f -I./m4 cshift0.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_cshift1_c} ; do + ${M4} -Dfile=$f -I./m4 cshift1.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_cshift1a_c} ; do + ${M4} -Dfile=$f -I./m4 cshift1a.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${in_pack_c} ; do + ${M4} -Dfile=$f -I./m4 in_pack.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${in_unpack_c} ; do + ${M4} -Dfile=$f -I./m4 in_unpack.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_pow_c} ; do + ${M4} -Dfile=$f -I./m4 pow.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_powu_c} ; do + ${M4} -Dfile=$f -I./m4 powu.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_pack_c} ; do + ${M4} -Dfile=$f -I./m4 pack.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_unpack_c} ; do + ${M4} -Dfile=$f -I./m4 unpack.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${i_spread_c} ; do + ${M4} -Dfile=$f -I./m4 spread.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${gfor_built_specific_src} ; do + ${M4} -Dfile=$f -I./m4 specific.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${gfor_built_specific2_src} ; do + ${M4} -Dfile=$f -I./m4 specific2.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +for f in ${gfor_misc_specifics} ; do + ${M4} -Dfile=$f -I./m4 misc_specifics.m4 > $f.tmp + ../move-if-change $f.tmp $f +done + +# Check that all generated files are listed in Makefile.am + +for i in generated/*.c generated/*.F90 ; do + if ! grep -q "$i" Makefile.am ; then + echo "File $i is not present in Makefile.am" + fi +done + +# Check that all generated files listed in Makefile.am actually exist + +genlist=`tr ' ' '\n' < Makefile.am | grep 'generated/'` +for i in $genlist ; do + if ! test -e "$i" ; then + echo "File $i listed in Makefile.am does not exist" + fi +done + diff --git a/libgm2/ChangeLog b/libgm2/ChangeLog index 51a8e38a62ad..7ca3c03d5246 100644 --- a/libgm2/ChangeLog +++ b/libgm2/ChangeLog @@ -1,3 +1,22 @@ +2025-06-29 Gaius Mulley + + PR modula2/117203 + * libm2iso/Makefile.am (M2DEFS): Add IOChanUtils.def. + (M2MODS): Add IOChanUtils.mod. + * libm2iso/Makefile.in: Regenerate. + +2025-06-07 Gaius Mulley + + PR modula2/119650 + PR modula2/117203 + * libm2pim/Makefile.am (M2MODS): Add ARRAYOFCHAR, + CHAR.mod, StringFileSysOp.mod and String.mod. + (M2DEFS): Add ARRAYOFCHAR, CHAR.mod, + StringFileSysOp.mod and String.mod. + (libm2pim_la_SOURCES): Add CFileSysOp.c. + * libm2pim/Makefile.in: Regenerate. + * libm2pim/CFileSysOp.cc: New file. + 2025-04-24 Gaius Mulley PR modula2/115276 diff --git a/libgm2/libm2iso/Makefile.am b/libgm2/libm2iso/Makefile.am index 12ea38f43a84..bd8af623222f 100644 --- a/libgm2/libm2iso/Makefile.am +++ b/libgm2/libm2iso/Makefile.am @@ -104,6 +104,7 @@ M2DEFS = ChanConsts.def CharClass.def \ ConvTypes.def COROUTINES.def \ ErrnoCategory.def EXCEPTIONS.def \ GeneralUserExceptions.def IOChan.def \ + IOChanUtils.def \ IOConsts.def IOLink.def \ IOResult.def LongComplexMath.def \ LongConv.def LongIO.def \ @@ -149,7 +150,8 @@ M2MODS = ChanConsts.mod CharClass.mod \ ConvStringShort.mod \ ConvTypes.mod COROUTINES.mod \ EXCEPTIONS.mod GeneralUserExceptions.mod \ - IOChan.mod IOConsts.mod \ + IOChan.mod IOChanUtils.mod \ + IOConsts.mod \ IOLink.mod IOResult.mod \ LongComplexMath.mod LongConv.mod \ LongIO.mod LongMath.mod \ diff --git a/libgm2/libm2iso/Makefile.in b/libgm2/libm2iso/Makefile.in index 628d94240149..1e48ad06ac49 100644 --- a/libgm2/libm2iso/Makefile.in +++ b/libgm2/libm2iso/Makefile.in @@ -163,16 +163,17 @@ libm2iso_la_LIBADD = @BUILD_ISOLIB_TRUE@ ConvStringShort.lo ConvTypes.lo \ @BUILD_ISOLIB_TRUE@ COROUTINES.lo EXCEPTIONS.lo \ @BUILD_ISOLIB_TRUE@ GeneralUserExceptions.lo IOChan.lo \ -@BUILD_ISOLIB_TRUE@ IOConsts.lo IOLink.lo IOResult.lo \ -@BUILD_ISOLIB_TRUE@ LongComplexMath.lo LongConv.lo LongIO.lo \ -@BUILD_ISOLIB_TRUE@ LongMath.lo LongStr.lo LongWholeIO.lo \ -@BUILD_ISOLIB_TRUE@ LowLong.lo LowReal.lo LowShort.lo \ -@BUILD_ISOLIB_TRUE@ M2EXCEPTION.lo M2RTS.lo MemStream.lo \ -@BUILD_ISOLIB_TRUE@ Preemptive.lo Processes.lo ProgramArgs.lo \ -@BUILD_ISOLIB_TRUE@ RandomNumber.lo RawIO.lo RealConv.lo \ -@BUILD_ISOLIB_TRUE@ RealIO.lo RealMath.lo RealStr.lo RndFile.lo \ -@BUILD_ISOLIB_TRUE@ RTdata.lo RTentity.lo RTfio.lo RTgenif.lo \ -@BUILD_ISOLIB_TRUE@ RTgen.lo RTio.lo Semaphores.lo SeqFile.lo \ +@BUILD_ISOLIB_TRUE@ IOChanUtils.lo IOConsts.lo IOLink.lo \ +@BUILD_ISOLIB_TRUE@ IOResult.lo LongComplexMath.lo LongConv.lo \ +@BUILD_ISOLIB_TRUE@ LongIO.lo LongMath.lo LongStr.lo \ +@BUILD_ISOLIB_TRUE@ LongWholeIO.lo LowLong.lo LowReal.lo \ +@BUILD_ISOLIB_TRUE@ LowShort.lo M2EXCEPTION.lo M2RTS.lo \ +@BUILD_ISOLIB_TRUE@ MemStream.lo Preemptive.lo Processes.lo \ +@BUILD_ISOLIB_TRUE@ ProgramArgs.lo RandomNumber.lo RawIO.lo \ +@BUILD_ISOLIB_TRUE@ RealConv.lo RealIO.lo RealMath.lo \ +@BUILD_ISOLIB_TRUE@ RealStr.lo RndFile.lo RTdata.lo RTentity.lo \ +@BUILD_ISOLIB_TRUE@ RTfio.lo RTgenif.lo RTgen.lo RTio.lo \ +@BUILD_ISOLIB_TRUE@ Semaphores.lo SeqFile.lo \ @BUILD_ISOLIB_TRUE@ ShortComplexMath.lo ShortConv.lo ShortIO.lo \ @BUILD_ISOLIB_TRUE@ ShortMath.lo ShortStr.lo ShortWholeIO.lo \ @BUILD_ISOLIB_TRUE@ SimpleCipher.lo SIOResult.lo SLongIO.lo \ @@ -492,6 +493,7 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS) @BUILD_ISOLIB_TRUE@ ConvTypes.def COROUTINES.def \ @BUILD_ISOLIB_TRUE@ ErrnoCategory.def EXCEPTIONS.def \ @BUILD_ISOLIB_TRUE@ GeneralUserExceptions.def IOChan.def \ +@BUILD_ISOLIB_TRUE@ IOChanUtils.def \ @BUILD_ISOLIB_TRUE@ IOConsts.def IOLink.def \ @BUILD_ISOLIB_TRUE@ IOResult.def LongComplexMath.def \ @BUILD_ISOLIB_TRUE@ LongConv.def LongIO.def \ @@ -537,7 +539,8 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS) @BUILD_ISOLIB_TRUE@ ConvStringShort.mod \ @BUILD_ISOLIB_TRUE@ ConvTypes.mod COROUTINES.mod \ @BUILD_ISOLIB_TRUE@ EXCEPTIONS.mod GeneralUserExceptions.mod \ -@BUILD_ISOLIB_TRUE@ IOChan.mod IOConsts.mod \ +@BUILD_ISOLIB_TRUE@ IOChan.mod IOChanUtils.mod \ +@BUILD_ISOLIB_TRUE@ IOConsts.mod \ @BUILD_ISOLIB_TRUE@ IOLink.mod IOResult.mod \ @BUILD_ISOLIB_TRUE@ LongComplexMath.mod LongConv.mod \ @BUILD_ISOLIB_TRUE@ LongIO.mod LongMath.mod \ diff --git a/libgm2/libm2pim/CFileSysOp.cc b/libgm2/libm2pim/CFileSysOp.cc new file mode 100644 index 000000000000..fc2538c3cb9c --- /dev/null +++ b/libgm2/libm2pim/CFileSysOp.cc @@ -0,0 +1,145 @@ + + +/* A C++ implementation for CFileSysOp.def. This file will use + autoconf to test for the presence of operating system facilities. */ + +#include +#include + +#define EXPORT(FUNC) m2pim ## _CFileSysOp_ ## FUNC +#define M2EXPORT(FUNC) m2pim ## _M2_CFileSysOp_ ## FUNC +#define M2LIBNAME "m2pim" + +#if defined(HAVE_STDLIB_H) +#include +#endif + +#if defined(HAVE_UNISTD_H) +#include +#endif + +#if defined(HAVE_SYS_STAT_H) +#include +#endif + +#ifdef HAVE_STDIO_H +#include +#endif + +#if defined(HAVE_SYS_TYPES_H) +#include +#endif + +#ifdef HAVE_FCNTL_H +#include +#endif + +/* Define a generic NULL if one hasn't already been defined. */ + +#if !defined(NULL) +#define NULL 0 +#endif + +#define A_FAIL (1<<5) + + +extern "C" int +EXPORT(Unlink) (char *filename) +{ +#if defined(HAVE_UNLINK) + return unlink (filename); +#else + return -1; +#endif +} + + +/* Access test access to a path or file. The behavior is + the same as defined in access(2). Except that A_FAIL + is only used during the return result indicating the + underlying C access has returned -1 (and errno can be + checked). */ + +extern "C" int +EXPORT(Access) (char *pathname, int mode) +{ +#if defined(HAVE_ACCESS) + int result = access (pathname, mode); + + if (result == -1) + return A_FAIL; + return result; +#else + return A_FAIL; +#endif +} + + +/* Exists return true if pathname exists. */ + +extern "C" bool +EXPORT(Exists) (char *pathname) +{ +#if defined(HAVE_ACCESS) + return (access (pathname, F_OK) == 0); +#else + return false; +#endif +} + +/* IsDir return true if filename is a regular directory. */ + +extern "C" bool +EXPORT(IsDir) (char *dirname) +{ +#if defined(HAVE_SYS_STAT_H) && defined(HAVE_STRUCT_STAT) + struct stat dir_stat; + int res = stat (dirname, (struct stat *)&dir_stat); + if (res == 0) + return (dir_stat.st_mode & S_IFMT) == S_IFDIR; + return false; +#else + return false; +#endif +} + +/* IsFile return true if filename is a regular file. */ + +extern "C" bool +EXPORT(IsFile) (char *filename) +{ +#if defined(HAVE_SYS_STAT_H) && defined(HAVE_STRUCT_STAT) + struct stat file_stat; + int res = stat (filename, (struct stat *)&file_stat); + if (res == 0) + return (file_stat.st_mode & S_IFMT) == S_IFREG; + return false; +#else + return false; +#endif +} + +/* GNU Modula-2 linking hooks. */ + +extern "C" void +M2EXPORT(init) (int, char **, char **) +{ +} + +extern "C" void +M2EXPORT(fini) (int, char **, char **) +{ +} + +extern "C" void +M2EXPORT(dep) (void) +{ +} + +extern "C" void __attribute__((__constructor__)) +M2EXPORT(ctor) (void) +{ + m2pim_M2RTS_RegisterModule ("CfileSysOp", M2LIBNAME, + M2EXPORT(init), M2EXPORT(fini), + M2EXPORT(dep)); +} diff --git a/libgm2/libm2pim/Makefile.am b/libgm2/libm2pim/Makefile.am index 2252f28d6e2f..f8e9aaeafc91 100644 --- a/libgm2/libm2pim/Makefile.am +++ b/libgm2/libm2pim/Makefile.am @@ -118,14 +118,20 @@ M2MODS = ASCII.mod IO.mod \ Indexing.mod \ LMathLib0.mod LegacyReal.mod \ MemUtils.mod gdbif.mod \ - GetOpt.mod OptLib.mod + GetOpt.mod OptLib.mod \ + ARRAYOFCHAR.mod \ + CHAR.mod \ + StringFileSysOp.mod \ + String.mod \ + FileSysOp.mod # COROUTINES.mod has been removed as it is implemented in ../libm2iso. M2DEFS = Args.def ASCII.def \ Assertion.def Break.def \ Builtins.def cbuiltin.def \ - CmdArgs.def COROUTINES.def \ + CmdArgs.def CFileSysOp.def \ + COROUTINES.def \ cxxabi.def Debug.def \ dtoa.def DynamicStrings.def \ Environment.def errno.def \ @@ -153,7 +159,12 @@ M2DEFS = Args.def ASCII.def \ termios.def TimeString.def \ UnixArgs.def wrapc.def \ GetOpt.def OptLib.def \ - cgetopt.def + cgetopt.def \ + ARRAYOFCHAR.def \ + CHAR.def \ + StringFileSysOp.def \ + String.def \ + FileSysOp.def libm2pim_la_SOURCES = $(M2MODS) \ UnixArgs.cc \ @@ -161,7 +172,8 @@ libm2pim_la_SOURCES = $(M2MODS) \ errno.cc dtoa.cc \ ldtoa.cc termios.cc \ SysExceptions.cc target.c \ - wrapc.cc cgetopt.cc + wrapc.cc cgetopt.cc \ + CFileSysOp.cc libm2pimdir = libm2pim libm2pim_la_DEPENDENCIES = SYSTEM.def $(addsuffix .lo, $(basename $(libm2pim_la_SOURCES))) diff --git a/libgm2/libm2pim/Makefile.in b/libgm2/libm2pim/Makefile.in index f4313e934698..8d101c440525 100644 --- a/libgm2/libm2pim/Makefile.in +++ b/libgm2/libm2pim/Makefile.in @@ -169,12 +169,14 @@ libm2pim_la_LIBADD = @BUILD_PIMLIB_TRUE@ Builtins.lo MathLib0.lo M2EXCEPTION.lo \ @BUILD_PIMLIB_TRUE@ RTExceptions.lo SMathLib0.lo RTint.lo \ @BUILD_PIMLIB_TRUE@ Indexing.lo LMathLib0.lo LegacyReal.lo \ -@BUILD_PIMLIB_TRUE@ MemUtils.lo gdbif.lo GetOpt.lo OptLib.lo +@BUILD_PIMLIB_TRUE@ MemUtils.lo gdbif.lo GetOpt.lo OptLib.lo \ +@BUILD_PIMLIB_TRUE@ ARRAYOFCHAR.lo CHAR.lo StringFileSysOp.lo \ +@BUILD_PIMLIB_TRUE@ String.lo FileSysOp.lo @BUILD_PIMLIB_TRUE@am_libm2pim_la_OBJECTS = $(am__objects_1) \ @BUILD_PIMLIB_TRUE@ UnixArgs.lo Selective.lo sckt.lo errno.lo \ @BUILD_PIMLIB_TRUE@ dtoa.lo ldtoa.lo termios.lo \ @BUILD_PIMLIB_TRUE@ SysExceptions.lo libm2pim_la-target.lo \ -@BUILD_PIMLIB_TRUE@ wrapc.lo cgetopt.lo +@BUILD_PIMLIB_TRUE@ wrapc.lo cgetopt.lo CFileSysOp.lo libm2pim_la_OBJECTS = $(am_libm2pim_la_OBJECTS) @BUILD_PIMLIB_TRUE@am_libm2pim_la_rpath = -rpath $(toolexeclibdir) AM_V_P = $(am__v_P_@AM_V@) @@ -495,14 +497,20 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS) @BUILD_PIMLIB_TRUE@ Indexing.mod \ @BUILD_PIMLIB_TRUE@ LMathLib0.mod LegacyReal.mod \ @BUILD_PIMLIB_TRUE@ MemUtils.mod gdbif.mod \ -@BUILD_PIMLIB_TRUE@ GetOpt.mod OptLib.mod +@BUILD_PIMLIB_TRUE@ GetOpt.mod OptLib.mod \ +@BUILD_PIMLIB_TRUE@ ARRAYOFCHAR.mod \ +@BUILD_PIMLIB_TRUE@ CHAR.mod \ +@BUILD_PIMLIB_TRUE@ StringFileSysOp.mod \ +@BUILD_PIMLIB_TRUE@ String.mod \ +@BUILD_PIMLIB_TRUE@ FileSysOp.mod # COROUTINES.mod has been removed as it is implemented in ../libm2iso. @BUILD_PIMLIB_TRUE@M2DEFS = Args.def ASCII.def \ @BUILD_PIMLIB_TRUE@ Assertion.def Break.def \ @BUILD_PIMLIB_TRUE@ Builtins.def cbuiltin.def \ -@BUILD_PIMLIB_TRUE@ CmdArgs.def COROUTINES.def \ +@BUILD_PIMLIB_TRUE@ CmdArgs.def CFileSysOp.def \ +@BUILD_PIMLIB_TRUE@ COROUTINES.def \ @BUILD_PIMLIB_TRUE@ cxxabi.def Debug.def \ @BUILD_PIMLIB_TRUE@ dtoa.def DynamicStrings.def \ @BUILD_PIMLIB_TRUE@ Environment.def errno.def \ @@ -530,7 +538,12 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS) @BUILD_PIMLIB_TRUE@ termios.def TimeString.def \ @BUILD_PIMLIB_TRUE@ UnixArgs.def wrapc.def \ @BUILD_PIMLIB_TRUE@ GetOpt.def OptLib.def \ -@BUILD_PIMLIB_TRUE@ cgetopt.def +@BUILD_PIMLIB_TRUE@ cgetopt.def \ +@BUILD_PIMLIB_TRUE@ ARRAYOFCHAR.def \ +@BUILD_PIMLIB_TRUE@ CHAR.def \ +@BUILD_PIMLIB_TRUE@ StringFileSysOp.def \ +@BUILD_PIMLIB_TRUE@ String.def \ +@BUILD_PIMLIB_TRUE@ FileSysOp.def @BUILD_PIMLIB_TRUE@libm2pim_la_SOURCES = $(M2MODS) \ @BUILD_PIMLIB_TRUE@ UnixArgs.cc \ @@ -538,7 +551,8 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS) @BUILD_PIMLIB_TRUE@ errno.cc dtoa.cc \ @BUILD_PIMLIB_TRUE@ ldtoa.cc termios.cc \ @BUILD_PIMLIB_TRUE@ SysExceptions.cc target.c \ -@BUILD_PIMLIB_TRUE@ wrapc.cc cgetopt.cc +@BUILD_PIMLIB_TRUE@ wrapc.cc cgetopt.cc \ +@BUILD_PIMLIB_TRUE@ CFileSysOp.cc @BUILD_PIMLIB_TRUE@libm2pimdir = libm2pim @BUILD_PIMLIB_TRUE@libm2pim_la_DEPENDENCIES = SYSTEM.def $(addsuffix .lo, $(basename $(libm2pim_la_SOURCES))) @@ -639,6 +653,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CFileSysOp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Selective.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SysExceptions.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnixArgs.Plo@am__quote@ diff --git a/libgo/go/syscall/socket.go b/libgo/go/syscall/socket.go index 54a4a9940c64..35665d507232 100644 --- a/libgo/go/syscall/socket.go +++ b/libgo/go/syscall/socket.go @@ -467,7 +467,7 @@ func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) { func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) { var msg Msghdr - msg.Name = (*byte)(unsafe.Pointer(&rsa)) + msg.Name = (*byte)(unsafe.Pointer(rsa)) msg.Namelen = uint32(SizeofSockaddrAny) var iov Iovec if len(p) > 0 { diff --git a/libgo/runtime/go-memclr.c b/libgo/runtime/go-memclr.c index 53b811785392..84df98db6d41 100644 --- a/libgo/runtime/go-memclr.c +++ b/libgo/runtime/go-memclr.c @@ -11,50 +11,39 @@ void memclrNoHeapPointers(void *, uintptr) __attribute__ ((no_split_stack)); void -memclrNoHeapPointers (void *p1, uintptr len) +memclrNoHeapPointers(void *p1, uintptr len) { - -#if !defined(__PPC64__) - __builtin_memset(p1, 0, len); -#else - int64 rem,drem,i; - uint64 offset; - volatile uint64 *vp; + const uintptr ptr_size = sizeof(p1); + uintptr rem,drem,i; + uintptr offset; + volatile uintptr *vp; if (len == 0) { return; } rem = len; - offset = (uint64)p1 % 8; - // This memset is OK since it can't contain - // an 8 byte aligned pointer. - if ((rem < 8) || (offset > 0 && offset+rem <= 16)) { + offset = (uintptr)p1 % ptr_size; + if (rem < ptr_size || offset > 0) { + // This memset is OK since it can't contain + // an pointer aligned pointer. __builtin_memset(p1, 0, rem); return; } - // Move initial bytes to get to 8 byte boundary - if (offset > 0) { - __builtin_memset(p1, 0, 8-offset); - p1 = (void*)((char*)p1+8-offset); - rem -= 8-offset; - } - // If at least 8 bytes left, clear - drem = rem>>3; + drem = rem / ptr_size; - vp = (volatile uint64*)(p1); + vp = (volatile uintptr*)(p1); // Without the use of volatile here, the compiler // might convert the loop into a memset. for (i=0; i 0) { - __builtin_memset (p1, 0, rem); + p1 = (void*)((char*)p1 + ptr_size*drem); + __builtin_memset(p1, 0, rem); } -#endif } diff --git a/libgo/runtime/go-memmove.c b/libgo/runtime/go-memmove.c index 1ca3f4822b73..1dbd2b392734 100644 --- a/libgo/runtime/go-memmove.c +++ b/libgo/runtime/go-memmove.c @@ -12,78 +12,60 @@ void gomemmove(void *, void *, uintptr) // This implementation is necessary since // the __builtin_memmove might use __libc_memmove -// which doesn't require atomicity of 8 byte +// which doesn't require atomicity of pointer-sized // moves. void -gomemmove (void *dst, void *src, uintptr len) +gomemmove(void *dst, void *src, uintptr len) { -#if !defined(__PPC64__) - __builtin_memmove(dst, src, len); -#else - uint64 offset, tail; - int64 rem; - uint64 dwords; - uint64 i; - char *bdst,*bsrc; - - rem = len; + const uintptr ptr_size = sizeof(dst); + uintptr tail; + uintptr rem; + uintptr dwords; + uintptr i; + char *bdst, *bsrc; if (len == 0) { - return; + return; } - // If src and dst don't have the same 8 byte alignment then - // there is no issue with copying pointer atomicity. Use the - // builtin. - if (((uint64)dst % 8) != ((uint64)src % 8) || len < 8) { - __builtin_memmove(dst, src, len); - return; + // We expect pointer-containing values to be pointer-aligned. + // If these pointers are not aligned, they don't contain pointers. + if ((uintptr)dst % ptr_size != 0 || (uintptr)src % ptr_size != 0 || len < ptr_size) { + __builtin_memmove(dst, src, len); + return; } - // Length >= 8 && same ptr alignment - offset = (uint64)dst % 8; - - // If not 8 byte alignment, move the intial bytes. - if (offset > 0) { - __builtin_memmove(dst, src, 8-offset); - dst += (8-offset); - src += (8-offset); - rem -= (8-offset); - } + bdst = (char*)dst; + bsrc = (char*)src; - // Move the tail bytes to make the backward move - // easier. - tail = rem % 8; + // Move the tail bytes to make the backward move easier. + rem = len; + tail = rem % ptr_size; if (tail > 0) { - __builtin_memmove(dst+rem-tail, src+rem-tail, tail); - rem -= tail; - } - - if (rem == 0) { - return; + __builtin_memmove(bdst+rem-tail, bsrc+rem-tail, tail); + rem -= tail; } - // Must now be 8 byte alignment and rem is multiple of 8. - dwords = len>>3; + // Must now be pointer alignment and rem is multiple of ptr_size. + dwords = rem / ptr_size; - // Determine if a backwards move is needed - // Forward or backward, move all doublewords + // Determine if a backwards move is needed. + // Forward or backward, move all words. - if ((uint64)(dst - src) < (uint64)rem) { - bdst = dst+rem-8; - bsrc = src+rem-8; - for (i = 0; i + + PR target/119853 + PR target/119854 + * testsuite/libgomp.c++/target-cdtor-1.C: Adjust for + 'targetm.cxx.use_aeabi_atexit'. + * testsuite/libgomp.c++/target-cdtor-2.C: Likewise. + +2025-07-18 Andrew Stubbs + + PR target/121156 + * config/gcn/bar.c (gomp_team_barrier_wait_end): Remove unused + "generation" variable. + (gomp_team_barrier_wait_cancel_end): Likewise. + +2025-07-17 Thomas Schwinge + + PR target/119692 + * testsuite/libgomp.c++/pr119692-1-4.C: '{ dg-timeout 10 { target offload_device } }'. + * testsuite/libgomp.c++/pr119692-1-5.C: Likewise. + * testsuite/libgomp.c++/target-exceptions-bad_cast-1.C: Likewise. + * testsuite/libgomp.c++/target-exceptions-bad_cast-2.C: Likewise. + * testsuite/libgomp.oacc-c++/exceptions-bad_cast-1.C: Likewise. + * testsuite/libgomp.oacc-c++/exceptions-bad_cast-2.C: Likewise. + +2025-06-24 Tobias Burnus + + * libgomp.texi (acc_attach, acc_detach): Update for Fortran + version. + * openacc.f90 (acc_attach{,_async}, acc_detach{,_finalize}{,_async}): + Add. + * openacc_lib.h: Likewise. + * testsuite/libgomp.oacc-fortran/acc-attach-detach-1.f90: New test. + * testsuite/libgomp.oacc-fortran/acc-attach-detach-2.f90: New test. + +2025-06-19 Tobias Burnus + + * target.c (GOMP_REQUIRES_NAME_BUF_LEN): Define. + (GOMP_offload_register_ver, gomp_target_init): Use it for the + char buffer size. + +2025-06-19 Tobias Burnus + waffl3x + + * libgomp.texi (omp_init_allocator): Refer to 'Memory allocation' + for available memory spaces. + (OMP_ALLOCATOR): Move list of traits and predefined memspaces + and allocators to ... + (Memory allocation): ... here. Document omp(x)::allocator::*; + minor wording tweaks, be more explicit about memkind, pinned and + pool_size. + +2025-06-17 Tobias Burnus + + * testsuite/libgomp.c++/declare_target-2.C: New test. + +2025-06-10 Tobias Burnus + + * testsuite/libgomp.c/declare-variant-4.h (gfx942): New variant function. + * testsuite/libgomp.c/declare-variant-4-gfx942.c: New test. + +2025-06-06 Tobias Burnus + Sandra Loosemore + + * libgomp.texi (omp_get_num_devices, omp_get_intrinsic_device): + Document builtin handling. + +2025-06-06 Tobias Burnus + + PR target/120530 + * testsuite/libgomp.c/target-map-zero-sized-3.c (main): Add missing + map clause; remove unused variable. + +2025-06-04 Tobias Burnus + Sandra Loosemore + + * libgomp.texi (omp_interop_{int,ptr,str,rc_desc}): Add note about + the 'ret_code' type change in OpenMP 6. + 2025-06-03 Jakub Jelinek PR libgomp/120444 diff --git a/libgomp/config/gcn/bar.c b/libgomp/config/gcn/bar.c index 52b344c9ab26..57ac648477ea 100644 --- a/libgomp/config/gcn/bar.c +++ b/libgomp/config/gcn/bar.c @@ -79,7 +79,7 @@ gomp_team_barrier_wake (gomp_barrier_t *bar, int count) void gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state) { - unsigned int generation, gen; + unsigned int gen; if (__builtin_expect (state & BAR_WAS_LAST, 0)) { @@ -105,7 +105,6 @@ gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state) } } - generation = state; state &= ~BAR_CANCELLED; int retry = 100; do @@ -128,7 +127,6 @@ gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state) gomp_barrier_handle_tasks (state); gen = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE); } - generation |= gen & BAR_WAITING_FOR_TASK; } while (gen != state + BAR_INCR); } @@ -152,7 +150,7 @@ bool gomp_team_barrier_wait_cancel_end (gomp_barrier_t *bar, gomp_barrier_state_t state) { - unsigned int generation, gen; + unsigned int gen; if (__builtin_expect (state & BAR_WAS_LAST, 0)) { @@ -184,7 +182,6 @@ gomp_team_barrier_wait_cancel_end (gomp_barrier_t *bar, if (__builtin_expect (state & BAR_CANCELLED, 0)) return true; - generation = state; int retry = 100; do { @@ -209,7 +206,6 @@ gomp_team_barrier_wait_cancel_end (gomp_barrier_t *bar, gomp_barrier_handle_tasks (state); gen = __atomic_load_n (&bar->generation, MEMMODEL_RELAXED); } - generation |= gen & BAR_WAITING_FOR_TASK; } while (gen != state + BAR_INCR); diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi index 7116fcda13fe..5518033f1f30 100644 --- a/libgomp/libgomp.texi +++ b/libgomp/libgomp.texi @@ -1802,6 +1802,11 @@ Returns the number of available non-host devices. The effect of running this routine in a @code{target} region is unspecified. +Note that in GCC the function is marked pure, i.e. as returning always the +same number. When GCC was not configured to support offloading, it is replaced +by zero; compile with @option{-fno-builtin-omp_get_num_devices} if a run-time +function is desired. + @item @emph{C/C++}: @multitable @columnfractions .20 .80 @item @emph{Prototype}: @tab @code{int omp_get_num_devices(void);} @@ -1812,6 +1817,9 @@ The effect of running this routine in a @code{target} region is unspecified. @item @emph{Interface}: @tab @code{integer function omp_get_num_devices()} @end multitable +@item @emph{See also}: +@ref{omp_get_initial_device} + @item @emph{Reference}: @uref{https://www.openmp.org, OpenMP specification v4.5}, Section 3.2.31. @end table @@ -1950,6 +1958,12 @@ the value of @code{omp_initial_device}. The effect of running this routine in a @code{target} region is unspecified. +Note that GCC inlines this function unless you compile with +@option{-fno-builtin-omp_get_initial_device}. If GCC was not configured to +support offloading, it expands to constant zero; in non-host code it expands +to @code{omp_initial_device}; and otherwise it is replaced with a call to +@code{omp_get_num_devices}. + @item @emph{C/C++} @multitable @columnfractions .20 .80 @item @emph{Prototype}: @tab @code{int omp_get_initial_device(void);} @@ -3439,7 +3453,7 @@ traits; if an allocator that fulfills the requirements cannot be created, @code{omp_null_allocator} is returned. The predefined memory spaces and available traits can be found at -@ref{OMP_ALLOCATOR}, where the trait names have to be prefixed by +@ref{Memory allocation}, where the trait names have to be prefixed by @code{omp_atk_} (e.g. @code{omp_atk_pinned}) and the named trait values by @code{omp_atv_} (e.g. @code{omp_atv_true}); additionally, @code{omp_atv_default} may be used as trait value to specify that the default value should be used. @@ -3462,7 +3476,7 @@ may be used as trait value to specify that the default value should be used. @end multitable @item @emph{See also}: -@ref{OMP_ALLOCATOR}, @ref{Memory allocation}, @ref{omp_destroy_allocator} +@ref{Memory allocation}, @ref{OMP_ALLOCATOR}, @ref{omp_destroy_allocator} @item @emph{Reference}: @uref{https://www.openmp.org, OpenMP specification v5.0}, Section 3.7.2 @@ -4043,63 +4057,15 @@ The value can either be a predefined allocator or a predefined memory space or a predefined memory space followed by a colon and a comma-separated list of memory trait and value pairs, separated by @code{=}. +See @ref{Memory allocation} for a list of supported prefedined allocators, +memory spaces, and traits. + Note: The corresponding device environment variables are currently not supported. Therefore, the non-host @var{def-allocator-var} ICVs are always initialized to @code{omp_default_mem_alloc}. However, on all devices, the @code{omp_set_default_allocator} API routine can be used to change value. -@multitable @columnfractions .45 .45 -@headitem Predefined allocators @tab Associated predefined memory spaces -@item omp_default_mem_alloc @tab omp_default_mem_space -@item omp_large_cap_mem_alloc @tab omp_large_cap_mem_space -@item omp_const_mem_alloc @tab omp_const_mem_space -@item omp_high_bw_mem_alloc @tab omp_high_bw_mem_space -@item omp_low_lat_mem_alloc @tab omp_low_lat_mem_space -@item omp_cgroup_mem_alloc @tab omp_low_lat_mem_space (implementation defined) -@item omp_pteam_mem_alloc @tab omp_low_lat_mem_space (implementation defined) -@item omp_thread_mem_alloc @tab omp_low_lat_mem_space (implementation defined) -@item ompx_gnu_pinned_mem_alloc @tab omp_default_mem_space (GNU extension) -@end multitable - -The predefined allocators use the default values for the traits, -as listed below. Except that the last three allocators have the -@code{access} trait set to @code{cgroup}, @code{pteam}, and -@code{thread}, respectively. - -@multitable @columnfractions .25 .40 .25 -@headitem Trait @tab Allowed values @tab Default value -@item @code{sync_hint} @tab @code{contended}, @code{uncontended}, - @code{serialized}, @code{private} - @tab @code{contended} -@item @code{alignment} @tab Positive integer being a power of two - @tab 1 byte -@item @code{access} @tab @code{all}, @code{cgroup}, - @code{pteam}, @code{thread} - @tab @code{all} -@item @code{pool_size} @tab Positive integer - @tab See @ref{Memory allocation} -@item @code{fallback} @tab @code{default_mem_fb}, @code{null_fb}, - @code{abort_fb}, @code{allocator_fb} - @tab See below -@item @code{fb_data} @tab @emph{unsupported as it needs an allocator handle} - @tab (none) -@item @code{pinned} @tab @code{true}, @code{false} - @tab See below -@item @code{partition} @tab @code{environment}, @code{nearest}, - @code{blocked}, @code{interleaved} - @tab @code{environment} -@end multitable - -For the @code{fallback} trait, the default value is @code{null_fb} for the -@code{omp_default_mem_alloc} allocator and any allocator that is associated -with device memory; for all other allocators, it is @code{default_mem_fb} -by default. - -For the @code{pinned} trait, the default value is @code{true} for -predefined allocator @code{ompx_gnu_pinned_mem_alloc} (a GNU extension), and -@code{false} for all others. - Examples: @smallexample OMP_ALLOCATOR=omp_high_bw_mem_alloc @@ -5958,7 +5924,7 @@ This function copies device memory from one memory location to another on the current device. It copies @var{bytes} bytes of data from the device address, specified by @var{data_dev_src}, to the device address @var{data_dev_dest}. The @code{_async} version performs the transfer -asnychronously using the queue associated with @var{async_arg}. +asynchronously using the queue associated with @var{async_arg}. @item @emph{C/C++}: @multitable @columnfractions .20 .80 @@ -6001,19 +5967,19 @@ address to pointing to the corresponding device data. @item @emph{Prototype}: @tab @code{void acc_attach_async(h_void **ptr_addr, int async);} @end multitable -@c @item @emph{Fortran}: -@c @multitable @columnfractions .20 .80 -@c @item @emph{Interface}: @tab @code{subroutine acc_attach(ptr_addr)} -@c @item @emph{Interface}: @tab @code{subroutine acc_attach_async(ptr_addr, async_arg)} -@c @item @tab @code{type(*), dimension(..) :: ptr_addr} -@c @item @tab @code{integer(acc_handle_kind), value :: async_arg} -@c @end multitable +@item @emph{Fortran}: +@multitable @columnfractions .20 .80 +@item @emph{Interface}: @tab @code{subroutine acc_attach(ptr_addr)} +@item @emph{Interface}: @tab @code{subroutine acc_attach_async(ptr_addr, async_arg)} +@item @tab @code{type(*), dimension(..) :: ptr_addr} +@item @tab @code{integer(acc_handle_kind), value :: async_arg} +@end multitable @item @emph{Reference}: @uref{https://www.openacc.org, OpenACC specification v2.6}, section 3.2.34. -@c @uref{https://www.openacc.org, OpenACC specification v3.3}, section -@c 3.2.29. + @uref{https://www.openacc.org, OpenACC specification v3.3}, section +3.2.29. @end table @@ -6033,21 +5999,21 @@ address to pointing to the corresponding host data. @item @emph{Prototype}: @tab @code{void acc_detach_finalize_async(h_void **ptr_addr, int async);} @end multitable -@c @item @emph{Fortran}: -@c @multitable @columnfractions .20 .80 -@c @item @emph{Interface}: @tab @code{subroutine acc_detach(ptr_addr)} -@c @item @emph{Interface}: @tab @code{subroutine acc_detach_async(ptr_addr, async_arg)} -@c @item @emph{Interface}: @tab @code{subroutine acc_detach_finalize(ptr_addr)} -@c @item @emph{Interface}: @tab @code{subroutine acc_detach_finalize_async(ptr_addr, async_arg)} -@c @item @tab @code{type(*), dimension(..) :: ptr_addr} -@c @item @tab @code{integer(acc_handle_kind), value :: async_arg} -@c @end multitable +@item @emph{Fortran}: +@multitable @columnfractions .20 .80 +@item @emph{Interface}: @tab @code{subroutine acc_detach(ptr_addr)} +@item @emph{Interface}: @tab @code{subroutine acc_detach_async(ptr_addr, async_arg)} +@item @emph{Interface}: @tab @code{subroutine acc_detach_finalize(ptr_addr)} +@item @emph{Interface}: @tab @code{subroutine acc_detach_finalize_async(ptr_addr, async_arg)} +@item @tab @code{type(*), dimension(..) :: ptr_addr} +@item @tab @code{integer(acc_handle_kind), value :: async_arg} +@end multitable @item @emph{Reference}: @uref{https://www.openacc.org, OpenACC specification v2.6}, section 3.2.35. -@c @uref{https://www.openacc.org, OpenACC specification v3.3}, section -@c 3.2.29. +@uref{https://www.openacc.org, OpenACC specification v3.3}, section +3.2.29. @end table @@ -6869,6 +6835,7 @@ on more architectures, GCC currently does not match any @code{arch} or @tab See @code{-march=} in ``Nvidia PTX Options'' @end multitable + @node Memory allocation @section Memory allocation @@ -6903,11 +6870,94 @@ The description below applies to: @code{_Alignof} and C++'s @code{alignof}. @end itemize -For the available predefined allocators and, as applicable, their associated -predefined memory spaces and for the available traits and their default values, -see @ref{OMP_ALLOCATOR}. Predefined allocators without an associated memory -space use the @code{omp_default_mem_space} memory space. See additionally -@ref{Offload-Target Specifics}. +GCC supports the following predefined allocators and predefined memory spaces: + +@multitable @columnfractions .45 .45 +@headitem Predefined allocators @tab Associated predefined memory spaces +@item omp_default_mem_alloc @tab omp_default_mem_space +@item omp_large_cap_mem_alloc @tab omp_large_cap_mem_space +@item omp_const_mem_alloc @tab omp_const_mem_space +@item omp_high_bw_mem_alloc @tab omp_high_bw_mem_space +@item omp_low_lat_mem_alloc @tab omp_low_lat_mem_space +@item omp_cgroup_mem_alloc @tab omp_low_lat_mem_space (implementation defined) +@item omp_pteam_mem_alloc @tab omp_low_lat_mem_space (implementation defined) +@item omp_thread_mem_alloc @tab omp_low_lat_mem_space (implementation defined) +@item ompx_gnu_pinned_mem_alloc @tab omp_default_mem_space (GNU extension) +@end multitable + +Each predefined allocator, including @code{omp_null_allocator}, has a corresponding +allocator class template that meet the C++ allocator completeness requirements. +These are located in the @code{omp::allocator} namespace, and the +@code{ompx::allocator} namespace for gnu extensions. This allows the +allocator-aware C++ standard library containers to use OpenMP allocation routines; +for instance: + +@smallexample +std::vector> vec; +@end smallexample + +The following allocator templates are supported: + +@multitable @columnfractions .45 .45 +@headitem Predefined allocators @tab Associated allocator template +@item omp_null_allocator @tab omp::allocator::null_allocator +@item omp_default_mem_alloc @tab omp::allocator::default_mem +@item omp_large_cap_mem_alloc @tab omp::allocator::large_cap_mem +@item omp_const_mem_alloc @tab omp::allocator::const_mem +@item omp_high_bw_mem_alloc @tab omp::allocator::high_bw_mem +@item omp_low_lat_mem_alloc @tab omp::allocator::low_lat_mem +@item omp_cgroup_mem_alloc @tab omp::allocator::cgroup_mem +@item omp_pteam_mem_alloc @tab omp::allocator::pteam_mem +@item omp_thread_mem_alloc @tab omp::allocator::thread_mem +@item ompx_gnu_pinned_mem_alloc @tab ompx::allocator::gnu_pinned_mem +@end multitable + +The following traits are available when constructing a new allocator; +if a trait is not specified or with the value @code{default}, the +specified default value is used for that trait. The predefined +allocators use the default values of each trait, except that the +@code{omp_cgroup_mem_alloc}, @code{omp_pteam_mem_alloc}, and +@code{omp_thread_mem_alloc} allocators have the @code{access} trait +set to @code{cgroup}, @code{pteam}, and @code{thread}, respectively. +For each trait, a named constant prefixed by @code{omp_atk_} exists; +for each non-numeric value, a named constant prefixed by @code{omp_atv_} +exists. + +@multitable @columnfractions .25 .40 .25 +@headitem Trait @tab Allowed values @tab Default value +@item @code{sync_hint} @tab @code{contended}, @code{uncontended}, + @code{serialized}, @code{private} + @tab @code{contended} +@item @code{alignment} @tab Positive integer being a power of two + @tab 1 byte +@item @code{access} @tab @code{all}, @code{cgroup}, + @code{pteam}, @code{thread} + @tab @code{all} +@item @code{pool_size} @tab Positive integer (bytes) + @tab See below. +@item @code{fallback} @tab @code{default_mem_fb}, @code{null_fb}, + @code{abort_fb}, @code{allocator_fb} + @tab See below +@item @code{fb_data} @tab @emph{allocator handle} + @tab (none) +@item @code{pinned} @tab @code{true}, @code{false} + @tab See below +@item @code{partition} @tab @code{environment}, @code{nearest}, + @code{blocked}, @code{interleaved} + @tab @code{environment} +@end multitable + +For the @code{fallback} trait, the default value is @code{null_fb} for the +@code{omp_default_mem_alloc} allocator and any allocator that is associated +with device memory; for all other allocators, it is @code{default_mem_fb} +by default. + +For the @code{pinned} trait, the default value is @code{true} for +predefined allocator @code{ompx_gnu_pinned_mem_alloc} (a GNU extension), and +@code{false} for all others. + +The following description applies to the initial device (the host) and largely +also to non-host devices; for the latter, also see @ref{Offload-Target Specifics}. For the memory spaces, the following applies: @itemize @@ -6922,14 +6972,16 @@ For the memory spaces, the following applies: @end itemize On Linux systems, where the @uref{https://github.com/memkind/memkind, memkind -library} (@code{libmemkind.so.0}) is available at runtime, it is used when -creating memory allocators requesting +library} (@code{libmemkind.so.0}) is available at runtime and the respective +memkind kind is supported, it is used when creating memory allocators requesting @itemize -@item the memory space @code{omp_high_bw_mem_space} -@item the memory space @code{omp_large_cap_mem_space} -@item the @code{partition} trait @code{interleaved}; note that for - @code{omp_large_cap_mem_space} the allocation will not be interleaved +@item the @code{partition} trait @code{interleaved} except when the memory space + is @code{omp_large_cap_mem_space} (uses @code{MEMKIND_HBW_INTERLEAVE}) +@item the memory space is @code{omp_high_bw_mem_space} (uses + @code{MEMKIND_HBW_PREFERRED}) +@item the memory space is @code{omp_large_cap_mem_space} (uses + @code{MEMKIND_DAX_KMEM_ALL} or, if not available, @code{MEMKIND_DAX_KMEM}) @end itemize On Linux systems, where the @uref{https://github.com/numactl/numactl, numa @@ -6955,10 +7007,15 @@ a @code{nearest} allocation. Additional notes regarding the traits: @itemize @item The @code{pinned} trait is supported on Linux hosts, but is subject to - the OS @code{ulimit}/@code{rlimit} locked memory settings. + the OS @code{ulimit}/@code{rlimit} locked memory settings. It currently + uses @code{mmap} and is therefore optimized for few allocations, including + large data. If the conditions for numa or memkind allocations are + fulfilled, those allocators are used instead. @item The default for the @code{pool_size} trait is no pool and for every (re)allocation the associated library routine is called, which might - internally use a memory pool. + internally use a memory pool. Currently, the same applies when a + @code{pool_size} has been specified, except that once allocations exceed + the the pool size, the action of the @code{fallback} trait applies. @item For the @code{partition} trait, the partition part size will be the same as the requested size (i.e. @code{interleaved} or @code{blocked} has no effect), except for @code{interleaved} when the memkind library is @@ -6967,13 +7024,15 @@ Additional notes regarding the traits: that allocated the memory; on Linux, this is in particular the case when the memory placement policy is set to preferred. @item The @code{access} trait has no effect such that memory is always - accessible by all threads. + accessible by all threads. (Except on supported no-host devices.) @item The @code{sync_hint} trait has no effect. @end itemize See also: @ref{Offload-Target Specifics} + + @c --------------------------------------------------------------------- @c Offload-Target Specifics @c --------------------------------------------------------------------- diff --git a/libgomp/openacc.f90 b/libgomp/openacc.f90 index 9d51f017985e..3f2db45617b1 100644 --- a/libgomp/openacc.f90 +++ b/libgomp/openacc.f90 @@ -798,6 +798,8 @@ module openacc public :: acc_memcpy_to_device, acc_memcpy_to_device_async public :: acc_memcpy_from_device, acc_memcpy_from_device_async public :: acc_memcpy_device, acc_memcpy_device_async + public :: acc_attach, acc_attach_async, acc_detach, acc_detach_async + public :: acc_detach_finalize, acc_detach_finalize_async integer, parameter :: openacc_version = 201711 @@ -1068,6 +1070,48 @@ subroutine acc_memcpy_device_async (data_dev_dest, data_dev_src, & end subroutine end interface + interface + subroutine acc_attach (ptr_addr) bind(C) + type(*), dimension(..) :: ptr_addr + end subroutine + end interface + + interface + subroutine acc_attach_async (ptr_addr, async_arg) bind(C) + import :: acc_handle_kind + type(*), dimension(..) :: ptr_addr + integer(acc_handle_kind), value :: async_arg + end subroutine + end interface + + interface + subroutine acc_detach (ptr_addr) bind(C) + type(*), dimension(..) :: ptr_addr + end subroutine + end interface + + interface + subroutine acc_detach_async (ptr_addr, async_arg) bind(C) + import :: acc_handle_kind + type(*), dimension(..) :: ptr_addr + integer(acc_handle_kind), value :: async_arg + end subroutine + end interface + + interface + subroutine acc_detach_finalize (ptr_addr) bind(C) + type(*), dimension(..) :: ptr_addr + end subroutine + end interface + + interface + subroutine acc_detach_finalize_async (ptr_addr, async_arg) bind(C) + import :: acc_handle_kind + type(*), dimension(..) :: ptr_addr + integer(acc_handle_kind), value :: async_arg + end subroutine + end interface + interface acc_copyin_async procedure :: acc_copyin_async_32_h procedure :: acc_copyin_async_64_h diff --git a/libgomp/openacc_lib.h b/libgomp/openacc_lib.h index 9333c481502d..dbdc4d7bc402 100644 --- a/libgomp/openacc_lib.h +++ b/libgomp/openacc_lib.h @@ -707,3 +707,45 @@ integer (acc_handle_kind) async_ end subroutine end interface + + interface + subroutine acc_attach (ptr_addr) bind(C) + type(*), dimension(..) :: ptr_addr + end subroutine + end interface + + interface + subroutine acc_attach_async (ptr_addr, async_arg) bind(C) + import :: acc_handle_kind + type(*), dimension(..) :: ptr_addr + integer(acc_handle_kind), value :: async_arg + end subroutine + end interface + + interface + subroutine acc_detach (ptr_addr) bind(C) + type(*), dimension(..) :: ptr_addr + end subroutine + end interface + + interface + subroutine acc_detach_async (ptr_addr, async_arg) bind(C) + import :: acc_handle_kind + type(*), dimension(..) :: ptr_addr + integer(acc_handle_kind), value :: async_arg + end subroutine + end interface + + interface + subroutine acc_detach_finalize (ptr_addr) bind(C) + type(*), dimension(..) :: ptr_addr + end subroutine + end interface + + interface + subroutine acc_detach_finalize_async(ptr_addr, async_arg)bind(C) + import :: acc_handle_kind + type(*), dimension(..) :: ptr_addr + integer(acc_handle_kind), value :: async_arg + end subroutine + end interface diff --git a/libgomp/target.c b/libgomp/target.c index a2a4a7299e58..cda092bd044c 100644 --- a/libgomp/target.c +++ b/libgomp/target.c @@ -2641,6 +2641,10 @@ gomp_unload_image_from_device (struct gomp_device_descr *devicep, } } +#define GOMP_REQUIRES_NAME_BUF_LEN \ + sizeof ("unified_address, unified_shared_memory, " \ + "self_maps, reverse_offload") + static void gomp_requires_to_name (char *buf, size_t size, int requires_mask) { @@ -2689,10 +2693,8 @@ GOMP_offload_register_ver (unsigned version, const void *host_table, if (omp_req && omp_requires_mask && omp_requires_mask != omp_req) { - char buf1[sizeof ("unified_address, unified_shared_memory, " - "self_maps, reverse_offload")]; - char buf2[sizeof ("unified_address, unified_shared_memory, " - "self_maps, reverse_offload")]; + char buf1[GOMP_REQUIRES_NAME_BUF_LEN]; + char buf2[GOMP_REQUIRES_NAME_BUF_LEN]; gomp_requires_to_name (buf2, sizeof (buf2), omp_req != GOMP_REQUIRES_TARGET_USED ? omp_req : omp_requires_mask); @@ -5786,8 +5788,7 @@ gomp_target_init (void) found = true; if (found) { - char buf[sizeof ("unified_address, unified_shared_memory, " - "reverse_offload")]; + char buf[GOMP_REQUIRES_NAME_BUF_LEN]; gomp_requires_to_name (buf, sizeof (buf), omp_req); char *name = (char *) malloc (cur_len + 1); memcpy (name, cur, cur_len); diff --git a/libgomp/testsuite/libgomp.c++/declare_target-2.C b/libgomp/testsuite/libgomp.c++/declare_target-2.C new file mode 100644 index 000000000000..ab94a5568881 --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/declare_target-2.C @@ -0,0 +1,25 @@ +// { dg-do link } + +// Actually not needed: -fipa-cp is default with -O2: +// { dg-additional-options "-O2 -fipa-cp" } + +// The code failed because 'std::endl' becoḿes implicitly 'declare target' +// but not the 'widen' function it calls. While the linker had no issues +// (endl is never called, either because it is inlined or optimized away), +// the IPA-CP (enabled by -O2 and higher) failed as the definition for +// 'widen' did not exist on the offload side. + +#include + +void func (int m) +{ + if (m < 0) + std::cout << "should not happen" << std::endl; +} + + +int main() +{ + #pragma omp target + func (1); +} diff --git a/libgomp/testsuite/libgomp.c++/pr119692-1-4.C b/libgomp/testsuite/libgomp.c++/pr119692-1-4.C index af9fe1c8c183..d329ad394f08 100644 --- a/libgomp/testsuite/libgomp.c++/pr119692-1-4.C +++ b/libgomp/testsuite/libgomp.c++/pr119692-1-4.C @@ -5,7 +5,7 @@ { dg-xfail-run-if PR119692 { offload_device } } */ /* There are configurations where we 'WARNING: program timed out.' while in 'dynamic_cast', see . - { dg-timeout 10 } ... to make sure that happens quickly. */ + { dg-timeout 10 { target offload_device } } ... to make sure that happens quickly. */ /* { dg-additional-options -fdump-tree-gimple } */ #include "pr119692-1-1.C" diff --git a/libgomp/testsuite/libgomp.c++/pr119692-1-5.C b/libgomp/testsuite/libgomp.c++/pr119692-1-5.C index e5c6e077fc8d..6bbe1864fa57 100644 --- a/libgomp/testsuite/libgomp.c++/pr119692-1-5.C +++ b/libgomp/testsuite/libgomp.c++/pr119692-1-5.C @@ -5,7 +5,7 @@ { dg-xfail-run-if PR119692 { offload_device } } */ /* There are configurations where we 'WARNING: program timed out.' while in 'dynamic_cast', see . - { dg-timeout 10 } ... to make sure that happens quickly. */ + { dg-timeout 10 { target offload_device } } ... to make sure that happens quickly. */ /* { dg-additional-options -fdump-tree-gimple } */ #include "pr119692-1-1.C" diff --git a/libgomp/testsuite/libgomp.c++/target-cdtor-1.C b/libgomp/testsuite/libgomp.c++/target-cdtor-1.C index ecb029e6b7d5..7e8cc582e94e 100644 --- a/libgomp/testsuite/libgomp.c++/target-cdtor-1.C +++ b/libgomp/testsuite/libgomp.c++/target-cdtor-1.C @@ -63,14 +63,19 @@ int main() return 0; } -/* Verify '__cxa_atexit' calls. +/* Verify '__cxa_atexit' calls (or '__aeabi_atexit', per 'targetm.cxx.use_aeabi_atexit'). For the host, there are four expected calls: - { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, } 4 optimized { target cxa_atexit } } } - { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sH1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } - { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sHD1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } - { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZNSt6vectorI1SSaIS0_EED1Ev, \&svHD1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } - { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sH2, \&__dso_handle>} 1 optimized { target cxa_atexit } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, } 4 optimized { target { cxa_atexit && { ! arm_eabi } } } } } + { dg-final { scan-tree-dump-times {gimple_call <__aeabi_atexit, } 4 optimized { target { cxa_atexit && arm_eabi } } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sH1, \&__dso_handle>} 1 optimized { target { cxa_atexit && { ! arm_eabi } } } } } + { dg-final { scan-tree-dump-times {gimple_call <__aeabi_atexit, NULL, \&sH1, _ZN1SD1Ev, \&__dso_handle>} 1 optimized { target { cxa_atexit && arm_eabi } } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sHD1, \&__dso_handle>} 1 optimized { target { cxa_atexit && { ! arm_eabi } } } } } + { dg-final { scan-tree-dump-times {gimple_call <__aeabi_atexit, NULL, \&sHD1, _ZN1SD1Ev, \&__dso_handle>} 1 optimized { target { cxa_atexit && arm_eabi } } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZNSt6vectorI1SSaIS0_EED1Ev, \&svHD1, \&__dso_handle>} 1 optimized { target { cxa_atexit && { ! arm_eabi } } } } } + { dg-final { scan-tree-dump-times {gimple_call <__aeabi_atexit, NULL, \&svHD1, _ZNSt6vectorI1SSaIS0_EED1Ev, \&__dso_handle>} 1 optimized { target { cxa_atexit && arm_eabi } } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sH2, \&__dso_handle>} 1 optimized { target { cxa_atexit && { ! arm_eabi } } } } } + { dg-final { scan-tree-dump-times {gimple_call <__aeabi_atexit, NULL, \&sH2, _ZN1SD1Ev, \&__dso_handle>} 1 optimized { target { cxa_atexit && arm_eabi } } } } For the device, there are two expected calls: { dg-final { scan-offload-tree-dump-times {gimple_call <__cxa_atexit, } 2 optimized { target cxa_atexit } } } diff --git a/libgomp/testsuite/libgomp.c++/target-cdtor-2.C b/libgomp/testsuite/libgomp.c++/target-cdtor-2.C index 75e48ca2f67b..9c8512245b13 100644 --- a/libgomp/testsuite/libgomp.c++/target-cdtor-2.C +++ b/libgomp/testsuite/libgomp.c++/target-cdtor-2.C @@ -93,14 +93,19 @@ int main() return 0; } -/* Verify '__cxa_atexit' calls. +/* Verify '__cxa_atexit' calls (or '__aeabi_atexit', per 'targetm.cxx.use_aeabi_atexit'). For the host, there are four expected calls: - { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, } 4 optimized { target cxa_atexit } } } - { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sH1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } - { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sHD1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } - { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZNSt6vectorI1SSaIS0_EED1Ev, \&svHD1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } - { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sH2, \&__dso_handle>} 1 optimized { target cxa_atexit } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, } 4 optimized { target { cxa_atexit && { ! arm_eabi } } } } } + { dg-final { scan-tree-dump-times {gimple_call <__aeabi_atexit, } 4 optimized { target { cxa_atexit && arm_eabi } } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sH1, \&__dso_handle>} 1 optimized { target { cxa_atexit && { ! arm_eabi } } } } } + { dg-final { scan-tree-dump-times {gimple_call <__aeabi_atexit, NULL, \&sH1, _ZN1SD1Ev, \&__dso_handle>} 1 optimized { target { cxa_atexit && arm_eabi } } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sHD1, \&__dso_handle>} 1 optimized { target { cxa_atexit && { ! arm_eabi } } } } } + { dg-final { scan-tree-dump-times {gimple_call <__aeabi_atexit, NULL, \&sHD1, _ZN1SD1Ev, \&__dso_handle>} 1 optimized { target { cxa_atexit && arm_eabi } } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZNSt6vectorI1SSaIS0_EED1Ev, \&svHD1, \&__dso_handle>} 1 optimized { target { cxa_atexit && { ! arm_eabi } } } } } + { dg-final { scan-tree-dump-times {gimple_call <__aeabi_atexit, NULL, \&svHD1, _ZNSt6vectorI1SSaIS0_EED1Ev, \&__dso_handle>} 1 optimized { target { cxa_atexit && arm_eabi } } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sH2, \&__dso_handle>} 1 optimized { target { cxa_atexit && { ! arm_eabi } } } } } + { dg-final { scan-tree-dump-times {gimple_call <__aeabi_atexit, NULL, \&sH2, _ZN1SD1Ev, \&__dso_handle>} 1 optimized { target { cxa_atexit && arm_eabi } } } } For the device, there are two expected calls: { dg-final { scan-offload-tree-dump-times {gimple_call <__cxa_atexit, } 2 optimized { target cxa_atexit } } } diff --git a/libgomp/testsuite/libgomp.c++/target-exceptions-bad_cast-1.C b/libgomp/testsuite/libgomp.c++/target-exceptions-bad_cast-1.C index a862652f4a8e..4158eced10bf 100644 --- a/libgomp/testsuite/libgomp.c++/target-exceptions-bad_cast-1.C +++ b/libgomp/testsuite/libgomp.c++/target-exceptions-bad_cast-1.C @@ -25,4 +25,4 @@ { dg-shouldfail {'std::bad_cast' exception} } */ /* There are configurations where we 'WARNING: program timed out.' while in 'dynamic_cast', see . - { dg-timeout 10 } ... to make sure that happens quickly. */ + { dg-timeout 10 { target offload_device } } ... to make sure that happens quickly. */ diff --git a/libgomp/testsuite/libgomp.c++/target-exceptions-bad_cast-2.C b/libgomp/testsuite/libgomp.c++/target-exceptions-bad_cast-2.C index ff15c9fa61f6..ca72e577f761 100644 --- a/libgomp/testsuite/libgomp.c++/target-exceptions-bad_cast-2.C +++ b/libgomp/testsuite/libgomp.c++/target-exceptions-bad_cast-2.C @@ -24,4 +24,4 @@ { dg-shouldfail {'MyException' exception} { offload_device } } */ /* There are configurations where we 'WARNING: program timed out.' while in 'dynamic_cast', see . - { dg-timeout 10 } ... to make sure that happens quickly. */ + { dg-timeout 10 { target offload_device } } ... to make sure that happens quickly. */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx942.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx942.c new file mode 100644 index 000000000000..d1df5500d5f9 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx942.c @@ -0,0 +1,8 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx942 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx942 \\(\\);" "optimized" } } */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4.h b/libgomp/testsuite/libgomp.c/declare-variant-4.h index 53788d2f9228..2257f4c5508c 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4.h +++ b/libgomp/testsuite/libgomp.c/declare-variant-4.h @@ -35,6 +35,13 @@ gfx90c (void) return 0x90c; } +__attribute__ ((noipa)) +int +gfx942 (void) +{ + return 0x942; +} + __attribute__ ((noipa)) int gfx1030 (void) @@ -68,6 +75,7 @@ gfx1103 (void) #pragma omp declare variant(gfx908) match(device = {isa("gfx908")}) #pragma omp declare variant(gfx90a) match(device = {isa("gfx90a")}) #pragma omp declare variant(gfx90c) match(device = {isa("gfx90c")}) +#pragma omp declare variant(gfx942) match(device = {isa("gfx942")}) #pragma omp declare variant(gfx1030) match(device = {isa("gfx1030")}) #pragma omp declare variant(gfx1036) match(device = {isa("gfx1036")}) #pragma omp declare variant(gfx1100) match(device = {isa("gfx1100")}) diff --git a/libgomp/testsuite/libgomp.c/target-map-zero-sized-3.c b/libgomp/testsuite/libgomp.c/target-map-zero-sized-3.c index f968bd377c2c..580c6ad89bf5 100644 --- a/libgomp/testsuite/libgomp.c/target-map-zero-sized-3.c +++ b/libgomp/testsuite/libgomp.c/target-map-zero-sized-3.c @@ -1,7 +1,7 @@ int main () { - int i, n, n2; + int i, n; int data[] = {1,2}; struct S { int **ptrset; @@ -33,16 +33,17 @@ main () i = 1; n = 0; - n2 = 2; + #pragma omp target enter data map(data) #pragma omp target enter data map(sptr1[:1], sptr1->ptrset[:3], sptr1->ptrset2[:3]) #pragma omp target enter data map(sptr1->ptrset[i][:n], sptr1->ptrset2[i][:n]) - #pragma omp target + #pragma omp target map(sptr1->ptrset[i][:n], sptr1->ptrset2[i][:n]) if (sptr1->ptrset2[1][0] != 1 || sptr1->ptrset2[1][1] != 2) __builtin_abort (); #pragma omp target exit data map(sptr1->ptrset[i][:n], sptr1->ptrset2[i][:n]) #pragma omp target exit data map(sptr1[:1], sptr1->ptrset[:3], sptr1->ptrset2[:3]) + #pragma omp target exit data map(data) __builtin_free (s1.ptrset); __builtin_free (s1.ptrset2); diff --git a/libgomp/testsuite/libgomp.oacc-c++/exceptions-bad_cast-1.C b/libgomp/testsuite/libgomp.oacc-c++/exceptions-bad_cast-1.C index 6957a6caec70..e6cbe17f4145 100644 --- a/libgomp/testsuite/libgomp.oacc-c++/exceptions-bad_cast-1.C +++ b/libgomp/testsuite/libgomp.oacc-c++/exceptions-bad_cast-1.C @@ -54,4 +54,4 @@ int main() { dg-shouldfail {'std::bad_cast' exception} } */ /* There are configurations where we 'WARNING: program timed out.' while in 'dynamic_cast', see . - { dg-timeout 10 } ... to make sure that happens quickly. */ + { dg-timeout 10 { target offload_device } } ... to make sure that happens quickly. */ diff --git a/libgomp/testsuite/libgomp.oacc-c++/exceptions-bad_cast-2.C b/libgomp/testsuite/libgomp.oacc-c++/exceptions-bad_cast-2.C index 0f84cf212c25..599425ff3eeb 100644 --- a/libgomp/testsuite/libgomp.oacc-c++/exceptions-bad_cast-2.C +++ b/libgomp/testsuite/libgomp.oacc-c++/exceptions-bad_cast-2.C @@ -60,4 +60,4 @@ int main() { dg-shouldfail {'std::bad_cast' exception} { ! openacc_host_selected } } */ /* There are configurations where we 'WARNING: program timed out.' while in 'dynamic_cast', see . - { dg-timeout 10 } ... to make sure that happens quickly. */ + { dg-timeout 10 { target offload_device } } ... to make sure that happens quickly. */ diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc-attach-detach-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/acc-attach-detach-1.f90 new file mode 100644 index 000000000000..15393b456c85 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/acc-attach-detach-1.f90 @@ -0,0 +1,25 @@ +! { dg-do compile } +! { dg-additional-options "-fdump-tree-original" } + +use openacc +implicit none (type, external) +integer,pointer :: a, b(:) +integer,allocatable :: c, d(:) + +call acc_attach(a) ! ICE +call acc_attach_async(b, 4) +call acc_attach(c) + +call acc_detach(a) +call acc_detach_async(b, 4) +call acc_detach_finalize(c) +call acc_detach_finalize_async(d,7) +end + +! { dg-final { scan-tree-dump-times "acc_attach \\(&a\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times "acc_attach_async \\(&\\(integer\\(kind=4\\)\\\[0:\\\] \\*\\) b.data, 4\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times "acc_attach \\(&c\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times "acc_detach \\(&a\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times "acc_detach_async \\(&\\(integer\\(kind=4\\)\\\[0:\\\] \\*\\) b.data, 4\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times "acc_detach_finalize \\(&c\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times "acc_detach_finalize_async \\(&\\(integer\\(kind=4\\)\\\[0:\\\] \\* restrict\\) d.data, 7\\);" 1 "original" } } diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc-attach-detach-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/acc-attach-detach-2.f90 new file mode 100644 index 000000000000..b2204ac44670 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/acc-attach-detach-2.f90 @@ -0,0 +1,62 @@ +! { dg-do run } + +use openacc +implicit none (type, external) +integer, target :: tgt_a, tgt_b(5) + +integer, pointer :: p1, p2(:) + +type t + integer,pointer :: a => null () + integer,pointer :: b(:) => null () + integer,allocatable :: c, d(:) +end type t + +type(t), target :: var + +tgt_a = 51 +tgt_b = [11,22,33,44,55] + +var%b => tgt_b +!$acc enter data copyin(var, tgt_a, tgt_b) +var%a => tgt_a + +call acc_attach(var%a) +call acc_attach(var%b) + +!$acc serial +! { dg-warning "using .vector_length \\(32\\)., ignoring 1" "" { target openacc_nvidia_accel_selected } .-1 } + if (var%a /= 51) stop 1 + if (any (var%b /= [11,22,33,44,55])) stop 2 +!$acc end serial + +call acc_detach(var%a) +call acc_detach(var%b) + +!$acc exit data delete(var, tgt_a, tgt_b) + +var%c = 9 +var%d = [1,2,3] + +p1 => var%c +p2 => var%d + +!$acc enter data copyin(p1, p2) +!$acc enter data copyin(var) +call acc_attach(var%c) +call acc_attach(var%d) + +!$acc serial +! { dg-warning "using .vector_length \\(32\\)., ignoring 1" "" { target openacc_nvidia_accel_selected } .-1 } + if (var%c /= 9) stop 3 + if (any (var%d /= [1,2,3])) stop 4 +!$acc end serial + +call acc_detach(var%c) +call acc_detach(var%d) + +!$acc exit data delete(var, p1, p2) + +deallocate(var%d) + +end diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 2ae5626ed2e2..cf909171d053 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,9 @@ +2025-07-09 Matthieu Longo + + * Makefile.in: Add new header. + * testsuite/Makefile.in: Add new test. + * testsuite/test-doubly-linked-list.c: New test. + 2025-05-13 Andreas Schwab * regex.c (regex_compile): Don't write beyond array bounds when diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in index ce54d88278d2..e4d7d0aafa0b 100644 --- a/libiberty/Makefile.in +++ b/libiberty/Makefile.in @@ -237,6 +237,7 @@ CONFIGURED_OFILES = ./asprintf.$(objext) ./atexit.$(objext) \ INSTALLED_HEADERS = \ $(INCDIR)/ansidecl.h \ $(INCDIR)/demangle.h \ + $(INCDIR)/doubly-linked-list.h \ $(INCDIR)/dyn-string.h \ $(INCDIR)/fibheap.h \ $(INCDIR)/floatformat.h \ diff --git a/libiberty/testsuite/Makefile.in b/libiberty/testsuite/Makefile.in index 2b0883c7630e..ef549ca910aa 100644 --- a/libiberty/testsuite/Makefile.in +++ b/libiberty/testsuite/Makefile.in @@ -45,7 +45,8 @@ all: check: @CHECK@ really-check: check-cplus-dem check-d-demangle check-rust-demangle \ - check-pexecute check-expandargv check-strtol + check-pexecute check-expandargv check-strtol \ + check-doubly-linked-list # Run some tests of the demangler. check-cplus-dem: test-demangle $(srcdir)/demangle-expected @@ -69,6 +70,10 @@ check-expandargv: test-expandargv check-strtol: test-strtol ./test-strtol +# Check the linked list functionality +check-doubly-linked-list: test-doubly-linked-list + ./test-doubly-linked-list + # Run the demangler fuzzer fuzz-demangler: demangler-fuzzer ./demangler-fuzzer @@ -90,6 +95,10 @@ test-strtol: $(srcdir)/test-strtol.c ../libiberty.a $(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-strtol \ $(srcdir)/test-strtol.c ../libiberty.a +test-doubly-linked-list: $(srcdir)/test-doubly-linked-list.c + $(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-doubly-linked-list \ + $(srcdir)/test-doubly-linked-list.c + demangler-fuzzer: $(srcdir)/demangler-fuzzer.c ../libiberty.a $(TEST_COMPILE) -o demangler-fuzzer \ $(srcdir)/demangler-fuzzer.c ../libiberty.a @@ -104,6 +113,7 @@ mostlyclean: rm -f test-pexecute rm -f test-expandargv rm -f test-strtol + rm -f test-doubly-linked-list rm -f demangler-fuzzer rm -f core clean: mostlyclean diff --git a/libiberty/testsuite/test-doubly-linked-list.c b/libiberty/testsuite/test-doubly-linked-list.c new file mode 100644 index 000000000000..1e1fc6376537 --- /dev/null +++ b/libiberty/testsuite/test-doubly-linked-list.c @@ -0,0 +1,269 @@ +#include +#include +#include + +#include "doubly-linked-list.h" + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + +/* Implementation */ + +typedef int T; + +typedef struct ListNodeType +{ + T value; + struct ListNodeType *next; + struct ListNodeType *prev; +} ListNodeType; + +ListNodeType * l_new_node (T value) +{ + ListNodeType *n = malloc (sizeof (ListNodeType)); + n->next = NULL; + n->prev = NULL; + n->value = value; + return n; +} + +typedef struct LinkedListWrapperType +{ + ListNodeType *first; + ListNodeType *last; + size_t size; +} LinkedListWrapperType; + +int compare_nodes (const ListNodeType *n1, const ListNodeType *n2) +{ + if (n1->value == n2->value) + return 0; + else if (n1->value < n2->value) + return -1; + else + return 1; +} + +LINKED_LIST_MUTATIVE_OPS_PROTOTYPE (LinkedListWrapperType, ListNodeType, static); +LINKED_LIST_MERGE_SORT_PROTOTYPE (LinkedListWrapperType, ListNodeType, static); + +LINKED_LIST_MUTATIVE_OPS_DECL (LinkedListWrapperType, ListNodeType, static) +LINKED_LIST_MERGE_SORT_DECL (LinkedListWrapperType, ListNodeType, static) + +ListNodeType * find_last_node (ListNodeType *head) +{ + if (head == NULL) + return NULL; + + ListNodeType *n = head; + while (n->next != NULL) + n = n->next; + + return n; +} + +void l_print (ListNodeType *node) +{ + for (ListNodeType *l = node; l != NULL; l = l->next) + printf ("%d ", l->value); + printf ("\n"); +} + +void l_reverse_print (ListNodeType *last_node) +{ + for (ListNodeType *l = last_node; l != NULL; l = l->prev) + printf ("%d ", l->value); + printf ("\n"); +} + +struct test_data_t +{ + T const *content; + size_t size; +}; + +bool run_test (const struct test_data_t *expect, + LinkedListWrapperType *current, + bool reversed) +{ + ListNodeType *node = (reversed) ? current->last : current->first; + bool passed = true; + for (int i=0; isize && node != NULL; ++i) + { + if (reversed) + { + if (expect->content[expect->size - 1 - i] != node->value) + { + printf ("FAIL: mismatching expected (%d) VS current (%d).\n", + expect->content[expect->size - 1 - i], node->value); + passed = false; + } + if (node->prev == NULL && current->first != node) + { + printf ("FAIL: first is not matching the first node.\n"); + passed = false; + } + } + else + { + if (expect->content[i] != node->value) + { + printf ("FAIL: mismatching expected (%d) VS current (%d).\n", + expect->content[i], node->value); + passed = false; + } + if (node->next == NULL && current->last != node) + { + printf ("FAIL: last_ is not matching the last node.\n"); + passed = false; + } + } + + if (!passed) + return false; + + if (reversed) + node = node->prev; + else + node = node->next; + } + + if (node != NULL) + { + printf ("FAIL: the list is longer than expected.\n"); + passed = false; + } + if (expect->size != current->size) + { + printf ("FAIL: size (%ld) is not matching the real size of the list (%ld).\n", + current->size, expect->size); + passed = false; + } + + return passed; +} + +bool check(const char *op, + const struct test_data_t *expect, + LinkedListWrapperType *wrapper) +{ + bool success = true; + bool res; + + l_print (wrapper->first); + res = run_test (expect, wrapper, false); + printf ("%s: test-linked-list::%s: check forward conformity\n", + res ? "PASS": "FAIL", op); + success &= res; + + l_reverse_print (wrapper->last); + res = run_test (expect, wrapper, true); + printf ("%s: test-linked-list::%s: check backward conformity\n", + res ? "PASS": "FAIL", op); + success &= res; + + printf("\n"); + + return success; +} + +const int EXPECT_0 [] = { 10, 4, 3, 1, 9, 2 }; +const int EXPECT_1 [] = { 1, 2, 3, 4, 9, 10 }; +const int EXPECT_2 [] = { 11, 1, 2, 3, 4, 9, 10 }; +const int EXPECT_3 [] = { 11, 1, 2, 3, 4, 9, 8, 10 }; +const int EXPECT_4 [] = { 11, 2, 3, 4, 9, 8, 10 }; +const int EXPECT_5 [] = { 10, 2, 3, 4, 9, 8, 11 }; +const int EXPECT_6 [] = { 10, 3, 2, 4, 9, 8, 11 }; +const int EXPECT_7 [] = { 10, 9, 2, 4, 3, 8, 11 }; +const int EXPECT_8 [] = { 2, 3, 4, 8, 9, 10, 11 }; +const int EXPECT_9 [] = { 3, 4, 8, 9, 10, 11 }; +const int EXPECT_10 [] = { 3, 4, 8, 9, 10 }; +const struct test_data_t test_data[] = { + { .content = EXPECT_0, .size = sizeof(EXPECT_0) / sizeof(EXPECT_0[0]) }, + { .content = EXPECT_1, .size = sizeof(EXPECT_1) / sizeof(EXPECT_1[0]) }, + { .content = EXPECT_2, .size = sizeof(EXPECT_2) / sizeof(EXPECT_2[0]) }, + { .content = EXPECT_3, .size = sizeof(EXPECT_3) / sizeof(EXPECT_3[0]) }, + { .content = EXPECT_4, .size = sizeof(EXPECT_4) / sizeof(EXPECT_4[0]) }, + { .content = EXPECT_5, .size = sizeof(EXPECT_5) / sizeof(EXPECT_5[0]) }, + { .content = EXPECT_6, .size = sizeof(EXPECT_6) / sizeof(EXPECT_6[0]) }, + { .content = EXPECT_7, .size = sizeof(EXPECT_7) / sizeof(EXPECT_7[0]) }, + { .content = EXPECT_8, .size = sizeof(EXPECT_8) / sizeof(EXPECT_8[0]) }, + { .content = EXPECT_9, .size = sizeof(EXPECT_9) / sizeof(EXPECT_9[0]) }, + { .content = EXPECT_10, .size = sizeof(EXPECT_10) / sizeof(EXPECT_10[0]) }, +}; + +int main (void) +{ + int failures = 0; + + LinkedListWrapperType wrapper = { + .first = NULL, + .last = NULL, + .size = 0, + }; + + /* Append nodes. */ + LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (10)); + LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (4)); + LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (3)); + LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (1)); + LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (9)); + LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (2)); + + failures += ! check ("append", &test_data[0], &wrapper); + + /* Sort nodes (without updating wrapper). */ + wrapper.first = + LINKED_LIST_MERGE_SORT_(ListNodeType) (wrapper.first, compare_nodes); + wrapper.last = find_last_node (wrapper.first); + + failures += ! check ("sort", &test_data[1], &wrapper); + + /* Save a reference to this node for later. */ + ListNodeType *n_to_remove = wrapper.first; + + /* Prepend node. */ + LINKED_LIST_PREPEND(ListNodeType) (&wrapper, l_new_node (11)); + failures += ! check ("prepend", &test_data[2], &wrapper); + + /* Insert node. */ + LINKED_LIST_INSERT_BEFORE(ListNodeType) (&wrapper, l_new_node (8), wrapper.last); + failures += ! check ("insert_before", &test_data[3], &wrapper); + + /* Remove a node. */ + LINKED_LIST_REMOVE(ListNodeType) (&wrapper, n_to_remove); + failures += ! check ("remove", &test_data[4], &wrapper); + + /* Swap first and last. */ + LINKED_LIST_SWAP(ListNodeType) (&wrapper, wrapper.first, wrapper.last); + failures += ! check ("swap first and last", &test_data[5], &wrapper); + + /* Swap adjacent nodes. */ + LINKED_LIST_SWAP(ListNodeType) (&wrapper, wrapper.first->next, + wrapper.first->next->next); + failures += ! check ("swap adjacent nodes", &test_data[6], &wrapper); + + /* Swap non-adjacent nodes, but neither first nor last. */ + LINKED_LIST_SWAP(ListNodeType) (&wrapper, wrapper.first->next, + wrapper.first->next->next->next->next); + failures += ! check ("swap non-adjacent nodes", &test_data[7], &wrapper); + + /* Sort nodes. */ + LINKED_LIST_MERGE_SORT(ListNodeType) (&wrapper, compare_nodes); + failures += ! check ("sort", &test_data[8], &wrapper); + + /* Pop front. */ + LINKED_LIST_POP_FRONT(ListNodeType) (&wrapper); + failures += ! check ("pop_front", &test_data[9], &wrapper); + + /* Pop back. */ + LINKED_LIST_POP_BACK(ListNodeType) (&wrapper); + failures += ! check ("pop_back", &test_data[10], &wrapper); + + exit (failures ? EXIT_FAILURE : EXIT_SUCCESS); +} diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index a1480d48aeb5..dbc769f30f5e 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,8 @@ +2025-07-01 Rainer Orth + + * configure.tgt : Also consider minor + versions supported. + 2025-05-09 David Malcolm PR other/116792 diff --git a/libphobos/configure.tgt b/libphobos/configure.tgt index 76c09c4640dd..fb671838d9df 100644 --- a/libphobos/configure.tgt +++ b/libphobos/configure.tgt @@ -64,7 +64,7 @@ case "${target}" in *-*-darwin9* | *-*-darwin1[01]*) LIBDRUNTIME_ONLY=yes ;; - x86_64-*-darwin1[2-9]* | x86_64-*-darwin2* | i?86-*-darwin1[2-7]) + x86_64-*-darwin1[2-9]* | x86_64-*-darwin2* | i?86-*-darwin1[2-7]*) LIBPHOBOS_SUPPORTED=yes ;; x86_64-*-freebsd* | i?86-*-freebsd*) diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cpp b/libsanitizer/sanitizer_common/sanitizer_linux.cpp index 8b1850f85010..6331c26c0a92 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_linux.cpp @@ -86,6 +86,10 @@ # include # endif +# if SANITIZER_LINUX && defined(__powerpc64__) +# include +# endif + # if SANITIZER_FREEBSD # include # include diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp index ed19e4031a53..9d01a97af5f4 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -619,21 +619,22 @@ static void GetTls(uptr *addr, uptr *size) { *addr = tp - RoundUpTo(*size, align); *size = tp - *addr + ThreadDescriptorSize(); # else - if (SANITIZER_GLIBC) - *size += 1664; - else if (SANITIZER_FREEBSD) - *size += 128; // RTLD_STATIC_TLS_EXTRA -# if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64 +# if SANITIZER_GLIBC + *size += 1664; +# elif SANITIZER_FREEBSD + *size += 128; // RTLD_STATIC_TLS_EXTRA +# if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64 const uptr pre_tcb_size = TlsPreTcbSize(); *addr -= pre_tcb_size; *size += pre_tcb_size; -# else +# else // arm and aarch64 reserve two words at TP, so this underestimates the range. // However, this is sufficient for the purpose of finding the pointers to // thread-specific data keys. const uptr tcb_size = ThreadDescriptorSize(); *addr -= tcb_size; *size += tcb_size; +# endif # endif # endif # elif SANITIZER_NETBSD diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp index 7bbc6f2edac2..490e75fe8f65 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -96,7 +96,7 @@ # include # if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ defined(__hexagon__) || defined(__loongarch__) || SANITIZER_RISCV64 || \ - defined(__sparc__) + defined(__sparc__) || defined(__powerpc64__) # include # ifdef __arm__ typedef struct user_fpregs elf_fpregset_t; diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp index 945da99d41f4..58d17d90c343 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp @@ -31,7 +31,8 @@ #include // for pid_t #include // for iovec #include // for NT_PRSTATUS -#if (defined(__aarch64__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64) && \ +#if (defined(__aarch64__) || defined(__powerpc64__) || \ + SANITIZER_RISCV64 || SANITIZER_LOONGARCH64) && \ !SANITIZER_ANDROID // GLIBC 2.20+ sys/user does not include asm/ptrace.h # include diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9cbb8a05ffb4..cf86ee22e3c2 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,1839 @@ +2025-07-21 Luc Grosheintz + + * include/std/mdspan (mdspan::mdspan): Make default ctor + conditionally noexcept. + * testsuite/23_containers/mdspan/mdspan.cc: Add tests. + +2025-07-21 Luc Grosheintz + + * include/std/mdspan (mdspan::is_always_unique): Make + conditionally noexcept. + (mdspan::is_always_exhaustive): Ditto. + (mdspan::is_always_strided): Ditto. + (mdspan::is_unique): Ditto. + (mdspan::is_exhaustive): Ditto. + (mdspan::is_strided): Ditto. + * testsuite/23_containers/mdspan/layout_like.h: Make noexcept + configurable. Add ThrowingLayout. + * testsuite/23_containers/mdspan/mdspan.cc: Add tests for + noexcept. + +2025-07-20 Jakub Jelinek + + PR libstdc++/121174 + * src/c++23/std.cc.in (std::dextents): Export. Add to FIXME comments + other not yet implemented nor exported entities. + +2025-07-18 Jonathan Wakely + + * include/bits/stl_iterator_base_types.h (__any_input_iterator): + Only define when __cpp_lib_concepts is defined. + +2025-07-18 Jonathan Wakely + + * doc/xml/manual/appendix_contributing.xml: Remove Paolo from + list of maintainers to contact about contributing. + * doc/html/manual/appendix_contributing.html: Regenerate. + +2025-07-18 Jonathan Wakely + + * doc/xml/manual/build_hacking.xml: Document that + windows_zones-map.h is a generated file. + * doc/html/manual/appendix_porting.html: Regenerate. + +2025-07-18 Tomasz Kamiński + + PR libstdc++/119137 + * include/std/inplace_vector (inplace_vector::operator=): + Qualify call to std::addressof. + +2025-07-18 Tomasz Kamiński + + PR libstdc++/121154 + * include/bits/chrono_io.h (_ChronoSpec::_M_time_point): Remove. + (_ChronoSpec::_M_needs_ok_check): Define + (__formatter_chrono::_M_parse): Set _M_needs_ok_check. + (__formatter_chrono::_M_check_ok): Check values also for debug mode, + and return __string_view. + (__formatter_chrono::_M_format_to): Handle results of _M_check_ok. + (__formatter_chrono::_M_wi, __formatter_chrono::_M_a_A) + (__formatter_chrono::_M_b_B, __formatter_chrono::_M_C_y_Y) + (__formatter_chrono::_M_d_e, __formatter_chrono::_M_F): + Removed handling of _M_debug. + (__formatter_chrono::__M_m): Print zero unpadded in _M_debug mode. + (__formatter_duration::_S_spec_for): Remove _M_time_point refernce. + (__formatter_duration::_M_parse): Override _M_needs_ok_check. + * testsuite/std/time/month/io.cc: Test for localized !ok() values. + * testsuite/std/time/weekday/io.cc: Test for localized !ok() values. + +2025-07-18 Jonathan Wakely + + PR libstdc++/121150 + * testsuite/20_util/hash/int128.cc: Cast expected values to + size_t. + +2025-07-18 Jonathan Wakely + + * include/bits/unicode.h (_Utf_iterator::operator--): Reorder + conditions and update position after reading a code unit. + (_Utf_iterator::_M_read_reverse): Define. + (_Utf_iterator::_M_read_utf8): Return extracted code point. + (_Utf_iterator::_M_read_reverse_utf8): Define. + (_Utf_iterator::_M_read_reverse_utf16): Define. + (_Utf_iterator::_M_read_reverse_utf32): Define. + * testsuite/ext/unicode/view.cc: Add checks for reversed views + and reverse iteration. + +2025-07-18 Jonathan Wakely + + * include/bits/unicode.h (_Utf_iterator): Reorder data members + to be more compact. + +2025-07-18 Jonathan Wakely + Tomasz Kamiński + + PR libstdc++/119137 + * doc/doxygen/user.cfg.in (INPUT): Add new header. + * include/Makefile.am: Add new header. + * include/Makefile.in: Regenerate. + * include/bits/stl_iterator_base_types.h (__any_input_iterator): + Define. + * include/bits/version.def (inplace_vector): Define. + * include/bits/version.h: Regenerate. + * include/precompiled/stdc++.h: Include new header. + * src/c++23/std.cc.in: Export contents if new header. + * include/std/inplace_vector: New file. + * testsuite/23_containers/inplace_vector/access/capacity.cc: New file. + * testsuite/23_containers/inplace_vector/access/elem.cc: New file. + * testsuite/23_containers/inplace_vector/access/elem_neg.cc: New file. + * testsuite/23_containers/inplace_vector/cons/1.cc: New file. + * testsuite/23_containers/inplace_vector/cons/from_range.cc: New file. + * testsuite/23_containers/inplace_vector/cons/throws.cc: New file. + * testsuite/23_containers/inplace_vector/copy.cc: New file. + * testsuite/23_containers/inplace_vector/erasure.cc: New file. + * testsuite/23_containers/inplace_vector/modifiers/assign.cc: New file. + * testsuite/23_containers/inplace_vector/modifiers/erase.cc: New file. + * testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc: + New file. + * testsuite/23_containers/inplace_vector/modifiers/single_insert.cc: + New file. + * testsuite/23_containers/inplace_vector/move.cc: New file. + * testsuite/23_containers/inplace_vector/relops.cc: New file. + * testsuite/23_containers/inplace_vector/version.cc: New file. + * testsuite/util/testsuite_iterators.h (input_iterator_wrapper::base): + Define. + +2025-07-17 Jonathan Wakely + + PR libstdc++/96710 + * doc/xml/manual/evolution.xml: Document change or __int128. + * doc/html/manual/api.html: Regenerate. + +2025-07-17 Luc Grosheintz + + PR libstdc++/121061 + * include/std/mdspan (extents::extents): Perform conversion to + index_type of an r-value reference. + (layout_left::mapping::operator()): Ditto. + (layout_right::mapping::operator()): Ditto. + (layout_stride::mapping::operator()): Ditto. + * testsuite/23_containers/mdspan/extents/custom_integer.cc: Add + tests for RValueInt and MutatingInt. + * testsuite/23_containers/mdspan/int_like.h (RValueInt): Add. + * testsuite/23_containers/mdspan/layouts/mapping.cc: Test with + RValueInt. + * testsuite/23_containers/mdspan/mdspan.cc: Ditto. + +2025-07-17 Luc Grosheintz + + PR libstdc++/121061 + * include/std/mdspan (extents::extents): Fix constraint to + prevent non-const conversion to index_type. + (layout_stride::mapping::mapping): Ditto. + (mdspan::mdspan): Ditto. + (mdspan::operator[]): Ditto. + * testsuite/23_containers/mdspan/extents/custom_integer.cc: Add + test for MutatingInt. + * testsuite/23_containers/mdspan/int_like.h (MutatingInt): Add. + * testsuite/23_containers/mdspan/layouts/mapping.cc: Add test for + MutatingInt. + * testsuite/23_containers/mdspan/layouts/stride.cc: Ditto. + * testsuite/23_containers/mdspan/mdspan.cc: Ditto. + +2025-07-17 Luc Grosheintz + + PR libstdc++/121061 + * testsuite/23_containers/mdspan/extents/custom_integer.cc: + Enable checking with different custom integers. Improve + checking non-existence of overloads for incompatible custom + integers. + * testsuite/23_containers/mdspan/layouts/mapping.cc: ditto. Also + improve reuse of int_like.h. + * testsuite/23_containers/mdspan/layouts/stride.cc: ditto. + * testsuite/23_containers/mdspan/mdspan.cc: ditto. + * testsuite/23_containers/mdspan/extents/int_like.h: Rename (old + name). + * testsuite/23_containers/mdspan/int_like.h: Rename (new name). + (ThrowingInt): Add. + (NotIntLike): Add. + +2025-07-17 Jonathan Wakely + + * include/bits/unicode.h (__unicode::_Utf_iterator): Add + comments. + (__unicode:_Utf_iterator::operator++()): Check whether to + iterate over the buffer first. + +2025-07-17 Jonathan Wakely + + PR libstdc++/121097 + * include/c_global/cmath (hypot): Use __promote_3 instead of + __promoted. + +2025-07-16 Jonathan Wakely + + * include/std/bitset (__bitset::__string) [__cpp_lib_bitset]: + Change alias to refer to basic_string_view instead. + +2025-07-16 Tomasz Kamiński + + PR libstdc++/121114 + * include/bits/version.def (constexpr_exceptions): Add no_stdname + and changed value. + * include/bits/version.h: Regenerated. + * testsuite/18_support/exception/version.cc: Test that macro is + not exported. + +2025-07-15 Jonathan Wakely + + * include/bits/move.h (swap): Replace enable_if with concepts + when available, and with __enable_if_t alias otherwise. + +2025-07-15 Jonathan Wakely + + * include/bits/ranges_base.h (ranges::advance(i, n, bound)): + Ensure that observable side effects on iterators match what is + specified in the standard. + +2025-07-15 Patrick Palka + + PR libstdc++/119962 + * include/std/ranges (join_view::_Iterator::_M_outer): Initialize. + (lazy_split_view::_OuterIter::_M_current): Initialize. + (join_with_view::_Iterator::_M_outer_it): Initialize. + * testsuite/std/ranges/adaptors/join.cc (test15): New test. + * testsuite/std/ranges/adaptors/join_with/1.cc (test05): New test. + * testsuite/std/ranges/adaptors/lazy_split.cc (test13): New test. + +2025-07-15 Björn Schäpers + + PR libstdc++/108409 + * scripts/gen_windows_zones_map.py: New file, generates + windows_zones-map.h. + * src/c++20/windows_zones-map.h: New file, contains the look up + table. + * src/c++20/tzdb.cc (tzdb::current_zone): Add Windows code path. + +2025-07-15 Björn Schäpers + + * src/c++20/tzdb.cc (zoneinfo_file): On Windows look relative + from the DLL path for the time zone information. + +2025-07-15 Jonathan Wakely + + * testsuite/25_algorithms/copy/debug/constexpr_neg.cc: + * testsuite/25_algorithms/copy_backward/debug/constexpr_neg.cc: + * testsuite/25_algorithms/equal/debug/constexpr_neg.cc: + * testsuite/25_algorithms/lower_bound/debug/constexpr_partitioned_neg.cc: + * testsuite/25_algorithms/lower_bound/debug/constexpr_partitioned_pred_neg.cc: + * testsuite/25_algorithms/lower_bound/debug/constexpr_valid_range_neg.cc: + * testsuite/25_algorithms/upper_bound/debug/constexpr_partitioned_neg.cc: + * testsuite/25_algorithms/upper_bound/debug/constexpr_partitioned_pred_neg.cc: + * testsuite/25_algorithms/upper_bound/debug/constexpr_valid_range_neg.cc: + +2025-07-15 Jonathan Wakely + + PR libstdc++/121024 + * include/bits/ranges_uninitialized.h (ranges::destroy): Do not + optimize away trivial destructors during constant evaluation. + (ranges::destroy_n): Likewise. + * testsuite/20_util/specialized_algorithms/destroy/121024.cc: + New test. + +2025-07-15 Jonathan Wakely + + * include/experimental/memory (swap, make_observer_ptr): Add + constexpr. + (operator==, operator!=, operator<, operator>, operator<=) + (operator>=): Likewise. + * testsuite/experimental/memory/observer_ptr/make_observer.cc: + Checks for constant evaluation. + * testsuite/experimental/memory/observer_ptr/relops/relops.cc: + Likewise. + * testsuite/experimental/memory/observer_ptr/swap/swap.cc: + Likewise. + +2025-07-15 Jonathan Wakely + + * include/std/type_traits (__make_unsigned_selector): Add + unsigned __int128 to type list. + * testsuite/20_util/make_unsigned/int128.cc: New test. + +2025-07-15 Jonathan Wakely + + PR libstdc++/96710 + * include/bits/functional_hash.h (hash<__int128>): Define for + strict modes. + (hash): Likewise. + * testsuite/20_util/hash/int128.cc: New test. + +2025-07-15 Tomasz Kamiński + + PR libstdc++/110739 + * include/bits/chrono_io.h (__formatter_chrono::_S_weekdays) + (__formatter_chrono::_S_months, __formatter_chrono::_S_fill_ampm): + Define. + (__formatter_chrono::_M_format_to): Do not pass context parameter + to functions listed below. + (__formatter_chrono::_M_a_A, __formatter_chrono::_M_b_B): Implement + using harcoded list of names, and remove format context parameter. + (__formatter_chrono::_M_p, __formatter_chrono::_M_r): Implement + using _S_fill_ampm. + (__formatter_chrono::_M_c): Removed format context parameter. + (__formatter_chrono::_M_subsecs): Call __ctx.locale() directly, + instead of _M_locale and do not compare with locale::classic(). + Add [[unlikely]] attributes. + (__formatter_chrono::_M_locale): Move to __formatter_duration. + (__formatter_duration::_M_locale): Moved from __formatter_chrono. + +2025-07-14 Jonathan Wakely + + * include/bits/stl_pair.h (swap): Add comment to deleted + overload. + * include/bits/unique_ptr.h (swap): Likewise. + * include/std/array (swap): Likewise. + * include/std/optional (swap): Likewise. + * include/std/tuple (swap): Likewise. + * include/std/variant (swap): Likewise. + * testsuite/23_containers/array/tuple_interface/get_neg.cc: + Adjust dg-error line numbers. + +2025-07-14 Jonathan Wakely + + * include/pstl/algorithm_impl.h (__for_each_n_it_serial): + Protect against overloaded comma operator. + (__brick_walk2): Likewise. + (__brick_walk2_n): Likewise. + (__brick_walk3): Likewise. + (__brick_move_destroy::operator()): Likewise. + (__brick_calc_mask_1): Likewise. + (__brick_copy_by_mask): Likewise. + (__brick_partition_by_mask): Likewise. + (__brick_calc_mask_2): Likewise. + (__brick_reverse): Likewise. + (__pattern_partial_sort_copy): Likewise. + * include/pstl/memory_impl.h (__brick_uninitialized_move): + Likewise. + (__brick_uninitialized_copy): Likewise. + * include/pstl/numeric_impl.h (__brick_transform_scan): + Likewise. + +2025-07-14 Jonathan Wakely + + PR libstdc++/117785 + * include/bits/version.def (constexpr_exceptions): Define + correct value. + * include/bits/version.h: Regenerate. + * libsupc++/exception: Check correct value. + * testsuite/18_support/exception/version.cc: New test. + +2025-07-14 Jonathan Wakely + + * libsupc++/exception_ptr.h (make_exception_ptr): Return null + for consteval when -fno-exceptions is used. + (exception_ptr_cast): Likewise. Allow consteval path to work + with -fno-rtti. + +2025-07-11 Jakub Jelinek + + * libsupc++/exception_ptr.h: Implement C++26 P3748R0 - Inspecting + exception_ptr should be constexpr. + (std::exception_ptr_cast): Make constexpr, remove inline keyword. Add + static_asserts for Mandates. For if consteval use std::rethrow_exception, + catch it and return its address or nullptr. + * testsuite/18_support/exception_ptr/exception_ptr_cast.cc (E::~E): Add + constexpr. + (G::G): Likewise. + (test01): Likewise. Return bool and take bool argument, throw if the + argument is true. Add static_assert(test01(false)). + (main): Call test01(true) in try. + +2025-07-11 Jonathan Wakely + + * include/bits/cpp_type_traits.h (__is_floating<__float128>): + Do not depend on __STRICT_ANSI__. + * include/bits/stl_algobase.h (__size_to_integer(__float128)): + Likewise. + * include/std/type_traits (__is_floating_point_helper<__float128>): + Likewise. + +2025-07-11 Jonathan Wakely + + PR libstdc++/96710 + * include/bits/cpp_type_traits.h (__is_integer): Define explicit + specializations for __int128. + (__memcpyable_integer): Remove explicit specializations for + __int128. + * include/bits/iterator_concepts.h (incrementable_traits): + Likewise. + (__is_signed_int128, __is_unsigned_int128, __is_int128): Remove. + (__is_integer_like, __is_signed_integer_like): Remove check for + __int128. + * include/bits/max_size_type.h: Remove all uses of __is_int128 + in constraints. + * include/bits/ranges_base.h (__to_unsigned_like): Remove + overloads for __int128. + (ranges::ssize): Remove special case for __int128. + * include/bits/stl_algobase.h (__size_to_integer): Define + __int128 overloads for strict modes. + * include/ext/numeric_traits.h (__is_integer_nonstrict): Remove + explicit specializations for __int128. + * include/std/charconv (to_chars): Define overloads for + __int128. + * include/std/format (__format::make_unsigned_t): Remove. + (__format::to_chars): Remove. + * include/std/limits (numeric_limits): Define explicit + specializations for __int128. + * include/std/type_traits (__is_integral_helper): Likewise. + (__make_unsigned, __make_signed): Likewise. + +2025-07-10 Jakub Jelinek + + PR c++/117785 + * include/bits/version.def (constexpr_exceptions): New. + * include/bits/version.h: Regenerate. + * libsupc++/exception (std::bad_exception::bad_exception): Add + _GLIBCXX26_CONSTEXPR. + (std::bad_exception::~bad_exception, std::bad_exception::what): For + C++26 add constexpr and define inline. + * libsupc++/exception.h (std::exception::exception, + std::exception::operator=): Add _GLIBCXX26_CONSTEXPR. + (std::exception::~exception, std::exception::what): For C++26 add + constexpr and define inline. + * libsupc++/exception_ptr.h (std::make_exception_ptr): Add + _GLIBCXX26_CONSTEXPR. For if consteval use just throw with + current_exception() in catch. + (std::exception_ptr::exception_ptr(void*)): For C++26 add constexpr + and define inline. + (std::exception_ptr::exception_ptr()): Add _GLIBCXX26_CONSTEXPR. + (std::exception_ptr::exception_ptr(const exception_ptr&)): Likewise. + Use __builtin_eh_ptr_adjust_ref if consteval and compiler has it + instead of _M_addref. + (std::exception_ptr::exception_ptr(nullptr_t)): Add + _GLIBCXX26_CONSTEXPR. + (std::exception_ptr::exception_ptr(exception_ptr&&)): Likewise. + (std::exception_ptr::operator=): Likewise. + (std::exception_ptr::~exception_ptr): Likewise. Use + __builtin_eh_ptr_adjust_ref if consteval and compiler has it + instead of _M_release. + (std::exception_ptr::swap): Add _GLIBCXX26_CONSTEXPR. + (std::exception_ptr::operator bool): Likewise. + (std::exception_ptr::operator==): Likewise. + * libsupc++/nested_exception.h + (std::nested_exception::nested_exception): Add _GLIBCXX26_CONSTEXPR. + (std::nested_exception::operator=): Likewise. + (std::nested_exception::~nested_exception): For C++26 add constexpr + and define inline. + (std::nested_exception::rethrow_if_nested): Add _GLIBCXX26_CONSTEXPR. + (std::nested_exception::nested_ptr): Likewise. + (std::_Nested_exception::_Nested_exception): Likewise. + (std::throw_with_nested, std::rethrow_if_nested): Likewise. + * libsupc++/new (std::bad_alloc::bad_alloc): Likewise. + (std::bad_alloc::operator=): Likewise. + (std::bad_alloc::~bad_alloc): For C++26 add constexpr and define + inline. + (std::bad_alloc::what): Likewise. + (std::bad_array_new_length::bad_array_new_length): Add + _GLIBCXX26_CONSTEXPR. + (std::bad_array_new_length::~bad_array_new_length): For C++26 add + constexpr and define inline. + (std::bad_array_new_length::what): Likewise. + * libsupc++/typeinfo (std::bad_cast::bad_cast): Add + _GLIBCXX26_CONSTEXPR. + (std::bad_cast::~bad_cast): For C++26 add constexpr and define inline. + (std::bad_cast::what): Likewise. + (std::bad_typeid::bad_typeid): Add _GLIBCXX26_CONSTEXPR. + (std::bad_typeid::~bad_typeid): For C++26 add constexpr and define + inline. + (std::bad_typeid::what): Likewise. + +2025-07-10 Jakub Jelinek + + * testsuite/22_locale/codecvt/codecvt_unicode.h + (ucs2_to_utf8_out_error): Comment spelling fix: bellow -> below. + (utf16_to_ucs2_in_error): Likewise. + +2025-07-09 Jonathan Wakely + + * include/bits/stl_uninitialized.h (__uninitialized_default): + Do not use optimized implementation for constexpr case. Use + _GLIBCXX20_CONSTEXPR instead of _GLIBCXX26_CONSTEXPR. + +2025-07-09 Jonathan Wakely + + * include/std/mdspan (mdspan): Add template keyword for + dependent name. + +2025-07-09 Jonathan Wakely + + PR libstdc++/120997 + * include/std/span (span::first, span::last, span::subspan): Do + not use braced-init-list for return statements. + * testsuite/23_containers/span/120997.cc: New test. + +2025-07-09 Paul Keir + + PR libstdc++/117403 + * include/bits/shared_ptr.h (shared_ptr::owner_equal) + (shared_ptr::owner_hash, weak_ptr::owner_equal) + (weak_ptr::owner_hash): Define new member functions. + * include/bits/shared_ptr_base.h (owner_equal, owner_hash): + Define new structs. + * include/bits/version.def (smart_ptr_owner_equality): Define. + * include/bits/version.h: Regenerate. + * include/std/memory: Added define for + __glibcxx_want_smart_ptr_owner_equality. + * testsuite/20_util/owner_equal/version.cc: New test. + * testsuite/20_util/owner_equal/cmp.cc: New test. + * testsuite/20_util/owner_equal/noexcept.cc: New test. + * testsuite/20_util/owner_hash/cmp.cc: New test. + * testsuite/20_util/owner_hash/noexcept.cc: New test. + * testsuite/20_util/shared_ptr/observers/owner_equal.cc: New + test. + * testsuite/20_util/shared_ptr/observers/owner_hash.cc: + New test. + * testsuite/20_util/weak_ptr/observers/owner_equal.cc: New test. + * testsuite/20_util/weak_ptr/observers/owner_hash.cc: New test. + +2025-07-09 Mateusz Zych + + * include/bits/max_size_type.h (numeric_limits<__max_size_type>): + New members. + (numeric_limits<__max_diff_type>): Likewise. + * testsuite/std/ranges/iota/max_size_type.cc: New test cases. + +2025-07-09 Jonathan Wakely + + * src/c++17/memory_resource.cc: Adjust indentation of unnamed + namespaces. + (pool_sizes): Add comment. + (choose_block_size): Move outside preprocessor group for + gthreads targets. + * testsuite/20_util/synchronized_pool_resource/118681.cc: + Require gthreads. + +2025-07-09 H.J. Lu + + * config/abi/post/x86_64-linux-gnu/x32/baseline_symbols.txt: + Updated. + +2025-07-08 Jonathan Wakely + + PR libstdc++/118681 + * testsuite/20_util/unsynchronized_pool_resource/118681.cc: Fix + deallocate argument. + +2025-07-08 Jonathan Wakely + + PR libstdc++/118681 + * src/c++17/memory_resource.cc (choose_block_size): New + function. + (synchronized_pool_resource::do_allocate): Use choose_block_size + to determine appropriate block size. + (synchronized_pool_resource::do_deallocate): Likewise + (unsynchronized_pool_resource::do_allocate): Likewise. + (unsynchronized_pool_resource::do_deallocate): Likewise + * testsuite/20_util/synchronized_pool_resource/118681.cc: New + test. + * testsuite/20_util/unsynchronized_pool_resource/118681.cc: New + test. + +2025-07-08 Jonathan Wakely + + * include/debug/forward_list (_Safe_forward_list<>::_M_swap): + Adapt to _M_this() signature change. + +2025-07-08 Tomasz Kamiński + + PR libstdc++/119861 + * include/std/format (formatter<_Rg, _CharT>::set_separator) + (formatter<_Rg, _CharT>::set_brackets): Constrain with + (format_kind<_Rg> == range_format::sequence). + * testsuite/std/format/ranges/pr119861_neg.cc: New test. + +2025-07-08 Luc Grosheintz + + PR libstdc++/120914 + * include/std/span (span): Update CTAD to enable + integral constants [P3029R1]. + * include/std/mdspan (extents): ditto. + (mdspan): ditto. + * testsuite/23_containers/span/deduction.cc: Test deduction + guide. + * testsuite/23_containers/mdspan/extents/misc.cc: ditto. + * testsuite/23_containers/mdspan/mdspan.cc: ditto. + +2025-07-08 Luc Grosheintz + + * testsuite/23_containers/span/contiguous_range_neg.cc: Silence + warning about unused variable myspan. + +2025-07-08 Luc Grosheintz + + PR libstdc++/107761 + * include/bits/version.def (mdspan): Set to 202207 and remove + no_stdname. + * include/bits/version.h: Regenerate. + * testsuite/23_containers/mdspan/version.cc: Test presence + of feature test macro. + +2025-07-08 Luc Grosheintz + + PR libstdc++/107761 + * include/std/mdspan (mdspan): New class. + * src/c++23/std.cc.in (mdspan): Add. + * testsuite/23_containers/mdspan/class_mandate_neg.cc: New test. + * testsuite/23_containers/mdspan/mdspan.cc: New test. + * testsuite/23_containers/mdspan/layout_like.h: Add class + LayoutLike which models a user-defined layout. + * testsuite/23_containers/mdspan/out_of_bounds_neg.cc: New file. + +2025-07-08 Luc Grosheintz + + * include/std/mdspan (__mdspan::__size): New function. + +2025-07-08 Luc Grosheintz + + * testsuite/23_containers/mdspan/extents/custom_integer.cc: + Delete IntLike and include "int_like.h". + * testsuite/23_containers/mdspan/extents/int_like.h: Add + IntLike. + +2025-07-08 Luc Grosheintz + + * include/std/mdspan (extents): Check prerequisite of the ctor that + static_extent(i) == dynamic_extent || extent(i) == other.extent(i). + * testsuite/23_containers/mdspan/extents/class_mandates_neg.cc: + Test the implemented prerequisite. + * testsuite/23_containers/mdspan/extents/extents_mismatch_neg.cc: New file. + +2025-07-08 Luc Grosheintz + + * include/std/mdspan: Check prerequisites of + layout_*::operator() with _GLIBCXX_DEBUG_ASSERTs. + * testsuite/23_containers/mdspan/layouts/debug/out_of_bounds_neg.cc: + Add tests for prerequisites. + +2025-07-08 Tomasz Kamiński + + * include/std/queue (formatter, _CharT>) + (formatter, _CharT>): + Add _GLIBCXX_RESOLVE_LIB_DEFECTS comments. + +2025-07-08 François Dumont + + PR c++/116369 + * config/abi/pre/gnu-versioned-namespace.ver: Use new const qualified symbols. + * config/abi/pre/gnu.ver: Add new const qualified symbols. + * include/debug/safe_base.h + (_Safe_iterator_base::_M_sequence): Declare as pointer-to-const. + (_Safe_iterator_base::_M_attach, _M_attach_single): New, take pointer-to-const + _Safe_sequence_base. + (_Safe_sequence_base::_M_detach_all, _M_detach_singular, _M_revalidate_singular) + (_M_swap, _M_get_mutex): New, const qualified. + (_Safe_sequence_base::_M_attach, _M_attach_single, _M_detach, _M_detach_single): + const qualify. + * include/debug/safe_container.h (_Safe_container<>::_M_cont): Add const qualifier. + (_Safe_container<>::_M_swap_base): New. + (_Safe_container(_Safe_container&&, const _Alloc&, std::false_type)): + Adapt to use latter. + (_Safe_container<>::operator=(_Safe_container&&)): Likewise. + (_Safe_container<>::_M_swap): Likewise and take parameter as const reference. + * include/debug/safe_unordered_base.h + (_Safe_local_iterator_base::_M_safe_container): New. + (_Safe_local_iterator_base::_Safe_local_iterator_base): Take + _Safe_unordered_container_base as pointer-to-const. + (_Safe_unordered_container_base::_M_attach, _M_attach_single): New, take + container as _Safe_unordered_container_base pointer-to-const. + (_Safe_unordered_container_base::_M_local_iterators, _M_const_local_iterators): + Add mutable. + (_Safe_unordered_container_base::_M_detach_all, _M_swap): New, const qualify. + (_Safe_unordered_container_base::_M_attach_local, _M_attach_local_single) + (_M_detach_local, _M_detach_local_single): Add const qualifier. + * include/debug/safe_unordered_container.h (_Safe_unordered_container::_M_self()): New. + * include/debug/safe_unordered_container.tcc + (_Safe_unordered_container::_M_invalidate_if, _M_invalidated_local_if): Use latter. + * include/debug/safe_iterator.h (_Safe_iterator<>::_M_attach, _M_attach_single): + Take _Safe_sequence_base as pointer-to-const. + (_Safe_iterator<>::_M_get_sequence): Add const_cast and comment about it. + * include/debug/safe_local_iterator.h (_Safe_local_iterator<>): Replace usages + of _M_sequence member by _M_safe_container(). + (_Safe_local_iterator<>::_M_attach, _M_attach_single): Take + _Safe_unordered_container_base as pointer-to-const. + (_Safe_local_iterator<>::_M_get_sequence): Rename into... + (_Safe_local_iterator<>::_M_get_ucontainer): ...this. Add necessary const_cast and + comment to explain it. + (_Safe_local_iterator<>::_M_is_begin, _M_is_end): Adapt. + * include/debug/safe_local_iterator.tcc: Adapt. + * include/debug/safe_sequence.h + (_Safe_sequence<>::_M_invalidate_if, _M_transfer_from_if): Add const qualifier. + * include/debug/safe_sequence.tcc: Adapt. + * include/debug/deque (std::__debug::deque::erase): Adapt to use new const + qualified methods. + * include/debug/formatter.h: Adapt. + * include/debug/forward_list (_Safe_forward_list::_M_this): Add const + qualification and return pointer for consistency with 'this' keyword. + (_Safe_forward_list::_M_swap_aux): Rename into... + (_Safe_forward_list::_S_swap_aux): ...this and take sequence as const reference. + (forward_list<>::resize): Adapt to use const methods. + * include/debug/list (list<>::resize): Likewise. + * src/c++11/debug.cc: Adapt to const qualification. + * testsuite/util/testsuite_containers.h + (forward_members_unordered::forward_members_unordered): Add check on local_iterator + conversion to const_local_iterator. + (forward_members::forward_members): Add check on iterator conversion to + const_iterator. + * testsuite/23_containers/unordered_map/const_container.cc: New test case. + * testsuite/23_containers/unordered_multimap/const_container.cc: New test case. + * testsuite/23_containers/unordered_multiset/const_container.cc: New test case. + * testsuite/23_containers/unordered_set/const_container.cc: New test case. + * testsuite/23_containers/vector/debug/mutex_association.cc: Adapt. + +2025-07-07 Jonathan Wakely + + PR libstdc++/120949 + * include/bits/stl_iterator.h (__normal_iterator): Fix order of + always_inline and nodiscard attributes for Clang compatibility. + +2025-07-07 Jonathan Wakely + + * testsuite/util/testsuite_hooks.h (VERIFY): Define as variadic + macro. + * testsuite/ext/verify_neg.cc: New test. + +2025-07-07 Jonathan Wakely + + * include/std/mdspan (__mapping_of): Add template keyword. + +2025-07-07 XU Kailiang + Tomasz Kaminski + + PR libstdc++/117214 + * include/bits/chrono_io.h (_ChronoSpec::_M_time_only): Remove. + (_ChronoSpec::_M_time_point): Define. + (__formatter_chrono::_M_parse): Use __parts to determine + interpretation of j. + (__formatter_chrono::_M_check_ok): Define. + (__formatter_chrono::_M_format_to): Invoke _M_check_ok. + (__formatter_chrono::_M_a_A, __formatter_chrono::_M_b_B): Move + exception throwing to _M_check_ok. + (__formatter_chrono::_M_j): Use _M_needs to define interpretation. + (__formatter_duration::_S_spec_for): Set _M_time_point. + * testsuite/std/time/format/format.cc: Test for exception for !ok() + months/weekday. + * testsuite/std/time/format/pr117214_custom_timeput.cc: New + test. + +2025-07-07 Tomasz Kamiński + + PR libstdc++/120976 + * include/std/format (formatter<__float128, _Char_T): Define if + _GLIBCXX_FORMAT_F128 == 2. + +2025-07-06 Patrick Palka + + * include/bits/ranges_algo.h (shift_left, shift_right): Guard + with __glibcxx_shift >= 201806L. + (ranges::__shift_left_fn, ranges::shift_left): Define for C++23. + (ranges::__shift_right_fn, ranges::shift_right): Likewise. + * include/bits/version.def (shift): Update for C++23. + * include/bits/version.h: Regenerate. + * src/c++23/std.cc.in: Add ranges::shift_left/right. + * testsuite/25_algorithms/shift_left/constrained.cc: New test, + based off of 1.cc. + * testsuite/25_algorithms/shift_right/constrained.cc: New test, + based off of 1.cc. + +2025-07-04 Jonathan Wakely + + * include/bits/chrono_io.h (__formatter_duration::_S_spec_for): + Add default case to switch and use __builtin_unreachable. + +2025-07-04 Jonathan Wakely + + * include/bits/stl_algobase.h (__size_to_integer): Move + misplaced unsigned keyword on __size_to_integer overloads for + __GLIBCXX_TYPE_INT_N_3 integer type. + +2025-07-03 Nathan Myers + + * include/bits/version.def: Fix typo. + * include/bits/version.h: Rebuilt. + +2025-07-03 Patrick Palka + + PR libstdc++/120934 + * include/std/ranges (concat_view::end): Refine condition + for returning an iterator instead of default_sentinel as + per the updated P/R for LWG 4166. + * testsuite/std/ranges/concat/1.cc (test05): New test. + +2025-07-03 Nathan Myers + + PR libstdc++/119742 + * include/bits/version.def: Add preprocessor symbol. + * include/bits/version.h: Add preprocessor symbol. + * include/std/bitset: Add constructor. + * testsuite/20_util/bitset/cons/1.cc: Fix. + * testsuite/20_util/bitset/cons/6282.cc: Fix. + * testsuite/20_util/bitset/cons/string_view.cc: Test new ctor. + * testsuite/20_util/bitset/cons/string_view_wide.cc: Test new ctor. + +2025-07-03 Jonathan Wakely + + PR libstdc++/120931 + * include/bits/stl_uninitialized.h (__uninitialized_fill): + Fix typo resulting in call to __do_uninit_copy instead of + __do_uninit_fill. + * testsuite/20_util/specialized_algorithms/uninitialized_fill/120931.cc: + New test. + +2025-07-02 Jonathan Wakely + + * include/bits/stl_iterator.h (__normal_iterator): Make all + non-member operators hidden friends, except ... + (operator<=>(__normal_iterator, __normal_iterator)): + Remove. + * src/c++11/string-inst.cc: Remove explicit instantiations of + operators that are no longer templates. + * src/c++23/std.cc.in (__gnu_cxx): Do not export operators for + __normal_iterator. + +2025-07-02 Nathan Myers + + PR libstdc++/119744 + * include/std/ranges: View ctors become explicit. + +2025-07-01 Patrick Palka + + PR libstdc++/120789 + * include/bits/ranges_algo.h (__remove_if_fn::operator()): Use + ranges::iter_move(iter) instead of std::move(*iter). + * testsuite/25_algorithms/remove_if/120789.cc: New test. + +2025-07-01 Patrick Palka + + PR libstdc++/120789 + * include/bits/ranges_algo.h (__unique_fn::operator()): Use + ranges::iter_move(iter) instead of std::move(*iter). + * testsuite/25_algorithms/unique/120789.cc: New test. + +2025-07-01 Luc Grosheintz + + * include/std/mdspan (default_accessor): New class. + * src/c++23/std.cc.in: Register default_accessor. + * testsuite/23_containers/mdspan/accessors/default.cc: New test. + * testsuite/23_containers/mdspan/accessors/default_neg.cc: New test. + +2025-06-27 Patrick Palka + + PR libstdc++/100795 + * include/bits/ranges_algo.h (shuffle_fn::operator()): + Reimplement directly, based on the stl_algo.h implementation. + * testsuite/25_algorithms/shuffle/constrained.cc (test02): + New test. + +2025-06-27 Patrick Palka + + PR libstdc++/100795 + * include/bits/ranges_algo.h (__sample_fn::operator()): + Reimplement the forward_iterator branch directly, based + on the stl_algo.h implementation. Add explicit cast to + _Out's difference_type in the !forward_iterator branch. + * testsuite/25_algorithms/sample/constrained.cc (test02): + New test. + +2025-06-27 Patrick Palka + + PR libstdc++/100795 + * include/bits/ranges_algo.h (__detail::__introselect): New, + based on the stl_algo.h implementation. + (nth_element_fn::operator()): Reimplement in terms of the above. + * testsuite/25_algorithms/nth_element/constrained.cc: + +2025-06-27 Patrick Palka + + PR libstdc++/100795 + * include/bits/ranges_algo.h (__detail::__find_if_not_n): New, + based on the stl_algo.h implementation. + (__detail::__stable_partition_adaptive): Likewise. + (__stable_partition_fn::operator()): Reimplement in terms of + the above. + * testsuite/25_algorithms/stable_partition/constrained.cc + (test03): New test. + +2025-06-27 Patrick Palka + + PR libstdc++/100795 + * include/bits/ranges_algo.h (__detail::__move_merge): New, + based on the stl_algo.h implementation. + (__detail::__merge_sort_loop): Likewise. + (__detail::__chunk_insertion_sort): Likewise. + (__detail::__merge_sort_with_buffer): Likewise. + (__detail::__stable_sort_adaptive): Likewise. + (__detail::__stable_sort_adaptive_resize): Likewise. + (__detail::__inplace_stable_sort): Likewise. + (__stable_sort_fn::operator()): Reimplement in terms of the above. + * testsuite/25_algorithms/stable_sort/constrained.cc: + +2025-06-27 Patrick Palka + + PR libstdc++/100795 + * include/bits/ranges_algo.h (__detail::__move_merge_adaptive): + New, based on the stl_algo.h implementation. + (__detail::__move_merge_adaptive_backward): Likewise. + (__detail::__rotate_adaptive): Likewise. + (__detail::__merge_adaptive): Likewise. + (__detail::__merge_adaptive_resize): Likewise. + (__detail::__merge_without_buffer): Likewise. + (__inplace_merge_fn::operator()): Reimplement in terms of the + above. + * testsuite/25_algorithms/inplace_merge/constrained.cc (test03): + New test. + +2025-06-27 Patrick Palka + + PR libstdc++/100795 + PR libstdc++/118209 + * include/bits/max_size_type.h (__bit_width): New explicit + specialization for __max_size_type. + * include/bits/ranges_algo.h (__detail::__move_median_to_first): + New, based on the stl_algo.h implementation. + (__detail::__unguarded_liner_insert): Likewise. + (__detail::__insertion_sort): Likewise. + (__detail::__sort_threshold): Likewise. + (__detail::__unguarded_insertion_sort): Likewise. + (__detail::__final_insertion_sort): Likewise. + (__detail::__unguarded_partition): Likewise. + (__detail::__unguarded_partition_pivot): Likewise. + (__detail::__heap_select): Likewise. + (__detail::__partial_sort): Likewise. + (__detail::__introsort_loop): Likewise. + (__sort_fn::operator()): Reimplement in terms of the above. + * testsuite/25_algorithms/sort/118209.cc: New test. + * testsuite/25_algorithms/sort/constrained.cc (test03): New test. + +2025-06-27 Patrick Palka + + PR libstdc++/100795 + * include/bits/ranges_algo.h (__detail::__push_heap): New, + based on the stl_heap.h implementation. + (__push_heap_fn::operator()): Reimplement in terms of the above. + (__detail::__adjust_heap): New, based on the stl_heap.h + implementation. + (__deatil::__pop_heap): Likewise. + (__pop_heap_fn::operator()): Reimplement in terms of the above. + (__make_heap_fn::operator()): Likewise. + (__sort_heap_fn::operator()): Likewise. + * testsuite/25_algorithms/heap/constrained.cc (test03): New + test. + +2025-06-27 Tomasz Kamiński + + PR libstdc++/110739 + * include/bits/chrono_io.h (__formatter_chrono::_S_empty_fs): Define. + (__formatter_chrono::_S_str_d2): Use _S_str_d3 for 3+ digits and + place allways_inline attribute after comment. + (__formatter_chrono::_S_str_d3): Extracted from _S_str_d2. + (__formatter_chrono::_M_H_I, __formatter_chrono::_M_R_X): Replace + _S_empty_spec with _S_empty_fs(). + (__formatter_chrono::_M_j): Likewise and use _S_str_d3 in common + case. + (__format::operator-(_ChronoParts, _ChronoParts)) + (__format::operator-=(_ChronoParts, _ChronoParts)) + (__formatter_chrono::_S_fill_two_digits) + (__formatter_chrono::_S_str_d1): Place always_inline attribute + after comment. + +2025-06-27 Tomasz Kamiński + + PR libstdc++/110739 + * include/bits/chrono_io.h (__formatter_chrono::_M_format_to): + Rename _Out to _OutIter for consistency, and update calls + to specifier functions. + (__formatter_chrono::_M_wi, __formatter_chrono::_M_C_y_Y) + (__formatter_chrono::_M_D_x, __formatter_chrono::_M_d_e) + (__formatter_chrono::_M_F, __formatter_chrono::_M_g_G) + (__formatter_chrono::_M_H_I, __formatter_chrono::_M_j) + (__formatter_chrono::_M_m, __formatter_chrono::_M_M) + (__formatter_chrono::_M_q, __formatter_chrono::_M_R_X) + (__formatter_chrono::_M_u_w, __formatter_chrono::_M_U_V_W) + (__formatter_chrono::_M_z, __formatter_chrono::_M_z): + Remove _FormatContext parameter, and introduce _OutIter + for __out type. + (__formatter_chrono::_M_a_A, __formatter_chrono::_M_B_b) + (__formatter_chrono::_M_p, __formatter_chrono::_M_Q) + (__formatter_chrono::_M_r, __formatter_chrono::_M_S) + (__formatter_chrono::_M_subsecs, __formatter_chrono::_M_T): + Introduce separate _OutIter template parameter for __out. + (__formatter_chrono::_M_c, __formatter_chrono::_M_T): + Likewise, and adjust calls to specifiers functions. + * testsuite/std/time/format/empty_spec.cc: Make underlying + type for Rep configurable. + +2025-06-27 Iain Sandoe + + * config/abi/pre/gnu.ver: Keep the closing brace of the + CXXABI_1.3.17 symbol group together with the identifier + for the inherited group. + +2025-06-26 Tomasz Kamiński + + PR libstdc++/110739 + * include/bits/chrono_io.h (__formatter_chrono::_M_use_locale_fmt): + Define. + (__formatter_chrono::_M_locale_fmt): Moved to front of the class. + (__formatter_chrono::_M_format_to): Construct and initialize + struct tm and call _M_locale_fmt if needed. + (__formatter_chrono::_M_c_r_x_X): Split into separate methods. + (__formatter_chrono::_M_c, __formatter_chrono::_M_r): Define. + (__formatter_chrono::_M_D): Renamed to _M_D_x. + (__formatter_chrono::_M_D_x): Renamed from _M_D. + (__formatter_chrono::_M_R_T): Split into _M_R_X and _M_T. + (__formatter_chrono::_M_R_X): Extracted from _M_R_T. + (__formatter_chrono::_M_T): Define in terms of _M_R_X and _M_subsecs. + (__formatter_chrono::_M_subsecs): Extracted from _M_S. + (__formatter_chrono::_M_S): Replaced __mod with __subs argument, + removed _M_locale_fmt call, and delegate to _M_subsecs. + (__formatter_chrono::_M_C_y_Y, __formatter_chrono::_M_d_e) + (__formatter_chrono::_M_H_I, __formatter_chrono::_M_m) + (__formatter_chrono::_M_u_w, __formatter_chrono::_M_U_V_W): Remove + __mod argument and call to _M_locale_fmt. + +2025-06-26 Tomasz Kamiński + + PR libstdc++/110739 + * include/bits/chrono_io.h (__format::__no_timezone_available): + Removed, replaced with separate throws in formatter for + __local_time_fmt + (__format::_ChronoParts): Defined additional enumertors and + declared as enum class. + (__format::operator&(_ChronoParts, _ChronoParts)) + (__format::operator&=(_ChronoParts&, _ChronoParts)) + (__format::operator-(_ChronoParts, _ChronoParts)) + (__format::operator-=(_ChronoParts&, _ChronoParts)) + (__format::operator==(_ChronoParts, decltype(nullptr))) + (_ChronoSpec::_M_time_only, _ChronoSpec::_M_floating_point_rep) + (_ChronoSpec::_M_custom_rep, _ChronoSpec::_M_needed) + (_ChronoSpec::_M_needs, __format::_ChronoData): Define. + (__format::__formatter_chrono): Redefine to accept _ChronoData. + (__formatter_chrono::_M_format_to_ostream): Moved to + __formatter_duration. + (__format::__formatter_duration): Define. + (__formatter_chrono_info::format): Pass value-constructed + _ChronoData. + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter): + Construct _ChronoData in format, and configure _M_needed in + _ChronoSpec. + (std::formatter, _CharT>) + (std::formatter, _CharT>) + (std::formatter, _CharT>) + (std::formatter, _CharT>) + (std::formatter, _CharT>) + (std::formatter, _CharT>) + (std::formatter, _CharT>) + (std::formatter, _CharT>) + (std::formatter, _CharT>): + Reworked in terms of __formatter_duration and _ChronoData. + (std::formatter, _CharT>): + Removed. + (_Parser<_Duration>::operator()): Adjusted for _ChronoParts + being enum class. + * include/std/chrono (__detail::__utc_leap_second): Removed, + replaced with simply bumping _M_seconds in _ChronoData. + * testsuite/std/time/format/empty_spec.cc: Updated %S integral + ouput. + +2025-06-26 Jakub Jelinek + + * include/bits/version.def (exception_ptr_cast): Add. + * include/bits/version.h: Regenerate. + * libsupc++/exception: Define __glibcxx_want_exception_ptr_cast before + including bits/version.h. + * libsupc++/exception_ptr.h (std::exception_ptr_cast): Define. + (std::__exception_ptr::exception_ptr::_M_exception_ptr_cast): Declare. + * libsupc++/eh_ptr.cc + (std::__exception_ptr::exception_ptr::_M_exception_ptr_cast): Define. + * src/c++23/std.cc.in (std::exception_ptr_cast): Export. + * config/abi/pre/gnu.ver: Export + _ZNKSt15__exception_ptr13exception_ptr21_M_exception_ptr_castERKSt9type_info + at CXXABI_1.3.17. + * testsuite/util/testsuite_abi.cc (check_version): Allow CXXABI_1.3.17. + * testsuite/18_support/exception_ptr/exception_ptr_cast.cc: New test. + +2025-06-26 Jakub Jelinek + + * include/bits/version.def (type_order): New. + * include/bits/version.h: Regenerate. + * libsupc++/compare: Define __glibcxx_want_type_order before + including bits/version.h. + (std::type_order, std::type_order_v): New trait and template variable. + * src/c++23/std.cc.in (std::type_order, std::type_order_v): Export. + * testsuite/18_support/comparisons/type_order/1.cc: New test. + +2025-06-25 Tomasz Kamiński + + * testsuite/std/time/format/precision.cc: New tests. + +2025-06-25 Tomasz Kamiński + + PR libstdc++/120650 + * include/bits/chrono_io.h + (formatter::parse): Call _M_parse with + only Month being available. + * testsuite/std/time/format/data_not_present_neg.cc: New test. + +2025-06-24 Patrick Palka + Jonathan Wakely + + PR libstdc++/120717 + * include/std/type_traits (__maybe_complete_object_type): New + helper trait, factored out from ... + (__is_complete_or_unbounded): ... here. Only check sizeof on a + __maybe_complete_object_type type. Fix formatting. + * testsuite/20_util/is_complete_or_unbounded/120717.cc: New test. + +2025-06-16 Jason Merrill + + * testsuite/20_util/is_complete_or_unbounded/memoization.cc + * testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc: + Expect -Wsfinae-incomplete. + +2025-06-13 Jonathan Wakely + + PR libstdc++/120397 + * include/bits/stl_uninitialized.h (_UninitDestroyGuard): + Add new member function _S_destroy and call it from the + destructor (for C++17 only). + * testsuite/20_util/specialized_algorithms/uninitialized_default_construct/120397.cc: + New test. + * testsuite/20_util/specialized_algorithms/uninitialized_value_construct/120397.cc: + New test. + +2025-06-13 Tomasz Kamiński + + PR libstdc++/120648 + * include/bits/chrono_io.h (__formatter_chrono::_M_format_to): + Handle %c, %r, %x and %X by passing them to _M_c_r_x_X. + (__formatter_chrono::_M_c_r_x_X): Reworked from _M_c. + (__formatter_chrono::_M_c): Renamed into above. + (__formatter_chrono::_M_r, __formatter_chrono::_M_x) + (__formatter_chrono::_M_X): Removed. + * testsuite/std/time/format/pr117214.cc: New tests for %r, %x, + %X with date, time and durations. + +2025-06-13 Patrick Palka + + * include/bits/ranges_algo.h (__detail::__by_ref_or_value_fn): New. + (__detail::_Comp_proj): New. + (__detail::__make_comp_proj): Use it instead. + (__detail::_Pred_proj): New. + (__detail::__make_pred_proj): Use it instead. + +2025-06-13 Giuseppe D'Angelo + + PR c++/120644 + * include/std/optional (format_kind): Do not use `auto`. + +2025-06-13 Tomasz Kamiński + + * testsuite/23_containers/vector/bool/format.cc: Replaced _CharT + with CharT. + * testsuite/std/format/debug.cc: Likewise. + * testsuite/std/format/ranges/adaptors.cc: Likewise. + * testsuite/std/format/ranges/formatter.cc: Likewise. + * testsuite/std/format/ranges/map.cc: Likewise. + * testsuite/std/format/ranges/sequence.cc: Likewise. + * testsuite/std/format/ranges/string.cc: Likewise. + * testsuite/std/format/tuple.cc: Likewise. + * testsuite/std/time/format/empty_spec.cc: Likewise. + * testsuite/std/time/format/pr120114.cc: Likewise. + * testsuite/std/time/format/pr120481.cc: Likewise. + * testsuite/std/time/format/precision.cc: Likewise. + +2025-06-13 Tomasz Kamiński + + * include/bits/chrono_io.h (__formatter_chrono::_M_format): + Remove handling of empty _M_chrono_specs. + (__formatter_chrono::_M_format_to_ostream): Changed to accept + only chrono::duration and made public. + (std::formatter, _CharT>): + Configure __defSpec and handle empty chrono-spec locally. + +2025-06-13 Tomasz Kamiński + + * include/bits/chrono_io.h (__format::__formatter_chrono_info) + [_GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI]: Define. + (std::formatter) + (std::formatter): Delegate to + __format::__formatter_chrono_info. + (std::operator<<(basic_ostream<_CharT, _Traits>& const sys_info&)): + Use format on sys_info with empty format spec. + +2025-06-13 Tomasz Kamiński + + * testsuite/std/time/format/whitespace.cc: New test. + +2025-06-12 Giuseppe D'Angelo + + PR libstdc++/119496 + * include/bits/stl_algo.h: Adjust calls to requested_size. + * include/bits/stl_tempbuf.h (requested_size): Rename with + an _M_ prefix. + * testsuite/17_intro/names.cc: Add a #define for + requested_size. + +2025-06-12 Giuseppe D'Angelo + + * include/bits/formatfwd.h (format_kind): Move the definition + (and some supporting code) from . + * include/std/format (format_kind): Likewise. + * include/bits/version.def (optional_range_support): Add + the feature-testing macro. + * include/bits/version.h: Regenerate. + * include/std/optional (iterator, const_iterator, begin, end): + Add range support. + (enable_view): Specialize for std::optional. + (format_kind): Specialize for std::optional. + * testsuite/20_util/optional/range.cc: New test. + * testsuite/20_util/optional/version.cc: Test the new + feature-testing macro. + +2025-06-12 Tomasz Kamiński + + * include/bits/chrono_io.h (_ChronoFormats::_S_ftz) + (_ChronoFormats::_S_ft, _ChronoFormats::_S_t): Define. + (__formatter_chrono::_M_format_to_ostream): Remove handling for + time_points. + (std::formatter, _CharT>) + (std::formatter, _CharT>) + (std::formatter, _CharT>) + (std::formatter, _CharT>) + (std::formatter, _CharT>) + (std::formatter, _CharT>) + (std::formatter, _CharT>) + (std::formatter, _CharT>) + (std::formatter, _CharT>): + Define __defSpec, and pass it as argument to _M_prase and + constructor of __formatter_chrono. + +2025-06-12 Tomasz Kamiński + + * include/bits/chrono_io.h (__format::_ChronoFormats): Define. + (__formatter_chrono::__formatter_chrono()) + (__formatter_chrono::__formatter_chrono(_ChronoSpec<_CharT>)): Define. + (__formatter_chrono::_M_parse): Add parameter with default spec, + and merge it with new values. Handle '%\0' as weekday index + specifier. + (__formatter_chrono::_M_a_A, __formatter_chrono::_M_b_B) + (__formatter_chrono::_M_C_y_Y, __formatter_chrono::_M_d_e) + (__formatter_chrono::_M_F): Support _M_debug flag. + (__formatter_chrono::_M_wi, __formatter_chrono::_S_weekday_index): + Define. + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter) + (std::formatter): + Define __defSpec, and pass it as argument to _M_parse and + constructor of __formatter_chrono. + +2025-06-12 Tomasz Kamiński + + * include/std/mdspan (__mdspan::__mapping_alike): Rename template + parameter from M to _M_p. + (layout_right::mapping): Replace class with typename in template + head. + (layout_stride::mapping): Fix typo in comment. + * testsuite/23_containers/mdspan/layouts/class_mandate_neg.cc: + Changed B to function. + +2025-06-12 Luc Grosheintz + + * include/std/mdspan (layout_left): Strengthen the exception + guarantees of layout_left::mapping(layout_stride::mapping). + * testsuite/23_containers/mdspan/layouts/ctors.cc: + Simplify tests to reflect the change. + +2025-06-12 Luc Grosheintz + + * testsuite/23_containers/mdspan/layouts/class_mandate_neg.cc: Add + tests for layout_stride. + * testsuite/23_containers/mdspan/layouts/ctors.cc: Add test for + layout_stride and the interaction with other layouts. + * testsuite/23_containers/mdspan/layouts/empty.cc: Ditto. + * testsuite/23_containers/mdspan/layouts/mapping.cc: Ditto. + * testsuite/23_containers/mdspan/layouts/stride.cc: New test. + +2025-06-12 Luc Grosheintz + + * include/std/mdspan (layout_stride): New class. + * src/c++23/std.cc.in: Add layout_stride. + +2025-06-12 Luc Grosheintz + + * testsuite/23_containers/mdspan/layouts/class_mandate_neg.cc: Add + tests for layout_right. + * testsuite/23_containers/mdspan/layouts/ctors.cc: Add tests for + layout_right and the interaction with layout_left. + * testsuite/23_containers/mdspan/layouts/empty.cc: ditto. + * testsuite/23_containers/mdspan/layouts/mapping.cc: ditto. + +2025-06-12 Luc Grosheintz + + * include/std/mdspan (layout_right): New class. + * src/c++23/std.cc.in: Add layout_right. + +2025-06-12 Luc Grosheintz + + * testsuite/23_containers/mdspan/layouts/class_mandate_neg.cc: New test. + * testsuite/23_containers/mdspan/layouts/ctors.cc: New test. + * testsuite/23_containers/mdspan/layouts/empty.cc: New test. + * testsuite/23_containers/mdspan/layouts/mapping.cc: New test. + +2025-06-12 Luc Grosheintz + + * include/std/mdspan (layout_left): New class. + * src/c++23/std.cc.in: Add layout_left. + +2025-06-12 Luc Grosheintz + + * include/std/mdspan(__mdspan::_ExtentsStorage): Change name + of private member _M_dynamic_extens to _M_dyn_exts. + (extents): Change name of private member from _M_dynamic_extents + to _M_exts. + Fix two instances of whitespace errors. + * testsuite/23_containers/mdspan/extents/ctor_default.cc: Fix + integer comparison with cmp_equal. + +2025-06-12 Jonathan Wakely + + * doc/xml/manual/test.xml: Improve discussion of copyright + notices in new test cases. + * doc/html/manual/test.html: Regenerate. + +2025-06-12 Jonathan Wakely + + * scripts/create_testsuite_files: Remove incorrect comment about + filtering out wchar_t tests. + +2025-06-12 Jonathan Wakely + + PR libstdc++/120625 + * include/std/format (__format::__disabled): Remove. + (__formatter_disabled): New type. + (formatter, formatter) + (formatter, formatter) + (formatter): Use __formatter_disabled as + base class instead of formatter<__disabled, wchar_t>. + * testsuite/std/format/formatter/120625.cc: New test. + +2025-06-11 Jonathan Wakely + + * doc/doxygen/user.cfg.in (PREDEFINED): Remove -D prefixes from + some macros. Define _GLIBCXX_USE_BUILTIN_TRAIT and + _GLIBCXX_HAVE_ICONV macros. + +2025-06-11 Jonathan Wakely + + * libsupc++/exception: Remove redundant parentheses and adjust + whitespace. + +2025-06-11 Jonathan Wakely + + * include/std/type_traits: Restore @cond and @endcond balance. + +2025-06-11 Tomasz Kamiński + + * testsuite/std/time/format/empty_spec.cc: New tests. + * testsuite/std/time/format/precision.cc: New test. + +2025-06-11 Jonathan Wakely + + * include/bits/stl_construct.h: Replace std::__addressof with + std::addressof in code that doesn't need to compile as C++98. + Replace std::__is_constant_evaluated with + std::is_constant_evaluated in code that doesn't need to compile + as C++17 or earlier. + * include/bits/stl_uninitialized.h: Likewise for __addressof. + +2025-06-11 Jonathan Wakely + + * doc/xml/manual/test.xml: Remove note about unused 'test' + variables for old definition of VERIFY. + * doc/html/manual/test.html: Regenerate. + * testsuite/experimental/net/buffer/arithmetic.cc: Remove unused + variable. + * testsuite/experimental/net/buffer/const.cc: Likewise. + * testsuite/experimental/net/buffer/mutable.cc: Likewise. + * testsuite/experimental/net/buffer/size.cc: Likewise. + * testsuite/experimental/net/timer/waitable/cons.cc: Likewise. + * testsuite/experimental/net/timer/waitable/dest.cc: Likewise. + * testsuite/experimental/net/timer/waitable/ops.cc: Likewise. + * testsuite/ext/special_functions/airy_ai/check_value.cc: + Likewise. + * testsuite/ext/special_functions/airy_bi/check_value.cc: + Likewise. + * testsuite/ext/special_functions/conf_hyperg/check_value.cc: + Likewise. + * testsuite/ext/special_functions/hyperg/check_value.cc: + Likewise. + * testsuite/special_functions/01_assoc_laguerre/check_value.cc: + Likewise. + * testsuite/special_functions/02_assoc_legendre/check_value.cc: + Likewise. + * testsuite/special_functions/02_assoc_legendre/pr86655.cc: + Likewise. + * testsuite/special_functions/03_beta/check_value.cc: Likewise. + * testsuite/special_functions/04_comp_ellint_1/check_value.cc: + Likewise. + * testsuite/special_functions/05_comp_ellint_2/check_value.cc: + Likewise. + * testsuite/special_functions/06_comp_ellint_3/check_value.cc: + Likewise. + * testsuite/special_functions/07_cyl_bessel_i/check_value.cc: + Likewise. + * testsuite/special_functions/08_cyl_bessel_j/check_value.cc: + Likewise. + * testsuite/special_functions/09_cyl_bessel_k/check_value.cc: + Likewise. + * testsuite/special_functions/10_cyl_neumann/check_value.cc: + Likewise. + * testsuite/special_functions/11_ellint_1/check_value.cc: + Likewise. + * testsuite/special_functions/12_ellint_2/check_value.cc: + Likewise. + * testsuite/special_functions/13_ellint_3/check_value.cc: + Likewise. + * testsuite/special_functions/14_expint/check_value.cc: + Likewise. + * testsuite/special_functions/15_hermite/check_value.cc: + Likewise. + * testsuite/special_functions/16_laguerre/check_value.cc: + Likewise. + * testsuite/special_functions/17_legendre/check_value.cc: + Likewise. + * testsuite/special_functions/18_riemann_zeta/check_value.cc: + Likewise. + * testsuite/special_functions/19_sph_bessel/check_value.cc: + Likewise. + * testsuite/special_functions/20_sph_legendre/check_value.cc: + Likewise. + * testsuite/special_functions/20_sph_legendre/pr86655.cc: + Likewise. + * testsuite/special_functions/21_sph_neumann/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/01_assoc_laguerre/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/02_assoc_legendre/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/02_assoc_legendre/pr86655.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/03_beta/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/04_comp_ellint_1/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/05_comp_ellint_2/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/06_comp_ellint_3/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/07_conf_hyperg/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/08_cyl_bessel_i/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/09_cyl_bessel_j/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/10_cyl_bessel_k/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/11_cyl_neumann/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/12_ellint_1/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/13_ellint_2/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/14_ellint_3/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/15_expint/check_value_neg.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/16_hermite/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/17_hyperg/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/18_laguerre/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/19_legendre/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/20_riemann_zeta/check_value_neg.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/21_sph_bessel/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/22_sph_legendre/check_value.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/22_sph_legendre/pr86655.cc: + Likewise. + * testsuite/tr1/5_numerical_facilities/special_functions/23_sph_neumann/check_value.cc: + Likewise. + +2025-06-11 Jonathan Wakely + + * include/std/sstream: Adjust whitespace. + +2025-06-11 Jonathan Wakely + + PR libstdc++/120390 + * include/bits/stl_construct.h (_Destroy_aux::__destroy_n): New + static member function. + (_Destroy_aux::__destroy_n): Likewise. + (_Destroy_n_aux): Remove. + (_Destroy(ForwardIterator, ForwardIterator)): Remove + static_assert. Use is_trivially_destructible instead of + __has_trivial_destructor. + (_Destroy_n): Likewise. Use _Destroy_aux::__destroy_n instead of + _Destroy_n_aux::__destroy_n. + * testsuite/20_util/specialized_algorithms/memory_management_tools/destroy_neg.cc: + Adjust dg-error strings. Move destroy_n tests to ... + * testsuite/20_util/specialized_algorithms/memory_management_tools/destroy_n_neg.cc: + New test. + * testsuite/23_containers/vector/cons/destructible_debug_neg.cc: + Adjust dg-error strings. + * testsuite/23_containers/vector/cons/destructible_neg.cc: + Likewise. + +2025-06-11 Jonathan Wakely + + * testsuite/27_io/basic_istringstream/cons/char/string_view.cc: + Only check get_allocator() for new string ABI. + * testsuite/27_io/basic_ostringstream/cons/char/string_view.cc: + Likewise. + * testsuite/27_io/basic_stringbuf/cons/char/string_view.cc: + Likewise. + * testsuite/27_io/basic_stringstream/cons/char/string_view.cc: + Likewise. + +2025-06-10 Patrick Palka + + * include/bits/max_size_type.h (__max_size_type::_M_val): Make + public instead of private. + (__max_size_type::_M_msb): Likewise. + (__max_diff_type::_M_rep): Likewise. + * testsuite/std/ranges/iota/max_size_type.cc: Verify + __max_diff_type and __max_size_type are structural. + +2025-06-10 Yihan Wang + Jonathan Wakely + + * include/std/tuple (__can_make_from_tuple): New variable + template. + (__make_from_tuple_impl): Add static_assert. + (make_from_tuple): Constrain using __can_make_from_tuple. + * testsuite/20_util/tuple/dr3528.cc: New test. + +2025-06-09 Nathan Myers + + PR libstdc++/119741 + * include/std/sstream: full implementation, really just + decls, requires clause and plumbing. + * include/bits/version.def, include/bits/version.h: + new preprocessor symbol + __cpp_lib_sstream_from_string_view. + * testsuite/27_io/basic_stringbuf/cons/char/string_view.cc: + New tests. + * testsuite/27_io/basic_istringstream/cons/char/string_view.cc: + New tests. + * testsuite/27_io/basic_ostringstream/cons/char/string_view.cc: + New tests. + * testsuite/27_io/basic_stringstream/cons/char/string_view.cc: + New tests. + * testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc: + New tests. + * testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc: + New tests. + * testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc: + New tests. + * testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc: + New tests. + +2025-06-08 John David Anglin + + * config/abi/post/hppa-linux-gnu/baseline_symbols.txt: Update. + +2025-06-06 Jonathan Wakely + + * testsuite/30_threads/semaphore/1.cc: Check type properties and + max() values. + * testsuite/30_threads/semaphore/3.cc: New test. + * testsuite/30_threads/semaphore/cons_neg.cc: New test. + +2025-06-06 Jonathan Wakely + + * include/bits/semaphore_base.h (_Select_semaphore_impl): Rename + to _Semaphore_impl and use std::conditional_t instead of an + immediately invoked lambda expression. + * include/std/semaphore (counting_semaphore): Adjust to use new + name. + +2025-06-06 Jonathan Wakely + + * testsuite/30_threads/barrier/1.cc: Require hosted. Only + require gthreads for non-linux targets. + * testsuite/30_threads/barrier/2.cc: Likewise. + * testsuite/30_threads/semaphore/1.cc: Likewise. + * testsuite/30_threads/semaphore/2.cc: Likewise. + * testsuite/30_threads/semaphore/cons.cc: Likewise. + * testsuite/30_threads/semaphore/least_max_value_neg.cc: + Likewise. + * testsuite/30_threads/semaphore/try_acquire.cc: Likewise. + +2025-06-06 Patrick Palka + + PR libstdc++/120432 + * include/std/flat_map (flat_map::operator[]): Make the + non-template overloads call try_emplace directly. Remove + non-standard same_as constraint on the template overload. + * testsuite/23_containers/flat_map/1.cc (test08): New test. + +2025-06-06 Jonathan Wakely + + * include/bits/atomic_timed_wait.h (__atomic_wait_address_until_v): + Add assertion to prevent use with proxy waits. + (__atomic_wait_address_for_v): Likewise. + * include/bits/atomic_wait.h (__atomic_wait_address_v): + Likewise. + +2025-06-06 Jonathan Wakely + + * include/bits/atomic_wait.h (__atomic_wait_address_v): Add bare + wait flag. + * include/bits/semaphore_base.h (__semaphore_base): Rename to + __semaphore_impl. Replace local variable and predicate lambdas + with _Available struct. + (__platform_semaphore_impl): New class template. + (__semaphore_impl): Remove alias template. + (_Select_semaphore_impl): New alias template. + * include/std/semaphore (counting_semaphore): Use + _Select_semaphore_impl. + +2025-06-06 Tomasz Kamiński + + PR libstdc++/120565 + * include/bits/chrono_io.h + (operator<<(basic_ostream<_CharT, _Traits>&, const sys_info&)) + (operator<<(basic_ostream<_CharT, _Traits>&, const local_info&)): + Support wchar_t as _CharT. + * testsuite/std/time/format/empty_spec.cc: Instantiated test_infos for + wchar_t and increase timeout. + +2025-06-06 Tomasz Kamiński + + * testsuite/std/time/format/empty_spec.cc: New tests and increased + timeout. + +2025-06-05 Jonathan Wakely + + PR libstdc++/120548 + * include/std/format (__formatter_fp::_M_localize): Do not + include a leading sign character in the string to be grouped. + * testsuite/std/format/functions/format.cc: Check grouping when + sign is present in the output. + +2025-06-05 Tomasz Kamiński + + PR libstdc++/119152 + * src/c++23/std.cc.in (std::indirect, pmr::indirect) + [__cpp_lib_indirect] + (std::polymorphic, pmr::polymorphic) [__cpp_lib_polymorphic]: Export. + +2025-06-05 Tomasz Kamiński + + PR libstdc++/120481 + * include/bits/chrono_io.h (__format::_S_chars): Reorder so it + contains "-{}". + (__format::_S_colon, __format::_S_slash, __format::_S_space) + (__format::_S_plus_minus): Updated starting indicies. + (__format::_S_minus_empty_spec): Define. + (__formatter_chrono::_M_C_y_Y, __formatter_chrono::_M_R_T): + Rework implementation. + (__formatter_chrono::_M_d_e, __formatter_chrono::_M_F) + (__formatter_chrono::_M_m, __formatter_chrono::_M_u_w) + (__formatter_chrono::_M_H_I, __formatter_chrono::_M_p): + Handle multi digits values. + (__formatter_chrono::_S_digit): Return string view. + (__formatter_chrono::_S_str_d1, __formatter_chrono::_S_str_d2) + (__formatter_chrono::_S_fill_two_digits): Define. + * testsuite/std/time/format/empty_spec.cc: Update test for + year_month_day, that uses '%F'. + * testsuite/std/time/format/pr120481.cc: New test. + +2025-06-05 Nathan Myers + + Revert: + 2025-06-04 Nathan Myers + + PR libstdc++/119741 + * include/std/sstream: full implementation, really just + decls, requires clause and plumbing. + * include/bits/version.def, include/bits/version.h: + new preprocessor symbol + __cpp_lib_sstream_from_string_view. + * testsuite/27_io/basic_stringbuf/cons/char/string_view.cc: + New tests. + * testsuite/27_io/basic_istringstream/cons/char/string_view.cc: + New tests. + * testsuite/27_io/basic_ostringstream/cons/char/string_view.cc: + New tests. + * testsuite/27_io/basic_stringstream/cons/char/string_view.cc: + New tests. + * testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc: + New tests. + * testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc: + New tests. + * testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc: + New tests. + * testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc: + New tests. + +2025-06-04 Jonathan Wakely + + * testsuite/std/time/format/empty_spec.cc: Only test time zones + for cxx11 string ABI. + +2025-06-04 Jonathan Wakely + + PR libstdc++/99832 + * include/bits/chrono.h (system_clock::to_time_t): Add + always_inline attribute to be agnostic to the underlying type of + time_t. + (system_clock::from_time_t): Add always_inline for consistency + with to_time_t. + * testsuite/20_util/system_clock/99832.cc: New test. + +2025-06-04 Nathan Myers + + PR libstdc++/119741 + * include/std/sstream: full implementation, really just + decls, requires clause and plumbing. + * include/bits/version.def, include/bits/version.h: + new preprocessor symbol + __cpp_lib_sstream_from_string_view. + * testsuite/27_io/basic_stringbuf/cons/char/string_view.cc: + New tests. + * testsuite/27_io/basic_istringstream/cons/char/string_view.cc: + New tests. + * testsuite/27_io/basic_ostringstream/cons/char/string_view.cc: + New tests. + * testsuite/27_io/basic_stringstream/cons/char/string_view.cc: + New tests. + * testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc: + New tests. + * testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc: + New tests. + * testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc: + New tests. + * testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc: + New tests. + +2025-06-04 Patrick Palka + + * include/bits/c++config (_GLIBCXX_AUTO_CAST): Define. + * include/bits/iterator_concepts.h (_Decay_copy, __decay_copy): + Remove. + (__member_begin, __adl_begin): Use _GLIBCXX_AUTO_CAST instead of + __decay_copy as per P0849R8. + * include/bits/ranges_base.h (_Begin): Likewise. + (__member_end, __adl_end, _End): Likewise. + (__member_rbegin, __adl_rbegin, _RBegin): Likewise. + (__member_rend, __adl_rend, _Rend): Likewise. + (__member_size, __adl_size, _Size): Likewise. + (_Data): Likewise. + +2025-06-04 Tomasz Kamiński + + * testsuite/std/time/format/empty_spec.cc: New tests. + +2025-06-04 Patrick Palka + + * include/bits/ranges_algo.h (__starts_with_fn, starts_with): + Define. + (__ends_with_fn, ends_with): Define. + * include/bits/version.def (ranges_starts_ends_with): Define. + * include/bits/version.h: Regenerate. + * include/std/algorithm: Provide __cpp_lib_ranges_starts_ends_with. + * src/c++23/std.cc.in (ranges::starts_with): Export. + (ranges::ends_with): Export. + * testsuite/25_algorithms/ends_with/1.cc: New test. + * testsuite/25_algorithms/starts_with/1.cc: New test. + +2025-06-04 Jonathan Wakely + + * include/bits/semaphore_base.h (_S_get_current): Replace with + non-static _M_get_current. + (_S_do_try_acquire): Replace with non-static _M_do_try_acquire. + +2025-06-04 Jonathan Wakely + + PR libstdc++/104928 + * include/bits/semaphore_base.h (_S_do_try_acquire): Take old + value by reference. + (_M_acquire): Move _S_do_try_acquire call out of the predicate + and loop on its result. Make the predicate capture and update + the local copy of the value. + (_M_try_acquire_until, _M_try_acquire_for): Likewise. + (_M_try_acquire): Just call _M_try_acquire_for. + * testsuite/30_threads/semaphore/104928-2.cc: New test. + * testsuite/30_threads/semaphore/104928.cc: New test. + +2025-06-04 Tomasz Kamiński + + * include/bits/chrono_io.h (__formatter_chrono:_M_s): Add missing + __out argument to format_to call. + * testsuite/std/time/format/empty_spec.cc: New test. + 2025-06-03 Jonathan Wakely * include/std/stop_token: Check __glibcxx_jthread instead of diff --git a/libstdc++-v3/config/abi/post/hppa-linux-gnu/baseline_symbols.txt b/libstdc++-v3/config/abi/post/hppa-linux-gnu/baseline_symbols.txt index b41e57125efd..fa2a06615b5d 100644 --- a/libstdc++-v3/config/abi/post/hppa-linux-gnu/baseline_symbols.txt +++ b/libstdc++-v3/config/abi/post/hppa-linux-gnu/baseline_symbols.txt @@ -1,9084 +1,4589 @@ -FUNC:_ZGTtNKSt11logic_error4whatEv FUNC:_ZGTtNKSt11logic_error4whatEv@@GLIBCXX_3.4.22 -FUNC:_ZGTtNKSt13bad_exception4whatEv FUNC:_ZGTtNKSt13bad_exception4whatEv@@CXXABI_1.3.10 -FUNC:_ZGTtNKSt13bad_exceptionD1Ev FUNC:_ZGTtNKSt13bad_exceptionD1Ev@@CXXABI_1.3.10 -FUNC:_ZGTtNKSt13runtime_error4whatEv FUNC:_ZGTtNKSt13runtime_error4whatEv@@GLIBCXX_3.4.22 -FUNC:_ZGTtNKSt9exception4whatEv FUNC:_ZGTtNKSt9exception4whatEv@@CXXABI_1.3.10 -FUNC:_ZGTtNKSt9exceptionD1Ev FUNC:_ZGTtNKSt9exceptionD1Ev@@CXXABI_1.3.10 -FUNC:_ZGTtNSt11logic_errorC1EPKc FUNC:_ZGTtNSt11logic_errorC1EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt11logic_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt11logic_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt11logic_errorC2EPKc FUNC:_ZGTtNSt11logic_errorC2EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt11logic_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt11logic_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt11logic_errorD0Ev FUNC:_ZGTtNSt11logic_errorD0Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt11logic_errorD1Ev FUNC:_ZGTtNSt11logic_errorD1Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt11logic_errorD2Ev FUNC:_ZGTtNSt11logic_errorD2Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt11range_errorC1EPKc FUNC:_ZGTtNSt11range_errorC1EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt11range_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt11range_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt11range_errorC2EPKc FUNC:_ZGTtNSt11range_errorC2EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt11range_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt11range_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt11range_errorD0Ev FUNC:_ZGTtNSt11range_errorD0Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt11range_errorD1Ev FUNC:_ZGTtNSt11range_errorD1Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt11range_errorD2Ev FUNC:_ZGTtNSt11range_errorD2Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12domain_errorC1EPKc FUNC:_ZGTtNSt12domain_errorC1EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12domain_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt12domain_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12domain_errorC2EPKc FUNC:_ZGTtNSt12domain_errorC2EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12domain_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt12domain_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12domain_errorD0Ev FUNC:_ZGTtNSt12domain_errorD0Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12domain_errorD1Ev FUNC:_ZGTtNSt12domain_errorD1Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12domain_errorD2Ev FUNC:_ZGTtNSt12domain_errorD2Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12length_errorC1EPKc FUNC:_ZGTtNSt12length_errorC1EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12length_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt12length_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12length_errorC2EPKc FUNC:_ZGTtNSt12length_errorC2EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12length_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt12length_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12length_errorD0Ev FUNC:_ZGTtNSt12length_errorD0Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12length_errorD1Ev FUNC:_ZGTtNSt12length_errorD1Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12length_errorD2Ev FUNC:_ZGTtNSt12length_errorD2Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12out_of_rangeC1EPKc FUNC:_ZGTtNSt12out_of_rangeC1EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12out_of_rangeC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt12out_of_rangeC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12out_of_rangeC2EPKc FUNC:_ZGTtNSt12out_of_rangeC2EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12out_of_rangeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt12out_of_rangeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12out_of_rangeD0Ev FUNC:_ZGTtNSt12out_of_rangeD0Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12out_of_rangeD1Ev FUNC:_ZGTtNSt12out_of_rangeD1Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt12out_of_rangeD2Ev FUNC:_ZGTtNSt12out_of_rangeD2Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt13runtime_errorC1EPKc FUNC:_ZGTtNSt13runtime_errorC1EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt13runtime_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt13runtime_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt13runtime_errorC2EPKc FUNC:_ZGTtNSt13runtime_errorC2EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt13runtime_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt13runtime_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt13runtime_errorD0Ev FUNC:_ZGTtNSt13runtime_errorD0Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt13runtime_errorD1Ev FUNC:_ZGTtNSt13runtime_errorD1Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt13runtime_errorD2Ev FUNC:_ZGTtNSt13runtime_errorD2Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt14overflow_errorC1EPKc FUNC:_ZGTtNSt14overflow_errorC1EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt14overflow_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt14overflow_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt14overflow_errorC2EPKc FUNC:_ZGTtNSt14overflow_errorC2EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt14overflow_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt14overflow_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt14overflow_errorD0Ev FUNC:_ZGTtNSt14overflow_errorD0Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt14overflow_errorD1Ev FUNC:_ZGTtNSt14overflow_errorD1Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt14overflow_errorD2Ev FUNC:_ZGTtNSt14overflow_errorD2Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt15underflow_errorC1EPKc FUNC:_ZGTtNSt15underflow_errorC1EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt15underflow_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt15underflow_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt15underflow_errorC2EPKc FUNC:_ZGTtNSt15underflow_errorC2EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt15underflow_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt15underflow_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt15underflow_errorD0Ev FUNC:_ZGTtNSt15underflow_errorD0Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt15underflow_errorD1Ev FUNC:_ZGTtNSt15underflow_errorD1Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt15underflow_errorD2Ev FUNC:_ZGTtNSt15underflow_errorD2Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt16invalid_argumentC1EPKc FUNC:_ZGTtNSt16invalid_argumentC1EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt16invalid_argumentC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt16invalid_argumentC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt16invalid_argumentC2EPKc FUNC:_ZGTtNSt16invalid_argumentC2EPKc@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt16invalid_argumentC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZGTtNSt16invalid_argumentC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt16invalid_argumentD0Ev FUNC:_ZGTtNSt16invalid_argumentD0Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt16invalid_argumentD1Ev FUNC:_ZGTtNSt16invalid_argumentD1Ev@@GLIBCXX_3.4.22 -FUNC:_ZGTtNSt16invalid_argumentD2Ev FUNC:_ZGTtNSt16invalid_argumentD2Ev@@GLIBCXX_3.4.22 -FUNC:_ZN10__cxxabiv116__enum_type_infoD0Ev FUNC:_ZN10__cxxabiv116__enum_type_infoD0Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv116__enum_type_infoD1Ev FUNC:_ZN10__cxxabiv116__enum_type_infoD1Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv116__enum_type_infoD2Ev FUNC:_ZN10__cxxabiv116__enum_type_infoD2Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv117__array_type_infoD0Ev FUNC:_ZN10__cxxabiv117__array_type_infoD0Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv117__array_type_infoD1Ev FUNC:_ZN10__cxxabiv117__array_type_infoD1Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv117__array_type_infoD2Ev FUNC:_ZN10__cxxabiv117__array_type_infoD2Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv117__class_type_infoD0Ev FUNC:_ZN10__cxxabiv117__class_type_infoD0Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv117__class_type_infoD1Ev FUNC:_ZN10__cxxabiv117__class_type_infoD1Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv117__class_type_infoD2Ev FUNC:_ZN10__cxxabiv117__class_type_infoD2Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv117__pbase_type_infoD0Ev FUNC:_ZN10__cxxabiv117__pbase_type_infoD0Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv117__pbase_type_infoD1Ev FUNC:_ZN10__cxxabiv117__pbase_type_infoD1Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv117__pbase_type_infoD2Ev FUNC:_ZN10__cxxabiv117__pbase_type_infoD2Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv119__pointer_type_infoD0Ev FUNC:_ZN10__cxxabiv119__pointer_type_infoD0Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv119__pointer_type_infoD1Ev FUNC:_ZN10__cxxabiv119__pointer_type_infoD1Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv119__pointer_type_infoD2Ev FUNC:_ZN10__cxxabiv119__pointer_type_infoD2Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv120__function_type_infoD0Ev FUNC:_ZN10__cxxabiv120__function_type_infoD0Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv120__function_type_infoD1Ev FUNC:_ZN10__cxxabiv120__function_type_infoD1Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv120__function_type_infoD2Ev FUNC:_ZN10__cxxabiv120__function_type_infoD2Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv120__si_class_type_infoD0Ev FUNC:_ZN10__cxxabiv120__si_class_type_infoD0Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv120__si_class_type_infoD1Ev FUNC:_ZN10__cxxabiv120__si_class_type_infoD1Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv120__si_class_type_infoD2Ev FUNC:_ZN10__cxxabiv120__si_class_type_infoD2Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv121__vmi_class_type_infoD0Ev FUNC:_ZN10__cxxabiv121__vmi_class_type_infoD0Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv121__vmi_class_type_infoD1Ev FUNC:_ZN10__cxxabiv121__vmi_class_type_infoD1Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv121__vmi_class_type_infoD2Ev FUNC:_ZN10__cxxabiv121__vmi_class_type_infoD2Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv123__fundamental_type_infoD0Ev FUNC:_ZN10__cxxabiv123__fundamental_type_infoD0Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv123__fundamental_type_infoD1Ev FUNC:_ZN10__cxxabiv123__fundamental_type_infoD1Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv123__fundamental_type_infoD2Ev FUNC:_ZN10__cxxabiv123__fundamental_type_infoD2Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv129__pointer_to_member_type_infoD0Ev FUNC:_ZN10__cxxabiv129__pointer_to_member_type_infoD0Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv129__pointer_to_member_type_infoD1Ev FUNC:_ZN10__cxxabiv129__pointer_to_member_type_infoD1Ev@@CXXABI_1.3 -FUNC:_ZN10__cxxabiv129__pointer_to_member_type_infoD2Ev FUNC:_ZN10__cxxabiv129__pointer_to_member_type_infoD2Ev@@CXXABI_1.3 FUNC:_ZN10__gnu_norm15_List_node_base4hookEPS0_@@GLIBCXX_3.4 FUNC:_ZN10__gnu_norm15_List_node_base4swapERS0_S1_@@GLIBCXX_3.4 FUNC:_ZN10__gnu_norm15_List_node_base6unhookEv@@GLIBCXX_3.4 FUNC:_ZN10__gnu_norm15_List_node_base7reverseEv@@GLIBCXX_3.4 FUNC:_ZN10__gnu_norm15_List_node_base8transferEPS0_S1_@@GLIBCXX_3.4 -FUNC:_ZN11__gnu_debug19_Safe_iterator_base12_M_get_mutexEv FUNC:_ZN11__gnu_debug19_Safe_iterator_base12_M_get_mutexEv@@GLIBCXX_3.4.9 -FUNC:_ZN11__gnu_debug19_Safe_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb FUNC:_ZN11__gnu_debug19_Safe_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4.9 -FUNC:_ZN11__gnu_debug19_Safe_iterator_base16_M_detach_singleEv FUNC:_ZN11__gnu_debug19_Safe_iterator_base16_M_detach_singleEv@@GLIBCXX_3.4.9 -FUNC:_ZN11__gnu_debug19_Safe_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb FUNC:_ZN11__gnu_debug19_Safe_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4 -FUNC:_ZN11__gnu_debug19_Safe_iterator_base9_M_detachEv FUNC:_ZN11__gnu_debug19_Safe_iterator_base9_M_detachEv@@GLIBCXX_3.4 -FUNC:_ZN11__gnu_debug19_Safe_sequence_base12_M_get_mutexEv FUNC:_ZN11__gnu_debug19_Safe_sequence_base12_M_get_mutexEv@@GLIBCXX_3.4.9 -FUNC:_ZN11__gnu_debug19_Safe_sequence_base13_M_detach_allEv FUNC:_ZN11__gnu_debug19_Safe_sequence_base13_M_detach_allEv@@GLIBCXX_3.4 -FUNC:_ZN11__gnu_debug19_Safe_sequence_base18_M_detach_singularEv FUNC:_ZN11__gnu_debug19_Safe_sequence_base18_M_detach_singularEv@@GLIBCXX_3.4 -FUNC:_ZN11__gnu_debug19_Safe_sequence_base22_M_revalidate_singularEv FUNC:_ZN11__gnu_debug19_Safe_sequence_base22_M_revalidate_singularEv@@GLIBCXX_3.4 -FUNC:_ZN11__gnu_debug19_Safe_sequence_base7_M_swapERS0_ FUNC:_ZN11__gnu_debug19_Safe_sequence_base7_M_swapERS0_@@GLIBCXX_3.4 -FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4.26 -FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4.17 -FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base9_M_detachEv FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base9_M_detachEv@@GLIBCXX_3.4.17 -FUNC:_ZN11__gnu_debug30_Safe_unordered_container_base13_M_detach_allEv FUNC:_ZN11__gnu_debug30_Safe_unordered_container_base13_M_detach_allEv@@GLIBCXX_3.4.17 -FUNC:_ZN11__gnu_debug30_Safe_unordered_container_base7_M_swapERS0_ FUNC:_ZN11__gnu_debug30_Safe_unordered_container_base7_M_swapERS0_@@GLIBCXX_3.4.17 -FUNC:_ZN14__gnu_parallel9_Settings3getEv FUNC:_ZN14__gnu_parallel9_Settings3getEv@@GLIBCXX_3.4.10 -FUNC:_ZN14__gnu_parallel9_Settings3setERS0_ FUNC:_ZN14__gnu_parallel9_Settings3setERS0_@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx12__atomic_addEPVii FUNC:_ZN9__gnu_cxx12__atomic_addEPVii@@GLIBCXX_3.4 -FUNC:_ZN9__gnu_cxx17__pool_alloc_base12_M_get_mutexEv FUNC:_ZN9__gnu_cxx17__pool_alloc_base12_M_get_mutexEv@@GLIBCXX_3.4.2 -FUNC:_ZN9__gnu_cxx17__pool_alloc_base16_M_get_free_listEj FUNC:_ZN9__gnu_cxx17__pool_alloc_base16_M_get_free_listEj@@GLIBCXX_3.4.2 -FUNC:_ZN9__gnu_cxx17__pool_alloc_base9_M_refillEj FUNC:_ZN9__gnu_cxx17__pool_alloc_base9_M_refillEj@@GLIBCXX_3.4.2 -FUNC:_ZN9__gnu_cxx18__exchange_and_addEPVii FUNC:_ZN9__gnu_cxx18__exchange_and_addEPVii@@GLIBCXX_3.4 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE4fileEv FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE4fileEv@@GLIBCXX_3.4.2 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE4syncEv FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE4syncEv@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE5uflowEv FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE5uflowEv@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE6xsgetnEPci FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE6xsgetnEPci@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE6xsputnEPKci FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE6xsputnEPKci@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE8overflowEi FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE8overflowEi@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE9pbackfailEi FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE9pbackfailEi@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE9underflowEv FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE9underflowEv@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEC1EOS3_ FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEC1EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEC1EP8_IO_FILE FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEC1EP8_IO_FILE@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEC2EOS3_ FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEC2EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEC2EP8_IO_FILE FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEC2EP8_IO_FILE@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEED0Ev FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEED1Ev FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEaSEOS3_ FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEaSEOS3_@@GLIBCXX_3.4.21 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE4fileEv FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE4fileEv@@GLIBCXX_3.4.2 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE4syncEv FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE4syncEv@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE5uflowEv FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE5uflowEv@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE6xsgetnEPwi FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE6xsgetnEPwi@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE6xsputnEPKwi FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE6xsputnEPKwi@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE8overflowEj FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE8overflowEj@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE9pbackfailEj FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE9pbackfailEj@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE9underflowEv FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE9underflowEv@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEC1EOS3_ FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEC1EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEC1EP8_IO_FILE FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEC1EP8_IO_FILE@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEC2EOS3_ FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEC2EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEC2EP8_IO_FILE FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEC2EP8_IO_FILE@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEED0Ev FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEED1Ev FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4.10 -FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEaSEOS3_ FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEaSEOS3_@@GLIBCXX_3.4.21 -FUNC:_ZN9__gnu_cxx27__verbose_terminate_handlerEv FUNC:_ZN9__gnu_cxx27__verbose_terminate_handlerEv@@CXXABI_1.3 -FUNC:_ZN9__gnu_cxx6__poolILb0EE10_M_destroyEv FUNC:_ZN9__gnu_cxx6__poolILb0EE10_M_destroyEv@@GLIBCXX_3.4.4 -FUNC:_ZN9__gnu_cxx6__poolILb0EE13_M_initializeEv FUNC:_ZN9__gnu_cxx6__poolILb0EE13_M_initializeEv@@GLIBCXX_3.4.4 -FUNC:_ZN9__gnu_cxx6__poolILb0EE16_M_reclaim_blockEPcj FUNC:_ZN9__gnu_cxx6__poolILb0EE16_M_reclaim_blockEPcj@@GLIBCXX_3.4.4 -FUNC:_ZN9__gnu_cxx6__poolILb0EE16_M_reserve_blockEjj FUNC:_ZN9__gnu_cxx6__poolILb0EE16_M_reserve_blockEjj@@GLIBCXX_3.4.4 -FUNC:_ZN9__gnu_cxx6__poolILb1EE10_M_destroyEv FUNC:_ZN9__gnu_cxx6__poolILb1EE10_M_destroyEv@@GLIBCXX_3.4.4 -FUNC:_ZN9__gnu_cxx6__poolILb1EE13_M_initializeEPFvPvE FUNC:_ZN9__gnu_cxx6__poolILb1EE13_M_initializeEPFvPvE@@GLIBCXX_3.4.4 -FUNC:_ZN9__gnu_cxx6__poolILb1EE13_M_initializeEv FUNC:_ZN9__gnu_cxx6__poolILb1EE13_M_initializeEv@@GLIBCXX_3.4.6 -FUNC:_ZN9__gnu_cxx6__poolILb1EE16_M_get_thread_idEv FUNC:_ZN9__gnu_cxx6__poolILb1EE16_M_get_thread_idEv@@GLIBCXX_3.4.4 -FUNC:_ZN9__gnu_cxx6__poolILb1EE16_M_reclaim_blockEPcj FUNC:_ZN9__gnu_cxx6__poolILb1EE16_M_reclaim_blockEPcj@@GLIBCXX_3.4.4 -FUNC:_ZN9__gnu_cxx6__poolILb1EE16_M_reserve_blockEjj FUNC:_ZN9__gnu_cxx6__poolILb1EE16_M_reserve_blockEjj@@GLIBCXX_3.4.4 -FUNC:_ZN9__gnu_cxx6__poolILb1EE21_M_destroy_thread_keyEPv FUNC:_ZN9__gnu_cxx6__poolILb1EE21_M_destroy_thread_keyEPv@@GLIBCXX_3.4.4 -FUNC:_ZN9__gnu_cxx9__freeresEv FUNC:_ZN9__gnu_cxx9__freeresEv@@CXXABI_1.3.10 -FUNC:_ZN9__gnu_cxx9free_list6_M_getEj FUNC:_ZN9__gnu_cxx9free_list6_M_getEj@@GLIBCXX_3.4.4 -FUNC:_ZN9__gnu_cxx9free_list8_M_clearEv FUNC:_ZN9__gnu_cxx9free_list8_M_clearEv@@GLIBCXX_3.4.4 -FUNC:_ZNK10__cxxabiv117__class_type_info10__do_catchEPKSt9type_infoPPvj FUNC:_ZNK10__cxxabiv117__class_type_info10__do_catchEPKSt9type_infoPPvj@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PKvRNS0_15__upcast_resultE FUNC:_ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PKvRNS0_15__upcast_resultE@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PPv FUNC:_ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PPv@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv117__class_type_info12__do_dyncastEiNS0_10__sub_kindEPKS0_PKvS3_S5_RNS0_16__dyncast_resultE FUNC:_ZNK10__cxxabiv117__class_type_info12__do_dyncastEiNS0_10__sub_kindEPKS0_PKvS3_S5_RNS0_16__dyncast_resultE@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv117__class_type_info20__do_find_public_srcEiPKvPKS0_S2_ FUNC:_ZNK10__cxxabiv117__class_type_info20__do_find_public_srcEiPKvPKS0_S2_@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv117__pbase_type_info10__do_catchEPKSt9type_infoPPvj FUNC:_ZNK10__cxxabiv117__pbase_type_info10__do_catchEPKSt9type_infoPPvj@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv117__pbase_type_info15__pointer_catchEPKS0_PPvj FUNC:_ZNK10__cxxabiv117__pbase_type_info15__pointer_catchEPKS0_PPvj@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv119__pointer_type_info14__is_pointer_pEv FUNC:_ZNK10__cxxabiv119__pointer_type_info14__is_pointer_pEv@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv119__pointer_type_info15__pointer_catchEPKNS_17__pbase_type_infoEPPvj FUNC:_ZNK10__cxxabiv119__pointer_type_info15__pointer_catchEPKNS_17__pbase_type_infoEPPvj@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv120__function_type_info15__is_function_pEv FUNC:_ZNK10__cxxabiv120__function_type_info15__is_function_pEv@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv120__si_class_type_info11__do_upcastEPKNS_17__class_type_infoEPKvRNS1_15__upcast_resultE FUNC:_ZNK10__cxxabiv120__si_class_type_info11__do_upcastEPKNS_17__class_type_infoEPKvRNS1_15__upcast_resultE@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv120__si_class_type_info12__do_dyncastEiNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE FUNC:_ZNK10__cxxabiv120__si_class_type_info12__do_dyncastEiNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv120__si_class_type_info20__do_find_public_srcEiPKvPKNS_17__class_type_infoES2_ FUNC:_ZNK10__cxxabiv120__si_class_type_info20__do_find_public_srcEiPKvPKNS_17__class_type_infoES2_@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv121__vmi_class_type_info11__do_upcastEPKNS_17__class_type_infoEPKvRNS1_15__upcast_resultE FUNC:_ZNK10__cxxabiv121__vmi_class_type_info11__do_upcastEPKNS_17__class_type_infoEPKvRNS1_15__upcast_resultE@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv121__vmi_class_type_info12__do_dyncastEiNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE FUNC:_ZNK10__cxxabiv121__vmi_class_type_info12__do_dyncastEiNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv121__vmi_class_type_info20__do_find_public_srcEiPKvPKNS_17__class_type_infoES2_ FUNC:_ZNK10__cxxabiv121__vmi_class_type_info20__do_find_public_srcEiPKvPKNS_17__class_type_infoES2_@@CXXABI_1.3 -FUNC:_ZNK10__cxxabiv129__pointer_to_member_type_info15__pointer_catchEPKNS_17__pbase_type_infoEPPvj FUNC:_ZNK10__cxxabiv129__pointer_to_member_type_info15__pointer_catchEPKNS_17__pbase_type_infoEPPvj@@CXXABI_1.3 -FUNC:_ZNK11__gnu_debug16_Error_formatter10_M_messageENS_13_Debug_msg_idE FUNC:_ZNK11__gnu_debug16_Error_formatter10_M_messageENS_13_Debug_msg_idE@@GLIBCXX_3.4 -FUNC:_ZNK11__gnu_debug16_Error_formatter10_Parameter14_M_print_fieldEPKS0_PKc FUNC:_ZNK11__gnu_debug16_Error_formatter10_Parameter14_M_print_fieldEPKS0_PKc@@GLIBCXX_3.4 -FUNC:_ZNK11__gnu_debug16_Error_formatter10_Parameter20_M_print_descriptionEPKS0_ FUNC:_ZNK11__gnu_debug16_Error_formatter10_Parameter20_M_print_descriptionEPKS0_@@GLIBCXX_3.4 -FUNC:_ZNK11__gnu_debug16_Error_formatter13_M_print_wordEPKc FUNC:_ZNK11__gnu_debug16_Error_formatter13_M_print_wordEPKc@@GLIBCXX_3.4 -FUNC:_ZNK11__gnu_debug16_Error_formatter15_M_print_stringEPKc FUNC:_ZNK11__gnu_debug16_Error_formatter15_M_print_stringEPKc@@GLIBCXX_3.4 -FUNC:_ZNK11__gnu_debug16_Error_formatter17_M_get_max_lengthEv FUNC:_ZNK11__gnu_debug16_Error_formatter17_M_get_max_lengthEv@@GLIBCXX_3.4.10 -FUNC:_ZNK11__gnu_debug16_Error_formatter8_M_errorEv FUNC:_ZNK11__gnu_debug16_Error_formatter8_M_errorEv@@GLIBCXX_3.4 -FUNC:_ZNK11__gnu_debug19_Safe_iterator_base11_M_singularEv FUNC:_ZNK11__gnu_debug19_Safe_iterator_base11_M_singularEv@@GLIBCXX_3.4 -FUNC:_ZNK11__gnu_debug19_Safe_iterator_base14_M_can_compareERKS0_ FUNC:_ZNK11__gnu_debug19_Safe_iterator_base14_M_can_compareERKS0_@@GLIBCXX_3.4 -FUNC:_ZNKRSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNKRSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNKRSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNKRSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNKRSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNKRSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNKRSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNKRSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNKRSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNKRSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNKRSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNKRSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNKRSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNKRSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNKRSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNKRSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.29 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE11_M_disjunctEPKw@@GLIBCXX_3.4.5 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE11_M_disjunctEPKw@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwjj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwjj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofERKS2_j FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofERKS2_j@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEwj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEwj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEPKwj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEPKwj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEPKwjj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEPKwjj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofERKS2_j FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofERKS2_j@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEwj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEwj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13get_allocatorEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13get_allocatorEv@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE15_M_check_lengthEjjPKc@@GLIBCXX_3.4.5 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE15_M_check_lengthEjjPKc@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwjj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwjj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofERKS2_j FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofERKS2_j@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEwj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEwj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwjj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwjj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofERKS2_j FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofERKS2_j@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEwj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEwj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE2atEj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE2atEj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE3endEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_leakedEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_leakedEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_sharedEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_sharedEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4backEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.15 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4cendEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4cendEv@@GLIBCXX_3.4.14 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4copyEPwjj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4copyEPwjj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4dataEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4findERKS2_j FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4findERKS2_j@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4findEwj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4findEwj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4rendEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4sizeEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4sizeEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5beginEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5c_strEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5c_strEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5crendEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5crendEv@@GLIBCXX_3.4.14 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5emptyEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5emptyEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5frontEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5frontEv@@GLIBCXX_3.4.15 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwjj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwjj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindERKS2_j FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindERKS2_j@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEwj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEwj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6_M_repEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6_M_repEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6cbeginEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6cbeginEv@@GLIBCXX_3.4.14 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6lengthEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6lengthEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6rbeginEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6rbeginEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6substrEjj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6substrEjj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7_M_dataEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7_M_dataEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7_M_iendEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7_M_iendEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEPKw FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEPKw@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareERKS2_ FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareERKS2_@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjPKw FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjPKw@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjPKwj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjPKwj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjRKS2_ FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjRKS2_@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjRKS2_jj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjRKS2_jj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7crbeginEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7crbeginEv@@GLIBCXX_3.4.14 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8_M_checkEjPKc FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8_M_checkEjPKc@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8_M_limitEjj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8_M_limitEjj@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8capacityEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8capacityEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8max_sizeEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8max_sizeEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE9_M_ibeginEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE9_M_ibeginEv@@GLIBCXX_3.4 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEEcvSt17basic_string_viewIwS0_EEv FUNC:_ZNKSbIwSt11char_traitsIwESaIwEEcvSt17basic_string_viewIwS0_EEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSbIwSt11char_traitsIwESaIwEEixEj FUNC:_ZNKSbIwSt11char_traitsIwESaIwEEixEj@@GLIBCXX_3.4 -FUNC:_ZNKSi6gcountEv FUNC:_ZNKSi6gcountEv@@GLIBCXX_3.4 -FUNC:_ZNKSi6sentrycvbEv FUNC:_ZNKSi6sentrycvbEv@@GLIBCXX_3.4 -FUNC:_ZNKSo6sentrycvbEv FUNC:_ZNKSo6sentrycvbEv@@GLIBCXX_3.4 FUNC:_ZNKSs11_M_disjunctEPKc@@GLIBCXX_3.4.5 FUNC:_ZNKSs11_M_disjunctEPKc@GLIBCXX_3.4 -FUNC:_ZNKSs12find_last_ofEPKcj FUNC:_ZNKSs12find_last_ofEPKcj@@GLIBCXX_3.4 -FUNC:_ZNKSs12find_last_ofEPKcjj FUNC:_ZNKSs12find_last_ofEPKcjj@@GLIBCXX_3.4 -FUNC:_ZNKSs12find_last_ofERKSsj FUNC:_ZNKSs12find_last_ofERKSsj@@GLIBCXX_3.4 -FUNC:_ZNKSs12find_last_ofEcj FUNC:_ZNKSs12find_last_ofEcj@@GLIBCXX_3.4 -FUNC:_ZNKSs13find_first_ofEPKcj FUNC:_ZNKSs13find_first_ofEPKcj@@GLIBCXX_3.4 -FUNC:_ZNKSs13find_first_ofEPKcjj FUNC:_ZNKSs13find_first_ofEPKcjj@@GLIBCXX_3.4 -FUNC:_ZNKSs13find_first_ofERKSsj FUNC:_ZNKSs13find_first_ofERKSsj@@GLIBCXX_3.4 -FUNC:_ZNKSs13find_first_ofEcj FUNC:_ZNKSs13find_first_ofEcj@@GLIBCXX_3.4 -FUNC:_ZNKSs13get_allocatorEv FUNC:_ZNKSs13get_allocatorEv@@GLIBCXX_3.4 FUNC:_ZNKSs15_M_check_lengthEjjPKc@@GLIBCXX_3.4.5 FUNC:_ZNKSs15_M_check_lengthEjjPKc@GLIBCXX_3.4 -FUNC:_ZNKSs16find_last_not_ofEPKcj FUNC:_ZNKSs16find_last_not_ofEPKcj@@GLIBCXX_3.4 -FUNC:_ZNKSs16find_last_not_ofEPKcjj FUNC:_ZNKSs16find_last_not_ofEPKcjj@@GLIBCXX_3.4 -FUNC:_ZNKSs16find_last_not_ofERKSsj FUNC:_ZNKSs16find_last_not_ofERKSsj@@GLIBCXX_3.4 -FUNC:_ZNKSs16find_last_not_ofEcj FUNC:_ZNKSs16find_last_not_ofEcj@@GLIBCXX_3.4 -FUNC:_ZNKSs17find_first_not_ofEPKcj FUNC:_ZNKSs17find_first_not_ofEPKcj@@GLIBCXX_3.4 -FUNC:_ZNKSs17find_first_not_ofEPKcjj FUNC:_ZNKSs17find_first_not_ofEPKcjj@@GLIBCXX_3.4 -FUNC:_ZNKSs17find_first_not_ofERKSsj FUNC:_ZNKSs17find_first_not_ofERKSsj@@GLIBCXX_3.4 -FUNC:_ZNKSs17find_first_not_ofEcj FUNC:_ZNKSs17find_first_not_ofEcj@@GLIBCXX_3.4 -FUNC:_ZNKSs2atEj FUNC:_ZNKSs2atEj@@GLIBCXX_3.4 -FUNC:_ZNKSs3endEv FUNC:_ZNKSs3endEv@@GLIBCXX_3.4 -FUNC:_ZNKSs4_Rep12_M_is_leakedEv FUNC:_ZNKSs4_Rep12_M_is_leakedEv@@GLIBCXX_3.4 -FUNC:_ZNKSs4_Rep12_M_is_sharedEv FUNC:_ZNKSs4_Rep12_M_is_sharedEv@@GLIBCXX_3.4 -FUNC:_ZNKSs4backEv FUNC:_ZNKSs4backEv@@GLIBCXX_3.4.15 -FUNC:_ZNKSs4cendEv FUNC:_ZNKSs4cendEv@@GLIBCXX_3.4.14 -FUNC:_ZNKSs4copyEPcjj FUNC:_ZNKSs4copyEPcjj@@GLIBCXX_3.4 -FUNC:_ZNKSs4dataEv FUNC:_ZNKSs4dataEv@@GLIBCXX_3.4 -FUNC:_ZNKSs4findEPKcj FUNC:_ZNKSs4findEPKcj@@GLIBCXX_3.4 -FUNC:_ZNKSs4findEPKcjj FUNC:_ZNKSs4findEPKcjj@@GLIBCXX_3.4 -FUNC:_ZNKSs4findERKSsj FUNC:_ZNKSs4findERKSsj@@GLIBCXX_3.4 -FUNC:_ZNKSs4findEcj FUNC:_ZNKSs4findEcj@@GLIBCXX_3.4 -FUNC:_ZNKSs4rendEv FUNC:_ZNKSs4rendEv@@GLIBCXX_3.4 -FUNC:_ZNKSs4sizeEv FUNC:_ZNKSs4sizeEv@@GLIBCXX_3.4 -FUNC:_ZNKSs5beginEv FUNC:_ZNKSs5beginEv@@GLIBCXX_3.4 -FUNC:_ZNKSs5c_strEv FUNC:_ZNKSs5c_strEv@@GLIBCXX_3.4 -FUNC:_ZNKSs5crendEv FUNC:_ZNKSs5crendEv@@GLIBCXX_3.4.14 -FUNC:_ZNKSs5emptyEv FUNC:_ZNKSs5emptyEv@@GLIBCXX_3.4 -FUNC:_ZNKSs5frontEv FUNC:_ZNKSs5frontEv@@GLIBCXX_3.4.15 -FUNC:_ZNKSs5rfindEPKcj FUNC:_ZNKSs5rfindEPKcj@@GLIBCXX_3.4 -FUNC:_ZNKSs5rfindEPKcjj FUNC:_ZNKSs5rfindEPKcjj@@GLIBCXX_3.4 -FUNC:_ZNKSs5rfindERKSsj FUNC:_ZNKSs5rfindERKSsj@@GLIBCXX_3.4 -FUNC:_ZNKSs5rfindEcj FUNC:_ZNKSs5rfindEcj@@GLIBCXX_3.4 -FUNC:_ZNKSs6_M_repEv FUNC:_ZNKSs6_M_repEv@@GLIBCXX_3.4 -FUNC:_ZNKSs6cbeginEv FUNC:_ZNKSs6cbeginEv@@GLIBCXX_3.4.14 -FUNC:_ZNKSs6lengthEv FUNC:_ZNKSs6lengthEv@@GLIBCXX_3.4 -FUNC:_ZNKSs6rbeginEv FUNC:_ZNKSs6rbeginEv@@GLIBCXX_3.4 -FUNC:_ZNKSs6substrEjj FUNC:_ZNKSs6substrEjj@@GLIBCXX_3.4 -FUNC:_ZNKSs7_M_dataEv FUNC:_ZNKSs7_M_dataEv@@GLIBCXX_3.4 -FUNC:_ZNKSs7_M_iendEv FUNC:_ZNKSs7_M_iendEv@@GLIBCXX_3.4 -FUNC:_ZNKSs7compareEPKc FUNC:_ZNKSs7compareEPKc@@GLIBCXX_3.4 -FUNC:_ZNKSs7compareERKSs FUNC:_ZNKSs7compareERKSs@@GLIBCXX_3.4 -FUNC:_ZNKSs7compareEjjPKc FUNC:_ZNKSs7compareEjjPKc@@GLIBCXX_3.4 -FUNC:_ZNKSs7compareEjjPKcj FUNC:_ZNKSs7compareEjjPKcj@@GLIBCXX_3.4 -FUNC:_ZNKSs7compareEjjRKSs FUNC:_ZNKSs7compareEjjRKSs@@GLIBCXX_3.4 -FUNC:_ZNKSs7compareEjjRKSsjj FUNC:_ZNKSs7compareEjjRKSsjj@@GLIBCXX_3.4 -FUNC:_ZNKSs7crbeginEv FUNC:_ZNKSs7crbeginEv@@GLIBCXX_3.4.14 -FUNC:_ZNKSs8_M_checkEjPKc FUNC:_ZNKSs8_M_checkEjPKc@@GLIBCXX_3.4 -FUNC:_ZNKSs8_M_limitEjj FUNC:_ZNKSs8_M_limitEjj@@GLIBCXX_3.4 -FUNC:_ZNKSs8capacityEv FUNC:_ZNKSs8capacityEv@@GLIBCXX_3.4 -FUNC:_ZNKSs8max_sizeEv FUNC:_ZNKSs8max_sizeEv@@GLIBCXX_3.4 -FUNC:_ZNKSs9_M_ibeginEv FUNC:_ZNKSs9_M_ibeginEv@@GLIBCXX_3.4 -FUNC:_ZNKSscvSt17basic_string_viewIcSt11char_traitsIcEEEv FUNC:_ZNKSscvSt17basic_string_viewIcSt11char_traitsIcEEEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSsixEj FUNC:_ZNKSsixEj@@GLIBCXX_3.4 -FUNC:_ZNKSt10bad_typeid4whatEv FUNC:_ZNKSt10bad_typeid4whatEv@@GLIBCXX_3.4.9 -FUNC:_ZNKSt10error_code23default_error_conditionEv FUNC:_ZNKSt10error_code23default_error_conditionEv@@GLIBCXX_3.4.11 -FUNC:_ZNKSt10filesystem16filesystem_error4whatEv FUNC:_ZNKSt10filesystem16filesystem_error4whatEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem16filesystem_error5path1Ev FUNC:_ZNKSt10filesystem16filesystem_error5path1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem16filesystem_error5path2Ev FUNC:_ZNKSt10filesystem16filesystem_error5path2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem18directory_iteratordeEv FUNC:_ZNKSt10filesystem18directory_iteratordeEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem28recursive_directory_iterator17recursion_pendingEv FUNC:_ZNKSt10filesystem28recursive_directory_iterator17recursion_pendingEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem28recursive_directory_iterator5depthEv FUNC:_ZNKSt10filesystem28recursive_directory_iterator5depthEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem28recursive_directory_iterator7optionsEv FUNC:_ZNKSt10filesystem28recursive_directory_iterator7optionsEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem28recursive_directory_iteratordeEv FUNC:_ZNKSt10filesystem28recursive_directory_iteratordeEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path11parent_pathEv FUNC:_ZNKSt10filesystem4path11parent_pathEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path12has_filenameEv FUNC:_ZNKSt10filesystem4path12has_filenameEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path13has_root_nameEv FUNC:_ZNKSt10filesystem4path13has_root_nameEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path13has_root_pathEv FUNC:_ZNKSt10filesystem4path13has_root_pathEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path13relative_pathEv FUNC:_ZNKSt10filesystem4path13relative_pathEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path14root_directoryEv FUNC:_ZNKSt10filesystem4path14root_directoryEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path15has_parent_pathEv FUNC:_ZNKSt10filesystem4path15has_parent_pathEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path16lexically_normalEv FUNC:_ZNKSt10filesystem4path16lexically_normalEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path17_M_find_extensionEv FUNC:_ZNKSt10filesystem4path17_M_find_extensionEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path17has_relative_pathEv FUNC:_ZNKSt10filesystem4path17has_relative_pathEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path18has_root_directoryEv FUNC:_ZNKSt10filesystem4path18has_root_directoryEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path18lexically_relativeERKS0_ FUNC:_ZNKSt10filesystem4path18lexically_relativeERKS0_@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path19lexically_proximateERKS0_ FUNC:_ZNKSt10filesystem4path19lexically_proximateERKS0_@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path5_List13_Impl_deleterclEPNS1_5_ImplE FUNC:_ZNKSt10filesystem4path5_List13_Impl_deleterclEPNS1_5_ImplE@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path5_List3endEv FUNC:_ZNKSt10filesystem4path5_List3endEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path5_List5beginEv FUNC:_ZNKSt10filesystem4path5_List5beginEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path7compareERKS0_ FUNC:_ZNKSt10filesystem4path7compareERKS0_@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path7compareESt17basic_string_viewIcSt11char_traitsIcEE FUNC:_ZNKSt10filesystem4path7compareESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path9root_nameEv FUNC:_ZNKSt10filesystem4path9root_nameEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem4path9root_pathEv FUNC:_ZNKSt10filesystem4path9root_pathEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error4whatEv FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error4whatEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error5path1Ev FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error5path1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error5path2Ev FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error5path2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx1118directory_iteratordeEv FUNC:_ZNKSt10filesystem7__cxx1118directory_iteratordeEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator17recursion_pendingEv FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator17recursion_pendingEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator5depthEv FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator5depthEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator7optionsEv FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator7optionsEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iteratordeEv FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iteratordeEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path11parent_pathEv FUNC:_ZNKSt10filesystem7__cxx114path11parent_pathEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path12has_filenameEv FUNC:_ZNKSt10filesystem7__cxx114path12has_filenameEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path13has_root_nameEv FUNC:_ZNKSt10filesystem7__cxx114path13has_root_nameEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path13has_root_pathEv FUNC:_ZNKSt10filesystem7__cxx114path13has_root_pathEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path13relative_pathEv FUNC:_ZNKSt10filesystem7__cxx114path13relative_pathEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path14root_directoryEv FUNC:_ZNKSt10filesystem7__cxx114path14root_directoryEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path15has_parent_pathEv FUNC:_ZNKSt10filesystem7__cxx114path15has_parent_pathEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path16lexically_normalEv FUNC:_ZNKSt10filesystem7__cxx114path16lexically_normalEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path17_M_find_extensionEv FUNC:_ZNKSt10filesystem7__cxx114path17_M_find_extensionEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path17has_relative_pathEv FUNC:_ZNKSt10filesystem7__cxx114path17has_relative_pathEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path18has_root_directoryEv FUNC:_ZNKSt10filesystem7__cxx114path18has_root_directoryEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path18lexically_relativeERKS1_ FUNC:_ZNKSt10filesystem7__cxx114path18lexically_relativeERKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path19lexically_proximateERKS1_ FUNC:_ZNKSt10filesystem7__cxx114path19lexically_proximateERKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path5_List13_Impl_deleterclEPNS2_5_ImplE FUNC:_ZNKSt10filesystem7__cxx114path5_List13_Impl_deleterclEPNS2_5_ImplE@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path5_List3endEv FUNC:_ZNKSt10filesystem7__cxx114path5_List3endEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path5_List5beginEv FUNC:_ZNKSt10filesystem7__cxx114path5_List5beginEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path7compareERKS1_ FUNC:_ZNKSt10filesystem7__cxx114path7compareERKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path7compareESt17basic_string_viewIcSt11char_traitsIcEE FUNC:_ZNKSt10filesystem7__cxx114path7compareESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path9root_nameEv FUNC:_ZNKSt10filesystem7__cxx114path9root_nameEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10filesystem7__cxx114path9root_pathEv FUNC:_ZNKSt10filesystem7__cxx114path9root_pathEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt10istrstream5rdbufEv FUNC:_ZNKSt10istrstream5rdbufEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10lock_error4whatEv FUNC:_ZNKSt10lock_error4whatEv@@GLIBCXX_3.4.11 -FUNC:_ZNKSt10moneypunctIcLb0EE10neg_formatEv FUNC:_ZNKSt10moneypunctIcLb0EE10neg_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE10pos_formatEv FUNC:_ZNKSt10moneypunctIcLb0EE10pos_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE11curr_symbolEv FUNC:_ZNKSt10moneypunctIcLb0EE11curr_symbolEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE11do_groupingEv FUNC:_ZNKSt10moneypunctIcLb0EE11do_groupingEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE11frac_digitsEv FUNC:_ZNKSt10moneypunctIcLb0EE11frac_digitsEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE13decimal_pointEv FUNC:_ZNKSt10moneypunctIcLb0EE13decimal_pointEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE13do_neg_formatEv FUNC:_ZNKSt10moneypunctIcLb0EE13do_neg_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE13do_pos_formatEv FUNC:_ZNKSt10moneypunctIcLb0EE13do_pos_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE13negative_signEv FUNC:_ZNKSt10moneypunctIcLb0EE13negative_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE13positive_signEv FUNC:_ZNKSt10moneypunctIcLb0EE13positive_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE13thousands_sepEv FUNC:_ZNKSt10moneypunctIcLb0EE13thousands_sepEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE14do_curr_symbolEv FUNC:_ZNKSt10moneypunctIcLb0EE14do_curr_symbolEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE14do_frac_digitsEv FUNC:_ZNKSt10moneypunctIcLb0EE14do_frac_digitsEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE16do_decimal_pointEv FUNC:_ZNKSt10moneypunctIcLb0EE16do_decimal_pointEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE16do_negative_signEv FUNC:_ZNKSt10moneypunctIcLb0EE16do_negative_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE16do_positive_signEv FUNC:_ZNKSt10moneypunctIcLb0EE16do_positive_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE16do_thousands_sepEv FUNC:_ZNKSt10moneypunctIcLb0EE16do_thousands_sepEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb0EE8groupingEv FUNC:_ZNKSt10moneypunctIcLb0EE8groupingEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE10neg_formatEv FUNC:_ZNKSt10moneypunctIcLb1EE10neg_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE10pos_formatEv FUNC:_ZNKSt10moneypunctIcLb1EE10pos_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE11curr_symbolEv FUNC:_ZNKSt10moneypunctIcLb1EE11curr_symbolEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE11do_groupingEv FUNC:_ZNKSt10moneypunctIcLb1EE11do_groupingEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE11frac_digitsEv FUNC:_ZNKSt10moneypunctIcLb1EE11frac_digitsEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE13decimal_pointEv FUNC:_ZNKSt10moneypunctIcLb1EE13decimal_pointEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE13do_neg_formatEv FUNC:_ZNKSt10moneypunctIcLb1EE13do_neg_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE13do_pos_formatEv FUNC:_ZNKSt10moneypunctIcLb1EE13do_pos_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE13negative_signEv FUNC:_ZNKSt10moneypunctIcLb1EE13negative_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE13positive_signEv FUNC:_ZNKSt10moneypunctIcLb1EE13positive_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE13thousands_sepEv FUNC:_ZNKSt10moneypunctIcLb1EE13thousands_sepEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE14do_curr_symbolEv FUNC:_ZNKSt10moneypunctIcLb1EE14do_curr_symbolEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE14do_frac_digitsEv FUNC:_ZNKSt10moneypunctIcLb1EE14do_frac_digitsEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE16do_decimal_pointEv FUNC:_ZNKSt10moneypunctIcLb1EE16do_decimal_pointEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE16do_negative_signEv FUNC:_ZNKSt10moneypunctIcLb1EE16do_negative_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE16do_positive_signEv FUNC:_ZNKSt10moneypunctIcLb1EE16do_positive_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE16do_thousands_sepEv FUNC:_ZNKSt10moneypunctIcLb1EE16do_thousands_sepEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIcLb1EE8groupingEv FUNC:_ZNKSt10moneypunctIcLb1EE8groupingEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE10neg_formatEv FUNC:_ZNKSt10moneypunctIwLb0EE10neg_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE10pos_formatEv FUNC:_ZNKSt10moneypunctIwLb0EE10pos_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE11curr_symbolEv FUNC:_ZNKSt10moneypunctIwLb0EE11curr_symbolEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE11do_groupingEv FUNC:_ZNKSt10moneypunctIwLb0EE11do_groupingEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE11frac_digitsEv FUNC:_ZNKSt10moneypunctIwLb0EE11frac_digitsEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE13decimal_pointEv FUNC:_ZNKSt10moneypunctIwLb0EE13decimal_pointEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE13do_neg_formatEv FUNC:_ZNKSt10moneypunctIwLb0EE13do_neg_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE13do_pos_formatEv FUNC:_ZNKSt10moneypunctIwLb0EE13do_pos_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE13negative_signEv FUNC:_ZNKSt10moneypunctIwLb0EE13negative_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE13positive_signEv FUNC:_ZNKSt10moneypunctIwLb0EE13positive_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE13thousands_sepEv FUNC:_ZNKSt10moneypunctIwLb0EE13thousands_sepEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE14do_curr_symbolEv FUNC:_ZNKSt10moneypunctIwLb0EE14do_curr_symbolEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE14do_frac_digitsEv FUNC:_ZNKSt10moneypunctIwLb0EE14do_frac_digitsEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE16do_decimal_pointEv FUNC:_ZNKSt10moneypunctIwLb0EE16do_decimal_pointEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE16do_negative_signEv FUNC:_ZNKSt10moneypunctIwLb0EE16do_negative_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE16do_positive_signEv FUNC:_ZNKSt10moneypunctIwLb0EE16do_positive_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE16do_thousands_sepEv FUNC:_ZNKSt10moneypunctIwLb0EE16do_thousands_sepEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb0EE8groupingEv FUNC:_ZNKSt10moneypunctIwLb0EE8groupingEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE10neg_formatEv FUNC:_ZNKSt10moneypunctIwLb1EE10neg_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE10pos_formatEv FUNC:_ZNKSt10moneypunctIwLb1EE10pos_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE11curr_symbolEv FUNC:_ZNKSt10moneypunctIwLb1EE11curr_symbolEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE11do_groupingEv FUNC:_ZNKSt10moneypunctIwLb1EE11do_groupingEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE11frac_digitsEv FUNC:_ZNKSt10moneypunctIwLb1EE11frac_digitsEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE13decimal_pointEv FUNC:_ZNKSt10moneypunctIwLb1EE13decimal_pointEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE13do_neg_formatEv FUNC:_ZNKSt10moneypunctIwLb1EE13do_neg_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE13do_pos_formatEv FUNC:_ZNKSt10moneypunctIwLb1EE13do_pos_formatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE13negative_signEv FUNC:_ZNKSt10moneypunctIwLb1EE13negative_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE13positive_signEv FUNC:_ZNKSt10moneypunctIwLb1EE13positive_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE13thousands_sepEv FUNC:_ZNKSt10moneypunctIwLb1EE13thousands_sepEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE14do_curr_symbolEv FUNC:_ZNKSt10moneypunctIwLb1EE14do_curr_symbolEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE14do_frac_digitsEv FUNC:_ZNKSt10moneypunctIwLb1EE14do_frac_digitsEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE16do_decimal_pointEv FUNC:_ZNKSt10moneypunctIwLb1EE16do_decimal_pointEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE16do_negative_signEv FUNC:_ZNKSt10moneypunctIwLb1EE16do_negative_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE16do_positive_signEv FUNC:_ZNKSt10moneypunctIwLb1EE16do_positive_signEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE16do_thousands_sepEv FUNC:_ZNKSt10moneypunctIwLb1EE16do_thousands_sepEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10moneypunctIwLb1EE8groupingEv FUNC:_ZNKSt10moneypunctIwLb1EE8groupingEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10ostrstream5rdbufEv FUNC:_ZNKSt10ostrstream5rdbufEv@@GLIBCXX_3.4 -FUNC:_ZNKSt10ostrstream6pcountEv FUNC:_ZNKSt10ostrstream6pcountEv@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIcE15_M_am_pm_formatEPKc FUNC:_ZNKSt11__timepunctIcE15_M_am_pm_formatEPKc@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIcE15_M_am_pm_formatEPPKc FUNC:_ZNKSt11__timepunctIcE15_M_am_pm_formatEPPKc@@GLIBCXX_3.4.30 -FUNC:_ZNKSt11__timepunctIcE15_M_date_formatsEPPKc FUNC:_ZNKSt11__timepunctIcE15_M_date_formatsEPPKc@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIcE15_M_time_formatsEPPKc FUNC:_ZNKSt11__timepunctIcE15_M_time_formatsEPPKc@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIcE19_M_days_abbreviatedEPPKc FUNC:_ZNKSt11__timepunctIcE19_M_days_abbreviatedEPPKc@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIcE20_M_date_time_formatsEPPKc FUNC:_ZNKSt11__timepunctIcE20_M_date_time_formatsEPPKc@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIcE21_M_months_abbreviatedEPPKc FUNC:_ZNKSt11__timepunctIcE21_M_months_abbreviatedEPPKc@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIcE6_M_putEPcjPKcPK2tm FUNC:_ZNKSt11__timepunctIcE6_M_putEPcjPKcPK2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIcE7_M_daysEPPKc FUNC:_ZNKSt11__timepunctIcE7_M_daysEPPKc@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIcE8_M_am_pmEPPKc FUNC:_ZNKSt11__timepunctIcE8_M_am_pmEPPKc@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIcE9_M_monthsEPPKc FUNC:_ZNKSt11__timepunctIcE9_M_monthsEPPKc@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIwE15_M_am_pm_formatEPKw FUNC:_ZNKSt11__timepunctIwE15_M_am_pm_formatEPKw@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIwE15_M_am_pm_formatEPPKw FUNC:_ZNKSt11__timepunctIwE15_M_am_pm_formatEPPKw@@GLIBCXX_3.4.30 -FUNC:_ZNKSt11__timepunctIwE15_M_date_formatsEPPKw FUNC:_ZNKSt11__timepunctIwE15_M_date_formatsEPPKw@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIwE15_M_time_formatsEPPKw FUNC:_ZNKSt11__timepunctIwE15_M_time_formatsEPPKw@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIwE19_M_days_abbreviatedEPPKw FUNC:_ZNKSt11__timepunctIwE19_M_days_abbreviatedEPPKw@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIwE20_M_date_time_formatsEPPKw FUNC:_ZNKSt11__timepunctIwE20_M_date_time_formatsEPPKw@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIwE21_M_months_abbreviatedEPPKw FUNC:_ZNKSt11__timepunctIwE21_M_months_abbreviatedEPPKw@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIwE6_M_putEPwjPKwPK2tm FUNC:_ZNKSt11__timepunctIwE6_M_putEPwjPKwPK2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIwE7_M_daysEPPKw FUNC:_ZNKSt11__timepunctIwE7_M_daysEPPKw@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIwE8_M_am_pmEPPKw FUNC:_ZNKSt11__timepunctIwE8_M_am_pmEPPKw@@GLIBCXX_3.4 -FUNC:_ZNKSt11__timepunctIwE9_M_monthsEPPKw FUNC:_ZNKSt11__timepunctIwE9_M_monthsEPPKw@@GLIBCXX_3.4 -FUNC:_ZNKSt11logic_error4whatEv FUNC:_ZNKSt11logic_error4whatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt12__basic_fileIcE13native_handleEv -FUNC:_ZNKSt12__basic_fileIcE13native_handleEv@@GLIBCXX_3.4.32 -FUNC:_ZNKSt12__basic_fileIcE7is_openEv +FUNC:_ZNKSt12__basic_fileIcE13native_handleEv@@GLIBCXX_3.4.33 FUNC:_ZNKSt12__basic_fileIcE7is_openEv@@GLIBCXX_3.4 -FUNC:_ZNKSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEcvbEv FUNC:_ZNKSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEcvbEv@@GLIBCXX_3.4.31 -FUNC:_ZNKSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEcvbEv FUNC:_ZNKSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEcvbEv@@GLIBCXX_3.4.31 -FUNC:_ZNKSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEcvbEv FUNC:_ZNKSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEcvbEv@@GLIBCXX_3.4.31 -FUNC:_ZNKSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEcvbEv FUNC:_ZNKSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEcvbEv@@GLIBCXX_3.4.31 -FUNC:_ZNKSt12bad_weak_ptr4whatEv FUNC:_ZNKSt12bad_weak_ptr4whatEv@@GLIBCXX_3.4.15 -FUNC:_ZNKSt12future_error4whatEv FUNC:_ZNKSt12future_error4whatEv@@GLIBCXX_3.4.14 -FUNC:_ZNKSt12strstreambuf6pcountEv FUNC:_ZNKSt12strstreambuf6pcountEv@@GLIBCXX_3.4 -FUNC:_ZNKSt13bad_exception4whatEv FUNC:_ZNKSt13bad_exception4whatEv@@GLIBCXX_3.4.9 -FUNC:_ZNKSt13basic_filebufIcSt11char_traitsIcEE7is_openEv FUNC:_ZNKSt13basic_filebufIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4 -FUNC:_ZNKSt13basic_filebufIwSt11char_traitsIwEE7is_openEv FUNC:_ZNKSt13basic_filebufIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4 -FUNC:_ZNKSt13basic_fstreamIcSt11char_traitsIcEE5rdbufEv FUNC:_ZNKSt13basic_fstreamIcSt11char_traitsIcEE5rdbufEv@@GLIBCXX_3.4 FUNC:_ZNKSt13basic_fstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4.5 FUNC:_ZNKSt13basic_fstreamIcSt11char_traitsIcEE7is_openEv@GLIBCXX_3.4 -FUNC:_ZNKSt13basic_fstreamIwSt11char_traitsIwEE5rdbufEv FUNC:_ZNKSt13basic_fstreamIwSt11char_traitsIwEE5rdbufEv@@GLIBCXX_3.4 FUNC:_ZNKSt13basic_fstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4.5 FUNC:_ZNKSt13basic_fstreamIwSt11char_traitsIwEE7is_openEv@GLIBCXX_3.4 -FUNC:_ZNKSt13basic_istreamIwSt11char_traitsIwEE6gcountEv FUNC:_ZNKSt13basic_istreamIwSt11char_traitsIwEE6gcountEv@@GLIBCXX_3.4 -FUNC:_ZNKSt13basic_istreamIwSt11char_traitsIwEE6sentrycvbEv FUNC:_ZNKSt13basic_istreamIwSt11char_traitsIwEE6sentrycvbEv@@GLIBCXX_3.4 -FUNC:_ZNKSt13basic_ostreamIwSt11char_traitsIwEE6sentrycvbEv FUNC:_ZNKSt13basic_ostreamIwSt11char_traitsIwEE6sentrycvbEv@@GLIBCXX_3.4 -FUNC:_ZNKSt13random_device13_M_getentropyEv FUNC:_ZNKSt13random_device13_M_getentropyEv@@GLIBCXX_3.4.25 -FUNC:_ZNKSt13runtime_error4whatEv FUNC:_ZNKSt13runtime_error4whatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt14basic_ifstreamIcSt11char_traitsIcEE5rdbufEv FUNC:_ZNKSt14basic_ifstreamIcSt11char_traitsIcEE5rdbufEv@@GLIBCXX_3.4 FUNC:_ZNKSt14basic_ifstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4.5 FUNC:_ZNKSt14basic_ifstreamIcSt11char_traitsIcEE7is_openEv@GLIBCXX_3.4 -FUNC:_ZNKSt14basic_ifstreamIwSt11char_traitsIwEE5rdbufEv FUNC:_ZNKSt14basic_ifstreamIwSt11char_traitsIwEE5rdbufEv@@GLIBCXX_3.4 FUNC:_ZNKSt14basic_ifstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4.5 FUNC:_ZNKSt14basic_ifstreamIwSt11char_traitsIwEE7is_openEv@GLIBCXX_3.4 -FUNC:_ZNKSt14basic_ofstreamIcSt11char_traitsIcEE5rdbufEv FUNC:_ZNKSt14basic_ofstreamIcSt11char_traitsIcEE5rdbufEv@@GLIBCXX_3.4 FUNC:_ZNKSt14basic_ofstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4.5 FUNC:_ZNKSt14basic_ofstreamIcSt11char_traitsIcEE7is_openEv@GLIBCXX_3.4 -FUNC:_ZNKSt14basic_ofstreamIwSt11char_traitsIwEE5rdbufEv FUNC:_ZNKSt14basic_ofstreamIwSt11char_traitsIwEE5rdbufEv@@GLIBCXX_3.4 FUNC:_ZNKSt14basic_ofstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4.5 FUNC:_ZNKSt14basic_ofstreamIwSt11char_traitsIwEE7is_openEv@GLIBCXX_3.4 -FUNC:_ZNKSt14error_category10equivalentERKSt10error_codei FUNC:_ZNKSt14error_category10equivalentERKSt10error_codei@@GLIBCXX_3.4.11 -FUNC:_ZNKSt14error_category10equivalentEiRKSt15error_condition FUNC:_ZNKSt14error_category10equivalentEiRKSt15error_condition@@GLIBCXX_3.4.11 -FUNC:_ZNKSt14error_category23default_error_conditionEi FUNC:_ZNKSt14error_category23default_error_conditionEi@@GLIBCXX_3.4.11 -FUNC:_ZNKSt15__exception_ptr13exception_ptr20__cxa_exception_typeEv FUNC:_ZNKSt15__exception_ptr13exception_ptr20__cxa_exception_typeEv@@CXXABI_1.3.3 -FUNC:_ZNKSt15__exception_ptr13exception_ptrcvMS0_FvvEEv FUNC:_ZNKSt15__exception_ptr13exception_ptrcvMS0_FvvEEv@@CXXABI_1.3.3 -FUNC:_ZNKSt15__exception_ptr13exception_ptrntEv FUNC:_ZNKSt15__exception_ptr13exception_ptrntEv@@CXXABI_1.3.3 -FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE4gptrEv FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE4gptrEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE4pptrEv FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE4pptrEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE5ebackEv FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE5ebackEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE5egptrEv FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE5egptrEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE5epptrEv FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE5epptrEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE5pbaseEv FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE5pbaseEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE6getlocEv FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE6getlocEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE4gptrEv FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE4gptrEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE4pptrEv FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE4pptrEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE5ebackEv FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE5ebackEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE5egptrEv FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE5egptrEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE5epptrEv FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE5epptrEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE5pbaseEv FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE5pbaseEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE6getlocEv FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE6getlocEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNKSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4 -FUNC:_ZNKSt15basic_stringbufIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNKSt15basic_stringbufIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4 -FUNC:_ZNKSt16bad_array_length4whatEv FUNC:_ZNKSt16bad_array_length4whatEv@@CXXABI_1.3.8 -FUNC:_ZNKSt17bad_function_call4whatEv FUNC:_ZNKSt17bad_function_call4whatEv@@GLIBCXX_3.4.18 -FUNC:_ZNKSt18basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNKSt18basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4 -FUNC:_ZNKSt18basic_stringstreamIcSt11char_traitsIcESaIcEE5rdbufEv FUNC:_ZNKSt18basic_stringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4 -FUNC:_ZNKSt18basic_stringstreamIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNKSt18basic_stringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4 -FUNC:_ZNKSt18basic_stringstreamIwSt11char_traitsIwESaIwEE5rdbufEv FUNC:_ZNKSt18basic_stringstreamIwSt11char_traitsIwESaIwEE5rdbufEv@@GLIBCXX_3.4 -FUNC:_ZNKSt19__codecvt_utf8_baseIDiE10do_unshiftER11__mbstate_tPcS3_RS3_ FUNC:_ZNKSt19__codecvt_utf8_baseIDiE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIDiE11do_encodingEv FUNC:_ZNKSt19__codecvt_utf8_baseIDiE11do_encodingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIDiE13do_max_lengthEv FUNC:_ZNKSt19__codecvt_utf8_baseIDiE13do_max_lengthEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIDiE16do_always_noconvEv FUNC:_ZNKSt19__codecvt_utf8_baseIDiE16do_always_noconvEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIDiE5do_inER11__mbstate_tPKcS4_RS4_PDiS6_RS6_ FUNC:_ZNKSt19__codecvt_utf8_baseIDiE5do_inER11__mbstate_tPKcS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIDiE6do_outER11__mbstate_tPKDiS4_RS4_PcS6_RS6_ FUNC:_ZNKSt19__codecvt_utf8_baseIDiE6do_outER11__mbstate_tPKDiS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIDiE9do_lengthER11__mbstate_tPKcS4_j FUNC:_ZNKSt19__codecvt_utf8_baseIDiE9do_lengthER11__mbstate_tPKcS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIDsE10do_unshiftER11__mbstate_tPcS3_RS3_ FUNC:_ZNKSt19__codecvt_utf8_baseIDsE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIDsE11do_encodingEv FUNC:_ZNKSt19__codecvt_utf8_baseIDsE11do_encodingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIDsE13do_max_lengthEv FUNC:_ZNKSt19__codecvt_utf8_baseIDsE13do_max_lengthEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIDsE16do_always_noconvEv FUNC:_ZNKSt19__codecvt_utf8_baseIDsE16do_always_noconvEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIDsE5do_inER11__mbstate_tPKcS4_RS4_PDsS6_RS6_ FUNC:_ZNKSt19__codecvt_utf8_baseIDsE5do_inER11__mbstate_tPKcS4_RS4_PDsS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIDsE6do_outER11__mbstate_tPKDsS4_RS4_PcS6_RS6_ FUNC:_ZNKSt19__codecvt_utf8_baseIDsE6do_outER11__mbstate_tPKDsS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIDsE9do_lengthER11__mbstate_tPKcS4_j FUNC:_ZNKSt19__codecvt_utf8_baseIDsE9do_lengthER11__mbstate_tPKcS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIwE10do_unshiftER11__mbstate_tPcS3_RS3_ FUNC:_ZNKSt19__codecvt_utf8_baseIwE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIwE11do_encodingEv FUNC:_ZNKSt19__codecvt_utf8_baseIwE11do_encodingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIwE13do_max_lengthEv FUNC:_ZNKSt19__codecvt_utf8_baseIwE13do_max_lengthEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIwE16do_always_noconvEv FUNC:_ZNKSt19__codecvt_utf8_baseIwE16do_always_noconvEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIwE5do_inER11__mbstate_tPKcS4_RS4_PwS6_RS6_ FUNC:_ZNKSt19__codecvt_utf8_baseIwE5do_inER11__mbstate_tPKcS4_RS4_PwS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIwE6do_outER11__mbstate_tPKwS4_RS4_PcS6_RS6_ FUNC:_ZNKSt19__codecvt_utf8_baseIwE6do_outER11__mbstate_tPKwS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19__codecvt_utf8_baseIwE9do_lengthER11__mbstate_tPKcS4_j FUNC:_ZNKSt19__codecvt_utf8_baseIwE9do_lengthER11__mbstate_tPKcS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt19basic_istringstreamIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNKSt19basic_istringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4 -FUNC:_ZNKSt19basic_istringstreamIcSt11char_traitsIcESaIcEE5rdbufEv FUNC:_ZNKSt19basic_istringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4 -FUNC:_ZNKSt19basic_istringstreamIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNKSt19basic_istringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4 -FUNC:_ZNKSt19basic_istringstreamIwSt11char_traitsIwESaIwEE5rdbufEv FUNC:_ZNKSt19basic_istringstreamIwSt11char_traitsIwESaIwEE5rdbufEv@@GLIBCXX_3.4 -FUNC:_ZNKSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNKSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4 -FUNC:_ZNKSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE5rdbufEv FUNC:_ZNKSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4 -FUNC:_ZNKSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNKSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4 -FUNC:_ZNKSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE5rdbufEv FUNC:_ZNKSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE5rdbufEv@@GLIBCXX_3.4 -FUNC:_ZNKSt20__codecvt_utf16_baseIDiE10do_unshiftER11__mbstate_tPcS3_RS3_ FUNC:_ZNKSt20__codecvt_utf16_baseIDiE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIDiE11do_encodingEv FUNC:_ZNKSt20__codecvt_utf16_baseIDiE11do_encodingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIDiE13do_max_lengthEv FUNC:_ZNKSt20__codecvt_utf16_baseIDiE13do_max_lengthEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIDiE16do_always_noconvEv FUNC:_ZNKSt20__codecvt_utf16_baseIDiE16do_always_noconvEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIDiE5do_inER11__mbstate_tPKcS4_RS4_PDiS6_RS6_ FUNC:_ZNKSt20__codecvt_utf16_baseIDiE5do_inER11__mbstate_tPKcS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIDiE6do_outER11__mbstate_tPKDiS4_RS4_PcS6_RS6_ FUNC:_ZNKSt20__codecvt_utf16_baseIDiE6do_outER11__mbstate_tPKDiS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIDiE9do_lengthER11__mbstate_tPKcS4_j FUNC:_ZNKSt20__codecvt_utf16_baseIDiE9do_lengthER11__mbstate_tPKcS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIDsE10do_unshiftER11__mbstate_tPcS3_RS3_ FUNC:_ZNKSt20__codecvt_utf16_baseIDsE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIDsE11do_encodingEv FUNC:_ZNKSt20__codecvt_utf16_baseIDsE11do_encodingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIDsE13do_max_lengthEv FUNC:_ZNKSt20__codecvt_utf16_baseIDsE13do_max_lengthEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIDsE16do_always_noconvEv FUNC:_ZNKSt20__codecvt_utf16_baseIDsE16do_always_noconvEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIDsE5do_inER11__mbstate_tPKcS4_RS4_PDsS6_RS6_ FUNC:_ZNKSt20__codecvt_utf16_baseIDsE5do_inER11__mbstate_tPKcS4_RS4_PDsS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIDsE6do_outER11__mbstate_tPKDsS4_RS4_PcS6_RS6_ FUNC:_ZNKSt20__codecvt_utf16_baseIDsE6do_outER11__mbstate_tPKDsS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIDsE9do_lengthER11__mbstate_tPKcS4_j FUNC:_ZNKSt20__codecvt_utf16_baseIDsE9do_lengthER11__mbstate_tPKcS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIwE10do_unshiftER11__mbstate_tPcS3_RS3_ FUNC:_ZNKSt20__codecvt_utf16_baseIwE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIwE11do_encodingEv FUNC:_ZNKSt20__codecvt_utf16_baseIwE11do_encodingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIwE13do_max_lengthEv FUNC:_ZNKSt20__codecvt_utf16_baseIwE13do_max_lengthEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIwE16do_always_noconvEv FUNC:_ZNKSt20__codecvt_utf16_baseIwE16do_always_noconvEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIwE5do_inER11__mbstate_tPKcS4_RS4_PwS6_RS6_ FUNC:_ZNKSt20__codecvt_utf16_baseIwE5do_inER11__mbstate_tPKcS4_RS4_PwS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIwE6do_outER11__mbstate_tPKwS4_RS4_PcS6_RS6_ FUNC:_ZNKSt20__codecvt_utf16_baseIwE6do_outER11__mbstate_tPKwS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20__codecvt_utf16_baseIwE9do_lengthER11__mbstate_tPKcS4_j FUNC:_ZNKSt20__codecvt_utf16_baseIwE9do_lengthER11__mbstate_tPKcS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt20bad_array_new_length4whatEv FUNC:_ZNKSt20bad_array_new_length4whatEv@@CXXABI_1.3.8 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE10do_unshiftER11__mbstate_tPcS3_RS3_ FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE11do_encodingEv FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE11do_encodingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE13do_max_lengthEv FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE13do_max_lengthEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE16do_always_noconvEv FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE16do_always_noconvEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE5do_inER11__mbstate_tPKcS4_RS4_PDiS6_RS6_ FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE5do_inER11__mbstate_tPKcS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE6do_outER11__mbstate_tPKDiS4_RS4_PcS6_RS6_ FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE6do_outER11__mbstate_tPKDiS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE9do_lengthER11__mbstate_tPKcS4_j FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE9do_lengthER11__mbstate_tPKcS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE10do_unshiftER11__mbstate_tPcS3_RS3_ FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE11do_encodingEv FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE11do_encodingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE13do_max_lengthEv FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE13do_max_lengthEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE16do_always_noconvEv FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE16do_always_noconvEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE5do_inER11__mbstate_tPKcS4_RS4_PDsS6_RS6_ FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE5do_inER11__mbstate_tPKcS4_RS4_PDsS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE6do_outER11__mbstate_tPKDsS4_RS4_PcS6_RS6_ FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE6do_outER11__mbstate_tPKDsS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE9do_lengthER11__mbstate_tPKcS4_j FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE9do_lengthER11__mbstate_tPKcS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE10do_unshiftER11__mbstate_tPcS3_RS3_ FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE11do_encodingEv FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE11do_encodingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE13do_max_lengthEv FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE13do_max_lengthEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE16do_always_noconvEv FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE16do_always_noconvEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE5do_inER11__mbstate_tPKcS4_RS4_PwS6_RS6_ FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE5do_inER11__mbstate_tPKcS4_RS4_PwS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE6do_outER11__mbstate_tPKwS4_RS4_PcS6_RS6_ FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE6do_outER11__mbstate_tPKwS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE9do_lengthER11__mbstate_tPKcS4_j FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE9do_lengthER11__mbstate_tPKcS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt3_V214error_category10_M_messageB5cxx11Ei FUNC:_ZNKSt3_V214error_category10_M_messageB5cxx11Ei@@GLIBCXX_3.4.21 -FUNC:_ZNKSt3_V214error_category10_M_messageEi FUNC:_ZNKSt3_V214error_category10_M_messageEi@@GLIBCXX_3.4.21 -FUNC:_ZNKSt3_V214error_category10equivalentERKSt10error_codei FUNC:_ZNKSt3_V214error_category10equivalentERKSt10error_codei@@GLIBCXX_3.4.21 -FUNC:_ZNKSt3_V214error_category10equivalentEiRKSt15error_condition FUNC:_ZNKSt3_V214error_category10equivalentEiRKSt15error_condition@@GLIBCXX_3.4.21 -FUNC:_ZNKSt3_V214error_category23default_error_conditionEi FUNC:_ZNKSt3_V214error_category23default_error_conditionEi@@GLIBCXX_3.4.21 -FUNC:_ZNKSt3tr14hashINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEclES6_ FUNC:_ZNKSt3tr14hashINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEclES6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt3tr14hashINSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEEEclES6_ FUNC:_ZNKSt3tr14hashINSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEEEclES6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt3tr14hashIRKSbIwSt11char_traitsIwESaIwEEEclES6_ FUNC:_ZNKSt3tr14hashIRKSbIwSt11char_traitsIwESaIwEEEclES6_@@GLIBCXX_3.4.10 -FUNC:_ZNKSt3tr14hashIRKSsEclES2_ FUNC:_ZNKSt3tr14hashIRKSsEclES2_@@GLIBCXX_3.4.10 -FUNC:_ZNKSt3tr14hashISbIwSt11char_traitsIwESaIwEEEclES4_ FUNC:_ZNKSt3tr14hashISbIwSt11char_traitsIwESaIwEEEclES4_@@GLIBCXX_3.4.10 -FUNC:_ZNKSt3tr14hashISsEclESs FUNC:_ZNKSt3tr14hashISsEclESs@@GLIBCXX_3.4.10 -FUNC:_ZNKSt3tr14hashIeEclEe FUNC:_ZNKSt3tr14hashIeEclEe@@GLIBCXX_3.4.10 -FUNC:_ZNKSt4hashIRKSbIwSt11char_traitsIwESaIwEEEclES5_ FUNC:_ZNKSt4hashIRKSbIwSt11char_traitsIwESaIwEEEclES5_@@GLIBCXX_3.4.10 -FUNC:_ZNKSt4hashIRKSsEclES1_ FUNC:_ZNKSt4hashIRKSsEclES1_@@GLIBCXX_3.4.10 -FUNC:_ZNKSt4hashISbIwSt11char_traitsIwESaIwEEEclES3_ FUNC:_ZNKSt4hashISbIwSt11char_traitsIwESaIwEEEclES3_@@GLIBCXX_3.4.10 -FUNC:_ZNKSt4hashISsEclESs FUNC:_ZNKSt4hashISsEclESs@@GLIBCXX_3.4.10 -FUNC:_ZNKSt4hashISt10error_codeEclES0_ FUNC:_ZNKSt4hashISt10error_codeEclES0_@@GLIBCXX_3.4.11 -FUNC:_ZNKSt4hashIeEclEe FUNC:_ZNKSt4hashIeEclEe@@GLIBCXX_3.4.10 -FUNC:_ZNKSt5ctypeIcE10do_tolowerEPcPKc FUNC:_ZNKSt5ctypeIcE10do_tolowerEPcPKc@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIcE10do_tolowerEc FUNC:_ZNKSt5ctypeIcE10do_tolowerEc@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIcE10do_toupperEPcPKc FUNC:_ZNKSt5ctypeIcE10do_toupperEPcPKc@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIcE10do_toupperEc FUNC:_ZNKSt5ctypeIcE10do_toupperEc@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIcE13_M_widen_initEv FUNC:_ZNKSt5ctypeIcE13_M_widen_initEv@@GLIBCXX_3.4.11 -FUNC:_ZNKSt5ctypeIcE14_M_narrow_initEv FUNC:_ZNKSt5ctypeIcE14_M_narrow_initEv@@GLIBCXX_3.4.11 -FUNC:_ZNKSt5ctypeIcE8do_widenEPKcS2_Pc FUNC:_ZNKSt5ctypeIcE8do_widenEPKcS2_Pc@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIcE8do_widenEc FUNC:_ZNKSt5ctypeIcE8do_widenEc@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIcE9do_narrowEPKcS2_cPc FUNC:_ZNKSt5ctypeIcE9do_narrowEPKcS2_cPc@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIcE9do_narrowEcc FUNC:_ZNKSt5ctypeIcE9do_narrowEcc@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIwE10do_scan_isEtPKwS2_ FUNC:_ZNKSt5ctypeIwE10do_scan_isEtPKwS2_@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIwE10do_tolowerEPwPKw FUNC:_ZNKSt5ctypeIwE10do_tolowerEPwPKw@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIwE10do_tolowerEw FUNC:_ZNKSt5ctypeIwE10do_tolowerEw@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIwE10do_toupperEPwPKw FUNC:_ZNKSt5ctypeIwE10do_toupperEPwPKw@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIwE10do_toupperEw FUNC:_ZNKSt5ctypeIwE10do_toupperEw@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIwE11do_scan_notEtPKwS2_ FUNC:_ZNKSt5ctypeIwE11do_scan_notEtPKwS2_@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIwE19_M_convert_to_wmaskEt FUNC:_ZNKSt5ctypeIwE19_M_convert_to_wmaskEt@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIwE5do_isEPKwS2_Pt FUNC:_ZNKSt5ctypeIwE5do_isEPKwS2_Pt@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIwE5do_isEtw FUNC:_ZNKSt5ctypeIwE5do_isEtw@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIwE8do_widenEPKcS2_Pw FUNC:_ZNKSt5ctypeIwE8do_widenEPKcS2_Pw@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIwE8do_widenEc FUNC:_ZNKSt5ctypeIwE8do_widenEc@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIwE9do_narrowEPKwS2_cPc FUNC:_ZNKSt5ctypeIwE9do_narrowEPKwS2_cPc@@GLIBCXX_3.4 -FUNC:_ZNKSt5ctypeIwE9do_narrowEwc FUNC:_ZNKSt5ctypeIwE9do_narrowEwc@@GLIBCXX_3.4 -FUNC:_ZNKSt6chrono4tzdb11locate_zoneESt17basic_string_viewIcSt11char_traitsIcEE FUNC:_ZNKSt6chrono4tzdb11locate_zoneESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.31 -FUNC:_ZNKSt6chrono4tzdb12current_zoneEv FUNC:_ZNKSt6chrono4tzdb12current_zoneEv@@GLIBCXX_3.4.31 -FUNC:_ZNKSt6chrono9time_zone15_M_get_sys_infoENS_10time_pointINS_3_V212system_clockENS_8durationIxSt5ratioILx1ELx1EEEEEE FUNC:_ZNKSt6chrono9time_zone15_M_get_sys_infoENS_10time_pointINS_3_V212system_clockENS_8durationIxSt5ratioILx1ELx1EEEEEE@@GLIBCXX_3.4.31 -FUNC:_ZNKSt6chrono9time_zone17_M_get_local_infoENS_10time_pointINS_7local_tENS_8durationIxSt5ratioILx1ELx1EEEEEE FUNC:_ZNKSt6chrono9time_zone17_M_get_local_infoENS_10time_pointINS_7local_tENS_8durationIxSt5ratioILx1ELx1EEEEEE@@GLIBCXX_3.4.31 -FUNC:_ZNKSt6chrono9tzdb_list14const_iteratordeEv FUNC:_ZNKSt6chrono9tzdb_list14const_iteratordeEv@@GLIBCXX_3.4.31 -FUNC:_ZNKSt6chrono9tzdb_list5beginEv FUNC:_ZNKSt6chrono9tzdb_list5beginEv@@GLIBCXX_3.4.31 -FUNC:_ZNKSt6chrono9tzdb_list5frontEv FUNC:_ZNKSt6chrono9tzdb_list5frontEv@@GLIBCXX_3.4.31 -FUNC:_ZNKSt6locale2id5_M_idEv FUNC:_ZNKSt6locale2id5_M_idEv@@GLIBCXX_3.4 -FUNC:_ZNKSt6locale4nameB5cxx11Ev FUNC:_ZNKSt6locale4nameB5cxx11Ev@@GLIBCXX_3.4.21 -FUNC:_ZNKSt6locale4nameEv FUNC:_ZNKSt6locale4nameEv@@GLIBCXX_3.4 -FUNC:_ZNKSt6localeeqERKS_ FUNC:_ZNKSt6localeeqERKS_@@GLIBCXX_3.4 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE10neg_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE10neg_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE10pos_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE10pos_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE11curr_symbolEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE11curr_symbolEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE11do_groupingEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE11do_groupingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE11frac_digitsEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE11frac_digitsEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13decimal_pointEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13decimal_pointEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13do_neg_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13do_neg_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13do_pos_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13do_pos_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13negative_signEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13negative_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13positive_signEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13positive_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13thousands_sepEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13thousands_sepEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE14do_curr_symbolEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE14do_curr_symbolEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE14do_frac_digitsEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE14do_frac_digitsEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE16do_decimal_pointEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE16do_decimal_pointEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE16do_negative_signEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE16do_negative_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE16do_positive_signEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE16do_positive_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE16do_thousands_sepEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE16do_thousands_sepEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE8groupingEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE8groupingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE10neg_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE10neg_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE10pos_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE10pos_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE11curr_symbolEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE11curr_symbolEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE11do_groupingEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE11do_groupingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE11frac_digitsEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE11frac_digitsEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13decimal_pointEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13decimal_pointEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13do_neg_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13do_neg_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13do_pos_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13do_pos_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13negative_signEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13negative_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13positive_signEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13positive_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13thousands_sepEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13thousands_sepEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE14do_curr_symbolEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE14do_curr_symbolEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE14do_frac_digitsEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE14do_frac_digitsEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE16do_decimal_pointEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE16do_decimal_pointEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE16do_negative_signEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE16do_negative_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE16do_positive_signEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE16do_positive_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE16do_thousands_sepEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE16do_thousands_sepEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE8groupingEv FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE8groupingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE10neg_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE10neg_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE10pos_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE10pos_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE11curr_symbolEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE11curr_symbolEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE11do_groupingEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE11do_groupingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE11frac_digitsEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE11frac_digitsEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13decimal_pointEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13decimal_pointEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13do_neg_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13do_neg_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13do_pos_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13do_pos_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13negative_signEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13negative_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13positive_signEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13positive_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13thousands_sepEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13thousands_sepEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE14do_curr_symbolEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE14do_curr_symbolEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE14do_frac_digitsEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE14do_frac_digitsEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE16do_decimal_pointEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE16do_decimal_pointEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE16do_negative_signEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE16do_negative_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE16do_positive_signEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE16do_positive_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE16do_thousands_sepEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE16do_thousands_sepEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE8groupingEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE8groupingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE10neg_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE10neg_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE10pos_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE10pos_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE11curr_symbolEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE11curr_symbolEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE11do_groupingEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE11do_groupingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE11frac_digitsEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE11frac_digitsEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13decimal_pointEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13decimal_pointEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13do_neg_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13do_neg_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13do_pos_formatEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13do_pos_formatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13negative_signEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13negative_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13positive_signEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13positive_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13thousands_sepEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13thousands_sepEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE14do_curr_symbolEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE14do_curr_symbolEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE14do_frac_digitsEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE14do_frac_digitsEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE16do_decimal_pointEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE16do_decimal_pointEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE16do_negative_signEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE16do_negative_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE16do_positive_signEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE16do_positive_signEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE16do_thousands_sepEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE16do_thousands_sepEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE8groupingEv FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE8groupingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE11_M_disjunctEPKc FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE11_M_disjunctEPKc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE11_M_is_localEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE11_M_is_localEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12find_last_ofEPKcj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12find_last_ofEPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12find_last_ofEPKcjj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12find_last_ofEPKcjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12find_last_ofERKS4_j FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12find_last_ofERKS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12find_last_ofEcj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12find_last_ofEcj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_local_dataEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_local_dataEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofEPKcj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofEPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofEPKcjj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofEPKcjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofERKS4_j FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofERKS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofEcj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofEcj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13get_allocatorEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13get_allocatorEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE15_M_check_lengthEjjPKc FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE15_M_check_lengthEjjPKc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16_M_get_allocatorEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16_M_get_allocatorEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16find_last_not_ofEPKcj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16find_last_not_ofEPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16find_last_not_ofEPKcjj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16find_last_not_ofEPKcjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16find_last_not_ofERKS4_j FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16find_last_not_ofERKS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16find_last_not_ofEcj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16find_last_not_ofEcj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17find_first_not_ofEPKcj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17find_first_not_ofEPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17find_first_not_ofEPKcjj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17find_first_not_ofEPKcjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17find_first_not_ofERKS4_j FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17find_first_not_ofERKS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17find_first_not_ofEcj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17find_first_not_ofEcj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE2atEj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE2atEj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE3endEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE3endEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4backEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4backEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4cendEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4cendEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4copyEPcjj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4copyEPcjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4dataEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4dataEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findEPKcj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findEPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findEPKcjj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findEPKcjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findERKS4_j FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findERKS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findEcj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findEcj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4rendEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4rendEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4sizeEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4sizeEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5beginEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5beginEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5c_strEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5c_strEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5crendEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5crendEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5emptyEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5emptyEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5frontEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5frontEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEPKcj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEPKcjj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEPKcjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindERKS4_j FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindERKS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEcj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEcj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6cbeginEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6cbeginEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6lengthEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6lengthEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6rbeginEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6rbeginEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6substrEjj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6substrEjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7_M_dataEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7_M_dataEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEPKc FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEPKc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareERKS4_ FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEjjPKc FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEjjPKc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEjjPKcj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEjjPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEjjRKS4_ FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEjjRKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEjjRKS4_jj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEjjRKS4_jj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7crbeginEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7crbeginEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_checkEjPKc FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_checkEjPKc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_limitEjj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_limitEjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8capacityEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8capacityEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8max_sizeEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8max_sizeEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEcvSt17basic_string_viewIcS2_EEv FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEcvSt17basic_string_viewIcS2_EEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEixEj FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEixEj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_disjunctEPKw FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_disjunctEPKw@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_is_localEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_is_localEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12find_last_ofEPKwj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12find_last_ofEPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12find_last_ofEPKwjj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12find_last_ofEPKwjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12find_last_ofERKS4_j FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12find_last_ofERKS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12find_last_ofEwj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12find_last_ofEwj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_local_dataEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_local_dataEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13find_first_ofEPKwj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13find_first_ofEPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13find_first_ofEPKwjj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13find_first_ofEPKwjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13find_first_ofERKS4_j FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13find_first_ofERKS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13find_first_ofEwj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13find_first_ofEwj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13get_allocatorEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13get_allocatorEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE15_M_check_lengthEjjPKc FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE15_M_check_lengthEjjPKc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16_M_get_allocatorEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16_M_get_allocatorEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwjj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16find_last_not_ofERKS4_j FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16find_last_not_ofERKS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16find_last_not_ofEwj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16find_last_not_ofEwj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwjj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17find_first_not_ofERKS4_j FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17find_first_not_ofERKS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17find_first_not_ofEwj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17find_first_not_ofEwj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE2atEj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE2atEj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE3endEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4backEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4cendEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4cendEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4copyEPwjj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4copyEPwjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4dataEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4findEPKwj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4findEPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4findEPKwjj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4findEPKwjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4findERKS4_j FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4findERKS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4findEwj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4findEwj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4rendEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4sizeEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4sizeEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5beginEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5c_strEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5c_strEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5crendEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5crendEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5emptyEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5emptyEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5frontEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5frontEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5rfindEPKwj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5rfindEPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5rfindEPKwjj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5rfindEPKwjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5rfindERKS4_j FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5rfindERKS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5rfindEwj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5rfindEwj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6cbeginEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6cbeginEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6lengthEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6lengthEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6rbeginEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6rbeginEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6substrEjj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6substrEjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7_M_dataEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7_M_dataEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEPKw FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEPKw@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareERKS4_ FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEjjPKw FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEjjPKw@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEjjPKwj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEjjPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEjjRKS4_ FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEjjRKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEjjRKS4_jj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEjjRKS4_jj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7crbeginEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7crbeginEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_checkEjPKc FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_checkEjPKc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_limitEjj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_limitEjj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8capacityEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8capacityEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8max_sizeEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8max_sizeEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEcvSt17basic_string_viewIwS2_EEv FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEcvSt17basic_string_viewIwS2_EEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEixEj FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEixEj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE13get_allocatorEv FUNC:_ZNKSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE13get_allocatorEv@@GLIBCXX_3.4.29 -FUNC:_ZNKSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNKSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE4viewEv FUNC:_ZNKSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE4viewEv@@GLIBCXX_3.4.29 -FUNC:_ZNKSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE13get_allocatorEv FUNC:_ZNKSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE13get_allocatorEv@@GLIBCXX_3.4.29 -FUNC:_ZNKSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNKSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE4viewEv FUNC:_ZNKSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE4viewEv@@GLIBCXX_3.4.29 -FUNC:_ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE4viewEv FUNC:_ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE4viewEv@@GLIBCXX_3.4.29 -FUNC:_ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE5rdbufEv FUNC:_ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNKSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE4viewEv FUNC:_ZNKSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE4viewEv@@GLIBCXX_3.4.29 -FUNC:_ZNKSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE5rdbufEv FUNC:_ZNKSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE5rdbufEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNKSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE4viewEv FUNC:_ZNKSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE4viewEv@@GLIBCXX_3.4.29 -FUNC:_ZNKSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE5rdbufEv FUNC:_ZNKSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNKSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE4viewEv FUNC:_ZNKSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE4viewEv@@GLIBCXX_3.4.29 -FUNC:_ZNKSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE5rdbufEv FUNC:_ZNKSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE5rdbufEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNKSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE4viewEv FUNC:_ZNKSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE4viewEv@@GLIBCXX_3.4.29 -FUNC:_ZNKSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE5rdbufEv FUNC:_ZNKSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNKSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE4viewEv FUNC:_ZNKSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE4viewEv@@GLIBCXX_3.4.29 -FUNC:_ZNKSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE5rdbufEv FUNC:_ZNKSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE5rdbufEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIcE10_M_compareEPKcS3_ FUNC:_ZNKSt7__cxx117collateIcE10_M_compareEPKcS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIcE10do_compareEPKcS3_S3_S3_ FUNC:_ZNKSt7__cxx117collateIcE10do_compareEPKcS3_S3_S3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIcE12_M_transformEPcPKcj FUNC:_ZNKSt7__cxx117collateIcE12_M_transformEPcPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIcE12do_transformEPKcS3_ FUNC:_ZNKSt7__cxx117collateIcE12do_transformEPKcS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIcE4hashEPKcS3_ FUNC:_ZNKSt7__cxx117collateIcE4hashEPKcS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIcE7compareEPKcS3_S3_S3_ FUNC:_ZNKSt7__cxx117collateIcE7compareEPKcS3_S3_S3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIcE7do_hashEPKcS3_ FUNC:_ZNKSt7__cxx117collateIcE7do_hashEPKcS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIcE9transformEPKcS3_ FUNC:_ZNKSt7__cxx117collateIcE9transformEPKcS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIwE10_M_compareEPKwS3_ FUNC:_ZNKSt7__cxx117collateIwE10_M_compareEPKwS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIwE10do_compareEPKwS3_S3_S3_ FUNC:_ZNKSt7__cxx117collateIwE10do_compareEPKwS3_S3_S3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIwE12_M_transformEPwPKwj FUNC:_ZNKSt7__cxx117collateIwE12_M_transformEPwPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIwE12do_transformEPKwS3_ FUNC:_ZNKSt7__cxx117collateIwE12do_transformEPKwS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIwE4hashEPKwS3_ FUNC:_ZNKSt7__cxx117collateIwE4hashEPKwS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIwE7compareEPKwS3_S3_S3_ FUNC:_ZNKSt7__cxx117collateIwE7compareEPKwS3_S3_S3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIwE7do_hashEPKwS3_ FUNC:_ZNKSt7__cxx117collateIwE7do_hashEPKwS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx117collateIwE9transformEPKwS3_ FUNC:_ZNKSt7__cxx117collateIwE9transformEPKwS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIcE18_M_convert_to_charERKNS_12basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNKSt7__cxx118messagesIcE18_M_convert_to_charERKNS_12basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIcE20_M_convert_from_charEPc FUNC:_ZNKSt7__cxx118messagesIcE20_M_convert_from_charEPc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIcE3getEiiiRKNS_12basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNKSt7__cxx118messagesIcE3getEiiiRKNS_12basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIcE4openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6locale FUNC:_ZNKSt7__cxx118messagesIcE4openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIcE4openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6localePKc FUNC:_ZNKSt7__cxx118messagesIcE4openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6localePKc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIcE5closeEi FUNC:_ZNKSt7__cxx118messagesIcE5closeEi@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIcE6do_getEiiiRKNS_12basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNKSt7__cxx118messagesIcE6do_getEiiiRKNS_12basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIcE7do_openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6locale FUNC:_ZNKSt7__cxx118messagesIcE7do_openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIcE8do_closeEi FUNC:_ZNKSt7__cxx118messagesIcE8do_closeEi@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIwE18_M_convert_to_charERKNS_12basic_stringIwSt11char_traitsIwESaIwEEE FUNC:_ZNKSt7__cxx118messagesIwE18_M_convert_to_charERKNS_12basic_stringIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIwE20_M_convert_from_charEPc FUNC:_ZNKSt7__cxx118messagesIwE20_M_convert_from_charEPc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIwE3getEiiiRKNS_12basic_stringIwSt11char_traitsIwESaIwEEE FUNC:_ZNKSt7__cxx118messagesIwE3getEiiiRKNS_12basic_stringIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIwE4openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6locale FUNC:_ZNKSt7__cxx118messagesIwE4openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIwE4openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6localePKc FUNC:_ZNKSt7__cxx118messagesIwE4openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6localePKc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIwE5closeEi FUNC:_ZNKSt7__cxx118messagesIwE5closeEi@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIwE6do_getEiiiRKNS_12basic_stringIwSt11char_traitsIwESaIwEEE FUNC:_ZNKSt7__cxx118messagesIwE6do_getEiiiRKNS_12basic_stringIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIwE7do_openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6locale FUNC:_ZNKSt7__cxx118messagesIwE7do_openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118messagesIwE8do_closeEi FUNC:_ZNKSt7__cxx118messagesIwE8do_closeEi@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIcE11do_groupingEv FUNC:_ZNKSt7__cxx118numpunctIcE11do_groupingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIcE11do_truenameEv FUNC:_ZNKSt7__cxx118numpunctIcE11do_truenameEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIcE12do_falsenameEv FUNC:_ZNKSt7__cxx118numpunctIcE12do_falsenameEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIcE13decimal_pointEv FUNC:_ZNKSt7__cxx118numpunctIcE13decimal_pointEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIcE13thousands_sepEv FUNC:_ZNKSt7__cxx118numpunctIcE13thousands_sepEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIcE16do_decimal_pointEv FUNC:_ZNKSt7__cxx118numpunctIcE16do_decimal_pointEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIcE16do_thousands_sepEv FUNC:_ZNKSt7__cxx118numpunctIcE16do_thousands_sepEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIcE8groupingEv FUNC:_ZNKSt7__cxx118numpunctIcE8groupingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIcE8truenameEv FUNC:_ZNKSt7__cxx118numpunctIcE8truenameEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIcE9falsenameEv FUNC:_ZNKSt7__cxx118numpunctIcE9falsenameEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIwE11do_groupingEv FUNC:_ZNKSt7__cxx118numpunctIwE11do_groupingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIwE11do_truenameEv FUNC:_ZNKSt7__cxx118numpunctIwE11do_truenameEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIwE12do_falsenameEv FUNC:_ZNKSt7__cxx118numpunctIwE12do_falsenameEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIwE13decimal_pointEv FUNC:_ZNKSt7__cxx118numpunctIwE13decimal_pointEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIwE13thousands_sepEv FUNC:_ZNKSt7__cxx118numpunctIwE13thousands_sepEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIwE16do_decimal_pointEv FUNC:_ZNKSt7__cxx118numpunctIwE16do_decimal_pointEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIwE16do_thousands_sepEv FUNC:_ZNKSt7__cxx118numpunctIwE16do_thousands_sepEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIwE8groupingEv FUNC:_ZNKSt7__cxx118numpunctIwE8groupingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIwE8truenameEv FUNC:_ZNKSt7__cxx118numpunctIwE8truenameEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118numpunctIwE9falsenameEv FUNC:_ZNKSt7__cxx118numpunctIwE9falsenameEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10date_orderEv FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10date_orderEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_dateES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_dateES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_timeES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_timeES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_yearES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_yearES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11get_weekdayES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11get_weekdayES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE13do_date_orderEv FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE13do_date_orderEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE13get_monthnameES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE13get_monthnameES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_numES4_S4_RiiijRSt8ios_baseRSt12_Ios_Iostate FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_numES4_S4_RiiijRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14do_get_weekdayES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14do_get_weekdayES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE15_M_extract_nameES4_S4_RiPPKcjRSt8ios_baseRSt12_Ios_Iostate FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE15_M_extract_nameES4_S4_RiPPKcjRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE16do_get_monthnameES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE16do_get_monthnameES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKc FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKcRSt16__time_get_state FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKcRSt16__time_get_state@@GLIBCXX_3.4.30 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE24_M_extract_wday_or_monthES4_S4_RiPPKcjRSt8ios_baseRSt12_Ios_Iostate FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE24_M_extract_wday_or_monthES4_S4_RiPPKcjRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKcSD_ FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKcSD_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmcc FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmcc FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_dateES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_dateES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_timeES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_timeES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_yearES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_yearES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10date_orderEv FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10date_orderEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_dateES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_dateES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_timeES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_timeES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_yearES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_yearES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11get_weekdayES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11get_weekdayES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE13do_date_orderEv FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE13do_date_orderEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE13get_monthnameES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE13get_monthnameES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_numES4_S4_RiiijRSt8ios_baseRSt12_Ios_Iostate FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_numES4_S4_RiiijRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14do_get_weekdayES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14do_get_weekdayES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE15_M_extract_nameES4_S4_RiPPKwjRSt8ios_baseRSt12_Ios_Iostate FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE15_M_extract_nameES4_S4_RiPPKwjRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16do_get_monthnameES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16do_get_monthnameES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE21_M_extract_via_formatES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKw FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE21_M_extract_via_formatES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKw@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE21_M_extract_via_formatES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKwRSt16__time_get_state FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE21_M_extract_via_formatES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKwRSt16__time_get_state@@GLIBCXX_3.4.30 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE24_M_extract_wday_or_monthES4_S4_RiPPKwjRSt8ios_baseRSt12_Ios_Iostate FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE24_M_extract_wday_or_monthES4_S4_RiPPKwjRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKwSD_ FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKwSD_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmcc FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmcc FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_dateES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_dateES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_timeES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_timeES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_yearES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_yearES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS3_SaIcEEE FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS3_SaIcEEE FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS3_SaIcEEE FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRe FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS3_SaIcEEE FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRe FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS2_IcESaIcEEE FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS2_IcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS2_IcESaIcEEE FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS2_IcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIwS3_SaIwEEE FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRe FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIwS3_SaIwEEE FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRe FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_bRSt8ios_basecRKNS_12basic_stringIcS3_SaIcEEE FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_bRSt8ios_basecRKNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_bRSt8ios_basece FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_bRSt8ios_basece@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basecRKNS_12basic_stringIcS3_SaIcEEE FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basecRKNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basece FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basece@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES4_S4_RSt8ios_basecRKNS_12basic_stringIcS3_SaIcEEE FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES4_S4_RSt8ios_basecRKNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES4_S4_RSt8ios_basecRKNS_12basic_stringIcS3_SaIcEEE FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES4_S4_RSt8ios_basecRKNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_bRSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_bRSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_bRSt8ios_basewe FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_bRSt8ios_basewe@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_bRSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_bRSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_bRSt8ios_basewe FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_bRSt8ios_basewe@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES4_S4_RSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES4_S4_RSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES4_S4_RSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES4_S4_RSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE10do_unshiftERS0_PDuS3_RS3_ FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE10do_unshiftERS0_PDuS3_RS3_@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE11do_encodingEv FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE13do_max_lengthEv FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE16do_always_noconvEv FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE5do_inERS0_PKDuS4_RS4_PDiS6_RS6_ FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE5do_inERS0_PKDuS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE6do_outERS0_PKDiS4_RS4_PDuS6_RS6_ FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE6do_outERS0_PKDiS4_RS4_PDuS6_RS6_@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE9do_lengthERS0_PKDuS4_j FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE9do_lengthERS0_PKDuS4_j@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7codecvtIDic11__mbstate_tE10do_unshiftERS0_PcS3_RS3_ FUNC:_ZNKSt7codecvtIDic11__mbstate_tE10do_unshiftERS0_PcS3_RS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIDic11__mbstate_tE11do_encodingEv FUNC:_ZNKSt7codecvtIDic11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIDic11__mbstate_tE13do_max_lengthEv FUNC:_ZNKSt7codecvtIDic11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIDic11__mbstate_tE16do_always_noconvEv FUNC:_ZNKSt7codecvtIDic11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIDic11__mbstate_tE5do_inERS0_PKcS4_RS4_PDiS6_RS6_ FUNC:_ZNKSt7codecvtIDic11__mbstate_tE5do_inERS0_PKcS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIDic11__mbstate_tE6do_outERS0_PKDiS4_RS4_PcS6_RS6_ FUNC:_ZNKSt7codecvtIDic11__mbstate_tE6do_outERS0_PKDiS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIDic11__mbstate_tE9do_lengthERS0_PKcS4_j FUNC:_ZNKSt7codecvtIDic11__mbstate_tE9do_lengthERS0_PKcS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE10do_unshiftERS0_PDuS3_RS3_ FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE10do_unshiftERS0_PDuS3_RS3_@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE11do_encodingEv FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE13do_max_lengthEv FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE16do_always_noconvEv FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE5do_inERS0_PKDuS4_RS4_PDsS6_RS6_ FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE5do_inERS0_PKDuS4_RS4_PDsS6_RS6_@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE6do_outERS0_PKDsS4_RS4_PDuS6_RS6_ FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE6do_outERS0_PKDsS4_RS4_PDuS6_RS6_@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE9do_lengthERS0_PKDuS4_j FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE9do_lengthERS0_PKDuS4_j@@GLIBCXX_3.4.26 -FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE10do_unshiftERS0_PcS3_RS3_ FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE10do_unshiftERS0_PcS3_RS3_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE11do_encodingEv FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE13do_max_lengthEv FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE16do_always_noconvEv FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE5do_inERS0_PKcS4_RS4_PDsS6_RS6_ FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE5do_inERS0_PKcS4_RS4_PDsS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE6do_outERS0_PKDsS4_RS4_PcS6_RS6_ FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE6do_outERS0_PKDsS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE9do_lengthERS0_PKcS4_j FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE9do_lengthERS0_PKcS4_j@@GLIBCXX_3.4.21 -FUNC:_ZNKSt7codecvtIcc11__mbstate_tE10do_unshiftERS0_PcS3_RS3_ FUNC:_ZNKSt7codecvtIcc11__mbstate_tE10do_unshiftERS0_PcS3_RS3_@@GLIBCXX_3.4 -FUNC:_ZNKSt7codecvtIcc11__mbstate_tE11do_encodingEv FUNC:_ZNKSt7codecvtIcc11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4 -FUNC:_ZNKSt7codecvtIcc11__mbstate_tE13do_max_lengthEv FUNC:_ZNKSt7codecvtIcc11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4 -FUNC:_ZNKSt7codecvtIcc11__mbstate_tE16do_always_noconvEv FUNC:_ZNKSt7codecvtIcc11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4 -FUNC:_ZNKSt7codecvtIcc11__mbstate_tE5do_inERS0_PKcS4_RS4_PcS6_RS6_ FUNC:_ZNKSt7codecvtIcc11__mbstate_tE5do_inERS0_PKcS4_RS4_PcS6_RS6_@@GLIBCXX_3.4 -FUNC:_ZNKSt7codecvtIcc11__mbstate_tE6do_outERS0_PKcS4_RS4_PcS6_RS6_ FUNC:_ZNKSt7codecvtIcc11__mbstate_tE6do_outERS0_PKcS4_RS4_PcS6_RS6_@@GLIBCXX_3.4 -FUNC:_ZNKSt7codecvtIcc11__mbstate_tE9do_lengthERS0_PKcS4_j FUNC:_ZNKSt7codecvtIcc11__mbstate_tE9do_lengthERS0_PKcS4_j@@GLIBCXX_3.4 -FUNC:_ZNKSt7codecvtIwc11__mbstate_tE10do_unshiftERS0_PcS3_RS3_ FUNC:_ZNKSt7codecvtIwc11__mbstate_tE10do_unshiftERS0_PcS3_RS3_@@GLIBCXX_3.4 -FUNC:_ZNKSt7codecvtIwc11__mbstate_tE11do_encodingEv FUNC:_ZNKSt7codecvtIwc11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4 -FUNC:_ZNKSt7codecvtIwc11__mbstate_tE13do_max_lengthEv FUNC:_ZNKSt7codecvtIwc11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4 -FUNC:_ZNKSt7codecvtIwc11__mbstate_tE16do_always_noconvEv FUNC:_ZNKSt7codecvtIwc11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4 -FUNC:_ZNKSt7codecvtIwc11__mbstate_tE5do_inERS0_PKcS4_RS4_PwS6_RS6_ FUNC:_ZNKSt7codecvtIwc11__mbstate_tE5do_inERS0_PKcS4_RS4_PwS6_RS6_@@GLIBCXX_3.4 -FUNC:_ZNKSt7codecvtIwc11__mbstate_tE6do_outERS0_PKwS4_RS4_PcS6_RS6_ FUNC:_ZNKSt7codecvtIwc11__mbstate_tE6do_outERS0_PKwS4_RS4_PcS6_RS6_@@GLIBCXX_3.4 -FUNC:_ZNKSt7codecvtIwc11__mbstate_tE9do_lengthERS0_PKcS4_j FUNC:_ZNKSt7codecvtIwc11__mbstate_tE9do_lengthERS0_PKcS4_j@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIcE10_M_compareEPKcS2_ FUNC:_ZNKSt7collateIcE10_M_compareEPKcS2_@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIcE10do_compareEPKcS2_S2_S2_ FUNC:_ZNKSt7collateIcE10do_compareEPKcS2_S2_S2_@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIcE12_M_transformEPcPKcj FUNC:_ZNKSt7collateIcE12_M_transformEPcPKcj@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIcE12do_transformEPKcS2_ FUNC:_ZNKSt7collateIcE12do_transformEPKcS2_@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIcE4hashEPKcS2_ FUNC:_ZNKSt7collateIcE4hashEPKcS2_@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIcE7compareEPKcS2_S2_S2_ FUNC:_ZNKSt7collateIcE7compareEPKcS2_S2_S2_@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIcE7do_hashEPKcS2_ FUNC:_ZNKSt7collateIcE7do_hashEPKcS2_@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIcE9transformEPKcS2_ FUNC:_ZNKSt7collateIcE9transformEPKcS2_@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIwE10_M_compareEPKwS2_ FUNC:_ZNKSt7collateIwE10_M_compareEPKwS2_@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIwE10do_compareEPKwS2_S2_S2_ FUNC:_ZNKSt7collateIwE10do_compareEPKwS2_S2_S2_@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIwE12_M_transformEPwPKwj FUNC:_ZNKSt7collateIwE12_M_transformEPwPKwj@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIwE12do_transformEPKwS2_ FUNC:_ZNKSt7collateIwE12do_transformEPKwS2_@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIwE4hashEPKwS2_ FUNC:_ZNKSt7collateIwE4hashEPKwS2_@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIwE7compareEPKwS2_S2_S2_ FUNC:_ZNKSt7collateIwE7compareEPKwS2_S2_S2_@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIwE7do_hashEPKwS2_ FUNC:_ZNKSt7collateIwE7do_hashEPKwS2_@@GLIBCXX_3.4 -FUNC:_ZNKSt7collateIwE9transformEPKwS2_ FUNC:_ZNKSt7collateIwE9transformEPKwS2_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIjEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_ FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIjEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIlEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_ FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIlEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intImEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_ FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intImEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intItEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_ FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intItEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIxEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_ FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIxEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIyEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_ FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIyEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE16_M_extract_floatES3_S3_RSt8ios_baseRSt12_Ios_IostateRSs FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE16_M_extract_floatES3_S3_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRPv FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRPv@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRb FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRb@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRe FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRf FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRf@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRj FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRj@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRl FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRl@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRm FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRm@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRt FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRt@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRx FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRx@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRy FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRy@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRPv FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRPv@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRb FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRb@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRe FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRf FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRf@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRj FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRj@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRl FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRl@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRm FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRm@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRt FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRt@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRx FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRx@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRy FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRy@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIjEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_ FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIjEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIlEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_ FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIlEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intImEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_ FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intImEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intItEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_ FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intItEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIxEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_ FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIxEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIyEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_ FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIyEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16_M_extract_floatES3_S3_RSt8ios_baseRSt12_Ios_IostateRSs FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16_M_extract_floatES3_S3_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRPv FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRPv@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRb FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRb@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRe FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRf FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRf@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRj FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRj@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRl FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRl@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRm FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRm@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRt FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRt@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRx FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRx@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRy FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRy@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRPv FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRPv@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRb FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRb@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRe FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRf FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRf@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRj FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRj@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRl FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRl@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRm FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRm@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRt FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRt@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRx FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRx@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRy FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRy@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE12_M_group_intEPKcjcRSt8ios_basePcS9_Ri FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE12_M_group_intEPKcjcRSt8ios_basePcS9_Ri@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIlEES3_S3_RSt8ios_basecT_ FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIlEES3_S3_RSt8ios_basecT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intImEES3_S3_RSt8ios_basecT_ FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intImEES3_S3_RSt8ios_basecT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIxEES3_S3_RSt8ios_basecT_ FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIxEES3_S3_RSt8ios_basecT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIyEES3_S3_RSt8ios_basecT_ FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIyEES3_S3_RSt8ios_basecT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE14_M_group_floatEPKcjcS6_PcS7_Ri FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE14_M_group_floatEPKcjcS6_PcS7_Ri@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_ FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIeEES3_S3_RSt8ios_baseccT_ FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIeEES3_S3_RSt8ios_baseccT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecPKv FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecPKv@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecb FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecb@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecd FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecd@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basece FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basece@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecl FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecl@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecm FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecm@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecx FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecx@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecy FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecy@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6_M_padEciRSt8ios_basePcPKcRi FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6_M_padEciRSt8ios_basePcPKcRi@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecPKv FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecPKv@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecb FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecb@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basece FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basece@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecl FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecl@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecm FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecm@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecx FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecx@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecy FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecy@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE12_M_group_intEPKcjwRSt8ios_basePwS9_Ri FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE12_M_group_intEPKcjwRSt8ios_basePwS9_Ri@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIlEES3_S3_RSt8ios_basewT_ FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIlEES3_S3_RSt8ios_basewT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intImEES3_S3_RSt8ios_basewT_ FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intImEES3_S3_RSt8ios_basewT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIxEES3_S3_RSt8ios_basewT_ FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIxEES3_S3_RSt8ios_basewT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIyEES3_S3_RSt8ios_basewT_ FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIyEES3_S3_RSt8ios_basewT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE14_M_group_floatEPKcjwPKwPwS9_Ri FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE14_M_group_floatEPKcjwPKwPwS9_Ri@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES3_S3_RSt8ios_basewcT_ FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES3_S3_RSt8ios_basewcT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIeEES3_S3_RSt8ios_basewcT_ FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIeEES3_S3_RSt8ios_basewcT_@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewPKv FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewPKv@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewb FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewb@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewd FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewd@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewe FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewe@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewl FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewl@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewm FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewm@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewx FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewx@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewy FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewy@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6_M_padEwiRSt8ios_basePwPKwRi FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6_M_padEwiRSt8ios_basePwPKwRi@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewPKv FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewPKv@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewb FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewb@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewd FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewd@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewe FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewe@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewl FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewl@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewm FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewm@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewx FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewx@@GLIBCXX_3.4 -FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewy FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewy@@GLIBCXX_3.4 -FUNC:_ZNKSt8__detail20_Prime_rehash_policy11_M_next_bktEj FUNC:_ZNKSt8__detail20_Prime_rehash_policy11_M_next_bktEj@@GLIBCXX_3.4.18 -FUNC:_ZNKSt8__detail20_Prime_rehash_policy14_M_need_rehashEjjj FUNC:_ZNKSt8__detail20_Prime_rehash_policy14_M_need_rehashEjjj@@GLIBCXX_3.4.18 -FUNC:_ZNKSt8bad_cast4whatEv FUNC:_ZNKSt8bad_cast4whatEv@@GLIBCXX_3.4.9 -FUNC:_ZNKSt8ios_base7failure4whatEv FUNC:_ZNKSt8ios_base7failure4whatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8ios_base7failureB5cxx114whatEv FUNC:_ZNKSt8ios_base7failureB5cxx114whatEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt8messagesIcE18_M_convert_to_charERKSs FUNC:_ZNKSt8messagesIcE18_M_convert_to_charERKSs@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIcE20_M_convert_from_charEPc FUNC:_ZNKSt8messagesIcE20_M_convert_from_charEPc@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIcE3getEiiiRKSs FUNC:_ZNKSt8messagesIcE3getEiiiRKSs@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIcE4openERKSsRKSt6locale FUNC:_ZNKSt8messagesIcE4openERKSsRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIcE4openERKSsRKSt6localePKc FUNC:_ZNKSt8messagesIcE4openERKSsRKSt6localePKc@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIcE5closeEi FUNC:_ZNKSt8messagesIcE5closeEi@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIcE6do_getEiiiRKSs FUNC:_ZNKSt8messagesIcE6do_getEiiiRKSs@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIcE7do_openERKSsRKSt6locale FUNC:_ZNKSt8messagesIcE7do_openERKSsRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIcE8do_closeEi FUNC:_ZNKSt8messagesIcE8do_closeEi@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIwE18_M_convert_to_charERKSbIwSt11char_traitsIwESaIwEE FUNC:_ZNKSt8messagesIwE18_M_convert_to_charERKSbIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIwE20_M_convert_from_charEPc FUNC:_ZNKSt8messagesIwE20_M_convert_from_charEPc@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIwE3getEiiiRKSbIwSt11char_traitsIwESaIwEE FUNC:_ZNKSt8messagesIwE3getEiiiRKSbIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIwE4openERKSsRKSt6locale FUNC:_ZNKSt8messagesIwE4openERKSsRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIwE4openERKSsRKSt6localePKc FUNC:_ZNKSt8messagesIwE4openERKSsRKSt6localePKc@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIwE5closeEi FUNC:_ZNKSt8messagesIwE5closeEi@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIwE6do_getEiiiRKSbIwSt11char_traitsIwESaIwEE FUNC:_ZNKSt8messagesIwE6do_getEiiiRKSbIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIwE7do_openERKSsRKSt6locale FUNC:_ZNKSt8messagesIwE7do_openERKSsRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNKSt8messagesIwE8do_closeEi FUNC:_ZNKSt8messagesIwE8do_closeEi@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIcE11do_groupingEv FUNC:_ZNKSt8numpunctIcE11do_groupingEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIcE11do_truenameEv FUNC:_ZNKSt8numpunctIcE11do_truenameEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIcE12do_falsenameEv FUNC:_ZNKSt8numpunctIcE12do_falsenameEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIcE13decimal_pointEv FUNC:_ZNKSt8numpunctIcE13decimal_pointEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIcE13thousands_sepEv FUNC:_ZNKSt8numpunctIcE13thousands_sepEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIcE16do_decimal_pointEv FUNC:_ZNKSt8numpunctIcE16do_decimal_pointEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIcE16do_thousands_sepEv FUNC:_ZNKSt8numpunctIcE16do_thousands_sepEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIcE8groupingEv FUNC:_ZNKSt8numpunctIcE8groupingEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIcE8truenameEv FUNC:_ZNKSt8numpunctIcE8truenameEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIcE9falsenameEv FUNC:_ZNKSt8numpunctIcE9falsenameEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIwE11do_groupingEv FUNC:_ZNKSt8numpunctIwE11do_groupingEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIwE11do_truenameEv FUNC:_ZNKSt8numpunctIwE11do_truenameEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIwE12do_falsenameEv FUNC:_ZNKSt8numpunctIwE12do_falsenameEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIwE13decimal_pointEv FUNC:_ZNKSt8numpunctIwE13decimal_pointEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIwE13thousands_sepEv FUNC:_ZNKSt8numpunctIwE13thousands_sepEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIwE16do_decimal_pointEv FUNC:_ZNKSt8numpunctIwE16do_decimal_pointEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIwE16do_thousands_sepEv FUNC:_ZNKSt8numpunctIwE16do_thousands_sepEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIwE8groupingEv FUNC:_ZNKSt8numpunctIwE8groupingEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIwE8truenameEv FUNC:_ZNKSt8numpunctIwE8truenameEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8numpunctIwE9falsenameEv FUNC:_ZNKSt8numpunctIwE9falsenameEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10date_orderEv FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10date_orderEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_yearES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_yearES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11get_weekdayES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11get_weekdayES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE13do_date_orderEv FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE13do_date_orderEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE13get_monthnameES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE13get_monthnameES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_numES3_S3_RiiijRSt8ios_baseRSt12_Ios_Iostate FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_numES3_S3_RiiijRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14do_get_weekdayES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14do_get_weekdayES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE15_M_extract_nameES3_S3_RiPPKcjRSt8ios_baseRSt12_Ios_Iostate FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE15_M_extract_nameES3_S3_RiPPKcjRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE16do_get_monthnameES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE16do_get_monthnameES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKc FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKc@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKcRSt16__time_get_state FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKcRSt16__time_get_state@@GLIBCXX_3.4.30 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE24_M_extract_wday_or_monthES3_S3_RiPPKcjRSt8ios_baseRSt12_Ios_Iostate FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE24_M_extract_wday_or_monthES3_S3_RiPPKcjRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.14 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKcSC_ FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKcSC_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.26 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_yearES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_yearES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10date_orderEv FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10date_orderEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_yearES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_yearES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11get_weekdayES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11get_weekdayES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE13do_date_orderEv FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE13do_date_orderEv@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE13get_monthnameES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE13get_monthnameES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_numES3_S3_RiiijRSt8ios_baseRSt12_Ios_Iostate FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_numES3_S3_RiiijRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14do_get_weekdayES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14do_get_weekdayES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE15_M_extract_nameES3_S3_RiPPKwjRSt8ios_baseRSt12_Ios_Iostate FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE15_M_extract_nameES3_S3_RiPPKwjRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16do_get_monthnameES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16do_get_monthnameES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKw FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKw@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKwRSt16__time_get_state FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKwRSt16__time_get_state@@GLIBCXX_3.4.30 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE24_M_extract_wday_or_monthES3_S3_RiPPKwjRSt8ios_baseRSt12_Ios_Iostate FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE24_M_extract_wday_or_monthES3_S3_RiPPKwjRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.14 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKwSC_ FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKwSC_@@GLIBCXX_3.4.21 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.26 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_yearES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_yearES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecPK2tmPKcSB_ FUNC:_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecPK2tmPKcSB_@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecPK2tmcc FUNC:_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecPK2tmcc@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecPK2tmcc FUNC:_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecPK2tmcc@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewPK2tmPKwSB_ FUNC:_ZNKSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewPK2tmPKwSB_@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewPK2tmcc FUNC:_ZNKSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewPK2tmcc@@GLIBCXX_3.4 -FUNC:_ZNKSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewPK2tmcc FUNC:_ZNKSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewPK2tmcc@@GLIBCXX_3.4 -FUNC:_ZNKSt8valarrayIjE4sizeEv FUNC:_ZNKSt8valarrayIjE4sizeEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9bad_alloc4whatEv FUNC:_ZNKSt9bad_alloc4whatEv@@GLIBCXX_3.4.9 -FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE10exceptionsEv FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE10exceptionsEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE3badEv FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE3badEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE3eofEv FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE3eofEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE3tieEv FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE3tieEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE4failEv FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE4failEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE4fillEv FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE4fillEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE4goodEv FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE4goodEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE5rdbufEv FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE5rdbufEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE5widenEc FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE5widenEc@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE6narrowEcc FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE6narrowEcc@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE7rdstateEv FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE7rdstateEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEEcvPvEv FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEEcvPvEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEEcvbEv FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEEcvbEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEEntEv FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEEntEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE10exceptionsEv FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE10exceptionsEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE3badEv FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE3badEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE3eofEv FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE3eofEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE3tieEv FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE3tieEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE4failEv FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE4failEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE4fillEv FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE4fillEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE4goodEv FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE4goodEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE5rdbufEv FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE5rdbufEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE5widenEc FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE5widenEc@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE6narrowEwc FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE6narrowEwc@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE7rdstateEv FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE7rdstateEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEEcvPvEv FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEEcvPvEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEEcvbEv FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEEcvbEv@@GLIBCXX_3.4.21 -FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEEntEv FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEEntEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9exception4whatEv FUNC:_ZNKSt9exception4whatEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRSs FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRe FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRSs FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRe FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRSbIwS2_SaIwEE FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRSbIwS2_SaIwEE@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRe FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRSbIwS2_SaIwEE FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRSbIwS2_SaIwEE@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRe FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_bRSt8ios_basecRKSs FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_bRSt8ios_basecRKSs@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_bRSt8ios_basece FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_bRSt8ios_basece@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_bRSt8ios_basecRKSs FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_bRSt8ios_basecRKSs@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_bRSt8ios_basece FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_bRSt8ios_basece@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES3_S3_RSt8ios_basecRKSs FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES3_S3_RSt8ios_basecRKSs@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES3_S3_RSt8ios_basecRKSs FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES3_S3_RSt8ios_basecRKSs@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_bRSt8ios_basewRKSbIwS2_SaIwEE FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_bRSt8ios_basewRKSbIwS2_SaIwEE@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_bRSt8ios_basewe FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_bRSt8ios_basewe@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_bRSt8ios_basewRKSbIwS2_SaIwEE FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_bRSt8ios_basewRKSbIwS2_SaIwEE@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_bRSt8ios_basewe FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_bRSt8ios_basewe@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE@@GLIBCXX_3.4 -FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE@@GLIBCXX_3.4 -FUNC:_ZNKSt9strstream5rdbufEv FUNC:_ZNKSt9strstream5rdbufEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9strstream6pcountEv FUNC:_ZNKSt9strstream6pcountEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9type_info10__do_catchEPKS_PPvj FUNC:_ZNKSt9type_info10__do_catchEPKS_PPvj@@GLIBCXX_3.4 -FUNC:_ZNKSt9type_info11__do_upcastEPKN10__cxxabiv117__class_type_infoEPPv FUNC:_ZNKSt9type_info11__do_upcastEPKN10__cxxabiv117__class_type_infoEPPv@@GLIBCXX_3.4 -FUNC:_ZNKSt9type_info14__is_pointer_pEv FUNC:_ZNKSt9type_info14__is_pointer_pEv@@GLIBCXX_3.4 -FUNC:_ZNKSt9type_info15__is_function_pEv FUNC:_ZNKSt9type_info15__is_function_pEv@@GLIBCXX_3.4 -FUNC:_ZNOSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNOSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNOSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNOSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNOSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNOSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNOSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNOSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNOSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNOSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNOSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNOSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNOSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv FUNC:_ZNOSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNOSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE3strEv FUNC:_ZNOSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.29 -FUNC:_ZNSaIcEC1ERKS_ FUNC:_ZNSaIcEC1ERKS_@@GLIBCXX_3.4 -FUNC:_ZNSaIcEC1Ev FUNC:_ZNSaIcEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSaIcEC2ERKS_ FUNC:_ZNSaIcEC2ERKS_@@GLIBCXX_3.4 -FUNC:_ZNSaIcEC2Ev FUNC:_ZNSaIcEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSaIcED1Ev FUNC:_ZNSaIcED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSaIcED2Ev FUNC:_ZNSaIcED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSaIwEC1ERKS_ FUNC:_ZNSaIwEC1ERKS_@@GLIBCXX_3.4 -FUNC:_ZNSaIwEC1Ev FUNC:_ZNSaIwEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSaIwEC2ERKS_ FUNC:_ZNSaIwEC2ERKS_@@GLIBCXX_3.4 -FUNC:_ZNSaIwEC2Ev FUNC:_ZNSaIwEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSaIwED1Ev FUNC:_ZNSaIwED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSaIwED2Ev FUNC:_ZNSaIwED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE10_S_compareEjj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE10_S_compareEjj@@GLIBCXX_3.4.16 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_Alloc_hiderC1EPwRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_Alloc_hiderC1EPwRKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_Alloc_hiderC2EPwRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_Alloc_hiderC2EPwRKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_M_leak_hardEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_M_leak_hardEv@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructEjwRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructEjwRKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIN9__gnu_cxx17__normal_iteratorIPwS2_EEEES6_T_S8_RKS1_St20forward_iterator_tag FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIN9__gnu_cxx17__normal_iteratorIPwS2_EEEES6_T_S8_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIPKwEEPwT_S7_RKS1_St20forward_iterator_tag FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIPKwEEPwT_S7_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIPwEES4_T_S5_RKS1_St20forward_iterator_tag FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIPwEES4_T_S5_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_empty_repEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_empty_repEv@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12__sv_wrapperC1ESt17basic_string_viewIwS0_E FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12__sv_wrapperC1ESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12__sv_wrapperC2ESt17basic_string_viewIwS0_E FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12__sv_wrapperC2ESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS2_EES8_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS2_EES8_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIS3_S2_EES6_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIS3_S2_EES6_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwPKwS5_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwPKwS5_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS3_S3_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS3_S3_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13shrink_to_fitEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13shrink_to_fitEv@@GLIBCXX_3.4.14 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE14_M_replace_auxEjjjw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE14_M_replace_auxEjjjw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE15_M_replace_safeEjjPKwj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE15_M_replace_safeEjjPKwj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE17_S_to_string_viewESt17basic_string_viewIwS0_E FUNC:_ZNSbIwSt11char_traitsIwESaIwEE17_S_to_string_viewESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE18_S_construct_aux_2EjwRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE18_S_construct_aux_2EjwRKS1_@@GLIBCXX_3.4.14 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE2atEj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE2atEj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE3endEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroyERKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroyERKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_disposeERKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_disposeERKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refcopyEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refcopyEv@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refdataEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refdataEv@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep12_S_empty_repEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep12_S_empty_repEv@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep13_M_set_leakedEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep13_M_set_leakedEv@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep15_M_set_sharableEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep15_M_set_sharableEv@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep26_M_set_length_and_sharableEj@@GLIBCXX_3.4.5 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep26_M_set_length_and_sharableEj@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep7_M_grabERKS1_S5_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep7_M_grabERKS1_S5_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep8_M_cloneERKS1_j FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep8_M_cloneERKS1_j@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep9_S_createEjjRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep9_S_createEjjRKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4backEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.15 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4dataEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4.26 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4rendEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4swapERS2_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4swapERS2_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5beginEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5clearEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5clearEv@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EE FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EE@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5eraseEjj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5eraseEjj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5frontEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5frontEv@@GLIBCXX_3.4.15 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKwj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKwj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2_jj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2_jj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendESt16initializer_listIwE FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendESt16initializer_listIwE@@GLIBCXX_3.4.11 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendEjw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendEjw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEOS2_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEOS2_@@GLIBCXX_3.4.14 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKwj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKwj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_jj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_jj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignESt16initializer_listIwE FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignESt16initializer_listIwE@@GLIBCXX_3.4.11 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEjw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEjw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EESt16initializer_listIwE FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EESt16initializer_listIwE@@GLIBCXX_3.4.11 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EEjw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EEjw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EEw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EEw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEjPKw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEjPKw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEjPKwj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEjPKwj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEjRKS2_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEjRKS2_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEjRKS2_jj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEjRKS2_jj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEjjw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEjjw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6rbeginEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6rbeginEv@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6resizeEj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6resizeEj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6resizeEjw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6resizeEjw@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7_M_copyEPwPKwj@@GLIBCXX_3.4.5 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7_M_copyEPwPKwj@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7_M_dataEPw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7_M_dataEPw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7_M_leakEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7_M_leakEv@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7_M_moveEPwPKwj@@GLIBCXX_3.4.5 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7_M_moveEPwPKwj@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_NS4_IPKwS2_EES9_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_NS4_IPKwS2_EES9_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKwS8_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKwS8_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKwj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKwj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_RKS2_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_RKS2_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_S5_S5_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_S5_S5_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_S6_S6_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_S6_S6_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_St16initializer_listIwE FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_St16initializer_listIwE@@GLIBCXX_3.4.11 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_jw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_jw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjPKw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjPKw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjPKwj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjPKwj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjRKS2_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjRKS2_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjRKS2_jj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjRKS2_jj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjjw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjjw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7reserveEj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7reserveEj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7reserveEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7reserveEv@@GLIBCXX_3.4.29 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE8pop_backEv FUNC:_ZNSbIwSt11char_traitsIwESaIwEE8pop_backEv@@GLIBCXX_3.4.17 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwjw@@GLIBCXX_3.4.5 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwjw@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_mutateEjjj FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_mutateEjjj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9push_backEw FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9push_backEw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ENS2_12__sv_wrapperERKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ENS2_12__sv_wrapperERKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EOS2_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EOS2_@@GLIBCXX_3.4.14 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EOS2_RKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EOS2_RKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EPKwRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EPKwRKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EPKwjRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EPKwjRKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_RKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_RKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_jRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_jRKS1_@@GLIBCXX_3.4.24 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_jj FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_jj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_jjRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_jjRKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ESt16initializer_listIwERKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ESt16initializer_listIwERKS1_@@GLIBCXX_3.4.11 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EjwRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EjwRKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1Ev FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IN9__gnu_cxx17__normal_iteratorIPwS2_EEEET_S8_RKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IN9__gnu_cxx17__normal_iteratorIPwS2_EEEET_S8_RKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IPKwEET_S6_RKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IPKwEET_S6_RKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IPwEET_S5_RKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IPwEET_S5_RKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ENS2_12__sv_wrapperERKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ENS2_12__sv_wrapperERKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EOS2_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EOS2_@@GLIBCXX_3.4.15 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EOS2_RKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EOS2_RKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EPKwRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EPKwRKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EPKwjRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EPKwjRKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_RKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_RKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_jRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_jRKS1_@@GLIBCXX_3.4.24 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_jj FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_jj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_jjRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_jjRKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ESt16initializer_listIwERKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ESt16initializer_listIwERKS1_@@GLIBCXX_3.4.11 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EjwRKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EjwRKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2Ev FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2IN9__gnu_cxx17__normal_iteratorIPwS2_EEEET_S8_RKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2IN9__gnu_cxx17__normal_iteratorIPwS2_EEEET_S8_RKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2IPKwEET_S6_RKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2IPKwEET_S6_RKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2IPwEET_S5_RKS1_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2IPwEET_S5_RKS1_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZNSbIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEED2Ev FUNC:_ZNSbIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSEOS2_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSEOS2_@@GLIBCXX_3.4.14 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSEPKw FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSEPKw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSERKS2_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSERKS2_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSESt16initializer_listIwE FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSESt16initializer_listIwE@@GLIBCXX_3.4.11 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSEw FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSEw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEixEj FUNC:_ZNSbIwSt11char_traitsIwESaIwEEixEj@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEpLEPKw FUNC:_ZNSbIwSt11char_traitsIwESaIwEEpLEPKw@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEpLERKS2_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEpLERKS2_@@GLIBCXX_3.4 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEpLESt16initializer_listIwE FUNC:_ZNSbIwSt11char_traitsIwESaIwEEpLESt16initializer_listIwE@@GLIBCXX_3.4.11 -FUNC:_ZNSbIwSt11char_traitsIwESaIwEEpLEw FUNC:_ZNSbIwSt11char_traitsIwESaIwEEpLEw@@GLIBCXX_3.4 -FUNC:_ZNSd4swapERSd FUNC:_ZNSd4swapERSd@@GLIBCXX_3.4.21 -FUNC:_ZNSdC1EOSd FUNC:_ZNSdC1EOSd@@GLIBCXX_3.4.21 -FUNC:_ZNSdC1EPSt15basic_streambufIcSt11char_traitsIcEE FUNC:_ZNSdC1EPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -FUNC:_ZNSdC1Ev FUNC:_ZNSdC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSdC2EOSd FUNC:_ZNSdC2EOSd@@GLIBCXX_3.4.21 -FUNC:_ZNSdC2EPSt15basic_streambufIcSt11char_traitsIcEE FUNC:_ZNSdC2EPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -FUNC:_ZNSdC2Ev FUNC:_ZNSdC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSdD0Ev FUNC:_ZNSdD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSdD1Ev FUNC:_ZNSdD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSdD2Ev FUNC:_ZNSdD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSdaSEOSd FUNC:_ZNSdaSEOSd@@GLIBCXX_3.4.21 -FUNC:_ZNSi10_M_extractIPvEERSiRT_ FUNC:_ZNSi10_M_extractIPvEERSiRT_@@GLIBCXX_3.4.9 -FUNC:_ZNSi10_M_extractIbEERSiRT_ FUNC:_ZNSi10_M_extractIbEERSiRT_@@GLIBCXX_3.4.9 -FUNC:_ZNSi10_M_extractIdEERSiRT_ FUNC:_ZNSi10_M_extractIdEERSiRT_@@GLIBCXX_3.4.9 -FUNC:_ZNSi10_M_extractIeEERSiRT_ FUNC:_ZNSi10_M_extractIeEERSiRT_@@GLIBCXX_3.4.9 -FUNC:_ZNSi10_M_extractIfEERSiRT_ FUNC:_ZNSi10_M_extractIfEERSiRT_@@GLIBCXX_3.4.9 -FUNC:_ZNSi10_M_extractIjEERSiRT_ FUNC:_ZNSi10_M_extractIjEERSiRT_@@GLIBCXX_3.4.9 -FUNC:_ZNSi10_M_extractIlEERSiRT_ FUNC:_ZNSi10_M_extractIlEERSiRT_@@GLIBCXX_3.4.9 -FUNC:_ZNSi10_M_extractImEERSiRT_ FUNC:_ZNSi10_M_extractImEERSiRT_@@GLIBCXX_3.4.9 -FUNC:_ZNSi10_M_extractItEERSiRT_ FUNC:_ZNSi10_M_extractItEERSiRT_@@GLIBCXX_3.4.9 -FUNC:_ZNSi10_M_extractIxEERSiRT_ FUNC:_ZNSi10_M_extractIxEERSiRT_@@GLIBCXX_3.4.9 -FUNC:_ZNSi10_M_extractIyEERSiRT_ FUNC:_ZNSi10_M_extractIyEERSiRT_@@GLIBCXX_3.4.9 -FUNC:_ZNSi3getEPci FUNC:_ZNSi3getEPci@@GLIBCXX_3.4 -FUNC:_ZNSi3getEPcic FUNC:_ZNSi3getEPcic@@GLIBCXX_3.4 -FUNC:_ZNSi3getERSt15basic_streambufIcSt11char_traitsIcEE FUNC:_ZNSi3getERSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -FUNC:_ZNSi3getERSt15basic_streambufIcSt11char_traitsIcEEc FUNC:_ZNSi3getERSt15basic_streambufIcSt11char_traitsIcEEc@@GLIBCXX_3.4 -FUNC:_ZNSi3getERc FUNC:_ZNSi3getERc@@GLIBCXX_3.4 -FUNC:_ZNSi3getEv FUNC:_ZNSi3getEv@@GLIBCXX_3.4 -FUNC:_ZNSi4peekEv FUNC:_ZNSi4peekEv@@GLIBCXX_3.4 -FUNC:_ZNSi4readEPci FUNC:_ZNSi4readEPci@@GLIBCXX_3.4 -FUNC:_ZNSi4swapERSi FUNC:_ZNSi4swapERSi@@GLIBCXX_3.4.21 -FUNC:_ZNSi4syncEv FUNC:_ZNSi4syncEv@@GLIBCXX_3.4 -FUNC:_ZNSi5seekgESt4fposI11__mbstate_tE FUNC:_ZNSi5seekgESt4fposI11__mbstate_tE@@GLIBCXX_3.4 -FUNC:_ZNSi5seekgExSt12_Ios_Seekdir FUNC:_ZNSi5seekgExSt12_Ios_Seekdir@@GLIBCXX_3.4 -FUNC:_ZNSi5tellgEv FUNC:_ZNSi5tellgEv@@GLIBCXX_3.4 -FUNC:_ZNSi5ungetEv FUNC:_ZNSi5ungetEv@@GLIBCXX_3.4 FUNC:_ZNSi6ignoreEi@@GLIBCXX_3.4.5 FUNC:_ZNSi6ignoreEi@GLIBCXX_3.4 -FUNC:_ZNSi6ignoreEii FUNC:_ZNSi6ignoreEii@@GLIBCXX_3.4 FUNC:_ZNSi6ignoreEv@@GLIBCXX_3.4.5 FUNC:_ZNSi6ignoreEv@GLIBCXX_3.4 -FUNC:_ZNSi6sentryC1ERSib FUNC:_ZNSi6sentryC1ERSib@@GLIBCXX_3.4 -FUNC:_ZNSi6sentryC2ERSib FUNC:_ZNSi6sentryC2ERSib@@GLIBCXX_3.4 -FUNC:_ZNSi7getlineEPci FUNC:_ZNSi7getlineEPci@@GLIBCXX_3.4 -FUNC:_ZNSi7getlineEPcic FUNC:_ZNSi7getlineEPcic@@GLIBCXX_3.4 -FUNC:_ZNSi7putbackEc FUNC:_ZNSi7putbackEc@@GLIBCXX_3.4 -FUNC:_ZNSi8readsomeEPci FUNC:_ZNSi8readsomeEPci@@GLIBCXX_3.4 -FUNC:_ZNSiC1EOSi FUNC:_ZNSiC1EOSi@@GLIBCXX_3.4.21 -FUNC:_ZNSiC1EPSt15basic_streambufIcSt11char_traitsIcEE FUNC:_ZNSiC1EPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -FUNC:_ZNSiC1Ev FUNC:_ZNSiC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSiC2EOSi FUNC:_ZNSiC2EOSi@@GLIBCXX_3.4.21 -FUNC:_ZNSiC2EPSt15basic_streambufIcSt11char_traitsIcEE FUNC:_ZNSiC2EPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -FUNC:_ZNSiC2Ev FUNC:_ZNSiC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSiD0Ev FUNC:_ZNSiD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSiD1Ev FUNC:_ZNSiD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSiD2Ev FUNC:_ZNSiD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSiaSEOSi FUNC:_ZNSiaSEOSi@@GLIBCXX_3.4.21 -FUNC:_ZNSirsEPFRSiS_E FUNC:_ZNSirsEPFRSiS_E@@GLIBCXX_3.4 -FUNC:_ZNSirsEPFRSt8ios_baseS0_E FUNC:_ZNSirsEPFRSt8ios_baseS0_E@@GLIBCXX_3.4 -FUNC:_ZNSirsEPFRSt9basic_iosIcSt11char_traitsIcEES3_E FUNC:_ZNSirsEPFRSt9basic_iosIcSt11char_traitsIcEES3_E@@GLIBCXX_3.4 -FUNC:_ZNSirsEPSt15basic_streambufIcSt11char_traitsIcEE FUNC:_ZNSirsEPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -FUNC:_ZNSirsERPv FUNC:_ZNSirsERPv@@GLIBCXX_3.4 -FUNC:_ZNSirsERb FUNC:_ZNSirsERb@@GLIBCXX_3.4 -FUNC:_ZNSirsERd FUNC:_ZNSirsERd@@GLIBCXX_3.4 -FUNC:_ZNSirsERe FUNC:_ZNSirsERe@@GLIBCXX_3.4 -FUNC:_ZNSirsERf FUNC:_ZNSirsERf@@GLIBCXX_3.4 -FUNC:_ZNSirsERi FUNC:_ZNSirsERi@@GLIBCXX_3.4 -FUNC:_ZNSirsERj FUNC:_ZNSirsERj@@GLIBCXX_3.4 -FUNC:_ZNSirsERl FUNC:_ZNSirsERl@@GLIBCXX_3.4 -FUNC:_ZNSirsERm FUNC:_ZNSirsERm@@GLIBCXX_3.4 -FUNC:_ZNSirsERs FUNC:_ZNSirsERs@@GLIBCXX_3.4 -FUNC:_ZNSirsERt FUNC:_ZNSirsERt@@GLIBCXX_3.4 -FUNC:_ZNSirsERx FUNC:_ZNSirsERx@@GLIBCXX_3.4 -FUNC:_ZNSirsERy FUNC:_ZNSirsERy@@GLIBCXX_3.4 -FUNC:_ZNSo3putEc FUNC:_ZNSo3putEc@@GLIBCXX_3.4 -FUNC:_ZNSo4swapERSo FUNC:_ZNSo4swapERSo@@GLIBCXX_3.4.21 -FUNC:_ZNSo5flushEv FUNC:_ZNSo5flushEv@@GLIBCXX_3.4 -FUNC:_ZNSo5seekpESt4fposI11__mbstate_tE FUNC:_ZNSo5seekpESt4fposI11__mbstate_tE@@GLIBCXX_3.4 -FUNC:_ZNSo5seekpExSt12_Ios_Seekdir FUNC:_ZNSo5seekpExSt12_Ios_Seekdir@@GLIBCXX_3.4 -FUNC:_ZNSo5tellpEv FUNC:_ZNSo5tellpEv@@GLIBCXX_3.4 -FUNC:_ZNSo5writeEPKci FUNC:_ZNSo5writeEPKci@@GLIBCXX_3.4 -FUNC:_ZNSo6sentryC1ERSo FUNC:_ZNSo6sentryC1ERSo@@GLIBCXX_3.4 -FUNC:_ZNSo6sentryC2ERSo FUNC:_ZNSo6sentryC2ERSo@@GLIBCXX_3.4 -FUNC:_ZNSo6sentryD1Ev FUNC:_ZNSo6sentryD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSo6sentryD2Ev FUNC:_ZNSo6sentryD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSo8_M_writeEPKci FUNC:_ZNSo8_M_writeEPKci@@GLIBCXX_3.4 -FUNC:_ZNSo9_M_insertIPKvEERSoT_ FUNC:_ZNSo9_M_insertIPKvEERSoT_@@GLIBCXX_3.4.9 -FUNC:_ZNSo9_M_insertIbEERSoT_ FUNC:_ZNSo9_M_insertIbEERSoT_@@GLIBCXX_3.4.9 -FUNC:_ZNSo9_M_insertIdEERSoT_ FUNC:_ZNSo9_M_insertIdEERSoT_@@GLIBCXX_3.4.9 -FUNC:_ZNSo9_M_insertIeEERSoT_ FUNC:_ZNSo9_M_insertIeEERSoT_@@GLIBCXX_3.4.9 -FUNC:_ZNSo9_M_insertIlEERSoT_ FUNC:_ZNSo9_M_insertIlEERSoT_@@GLIBCXX_3.4.9 -FUNC:_ZNSo9_M_insertImEERSoT_ FUNC:_ZNSo9_M_insertImEERSoT_@@GLIBCXX_3.4.9 -FUNC:_ZNSo9_M_insertIxEERSoT_ FUNC:_ZNSo9_M_insertIxEERSoT_@@GLIBCXX_3.4.9 -FUNC:_ZNSo9_M_insertIyEERSoT_ FUNC:_ZNSo9_M_insertIyEERSoT_@@GLIBCXX_3.4.9 -FUNC:_ZNSoC1EOSo FUNC:_ZNSoC1EOSo@@GLIBCXX_3.4.21 -FUNC:_ZNSoC1EPSt15basic_streambufIcSt11char_traitsIcEE FUNC:_ZNSoC1EPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -FUNC:_ZNSoC1ERSd FUNC:_ZNSoC1ERSd@@GLIBCXX_3.4.21 -FUNC:_ZNSoC1Ev FUNC:_ZNSoC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSoC2EOSo FUNC:_ZNSoC2EOSo@@GLIBCXX_3.4.21 -FUNC:_ZNSoC2EPSt15basic_streambufIcSt11char_traitsIcEE FUNC:_ZNSoC2EPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -FUNC:_ZNSoC2ERSd FUNC:_ZNSoC2ERSd@@GLIBCXX_3.4.21 -FUNC:_ZNSoC2Ev FUNC:_ZNSoC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSoD0Ev FUNC:_ZNSoD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSoD1Ev FUNC:_ZNSoD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSoD2Ev FUNC:_ZNSoD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSoaSEOSo FUNC:_ZNSoaSEOSo@@GLIBCXX_3.4.21 -FUNC:_ZNSolsEDn FUNC:_ZNSolsEDn@@GLIBCXX_3.4.26 -FUNC:_ZNSolsEPFRSoS_E FUNC:_ZNSolsEPFRSoS_E@@GLIBCXX_3.4 -FUNC:_ZNSolsEPFRSt8ios_baseS0_E FUNC:_ZNSolsEPFRSt8ios_baseS0_E@@GLIBCXX_3.4 -FUNC:_ZNSolsEPFRSt9basic_iosIcSt11char_traitsIcEES3_E FUNC:_ZNSolsEPFRSt9basic_iosIcSt11char_traitsIcEES3_E@@GLIBCXX_3.4 -FUNC:_ZNSolsEPKv FUNC:_ZNSolsEPKv@@GLIBCXX_3.4 -FUNC:_ZNSolsEPSt15basic_streambufIcSt11char_traitsIcEE FUNC:_ZNSolsEPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -FUNC:_ZNSolsEb FUNC:_ZNSolsEb@@GLIBCXX_3.4 -FUNC:_ZNSolsEd FUNC:_ZNSolsEd@@GLIBCXX_3.4 -FUNC:_ZNSolsEe FUNC:_ZNSolsEe@@GLIBCXX_3.4 -FUNC:_ZNSolsEf FUNC:_ZNSolsEf@@GLIBCXX_3.4 -FUNC:_ZNSolsEi FUNC:_ZNSolsEi@@GLIBCXX_3.4 -FUNC:_ZNSolsEj FUNC:_ZNSolsEj@@GLIBCXX_3.4 -FUNC:_ZNSolsEl FUNC:_ZNSolsEl@@GLIBCXX_3.4 -FUNC:_ZNSolsEm FUNC:_ZNSolsEm@@GLIBCXX_3.4 -FUNC:_ZNSolsEs FUNC:_ZNSolsEs@@GLIBCXX_3.4 -FUNC:_ZNSolsEt FUNC:_ZNSolsEt@@GLIBCXX_3.4 -FUNC:_ZNSolsEx FUNC:_ZNSolsEx@@GLIBCXX_3.4 -FUNC:_ZNSolsEy FUNC:_ZNSolsEy@@GLIBCXX_3.4 -FUNC:_ZNSs10_S_compareEjj FUNC:_ZNSs10_S_compareEjj@@GLIBCXX_3.4.16 -FUNC:_ZNSs12_Alloc_hiderC1EPcRKSaIcE FUNC:_ZNSs12_Alloc_hiderC1EPcRKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSs12_Alloc_hiderC2EPcRKSaIcE FUNC:_ZNSs12_Alloc_hiderC2EPcRKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSs12_M_leak_hardEv FUNC:_ZNSs12_M_leak_hardEv@@GLIBCXX_3.4 -FUNC:_ZNSs12_S_constructEjcRKSaIcE FUNC:_ZNSs12_S_constructEjcRKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSs12_S_constructIN9__gnu_cxx17__normal_iteratorIPcSsEEEES2_T_S4_RKSaIcESt20forward_iterator_tag FUNC:_ZNSs12_S_constructIN9__gnu_cxx17__normal_iteratorIPcSsEEEES2_T_S4_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14 -FUNC:_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag FUNC:_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14 -FUNC:_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tag FUNC:_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14 -FUNC:_ZNSs12_S_empty_repEv FUNC:_ZNSs12_S_empty_repEv@@GLIBCXX_3.4 -FUNC:_ZNSs12__sv_wrapperC1ESt17basic_string_viewIcSt11char_traitsIcEE FUNC:_ZNSs12__sv_wrapperC1ESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 -FUNC:_ZNSs12__sv_wrapperC2ESt17basic_string_viewIcSt11char_traitsIcEE FUNC:_ZNSs12__sv_wrapperC2ESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 -FUNC:_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcSsEES4_ FUNC:_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcSsEES4_@@GLIBCXX_3.4 -FUNC:_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS_SsEES2_ FUNC:_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS_SsEES2_@@GLIBCXX_3.4 -FUNC:_ZNSs13_S_copy_charsEPcPKcS1_ FUNC:_ZNSs13_S_copy_charsEPcPKcS1_@@GLIBCXX_3.4 -FUNC:_ZNSs13_S_copy_charsEPcS_S_ FUNC:_ZNSs13_S_copy_charsEPcS_S_@@GLIBCXX_3.4 -FUNC:_ZNSs13shrink_to_fitEv FUNC:_ZNSs13shrink_to_fitEv@@GLIBCXX_3.4.14 -FUNC:_ZNSs14_M_replace_auxEjjjc FUNC:_ZNSs14_M_replace_auxEjjjc@@GLIBCXX_3.4 -FUNC:_ZNSs15_M_replace_safeEjjPKcj FUNC:_ZNSs15_M_replace_safeEjjPKcj@@GLIBCXX_3.4 -FUNC:_ZNSs17_S_to_string_viewESt17basic_string_viewIcSt11char_traitsIcEE FUNC:_ZNSs17_S_to_string_viewESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 -FUNC:_ZNSs18_S_construct_aux_2EjcRKSaIcE FUNC:_ZNSs18_S_construct_aux_2EjcRKSaIcE@@GLIBCXX_3.4.14 -FUNC:_ZNSs2atEj FUNC:_ZNSs2atEj@@GLIBCXX_3.4 -FUNC:_ZNSs3endEv FUNC:_ZNSs3endEv@@GLIBCXX_3.4 -FUNC:_ZNSs4_Rep10_M_destroyERKSaIcE FUNC:_ZNSs4_Rep10_M_destroyERKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSs4_Rep10_M_disposeERKSaIcE FUNC:_ZNSs4_Rep10_M_disposeERKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSs4_Rep10_M_refcopyEv FUNC:_ZNSs4_Rep10_M_refcopyEv@@GLIBCXX_3.4 -FUNC:_ZNSs4_Rep10_M_refdataEv FUNC:_ZNSs4_Rep10_M_refdataEv@@GLIBCXX_3.4 -FUNC:_ZNSs4_Rep12_S_empty_repEv FUNC:_ZNSs4_Rep12_S_empty_repEv@@GLIBCXX_3.4 -FUNC:_ZNSs4_Rep13_M_set_leakedEv FUNC:_ZNSs4_Rep13_M_set_leakedEv@@GLIBCXX_3.4 -FUNC:_ZNSs4_Rep15_M_set_sharableEv FUNC:_ZNSs4_Rep15_M_set_sharableEv@@GLIBCXX_3.4 FUNC:_ZNSs4_Rep26_M_set_length_and_sharableEj@@GLIBCXX_3.4.5 FUNC:_ZNSs4_Rep26_M_set_length_and_sharableEj@GLIBCXX_3.4 -FUNC:_ZNSs4_Rep7_M_grabERKSaIcES2_ FUNC:_ZNSs4_Rep7_M_grabERKSaIcES2_@@GLIBCXX_3.4 -FUNC:_ZNSs4_Rep8_M_cloneERKSaIcEj FUNC:_ZNSs4_Rep8_M_cloneERKSaIcEj@@GLIBCXX_3.4 -FUNC:_ZNSs4_Rep9_S_createEjjRKSaIcE FUNC:_ZNSs4_Rep9_S_createEjjRKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSs4backEv FUNC:_ZNSs4backEv@@GLIBCXX_3.4.15 -FUNC:_ZNSs4dataEv FUNC:_ZNSs4dataEv@@GLIBCXX_3.4.26 -FUNC:_ZNSs4rendEv FUNC:_ZNSs4rendEv@@GLIBCXX_3.4 -FUNC:_ZNSs4swapERSs FUNC:_ZNSs4swapERSs@@GLIBCXX_3.4 -FUNC:_ZNSs5beginEv FUNC:_ZNSs5beginEv@@GLIBCXX_3.4 -FUNC:_ZNSs5clearEv FUNC:_ZNSs5clearEv@@GLIBCXX_3.4 -FUNC:_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEE FUNC:_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEE@@GLIBCXX_3.4 -FUNC:_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEES2_ FUNC:_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEES2_@@GLIBCXX_3.4 -FUNC:_ZNSs5eraseEjj FUNC:_ZNSs5eraseEjj@@GLIBCXX_3.4 -FUNC:_ZNSs5frontEv FUNC:_ZNSs5frontEv@@GLIBCXX_3.4.15 -FUNC:_ZNSs6appendEPKc FUNC:_ZNSs6appendEPKc@@GLIBCXX_3.4 -FUNC:_ZNSs6appendEPKcj FUNC:_ZNSs6appendEPKcj@@GLIBCXX_3.4 -FUNC:_ZNSs6appendERKSs FUNC:_ZNSs6appendERKSs@@GLIBCXX_3.4 -FUNC:_ZNSs6appendERKSsjj FUNC:_ZNSs6appendERKSsjj@@GLIBCXX_3.4 -FUNC:_ZNSs6appendESt16initializer_listIcE FUNC:_ZNSs6appendESt16initializer_listIcE@@GLIBCXX_3.4.11 -FUNC:_ZNSs6appendEjc FUNC:_ZNSs6appendEjc@@GLIBCXX_3.4 -FUNC:_ZNSs6assignEOSs FUNC:_ZNSs6assignEOSs@@GLIBCXX_3.4.14 -FUNC:_ZNSs6assignEPKc FUNC:_ZNSs6assignEPKc@@GLIBCXX_3.4 -FUNC:_ZNSs6assignEPKcj FUNC:_ZNSs6assignEPKcj@@GLIBCXX_3.4 -FUNC:_ZNSs6assignERKSs FUNC:_ZNSs6assignERKSs@@GLIBCXX_3.4 -FUNC:_ZNSs6assignERKSsjj FUNC:_ZNSs6assignERKSsjj@@GLIBCXX_3.4 -FUNC:_ZNSs6assignESt16initializer_listIcE FUNC:_ZNSs6assignESt16initializer_listIcE@@GLIBCXX_3.4.11 -FUNC:_ZNSs6assignEjc FUNC:_ZNSs6assignEjc@@GLIBCXX_3.4 -FUNC:_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEESt16initializer_listIcE FUNC:_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEESt16initializer_listIcE@@GLIBCXX_3.4.11 -FUNC:_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEc FUNC:_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEc@@GLIBCXX_3.4 -FUNC:_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEjc FUNC:_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEjc@@GLIBCXX_3.4 -FUNC:_ZNSs6insertEjPKc FUNC:_ZNSs6insertEjPKc@@GLIBCXX_3.4 -FUNC:_ZNSs6insertEjPKcj FUNC:_ZNSs6insertEjPKcj@@GLIBCXX_3.4 -FUNC:_ZNSs6insertEjRKSs FUNC:_ZNSs6insertEjRKSs@@GLIBCXX_3.4 -FUNC:_ZNSs6insertEjRKSsjj FUNC:_ZNSs6insertEjRKSsjj@@GLIBCXX_3.4 -FUNC:_ZNSs6insertEjjc FUNC:_ZNSs6insertEjjc@@GLIBCXX_3.4 -FUNC:_ZNSs6rbeginEv FUNC:_ZNSs6rbeginEv@@GLIBCXX_3.4 -FUNC:_ZNSs6resizeEj FUNC:_ZNSs6resizeEj@@GLIBCXX_3.4 -FUNC:_ZNSs6resizeEjc FUNC:_ZNSs6resizeEjc@@GLIBCXX_3.4 FUNC:_ZNSs7_M_copyEPcPKcj@@GLIBCXX_3.4.5 FUNC:_ZNSs7_M_copyEPcPKcj@GLIBCXX_3.4 -FUNC:_ZNSs7_M_dataEPc FUNC:_ZNSs7_M_dataEPc@@GLIBCXX_3.4 -FUNC:_ZNSs7_M_leakEv FUNC:_ZNSs7_M_leakEv@@GLIBCXX_3.4 FUNC:_ZNSs7_M_moveEPcPKcj@@GLIBCXX_3.4.5 FUNC:_ZNSs7_M_moveEPcPKcj@GLIBCXX_3.4 -FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_NS0_IPKcSsEES5_ FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_NS0_IPKcSsEES5_@@GLIBCXX_3.4 -FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKc FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKc@@GLIBCXX_3.4 -FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcS4_ FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcS4_@@GLIBCXX_3.4 -FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcj FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcj@@GLIBCXX_3.4 -FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_RKSs FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_RKSs@@GLIBCXX_3.4 -FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S1_S1_ FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S1_S1_@@GLIBCXX_3.4 -FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S2_S2_ FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S2_S2_@@GLIBCXX_3.4 -FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_St16initializer_listIcE FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_St16initializer_listIcE@@GLIBCXX_3.4.11 -FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_jc FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_jc@@GLIBCXX_3.4 -FUNC:_ZNSs7replaceEjjPKc FUNC:_ZNSs7replaceEjjPKc@@GLIBCXX_3.4 -FUNC:_ZNSs7replaceEjjPKcj FUNC:_ZNSs7replaceEjjPKcj@@GLIBCXX_3.4 -FUNC:_ZNSs7replaceEjjRKSs FUNC:_ZNSs7replaceEjjRKSs@@GLIBCXX_3.4 -FUNC:_ZNSs7replaceEjjRKSsjj FUNC:_ZNSs7replaceEjjRKSsjj@@GLIBCXX_3.4 -FUNC:_ZNSs7replaceEjjjc FUNC:_ZNSs7replaceEjjjc@@GLIBCXX_3.4 -FUNC:_ZNSs7reserveEj FUNC:_ZNSs7reserveEj@@GLIBCXX_3.4 -FUNC:_ZNSs7reserveEv FUNC:_ZNSs7reserveEv@@GLIBCXX_3.4.29 -FUNC:_ZNSs8pop_backEv FUNC:_ZNSs8pop_backEv@@GLIBCXX_3.4.17 FUNC:_ZNSs9_M_assignEPcjc@@GLIBCXX_3.4.5 FUNC:_ZNSs9_M_assignEPcjc@GLIBCXX_3.4 -FUNC:_ZNSs9_M_mutateEjjj FUNC:_ZNSs9_M_mutateEjjj@@GLIBCXX_3.4 -FUNC:_ZNSs9push_backEc FUNC:_ZNSs9push_backEc@@GLIBCXX_3.4 -FUNC:_ZNSsC1ENSs12__sv_wrapperERKSaIcE FUNC:_ZNSsC1ENSs12__sv_wrapperERKSaIcE@@GLIBCXX_3.4.26 -FUNC:_ZNSsC1EOSs FUNC:_ZNSsC1EOSs@@GLIBCXX_3.4.14 -FUNC:_ZNSsC1EOSsRKSaIcE FUNC:_ZNSsC1EOSsRKSaIcE@@GLIBCXX_3.4.26 -FUNC:_ZNSsC1EPKcRKSaIcE FUNC:_ZNSsC1EPKcRKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC1EPKcjRKSaIcE FUNC:_ZNSsC1EPKcjRKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC1ERKSaIcE FUNC:_ZNSsC1ERKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC1ERKSs FUNC:_ZNSsC1ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSsC1ERKSsRKSaIcE FUNC:_ZNSsC1ERKSsRKSaIcE@@GLIBCXX_3.4.26 -FUNC:_ZNSsC1ERKSsjRKSaIcE FUNC:_ZNSsC1ERKSsjRKSaIcE@@GLIBCXX_3.4.23 -FUNC:_ZNSsC1ERKSsjj FUNC:_ZNSsC1ERKSsjj@@GLIBCXX_3.4 -FUNC:_ZNSsC1ERKSsjjRKSaIcE FUNC:_ZNSsC1ERKSsjjRKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC1ESt16initializer_listIcERKSaIcE FUNC:_ZNSsC1ESt16initializer_listIcERKSaIcE@@GLIBCXX_3.4.11 -FUNC:_ZNSsC1EjcRKSaIcE FUNC:_ZNSsC1EjcRKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC1Ev FUNC:_ZNSsC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSsC1IN9__gnu_cxx17__normal_iteratorIPcSsEEEET_S4_RKSaIcE FUNC:_ZNSsC1IN9__gnu_cxx17__normal_iteratorIPcSsEEEET_S4_RKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC1IPKcEET_S2_RKSaIcE FUNC:_ZNSsC1IPKcEET_S2_RKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC1IPcEET_S1_RKSaIcE FUNC:_ZNSsC1IPcEET_S1_RKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC2ENSs12__sv_wrapperERKSaIcE FUNC:_ZNSsC2ENSs12__sv_wrapperERKSaIcE@@GLIBCXX_3.4.26 -FUNC:_ZNSsC2EOSs FUNC:_ZNSsC2EOSs@@GLIBCXX_3.4.15 -FUNC:_ZNSsC2EOSsRKSaIcE FUNC:_ZNSsC2EOSsRKSaIcE@@GLIBCXX_3.4.26 -FUNC:_ZNSsC2EPKcRKSaIcE FUNC:_ZNSsC2EPKcRKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC2EPKcjRKSaIcE FUNC:_ZNSsC2EPKcjRKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC2ERKSaIcE FUNC:_ZNSsC2ERKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC2ERKSs FUNC:_ZNSsC2ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSsC2ERKSsRKSaIcE FUNC:_ZNSsC2ERKSsRKSaIcE@@GLIBCXX_3.4.26 -FUNC:_ZNSsC2ERKSsjRKSaIcE FUNC:_ZNSsC2ERKSsjRKSaIcE@@GLIBCXX_3.4.23 -FUNC:_ZNSsC2ERKSsjj FUNC:_ZNSsC2ERKSsjj@@GLIBCXX_3.4 -FUNC:_ZNSsC2ERKSsjjRKSaIcE FUNC:_ZNSsC2ERKSsjjRKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC2ESt16initializer_listIcERKSaIcE FUNC:_ZNSsC2ESt16initializer_listIcERKSaIcE@@GLIBCXX_3.4.11 -FUNC:_ZNSsC2EjcRKSaIcE FUNC:_ZNSsC2EjcRKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC2Ev FUNC:_ZNSsC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSsC2IN9__gnu_cxx17__normal_iteratorIPcSsEEEET_S4_RKSaIcE FUNC:_ZNSsC2IN9__gnu_cxx17__normal_iteratorIPcSsEEEET_S4_RKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC2IPKcEET_S2_RKSaIcE FUNC:_ZNSsC2IPKcEET_S2_RKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsC2IPcEET_S1_RKSaIcE FUNC:_ZNSsC2IPcEET_S1_RKSaIcE@@GLIBCXX_3.4 -FUNC:_ZNSsD1Ev FUNC:_ZNSsD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSsD2Ev FUNC:_ZNSsD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSsaSEOSs FUNC:_ZNSsaSEOSs@@GLIBCXX_3.4.14 -FUNC:_ZNSsaSEPKc FUNC:_ZNSsaSEPKc@@GLIBCXX_3.4 -FUNC:_ZNSsaSERKSs FUNC:_ZNSsaSERKSs@@GLIBCXX_3.4 -FUNC:_ZNSsaSESt16initializer_listIcE FUNC:_ZNSsaSESt16initializer_listIcE@@GLIBCXX_3.4.11 -FUNC:_ZNSsaSEc FUNC:_ZNSsaSEc@@GLIBCXX_3.4 -FUNC:_ZNSsixEj FUNC:_ZNSsixEj@@GLIBCXX_3.4 -FUNC:_ZNSspLEPKc FUNC:_ZNSspLEPKc@@GLIBCXX_3.4 -FUNC:_ZNSspLERKSs FUNC:_ZNSspLERKSs@@GLIBCXX_3.4 -FUNC:_ZNSspLESt16initializer_listIcE FUNC:_ZNSspLESt16initializer_listIcE@@GLIBCXX_3.4.11 -FUNC:_ZNSspLEc FUNC:_ZNSspLEc@@GLIBCXX_3.4 -FUNC:_ZNSt10_Sp_lockerC1EPKv FUNC:_ZNSt10_Sp_lockerC1EPKv@@GLIBCXX_3.4.21 -FUNC:_ZNSt10_Sp_lockerC1EPKvS1_ FUNC:_ZNSt10_Sp_lockerC1EPKvS1_@@GLIBCXX_3.4.21 -FUNC:_ZNSt10_Sp_lockerC2EPKv FUNC:_ZNSt10_Sp_lockerC2EPKv@@GLIBCXX_3.4.21 -FUNC:_ZNSt10_Sp_lockerC2EPKvS1_ FUNC:_ZNSt10_Sp_lockerC2EPKvS1_@@GLIBCXX_3.4.21 -FUNC:_ZNSt10_Sp_lockerD1Ev FUNC:_ZNSt10_Sp_lockerD1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt10_Sp_lockerD2Ev FUNC:_ZNSt10_Sp_lockerD2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt10__num_base15_S_format_floatERKSt8ios_basePcc FUNC:_ZNSt10__num_base15_S_format_floatERKSt8ios_basePcc@@GLIBCXX_3.4 -FUNC:_ZNSt10bad_typeidD0Ev FUNC:_ZNSt10bad_typeidD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10bad_typeidD1Ev FUNC:_ZNSt10bad_typeidD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10bad_typeidD2Ev FUNC:_ZNSt10bad_typeidD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10filesystem10equivalentERKNS_4pathES2_ FUNC:_ZNSt10filesystem10equivalentERKNS_4pathES2_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem10equivalentERKNS_4pathES2_RSt10error_code FUNC:_ZNSt10filesystem10equivalentERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem10equivalentERKNS_7__cxx114pathES3_ FUNC:_ZNSt10filesystem10equivalentERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem10equivalentERKNS_7__cxx114pathES3_RSt10error_code FUNC:_ZNSt10filesystem10equivalentERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem10hash_valueERKNS_4pathE FUNC:_ZNSt10filesystem10hash_valueERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem10remove_allERKNS_4pathE FUNC:_ZNSt10filesystem10remove_allERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem10remove_allERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem10remove_allERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem10remove_allERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem10remove_allERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem10remove_allERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem10remove_allERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem11permissionsERKNS_4pathENS_5permsENS_12perm_optionsE FUNC:_ZNSt10filesystem11permissionsERKNS_4pathENS_5permsENS_12perm_optionsE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem11permissionsERKNS_4pathENS_5permsENS_12perm_optionsERSt10error_code FUNC:_ZNSt10filesystem11permissionsERKNS_4pathENS_5permsENS_12perm_optionsERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem11permissionsERKNS_7__cxx114pathENS_5permsENS_12perm_optionsE FUNC:_ZNSt10filesystem11permissionsERKNS_7__cxx114pathENS_5permsENS_12perm_optionsE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem11permissionsERKNS_7__cxx114pathENS_5permsENS_12perm_optionsERSt10error_code FUNC:_ZNSt10filesystem11permissionsERKNS_7__cxx114pathENS_5permsENS_12perm_optionsERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem11resize_fileERKNS_4pathEy FUNC:_ZNSt10filesystem11resize_fileERKNS_4pathEy@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem11resize_fileERKNS_4pathEyRSt10error_code FUNC:_ZNSt10filesystem11resize_fileERKNS_4pathEyRSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem11resize_fileERKNS_7__cxx114pathEy FUNC:_ZNSt10filesystem11resize_fileERKNS_7__cxx114pathEy@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem11resize_fileERKNS_7__cxx114pathEyRSt10error_code FUNC:_ZNSt10filesystem11resize_fileERKNS_7__cxx114pathEyRSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12copy_symlinkERKNS_4pathES2_ FUNC:_ZNSt10filesystem12copy_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12copy_symlinkERKNS_4pathES2_RSt10error_code FUNC:_ZNSt10filesystem12copy_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12copy_symlinkERKNS_7__cxx114pathES3_ FUNC:_ZNSt10filesystem12copy_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12copy_symlinkERKNS_7__cxx114pathES3_RSt10error_code FUNC:_ZNSt10filesystem12copy_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12current_pathB5cxx11ERSt10error_code FUNC:_ZNSt10filesystem12current_pathB5cxx11ERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12current_pathB5cxx11Ev FUNC:_ZNSt10filesystem12current_pathB5cxx11Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12current_pathERKNS_4pathE FUNC:_ZNSt10filesystem12current_pathERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12current_pathERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem12current_pathERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12current_pathERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem12current_pathERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12current_pathERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem12current_pathERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12current_pathERSt10error_code FUNC:_ZNSt10filesystem12current_pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12current_pathEv FUNC:_ZNSt10filesystem12current_pathEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12read_symlinkERKNS_4pathE FUNC:_ZNSt10filesystem12read_symlinkERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12read_symlinkERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem12read_symlinkERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12read_symlinkERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem12read_symlinkERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem12read_symlinkERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem12read_symlinkERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem14create_symlinkERKNS_4pathES2_ FUNC:_ZNSt10filesystem14create_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem14create_symlinkERKNS_4pathES2_RSt10error_code FUNC:_ZNSt10filesystem14create_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem14create_symlinkERKNS_7__cxx114pathES3_ FUNC:_ZNSt10filesystem14create_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem14create_symlinkERKNS_7__cxx114pathES3_RSt10error_code FUNC:_ZNSt10filesystem14create_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem14symlink_statusERKNS_4pathE FUNC:_ZNSt10filesystem14symlink_statusERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem14symlink_statusERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem14symlink_statusERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem14symlink_statusERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem14symlink_statusERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem14symlink_statusERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem14symlink_statusERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem15hard_link_countERKNS_4pathE FUNC:_ZNSt10filesystem15hard_link_countERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem15hard_link_countERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem15hard_link_countERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem15hard_link_countERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem15hard_link_countERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem15hard_link_countERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem15hard_link_countERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathE FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathENSt6chrono10time_pointINS_12__file_clockENS3_8durationIxSt5ratioILx1ELx1000000000EEEEEE FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathENSt6chrono10time_pointINS_12__file_clockENS3_8durationIxSt5ratioILx1ELx1000000000EEEEEE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathENSt6chrono10time_pointINS_12__file_clockENS3_8durationIxSt5ratioILx1ELx1000000000EEEEEERSt10error_code FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathENSt6chrono10time_pointINS_12__file_clockENS3_8durationIxSt5ratioILx1ELx1000000000EEEEEERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathENSt6chrono10time_pointINS_12__file_clockENS4_8durationIxSt5ratioILx1ELx1000000000EEEEEE FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathENSt6chrono10time_pointINS_12__file_clockENS4_8durationIxSt5ratioILx1ELx1000000000EEEEEE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathENSt6chrono10time_pointINS_12__file_clockENS4_8durationIxSt5ratioILx1ELx1000000000EEEEEERSt10error_code FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathENSt6chrono10time_pointINS_12__file_clockENS4_8durationIxSt5ratioILx1ELx1000000000EEEEEERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathE FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathES2_ FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathES2_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathES2_RSt10error_code FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathES3_ FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathES3_RSt10error_code FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16create_hard_linkERKNS_4pathES2_ FUNC:_ZNSt10filesystem16create_hard_linkERKNS_4pathES2_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16create_hard_linkERKNS_4pathES2_RSt10error_code FUNC:_ZNSt10filesystem16create_hard_linkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16create_hard_linkERKNS_7__cxx114pathES3_ FUNC:_ZNSt10filesystem16create_hard_linkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16create_hard_linkERKNS_7__cxx114pathES3_RSt10error_code FUNC:_ZNSt10filesystem16create_hard_linkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsRKNS_4pathES5_St10error_code FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsRKNS_4pathES5_St10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsRKNS_4pathESt10error_code FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsRKNS_4pathESt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsSt10error_code FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsRKNS_4pathES5_St10error_code FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsRKNS_4pathES5_St10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsRKNS_4pathESt10error_code FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsRKNS_4pathESt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsSt10error_code FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16filesystem_errorD0Ev FUNC:_ZNSt10filesystem16filesystem_errorD0Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16filesystem_errorD1Ev FUNC:_ZNSt10filesystem16filesystem_errorD1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16filesystem_errorD2Ev FUNC:_ZNSt10filesystem16filesystem_errorD2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_4pathE FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem18create_directoriesERKNS_4pathE FUNC:_ZNSt10filesystem18create_directoriesERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem18create_directoriesERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem18create_directoriesERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem18create_directoriesERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem18create_directoriesERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem18create_directoriesERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem18create_directoriesERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem18directory_iterator9incrementERSt10error_code FUNC:_ZNSt10filesystem18directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem18directory_iteratorC1ERKNS_4pathENS_17directory_optionsEPSt10error_code FUNC:_ZNSt10filesystem18directory_iteratorC1ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem18directory_iteratorC2ERKNS_4pathENS_17directory_optionsEPSt10error_code FUNC:_ZNSt10filesystem18directory_iteratorC2ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem18directory_iteratorppEv FUNC:_ZNSt10filesystem18directory_iteratorppEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem19temp_directory_pathB5cxx11ERSt10error_code FUNC:_ZNSt10filesystem19temp_directory_pathB5cxx11ERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem19temp_directory_pathB5cxx11Ev FUNC:_ZNSt10filesystem19temp_directory_pathB5cxx11Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem19temp_directory_pathERSt10error_code FUNC:_ZNSt10filesystem19temp_directory_pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem19temp_directory_pathEv FUNC:_ZNSt10filesystem19temp_directory_pathEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_4pathES2_ FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_4pathES2_RSt10error_code FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_7__cxx114pathES3_ FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_7__cxx114pathES3_RSt10error_code FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem28recursive_directory_iterator25disable_recursion_pendingEv FUNC:_ZNSt10filesystem28recursive_directory_iterator25disable_recursion_pendingEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem28recursive_directory_iterator3popERSt10error_code FUNC:_ZNSt10filesystem28recursive_directory_iterator3popERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem28recursive_directory_iterator3popEv FUNC:_ZNSt10filesystem28recursive_directory_iterator3popEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem28recursive_directory_iterator9incrementERSt10error_code FUNC:_ZNSt10filesystem28recursive_directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem28recursive_directory_iteratorC1ERKNS_4pathENS_17directory_optionsEPSt10error_code FUNC:_ZNSt10filesystem28recursive_directory_iteratorC1ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem28recursive_directory_iteratorC2ERKNS_4pathENS_17directory_optionsEPSt10error_code FUNC:_ZNSt10filesystem28recursive_directory_iteratorC2ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem28recursive_directory_iteratorD1Ev FUNC:_ZNSt10filesystem28recursive_directory_iteratorD1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem28recursive_directory_iteratorD2Ev FUNC:_ZNSt10filesystem28recursive_directory_iteratorD2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem28recursive_directory_iteratoraSEOS0_ FUNC:_ZNSt10filesystem28recursive_directory_iteratoraSEOS0_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem28recursive_directory_iteratoraSERKS0_ FUNC:_ZNSt10filesystem28recursive_directory_iteratoraSERKS0_@@GLIBCXX_3.4.27 -FUNC:_ZNSt10filesystem28recursive_directory_iteratorppEv FUNC:_ZNSt10filesystem28recursive_directory_iteratorppEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4copyERKNS_4pathES2_NS_12copy_optionsE FUNC:_ZNSt10filesystem4copyERKNS_4pathES2_NS_12copy_optionsE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4copyERKNS_4pathES2_NS_12copy_optionsERSt10error_code FUNC:_ZNSt10filesystem4copyERKNS_4pathES2_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4copyERKNS_7__cxx114pathES3_NS_12copy_optionsE FUNC:_ZNSt10filesystem4copyERKNS_7__cxx114pathES3_NS_12copy_optionsE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4copyERKNS_7__cxx114pathES3_NS_12copy_optionsERSt10error_code FUNC:_ZNSt10filesystem4copyERKNS_7__cxx114pathES3_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4path14_M_split_cmptsEv FUNC:_ZNSt10filesystem4path14_M_split_cmptsEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4path14_S_convert_locEPKcS2_RKSt6locale FUNC:_ZNSt10filesystem4path14_S_convert_locEPKcS2_RKSt6locale@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4path15remove_filenameEv FUNC:_ZNSt10filesystem4path15remove_filenameEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4path16replace_filenameERKS0_ FUNC:_ZNSt10filesystem4path16replace_filenameERKS0_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4path17replace_extensionERKS0_ FUNC:_ZNSt10filesystem4path17replace_extensionERKS0_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4path5_ListC1ERKS1_ FUNC:_ZNSt10filesystem4path5_ListC1ERKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4path5_ListC1Ev FUNC:_ZNSt10filesystem4path5_ListC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4path9_M_appendESt17basic_string_viewIcSt11char_traitsIcEE FUNC:_ZNSt10filesystem4path9_M_appendESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4path9_M_concatESt17basic_string_viewIcSt11char_traitsIcEE FUNC:_ZNSt10filesystem4path9_M_concatESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4pathaSERKS0_ FUNC:_ZNSt10filesystem4pathaSERKS0_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4pathdVERKS0_ FUNC:_ZNSt10filesystem4pathdVERKS0_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem4pathpLERKS0_ FUNC:_ZNSt10filesystem4pathpLERKS0_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem5spaceERKNS_4pathE FUNC:_ZNSt10filesystem5spaceERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem5spaceERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem5spaceERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem5spaceERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem5spaceERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem5spaceERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem5spaceERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem6removeERKNS_4pathE FUNC:_ZNSt10filesystem6removeERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem6removeERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem6removeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem6removeERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem6removeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem6removeERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem6removeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem6renameERKNS_4pathES2_ FUNC:_ZNSt10filesystem6renameERKNS_4pathES2_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem6renameERKNS_4pathES2_RSt10error_code FUNC:_ZNSt10filesystem6renameERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem6renameERKNS_7__cxx114pathES3_ FUNC:_ZNSt10filesystem6renameERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem6renameERKNS_7__cxx114pathES3_RSt10error_code FUNC:_ZNSt10filesystem6renameERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem6statusERKNS_4pathE FUNC:_ZNSt10filesystem6statusERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem6statusERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem6statusERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem6statusERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem6statusERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem6statusERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem6statusERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1110hash_valueERKNS0_4pathE FUNC:_ZNSt10filesystem7__cxx1110hash_valueERKNS0_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESC_St10error_code FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESC_St10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESt10error_code FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESC_St10error_code FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESC_St10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESt10error_code FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD0Ev FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD0Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD1Ev FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD2Ev FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1118directory_iterator9incrementERSt10error_code FUNC:_ZNSt10filesystem7__cxx1118directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorC1ERKNS0_4pathENS_17directory_optionsEPSt10error_code FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorC1ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorC2ERKNS0_4pathENS_17directory_optionsEPSt10error_code FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorC2ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorppEv FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorppEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator25disable_recursion_pendingEv FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator25disable_recursion_pendingEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator3popERSt10error_code FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator3popERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator3popEv FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator3popEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator9incrementERSt10error_code FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorC1ERKNS0_4pathENS_17directory_optionsEPSt10error_code FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorC1ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorC2ERKNS0_4pathENS_17directory_optionsEPSt10error_code FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorC2ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorD1Ev FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorD1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorD2Ev FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorD2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratoraSEOS1_ FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratoraSEOS1_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratoraSERKS1_ FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratoraSERKS1_@@GLIBCXX_3.4.27 -FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorppEv FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorppEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx114path14_M_split_cmptsEv FUNC:_ZNSt10filesystem7__cxx114path14_M_split_cmptsEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx114path14_S_convert_locEPKcS3_RKSt6locale FUNC:_ZNSt10filesystem7__cxx114path14_S_convert_locEPKcS3_RKSt6locale@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx114path15remove_filenameEv FUNC:_ZNSt10filesystem7__cxx114path15remove_filenameEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx114path16replace_filenameERKS1_ FUNC:_ZNSt10filesystem7__cxx114path16replace_filenameERKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx114path17replace_extensionERKS1_ FUNC:_ZNSt10filesystem7__cxx114path17replace_extensionERKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx114path5_ListC1ERKS2_ FUNC:_ZNSt10filesystem7__cxx114path5_ListC1ERKS2_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx114path5_ListC1Ev FUNC:_ZNSt10filesystem7__cxx114path5_ListC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx114path9_M_appendESt17basic_string_viewIcSt11char_traitsIcEE FUNC:_ZNSt10filesystem7__cxx114path9_M_appendESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx114path9_M_concatESt17basic_string_viewIcSt11char_traitsIcEE FUNC:_ZNSt10filesystem7__cxx114path9_M_concatESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx114pathaSERKS1_ FUNC:_ZNSt10filesystem7__cxx114pathaSERKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx114pathdVERKS1_ FUNC:_ZNSt10filesystem7__cxx114pathdVERKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem7__cxx114pathpLERKS1_ FUNC:_ZNSt10filesystem7__cxx114pathpLERKS1_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem8absoluteERKNS_4pathE FUNC:_ZNSt10filesystem8absoluteERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem8absoluteERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem8absoluteERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem8absoluteERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem8absoluteERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem8absoluteERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem8absoluteERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem8is_emptyERKNS_4pathE FUNC:_ZNSt10filesystem8is_emptyERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem8is_emptyERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem8is_emptyERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem8is_emptyERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem8is_emptyERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem8is_emptyERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem8is_emptyERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem8relativeERKNS_4pathES2_ FUNC:_ZNSt10filesystem8relativeERKNS_4pathES2_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem8relativeERKNS_4pathES2_RSt10error_code FUNC:_ZNSt10filesystem8relativeERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem8relativeERKNS_7__cxx114pathES3_ FUNC:_ZNSt10filesystem8relativeERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem8relativeERKNS_7__cxx114pathES3_RSt10error_code FUNC:_ZNSt10filesystem8relativeERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9canonicalERKNS_4pathE FUNC:_ZNSt10filesystem9canonicalERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9canonicalERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem9canonicalERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9canonicalERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem9canonicalERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9canonicalERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem9canonicalERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9copy_fileERKNS_4pathES2_NS_12copy_optionsE FUNC:_ZNSt10filesystem9copy_fileERKNS_4pathES2_NS_12copy_optionsE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9copy_fileERKNS_4pathES2_NS_12copy_optionsERSt10error_code FUNC:_ZNSt10filesystem9copy_fileERKNS_4pathES2_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9copy_fileERKNS_7__cxx114pathES3_NS_12copy_optionsE FUNC:_ZNSt10filesystem9copy_fileERKNS_7__cxx114pathES3_NS_12copy_optionsE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9copy_fileERKNS_7__cxx114pathES3_NS_12copy_optionsERSt10error_code FUNC:_ZNSt10filesystem9copy_fileERKNS_7__cxx114pathES3_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9file_sizeERKNS_4pathE FUNC:_ZNSt10filesystem9file_sizeERKNS_4pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9file_sizeERKNS_4pathERSt10error_code FUNC:_ZNSt10filesystem9file_sizeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9file_sizeERKNS_7__cxx114pathE FUNC:_ZNSt10filesystem9file_sizeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9file_sizeERKNS_7__cxx114pathERSt10error_code FUNC:_ZNSt10filesystem9file_sizeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9proximateERKNS_4pathES2_ FUNC:_ZNSt10filesystem9proximateERKNS_4pathES2_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9proximateERKNS_4pathES2_RSt10error_code FUNC:_ZNSt10filesystem9proximateERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9proximateERKNS_7__cxx114pathES3_ FUNC:_ZNSt10filesystem9proximateERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 -FUNC:_ZNSt10filesystem9proximateERKNS_7__cxx114pathES3_RSt10error_code FUNC:_ZNSt10filesystem9proximateERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 -FUNC:_ZNSt10istrstream3strEv FUNC:_ZNSt10istrstream3strEv@@GLIBCXX_3.4 -FUNC:_ZNSt10istrstreamC1EPKc FUNC:_ZNSt10istrstreamC1EPKc@@GLIBCXX_3.4 -FUNC:_ZNSt10istrstreamC1EPKci FUNC:_ZNSt10istrstreamC1EPKci@@GLIBCXX_3.4 -FUNC:_ZNSt10istrstreamC1EPc FUNC:_ZNSt10istrstreamC1EPc@@GLIBCXX_3.4 -FUNC:_ZNSt10istrstreamC1EPci FUNC:_ZNSt10istrstreamC1EPci@@GLIBCXX_3.4 -FUNC:_ZNSt10istrstreamC2EPKc FUNC:_ZNSt10istrstreamC2EPKc@@GLIBCXX_3.4 -FUNC:_ZNSt10istrstreamC2EPKci FUNC:_ZNSt10istrstreamC2EPKci@@GLIBCXX_3.4 -FUNC:_ZNSt10istrstreamC2EPc FUNC:_ZNSt10istrstreamC2EPc@@GLIBCXX_3.4 -FUNC:_ZNSt10istrstreamC2EPci FUNC:_ZNSt10istrstreamC2EPci@@GLIBCXX_3.4 -FUNC:_ZNSt10istrstreamD0Ev FUNC:_ZNSt10istrstreamD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10istrstreamD1Ev FUNC:_ZNSt10istrstreamD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10istrstreamD2Ev FUNC:_ZNSt10istrstreamD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10money_base20_S_construct_patternEccc FUNC:_ZNSt10money_base20_S_construct_patternEccc@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb0EE24_M_initialize_moneypunctEP15__locale_structPKc FUNC:_ZNSt10moneypunctIcLb0EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb0EEC1EP15__locale_structPKcj FUNC:_ZNSt10moneypunctIcLb0EEC1EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb0EEC1EPSt18__moneypunct_cacheIcLb0EEj FUNC:_ZNSt10moneypunctIcLb0EEC1EPSt18__moneypunct_cacheIcLb0EEj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb0EEC1Ej FUNC:_ZNSt10moneypunctIcLb0EEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb0EEC2EP15__locale_structPKcj FUNC:_ZNSt10moneypunctIcLb0EEC2EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb0EEC2EPSt18__moneypunct_cacheIcLb0EEj FUNC:_ZNSt10moneypunctIcLb0EEC2EPSt18__moneypunct_cacheIcLb0EEj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb0EEC2Ej FUNC:_ZNSt10moneypunctIcLb0EEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb0EED0Ev FUNC:_ZNSt10moneypunctIcLb0EED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb0EED1Ev FUNC:_ZNSt10moneypunctIcLb0EED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb0EED2Ev FUNC:_ZNSt10moneypunctIcLb0EED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb1EE24_M_initialize_moneypunctEP15__locale_structPKc FUNC:_ZNSt10moneypunctIcLb1EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb1EEC1EP15__locale_structPKcj FUNC:_ZNSt10moneypunctIcLb1EEC1EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb1EEC1EPSt18__moneypunct_cacheIcLb1EEj FUNC:_ZNSt10moneypunctIcLb1EEC1EPSt18__moneypunct_cacheIcLb1EEj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb1EEC1Ej FUNC:_ZNSt10moneypunctIcLb1EEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb1EEC2EP15__locale_structPKcj FUNC:_ZNSt10moneypunctIcLb1EEC2EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb1EEC2EPSt18__moneypunct_cacheIcLb1EEj FUNC:_ZNSt10moneypunctIcLb1EEC2EPSt18__moneypunct_cacheIcLb1EEj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb1EEC2Ej FUNC:_ZNSt10moneypunctIcLb1EEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb1EED0Ev FUNC:_ZNSt10moneypunctIcLb1EED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb1EED1Ev FUNC:_ZNSt10moneypunctIcLb1EED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIcLb1EED2Ev FUNC:_ZNSt10moneypunctIcLb1EED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb0EE24_M_initialize_moneypunctEP15__locale_structPKc FUNC:_ZNSt10moneypunctIwLb0EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb0EEC1EP15__locale_structPKcj FUNC:_ZNSt10moneypunctIwLb0EEC1EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb0EEC1EPSt18__moneypunct_cacheIwLb0EEj FUNC:_ZNSt10moneypunctIwLb0EEC1EPSt18__moneypunct_cacheIwLb0EEj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb0EEC1Ej FUNC:_ZNSt10moneypunctIwLb0EEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb0EEC2EP15__locale_structPKcj FUNC:_ZNSt10moneypunctIwLb0EEC2EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb0EEC2EPSt18__moneypunct_cacheIwLb0EEj FUNC:_ZNSt10moneypunctIwLb0EEC2EPSt18__moneypunct_cacheIwLb0EEj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb0EEC2Ej FUNC:_ZNSt10moneypunctIwLb0EEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb0EED0Ev FUNC:_ZNSt10moneypunctIwLb0EED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb0EED1Ev FUNC:_ZNSt10moneypunctIwLb0EED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb0EED2Ev FUNC:_ZNSt10moneypunctIwLb0EED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb1EE24_M_initialize_moneypunctEP15__locale_structPKc FUNC:_ZNSt10moneypunctIwLb1EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb1EEC1EP15__locale_structPKcj FUNC:_ZNSt10moneypunctIwLb1EEC1EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb1EEC1EPSt18__moneypunct_cacheIwLb1EEj FUNC:_ZNSt10moneypunctIwLb1EEC1EPSt18__moneypunct_cacheIwLb1EEj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb1EEC1Ej FUNC:_ZNSt10moneypunctIwLb1EEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb1EEC2EP15__locale_structPKcj FUNC:_ZNSt10moneypunctIwLb1EEC2EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb1EEC2EPSt18__moneypunct_cacheIwLb1EEj FUNC:_ZNSt10moneypunctIwLb1EEC2EPSt18__moneypunct_cacheIwLb1EEj@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb1EEC2Ej FUNC:_ZNSt10moneypunctIwLb1EEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb1EED0Ev FUNC:_ZNSt10moneypunctIwLb1EED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb1EED1Ev FUNC:_ZNSt10moneypunctIwLb1EED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10moneypunctIwLb1EED2Ev FUNC:_ZNSt10moneypunctIwLb1EED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10ostrstream3strEv FUNC:_ZNSt10ostrstream3strEv@@GLIBCXX_3.4 -FUNC:_ZNSt10ostrstream6freezeEb FUNC:_ZNSt10ostrstream6freezeEb@@GLIBCXX_3.4 -FUNC:_ZNSt10ostrstreamC1EPciSt13_Ios_Openmode FUNC:_ZNSt10ostrstreamC1EPciSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt10ostrstreamC1Ev FUNC:_ZNSt10ostrstreamC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10ostrstreamC2EPciSt13_Ios_Openmode FUNC:_ZNSt10ostrstreamC2EPciSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt10ostrstreamC2Ev FUNC:_ZNSt10ostrstreamC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10ostrstreamD0Ev FUNC:_ZNSt10ostrstreamD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10ostrstreamD1Ev FUNC:_ZNSt10ostrstreamD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt10ostrstreamD2Ev FUNC:_ZNSt10ostrstreamD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIcE23_M_initialize_timepunctEP15__locale_struct FUNC:_ZNSt11__timepunctIcE23_M_initialize_timepunctEP15__locale_struct@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIcEC1EP15__locale_structPKcj FUNC:_ZNSt11__timepunctIcEC1EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIcEC1EPSt17__timepunct_cacheIcEj FUNC:_ZNSt11__timepunctIcEC1EPSt17__timepunct_cacheIcEj@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIcEC1Ej FUNC:_ZNSt11__timepunctIcEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIcEC2EP15__locale_structPKcj FUNC:_ZNSt11__timepunctIcEC2EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIcEC2EPSt17__timepunct_cacheIcEj FUNC:_ZNSt11__timepunctIcEC2EPSt17__timepunct_cacheIcEj@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIcEC2Ej FUNC:_ZNSt11__timepunctIcEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIcED0Ev FUNC:_ZNSt11__timepunctIcED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIcED1Ev FUNC:_ZNSt11__timepunctIcED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIcED2Ev FUNC:_ZNSt11__timepunctIcED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIwE23_M_initialize_timepunctEP15__locale_struct FUNC:_ZNSt11__timepunctIwE23_M_initialize_timepunctEP15__locale_struct@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIwEC1EP15__locale_structPKcj FUNC:_ZNSt11__timepunctIwEC1EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIwEC1EPSt17__timepunct_cacheIwEj FUNC:_ZNSt11__timepunctIwEC1EPSt17__timepunct_cacheIwEj@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIwEC1Ej FUNC:_ZNSt11__timepunctIwEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIwEC2EP15__locale_structPKcj FUNC:_ZNSt11__timepunctIwEC2EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIwEC2EPSt17__timepunct_cacheIwEj FUNC:_ZNSt11__timepunctIwEC2EPSt17__timepunct_cacheIwEj@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIwEC2Ej FUNC:_ZNSt11__timepunctIwEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIwED0Ev FUNC:_ZNSt11__timepunctIwED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIwED1Ev FUNC:_ZNSt11__timepunctIwED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt11__timepunctIwED2Ev FUNC:_ZNSt11__timepunctIwED2Ev@@GLIBCXX_3.4 FUNC:_ZNSt11char_traitsIcE2eqERKcS2_@@GLIBCXX_3.4.5 FUNC:_ZNSt11char_traitsIcE2eqERKcS2_@GLIBCXX_3.4 FUNC:_ZNSt11char_traitsIwE2eqERKwS2_@@GLIBCXX_3.4.5 FUNC:_ZNSt11char_traitsIwE2eqERKwS2_@GLIBCXX_3.4 -FUNC:_ZNSt11logic_errorC1EOS_ FUNC:_ZNSt11logic_errorC1EOS_@@GLIBCXX_3.4.26 -FUNC:_ZNSt11logic_errorC1EPKc FUNC:_ZNSt11logic_errorC1EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt11logic_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt11logic_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt11logic_errorC1ERKS_ FUNC:_ZNSt11logic_errorC1ERKS_@@GLIBCXX_3.4.21 -FUNC:_ZNSt11logic_errorC1ERKSs FUNC:_ZNSt11logic_errorC1ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt11logic_errorC2EOS_ FUNC:_ZNSt11logic_errorC2EOS_@@GLIBCXX_3.4.26 -FUNC:_ZNSt11logic_errorC2EPKc FUNC:_ZNSt11logic_errorC2EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt11logic_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt11logic_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt11logic_errorC2ERKS_ FUNC:_ZNSt11logic_errorC2ERKS_@@GLIBCXX_3.4.21 -FUNC:_ZNSt11logic_errorC2ERKSs FUNC:_ZNSt11logic_errorC2ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt11logic_errorD0Ev FUNC:_ZNSt11logic_errorD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt11logic_errorD1Ev FUNC:_ZNSt11logic_errorD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt11logic_errorD2Ev FUNC:_ZNSt11logic_errorD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt11logic_erroraSEOS_ FUNC:_ZNSt11logic_erroraSEOS_@@GLIBCXX_3.4.26 -FUNC:_ZNSt11logic_erroraSERKS_ FUNC:_ZNSt11logic_erroraSERKS_@@GLIBCXX_3.4.21 -FUNC:_ZNSt11range_errorC1EPKc FUNC:_ZNSt11range_errorC1EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt11range_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt11range_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt11range_errorC1ERKSs FUNC:_ZNSt11range_errorC1ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt11range_errorC2EPKc FUNC:_ZNSt11range_errorC2EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt11range_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt11range_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt11range_errorC2ERKSs FUNC:_ZNSt11range_errorC2ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt11range_errorD0Ev FUNC:_ZNSt11range_errorD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt11range_errorD1Ev FUNC:_ZNSt11range_errorD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt11range_errorD2Ev FUNC:_ZNSt11range_errorD2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt11regex_errorC1ENSt15regex_constants10error_typeE FUNC:_ZNSt11regex_errorC1ENSt15regex_constants10error_typeE@@GLIBCXX_3.4.20 -FUNC:_ZNSt11regex_errorC2ENSt15regex_constants10error_typeE FUNC:_ZNSt11regex_errorC2ENSt15regex_constants10error_typeE@@GLIBCXX_3.4.21 -FUNC:_ZNSt11regex_errorD0Ev FUNC:_ZNSt11regex_errorD0Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt11regex_errorD1Ev FUNC:_ZNSt11regex_errorD1Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt11regex_errorD2Ev FUNC:_ZNSt11regex_errorD2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt11this_thread11__sleep_forENSt6chrono8durationIxSt5ratioILx1ELx1EEEENS1_IxS2_ILx1ELx1000000000EEEE FUNC:_ZNSt11this_thread11__sleep_forENSt6chrono8durationIxSt5ratioILx1ELx1EEEENS1_IxS2_ILx1ELx1000000000EEEE@@GLIBCXX_3.4.18 -FUNC:_ZNSt12__basic_fileIcE2fdEv FUNC:_ZNSt12__basic_fileIcE2fdEv@@GLIBCXX_3.4 -FUNC:_ZNSt12__basic_fileIcE4fileEv FUNC:_ZNSt12__basic_fileIcE4fileEv@@GLIBCXX_3.4.1 -FUNC:_ZNSt12__basic_fileIcE4openEPKcSt13_Ios_Openmodei FUNC:_ZNSt12__basic_fileIcE4openEPKcSt13_Ios_Openmodei@@GLIBCXX_3.4 -FUNC:_ZNSt12__basic_fileIcE4syncEv FUNC:_ZNSt12__basic_fileIcE4syncEv@@GLIBCXX_3.4 -FUNC:_ZNSt12__basic_fileIcE5closeEv FUNC:_ZNSt12__basic_fileIcE5closeEv@@GLIBCXX_3.4 -FUNC:_ZNSt12__basic_fileIcE6xsgetnEPci FUNC:_ZNSt12__basic_fileIcE6xsgetnEPci@@GLIBCXX_3.4 -FUNC:_ZNSt12__basic_fileIcE6xsputnEPKci FUNC:_ZNSt12__basic_fileIcE6xsputnEPKci@@GLIBCXX_3.4 -FUNC:_ZNSt12__basic_fileIcE7seekoffExSt12_Ios_Seekdir FUNC:_ZNSt12__basic_fileIcE7seekoffExSt12_Ios_Seekdir@@GLIBCXX_3.4 -FUNC:_ZNSt12__basic_fileIcE8sys_openEP8_IO_FILESt13_Ios_Openmode FUNC:_ZNSt12__basic_fileIcE8sys_openEP8_IO_FILESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt12__basic_fileIcE8sys_openEiSt13_Ios_Openmode FUNC:_ZNSt12__basic_fileIcE8sys_openEiSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt12__basic_fileIcE8xsputn_2EPKciS2_i FUNC:_ZNSt12__basic_fileIcE8xsputn_2EPKciS2_i@@GLIBCXX_3.4 -FUNC:_ZNSt12__basic_fileIcE9showmanycEv FUNC:_ZNSt12__basic_fileIcE9showmanycEv@@GLIBCXX_3.4 -FUNC:_ZNSt12__basic_fileIcEC1EP15pthread_mutex_t FUNC:_ZNSt12__basic_fileIcEC1EP15pthread_mutex_t@@GLIBCXX_3.4 -FUNC:_ZNSt12__basic_fileIcEC2EP15pthread_mutex_t FUNC:_ZNSt12__basic_fileIcEC2EP15pthread_mutex_t@@GLIBCXX_3.4 -FUNC:_ZNSt12__basic_fileIcED1Ev FUNC:_ZNSt12__basic_fileIcED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12__basic_fileIcED2Ev FUNC:_ZNSt12__basic_fileIcED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1EOS5_ FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1EOS5_@@GLIBCXX_3.4.26 -FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1Ev FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2EOS5_ FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2EOS5_@@GLIBCXX_3.4.28 -FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2Ev FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27 -FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC1EOS4_ FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC1EOS4_@@GLIBCXX_3.4.26 -FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC1Ev FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC2EOS4_ FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC2EOS4_@@GLIBCXX_3.4.28 -FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC2Ev FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27 -FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEaSEOS4_ FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEaSEOS4_@@GLIBCXX_3.4.26 -FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1EOS6_ FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1EOS6_@@GLIBCXX_3.4.26 -FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1Ev FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2EOS6_ FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2EOS6_@@GLIBCXX_3.4.28 -FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2Ev FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27 -FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC1EOS5_ FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC1EOS5_@@GLIBCXX_3.4.26 -FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC1Ev FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC2EOS5_ FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC2EOS5_@@GLIBCXX_3.4.28 -FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC2Ev FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27 -FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEaSEOS5_ FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEaSEOS5_@@GLIBCXX_3.4.26 -FUNC:_ZNSt12bad_weak_ptrD0Ev +FUNC:_ZNSt12__sso_stringC1Ev@@GLIBCXX_3.4.34 +FUNC:_ZNSt12__sso_stringC2Ev@@GLIBCXX_3.4.34 +FUNC:_ZNSt12__sso_stringD1Ev@@GLIBCXX_3.4.34 +FUNC:_ZNSt12__sso_stringD2Ev@@GLIBCXX_3.4.34 FUNC:_ZNSt12bad_weak_ptrD0Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt12bad_weak_ptrD1Ev FUNC:_ZNSt12bad_weak_ptrD1Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt12bad_weak_ptrD2Ev FUNC:_ZNSt12bad_weak_ptrD2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt12ctype_bynameIcEC1EPKcj FUNC:_ZNSt12ctype_bynameIcEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt12ctype_bynameIcEC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt12ctype_bynameIcEC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt12ctype_bynameIcEC1ERKSsj FUNC:_ZNSt12ctype_bynameIcEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt12ctype_bynameIcEC2EPKcj FUNC:_ZNSt12ctype_bynameIcEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt12ctype_bynameIcEC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt12ctype_bynameIcEC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt12ctype_bynameIcEC2ERKSsj FUNC:_ZNSt12ctype_bynameIcEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt12ctype_bynameIcED0Ev FUNC:_ZNSt12ctype_bynameIcED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12ctype_bynameIcED1Ev FUNC:_ZNSt12ctype_bynameIcED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12ctype_bynameIcED2Ev FUNC:_ZNSt12ctype_bynameIcED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12ctype_bynameIwEC1EPKcj FUNC:_ZNSt12ctype_bynameIwEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt12ctype_bynameIwEC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt12ctype_bynameIwEC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt12ctype_bynameIwEC1ERKSsj FUNC:_ZNSt12ctype_bynameIwEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt12ctype_bynameIwEC2EPKcj FUNC:_ZNSt12ctype_bynameIwEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt12ctype_bynameIwEC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt12ctype_bynameIwEC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt12ctype_bynameIwEC2ERKSsj FUNC:_ZNSt12ctype_bynameIwEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt12ctype_bynameIwED0Ev FUNC:_ZNSt12ctype_bynameIwED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12ctype_bynameIwED1Ev FUNC:_ZNSt12ctype_bynameIwED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12ctype_bynameIwED2Ev FUNC:_ZNSt12ctype_bynameIwED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12domain_errorC1EPKc FUNC:_ZNSt12domain_errorC1EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt12domain_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt12domain_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt12domain_errorC1ERKSs FUNC:_ZNSt12domain_errorC1ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt12domain_errorC2EPKc FUNC:_ZNSt12domain_errorC2EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt12domain_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt12domain_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt12domain_errorC2ERKSs FUNC:_ZNSt12domain_errorC2ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt12domain_errorD0Ev FUNC:_ZNSt12domain_errorD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12domain_errorD1Ev FUNC:_ZNSt12domain_errorD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12domain_errorD2Ev FUNC:_ZNSt12domain_errorD2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt12future_errorD0Ev FUNC:_ZNSt12future_errorD0Ev@@GLIBCXX_3.4.14 -FUNC:_ZNSt12future_errorD1Ev FUNC:_ZNSt12future_errorD1Ev@@GLIBCXX_3.4.14 -FUNC:_ZNSt12future_errorD2Ev FUNC:_ZNSt12future_errorD2Ev@@GLIBCXX_3.4.14 -FUNC:_ZNSt12length_errorC1EPKc FUNC:_ZNSt12length_errorC1EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt12length_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt12length_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt12length_errorC1ERKSs FUNC:_ZNSt12length_errorC1ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt12length_errorC2EPKc FUNC:_ZNSt12length_errorC2EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt12length_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt12length_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt12length_errorC2ERKSs FUNC:_ZNSt12length_errorC2ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt12length_errorD0Ev FUNC:_ZNSt12length_errorD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12length_errorD1Ev FUNC:_ZNSt12length_errorD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12length_errorD2Ev FUNC:_ZNSt12length_errorD2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt12out_of_rangeC1EPKc FUNC:_ZNSt12out_of_rangeC1EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt12out_of_rangeC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt12out_of_rangeC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt12out_of_rangeC1ERKSs FUNC:_ZNSt12out_of_rangeC1ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt12out_of_rangeC2EPKc FUNC:_ZNSt12out_of_rangeC2EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt12out_of_rangeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt12out_of_rangeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt12out_of_rangeC2ERKSs FUNC:_ZNSt12out_of_rangeC2ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt12out_of_rangeD0Ev FUNC:_ZNSt12out_of_rangeD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12out_of_rangeD1Ev FUNC:_ZNSt12out_of_rangeD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12out_of_rangeD2Ev FUNC:_ZNSt12out_of_rangeD2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt12strstreambuf3strEv FUNC:_ZNSt12strstreambuf3strEv@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambuf6freezeEb FUNC:_ZNSt12strstreambuf6freezeEb@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambuf6setbufEPci FUNC:_ZNSt12strstreambuf6setbufEPci@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambuf7_M_freeEPc FUNC:_ZNSt12strstreambuf7_M_freeEPc@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambuf7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode FUNC:_ZNSt12strstreambuf7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambuf7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode FUNC:_ZNSt12strstreambuf7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambuf8_M_allocEj FUNC:_ZNSt12strstreambuf8_M_allocEj@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambuf8_M_setupEPcS0_i FUNC:_ZNSt12strstreambuf8_M_setupEPcS0_i@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambuf8overflowEi FUNC:_ZNSt12strstreambuf8overflowEi@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambuf9pbackfailEi FUNC:_ZNSt12strstreambuf9pbackfailEi@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambuf9underflowEv FUNC:_ZNSt12strstreambuf9underflowEv@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC1EPFPvjEPFvS0_E FUNC:_ZNSt12strstreambufC1EPFPvjEPFvS0_E@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC1EPKai FUNC:_ZNSt12strstreambufC1EPKai@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC1EPKci FUNC:_ZNSt12strstreambufC1EPKci@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC1EPKhi FUNC:_ZNSt12strstreambufC1EPKhi@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC1EPaiS0_ FUNC:_ZNSt12strstreambufC1EPaiS0_@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC1EPciS0_ FUNC:_ZNSt12strstreambufC1EPciS0_@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC1EPhiS0_ FUNC:_ZNSt12strstreambufC1EPhiS0_@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC1Ei FUNC:_ZNSt12strstreambufC1Ei@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC2EPFPvjEPFvS0_E FUNC:_ZNSt12strstreambufC2EPFPvjEPFvS0_E@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC2EPKai FUNC:_ZNSt12strstreambufC2EPKai@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC2EPKci FUNC:_ZNSt12strstreambufC2EPKci@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC2EPKhi FUNC:_ZNSt12strstreambufC2EPKhi@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC2EPaiS0_ FUNC:_ZNSt12strstreambufC2EPaiS0_@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC2EPciS0_ FUNC:_ZNSt12strstreambufC2EPciS0_@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC2EPhiS0_ FUNC:_ZNSt12strstreambufC2EPhiS0_@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufC2Ei FUNC:_ZNSt12strstreambufC2Ei@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufD0Ev FUNC:_ZNSt12strstreambufD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufD1Ev FUNC:_ZNSt12strstreambufD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12strstreambufD2Ev FUNC:_ZNSt12strstreambufD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt12system_errorD0Ev FUNC:_ZNSt12system_errorD0Ev@@GLIBCXX_3.4.11 -FUNC:_ZNSt12system_errorD1Ev FUNC:_ZNSt12system_errorD1Ev@@GLIBCXX_3.4.11 -FUNC:_ZNSt12system_errorD2Ev FUNC:_ZNSt12system_errorD2Ev@@GLIBCXX_3.4.11 -FUNC:_ZNSt13__future_base11_State_baseD0Ev FUNC:_ZNSt13__future_base11_State_baseD0Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt13__future_base11_State_baseD1Ev FUNC:_ZNSt13__future_base11_State_baseD1Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt13__future_base11_State_baseD2Ev FUNC:_ZNSt13__future_base11_State_baseD2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt13__future_base12_Result_baseC1Ev FUNC:_ZNSt13__future_base12_Result_baseC1Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt13__future_base12_Result_baseC2Ev FUNC:_ZNSt13__future_base12_Result_baseC2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt13__future_base12_Result_baseD0Ev FUNC:_ZNSt13__future_base12_Result_baseD0Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt13__future_base12_Result_baseD1Ev FUNC:_ZNSt13__future_base12_Result_baseD1Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt13__future_base12_Result_baseD2Ev FUNC:_ZNSt13__future_base12_Result_baseD2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt13__future_base13_State_baseV211_Make_ready6_M_setEv FUNC:_ZNSt13__future_base13_State_baseV211_Make_ready6_M_setEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt13__future_base19_Async_state_commonD0Ev FUNC:_ZNSt13__future_base19_Async_state_commonD0Ev@@GLIBCXX_3.4.17 -FUNC:_ZNSt13__future_base19_Async_state_commonD1Ev FUNC:_ZNSt13__future_base19_Async_state_commonD1Ev@@GLIBCXX_3.4.17 -FUNC:_ZNSt13__future_base19_Async_state_commonD2Ev FUNC:_ZNSt13__future_base19_Async_state_commonD2Ev@@GLIBCXX_3.4.17 -FUNC:_ZNSt13bad_exceptionD0Ev FUNC:_ZNSt13bad_exceptionD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13bad_exceptionD1Ev FUNC:_ZNSt13bad_exceptionD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13bad_exceptionD2Ev FUNC:_ZNSt13bad_exceptionD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE13_M_set_bufferEi FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE13_M_set_bufferEi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE14_M_get_ext_posER11__mbstate_t FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE14_M_get_ext_posER11__mbstate_t@@GLIBCXX_3.4.15 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE15_M_create_pbackEv FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE15_M_create_pbackEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE16_M_destroy_pbackEv FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE16_M_destroy_pbackEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE19_M_terminate_outputEv FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE19_M_terminate_outputEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE22_M_convert_to_externalEPci FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE22_M_convert_to_externalEPci@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE26_M_destroy_internal_bufferEv FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE26_M_destroy_internal_bufferEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE27_M_allocate_internal_bufferEv FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE27_M_allocate_internal_bufferEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4swapERS2_ FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4syncEv FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4syncEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE5closeEv FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE5closeEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE5imbueERKSt6locale FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE5imbueERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE6setbufEPci FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE6setbufEPci@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE6xsgetnEPci FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE6xsgetnEPci@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE6xsputnEPKci FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE6xsputnEPKci@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE7_M_seekExSt12_Ios_Seekdir11__mbstate_t FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE7_M_seekExSt12_Ios_Seekdir11__mbstate_t@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE8overflowEi FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE8overflowEi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE9pbackfailEi FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE9pbackfailEi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE9showmanycEv FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE9showmanycEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE9underflowEv FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE9underflowEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEC1EOS2_ FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEC1EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEC1Ev FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEC2EOS2_ FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEC2EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEC2Ev FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEED0Ev FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEED1Ev FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEED2Ev FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEaSEOS2_ FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEaSEOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE13_M_set_bufferEi FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE13_M_set_bufferEi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE14_M_get_ext_posER11__mbstate_t FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE14_M_get_ext_posER11__mbstate_t@@GLIBCXX_3.4.15 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE15_M_create_pbackEv FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE15_M_create_pbackEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE16_M_destroy_pbackEv FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE16_M_destroy_pbackEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE19_M_terminate_outputEv FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE19_M_terminate_outputEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE22_M_convert_to_externalEPwi FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE22_M_convert_to_externalEPwi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE26_M_destroy_internal_bufferEv FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE26_M_destroy_internal_bufferEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE27_M_allocate_internal_bufferEv FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE27_M_allocate_internal_bufferEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4openERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4openERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4swapERS2_ FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4syncEv FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4syncEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE5closeEv FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE5closeEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE5imbueERKSt6locale FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE5imbueERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE6setbufEPwi FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE6setbufEPwi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE6xsgetnEPwi FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE6xsgetnEPwi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE6xsputnEPKwi FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE6xsputnEPKwi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE7_M_seekExSt12_Ios_Seekdir11__mbstate_t FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE7_M_seekExSt12_Ios_Seekdir11__mbstate_t@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE8overflowEj FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE8overflowEj@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE9pbackfailEj FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE9pbackfailEj@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE9showmanycEv FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE9showmanycEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE9underflowEv FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE9underflowEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEC1EOS2_ FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEC1EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEC1Ev FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEC2EOS2_ FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEC2EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEC2Ev FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEED0Ev FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEED1Ev FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEED2Ev FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEaSEOS2_ FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE4swapERS2_ FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE5closeEv FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE5closeEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE7is_openEv FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1EOS2_ FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1ERKSsSt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1Ev FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2EOS2_ FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2EPKcSt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2ERKSsSt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2Ev FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEED0Ev FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEED1Ev FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEED2Ev FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEaSEOS2_ FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEaSEOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE4openERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE4openERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE4swapERS2_ FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE5closeEv FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE5closeEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE7is_openEv FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1EOS2_ FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1EPKcSt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1ERKSsSt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1Ev FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2EOS2_ FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2EPKcSt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2ERKSsSt13_Ios_Openmode FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2Ev FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEED0Ev FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEED1Ev FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEED2Ev FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEaSEOS2_ FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIPvEERS2_RT_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIPvEERS2_RT_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIbEERS2_RT_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIbEERS2_RT_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIdEERS2_RT_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIdEERS2_RT_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIeEERS2_RT_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIeEERS2_RT_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIfEERS2_RT_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIfEERS2_RT_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIjEERS2_RT_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIjEERS2_RT_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIlEERS2_RT_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIlEERS2_RT_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractImEERS2_RT_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractImEERS2_RT_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractItEERS2_RT_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractItEERS2_RT_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIxEERS2_RT_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIxEERS2_RT_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIyEERS2_RT_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIyEERS2_RT_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getEPwi FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getEPwi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getEPwiw FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getEPwiw@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getERSt15basic_streambufIwS1_E FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getERSt15basic_streambufIwS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getERSt15basic_streambufIwS1_Ew FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getERSt15basic_streambufIwS1_Ew@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getERw FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getERw@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getEv FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE4peekEv FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE4peekEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE4readEPwi FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE4readEPwi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE4swapERS2_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE4syncEv FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE4syncEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE5seekgESt4fposI11__mbstate_tE FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE5seekgESt4fposI11__mbstate_tE@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE5seekgExSt12_Ios_Seekdir FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE5seekgExSt12_Ios_Seekdir@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE5tellgEv FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE5tellgEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE5ungetEv FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE5ungetEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEi@@GLIBCXX_3.4.5 FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEi@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEij FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEij@@GLIBCXX_3.4 FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEv@@GLIBCXX_3.4.5 FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEv@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6sentryC1ERS2_b FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6sentryC1ERS2_b@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6sentryC2ERS2_b FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6sentryC2ERS2_b@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE7getlineEPwi FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE7getlineEPwi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE7getlineEPwiw FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE7getlineEPwiw@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE7putbackEw FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE7putbackEw@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE8readsomeEPwi FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE8readsomeEPwi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC1EOS2_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC1EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC1EPSt15basic_streambufIwS1_E FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC1EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC1Ev FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC2EOS2_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC2EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC2EPSt15basic_streambufIwS1_E FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC2EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC2Ev FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEED0Ev FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEED1Ev FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEED2Ev FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEaSEOS2_ FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsEPFRS2_S3_E FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsEPFRS2_S3_E@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsEPFRSt8ios_baseS4_E FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsEPFRSt8ios_baseS4_E@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsEPFRSt9basic_iosIwS1_ES5_E FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsEPFRSt9basic_iosIwS1_ES5_E@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsEPSt15basic_streambufIwS1_E FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsEPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERPv FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERPv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERb FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERb@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERd FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERd@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERe FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERe@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERf FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERf@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERi FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERj FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERj@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERl FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERl@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERm FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERm@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERs FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERs@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERt FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERt@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERx FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERx@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERy FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERy@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE3putEw FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE3putEw@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE4swapERS2_ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5flushEv FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5flushEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5seekpESt4fposI11__mbstate_tE FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5seekpESt4fposI11__mbstate_tE@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5seekpExSt12_Ios_Seekdir FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5seekpExSt12_Ios_Seekdir@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5tellpEv FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5tellpEv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5writeEPKwi FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5writeEPKwi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentryC1ERS2_ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentryC1ERS2_@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentryC2ERS2_ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentryC2ERS2_@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentryD1Ev FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentryD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentryD2Ev FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentryD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE8_M_writeEPKwi FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE8_M_writeEPKwi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIPKvEERS2_T_ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIPKvEERS2_T_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIbEERS2_T_ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIbEERS2_T_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIdEERS2_T_ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIdEERS2_T_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIeEERS2_T_ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIeEERS2_T_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIlEERS2_T_ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIlEERS2_T_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertImEERS2_T_ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertImEERS2_T_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIxEERS2_T_ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIxEERS2_T_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIyEERS2_T_ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIyEERS2_T_@@GLIBCXX_3.4.9 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC1EOS2_ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC1EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC1EPSt15basic_streambufIwS1_E FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC1EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC1ERSt14basic_iostreamIwS1_E FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC1ERSt14basic_iostreamIwS1_E@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC1Ev FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC2EOS2_ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC2EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC2EPSt15basic_streambufIwS1_E FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC2EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC2ERSt14basic_iostreamIwS1_E FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC2ERSt14basic_iostreamIwS1_E@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC2Ev FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED0Ev FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED1Ev FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED2Ev FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEaSEOS2_ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn@@GLIBCXX_3.4.26 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRS2_S3_E FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRS2_S3_E@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRSt8ios_baseS4_E FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRSt8ios_baseS4_E@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRSt9basic_iosIwS1_ES5_E FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRSt9basic_iosIwS1_ES5_E@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPKv FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPKv@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPSt15basic_streambufIwS1_E FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEb FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEb@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEd FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEd@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEe FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEe@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEf FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEf@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEi FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEi@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEj FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEj@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEl FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEl@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEm FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEm@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEs FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEs@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEt FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEt@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEx FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEx@@GLIBCXX_3.4 -FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEy FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEy@@GLIBCXX_3.4 -FUNC:_ZNSt13random_device14_M_init_pretr1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt13random_device14_M_init_pretr1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt13random_device14_M_init_pretr1ERKSs FUNC:_ZNSt13random_device14_M_init_pretr1ERKSs@@GLIBCXX_3.4.18 -FUNC:_ZNSt13random_device16_M_getval_pretr1Ev FUNC:_ZNSt13random_device16_M_getval_pretr1Ev@@GLIBCXX_3.4.18 -FUNC:_ZNSt13random_device7_M_finiEv FUNC:_ZNSt13random_device7_M_finiEv@@GLIBCXX_3.4.18 -FUNC:_ZNSt13random_device7_M_initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt13random_device7_M_initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt13random_device7_M_initERKSs FUNC:_ZNSt13random_device7_M_initERKSs@@GLIBCXX_3.4.18 -FUNC:_ZNSt13random_device9_M_getvalEv FUNC:_ZNSt13random_device9_M_getvalEv@@GLIBCXX_3.4.18 -FUNC:_ZNSt13runtime_errorC1EOS_ FUNC:_ZNSt13runtime_errorC1EOS_@@GLIBCXX_3.4.26 -FUNC:_ZNSt13runtime_errorC1EPKc FUNC:_ZNSt13runtime_errorC1EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt13runtime_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt13runtime_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt13runtime_errorC1ERKS_ FUNC:_ZNSt13runtime_errorC1ERKS_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13runtime_errorC1ERKSs FUNC:_ZNSt13runtime_errorC1ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt13runtime_errorC2EOS_ FUNC:_ZNSt13runtime_errorC2EOS_@@GLIBCXX_3.4.26 -FUNC:_ZNSt13runtime_errorC2EPKc FUNC:_ZNSt13runtime_errorC2EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt13runtime_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt13runtime_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt13runtime_errorC2ERKS_ FUNC:_ZNSt13runtime_errorC2ERKS_@@GLIBCXX_3.4.21 -FUNC:_ZNSt13runtime_errorC2ERKSs FUNC:_ZNSt13runtime_errorC2ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt13runtime_errorD0Ev FUNC:_ZNSt13runtime_errorD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13runtime_errorD1Ev FUNC:_ZNSt13runtime_errorD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13runtime_errorD2Ev FUNC:_ZNSt13runtime_errorD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt13runtime_erroraSEOS_ FUNC:_ZNSt13runtime_erroraSEOS_@@GLIBCXX_3.4.26 -FUNC:_ZNSt13runtime_erroraSERKS_ FUNC:_ZNSt13runtime_erroraSERKS_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4swapERS2_ FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE5closeEv FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE5closeEv@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE7is_openEv FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1EOS2_ FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1ERKSsSt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1Ev FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2EOS2_ FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2EPKcSt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2ERKSsSt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2Ev FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEED0Ev FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEED1Ev FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEED2Ev FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEaSEOS2_ FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEaSEOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE4openERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE4openERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE4swapERS2_ FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE5closeEv FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE5closeEv@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE7is_openEv FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1EOS2_ FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1EPKcSt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1ERKSsSt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1Ev FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2EOS2_ FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2EPKcSt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2ERKSsSt13_Ios_Openmode FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2Ev FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEED0Ev FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEED1Ev FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEED2Ev FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEaSEOS2_ FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEE4swapERS2_ FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC1EOS2_ FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC1EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC1EPSt15basic_streambufIwS1_E FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC1EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC1Ev FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC2EOS2_ FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC2EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC2EPSt15basic_streambufIwS1_E FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC2EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC2Ev FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEED0Ev FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEED1Ev FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEED2Ev FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEaSEOS2_ FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4swapERS2_ FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE5closeEv FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE5closeEv@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE7is_openEv FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1EOS2_ FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1ERKSsSt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1Ev FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2EOS2_ FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2EPKcSt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2ERKSsSt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2Ev FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEED0Ev FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEED1Ev FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEED2Ev FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEaSEOS2_ FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEaSEOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE4openERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE4openERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE4swapERS2_ FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE5closeEv FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE5closeEv@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE7is_openEv FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1EOS2_ FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1EPKcSt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1ERKSsSt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1Ev FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2EOS2_ FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2EOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2EPKcSt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2ERKSsSt13_Ios_Openmode FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2Ev FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEED0Ev FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEED1Ev FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEED2Ev FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEaSEOS2_ FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC1EPKcj FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC1ERKSsj FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC2EPKcj FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC2ERKSsj FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tED0Ev FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tED1Ev FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tED2Ev FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC1EPKcj FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC1ERKSsj FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC2EPKcj FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC2ERKSsj FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED0Ev FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED1Ev FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED2Ev FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14collate_bynameIcEC1EPKcj FUNC:_ZNSt14collate_bynameIcEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt14collate_bynameIcEC1ERKSsj FUNC:_ZNSt14collate_bynameIcEC1ERKSsj@@GLIBCXX_3.4.26 -FUNC:_ZNSt14collate_bynameIcEC2EPKcj FUNC:_ZNSt14collate_bynameIcEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt14collate_bynameIcEC2ERKSsj FUNC:_ZNSt14collate_bynameIcEC2ERKSsj@@GLIBCXX_3.4.26 -FUNC:_ZNSt14collate_bynameIcED0Ev FUNC:_ZNSt14collate_bynameIcED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14collate_bynameIcED1Ev FUNC:_ZNSt14collate_bynameIcED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14collate_bynameIcED2Ev FUNC:_ZNSt14collate_bynameIcED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14collate_bynameIwEC1EPKcj FUNC:_ZNSt14collate_bynameIwEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt14collate_bynameIwEC1ERKSsj FUNC:_ZNSt14collate_bynameIwEC1ERKSsj@@GLIBCXX_3.4.26 -FUNC:_ZNSt14collate_bynameIwEC2EPKcj FUNC:_ZNSt14collate_bynameIwEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt14collate_bynameIwEC2ERKSsj FUNC:_ZNSt14collate_bynameIwEC2ERKSsj@@GLIBCXX_3.4.26 -FUNC:_ZNSt14collate_bynameIwED0Ev FUNC:_ZNSt14collate_bynameIwED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14collate_bynameIwED1Ev FUNC:_ZNSt14collate_bynameIwED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14collate_bynameIwED2Ev FUNC:_ZNSt14collate_bynameIwED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14error_categoryC1Ev FUNC:_ZNSt14error_categoryC1Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt14error_categoryC2Ev FUNC:_ZNSt14error_categoryC2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt14error_categoryD0Ev FUNC:_ZNSt14error_categoryD0Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt14error_categoryD1Ev FUNC:_ZNSt14error_categoryD1Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt14error_categoryD2Ev FUNC:_ZNSt14error_categoryD2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt14overflow_errorC1EPKc FUNC:_ZNSt14overflow_errorC1EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt14overflow_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt14overflow_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt14overflow_errorC1ERKSs FUNC:_ZNSt14overflow_errorC1ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt14overflow_errorC2EPKc FUNC:_ZNSt14overflow_errorC2EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt14overflow_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt14overflow_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt14overflow_errorC2ERKSs FUNC:_ZNSt14overflow_errorC2ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt14overflow_errorD0Ev FUNC:_ZNSt14overflow_errorD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14overflow_errorD1Ev FUNC:_ZNSt14overflow_errorD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt14overflow_errorD2Ev FUNC:_ZNSt14overflow_errorD2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt15_List_node_base10_M_reverseEv FUNC:_ZNSt15_List_node_base10_M_reverseEv@@GLIBCXX_3.4.14 -FUNC:_ZNSt15_List_node_base11_M_transferEPS_S0_ FUNC:_ZNSt15_List_node_base11_M_transferEPS_S0_@@GLIBCXX_3.4.14 -FUNC:_ZNSt15_List_node_base4hookEPS_ FUNC:_ZNSt15_List_node_base4hookEPS_@@GLIBCXX_3.4 -FUNC:_ZNSt15_List_node_base4swapERS_S0_ FUNC:_ZNSt15_List_node_base4swapERS_S0_@@GLIBCXX_3.4 -FUNC:_ZNSt15_List_node_base6unhookEv FUNC:_ZNSt15_List_node_base6unhookEv@@GLIBCXX_3.4 -FUNC:_ZNSt15_List_node_base7_M_hookEPS_ FUNC:_ZNSt15_List_node_base7_M_hookEPS_@@GLIBCXX_3.4.14 -FUNC:_ZNSt15_List_node_base7reverseEv FUNC:_ZNSt15_List_node_base7reverseEv@@GLIBCXX_3.4 -FUNC:_ZNSt15_List_node_base8transferEPS_S0_ FUNC:_ZNSt15_List_node_base8transferEPS_S0_@@GLIBCXX_3.4 -FUNC:_ZNSt15_List_node_base9_M_unhookEv FUNC:_ZNSt15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.14 -FUNC:_ZNSt15__exception_ptr13exception_ptr10_M_releaseEv FUNC:_ZNSt15__exception_ptr13exception_ptr10_M_releaseEv@@CXXABI_1.3.13 -FUNC:_ZNSt15__exception_ptr13exception_ptr4swapERS0_ FUNC:_ZNSt15__exception_ptr13exception_ptr4swapERS0_@@CXXABI_1.3.3 -FUNC:_ZNSt15__exception_ptr13exception_ptr9_M_addrefEv FUNC:_ZNSt15__exception_ptr13exception_ptr9_M_addrefEv@@CXXABI_1.3.13 -FUNC:_ZNSt15__exception_ptr13exception_ptrC1EMS0_FvvE FUNC:_ZNSt15__exception_ptr13exception_ptrC1EMS0_FvvE@@CXXABI_1.3.3 -FUNC:_ZNSt15__exception_ptr13exception_ptrC1EPv FUNC:_ZNSt15__exception_ptr13exception_ptrC1EPv@@CXXABI_1.3.11 -FUNC:_ZNSt15__exception_ptr13exception_ptrC1ERKS0_ FUNC:_ZNSt15__exception_ptr13exception_ptrC1ERKS0_@@CXXABI_1.3.3 -FUNC:_ZNSt15__exception_ptr13exception_ptrC1Ev FUNC:_ZNSt15__exception_ptr13exception_ptrC1Ev@@CXXABI_1.3.3 -FUNC:_ZNSt15__exception_ptr13exception_ptrC2EMS0_FvvE FUNC:_ZNSt15__exception_ptr13exception_ptrC2EMS0_FvvE@@CXXABI_1.3.3 -FUNC:_ZNSt15__exception_ptr13exception_ptrC2ERKS0_ FUNC:_ZNSt15__exception_ptr13exception_ptrC2ERKS0_@@CXXABI_1.3.3 -FUNC:_ZNSt15__exception_ptr13exception_ptrC2Ev FUNC:_ZNSt15__exception_ptr13exception_ptrC2Ev@@CXXABI_1.3.3 -FUNC:_ZNSt15__exception_ptr13exception_ptrD1Ev FUNC:_ZNSt15__exception_ptr13exception_ptrD1Ev@@CXXABI_1.3.3 -FUNC:_ZNSt15__exception_ptr13exception_ptrD2Ev FUNC:_ZNSt15__exception_ptr13exception_ptrD2Ev@@CXXABI_1.3.3 -FUNC:_ZNSt15__exception_ptr13exception_ptraSERKS0_ FUNC:_ZNSt15__exception_ptr13exception_ptraSERKS0_@@CXXABI_1.3.3 -FUNC:_ZNSt15__exception_ptreqERKNS_13exception_ptrES2_ FUNC:_ZNSt15__exception_ptreqERKNS_13exception_ptrES2_@@CXXABI_1.3.3 -FUNC:_ZNSt15__exception_ptrneERKNS_13exception_ptrES2_ FUNC:_ZNSt15__exception_ptrneERKNS_13exception_ptrES2_@@CXXABI_1.3.3 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE10pubseekoffExSt12_Ios_SeekdirSt13_Ios_Openmode FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE10pubseekoffExSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE10pubseekposESt4fposI11__mbstate_tESt13_Ios_Openmode FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE10pubseekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE12__safe_gbumpEi FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE12__safe_gbumpEi@@GLIBCXX_3.4.16 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE12__safe_pbumpEi FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE12__safe_pbumpEi@@GLIBCXX_3.4.16 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4setgEPcS3_S3_ FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4setgEPcS3_S3_@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4setpEPcS3_ FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4setpEPcS3_@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4swapERS2_ FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4syncEv FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4syncEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5gbumpEi FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5gbumpEi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5imbueERKSt6locale FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5imbueERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5pbumpEi FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5pbumpEi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5sgetcEv FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5sgetcEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5sgetnEPci FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5sgetnEPci@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5sputcEc FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5sputcEc@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5sputnEPKci FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5sputnEPKci@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5uflowEv FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5uflowEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6sbumpcEv FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6sbumpcEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6setbufEPci FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6setbufEPci@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6snextcEv FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6snextcEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6stosscEv FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6stosscEv@@GLIBCXX_3.4.10 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6xsgetnEPci FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6xsgetnEPci@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6xsputnEPKci FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6xsputnEPKci@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE7pubsyncEv FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE7pubsyncEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE7sungetcEv FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE7sungetcEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE8in_availEv FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE8in_availEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE8overflowEi FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE8overflowEi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE8pubimbueERKSt6locale FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE8pubimbueERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9pbackfailEi FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9pbackfailEi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9pubsetbufEPci FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9pubsetbufEPci@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9showmanycEv FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9showmanycEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9sputbackcEc FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9sputbackcEc@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9underflowEv FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9underflowEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEC1ERKS2_ FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEC1ERKS2_@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEC1Ev FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEC2ERKS2_ FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEC2ERKS2_@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEC2Ev FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEED0Ev FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEED1Ev FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEED2Ev FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEaSERKS2_ FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEaSERKS2_@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE10pubseekoffExSt12_Ios_SeekdirSt13_Ios_Openmode FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE10pubseekoffExSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE10pubseekposESt4fposI11__mbstate_tESt13_Ios_Openmode FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE10pubseekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE12__safe_gbumpEi FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE12__safe_gbumpEi@@GLIBCXX_3.4.16 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE12__safe_pbumpEi FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE12__safe_pbumpEi@@GLIBCXX_3.4.16 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4setgEPwS3_S3_ FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4setgEPwS3_S3_@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4setpEPwS3_ FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4setpEPwS3_@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4swapERS2_ FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4syncEv FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4syncEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5gbumpEi FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5gbumpEi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5imbueERKSt6locale FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5imbueERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5pbumpEi FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5pbumpEi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5sgetcEv FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5sgetcEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5sgetnEPwi FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5sgetnEPwi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5sputcEw FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5sputcEw@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5sputnEPKwi FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5sputnEPKwi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5uflowEv FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5uflowEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6sbumpcEv FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6sbumpcEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6setbufEPwi FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6setbufEPwi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6snextcEv FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6snextcEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6stosscEv FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6stosscEv@@GLIBCXX_3.4.10 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6xsgetnEPwi FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6xsgetnEPwi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6xsputnEPKwi FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6xsputnEPKwi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE7pubsyncEv FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE7pubsyncEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE7sungetcEv FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE7sungetcEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE8in_availEv FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE8in_availEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE8overflowEj FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE8overflowEj@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE8pubimbueERKSt6locale FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE8pubimbueERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9pbackfailEj FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9pbackfailEj@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9pubsetbufEPwi FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9pubsetbufEPwi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9showmanycEv FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9showmanycEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9sputbackcEw FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9sputbackcEw@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9underflowEv FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9underflowEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEC1ERKS2_ FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEC1ERKS2_@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEC1Ev FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEC2ERKS2_ FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEC2ERKS2_@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEC2Ev FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEED0Ev FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEED1Ev FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEED2Ev FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEaSERKS2_ FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEaSERKS2_@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE15_M_update_egptrEv FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE15_M_update_egptrEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE17_M_stringbuf_initESt13_Ios_Openmode FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE17_M_stringbuf_initESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strERKSs FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE4swapERS3_ FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE6setbufEPci FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE6setbufEPci@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE7_M_syncEPcjj FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE7_M_syncEPcjj@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE8_M_pbumpEPcS4_x FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE8_M_pbumpEPcS4_x@@GLIBCXX_3.4.16 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE8overflowEi FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE8overflowEi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9pbackfailEi FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9pbackfailEi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9showmanycEv FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9showmanycEv@@GLIBCXX_3.4.6 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9underflowEv FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9underflowEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS3_ FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1Ev FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS3_ FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2Ev FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEaSEOS3_ FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEaSEOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE15_M_update_egptrEv FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE15_M_update_egptrEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE17_M_stringbuf_initESt13_Ios_Openmode FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE17_M_stringbuf_initESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE3strERKSbIwS1_S2_E FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE3strERKSbIwS1_S2_E@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE4swapERS3_ FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE6setbufEPwi FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE6setbufEPwi@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE7_M_syncEPwjj FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE7_M_syncEPwjj@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE8_M_pbumpEPwS4_x FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE8_M_pbumpEPwS4_x@@GLIBCXX_3.4.16 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE8overflowEj FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE8overflowEj@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9pbackfailEj FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9pbackfailEj@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9showmanycEv FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9showmanycEv@@GLIBCXX_3.4.6 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9underflowEv FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9underflowEv@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS3_ FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1Ev FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS3_ FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2Ev FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEaSEOS3_ FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEaSEOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt15messages_bynameIcEC1EPKcj FUNC:_ZNSt15messages_bynameIcEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15messages_bynameIcEC1ERKSsj FUNC:_ZNSt15messages_bynameIcEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15messages_bynameIcEC2EPKcj FUNC:_ZNSt15messages_bynameIcEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15messages_bynameIcEC2ERKSsj FUNC:_ZNSt15messages_bynameIcEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15messages_bynameIcED0Ev FUNC:_ZNSt15messages_bynameIcED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15messages_bynameIcED1Ev FUNC:_ZNSt15messages_bynameIcED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15messages_bynameIcED2Ev FUNC:_ZNSt15messages_bynameIcED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15messages_bynameIwEC1EPKcj FUNC:_ZNSt15messages_bynameIwEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15messages_bynameIwEC1ERKSsj FUNC:_ZNSt15messages_bynameIwEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15messages_bynameIwEC2EPKcj FUNC:_ZNSt15messages_bynameIwEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15messages_bynameIwEC2ERKSsj FUNC:_ZNSt15messages_bynameIwEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15messages_bynameIwED0Ev FUNC:_ZNSt15messages_bynameIwED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15messages_bynameIwED1Ev FUNC:_ZNSt15messages_bynameIwED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15messages_bynameIwED2Ev FUNC:_ZNSt15messages_bynameIwED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15numpunct_bynameIcEC1EPKcj FUNC:_ZNSt15numpunct_bynameIcEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15numpunct_bynameIcEC1ERKSsj FUNC:_ZNSt15numpunct_bynameIcEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15numpunct_bynameIcEC2EPKcj FUNC:_ZNSt15numpunct_bynameIcEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15numpunct_bynameIcEC2ERKSsj FUNC:_ZNSt15numpunct_bynameIcEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15numpunct_bynameIcED0Ev FUNC:_ZNSt15numpunct_bynameIcED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15numpunct_bynameIcED1Ev FUNC:_ZNSt15numpunct_bynameIcED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15numpunct_bynameIcED2Ev FUNC:_ZNSt15numpunct_bynameIcED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15numpunct_bynameIwEC1EPKcj FUNC:_ZNSt15numpunct_bynameIwEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15numpunct_bynameIwEC1ERKSsj FUNC:_ZNSt15numpunct_bynameIwEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15numpunct_bynameIwEC2EPKcj FUNC:_ZNSt15numpunct_bynameIwEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15numpunct_bynameIwEC2ERKSsj FUNC:_ZNSt15numpunct_bynameIwEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15numpunct_bynameIwED0Ev FUNC:_ZNSt15numpunct_bynameIwED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15numpunct_bynameIwED1Ev FUNC:_ZNSt15numpunct_bynameIwED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15numpunct_bynameIwED2Ev FUNC:_ZNSt15numpunct_bynameIwED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1EPKcj FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1ERKSsj FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2EPKcj FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2ERKSsj FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1EPKcj FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1ERKSsj FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2EPKcj FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2ERKSsj FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1EPKcj FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1ERKNSt7__cxx1112basic_stringIcS2_SaIcEEEj FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1ERKNSt7__cxx1112basic_stringIcS2_SaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1ERKSsj FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2EPKcj FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2ERKNSt7__cxx1112basic_stringIcS2_SaIcEEEj FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2ERKNSt7__cxx1112basic_stringIcS2_SaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2ERKSsj FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1EPKcj FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1ERKSsj FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2EPKcj FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2ERKSsj FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15underflow_errorC1EPKc FUNC:_ZNSt15underflow_errorC1EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt15underflow_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt15underflow_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt15underflow_errorC1ERKSs FUNC:_ZNSt15underflow_errorC1ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt15underflow_errorC2EPKc FUNC:_ZNSt15underflow_errorC2EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt15underflow_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt15underflow_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt15underflow_errorC2ERKSs FUNC:_ZNSt15underflow_errorC2ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt15underflow_errorD0Ev FUNC:_ZNSt15underflow_errorD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15underflow_errorD1Ev FUNC:_ZNSt15underflow_errorD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt15underflow_errorD2Ev FUNC:_ZNSt15underflow_errorD2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt16__numpunct_cacheIcE8_M_cacheERKSt6locale FUNC:_ZNSt16__numpunct_cacheIcE8_M_cacheERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt16__numpunct_cacheIcEC1Ej FUNC:_ZNSt16__numpunct_cacheIcEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt16__numpunct_cacheIcEC2Ej FUNC:_ZNSt16__numpunct_cacheIcEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt16__numpunct_cacheIcED0Ev FUNC:_ZNSt16__numpunct_cacheIcED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt16__numpunct_cacheIcED1Ev FUNC:_ZNSt16__numpunct_cacheIcED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt16__numpunct_cacheIcED2Ev FUNC:_ZNSt16__numpunct_cacheIcED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt16__numpunct_cacheIwE8_M_cacheERKSt6locale FUNC:_ZNSt16__numpunct_cacheIwE8_M_cacheERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt16__numpunct_cacheIwEC1Ej FUNC:_ZNSt16__numpunct_cacheIwEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt16__numpunct_cacheIwEC2Ej FUNC:_ZNSt16__numpunct_cacheIwEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt16__numpunct_cacheIwED0Ev FUNC:_ZNSt16__numpunct_cacheIwED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt16__numpunct_cacheIwED1Ev FUNC:_ZNSt16__numpunct_cacheIwED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt16__numpunct_cacheIwED2Ev FUNC:_ZNSt16__numpunct_cacheIwED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt16__time_get_state17_M_finalize_stateEP2tm FUNC:_ZNSt16__time_get_state17_M_finalize_stateEP2tm@@GLIBCXX_3.4.30 -FUNC:_ZNSt16bad_array_lengthD0Ev FUNC:_ZNSt16bad_array_lengthD0Ev@@CXXABI_1.3.8 -FUNC:_ZNSt16bad_array_lengthD1Ev FUNC:_ZNSt16bad_array_lengthD1Ev@@CXXABI_1.3.8 -FUNC:_ZNSt16bad_array_lengthD2Ev FUNC:_ZNSt16bad_array_lengthD2Ev@@CXXABI_1.3.8 -FUNC:_ZNSt16invalid_argumentC1EPKc FUNC:_ZNSt16invalid_argumentC1EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt16invalid_argumentC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt16invalid_argumentC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt16invalid_argumentC1ERKSs FUNC:_ZNSt16invalid_argumentC1ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt16invalid_argumentC2EPKc FUNC:_ZNSt16invalid_argumentC2EPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt16invalid_argumentC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt16invalid_argumentC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt16invalid_argumentC2ERKSs FUNC:_ZNSt16invalid_argumentC2ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt16invalid_argumentD0Ev FUNC:_ZNSt16invalid_argumentD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt16invalid_argumentD1Ev FUNC:_ZNSt16invalid_argumentD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt16invalid_argumentD2Ev FUNC:_ZNSt16invalid_argumentD2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt16nested_exceptionD0Ev FUNC:_ZNSt16nested_exceptionD0Ev@@CXXABI_1.3.5 -FUNC:_ZNSt16nested_exceptionD1Ev FUNC:_ZNSt16nested_exceptionD1Ev@@CXXABI_1.3.5 -FUNC:_ZNSt16nested_exceptionD2Ev FUNC:_ZNSt16nested_exceptionD2Ev@@CXXABI_1.3.5 -FUNC:_ZNSt17__timepunct_cacheIcEC1Ej FUNC:_ZNSt17__timepunct_cacheIcEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt17__timepunct_cacheIcEC2Ej FUNC:_ZNSt17__timepunct_cacheIcEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt17__timepunct_cacheIcED0Ev FUNC:_ZNSt17__timepunct_cacheIcED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17__timepunct_cacheIcED1Ev FUNC:_ZNSt17__timepunct_cacheIcED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17__timepunct_cacheIcED2Ev FUNC:_ZNSt17__timepunct_cacheIcED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17__timepunct_cacheIwEC1Ej FUNC:_ZNSt17__timepunct_cacheIwEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt17__timepunct_cacheIwEC2Ej FUNC:_ZNSt17__timepunct_cacheIwEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt17__timepunct_cacheIwED0Ev FUNC:_ZNSt17__timepunct_cacheIwED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17__timepunct_cacheIwED1Ev FUNC:_ZNSt17__timepunct_cacheIwED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17__timepunct_cacheIwED2Ev FUNC:_ZNSt17__timepunct_cacheIwED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17bad_function_callD0Ev FUNC:_ZNSt17bad_function_callD0Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt17bad_function_callD1Ev FUNC:_ZNSt17bad_function_callD1Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt17bad_function_callD2Ev FUNC:_ZNSt17bad_function_callD2Ev@@GLIBCXX_3.4.15 -FUNC:_ZNSt17moneypunct_bynameIcLb0EEC1EPKcj FUNC:_ZNSt17moneypunct_bynameIcLb0EEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIcLb0EEC1ERKSsj FUNC:_ZNSt17moneypunct_bynameIcLb0EEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt17moneypunct_bynameIcLb0EEC2EPKcj FUNC:_ZNSt17moneypunct_bynameIcLb0EEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIcLb0EEC2ERKSsj FUNC:_ZNSt17moneypunct_bynameIcLb0EEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt17moneypunct_bynameIcLb0EED0Ev FUNC:_ZNSt17moneypunct_bynameIcLb0EED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIcLb0EED1Ev FUNC:_ZNSt17moneypunct_bynameIcLb0EED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIcLb0EED2Ev FUNC:_ZNSt17moneypunct_bynameIcLb0EED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIcLb1EEC1EPKcj FUNC:_ZNSt17moneypunct_bynameIcLb1EEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIcLb1EEC1ERKSsj FUNC:_ZNSt17moneypunct_bynameIcLb1EEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt17moneypunct_bynameIcLb1EEC2EPKcj FUNC:_ZNSt17moneypunct_bynameIcLb1EEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIcLb1EEC2ERKSsj FUNC:_ZNSt17moneypunct_bynameIcLb1EEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt17moneypunct_bynameIcLb1EED0Ev FUNC:_ZNSt17moneypunct_bynameIcLb1EED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIcLb1EED1Ev FUNC:_ZNSt17moneypunct_bynameIcLb1EED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIcLb1EED2Ev FUNC:_ZNSt17moneypunct_bynameIcLb1EED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIwLb0EEC1EPKcj FUNC:_ZNSt17moneypunct_bynameIwLb0EEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIwLb0EEC1ERKSsj FUNC:_ZNSt17moneypunct_bynameIwLb0EEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt17moneypunct_bynameIwLb0EEC2EPKcj FUNC:_ZNSt17moneypunct_bynameIwLb0EEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIwLb0EEC2ERKSsj FUNC:_ZNSt17moneypunct_bynameIwLb0EEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt17moneypunct_bynameIwLb0EED0Ev FUNC:_ZNSt17moneypunct_bynameIwLb0EED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIwLb0EED1Ev FUNC:_ZNSt17moneypunct_bynameIwLb0EED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIwLb0EED2Ev FUNC:_ZNSt17moneypunct_bynameIwLb0EED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIwLb1EEC1EPKcj FUNC:_ZNSt17moneypunct_bynameIwLb1EEC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIwLb1EEC1ERKSsj FUNC:_ZNSt17moneypunct_bynameIwLb1EEC1ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt17moneypunct_bynameIwLb1EEC2EPKcj FUNC:_ZNSt17moneypunct_bynameIwLb1EEC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIwLb1EEC2ERKSsj FUNC:_ZNSt17moneypunct_bynameIwLb1EEC2ERKSsj@@GLIBCXX_3.4.21 -FUNC:_ZNSt17moneypunct_bynameIwLb1EED0Ev FUNC:_ZNSt17moneypunct_bynameIwLb1EED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIwLb1EED1Ev FUNC:_ZNSt17moneypunct_bynameIwLb1EED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt17moneypunct_bynameIwLb1EED2Ev FUNC:_ZNSt17moneypunct_bynameIwLb1EED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIcLb0EE8_M_cacheERKSt6locale FUNC:_ZNSt18__moneypunct_cacheIcLb0EE8_M_cacheERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIcLb0EEC1Ej FUNC:_ZNSt18__moneypunct_cacheIcLb0EEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIcLb0EEC2Ej FUNC:_ZNSt18__moneypunct_cacheIcLb0EEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIcLb0EED0Ev FUNC:_ZNSt18__moneypunct_cacheIcLb0EED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIcLb0EED1Ev FUNC:_ZNSt18__moneypunct_cacheIcLb0EED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIcLb0EED2Ev FUNC:_ZNSt18__moneypunct_cacheIcLb0EED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIcLb1EE8_M_cacheERKSt6locale FUNC:_ZNSt18__moneypunct_cacheIcLb1EE8_M_cacheERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIcLb1EEC1Ej FUNC:_ZNSt18__moneypunct_cacheIcLb1EEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIcLb1EEC2Ej FUNC:_ZNSt18__moneypunct_cacheIcLb1EEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIcLb1EED0Ev FUNC:_ZNSt18__moneypunct_cacheIcLb1EED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIcLb1EED1Ev FUNC:_ZNSt18__moneypunct_cacheIcLb1EED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIcLb1EED2Ev FUNC:_ZNSt18__moneypunct_cacheIcLb1EED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIwLb0EE8_M_cacheERKSt6locale FUNC:_ZNSt18__moneypunct_cacheIwLb0EE8_M_cacheERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIwLb0EEC1Ej FUNC:_ZNSt18__moneypunct_cacheIwLb0EEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIwLb0EEC2Ej FUNC:_ZNSt18__moneypunct_cacheIwLb0EEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIwLb0EED0Ev FUNC:_ZNSt18__moneypunct_cacheIwLb0EED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIwLb0EED1Ev FUNC:_ZNSt18__moneypunct_cacheIwLb0EED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIwLb0EED2Ev FUNC:_ZNSt18__moneypunct_cacheIwLb0EED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIwLb1EE8_M_cacheERKSt6locale FUNC:_ZNSt18__moneypunct_cacheIwLb1EE8_M_cacheERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIwLb1EEC1Ej FUNC:_ZNSt18__moneypunct_cacheIwLb1EEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIwLb1EEC2Ej FUNC:_ZNSt18__moneypunct_cacheIwLb1EEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIwLb1EED0Ev FUNC:_ZNSt18__moneypunct_cacheIwLb1EED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIwLb1EED1Ev FUNC:_ZNSt18__moneypunct_cacheIwLb1EED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18__moneypunct_cacheIwLb1EED2Ev FUNC:_ZNSt18__moneypunct_cacheIwLb1EED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEE3strERKSs FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEE3strERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEE4swapERS3_ FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1EOS3_ FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1Ev FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2EOS3_ FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2Ev FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED2Ev FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEaSEOS3_ FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEaSEOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEE3strERKSbIwS1_S2_E FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEE3strERKSbIwS1_S2_E@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEE4swapERS3_ FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1EOS3_ FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1Ev FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2EOS3_ FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2Ev FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED2Ev FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEaSEOS3_ FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEaSEOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt18condition_variable10notify_allEv FUNC:_ZNSt18condition_variable10notify_allEv@@GLIBCXX_3.4.11 -FUNC:_ZNSt18condition_variable10notify_oneEv FUNC:_ZNSt18condition_variable10notify_oneEv@@GLIBCXX_3.4.11 -FUNC:_ZNSt18condition_variable4waitERSt11unique_lockISt5mutexE FUNC:_ZNSt18condition_variable4waitERSt11unique_lockISt5mutexE@@GLIBCXX_3.4.30 FUNC:_ZNSt18condition_variable4waitERSt11unique_lockISt5mutexE@GLIBCXX_3.4.11 -FUNC:_ZNSt18condition_variableC1Ev FUNC:_ZNSt18condition_variableC1Ev@@GLIBCXX_3.4.11 -FUNC:_ZNSt18condition_variableC2Ev FUNC:_ZNSt18condition_variableC2Ev@@GLIBCXX_3.4.11 -FUNC:_ZNSt18condition_variableD1Ev FUNC:_ZNSt18condition_variableD1Ev@@GLIBCXX_3.4.11 -FUNC:_ZNSt18condition_variableD2Ev FUNC:_ZNSt18condition_variableD2Ev@@GLIBCXX_3.4.11 -FUNC:_ZNSt19_Sp_make_shared_tag5_S_eqERKSt9type_info FUNC:_ZNSt19_Sp_make_shared_tag5_S_eqERKSt9type_info@@GLIBCXX_3.4.26 -FUNC:_ZNSt19__codecvt_utf8_baseIDiED0Ev FUNC:_ZNSt19__codecvt_utf8_baseIDiED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt19__codecvt_utf8_baseIDiED1Ev FUNC:_ZNSt19__codecvt_utf8_baseIDiED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt19__codecvt_utf8_baseIDiED2Ev FUNC:_ZNSt19__codecvt_utf8_baseIDiED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt19__codecvt_utf8_baseIDsED0Ev FUNC:_ZNSt19__codecvt_utf8_baseIDsED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt19__codecvt_utf8_baseIDsED1Ev FUNC:_ZNSt19__codecvt_utf8_baseIDsED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt19__codecvt_utf8_baseIDsED2Ev FUNC:_ZNSt19__codecvt_utf8_baseIDsED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt19__codecvt_utf8_baseIwED0Ev FUNC:_ZNSt19__codecvt_utf8_baseIwED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt19__codecvt_utf8_baseIwED1Ev FUNC:_ZNSt19__codecvt_utf8_baseIwED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt19__codecvt_utf8_baseIwED2Ev FUNC:_ZNSt19__codecvt_utf8_baseIwED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEE3strERKSs FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEE3strERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEE4swapERS3_ FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1EOS3_ FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1Ev FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2EOS3_ FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2Ev FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED2Ev FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEaSEOS3_ FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEaSEOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEE3strERKSbIwS1_S2_E FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEE3strERKSbIwS1_S2_E@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEE4swapERS3_ FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1EOS3_ FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1Ev FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2EOS3_ FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2Ev FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED2Ev FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEaSEOS3_ FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEaSEOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE3strERKSs FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE3strERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE4swapERS3_ FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1EOS3_ FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2EOS3_ FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2Ev FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED2Ev FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEaSEOS3_ FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEaSEOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE3strERKSbIwS1_S2_E FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE3strERKSbIwS1_S2_E@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE4swapERS3_ FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1EOS3_ FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1Ev FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2EOS3_ FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2Ev FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED2Ev FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEaSEOS3_ FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEaSEOS3_@@GLIBCXX_3.4.21 FUNC:_ZNSt19istreambuf_iteratorIcSt11char_traitsIcEEppEv@@GLIBCXX_3.4.5 FUNC:_ZNSt19istreambuf_iteratorIcSt11char_traitsIcEEppEv@GLIBCXX_3.4 FUNC:_ZNSt19istreambuf_iteratorIwSt11char_traitsIwEEppEv@@GLIBCXX_3.4.5 FUNC:_ZNSt19istreambuf_iteratorIwSt11char_traitsIwEEppEv@GLIBCXX_3.4 -FUNC:_ZNSt20__codecvt_utf16_baseIDiED0Ev FUNC:_ZNSt20__codecvt_utf16_baseIDiED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt20__codecvt_utf16_baseIDiED1Ev FUNC:_ZNSt20__codecvt_utf16_baseIDiED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt20__codecvt_utf16_baseIDiED2Ev FUNC:_ZNSt20__codecvt_utf16_baseIDiED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt20__codecvt_utf16_baseIDsED0Ev FUNC:_ZNSt20__codecvt_utf16_baseIDsED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt20__codecvt_utf16_baseIDsED1Ev FUNC:_ZNSt20__codecvt_utf16_baseIDsED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt20__codecvt_utf16_baseIDsED2Ev FUNC:_ZNSt20__codecvt_utf16_baseIDsED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt20__codecvt_utf16_baseIwED0Ev FUNC:_ZNSt20__codecvt_utf16_baseIwED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt20__codecvt_utf16_baseIwED1Ev FUNC:_ZNSt20__codecvt_utf16_baseIwED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt20__codecvt_utf16_baseIwED2Ev FUNC:_ZNSt20__codecvt_utf16_baseIwED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt20bad_array_new_lengthD0Ev FUNC:_ZNSt20bad_array_new_lengthD0Ev@@CXXABI_1.3.8 -FUNC:_ZNSt20bad_array_new_lengthD1Ev FUNC:_ZNSt20bad_array_new_lengthD1Ev@@CXXABI_1.3.8 -FUNC:_ZNSt20bad_array_new_lengthD2Ev FUNC:_ZNSt20bad_array_new_lengthD2Ev@@CXXABI_1.3.8 -FUNC:_ZNSt22condition_variable_anyC1Ev FUNC:_ZNSt22condition_variable_anyC1Ev@@GLIBCXX_3.4.11 -FUNC:_ZNSt22condition_variable_anyC2Ev FUNC:_ZNSt22condition_variable_anyC2Ev@@GLIBCXX_3.4.11 -FUNC:_ZNSt22condition_variable_anyD1Ev FUNC:_ZNSt22condition_variable_anyD1Ev@@GLIBCXX_3.4.11 -FUNC:_ZNSt22condition_variable_anyD2Ev FUNC:_ZNSt22condition_variable_anyD2Ev@@GLIBCXX_3.4.11 -FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDiED0Ev FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDiED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDiED1Ev FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDiED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDiED2Ev FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDiED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDsED0Ev FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDsED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDsED1Ev FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDsED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDsED2Ev FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDsED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt25__codecvt_utf8_utf16_baseIwED0Ev FUNC:_ZNSt25__codecvt_utf8_utf16_baseIwED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt25__codecvt_utf8_utf16_baseIwED1Ev FUNC:_ZNSt25__codecvt_utf8_utf16_baseIwED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt25__codecvt_utf8_utf16_baseIwED2Ev FUNC:_ZNSt25__codecvt_utf8_utf16_baseIwED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt28__atomic_futex_unsigned_base19_M_futex_notify_allEPj FUNC:_ZNSt28__atomic_futex_unsigned_base19_M_futex_notify_allEPj@@GLIBCXX_3.4.21 -FUNC:_ZNSt28__atomic_futex_unsigned_base19_M_futex_wait_untilEPjjbNSt6chrono8durationIxSt5ratioILx1ELx1EEEENS2_IxS3_ILx1ELx1000000000EEEE FUNC:_ZNSt28__atomic_futex_unsigned_base19_M_futex_wait_untilEPjjbNSt6chrono8durationIxSt5ratioILx1ELx1EEEENS2_IxS3_ILx1ELx1000000000EEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt28__atomic_futex_unsigned_base26_M_futex_wait_until_steadyEPjjbNSt6chrono8durationIxSt5ratioILx1ELx1EEEENS2_IxS3_ILx1ELx1000000000EEEE FUNC:_ZNSt28__atomic_futex_unsigned_base26_M_futex_wait_until_steadyEPjjbNSt6chrono8durationIxSt5ratioILx1ELx1EEEENS2_IxS3_ILx1ELx1000000000EEEE@@GLIBCXX_3.4.29 -FUNC:_ZNSt3_V214error_categoryD0Ev FUNC:_ZNSt3_V214error_categoryD0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt3_V214error_categoryD1Ev FUNC:_ZNSt3_V214error_categoryD1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt3_V214error_categoryD2Ev FUNC:_ZNSt3_V214error_categoryD2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt3_V215system_categoryEv FUNC:_ZNSt3_V215system_categoryEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt3_V216generic_categoryEv FUNC:_ZNSt3_V216generic_categoryEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt3pmr15memory_resourceD0Ev FUNC:_ZNSt3pmr15memory_resourceD0Ev@@GLIBCXX_3.4.28 -FUNC:_ZNSt3pmr15memory_resourceD1Ev FUNC:_ZNSt3pmr15memory_resourceD1Ev@@GLIBCXX_3.4.28 -FUNC:_ZNSt3pmr15memory_resourceD2Ev FUNC:_ZNSt3pmr15memory_resourceD2Ev@@GLIBCXX_3.4.28 -FUNC:_ZNSt3pmr19new_delete_resourceEv FUNC:_ZNSt3pmr19new_delete_resourceEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr20get_default_resourceEv FUNC:_ZNSt3pmr20get_default_resourceEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr20null_memory_resourceEv FUNC:_ZNSt3pmr20null_memory_resourceEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr20set_default_resourceEPNS_15memory_resourceE FUNC:_ZNSt3pmr20set_default_resourceEPNS_15memory_resourceE@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr25monotonic_buffer_resource13_M_new_bufferEjj FUNC:_ZNSt3pmr25monotonic_buffer_resource13_M_new_bufferEjj@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr25monotonic_buffer_resource18_M_release_buffersEv FUNC:_ZNSt3pmr25monotonic_buffer_resource18_M_release_buffersEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr25monotonic_buffer_resourceD0Ev FUNC:_ZNSt3pmr25monotonic_buffer_resourceD0Ev@@GLIBCXX_3.4.28 -FUNC:_ZNSt3pmr25monotonic_buffer_resourceD1Ev FUNC:_ZNSt3pmr25monotonic_buffer_resourceD1Ev@@GLIBCXX_3.4.28 -FUNC:_ZNSt3pmr25monotonic_buffer_resourceD2Ev FUNC:_ZNSt3pmr25monotonic_buffer_resourceD2Ev@@GLIBCXX_3.4.28 -FUNC:_ZNSt3pmr26synchronized_pool_resource11do_allocateEjj FUNC:_ZNSt3pmr26synchronized_pool_resource11do_allocateEjj@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr26synchronized_pool_resource13do_deallocateEPvjj FUNC:_ZNSt3pmr26synchronized_pool_resource13do_deallocateEPvjj@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr26synchronized_pool_resource7releaseEv FUNC:_ZNSt3pmr26synchronized_pool_resource7releaseEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr26synchronized_pool_resourceC1ERKNS_12pool_optionsEPNS_15memory_resourceE FUNC:_ZNSt3pmr26synchronized_pool_resourceC1ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr26synchronized_pool_resourceC2ERKNS_12pool_optionsEPNS_15memory_resourceE FUNC:_ZNSt3pmr26synchronized_pool_resourceC2ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr26synchronized_pool_resourceD1Ev FUNC:_ZNSt3pmr26synchronized_pool_resourceD1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr26synchronized_pool_resourceD2Ev FUNC:_ZNSt3pmr26synchronized_pool_resourceD2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr28unsynchronized_pool_resource11do_allocateEjj FUNC:_ZNSt3pmr28unsynchronized_pool_resource11do_allocateEjj@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr28unsynchronized_pool_resource13do_deallocateEPvjj FUNC:_ZNSt3pmr28unsynchronized_pool_resource13do_deallocateEPvjj@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr28unsynchronized_pool_resource7releaseEv FUNC:_ZNSt3pmr28unsynchronized_pool_resource7releaseEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr28unsynchronized_pool_resourceC1ERKNS_12pool_optionsEPNS_15memory_resourceE FUNC:_ZNSt3pmr28unsynchronized_pool_resourceC1ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr28unsynchronized_pool_resourceC2ERKNS_12pool_optionsEPNS_15memory_resourceE FUNC:_ZNSt3pmr28unsynchronized_pool_resourceC2ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr28unsynchronized_pool_resourceD1Ev FUNC:_ZNSt3pmr28unsynchronized_pool_resourceD1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt3pmr28unsynchronized_pool_resourceD2Ev FUNC:_ZNSt3pmr28unsynchronized_pool_resourceD2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt5ctypeIcE13classic_tableEv FUNC:_ZNSt5ctypeIcE13classic_tableEv@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIcEC1EP15__locale_structPKtbj FUNC:_ZNSt5ctypeIcEC1EP15__locale_structPKtbj@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIcEC1EPKtbj FUNC:_ZNSt5ctypeIcEC1EPKtbj@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIcEC2EP15__locale_structPKtbj FUNC:_ZNSt5ctypeIcEC2EP15__locale_structPKtbj@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIcEC2EPKtbj FUNC:_ZNSt5ctypeIcEC2EPKtbj@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIcED0Ev FUNC:_ZNSt5ctypeIcED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIcED1Ev FUNC:_ZNSt5ctypeIcED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIcED2Ev FUNC:_ZNSt5ctypeIcED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIwE19_M_initialize_ctypeEv FUNC:_ZNSt5ctypeIwE19_M_initialize_ctypeEv@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIwEC1EP15__locale_structj FUNC:_ZNSt5ctypeIwEC1EP15__locale_structj@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIwEC1Ej FUNC:_ZNSt5ctypeIwEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIwEC2EP15__locale_structj FUNC:_ZNSt5ctypeIwEC2EP15__locale_structj@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIwEC2Ej FUNC:_ZNSt5ctypeIwEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIwED0Ev FUNC:_ZNSt5ctypeIwED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIwED1Ev FUNC:_ZNSt5ctypeIwED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt5ctypeIwED2Ev FUNC:_ZNSt5ctypeIwED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt6__norm15_List_node_base10_M_reverseEv FUNC:_ZNSt6__norm15_List_node_base10_M_reverseEv@@GLIBCXX_3.4.14 -FUNC:_ZNSt6__norm15_List_node_base11_M_transferEPS0_S1_ FUNC:_ZNSt6__norm15_List_node_base11_M_transferEPS0_S1_@@GLIBCXX_3.4.14 -FUNC:_ZNSt6__norm15_List_node_base4hookEPS0_ FUNC:_ZNSt6__norm15_List_node_base4hookEPS0_@@GLIBCXX_3.4.9 -FUNC:_ZNSt6__norm15_List_node_base4swapERS0_S1_ FUNC:_ZNSt6__norm15_List_node_base4swapERS0_S1_@@GLIBCXX_3.4.9 -FUNC:_ZNSt6__norm15_List_node_base6unhookEv FUNC:_ZNSt6__norm15_List_node_base6unhookEv@@GLIBCXX_3.4.9 -FUNC:_ZNSt6__norm15_List_node_base7_M_hookEPS0_ FUNC:_ZNSt6__norm15_List_node_base7_M_hookEPS0_@@GLIBCXX_3.4.14 -FUNC:_ZNSt6__norm15_List_node_base7reverseEv FUNC:_ZNSt6__norm15_List_node_base7reverseEv@@GLIBCXX_3.4.9 -FUNC:_ZNSt6__norm15_List_node_base8transferEPS0_S1_ FUNC:_ZNSt6__norm15_List_node_base8transferEPS0_S1_@@GLIBCXX_3.4.9 -FUNC:_ZNSt6__norm15_List_node_base9_M_unhookEv FUNC:_ZNSt6__norm15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.14 -FUNC:_ZNSt6chrono11locate_zoneESt17basic_string_viewIcSt11char_traitsIcEE FUNC:_ZNSt6chrono11locate_zoneESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.31 -FUNC:_ZNSt6chrono11reload_tzdbEv FUNC:_ZNSt6chrono11reload_tzdbEv@@GLIBCXX_3.4.31 -FUNC:_ZNSt6chrono12current_zoneEv FUNC:_ZNSt6chrono12current_zoneEv@@GLIBCXX_3.4.31 -FUNC:_ZNSt6chrono12system_clock3nowEv FUNC:_ZNSt6chrono12system_clock3nowEv@@GLIBCXX_3.4.11 -FUNC:_ZNSt6chrono13get_tzdb_listEv FUNC:_ZNSt6chrono13get_tzdb_listEv@@GLIBCXX_3.4.31 -FUNC:_ZNSt6chrono14remote_versionB5cxx11Ev FUNC:_ZNSt6chrono14remote_versionB5cxx11Ev@@GLIBCXX_3.4.31 -FUNC:_ZNSt6chrono3_V212steady_clock3nowEv FUNC:_ZNSt6chrono3_V212steady_clock3nowEv@@GLIBCXX_3.4.19 -FUNC:_ZNSt6chrono3_V212system_clock3nowEv FUNC:_ZNSt6chrono3_V212system_clock3nowEv@@GLIBCXX_3.4.19 -FUNC:_ZNSt6chrono8get_tzdbEv FUNC:_ZNSt6chrono8get_tzdbEv@@GLIBCXX_3.4.31 -FUNC:_ZNSt6chrono9tzdb_list11erase_afterENS0_14const_iteratorE FUNC:_ZNSt6chrono9tzdb_list11erase_afterENS0_14const_iteratorE@@GLIBCXX_3.4.31 -FUNC:_ZNSt6chrono9tzdb_list14const_iteratorppEi FUNC:_ZNSt6chrono9tzdb_list14const_iteratorppEi@@GLIBCXX_3.4.31 -FUNC:_ZNSt6chrono9tzdb_list14const_iteratorppEv FUNC:_ZNSt6chrono9tzdb_list14const_iteratorppEv@@GLIBCXX_3.4.31 -FUNC:_ZNSt6gslice8_IndexerC1EjRKSt8valarrayIjES4_ FUNC:_ZNSt6gslice8_IndexerC1EjRKSt8valarrayIjES4_@@GLIBCXX_3.4 -FUNC:_ZNSt6gslice8_IndexerC2EjRKSt8valarrayIjES4_ FUNC:_ZNSt6gslice8_IndexerC2EjRKSt8valarrayIjES4_@@GLIBCXX_3.4 -FUNC:_ZNSt6locale11_M_coalesceERKS_S1_i FUNC:_ZNSt6locale11_M_coalesceERKS_S1_i@@GLIBCXX_3.4 -FUNC:_ZNSt6locale21_S_normalize_categoryEi FUNC:_ZNSt6locale21_S_normalize_categoryEi@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5_Impl16_M_install_cacheEPKNS_5facetEj FUNC:_ZNSt6locale5_Impl16_M_install_cacheEPKNS_5facetEj@@GLIBCXX_3.4.7 -FUNC:_ZNSt6locale5_Impl16_M_install_facetEPKNS_2idEPKNS_5facetE FUNC:_ZNSt6locale5_Impl16_M_install_facetEPKNS_2idEPKNS_5facetE@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5_Impl16_M_replace_facetEPKS0_PKNS_2idE FUNC:_ZNSt6locale5_Impl16_M_replace_facetEPKS0_PKNS_2idE@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5_Impl19_M_replace_categoryEPKS0_PKPKNS_2idE FUNC:_ZNSt6locale5_Impl19_M_replace_categoryEPKS0_PKPKNS_2idE@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5_Impl21_M_replace_categoriesEPKS0_i FUNC:_ZNSt6locale5_Impl21_M_replace_categoriesEPKS0_i@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5_ImplC1EPKcj FUNC:_ZNSt6locale5_ImplC1EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5_ImplC1ERKS0_j FUNC:_ZNSt6locale5_ImplC1ERKS0_j@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5_ImplC1Ej FUNC:_ZNSt6locale5_ImplC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5_ImplC2EPKcj FUNC:_ZNSt6locale5_ImplC2EPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5_ImplC2ERKS0_j FUNC:_ZNSt6locale5_ImplC2ERKS0_j@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5_ImplC2Ej FUNC:_ZNSt6locale5_ImplC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5_ImplD1Ev FUNC:_ZNSt6locale5_ImplD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5_ImplD2Ev FUNC:_ZNSt6locale5_ImplD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5facet13_S_get_c_nameEv FUNC:_ZNSt6locale5facet13_S_get_c_nameEv@@GLIBCXX_3.4.6 -FUNC:_ZNSt6locale5facet15_S_get_c_localeEv FUNC:_ZNSt6locale5facet15_S_get_c_localeEv@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5facet17_S_clone_c_localeERP15__locale_struct FUNC:_ZNSt6locale5facet17_S_clone_c_localeERP15__locale_struct@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5facet18_S_create_c_localeERP15__locale_structPKcS2_ FUNC:_ZNSt6locale5facet18_S_create_c_localeERP15__locale_structPKcS2_@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5facet19_S_destroy_c_localeERP15__locale_struct FUNC:_ZNSt6locale5facet19_S_destroy_c_localeERP15__locale_struct@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5facetD0Ev FUNC:_ZNSt6locale5facetD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5facetD1Ev FUNC:_ZNSt6locale5facetD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt6locale5facetD2Ev FUNC:_ZNSt6locale5facetD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt6locale6globalERKS_ FUNC:_ZNSt6locale6globalERKS_@@GLIBCXX_3.4 -FUNC:_ZNSt6locale7classicEv FUNC:_ZNSt6locale7classicEv@@GLIBCXX_3.4 -FUNC:_ZNSt6localeC1EPKc FUNC:_ZNSt6localeC1EPKc@@GLIBCXX_3.4 -FUNC:_ZNSt6localeC1EPNS_5_ImplE FUNC:_ZNSt6localeC1EPNS_5_ImplE@@GLIBCXX_3.4 -FUNC:_ZNSt6localeC1ERKS_ FUNC:_ZNSt6localeC1ERKS_@@GLIBCXX_3.4 -FUNC:_ZNSt6localeC1ERKS_PKci FUNC:_ZNSt6localeC1ERKS_PKci@@GLIBCXX_3.4 -FUNC:_ZNSt6localeC1ERKS_S1_i FUNC:_ZNSt6localeC1ERKS_S1_i@@GLIBCXX_3.4 -FUNC:_ZNSt6localeC1Ev FUNC:_ZNSt6localeC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt6localeC2EPKc FUNC:_ZNSt6localeC2EPKc@@GLIBCXX_3.4 -FUNC:_ZNSt6localeC2EPNS_5_ImplE FUNC:_ZNSt6localeC2EPNS_5_ImplE@@GLIBCXX_3.4 -FUNC:_ZNSt6localeC2ERKS_ FUNC:_ZNSt6localeC2ERKS_@@GLIBCXX_3.4 -FUNC:_ZNSt6localeC2ERKS_PKci FUNC:_ZNSt6localeC2ERKS_PKci@@GLIBCXX_3.4 -FUNC:_ZNSt6localeC2ERKS_S1_i FUNC:_ZNSt6localeC2ERKS_S1_i@@GLIBCXX_3.4 -FUNC:_ZNSt6localeC2Ev FUNC:_ZNSt6localeC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt6localeD1Ev FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt6localeD2Ev FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt6localeaSERKS_ FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4 -FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11 -FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFvvE FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFvvE@@GLIBCXX_3.4.21 -FUNC:_ZNSt6thread15_M_start_threadESt10unique_ptrINS_6_StateESt14default_deleteIS1_EEPFvvE FUNC:_ZNSt6thread15_M_start_threadESt10unique_ptrINS_6_StateESt14default_deleteIS1_EEPFvvE@@GLIBCXX_3.4.22 -FUNC:_ZNSt6thread20hardware_concurrencyEv FUNC:_ZNSt6thread20hardware_concurrencyEv@@GLIBCXX_3.4.17 -FUNC:_ZNSt6thread4joinEv FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11 -FUNC:_ZNSt6thread6_StateD0Ev FUNC:_ZNSt6thread6_StateD0Ev@@GLIBCXX_3.4.22 -FUNC:_ZNSt6thread6_StateD1Ev FUNC:_ZNSt6thread6_StateD1Ev@@GLIBCXX_3.4.22 -FUNC:_ZNSt6thread6_StateD2Ev FUNC:_ZNSt6thread6_StateD2Ev@@GLIBCXX_3.4.22 -FUNC:_ZNSt6thread6detachEv FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11 -FUNC:_ZNSt7__cxx1110moneypunctIcLb0EE24_M_initialize_moneypunctEP15__locale_structPKc FUNC:_ZNSt7__cxx1110moneypunctIcLb0EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC1EP15__locale_structPKcj FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC1EP15__locale_structPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC1EPSt18__moneypunct_cacheIcLb0EEj FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC1EPSt18__moneypunct_cacheIcLb0EEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC1Ej FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC2EP15__locale_structPKcj FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC2EP15__locale_structPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC2EPSt18__moneypunct_cacheIcLb0EEj FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC2EPSt18__moneypunct_cacheIcLb0EEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC2Ej FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb0EED0Ev FUNC:_ZNSt7__cxx1110moneypunctIcLb0EED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb0EED1Ev FUNC:_ZNSt7__cxx1110moneypunctIcLb0EED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb0EED2Ev FUNC:_ZNSt7__cxx1110moneypunctIcLb0EED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb1EE24_M_initialize_moneypunctEP15__locale_structPKc FUNC:_ZNSt7__cxx1110moneypunctIcLb1EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC1EP15__locale_structPKcj FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC1EP15__locale_structPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC1EPSt18__moneypunct_cacheIcLb1EEj FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC1EPSt18__moneypunct_cacheIcLb1EEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC1Ej FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC2EP15__locale_structPKcj FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC2EP15__locale_structPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC2EPSt18__moneypunct_cacheIcLb1EEj FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC2EPSt18__moneypunct_cacheIcLb1EEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC2Ej FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb1EED0Ev FUNC:_ZNSt7__cxx1110moneypunctIcLb1EED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb1EED1Ev FUNC:_ZNSt7__cxx1110moneypunctIcLb1EED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIcLb1EED2Ev FUNC:_ZNSt7__cxx1110moneypunctIcLb1EED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb0EE24_M_initialize_moneypunctEP15__locale_structPKc FUNC:_ZNSt7__cxx1110moneypunctIwLb0EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC1EP15__locale_structPKcj FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC1EP15__locale_structPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC1EPSt18__moneypunct_cacheIwLb0EEj FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC1EPSt18__moneypunct_cacheIwLb0EEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC1Ej FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC2EP15__locale_structPKcj FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC2EP15__locale_structPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC2EPSt18__moneypunct_cacheIwLb0EEj FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC2EPSt18__moneypunct_cacheIwLb0EEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC2Ej FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb0EED0Ev FUNC:_ZNSt7__cxx1110moneypunctIwLb0EED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb0EED1Ev FUNC:_ZNSt7__cxx1110moneypunctIwLb0EED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb0EED2Ev FUNC:_ZNSt7__cxx1110moneypunctIwLb0EED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb1EE24_M_initialize_moneypunctEP15__locale_structPKc FUNC:_ZNSt7__cxx1110moneypunctIwLb1EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC1EP15__locale_structPKcj FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC1EP15__locale_structPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC1EPSt18__moneypunct_cacheIwLb1EEj FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC1EPSt18__moneypunct_cacheIwLb1EEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC1Ej FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC2EP15__locale_structPKcj FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC2EP15__locale_structPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC2EPSt18__moneypunct_cacheIwLb1EEj FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC2EPSt18__moneypunct_cacheIwLb1EEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC2Ej FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb1EED0Ev FUNC:_ZNSt7__cxx1110moneypunctIwLb1EED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb1EED1Ev FUNC:_ZNSt7__cxx1110moneypunctIwLb1EED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1110moneypunctIwLb1EED2Ev FUNC:_ZNSt7__cxx1110moneypunctIwLb1EED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_destroyEj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_destroyEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_disposeEv FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_disposeEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_replaceEjjPKcj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_replaceEjjPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_S_compareEjj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_S_compareEjj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE11_M_capacityEj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE11_M_capacityEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE11_S_allocateERS3_j FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE11_S_allocateERS3_j@@GLIBCXX_3.4.32 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC1EPcOS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC1EPcOS3_@@GLIBCXX_3.4.23 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC1EPcRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC1EPcRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC2EPcOS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC2EPcOS3_@@GLIBCXX_3.4.23 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC2EPcRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC2EPcRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructEjc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructEjc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPKcS4_EEEEvT_SB_St20forward_iterator_tag +FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructILb0EEEvPKcj@@GLIBCXX_3.4.34 +FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructILb1EEEvPKcj@@GLIBCXX_3.4.34 FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPKcS4_EEEEvT_SB_St20forward_iterator_tag@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPcS4_EEEEvT_SA_St20forward_iterator_tag FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPcS4_EEEEvT_SA_St20forward_iterator_tag@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPcEEvT_S7_St20forward_iterator_tag FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPcEEvT_S7_St20forward_iterator_tag@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12__sv_wrapperC1ESt17basic_string_viewIcS2_E FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12__sv_wrapperC1ESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12__sv_wrapperC2ESt17basic_string_viewIcS2_E FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12__sv_wrapperC2ESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_local_dataEv FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_local_dataEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_set_lengthEj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_set_lengthEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcS4_EESA_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcS4_EESA_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS5_S4_EES8_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS5_S4_EES8_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcPKcS7_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcPKcS7_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcS5_S5_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcS5_S5_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13shrink_to_fitEv FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13shrink_to_fitEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE14_M_replace_auxEjjjc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE14_M_replace_auxEjjjc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE15_M_replace_coldEPcjPKcjj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE15_M_replace_coldEPcjPKcjj@@GLIBCXX_3.4.31 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16_M_get_allocatorEv FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16_M_get_allocatorEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17_S_to_string_viewESt17basic_string_viewIcS2_E FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17_S_to_string_viewESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE18_M_construct_aux_2Ejc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE18_M_construct_aux_2Ejc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE2atEj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE2atEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE3endEv FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE3endEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4backEv FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4backEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4dataEv FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4dataEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4rendEv FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4rendEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4swapERS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5beginEv FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5beginEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5clearEv FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5clearEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEN9__gnu_cxx17__normal_iteratorIPKcS4_EE FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEN9__gnu_cxx17__normal_iteratorIPKcS4_EE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEN9__gnu_cxx17__normal_iteratorIPcS4_EE FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEN9__gnu_cxx17__normal_iteratorIPcS4_EE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEjj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEjj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5frontEv FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5frontEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendEPKc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendEPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendEPKcj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendEPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendERKS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendERKS4_jj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendERKS4_jj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendESt16initializer_listIcE FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendESt16initializer_listIcE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendEjc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendEjc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEOS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEPKc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEPKcj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignERKS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignERKS4_jj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignERKS4_jj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignESt16initializer_listIcE FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignESt16initializer_listIcE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEjc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEjc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EESt16initializer_listIcE FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EESt16initializer_listIcE@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EEc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EEc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EEjc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EEjc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPcS4_EESt16initializer_listIcE FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPcS4_EESt16initializer_listIcE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPcS4_EEc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPcS4_EEc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPcS4_EEjc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPcS4_EEjc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEjPKc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEjPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEjPKcj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEjPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEjRKS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEjRKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEjRKS4_jj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEjRKS4_jj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEjjc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEjjc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertIN9__gnu_cxx17__normal_iteratorIPcS4_EEEEvS9_T_SA_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertIN9__gnu_cxx17__normal_iteratorIPcS4_EEEEvS9_T_SA_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6rbeginEv FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6rbeginEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6resizeEj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6resizeEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6resizeEjc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6resizeEjc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7_M_dataEPc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7_M_dataEPc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7_S_copyEPcPKcj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7_S_copyEPcPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7_S_moveEPcPKcj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7_S_moveEPcPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_NS6_IPcS4_EESB_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_NS6_IPcS4_EESB_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_PcSA_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_PcSA_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_RKS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_RKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_S8_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_S8_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_S8_S8_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_S8_S8_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_S8_j FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_S8_j@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_S9_S9_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_S9_S9_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_St16initializer_listIcE FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_St16initializer_listIcE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_jc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_jc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_NS6_IPKcS4_EESB_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_NS6_IPKcS4_EESB_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_PKc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_PKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_PKcSA_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_PKcSA_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_PKcj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_PKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_RKS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_RKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_S7_S7_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_S7_S7_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_S8_S8_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_S8_S8_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_jc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_jc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEjjPKc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEjjPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEjjPKcj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEjjPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEjjRKS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEjjRKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEjjRKS4_jj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEjjRKS4_jj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEjjjc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEjjjc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7reserveEj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7reserveEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7reserveEv FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7reserveEv@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_eraseEjj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_eraseEjj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8pop_backEv FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8pop_backEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_appendEPKcj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_appendEPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_assignERKS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_assignERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_createERjj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_createERjj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_lengthEj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_lengthEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEjjPKcj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEjjPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_S_assignEPcjc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_S_assignEPcjc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9push_backEc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9push_backEc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ENS4_12__sv_wrapperERKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EOS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EOS4_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EOS4_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcjRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcjRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_jRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_jRKS3_@@GLIBCXX_3.4.23 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_jj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_jj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_jjRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_jjRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ESt16initializer_listIcERKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ESt16initializer_listIcERKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EjcRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EjcRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IN9__gnu_cxx17__normal_iteratorIPcS4_EEvEET_SA_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IN9__gnu_cxx17__normal_iteratorIPcS4_EEvEET_SA_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IPKcvEET_S8_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IPKcvEET_S8_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IPcvEET_S7_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IPcvEET_S7_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ENS4_12__sv_wrapperERKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EOS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EOS4_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EOS4_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EPKcjRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EPKcjRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_jRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_jRKS3_@@GLIBCXX_3.4.23 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_jj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_jj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_jjRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_jjRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ESt16initializer_listIcERKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ESt16initializer_listIcERKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EjcRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EjcRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2Ev FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IN9__gnu_cxx17__normal_iteratorIPcS4_EEvEET_SA_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IN9__gnu_cxx17__normal_iteratorIPcS4_EEvEET_SA_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IPKcvEET_S8_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IPKcvEET_S8_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IPcvEET_S7_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IPcvEET_S7_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED2Ev FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEOS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEPKc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSERKS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSESt16initializer_listIcE FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSESt16initializer_listIcE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEixEj FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEixEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLEPKc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLEPKc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLERKS4_ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLESt16initializer_listIcE FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLESt16initializer_listIcE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLEc FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLEc@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE10_M_destroyEj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE10_M_destroyEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE10_M_disposeEv FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE10_M_disposeEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE10_M_replaceEjjPKwj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE10_M_replaceEjjPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE10_S_compareEjj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE10_S_compareEjj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_capacityEj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_capacityEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_S_allocateERS3_j FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_S_allocateERS3_j@@GLIBCXX_3.4.32 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC1EPwOS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC1EPwOS3_@@GLIBCXX_3.4.23 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC1EPwRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC1EPwRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC2EPwOS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC2EPwOS3_@@GLIBCXX_3.4.23 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC2EPwRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC2EPwRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructEjw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructEjw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPKwS4_EEEEvT_SB_St20forward_iterator_tag +FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructILb0EEEvPKwj@@GLIBCXX_3.4.34 +FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructILb1EEEvPKwj@@GLIBCXX_3.4.34 FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPKwS4_EEEEvT_SB_St20forward_iterator_tag@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPwS4_EEEEvT_SA_St20forward_iterator_tag FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPwS4_EEEEvT_SA_St20forward_iterator_tag@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIPKwEEvT_S8_St20forward_iterator_tag FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIPKwEEvT_S8_St20forward_iterator_tag@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIPwEEvT_S7_St20forward_iterator_tag FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIPwEEvT_S7_St20forward_iterator_tag@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12__sv_wrapperC1ESt17basic_string_viewIwS2_E FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12__sv_wrapperC1ESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12__sv_wrapperC2ESt17basic_string_viewIwS2_E FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12__sv_wrapperC2ESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_local_dataEv FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_local_dataEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_set_lengthEj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_set_lengthEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS4_EESA_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS4_EESA_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIS5_S4_EES8_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIS5_S4_EES8_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwPKwS7_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwPKwS7_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS5_S5_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS5_S5_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13shrink_to_fitEv FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13shrink_to_fitEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE14_M_replace_auxEjjjw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE14_M_replace_auxEjjjw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE15_M_replace_coldEPwjPKwjj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE15_M_replace_coldEPwjPKwjj@@GLIBCXX_3.4.31 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16_M_get_allocatorEv FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16_M_get_allocatorEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17_S_to_string_viewESt17basic_string_viewIwS2_E FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17_S_to_string_viewESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE18_M_construct_aux_2Ejw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE18_M_construct_aux_2Ejw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE2atEj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE2atEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE3endEv FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4backEv FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4dataEv FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4rendEv FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4swapERS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5beginEv FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5clearEv FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5clearEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPKwS4_EE FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPKwS4_EE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS4_EE FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS4_EE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEjj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEjj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5frontEv FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5frontEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendEPKw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendEPKw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendEPKwj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendEPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendERKS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendERKS4_jj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendERKS4_jj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendESt16initializer_listIwE FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendESt16initializer_listIwE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendEjw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendEjw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEOS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEPKw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEPKw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEPKwj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignERKS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignERKS4_jj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignERKS4_jj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignESt16initializer_listIwE FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignESt16initializer_listIwE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEjw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEjw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EESt16initializer_listIwE FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EESt16initializer_listIwE@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EEjw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EEjw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EEw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EEw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS4_EESt16initializer_listIwE FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS4_EESt16initializer_listIwE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS4_EEjw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS4_EEjw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS4_EEw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS4_EEw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEjPKw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEjPKw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEjPKwj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEjPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEjRKS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEjRKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEjRKS4_jj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEjRKS4_jj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEjjw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEjjw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertIN9__gnu_cxx17__normal_iteratorIPwS4_EEEEvS9_T_SA_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertIN9__gnu_cxx17__normal_iteratorIPwS4_EEEEvS9_T_SA_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6rbeginEv FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6rbeginEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6resizeEj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6resizeEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6resizeEjw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6resizeEjw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7_M_dataEPw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7_M_dataEPw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7_S_copyEPwPKwj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7_S_copyEPwPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7_S_moveEPwPKwj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7_S_moveEPwPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_NS6_IPwS4_EESB_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_NS6_IPwS4_EESB_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_PwSA_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_PwSA_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_RKS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_RKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_S8_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_S8_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_S8_S8_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_S8_S8_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_S8_j FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_S8_j@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_S9_S9_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_S9_S9_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_St16initializer_listIwE FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_St16initializer_listIwE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_jw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_jw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_NS6_IPKwS4_EESB_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_NS6_IPKwS4_EESB_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_PKw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_PKw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_PKwSA_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_PKwSA_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_PKwj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_PKwj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_RKS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_RKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_S7_S7_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_S7_S7_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_S8_S8_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_S8_S8_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_jw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_jw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEjjPKw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEjjPKw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEjjPKwj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEjjPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEjjRKS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEjjRKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEjjRKS4_jj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEjjRKS4_jj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEjjjw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEjjjw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7reserveEj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7reserveEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7reserveEv FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7reserveEv@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_eraseEjj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_eraseEjj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8pop_backEv FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8pop_backEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_appendEPKwj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_appendEPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_assignERKS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_assignERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_createERjj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_createERjj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_lengthEj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_lengthEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_mutateEjjPKwj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_mutateEjjPKwj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_S_assignEPwjw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_S_assignEPwjw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9push_backEw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9push_backEw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ENS4_12__sv_wrapperERKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EOS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EOS4_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EOS4_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EPKwRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EPKwRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EPKwjRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EPKwjRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_jRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_jRKS3_@@GLIBCXX_3.4.23 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_jj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_jj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_jjRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_jjRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ESt16initializer_listIwERKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ESt16initializer_listIwERKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EjwRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EjwRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1Ev FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IN9__gnu_cxx17__normal_iteratorIPwS4_EEvEET_SA_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IN9__gnu_cxx17__normal_iteratorIPwS4_EEvEET_SA_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IPKwvEET_S8_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IPKwvEET_S8_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IPwvEET_S7_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IPwvEET_S7_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ENS4_12__sv_wrapperERKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EOS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EOS4_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EOS4_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EPKwRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EPKwRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EPKwjRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EPKwjRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_jRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_jRKS3_@@GLIBCXX_3.4.23 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_jj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_jj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_jjRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_jjRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ESt16initializer_listIwERKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ESt16initializer_listIwERKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EjwRKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EjwRKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2Ev FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2IN9__gnu_cxx17__normal_iteratorIPwS4_EEvEET_SA_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2IN9__gnu_cxx17__normal_iteratorIPwS4_EEvEET_SA_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2IPKwvEET_S8_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2IPKwvEET_S8_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2IPwvEET_S7_RKS3_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2IPwvEET_S7_RKS3_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEED2Ev FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSEOS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSEOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSEPKw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSEPKw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSERKS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSESt16initializer_listIwE FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSESt16initializer_listIwE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSEw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSEw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEixEj FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEixEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEpLEPKw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEpLEPKw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEpLERKS4_ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEpLERKS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEpLESt16initializer_listIwE FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEpLESt16initializer_listIwE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEpLEw FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEpLEw@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1114collate_bynameIcEC1EPKcj FUNC:_ZNSt7__cxx1114collate_bynameIcEC1EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1114collate_bynameIcEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1114collate_bynameIcEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1114collate_bynameIcEC2EPKcj FUNC:_ZNSt7__cxx1114collate_bynameIcEC2EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1114collate_bynameIcEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1114collate_bynameIcEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1114collate_bynameIcED0Ev FUNC:_ZNSt7__cxx1114collate_bynameIcED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1114collate_bynameIcED1Ev FUNC:_ZNSt7__cxx1114collate_bynameIcED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1114collate_bynameIcED2Ev FUNC:_ZNSt7__cxx1114collate_bynameIcED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1114collate_bynameIwEC1EPKcj FUNC:_ZNSt7__cxx1114collate_bynameIwEC1EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1114collate_bynameIwEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1114collate_bynameIwEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1114collate_bynameIwEC2EPKcj FUNC:_ZNSt7__cxx1114collate_bynameIwEC2EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1114collate_bynameIwEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1114collate_bynameIwEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1114collate_bynameIwED0Ev FUNC:_ZNSt7__cxx1114collate_bynameIwED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1114collate_bynameIwED1Ev FUNC:_ZNSt7__cxx1114collate_bynameIwED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1114collate_bynameIwED2Ev FUNC:_ZNSt7__cxx1114collate_bynameIwED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE14__xfer_bufptrsC1ERKS4_PS4_ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE14__xfer_bufptrsC1ERKS4_PS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE14__xfer_bufptrsC2ERKS4_PS4_ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE14__xfer_bufptrsC2ERKS4_PS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE14__xfer_bufptrsD1Ev FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE14__xfer_bufptrsD1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE14__xfer_bufptrsD2Ev FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE14__xfer_bufptrsD2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE15_M_update_egptrEv FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE15_M_update_egptrEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE17_M_stringbuf_initESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE17_M_stringbuf_initESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strEONS_12basic_stringIcS2_S3_EE FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strEONS_12basic_stringIcS2_S3_EE@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strERKNS_12basic_stringIcS2_S3_EE FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strERKNS_12basic_stringIcS2_S3_EE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE4swapERS4_ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE6setbufEPci FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE6setbufEPci@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE7_M_syncEPcjj FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE7_M_syncEPcjj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE8_M_pbumpEPcS5_x FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE8_M_pbumpEPcS5_x@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE8overflowEi FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE8overflowEi@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE9pbackfailEi FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE9pbackfailEi@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE9showmanycEv FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE9showmanycEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE9underflowEv FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE9underflowEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_ONS4_14__xfer_bufptrsE FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_RKS3_ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_RKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_RKS3_ONS4_14__xfer_bufptrsE FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_RKS3_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ERKS3_ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ERKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1Ev FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_ONS4_14__xfer_bufptrsE FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_RKS3_ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_RKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_RKS3_ONS4_14__xfer_bufptrsE FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_RKS3_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ERKS3_ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ERKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2Ev FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED2Ev FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEaSEOS4_ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEaSEOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE14__xfer_bufptrsC1ERKS4_PS4_ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE14__xfer_bufptrsC1ERKS4_PS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE14__xfer_bufptrsC2ERKS4_PS4_ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE14__xfer_bufptrsC2ERKS4_PS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE14__xfer_bufptrsD1Ev FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE14__xfer_bufptrsD1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE14__xfer_bufptrsD2Ev FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE14__xfer_bufptrsD2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE15_M_update_egptrEv FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE15_M_update_egptrEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE17_M_stringbuf_initESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE17_M_stringbuf_initESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strEONS_12basic_stringIwS2_S3_EE FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strEONS_12basic_stringIwS2_S3_EE@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strERKNS_12basic_stringIwS2_S3_EE FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strERKNS_12basic_stringIwS2_S3_EE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE4swapERS4_ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE6setbufEPwi FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE6setbufEPwi@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE7_M_syncEPwjj FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE7_M_syncEPwjj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE8_M_pbumpEPwS5_x FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE8_M_pbumpEPwS5_x@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE8overflowEj FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE8overflowEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE9pbackfailEj FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE9pbackfailEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE9showmanycEv FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE9showmanycEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE9underflowEv FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE9underflowEv@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_ONS4_14__xfer_bufptrsE FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_RKS3_ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_RKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_RKS3_ONS4_14__xfer_bufptrsE FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_RKS3_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ERKS3_ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ERKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1Ev FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_ONS4_14__xfer_bufptrsE FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_RKS3_ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_RKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_RKS3_ONS4_14__xfer_bufptrsE FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_RKS3_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ERKS3_ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ERKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2Ev FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED2Ev FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEaSEOS4_ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEaSEOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115messages_bynameIcEC1EPKcj FUNC:_ZNSt7__cxx1115messages_bynameIcEC1EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115messages_bynameIcEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1115messages_bynameIcEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115messages_bynameIcEC2EPKcj FUNC:_ZNSt7__cxx1115messages_bynameIcEC2EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115messages_bynameIcEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1115messages_bynameIcEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115messages_bynameIcED0Ev FUNC:_ZNSt7__cxx1115messages_bynameIcED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115messages_bynameIcED1Ev FUNC:_ZNSt7__cxx1115messages_bynameIcED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115messages_bynameIcED2Ev FUNC:_ZNSt7__cxx1115messages_bynameIcED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115messages_bynameIwEC1EPKcj FUNC:_ZNSt7__cxx1115messages_bynameIwEC1EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115messages_bynameIwEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1115messages_bynameIwEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115messages_bynameIwEC2EPKcj FUNC:_ZNSt7__cxx1115messages_bynameIwEC2EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115messages_bynameIwEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1115messages_bynameIwEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115messages_bynameIwED0Ev FUNC:_ZNSt7__cxx1115messages_bynameIwED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115messages_bynameIwED1Ev FUNC:_ZNSt7__cxx1115messages_bynameIwED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115messages_bynameIwED2Ev FUNC:_ZNSt7__cxx1115messages_bynameIwED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115numpunct_bynameIcEC1EPKcj FUNC:_ZNSt7__cxx1115numpunct_bynameIcEC1EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115numpunct_bynameIcEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1115numpunct_bynameIcEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115numpunct_bynameIcEC2EPKcj FUNC:_ZNSt7__cxx1115numpunct_bynameIcEC2EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115numpunct_bynameIcEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1115numpunct_bynameIcEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115numpunct_bynameIcED0Ev FUNC:_ZNSt7__cxx1115numpunct_bynameIcED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115numpunct_bynameIcED1Ev FUNC:_ZNSt7__cxx1115numpunct_bynameIcED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115numpunct_bynameIcED2Ev FUNC:_ZNSt7__cxx1115numpunct_bynameIcED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115numpunct_bynameIwEC1EPKcj FUNC:_ZNSt7__cxx1115numpunct_bynameIwEC1EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115numpunct_bynameIwEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1115numpunct_bynameIwEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115numpunct_bynameIwEC2EPKcj FUNC:_ZNSt7__cxx1115numpunct_bynameIwEC2EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115numpunct_bynameIwEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1115numpunct_bynameIwEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115numpunct_bynameIwED0Ev FUNC:_ZNSt7__cxx1115numpunct_bynameIwED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115numpunct_bynameIwED1Ev FUNC:_ZNSt7__cxx1115numpunct_bynameIwED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115numpunct_bynameIwED2Ev FUNC:_ZNSt7__cxx1115numpunct_bynameIwED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1EPKcj FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1ERKNS_12basic_stringIcS3_SaIcEEEj FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1ERKNS_12basic_stringIcS3_SaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2EPKcj FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2ERKNS_12basic_stringIcS3_SaIcEEEj FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2ERKNS_12basic_stringIcS3_SaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1EPKcj FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1ERKNS_12basic_stringIcS2_IcESaIcEEEj FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1ERKNS_12basic_stringIcS2_IcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2EPKcj FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2ERKNS_12basic_stringIcS2_IcESaIcEEEj FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2ERKNS_12basic_stringIcS2_IcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EEC1EPKcj FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EEC1EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EEC2EPKcj FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EEC2EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EED0Ev FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EED1Ev FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EED2Ev FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EEC1EPKcj FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EEC1EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EEC2EPKcj FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EEC2EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EED0Ev FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EED1Ev FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EED2Ev FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EEC1EPKcj FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EEC1EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EEC2EPKcj FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EEC2EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EED0Ev FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EED1Ev FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EED2Ev FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EEC1EPKcj FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EEC1EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EEC2EPKcj FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EEC2EPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EED0Ev FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EED1Ev FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EED2Ev FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEONS_12basic_stringIcS2_S3_EE FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEONS_12basic_stringIcS2_S3_EE@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strERKNS_12basic_stringIcS2_S3_EE FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strERKNS_12basic_stringIcS2_S3_EE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE4swapERS4_ FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1EOS4_ FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1Ev FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2EOS4_ FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2Ev FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED2Ev FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEaSEOS4_ FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEaSEOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE3strEONS_12basic_stringIwS2_S3_EE FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE3strEONS_12basic_stringIwS2_S3_EE@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE3strERKNS_12basic_stringIwS2_S3_EE FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE3strERKNS_12basic_stringIwS2_S3_EE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE4swapERS4_ FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1EOS4_ FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1Ev FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2EOS4_ FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2Ev FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED2Ev FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEaSEOS4_ FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEaSEOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE3strEONS_12basic_stringIcS2_S3_EE FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE3strEONS_12basic_stringIcS2_S3_EE@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE3strERKNS_12basic_stringIcS2_S3_EE FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE3strERKNS_12basic_stringIcS2_S3_EE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE4swapERS4_ FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1EOS4_ FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1Ev FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2EOS4_ FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2Ev FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED2Ev FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEaSEOS4_ FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEaSEOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE3strEONS_12basic_stringIwS2_S3_EE FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE3strEONS_12basic_stringIwS2_S3_EE@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE3strERKNS_12basic_stringIwS2_S3_EE FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE3strERKNS_12basic_stringIwS2_S3_EE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE4swapERS4_ FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1EOS4_ FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1Ev FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2EOS4_ FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2Ev FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED2Ev FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEaSEOS4_ FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEaSEOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEONS_12basic_stringIcS2_S3_EE FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEONS_12basic_stringIcS2_S3_EE@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE3strERKNS_12basic_stringIcS2_S3_EE FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE3strERKNS_12basic_stringIcS2_S3_EE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE4swapERS4_ FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1EOS4_ FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2EONS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2EOS4_ FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2Ev FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED2Ev FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEaSEOS4_ FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEaSEOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE3strEONS_12basic_stringIwS2_S3_EE FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE3strEONS_12basic_stringIwS2_S3_EE@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE3strERKNS_12basic_stringIwS2_S3_EE FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE3strERKNS_12basic_stringIwS2_S3_EE@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE4swapERS4_ FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1EOS4_ FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1Ev FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2EONS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2EOS4_ FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_OpenmodeRKS3_ FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_OpenmodeRKS3_@@GLIBCXX_3.4.29 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2Ev FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED2Ev FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEaSEOS4_ FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEaSEOS4_@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx117collateIcEC1EP15__locale_structj FUNC:_ZNSt7__cxx117collateIcEC1EP15__locale_structj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx117collateIcEC1Ej FUNC:_ZNSt7__cxx117collateIcEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx117collateIcEC2EP15__locale_structj FUNC:_ZNSt7__cxx117collateIcEC2EP15__locale_structj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx117collateIcEC2Ej FUNC:_ZNSt7__cxx117collateIcEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx117collateIcED0Ev FUNC:_ZNSt7__cxx117collateIcED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx117collateIcED1Ev FUNC:_ZNSt7__cxx117collateIcED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx117collateIcED2Ev FUNC:_ZNSt7__cxx117collateIcED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx117collateIwEC1EP15__locale_structj FUNC:_ZNSt7__cxx117collateIwEC1EP15__locale_structj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx117collateIwEC1Ej FUNC:_ZNSt7__cxx117collateIwEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx117collateIwEC2EP15__locale_structj FUNC:_ZNSt7__cxx117collateIwEC2EP15__locale_structj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx117collateIwEC2Ej FUNC:_ZNSt7__cxx117collateIwEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx117collateIwED0Ev FUNC:_ZNSt7__cxx117collateIwED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx117collateIwED1Ev FUNC:_ZNSt7__cxx117collateIwED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx117collateIwED2Ev FUNC:_ZNSt7__cxx117collateIwED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118messagesIcEC1EP15__locale_structPKcj FUNC:_ZNSt7__cxx118messagesIcEC1EP15__locale_structPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118messagesIcEC1Ej FUNC:_ZNSt7__cxx118messagesIcEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118messagesIcEC2EP15__locale_structPKcj FUNC:_ZNSt7__cxx118messagesIcEC2EP15__locale_structPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118messagesIcEC2Ej FUNC:_ZNSt7__cxx118messagesIcEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118messagesIcED0Ev FUNC:_ZNSt7__cxx118messagesIcED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118messagesIcED1Ev FUNC:_ZNSt7__cxx118messagesIcED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118messagesIcED2Ev FUNC:_ZNSt7__cxx118messagesIcED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118messagesIwEC1EP15__locale_structPKcj FUNC:_ZNSt7__cxx118messagesIwEC1EP15__locale_structPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118messagesIwEC1Ej FUNC:_ZNSt7__cxx118messagesIwEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118messagesIwEC2EP15__locale_structPKcj FUNC:_ZNSt7__cxx118messagesIwEC2EP15__locale_structPKcj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118messagesIwEC2Ej FUNC:_ZNSt7__cxx118messagesIwEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118messagesIwED0Ev FUNC:_ZNSt7__cxx118messagesIwED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118messagesIwED1Ev FUNC:_ZNSt7__cxx118messagesIwED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118messagesIwED2Ev FUNC:_ZNSt7__cxx118messagesIwED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIcE22_M_initialize_numpunctEP15__locale_struct FUNC:_ZNSt7__cxx118numpunctIcE22_M_initialize_numpunctEP15__locale_struct@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIcEC1EP15__locale_structj FUNC:_ZNSt7__cxx118numpunctIcEC1EP15__locale_structj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIcEC1EPSt16__numpunct_cacheIcEj FUNC:_ZNSt7__cxx118numpunctIcEC1EPSt16__numpunct_cacheIcEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIcEC1Ej FUNC:_ZNSt7__cxx118numpunctIcEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIcEC2EP15__locale_structj FUNC:_ZNSt7__cxx118numpunctIcEC2EP15__locale_structj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIcEC2EPSt16__numpunct_cacheIcEj FUNC:_ZNSt7__cxx118numpunctIcEC2EPSt16__numpunct_cacheIcEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIcEC2Ej FUNC:_ZNSt7__cxx118numpunctIcEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIcED0Ev FUNC:_ZNSt7__cxx118numpunctIcED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIcED1Ev FUNC:_ZNSt7__cxx118numpunctIcED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIcED2Ev FUNC:_ZNSt7__cxx118numpunctIcED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIwE22_M_initialize_numpunctEP15__locale_struct FUNC:_ZNSt7__cxx118numpunctIwE22_M_initialize_numpunctEP15__locale_struct@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIwEC1EP15__locale_structj FUNC:_ZNSt7__cxx118numpunctIwEC1EP15__locale_structj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIwEC1EPSt16__numpunct_cacheIwEj FUNC:_ZNSt7__cxx118numpunctIwEC1EPSt16__numpunct_cacheIwEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIwEC1Ej FUNC:_ZNSt7__cxx118numpunctIwEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIwEC2EP15__locale_structj FUNC:_ZNSt7__cxx118numpunctIwEC2EP15__locale_structj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIwEC2EPSt16__numpunct_cacheIwEj FUNC:_ZNSt7__cxx118numpunctIwEC2EPSt16__numpunct_cacheIwEj@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIwEC2Ej FUNC:_ZNSt7__cxx118numpunctIwEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIwED0Ev FUNC:_ZNSt7__cxx118numpunctIwED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIwED1Ev FUNC:_ZNSt7__cxx118numpunctIwED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118numpunctIwED2Ev FUNC:_ZNSt7__cxx118numpunctIwED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Ej FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Ej FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Ej FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Ej FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Ej FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Ej FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Ej FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Ej FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1Ej FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2Ej FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1Ej FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Ej FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Ej@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED0Ev FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED0Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED1Ev FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED2Ev FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7codecvtIDic11__mbstate_tED0Ev FUNC:_ZNSt7codecvtIDic11__mbstate_tED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7codecvtIDic11__mbstate_tED1Ev FUNC:_ZNSt7codecvtIDic11__mbstate_tED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7codecvtIDic11__mbstate_tED2Ev FUNC:_ZNSt7codecvtIDic11__mbstate_tED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED0Ev FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED0Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED1Ev FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED1Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED2Ev FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED2Ev@@GLIBCXX_3.4.26 -FUNC:_ZNSt7codecvtIDsc11__mbstate_tED0Ev FUNC:_ZNSt7codecvtIDsc11__mbstate_tED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7codecvtIDsc11__mbstate_tED1Ev FUNC:_ZNSt7codecvtIDsc11__mbstate_tED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7codecvtIDsc11__mbstate_tED2Ev FUNC:_ZNSt7codecvtIDsc11__mbstate_tED2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structj FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structj@@GLIBCXX_3.4 -FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1Ej FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7codecvtIcc11__mbstate_tEC2EP15__locale_structj FUNC:_ZNSt7codecvtIcc11__mbstate_tEC2EP15__locale_structj@@GLIBCXX_3.4 -FUNC:_ZNSt7codecvtIcc11__mbstate_tEC2Ej FUNC:_ZNSt7codecvtIcc11__mbstate_tEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7codecvtIcc11__mbstate_tED0Ev FUNC:_ZNSt7codecvtIcc11__mbstate_tED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7codecvtIcc11__mbstate_tED1Ev FUNC:_ZNSt7codecvtIcc11__mbstate_tED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7codecvtIcc11__mbstate_tED2Ev FUNC:_ZNSt7codecvtIcc11__mbstate_tED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7codecvtIwc11__mbstate_tEC1EP15__locale_structj FUNC:_ZNSt7codecvtIwc11__mbstate_tEC1EP15__locale_structj@@GLIBCXX_3.4 -FUNC:_ZNSt7codecvtIwc11__mbstate_tEC1Ej FUNC:_ZNSt7codecvtIwc11__mbstate_tEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7codecvtIwc11__mbstate_tEC2EP15__locale_structj FUNC:_ZNSt7codecvtIwc11__mbstate_tEC2EP15__locale_structj@@GLIBCXX_3.4 -FUNC:_ZNSt7codecvtIwc11__mbstate_tEC2Ej FUNC:_ZNSt7codecvtIwc11__mbstate_tEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7codecvtIwc11__mbstate_tED0Ev FUNC:_ZNSt7codecvtIwc11__mbstate_tED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7codecvtIwc11__mbstate_tED1Ev FUNC:_ZNSt7codecvtIwc11__mbstate_tED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7codecvtIwc11__mbstate_tED2Ev FUNC:_ZNSt7codecvtIwc11__mbstate_tED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7collateIcEC1EP15__locale_structj FUNC:_ZNSt7collateIcEC1EP15__locale_structj@@GLIBCXX_3.4 -FUNC:_ZNSt7collateIcEC1Ej FUNC:_ZNSt7collateIcEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7collateIcEC2EP15__locale_structj FUNC:_ZNSt7collateIcEC2EP15__locale_structj@@GLIBCXX_3.4 -FUNC:_ZNSt7collateIcEC2Ej FUNC:_ZNSt7collateIcEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7collateIcED0Ev FUNC:_ZNSt7collateIcED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7collateIcED1Ev FUNC:_ZNSt7collateIcED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7collateIcED2Ev FUNC:_ZNSt7collateIcED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7collateIwEC1EP15__locale_structj FUNC:_ZNSt7collateIwEC1EP15__locale_structj@@GLIBCXX_3.4 -FUNC:_ZNSt7collateIwEC1Ej FUNC:_ZNSt7collateIwEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7collateIwEC2EP15__locale_structj FUNC:_ZNSt7collateIwEC2EP15__locale_structj@@GLIBCXX_3.4 -FUNC:_ZNSt7collateIwEC2Ej FUNC:_ZNSt7collateIwEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7collateIwED0Ev FUNC:_ZNSt7collateIwED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7collateIwED1Ev FUNC:_ZNSt7collateIwED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7collateIwED2Ev FUNC:_ZNSt7collateIwED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Ej FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Ej FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Ej FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Ej FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1Ej FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2Ej FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1Ej FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Ej FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8__detail15_List_node_base10_M_reverseEv +FUNC:_ZNSt8__detail11__wait_args22_M_load_proxy_wait_valEPKv@@GLIBCXX_3.4.35 +FUNC:_ZNSt8__detail11__wait_implEPKvRNS_16__wait_args_baseE@@GLIBCXX_3.4.35 +FUNC:_ZNSt8__detail13__notify_implEPKvbRKNS_16__wait_args_baseE@@GLIBCXX_3.4.35 FUNC:_ZNSt8__detail15_List_node_base10_M_reverseEv@@GLIBCXX_3.4.15 -FUNC:_ZNSt8__detail15_List_node_base11_M_transferEPS0_S1_ FUNC:_ZNSt8__detail15_List_node_base11_M_transferEPS0_S1_@@GLIBCXX_3.4.15 -FUNC:_ZNSt8__detail15_List_node_base4swapERS0_S1_ FUNC:_ZNSt8__detail15_List_node_base4swapERS0_S1_@@GLIBCXX_3.4.15 -FUNC:_ZNSt8__detail15_List_node_base7_M_hookEPS0_ FUNC:_ZNSt8__detail15_List_node_base7_M_hookEPS0_@@GLIBCXX_3.4.15 -FUNC:_ZNSt8__detail15_List_node_base9_M_unhookEv FUNC:_ZNSt8__detail15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.15 -FUNC:_ZNSt8bad_castD0Ev +FUNC:_ZNSt8__detail17__wait_until_implEPKvRNS_16__wait_args_baseERKNSt6chrono8durationIxSt5ratioILx1ELx1000000000EEEE@@GLIBCXX_3.4.35 +FUNC:_ZNSt8__format25__locale_encoding_to_utf8ERKSt6localeSt17basic_string_viewIcSt11char_traitsIcEEPv@@GLIBCXX_3.4.34 +FUNC:_ZNSt8__format26__with_encoding_conversionERKSt6locale@@GLIBCXX_3.4.34 FUNC:_ZNSt8bad_castD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8bad_castD1Ev FUNC:_ZNSt8bad_castD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8bad_castD2Ev FUNC:_ZNSt8bad_castD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base13_M_grow_wordsEib FUNC:_ZNSt8ios_base13_M_grow_wordsEib@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base15sync_with_stdioEb FUNC:_ZNSt8ios_base15sync_with_stdioEb@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base17_M_call_callbacksENS_5eventE FUNC:_ZNSt8ios_base17_M_call_callbacksENS_5eventE@@GLIBCXX_3.4.6 -FUNC:_ZNSt8ios_base17register_callbackEPFvNS_5eventERS_iEi FUNC:_ZNSt8ios_base17register_callbackEPFvNS_5eventERS_iEi@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base20_M_dispose_callbacksEv FUNC:_ZNSt8ios_base20_M_dispose_callbacksEv@@GLIBCXX_3.4.6 -FUNC:_ZNSt8ios_base4InitC1Ev FUNC:_ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base4InitC2Ev FUNC:_ZNSt8ios_base4InitC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base4InitD1Ev FUNC:_ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base4InitD2Ev FUNC:_ZNSt8ios_base4InitD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base5imbueERKSt6locale FUNC:_ZNSt8ios_base5imbueERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base6xallocEv FUNC:_ZNSt8ios_base6xallocEv@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base7_M_initEv FUNC:_ZNSt8ios_base7_M_initEv@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base7_M_moveERS_ FUNC:_ZNSt8ios_base7_M_moveERS_@@GLIBCXX_3.4.21 -FUNC:_ZNSt8ios_base7_M_swapERS_ FUNC:_ZNSt8ios_base7_M_swapERS_@@GLIBCXX_3.4.21 -FUNC:_ZNSt8ios_base7failureB5cxx11C1EPKcRKSt10error_code FUNC:_ZNSt8ios_base7failureB5cxx11C1EPKcRKSt10error_code@@GLIBCXX_3.4.21 -FUNC:_ZNSt8ios_base7failureB5cxx11C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt8ios_base7failureB5cxx11C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt8ios_base7failureB5cxx11C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt10error_code FUNC:_ZNSt8ios_base7failureB5cxx11C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt10error_code@@GLIBCXX_3.4.21 -FUNC:_ZNSt8ios_base7failureB5cxx11C2EPKcRKSt10error_code FUNC:_ZNSt8ios_base7failureB5cxx11C2EPKcRKSt10error_code@@GLIBCXX_3.4.21 -FUNC:_ZNSt8ios_base7failureB5cxx11C2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZNSt8ios_base7failureB5cxx11C2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZNSt8ios_base7failureB5cxx11C2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt10error_code FUNC:_ZNSt8ios_base7failureB5cxx11C2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt10error_code@@GLIBCXX_3.4.21 -FUNC:_ZNSt8ios_base7failureB5cxx11D0Ev FUNC:_ZNSt8ios_base7failureB5cxx11D0Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt8ios_base7failureB5cxx11D1Ev FUNC:_ZNSt8ios_base7failureB5cxx11D1Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt8ios_base7failureB5cxx11D2Ev FUNC:_ZNSt8ios_base7failureB5cxx11D2Ev@@GLIBCXX_3.4.21 -FUNC:_ZNSt8ios_base7failureC1ERKSs FUNC:_ZNSt8ios_base7failureC1ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base7failureC2ERKSs FUNC:_ZNSt8ios_base7failureC2ERKSs@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base7failureD0Ev FUNC:_ZNSt8ios_base7failureD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base7failureD1Ev FUNC:_ZNSt8ios_base7failureD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_base7failureD2Ev FUNC:_ZNSt8ios_base7failureD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_baseC1Ev FUNC:_ZNSt8ios_baseC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_baseC2Ev FUNC:_ZNSt8ios_baseC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_baseD0Ev FUNC:_ZNSt8ios_baseD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_baseD1Ev FUNC:_ZNSt8ios_baseD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8ios_baseD2Ev FUNC:_ZNSt8ios_baseD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8messagesIcEC1EP15__locale_structPKcj FUNC:_ZNSt8messagesIcEC1EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt8messagesIcEC1Ej FUNC:_ZNSt8messagesIcEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8messagesIcEC2EP15__locale_structPKcj FUNC:_ZNSt8messagesIcEC2EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt8messagesIcEC2Ej FUNC:_ZNSt8messagesIcEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8messagesIcED0Ev FUNC:_ZNSt8messagesIcED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8messagesIcED1Ev FUNC:_ZNSt8messagesIcED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8messagesIcED2Ev FUNC:_ZNSt8messagesIcED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8messagesIwEC1EP15__locale_structPKcj FUNC:_ZNSt8messagesIwEC1EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt8messagesIwEC1Ej FUNC:_ZNSt8messagesIwEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8messagesIwEC2EP15__locale_structPKcj FUNC:_ZNSt8messagesIwEC2EP15__locale_structPKcj@@GLIBCXX_3.4 -FUNC:_ZNSt8messagesIwEC2Ej FUNC:_ZNSt8messagesIwEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8messagesIwED0Ev FUNC:_ZNSt8messagesIwED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8messagesIwED1Ev FUNC:_ZNSt8messagesIwED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8messagesIwED2Ev FUNC:_ZNSt8messagesIwED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIcE22_M_initialize_numpunctEP15__locale_struct FUNC:_ZNSt8numpunctIcE22_M_initialize_numpunctEP15__locale_struct@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIcEC1EP15__locale_structj FUNC:_ZNSt8numpunctIcEC1EP15__locale_structj@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIcEC1EPSt16__numpunct_cacheIcEj FUNC:_ZNSt8numpunctIcEC1EPSt16__numpunct_cacheIcEj@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIcEC1Ej FUNC:_ZNSt8numpunctIcEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIcEC2EP15__locale_structj FUNC:_ZNSt8numpunctIcEC2EP15__locale_structj@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIcEC2EPSt16__numpunct_cacheIcEj FUNC:_ZNSt8numpunctIcEC2EPSt16__numpunct_cacheIcEj@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIcEC2Ej FUNC:_ZNSt8numpunctIcEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIcED0Ev FUNC:_ZNSt8numpunctIcED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIcED1Ev FUNC:_ZNSt8numpunctIcED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIcED2Ev FUNC:_ZNSt8numpunctIcED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIwE22_M_initialize_numpunctEP15__locale_struct FUNC:_ZNSt8numpunctIwE22_M_initialize_numpunctEP15__locale_struct@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIwEC1EP15__locale_structj FUNC:_ZNSt8numpunctIwEC1EP15__locale_structj@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIwEC1EPSt16__numpunct_cacheIwEj FUNC:_ZNSt8numpunctIwEC1EPSt16__numpunct_cacheIwEj@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIwEC1Ej FUNC:_ZNSt8numpunctIwEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIwEC2EP15__locale_structj FUNC:_ZNSt8numpunctIwEC2EP15__locale_structj@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIwEC2EPSt16__numpunct_cacheIwEj FUNC:_ZNSt8numpunctIwEC2EPSt16__numpunct_cacheIwEj@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIwEC2Ej FUNC:_ZNSt8numpunctIwEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIwED0Ev FUNC:_ZNSt8numpunctIwED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIwED1Ev FUNC:_ZNSt8numpunctIwED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8numpunctIwED2Ev FUNC:_ZNSt8numpunctIwED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Ej FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Ej FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Ej FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Ej FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1Ej FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2Ej FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1Ej FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Ej FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8valarrayIjEC1ERKS0_ FUNC:_ZNSt8valarrayIjEC1ERKS0_@@GLIBCXX_3.4 -FUNC:_ZNSt8valarrayIjEC1Ej FUNC:_ZNSt8valarrayIjEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8valarrayIjEC2ERKS0_ FUNC:_ZNSt8valarrayIjEC2ERKS0_@@GLIBCXX_3.4 -FUNC:_ZNSt8valarrayIjEC2Ej FUNC:_ZNSt8valarrayIjEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt8valarrayIjED1Ev FUNC:_ZNSt8valarrayIjED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8valarrayIjED2Ev FUNC:_ZNSt8valarrayIjED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt8valarrayIjEixEj FUNC:_ZNSt8valarrayIjEixEj@@GLIBCXX_3.4 -FUNC:_ZNSt9__atomic011atomic_flag12test_and_setESt12memory_order FUNC:_ZNSt9__atomic011atomic_flag12test_and_setESt12memory_order@@GLIBCXX_3.4.14 -FUNC:_ZNSt9__atomic011atomic_flag5clearESt12memory_order FUNC:_ZNSt9__atomic011atomic_flag5clearESt12memory_order@@GLIBCXX_3.4.14 -FUNC:_ZNSt9__cxx199815_List_node_base10_M_reverseEv FUNC:_ZNSt9__cxx199815_List_node_base10_M_reverseEv@@GLIBCXX_3.4.14 -FUNC:_ZNSt9__cxx199815_List_node_base11_M_transferEPS0_S1_ FUNC:_ZNSt9__cxx199815_List_node_base11_M_transferEPS0_S1_@@GLIBCXX_3.4.14 -FUNC:_ZNSt9__cxx199815_List_node_base4hookEPS0_ FUNC:_ZNSt9__cxx199815_List_node_base4hookEPS0_@@GLIBCXX_3.4.10 -FUNC:_ZNSt9__cxx199815_List_node_base4swapERS0_S1_ FUNC:_ZNSt9__cxx199815_List_node_base4swapERS0_S1_@@GLIBCXX_3.4.10 -FUNC:_ZNSt9__cxx199815_List_node_base6unhookEv FUNC:_ZNSt9__cxx199815_List_node_base6unhookEv@@GLIBCXX_3.4.10 -FUNC:_ZNSt9__cxx199815_List_node_base7_M_hookEPS0_ FUNC:_ZNSt9__cxx199815_List_node_base7_M_hookEPS0_@@GLIBCXX_3.4.14 -FUNC:_ZNSt9__cxx199815_List_node_base7reverseEv FUNC:_ZNSt9__cxx199815_List_node_base7reverseEv@@GLIBCXX_3.4.10 -FUNC:_ZNSt9__cxx199815_List_node_base8transferEPS0_S1_ FUNC:_ZNSt9__cxx199815_List_node_base8transferEPS0_S1_@@GLIBCXX_3.4.10 -FUNC:_ZNSt9__cxx199815_List_node_base9_M_unhookEv FUNC:_ZNSt9__cxx199815_List_node_base9_M_unhookEv@@GLIBCXX_3.4.14 -FUNC:_ZNSt9bad_allocD0Ev FUNC:_ZNSt9bad_allocD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9bad_allocD1Ev FUNC:_ZNSt9bad_allocD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9bad_allocD2Ev FUNC:_ZNSt9bad_allocD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE10exceptionsESt12_Ios_Iostate FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE10exceptionsESt12_Ios_Iostate@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE11_M_setstateESt12_Ios_Iostate FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE11_M_setstateESt12_Ios_Iostate@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE15_M_cache_localeERKSt6locale FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE15_M_cache_localeERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE3tieEPSo FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE3tieEPSo@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4fillEc FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4fillEc@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4moveEOS2_ FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4moveEOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4moveERS2_ FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4moveERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4swapERS2_ FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE5imbueERKSt6locale FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE5imbueERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE5rdbufEPSt15basic_streambufIcS1_E FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE5rdbufEPSt15basic_streambufIcS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE7copyfmtERKS2_ FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE7copyfmtERKS2_@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE8setstateESt12_Ios_Iostate FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE8setstateESt12_Ios_Iostate@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE9set_rdbufEPSt15basic_streambufIcS1_E FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE9set_rdbufEPSt15basic_streambufIcS1_E@@GLIBCXX_3.4.21 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEEC1EPSt15basic_streambufIcS1_E FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEEC1EPSt15basic_streambufIcS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEEC1Ev FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEEC2EPSt15basic_streambufIcS1_E FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEEC2EPSt15basic_streambufIcS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEEC2Ev FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEED0Ev FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEED1Ev FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEED2Ev FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE10exceptionsESt12_Ios_Iostate FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE10exceptionsESt12_Ios_Iostate@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE11_M_setstateESt12_Ios_Iostate FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE11_M_setstateESt12_Ios_Iostate@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE15_M_cache_localeERKSt6locale FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE15_M_cache_localeERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE3tieEPSt13basic_ostreamIwS1_E FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE3tieEPSt13basic_ostreamIwS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4fillEw FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4fillEw@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4initEPSt15basic_streambufIwS1_E FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4initEPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4moveEOS2_ FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4moveEOS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4moveERS2_ FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4moveERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4swapERS2_ FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE5clearESt12_Ios_Iostate FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE5clearESt12_Ios_Iostate@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE5imbueERKSt6locale FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE5imbueERKSt6locale@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE5rdbufEPSt15basic_streambufIwS1_E FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE5rdbufEPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE7copyfmtERKS2_ FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE7copyfmtERKS2_@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE8setstateESt12_Ios_Iostate FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE8setstateESt12_Ios_Iostate@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE9set_rdbufEPSt15basic_streambufIwS1_E FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE9set_rdbufEPSt15basic_streambufIwS1_E@@GLIBCXX_3.4.21 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEEC1EPSt15basic_streambufIwS1_E FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEEC1EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEEC1Ev FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEEC2EPSt15basic_streambufIwS1_E FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEEC2EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEEC2Ev FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEED0Ev FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEED1Ev FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEED2Ev FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9exceptionD0Ev FUNC:_ZNSt9exceptionD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9exceptionD1Ev FUNC:_ZNSt9exceptionD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9exceptionD2Ev FUNC:_ZNSt9exceptionD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Ej FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Ej FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Ej FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Ej FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1Ej FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2Ej FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1Ej FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1Ej@@GLIBCXX_3.4 -FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Ej FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Ej@@GLIBCXX_3.4 -FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9strstream3strEv FUNC:_ZNSt9strstream3strEv@@GLIBCXX_3.4 -FUNC:_ZNSt9strstream6freezeEb FUNC:_ZNSt9strstream6freezeEb@@GLIBCXX_3.4 -FUNC:_ZNSt9strstreamC1EPciSt13_Ios_Openmode FUNC:_ZNSt9strstreamC1EPciSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt9strstreamC1Ev FUNC:_ZNSt9strstreamC1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9strstreamC2EPciSt13_Ios_Openmode FUNC:_ZNSt9strstreamC2EPciSt13_Ios_Openmode@@GLIBCXX_3.4 -FUNC:_ZNSt9strstreamC2Ev FUNC:_ZNSt9strstreamC2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9strstreamD0Ev FUNC:_ZNSt9strstreamD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9strstreamD1Ev FUNC:_ZNSt9strstreamD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9strstreamD2Ev FUNC:_ZNSt9strstreamD2Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9type_infoD0Ev FUNC:_ZNSt9type_infoD0Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9type_infoD1Ev FUNC:_ZNSt9type_infoD1Ev@@GLIBCXX_3.4 -FUNC:_ZNSt9type_infoD2Ev FUNC:_ZNSt9type_infoD2Ev@@GLIBCXX_3.4 FUNC:_ZNVSt9__atomic011atomic_flag12test_and_setESt12memory_order@@GLIBCXX_3.4.11 FUNC:_ZNVSt9__atomic011atomic_flag5clearESt12memory_order@@GLIBCXX_3.4.11 -FUNC:_ZSt10from_charsPKcS0_RdSt12chars_format FUNC:_ZSt10from_charsPKcS0_RdSt12chars_format@@GLIBCXX_3.4.29 -FUNC:_ZSt10from_charsPKcS0_ReSt12chars_format FUNC:_ZSt10from_charsPKcS0_ReSt12chars_format@@GLIBCXX_3.4.29 -FUNC:_ZSt10from_charsPKcS0_RfSt12chars_format FUNC:_ZSt10from_charsPKcS0_RfSt12chars_format@@GLIBCXX_3.4.29 -FUNC:_ZSt10unexpectedv FUNC:_ZSt10unexpectedv@@GLIBCXX_3.4 -FUNC:_ZSt11_Hash_bytesPKvjj FUNC:_ZSt11_Hash_bytesPKvjj@@CXXABI_1.3.5 -FUNC:_ZSt13get_terminatev FUNC:_ZSt13get_terminatev@@GLIBCXX_3.4.20 -FUNC:_ZSt13set_terminatePFvvE FUNC:_ZSt13set_terminatePFvvE@@GLIBCXX_3.4 -FUNC:_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct FUNC:_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct@@GLIBCXX_3.4 -FUNC:_ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct FUNC:_ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct@@GLIBCXX_3.4 -FUNC:_ZSt14__convert_to_vIfEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct FUNC:_ZSt14__convert_to_vIfEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct@@GLIBCXX_3.4 -FUNC:_ZSt14get_unexpectedv FUNC:_ZSt14get_unexpectedv@@GLIBCXX_3.4.20 -FUNC:_ZSt14set_unexpectedPFvvE FUNC:_ZSt14set_unexpectedPFvvE@@GLIBCXX_3.4 -FUNC:_ZSt15_Fnv_hash_bytesPKvjj FUNC:_ZSt15_Fnv_hash_bytesPKvjj@@CXXABI_1.3.5 -FUNC:_ZSt15__try_use_facetINSt7__cxx1110moneypunctIcLb0EEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx1110moneypunctIcLb0EEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx1110moneypunctIcLb1EEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx1110moneypunctIcLb1EEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx1110moneypunctIwLb0EEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx1110moneypunctIwLb0EEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx1110moneypunctIwLb1EEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx1110moneypunctIwLb1EEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx117collateIcEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx117collateIcEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx117collateIwEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx117collateIwEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx118messagesIcEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx118messagesIcEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx118messagesIwEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx118messagesIwEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx118numpunctIcEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx118numpunctIcEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx118numpunctIwEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx118numpunctIwEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetINSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetINSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt10moneypunctIcLb0EEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt10moneypunctIcLb0EEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt10moneypunctIcLb1EEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt10moneypunctIcLb1EEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt10moneypunctIwLb0EEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt10moneypunctIwLb0EEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt10moneypunctIwLb1EEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt10moneypunctIwLb1EEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt11__timepunctIcEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt11__timepunctIcEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt11__timepunctIwEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt11__timepunctIwEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt5ctypeIcEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt5ctypeIcEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt5ctypeIwEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt5ctypeIwEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt7codecvtIcc11__mbstate_tEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt7codecvtIcc11__mbstate_tEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt7codecvtIwc11__mbstate_tEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt7codecvtIwc11__mbstate_tEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt7collateIcEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt7collateIcEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt7collateIwEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt7collateIwEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt8messagesIcEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt8messagesIcEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt8messagesIwEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt8messagesIwEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt8numpunctIcEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt8numpunctIcEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt8numpunctIwEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt8numpunctIwEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15__try_use_facetISt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEPKT_RKSt6locale FUNC:_ZSt15__try_use_facetISt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEPKT_RKSt6locale@@GLIBCXX_3.4.31 -FUNC:_ZSt15future_categoryv FUNC:_ZSt15future_categoryv@@GLIBCXX_3.4.15 -FUNC:_ZSt15get_new_handlerv FUNC:_ZSt15get_new_handlerv@@GLIBCXX_3.4.20 -FUNC:_ZSt15set_new_handlerPFvvE FUNC:_ZSt15set_new_handlerPFvvE@@GLIBCXX_3.4 -FUNC:_ZSt15system_categoryv FUNC:_ZSt15system_categoryv@@GLIBCXX_3.4.11 -FUNC:_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i FUNC:_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i@@GLIBCXX_3.4.9 -FUNC:_ZSt16__ostream_insertIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_PKS3_i FUNC:_ZSt16__ostream_insertIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_PKS3_i@@GLIBCXX_3.4.9 -FUNC:_ZSt16__throw_bad_castv FUNC:_ZSt16__throw_bad_castv@@GLIBCXX_3.4 -FUNC:_ZSt16generic_categoryv FUNC:_ZSt16generic_categoryv@@GLIBCXX_3.4.11 -FUNC:_ZSt17__copy_streambufsIcSt11char_traitsIcEEiPSt15basic_streambufIT_T0_ES6_ FUNC:_ZSt17__copy_streambufsIcSt11char_traitsIcEEiPSt15basic_streambufIT_T0_ES6_@@GLIBCXX_3.4.6 -FUNC:_ZSt17__copy_streambufsIwSt11char_traitsIwEEiPSt15basic_streambufIT_T0_ES6_ FUNC:_ZSt17__copy_streambufsIwSt11char_traitsIwEEiPSt15basic_streambufIT_T0_ES6_@@GLIBCXX_3.4.6 -FUNC:_ZSt17__istream_extractIwSt11char_traitsIwEEvRSt13basic_istreamIT_T0_EPS3_i FUNC:_ZSt17__istream_extractIwSt11char_traitsIwEEvRSt13basic_istreamIT_T0_EPS3_i@@GLIBCXX_3.4.29 -FUNC:_ZSt17__istream_extractRSiPci FUNC:_ZSt17__istream_extractRSiPci@@GLIBCXX_3.4.29 -FUNC:_ZSt17__throw_bad_allocv FUNC:_ZSt17__throw_bad_allocv@@GLIBCXX_3.4 -FUNC:_ZSt17__verify_groupingPKcjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE FUNC:_ZSt17__verify_groupingPKcjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -FUNC:_ZSt17__verify_groupingPKcjRKSs FUNC:_ZSt17__verify_groupingPKcjRKSs@@GLIBCXX_3.4.10 -FUNC:_ZSt17current_exceptionv FUNC:_ZSt17current_exceptionv@@CXXABI_1.3.3 -FUNC:_ZSt17iostream_categoryv FUNC:_ZSt17iostream_categoryv@@GLIBCXX_3.4.21 -FUNC:_ZSt17rethrow_exceptionNSt15__exception_ptr13exception_ptrE FUNC:_ZSt17rethrow_exceptionNSt15__exception_ptr13exception_ptrE@@CXXABI_1.3.3 -FUNC:_ZSt18_Rb_tree_decrementPKSt18_Rb_tree_node_base FUNC:_ZSt18_Rb_tree_decrementPKSt18_Rb_tree_node_base@@GLIBCXX_3.4 -FUNC:_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base FUNC:_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base@@GLIBCXX_3.4 -FUNC:_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base FUNC:_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base@@GLIBCXX_3.4 -FUNC:_ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base FUNC:_ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base@@GLIBCXX_3.4 -FUNC:_ZSt18__throw_bad_typeidv FUNC:_ZSt18__throw_bad_typeidv@@GLIBCXX_3.4 -FUNC:_ZSt18uncaught_exceptionv FUNC:_ZSt18uncaught_exceptionv@@GLIBCXX_3.4 -FUNC:_ZSt19__throw_ios_failurePKc FUNC:_ZSt19__throw_ios_failurePKc@@GLIBCXX_3.4 -FUNC:_ZSt19__throw_ios_failurePKci FUNC:_ZSt19__throw_ios_failurePKci@@GLIBCXX_3.4.26 -FUNC:_ZSt19__throw_logic_errorPKc FUNC:_ZSt19__throw_logic_errorPKc@@GLIBCXX_3.4 -FUNC:_ZSt19__throw_range_errorPKc FUNC:_ZSt19__throw_range_errorPKc@@GLIBCXX_3.4 -FUNC:_ZSt19__throw_regex_errorNSt15regex_constants10error_typeE FUNC:_ZSt19__throw_regex_errorNSt15regex_constants10error_typeE@@GLIBCXX_3.4.15 -FUNC:_ZSt19uncaught_exceptionsv FUNC:_ZSt19uncaught_exceptionsv@@GLIBCXX_3.4.22 -FUNC:_ZSt20_Rb_tree_black_countPKSt18_Rb_tree_node_baseS1_ FUNC:_ZSt20_Rb_tree_black_countPKSt18_Rb_tree_node_baseS1_@@GLIBCXX_3.4 -FUNC:_ZSt20_Rb_tree_rotate_leftPSt18_Rb_tree_node_baseRS0_ FUNC:_ZSt20_Rb_tree_rotate_leftPSt18_Rb_tree_node_baseRS0_@@GLIBCXX_3.4 -FUNC:_ZSt20__throw_domain_errorPKc FUNC:_ZSt20__throw_domain_errorPKc@@GLIBCXX_3.4 -FUNC:_ZSt20__throw_future_errori FUNC:_ZSt20__throw_future_errori@@GLIBCXX_3.4.14 -FUNC:_ZSt20__throw_length_errorPKc FUNC:_ZSt20__throw_length_errorPKc@@GLIBCXX_3.4 -FUNC:_ZSt20__throw_out_of_rangePKc FUNC:_ZSt20__throw_out_of_rangePKc@@GLIBCXX_3.4 -FUNC:_ZSt20__throw_system_errori FUNC:_ZSt20__throw_system_errori@@GLIBCXX_3.4.11 -FUNC:_ZSt20__to_chars_float16_tPcS_fSt12chars_format FUNC:_ZSt20__to_chars_float16_tPcS_fSt12chars_format@@GLIBCXX_3.4.31 -FUNC:_ZSt21_Rb_tree_rotate_rightPSt18_Rb_tree_node_baseRS0_ FUNC:_ZSt21_Rb_tree_rotate_rightPSt18_Rb_tree_node_baseRS0_@@GLIBCXX_3.4 -FUNC:_ZSt21__copy_streambufs_eofIcSt11char_traitsIcEEiPSt15basic_streambufIT_T0_ES6_Rb FUNC:_ZSt21__copy_streambufs_eofIcSt11char_traitsIcEEiPSt15basic_streambufIT_T0_ES6_Rb@@GLIBCXX_3.4.9 -FUNC:_ZSt21__copy_streambufs_eofIwSt11char_traitsIwEEiPSt15basic_streambufIT_T0_ES6_Rb FUNC:_ZSt21__copy_streambufs_eofIwSt11char_traitsIwEEiPSt15basic_streambufIT_T0_ES6_Rb@@GLIBCXX_3.4.9 -FUNC:_ZSt21__glibcxx_assert_failPKciS0_S0_ FUNC:_ZSt21__glibcxx_assert_failPKciS0_S0_@@GLIBCXX_3.4.30 -FUNC:_ZSt21__throw_bad_exceptionv FUNC:_ZSt21__throw_bad_exceptionv@@GLIBCXX_3.4 -FUNC:_ZSt21__throw_runtime_errorPKc FUNC:_ZSt21__throw_runtime_errorPKc@@GLIBCXX_3.4 -FUNC:_ZSt21__to_chars_bfloat16_tPcS_fSt12chars_format FUNC:_ZSt21__to_chars_bfloat16_tPcS_fSt12chars_format@@GLIBCXX_3.4.31 -FUNC:_ZSt21ios_base_library_initv FUNC:_ZSt21ios_base_library_initv@@GLIBCXX_3.4.32 -FUNC:_ZSt22__from_chars_float16_tPKcS0_RfSt12chars_format FUNC:_ZSt22__from_chars_float16_tPKcS0_RfSt12chars_format@@GLIBCXX_3.4.31 -FUNC:_ZSt22__throw_overflow_errorPKc FUNC:_ZSt22__throw_overflow_errorPKc@@GLIBCXX_3.4 -FUNC:_ZSt23__from_chars_bfloat16_tPKcS0_RfSt12chars_format FUNC:_ZSt23__from_chars_bfloat16_tPKcS0_RfSt12chars_format@@GLIBCXX_3.4.31 -FUNC:_ZSt23__throw_underflow_errorPKc FUNC:_ZSt23__throw_underflow_errorPKc@@GLIBCXX_3.4 -FUNC:_ZSt24__throw_invalid_argumentPKc FUNC:_ZSt24__throw_invalid_argumentPKc@@GLIBCXX_3.4 -FUNC:_ZSt24__throw_out_of_range_fmtPKcz FUNC:_ZSt24__throw_out_of_range_fmtPKcz@@GLIBCXX_3.4.20 -FUNC:_ZSt25__throw_bad_function_callv FUNC:_ZSt25__throw_bad_function_callv@@GLIBCXX_3.4.14 -FUNC:_ZSt25notify_all_at_thread_exitRSt18condition_variableSt11unique_lockISt5mutexE FUNC:_ZSt25notify_all_at_thread_exitRSt18condition_variableSt11unique_lockISt5mutexE@@GLIBCXX_3.4.21 -FUNC:_ZSt28_Rb_tree_rebalance_for_erasePSt18_Rb_tree_node_baseRS_ FUNC:_ZSt28_Rb_tree_rebalance_for_erasePSt18_Rb_tree_node_baseRS_@@GLIBCXX_3.4 -FUNC:_ZSt28__throw_bad_array_new_lengthv FUNC:_ZSt28__throw_bad_array_new_lengthv@@GLIBCXX_3.4.29 -FUNC:_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_ FUNC:_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_@@GLIBCXX_3.4 -FUNC:_ZSt2wsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_ FUNC:_ZSt2wsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_@@GLIBCXX_3.4 -FUNC:_ZSt2wsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_ FUNC:_ZSt2wsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_@@GLIBCXX_3.4 -FUNC:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ FUNC:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4 -FUNC:_ZSt4endlIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_ FUNC:_ZSt4endlIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4 -FUNC:_ZSt4endsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ FUNC:_ZSt4endsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4 -FUNC:_ZSt4endsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_ FUNC:_ZSt4endsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4 -FUNC:_ZSt5flushIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ FUNC:_ZSt5flushIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4 -FUNC:_ZSt5flushIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_ FUNC:_ZSt5flushIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4 -FUNC:_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EE FUNC:_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EE@@GLIBCXX_3.4.21 -FUNC:_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EES4_ FUNC:_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EES4_@@GLIBCXX_3.4.21 -FUNC:_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E FUNC:_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E@@GLIBCXX_3.4 -FUNC:_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_ES4_ FUNC:_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_ES4_@@GLIBCXX_3.4 -FUNC:_ZSt7getlineIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EE FUNC:_ZSt7getlineIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EE@@GLIBCXX_3.4.21 -FUNC:_ZSt7getlineIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EES4_ FUNC:_ZSt7getlineIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EES4_@@GLIBCXX_3.4.21 -FUNC:_ZSt7getlineIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E FUNC:_ZSt7getlineIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E@@GLIBCXX_3.4 -FUNC:_ZSt7getlineIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_ES4_ FUNC:_ZSt7getlineIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_ES4_@@GLIBCXX_3.4 -FUNC:_ZSt8to_charsPcS_d FUNC:_ZSt8to_charsPcS_d@@GLIBCXX_3.4.29 -FUNC:_ZSt8to_charsPcS_dSt12chars_format FUNC:_ZSt8to_charsPcS_dSt12chars_format@@GLIBCXX_3.4.29 -FUNC:_ZSt8to_charsPcS_dSt12chars_formati FUNC:_ZSt8to_charsPcS_dSt12chars_formati@@GLIBCXX_3.4.29 -FUNC:_ZSt8to_charsPcS_e FUNC:_ZSt8to_charsPcS_e@@GLIBCXX_3.4.29 -FUNC:_ZSt8to_charsPcS_eSt12chars_format FUNC:_ZSt8to_charsPcS_eSt12chars_format@@GLIBCXX_3.4.29 -FUNC:_ZSt8to_charsPcS_eSt12chars_formati FUNC:_ZSt8to_charsPcS_eSt12chars_formati@@GLIBCXX_3.4.29 -FUNC:_ZSt8to_charsPcS_f FUNC:_ZSt8to_charsPcS_f@@GLIBCXX_3.4.29 -FUNC:_ZSt8to_charsPcS_fSt12chars_format FUNC:_ZSt8to_charsPcS_fSt12chars_format@@GLIBCXX_3.4.29 -FUNC:_ZSt8to_charsPcS_fSt12chars_formati FUNC:_ZSt8to_charsPcS_fSt12chars_formati@@GLIBCXX_3.4.29 -FUNC:_ZSt9has_facetINSt7__cxx1110moneypunctIcLb0EEEEbRKSt6locale FUNC:_ZSt9has_facetINSt7__cxx1110moneypunctIcLb0EEEEbRKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9has_facetINSt7__cxx1110moneypunctIwLb0EEEEbRKSt6locale FUNC:_ZSt9has_facetINSt7__cxx1110moneypunctIwLb0EEEEbRKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9has_facetINSt7__cxx117collateIcEEEbRKSt6locale FUNC:_ZSt9has_facetINSt7__cxx117collateIcEEEbRKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9has_facetINSt7__cxx117collateIwEEEbRKSt6locale FUNC:_ZSt9has_facetINSt7__cxx117collateIwEEEbRKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9has_facetINSt7__cxx118messagesIcEEEbRKSt6locale FUNC:_ZSt9has_facetINSt7__cxx118messagesIcEEEbRKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9has_facetINSt7__cxx118messagesIwEEEbRKSt6locale FUNC:_ZSt9has_facetINSt7__cxx118messagesIwEEEbRKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9has_facetINSt7__cxx118numpunctIcEEEbRKSt6locale FUNC:_ZSt9has_facetINSt7__cxx118numpunctIcEEEbRKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9has_facetINSt7__cxx118numpunctIwEEEbRKSt6locale FUNC:_ZSt9has_facetINSt7__cxx118numpunctIwEEEbRKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9has_facetINSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEEbRKSt6locale FUNC:_ZSt9has_facetINSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEEbRKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9has_facetINSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEEbRKSt6locale FUNC:_ZSt9has_facetINSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEEbRKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9has_facetINSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEEbRKSt6locale FUNC:_ZSt9has_facetINSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEEbRKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9has_facetINSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEEbRKSt6locale FUNC:_ZSt9has_facetINSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEEbRKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9has_facetINSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEEbRKSt6locale FUNC:_ZSt9has_facetINSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEEbRKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9has_facetINSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEEbRKSt6locale FUNC:_ZSt9has_facetINSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEEbRKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9has_facetISt10moneypunctIcLb0EEEbRKSt6locale FUNC:_ZSt9has_facetISt10moneypunctIcLb0EEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt10moneypunctIwLb0EEEbRKSt6locale FUNC:_ZSt9has_facetISt10moneypunctIwLb0EEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt11__timepunctIcEEbRKSt6locale FUNC:_ZSt9has_facetISt11__timepunctIcEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt11__timepunctIwEEbRKSt6locale FUNC:_ZSt9has_facetISt11__timepunctIwEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt5ctypeIcEEbRKSt6locale FUNC:_ZSt9has_facetISt5ctypeIcEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt5ctypeIwEEbRKSt6locale FUNC:_ZSt9has_facetISt5ctypeIwEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt7codecvtIcc11__mbstate_tEEbRKSt6locale FUNC:_ZSt9has_facetISt7codecvtIcc11__mbstate_tEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt7codecvtIwc11__mbstate_tEEbRKSt6locale FUNC:_ZSt9has_facetISt7codecvtIwc11__mbstate_tEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt7collateIcEEbRKSt6locale FUNC:_ZSt9has_facetISt7collateIcEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt7collateIwEEbRKSt6locale FUNC:_ZSt9has_facetISt7collateIwEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale FUNC:_ZSt9has_facetISt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale FUNC:_ZSt9has_facetISt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale FUNC:_ZSt9has_facetISt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale FUNC:_ZSt9has_facetISt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt8messagesIcEEbRKSt6locale FUNC:_ZSt9has_facetISt8messagesIcEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt8messagesIwEEbRKSt6locale FUNC:_ZSt9has_facetISt8messagesIwEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt8numpunctIcEEbRKSt6locale FUNC:_ZSt9has_facetISt8numpunctIcEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt8numpunctIwEEbRKSt6locale FUNC:_ZSt9has_facetISt8numpunctIwEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale FUNC:_ZSt9has_facetISt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale FUNC:_ZSt9has_facetISt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale FUNC:_ZSt9has_facetISt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale FUNC:_ZSt9has_facetISt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale FUNC:_ZSt9has_facetISt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale FUNC:_ZSt9has_facetISt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale FUNC:_ZSt9has_facetISt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9has_facetISt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale FUNC:_ZSt9has_facetISt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9terminatev FUNC:_ZSt9terminatev@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetINSt7__cxx1110moneypunctIcLb0EEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx1110moneypunctIcLb0EEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx1110moneypunctIcLb1EEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx1110moneypunctIcLb1EEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx1110moneypunctIwLb0EEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx1110moneypunctIwLb0EEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx1110moneypunctIwLb1EEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx1110moneypunctIwLb1EEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx117collateIcEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx117collateIcEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx117collateIwEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx117collateIwEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx118messagesIcEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx118messagesIcEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx118messagesIwEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx118messagesIwEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx118numpunctIcEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx118numpunctIcEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx118numpunctIwEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx118numpunctIwEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetINSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEERKT_RKSt6locale FUNC:_ZSt9use_facetINSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEERKT_RKSt6locale@@GLIBCXX_3.4.21 -FUNC:_ZSt9use_facetISt10moneypunctIcLb0EEERKT_RKSt6locale FUNC:_ZSt9use_facetISt10moneypunctIcLb0EEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt10moneypunctIcLb1EEERKT_RKSt6locale FUNC:_ZSt9use_facetISt10moneypunctIcLb1EEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt10moneypunctIwLb0EEERKT_RKSt6locale FUNC:_ZSt9use_facetISt10moneypunctIwLb0EEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt10moneypunctIwLb1EEERKT_RKSt6locale FUNC:_ZSt9use_facetISt10moneypunctIwLb1EEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt11__timepunctIcEERKT_RKSt6locale FUNC:_ZSt9use_facetISt11__timepunctIcEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt11__timepunctIwEERKT_RKSt6locale FUNC:_ZSt9use_facetISt11__timepunctIwEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt5ctypeIcEERKT_RKSt6locale FUNC:_ZSt9use_facetISt5ctypeIcEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt5ctypeIwEERKT_RKSt6locale FUNC:_ZSt9use_facetISt5ctypeIwEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt7codecvtIcc11__mbstate_tEERKT_RKSt6locale FUNC:_ZSt9use_facetISt7codecvtIcc11__mbstate_tEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt7codecvtIwc11__mbstate_tEERKT_RKSt6locale FUNC:_ZSt9use_facetISt7codecvtIwc11__mbstate_tEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt7collateIcEERKT_RKSt6locale FUNC:_ZSt9use_facetISt7collateIcEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt7collateIwEERKT_RKSt6locale FUNC:_ZSt9use_facetISt7collateIwEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale FUNC:_ZSt9use_facetISt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale FUNC:_ZSt9use_facetISt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale FUNC:_ZSt9use_facetISt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale FUNC:_ZSt9use_facetISt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt8messagesIcEERKT_RKSt6locale FUNC:_ZSt9use_facetISt8messagesIcEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt8messagesIwEERKT_RKSt6locale FUNC:_ZSt9use_facetISt8messagesIwEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt8numpunctIcEERKT_RKSt6locale FUNC:_ZSt9use_facetISt8numpunctIcEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt8numpunctIwEERKT_RKSt6locale FUNC:_ZSt9use_facetISt8numpunctIwEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale FUNC:_ZSt9use_facetISt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale FUNC:_ZSt9use_facetISt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale FUNC:_ZSt9use_facetISt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale FUNC:_ZSt9use_facetISt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale FUNC:_ZSt9use_facetISt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale FUNC:_ZSt9use_facetISt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale FUNC:_ZSt9use_facetISt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZSt9use_facetISt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale FUNC:_ZSt9use_facetISt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale@@GLIBCXX_3.4 -FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKa FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKa@@GLIBCXX_3.4 -FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@@GLIBCXX_3.4 -FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKh FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKh@@GLIBCXX_3.4 -FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_a FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_a@@GLIBCXX_3.4 -FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_c FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_c@@GLIBCXX_3.4 -FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_h FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_h@@GLIBCXX_3.4 -FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St12_Setiosflags FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St12_Setiosflags@@GLIBCXX_3.4 -FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St13_Setprecision FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St13_Setprecision@@GLIBCXX_3.4 -FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St14_Resetiosflags FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St14_Resetiosflags@@GLIBCXX_3.4 -FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St5_Setw FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St5_Setw@@GLIBCXX_3.4 -FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St8_Setbase FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St8_Setbase@@GLIBCXX_3.4 -FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St8_SetfillIS3_E FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St8_SetfillIS3_E@@GLIBCXX_3.4 -FUNC:_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKNSt7__cxx1112basic_stringIS4_S5_T1_EE FUNC:_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKNSt7__cxx1112basic_stringIS4_S5_T1_EE@@GLIBCXX_3.4.21 -FUNC:_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKSbIS4_S5_T1_E FUNC:_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKSbIS4_S5_T1_E@@GLIBCXX_3.4 -FUNC:_ZStlsIdcSt11char_traitsIcEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E FUNC:_ZStlsIdcSt11char_traitsIcEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E@@GLIBCXX_3.4 -FUNC:_ZStlsIdwSt11char_traitsIwEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E FUNC:_ZStlsIdwSt11char_traitsIwEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E@@GLIBCXX_3.4 -FUNC:_ZStlsIecSt11char_traitsIcEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E FUNC:_ZStlsIecSt11char_traitsIcEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E@@GLIBCXX_3.4 -FUNC:_ZStlsIewSt11char_traitsIwEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E FUNC:_ZStlsIewSt11char_traitsIwEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E@@GLIBCXX_3.4 -FUNC:_ZStlsIfcSt11char_traitsIcEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E FUNC:_ZStlsIfcSt11char_traitsIcEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E@@GLIBCXX_3.4 -FUNC:_ZStlsIfwSt11char_traitsIwEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E FUNC:_ZStlsIfwSt11char_traitsIwEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E@@GLIBCXX_3.4 -FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_PKS3_ FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_PKS3_@@GLIBCXX_3.4 -FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_PKc FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_PKc@@GLIBCXX_3.4 -FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_S3_ FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_S3_@@GLIBCXX_3.4 -FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St12_Setiosflags FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St12_Setiosflags@@GLIBCXX_3.4 -FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St13_Setprecision FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St13_Setprecision@@GLIBCXX_3.4 -FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St14_Resetiosflags FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St14_Resetiosflags@@GLIBCXX_3.4 -FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St5_Setw FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St5_Setw@@GLIBCXX_3.4 -FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St8_Setbase FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St8_Setbase@@GLIBCXX_3.4 -FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St8_SetfillIS3_E FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St8_SetfillIS3_E@@GLIBCXX_3.4 -FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_c FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_c@@GLIBCXX_3.4 -FUNC:_ZStlsIwSt11char_traitsIwESaIwEERSt13basic_ostreamIT_T0_ES7_RKNSt7__cxx1112basic_stringIS4_S5_T1_EE FUNC:_ZStlsIwSt11char_traitsIwESaIwEERSt13basic_ostreamIT_T0_ES7_RKNSt7__cxx1112basic_stringIS4_S5_T1_EE@@GLIBCXX_3.4.21 -FUNC:_ZStlsIwSt11char_traitsIwESaIwEERSt13basic_ostreamIT_T0_ES7_RKSbIS4_S5_T1_E FUNC:_ZStlsIwSt11char_traitsIwESaIwEERSt13basic_ostreamIT_T0_ES7_RKSbIS4_S5_T1_E@@GLIBCXX_3.4 -FUNC:_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_RKS8_ FUNC:_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_RKS8_@@GLIBCXX_3.4.21 -FUNC:_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_SA_ FUNC:_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_SA_@@GLIBCXX_3.4.21 -FUNC:_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EES5_RKS8_ FUNC:_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EES5_RKS8_@@GLIBCXX_3.4.21 -FUNC:_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6_ FUNC:_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6_@@GLIBCXX_3.4 -FUNC:_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_ FUNC:_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_@@GLIBCXX_3.4 -FUNC:_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ES3_RKS6_ FUNC:_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ES3_RKS6_@@GLIBCXX_3.4 -FUNC:_ZStplIwSt11char_traitsIwESaIwEENSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_RKS8_ FUNC:_ZStplIwSt11char_traitsIwESaIwEENSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_RKS8_@@GLIBCXX_3.4.21 -FUNC:_ZStplIwSt11char_traitsIwESaIwEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_SA_ FUNC:_ZStplIwSt11char_traitsIwESaIwEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_SA_@@GLIBCXX_3.4.21 -FUNC:_ZStplIwSt11char_traitsIwESaIwEENSt7__cxx1112basic_stringIT_T0_T1_EES5_RKS8_ FUNC:_ZStplIwSt11char_traitsIwESaIwEENSt7__cxx1112basic_stringIT_T0_T1_EES5_RKS8_@@GLIBCXX_3.4.21 -FUNC:_ZStplIwSt11char_traitsIwESaIwEESbIT_T0_T1_EPKS3_RKS6_ FUNC:_ZStplIwSt11char_traitsIwESaIwEESbIT_T0_T1_EPKS3_RKS6_@@GLIBCXX_3.4 -FUNC:_ZStplIwSt11char_traitsIwESaIwEESbIT_T0_T1_ERKS6_S8_ FUNC:_ZStplIwSt11char_traitsIwESaIwEESbIT_T0_T1_ERKS6_S8_@@GLIBCXX_3.4 -FUNC:_ZStplIwSt11char_traitsIwESaIwEESbIT_T0_T1_ES3_RKS6_ FUNC:_ZStplIwSt11char_traitsIwESaIwEESbIT_T0_T1_ES3_RKS6_@@GLIBCXX_3.4 -FUNC:_ZStrsISt11char_traitsIcEERSt13basic_istreamIcT_ES5_Pa FUNC:_ZStrsISt11char_traitsIcEERSt13basic_istreamIcT_ES5_Pa@@GLIBCXX_3.4 -FUNC:_ZStrsISt11char_traitsIcEERSt13basic_istreamIcT_ES5_Ph FUNC:_ZStrsISt11char_traitsIcEERSt13basic_istreamIcT_ES5_Ph@@GLIBCXX_3.4 -FUNC:_ZStrsISt11char_traitsIcEERSt13basic_istreamIcT_ES5_Ra FUNC:_ZStrsISt11char_traitsIcEERSt13basic_istreamIcT_ES5_Ra@@GLIBCXX_3.4 -FUNC:_ZStrsISt11char_traitsIcEERSt13basic_istreamIcT_ES5_Rh FUNC:_ZStrsISt11char_traitsIcEERSt13basic_istreamIcT_ES5_Rh@@GLIBCXX_3.4 -FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_PS3_ FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_PS3_@@GLIBCXX_3.4 -FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_RS3_ FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_RS3_@@GLIBCXX_3.4 -FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St12_Setiosflags FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St12_Setiosflags@@GLIBCXX_3.4 -FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St13_Setprecision FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St13_Setprecision@@GLIBCXX_3.4 -FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St14_Resetiosflags FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St14_Resetiosflags@@GLIBCXX_3.4 -FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St5_Setw FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St5_Setw@@GLIBCXX_3.4 -FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St8_Setbase FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St8_Setbase@@GLIBCXX_3.4 -FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St8_SetfillIS3_E FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St8_SetfillIS3_E@@GLIBCXX_3.4 -FUNC:_ZStrsIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EE FUNC:_ZStrsIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EE@@GLIBCXX_3.4.21 -FUNC:_ZStrsIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E FUNC:_ZStrsIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E@@GLIBCXX_3.4 -FUNC:_ZStrsIdcSt11char_traitsIcEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E FUNC:_ZStrsIdcSt11char_traitsIcEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E@@GLIBCXX_3.4 -FUNC:_ZStrsIdwSt11char_traitsIwEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E FUNC:_ZStrsIdwSt11char_traitsIwEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E@@GLIBCXX_3.4 -FUNC:_ZStrsIecSt11char_traitsIcEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E FUNC:_ZStrsIecSt11char_traitsIcEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E@@GLIBCXX_3.4 -FUNC:_ZStrsIewSt11char_traitsIwEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E FUNC:_ZStrsIewSt11char_traitsIwEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E@@GLIBCXX_3.4 -FUNC:_ZStrsIfcSt11char_traitsIcEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E FUNC:_ZStrsIfcSt11char_traitsIcEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E@@GLIBCXX_3.4 -FUNC:_ZStrsIfwSt11char_traitsIwEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E FUNC:_ZStrsIfwSt11char_traitsIwEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E@@GLIBCXX_3.4 -FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_PS3_ FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_PS3_@@GLIBCXX_3.4 -FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_RS3_ FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_RS3_@@GLIBCXX_3.4 -FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St12_Setiosflags FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St12_Setiosflags@@GLIBCXX_3.4 -FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St13_Setprecision FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St13_Setprecision@@GLIBCXX_3.4 -FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St14_Resetiosflags FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St14_Resetiosflags@@GLIBCXX_3.4 -FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St5_Setw FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St5_Setw@@GLIBCXX_3.4 -FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St8_Setbase FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St8_Setbase@@GLIBCXX_3.4 -FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St8_SetfillIS3_E FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St8_SetfillIS3_E@@GLIBCXX_3.4 -FUNC:_ZStrsIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EE FUNC:_ZStrsIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EE@@GLIBCXX_3.4.21 -FUNC:_ZStrsIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E FUNC:_ZStrsIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E@@GLIBCXX_3.4 -FUNC:_ZThn8_NSdD0Ev FUNC:_ZThn8_NSdD0Ev@@GLIBCXX_3.4 -FUNC:_ZThn8_NSdD1Ev FUNC:_ZThn8_NSdD1Ev@@GLIBCXX_3.4 -FUNC:_ZThn8_NSt13basic_fstreamIcSt11char_traitsIcEED0Ev FUNC:_ZThn8_NSt13basic_fstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZThn8_NSt13basic_fstreamIcSt11char_traitsIcEED1Ev FUNC:_ZThn8_NSt13basic_fstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZThn8_NSt13basic_fstreamIwSt11char_traitsIwEED0Ev FUNC:_ZThn8_NSt13basic_fstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZThn8_NSt13basic_fstreamIwSt11char_traitsIwEED1Ev FUNC:_ZThn8_NSt13basic_fstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZThn8_NSt14basic_iostreamIwSt11char_traitsIwEED0Ev FUNC:_ZThn8_NSt14basic_iostreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZThn8_NSt14basic_iostreamIwSt11char_traitsIwEED1Ev FUNC:_ZThn8_NSt14basic_iostreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZThn8_NSt18basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZThn8_NSt18basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZThn8_NSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZThn8_NSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZThn8_NSt18basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZThn8_NSt18basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZThn8_NSt18basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZThn8_NSt18basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZThn8_NSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZThn8_NSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZThn8_NSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZThn8_NSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZThn8_NSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZThn8_NSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZThn8_NSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZThn8_NSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZThn8_NSt9strstreamD0Ev FUNC:_ZThn8_NSt9strstreamD0Ev@@GLIBCXX_3.4 -FUNC:_ZThn8_NSt9strstreamD1Ev FUNC:_ZThn8_NSt9strstreamD1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSdD0Ev FUNC:_ZTv0_n12_NSdD0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSdD1Ev FUNC:_ZTv0_n12_NSdD1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSiD0Ev FUNC:_ZTv0_n12_NSiD0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSiD1Ev FUNC:_ZTv0_n12_NSiD1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSoD0Ev FUNC:_ZTv0_n12_NSoD0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSoD1Ev FUNC:_ZTv0_n12_NSoD1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt10istrstreamD0Ev FUNC:_ZTv0_n12_NSt10istrstreamD0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt10istrstreamD1Ev FUNC:_ZTv0_n12_NSt10istrstreamD1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt10ostrstreamD0Ev FUNC:_ZTv0_n12_NSt10ostrstreamD0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt10ostrstreamD1Ev FUNC:_ZTv0_n12_NSt10ostrstreamD1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt13basic_fstreamIcSt11char_traitsIcEED0Ev FUNC:_ZTv0_n12_NSt13basic_fstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt13basic_fstreamIcSt11char_traitsIcEED1Ev FUNC:_ZTv0_n12_NSt13basic_fstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt13basic_fstreamIwSt11char_traitsIwEED0Ev FUNC:_ZTv0_n12_NSt13basic_fstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt13basic_fstreamIwSt11char_traitsIwEED1Ev FUNC:_ZTv0_n12_NSt13basic_fstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt13basic_istreamIwSt11char_traitsIwEED0Ev FUNC:_ZTv0_n12_NSt13basic_istreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt13basic_istreamIwSt11char_traitsIwEED1Ev FUNC:_ZTv0_n12_NSt13basic_istreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt13basic_ostreamIwSt11char_traitsIwEED0Ev FUNC:_ZTv0_n12_NSt13basic_ostreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt13basic_ostreamIwSt11char_traitsIwEED1Ev FUNC:_ZTv0_n12_NSt13basic_ostreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt14basic_ifstreamIcSt11char_traitsIcEED0Ev FUNC:_ZTv0_n12_NSt14basic_ifstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt14basic_ifstreamIcSt11char_traitsIcEED1Ev FUNC:_ZTv0_n12_NSt14basic_ifstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt14basic_ifstreamIwSt11char_traitsIwEED0Ev FUNC:_ZTv0_n12_NSt14basic_ifstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt14basic_ifstreamIwSt11char_traitsIwEED1Ev FUNC:_ZTv0_n12_NSt14basic_ifstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt14basic_iostreamIwSt11char_traitsIwEED0Ev FUNC:_ZTv0_n12_NSt14basic_iostreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt14basic_iostreamIwSt11char_traitsIwEED1Ev FUNC:_ZTv0_n12_NSt14basic_iostreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt14basic_ofstreamIcSt11char_traitsIcEED0Ev FUNC:_ZTv0_n12_NSt14basic_ofstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt14basic_ofstreamIcSt11char_traitsIcEED1Ev FUNC:_ZTv0_n12_NSt14basic_ofstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt14basic_ofstreamIwSt11char_traitsIwEED0Ev FUNC:_ZTv0_n12_NSt14basic_ofstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt14basic_ofstreamIwSt11char_traitsIwEED1Ev FUNC:_ZTv0_n12_NSt14basic_ofstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt18basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZTv0_n12_NSt18basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZTv0_n12_NSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt18basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZTv0_n12_NSt18basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt18basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZTv0_n12_NSt18basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt19basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZTv0_n12_NSt19basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt19basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZTv0_n12_NSt19basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt19basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZTv0_n12_NSt19basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt19basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZTv0_n12_NSt19basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZTv0_n12_NSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZTv0_n12_NSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZTv0_n12_NSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZTv0_n12_NSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZTv0_n12_NSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZTv0_n12_NSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZTv0_n12_NSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZTv0_n12_NSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZTv0_n12_NSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZTv0_n12_NSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZTv0_n12_NSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZTv0_n12_NSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZTv0_n12_NSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZTv0_n12_NSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZTv0_n12_NSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZTv0_n12_NSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZTv0_n12_NSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZTv0_n12_NSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZTv0_n12_NSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZTv0_n12_NSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev FUNC:_ZTv0_n12_NSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZTv0_n12_NSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev FUNC:_ZTv0_n12_NSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZTv0_n12_NSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev FUNC:_ZTv0_n12_NSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 -FUNC:_ZTv0_n12_NSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev FUNC:_ZTv0_n12_NSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 -FUNC:_ZTv0_n12_NSt9strstreamD0Ev FUNC:_ZTv0_n12_NSt9strstreamD0Ev@@GLIBCXX_3.4 -FUNC:_ZTv0_n12_NSt9strstreamD1Ev FUNC:_ZTv0_n12_NSt9strstreamD1Ev@@GLIBCXX_3.4 -FUNC:_ZdaPv FUNC:_ZdaPv@@GLIBCXX_3.4 -FUNC:_ZdaPvRKSt9nothrow_t FUNC:_ZdaPvRKSt9nothrow_t@@GLIBCXX_3.4 -FUNC:_ZdaPvSt11align_val_t FUNC:_ZdaPvSt11align_val_t@@CXXABI_1.3.11 -FUNC:_ZdaPvSt11align_val_tRKSt9nothrow_t FUNC:_ZdaPvSt11align_val_tRKSt9nothrow_t@@CXXABI_1.3.11 -FUNC:_ZdaPvj FUNC:_ZdaPvj@@CXXABI_1.3.9 -FUNC:_ZdaPvjSt11align_val_t FUNC:_ZdaPvjSt11align_val_t@@CXXABI_1.3.11 -FUNC:_ZdlPv FUNC:_ZdlPv@@GLIBCXX_3.4 -FUNC:_ZdlPvRKSt9nothrow_t FUNC:_ZdlPvRKSt9nothrow_t@@GLIBCXX_3.4 -FUNC:_ZdlPvSt11align_val_t FUNC:_ZdlPvSt11align_val_t@@CXXABI_1.3.11 -FUNC:_ZdlPvSt11align_val_tRKSt9nothrow_t FUNC:_ZdlPvSt11align_val_tRKSt9nothrow_t@@CXXABI_1.3.11 -FUNC:_ZdlPvj FUNC:_ZdlPvj@@CXXABI_1.3.9 -FUNC:_ZdlPvjSt11align_val_t FUNC:_ZdlPvjSt11align_val_t@@CXXABI_1.3.11 -FUNC:_Znaj FUNC:_Znaj@@GLIBCXX_3.4 -FUNC:_ZnajRKSt9nothrow_t FUNC:_ZnajRKSt9nothrow_t@@GLIBCXX_3.4 -FUNC:_ZnajSt11align_val_t FUNC:_ZnajSt11align_val_t@@CXXABI_1.3.11 -FUNC:_ZnajSt11align_val_tRKSt9nothrow_t FUNC:_ZnajSt11align_val_tRKSt9nothrow_t@@CXXABI_1.3.11 -FUNC:_Znwj FUNC:_Znwj@@GLIBCXX_3.4 -FUNC:_ZnwjRKSt9nothrow_t FUNC:_ZnwjRKSt9nothrow_t@@GLIBCXX_3.4 -FUNC:_ZnwjSt11align_val_t FUNC:_ZnwjSt11align_val_t@@CXXABI_1.3.11 -FUNC:_ZnwjSt11align_val_tRKSt9nothrow_t FUNC:_ZnwjSt11align_val_tRKSt9nothrow_t@@CXXABI_1.3.11 -FUNC:__atomic_flag_for_address FUNC:__atomic_flag_for_address@@GLIBCXX_3.4.11 -FUNC:__atomic_flag_wait_explicit FUNC:__atomic_flag_wait_explicit@@GLIBCXX_3.4.11 -FUNC:__cxa_allocate_dependent_exception FUNC:__cxa_allocate_dependent_exception@@CXXABI_1.3.6 -FUNC:__cxa_allocate_exception FUNC:__cxa_allocate_exception@@CXXABI_1.3 -FUNC:__cxa_bad_cast FUNC:__cxa_bad_cast@@CXXABI_1.3 -FUNC:__cxa_bad_typeid FUNC:__cxa_bad_typeid@@CXXABI_1.3 -FUNC:__cxa_begin_catch FUNC:__cxa_begin_catch@@CXXABI_1.3 -FUNC:__cxa_call_terminate FUNC:__cxa_call_terminate@@CXXABI_1.3.15 -FUNC:__cxa_call_unexpected FUNC:__cxa_call_unexpected@@CXXABI_1.3 -FUNC:__cxa_current_exception_type FUNC:__cxa_current_exception_type@@CXXABI_1.3 -FUNC:__cxa_deleted_virtual FUNC:__cxa_deleted_virtual@@CXXABI_1.3.6 -FUNC:__cxa_demangle FUNC:__cxa_demangle@@CXXABI_1.3 -FUNC:__cxa_end_catch FUNC:__cxa_end_catch@@CXXABI_1.3 -FUNC:__cxa_free_dependent_exception FUNC:__cxa_free_dependent_exception@@CXXABI_1.3.6 -FUNC:__cxa_free_exception FUNC:__cxa_free_exception@@CXXABI_1.3 -FUNC:__cxa_get_exception_ptr FUNC:__cxa_get_exception_ptr@@CXXABI_1.3.1 -FUNC:__cxa_get_globals FUNC:__cxa_get_globals@@CXXABI_1.3 -FUNC:__cxa_get_globals_fast FUNC:__cxa_get_globals_fast@@CXXABI_1.3 -FUNC:__cxa_guard_abort FUNC:__cxa_guard_abort@@CXXABI_1.3 -FUNC:__cxa_guard_acquire FUNC:__cxa_guard_acquire@@CXXABI_1.3 -FUNC:__cxa_guard_release FUNC:__cxa_guard_release@@CXXABI_1.3 -FUNC:__cxa_init_primary_exception FUNC:__cxa_init_primary_exception@@CXXABI_1.3.11 -FUNC:__cxa_pure_virtual FUNC:__cxa_pure_virtual@@CXXABI_1.3 -FUNC:__cxa_rethrow FUNC:__cxa_rethrow@@CXXABI_1.3 -FUNC:__cxa_thread_atexit FUNC:__cxa_thread_atexit@@CXXABI_1.3.7 -FUNC:__cxa_throw FUNC:__cxa_throw@@CXXABI_1.3 -FUNC:__cxa_throw_bad_array_length FUNC:__cxa_throw_bad_array_length@@CXXABI_1.3.8 -FUNC:__cxa_throw_bad_array_new_length FUNC:__cxa_throw_bad_array_new_length@@CXXABI_1.3.8 -FUNC:__cxa_tm_cleanup FUNC:__cxa_tm_cleanup@@CXXABI_TM_1 -FUNC:__cxa_vec_cctor FUNC:__cxa_vec_cctor@@CXXABI_1.3 -FUNC:__cxa_vec_cleanup FUNC:__cxa_vec_cleanup@@CXXABI_1.3 -FUNC:__cxa_vec_ctor FUNC:__cxa_vec_ctor@@CXXABI_1.3 -FUNC:__cxa_vec_delete -FUNC:__cxa_vec_delete2 FUNC:__cxa_vec_delete2@@CXXABI_1.3 -FUNC:__cxa_vec_delete3 FUNC:__cxa_vec_delete3@@CXXABI_1.3 FUNC:__cxa_vec_delete@@CXXABI_1.3 -FUNC:__cxa_vec_dtor FUNC:__cxa_vec_dtor@@CXXABI_1.3 -FUNC:__cxa_vec_new -FUNC:__cxa_vec_new2 FUNC:__cxa_vec_new2@@CXXABI_1.3 -FUNC:__cxa_vec_new3 FUNC:__cxa_vec_new3@@CXXABI_1.3 FUNC:__cxa_vec_new@@CXXABI_1.3 -FUNC:__dynamic_cast FUNC:__dynamic_cast@@CXXABI_1.3 -FUNC:__gxx_personality_v0 FUNC:__gxx_personality_v0@@CXXABI_1.3 -FUNC:__once_proxy FUNC:__once_proxy@@GLIBCXX_3.4.11 FUNC:acosl@GLIBCXX_3.4.3 FUNC:asinl@GLIBCXX_3.4.3 FUNC:atan2l@GLIBCXX_3.4 FUNC:atanl@GLIBCXX_3.4.3 -FUNC:atomic_flag_clear_explicit FUNC:atomic_flag_clear_explicit@@GLIBCXX_3.4.11 -FUNC:atomic_flag_test_and_set_explicit FUNC:atomic_flag_test_and_set_explicit@@GLIBCXX_3.4.11 FUNC:ceill@GLIBCXX_3.4.3 FUNC:coshl@GLIBCXX_3.4 @@ -9142,2771 +4647,1395 @@ OBJECT:0:GLIBCXX_3.4.3 OBJECT:0:GLIBCXX_3.4.30 OBJECT:0:GLIBCXX_3.4.31 OBJECT:0:GLIBCXX_3.4.32 +OBJECT:0:GLIBCXX_3.4.33 +OBJECT:0:GLIBCXX_3.4.34 +OBJECT:0:GLIBCXX_3.4.35 OBJECT:0:GLIBCXX_3.4.4 OBJECT:0:GLIBCXX_3.4.5 OBJECT:0:GLIBCXX_3.4.6 OBJECT:0:GLIBCXX_3.4.7 OBJECT:0:GLIBCXX_3.4.8 OBJECT:0:GLIBCXX_3.4.9 -OBJECT:1028:_ZNSt3tr18__detail12__prime_listE OBJECT:1028:_ZNSt3tr18__detail12__prime_listE@@GLIBCXX_3.4.10 -OBJECT:1028:_ZNSt8__detail12__prime_listE OBJECT:1028:_ZNSt8__detail12__prime_listE@@GLIBCXX_3.4.10 -OBJECT:12:_ZTIN10__cxxabiv116__enum_type_infoE OBJECT:12:_ZTIN10__cxxabiv116__enum_type_infoE@@CXXABI_1.3 -OBJECT:12:_ZTIN10__cxxabiv117__array_type_infoE OBJECT:12:_ZTIN10__cxxabiv117__array_type_infoE@@CXXABI_1.3 -OBJECT:12:_ZTIN10__cxxabiv117__class_type_infoE OBJECT:12:_ZTIN10__cxxabiv117__class_type_infoE@@CXXABI_1.3 -OBJECT:12:_ZTIN10__cxxabiv117__pbase_type_infoE OBJECT:12:_ZTIN10__cxxabiv117__pbase_type_infoE@@CXXABI_1.3 -OBJECT:12:_ZTIN10__cxxabiv119__pointer_type_infoE OBJECT:12:_ZTIN10__cxxabiv119__pointer_type_infoE@@CXXABI_1.3 -OBJECT:12:_ZTIN10__cxxabiv120__function_type_infoE OBJECT:12:_ZTIN10__cxxabiv120__function_type_infoE@@CXXABI_1.3 -OBJECT:12:_ZTIN10__cxxabiv120__si_class_type_infoE OBJECT:12:_ZTIN10__cxxabiv120__si_class_type_infoE@@CXXABI_1.3 -OBJECT:12:_ZTIN10__cxxabiv121__vmi_class_type_infoE OBJECT:12:_ZTIN10__cxxabiv121__vmi_class_type_infoE@@CXXABI_1.3 -OBJECT:12:_ZTIN10__cxxabiv123__fundamental_type_infoE OBJECT:12:_ZTIN10__cxxabiv123__fundamental_type_infoE@@CXXABI_1.3 -OBJECT:12:_ZTIN10__cxxabiv129__pointer_to_member_type_infoE OBJECT:12:_ZTIN10__cxxabiv129__pointer_to_member_type_infoE@@CXXABI_1.3 -OBJECT:12:_ZTIN9__gnu_cxx13stdio_filebufIcSt11char_traitsIcEEE OBJECT:12:_ZTIN9__gnu_cxx13stdio_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTIN9__gnu_cxx13stdio_filebufIwSt11char_traitsIwEEE OBJECT:12:_ZTIN9__gnu_cxx13stdio_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTIN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEE OBJECT:12:_ZTIN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTIN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEE OBJECT:12:_ZTIN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTINSt10filesystem16filesystem_errorE OBJECT:12:_ZTINSt10filesystem16filesystem_errorE@@GLIBCXX_3.4.26 -OBJECT:12:_ZTINSt10filesystem7__cxx1116filesystem_errorE OBJECT:12:_ZTINSt10filesystem7__cxx1116filesystem_errorE@@GLIBCXX_3.4.26 -OBJECT:12:_ZTINSt13__future_base19_Async_state_commonE OBJECT:12:_ZTINSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17 -OBJECT:12:_ZTINSt3pmr25monotonic_buffer_resourceE OBJECT:12:_ZTINSt3pmr25monotonic_buffer_resourceE@@GLIBCXX_3.4.28 -OBJECT:12:_ZTINSt3pmr26synchronized_pool_resourceE OBJECT:12:_ZTINSt3pmr26synchronized_pool_resourceE@@GLIBCXX_3.4.26 -OBJECT:12:_ZTINSt3pmr28unsynchronized_pool_resourceE OBJECT:12:_ZTINSt3pmr28unsynchronized_pool_resourceE@@GLIBCXX_3.4.26 -OBJECT:12:_ZTINSt7__cxx1114collate_bynameIcEE OBJECT:12:_ZTINSt7__cxx1114collate_bynameIcEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1114collate_bynameIwEE OBJECT:12:_ZTINSt7__cxx1114collate_bynameIwEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE OBJECT:12:_ZTINSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEE OBJECT:12:_ZTINSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1115messages_bynameIcEE OBJECT:12:_ZTINSt7__cxx1115messages_bynameIcEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1115messages_bynameIwEE OBJECT:12:_ZTINSt7__cxx1115messages_bynameIwEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1115numpunct_bynameIcEE OBJECT:12:_ZTINSt7__cxx1115numpunct_bynameIcEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1115numpunct_bynameIwEE OBJECT:12:_ZTINSt7__cxx1115numpunct_bynameIwEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE OBJECT:12:_ZTINSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE OBJECT:12:_ZTINSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1117moneypunct_bynameIcLb0EEE OBJECT:12:_ZTINSt7__cxx1117moneypunct_bynameIcLb0EEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1117moneypunct_bynameIcLb1EEE OBJECT:12:_ZTINSt7__cxx1117moneypunct_bynameIcLb1EEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1117moneypunct_bynameIwLb0EEE OBJECT:12:_ZTINSt7__cxx1117moneypunct_bynameIwLb0EEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1117moneypunct_bynameIwLb1EEE OBJECT:12:_ZTINSt7__cxx1117moneypunct_bynameIwLb1EEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE OBJECT:12:_ZTINSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE OBJECT:12:_ZTINSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE OBJECT:12:_ZTINSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE OBJECT:12:_ZTINSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE OBJECT:12:_ZTINSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE OBJECT:12:_ZTINSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx117collateIcEE OBJECT:12:_ZTINSt7__cxx117collateIcEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx117collateIwEE OBJECT:12:_ZTINSt7__cxx117collateIwEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx118numpunctIcEE OBJECT:12:_ZTINSt7__cxx118numpunctIcEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx118numpunctIwEE OBJECT:12:_ZTINSt7__cxx118numpunctIwEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE OBJECT:12:_ZTINSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE OBJECT:12:_ZTINSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE OBJECT:12:_ZTINSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE OBJECT:12:_ZTINSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt8ios_base7failureB5cxx11E OBJECT:12:_ZTINSt8ios_base7failureB5cxx11E@@GLIBCXX_3.4.21 -OBJECT:12:_ZTINSt8ios_base7failureE OBJECT:12:_ZTINSt8ios_base7failureE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt10bad_typeid OBJECT:12:_ZTISt10bad_typeid@@GLIBCXX_3.4 -OBJECT:12:_ZTISt10istrstream OBJECT:12:_ZTISt10istrstream@@GLIBCXX_3.4 -OBJECT:12:_ZTISt10lock_error OBJECT:12:_ZTISt10lock_error@@GLIBCXX_3.4.11 -OBJECT:12:_ZTISt10ostrstream OBJECT:12:_ZTISt10ostrstream@@GLIBCXX_3.4 -OBJECT:12:_ZTISt11__timepunctIcE OBJECT:12:_ZTISt11__timepunctIcE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt11__timepunctIwE OBJECT:12:_ZTISt11__timepunctIwE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt11logic_error OBJECT:12:_ZTISt11logic_error@@GLIBCXX_3.4 -OBJECT:12:_ZTISt11range_error OBJECT:12:_ZTISt11range_error@@GLIBCXX_3.4 -OBJECT:12:_ZTISt11regex_error OBJECT:12:_ZTISt11regex_error@@GLIBCXX_3.4.15 -OBJECT:12:_ZTISt12bad_weak_ptr OBJECT:12:_ZTISt12bad_weak_ptr@@GLIBCXX_3.4.15 -OBJECT:12:_ZTISt12ctype_bynameIcE OBJECT:12:_ZTISt12ctype_bynameIcE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt12ctype_bynameIwE OBJECT:12:_ZTISt12ctype_bynameIwE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt12domain_error OBJECT:12:_ZTISt12domain_error@@GLIBCXX_3.4 -OBJECT:12:_ZTISt12future_error OBJECT:12:_ZTISt12future_error@@GLIBCXX_3.4.14 -OBJECT:12:_ZTISt12length_error OBJECT:12:_ZTISt12length_error@@GLIBCXX_3.4 -OBJECT:12:_ZTISt12out_of_range OBJECT:12:_ZTISt12out_of_range@@GLIBCXX_3.4 -OBJECT:12:_ZTISt12strstreambuf OBJECT:12:_ZTISt12strstreambuf@@GLIBCXX_3.4 -OBJECT:12:_ZTISt12system_error OBJECT:12:_ZTISt12system_error@@GLIBCXX_3.4.11 -OBJECT:12:_ZTISt13bad_exception OBJECT:12:_ZTISt13bad_exception@@GLIBCXX_3.4 -OBJECT:12:_ZTISt13basic_filebufIcSt11char_traitsIcEE OBJECT:12:_ZTISt13basic_filebufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt13basic_filebufIwSt11char_traitsIwEE OBJECT:12:_ZTISt13basic_filebufIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt13basic_fstreamIcSt11char_traitsIcEE OBJECT:12:_ZTISt13basic_fstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt13basic_fstreamIwSt11char_traitsIwEE OBJECT:12:_ZTISt13basic_fstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt13runtime_error OBJECT:12:_ZTISt13runtime_error@@GLIBCXX_3.4 -OBJECT:12:_ZTISt14basic_ifstreamIcSt11char_traitsIcEE OBJECT:12:_ZTISt14basic_ifstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt14basic_ifstreamIwSt11char_traitsIwEE OBJECT:12:_ZTISt14basic_ifstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt14basic_ofstreamIcSt11char_traitsIcEE OBJECT:12:_ZTISt14basic_ofstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt14basic_ofstreamIwSt11char_traitsIwEE OBJECT:12:_ZTISt14basic_ofstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt14codecvt_bynameIcc11__mbstate_tE OBJECT:12:_ZTISt14codecvt_bynameIcc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt14codecvt_bynameIwc11__mbstate_tE OBJECT:12:_ZTISt14codecvt_bynameIwc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt14collate_bynameIcE OBJECT:12:_ZTISt14collate_bynameIcE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt14collate_bynameIwE OBJECT:12:_ZTISt14collate_bynameIwE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt14overflow_error OBJECT:12:_ZTISt14overflow_error@@GLIBCXX_3.4 -OBJECT:12:_ZTISt15basic_stringbufIcSt11char_traitsIcESaIcEE OBJECT:12:_ZTISt15basic_stringbufIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt15basic_stringbufIwSt11char_traitsIwESaIwEE OBJECT:12:_ZTISt15basic_stringbufIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt15messages_bynameIcE OBJECT:12:_ZTISt15messages_bynameIcE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt15messages_bynameIwE OBJECT:12:_ZTISt15messages_bynameIwE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt15numpunct_bynameIcE OBJECT:12:_ZTISt15numpunct_bynameIcE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt15numpunct_bynameIwE OBJECT:12:_ZTISt15numpunct_bynameIwE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:12:_ZTISt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:12:_ZTISt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:12:_ZTISt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:12:_ZTISt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt15underflow_error OBJECT:12:_ZTISt15underflow_error@@GLIBCXX_3.4 -OBJECT:12:_ZTISt16bad_array_length OBJECT:12:_ZTISt16bad_array_length@@CXXABI_1.3.8 -OBJECT:12:_ZTISt16invalid_argument OBJECT:12:_ZTISt16invalid_argument@@GLIBCXX_3.4 -OBJECT:12:_ZTISt17bad_function_call OBJECT:12:_ZTISt17bad_function_call@@GLIBCXX_3.4.15 -OBJECT:12:_ZTISt17moneypunct_bynameIcLb0EE OBJECT:12:_ZTISt17moneypunct_bynameIcLb0EE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt17moneypunct_bynameIcLb1EE OBJECT:12:_ZTISt17moneypunct_bynameIcLb1EE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt17moneypunct_bynameIwLb0EE OBJECT:12:_ZTISt17moneypunct_bynameIwLb0EE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt17moneypunct_bynameIwLb1EE OBJECT:12:_ZTISt17moneypunct_bynameIwLb1EE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt18basic_stringstreamIcSt11char_traitsIcESaIcEE OBJECT:12:_ZTISt18basic_stringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt18basic_stringstreamIwSt11char_traitsIwESaIwEE OBJECT:12:_ZTISt18basic_stringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt19__codecvt_utf8_baseIDiE OBJECT:12:_ZTISt19__codecvt_utf8_baseIDiE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTISt19__codecvt_utf8_baseIDsE OBJECT:12:_ZTISt19__codecvt_utf8_baseIDsE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTISt19__codecvt_utf8_baseIwE OBJECT:12:_ZTISt19__codecvt_utf8_baseIwE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTISt19basic_istringstreamIcSt11char_traitsIcESaIcEE OBJECT:12:_ZTISt19basic_istringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt19basic_istringstreamIwSt11char_traitsIwESaIwEE OBJECT:12:_ZTISt19basic_istringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt19basic_ostringstreamIcSt11char_traitsIcESaIcEE OBJECT:12:_ZTISt19basic_ostringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt19basic_ostringstreamIwSt11char_traitsIwESaIwEE OBJECT:12:_ZTISt19basic_ostringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt20__codecvt_utf16_baseIDiE OBJECT:12:_ZTISt20__codecvt_utf16_baseIDiE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTISt20__codecvt_utf16_baseIDsE OBJECT:12:_ZTISt20__codecvt_utf16_baseIDsE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTISt20__codecvt_utf16_baseIwE OBJECT:12:_ZTISt20__codecvt_utf16_baseIwE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTISt20bad_array_new_length OBJECT:12:_ZTISt20bad_array_new_length@@CXXABI_1.3.8 -OBJECT:12:_ZTISt25__codecvt_utf8_utf16_baseIDiE OBJECT:12:_ZTISt25__codecvt_utf8_utf16_baseIDiE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTISt25__codecvt_utf8_utf16_baseIDsE OBJECT:12:_ZTISt25__codecvt_utf8_utf16_baseIDsE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTISt25__codecvt_utf8_utf16_baseIwE OBJECT:12:_ZTISt25__codecvt_utf8_utf16_baseIwE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTISt5ctypeIwE OBJECT:12:_ZTISt5ctypeIwE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt7codecvtIDiDu11__mbstate_tE OBJECT:12:_ZTISt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26 -OBJECT:12:_ZTISt7codecvtIDic11__mbstate_tE OBJECT:12:_ZTISt7codecvtIDic11__mbstate_tE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTISt7codecvtIDsDu11__mbstate_tE OBJECT:12:_ZTISt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26 -OBJECT:12:_ZTISt7codecvtIDsc11__mbstate_tE OBJECT:12:_ZTISt7codecvtIDsc11__mbstate_tE@@GLIBCXX_3.4.21 -OBJECT:12:_ZTISt7codecvtIcc11__mbstate_tE OBJECT:12:_ZTISt7codecvtIcc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt7codecvtIwc11__mbstate_tE OBJECT:12:_ZTISt7codecvtIwc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt7collateIcE OBJECT:12:_ZTISt7collateIcE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt7collateIwE OBJECT:12:_ZTISt7collateIwE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:12:_ZTISt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:12:_ZTISt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:12:_ZTISt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:12:_ZTISt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt8bad_cast OBJECT:12:_ZTISt8bad_cast@@GLIBCXX_3.4 -OBJECT:12:_ZTISt8numpunctIcE OBJECT:12:_ZTISt8numpunctIcE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt8numpunctIwE OBJECT:12:_ZTISt8numpunctIwE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:12:_ZTISt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:12:_ZTISt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt9bad_alloc OBJECT:12:_ZTISt9bad_alloc@@GLIBCXX_3.4 -OBJECT:12:_ZTISt9basic_iosIcSt11char_traitsIcEE OBJECT:12:_ZTISt9basic_iosIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt9basic_iosIwSt11char_traitsIwEE OBJECT:12:_ZTISt9basic_iosIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:12:_ZTISt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:12:_ZTISt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:12:_ZTISt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:12:_ZTISt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:12:_ZTISt9strstream OBJECT:12:_ZTISt9strstream@@GLIBCXX_3.4 -OBJECT:12:_ZTSSt5ctypeIcE OBJECT:12:_ZTSSt5ctypeIcE@@GLIBCXX_3.4 -OBJECT:12:_ZTSSt5ctypeIwE OBJECT:12:_ZTSSt5ctypeIwE@@GLIBCXX_3.4 -OBJECT:12:_ZTSSt8bad_cast OBJECT:12:_ZTSSt8bad_cast@@GLIBCXX_3.4 -OBJECT:12:_ZTSSt8ios_base OBJECT:12:_ZTSSt8ios_base@@GLIBCXX_3.4 -OBJECT:13:_ZTSSt9bad_alloc OBJECT:13:_ZTSSt9bad_alloc@@GLIBCXX_3.4 -OBJECT:13:_ZTSSt9exception OBJECT:13:_ZTSSt9exception@@GLIBCXX_3.4 -OBJECT:13:_ZTSSt9strstream OBJECT:13:_ZTSSt9strstream@@GLIBCXX_3.4 -OBJECT:13:_ZTSSt9time_base OBJECT:13:_ZTSSt9time_base@@GLIBCXX_3.4 -OBJECT:13:_ZTSSt9type_info OBJECT:13:_ZTSSt9type_info@@GLIBCXX_3.4 -OBJECT:140:_ZSt4cerr OBJECT:140:_ZSt4cerr@@GLIBCXX_3.4 -OBJECT:140:_ZSt4clog OBJECT:140:_ZSt4clog@@GLIBCXX_3.4 -OBJECT:140:_ZSt4cout OBJECT:140:_ZSt4cout@@GLIBCXX_3.4 -OBJECT:144:_ZSt3cin OBJECT:144:_ZSt3cin@@GLIBCXX_3.4 -OBJECT:144:_ZSt5wcerr OBJECT:144:_ZSt5wcerr@@GLIBCXX_3.4 -OBJECT:144:_ZSt5wclog OBJECT:144:_ZSt5wclog@@GLIBCXX_3.4 -OBJECT:144:_ZSt5wcout OBJECT:144:_ZSt5wcout@@GLIBCXX_3.4 -OBJECT:148:_ZSt4wcin OBJECT:148:_ZSt4wcin@@GLIBCXX_3.4 -OBJECT:14:_ZTSSt7collateIcE OBJECT:14:_ZTSSt7collateIcE@@GLIBCXX_3.4 -OBJECT:14:_ZTSSt7collateIwE OBJECT:14:_ZTSSt7collateIwE@@GLIBCXX_3.4 -OBJECT:15:_ZTSSt10bad_typeid OBJECT:15:_ZTSSt10bad_typeid@@GLIBCXX_3.4 -OBJECT:15:_ZTSSt10ctype_base OBJECT:15:_ZTSSt10ctype_base@@GLIBCXX_3.4 -OBJECT:15:_ZTSSt10istrstream OBJECT:15:_ZTSSt10istrstream@@GLIBCXX_3.4 -OBJECT:15:_ZTSSt10lock_error OBJECT:15:_ZTSSt10lock_error@@GLIBCXX_3.4.11 -OBJECT:15:_ZTSSt10money_base OBJECT:15:_ZTSSt10money_base@@GLIBCXX_3.4 -OBJECT:15:_ZTSSt10ostrstream OBJECT:15:_ZTSSt10ostrstream@@GLIBCXX_3.4 -OBJECT:15:_ZTSSt8messagesIcE OBJECT:15:_ZTSSt8messagesIcE@@GLIBCXX_3.4 -OBJECT:15:_ZTSSt8messagesIwE OBJECT:15:_ZTSSt8messagesIwE@@GLIBCXX_3.4 -OBJECT:15:_ZTSSt8numpunctIcE OBJECT:15:_ZTSSt8numpunctIcE@@GLIBCXX_3.4 -OBJECT:15:_ZTSSt8numpunctIwE OBJECT:15:_ZTSSt8numpunctIwE@@GLIBCXX_3.4 -OBJECT:16:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE OBJECT:16:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4 -OBJECT:16:_ZNSs4_Rep20_S_empty_rep_storageE OBJECT:16:_ZNSs4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4 -OBJECT:16:_ZTIPDF32_ OBJECT:16:_ZTIPDF32_@@CXXABI_1.3.14 -OBJECT:16:_ZTIPDF32x OBJECT:16:_ZTIPDF32x@@CXXABI_1.3.14 -OBJECT:16:_ZTIPDF64_ OBJECT:16:_ZTIPDF64_@@CXXABI_1.3.14 -OBJECT:16:_ZTIPDd OBJECT:16:_ZTIPDd@@CXXABI_1.3.4 -OBJECT:16:_ZTIPDe OBJECT:16:_ZTIPDe@@CXXABI_1.3.4 -OBJECT:16:_ZTIPDf OBJECT:16:_ZTIPDf@@CXXABI_1.3.4 -OBJECT:16:_ZTIPDi OBJECT:16:_ZTIPDi@@CXXABI_1.3.3 -OBJECT:16:_ZTIPDn OBJECT:16:_ZTIPDn@@CXXABI_1.3.5 -OBJECT:16:_ZTIPDs OBJECT:16:_ZTIPDs@@CXXABI_1.3.3 -OBJECT:16:_ZTIPDu OBJECT:16:_ZTIPDu@@CXXABI_1.3.12 -OBJECT:16:_ZTIPKDF32_ OBJECT:16:_ZTIPKDF32_@@CXXABI_1.3.14 -OBJECT:16:_ZTIPKDF32x OBJECT:16:_ZTIPKDF32x@@CXXABI_1.3.14 -OBJECT:16:_ZTIPKDF64_ OBJECT:16:_ZTIPKDF64_@@CXXABI_1.3.14 -OBJECT:16:_ZTIPKDd OBJECT:16:_ZTIPKDd@@CXXABI_1.3.4 -OBJECT:16:_ZTIPKDe OBJECT:16:_ZTIPKDe@@CXXABI_1.3.4 -OBJECT:16:_ZTIPKDf OBJECT:16:_ZTIPKDf@@CXXABI_1.3.4 -OBJECT:16:_ZTIPKDi OBJECT:16:_ZTIPKDi@@CXXABI_1.3.3 -OBJECT:16:_ZTIPKDn OBJECT:16:_ZTIPKDn@@CXXABI_1.3.5 -OBJECT:16:_ZTIPKDs OBJECT:16:_ZTIPKDs@@CXXABI_1.3.3 -OBJECT:16:_ZTIPKDu OBJECT:16:_ZTIPKDu@@CXXABI_1.3.12 -OBJECT:16:_ZTIPKa OBJECT:16:_ZTIPKa@@CXXABI_1.3 -OBJECT:16:_ZTIPKb OBJECT:16:_ZTIPKb@@CXXABI_1.3 -OBJECT:16:_ZTIPKc OBJECT:16:_ZTIPKc@@CXXABI_1.3 -OBJECT:16:_ZTIPKd OBJECT:16:_ZTIPKd@@CXXABI_1.3 -OBJECT:16:_ZTIPKe OBJECT:16:_ZTIPKe@@CXXABI_1.3 -OBJECT:16:_ZTIPKf OBJECT:16:_ZTIPKf@@CXXABI_1.3 -OBJECT:16:_ZTIPKh OBJECT:16:_ZTIPKh@@CXXABI_1.3 -OBJECT:16:_ZTIPKi OBJECT:16:_ZTIPKi@@CXXABI_1.3 -OBJECT:16:_ZTIPKj OBJECT:16:_ZTIPKj@@CXXABI_1.3 -OBJECT:16:_ZTIPKl OBJECT:16:_ZTIPKl@@CXXABI_1.3 -OBJECT:16:_ZTIPKm OBJECT:16:_ZTIPKm@@CXXABI_1.3 -OBJECT:16:_ZTIPKs OBJECT:16:_ZTIPKs@@CXXABI_1.3 -OBJECT:16:_ZTIPKt OBJECT:16:_ZTIPKt@@CXXABI_1.3 -OBJECT:16:_ZTIPKv OBJECT:16:_ZTIPKv@@CXXABI_1.3 -OBJECT:16:_ZTIPKw OBJECT:16:_ZTIPKw@@CXXABI_1.3 -OBJECT:16:_ZTIPKx OBJECT:16:_ZTIPKx@@CXXABI_1.3 -OBJECT:16:_ZTIPKy OBJECT:16:_ZTIPKy@@CXXABI_1.3 -OBJECT:16:_ZTIPa OBJECT:16:_ZTIPa@@CXXABI_1.3 -OBJECT:16:_ZTIPb OBJECT:16:_ZTIPb@@CXXABI_1.3 -OBJECT:16:_ZTIPc OBJECT:16:_ZTIPc@@CXXABI_1.3 -OBJECT:16:_ZTIPd OBJECT:16:_ZTIPd@@CXXABI_1.3 -OBJECT:16:_ZTIPe OBJECT:16:_ZTIPe@@CXXABI_1.3 -OBJECT:16:_ZTIPf OBJECT:16:_ZTIPf@@CXXABI_1.3 -OBJECT:16:_ZTIPh OBJECT:16:_ZTIPh@@CXXABI_1.3 -OBJECT:16:_ZTIPi OBJECT:16:_ZTIPi@@CXXABI_1.3 -OBJECT:16:_ZTIPj OBJECT:16:_ZTIPj@@CXXABI_1.3 -OBJECT:16:_ZTIPl OBJECT:16:_ZTIPl@@CXXABI_1.3 -OBJECT:16:_ZTIPm OBJECT:16:_ZTIPm@@CXXABI_1.3 -OBJECT:16:_ZTIPs OBJECT:16:_ZTIPs@@CXXABI_1.3 -OBJECT:16:_ZTIPt OBJECT:16:_ZTIPt@@CXXABI_1.3 -OBJECT:16:_ZTIPv OBJECT:16:_ZTIPv@@CXXABI_1.3 -OBJECT:16:_ZTIPw OBJECT:16:_ZTIPw@@CXXABI_1.3 -OBJECT:16:_ZTIPx OBJECT:16:_ZTIPx@@CXXABI_1.3 -OBJECT:16:_ZTIPy OBJECT:16:_ZTIPy@@CXXABI_1.3 -OBJECT:16:_ZTSSt11logic_error OBJECT:16:_ZTSSt11logic_error@@GLIBCXX_3.4 -OBJECT:16:_ZTSSt11range_error OBJECT:16:_ZTSSt11range_error@@GLIBCXX_3.4 -OBJECT:16:_ZTTNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE OBJECT:16:_ZTTNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:16:_ZTTNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE OBJECT:16:_ZTTNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:16:_ZTTNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE OBJECT:16:_ZTTNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:16:_ZTTNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE OBJECT:16:_ZTTNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:16:_ZTTSt10istrstream OBJECT:16:_ZTTSt10istrstream@@GLIBCXX_3.4 -OBJECT:16:_ZTTSt10ostrstream OBJECT:16:_ZTTSt10ostrstream@@GLIBCXX_3.4 -OBJECT:16:_ZTTSt14basic_ifstreamIcSt11char_traitsIcEE OBJECT:16:_ZTTSt14basic_ifstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:16:_ZTTSt14basic_ifstreamIwSt11char_traitsIwEE OBJECT:16:_ZTTSt14basic_ifstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:16:_ZTTSt14basic_ofstreamIcSt11char_traitsIcEE OBJECT:16:_ZTTSt14basic_ofstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:16:_ZTTSt14basic_ofstreamIwSt11char_traitsIwEE OBJECT:16:_ZTTSt14basic_ofstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:16:_ZTTSt19basic_istringstreamIcSt11char_traitsIcESaIcEE OBJECT:16:_ZTTSt19basic_istringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:16:_ZTTSt19basic_istringstreamIwSt11char_traitsIwESaIwEE OBJECT:16:_ZTTSt19basic_istringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:16:_ZTTSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE OBJECT:16:_ZTTSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:16:_ZTTSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE OBJECT:16:_ZTTSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:16:_ZTVNSt6locale5facetE OBJECT:16:_ZTVNSt6locale5facetE@@GLIBCXX_3.4 -OBJECT:16:_ZTVSt11__timepunctIcE OBJECT:16:_ZTVSt11__timepunctIcE@@GLIBCXX_3.4 -OBJECT:16:_ZTVSt11__timepunctIwE OBJECT:16:_ZTVSt11__timepunctIwE@@GLIBCXX_3.4 -OBJECT:16:_ZTVSt16nested_exception OBJECT:16:_ZTVSt16nested_exception@@CXXABI_1.3.5 -OBJECT:16:_ZTVSt8ios_base OBJECT:16:_ZTVSt8ios_base@@GLIBCXX_3.4 -OBJECT:16:_ZTVSt9basic_iosIcSt11char_traitsIcEE OBJECT:16:_ZTVSt9basic_iosIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:16:_ZTVSt9basic_iosIwSt11char_traitsIwEE OBJECT:16:_ZTVSt9basic_iosIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:17:_ZTSSt12codecvt_base OBJECT:17:_ZTSSt12codecvt_base@@GLIBCXX_3.4 -OBJECT:17:_ZTSSt12domain_error OBJECT:17:_ZTSSt12domain_error@@GLIBCXX_3.4 -OBJECT:17:_ZTSSt12future_error OBJECT:17:_ZTSSt12future_error@@GLIBCXX_3.4.14 -OBJECT:17:_ZTSSt12length_error OBJECT:17:_ZTSSt12length_error@@GLIBCXX_3.4 -OBJECT:17:_ZTSSt12out_of_range OBJECT:17:_ZTSSt12out_of_range@@GLIBCXX_3.4 -OBJECT:17:_ZTSSt12strstreambuf OBJECT:17:_ZTSSt12strstreambuf@@GLIBCXX_3.4 -OBJECT:17:_ZTSSt12system_error OBJECT:17:_ZTSSt12system_error@@GLIBCXX_3.4.11 -OBJECT:18:_ZTSNSt6locale5facetE OBJECT:18:_ZTSNSt6locale5facetE@@GLIBCXX_3.4 -OBJECT:18:_ZTSSt13bad_exception OBJECT:18:_ZTSSt13bad_exception@@GLIBCXX_3.4 -OBJECT:18:_ZTSSt13messages_base OBJECT:18:_ZTSSt13messages_base@@GLIBCXX_3.4 -OBJECT:18:_ZTSSt13runtime_error OBJECT:18:_ZTSSt13runtime_error@@GLIBCXX_3.4 -OBJECT:19:_ZTSNSt6thread6_StateE OBJECT:19:_ZTSNSt6thread6_StateE@@GLIBCXX_3.4.22 -OBJECT:19:_ZTSSt11__timepunctIcE OBJECT:19:_ZTSSt11__timepunctIcE@@GLIBCXX_3.4 -OBJECT:19:_ZTSSt11__timepunctIwE OBJECT:19:_ZTSSt11__timepunctIwE@@GLIBCXX_3.4 -OBJECT:19:_ZTSSt14error_category OBJECT:19:_ZTSSt14error_category@@GLIBCXX_3.4.11 -OBJECT:19:_ZTSSt14overflow_error OBJECT:19:_ZTSSt14overflow_error@@GLIBCXX_3.4 -OBJECT:1:_ZNSs4_Rep11_S_terminalE OBJECT:1:_ZNSs4_Rep11_S_terminalE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt10moneypunctIcLb0EE4intlE OBJECT:1:_ZNSt10moneypunctIcLb0EE4intlE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt10moneypunctIcLb1EE4intlE OBJECT:1:_ZNSt10moneypunctIcLb1EE4intlE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt10moneypunctIwLb0EE4intlE OBJECT:1:_ZNSt10moneypunctIwLb0EE4intlE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt10moneypunctIwLb1EE4intlE OBJECT:1:_ZNSt10moneypunctIwLb1EE4intlE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt12placeholders2_1E OBJECT:1:_ZNSt12placeholders2_1E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders2_2E OBJECT:1:_ZNSt12placeholders2_2E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders2_3E OBJECT:1:_ZNSt12placeholders2_3E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders2_4E OBJECT:1:_ZNSt12placeholders2_4E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders2_5E OBJECT:1:_ZNSt12placeholders2_5E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders2_6E OBJECT:1:_ZNSt12placeholders2_6E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders2_7E OBJECT:1:_ZNSt12placeholders2_7E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders2_8E OBJECT:1:_ZNSt12placeholders2_8E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders2_9E OBJECT:1:_ZNSt12placeholders2_9E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_10E OBJECT:1:_ZNSt12placeholders3_10E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_11E OBJECT:1:_ZNSt12placeholders3_11E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_12E OBJECT:1:_ZNSt12placeholders3_12E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_13E OBJECT:1:_ZNSt12placeholders3_13E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_14E OBJECT:1:_ZNSt12placeholders3_14E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_15E OBJECT:1:_ZNSt12placeholders3_15E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_16E OBJECT:1:_ZNSt12placeholders3_16E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_17E OBJECT:1:_ZNSt12placeholders3_17E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_18E OBJECT:1:_ZNSt12placeholders3_18E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_19E OBJECT:1:_ZNSt12placeholders3_19E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_20E OBJECT:1:_ZNSt12placeholders3_20E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_21E OBJECT:1:_ZNSt12placeholders3_21E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_22E OBJECT:1:_ZNSt12placeholders3_22E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_23E OBJECT:1:_ZNSt12placeholders3_23E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_24E OBJECT:1:_ZNSt12placeholders3_24E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_25E OBJECT:1:_ZNSt12placeholders3_25E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_26E OBJECT:1:_ZNSt12placeholders3_26E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_27E OBJECT:1:_ZNSt12placeholders3_27E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_28E OBJECT:1:_ZNSt12placeholders3_28E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt12placeholders3_29E OBJECT:1:_ZNSt12placeholders3_29E@@GLIBCXX_3.4.15 -OBJECT:1:_ZNSt14numeric_limitsIDiE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIDiE10is_boundedE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDiE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIDiE10is_integerE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDiE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIDiE12has_infinityE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDiE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIDiE13has_quiet_NaNE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDiE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIDiE14is_specializedE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDiE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIDiE15has_denorm_lossE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDiE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIDiE15tinyness_beforeE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDiE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIDiE17has_signaling_NaNE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDiE5trapsE OBJECT:1:_ZNSt14numeric_limitsIDiE5trapsE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDiE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIDiE8is_exactE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDiE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIDiE9is_iec559E@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDiE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIDiE9is_moduloE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDiE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIDiE9is_signedE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDsE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIDsE10is_boundedE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDsE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIDsE10is_integerE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDsE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIDsE12has_infinityE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDsE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIDsE13has_quiet_NaNE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDsE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIDsE14is_specializedE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDsE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIDsE15has_denorm_lossE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDsE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIDsE15tinyness_beforeE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDsE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIDsE17has_signaling_NaNE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDsE5trapsE OBJECT:1:_ZNSt14numeric_limitsIDsE5trapsE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDsE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIDsE8is_exactE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDsE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIDsE9is_iec559E@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDsE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIDsE9is_moduloE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDsE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIDsE9is_signedE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt14numeric_limitsIDuE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIDuE10is_boundedE@@GLIBCXX_3.4.26 -OBJECT:1:_ZNSt14numeric_limitsIDuE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIDuE10is_integerE@@GLIBCXX_3.4.26 -OBJECT:1:_ZNSt14numeric_limitsIDuE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIDuE12has_infinityE@@GLIBCXX_3.4.26 -OBJECT:1:_ZNSt14numeric_limitsIDuE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIDuE13has_quiet_NaNE@@GLIBCXX_3.4.26 -OBJECT:1:_ZNSt14numeric_limitsIDuE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIDuE14is_specializedE@@GLIBCXX_3.4.26 -OBJECT:1:_ZNSt14numeric_limitsIDuE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIDuE15has_denorm_lossE@@GLIBCXX_3.4.26 -OBJECT:1:_ZNSt14numeric_limitsIDuE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIDuE15tinyness_beforeE@@GLIBCXX_3.4.26 -OBJECT:1:_ZNSt14numeric_limitsIDuE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIDuE17has_signaling_NaNE@@GLIBCXX_3.4.26 -OBJECT:1:_ZNSt14numeric_limitsIDuE5trapsE OBJECT:1:_ZNSt14numeric_limitsIDuE5trapsE@@GLIBCXX_3.4.26 -OBJECT:1:_ZNSt14numeric_limitsIDuE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIDuE8is_exactE@@GLIBCXX_3.4.26 -OBJECT:1:_ZNSt14numeric_limitsIDuE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIDuE9is_iec559E@@GLIBCXX_3.4.26 -OBJECT:1:_ZNSt14numeric_limitsIDuE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIDuE9is_moduloE@@GLIBCXX_3.4.26 -OBJECT:1:_ZNSt14numeric_limitsIDuE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIDuE9is_signedE@@GLIBCXX_3.4.26 -OBJECT:1:_ZNSt14numeric_limitsIaE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIaE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIaE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIaE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIaE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIaE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIaE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIaE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIaE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIaE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIaE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIaE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIaE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIaE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIaE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIaE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIaE5trapsE OBJECT:1:_ZNSt14numeric_limitsIaE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIaE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIaE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIaE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIaE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIaE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIaE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIaE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIaE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIbE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIbE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIbE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIbE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIbE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIbE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIbE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIbE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIbE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIbE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIbE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIbE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIbE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIbE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIbE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIbE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIbE5trapsE OBJECT:1:_ZNSt14numeric_limitsIbE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIbE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIbE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIbE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIbE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIbE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIbE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIbE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIbE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIcE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIcE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIcE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIcE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIcE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIcE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIcE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIcE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIcE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIcE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIcE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIcE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIcE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIcE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIcE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIcE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIcE5trapsE OBJECT:1:_ZNSt14numeric_limitsIcE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIcE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIcE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIcE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIcE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIcE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIcE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIcE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIcE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIdE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIdE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIdE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIdE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIdE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIdE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIdE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIdE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIdE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIdE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIdE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIdE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIdE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIdE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIdE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIdE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIdE5trapsE OBJECT:1:_ZNSt14numeric_limitsIdE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIdE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIdE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIdE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIdE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIdE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIdE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIdE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIdE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIeE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIeE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIeE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIeE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIeE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIeE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIeE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIeE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIeE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIeE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIeE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIeE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIeE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIeE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIeE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIeE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIeE5trapsE OBJECT:1:_ZNSt14numeric_limitsIeE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIeE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIeE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIeE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIeE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIeE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIeE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIeE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIeE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIfE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIfE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIfE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIfE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIfE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIfE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIfE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIfE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIfE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIfE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIfE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIfE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIfE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIfE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIfE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIfE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIfE5trapsE OBJECT:1:_ZNSt14numeric_limitsIfE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIfE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIfE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIfE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIfE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIfE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIfE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIfE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIfE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIhE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIhE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIhE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIhE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIhE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIhE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIhE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIhE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIhE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIhE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIhE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIhE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIhE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIhE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIhE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIhE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIhE5trapsE OBJECT:1:_ZNSt14numeric_limitsIhE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIhE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIhE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIhE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIhE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIhE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIhE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIhE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIhE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIiE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIiE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIiE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIiE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIiE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIiE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIiE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIiE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIiE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIiE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIiE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIiE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIiE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIiE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIiE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIiE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIiE5trapsE OBJECT:1:_ZNSt14numeric_limitsIiE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIiE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIiE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIiE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIiE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIiE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIiE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIiE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIiE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIjE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIjE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIjE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIjE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIjE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIjE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIjE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIjE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIjE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIjE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIjE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIjE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIjE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIjE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIjE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIjE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIjE5trapsE OBJECT:1:_ZNSt14numeric_limitsIjE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIjE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIjE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIjE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIjE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIjE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIjE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIjE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIjE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIlE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIlE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIlE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIlE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIlE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIlE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIlE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIlE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIlE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIlE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIlE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIlE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIlE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIlE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIlE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIlE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIlE5trapsE OBJECT:1:_ZNSt14numeric_limitsIlE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIlE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIlE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIlE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIlE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIlE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIlE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIlE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIlE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsImE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsImE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsImE10is_integerE OBJECT:1:_ZNSt14numeric_limitsImE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsImE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsImE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsImE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsImE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsImE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsImE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsImE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsImE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsImE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsImE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsImE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsImE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsImE5trapsE OBJECT:1:_ZNSt14numeric_limitsImE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsImE8is_exactE OBJECT:1:_ZNSt14numeric_limitsImE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsImE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsImE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsImE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsImE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsImE9is_signedE OBJECT:1:_ZNSt14numeric_limitsImE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIsE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIsE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIsE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIsE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIsE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIsE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIsE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIsE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIsE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIsE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIsE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIsE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIsE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIsE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIsE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIsE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIsE5trapsE OBJECT:1:_ZNSt14numeric_limitsIsE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIsE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIsE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIsE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIsE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIsE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIsE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIsE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIsE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsItE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsItE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsItE10is_integerE OBJECT:1:_ZNSt14numeric_limitsItE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsItE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsItE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsItE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsItE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsItE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsItE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsItE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsItE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsItE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsItE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsItE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsItE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsItE5trapsE OBJECT:1:_ZNSt14numeric_limitsItE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsItE8is_exactE OBJECT:1:_ZNSt14numeric_limitsItE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsItE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsItE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsItE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsItE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsItE9is_signedE OBJECT:1:_ZNSt14numeric_limitsItE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIwE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIwE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIwE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIwE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIwE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIwE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIwE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIwE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIwE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIwE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIwE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIwE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIwE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIwE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIwE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIwE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIwE5trapsE OBJECT:1:_ZNSt14numeric_limitsIwE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIwE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIwE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIwE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIwE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIwE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIwE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIwE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIwE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIxE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIxE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIxE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIxE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIxE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIxE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIxE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIxE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIxE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIxE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIxE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIxE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIxE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIxE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIxE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIxE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIxE5trapsE OBJECT:1:_ZNSt14numeric_limitsIxE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIxE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIxE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIxE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIxE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIxE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIxE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIxE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIxE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIyE10is_boundedE OBJECT:1:_ZNSt14numeric_limitsIyE10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIyE10is_integerE OBJECT:1:_ZNSt14numeric_limitsIyE10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIyE12has_infinityE OBJECT:1:_ZNSt14numeric_limitsIyE12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIyE13has_quiet_NaNE OBJECT:1:_ZNSt14numeric_limitsIyE13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIyE14is_specializedE OBJECT:1:_ZNSt14numeric_limitsIyE14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIyE15has_denorm_lossE OBJECT:1:_ZNSt14numeric_limitsIyE15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIyE15tinyness_beforeE OBJECT:1:_ZNSt14numeric_limitsIyE15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIyE17has_signaling_NaNE OBJECT:1:_ZNSt14numeric_limitsIyE17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIyE5trapsE OBJECT:1:_ZNSt14numeric_limitsIyE5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIyE8is_exactE OBJECT:1:_ZNSt14numeric_limitsIyE8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIyE9is_iec559E OBJECT:1:_ZNSt14numeric_limitsIyE9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIyE9is_moduloE OBJECT:1:_ZNSt14numeric_limitsIyE9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt14numeric_limitsIyE9is_signedE OBJECT:1:_ZNSt14numeric_limitsIyE9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt17moneypunct_bynameIcLb0EE4intlE OBJECT:1:_ZNSt17moneypunct_bynameIcLb0EE4intlE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt17moneypunct_bynameIcLb1EE4intlE OBJECT:1:_ZNSt17moneypunct_bynameIcLb1EE4intlE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt17moneypunct_bynameIwLb0EE4intlE OBJECT:1:_ZNSt17moneypunct_bynameIwLb0EE4intlE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt17moneypunct_bynameIwLb1EE4intlE OBJECT:1:_ZNSt17moneypunct_bynameIwLb1EE4intlE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt21__numeric_limits_base10is_boundedE OBJECT:1:_ZNSt21__numeric_limits_base10is_boundedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt21__numeric_limits_base10is_integerE OBJECT:1:_ZNSt21__numeric_limits_base10is_integerE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt21__numeric_limits_base12has_infinityE OBJECT:1:_ZNSt21__numeric_limits_base12has_infinityE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt21__numeric_limits_base13has_quiet_NaNE OBJECT:1:_ZNSt21__numeric_limits_base13has_quiet_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt21__numeric_limits_base14is_specializedE OBJECT:1:_ZNSt21__numeric_limits_base14is_specializedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt21__numeric_limits_base15has_denorm_lossE OBJECT:1:_ZNSt21__numeric_limits_base15has_denorm_lossE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt21__numeric_limits_base15tinyness_beforeE OBJECT:1:_ZNSt21__numeric_limits_base15tinyness_beforeE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt21__numeric_limits_base17has_signaling_NaNE OBJECT:1:_ZNSt21__numeric_limits_base17has_signaling_NaNE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt21__numeric_limits_base5trapsE OBJECT:1:_ZNSt21__numeric_limits_base5trapsE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt21__numeric_limits_base8is_exactE OBJECT:1:_ZNSt21__numeric_limits_base8is_exactE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt21__numeric_limits_base9is_iec559E OBJECT:1:_ZNSt21__numeric_limits_base9is_iec559E@@GLIBCXX_3.4 -OBJECT:1:_ZNSt21__numeric_limits_base9is_moduloE OBJECT:1:_ZNSt21__numeric_limits_base9is_moduloE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt21__numeric_limits_base9is_signedE OBJECT:1:_ZNSt21__numeric_limits_base9is_signedE@@GLIBCXX_3.4 -OBJECT:1:_ZNSt6chrono12system_clock12is_monotonicE OBJECT:1:_ZNSt6chrono12system_clock12is_monotonicE@@GLIBCXX_3.4.11 -OBJECT:1:_ZNSt6chrono3_V212steady_clock9is_steadyE OBJECT:1:_ZNSt6chrono3_V212steady_clock9is_steadyE@@GLIBCXX_3.4.19 -OBJECT:1:_ZNSt6chrono3_V212system_clock9is_steadyE OBJECT:1:_ZNSt6chrono3_V212system_clock9is_steadyE@@GLIBCXX_3.4.19 -OBJECT:1:_ZNSt7__cxx1110moneypunctIcLb0EE4intlE OBJECT:1:_ZNSt7__cxx1110moneypunctIcLb0EE4intlE@@GLIBCXX_3.4.21 -OBJECT:1:_ZNSt7__cxx1110moneypunctIcLb1EE4intlE OBJECT:1:_ZNSt7__cxx1110moneypunctIcLb1EE4intlE@@GLIBCXX_3.4.21 -OBJECT:1:_ZNSt7__cxx1110moneypunctIwLb0EE4intlE OBJECT:1:_ZNSt7__cxx1110moneypunctIwLb0EE4intlE@@GLIBCXX_3.4.21 -OBJECT:1:_ZNSt7__cxx1110moneypunctIwLb1EE4intlE OBJECT:1:_ZNSt7__cxx1110moneypunctIwLb1EE4intlE@@GLIBCXX_3.4.21 -OBJECT:1:_ZNSt7__cxx1117moneypunct_bynameIcLb0EE4intlE OBJECT:1:_ZNSt7__cxx1117moneypunct_bynameIcLb0EE4intlE@@GLIBCXX_3.4.21 -OBJECT:1:_ZNSt7__cxx1117moneypunct_bynameIcLb1EE4intlE OBJECT:1:_ZNSt7__cxx1117moneypunct_bynameIcLb1EE4intlE@@GLIBCXX_3.4.21 -OBJECT:1:_ZNSt7__cxx1117moneypunct_bynameIwLb0EE4intlE OBJECT:1:_ZNSt7__cxx1117moneypunct_bynameIwLb0EE4intlE@@GLIBCXX_3.4.21 -OBJECT:1:_ZNSt7__cxx1117moneypunct_bynameIwLb1EE4intlE OBJECT:1:_ZNSt7__cxx1117moneypunct_bynameIwLb1EE4intlE@@GLIBCXX_3.4.21 OBJECT:1:_ZSt10adopt_lock@@GLIBCXX_3.4.11 OBJECT:1:_ZSt10defer_lock@@GLIBCXX_3.4.11 OBJECT:1:_ZSt11try_to_lock@@GLIBCXX_3.4.11 -OBJECT:1:_ZSt7nothrow OBJECT:1:_ZSt7nothrow@@GLIBCXX_3.4 -OBJECT:20:_ZTSSt12ctype_bynameIcE OBJECT:20:_ZTSSt12ctype_bynameIcE@@GLIBCXX_3.4 -OBJECT:20:_ZTSSt12ctype_bynameIwE OBJECT:20:_ZTSSt12ctype_bynameIwE@@GLIBCXX_3.4 -OBJECT:20:_ZTSSt15underflow_error OBJECT:20:_ZTSSt15underflow_error@@GLIBCXX_3.4 -OBJECT:20:_ZTVNSt10filesystem16filesystem_errorE OBJECT:20:_ZTVNSt10filesystem16filesystem_errorE@@GLIBCXX_3.4.26 -OBJECT:20:_ZTVNSt10filesystem7__cxx1116filesystem_errorE OBJECT:20:_ZTVNSt10filesystem7__cxx1116filesystem_errorE@@GLIBCXX_3.4.26 -OBJECT:20:_ZTVNSt13__future_base11_State_baseE OBJECT:20:_ZTVNSt13__future_base11_State_baseE@@GLIBCXX_3.4.15 -OBJECT:20:_ZTVNSt13__future_base12_Result_baseE OBJECT:20:_ZTVNSt13__future_base12_Result_baseE@@GLIBCXX_3.4.15 -OBJECT:20:_ZTVNSt13__future_base19_Async_state_commonE OBJECT:20:_ZTVNSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17 -OBJECT:20:_ZTVNSt6thread6_StateE OBJECT:20:_ZTVNSt6thread6_StateE@@GLIBCXX_3.4.22 -OBJECT:20:_ZTVNSt8ios_base7failureB5cxx11E OBJECT:20:_ZTVNSt8ios_base7failureB5cxx11E@@GLIBCXX_3.4.21 -OBJECT:20:_ZTVNSt8ios_base7failureE OBJECT:20:_ZTVNSt8ios_base7failureE@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt10bad_typeid OBJECT:20:_ZTVSt10bad_typeid@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt10lock_error OBJECT:20:_ZTVSt10lock_error@@GLIBCXX_3.4.11 -OBJECT:20:_ZTVSt11logic_error OBJECT:20:_ZTVSt11logic_error@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt11range_error OBJECT:20:_ZTVSt11range_error@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt11regex_error OBJECT:20:_ZTVSt11regex_error@@GLIBCXX_3.4.15 -OBJECT:20:_ZTVSt12bad_weak_ptr OBJECT:20:_ZTVSt12bad_weak_ptr@@GLIBCXX_3.4.15 -OBJECT:20:_ZTVSt12domain_error OBJECT:20:_ZTVSt12domain_error@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt12future_error OBJECT:20:_ZTVSt12future_error@@GLIBCXX_3.4.14 -OBJECT:20:_ZTVSt12length_error OBJECT:20:_ZTVSt12length_error@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt12out_of_range OBJECT:20:_ZTVSt12out_of_range@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt12system_error OBJECT:20:_ZTVSt12system_error@@GLIBCXX_3.4.11 -OBJECT:20:_ZTVSt13bad_exception OBJECT:20:_ZTVSt13bad_exception@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt13runtime_error OBJECT:20:_ZTVSt13runtime_error@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt14overflow_error OBJECT:20:_ZTVSt14overflow_error@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:20:_ZTVSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:20:_ZTVSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt15underflow_error OBJECT:20:_ZTVSt15underflow_error@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt16bad_array_length OBJECT:20:_ZTVSt16bad_array_length@@CXXABI_1.3.8 -OBJECT:20:_ZTVSt16invalid_argument OBJECT:20:_ZTVSt16invalid_argument@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt17bad_function_call OBJECT:20:_ZTVSt17bad_function_call@@GLIBCXX_3.4.15 -OBJECT:20:_ZTVSt20bad_array_new_length OBJECT:20:_ZTVSt20bad_array_new_length@@CXXABI_1.3.8 -OBJECT:20:_ZTVSt8bad_cast OBJECT:20:_ZTVSt8bad_cast@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:20:_ZTVSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:20:_ZTVSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt9bad_alloc OBJECT:20:_ZTVSt9bad_alloc@@GLIBCXX_3.4 -OBJECT:20:_ZTVSt9exception OBJECT:20:_ZTVSt9exception@@GLIBCXX_3.4 -OBJECT:21:_ZTSSt16bad_array_length OBJECT:21:_ZTSSt16bad_array_length@@CXXABI_1.3.8 -OBJECT:21:_ZTSSt16invalid_argument OBJECT:21:_ZTSSt16invalid_argument@@GLIBCXX_3.4 -OBJECT:22:_ZTSNSt8ios_base7failureE OBJECT:22:_ZTSNSt8ios_base7failureE@@GLIBCXX_3.4 -OBJECT:22:_ZTSSt10moneypunctIcLb0EE OBJECT:22:_ZTSSt10moneypunctIcLb0EE@@GLIBCXX_3.4 -OBJECT:22:_ZTSSt10moneypunctIcLb1EE OBJECT:22:_ZTSSt10moneypunctIcLb1EE@@GLIBCXX_3.4 -OBJECT:22:_ZTSSt10moneypunctIwLb0EE OBJECT:22:_ZTSSt10moneypunctIwLb0EE@@GLIBCXX_3.4 -OBJECT:22:_ZTSSt10moneypunctIwLb1EE OBJECT:22:_ZTSSt10moneypunctIwLb1EE@@GLIBCXX_3.4 -OBJECT:22:_ZTSSt14collate_bynameIcE OBJECT:22:_ZTSSt14collate_bynameIcE@@GLIBCXX_3.4 -OBJECT:22:_ZTSSt14collate_bynameIwE OBJECT:22:_ZTSSt14collate_bynameIwE@@GLIBCXX_3.4 -OBJECT:23:_ZTSSt15messages_bynameIcE OBJECT:23:_ZTSSt15messages_bynameIcE@@GLIBCXX_3.4 -OBJECT:23:_ZTSSt15messages_bynameIwE OBJECT:23:_ZTSSt15messages_bynameIwE@@GLIBCXX_3.4 -OBJECT:23:_ZTSSt15numpunct_bynameIcE OBJECT:23:_ZTSSt15numpunct_bynameIcE@@GLIBCXX_3.4 -OBJECT:23:_ZTSSt15numpunct_bynameIwE OBJECT:23:_ZTSSt15numpunct_bynameIwE@@GLIBCXX_3.4 -OBJECT:24:_ZTISi OBJECT:24:_ZTISi@@GLIBCXX_3.4 -OBJECT:24:_ZTISo OBJECT:24:_ZTISo@@GLIBCXX_3.4 -OBJECT:24:_ZTISt13basic_istreamIwSt11char_traitsIwEE OBJECT:24:_ZTISt13basic_istreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:24:_ZTISt13basic_ostreamIwSt11char_traitsIwEE OBJECT:24:_ZTISt13basic_ostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:24:_ZTSNSt7__cxx117collateIcEE OBJECT:24:_ZTSNSt7__cxx117collateIcEE@@GLIBCXX_3.4.21 -OBJECT:24:_ZTSNSt7__cxx117collateIwEE OBJECT:24:_ZTSNSt7__cxx117collateIwEE@@GLIBCXX_3.4.21 -OBJECT:24:_ZTVNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE OBJECT:24:_ZTVNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 -OBJECT:24:_ZTVNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE OBJECT:24:_ZTVNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 -OBJECT:24:_ZTVNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE OBJECT:24:_ZTVNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 -OBJECT:24:_ZTVNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE OBJECT:24:_ZTVNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 -OBJECT:24:_ZTVSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:24:_ZTVSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:24:_ZTVSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:24:_ZTVSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:24:_ZTVSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:24:_ZTVSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:24:_ZTVSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:24:_ZTVSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:25:_ZTSNSt7__cxx118messagesIcEE OBJECT:25:_ZTSNSt7__cxx118messagesIcEE@@GLIBCXX_3.4.21 -OBJECT:25:_ZTSNSt7__cxx118messagesIwEE OBJECT:25:_ZTSNSt7__cxx118messagesIwEE@@GLIBCXX_3.4.21 -OBJECT:25:_ZTSNSt7__cxx118numpunctIcEE OBJECT:25:_ZTSNSt7__cxx118numpunctIcEE@@GLIBCXX_3.4.21 -OBJECT:25:_ZTSNSt7__cxx118numpunctIwEE OBJECT:25:_ZTSNSt7__cxx118numpunctIwEE@@GLIBCXX_3.4.21 -OBJECT:25:_ZTSSt20bad_array_new_length OBJECT:25:_ZTSSt20bad_array_new_length@@CXXABI_1.3.8 -OBJECT:26:_ZTSNSt3pmr15memory_resourceE OBJECT:26:_ZTSNSt3pmr15memory_resourceE@@GLIBCXX_3.4.28 -OBJECT:27:_ZTSSt19__codecvt_utf8_baseIwE OBJECT:27:_ZTSSt19__codecvt_utf8_baseIwE@@GLIBCXX_3.4.21 -OBJECT:28:_ZTSSt19__codecvt_utf8_baseIDiE OBJECT:28:_ZTSSt19__codecvt_utf8_baseIDiE@@GLIBCXX_3.4.21 -OBJECT:28:_ZTSSt19__codecvt_utf8_baseIDsE OBJECT:28:_ZTSSt19__codecvt_utf8_baseIDsE@@GLIBCXX_3.4.21 -OBJECT:28:_ZTSSt20__codecvt_utf16_baseIwE OBJECT:28:_ZTSSt20__codecvt_utf16_baseIwE@@GLIBCXX_3.4.21 -OBJECT:28:_ZTSSt7codecvtIcc11__mbstate_tE OBJECT:28:_ZTSSt7codecvtIcc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:28:_ZTSSt7codecvtIwc11__mbstate_tE OBJECT:28:_ZTSSt7codecvtIwc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:28:_ZTTSd OBJECT:28:_ZTTSd@@GLIBCXX_3.4 -OBJECT:28:_ZTTSt14basic_iostreamIwSt11char_traitsIwEE OBJECT:28:_ZTTSt14basic_iostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:28:_ZTVNSt3pmr15memory_resourceE OBJECT:28:_ZTVNSt3pmr15memory_resourceE@@GLIBCXX_3.4.28 -OBJECT:28:_ZTVNSt3pmr25monotonic_buffer_resourceE OBJECT:28:_ZTVNSt3pmr25monotonic_buffer_resourceE@@GLIBCXX_3.4.28 -OBJECT:28:_ZTVNSt7__cxx1114collate_bynameIcEE OBJECT:28:_ZTVNSt7__cxx1114collate_bynameIcEE@@GLIBCXX_3.4.21 -OBJECT:28:_ZTVNSt7__cxx1114collate_bynameIwEE OBJECT:28:_ZTVNSt7__cxx1114collate_bynameIwEE@@GLIBCXX_3.4.21 -OBJECT:28:_ZTVNSt7__cxx1115messages_bynameIcEE OBJECT:28:_ZTVNSt7__cxx1115messages_bynameIcEE@@GLIBCXX_3.4.21 -OBJECT:28:_ZTVNSt7__cxx1115messages_bynameIwEE OBJECT:28:_ZTVNSt7__cxx1115messages_bynameIwEE@@GLIBCXX_3.4.21 -OBJECT:28:_ZTVNSt7__cxx117collateIcEE OBJECT:28:_ZTVNSt7__cxx117collateIcEE@@GLIBCXX_3.4.21 -OBJECT:28:_ZTVNSt7__cxx117collateIwEE OBJECT:28:_ZTVNSt7__cxx117collateIwEE@@GLIBCXX_3.4.21 -OBJECT:28:_ZTVNSt7__cxx118messagesIcEE OBJECT:28:_ZTVNSt7__cxx118messagesIcEE@@GLIBCXX_3.4.21 -OBJECT:28:_ZTVNSt7__cxx118messagesIwEE OBJECT:28:_ZTVNSt7__cxx118messagesIwEE@@GLIBCXX_3.4.21 -OBJECT:28:_ZTVSt14collate_bynameIcE OBJECT:28:_ZTVSt14collate_bynameIcE@@GLIBCXX_3.4 -OBJECT:28:_ZTVSt14collate_bynameIwE OBJECT:28:_ZTVSt14collate_bynameIwE@@GLIBCXX_3.4 -OBJECT:28:_ZTVSt15messages_bynameIcE OBJECT:28:_ZTVSt15messages_bynameIcE@@GLIBCXX_3.4 -OBJECT:28:_ZTVSt15messages_bynameIwE OBJECT:28:_ZTVSt15messages_bynameIwE@@GLIBCXX_3.4 -OBJECT:28:_ZTVSt7collateIcE OBJECT:28:_ZTVSt7collateIcE@@GLIBCXX_3.4 -OBJECT:28:_ZTVSt7collateIwE OBJECT:28:_ZTVSt7collateIwE@@GLIBCXX_3.4 -OBJECT:28:_ZTVSt8messagesIcE OBJECT:28:_ZTVSt8messagesIcE@@GLIBCXX_3.4 -OBJECT:28:_ZTVSt8messagesIwE OBJECT:28:_ZTVSt8messagesIwE@@GLIBCXX_3.4 -OBJECT:29:_ZTSNSt8ios_base7failureB5cxx11E OBJECT:29:_ZTSNSt8ios_base7failureB5cxx11E@@GLIBCXX_3.4.21 -OBJECT:29:_ZTSSt17moneypunct_bynameIcLb0EE OBJECT:29:_ZTSSt17moneypunct_bynameIcLb0EE@@GLIBCXX_3.4 -OBJECT:29:_ZTSSt17moneypunct_bynameIcLb1EE OBJECT:29:_ZTSSt17moneypunct_bynameIcLb1EE@@GLIBCXX_3.4 -OBJECT:29:_ZTSSt17moneypunct_bynameIwLb0EE OBJECT:29:_ZTSSt17moneypunct_bynameIwLb0EE@@GLIBCXX_3.4 -OBJECT:29:_ZTSSt17moneypunct_bynameIwLb1EE OBJECT:29:_ZTSSt17moneypunct_bynameIwLb1EE@@GLIBCXX_3.4 -OBJECT:29:_ZTSSt20__codecvt_utf16_baseIDiE OBJECT:29:_ZTSSt20__codecvt_utf16_baseIDiE@@GLIBCXX_3.4.21 -OBJECT:29:_ZTSSt20__codecvt_utf16_baseIDsE OBJECT:29:_ZTSSt20__codecvt_utf16_baseIDsE@@GLIBCXX_3.4.21 -OBJECT:29:_ZTSSt21__ctype_abstract_baseIcE OBJECT:29:_ZTSSt21__ctype_abstract_baseIcE@@GLIBCXX_3.4 -OBJECT:29:_ZTSSt21__ctype_abstract_baseIwE OBJECT:29:_ZTSSt21__ctype_abstract_baseIwE@@GLIBCXX_3.4 -OBJECT:29:_ZTSSt7codecvtIDic11__mbstate_tE OBJECT:29:_ZTSSt7codecvtIDic11__mbstate_tE@@GLIBCXX_3.4.21 -OBJECT:29:_ZTSSt7codecvtIDsc11__mbstate_tE OBJECT:29:_ZTSSt7codecvtIDsc11__mbstate_tE@@GLIBCXX_3.4.21 -OBJECT:2:_ZNSt10ctype_base5alnumE OBJECT:2:_ZNSt10ctype_base5alnumE@@GLIBCXX_3.4 -OBJECT:2:_ZNSt10ctype_base5alphaE OBJECT:2:_ZNSt10ctype_base5alphaE@@GLIBCXX_3.4 -OBJECT:2:_ZNSt10ctype_base5blankE OBJECT:2:_ZNSt10ctype_base5blankE@@GLIBCXX_3.4.21 -OBJECT:2:_ZNSt10ctype_base5cntrlE OBJECT:2:_ZNSt10ctype_base5cntrlE@@GLIBCXX_3.4 -OBJECT:2:_ZNSt10ctype_base5digitE OBJECT:2:_ZNSt10ctype_base5digitE@@GLIBCXX_3.4 -OBJECT:2:_ZNSt10ctype_base5graphE OBJECT:2:_ZNSt10ctype_base5graphE@@GLIBCXX_3.4 -OBJECT:2:_ZNSt10ctype_base5lowerE OBJECT:2:_ZNSt10ctype_base5lowerE@@GLIBCXX_3.4 -OBJECT:2:_ZNSt10ctype_base5printE OBJECT:2:_ZNSt10ctype_base5printE@@GLIBCXX_3.4 -OBJECT:2:_ZNSt10ctype_base5punctE OBJECT:2:_ZNSt10ctype_base5punctE@@GLIBCXX_3.4 -OBJECT:2:_ZNSt10ctype_base5spaceE OBJECT:2:_ZNSt10ctype_base5spaceE@@GLIBCXX_3.4 -OBJECT:2:_ZNSt10ctype_base5upperE OBJECT:2:_ZNSt10ctype_base5upperE@@GLIBCXX_3.4 -OBJECT:2:_ZNSt10ctype_base6xdigitE OBJECT:2:_ZNSt10ctype_base6xdigitE@@GLIBCXX_3.4 -OBJECT:2:_ZTSa OBJECT:2:_ZTSa@@CXXABI_1.3 -OBJECT:2:_ZTSb OBJECT:2:_ZTSb@@CXXABI_1.3 -OBJECT:2:_ZTSc OBJECT:2:_ZTSc@@CXXABI_1.3 -OBJECT:2:_ZTSd OBJECT:2:_ZTSd@@CXXABI_1.3 -OBJECT:2:_ZTSe OBJECT:2:_ZTSe@@CXXABI_1.3 -OBJECT:2:_ZTSf OBJECT:2:_ZTSf@@CXXABI_1.3 -OBJECT:2:_ZTSh OBJECT:2:_ZTSh@@CXXABI_1.3 -OBJECT:2:_ZTSi OBJECT:2:_ZTSi@@CXXABI_1.3 -OBJECT:2:_ZTSj OBJECT:2:_ZTSj@@CXXABI_1.3 -OBJECT:2:_ZTSl OBJECT:2:_ZTSl@@CXXABI_1.3 -OBJECT:2:_ZTSm OBJECT:2:_ZTSm@@CXXABI_1.3 -OBJECT:2:_ZTSs OBJECT:2:_ZTSs@@CXXABI_1.3 -OBJECT:2:_ZTSt OBJECT:2:_ZTSt@@CXXABI_1.3 -OBJECT:2:_ZTSv OBJECT:2:_ZTSv@@CXXABI_1.3 -OBJECT:2:_ZTSw OBJECT:2:_ZTSw@@CXXABI_1.3 -OBJECT:2:_ZTSx OBJECT:2:_ZTSx@@CXXABI_1.3 -OBJECT:2:_ZTSy OBJECT:2:_ZTSy@@CXXABI_1.3 -OBJECT:30:_ZTSSt7codecvtIDiDu11__mbstate_tE OBJECT:30:_ZTSSt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26 -OBJECT:30:_ZTSSt7codecvtIDsDu11__mbstate_tE OBJECT:30:_ZTSSt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26 -OBJECT:32:_ZTINSt7__cxx1110moneypunctIcLb0EEE OBJECT:32:_ZTINSt7__cxx1110moneypunctIcLb0EEE@@GLIBCXX_3.4.21 -OBJECT:32:_ZTINSt7__cxx1110moneypunctIcLb1EEE OBJECT:32:_ZTINSt7__cxx1110moneypunctIcLb1EEE@@GLIBCXX_3.4.21 -OBJECT:32:_ZTINSt7__cxx1110moneypunctIwLb0EEE OBJECT:32:_ZTINSt7__cxx1110moneypunctIwLb0EEE@@GLIBCXX_3.4.21 -OBJECT:32:_ZTINSt7__cxx1110moneypunctIwLb1EEE OBJECT:32:_ZTINSt7__cxx1110moneypunctIwLb1EEE@@GLIBCXX_3.4.21 -OBJECT:32:_ZTINSt7__cxx118messagesIcEE OBJECT:32:_ZTINSt7__cxx118messagesIcEE@@GLIBCXX_3.4.21 -OBJECT:32:_ZTINSt7__cxx118messagesIwEE OBJECT:32:_ZTINSt7__cxx118messagesIwEE@@GLIBCXX_3.4.21 -OBJECT:32:_ZTINSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE OBJECT:32:_ZTINSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 -OBJECT:32:_ZTINSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE OBJECT:32:_ZTINSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 -OBJECT:32:_ZTISd OBJECT:32:_ZTISd@@GLIBCXX_3.4 -OBJECT:32:_ZTISt10moneypunctIcLb0EE OBJECT:32:_ZTISt10moneypunctIcLb0EE@@GLIBCXX_3.4 -OBJECT:32:_ZTISt10moneypunctIcLb1EE OBJECT:32:_ZTISt10moneypunctIcLb1EE@@GLIBCXX_3.4 -OBJECT:32:_ZTISt10moneypunctIwLb0EE OBJECT:32:_ZTISt10moneypunctIwLb0EE@@GLIBCXX_3.4 -OBJECT:32:_ZTISt10moneypunctIwLb1EE OBJECT:32:_ZTISt10moneypunctIwLb1EE@@GLIBCXX_3.4 -OBJECT:32:_ZTISt14basic_iostreamIwSt11char_traitsIwEE OBJECT:32:_ZTISt14basic_iostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:32:_ZTISt21__ctype_abstract_baseIcE OBJECT:32:_ZTISt21__ctype_abstract_baseIcE@@GLIBCXX_3.4 -OBJECT:32:_ZTISt21__ctype_abstract_baseIwE OBJECT:32:_ZTISt21__ctype_abstract_baseIwE@@GLIBCXX_3.4 -OBJECT:32:_ZTISt23__codecvt_abstract_baseIcc11__mbstate_tE OBJECT:32:_ZTISt23__codecvt_abstract_baseIcc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:32:_ZTISt23__codecvt_abstract_baseIwc11__mbstate_tE OBJECT:32:_ZTISt23__codecvt_abstract_baseIwc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:32:_ZTISt5ctypeIcE OBJECT:32:_ZTISt5ctypeIcE@@GLIBCXX_3.4 -OBJECT:32:_ZTISt8messagesIcE OBJECT:32:_ZTISt8messagesIcE@@GLIBCXX_3.4 -OBJECT:32:_ZTISt8messagesIwE OBJECT:32:_ZTISt8messagesIwE@@GLIBCXX_3.4 -OBJECT:32:_ZTISt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:32:_ZTISt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:32:_ZTISt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:32:_ZTISt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:32:_ZTSNSt7__cxx1110moneypunctIcLb0EEE OBJECT:32:_ZTSNSt7__cxx1110moneypunctIcLb0EEE@@GLIBCXX_3.4.21 -OBJECT:32:_ZTSNSt7__cxx1110moneypunctIcLb1EEE OBJECT:32:_ZTSNSt7__cxx1110moneypunctIcLb1EEE@@GLIBCXX_3.4.21 -OBJECT:32:_ZTSNSt7__cxx1110moneypunctIwLb0EEE OBJECT:32:_ZTSNSt7__cxx1110moneypunctIwLb0EEE@@GLIBCXX_3.4.21 -OBJECT:32:_ZTSNSt7__cxx1110moneypunctIwLb1EEE OBJECT:32:_ZTSNSt7__cxx1110moneypunctIwLb1EEE@@GLIBCXX_3.4.21 -OBJECT:32:_ZTSNSt7__cxx1114collate_bynameIcEE OBJECT:32:_ZTSNSt7__cxx1114collate_bynameIcEE@@GLIBCXX_3.4.21 -OBJECT:32:_ZTSNSt7__cxx1114collate_bynameIwEE OBJECT:32:_ZTSNSt7__cxx1114collate_bynameIwEE@@GLIBCXX_3.4.21 -OBJECT:32:_ZTVN10__cxxabiv116__enum_type_infoE OBJECT:32:_ZTVN10__cxxabiv116__enum_type_infoE@@CXXABI_1.3 -OBJECT:32:_ZTVN10__cxxabiv117__array_type_infoE OBJECT:32:_ZTVN10__cxxabiv117__array_type_infoE@@CXXABI_1.3 -OBJECT:32:_ZTVN10__cxxabiv120__function_type_infoE OBJECT:32:_ZTVN10__cxxabiv120__function_type_infoE@@CXXABI_1.3 -OBJECT:32:_ZTVN10__cxxabiv123__fundamental_type_infoE OBJECT:32:_ZTVN10__cxxabiv123__fundamental_type_infoE@@CXXABI_1.3 -OBJECT:32:_ZTVSt9type_info OBJECT:32:_ZTVSt9type_info@@GLIBCXX_3.4 -OBJECT:33:_ZTSN10__cxxabiv116__enum_type_infoE OBJECT:33:_ZTSN10__cxxabiv116__enum_type_infoE@@CXXABI_1.3 -OBJECT:33:_ZTSNSt7__cxx1115messages_bynameIcEE OBJECT:33:_ZTSNSt7__cxx1115messages_bynameIcEE@@GLIBCXX_3.4.21 -OBJECT:33:_ZTSNSt7__cxx1115messages_bynameIwEE OBJECT:33:_ZTSNSt7__cxx1115messages_bynameIwEE@@GLIBCXX_3.4.21 -OBJECT:33:_ZTSNSt7__cxx1115numpunct_bynameIcEE OBJECT:33:_ZTSNSt7__cxx1115numpunct_bynameIcEE@@GLIBCXX_3.4.21 -OBJECT:33:_ZTSNSt7__cxx1115numpunct_bynameIwEE OBJECT:33:_ZTSNSt7__cxx1115numpunct_bynameIwEE@@GLIBCXX_3.4.21 -OBJECT:33:_ZTSSt25__codecvt_utf8_utf16_baseIwE OBJECT:33:_ZTSSt25__codecvt_utf8_utf16_baseIwE@@GLIBCXX_3.4.21 -OBJECT:34:_ZTSN10__cxxabiv117__array_type_infoE OBJECT:34:_ZTSN10__cxxabiv117__array_type_infoE@@CXXABI_1.3 -OBJECT:34:_ZTSN10__cxxabiv117__class_type_infoE OBJECT:34:_ZTSN10__cxxabiv117__class_type_infoE@@CXXABI_1.3 -OBJECT:34:_ZTSN10__cxxabiv117__pbase_type_infoE OBJECT:34:_ZTSN10__cxxabiv117__pbase_type_infoE@@CXXABI_1.3 -OBJECT:34:_ZTSSt25__codecvt_utf8_utf16_baseIDiE OBJECT:34:_ZTSSt25__codecvt_utf8_utf16_baseIDiE@@GLIBCXX_3.4.21 -OBJECT:34:_ZTSSt25__codecvt_utf8_utf16_baseIDsE OBJECT:34:_ZTSSt25__codecvt_utf8_utf16_baseIDsE@@GLIBCXX_3.4.21 -OBJECT:34:_ZTSSt9basic_iosIcSt11char_traitsIcEE OBJECT:34:_ZTSSt9basic_iosIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:34:_ZTSSt9basic_iosIwSt11char_traitsIwEE OBJECT:34:_ZTSSt9basic_iosIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:36:_ZTSN10__cxxabiv119__pointer_type_infoE OBJECT:36:_ZTSN10__cxxabiv119__pointer_type_infoE@@CXXABI_1.3 -OBJECT:36:_ZTSNSt3pmr25monotonic_buffer_resourceE OBJECT:36:_ZTSNSt3pmr25monotonic_buffer_resourceE@@GLIBCXX_3.4.28 -OBJECT:36:_ZTSSt14codecvt_bynameIcc11__mbstate_tE OBJECT:36:_ZTSSt14codecvt_bynameIcc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:36:_ZTSSt14codecvt_bynameIwc11__mbstate_tE OBJECT:36:_ZTSSt14codecvt_bynameIwc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:36:_ZTVN10__cxxabiv117__pbase_type_infoE OBJECT:36:_ZTVN10__cxxabiv117__pbase_type_infoE@@CXXABI_1.3 -OBJECT:36:_ZTVN10__cxxabiv119__pointer_type_infoE OBJECT:36:_ZTVN10__cxxabiv119__pointer_type_infoE@@CXXABI_1.3 -OBJECT:36:_ZTVN10__cxxabiv129__pointer_to_member_type_infoE OBJECT:36:_ZTVN10__cxxabiv129__pointer_to_member_type_infoE@@CXXABI_1.3 -OBJECT:36:_ZTVNSt7__cxx1115numpunct_bynameIcEE OBJECT:36:_ZTVNSt7__cxx1115numpunct_bynameIcEE@@GLIBCXX_3.4.21 -OBJECT:36:_ZTVNSt7__cxx1115numpunct_bynameIwEE OBJECT:36:_ZTVNSt7__cxx1115numpunct_bynameIwEE@@GLIBCXX_3.4.21 -OBJECT:36:_ZTVNSt7__cxx118numpunctIcEE OBJECT:36:_ZTVNSt7__cxx118numpunctIcEE@@GLIBCXX_3.4.21 -OBJECT:36:_ZTVNSt7__cxx118numpunctIwEE OBJECT:36:_ZTVNSt7__cxx118numpunctIwEE@@GLIBCXX_3.4.21 -OBJECT:36:_ZTVSt14error_category OBJECT:36:_ZTVSt14error_category@@GLIBCXX_3.4.11 -OBJECT:36:_ZTVSt15numpunct_bynameIcE OBJECT:36:_ZTVSt15numpunct_bynameIcE@@GLIBCXX_3.4 -OBJECT:36:_ZTVSt15numpunct_bynameIwE OBJECT:36:_ZTVSt15numpunct_bynameIwE@@GLIBCXX_3.4 -OBJECT:36:_ZTVSt8numpunctIcE OBJECT:36:_ZTVSt8numpunctIcE@@GLIBCXX_3.4 -OBJECT:36:_ZTVSt8numpunctIwE OBJECT:36:_ZTVSt8numpunctIwE@@GLIBCXX_3.4 -OBJECT:37:_ZTSN10__cxxabiv120__function_type_infoE OBJECT:37:_ZTSN10__cxxabiv120__function_type_infoE@@CXXABI_1.3 -OBJECT:37:_ZTSN10__cxxabiv120__si_class_type_infoE OBJECT:37:_ZTSN10__cxxabiv120__si_class_type_infoE@@CXXABI_1.3 -OBJECT:38:_ZTSN10__cxxabiv121__vmi_class_type_infoE OBJECT:38:_ZTSN10__cxxabiv121__vmi_class_type_infoE@@CXXABI_1.3 -OBJECT:39:_ZTSNSt7__cxx1117moneypunct_bynameIcLb0EEE OBJECT:39:_ZTSNSt7__cxx1117moneypunct_bynameIcLb0EEE@@GLIBCXX_3.4.21 -OBJECT:39:_ZTSNSt7__cxx1117moneypunct_bynameIcLb1EEE OBJECT:39:_ZTSNSt7__cxx1117moneypunct_bynameIcLb1EEE@@GLIBCXX_3.4.21 -OBJECT:39:_ZTSNSt7__cxx1117moneypunct_bynameIwLb0EEE OBJECT:39:_ZTSNSt7__cxx1117moneypunct_bynameIwLb0EEE@@GLIBCXX_3.4.21 -OBJECT:39:_ZTSNSt7__cxx1117moneypunct_bynameIwLb1EEE OBJECT:39:_ZTSNSt7__cxx1117moneypunct_bynameIwLb1EEE@@GLIBCXX_3.4.21 -OBJECT:39:_ZTSSt13basic_filebufIcSt11char_traitsIcEE OBJECT:39:_ZTSSt13basic_filebufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:39:_ZTSSt13basic_filebufIwSt11char_traitsIwEE OBJECT:39:_ZTSSt13basic_filebufIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:39:_ZTSSt13basic_fstreamIcSt11char_traitsIcEE OBJECT:39:_ZTSSt13basic_fstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:39:_ZTSSt13basic_fstreamIwSt11char_traitsIwEE OBJECT:39:_ZTSSt13basic_fstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:39:_ZTSSt13basic_istreamIwSt11char_traitsIwEE OBJECT:39:_ZTSSt13basic_istreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:39:_ZTSSt13basic_ostreamIwSt11char_traitsIwEE OBJECT:39:_ZTSSt13basic_ostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:3:_ZTSPa OBJECT:3:_ZTSPa@@CXXABI_1.3 -OBJECT:3:_ZTSPb OBJECT:3:_ZTSPb@@CXXABI_1.3 -OBJECT:3:_ZTSPc OBJECT:3:_ZTSPc@@CXXABI_1.3 -OBJECT:3:_ZTSPd OBJECT:3:_ZTSPd@@CXXABI_1.3 -OBJECT:3:_ZTSPe OBJECT:3:_ZTSPe@@CXXABI_1.3 -OBJECT:3:_ZTSPf OBJECT:3:_ZTSPf@@CXXABI_1.3 -OBJECT:3:_ZTSPh OBJECT:3:_ZTSPh@@CXXABI_1.3 -OBJECT:3:_ZTSPi OBJECT:3:_ZTSPi@@CXXABI_1.3 -OBJECT:3:_ZTSPj OBJECT:3:_ZTSPj@@CXXABI_1.3 -OBJECT:3:_ZTSPl OBJECT:3:_ZTSPl@@CXXABI_1.3 -OBJECT:3:_ZTSPm OBJECT:3:_ZTSPm@@CXXABI_1.3 -OBJECT:3:_ZTSPs OBJECT:3:_ZTSPs@@CXXABI_1.3 -OBJECT:3:_ZTSPt OBJECT:3:_ZTSPt@@CXXABI_1.3 -OBJECT:3:_ZTSPv OBJECT:3:_ZTSPv@@CXXABI_1.3 -OBJECT:3:_ZTSPw OBJECT:3:_ZTSPw@@CXXABI_1.3 -OBJECT:3:_ZTSPx OBJECT:3:_ZTSPx@@CXXABI_1.3 -OBJECT:3:_ZTSPy OBJECT:3:_ZTSPy@@CXXABI_1.3 -OBJECT:3:_ZTSSd OBJECT:3:_ZTSSd@@GLIBCXX_3.4 -OBJECT:3:_ZTSSi OBJECT:3:_ZTSSi@@GLIBCXX_3.4 -OBJECT:3:_ZTSSo OBJECT:3:_ZTSSo@@GLIBCXX_3.4 -OBJECT:40:_ZTSN10__cxxabiv123__fundamental_type_infoE OBJECT:40:_ZTSN10__cxxabiv123__fundamental_type_infoE@@CXXABI_1.3 -OBJECT:40:_ZTSSt14basic_ifstreamIcSt11char_traitsIcEE OBJECT:40:_ZTSSt14basic_ifstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:40:_ZTSSt14basic_ifstreamIwSt11char_traitsIwEE OBJECT:40:_ZTSSt14basic_ifstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:40:_ZTSSt14basic_iostreamIwSt11char_traitsIwEE OBJECT:40:_ZTSSt14basic_iostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:40:_ZTSSt14basic_ofstreamIcSt11char_traitsIcEE OBJECT:40:_ZTSSt14basic_ofstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:40:_ZTSSt14basic_ofstreamIwSt11char_traitsIwEE OBJECT:40:_ZTSSt14basic_ofstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:40:_ZTTNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE OBJECT:40:_ZTTNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:40:_ZTTNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE OBJECT:40:_ZTTNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:40:_ZTTSt13basic_fstreamIcSt11char_traitsIcEE OBJECT:40:_ZTTSt13basic_fstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:40:_ZTTSt13basic_fstreamIwSt11char_traitsIwEE OBJECT:40:_ZTTSt13basic_fstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:40:_ZTTSt18basic_stringstreamIcSt11char_traitsIcESaIcEE OBJECT:40:_ZTTSt18basic_stringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:40:_ZTTSt18basic_stringstreamIwSt11char_traitsIwESaIwEE OBJECT:40:_ZTTSt18basic_stringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:40:_ZTTSt9strstream OBJECT:40:_ZTTSt9strstream@@GLIBCXX_3.4 -OBJECT:40:_ZTVNSt3_V214error_categoryE OBJECT:40:_ZTVNSt3_V214error_categoryE@@GLIBCXX_3.4.21 -OBJECT:40:_ZTVNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE OBJECT:40:_ZTVNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:40:_ZTVNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE OBJECT:40:_ZTVNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:40:_ZTVNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE OBJECT:40:_ZTVNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:40:_ZTVNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE OBJECT:40:_ZTVNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:40:_ZTVSi OBJECT:40:_ZTVSi@@GLIBCXX_3.4 -OBJECT:40:_ZTVSo OBJECT:40:_ZTVSo@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt10istrstream OBJECT:40:_ZTVSt10istrstream@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt10ostrstream OBJECT:40:_ZTVSt10ostrstream@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt13basic_istreamIwSt11char_traitsIwEE OBJECT:40:_ZTVSt13basic_istreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt13basic_ostreamIwSt11char_traitsIwEE OBJECT:40:_ZTVSt13basic_ostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt14basic_ifstreamIcSt11char_traitsIcEE OBJECT:40:_ZTVSt14basic_ifstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt14basic_ifstreamIwSt11char_traitsIwEE OBJECT:40:_ZTVSt14basic_ifstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt14basic_ofstreamIcSt11char_traitsIcEE OBJECT:40:_ZTVSt14basic_ofstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt14basic_ofstreamIwSt11char_traitsIwEE OBJECT:40:_ZTVSt14basic_ofstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:40:_ZTVSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:40:_ZTVSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt19basic_istringstreamIcSt11char_traitsIcESaIcEE OBJECT:40:_ZTVSt19basic_istringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt19basic_istringstreamIwSt11char_traitsIwESaIwEE OBJECT:40:_ZTVSt19basic_istringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE OBJECT:40:_ZTVSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE OBJECT:40:_ZTVSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:40:_ZTVSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:40:_ZTVSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:40:_ZTVSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:41:_ZTSNSt13__future_base19_Async_state_commonE OBJECT:41:_ZTSNSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17 -OBJECT:41:_ZTSSt15basic_streambufIcSt11char_traitsIcEE OBJECT:41:_ZTSSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:41:_ZTSSt15basic_streambufIwSt11char_traitsIwEE OBJECT:41:_ZTSSt15basic_streambufIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:44:_ZTVN10__cxxabiv117__class_type_infoE OBJECT:44:_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3 -OBJECT:44:_ZTVN10__cxxabiv120__si_class_type_infoE OBJECT:44:_ZTVN10__cxxabiv120__si_class_type_infoE@@CXXABI_1.3 -OBJECT:44:_ZTVN10__cxxabiv121__vmi_class_type_infoE OBJECT:44:_ZTVN10__cxxabiv121__vmi_class_type_infoE@@CXXABI_1.3 -OBJECT:44:_ZTVNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE OBJECT:44:_ZTVNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE OBJECT:44:_ZTVNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE OBJECT:44:_ZTVNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE OBJECT:44:_ZTVNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVSt14codecvt_bynameIcc11__mbstate_tE OBJECT:44:_ZTVSt14codecvt_bynameIcc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:44:_ZTVSt14codecvt_bynameIwc11__mbstate_tE OBJECT:44:_ZTVSt14codecvt_bynameIwc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:44:_ZTVSt19__codecvt_utf8_baseIDiE OBJECT:44:_ZTVSt19__codecvt_utf8_baseIDiE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVSt19__codecvt_utf8_baseIDsE OBJECT:44:_ZTVSt19__codecvt_utf8_baseIDsE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVSt19__codecvt_utf8_baseIwE OBJECT:44:_ZTVSt19__codecvt_utf8_baseIwE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVSt20__codecvt_utf16_baseIDiE OBJECT:44:_ZTVSt20__codecvt_utf16_baseIDiE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVSt20__codecvt_utf16_baseIDsE OBJECT:44:_ZTVSt20__codecvt_utf16_baseIDsE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVSt20__codecvt_utf16_baseIwE OBJECT:44:_ZTVSt20__codecvt_utf16_baseIwE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVSt23__codecvt_abstract_baseIcc11__mbstate_tE OBJECT:44:_ZTVSt23__codecvt_abstract_baseIcc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:44:_ZTVSt23__codecvt_abstract_baseIwc11__mbstate_tE OBJECT:44:_ZTVSt23__codecvt_abstract_baseIwc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:44:_ZTVSt25__codecvt_utf8_utf16_baseIDiE OBJECT:44:_ZTVSt25__codecvt_utf8_utf16_baseIDiE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVSt25__codecvt_utf8_utf16_baseIDsE OBJECT:44:_ZTVSt25__codecvt_utf8_utf16_baseIDsE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVSt25__codecvt_utf8_utf16_baseIwE OBJECT:44:_ZTVSt25__codecvt_utf8_utf16_baseIwE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVSt7codecvtIDiDu11__mbstate_tE OBJECT:44:_ZTVSt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26 -OBJECT:44:_ZTVSt7codecvtIDic11__mbstate_tE OBJECT:44:_ZTVSt7codecvtIDic11__mbstate_tE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVSt7codecvtIDsDu11__mbstate_tE OBJECT:44:_ZTVSt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26 -OBJECT:44:_ZTVSt7codecvtIDsc11__mbstate_tE OBJECT:44:_ZTVSt7codecvtIDsc11__mbstate_tE@@GLIBCXX_3.4.21 -OBJECT:44:_ZTVSt7codecvtIcc11__mbstate_tE OBJECT:44:_ZTVSt7codecvtIcc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:44:_ZTVSt7codecvtIwc11__mbstate_tE OBJECT:44:_ZTVSt7codecvtIwc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:45:_ZTSSt23__codecvt_abstract_baseIcc11__mbstate_tE OBJECT:45:_ZTSSt23__codecvt_abstract_baseIcc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:45:_ZTSSt23__codecvt_abstract_baseIwc11__mbstate_tE OBJECT:45:_ZTSSt23__codecvt_abstract_baseIwc11__mbstate_tE@@GLIBCXX_3.4 -OBJECT:46:_ZTSN10__cxxabiv129__pointer_to_member_type_infoE OBJECT:46:_ZTSN10__cxxabiv129__pointer_to_member_type_infoE@@CXXABI_1.3 -OBJECT:46:_ZTSSt15basic_stringbufIcSt11char_traitsIcESaIcEE OBJECT:46:_ZTSSt15basic_stringbufIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:46:_ZTSSt15basic_stringbufIwSt11char_traitsIwESaIwEE OBJECT:46:_ZTSSt15basic_stringbufIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:48:_ZTVSt12ctype_bynameIcE OBJECT:48:_ZTVSt12ctype_bynameIcE@@GLIBCXX_3.4 -OBJECT:48:_ZTVSt5ctypeIcE OBJECT:48:_ZTVSt5ctypeIcE@@GLIBCXX_3.4 -OBJECT:48:_ZTVSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:48:_ZTVSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:48:_ZTVSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:48:_ZTVSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:49:_ZTSN9__gnu_cxx13stdio_filebufIcSt11char_traitsIcEEE OBJECT:49:_ZTSN9__gnu_cxx13stdio_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:49:_ZTSN9__gnu_cxx13stdio_filebufIwSt11char_traitsIwEEE OBJECT:49:_ZTSN9__gnu_cxx13stdio_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:49:_ZTSSt18basic_stringstreamIcSt11char_traitsIcESaIcEE OBJECT:49:_ZTSSt18basic_stringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:49:_ZTSSt18basic_stringstreamIwSt11char_traitsIwESaIwEE OBJECT:49:_ZTSSt18basic_stringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:4:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep11_S_max_sizeE OBJECT:4:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep11_S_max_sizeE@@GLIBCXX_3.4 -OBJECT:4:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep11_S_terminalE OBJECT:4:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep11_S_terminalE@@GLIBCXX_3.4 -OBJECT:4:_ZNSbIwSt11char_traitsIwESaIwEE4nposE OBJECT:4:_ZNSbIwSt11char_traitsIwESaIwEE4nposE@@GLIBCXX_3.4 -OBJECT:4:_ZNSs4_Rep11_S_max_sizeE OBJECT:4:_ZNSs4_Rep11_S_max_sizeE@@GLIBCXX_3.4 -OBJECT:4:_ZNSs4nposE OBJECT:4:_ZNSs4nposE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt10__num_base11_S_atoms_inE OBJECT:4:_ZNSt10__num_base11_S_atoms_inE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt10__num_base12_S_atoms_outE OBJECT:4:_ZNSt10__num_base12_S_atoms_outE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt10money_base18_S_default_patternE OBJECT:4:_ZNSt10money_base18_S_default_patternE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt10money_base8_S_atomsE OBJECT:4:_ZNSt10money_base8_S_atomsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt10moneypunctIcLb0EE2idE OBJECT:4:_ZNSt10moneypunctIcLb0EE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt10moneypunctIcLb1EE2idE OBJECT:4:_ZNSt10moneypunctIcLb1EE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt10moneypunctIwLb0EE2idE OBJECT:4:_ZNSt10moneypunctIwLb0EE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt10moneypunctIwLb1EE2idE OBJECT:4:_ZNSt10moneypunctIwLb1EE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt11__timepunctIcE2idE OBJECT:4:_ZNSt11__timepunctIcE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt11__timepunctIwE2idE OBJECT:4:_ZNSt11__timepunctIwE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIDiE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIDiE10has_denormE@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDiE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIDiE11round_styleE@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDiE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIDiE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIDiE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIDiE12max_exponentE@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDiE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIDiE12min_exponentE@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDiE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIDiE14max_exponent10E@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDiE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIDiE14min_exponent10E@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDiE5radixE OBJECT:4:_ZNSt14numeric_limitsIDiE5radixE@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDiE6digitsE OBJECT:4:_ZNSt14numeric_limitsIDiE6digitsE@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDiE8digits10E OBJECT:4:_ZNSt14numeric_limitsIDiE8digits10E@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDsE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIDsE10has_denormE@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDsE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIDsE11round_styleE@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDsE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIDsE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIDsE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIDsE12max_exponentE@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDsE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIDsE12min_exponentE@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDsE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIDsE14max_exponent10E@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDsE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIDsE14min_exponent10E@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDsE5radixE OBJECT:4:_ZNSt14numeric_limitsIDsE5radixE@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDsE6digitsE OBJECT:4:_ZNSt14numeric_limitsIDsE6digitsE@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDsE8digits10E OBJECT:4:_ZNSt14numeric_limitsIDsE8digits10E@@GLIBCXX_3.4.11 -OBJECT:4:_ZNSt14numeric_limitsIDuE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIDuE10has_denormE@@GLIBCXX_3.4.26 -OBJECT:4:_ZNSt14numeric_limitsIDuE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIDuE11round_styleE@@GLIBCXX_3.4.26 -OBJECT:4:_ZNSt14numeric_limitsIDuE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIDuE12max_exponentE@@GLIBCXX_3.4.26 -OBJECT:4:_ZNSt14numeric_limitsIDuE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIDuE12min_exponentE@@GLIBCXX_3.4.26 -OBJECT:4:_ZNSt14numeric_limitsIDuE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIDuE14max_exponent10E@@GLIBCXX_3.4.26 -OBJECT:4:_ZNSt14numeric_limitsIDuE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIDuE14min_exponent10E@@GLIBCXX_3.4.26 -OBJECT:4:_ZNSt14numeric_limitsIDuE5radixE OBJECT:4:_ZNSt14numeric_limitsIDuE5radixE@@GLIBCXX_3.4.26 -OBJECT:4:_ZNSt14numeric_limitsIDuE6digitsE OBJECT:4:_ZNSt14numeric_limitsIDuE6digitsE@@GLIBCXX_3.4.26 -OBJECT:4:_ZNSt14numeric_limitsIDuE8digits10E OBJECT:4:_ZNSt14numeric_limitsIDuE8digits10E@@GLIBCXX_3.4.26 -OBJECT:4:_ZNSt14numeric_limitsIaE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIaE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIaE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIaE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIaE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIaE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIaE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIaE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIaE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIaE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIaE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIaE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIaE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIaE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIaE5radixE OBJECT:4:_ZNSt14numeric_limitsIaE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIaE6digitsE OBJECT:4:_ZNSt14numeric_limitsIaE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIaE8digits10E OBJECT:4:_ZNSt14numeric_limitsIaE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIbE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIbE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIbE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIbE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIbE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIbE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIbE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIbE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIbE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIbE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIbE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIbE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIbE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIbE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIbE5radixE OBJECT:4:_ZNSt14numeric_limitsIbE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIbE6digitsE OBJECT:4:_ZNSt14numeric_limitsIbE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIbE8digits10E OBJECT:4:_ZNSt14numeric_limitsIbE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIcE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIcE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIcE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIcE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIcE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIcE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIcE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIcE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIcE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIcE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIcE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIcE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIcE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIcE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIcE5radixE OBJECT:4:_ZNSt14numeric_limitsIcE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIcE6digitsE OBJECT:4:_ZNSt14numeric_limitsIcE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIcE8digits10E OBJECT:4:_ZNSt14numeric_limitsIcE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIdE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIdE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIdE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIdE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIdE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIdE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIdE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIdE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIdE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIdE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIdE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIdE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIdE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIdE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIdE5radixE OBJECT:4:_ZNSt14numeric_limitsIdE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIdE6digitsE OBJECT:4:_ZNSt14numeric_limitsIdE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIdE8digits10E OBJECT:4:_ZNSt14numeric_limitsIdE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIeE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIeE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIeE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIeE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIeE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIeE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIeE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIeE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIeE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIeE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIeE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIeE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIeE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIeE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIeE5radixE OBJECT:4:_ZNSt14numeric_limitsIeE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIeE6digitsE OBJECT:4:_ZNSt14numeric_limitsIeE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIeE8digits10E OBJECT:4:_ZNSt14numeric_limitsIeE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIfE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIfE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIfE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIfE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIfE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIfE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIfE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIfE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIfE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIfE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIfE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIfE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIfE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIfE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIfE5radixE OBJECT:4:_ZNSt14numeric_limitsIfE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIfE6digitsE OBJECT:4:_ZNSt14numeric_limitsIfE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIfE8digits10E OBJECT:4:_ZNSt14numeric_limitsIfE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIhE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIhE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIhE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIhE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIhE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIhE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIhE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIhE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIhE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIhE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIhE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIhE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIhE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIhE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIhE5radixE OBJECT:4:_ZNSt14numeric_limitsIhE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIhE6digitsE OBJECT:4:_ZNSt14numeric_limitsIhE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIhE8digits10E OBJECT:4:_ZNSt14numeric_limitsIhE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIiE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIiE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIiE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIiE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIiE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIiE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIiE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIiE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIiE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIiE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIiE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIiE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIiE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIiE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIiE5radixE OBJECT:4:_ZNSt14numeric_limitsIiE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIiE6digitsE OBJECT:4:_ZNSt14numeric_limitsIiE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIiE8digits10E OBJECT:4:_ZNSt14numeric_limitsIiE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIjE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIjE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIjE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIjE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIjE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIjE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIjE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIjE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIjE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIjE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIjE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIjE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIjE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIjE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIjE5radixE OBJECT:4:_ZNSt14numeric_limitsIjE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIjE6digitsE OBJECT:4:_ZNSt14numeric_limitsIjE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIjE8digits10E OBJECT:4:_ZNSt14numeric_limitsIjE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIlE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIlE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIlE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIlE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIlE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIlE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIlE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIlE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIlE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIlE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIlE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIlE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIlE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIlE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIlE5radixE OBJECT:4:_ZNSt14numeric_limitsIlE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIlE6digitsE OBJECT:4:_ZNSt14numeric_limitsIlE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIlE8digits10E OBJECT:4:_ZNSt14numeric_limitsIlE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsImE10has_denormE OBJECT:4:_ZNSt14numeric_limitsImE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsImE11round_styleE OBJECT:4:_ZNSt14numeric_limitsImE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsImE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsImE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsImE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsImE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsImE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsImE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsImE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsImE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsImE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsImE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsImE5radixE OBJECT:4:_ZNSt14numeric_limitsImE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsImE6digitsE OBJECT:4:_ZNSt14numeric_limitsImE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsImE8digits10E OBJECT:4:_ZNSt14numeric_limitsImE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIsE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIsE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIsE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIsE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIsE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIsE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIsE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIsE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIsE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIsE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIsE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIsE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIsE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIsE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIsE5radixE OBJECT:4:_ZNSt14numeric_limitsIsE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIsE6digitsE OBJECT:4:_ZNSt14numeric_limitsIsE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIsE8digits10E OBJECT:4:_ZNSt14numeric_limitsIsE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsItE10has_denormE OBJECT:4:_ZNSt14numeric_limitsItE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsItE11round_styleE OBJECT:4:_ZNSt14numeric_limitsItE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsItE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsItE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsItE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsItE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsItE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsItE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsItE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsItE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsItE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsItE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsItE5radixE OBJECT:4:_ZNSt14numeric_limitsItE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsItE6digitsE OBJECT:4:_ZNSt14numeric_limitsItE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsItE8digits10E OBJECT:4:_ZNSt14numeric_limitsItE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIwE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIwE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIwE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIwE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIwE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIwE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIwE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIwE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIwE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIwE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIwE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIwE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIwE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIwE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIwE5radixE OBJECT:4:_ZNSt14numeric_limitsIwE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIwE6digitsE OBJECT:4:_ZNSt14numeric_limitsIwE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIwE8digits10E OBJECT:4:_ZNSt14numeric_limitsIwE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIxE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIxE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIxE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIxE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIxE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIxE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIxE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIxE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIxE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIxE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIxE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIxE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIxE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIxE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIxE5radixE OBJECT:4:_ZNSt14numeric_limitsIxE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIxE6digitsE OBJECT:4:_ZNSt14numeric_limitsIxE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIxE8digits10E OBJECT:4:_ZNSt14numeric_limitsIxE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIyE10has_denormE OBJECT:4:_ZNSt14numeric_limitsIyE10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIyE11round_styleE OBJECT:4:_ZNSt14numeric_limitsIyE11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIyE12max_digits10E OBJECT:4:_ZNSt14numeric_limitsIyE12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt14numeric_limitsIyE12max_exponentE OBJECT:4:_ZNSt14numeric_limitsIyE12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIyE12min_exponentE OBJECT:4:_ZNSt14numeric_limitsIyE12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIyE14max_exponent10E OBJECT:4:_ZNSt14numeric_limitsIyE14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIyE14min_exponent10E OBJECT:4:_ZNSt14numeric_limitsIyE14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIyE5radixE OBJECT:4:_ZNSt14numeric_limitsIyE5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIyE6digitsE OBJECT:4:_ZNSt14numeric_limitsIyE6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt14numeric_limitsIyE8digits10E OBJECT:4:_ZNSt14numeric_limitsIyE8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt21__numeric_limits_base10has_denormE OBJECT:4:_ZNSt21__numeric_limits_base10has_denormE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt21__numeric_limits_base11round_styleE OBJECT:4:_ZNSt21__numeric_limits_base11round_styleE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt21__numeric_limits_base12max_digits10E OBJECT:4:_ZNSt21__numeric_limits_base12max_digits10E@@GLIBCXX_3.4.14 -OBJECT:4:_ZNSt21__numeric_limits_base12max_exponentE OBJECT:4:_ZNSt21__numeric_limits_base12max_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt21__numeric_limits_base12min_exponentE OBJECT:4:_ZNSt21__numeric_limits_base12min_exponentE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt21__numeric_limits_base14max_exponent10E OBJECT:4:_ZNSt21__numeric_limits_base14max_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt21__numeric_limits_base14min_exponent10E OBJECT:4:_ZNSt21__numeric_limits_base14min_exponent10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt21__numeric_limits_base5radixE OBJECT:4:_ZNSt21__numeric_limits_base5radixE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt21__numeric_limits_base6digitsE OBJECT:4:_ZNSt21__numeric_limits_base6digitsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt21__numeric_limits_base8digits10E OBJECT:4:_ZNSt21__numeric_limits_base8digits10E@@GLIBCXX_3.4 -OBJECT:4:_ZNSt5ctypeIcE10table_sizeE OBJECT:4:_ZNSt5ctypeIcE10table_sizeE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt5ctypeIcE2idE OBJECT:4:_ZNSt5ctypeIcE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt5ctypeIwE2idE OBJECT:4:_ZNSt5ctypeIwE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt6locale3allE OBJECT:4:_ZNSt6locale3allE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt6locale4noneE OBJECT:4:_ZNSt6locale4noneE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt6locale4timeE OBJECT:4:_ZNSt6locale4timeE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt6locale5ctypeE OBJECT:4:_ZNSt6locale5ctypeE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt6locale7collateE OBJECT:4:_ZNSt6locale7collateE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt6locale7numericE OBJECT:4:_ZNSt6locale7numericE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt6locale8messagesE OBJECT:4:_ZNSt6locale8messagesE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt6locale8monetaryE OBJECT:4:_ZNSt6locale8monetaryE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt7__cxx1110moneypunctIcLb0EE2idE OBJECT:4:_ZNSt7__cxx1110moneypunctIcLb0EE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx1110moneypunctIcLb1EE2idE OBJECT:4:_ZNSt7__cxx1110moneypunctIcLb1EE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx1110moneypunctIwLb0EE2idE OBJECT:4:_ZNSt7__cxx1110moneypunctIwLb0EE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx1110moneypunctIwLb1EE2idE OBJECT:4:_ZNSt7__cxx1110moneypunctIwLb1EE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4nposE OBJECT:4:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4nposE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4nposE OBJECT:4:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4nposE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx117collateIcE2idE OBJECT:4:_ZNSt7__cxx117collateIcE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx117collateIwE2idE OBJECT:4:_ZNSt7__cxx117collateIwE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx118messagesIcE2idE OBJECT:4:_ZNSt7__cxx118messagesIcE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx118messagesIwE2idE OBJECT:4:_ZNSt7__cxx118messagesIwE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx118numpunctIcE2idE OBJECT:4:_ZNSt7__cxx118numpunctIcE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx118numpunctIwE2idE OBJECT:4:_ZNSt7__cxx118numpunctIwE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:4:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:4:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:4:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:4:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:4:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:4:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7codecvtIDiDu11__mbstate_tE2idE OBJECT:4:_ZNSt7codecvtIDiDu11__mbstate_tE2idE@@GLIBCXX_3.4.26 -OBJECT:4:_ZNSt7codecvtIDic11__mbstate_tE2idE OBJECT:4:_ZNSt7codecvtIDic11__mbstate_tE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7codecvtIDsDu11__mbstate_tE2idE OBJECT:4:_ZNSt7codecvtIDsDu11__mbstate_tE2idE@@GLIBCXX_3.4.26 -OBJECT:4:_ZNSt7codecvtIDsc11__mbstate_tE2idE OBJECT:4:_ZNSt7codecvtIDsc11__mbstate_tE2idE@@GLIBCXX_3.4.21 -OBJECT:4:_ZNSt7codecvtIcc11__mbstate_tE2idE OBJECT:4:_ZNSt7codecvtIcc11__mbstate_tE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt7codecvtIwc11__mbstate_tE2idE OBJECT:4:_ZNSt7codecvtIwc11__mbstate_tE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt7collateIcE2idE OBJECT:4:_ZNSt7collateIcE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt7collateIwE2idE OBJECT:4:_ZNSt7collateIwE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:4:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:4:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:4:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:4:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base10floatfieldE OBJECT:4:_ZNSt8ios_base10floatfieldE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base10scientificE OBJECT:4:_ZNSt8ios_base10scientificE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base11adjustfieldE OBJECT:4:_ZNSt8ios_base11adjustfieldE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base2inE OBJECT:4:_ZNSt8ios_base2inE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base3appE OBJECT:4:_ZNSt8ios_base3appE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base3ateE OBJECT:4:_ZNSt8ios_base3ateE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base3begE OBJECT:4:_ZNSt8ios_base3begE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base3curE OBJECT:4:_ZNSt8ios_base3curE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base3decE OBJECT:4:_ZNSt8ios_base3decE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base3endE OBJECT:4:_ZNSt8ios_base3endE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base3hexE OBJECT:4:_ZNSt8ios_base3hexE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base3octE OBJECT:4:_ZNSt8ios_base3octE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base3outE OBJECT:4:_ZNSt8ios_base3outE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base4leftE OBJECT:4:_ZNSt8ios_base4leftE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base5fixedE OBJECT:4:_ZNSt8ios_base5fixedE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base5rightE OBJECT:4:_ZNSt8ios_base5rightE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base5truncE OBJECT:4:_ZNSt8ios_base5truncE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base6badbitE OBJECT:4:_ZNSt8ios_base6badbitE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base6binaryE OBJECT:4:_ZNSt8ios_base6binaryE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base6eofbitE OBJECT:4:_ZNSt8ios_base6eofbitE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base6skipwsE OBJECT:4:_ZNSt8ios_base6skipwsE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base7failbitE OBJECT:4:_ZNSt8ios_base7failbitE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base7goodbitE OBJECT:4:_ZNSt8ios_base7goodbitE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base7showposE OBJECT:4:_ZNSt8ios_base7showposE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base7unitbufE OBJECT:4:_ZNSt8ios_base7unitbufE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base8internalE OBJECT:4:_ZNSt8ios_base8internalE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base8showbaseE OBJECT:4:_ZNSt8ios_base8showbaseE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base9basefieldE OBJECT:4:_ZNSt8ios_base9basefieldE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base9boolalphaE OBJECT:4:_ZNSt8ios_base9boolalphaE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base9showpointE OBJECT:4:_ZNSt8ios_base9showpointE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8ios_base9uppercaseE OBJECT:4:_ZNSt8ios_base9uppercaseE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8messagesIcE2idE OBJECT:4:_ZNSt8messagesIcE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8messagesIwE2idE OBJECT:4:_ZNSt8messagesIwE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8numpunctIcE2idE OBJECT:4:_ZNSt8numpunctIcE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8numpunctIwE2idE OBJECT:4:_ZNSt8numpunctIwE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:4:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:4:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:4:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:4:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:4:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:4:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:4:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 -OBJECT:4:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:4:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 OBJECT:4:_ZSt15future_category@@GLIBCXX_3.4.14 -OBJECT:4:_ZTSPKa OBJECT:4:_ZTSPKa@@CXXABI_1.3 -OBJECT:4:_ZTSPKb OBJECT:4:_ZTSPKb@@CXXABI_1.3 -OBJECT:4:_ZTSPKc OBJECT:4:_ZTSPKc@@CXXABI_1.3 -OBJECT:4:_ZTSPKd OBJECT:4:_ZTSPKd@@CXXABI_1.3 -OBJECT:4:_ZTSPKe OBJECT:4:_ZTSPKe@@CXXABI_1.3 -OBJECT:4:_ZTSPKf OBJECT:4:_ZTSPKf@@CXXABI_1.3 -OBJECT:4:_ZTSPKh OBJECT:4:_ZTSPKh@@CXXABI_1.3 -OBJECT:4:_ZTSPKi OBJECT:4:_ZTSPKi@@CXXABI_1.3 -OBJECT:4:_ZTSPKj OBJECT:4:_ZTSPKj@@CXXABI_1.3 -OBJECT:4:_ZTSPKl OBJECT:4:_ZTSPKl@@CXXABI_1.3 -OBJECT:4:_ZTSPKm OBJECT:4:_ZTSPKm@@CXXABI_1.3 -OBJECT:4:_ZTSPKs OBJECT:4:_ZTSPKs@@CXXABI_1.3 -OBJECT:4:_ZTSPKt OBJECT:4:_ZTSPKt@@CXXABI_1.3 -OBJECT:4:_ZTSPKv OBJECT:4:_ZTSPKv@@CXXABI_1.3 -OBJECT:4:_ZTSPKw OBJECT:4:_ZTSPKw@@CXXABI_1.3 -OBJECT:4:_ZTSPKx OBJECT:4:_ZTSPKx@@CXXABI_1.3 -OBJECT:4:_ZTSPKy OBJECT:4:_ZTSPKy@@CXXABI_1.3 -OBJECT:50:_ZTSSt19basic_istringstreamIcSt11char_traitsIcESaIcEE OBJECT:50:_ZTSSt19basic_istringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:50:_ZTSSt19basic_istringstreamIwSt11char_traitsIwESaIwEE OBJECT:50:_ZTSSt19basic_istringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:50:_ZTSSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE OBJECT:50:_ZTSSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:50:_ZTSSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE OBJECT:50:_ZTSSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:52:_ZTVNSt7__cxx1110moneypunctIcLb0EEE OBJECT:52:_ZTVNSt7__cxx1110moneypunctIcLb0EEE@@GLIBCXX_3.4.21 -OBJECT:52:_ZTVNSt7__cxx1110moneypunctIcLb1EEE OBJECT:52:_ZTVNSt7__cxx1110moneypunctIcLb1EEE@@GLIBCXX_3.4.21 -OBJECT:52:_ZTVNSt7__cxx1110moneypunctIwLb0EEE OBJECT:52:_ZTVNSt7__cxx1110moneypunctIwLb0EEE@@GLIBCXX_3.4.21 -OBJECT:52:_ZTVNSt7__cxx1110moneypunctIwLb1EEE OBJECT:52:_ZTVNSt7__cxx1110moneypunctIwLb1EEE@@GLIBCXX_3.4.21 -OBJECT:52:_ZTVNSt7__cxx1117moneypunct_bynameIcLb0EEE OBJECT:52:_ZTVNSt7__cxx1117moneypunct_bynameIcLb0EEE@@GLIBCXX_3.4.21 -OBJECT:52:_ZTVNSt7__cxx1117moneypunct_bynameIcLb1EEE OBJECT:52:_ZTVNSt7__cxx1117moneypunct_bynameIcLb1EEE@@GLIBCXX_3.4.21 -OBJECT:52:_ZTVNSt7__cxx1117moneypunct_bynameIwLb0EEE OBJECT:52:_ZTVNSt7__cxx1117moneypunct_bynameIwLb0EEE@@GLIBCXX_3.4.21 -OBJECT:52:_ZTVNSt7__cxx1117moneypunct_bynameIwLb1EEE OBJECT:52:_ZTVNSt7__cxx1117moneypunct_bynameIwLb1EEE@@GLIBCXX_3.4.21 -OBJECT:52:_ZTVSt10moneypunctIcLb0EE OBJECT:52:_ZTVSt10moneypunctIcLb0EE@@GLIBCXX_3.4 -OBJECT:52:_ZTVSt10moneypunctIcLb1EE OBJECT:52:_ZTVSt10moneypunctIcLb1EE@@GLIBCXX_3.4 -OBJECT:52:_ZTVSt10moneypunctIwLb0EE OBJECT:52:_ZTVSt10moneypunctIwLb0EE@@GLIBCXX_3.4 -OBJECT:52:_ZTVSt10moneypunctIwLb1EE OBJECT:52:_ZTVSt10moneypunctIwLb1EE@@GLIBCXX_3.4 -OBJECT:52:_ZTVSt17moneypunct_bynameIcLb0EE OBJECT:52:_ZTVSt17moneypunct_bynameIcLb0EE@@GLIBCXX_3.4 -OBJECT:52:_ZTVSt17moneypunct_bynameIcLb1EE OBJECT:52:_ZTVSt17moneypunct_bynameIcLb1EE@@GLIBCXX_3.4 -OBJECT:52:_ZTVSt17moneypunct_bynameIwLb0EE OBJECT:52:_ZTVSt17moneypunct_bynameIwLb0EE@@GLIBCXX_3.4 -OBJECT:52:_ZTVSt17moneypunct_bynameIwLb1EE OBJECT:52:_ZTVSt17moneypunct_bynameIwLb1EE@@GLIBCXX_3.4 -OBJECT:54:_ZTSN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEE OBJECT:54:_ZTSN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:54:_ZTSN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEE OBJECT:54:_ZTSN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:56:_ZNSt17__timepunct_cacheIcE12_S_timezonesE OBJECT:56:_ZNSt17__timepunct_cacheIcE12_S_timezonesE@@GLIBCXX_3.4 -OBJECT:56:_ZNSt17__timepunct_cacheIwE12_S_timezonesE OBJECT:56:_ZNSt17__timepunct_cacheIwE12_S_timezonesE@@GLIBCXX_3.4 -OBJECT:56:_ZTSNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE OBJECT:56:_ZTSNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:56:_ZTSNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEE OBJECT:56:_ZTSNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:58:_ZTSSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:58:_ZTSSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:58:_ZTSSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:58:_ZTSSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:58:_ZTSSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:58:_ZTSSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:58:_ZTSSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:58:_ZTSSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:59:_ZTSNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE OBJECT:59:_ZTSNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:59:_ZTSNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE OBJECT:59:_ZTSNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:59:_ZTSSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:59:_ZTSSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:59:_ZTSSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:59:_ZTSSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:59:_ZTSSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:59:_ZTSSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:59:_ZTSSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:59:_ZTSSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:60:_ZTSNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE OBJECT:60:_ZTSNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:60:_ZTSNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE OBJECT:60:_ZTSNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:60:_ZTSNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE OBJECT:60:_ZTSNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:60:_ZTSNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE OBJECT:60:_ZTSNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:60:_ZTSSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:60:_ZTSSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:60:_ZTSSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:60:_ZTSSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:60:_ZTSSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:60:_ZTSSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:60:_ZTSSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:60:_ZTSSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:60:_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE OBJECT:60:_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:60:_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE OBJECT:60:_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:60:_ZTVSd OBJECT:60:_ZTVSd@@GLIBCXX_3.4 -OBJECT:60:_ZTVSt13basic_fstreamIcSt11char_traitsIcEE OBJECT:60:_ZTVSt13basic_fstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:60:_ZTVSt13basic_fstreamIwSt11char_traitsIwEE OBJECT:60:_ZTVSt13basic_fstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:60:_ZTVSt14basic_iostreamIwSt11char_traitsIwEE OBJECT:60:_ZTVSt14basic_iostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:60:_ZTVSt18basic_stringstreamIcSt11char_traitsIcESaIcEE OBJECT:60:_ZTVSt18basic_stringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:60:_ZTVSt18basic_stringstreamIwSt11char_traitsIwESaIwEE OBJECT:60:_ZTVSt18basic_stringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:60:_ZTVSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:60:_ZTVSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:60:_ZTVSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:60:_ZTVSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:60:_ZTVSt9strstream OBJECT:60:_ZTVSt9strstream@@GLIBCXX_3.4 -OBJECT:64:_ZTVN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEE OBJECT:64:_ZTVN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:64:_ZTVN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEE OBJECT:64:_ZTVN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:64:_ZTVNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE OBJECT:64:_ZTVNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 -OBJECT:64:_ZTVNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEE OBJECT:64:_ZTVNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 -OBJECT:64:_ZTVSt12ctype_bynameIwE OBJECT:64:_ZTVSt12ctype_bynameIwE@@GLIBCXX_3.4 -OBJECT:64:_ZTVSt12strstreambuf OBJECT:64:_ZTVSt12strstreambuf@@GLIBCXX_3.4 -OBJECT:64:_ZTVSt13basic_filebufIcSt11char_traitsIcEE OBJECT:64:_ZTVSt13basic_filebufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:64:_ZTVSt13basic_filebufIwSt11char_traitsIwEE OBJECT:64:_ZTVSt13basic_filebufIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:64:_ZTVSt15basic_streambufIcSt11char_traitsIcEE OBJECT:64:_ZTVSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:64:_ZTVSt15basic_streambufIwSt11char_traitsIwEE OBJECT:64:_ZTVSt15basic_streambufIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:64:_ZTVSt15basic_stringbufIcSt11char_traitsIcESaIcEE OBJECT:64:_ZTVSt15basic_stringbufIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 -OBJECT:64:_ZTVSt15basic_stringbufIwSt11char_traitsIwESaIwEE OBJECT:64:_ZTVSt15basic_stringbufIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 -OBJECT:64:_ZTVSt21__ctype_abstract_baseIcE OBJECT:64:_ZTVSt21__ctype_abstract_baseIcE@@GLIBCXX_3.4 -OBJECT:64:_ZTVSt21__ctype_abstract_baseIwE OBJECT:64:_ZTVSt21__ctype_abstract_baseIwE@@GLIBCXX_3.4 -OBJECT:64:_ZTVSt5ctypeIwE OBJECT:64:_ZTVSt5ctypeIwE@@GLIBCXX_3.4 -OBJECT:67:_ZTSSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:67:_ZTSSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:67:_ZTSSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:67:_ZTSSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:67:_ZTSSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE OBJECT:67:_ZTSSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 -OBJECT:67:_ZTSSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:67:_ZTSSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -OBJECT:69:_ZTSNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE OBJECT:69:_ZTSNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 -OBJECT:69:_ZTSNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE OBJECT:69:_ZTSNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 -OBJECT:70:_ZTSNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE OBJECT:70:_ZTSNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 -OBJECT:70:_ZTSNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE OBJECT:70:_ZTSNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 -OBJECT:70:_ZTSNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE OBJECT:70:_ZTSNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 -OBJECT:70:_ZTSNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE OBJECT:70:_ZTSNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 -OBJECT:77:_ZTSNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE OBJECT:77:_ZTSNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 -OBJECT:77:_ZTSNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE OBJECT:77:_ZTSNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt10moneypunctIcLb0EE2idE OBJECT:8:_ZGVNSt10moneypunctIcLb0EE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt10moneypunctIcLb1EE2idE OBJECT:8:_ZGVNSt10moneypunctIcLb1EE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt10moneypunctIwLb0EE2idE OBJECT:8:_ZGVNSt10moneypunctIwLb0EE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt10moneypunctIwLb1EE2idE OBJECT:8:_ZGVNSt10moneypunctIwLb1EE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt11__timepunctIcE2idE OBJECT:8:_ZGVNSt11__timepunctIcE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt11__timepunctIwE2idE OBJECT:8:_ZGVNSt11__timepunctIwE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt7__cxx1110moneypunctIcLb0EE2idE OBJECT:8:_ZGVNSt7__cxx1110moneypunctIcLb0EE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx1110moneypunctIcLb1EE2idE OBJECT:8:_ZGVNSt7__cxx1110moneypunctIcLb1EE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx1110moneypunctIwLb0EE2idE OBJECT:8:_ZGVNSt7__cxx1110moneypunctIwLb0EE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx1110moneypunctIwLb1EE2idE OBJECT:8:_ZGVNSt7__cxx1110moneypunctIwLb1EE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx117collateIcE2idE OBJECT:8:_ZGVNSt7__cxx117collateIcE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx117collateIwE2idE OBJECT:8:_ZGVNSt7__cxx117collateIwE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx118messagesIcE2idE OBJECT:8:_ZGVNSt7__cxx118messagesIcE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx118messagesIwE2idE OBJECT:8:_ZGVNSt7__cxx118messagesIwE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx118numpunctIcE2idE OBJECT:8:_ZGVNSt7__cxx118numpunctIcE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx118numpunctIwE2idE OBJECT:8:_ZGVNSt7__cxx118numpunctIwE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:8:_ZGVNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:8:_ZGVNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:8:_ZGVNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:8:_ZGVNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:8:_ZGVNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:8:_ZGVNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21 -OBJECT:8:_ZGVNSt7collateIcE2idE OBJECT:8:_ZGVNSt7collateIcE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt7collateIwE2idE OBJECT:8:_ZGVNSt7collateIwE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:8:_ZGVNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:8:_ZGVNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:8:_ZGVNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:8:_ZGVNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt8messagesIcE2idE OBJECT:8:_ZGVNSt8messagesIcE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt8messagesIwE2idE OBJECT:8:_ZGVNSt8messagesIwE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt8numpunctIcE2idE OBJECT:8:_ZGVNSt8numpunctIcE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt8numpunctIwE2idE OBJECT:8:_ZGVNSt8numpunctIwE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:8:_ZGVNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:8:_ZGVNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:8:_ZGVNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:8:_ZGVNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:8:_ZGVNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:8:_ZGVNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE OBJECT:8:_ZGVNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZGVNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE OBJECT:8:_ZGVNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 -OBJECT:8:_ZTIDF32_ OBJECT:8:_ZTIDF32_@@CXXABI_1.3.14 -OBJECT:8:_ZTIDF32x OBJECT:8:_ZTIDF32x@@CXXABI_1.3.14 -OBJECT:8:_ZTIDF64_ OBJECT:8:_ZTIDF64_@@CXXABI_1.3.14 -OBJECT:8:_ZTIDd OBJECT:8:_ZTIDd@@CXXABI_1.3.4 -OBJECT:8:_ZTIDe OBJECT:8:_ZTIDe@@CXXABI_1.3.4 -OBJECT:8:_ZTIDf OBJECT:8:_ZTIDf@@CXXABI_1.3.4 -OBJECT:8:_ZTIDi OBJECT:8:_ZTIDi@@CXXABI_1.3.3 -OBJECT:8:_ZTIDn OBJECT:8:_ZTIDn@@CXXABI_1.3.5 -OBJECT:8:_ZTIDs OBJECT:8:_ZTIDs@@CXXABI_1.3.3 -OBJECT:8:_ZTIDu OBJECT:8:_ZTIDu@@CXXABI_1.3.12 -OBJECT:8:_ZTIN10__cxxabiv115__forced_unwindE OBJECT:8:_ZTIN10__cxxabiv115__forced_unwindE@@CXXABI_1.3.2 -OBJECT:8:_ZTIN10__cxxabiv119__foreign_exceptionE OBJECT:8:_ZTIN10__cxxabiv119__foreign_exceptionE@@CXXABI_1.3.2 -OBJECT:8:_ZTINSt13__future_base11_State_baseE OBJECT:8:_ZTINSt13__future_base11_State_baseE@@GLIBCXX_3.4.15 -OBJECT:8:_ZTINSt13__future_base12_Result_baseE OBJECT:8:_ZTINSt13__future_base12_Result_baseE@@GLIBCXX_3.4.15 -OBJECT:8:_ZTINSt3_V214error_categoryE OBJECT:8:_ZTINSt3_V214error_categoryE@@GLIBCXX_3.4.21 -OBJECT:8:_ZTINSt3pmr15memory_resourceE OBJECT:8:_ZTINSt3pmr15memory_resourceE@@GLIBCXX_3.4.28 -OBJECT:8:_ZTINSt6locale5facetE OBJECT:8:_ZTINSt6locale5facetE@@GLIBCXX_3.4 -OBJECT:8:_ZTINSt6thread6_StateE OBJECT:8:_ZTINSt6thread6_StateE@@GLIBCXX_3.4.22 -OBJECT:8:_ZTISt10ctype_base OBJECT:8:_ZTISt10ctype_base@@GLIBCXX_3.4 -OBJECT:8:_ZTISt10money_base OBJECT:8:_ZTISt10money_base@@GLIBCXX_3.4 -OBJECT:8:_ZTISt12codecvt_base OBJECT:8:_ZTISt12codecvt_base@@GLIBCXX_3.4 -OBJECT:8:_ZTISt13messages_base OBJECT:8:_ZTISt13messages_base@@GLIBCXX_3.4 -OBJECT:8:_ZTISt14error_category OBJECT:8:_ZTISt14error_category@@GLIBCXX_3.4.11 -OBJECT:8:_ZTISt15basic_streambufIcSt11char_traitsIcEE OBJECT:8:_ZTISt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 -OBJECT:8:_ZTISt15basic_streambufIwSt11char_traitsIwEE OBJECT:8:_ZTISt15basic_streambufIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:8:_ZTISt16nested_exception OBJECT:8:_ZTISt16nested_exception@@CXXABI_1.3.5 -OBJECT:8:_ZTISt8ios_base OBJECT:8:_ZTISt8ios_base@@GLIBCXX_3.4 -OBJECT:8:_ZTISt9exception OBJECT:8:_ZTISt9exception@@GLIBCXX_3.4 -OBJECT:8:_ZTISt9time_base OBJECT:8:_ZTISt9time_base@@GLIBCXX_3.4 -OBJECT:8:_ZTISt9type_info OBJECT:8:_ZTISt9type_info@@GLIBCXX_3.4 -OBJECT:8:_ZTIa OBJECT:8:_ZTIa@@CXXABI_1.3 -OBJECT:8:_ZTIb OBJECT:8:_ZTIb@@CXXABI_1.3 -OBJECT:8:_ZTIc OBJECT:8:_ZTIc@@CXXABI_1.3 -OBJECT:8:_ZTId OBJECT:8:_ZTId@@CXXABI_1.3 -OBJECT:8:_ZTIe OBJECT:8:_ZTIe@@CXXABI_1.3 -OBJECT:8:_ZTIf OBJECT:8:_ZTIf@@CXXABI_1.3 -OBJECT:8:_ZTIh OBJECT:8:_ZTIh@@CXXABI_1.3 -OBJECT:8:_ZTIi OBJECT:8:_ZTIi@@CXXABI_1.3 -OBJECT:8:_ZTIj OBJECT:8:_ZTIj@@CXXABI_1.3 -OBJECT:8:_ZTIl OBJECT:8:_ZTIl@@CXXABI_1.3 -OBJECT:8:_ZTIm OBJECT:8:_ZTIm@@CXXABI_1.3 -OBJECT:8:_ZTIs OBJECT:8:_ZTIs@@CXXABI_1.3 -OBJECT:8:_ZTIt OBJECT:8:_ZTIt@@CXXABI_1.3 -OBJECT:8:_ZTIv OBJECT:8:_ZTIv@@CXXABI_1.3 -OBJECT:8:_ZTIw OBJECT:8:_ZTIw@@CXXABI_1.3 -OBJECT:8:_ZTIx OBJECT:8:_ZTIx@@CXXABI_1.3 -OBJECT:8:_ZTIy OBJECT:8:_ZTIy@@CXXABI_1.3 -OBJECT:8:_ZTTSi OBJECT:8:_ZTTSi@@GLIBCXX_3.4 -OBJECT:8:_ZTTSo OBJECT:8:_ZTTSo@@GLIBCXX_3.4 -OBJECT:8:_ZTTSt13basic_istreamIwSt11char_traitsIwEE OBJECT:8:_ZTTSt13basic_istreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -OBJECT:8:_ZTTSt13basic_ostreamIwSt11char_traitsIwEE OBJECT:8:_ZTTSt13basic_ostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 diff --git a/libstdc++-v3/config/abi/post/x86_64-linux-gnu/x32/baseline_symbols.txt b/libstdc++-v3/config/abi/post/x86_64-linux-gnu/x32/baseline_symbols.txt index ac11d5dba4d3..5d552873896e 100644 --- a/libstdc++-v3/config/abi/post/x86_64-linux-gnu/x32/baseline_symbols.txt +++ b/libstdc++-v3/config/abi/post/x86_64-linux-gnu/x32/baseline_symbols.txt @@ -2124,6 +2124,10 @@ FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policy FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC2EOS5_@@GLIBCXX_3.4.28 FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27 FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEaSEOS5_@@GLIBCXX_3.4.26 +FUNC:_ZNSt12__sso_stringC1Ev@@GLIBCXX_3.4.34 +FUNC:_ZNSt12__sso_stringC2Ev@@GLIBCXX_3.4.34 +FUNC:_ZNSt12__sso_stringD1Ev@@GLIBCXX_3.4.34 +FUNC:_ZNSt12__sso_stringD2Ev@@GLIBCXX_3.4.34 FUNC:_ZNSt12bad_weak_ptrD0Ev@@GLIBCXX_3.4.15 FUNC:_ZNSt12bad_weak_ptrD1Ev@@GLIBCXX_3.4.15 FUNC:_ZNSt12bad_weak_ptrD2Ev@@GLIBCXX_3.4.15 @@ -3221,6 +3225,8 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC1EPcRKS FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC2EPcOS3_@@GLIBCXX_3.4.23 FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC2EPcRKS3_@@GLIBCXX_3.4.21 FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructEjc@@GLIBCXX_3.4.21 +FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructILb0EEEvPKcj@@GLIBCXX_3.4.34 +FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructILb1EEEvPKcj@@GLIBCXX_3.4.34 FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPKcS4_EEEEvT_SB_St20forward_iterator_tag@@GLIBCXX_3.4.21 FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPcS4_EEEEvT_SA_St20forward_iterator_tag@@GLIBCXX_3.4.21 FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag@@GLIBCXX_3.4.21 @@ -3374,6 +3380,8 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC1EPwRKS FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC2EPwOS3_@@GLIBCXX_3.4.23 FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC2EPwRKS3_@@GLIBCXX_3.4.21 FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructEjw@@GLIBCXX_3.4.21 +FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructILb0EEEvPKwj@@GLIBCXX_3.4.34 +FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructILb1EEEvPKwj@@GLIBCXX_3.4.34 FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPKwS4_EEEEvT_SB_St20forward_iterator_tag@@GLIBCXX_3.4.21 FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPwS4_EEEEvT_SA_St20forward_iterator_tag@@GLIBCXX_3.4.21 FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIPKwEEvT_S8_St20forward_iterator_tag@@GLIBCXX_3.4.21 @@ -3941,6 +3949,8 @@ FUNC:_ZNSt8__detail15_List_node_base11_M_transferEPS0_S1_@@GLIBCXX_3.4.15 FUNC:_ZNSt8__detail15_List_node_base4swapERS0_S1_@@GLIBCXX_3.4.15 FUNC:_ZNSt8__detail15_List_node_base7_M_hookEPS0_@@GLIBCXX_3.4.15 FUNC:_ZNSt8__detail15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.15 +FUNC:_ZNSt8__format25__locale_encoding_to_utf8ERKSt6localeSt17basic_string_viewIcSt11char_traitsIcEEPv@@GLIBCXX_3.4.34 +FUNC:_ZNSt8__format26__with_encoding_conversionERKSt6locale@@GLIBCXX_3.4.34 FUNC:_ZNSt8bad_castD0Ev@@GLIBCXX_3.4 FUNC:_ZNSt8bad_castD1Ev@@GLIBCXX_3.4 FUNC:_ZNSt8bad_castD2Ev@@GLIBCXX_3.4 @@ -4617,6 +4627,7 @@ OBJECT:0:GLIBCXX_3.4.30 OBJECT:0:GLIBCXX_3.4.31 OBJECT:0:GLIBCXX_3.4.32 OBJECT:0:GLIBCXX_3.4.33 +OBJECT:0:GLIBCXX_3.4.34 OBJECT:0:GLIBCXX_3.4.4 OBJECT:0:GLIBCXX_3.4.5 OBJECT:0:GLIBCXX_3.4.6 diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver index 2818ab3561f9..1c423ff2f572 100644 --- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver +++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver @@ -117,11 +117,11 @@ GLIBCXX_8.0 { _ZN9__gnu_cxx3__818stdio_sync_filebufI[cw]NSt3__811char_traitsI[cw]EEE[5-9]*; # debug mode - _ZN11__gnu_debug19_Safe_sequence_base12_M_get_mutexEv; - _ZN11__gnu_debug19_Safe_sequence_base13_M_detach_allEv; - _ZN11__gnu_debug19_Safe_sequence_base18_M_detach_singularEv; - _ZN11__gnu_debug19_Safe_sequence_base22_M_revalidate_singularEv; - _ZN11__gnu_debug19_Safe_sequence_base7_M_swapERS0_; + _ZNK11__gnu_debug19_Safe_sequence_base12_M_get_mutexEv; + _ZNK11__gnu_debug19_Safe_sequence_base13_M_detach_allEv; + _ZNK11__gnu_debug19_Safe_sequence_base18_M_detach_singularEv; + _ZNK11__gnu_debug19_Safe_sequence_base22_M_revalidate_singularEv; + _ZNK11__gnu_debug19_Safe_sequence_base7_M_swapERKS0_; _ZN11__gnu_debug19_Safe_iterator_base9_M_attach*; _ZN11__gnu_debug19_Safe_iterator_base16_M_attach_single*; @@ -136,11 +136,11 @@ GLIBCXX_8.0 { # __gnu_debug::_Safe_unordered_container_base # __gnu_debug::_Safe_local_iterator_base - _ZN11__gnu_debug30_Safe_unordered_container_base7_M_swapERS0_; - _ZN11__gnu_debug30_Safe_unordered_container_base13_M_detach_allEv; - _ZN11__gnu_debug25_Safe_local_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb; + _ZNK11__gnu_debug30_Safe_unordered_container_base7_M_swapERKS0_; + _ZNK11__gnu_debug30_Safe_unordered_container_base13_M_detach_allEv; + _ZN11__gnu_debug25_Safe_local_iterator_base9_M_attachEPKNS_30_Safe_unordered_container_baseEb; _ZN11__gnu_debug25_Safe_local_iterator_base9_M_detachEv; - _ZN11__gnu_debug25_Safe_local_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb; + _ZN11__gnu_debug25_Safe_local_iterator_base16_M_attach_singleEPKNS_30_Safe_unordered_container_baseEb; # parallel mode _ZN14__gnu_parallel9_Settings3getEv; diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index c36f1c347675..b5a89c31e0eb 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -2555,6 +2555,20 @@ GLIBCXX_3.4.35 { _ZNSt8__detail17__wait_until_implEPKvRNS_16__wait_args_baseERKNSt6chrono8durationI[lx]St5ratioIL[lx]1EL[lx]1000000000EEEE; _ZNSt8__detail11__wait_args22_M_load_proxy_wait_valEPKv; + # __gnu_debug::_Safe_iterator_base and _Safe_sequence_base const + _ZN11__gnu_debug19_Safe_iterator_base9_M_attachEPKNS_19_Safe_sequence_baseEb; + _ZN11__gnu_debug19_Safe_iterator_base16_M_attach_singleEPKNS_19_Safe_sequence_baseEb; + _ZNK11__gnu_debug19_Safe_sequence_base13_M_detach_allEv; + _ZNK11__gnu_debug19_Safe_sequence_base18_M_detach_singularEv; + _ZNK11__gnu_debug19_Safe_sequence_base12_M_get_mutexEv; + _ZNK11__gnu_debug19_Safe_sequence_base22_M_revalidate_singularEv; + _ZNK11__gnu_debug19_Safe_sequence_base7_M_swapERKS0_; + + # __gnu_debug::_Safe_local_iterator_base and _Safe_unordered_container_base const + _ZN11__gnu_debug25_Safe_local_iterator_base9_M_attachEPKNS_30_Safe_unordered_container_baseEb; + _ZN11__gnu_debug25_Safe_local_iterator_base16_M_attach_singleEPKNS_30_Safe_unordered_container_baseEb; + _ZNK11__gnu_debug30_Safe_unordered_container_base13_M_detach_allEv; + _ZNK11__gnu_debug30_Safe_unordered_container_base7_M_swapERKS0_; } GLIBCXX_3.4.34; # Symbols in the support library (libsupc++) have their own tag. @@ -2899,6 +2913,15 @@ CXXABI_1.3.16 { } CXXABI_1.3.15; #endif +CXXABI_1.3.17 { + # std::exception_ptr::_M_exception_ptr_cast + _ZNKSt15__exception_ptr13exception_ptr21_M_exception_ptr_castERKSt9type_info; +#ifdef __riscv +} CXXABI_1.3.16; +#else +} CXXABI_1.3.15; +#endif + # Symbols in the support library (libsupc++) supporting transactional memory. CXXABI_TM_1 { diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in b/libstdc++-v3/doc/doxygen/user.cfg.in index e926c6707f67..8969bb8b9489 100644 --- a/libstdc++-v3/doc/doxygen/user.cfg.in +++ b/libstdc++-v3/doc/doxygen/user.cfg.in @@ -869,6 +869,7 @@ INPUT = @srcdir@/doc/doxygen/doxygroups.cc \ include/functional \ include/future \ include/generator \ + include/inplace_vector \ include/iomanip \ include/ios \ include/iosfwd \ @@ -2350,8 +2351,8 @@ PREDEFINED = __cplusplus=202002L \ "_GLIBCXX_END_NAMESPACE_CONTAINER= " \ "_GLIBCXX_END_NAMESPACE_CXX11= " \ "_GLIBCXX_END_NAMESPACE_LDBL= " \ - "-D_GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(X)= " \ - "-D_GLIBCXX_END_INLINE_ABI_NAMESPACE(X)= " \ + "_GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(X)= " \ + "_GLIBCXX_END_INLINE_ABI_NAMESPACE(X)= " \ "_GLIBCXX_TEMPLATE_ARGS=... " \ "_GLIBCXX_DEPRECATED= " \ "_GLIBCXX_DEPRECATED_SUGGEST(E)= " \ @@ -2414,6 +2415,8 @@ PREDEFINED = __cplusplus=202002L \ _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE \ _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED \ _GLIBCXX_HAVE_BUILTIN_LAUNDER \ + "_GLIBCXX_USE_BUILTIN_TRAIT(X)=1" \ + _GLIBCXX_HAVE_ICONV=1 \ "_GLIBCXX_DOXYGEN_ONLY(X)=X " \ __exception_ptr=__unspecified__ \ diff --git a/libstdc++-v3/doc/html/manual/api.html b/libstdc++-v3/doc/html/manual/api.html index 4441d9cdbae0..f004ddc166d8 100644 --- a/libstdc++-v3/doc/html/manual/api.html +++ b/libstdc++-v3/doc/html/manual/api.html @@ -512,4 +512,7 @@

16

Deprecated the non-standard overload of std::fabs for std::complex arguments. +

+Made std::is_integral_v<__int128> true for strict +-std dialects.

\ No newline at end of file diff --git a/libstdc++-v3/doc/html/manual/appendix_contributing.html b/libstdc++-v3/doc/html/manual/appendix_contributing.html index 24d5a044dd8d..baac20a35849 100644 --- a/libstdc++-v3/doc/html/manual/appendix_contributing.html +++ b/libstdc++-v3/doc/html/manual/appendix_contributing.html @@ -60,13 +60,11 @@ this question would be appreciated.

Please contact - Paolo Carlini at - or Jonathan Wakely at if you are confused about the assignment or have general licensing questions. When requesting an assignment form from , please CC the libstdc++ - maintainers above so that progress can be monitored. + maintainer above so that progress can be monitored.

Getting Sources

Getting write access (look for "Write after approval") diff --git a/libstdc++-v3/doc/html/manual/appendix_porting.html b/libstdc++-v3/doc/html/manual/appendix_porting.html index e0f52dba6d2a..887fa50caa4c 100644 --- a/libstdc++-v3/doc/html/manual/appendix_porting.html +++ b/libstdc++-v3/doc/html/manual/appendix_porting.html @@ -497,4 +497,11 @@ See Configuring for the --with-libstdcxx-zoneinfo option that determines whether this file is used. +

  • + The header file + src/c++20/windows_zones-map.h + is generated by the Python script + scripts/gen_windows_zones_map.py + using the XML file https://github.com/unicode-org/cldr/blob/main/common/supplemental/windowsZones.xml + from the Unicode CLDR Project.

  • \ No newline at end of file diff --git a/libstdc++-v3/doc/html/manual/test.html b/libstdc++-v3/doc/html/manual/test.html index f2cf8c424370..497ee1ad36e5 100644 --- a/libstdc++-v3/doc/html/manual/test.html +++ b/libstdc++-v3/doc/html/manual/test.html @@ -389,10 +389,15 @@ We no longer require that, because most tests are uninteresting and contain no "original authorship", and so would not be protected by copyright anyway. - If you do want to add the FSF copyright notice and GPL licence text, + Adding the FSF copyright notice to new tests is incorrect unless you + (or your employer) have a copyright assignment on file with the FSF, + or if the test contains code copied from another test under FSF copyright. + In particular, new tests that contain original code are not copyright FSF + if contributed under the DCO terms. + If new tests do add the FSF copyright notice and GPL licence text, then the first copyright year should correspond to the date - the file was checked in to version control. If a test is copied from - an existing file it should retain the copyright years from the + the file was checked in to version control. If the test code is copied + from an existing file it should retain the copyright years from the original file.

    The DejaGnu instructions say to always return 0 @@ -415,18 +420,6 @@ __builtin_abort (to avoid using assert and being affected by NDEBUG). -

    - Prior to GCC 7.1, VERIFY was defined differently. - It usually expanded to the standard assert macro, but - allowed targets to define it to something different. In order to support - the alternative expansions of VERIFY, before any use - of the macro there needed to be a variable called test - in scope, which was usually defined like so (the attribute avoids - warnings about an unused variable): -

    -    bool test __attribute__((unused)) = true;
    -    

    - This is no longer needed, and should not be added to new tests.

    The testsuite uses the DejaGnu framework to compile and run the tests. Test cases are normal C++ files which contain special directives in diff --git a/libstdc++-v3/doc/xml/manual/appendix_contributing.xml b/libstdc++-v3/doc/xml/manual/appendix_contributing.xml index b9245453497b..b2bc1d7829e2 100644 --- a/libstdc++-v3/doc/xml/manual/appendix_contributing.xml +++ b/libstdc++-v3/doc/xml/manual/appendix_contributing.xml @@ -113,13 +113,11 @@ Please contact - Paolo Carlini at paolo.carlini@oracle.com - or Jonathan Wakely at jwakely+assign@redhat.com if you are confused about the assignment or have general licensing questions. When requesting an assignment form from assign@gnu.org, please CC the libstdc++ - maintainers above so that progress can be monitored. + maintainer above so that progress can be monitored. diff --git a/libstdc++-v3/doc/xml/manual/build_hacking.xml b/libstdc++-v3/doc/xml/manual/build_hacking.xml index 077c0632a791..20de49f553c0 100644 --- a/libstdc++-v3/doc/xml/manual/build_hacking.xml +++ b/libstdc++-v3/doc/xml/manual/build_hacking.xml @@ -742,6 +742,17 @@ baseline file. this file is used. + + + The header file + src/c++20/windows_zones-map.h + is generated by the Python script + scripts/gen_windows_zones_map.py + using the XML file + from the Unicode CLDR Project. + + diff --git a/libstdc++-v3/doc/xml/manual/evolution.xml b/libstdc++-v3/doc/xml/manual/evolution.xml index 73b9f17f3a38..911db8a7538b 100644 --- a/libstdc++-v3/doc/xml/manual/evolution.xml +++ b/libstdc++-v3/doc/xml/manual/evolution.xml @@ -1157,6 +1157,11 @@ Nested result_type and argument_type removed from Deprecated the non-standard overload of std::fabs for std::complex arguments. + + +Made std::is_integral_v<__int128> true for strict +-std dialects. + diff --git a/libstdc++-v3/doc/xml/manual/test.xml b/libstdc++-v3/doc/xml/manual/test.xml index 8e2729eedfdf..df49f56b0d03 100644 --- a/libstdc++-v3/doc/xml/manual/test.xml +++ b/libstdc++-v3/doc/xml/manual/test.xml @@ -650,10 +650,16 @@ cat 27_io/objects/char/3_xin.in | a.out We no longer require that, because most tests are uninteresting and contain no "original authorship", and so would not be protected by copyright anyway. - If you do want to add the FSF copyright notice and GPL licence text, + Adding the FSF copyright notice to new tests is incorrect unless you + (or your employer) have a copyright assignment on file with the FSF, + or if the test contains code copied from another test under FSF copyright. + In particular, new tests that contain original code are not copyright FSF + if contributed under the DCO terms. + If new tests do add the FSF copyright notice and GPL licence text, then the first copyright year should correspond to the date - the file was checked in to version control. If a test is copied from - an existing file it should retain the copyright years from the + the file was checked in to version control. If the test code is copied + from an existing file it should retain the copyright years from the original file. @@ -684,20 +690,6 @@ cat 27_io/objects/char/3_xin.in | a.out NDEBUG). - - Prior to GCC 7.1, VERIFY was defined differently. - It usually expanded to the standard assert macro, but - allowed targets to define it to something different. In order to support - the alternative expansions of VERIFY, before any use - of the macro there needed to be a variable called test - in scope, which was usually defined like so (the attribute avoids - warnings about an unused variable): - - bool test __attribute__((unused)) = true; - - This is no longer needed, and should not be added to new tests. - - The testsuite uses the DejaGnu framework to compile and run the tests. Test cases are normal C++ files which contain special directives in diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index cc402f0648f4..6f248fe48cb2 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -77,6 +77,7 @@ std_headers = \ ${std_srcdir}/forward_list \ ${std_srcdir}/fstream \ ${std_srcdir}/future \ + ${std_srcdir}/inplace_vector \ ${std_srcdir}/iomanip \ ${std_srcdir}/ios \ ${std_srcdir}/iosfwd \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 0ef8564f2385..014466fc40b8 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -433,6 +433,7 @@ std_freestanding = \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/forward_list \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/fstream \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/future \ +@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/inplace_vector \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/iomanip \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/ios \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/iosfwd \ diff --git a/libstdc++-v3/include/bits/atomic_timed_wait.h b/libstdc++-v3/include/bits/atomic_timed_wait.h index bd2e6bf61ecf..30f7ff616840 100644 --- a/libstdc++-v3/include/bits/atomic_timed_wait.h +++ b/libstdc++-v3/include/bits/atomic_timed_wait.h @@ -156,6 +156,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const chrono::time_point<_Clock, _Dur>& __atime, bool __bare_wait = false) noexcept { +#ifndef _GLIBCXX_HAVE_PLATFORM_TIMED_WAIT + __glibcxx_assert(false); // This function can't be used for proxy wait. +#endif __detail::__wait_args __args{ __addr, __old, __order, __bare_wait }; auto __res = __detail::__wait_until(__addr, __args, __atime); return !__res._M_timeout; // C++26 will also return last observed __val @@ -205,6 +208,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const chrono::duration<_Rep, _Period>& __rtime, bool __bare_wait = false) noexcept { +#ifndef _GLIBCXX_HAVE_PLATFORM_TIMED_WAIT + __glibcxx_assert(false); // This function can't be used for proxy wait. +#endif __detail::__wait_args __args{ __addr, __old, __order, __bare_wait }; auto __res = __detail::__wait_for(__addr, __args, __rtime); return !__res._M_timeout; // C++26 will also return last observed __val diff --git a/libstdc++-v3/include/bits/atomic_wait.h b/libstdc++-v3/include/bits/atomic_wait.h index 815726c16ccb..95151479c120 100644 --- a/libstdc++-v3/include/bits/atomic_wait.h +++ b/libstdc++-v3/include/bits/atomic_wait.h @@ -249,12 +249,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // C++26 will return __val } + // Wait on __addr while *__addr == __old is true. inline void __atomic_wait_address_v(const __detail::__platform_wait_t* __addr, __detail::__platform_wait_t __old, - int __order) + int __order, bool __bare_wait = false) { - __detail::__wait_args __args{ __addr, __old, __order }; +#ifndef _GLIBCXX_HAVE_PLATFORM_WAIT + __glibcxx_assert(false); // This function can't be used for proxy wait. +#endif + __detail::__wait_args __args{ __addr, __old, __order, __bare_wait }; // C++26 will not ignore the return value here __detail::__wait_impl(__addr, __args); } diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index 676f5eecbbb6..eec3a4a499dd 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -273,6 +273,12 @@ #define _GLIBCXX_NOEXCEPT_QUAL #endif +#if __cpp_auto_cast +# define _GLIBCXX_AUTO_CAST(X) auto(X) +#else +# define _GLIBCXX_AUTO_CAST(X) ::std::__decay_t(X) +#endif + // Macro for extern template, ie controlling template linkage via use // of extern keyword on template declaration. As documented in the g++ // manual, it inhibits all implicit instantiations and is used diff --git a/libstdc++-v3/include/bits/chrono.h b/libstdc++-v3/include/bits/chrono.h index fad216203d2f..8de8e756c714 100644 --- a/libstdc++-v3/include/bits/chrono.h +++ b/libstdc++-v3/include/bits/chrono.h @@ -1244,6 +1244,7 @@ _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2) now() noexcept; // Map to C API + [[__gnu__::__always_inline__]] static std::time_t to_time_t(const time_point& __t) noexcept { @@ -1251,6 +1252,7 @@ _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2) (__t.time_since_epoch()).count()); } + [[__gnu__::__always_inline__]] static time_point from_time_t(std::time_t __t) noexcept { diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h index 239f9c780094..809d795cbf2b 100644 --- a/libstdc++-v3/include/bits/chrono_io.h +++ b/libstdc++-v3/include/bits/chrono_io.h @@ -187,11 +187,6 @@ namespace __detail /// @cond undocumented namespace __format { - [[noreturn,__gnu__::__always_inline__]] - inline void - __no_timezone_available() - { __throw_format_error("format error: no timezone available for %Z or %z"); } - [[noreturn,__gnu__::__always_inline__]] inline void __not_valid_for_duration() @@ -204,9 +199,80 @@ namespace __format { __throw_format_error("format error: chrono-format-spec not valid for " "argument type"); } + // Represents the information provided by a chrono type. + // e.g. month_weekday has month and weekday but no year or time of day, + // hh_mm_ss has time of day but no date, sys_time is time_point+timezone. + enum class _ChronoParts : unsigned short { + _None = 0, _TotalSeconds = 1u, _Subseconds = 1u << 2, + + // time since epoch + _EpochUnits = 1u << 3, _UnitSuffix = 1u << 4, + _EpochSeconds = _EpochUnits | _TotalSeconds, + + // local (wall) time + _LocalDays = 1u << 5, + _LocalSeconds = _LocalDays | _TotalSeconds, + + _Year = 1u << 6, _Month = 1u << 7, _Day = 1u << 8, + _Weekday = 1u << 9, _WeekdayIndex = 1u << 10, _DayOfYear = 1u << 11, + _IndexedWeekday = _Weekday | _WeekdayIndex, + _YearMonthDay = _Year | _Month | _Day, + _Date = _LocalDays | _YearMonthDay | _IndexedWeekday | _DayOfYear, + + _HoursMinutesSeconds = 1u << 12, + _TimeOfDay = _HoursMinutesSeconds | _Subseconds, + _Time = _TimeOfDay | _TotalSeconds, + _EpochTime = _Time | _EpochUnits | _UnitSuffix, + _DateTime = _Date | _Time, + + _ZoneAbbrev = 1u << 13, _ZoneOffset = 1u << 14, + _TimeZone = _ZoneAbbrev | _ZoneOffset, + _ZonedDateTime = _DateTime | _TimeZone, + }; + + [[__gnu__::__always_inline__]] + constexpr _ChronoParts + operator&(_ChronoParts __x, _ChronoParts __y) noexcept + { return static_cast<_ChronoParts>((unsigned)__x & (unsigned)__y); } + + [[__gnu__::__always_inline__]] + constexpr _ChronoParts& + operator&=(_ChronoParts& __x, _ChronoParts __y) noexcept + { return __x = __x & __y; } + + [[__gnu__::__always_inline__]] + constexpr _ChronoParts + operator|(_ChronoParts __x, _ChronoParts __y) noexcept + { return static_cast<_ChronoParts>((unsigned short)__x | (unsigned short)__y); } + + [[__gnu__::__always_inline__]] + constexpr _ChronoParts& + operator|=(_ChronoParts& __x, _ChronoParts __y) noexcept + { return __x = __x | __y; } + + // returns copy of x with all bits from y unset. + [[__gnu__::__always_inline__]] + constexpr _ChronoParts + operator-(_ChronoParts __x, _ChronoParts __y) noexcept + { return static_cast<_ChronoParts>((unsigned short)__x & ~(unsigned short)__y); } + + // unsets all bits of x that are set in y + [[__gnu__::__always_inline__]] + constexpr _ChronoParts& + operator-=(_ChronoParts& __x, _ChronoParts __y) noexcept + { return __x = __x - __y; } + + [[__gnu__::__always_inline__]] + constexpr bool + operator==(_ChronoParts __x, decltype(nullptr)) noexcept + { return (unsigned short)__x == 0; } + template struct _ChronoSpec : _Spec<_CharT> { + // When _M_prec_kind is _WP_none, the _M_prec contains the default + // value of fraction digits to be used for time '%S'. + // Placed in tail-padding of __format::_Spec. // This indicates that a locale-dependent conversion specifier such as // %a is used in the chrono-specs. This is not the same as the @@ -214,29 +280,272 @@ namespace __format // in the format-spec, e.g. "{:L%a}" is localized and locale-specific, // but "{:L}" is only localized and "{:%a}" is only locale-specific. unsigned _M_locale_specific : 1; - + // Indicates if parts that are checked for ok come directly from the + // input, instead of being computed. + unsigned _M_needs_ok_check : 1; + // Indicates that duration should be treated as floating point. + unsigned _M_floating_point_rep : 1; + // Indicate that duration uses user-defined representation. + unsigned _M_custom_rep : 1; + unsigned _M_unused : 4; + + // Chrono parts required by format specs + _ChronoParts _M_needed; basic_string_view<_CharT> _M_chrono_specs; + + [[__gnu__::__always_inline__]] + constexpr bool + _M_needs(_ChronoParts __parts) const + { return (_M_needed & __parts) != 0; } }; - // Represents the information provided by a chrono type. - // e.g. month_weekday has month and weekday but no year or time of day, - // hh_mm_ss has time of day but no date, sys_time is time_point+timezone. - enum _ChronoParts { - _Year = 1, _Month = 2, _Day = 4, _Weekday = 8, _TimeOfDay = 16, - _TimeZone = 32, - _Date = _Year | _Month | _Day | _Weekday, - _DateTime = _Date | _TimeOfDay, - _ZonedDateTime = _DateTime | _TimeZone, - _Duration = 128 // special case + template + struct _ChronoFormats + { + using _String_view = basic_string_view<_CharT>; + + static consteval + _String_view + _S_ftz() noexcept + { return _GLIBCXX_WIDEN("%F %T %Z"); } + + static consteval + _String_view + _S_ft() noexcept + { return _S_ftz().substr(0, 5); } + + static consteval + _String_view + _S_f() noexcept + { return _S_ftz().substr(0, 2); } + + static consteval + _String_view + _S_t() noexcept + { return _S_ftz().substr(3, 2); } + + static consteval + _String_view + _S_ymd() noexcept + { return _GLIBCXX_WIDEN("%Y/%b/%d"); } + + static consteval + _String_view + _S_ym() noexcept + { return _S_ymd().substr(0, 5); } + + static consteval + _String_view + _S_md() noexcept + { return _S_ymd().substr(3); } + + static consteval + _String_view + _S_y() noexcept + { return _S_ymd().substr(0, 2); } + + static consteval + _String_view + _S_m() noexcept + { return _S_ymd().substr(3, 2); } + + static consteval + _String_view + _S_d() noexcept + { return _S_ymd().substr(6, 2); } + + static consteval + _String_view + _S_ymwi() noexcept + // %\0 is extension for handling weekday index + { return _String_view(_GLIBCXX_WIDEN("%Y/%b/%a[%\0]"), 12); } + + static consteval + _String_view + _S_mwi() noexcept + { return _S_ymwi().substr(3); } + + static consteval + _String_view + _S_wi() noexcept + { return _S_ymwi().substr(6); } + + static consteval + _String_view + _S_w() noexcept + { return _S_ymwi().substr(6, 2); } + + static consteval + _String_view + _S_ymwl() noexcept + { return _GLIBCXX_WIDEN("%Y/%b/%a[last]"); } + + static consteval + _String_view + _S_mwl() noexcept + { return _S_ymwl().substr(3); } + + static consteval + _String_view + _S_wl() noexcept + { return _S_ymwl().substr(6); } + + static consteval + _String_view + _S_yml() noexcept + { return _GLIBCXX_WIDEN("%Y/%b/last"); } + + static consteval + _String_view + _S_ml() noexcept + { return _S_yml().substr(3); } }; - constexpr _ChronoParts - operator|(_ChronoParts __x, _ChronoParts __y) noexcept - { return static_cast<_ChronoParts>((int)__x | (int)__y); } + template + struct _ChronoData + { + static constexpr unsigned _S_max_prec = 18; + using _Attoseconds = chrono::duration<__UINT_LEAST64_TYPE__, atto>; + + using _FormatContext + = basic_format_context<_Sink_iter<_CharT>, _CharT>; + using _FormatArgs = basic_format_args<_FormatContext>; + static inline auto _S_args = std::make_format_args<_FormatContext>(); + + _ChronoData() = default; + _ChronoData(_ChronoData&&) = delete; + + // time since epoch + chrono::seconds _M_eseconds; + // n.b. due offset being seconds or coarser, local and epoch subseconds + // has the same value + _Attoseconds _M_subseconds; + // _M_ereps.get(0) stores duration units + // _M_ereps.get(1) stores subseconds units + // _M_ereps.get(2) stores precision + _FormatArgs _M_ereps = _S_args; + basic_string_view<_CharT> _M_unit_suffix; + + // local (wall) time + chrono::local_seconds _M_lseconds; + chrono::local_days _M_ldays; + + chrono::year _M_year; + chrono::month _M_month; + chrono::day _M_day; + chrono::weekday _M_weekday; + unsigned char _M_weekday_index; + chrono::days _M_day_of_year; + + bool _M_is_neg; + chrono::hours _M_hours; + chrono::minutes _M_minutes; + chrono::seconds _M_seconds; + + chrono::seconds _M_zone_offset; + basic_string_view<_CharT> _M_zone_abbrev; + const char* _M_zone_cstr = ""; + + template + [[__gnu__::__always_inline__]] + _ChronoParts + _M_fill_year_month(const _YearMonth& __ym, _ChronoParts __parts) + { + _M_year = __ym.year(); + __parts -= _ChronoParts::_Year; + _M_month = __ym.month(); + __parts -= _ChronoParts::_Month; + return __parts; + } - constexpr _ChronoParts& - operator|=(_ChronoParts& __x, _ChronoParts __y) noexcept - { return __x = __x | __y; } + [[__gnu__::__always_inline__]] + _ChronoParts + _M_fill_day(chrono::day __d, _ChronoParts __parts) + { + _M_day = __d; + __parts -= _ChronoParts::_Day; + _M_weekday_index = ((unsigned)__d + 6u) % 7u; + __parts -= _ChronoParts::_WeekdayIndex; + return __parts; + } + + [[__gnu__::__always_inline__]] + _ChronoParts + _M_fill_weekday(chrono::weekday_indexed __wi, _ChronoParts __parts) + { + _M_weekday = __wi.weekday(); + __parts -= _ChronoParts::_Weekday; + _M_weekday_index = __wi.index(); + __parts -= _ChronoParts::_WeekdayIndex; + return __parts; + } + + [[__gnu__::__always_inline__]] + _ChronoParts + _M_fill_aux(chrono::local_days __ld, _ChronoParts __parts) + { + using namespace chrono; + if ((__parts & _ChronoParts::_Weekday) != 0) + _M_weekday = weekday(__ld); + __parts -= _ChronoParts::_Weekday; + if ((__parts & _ChronoParts::_DayOfYear) != 0) + // See "Calculating Ordinal Dates" at + // https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes + _M_day_of_year = __ld - local_days(_M_year/January/0); + __parts -= _ChronoParts::_DayOfYear; + return __parts; + } + + [[__gnu__::__always_inline__]] + _ChronoParts + _M_fill_ldays(chrono::local_days __ld, _ChronoParts __parts) + { + _M_ldays = __ld; + __parts -= _ChronoParts::_LocalDays; + return _M_fill_aux(__ld, __parts); + } + + void + _M_fill_time(chrono::seconds __d) + { + chrono::hh_mm_ss __hms(__d); + _M_hours = __hms.hours(); + _M_minutes = __hms.minutes(); + _M_seconds = __hms.seconds(); + } + + void + _M_fill_date_time(chrono::local_seconds __ls, _ChronoParts __parts) + { + _M_ldays = chrono::floor(__ls); + __parts -= _ChronoParts::_LocalDays; + if ((__parts & _ChronoParts::_HoursMinutesSeconds) != 0) + _M_fill_time(_M_lseconds - _M_ldays); + + if ((__parts & _ChronoParts::_Date) != 0) + { + const chrono::year_month_day __ymd(_M_ldays); + _M_fill_year_month(__ymd, __parts); + _M_fill_day(__ymd.day(), __parts); + _M_fill_aux(_M_ldays, __parts); + } + } + + void + _M_fill_zone(const char* __abbrev, const wchar_t* __wabbrev) + { + if constexpr (is_same_v<_CharT, char>) + _M_zone_abbrev = __abbrev; + else + _M_zone_abbrev = __wabbrev; + _M_zone_cstr = __abbrev; + } + + [[__gnu__::__always_inline__]] + void + _M_fill_utc_zone() + { _M_fill_zone("UTC", L"UTC"); } + }; // TODO rename this to chrono::__formatter? or chrono::__detail::__formatter? template @@ -245,16 +554,32 @@ namespace __format using __string_view = basic_string_view<_CharT>; using __string = basic_string<_CharT>; + __formatter_chrono() = default; + + constexpr explicit + __formatter_chrono(_ChronoSpec<_CharT> __spec) noexcept + : _M_spec(__spec) + { } + template constexpr typename _ParseContext::iterator - _M_parse(_ParseContext& __pc, _ChronoParts __parts) + _M_parse(_ParseContext& __pc, _ChronoParts __parts, + const _ChronoSpec<_CharT>& __def) { auto __first = __pc.begin(); auto __last = __pc.end(); - _ChronoSpec<_CharT> __spec{}; - - auto __finalize = [this, &__spec] { + _ChronoSpec<_CharT> __spec = __def; + + auto __finalize = [this, &__spec, &__def] { + using enum _ChronoParts; + _ChronoParts __checked + = __spec._M_debug ? _YearMonthDay|_IndexedWeekday + : _Month|_Weekday; + // n.b. for calendar types __def._M_needed contains only parts + // copied from the input, remaining ones are computed, and thus ok + __spec._M_needs_ok_check + = __spec._M_needs(__def._M_needed & __checked); _M_spec = __spec; }; @@ -278,13 +603,21 @@ namespace __format if (__finished()) return __first; - if (__parts & _ChronoParts::_Duration) + if (*__first == '.') { - __first = __spec._M_parse_precision(__first, __last, __pc); - if (__finished()) - return __first; + if ((__parts & _ChronoParts::_EpochUnits) == 0 + || !__spec._M_floating_point_rep) + __throw_format_error("format error: invalid precision for duration"); + + // Precision is allowed, but value is ignored. + __first = _Spec<_CharT>()._M_parse_precision(__first, __last, __pc); + // Still inditate that there was user supplied precision. + __spec._M_prec_kind = _WP_value; + if (__finished()) + return __first; } + __spec._M_localized = false; __first = __spec._M_parse_locale(__first, __last); if (__finished()) return __first; @@ -306,6 +639,10 @@ namespace __format // Parse chrono-specs in [first,last), checking each conversion-spec // against __parts (so fail for %Y if no year in parts). // Save range in __spec._M_chrono_specs. + __spec._M_debug = false; + __spec._M_locale_specific = false; + __spec._M_needed = _ChronoParts::_None; + __spec._M_chrono_specs = __string_view(); const auto __chrono_specs = __first++; // Skip leading '%' if (*__chrono_specs != '%') @@ -314,17 +651,18 @@ namespace __format _CharT __mod{}; bool __conv = true; - int __needed = 0; - bool __locale_specific = false; - while (__first != __last) { enum _Mods { _Mod_none, _Mod_E, _Mod_O, _Mod_E_O }; _Mods __allowed_mods = _Mod_none; + _ChronoParts __needed = _ChronoParts::_None; + bool __locale_specific = false; + _CharT __c = *__first++; switch (__c) { + using enum _ChronoParts; case 'a': case 'A': __needed = _Weekday; @@ -337,7 +675,7 @@ namespace __format __locale_specific = true; break; case 'c': - __needed = _DateTime; + __needed = _Date|_HoursMinutesSeconds; __allowed_mods = _Mod_E; __locale_specific = true; break; @@ -352,27 +690,30 @@ namespace __format break; case 'D': case 'F': - __needed = _Date; + __needed = _YearMonthDay; break; case 'g': case 'G': - __needed = _Date; + __needed = _LocalDays|_Weekday; break; case 'H': case 'I': - __needed = _TimeOfDay; + __needed = _HoursMinutesSeconds; __allowed_mods = _Mod_O; break; case 'j': - if (!(__parts & _Duration)) - __needed = _Date; + __needed = __parts & _DayOfYear; + // If we do not know day-of-year then we must have a duration, + // which is to be formatted as decimal number of days. + if (__needed == _None) + __needed = _HoursMinutesSeconds; break; case 'm': __needed = _Month; __allowed_mods = _Mod_O; break; case 'M': - __needed = _TimeOfDay; + __needed = _HoursMinutesSeconds; __allowed_mods = _Mod_O; break; case 'p': @@ -380,12 +721,16 @@ namespace __format __locale_specific = true; [[fallthrough]]; case 'R': + __needed = _HoursMinutesSeconds; + break; case 'T': __needed = _TimeOfDay; break; case 'q': + __needed = _UnitSuffix; + break; case 'Q': - __needed = _Duration; + __needed = _EpochUnits; break; case 'S': __needed = _TimeOfDay; @@ -399,7 +744,7 @@ namespace __format case 'U': case 'V': case 'W': - __needed = _Date; + __needed = _LocalDays|_Year|_DayOfYear|_Weekday; __allowed_mods = _Mod_O; break; case 'x': @@ -408,7 +753,7 @@ namespace __format __allowed_mods = _Mod_E; break; case 'X': - __needed = _TimeOfDay; + __needed = _HoursMinutesSeconds; __locale_specific = true; __allowed_mods = _Mod_E; break; @@ -421,11 +766,11 @@ namespace __format __allowed_mods = _Mod_E; break; case 'z': - __needed = _TimeZone; + __needed = _ZoneOffset; __allowed_mods = _Mod_E_O; break; case 'Z': - __needed = _TimeZone; + __needed = _ZoneAbbrev; break; case 'n': case 't': @@ -453,10 +798,16 @@ namespace __format __locale_specific = true; __mod = _CharT(); + // localized formats do not include subseconds + if (__locale_specific) + __needed -= _ChronoParts::_Subseconds; + if ((__parts & __needed) != __needed) __throw_format_error("chrono format error: format argument " "does not contain the information " "required by the chrono-specs"); + __spec._M_needed |= __needed; + __spec._M_locale_specific |= __locale_specific; // Scan for next '%', ignoring literal-chars before it. size_t __pos = __string_view(__first, __last - __first).find('%'); @@ -479,27 +830,18 @@ namespace __format __throw_format_error("chrono format error: unescaped '%' in " "chrono-specs"); - _M_spec = __spec; - _M_spec._M_chrono_specs - = __string_view(__chrono_specs, __first - __chrono_specs); - _M_spec._M_locale_specific = __locale_specific; + __spec._M_chrono_specs + = __string_view(__chrono_specs, __first - __chrono_specs); + __finalize(); return __first; } - // TODO this function template is instantiated for every different _Tp. - // Consider creating a polymorphic interface for calendar types so - // that we instantiate fewer different specializations. Similar to - // _Sink_iter for std::format. Replace each _S_year, _S_day etc. with - // member functions of that type. - template + // pre: !_M_spec._M_chrono_specs.empty() + template typename _FormatContext::iterator - _M_format(const _Tp& __t, _FormatContext& __fc, - bool __is_neg = false) const + _M_format(const _ChronoData<_CharT>& __t, _FormatContext& __fc) const { - if (_M_spec._M_chrono_specs.empty()) - return _M_format_to_ostream(__t, __fc, __is_neg); - #if defined _GLIBCXX_USE_NL_LANGINFO_L && __CHAR_BIT__ == 8 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3565. Handling of encodings in localized formatting @@ -514,36 +856,208 @@ namespace __format // in the locale's encoding to UTF-8. locale __loc = __fc.locale(); if (__loc != locale::classic()) - __fc._M_loc = __with_encoding_conversion(__loc); + __fc._M_loc = __with_encoding_conversion(__loc); } #endif - // formatter passes the correct value of __is_neg - // for durations but for hh_mm_ss we decide it here. - if constexpr (__is_specialization_of<_Tp, chrono::hh_mm_ss>) - __is_neg = __t.is_negative(); const size_t __padwidth = _M_spec._M_get_width(__fc); if (__padwidth == 0) - return _M_format_to(__t, __fc.out(), __fc, __is_neg); + return _M_format_to(__t, __fc.out(), __fc); using _Out = typename _FormatContext::iterator; _Padding_sink<_Out, _CharT> __sink(__fc.out(), __padwidth); - _M_format_to(__t, __sink.out(), __fc, __is_neg); + _M_format_to(__t, __sink.out(), __fc); return __sink._M_finish(_M_spec._M_align, _M_spec._M_fill); } - template - _Out - _M_format_to(const _Tp& __t, _Out __out, _FormatContext& __fc, - bool __is_neg) const + + _ChronoSpec<_CharT> _M_spec; + + protected: + static constexpr const _CharT* _S_chars + = _GLIBCXX_WIDEN("0123456789.Lf:/ +-{}"); + static constexpr _CharT _S_dot = _S_chars[10]; + static constexpr _CharT _S_colon = _S_chars[13]; + static constexpr _CharT _S_slash = _S_chars[14]; + static constexpr _CharT _S_space = _S_chars[15]; + static constexpr const _CharT* _S_fp_fmt = _S_chars + 11; + static constexpr const _CharT* _S_plus_minus = _S_chars + 16; + static constexpr const _CharT* _S_minus_empty_spec = _S_chars + 17; + static constexpr const _CharT* _S_empty_spec = _S_chars + 18; + + [[__gnu__::__always_inline__]] + static _Runtime_format_string<_CharT> + _S_empty_fs() + { return _Runtime_format_string<_CharT>(_S_empty_spec); } + + static constexpr const _CharT* _S_weekdays[] + { + _GLIBCXX_WIDEN("Sunday"), + _GLIBCXX_WIDEN("Monday"), + _GLIBCXX_WIDEN("Tuesday"), + _GLIBCXX_WIDEN("Wednesday"), + _GLIBCXX_WIDEN("Thursday"), + _GLIBCXX_WIDEN("Friday"), + _GLIBCXX_WIDEN("Saturday"), + }; + + static constexpr const _CharT* _S_months[] + { + _GLIBCXX_WIDEN("January"), + _GLIBCXX_WIDEN("February"), + _GLIBCXX_WIDEN("March"), + _GLIBCXX_WIDEN("April"), + _GLIBCXX_WIDEN("May"), + _GLIBCXX_WIDEN("June"), + _GLIBCXX_WIDEN("July"), + _GLIBCXX_WIDEN("August"), + _GLIBCXX_WIDEN("September"), + _GLIBCXX_WIDEN("October"), + _GLIBCXX_WIDEN("November"), + _GLIBCXX_WIDEN("December"), + }; + + private: + template + _OutIter + _M_write(_OutIter __out, const locale& __loc, __string_view __s) const + { +#if defined _GLIBCXX_USE_NL_LANGINFO_L && __CHAR_BIT__ == 8 + __sso_string __buf; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3565. Handling of encodings in localized formatting + // of chrono types is underspecified + if constexpr (is_same_v<_CharT, char>) + if constexpr (__unicode::__literal_encoding_is_utf8()) + if (_M_spec._M_localized && _M_spec._M_locale_specific + && __loc != locale::classic()) + { + extern string_view + __locale_encoding_to_utf8(const locale&, string_view, void*); + + __s = __locale_encoding_to_utf8(__loc, __s, &__buf); + } +#endif + return __format::__write(std::move(__out), __s); + } + + [[__gnu__::__always_inline__]] + static bool + _S_localized_spec(_CharT __conv, _CharT __mod) + { + switch (__conv) + { + case 'a': + case 'A': + case 'b': + case 'B': + case 'c': + case 'h': + case 'p': + case 'r': + case 'x': + case 'X': + return true; + case 'z': + return false; + default: + return (bool)__mod; + }; + } + + // Use the formatting locale's std::time_put facet to produce + // a locale-specific representation. + template + _Iter + _M_locale_fmt(_Iter __out, const locale& __loc, const struct tm& __tm, + char __fmt, char __mod) const + { + basic_ostringstream<_CharT> __os; + __os.imbue(__loc); + const auto& __tp = use_facet>(__loc); + __tp.put(__os, __os, _S_space, &__tm, __fmt, __mod); + if (__os) + __out = _M_write(std::move(__out), __loc, __os.view()); + return __out; + } + + __string_view + _M_check_ok(const _ChronoData<_CharT>& __t, _CharT& __conv) const + { + if (!_M_spec._M_debug) + { + switch (__conv) + { + case 'a': + case 'A': + if (!__t._M_weekday.ok()) [[unlikely]] + __throw_format_error("format error: invalid weekday"); + break; + case 'b': + case 'h': + case 'B': + if (!__t._M_month.ok()) [[unlikely]] + __throw_format_error("format error: invalid month"); + break; + default: + break; + } + return __string_view(); + } + + switch (__conv) + { + // %\0 is extension for handling weekday index + case '\0': + if (__t._M_weekday_index < 1 || __t._M_weekday_index > 5) [[unlikely]] + return _GLIBCXX_WIDEN("index"); + break; + case 'a': + case 'A': + if (!__t._M_weekday.ok()) [[unlikely]] + { + __conv = 'w'; // print as decimal number + return _GLIBCXX_WIDEN("weekday"); + } + break; + case 'b': + case 'h': + case 'B': + if (!__t._M_month.ok()) [[unlikely]] + { + __conv = 'm'; // print as decimal number + return _GLIBCXX_WIDEN("month"); + } + break; + case 'd': + case 'e': + if (!__t._M_day.ok()) [[unlikely]] + return _GLIBCXX_WIDEN("day"); + break; + case 'F': + if (!(__t._M_year/__t._M_month/__t._M_day).ok()) [[unlikely]] + return _GLIBCXX_WIDEN("date"); + break; + case 'Y': + if (!__t._M_year.ok()) [[unlikely]] + return _GLIBCXX_WIDEN("year"); + break; + default: + break; + } + return __string_view(); + } + + template + _OutIter + _M_format_to(const _ChronoData<_CharT>& __t, _OutIter __out, + _FormatContext& __fc) const { auto __first = _M_spec._M_chrono_specs.begin(); const auto __last = _M_spec._M_chrono_specs.end(); - auto __print_sign = [&__is_neg, &__out] { - if constexpr (chrono::__is_duration_v<_Tp> - || __is_specialization_of<_Tp, chrono::hh_mm_ss>) - if (__is_neg) + auto __print_sign = [__is_neg = __t._M_is_neg, &__out] () mutable { + if (__is_neg) { *__out++ = _S_plus_minus[1]; __is_neg = false; @@ -551,6 +1065,36 @@ namespace __format return std::move(__out); }; + struct tm __tm{}; + bool __use_locale_fmt = false; + if (_M_spec._M_localized && _M_spec._M_locale_specific) + if (__fc.locale() != locale::classic()) + { + __use_locale_fmt = true; + + __tm.tm_year = (int)__t._M_year - 1900; + __tm.tm_yday = __t._M_day_of_year.count(); + __tm.tm_mon = (unsigned)__t._M_month - 1; + __tm.tm_mday = (unsigned)__t._M_day; + __tm.tm_wday = __t._M_weekday.c_encoding(); + __tm.tm_hour = __t._M_hours.count(); + __tm.tm_min = __t._M_minutes.count(); + __tm.tm_sec = __t._M_seconds.count(); + + // Some locales use %Z in their %c format but we don't want strftime + // to use the system's local time zone (from /etc/localtime or $TZ) + // as the output for %Z. Setting tm_isdst to -1 says there is no + // time zone info available for the time in __tm. + __tm.tm_isdst = -1; + +#ifdef _GLIBCXX_USE_STRUCT_TM_TM_ZONE + // POSIX.1-2024 adds tm.tm_zone which will be used for %Z. + // BSD has had tm_zone since 1987 but as char* so cast away const. + if (__t._M_zone_cstr) + __tm.tm_zone = const_cast(__t._M_zone_cstr); +#endif + } + // Characters to output for "%n", "%t" and "%%" specifiers. constexpr const _CharT* __literals = _GLIBCXX_WIDEN("\n\t%"); @@ -560,100 +1104,101 @@ namespace __format do { _CharT __c = *__first++; - switch (__c) + __string_view __invalid; + if (_M_spec._M_needs_ok_check) + __invalid = _M_check_ok(__t, __c); + + if (__invalid.empty() &&__use_locale_fmt + && _S_localized_spec(__c, __mod)) [[unlikely]] + __out = _M_locale_fmt(std::move(__out), __fc.locale(), + __tm, __c, __mod); + else switch (__c) { + // %\0 is extension for handling weekday index + case '\0': + __out = _M_wi(__t._M_weekday_index, std::move(__out)); + break; case 'a': case 'A': - __out = _M_a_A(__t, std::move(__out), __fc, __c == 'A'); + __out = _M_a_A(__t._M_weekday, std::move(__out), __c == 'A'); break; case 'b': case 'h': case 'B': - __out = _M_b_B(__t, std::move(__out), __fc, __c == 'B'); + __out = _M_b_B(__t._M_month, std::move(__out), __c == 'B'); break; case 'c': - __out = _M_c(__t, std::move(__out), __fc, __mod == 'E'); + __out = _M_c(__t, std::move(__out)); break; case 'C': case 'y': case 'Y': - __out = _M_C_y_Y(__t, std::move(__out), __fc, __c, __mod); + __out = _M_C_y_Y(__t._M_year, std::move(__out), __c); break; case 'd': case 'e': - __out = _M_d_e(__t, std::move(__out), __fc, __c, __mod == 'O'); + __out = _M_d_e(__t._M_day, std::move(__out), __c); break; case 'D': - __out = _M_D(__t, std::move(__out), __fc); + case 'x': + __out = _M_D_x(__t, std::move(__out)); break; case 'F': - __out = _M_F(__t, std::move(__out), __fc); + __out = _M_F(__t, std::move(__out)); break; case 'g': case 'G': - __out = _M_g_G(__t, std::move(__out), __fc, __c == 'G'); + __out = _M_g_G(__t, std::move(__out), __c == 'G'); break; case 'H': case 'I': - __out = _M_H_I(__t, __print_sign(), __fc, __c, __mod == 'O'); + __out = _M_H_I(__t._M_hours, __print_sign(), __c); break; case 'j': - __out = _M_j(__t, __print_sign(), __fc); + __out = _M_j(__t, __print_sign()); break; case 'm': - __out = _M_m(__t, std::move(__out), __fc, __mod == 'O'); + __out = _M_m(__t._M_month, std::move(__out)); break; case 'M': - __out = _M_M(__t, __print_sign(), __fc, __mod == 'O'); + __out = _M_M(__t._M_minutes, __print_sign()); break; case 'p': - __out = _M_p(__t, std::move(__out), __fc); + __out = _M_p(__t._M_hours, std::move(__out)); break; case 'q': - __out = _M_q(__t, std::move(__out), __fc); + __out = _M_q(__t._M_unit_suffix, std::move(__out)); break; case 'Q': - // %Q The duration's numeric value. - if constexpr (chrono::__is_duration_v<_Tp>) - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 4118. How should duration formatters format custom rep? - __out = std::format_to(__print_sign(), _S_empty_spec, - +__t.count()); - else - __throw_format_error("chrono format error: argument is " - "not a duration"); + __out = _M_Q(__t, __print_sign(), __fc); break; case 'r': - __out = _M_r(__t, __print_sign(), __fc); + __out = _M_r(__t, __print_sign()); break; case 'R': + case 'X': + __out = _M_R_X(__t, __print_sign(), __c != 'R'); + break; case 'T': - __out = _M_R_T(__t, __print_sign(), __fc, __c == 'T'); + __out = _M_T(__t, __print_sign(), __fc); break; case 'S': - __out = _M_S(__t, __print_sign(), __fc, __mod == 'O'); + __out = _M_S(__t, __print_sign(), __fc, __mod != 'O'); break; case 'u': case 'w': - __out = _M_u_w(__t, std::move(__out), __fc, __c, __mod == 'O'); + __out = _M_u_w(__t._M_weekday, std::move(__out), __c); break; case 'U': case 'V': case 'W': - __out = _M_U_V_W(__t, std::move(__out), __fc, __c, - __mod == 'O'); - break; - case 'x': - __out = _M_x(__t, std::move(__out), __fc, __mod == 'E'); - break; - case 'X': - __out = _M_X(__t, __print_sign(), __fc, __mod == 'E'); + __out = _M_U_V_W(__t, std::move(__out), __c); break; case 'z': - __out = _M_z(__t, std::move(__out), __fc, (bool)__mod); + __out = _M_z(__t._M_zone_offset, std::move(__out), (bool)__mod); break; case 'Z': - __out = _M_Z(__t, std::move(__out), __fc); + __out = _M_Z(__t._M_zone_abbrev, std::move(__out)); break; case 'n': *__out++ = __literals[0]; @@ -672,6 +1217,14 @@ namespace __format __first = __last; break; } + + if (!__invalid.empty()) + { + constexpr __string_view __pref = _GLIBCXX_WIDEN(" is not a valid "); + __out = __format::__write(std::move(__out), __pref); + __out = __format::__write(std::move(__out), __invalid); + } + __mod = _CharT(); // Scan for next '%' and write out everything before it. __string_view __str(__first, __last - __first); @@ -694,233 +1247,61 @@ namespace __format return std::move(__out); } - _ChronoSpec<_CharT> _M_spec; - - private: - // Return the formatting locale. - template - std::locale - _M_locale(_FormatContext& __fc) const - { - if (!_M_spec._M_localized) - return std::locale::classic(); - else - return __fc.locale(); - } - - // Format for empty chrono-specs, e.g. "{}" (C++20 [time.format] p6). - // TODO: consider moving body of every operator<< into this function - // and use std::format("{}", t) to implement those operators. That - // would avoid std::format("{}", t) calling operator<< which calls - // std::format again. - template - typename _FormatContext::iterator - _M_format_to_ostream(const _Tp& __t, _FormatContext& __fc, - bool __is_neg) const - { - using ::std::chrono::__detail::__utc_leap_second; - using ::std::chrono::__detail::__local_time_fmt; - - basic_ostringstream<_CharT> __os; - __os.imbue(_M_locale(__fc)); - - if constexpr (__is_specialization_of<_Tp, __local_time_fmt>) - { - // Format as "{:L%F %T}" - auto __days = chrono::floor(__t._M_time); - __os << chrono::year_month_day(__days) << ' ' - << chrono::hh_mm_ss(__t._M_time - __days); - - // For __local_time_fmt the __is_neg flags says whether to - // append " %Z" to the result. - if (__is_neg) - { - if (!__t._M_abbrev) [[unlikely]] - __format::__no_timezone_available(); - else if constexpr (is_same_v<_CharT, char>) - __os << ' ' << *__t._M_abbrev; - else - { - __os << L' '; - for (char __c : *__t._M_abbrev) - __os << __c; - } - } - } - else - { - if constexpr (__is_specialization_of<_Tp, __utc_leap_second>) - __os << __t._M_date << ' ' << __t._M_time; - else if constexpr (chrono::__is_time_point_v<_Tp>) - { - // Need to be careful here because not all specializations - // of chrono::sys_time can be written to an ostream. - // For the specializations of time_point that can be - // formatted with an empty chrono-specs, either it's a - // sys_time with period greater or equal to days: - if constexpr (is_convertible_v<_Tp, chrono::sys_days>) - __os << _S_date(__t); - // Or a local_time with period greater or equal to days: - else if constexpr (is_convertible_v<_Tp, chrono::local_days>) - __os << _S_date(__t); - else // Or it's formatted as "{:L%F %T}": - { - auto __days = chrono::floor(__t); - __os << chrono::year_month_day(__days) << ' ' - << chrono::hh_mm_ss(__t - __days); - } - } - else - { - if constexpr (chrono::__is_duration_v<_Tp>) - if (__is_neg) [[unlikely]] - __os << _S_plus_minus[1]; - __os << __t; - } - } - - auto __str = std::move(__os).str(); - return __format::__write_padded_as_spec(__str, __str.size(), - __fc, _M_spec); - } - - static constexpr const _CharT* _S_chars - = _GLIBCXX_WIDEN("0123456789+-:/ {}"); - static constexpr const _CharT* _S_plus_minus = _S_chars + 10; - static constexpr _CharT _S_colon = _S_chars[12]; - static constexpr _CharT _S_slash = _S_chars[13]; - static constexpr _CharT _S_space = _S_chars[14]; - static constexpr const _CharT* _S_empty_spec = _S_chars + 15; - template _OutIter - _M_write(_OutIter __out, const locale& __loc, __string_view __s) const + _M_wi(unsigned __wi, _OutIter __out) const { -#if defined _GLIBCXX_USE_NL_LANGINFO_L && __CHAR_BIT__ == 8 - __sso_string __buf; - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 3565. Handling of encodings in localized formatting - // of chrono types is underspecified - if constexpr (is_same_v<_CharT, char>) - if constexpr (__unicode::__literal_encoding_is_utf8()) - if (_M_spec._M_localized && _M_spec._M_locale_specific - && __loc != locale::classic()) - { - extern string_view - __locale_encoding_to_utf8(const locale&, string_view, void*); - - __s = __locale_encoding_to_utf8(__loc, __s, &__buf); - } -#endif - return __format::__write(std::move(__out), __s); + // %\0 Extension to format weekday index, used only by empty format spec + _CharT __buf[3]; + __out = __format::__write(std::move(__out), _S_str_d1(__buf, __wi)); + return std::move(__out); } - template - typename _FormatContext::iterator - _M_a_A(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx, bool __full) const + template + _OutIter + _M_a_A(chrono::weekday __wd, _OutIter __out, bool __full) const { // %a Locale's abbreviated weekday name. // %A Locale's full weekday name. - chrono::weekday __wd = _S_weekday(__t); - if (!__wd.ok()) - __throw_format_error("format error: invalid weekday"); - - locale __loc = _M_locale(__ctx); - const auto& __tp = use_facet<__timepunct<_CharT>>(__loc); - const _CharT* __days[7]; - if (__full) - __tp._M_days(__days); - else - __tp._M_days_abbreviated(__days); - __string_view __str(__days[__wd.c_encoding()]); - return _M_write(std::move(__out), __loc, __str); + __string_view __str = _S_weekdays[__wd.c_encoding()]; + if (!__full) + __str = __str.substr(0, 3); + return __format::__write(std::move(__out), __str); } - template - typename _FormatContext::iterator - _M_b_B(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx, bool __full) const + template + _OutIter + _M_b_B(chrono::month __m, _OutIter __out, bool __full) const { // %b Locale's abbreviated month name. // %B Locale's full month name. - chrono::month __m = _S_month(__t); - if (!__m.ok()) - __throw_format_error("format error: invalid month"); - locale __loc = _M_locale(__ctx); - const auto& __tp = use_facet<__timepunct<_CharT>>(__loc); - const _CharT* __months[12]; - if (__full) - __tp._M_months(__months); - else - __tp._M_months_abbreviated(__months); - __string_view __str(__months[(unsigned)__m - 1]); - return _M_write(std::move(__out), __loc, __str); + __string_view __str = _S_months[(unsigned)__m - 1]; + if (!__full) + __str = __str.substr(0, 3); + return __format::__write(std::move(__out), __str); } - template - typename _FormatContext::iterator - _M_c(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx, bool __mod = false) const + template + _OutIter + _M_c(const _ChronoData<_CharT>& __t, _OutIter __out) const { - // %c Locale's date and time representation. - // %Ec Locale's alternate date and time representation. - - using namespace chrono; - using ::std::chrono::__detail::__utc_leap_second; - using ::std::chrono::__detail::__local_time_fmt; - - struct tm __tm{}; - - // Some locales use %Z in their %c format but we don't want strftime - // to use the system's local time zone (from /etc/localtime or $TZ) - // as the output for %Z. Setting tm_isdst to -1 says there is no - // time zone info available for the time in __tm. - __tm.tm_isdst = -1; - -#ifdef _GLIBCXX_USE_STRUCT_TM_TM_ZONE - // POSIX.1-2024 adds tm.tm_zone which will be used for %Z. - // BSD has had tm_zone since 1987 but as char* so cast away const. - if constexpr (__is_time_point_v<_Tp>) - { - // One of sys_time, utc_time, or local_time. - if constexpr (!is_same_v) - __tm.tm_zone = const_cast("UTC"); - } - else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>) - { - // local-time-format-t is used to provide time zone info for - // one of zoned_time, tai_time, gps_time, or local_time. - if (__t._M_abbrev) - __tm.tm_zone = const_cast(__t._M_abbrev->c_str()); - } - else - __tm.tm_zone = const_cast("UTC"); -#endif - - auto __d = _S_days(__t); // Either sys_days or local_days. - using _TDays = decltype(__d); - const year_month_day __ymd(__d); - const auto __y = __ymd.year(); - const auto __hms = _S_hms(__t); - - __tm.tm_year = (int)__y - 1900; - __tm.tm_yday = (__d - _TDays(__y/January/1)).count(); - __tm.tm_mon = (unsigned)__ymd.month() - 1; - __tm.tm_mday = (unsigned)__ymd.day(); - __tm.tm_wday = weekday(__d).c_encoding(); - __tm.tm_hour = __hms.hours().count(); - __tm.tm_min = __hms.minutes().count(); - __tm.tm_sec = __hms.seconds().count(); - - return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm, 'c', - __mod ? 'E' : '\0'); + // %c Locale's date and time representation, for C-locale: %a %b %e %T %Y + // %Ec Locale's alternate date and time representation, for C-locale same as above + + __out = _M_a_A(__t._M_weekday, std::move(__out), false); + *__out = _S_space; + __out = _M_b_B(__t._M_month, std::move(++__out), false); + *__out = _S_space; + __out = _M_d_e(__t._M_day, std::move(++__out), 'e'); + *__out = _S_space; + __out = _M_R_X(__t, std::move(++__out), true); + *__out = _S_space; + return _M_C_y_Y(__t._M_year, std::move(++__out), 'Y'); } - template - typename _FormatContext::iterator - _M_C_y_Y(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx, _CharT __conv, _CharT __mod = 0) const + template + _OutIter + _M_C_y_Y(chrono::year __y, _OutIter __out, _CharT __conv) const { // %C Year divided by 100 using floored division. // %EC Locale's alternative preresentation of the century (era name). @@ -930,415 +1311,407 @@ namespace __format // %Y Year as a decimal number. // %EY Locale's alternative full year representation. - chrono::year __y = _S_year(__t); - - if (__mod && _M_spec._M_localized) [[unlikely]] - if (auto __loc = __ctx.locale(); __loc != locale::classic()) - { - struct tm __tm{}; - __tm.tm_year = (int)__y - 1900; - return _M_locale_fmt(std::move(__out), __loc, __tm, - __conv, __mod); - } - - basic_string<_CharT> __s; int __yi = (int)__y; const bool __is_neg = __yi < 0; __yi = __builtin_abs(__yi); + int __ci = __yi / 100; + // For floored division -123//100 is -2 and -100//100 is -1 + if (__conv == 'C' && __is_neg && (__ci * 100) != __yi) [[unlikely]] + ++__ci; - if (__conv == 'Y' || __conv == 'C') + if (__conv != 'y' && __ci >= 100) [[unlikely]] + { + using _FmtStr = _Runtime_format_string<_CharT>; + __string_view __fs = _S_minus_empty_spec + !__is_neg; + __out = std::format_to(std::move(__out), _FmtStr(__fs), + __conv == 'C' ? __ci : __yi); + } + else { - int __ci = __yi / 100; - if (__is_neg) [[unlikely]] + _CharT __buf[5]; + __buf[0] = _S_plus_minus[1]; + __string_view __sv(__buf + 3, __buf + 3); + if (__conv != 'y') { - __s.assign(1, _S_plus_minus[1]); - // For floored division -123//100 is -2 and -100//100 is -1 - if (__conv == 'C' && (__ci * 100) != __yi) - ++__ci; + _S_fill_two_digits(__buf + 1, __ci); + __sv = __string_view(__buf + !__is_neg, __buf + 3); } - if (__ci >= 100) [[unlikely]] + if (__conv != 'C') { - __s += std::format(_S_empty_spec, __ci / 100); - __ci %= 100; + _S_fill_two_digits(__buf + 3, __yi % 100); + __sv = __string_view(__sv.data(), __buf + 5); } - __s += _S_two_digits(__ci); + __out = __format::__write(std::move(__out), __sv); } - - if (__conv == 'Y' || __conv == 'y') - __s += _S_two_digits(__yi % 100); - - return __format::__write(std::move(__out), __string_view(__s)); + return __out; } - template - typename _FormatContext::iterator - _M_D(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext&) const + template + _OutIter + _M_D_x(const _ChronoData<_CharT>& __t, _OutIter __out) const { - auto __ymd = _S_date(__t); - basic_string<_CharT> __s; -#if ! _GLIBCXX_USE_CXX11_ABI - __s.reserve(8); -#endif - __s = _S_two_digits((unsigned)__ymd.month()); - __s += _S_slash; - __s += _S_two_digits((unsigned)__ymd.day()); - __s += _S_slash; - __s += _S_two_digits(__builtin_abs((int)__ymd.year()) % 100); - return __format::__write(std::move(__out), __string_view(__s)); + // %D Equivalent to %m/%d/%y + // %x Locale's date rep, for C-locale: %m/%d/%y + // %Ex Locale's alternative date representation, for C-locale same as above + + auto __di = (unsigned)__t._M_day; + auto __mi = (unsigned)__t._M_month; + auto __yi = __builtin_abs((int)__t._M_year) % 100; + + if (__mi >= 100 || __di >= 100) [[unlikely]] + { + using _FmtStr = _Runtime_format_string<_CharT>; + __string_view __fs = _GLIBCXX_WIDEN("{:02d}/{:02d}/{:02d}"); + __out = std::format_to(std::move(__out), _FmtStr(__fs), + __mi, __di, __yi); + } + else + { + _CharT __buf[8]; + __buf[2] = _S_slash; + __buf[5] = _S_slash; + __string_view __sv(__buf, __buf + 8); + + _S_fill_two_digits(__buf, __mi); + _S_fill_two_digits(__buf + 3, __di); + _S_fill_two_digits(__buf + 6, __yi); + __out = __format::__write(std::move(__out), __sv); + } + return std::move(__out); } - template - typename _FormatContext::iterator - _M_d_e(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx, _CharT __conv, bool __mod = false) const + template + _OutIter + _M_d_e(chrono::day __d, _OutIter __out, _CharT __conv) const { // %d The day of month as a decimal number. // %Od Locale's alternative representation. // %e Day of month as decimal number, padded with space. // %Oe Locale's alternative digits. - chrono::day __d = _S_day(__t); unsigned __i = (unsigned)__d; - if (__mod && _M_spec._M_localized) [[unlikely]] - if (auto __loc = __ctx.locale(); __loc != locale::classic()) - { - struct tm __tm{}; - __tm.tm_mday = __i; - return _M_locale_fmt(std::move(__out), __loc, __tm, - (char)__conv, 'O'); - } - - auto __sv = _S_two_digits(__i); - _CharT __buf[2]; + _CharT __buf[3]; + auto __sv = _S_str_d2(__buf, __i); if (__conv == _CharT('e') && __i < 10) { - __buf[0] = _S_space; __buf[1] = __sv[1]; + __buf[0] = _S_space; __sv = {__buf, 2}; } - return __format::__write(std::move(__out), __sv); + + __out = __format::__write(std::move(__out), __sv); + return std::move(__out); } - template - typename _FormatContext::iterator - _M_F(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext&) const + template + _OutIter + _M_F(const _ChronoData<_CharT>& __t, _OutIter __out) const { - auto __ymd = _S_date(__t); - auto __s = std::format(_GLIBCXX_WIDEN("{:04d}- - "), - (int)__ymd.year()); - auto __sv = _S_two_digits((unsigned)__ymd.month()); - __s[__s.size() - 5] = __sv[0]; - __s[__s.size() - 4] = __sv[1]; - __sv = _S_two_digits((unsigned)__ymd.day()); - __s[__s.size() - 2] = __sv[0]; - __s[__s.size() - 1] = __sv[1]; - __sv = __s; - return __format::__write(std::move(__out), __sv); + auto __di = (unsigned)__t._M_day; + auto __mi = (unsigned)__t._M_month; + auto __yi = (int)__t._M_year; + const bool __is_neg = __yi < 0; + __yi = __builtin_abs(__yi); + + if (__yi >= 10000 || __mi >= 100 || __di >= 100) [[unlikely]] + { + using _FmtStr = _Runtime_format_string<_CharT>; + __string_view __fs + = _GLIBCXX_WIDEN("-{:04d}-{:02d}-{:02d}") + !__is_neg; + __out = std::format_to(std::move(__out), _FmtStr(__fs), + __yi, __mi, __di); + } + else + { + _CharT __buf[11]; + __buf[0] = _S_plus_minus[1]; + __buf[5] = _S_plus_minus[1]; + __buf[8] = _S_plus_minus[1]; + __string_view __sv(__buf + !__is_neg, __buf + 11); + + _S_fill_two_digits(__buf + 1, __yi / 100); + _S_fill_two_digits(__buf + 3, __yi % 100); + _S_fill_two_digits(__buf + 6, __mi); + _S_fill_two_digits(__buf + 9, __di); + __out = __format::__write(std::move(__out), __sv); + } + + return std::move(__out); } - template - typename _FormatContext::iterator - _M_g_G(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx, bool __full) const + template + _OutIter + _M_g_G(const _ChronoData<_CharT>& __t, _OutIter __out, + bool __full) const { // %g last two decimal digits of the ISO week-based year. // %G ISO week-based year. using namespace chrono; - auto __d = _S_days(__t); + auto __d = __t._M_ldays; // Move to nearest Thursday: - __d -= (weekday(__d) - Monday) - days(3); + __d -= (__t._M_weekday - Monday) - days(3); // ISO week-based year is the year that contains that Thursday: year __y = year_month_day(__d).year(); - return _M_C_y_Y(__y, std::move(__out), __ctx, "yY"[__full]); + return _M_C_y_Y(__y, std::move(__out), "yY"[__full]); } - template - typename _FormatContext::iterator - _M_H_I(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx, _CharT __conv, bool __mod = false) const + template + _OutIter + _M_H_I(chrono::hours __h, _OutIter __out, _CharT __conv) const { // %H The hour (24-hour clock) as a decimal number. // %OH Locale's alternative representation. // %I The hour (12-hour clock) as a decimal number. // %OI Locale's alternative representation. - const auto __hms = _S_hms(__t); - int __i = __hms.hours().count(); - - if (__mod && _M_spec._M_localized) [[unlikely]] - if (auto __loc = __ctx.locale(); __loc != locale::classic()) - { - struct tm __tm{}; - __tm.tm_hour = __i; - return _M_locale_fmt(std::move(__out), __loc, __tm, - (char)__conv, 'O'); - } + int __i = __h.count(); if (__conv == _CharT('I')) { + __i %= 12; if (__i == 0) __i = 12; - else if (__i > 12) - __i -= 12; } + else if (__i >= 100) [[unlikely]] + return std::format_to(std::move(__out), _S_empty_fs(), __i); + return __format::__write(std::move(__out), _S_two_digits(__i)); } - template - typename _FormatContext::iterator - _M_j(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext&) const + template + _OutIter + _M_j(const _ChronoData<_CharT>& __t, _OutIter __out) const { - if constexpr (chrono::__is_duration_v<_Tp>) - { - // Decimal number of days, without padding. - unsigned __d = chrono::duration_cast(__t).count(); - return std::format_to(std::move(__out), _S_empty_spec, __d); - } - else - { - // Day of the year as a decimal number, padding with zero. - using namespace chrono; - auto __day = _S_days(__t); - auto __ymd = _S_date(__t); - days __d; - // See "Calculating Ordinal Dates" at - // https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes - if constexpr (is_same_v) - __d = __day - local_days(__ymd.year()/January/0); - else - __d = __day - sys_days(__ymd.year()/January/0); - return std::format_to(std::move(__out), _GLIBCXX_WIDEN("{:03d}"), - __d.count()); - } + if (!_M_spec._M_needs(_ChronoParts::_DayOfYear)) + { + // Decimal number of days, without padding. + auto __d = chrono::floor(__t._M_hours).count(); + return std::format_to(std::move(__out), _S_empty_fs(), __d); + } + + auto __d = __t._M_day_of_year.count(); + if (__d >= 1000) [[unlikely]] + return std::format_to(std::move(__out), _S_empty_fs(), __d); + + _CharT __buf[3]; + return __format::__write(std::move(__out), _S_str_d3(__buf, __d)); } - template - typename _FormatContext::iterator - _M_m(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx, bool __mod) const + template + _OutIter + _M_m(chrono::month __m, _OutIter __out) const { // %m month as a decimal number. // %Om Locale's alternative representation. - - auto __m = _S_month(__t); auto __i = (unsigned)__m; + if (__i == 0 && _M_spec._M_debug) [[unlikely]] + // 0 should not be padded to two digits + return __format::__write(std::move(__out), _S_digit(0)); - if (__mod && _M_spec._M_localized) [[unlikely]] // %Om - if (auto __loc = __ctx.locale(); __loc != locale::classic()) - { - struct tm __tm{}; - __tm.tm_mon = __i - 1; - return _M_locale_fmt(std::move(__out), __loc, __tm, - 'm', 'O'); - } - - return __format::__write(std::move(__out), _S_two_digits(__i)); + _CharT __buf[3]; + return __format::__write(std::move(__out), _S_str_d2(__buf, __i)); } - template - typename _FormatContext::iterator - _M_M(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx, bool __mod) const + template + _OutIter + _M_M(chrono::minutes __m, _OutIter __out) const { // %M The minute as a decimal number. // %OM Locale's alternative representation. - auto __m = _S_hms(__t).minutes(); auto __i = __m.count(); - - if (__mod && _M_spec._M_localized) [[unlikely]] // %OM - if (auto __loc = __ctx.locale(); __loc != locale::classic()) - { - struct tm __tm{}; - __tm.tm_min = __i; - return _M_locale_fmt(std::move(__out), __loc, __tm, - 'M', 'O'); - } - return __format::__write(std::move(__out), _S_two_digits(__i)); } - template - typename _FormatContext::iterator - _M_p(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx) const + template + _OutIter + _M_p(chrono::hours __h, _OutIter __out) const { // %p The locale's equivalent of the AM/PM designations. - auto __hms = _S_hms(__t); - locale __loc = _M_locale(__ctx); - const auto& __tp = use_facet<__timepunct<_CharT>>(__loc); - const _CharT* __ampm[2]; - __tp._M_am_pm(__ampm); - return _M_write(std::move(__out), __loc, - __ampm[__hms.hours().count() >= 12]); + + _CharT __buf[2]; + _S_fill_ampm(__buf, __h); + return __format::__write(std::move(__out), __string_view(__buf, 2)); } - template - typename _FormatContext::iterator - _M_q(const _Tp&, typename _FormatContext::iterator __out, - _FormatContext&) const + template + _OutIter + _M_q(__string_view __us, _OutIter __out) const { // %q The duration's unit suffix - if constexpr (!chrono::__is_duration_v<_Tp>) - __throw_format_error("format error: argument is not a duration"); - else - { - namespace __d = chrono::__detail; - using period = typename _Tp::period; - return __d::__fmt_units_suffix(std::move(__out)); - } + return __format::__write(std::move(__out), __us); } - // %Q handled in _M_format + template + _OutIter + _M_Q(const _ChronoData<_CharT>& __t, _OutIter __out, + _FormatContext&) const + { + // %Q The duration's numeric value. + return std::vformat_to(std::move(__out), _S_empty_spec, __t._M_ereps); + } - template - typename _FormatContext::iterator - _M_r(const _Tp& __tt, typename _FormatContext::iterator __out, - _FormatContext& __ctx) const + template + _OutIter + _M_r(const _ChronoData<_CharT>& __t, _OutIter __out) const { - // %r locale's 12-hour clock time. - auto __t = _S_floor_seconds(__tt); - locale __loc = _M_locale(__ctx); - const auto& __tp = use_facet<__timepunct<_CharT>>(__loc); - const _CharT* __ampm_fmt; - __tp._M_am_pm_format(&__ampm_fmt); - basic_string<_CharT> __fmt(_S_empty_spec); - __fmt.insert(1u, 1u, _S_colon); - __fmt.insert(2u, __ampm_fmt); - using _FmtStr = _Runtime_format_string<_CharT>; - return _M_write(std::move(__out), __loc, - std::format(__loc, _FmtStr(__fmt), __t)); + // %r Locale's 12-hour clock time, for C-locale: %I:%M:%S %p + auto __hi = __t._M_hours.count() % 12; + if (__hi == 0) + __hi = 12; + + _CharT __buf[11]; + __buf[2] = _S_colon; + __buf[5] = _S_colon; + __buf[8] = _S_space; + _S_fill_two_digits(__buf, __hi); + _S_fill_two_digits(__buf + 3, __t._M_minutes.count()); + _S_fill_two_digits(__buf + 6, __t._M_seconds.count()); + _S_fill_ampm(__buf + 9, __t._M_hours); + + return __format::__write(std::move(__out), __string_view(__buf, 11)); } - template - typename _FormatContext::iterator - _M_R_T(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx, bool __secs) const + template + _OutIter + _M_R_X(const _ChronoData<_CharT>& __t, _OutIter __out, + bool __secs) const { - // %R Equivalent to %H:%M - // %T Equivalent to %H:%M:%S - auto __hms = _S_hms(__t); - - auto __s = std::format(_GLIBCXX_WIDEN("{:02d}:00"), - __hms.hours().count()); - auto __sv = _S_two_digits(__hms.minutes().count()); - __s[__s.size() - 2] = __sv[0]; - __s[__s.size() - 1] = __sv[1]; - __sv = __s; - __out = __format::__write(std::move(__out), __sv); - if (__secs) + // %R Equivalent to %H:%M + // %X Locale's time rep, for C-locale: %H:%M:%S (without subseconds) + // %EX Locale's alternative time representation, for C-locale same as above + + auto __hi = __t._M_hours.count(); + + _CharT __buf[8]; + __buf[2] = _S_colon; + __buf[5] = _S_colon; + __string_view __sv(__buf, 8); + + if (__hi >= 100) [[unlikely]] { - *__out++ = _S_colon; - __out = _M_S(__hms, std::move(__out), __ctx); + __out = std::format_to(std::move(__out), _S_empty_fs(), __hi); + __sv.remove_prefix(2); } - return __out; + else + _S_fill_two_digits(__buf, __hi); + + _S_fill_two_digits(__buf + 3, __t._M_minutes.count()); + if (__secs) + _S_fill_two_digits(__buf + 6, __t._M_seconds.count()); + else + __sv.remove_suffix(3); + + return __format::__write(std::move(__out), __sv); } - template - typename _FormatContext::iterator - _M_S(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx, bool __mod = false) const + template + _OutIter + _M_S(const _ChronoData<_CharT>& __t, _OutIter __out, + _FormatContext& __ctx, bool __subs = true) const { // %S Seconds as a decimal number. // %OS The locale's alternative representation. - auto __hms = _S_hms(__t); - auto __s = __hms.seconds(); + auto __s = __t._M_seconds; - if (__mod) [[unlikely]] // %OS - { - if (_M_spec._M_localized) - if (auto __loc = __ctx.locale(); __loc != locale::classic()) - { - struct tm __tm{}; - __tm.tm_sec = (int)__s.count(); - return _M_locale_fmt(std::move(__out), __loc, __tm, - 'S', 'O'); - } + __out = __format::__write(std::move(__out), + _S_two_digits(__s.count())); + if (__subs) + __out = _M_subsecs(__t, std::move(__out), __ctx); + return __out; + } - // %OS formats don't include subseconds, so just format that: - return __format::__write(std::move(__out), - _S_two_digits(__s.count())); + template + _OutIter + _M_subsecs(const _ChronoData<_CharT>& __t, _OutIter __out, + _FormatContext& __ctx) const + { + unsigned __prec = _M_spec._M_prec_kind != _WP_none + ? _M_spec._M_get_precision(__ctx) + : _M_spec._M_prec; + if (__prec == 0) + return __out; + + _CharT __dot = _S_dot; + if (_M_spec._M_localized) [[unlikely]] + { + auto __loc = __ctx.locale(); + const auto& __np = use_facet>(__loc); + __dot = __np.decimal_point(); } + *__out = __dot; + ++__out; - if constexpr (__hms.fractional_width == 0) - __out = __format::__write(std::move(__out), - _S_two_digits(__s.count())); - else + if (_M_spec._M_floating_point_rep) { - locale __loc = _M_locale(__ctx); - auto __ss = __hms.subseconds(); - using rep = typename decltype(__ss)::rep; - if constexpr (is_floating_point_v) - { - chrono::duration __fs = __s + __ss; - __out = std::format_to(std::move(__out), __loc, - _GLIBCXX_WIDEN("{:#0{}.{}Lf}"), - __fs.count(), - 3 + __hms.fractional_width, - __hms.fractional_width); - } + _Str_sink<_CharT> __sink; + if (_M_spec._M_localized && _M_spec._M_custom_rep) [[unlikely]] + std::vformat_to(__sink.out(), __ctx.locale(), + _GLIBCXX_WIDEN("{1:0.{2}Lf}"), __t._M_ereps); else - { - const auto& __np - = use_facet>(__loc); - __out = __format::__write(std::move(__out), - _S_two_digits(__s.count())); - *__out++ = __np.decimal_point(); - if constexpr (is_integral_v) - __out = std::format_to(std::move(__out), - _GLIBCXX_WIDEN("{:0{}}"), - __ss.count(), - __hms.fractional_width); - else - { - auto __str = std::format(_S_empty_spec, __ss.count()); - __out = std::format_to(std::move(__out), - _GLIBCXX_WIDEN("{:0>{}s}"), - __str, - __hms.fractional_width); - } - } + std::vformat_to(__sink.out(), + _GLIBCXX_WIDEN("{1:0.{2}f}"), __t._M_ereps); + + auto __sv = __sink.view(); + // Skip leading zero and dot + __sv.remove_prefix(2); + return __format::__write(std::move(__out), __sv); } - return __out; + + constexpr unsigned __max_prec = _ChronoData<_CharT>::_S_max_prec; + constexpr typename _ChronoData<_CharT>::_Attoseconds::rep __pow10t[] + { + 1u, + 10u, 100u, 1000u, + 10'000u, 100'000u, 1000'000u, + 10'000'000u, 100'000'000u, 1000'000'000u, + 10'000'000'000u, 100'000'000'000u, 1000'000'000'000u, + 10'000'000'000'000u, 100'000'000'000'000u, 1000'000'000'000'000u, + 10'000'000'000'000'000u, 100'000'000'000'000'000u, 1000'000'000'000'000'000u, + }; + + auto __subs = __t._M_subseconds.count(); + if (__prec < __max_prec) + __subs /= __pow10t[__max_prec - __prec]; + else if (__prec > __max_prec) + __prec = __max_prec; + + using _FmtStr = _Runtime_format_string<_CharT>; + return std::format_to(__out, _FmtStr(_GLIBCXX_WIDEN("{0:0{1}}")), + __subs, __prec); } // %t handled in _M_format - template - typename _FormatContext::iterator - _M_u_w(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx, _CharT __conv, bool __mod = false) const + template + _OutIter + _M_T(const _ChronoData<_CharT>& __t, _OutIter __out, + _FormatContext& __ctx) const + { + // %T Equivalent to %H:%M:%S, with subseconds + __out = _M_R_X(__t, std::move(__out), true); + return _M_subsecs(__t, std::move(__out), __ctx); + } + + template + _OutIter + _M_u_w(chrono::weekday __wd, _OutIter __out, _CharT __conv) const { // %u ISO weekday as a decimal number (1-7), where Monday is 1. // %Ou Locale's alternative numeric rep. // %w Weekday as a decimal number (0-6), where Sunday is 0. // %Ow Locale's alternative numeric rep. - - chrono::weekday __wd = _S_weekday(__t); - - if (__mod && _M_spec._M_localized) [[unlikely]] - if (auto __loc = __ctx.locale(); __loc != locale::classic()) - { - struct tm __tm{}; - __tm.tm_wday = __wd.c_encoding(); - return _M_locale_fmt(std::move(__out), __loc, __tm, - (char)__conv, 'O'); - } - unsigned __wdi = __conv == 'u' ? __wd.iso_encoding() : __wd.c_encoding(); - const _CharT __d = _S_digit(__wdi); - return __format::__write(std::move(__out), __string_view(&__d, 1)); + _CharT __buf[3]; + return __format::__write(std::move(__out), _S_str_d1(__buf, __wdi)); } - template - typename _FormatContext::iterator - _M_U_V_W(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx, _CharT __conv, bool __mod = false) const + template + _OutIter + _M_U_V_W(const _ChronoData<_CharT>& __t, _OutIter __out, + _CharT __conv) const { // %U Week number of the year as a decimal number, from first Sunday. // %OU Locale's alternative numeric rep. @@ -1347,372 +1720,410 @@ namespace __format // %W Week number of the year as a decimal number, from first Monday. // %OW Locale's alternative numeric rep. using namespace chrono; - auto __d = _S_days(__t); - using _TDays = decltype(__d); // Either sys_days or local_days. - - if (__mod && _M_spec._M_localized) [[unlikely]] - if (auto __loc = __ctx.locale(); __loc != locale::classic()) - { - const year_month_day __ymd(__d); - const year __y = __ymd.year(); - struct tm __tm{}; - __tm.tm_year = (int)__y - 1900; - __tm.tm_yday = (__d - _TDays(__y/January/1)).count(); - __tm.tm_wday = weekday(__d).c_encoding(); - return _M_locale_fmt(std::move(__out), __loc, __tm, - (char)__conv, 'O'); - } - _TDays __first; // First day of week 1. + auto __d = __t._M_ldays; + local_days __first; // First day of week 1. if (__conv == 'V') // W01 begins on Monday before first Thursday. { // Move to nearest Thursday: - __d -= (weekday(__d) - Monday) - days(3); + __d -= (__t._M_weekday - Monday) - days(3); // ISO week of __t is number of weeks since January 1 of the // same year as that nearest Thursday. - __first = _TDays(year_month_day(__d).year()/January/1); + __first = local_days(year_month_day(__d).year()/January/1); } else { - year __y; - if constexpr (requires { __t.year(); }) - __y = __t.year(); - else - __y = year_month_day(__d).year(); const weekday __weekstart = __conv == 'U' ? Sunday : Monday; - __first = _TDays(__y/January/__weekstart[1]); + __first = local_days(__t._M_year/January/__weekstart[1]); } auto __weeks = chrono::floor(__d - __first); __string_view __sv = _S_two_digits(__weeks.count() + 1); return __format::__write(std::move(__out), __sv); } - template - typename _FormatContext::iterator - _M_x(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx, bool __mod = false) const - { - // %x Locale's date rep - // %Ex Locale's alternative date representation. - locale __loc = _M_locale(__ctx); - const auto& __tp = use_facet<__timepunct<_CharT>>(__loc); - const _CharT* __date_reps[2]; - __tp._M_date_formats(__date_reps); - const _CharT* __rep = __date_reps[__mod]; - if (!*__rep) - return _M_D(__t, std::move(__out), __ctx); - - basic_string<_CharT> __fmt(_S_empty_spec); - __fmt.insert(1u, 1u, _S_colon); - __fmt.insert(2u, __rep); - using _FmtStr = _Runtime_format_string<_CharT>; - return _M_write(std::move(__out), __loc, - std::format(__loc, _FmtStr(__fmt), __t)); - } - - template - typename _FormatContext::iterator - _M_X(const _Tp& __tt, typename _FormatContext::iterator __out, - _FormatContext& __ctx, bool __mod = false) const - { - // %X Locale's time rep - // %EX Locale's alternative time representation. - auto __t = _S_floor_seconds(__tt); - locale __loc = _M_locale(__ctx); - const auto& __tp = use_facet<__timepunct<_CharT>>(__loc); - const _CharT* __time_reps[2]; - __tp._M_time_formats(__time_reps); - const _CharT* __rep = __time_reps[__mod]; - if (!*__rep) - return _M_R_T(__t, std::move(__out), __ctx, true); - - basic_string<_CharT> __fmt(_S_empty_spec); - __fmt.insert(1u, 1u, _S_colon); - __fmt.insert(2u, __rep); - using _FmtStr = _Runtime_format_string<_CharT>; - return _M_write(std::move(__out), __loc, - std::format(__loc, _FmtStr(__fmt), __t)); - } - - template - typename _FormatContext::iterator - _M_z(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext&, bool __mod = false) const + template + _OutIter + _M_z(chrono::seconds __ts, _OutIter __out, bool __mod = false) const { - using ::std::chrono::__detail::__utc_leap_second; - using ::std::chrono::__detail::__local_time_fmt; - - auto __utc = __mod ? __string_view(_GLIBCXX_WIDEN("+00:00"), 6) - : __string_view(_GLIBCXX_WIDEN("+0000"), 5); - - if constexpr (chrono::__is_time_point_v<_Tp>) - { - if constexpr (is_same_v) - return __format::__write(std::move(__out), __utc); - } - else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>) + if (__ts == 0s) { - if (__t._M_offset_sec) - { - auto __sv = __utc; - basic_string<_CharT> __s; - if (*__t._M_offset_sec != 0s) - { - chrono:: hh_mm_ss __hms(*__t._M_offset_sec); - __s = _S_plus_minus[__hms.is_negative()]; - __s += _S_two_digits(__hms.hours().count()); - if (__mod) - __s += _S_colon; - __s += _S_two_digits(__hms.minutes().count()); - __sv = __s; - } - return __format::__write(std::move(__out), __sv); - } + __string_view __zero + = __mod ? _GLIBCXX_WIDEN("+00:00") : _GLIBCXX_WIDEN("+0000"); + return __format::__write(std::move(__out), __zero); } - else if constexpr (__is_specialization_of<_Tp, __utc_leap_second>) - return __format::__write(std::move(__out), __utc); - - __no_timezone_available(); - } - template - typename _FormatContext::iterator - _M_Z(const _Tp& __t, typename _FormatContext::iterator __out, - _FormatContext& __ctx) const - { - using ::std::chrono::__detail::__utc_leap_second; - using ::std::chrono::__detail::__local_time_fmt; + chrono::hh_mm_ss __hms(__ts); + unsigned __mo = 3 + __mod; - __string_view __utc(_GLIBCXX_WIDEN("UTC"), 3); - if constexpr (chrono::__is_time_point_v<_Tp>) - { - if constexpr (is_same_v) - return __format::__write(std::move(__out), __utc); - } - else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>) - { - if (__t._M_abbrev) - { - string_view __sv = *__t._M_abbrev; - if constexpr (is_same_v<_CharT, char>) - return __format::__write(std::move(__out), __sv); - else - { - // TODO use resize_and_overwrite - basic_string<_CharT> __ws(__sv.size(), _CharT()); - auto& __ct = use_facet>(_M_locale(__ctx)); - __ct.widen(__sv.begin(), __sv.end(), __ws.data()); - __string_view __wsv = __ws; - return __format::__write(std::move(__out), __wsv); - } - } - } - else if constexpr (__is_specialization_of<_Tp, __utc_leap_second>) - return __format::__write(std::move(__out), __utc); + _CharT __buf[6]; + __buf[0] = _S_plus_minus[__hms.is_negative()]; + __buf[3] = _S_colon; + _S_fill_two_digits(__buf + 1, __hms.hours().count()); + _S_fill_two_digits(__buf + __mo, __hms.minutes().count()); - __no_timezone_available(); + __string_view __sv(__buf, __mo + 2); + return __format::__write(std::move(__out), __sv); } + template + _OutIter + _M_Z(__string_view __abbrev, _OutIter __out) const + { return __format::__write(std::move(__out), __abbrev); } + // %% handled in _M_format - // A single digit character in the range '0'..'9'. - static _CharT + // A string view of single digit character, "0".."9". + static basic_string_view<_CharT> _S_digit(int __n) noexcept { // Extra 9s avoid past-the-end read on bad input. - return _GLIBCXX_WIDEN("0123456789999999")[__n & 0xf]; + return { _GLIBCXX_WIDEN("0123456789999999") + (__n & 0xf), 1 }; + } + + // A string view of two digit characters, "00".."99". + static basic_string_view<_CharT> + _S_two_digits(int __n) noexcept + { + return { + _GLIBCXX_WIDEN("0001020304050607080910111213141516171819" + "2021222324252627282930313233343536373839" + "4041424344454647484950515253545556575859" + "6061626364656667686970717273747576777879" + "8081828384858687888990919293949596979899" + "9999999999999999999999999999999999999999" + "9999999999999999") + 2 * (__n & 0x7f), + 2 + }; + } + + // Fills __buf[0] and __buf[1] with 2 digit value of __n. + [[__gnu__::__always_inline__]] + static void + _S_fill_two_digits(_CharT* __buf, unsigned __n) + { + auto __sv = _S_two_digits(__n); + __buf[0] = __sv[0]; + __buf[1] = __sv[1]; + } + + // Fills __buf[0] and __buf[1] with "AM", "PM" depending on __h. + [[__gnu__::__always_inline__]] + static void + _S_fill_ampm(_CharT* __buf, chrono::hours __h) + { + auto __hi = __h.count(); + if (__hi >= 24) [[unlikely]] + __hi %= 24; + + constexpr const _CharT* __apm = _GLIBCXX_WIDEN("APM"); + __buf[0] = __apm[__hi >= 12]; + __buf[1] = __apm[2]; + } + + // Returns decimal representation of __n. + // Returned string_view may point to __buf. + [[__gnu__::__always_inline__]] + static basic_string_view<_CharT> + _S_str_d1(span<_CharT, 3> __buf, unsigned __n) + { + if (__n < 10) [[likely]] + return _S_digit(__n); + return _S_str_d2(__buf, __n); + } + + // Returns decimal representation of __n, padded to 2 digits. + // Returned string_view may point to __buf. + [[__gnu__::__always_inline__]] + static basic_string_view<_CharT> + _S_str_d2(span<_CharT, 3> __buf, unsigned __n) + { + if (__n < 100) [[likely]] + return _S_two_digits(__n); + return _S_str_d3(__buf, __n); } - // A string view of two digit characters, "00".."99". + // Returns decimal representation of __n, padded to 3 digits. + // Returned string_view points to __buf. + [[__gnu__::__always_inline__]] static basic_string_view<_CharT> - _S_two_digits(int __n) noexcept + _S_str_d3(span<_CharT, 3> __buf, unsigned __n) { - return { - _GLIBCXX_WIDEN("0001020304050607080910111213141516171819" - "2021222324252627282930313233343536373839" - "4041424344454647484950515253545556575859" - "6061626364656667686970717273747576777879" - "8081828384858687888990919293949596979899" - "9999999999999999999999999999999999999999" - "9999999999999999") + 2 * (__n & 0x7f), - 2 - }; + _S_fill_two_digits(__buf.data(), __n / 10); + __buf[2] = _S_chars[__n % 10]; + return __string_view(__buf.data(), 3); } + }; - // Accessors for the components of chrono types: - - // Returns a hh_mm_ss. - template - static decltype(auto) - _S_hms(const _Tp& __t) + template + struct __formatter_duration : private __formatter_chrono<_CharT> + { + template + constexpr static auto + _S_subseconds(const chrono::duration<_Rep, _Period>& __d) { - using ::std::chrono::__detail::__utc_leap_second; - using ::std::chrono::__detail::__local_time_fmt; - - if constexpr (__is_specialization_of<_Tp, chrono::hh_mm_ss>) - return __t; - else if constexpr (__is_specialization_of<_Tp, __utc_leap_second>) - return __t._M_time; - else if constexpr (chrono::__is_duration_v<_Tp>) - return chrono::hh_mm_ss<_Tp>(__t); - else if constexpr (chrono::__is_time_point_v<_Tp>) - return chrono::hh_mm_ss(__t - chrono::floor(__t)); - else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>) - return _S_hms(__t._M_time); + if constexpr (chrono::treat_as_floating_point_v<_Rep>) + return chrono::duration<_Rep>(__d); + else if constexpr (_Period::den == 1) + return chrono::seconds(0); else - { - __invalid_chrono_spec(); - return chrono::hh_mm_ss(); - } - } + { + using _Attoseconds = _ChronoData<_CharT>::_Attoseconds; + using _CRep = common_type_t<_Rep, typename _Attoseconds::rep>; + chrono::duration<_CRep, _Period> subs(__d.count()); + return chrono::duration_cast<_Attoseconds>(subs); + } + } - // Returns a sys_days or local_days. - template - static auto - _S_days(const _Tp& __t) + public: + template + static consteval + _ChronoSpec<_CharT> + _S_spec_for(_ChronoParts __parts) { - using namespace chrono; - using ::std::chrono::__detail::__utc_leap_second; - using ::std::chrono::__detail::__local_time_fmt; - - if constexpr (__is_time_point_v<_Tp>) - return chrono::floor(__t); - else if constexpr (__is_specialization_of<_Tp, __utc_leap_second>) - return __t._M_date; - else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>) - return chrono::floor(__t._M_time); - else if constexpr (is_same_v<_Tp, year_month_day> - || is_same_v<_Tp, year_month_day_last> - || is_same_v<_Tp, year_month_weekday> - || is_same_v<_Tp, year_month_weekday_last>) - return sys_days(__t); - else + using _Rep = typename _Duration::rep; + using enum _ChronoParts; + + _ChronoSpec<_CharT> __res{}; + __res._M_floating_point_rep = chrono::treat_as_floating_point_v<_Rep>; + __res._M_custom_rep = !is_arithmetic_v<_Rep>; + __res._M_prec = chrono::hh_mm_ss<_Duration>::fractional_width; + if ((__parts & _TimeOfDay) != 0) + __res._M_localized = __res._M_prec > 0 || __res._M_floating_point_rep; + + if ((__parts & _TimeOfDay) != 0) + __res._M_needed |= _TimeOfDay; + if ((__parts & _Date) != 0) + __res._M_needed |= _YearMonthDay; + if ((__parts & _ZoneAbbrev) != 0) + __res._M_needed |= _ZoneAbbrev; + + switch (__parts) { - if constexpr (__is_duration_v<_Tp>) - __not_valid_for_duration(); - else - __invalid_chrono_spec(); - return chrono::sys_days(); + case _ZonedDateTime: + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_ftz(); + break; + case _DateTime: + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_ft(); + break; + case _Date: + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_f(); + break; + case _Time: + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_t(); + break; + case _None: + break; + default: + __builtin_unreachable(); } - } + return __res; + }; + + using __formatter_chrono<_CharT>::__formatter_chrono; + using __formatter_chrono<_CharT>::_M_spec; - // Returns a year_month_day. - template - static chrono::year_month_day - _S_date(const _Tp& __t) + template + constexpr typename _ParseContext::iterator + _M_parse(_ParseContext& __pc, _ChronoParts __parts, + const _ChronoSpec<_CharT>& __def = {}) { - if constexpr (is_same_v<_Tp, chrono::year_month_day>) - return __t; - else - return chrono::year_month_day(_S_days(__t)); + using _Rep = typename _Duration::rep; + using enum _ChronoParts; + + auto __res + = __formatter_chrono<_CharT>::_M_parse(__pc, __parts, __def); + // n.b. durations do not contain date parts, and for time point all + // date parts are computed, and they are always ok. + _M_spec._M_needs_ok_check = false; + + // check for custom floating point durations, if digits of output + // will contain subseconds, then formatters must support specifying + // precision. + if constexpr (!is_floating_point_v<_Rep>) + if constexpr (chrono::treat_as_floating_point_v<_Rep>) + if (_M_spec._M_needs(_Subseconds|_EpochUnits) + || _M_spec._M_prec_kind != _WP_none + || _M_spec._M_prec_value > 0) + { + constexpr const _CharT* __fs = _GLIBCXX_WIDEN("#02.5Lf"); + basic_format_parse_context<_CharT> __npc(__fs); + formatter<_Rep, _CharT> __fmtter; + __fmtter.parse(__npc); + } + return __res; } - template - static chrono::day - _S_day(const _Tp& __t) + // Return the formatting locale. + template + std::locale + _M_locale(_FormatContext& __fc) const { - using namespace chrono; - - if constexpr (is_same_v<_Tp, day>) - return __t; - else if constexpr (requires { __t.day(); }) - return __t.day(); + if (!_M_spec._M_localized) + return std::locale::classic(); else - return _S_date(__t).day(); + return __fc.locale(); } - template - static chrono::month - _S_month(const _Tp& __t) + // Format duration for empty chrono-specs, e.g. "{}" (C++20 [time.format] p6). + template + typename _FormatContext::iterator + _M_format_to_ostream(const chrono::duration<_Rep, _Period>& __d, + bool __is_neg, + _FormatContext& __fc) const { - using namespace chrono; + basic_ostringstream<_CharT> __os; + __os.imbue(this->_M_locale(__fc)); - if constexpr (is_same_v<_Tp, month>) - return __t; - else if constexpr (requires { __t.month(); }) - return __t.month(); - else - return _S_date(__t).month(); + if (__is_neg) [[unlikely]] + __os << this->_S_plus_minus[1]; + __os << __d; + + auto __str = std::move(__os).str(); + return __format::__write_padded_as_spec(__str, __str.size(), + __fc, _M_spec); } - template - static chrono::year - _S_year(const _Tp& __t) + template + typename _FormatContext::iterator + _M_format_units(_ChronoData<_CharT>& __cd, + const chrono::duration<_Rep1, _Period1>& __ed, + const chrono::duration<_Rep2, _Period2>& __ss, + _FormatContext& __fc) const { - using namespace chrono; + __format::_Str_sink<_CharT> __suffix_store; + constexpr auto _S_unit_suffix + = chrono::__detail::__units_suffix<_Period1, _CharT>(); + if constexpr (!_S_unit_suffix.empty()) + __cd._M_unit_suffix = _S_unit_suffix; + else if (_M_spec._M_needs(_ChronoParts::_UnitSuffix)) + { + chrono::__detail:: + __fmt_units_suffix<_Period1, _CharT>(__suffix_store.out()); + __cd._M_unit_suffix = __suffix_store.view(); + } - if constexpr (is_same_v<_Tp, year>) - return __t; - else if constexpr (requires { __t.year(); }) - return __t.year(); - else - return _S_date(__t).year(); + const auto __prec = _M_spec._M_prec_kind != _WP_none + ? _M_spec._M_get_precision(__fc) + : _M_spec._M_prec; + + using _ErasedContext = typename _ChronoData<_CharT>::_FormatContext; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 4118. How should duration formatters format custom rep? + auto __ereps = +__ed.count(); + if (!_M_spec._M_needs(_ChronoParts::_Subseconds)) + { + auto __ssreps = 0u; + auto __args_store + = std::make_format_args<_ErasedContext>(__ereps, __ssreps, __prec); + __cd._M_ereps = __args_store; + return this->_M_format(__cd, __fc); + } + + using _Attoseconds = _ChronoData<_CharT>::_Attoseconds; + auto __nss = _S_subseconds(__ss); + __cd._M_subseconds = chrono::duration_cast<_Attoseconds>(__nss); + + auto __ssreps = __nss.count(); + auto __args_store + = std::make_format_args<_ErasedContext>(__ereps, __ssreps, __prec); + __cd._M_ereps = __args_store; + + return this->_M_format(__cd, __fc); } - template - static chrono::weekday - _S_weekday(const _Tp& __t) + // pre: __cd._M_lseconds and __cd._M_eseconds are set. + template + typename _FormatContext::iterator + _M_format_time_point(_ChronoData<_CharT>& __cd, + const chrono::duration<_Rep1, _Period1>& __ed, + _FormatContext& __fc) const { - using namespace ::std::chrono; - using ::std::chrono::__detail::__local_time_fmt; - - if constexpr (is_same_v<_Tp, weekday>) - return __t; - else if constexpr (requires { __t.weekday(); }) - return __t.weekday(); - else if constexpr (is_same_v<_Tp, month_weekday>) - return __t.weekday_indexed().weekday(); - else if constexpr (is_same_v<_Tp, month_weekday_last>) - return __t.weekday_last().weekday(); - else - return weekday(_S_days(__t)); + auto __parts = _M_spec._M_needed - _ChronoParts::_TotalSeconds; + if ((__parts & _ChronoParts::_DateTime) != 0) + __cd._M_fill_date_time(__cd._M_lseconds, __parts); + return _M_format_units(__cd, __ed, __ed - __cd._M_eseconds, __fc); } + }; + +#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI + template + struct __formatter_chrono_info + { + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, _ChronoParts(), {}); } - // Remove subsecond precision from a time_point. - template - static auto - _S_floor_seconds(const _Tp& __t) + template + typename basic_format_context<_Out, _CharT>::iterator + format(const _Info& __i, + basic_format_context<_Out, _CharT>& __fc) const { - using chrono::__detail::__local_time_fmt; - if constexpr (chrono::__is_time_point_v<_Tp> - || chrono::__is_duration_v<_Tp>) - { - if constexpr (_Tp::period::den != 1) - return chrono::floor(__t); - else - return __t; - } - else if constexpr (__is_specialization_of<_Tp, chrono::hh_mm_ss>) + // n.b. only acceptable chrono-spec for info is one containing + // only whitespaces and %%, that do not depend on formatted object. + if (!_M_f._M_spec._M_chrono_specs.empty()) [[unlikely]] + return _M_f._M_format(_ChronoData<_CharT>{}, __fc); + + const size_t __padwidth = _M_f._M_spec._M_get_width(__fc); + if (__padwidth == 0) + return _M_format_to(__fc.out(), __i); + + _Padding_sink<_Out, _CharT> __sink(__fc.out(), __padwidth); + _M_format_to(__sink.out(), __i); + return __sink._M_finish(_M_f._M_spec._M_align, _M_f._M_spec._M_fill); + } + + private: + template + _Out + _M_format_to(_Out __out, const chrono::sys_info& __si) const + { + using _FmtStr = _Runtime_format_string<_CharT>; + // n.b. only decimal separator is locale dependent for specifiers + // used below, as sys_info uses seconds and minutes duration, the + // output is locale-independent. + constexpr auto* __fs + = _GLIBCXX_WIDEN("[{0:%F %T},{1:%F %T},{2:%T},{3:%Q%q},{0:%Z}]"); + const chrono::local_seconds __lb(__si.begin.time_since_epoch()); + return std::format_to(std::move(__out), _FmtStr(__fs), + chrono::local_time_format(__lb, &__si.abbrev), + __si.end, __si.offset, __si.save); + } + + template + _Out + _M_format_to(_Out __out, const chrono::local_info& __li) const + { + *__out = _Separators<_CharT>::_S_squares()[0]; + ++__out; + if (__li.result == chrono::local_info::unique) + __out = _M_format_to(std::move(__out), __li.first); + else { - if constexpr (_Tp::fractional_width != 0) - return chrono::floor(__t.to_duration()); + basic_string_view<_CharT> __sv; + if (__li.result == chrono::local_info::nonexistent) + __sv =_GLIBCXX_WIDEN("nonexistent"); else - return __t; + __sv = _GLIBCXX_WIDEN("ambiguous"); + __out = __format::__write(std::move(__out), __sv); + + __sv = _GLIBCXX_WIDEN(" local time between "); + __out = __format::__write(std::move(__out), __sv); + __out = _M_format_to(std::move(__out), __li.first); + + __sv = _GLIBCXX_WIDEN(" and "); + __out = __format::__write(std::move(__out), __sv); + __out = _M_format_to(std::move(__out), __li.second); } - else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>) - return _S_floor_seconds(__t._M_time); - else - return __t; + *__out = _Separators<_CharT>::_S_squares()[1]; + ++__out; + return std::move(__out); } - // Use the formatting locale's std::time_put facet to produce - // a locale-specific representation. - template - _Iter - _M_locale_fmt(_Iter __out, const locale& __loc, const struct tm& __tm, - char __fmt, char __mod) const - { - basic_ostringstream<_CharT> __os; - __os.imbue(__loc); - const auto& __tp = use_facet>(__loc); - __tp.put(__os, __os, _S_space, &__tm, __fmt, __mod); - if (__os) - __out = _M_write(std::move(__out), __loc, __os.view()); - return __out; - } + __formatter_chrono<_CharT> _M_f; }; +#endif } // namespace __format /// @endcond @@ -1724,12 +2135,8 @@ namespace __format constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) { - using namespace __format; - auto __it = _M_f._M_parse(__pc, _Duration|_TimeOfDay); - if constexpr (!is_floating_point_v<_Rep>) - if (_M_f._M_spec._M_prec_kind != __format::_WP_none) - __throw_format_error("format error: invalid precision for duration"); - return __it; + using enum __format::_ChronoParts; + return _M_f.template _M_parse<_Duration>(__pc, _EpochTime, __defSpec); } template @@ -1747,16 +2154,54 @@ namespace __format using _URep = make_unsigned_t<_Rep>; auto __ucnt = -static_cast<_URep>(__d.count()); auto __ud = chrono::duration<_URep, _Period>(__ucnt); - return _M_f._M_format(__ud, __fc, true); + return _M_format(__ud, true, __fc); } else - return _M_f._M_format(-__d, __fc, true); + return _M_format(-__d, true, __fc); } - return _M_f._M_format(__d, __fc, false); + return _M_format(__d, false, __fc); } private: - __format::__formatter_chrono<_CharT> _M_f; + using _Duration = chrono::duration<_Rep, _Period>; + + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using enum __format::_ChronoParts; + auto __res = __format::__formatter_duration<_CharT>:: + template _S_spec_for<_Duration>(_None); + __res._M_localized = !is_integral_v<_Rep>; + // n.b. for integral format output is the same as ostream output + if constexpr (is_integral_v<_Rep>) + { + __res._M_needed = _EpochUnits|_UnitSuffix; + __res._M_chrono_specs = _GLIBCXX_WIDEN("%Q%q"); + } + return __res; + }(); + + template + typename basic_format_context<_Out, _CharT>::iterator + _M_format(const chrono::duration<_Rep2, _Period>& __d, + bool __is_neg, + basic_format_context<_Out, _CharT>& __fc) const + { + using namespace chrono; + using enum __format::_ChronoParts; + if constexpr (!is_integral_v<_Rep>) + if (_M_f._M_spec._M_chrono_specs.empty()) + return _M_f._M_format_to_ostream(__d, __is_neg, __fc); + + __format::_ChronoData<_CharT> __cd; + __cd._M_is_neg = __is_neg; + auto __ts = chrono::floor(__d); + __cd._M_eseconds = __ts; + if (_M_f._M_spec._M_needs(_HoursMinutesSeconds)) + __cd._M_fill_time(__ts); + return _M_f._M_format_units(__cd, __d, __d - __ts, __fc); + } + + __format::__formatter_duration<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -1764,16 +2209,35 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Day); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _Day|_WeekdayIndex, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::day& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + __cd._M_fill_day(__t, __defSpec._M_needed); + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_needed = _Day; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_d(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -1781,16 +2245,37 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Month); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _Month, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::month& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + __cd._M_month = __t; + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_localized = true; + __res._M_locale_specific = true; + __res._M_needed = _Month; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_m(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -1798,16 +2283,35 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Year); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _Year, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::year& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + __cd._M_year = __t; + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_needed = _Year; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_y(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -1815,16 +2319,37 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Weekday); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _Weekday, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::weekday& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + __cd._M_weekday = __t; + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_localized = true; + __res._M_locale_specific = true; + __res._M_needed = _Weekday; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_w(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -1832,16 +2357,37 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Weekday); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _IndexedWeekday, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::weekday_indexed& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + __cd._M_fill_weekday(__t, __defSpec._M_needed); + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_localized = true; + __res._M_locale_specific = true; + __res._M_needed = _IndexedWeekday; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_wi(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -1849,16 +2395,37 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Weekday); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _Weekday, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::weekday_last& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + __cd._M_weekday = __t.weekday(); + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_localized = true; + __res._M_locale_specific = true; + __res._M_needed = _Weekday; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_wl(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -1866,16 +2433,38 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Month|__format::_Day); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _Month|_Day|_WeekdayIndex, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::month_day& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + __cd._M_month = __t.month(); + __cd._M_fill_day(__t.day(), __defSpec._M_needed); + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_localized = true; + __res._M_locale_specific = true; + __res._M_needed = _Month|_Day; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_md(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -1883,16 +2472,37 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Month|__format::_Day); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _Month, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::month_day_last& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + __cd._M_month = __t.month(); + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_localized = true; + __res._M_locale_specific = true; + __res._M_needed = _Month; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_ml(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -1900,16 +2510,38 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Month|__format::_Weekday); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _Month|_IndexedWeekday, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::month_weekday& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + __cd._M_month = __t.month(); + __cd._M_fill_weekday(__t.weekday_indexed(), __defSpec._M_needed); + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_localized = true; + __res._M_locale_specific = true; + __res._M_needed = _Month|_IndexedWeekday; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_mwi(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -1917,16 +2549,38 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Month|__format::_Weekday); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _Month|_Weekday, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::month_weekday_last& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + __cd._M_month = __t.month(); + __cd._M_weekday = __t.weekday_last().weekday(); + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_localized = true; + __res._M_locale_specific = true; + __res._M_needed = _Month|_Weekday; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_mwl(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -1934,16 +2588,37 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Year|__format::_Month); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _Year|_Month, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::year_month& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + __cd._M_fill_year_month(__t, __defSpec._M_needed); + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_localized = true; + __res._M_locale_specific = true; + __res._M_needed = _Year|_Month; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_ym(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -1951,16 +2626,42 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Date); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _Date, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::year_month_day& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + auto __parts = _M_f._M_spec._M_needed; + __parts = __cd._M_fill_year_month(__t, __parts); + __parts = __cd._M_fill_day(__t.day(), __parts); + if (__parts == 0) + return _M_f._M_format(__cd, __fc); + + chrono::local_days __ld(__t); + __cd._M_fill_ldays(__ld, __parts); + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_needed = _YearMonthDay; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_f(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -1968,16 +2669,48 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Date); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _Date, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::year_month_day_last& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + auto __parts = _M_f._M_spec._M_needed; + __parts = __cd._M_fill_year_month(__t, __parts); + if (__parts == 0) + return _M_f._M_format(__cd, __fc); + + chrono::local_days __ld(__t); + __parts = __cd._M_fill_ldays(__ld, __parts); + if (__parts == 0) + return _M_f._M_format(__cd, __fc); + + chrono::year_month_day __ymd(__ld); + __cd._M_fill_day(__ymd.day(), __parts); + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_localized = true; + __res._M_locale_specific = true; + __res._M_needed = _Year|_Month; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_yml(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -1985,16 +2718,50 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Date); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _Date, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::year_month_weekday& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + auto __parts = _M_f._M_spec._M_needed; + __parts = __cd._M_fill_year_month(__t, __parts); + __parts = __cd._M_fill_weekday(__t.weekday_indexed(), __parts); + if (__parts == 0) + return _M_f._M_format(__cd, __fc); + + chrono::local_days __ld(__t); + __parts = __cd._M_fill_ldays(__ld, __parts); + if (__parts == 0) + return _M_f._M_format(__cd, __fc); + + chrono::year_month_day __ymd(__ld); + // n.b. weekday index is supplied by input, do not override it + __cd._M_day = __ymd.day(); + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_localized = true; + __res._M_locale_specific = true; + __res._M_needed = _Year|_Month|_IndexedWeekday; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_ymwi(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template<__format::__char _CharT> @@ -2002,16 +2769,50 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_Date); } + { + using enum __format::_ChronoParts; + return _M_f._M_parse(__pc, _Date, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::year_month_weekday_last& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + auto __parts = _M_f._M_spec._M_needed; + __parts = __cd._M_fill_year_month(__t, __parts); + __cd._M_weekday = __t.weekday_last().weekday(); + __parts -= __format::_ChronoParts::_Weekday; + if (__parts == 0) + return _M_f._M_format(__cd, __fc); + + chrono::local_days __ld(__t); + __parts = __cd._M_fill_ldays(__ld, __parts); + if (__parts == 0) + return _M_f._M_format(__cd, __fc); + + chrono::year_month_day __ymd(__ld); + __cd._M_fill_day(__ymd.day(), __parts); + return _M_f._M_format(__cd, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using __format::_ChronoFormats; + using enum __format::_ChronoParts; + + __format::_ChronoSpec<_CharT> __res{}; + __res._M_debug = true; + __res._M_localized = true; + __res._M_locale_specific = true; + __res._M_needed = _Year|_Month|_Weekday; + __res._M_chrono_specs = _ChronoFormats<_CharT>::_S_ymwl(); + return __res; + }(); + + __format::__formatter_chrono<_CharT> _M_f{__defSpec}; }; template @@ -2019,16 +2820,43 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_TimeOfDay); } + { + using enum __format::_ChronoParts; + return _M_f.template _M_parse<_Precision>(__pc, _Time, __defSpec); + } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::hh_mm_ss>& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + using enum __format::_ChronoParts; + + __format::_ChronoData<_CharT> __cd; + __cd._M_is_neg = __t.is_negative(); + __cd._M_hours = __t.hours(); + __cd._M_minutes = __t.minutes(); + __cd._M_seconds = __t.seconds(); + + _Precision __d(0); + // n.b. computing total duration or total seconds may overflow, + // do not compute them if not requested. + if (_M_f._M_spec._M_needs(_EpochUnits)) + __d = __t.to_duration(); + if (_M_f._M_spec._M_needs(_TotalSeconds)) + __cd._M_eseconds + = __cd._M_hours + __cd._M_minutes + __cd._M_seconds; + return _M_f._M_format_units(__cd, __d, __t.subseconds(), __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + using _Precision + = typename chrono::hh_mm_ss>::precision; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = + __format::__formatter_duration<_CharT>:: + template _S_spec_for<_Precision>(__format::_ChronoParts::_Time); + + __format::__formatter_duration<_CharT> _M_f{__defSpec}; }; #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI @@ -2037,16 +2865,16 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_ChronoParts{}); } + { return _M_f.parse(__pc); } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::sys_info& __i, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__i, __fc); } + { return _M_f.format(__i, __fc); } private: - __format::__formatter_chrono<_CharT> _M_f; + __format::__formatter_chrono_info<_CharT> _M_f; }; template<__format::__char _CharT> @@ -2054,16 +2882,16 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_ChronoParts{}); } + { return _M_f.parse(__pc); } template typename basic_format_context<_Out, _CharT>::iterator format(const chrono::local_info& __i, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__i, __fc); } + { return _M_f.format(__i, __fc); } private: - __format::__formatter_chrono<_CharT> _M_f; + __format::__formatter_chrono_info<_CharT> _M_f; }; #endif @@ -2073,7 +2901,9 @@ namespace __format constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) { - auto __next = _M_f._M_parse(__pc, __format::_ZonedDateTime); + using enum __format::_ChronoParts; + auto __next + = _M_f.template _M_parse<_Duration>(__pc, _ZonedDateTime, __defSpec); if constexpr (!__stream_insertable) if (_M_f._M_spec._M_chrono_specs.empty()) __format::__invalid_chrono_spec(); // chrono-specs can't be empty @@ -2084,14 +2914,34 @@ namespace __format typename basic_format_context<_Out, _CharT>::iterator format(const chrono::sys_time<_Duration>& __t, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + __cd._M_fill_utc_zone(); + + _Duration __ed = __t.time_since_epoch(); + __cd._M_eseconds = chrono::floor(__ed); + __cd._M_lseconds = chrono::local_seconds(__cd._M_eseconds); + return _M_f._M_format_time_point(__cd, __ed, __fc); + } private: static constexpr bool __stream_insertable = requires (basic_ostream<_CharT>& __os, chrono::sys_time<_Duration> __t) { __os << __t; }; - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using enum __format::_ChronoParts; + __format::_ChronoParts __needed = _DateTime; + if constexpr (!__stream_insertable) + __needed = _None; + else if constexpr (is_convertible_v<_Duration, chrono::days>) + __needed = _Date; + return __format::__formatter_duration<_CharT>:: + template _S_spec_for<_Duration>(__needed); + }(); + + __format::__formatter_duration<_CharT> _M_f{__defSpec}; }; template @@ -2100,32 +2950,43 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } + { + using enum __format::_ChronoParts; + return _M_f.template _M_parse<_Duration>(__pc, _ZonedDateTime, __defSpec); + } template - typename basic_format_context<_Out, _CharT>::iterator - format(const chrono::utc_time<_Duration>& __t, + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::utc_time<_Duration>& __t, basic_format_context<_Out, _CharT>& __fc) const { + using __format::_ChronoParts; + using namespace chrono; + __format::_ChronoData<_CharT> __cd{}; + __cd._M_fill_utc_zone(); + + _Duration __ed = __t.time_since_epoch(); + __cd._M_eseconds = chrono::floor(__ed); // Adjust by removing leap seconds to get equivalent sys_time. // We can't just use clock_cast because we want to know if the time // falls within a leap second insertion, and format seconds as "60". - using chrono::__detail::__utc_leap_second; - using chrono::seconds; - using chrono::sys_time; - using _CDur = common_type_t<_Duration, seconds>; const auto __li = chrono::get_leap_second_info(__t); - sys_time<_CDur> __s{__t.time_since_epoch() - __li.elapsed}; - if (!__li.is_leap_second) [[likely]] - return _M_f._M_format(__s, __fc); - else - return _M_f._M_format(__utc_leap_second(__s), __fc); + __cd._M_lseconds = local_seconds(__cd._M_eseconds - __li.elapsed); + auto __parts = _M_f._M_spec._M_needed - _ChronoParts::_TotalSeconds; + if ((__parts & _ChronoParts::_DateTime) != 0) + { + __cd._M_fill_date_time(__cd._M_lseconds, __parts); + __cd._M_seconds += seconds(__li.is_leap_second); + } + return _M_f._M_format_units(__cd, __ed, __ed - __cd._M_eseconds, __fc); } private: - friend formatter, _CharT>; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = + __format::__formatter_duration<_CharT>:: + template _S_spec_for<_Duration>(__format::_ChronoParts::_DateTime); - __format::__formatter_chrono<_CharT> _M_f; + __format::__formatter_duration<_CharT> _M_f{__defSpec}; }; template @@ -2134,29 +2995,34 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } + { + using enum __format::_ChronoParts; + return _M_f.template _M_parse<_Duration>(__pc, _ZonedDateTime, __defSpec); + } template - typename basic_format_context<_Out, _CharT>::iterator - format(const chrono::tai_time<_Duration>& __t, + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::tai_time<_Duration>& __t, basic_format_context<_Out, _CharT>& __fc) const { - // Convert to __local_time_fmt with abbrev "TAI" and offset 0s. - // We use __local_time_fmt and not sys_time (as the standard implies) - // because %Z for sys_time would print "UTC" and we want "TAI" here. + using namespace chrono; + __format::_ChronoData<_CharT> __cd{}; + __cd._M_fill_zone("TAI", L"TAI"); + _Duration __ed = __t.time_since_epoch(); + __cd._M_eseconds = chrono::floor(__ed); // Offset is 1970y/January/1 - 1958y/January/1 constexpr chrono::days __tai_offset = chrono::days(4383); - using _CDur = common_type_t<_Duration, chrono::days>; - chrono::local_time<_CDur> __lt(__t.time_since_epoch() - __tai_offset); - const string __abbrev("TAI", 3); - const chrono::seconds __off = 0s; - const auto __lf = chrono::local_time_format(__lt, &__abbrev, &__off); - return _M_f._M_format(__lf, __fc); + __cd._M_lseconds = local_seconds(__cd._M_eseconds - __tai_offset); + return _M_f._M_format_time_point(__cd, __ed, __fc); } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = + __format::__formatter_duration<_CharT>:: + template _S_spec_for<_Duration>(__format::_ChronoParts::_DateTime); + + __format::__formatter_duration<_CharT> _M_f{__defSpec}; }; template @@ -2165,29 +3031,34 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } + { + using enum __format::_ChronoParts; + return _M_f.template _M_parse<_Duration>(__pc, _ZonedDateTime, __defSpec); + } template - typename basic_format_context<_Out, _CharT>::iterator - format(const chrono::gps_time<_Duration>& __t, + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::gps_time<_Duration>& __t, basic_format_context<_Out, _CharT>& __fc) const { - // Convert to __local_time_fmt with abbrev "GPS" and offset 0s. - // We use __local_time_fmt and not sys_time (as the standard implies) - // because %Z for sys_time would print "UTC" and we want "GPS" here. + using namespace chrono; + __format::_ChronoData<_CharT> __cd{}; + __cd._M_fill_zone("GPS", L"GPS"); + _Duration __ed = __t.time_since_epoch(); + __cd._M_eseconds = chrono::floor(__ed); // Offset is 1980y/January/Sunday[1] - 1970y/January/1 constexpr chrono::days __gps_offset = chrono::days(3657); - using _CDur = common_type_t<_Duration, chrono::days>; - chrono::local_time<_CDur> __lt(__t.time_since_epoch() + __gps_offset); - const string __abbrev("GPS", 3); - const chrono::seconds __off = 0s; - const auto __lf = chrono::local_time_format(__lt, &__abbrev, &__off); - return _M_f._M_format(__lf, __fc); + __cd._M_lseconds = local_seconds(__cd._M_eseconds + __gps_offset); + return _M_f._M_format_time_point(__cd, __ed, __fc); } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = + __format::__formatter_duration<_CharT>:: + template _S_spec_for<_Duration>(__format::_ChronoParts::_DateTime); + + __format::__formatter_duration<_CharT> _M_f{__defSpec}; }; template @@ -2195,36 +3066,70 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } + { + using enum __format::_ChronoParts; + return _M_f.template _M_parse<_Duration>(__pc, _ZonedDateTime, __defSpec); + } template - typename basic_format_context<_Out, _CharT>::iterator - format(const chrono::file_time<_Duration>& __t, + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::file_time<_Duration>& __t, basic_format_context<_Out, _CharT>& __fc) const { using namespace chrono; - return _M_f._M_format(chrono::clock_cast(__t), __fc); + __format::_ChronoData<_CharT> __cd{}; + __cd._M_fill_utc_zone(); + + _Duration __ed = __t.time_since_epoch(); + __cd._M_eseconds = chrono::floor(__ed); + auto __st = chrono::clock_cast(__t); + __cd._M_lseconds + = local_seconds(chrono::floor(__st.time_since_epoch())); + return _M_f._M_format_time_point(__cd, __ed, __fc); } private: - __format::__formatter_chrono<_CharT> _M_f; - }; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = + __format::__formatter_duration<_CharT>:: + template _S_spec_for<_Duration>(__format::_ChronoParts::_DateTime); + + __format::__formatter_duration<_CharT> _M_f{__defSpec}; + }; template struct formatter, _CharT> { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_DateTime); } + { + using enum __format::_ChronoParts; + return _M_f.template _M_parse<_Duration>(__pc, _DateTime, __defSpec); + } template - typename basic_format_context<_Out, _CharT>::iterator - format(const chrono::local_time<_Duration>& __t, + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::local_time<_Duration>& __lt, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc); } + { + __format::_ChronoData<_CharT> __cd{}; + _Duration __ed = __lt.time_since_epoch(); + __cd._M_lseconds = chrono::floor(__lt); + __cd._M_eseconds = __cd._M_lseconds.time_since_epoch(); + return _M_f._M_format_time_point(__cd, __ed, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = [] + { + using enum __format::_ChronoParts; + __format::_ChronoParts __needed = _DateTime; + if constexpr (is_convertible_v<_Duration, chrono::days>) + __needed = _Date; + return __format::__formatter_duration<_CharT>:: + template _S_spec_for<_Duration>(__needed); + }(); + + __format::__formatter_duration<_CharT> _M_f{__defSpec}; }; template @@ -2232,16 +3137,59 @@ namespace __format { constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } + { + using enum __format::_ChronoParts; + return _M_f.template _M_parse<_Duration>(__pc, _ZonedDateTime, __defSpec); + } template - typename basic_format_context<_Out, _CharT>::iterator - format(const chrono::__detail::__local_time_fmt<_Duration>& __t, + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::__detail::__local_time_fmt<_Duration>& __zt, basic_format_context<_Out, _CharT>& __fc) const - { return _M_f._M_format(__t, __fc, /* use %Z for {} */ true); } + { + using enum __format::_ChronoParts; + __format::_ChronoData<_CharT> __cd{}; + + if (_M_f._M_spec._M_needs(_ZoneOffset)) + { + if (!__zt._M_offset_sec) + std::__throw_format_error("format error: no timezone available for %z"); + __cd._M_zone_offset = *__zt._M_offset_sec; + } + + basic_string<_CharT> __zone_store; + if (_M_f._M_spec._M_needs(_ZoneAbbrev)) + { + if (!__zt._M_abbrev) + std::__throw_format_error("format error: no timezone available for %Z"); + + __cd._M_zone_cstr = __zt._M_abbrev->data(); + if constexpr (is_same_v<_CharT, char>) + __cd._M_zone_abbrev = *__zt._M_abbrev; + else + { + // TODO: use resize_for_override + __zone_store.resize(__zt._M_abbrev->size()); + auto& __ct = use_facet>(_M_f._M_locale(__fc)); + __ct.widen(__zt._M_abbrev->data(), + __zt._M_abbrev->data() + __zt._M_abbrev->size(), + __zone_store.data()); + __cd._M_zone_abbrev = __zone_store; + } + } + + _Duration __ed = __zt._M_time.time_since_epoch(); + __cd._M_lseconds = chrono::floor(__zt._M_time); + __cd._M_eseconds = __cd._M_lseconds.time_since_epoch(); + return _M_f._M_format_time_point(__cd, __ed, __fc); + } private: - __format::__formatter_chrono<_CharT> _M_f; + static constexpr __format::_ChronoSpec<_CharT> __defSpec = + __format::__formatter_duration<_CharT>:: + template _S_spec_for<_Duration>(__format::_ChronoParts::_ZonedDateTime); + + __format::__formatter_duration<_CharT> _M_f{__defSpec}; }; #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI @@ -2250,8 +3198,8 @@ namespace __format : formatter, _CharT> { template - typename basic_format_context<_Out, _CharT>::iterator - format(const chrono::zoned_time<_Duration, _TimeZonePtr>& __tp, + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::zoned_time<_Duration, _TimeZonePtr>& __tp, basic_format_context<_Out, _CharT>& __fc) const { using _Ltf = chrono::__detail::__local_time_fmt_for<_Duration>; @@ -2265,18 +3213,6 @@ namespace __format }; #endif - // Partial specialization needed for %c formatting of __utc_leap_second. - template - struct formatter, _CharT> - : formatter, _CharT> - { - template - typename basic_format_context<_Out, _CharT>::iterator - format(const chrono::__detail::__utc_leap_second<_Duration>& __t, - basic_format_context<_Out, _CharT>& __fc) const - { return this->_M_f._M_format(__t, __fc); } - }; - namespace chrono { /// @addtogroup chrono @@ -2857,10 +3793,7 @@ namespace __detail basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_info& __i) { - __os << '[' << __i.begin << ',' << __i.end - << ',' << hh_mm_ss(__i.offset) << ',' << __i.save - << ',' << __i.abbrev << ']'; - return __os; + return __os << std::format(__os.getloc(), _GLIBCXX_WIDEN("{}"), __i); } /// Writes a local_info object to an ostream in an unspecified format. @@ -2868,19 +3801,19 @@ namespace __detail basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const local_info& __li) { - __os << '['; + __os << __format::_Separators<_CharT>::_S_squares()[0]; if (__li.result == local_info::unique) __os << __li.first; else { if (__li.result == local_info::nonexistent) - __os << "nonexistent"; + __os << _GLIBCXX_WIDEN("nonexistent"); else - __os << "ambiguous"; - __os << " local time between " << __li.first; - __os << " and " << __li.second; + __os << _GLIBCXX_WIDEN("ambiguous"); + __os << _GLIBCXX_WIDEN(" local time between ") << __li.first; + __os << _GLIBCXX_WIDEN(" and ") << __li.second; } - __os << ']'; + __os << __format::_Separators<_CharT>::_S_squares()[1]; return __os; } @@ -3037,8 +3970,7 @@ namespace __detail if (!__offset) __offset = &__off; using __format::_ChronoParts; - auto __need = _ChronoParts::_Year | _ChronoParts::_Month - | _ChronoParts::_Day | _ChronoParts::_TimeOfDay; + auto __need = _ChronoParts::_YearMonthDay | _ChronoParts::_TimeOfDay; __detail::_Parser_t<_Duration> __p(__need); if (__p(__is, __fmt, __abbrev, __offset)) { @@ -3096,8 +4028,7 @@ namespace __detail minutes* __offset = nullptr) { using __format::_ChronoParts; - auto __need = _ChronoParts::_Year | _ChronoParts::_Month - | _ChronoParts::_Day | _ChronoParts::_TimeOfDay; + auto __need = _ChronoParts::_YearMonthDay | _ChronoParts::_TimeOfDay; __detail::_Parser_t<_Duration> __p(__need); if (__p(__is, __fmt, __abbrev, __offset)) { @@ -3350,8 +4281,8 @@ namespace __detail minutes __tz_offset = __bad_min; basic_string<_CharT, _Traits> __tz_abbr; - if ((_M_need & _ChronoParts::_TimeOfDay) - && (_M_need & _ChronoParts::_Year)) + if ((_M_need & _ChronoParts::_TimeOfDay) != 0 + && (_M_need & _ChronoParts::_Year) != 0) { // For time_points assume "00:00:00" is implicitly present, // so we don't fail to parse if it's not (PR libstdc++/114240). @@ -3624,7 +4555,7 @@ namespace __detail } else { - if (_M_need & _ChronoParts::_TimeOfDay) + if ((_M_need & _ChronoParts::_TimeOfDay) != 0) __err |= ios_base::failbit; break; } @@ -3692,7 +4623,7 @@ namespace __detail __min = minutes(__val); else { - if (_M_need & _ChronoParts::_TimeOfDay) + if ((_M_need & _ChronoParts::_TimeOfDay) != 0) __err |= ios_base::failbit; break; } @@ -3782,7 +4713,7 @@ namespace __detail auto __val = __read_unsigned(2); if (__val == -1 || __val > 23) [[unlikely]] { - if (_M_need & _ChronoParts::_TimeOfDay) + if ((_M_need & _ChronoParts::_TimeOfDay) != 0) __err |= ios_base::failbit; break; } @@ -3793,7 +4724,7 @@ namespace __detail __val = __read_unsigned(2); if (__val == -1 || __val > 60) [[unlikely]] { - if (_M_need & _ChronoParts::_TimeOfDay) + if ((_M_need & _ChronoParts::_TimeOfDay) != 0) __err |= ios_base::failbit; break; } @@ -3828,7 +4759,7 @@ namespace __detail __s = seconds(__val); else { - if (_M_need & _ChronoParts::_TimeOfDay) + if ((_M_need & _ChronoParts::_TimeOfDay) != 0) __err |= ios_base::failbit; break; } @@ -4302,23 +5233,23 @@ namespace __detail // Whether the caller wants _M_wd. // The _Weekday bit is only set for chrono::weekday. - const bool __need_wday = _M_need & _ChronoParts::_Weekday; + const bool __need_wday = (_M_need & _ChronoParts::_Weekday) != 0; // Whether the caller wants _M_sys_days and _M_time. // Only true for durations and time_points. - const bool __need_time = _M_need & _ChronoParts::_TimeOfDay; + const bool __need_time = (_M_need & _ChronoParts::_TimeOfDay) != 0; if (__need_wday && __wday != __bad_wday) _M_wd = __wday; // Caller only wants a weekday and we have one. - else if (_M_need & _ChronoParts::_Date) // subsumes __need_wday + else if ((_M_need & _ChronoParts::_Date) != 0) // subsumes __need_wday { // Whether the caller wants _M_ymd. // True for chrono::year etc., false for time_points. const bool __need_ymd = !__need_wday && !__need_time; - if ((_M_need & _ChronoParts::_Year && __y == __bad_y) - || (_M_need & _ChronoParts::_Month && __m == __bad_mon) - || (_M_need & _ChronoParts::_Day && __d == __bad_day)) + if (((_M_need & _ChronoParts::_Year) != 0 && __y == __bad_y) + || ((_M_need & _ChronoParts::_Month) != 0 && __m == __bad_mon) + || ((_M_need & _ChronoParts::_Day) != 0 && __d == __bad_day)) { // Missing at least one of y/m/d so calculate sys_days // from the other data we have available. @@ -4395,7 +5326,7 @@ namespace __detail // but check that their values are in range. // Make unwanted fields valid so that _M_ymd.ok() is true. - if (_M_need & _ChronoParts::_Year) + if ((_M_need & _ChronoParts::_Year) != 0) { if (!__y.ok()) [[unlikely]] __err |= ios_base::failbit; @@ -4403,7 +5334,7 @@ namespace __detail else if (__y == __bad_y) __y = 1972y; // Leap year so that Feb 29 is valid. - if (_M_need & _ChronoParts::_Month) + if ((_M_need & _ChronoParts::_Month) != 0) { if (!__m.ok()) [[unlikely]] __err |= ios_base::failbit; @@ -4411,7 +5342,7 @@ namespace __detail else if (__m == __bad_mon) __m = January; - if (_M_need & _ChronoParts::_Day) + if ((_M_need & _ChronoParts::_Day) != 0) { if (__d < day(1) || __d > (__y/__m/last).day()) __err |= ios_base::failbit; diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h b/libstdc++-v3/include/bits/cpp_type_traits.h index b1a6206ce1eb..38cea4c67b76 100644 --- a/libstdc++-v3/include/bits/cpp_type_traits.h +++ b/libstdc++-v3/include/bits/cpp_type_traits.h @@ -273,6 +273,12 @@ __INT_N(__GLIBCXX_TYPE_INT_N_2) __INT_N(__GLIBCXX_TYPE_INT_N_3) #endif +#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ +// In strict modes __GLIBCXX_TYPE_INT_N_0 is not defined for __int128, +// but we want to always treat signed/unsigned __int128 as integral types. +__INT_N(__int128) +#endif + #undef __INT_N // @@ -307,6 +313,15 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3) typedef __true_type __type; }; +#ifdef _GLIBCXX_USE_FLOAT128 + template<> + struct __is_floating<__float128> + { + enum { __value = 1 }; + typedef __true_type __type; + }; +#endif + #ifdef __STDCPP_FLOAT16_T__ template<> struct __is_floating<_Float16> @@ -545,17 +560,6 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3) { enum { __width = __GLIBCXX_BITSIZE_INT_N_3 }; }; #endif -#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ - // In strict modes __is_integer<__int128> is false, - // but we want to allow memcpy between signed/unsigned __int128. - __extension__ - template<> - struct __memcpyable_integer<__int128> { enum { __width = 128 }; }; - __extension__ - template<> - struct __memcpyable_integer { enum { __width = 128 }; }; -#endif - #if _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 && _GLIBCXX_LDOUBLE_IS_IEEE_BINARY64 template<> struct __memcpyable { enum { __value = true }; }; diff --git a/libstdc++-v3/include/bits/formatfwd.h b/libstdc++-v3/include/bits/formatfwd.h index 777e6290f744..314b55d50bcd 100644 --- a/libstdc++-v3/include/bits/formatfwd.h +++ b/libstdc++-v3/include/bits/formatfwd.h @@ -162,6 +162,32 @@ namespace __format using __maybe_const = __conditional_t, const _Tp, _Tp>; } + + // [format.range], formatting of ranges + // [format.range.fmtkind], variable template format_kind + enum class range_format { + disabled, + map, + set, + sequence, + string, + debug_string + }; + + /** @brief A constant determining how a range should be formatted. + * + * The primary template of `std::format_kind` cannot be instantiated. + * There is a partial specialization for input ranges and you can + * specialize the variable template for your own cv-unqualified types + * that satisfy the `ranges::input_range` concept. + * + * @since C++23 + */ + template + constexpr auto format_kind = []{ + static_assert(false, "cannot use primary template of 'std::format_kind'"); + return type_identity<_Rg>{}; + }(); #endif // format_ranges _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/bits/functional_hash.h b/libstdc++-v3/include/bits/functional_hash.h index e84c9ee04be2..8456089f768d 100644 --- a/libstdc++-v3/include/bits/functional_hash.h +++ b/libstdc++-v3/include/bits/functional_hash.h @@ -199,6 +199,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_3 unsigned) #endif +#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ + // In strict modes __GLIBCXX_TYPE_INT_N_0 is not defined for __int128, + // but we want to always treat signed/unsigned __int128 as integral types. + __extension__ + _Cxx_hashtable_define_trivial_hash(__int128) + __extension__ + _Cxx_hashtable_define_trivial_hash(__int128 unsigned) +#endif + #undef _Cxx_hashtable_define_trivial_hash struct _Hash_impl diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h index 3b73ff9b6b59..979039e7da53 100644 --- a/libstdc++-v3/include/bits/iterator_concepts.h +++ b/libstdc++-v3/include/bits/iterator_concepts.h @@ -214,17 +214,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION = make_signed_t() - std::declval<_Tp>())>; }; -#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ - // __int128 is incrementable even if !integral<__int128> - template<> - struct incrementable_traits<__int128> - { using difference_type = __int128; }; - - template<> - struct incrementable_traits - { using difference_type = __int128; }; -#endif - namespace __detail { // An iterator such that iterator_traits<_Iter> names a specialization @@ -611,41 +600,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION class __max_diff_type; class __max_size_type; - __extension__ - template - concept __is_signed_int128 -#if __SIZEOF_INT128__ - = same_as<_Tp, __int128>; -#else - = false; -#endif - - __extension__ - template - concept __is_unsigned_int128 -#if __SIZEOF_INT128__ - = same_as<_Tp, unsigned __int128>; -#else - = false; -#endif - template concept __cv_bool = same_as; template concept __integral_nonbool = integral<_Tp> && !__cv_bool<_Tp>; - template - concept __is_int128 = __is_signed_int128<_Tp> || __is_unsigned_int128<_Tp>; - template concept __is_integer_like = __integral_nonbool<_Tp> - || __is_int128<_Tp> || same_as<_Tp, __max_diff_type> || same_as<_Tp, __max_size_type>; template concept __is_signed_integer_like = signed_integral<_Tp> - || __is_signed_int128<_Tp> || same_as<_Tp, __max_diff_type>; } // namespace ranges::__detail @@ -1022,19 +988,10 @@ namespace ranges { using std::__detail::__class_or_enum; - struct _Decay_copy final - { - template - constexpr decay_t<_Tp> - operator()(_Tp&& __t) const - noexcept(is_nothrow_convertible_v<_Tp, decay_t<_Tp>>) - { return std::forward<_Tp>(__t); } - } inline constexpr __decay_copy{}; - template concept __member_begin = requires(_Tp& __t) { - { __decay_copy(__t.begin()) } -> input_or_output_iterator; + { _GLIBCXX_AUTO_CAST(__t.begin()) } -> input_or_output_iterator; }; // Poison pill so that unqualified lookup doesn't find std::begin. @@ -1044,7 +1001,7 @@ namespace ranges concept __adl_begin = __class_or_enum> && requires(_Tp& __t) { - { __decay_copy(begin(__t)) } -> input_or_output_iterator; + { _GLIBCXX_AUTO_CAST(begin(__t)) } -> input_or_output_iterator; }; // Simplified version of std::ranges::begin that only supports lvalues, diff --git a/libstdc++-v3/include/bits/max_size_type.h b/libstdc++-v3/include/bits/max_size_type.h index 5bec0b5a519a..a34b91a04f1e 100644 --- a/libstdc++-v3/include/bits/max_size_type.h +++ b/libstdc++-v3/include/bits/max_size_type.h @@ -36,7 +36,9 @@ #if __cplusplus > 201703L && __cpp_lib_concepts #include +#include // __bit_width #include +#include // __glibcxx_integral_traps // This header implements unsigned and signed integer-class types (as per // [iterator.concept.winc]) that are one bit wider than the widest supported @@ -63,7 +65,7 @@ namespace ranges public: __max_size_type() = default; - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> constexpr __max_size_type(_Tp __i) noexcept : _M_val(__i), _M_msb(__i < 0) @@ -72,7 +74,7 @@ namespace ranges constexpr explicit __max_size_type(const __max_diff_type& __d) noexcept; - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> constexpr explicit operator _Tp() const noexcept { return _M_val; } @@ -258,52 +260,52 @@ namespace ranges return *this; } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator+=(_Tp& __a, const __max_size_type& __b) noexcept { return (__a = static_cast<_Tp>(__a + __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator-=(_Tp& __a, const __max_size_type& __b) noexcept { return (__a = static_cast<_Tp>(__a - __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator*=(_Tp& __a, const __max_size_type& __b) noexcept { return (__a = static_cast<_Tp>(__a * __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator/=(_Tp& __a, const __max_size_type& __b) noexcept { return (__a = static_cast<_Tp>(__a / __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator%=(_Tp& __a, const __max_size_type& __b) noexcept { return (__a = static_cast<_Tp>(__a % __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator&=(_Tp& __a, const __max_size_type& __b) noexcept { return (__a = static_cast<_Tp>(__a & __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator|=(_Tp& __a, const __max_size_type& __b) noexcept { return (__a = static_cast<_Tp>(__a | __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator^=(_Tp& __a, const __max_size_type& __b) noexcept { return (__a = static_cast<_Tp>(__a ^ __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator<<=(_Tp& __a, const __max_size_type& __b) noexcept { return (__a = static_cast<_Tp>(__a << __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator>>=(_Tp& __a, const __max_size_type& __b) noexcept { return (__a = static_cast<_Tp>(__a >> __b)); } @@ -425,10 +427,11 @@ namespace ranges using __rep = unsigned long long; #endif static constexpr size_t _S_rep_bits = sizeof(__rep) * __CHAR_BIT__; - private: + __rep _M_val = 0; unsigned _M_msb:1 = 0; + private: constexpr explicit __max_size_type(__rep __val, int __msb) noexcept : _M_val(__val), _M_msb(__msb) @@ -444,7 +447,7 @@ namespace ranges public: __max_diff_type() = default; - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> constexpr __max_diff_type(_Tp __i) noexcept : _M_rep(__i) @@ -455,7 +458,7 @@ namespace ranges : _M_rep(__d) { } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> constexpr explicit operator _Tp() const noexcept { return static_cast<_Tp>(_M_rep); } @@ -588,52 +591,52 @@ namespace ranges return *this; } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator+=(_Tp& __a, const __max_diff_type& __b) noexcept { return (__a = static_cast<_Tp>(__a + __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator-=(_Tp& __a, const __max_diff_type& __b) noexcept { return (__a = static_cast<_Tp>(__a - __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator*=(_Tp& __a, const __max_diff_type& __b) noexcept { return (__a = static_cast<_Tp>(__a * __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator/=(_Tp& __a, const __max_diff_type& __b) noexcept { return (__a = static_cast<_Tp>(__a / __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator%=(_Tp& __a, const __max_diff_type& __b) noexcept { return (__a = static_cast<_Tp>(__a % __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator&=(_Tp& __a, const __max_diff_type& __b) noexcept { return (__a = static_cast<_Tp>(__a & __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator|=(_Tp& __a, const __max_diff_type& __b) noexcept { return (__a = static_cast<_Tp>(__a | __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator^=(_Tp& __a, const __max_diff_type& __b) noexcept { return (__a = static_cast<_Tp>(__a ^ __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator<<=(_Tp& __a, const __max_diff_type& __b) noexcept { return (__a = static_cast<_Tp>(__a << __b)); } - template requires integral<_Tp> || __is_int128<_Tp> + template requires integral<_Tp> friend constexpr _Tp& operator>>=(_Tp& __a, const __max_diff_type& __b) noexcept { return (__a = static_cast<_Tp>(__a >> __b)); } @@ -752,7 +755,6 @@ namespace ranges { return !(__l < __r); } #endif - private: __max_size_type _M_rep = 0; friend class __max_size_type; @@ -774,10 +776,27 @@ namespace ranges static constexpr bool is_signed = false; static constexpr bool is_integer = true; static constexpr bool is_exact = true; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = true; + static constexpr bool traps = __glibcxx_integral_traps; + static constexpr int radix = 2; static constexpr int digits = __gnu_cxx::__int_traits<_Sp::__rep>::__digits + 1; static constexpr int digits10 = static_cast(digits * numbers::ln2 / numbers::ln10); + static constexpr int max_digits10 = 0; + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + static constexpr bool is_iec559 = false; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr bool has_denorm_loss = false; + static constexpr bool tinyness_before = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr float_round_style round_style = round_toward_zero; static constexpr _Sp min() noexcept @@ -790,6 +809,30 @@ namespace ranges static constexpr _Sp lowest() noexcept { return min(); } + + static constexpr _Sp + denorm_min() noexcept + { return 0; } + + static constexpr _Sp + epsilon() noexcept + { return 0; } + + static constexpr _Sp + round_error() noexcept + { return 0; } + + static constexpr _Sp + infinity() noexcept + { return 0; } + + static constexpr _Sp + quiet_NaN() noexcept + { return 0; } + + static constexpr _Sp + signaling_NaN() noexcept + { return 0; } }; template<> @@ -801,9 +844,26 @@ namespace ranges static constexpr bool is_signed = true; static constexpr bool is_integer = true; static constexpr bool is_exact = true; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + static constexpr bool traps = __glibcxx_integral_traps; + static constexpr int radix = 2; static constexpr int digits = numeric_limits<_Sp>::digits - 1; static constexpr int digits10 = static_cast(digits * numbers::ln2 / numbers::ln10); + static constexpr int max_digits10 = 0; + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + static constexpr bool is_iec559 = false; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr bool has_denorm_loss = false; + static constexpr bool tinyness_before = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr float_round_style round_style = round_toward_zero; static constexpr _Dp min() noexcept @@ -816,8 +876,42 @@ namespace ranges static constexpr _Dp lowest() noexcept { return min(); } + + static constexpr _Dp + denorm_min() noexcept + { return 0; } + + static constexpr _Dp + epsilon() noexcept + { return 0; } + + static constexpr _Dp + round_error() noexcept + { return 0; } + + static constexpr _Dp + infinity() noexcept + { return 0; } + + static constexpr _Dp + quiet_NaN() noexcept + { return 0; } + + static constexpr _Dp + signaling_NaN() noexcept + { return 0; } }; + template<> + inline constexpr int + __bit_width(ranges::__detail::__max_size_type __x) noexcept + { + if (__x._M_msb) + return numeric_limits::digits; + else + return std::__bit_width(__x._M_val); + } + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h index 085ca074fc88..061e6b4de3d8 100644 --- a/libstdc++-v3/include/bits/move.h +++ b/libstdc++-v3/include/bits/move.h @@ -215,14 +215,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @return Nothing. */ template - _GLIBCXX20_CONSTEXPR - inline -#if __cplusplus >= 201103L - typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>, - is_move_constructible<_Tp>, - is_move_assignable<_Tp>>::value>::type +#if __glibcxx_concepts // >= C++20 + requires (! __is_tuple_like<_Tp>::value) + && is_move_constructible_v<_Tp> + && is_move_assignable_v<_Tp> + constexpr void +#elif __cplusplus >= 201103L + _GLIBCXX20_CONSTEXPR inline + __enable_if_t<__and_<__not_<__is_tuple_like<_Tp>>, + is_move_constructible<_Tp>, + is_move_assignable<_Tp>>::value> #else - void + inline void #endif swap(_Tp& __a, _Tp& __b) _GLIBCXX_NOEXCEPT_IF(__and_, @@ -241,12 +245,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // DR 809. std::swap should be overloaded for array types. /// Swap the contents of two arrays. template - _GLIBCXX20_CONSTEXPR - inline -#if __cplusplus >= 201103L - typename enable_if<__is_swappable<_Tp>::value>::type +#if __glibcxx_concepts // >= C++20 + requires is_swappable_v<_Tp> + constexpr void +#elif __cplusplus >= 201103L + _GLIBCXX20_CONSTEXPR inline + __enable_if_t<__is_swappable<_Tp>::value> #else - void + inline void #endif swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Tp>::value) diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index a62c3cd3954d..9f8945a7133a 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -32,6 +32,7 @@ #if __cplusplus > 201703L +#include // __bit_width #if __cplusplus > 202002L #include #endif @@ -47,28 +48,60 @@ namespace ranges { namespace __detail { + template + using __by_ref_or_value_fn + = __conditional_t || is_empty_v<_Fp>, _Fp, _Fp&>; + template - constexpr auto + struct _Comp_proj + { + [[no_unique_address]] __by_ref_or_value_fn<_Comp> _M_comp; + [[no_unique_address]] __by_ref_or_value_fn<_Proj> _M_proj; + + constexpr + _Comp_proj(_Comp& __comp, _Proj& __proj) + : _M_comp(__comp), _M_proj(__proj) + { } + + template + constexpr bool + operator()(_Tp&& __x, _Up&& __y) + { + return std::__invoke(_M_comp, + std::__invoke(_M_proj, std::forward<_Tp>(__x)), + std::__invoke(_M_proj, std::forward<_Up>(__y))); + } + }; + + template + constexpr _Comp_proj<_Comp, _Proj> __make_comp_proj(_Comp& __comp, _Proj& __proj) + { return {__comp, __proj}; } + + template + struct _Pred_proj { - return [&] (auto&& __lhs, auto&& __rhs) -> bool { - using _TL = decltype(__lhs); - using _TR = decltype(__rhs); - return std::__invoke(__comp, - std::__invoke(__proj, std::forward<_TL>(__lhs)), - std::__invoke(__proj, std::forward<_TR>(__rhs))); - }; - } + [[no_unique_address]] __by_ref_or_value_fn<_Pred> _M_pred; + [[no_unique_address]] __by_ref_or_value_fn<_Proj> _M_proj; + + constexpr + _Pred_proj(_Pred& __pred, _Proj& __proj) + : _M_pred(__pred), _M_proj(__proj) + { } + + template + constexpr bool + operator()(_Tp&& __x) + { + return std::__invoke(_M_pred, + std::__invoke(_M_proj, std::forward<_Tp>(__x))); + } + }; template - constexpr auto + constexpr _Pred_proj<_Pred, _Proj> __make_pred_proj(_Pred& __pred, _Proj& __proj) - { - return [&] (_Tp&& __arg) -> bool { - return std::__invoke(__pred, - std::__invoke(__proj, std::forward<_Tp>(__arg))); - }; - } + { return {__pred, __proj}; } } // namespace __detail struct __all_of_fn @@ -1261,7 +1294,7 @@ namespace ranges for (; __first != __last; ++__first) if (!std::__invoke(__pred, std::__invoke(__proj, *__first))) { - *__result = std::move(*__first); + *__result = ranges::iter_move(__first); ++__result; } @@ -1421,7 +1454,7 @@ namespace ranges if (!std::__invoke(__comp, std::__invoke(__proj, *__dest), std::__invoke(__proj, *__first))) - *++__dest = std::move(*__first); + *++__dest = ranges::iter_move(__first); return {++__dest, __first}; } @@ -1806,14 +1839,70 @@ namespace ranges operator()(_Iter __first, _Sent __last, _Out __out, iter_difference_t<_Iter> __n, _Gen&& __g) const { + // FIXME: Correctly handle integer-class difference types. if constexpr (forward_iterator<_Iter>) { - // FIXME: Forwarding to std::sample here requires computing __lasti - // which may take linear time. - auto __lasti = ranges::next(__first, __last); - return _GLIBCXX_STD_A:: - sample(std::move(__first), std::move(__lasti), std::move(__out), - __n, std::forward<_Gen>(__g)); + using _Size = iter_difference_t<_Iter>; + using __distrib_type = uniform_int_distribution<_Size>; + using __param_type = typename __distrib_type::param_type; + using _USize = __detail::__make_unsigned_like_t<_Size>; + using __uc_type + = common_type_t::result_type, _USize>; + + if (__first == __last) + return __out; + + __distrib_type __d{}; + _Size __unsampled_sz = ranges::distance(__first, __last); + __n = std::min(__n, __unsampled_sz); + + // If possible, we use __gen_two_uniform_ints to efficiently produce + // two random numbers using a single distribution invocation: + + const __uc_type __urngrange = __g.max() - __g.min(); + if (__urngrange / __uc_type(__unsampled_sz) >= __uc_type(__unsampled_sz)) + // I.e. (__urngrange >= __unsampled_sz * __unsampled_sz) but without + // wrapping issues. + { + while (__n != 0 && __unsampled_sz >= 2) + { + const pair<_Size, _Size> __p = + __gen_two_uniform_ints(__unsampled_sz, __unsampled_sz - 1, __g); + + --__unsampled_sz; + if (__p.first < __n) + { + *__out = *__first; + ++__out; + --__n; + } + + ++__first; + + if (__n == 0) break; + + --__unsampled_sz; + if (__p.second < __n) + { + *__out = *__first; + ++__out; + --__n; + } + + ++__first; + } + } + + // The loop above is otherwise equivalent to this one-at-a-time version: + + for (; __n != 0; ++__first) + if (__d(__g, __param_type{0, --__unsampled_sz}) < __n) + { + *__out = *__first; + ++__out; + --__n; + } + return __out; } else { @@ -1834,7 +1923,7 @@ namespace ranges if (__k < __n) __out[__k] = *__first; } - return __out + __sample_sz; + return __out + iter_difference_t<_Out>(__sample_sz); } } @@ -1863,9 +1952,61 @@ namespace ranges _Iter operator()(_Iter __first, _Sent __last, _Gen&& __g) const { - auto __lasti = ranges::next(__first, __last); - std::shuffle(std::move(__first), __lasti, std::forward<_Gen>(__g)); - return __lasti; + // FIXME: Correctly handle integer-class difference types. + if (__first == __last) + return __first; + + using _DistanceType = iter_difference_t<_Iter>; + using __ud_type = __detail::__make_unsigned_like_t<_DistanceType>; + using __distr_type = std::uniform_int_distribution<__ud_type>; + using __p_type = typename __distr_type::param_type; + + using __uc_type + = common_type_t::result_type, __ud_type>; + + const __uc_type __urngrange = __g.max() - __g.min(); + const __uc_type __urange = __uc_type(__last - __first); + + if (__urngrange / __urange >= __urange) + // I.e. (__urngrange >= __urange * __urange) but without wrap issues. + { + _Iter __i = __first + 1; + + // Since we know the range isn't empty, an even number of elements + // means an uneven number of elements /to swap/, in which case we + // do the first one up front: + + if ((__urange % 2) == 0) + { + __distr_type __d{0, 1}; + ranges::iter_swap(__i++, __first + __d(__g)); + } + + // Now we know that __last - __i is even, so we do the rest in pairs, + // using a single distribution invocation to produce swap positions + // for two successive elements at a time: + + while (__i != __last) + { + const __uc_type __swap_range = __uc_type(__i - __first) + 1; + + const pair<__uc_type, __uc_type> __pospos = + __gen_two_uniform_ints(__swap_range, __swap_range + 1, __g); + + ranges::iter_swap(__i++, __first + __pospos.first); + ranges::iter_swap(__i++, __first + __pospos.second); + } + + return __i; + } + + __distr_type __d; + + _Iter __i = __first + 1; + for (; __i != __last; ++__i) + ranges::iter_swap(__i, __first + __d(__g, __p_type(0, __i - __first))); + + return __i; } template @@ -1881,6 +2022,28 @@ namespace ranges inline constexpr __shuffle_fn shuffle{}; + namespace __detail + { + template + constexpr void + __push_heap(_Iter __first, + iter_difference_t<_Iter> __holeIndex, + iter_difference_t<_Iter> __topIndex, + iter_value_t<_Iter> __value, + _Comp __comp) + { + auto __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex + && __comp(*(__first + __parent), __value)) + { + *(__first + __holeIndex) = ranges::iter_move(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = std::move(__value); + } + } // namespace __detail + struct __push_heap_fn { template _Sent, @@ -1890,10 +2053,17 @@ namespace ranges operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { - auto __lasti = ranges::next(__first, __last); - std::push_heap(__first, __lasti, - __detail::__make_comp_proj(__comp, __proj)); - return __lasti; + if constexpr (!same_as<_Iter, _Sent>) + return (*this)(__first, ranges::next(__first, __last), + std::move(__comp), std::move(__proj)); + else + { + auto __comp_proj = __detail::__make_comp_proj(__comp, __proj); + __detail::__push_heap(__first, (__last - __first) - 1, + 0, ranges::iter_move(__last - 1), + __comp_proj); + return __last; + } } template + constexpr void + __adjust_heap(_Iter __first, + iter_difference_t<_Iter> __holeIndex, + iter_difference_t<_Iter> __len, + iter_value_t<_Iter> __value, + _Comp __comp) + { + auto __topIndex = __holeIndex; + auto __secondChild = __holeIndex; + while (__secondChild < (__len - 1) / 2) + { + __secondChild = 2 * (__secondChild + 1); + if (__comp(*(__first + __secondChild), + *(__first + (__secondChild - 1)))) + __secondChild--; + *(__first + __holeIndex) = ranges::iter_move(__first + __secondChild); + __holeIndex = __secondChild; + } + if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2) + { + __secondChild = 2 * (__secondChild + 1); + *(__first + __holeIndex) = ranges::iter_move(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; + } + __detail::__push_heap(__first, __holeIndex, __topIndex, + std::move(__value), __comp); + } + + template + constexpr void + __pop_heap(_Iter __first, _Iter __last, _Iter __result, _Comp __comp) + { + iter_value_t<_Iter> __value = ranges::iter_move(__result); + *__result = ranges::iter_move(__first); + __detail::__adjust_heap(__first, 0, __last - __first, + std::move(__value), __comp); + } + } // namespace __detail + struct __pop_heap_fn { template _Sent, @@ -1918,10 +2130,18 @@ namespace ranges operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { - auto __lasti = ranges::next(__first, __last); - std::pop_heap(__first, __lasti, - __detail::__make_comp_proj(__comp, __proj)); - return __lasti; + if constexpr (!same_as<_Iter, _Sent>) + return (*this)(__first, ranges::next(__first, __last), + std::move(__comp), std::move(__proj)); + else + { + if (__last - __first > 1) + { + auto __comp_proj = __detail::__make_comp_proj(__comp, __proj); + __detail::__pop_heap(__first, __last - 1, __last - 1, __comp_proj); + } + return __last; + } } template) + return (*this)(__first, ranges::next(__first, __last), + std::move(__comp), std::move(__proj)); + else + { + const auto __len = __last - __first; + if (__len < 2) + return __last; + + auto __comp_proj = __detail::__make_comp_proj(__comp, __proj); + auto __parent = (__len - 2) / 2; + while (true) + { + iter_value_t<_Iter> __value = ranges::iter_move(__first + __parent); + __detail::__adjust_heap(__first, __parent, __len, + std::move(__value), + __comp_proj); + if (__parent == 0) + break; + __parent--; + } + return __last; + } } template) + return (*this)(__first, ranges::next(__first, __last), + std::move(__comp), std::move(__proj)); + else + { + auto __comp_proj = __detail::__make_comp_proj(__comp, __proj); + _Iter __ret = __last; + while (__last - __first > 1) + { + --__last; + __detail::__pop_heap(__first, __last, __last, __comp_proj); + } + return __ret; + } } template + constexpr void + __move_median_to_first(_Iter __result, _Iter __a, _Iter __b, _Iter __c, + _Comp __comp) + { + if (__comp(*__a, *__b)) + { + if (__comp(*__b, *__c)) + ranges::iter_swap(__result, __b); + else if (__comp(*__a, *__c)) + ranges::iter_swap(__result, __c); + else + ranges::iter_swap(__result, __a); + } + else if (__comp(*__a, *__c)) + ranges::iter_swap(__result, __a); + else if (__comp(*__b, *__c)) + ranges::iter_swap(__result, __c); + else + ranges::iter_swap(__result, __b); + } + + template + constexpr void + __unguarded_linear_insert(_Iter __last, _Comp __comp) + { + iter_value_t<_Iter> __val = ranges::iter_move(__last); + _Iter __next = __last; + --__next; + while (__comp(__val, *__next)) + { + *__last = ranges::iter_move(__next); + __last = __next; + --__next; + } + *__last = std::move(__val); + } + + template + constexpr void + __insertion_sort(_Iter __first, _Iter __last, _Comp __comp) + { + if (__first == __last) + return; + + for (_Iter __i = __first + 1; __i != __last; ++__i) + { + if (__comp(*__i, *__first)) + { + iter_value_t<_Iter> __val = ranges::iter_move(__i); + ranges::move_backward(__first, __i, __i + 1); + *__first = std::move(__val); + } + else + __detail::__unguarded_linear_insert(__i, __comp); + } + } + + template + constexpr void + __unguarded_insertion_sort(_Iter __first, _Iter __last, _Comp __comp) + { + for (_Iter __i = __first; __i != __last; ++__i) + __detail::__unguarded_linear_insert(__i, __comp); + } + + inline constexpr int __sort_threshold = 16; + + template + constexpr void + __final_insertion_sort(_Iter __first, _Iter __last, _Comp __comp) + { + if (__last - __first > __sort_threshold) + { + __detail::__insertion_sort(__first, __first + __sort_threshold, __comp); + __detail::__unguarded_insertion_sort(__first + __sort_threshold, __last, + __comp); + } + else + __detail::__insertion_sort(__first, __last, __comp); + } + + template + constexpr _Iter + __unguarded_partition(_Iter __first, _Iter __last, _Iter __pivot, _Comp __comp) + { + while (true) + { + while (__comp(*__first, *__pivot)) + ++__first; + --__last; + while (__comp(*__pivot, *__last)) + --__last; + if (!(__first < __last)) + return __first; + ranges::iter_swap(__first, __last); + ++__first; + } + } + + template + constexpr _Iter + __unguarded_partition_pivot(_Iter __first, _Iter __last, _Comp __comp) + { + _Iter __mid = __first + (__last - __first) / 2; + __detail::__move_median_to_first(__first, __first + 1, __mid, __last - 1, __comp); + return __detail::__unguarded_partition(__first + 1, __last, __first, __comp); + } + + template + constexpr void + __heap_select(_Iter __first, _Iter __middle, _Iter __last, _Comp __comp) + { + ranges::make_heap(__first, __middle, __comp); + for (_Iter __i = __middle; __i < __last; ++__i) + if (__comp(*__i, *__first)) + __detail::__pop_heap(__first, __middle, __i, __comp); + } + + template + constexpr void + __partial_sort(_Iter __first, _Iter __middle, _Iter __last, _Comp __comp) + { + __detail::__heap_select(__first, __middle, __last, __comp); + ranges::sort_heap(__first, __middle, __comp); + } + + template + constexpr void + __introsort_loop(_Iter __first, _Iter __last, unsigned __depth_limit, _Comp __comp) + { + while (__last - __first > __sort_threshold) + { + if (__depth_limit == 0) + { + __detail::__partial_sort(__first, __last, __last, __comp); + return; + } + --__depth_limit; + _Iter __cut = __detail::__unguarded_partition_pivot(__first, __last, __comp); + __detail::__introsort_loop(__cut, __last, __depth_limit, __comp); + __last = __cut; + } + } + } // namespace __detail + struct __sort_fn { template _Sent, @@ -2069,10 +2466,21 @@ namespace ranges operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { - auto __lasti = ranges::next(__first, __last); - _GLIBCXX_STD_A::sort(std::move(__first), __lasti, - __detail::__make_comp_proj(__comp, __proj)); - return __lasti; + if constexpr (!same_as<_Iter, _Sent>) + return (*this)(__first, ranges::next(__first, __last), + std::move(__comp), std::move(__proj)); + else + { + if (__first != __last) + { + auto __comp_proj = __detail::__make_comp_proj(__comp, __proj); + auto __n = __detail::__to_unsigned_like(__last - __first); + unsigned __depth_limit = (std::__bit_width(__n) - 1) * 2; + __detail::__introsort_loop(__first, __last, __depth_limit, __comp_proj); + __detail::__final_insertion_sort(__first, __last, __comp_proj); + } + return __last; + } } template + _Out + __move_merge(_Iter __first1, _Iter __last1, + _Iter __first2, _Iter __last2, + _Out __result, _Comp __comp) + { + while (__first1 != __last1 && __first2 != __last2) + { + if (__comp(*__first2, *__first1)) + { + *__result = ranges::iter_move(__first2); + ++__first2; + } + else + { + *__result = ranges::iter_move(__first1); + ++__first1; + } + ++__result; + } + return ranges::move(__first2, __last2, + ranges::move(__first1, __last1, __result).out).out; + } + + template + void + __merge_sort_loop(_Iter __first, _Iter __last, _Out __result, + _Distance __step_size, _Comp __comp) + { + const _Distance __two_step = 2 * __step_size; + + while (__last - __first >= __two_step) + { + __result = __detail::__move_merge(__first, __first + __step_size, + __first + __step_size, + __first + __two_step, + __result, __comp); + __first += __two_step; + } + __step_size = ranges::min(_Distance(__last - __first), __step_size); + + __detail::__move_merge(__first, __first + __step_size, + __first + __step_size, __last, __result, __comp); + } + + template + constexpr void + __chunk_insertion_sort(_Iter __first, _Iter __last, + _Distance __chunk_size, _Compare __comp) + { + while (__last - __first >= __chunk_size) + { + __detail::__insertion_sort(__first, __first + __chunk_size, __comp); + __first += __chunk_size; + } + __detail::__insertion_sort(__first, __last, __comp); + } + + template + void + __merge_sort_with_buffer(_Iter __first, _Iter __last, + _Pointer __buffer, _Comp __comp) + { + using _Distance = iter_difference_t<_Iter>; + + const _Distance __len = __last - __first; + const _Pointer __buffer_last = __buffer + ptrdiff_t(__len); + + constexpr int __chunk_size = 7; + _Distance __step_size = __chunk_size; + __detail::__chunk_insertion_sort(__first, __last, __step_size, __comp); + + while (__step_size < __len) + { + __detail::__merge_sort_loop(__first, __last, __buffer, + __step_size, __comp); + __step_size *= 2; + __detail::__merge_sort_loop(__buffer, __buffer_last, __first, + ptrdiff_t(__step_size), __comp); + __step_size *= 2; + } + } + + template + void + __merge_adaptive(_Iter __first, _Iter __middle, _Iter __last, + iter_difference_t<_Iter> __len1, + iter_difference_t<_Iter> __len2, + _Pointer __buffer, _Comp __comp); // defined near inplace_merge + + template + void + __merge_adaptive_resize(_Iter __first, _Iter __middle, _Iter __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size, + _Comp __comp); // defined near inplace_merge + + template + constexpr void + __merge_without_buffer(_Iter __first, _Iter __middle, _Iter __last, + _Distance __len1, _Distance __len2, + _Comp __comp); // defined near inplace_merge + + template + void + __stable_sort_adaptive(_Iter __first, _Iter __middle, _Iter __last, + _Pointer __buffer, _Comp __comp) + { + __detail::__merge_sort_with_buffer(__first, __middle, __buffer, __comp); + __detail::__merge_sort_with_buffer(__middle, __last, __buffer, __comp); + + __detail::__merge_adaptive(__first, __middle, __last, + __middle - __first, __last - __middle, + __buffer, __comp); + } + + template + void + __stable_sort_adaptive_resize(_Iter __first, _Iter __last, + _Pointer __buffer, _Distance __buffer_size, + _Comp __comp) + { + const _Distance __len = (__last - __first + 1) / 2; + const _Iter __middle = __first + __len; + if (__len > __buffer_size) + { + __detail::__stable_sort_adaptive_resize(__first, __middle, __buffer, + __buffer_size, __comp); + __detail::__stable_sort_adaptive_resize(__middle, __last, __buffer, + __buffer_size, __comp); + __detail::__merge_adaptive_resize(__first, __middle, __last, + _Distance(__middle - __first), + _Distance(__last - __middle), + __buffer, __buffer_size, + __comp); + } + else + __detail::__stable_sort_adaptive(__first, __middle, __last, + __buffer, __comp); + } + + template + constexpr void + __inplace_stable_sort(_Iter __first, _Iter __last, _Comp __comp) + { + if (__last - __first < 15) + { + __detail::__insertion_sort(__first, __last, __comp); + return; + } + _Iter __middle = __first + (__last - __first) / 2; + __detail::__inplace_stable_sort(__first, __middle, __comp); + __detail::__inplace_stable_sort(__middle, __last, __comp); + __detail::__merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle, + __comp); + } + } // namespace __detail + struct __stable_sort_fn { template _Sent, @@ -2098,10 +2669,46 @@ namespace ranges operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { - auto __lasti = ranges::next(__first, __last); - std::stable_sort(std::move(__first), __lasti, - __detail::__make_comp_proj(__comp, __proj)); - return __lasti; + if constexpr (!same_as<_Iter, _Sent>) + return (*this)(__first, ranges::next(__first, __last), + std::move(__comp), std::move(__proj)); + else + { + using _DistanceType = iter_difference_t<_Iter>; + + if (__first == __last) + return __last; + + auto __comp_proj = __detail::__make_comp_proj(__comp, __proj); + +#if _GLIBCXX_HOSTED +# if __glibcxx_constexpr_algorithms >= 202306L // >= C++26 + if consteval { + __detail::__inplace_stable_sort(__first, __last, __comp_proj); + return __last; + } +# endif + + typedef _Temporary_buffer<_Iter, iter_value_t<_Iter>> _TmpBuf; + // __stable_sort_adaptive sorts the range in two halves, + // so the buffer only needs to fit half the range at once. + _TmpBuf __buf(__first, ptrdiff_t((__last - __first + 1) / 2)); + + if (__buf._M_requested_size() == __buf.size()) [[likely]] + __detail::__stable_sort_adaptive(__first, + __first + _DistanceType(__buf.size()), + __last, __buf.begin(), __comp_proj); + else if (__buf.begin()) [[unlikely]] + __detail::__inplace_stable_sort(__first, __last, __comp_proj); + else + __detail::__stable_sort_adaptive_resize(__first, __last, __buf.begin(), + _DistanceType(__buf.size()), + __comp_proj); +#else + __detail::__inplace_stable_sort(__first, __last, __comp_proj); +#endif + return __last; + } } template + constexpr void + __introselect(_Iter __first, _Iter __nth, _Iter __last, + iter_difference_t<_Iter> __depth_limit, _Comp __comp) + { + while (__last - __first > 3) + { + if (__depth_limit == 0) + { + __detail::__heap_select(__first, __nth + 1, __last, __comp); + // Place the nth largest element in its final position. + ranges::iter_swap(__first, __nth); + return; + } + --__depth_limit; + _Iter __cut = __detail::__unguarded_partition_pivot(__first, __last, __comp); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + __detail::__insertion_sort(__first, __last, __comp); + } + } // namespace __detail + struct __nth_element_fn { template _Sent, @@ -2315,11 +2949,21 @@ namespace ranges operator()(_Iter __first, _Iter __nth, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { - auto __lasti = ranges::next(__first, __last); - _GLIBCXX_STD_A::nth_element(std::move(__first), std::move(__nth), - __lasti, - __detail::__make_comp_proj(__comp, __proj)); - return __lasti; + if constexpr (!same_as<_Iter, _Sent>) + return (*this)(__first, __nth, ranges::next(__first, __last), + std::move(__comp), std::move(__proj)); + else + { + if (__first == __last || __nth == __last) + return __last; + + auto __comp_proj = __detail::__make_comp_proj(__comp, __proj); + auto __n = __detail::__to_unsigned_like(__last - __first); + __detail::__introselect(__first, __nth, __last, + std::__bit_width(__n) * 2, + __comp_proj); + return __last; + } } template + constexpr _Iter + __find_if_not_n(_Iter __first, _Distance& __len, _Pred __pred) + { + for (; __len; --__len, (void) ++__first) + if (!__pred(*__first)) + break; + return __first; + } + + template + constexpr subrange<_Iter> + __stable_partition_adaptive(_Iter __first, _Sent __last, + _Pred __pred, _Distance __len, + _Pointer __buffer, + _Distance __buffer_size) + { + if (__len == 1) + return {__first, ranges::next(__first, 1)}; + + if (__len <= __buffer_size) + { + _Iter __result1 = __first; + _Pointer __result2 = __buffer; + + // The precondition guarantees that !__pred(__first), so + // move that element to the buffer before starting the loop. + // This ensures that we only call __pred once per element. + *__result2 = ranges::iter_move(__first); + ++__result2; + ++__first; + for (; __first != __last; ++__first) + if (__pred(*__first)) + { + *__result1 = ranges::iter_move(__first); + ++__result1; + } + else + { + *__result2 = ranges::iter_move(__first); + ++__result2; + } + + ranges::move(__buffer, __result2, __result1); + return {__result1, __first}; + } + + _Iter __middle = __first; + ranges::advance(__middle, __len / 2); + _Iter __left_split + = __detail::__stable_partition_adaptive(__first, __middle, __pred, + __len / 2, __buffer, + __buffer_size).begin(); + + // Advance past true-predicate values to satisfy this + // function's preconditions. + _Distance __right_len = __len - __len / 2; + _Iter __right_split = __detail::__find_if_not_n(__middle, __right_len, __pred); + + if (__right_len) + __right_split + = __detail::__stable_partition_adaptive(__right_split, __last, __pred, + __right_len, __buffer, __buffer_size).begin(); + + return ranges::rotate(__left_split, __middle, __right_split); + } + } // namespace __detail + struct __stable_partition_fn { template _Sent, @@ -2645,11 +3363,33 @@ namespace ranges operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { - auto __lasti = ranges::next(__first, __last); - auto __middle - = std::stable_partition(std::move(__first), __lasti, - __detail::__make_pred_proj(__pred, __proj)); - return {std::move(__middle), std::move(__lasti)}; + __first = ranges::find_if_not(__first, __last, __pred, __proj); + + if (__first == __last) + return {__first, __first}; + + using _DistanceType = iter_difference_t<_Iter>; + const _DistanceType __len = ranges::distance(__first, __last); + + auto __pred_proj = __detail::__make_pred_proj(__pred, __proj); + +#if __glibcxx_constexpr_algorithms >= 202306L // >= C++26 + if consteval { + // Simulate a _Temporary_buffer of length 1: + iter_value_t<_Iter> __buf = ranges::iter_move(__first); + *__first = std::move(__buf); + return __detail::__stable_partition_adaptive(__first, __last, + __pred_proj, + __len, &__buf, + _DistanceType(1)); + } +#endif + + _Temporary_buffer<_Iter, iter_value_t<_Iter>> __buf(__first, ptrdiff_t(__len)); + return __detail::__stable_partition_adaptive(__first, __last, + __pred_proj, + __len, __buf.begin(), + _DistanceType(__buf.size())); } template + void + __move_merge_adaptive(_Iter1 __first1, _Iter1 __last1, + _Iter2 __first2, _Iter2 __last2, + _Out __result, _Comp __comp) + { + while (__first1 != __last1 && __first2 != __last2) + { + if (__comp(*__first2, *__first1)) + { + *__result = ranges::iter_move(__first2); + ++__first2; + } + else + { + *__result = ranges::iter_move(__first1); + ++__first1; + } + ++__result; + } + if (__first1 != __last1) + ranges::move(__first1, __last1, __result); + } + + template + void + __move_merge_adaptive_backward(_Iter1 __first1, _Iter1 __last1, + _Iter2 __first2, _Iter2 __last2, + _Iter3 __result, _Comp __comp) + { + if (__first1 == __last1) + { + ranges::move_backward(__first2, __last2, __result); + return; + } + else if (__first2 == __last2) + return; + + --__last1; + --__last2; + while (true) + { + if (__comp(*__last2, *__last1)) + { + *--__result = ranges::iter_move(__last1); + if (__first1 == __last1) + { + ranges::move_backward(__first2, ++__last2, __result); + return; + } + --__last1; + } + else + { + *--__result = ranges::iter_move(__last2); + if (__first2 == __last2) + return; + --__last2; + } + } + } + + template + _Iter1 + __rotate_adaptive(_Iter1 __first, _Iter1 __middle, _Iter1 __last, + iter_difference_t<_Iter1> __len1, + iter_difference_t<_Iter1> __len2, + _Iter2 __buffer, + iter_difference_t<_Iter1> __buffer_size) + { + _Iter2 __buffer_end; + if (__len1 > __len2 && __len2 <= __buffer_size) + { + if (__len2) + { + __buffer_end = ranges::move(__middle, __last, __buffer).out; + ranges::move_backward(__first, __middle, __last); + return ranges::move(__buffer, __buffer_end, __first).out; + } + else + return __first; + } + else if (__len1 <= __buffer_size) + { + if (__len1) + { + __buffer_end = ranges::move(__first, __middle, __buffer).out; + ranges::move(__middle, __last, __first); + return ranges::move_backward(__buffer, __buffer_end, __last).out; + } + else + return __last; + } + else + return ranges::rotate(__first, __middle, __last).begin(); + } + + template + void + __merge_adaptive(_Iter __first, _Iter __middle, _Iter __last, + iter_difference_t<_Iter> __len1, + iter_difference_t<_Iter> __len2, + _Pointer __buffer, _Comp __comp) + { + if (__len1 <= __len2) + { + _Pointer __buffer_end = ranges::move(__first, __middle, __buffer).out; + __detail::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last, + __first, __comp); + } + else + { + _Pointer __buffer_end = ranges::move(__middle, __last, __buffer).out; + __detail::__move_merge_adaptive_backward(__first, __middle, __buffer, + __buffer_end, __last, __comp); + } + } + + template + void + __merge_adaptive_resize(_Iter __first, _Iter __middle, _Iter __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size, + _Comp __comp) + { + if (__len1 <= __buffer_size || __len2 <= __buffer_size) + __detail::__merge_adaptive(__first, __middle, __last, + __len1, __len2, __buffer, __comp); + else + { + _Iter __first_cut = __first; + _Iter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + ranges::advance(__first_cut, __len11); + __second_cut = ranges::lower_bound(__middle, __last, *__first_cut, + __comp); + __len22 = ranges::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + ranges::advance(__second_cut, __len22); + __first_cut = ranges::upper_bound(__first, __middle, *__second_cut, + __comp); + __len11 = ranges::distance(__first, __first_cut); + } + + _Iter __new_middle + = __detail::__rotate_adaptive(__first_cut, __middle, __second_cut, + _Distance(__len1 - __len11), __len22, + __buffer, __buffer_size); + __detail::__merge_adaptive_resize(__first, __first_cut, __new_middle, + __len11, __len22, + __buffer, __buffer_size, __comp); + __detail::__merge_adaptive_resize(__new_middle, __second_cut, __last, + _Distance(__len1 - __len11), + _Distance(__len2 - __len22), + __buffer, __buffer_size, __comp); + } + } + + template + constexpr void + __merge_without_buffer(_Iter __first, _Iter __middle, _Iter __last, + _Distance __len1, _Distance __len2, _Comp __comp) + { + if (__len1 == 0 || __len2 == 0) + return; + + if (__len1 + __len2 == 2) + { + if (__comp(*__middle, *__first)) + ranges::iter_swap(__first, __middle); + return; + } + + _Iter __first_cut = __first; + _Iter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + ranges::advance(__first_cut, __len11); + __second_cut = ranges::lower_bound(__middle, __last, *__first_cut, __comp); + __len22 = ranges::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + ranges::advance(__second_cut, __len22); + __first_cut = ranges::upper_bound(__first, __middle, *__second_cut, __comp); + __len11 = ranges::distance(__first, __first_cut); + } + + _Iter __new_middle = ranges::rotate(__first_cut, __middle, __second_cut).begin(); + __detail::__merge_without_buffer(__first, __first_cut, __new_middle, + __len11, __len22, __comp); + __detail::__merge_without_buffer(__new_middle, __second_cut, __last, + __len1 - __len11, __len2 - __len22, __comp); + } + } // namespace __detail + struct __inplace_merge_fn { template _Sent, @@ -2856,10 +3805,50 @@ namespace ranges operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { - auto __lasti = ranges::next(__first, __last); - std::inplace_merge(std::move(__first), std::move(__middle), __lasti, - __detail::__make_comp_proj(__comp, __proj)); - return __lasti; + if constexpr (!same_as<_Iter, _Sent>) + return (*this)(__first, __middle, ranges::next(__middle, __last), + std::move(__comp), std::move(__proj)); + else + { + using _DistanceType = iter_difference_t<_Iter>; + + if (__first == __middle || __middle == __last) + return __last; + + const _DistanceType __len1 = ranges::distance(__first, __middle); + const _DistanceType __len2 = ranges::distance(__middle, __last); + + auto __comp_proj = __detail::__make_comp_proj(__comp, __proj); + +#if _GLIBCXX_HOSTED +# if __glibcxx_constexpr_algorithms >= 202306L // >= C++26 + if consteval { + __detail::__merge_without_buffer(__first, __middle, __last, + __len1, __len2, __comp_proj); + return __last; + } +# endif + using _TmpBuf = _Temporary_buffer<_Iter, iter_value_t<_Iter>>; + // __merge_adaptive will use a buffer for the smaller of + // [first,middle) and [middle,last). + _TmpBuf __buf(__first, ptrdiff_t(ranges::min(__len1, __len2))); + + if (__buf.size() == __buf._M_requested_size()) [[likely]] + __detail::__merge_adaptive + (__first, __middle, __last, __len1, __len2, __buf.begin(), __comp_proj); + else if (__buf.begin() == 0) [[unlikely]] + __detail::__merge_without_buffer + (__first, __middle, __last, __len1, __len2, __comp_proj); + else + __detail::__merge_adaptive_resize + (__first, __middle, __last, __len1, __len2, __buf.begin(), + _DistanceType(__buf.size()), __comp_proj); +#else + __detail::__merge_without_buffer + (__first, __middle, __last, __len1, __len2, __comp_proj); +#endif + return __last; + } } template= 201806L // C++ >= 20 template constexpr _ForwardIterator shift_left(_ForwardIterator __first, _ForwardIterator __last, @@ -4319,6 +5309,120 @@ namespace ranges } } } +#endif + +namespace ranges +{ +#if __glibcxx_shift >= 202202L // C++ >= 23 + struct __shift_left_fn + { + template _Sent> + constexpr subrange<_Iter> + operator()(_Iter __first, _Sent __last, iter_difference_t<_Iter> __n) const + { + __glibcxx_assert(__n >= 0); + if (__n == 0) + return {__first, ranges::next(__first, __last)}; + + auto __mid = ranges::next(__first, __n, __last); + if (__mid == __last) + return {__first, __first}; + return {__first, ranges::move(__mid, __last, __first).out}; + } + + template + requires permutable> + constexpr borrowed_subrange_t<_Range> + operator()(_Range&& __r, range_difference_t<_Range> __n) const + { return (*this)(ranges::begin(__r), ranges::end(__r), __n); } + }; + + inline constexpr __shift_left_fn shift_left{}; + + struct __shift_right_fn + { + template _Sent> + constexpr subrange<_Iter> + operator()(_Iter __first, _Sent __last, iter_difference_t<_Iter> __n) const + { + __glibcxx_assert(__n >= 0); + if (__n == 0) + return {__first, ranges::next(__first, __last)}; + + if constexpr (bidirectional_iterator<_Iter> && same_as<_Iter, _Sent>) + { + auto __mid = ranges::next(__last, -__n, __first); + if (__mid == __first) + return {__last, __last}; + + return {ranges::move_backward(__first, __mid, __last).out, __last}; + } + else + { + auto __result = ranges::next(__first, __n, __last); + if (__result == __last) + return {__result, __result}; + + auto __dest_head = __first, __dest_tail = __result; + while (__dest_head != __result) + { + if (__dest_tail == __last) + { + // If we get here, then we must have + // 2*n >= distance(__first, __last) + // i.e. we are shifting out at least half of the range. In + // this case we can safely perform the shift with a single + // move. + auto __lasti = ranges::move(__first, __dest_head, __result).out; + // __glibcxx_assert(__lasti == __last); + return {__result, __lasti}; + } + ++__dest_head; + ++__dest_tail; + } + + for (;;) + { + // At the start of each iteration of this outer loop, the range + // [__first, __result) contains those elements that after shifting + // the whole range right by __n, should end up in + // [__dest_head, __dest_tail) in order. + + // The below inner loop swaps the elements of [__first, __result) + // and [__dest_head, __dest_tail), while simultaneously shifting + // the latter range by __n. + auto __cursor = __first; + while (__cursor != __result) + { + if (__dest_tail == __last) + { + // At this point the ranges [__first, result) and + // [__dest_head, dest_tail) are disjoint, so we can safely + // move the remaining elements. + __dest_head = ranges::move(__cursor, __result, __dest_head).out; + auto __lasti = ranges::move(__first, __cursor, __dest_head).out; + // __glibcxx_assert(__lasti == __last); + return {__result, __lasti}; + } + ranges::iter_swap(__cursor, __dest_head); + ++__dest_head; + ++__dest_tail; + ++__cursor; + } + } + } + } + + template + requires permutable> + constexpr borrowed_subrange_t<_Range> + operator()(_Range&& __r, range_difference_t<_Range> __n) const + { return (*this)(ranges::begin(__r), ranges::end(__r), __n); } + }; + + inline constexpr __shift_right_fn shift_right{}; +#endif // C++23 +} // namespace ranges _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h index dde164988569..7df638db2d6f 100644 --- a/libstdc++-v3/include/bits/ranges_base.h +++ b/libstdc++-v3/include/bits/ranges_base.h @@ -81,16 +81,6 @@ namespace ranges __to_unsigned_like(_Tp __t) noexcept { return static_cast>(__t); } -#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ - constexpr unsigned __int128 - __to_unsigned_like(__int128 __t) noexcept - { return __t; } - - constexpr unsigned __int128 - __to_unsigned_like(unsigned __int128 __t) noexcept - { return __t; } -#endif - template using __make_unsigned_like_t = decltype(__detail::__to_unsigned_like(std::declval<_Tp>())); @@ -119,9 +109,9 @@ namespace ranges if constexpr (is_array_v>) return true; else if constexpr (__member_begin<_Tp>) - return noexcept(__decay_copy(std::declval<_Tp&>().begin())); + return noexcept(_GLIBCXX_AUTO_CAST(std::declval<_Tp&>().begin())); else - return noexcept(__decay_copy(begin(std::declval<_Tp&>()))); + return noexcept(_GLIBCXX_AUTO_CAST(begin(std::declval<_Tp&>()))); } public: @@ -146,7 +136,7 @@ namespace ranges template concept __member_end = requires(_Tp& __t) { - { __decay_copy(__t.end()) } -> sentinel_for<__range_iter_t<_Tp>>; + { _GLIBCXX_AUTO_CAST(__t.end()) } -> sentinel_for<__range_iter_t<_Tp>>; }; // Poison pill so that unqualified lookup doesn't find std::end. @@ -156,7 +146,7 @@ namespace ranges concept __adl_end = __class_or_enum> && requires(_Tp& __t) { - { __decay_copy(end(__t)) } -> sentinel_for<__range_iter_t<_Tp>>; + { _GLIBCXX_AUTO_CAST(end(__t)) } -> sentinel_for<__range_iter_t<_Tp>>; }; struct _End @@ -169,9 +159,9 @@ namespace ranges if constexpr (is_bounded_array_v>) return true; else if constexpr (__member_end<_Tp>) - return noexcept(__decay_copy(std::declval<_Tp&>().end())); + return noexcept(_GLIBCXX_AUTO_CAST(std::declval<_Tp&>().end())); else - return noexcept(__decay_copy(end(std::declval<_Tp&>()))); + return noexcept(_GLIBCXX_AUTO_CAST(end(std::declval<_Tp&>()))); } public: @@ -196,7 +186,7 @@ namespace ranges template concept __member_rbegin = requires(_Tp& __t) { - { __decay_copy(__t.rbegin()) } -> input_or_output_iterator; + { _GLIBCXX_AUTO_CAST(__t.rbegin()) } -> input_or_output_iterator; }; void rbegin() = delete; @@ -205,7 +195,7 @@ namespace ranges concept __adl_rbegin = __class_or_enum> && requires(_Tp& __t) { - { __decay_copy(rbegin(__t)) } -> input_or_output_iterator; + { _GLIBCXX_AUTO_CAST(rbegin(__t)) } -> input_or_output_iterator; }; template @@ -223,9 +213,9 @@ namespace ranges _S_noexcept() { if constexpr (__member_rbegin<_Tp>) - return noexcept(__decay_copy(std::declval<_Tp&>().rbegin())); + return noexcept(_GLIBCXX_AUTO_CAST(std::declval<_Tp&>().rbegin())); else if constexpr (__adl_rbegin<_Tp>) - return noexcept(__decay_copy(rbegin(std::declval<_Tp&>()))); + return noexcept(_GLIBCXX_AUTO_CAST(rbegin(std::declval<_Tp&>()))); else { if constexpr (noexcept(_End{}(std::declval<_Tp&>()))) @@ -258,7 +248,7 @@ namespace ranges template concept __member_rend = requires(_Tp& __t) { - { __decay_copy(__t.rend()) } + { _GLIBCXX_AUTO_CAST(__t.rend()) } -> sentinel_for(__t)))>; }; @@ -268,7 +258,7 @@ namespace ranges concept __adl_rend = __class_or_enum> && requires(_Tp& __t) { - { __decay_copy(rend(__t)) } + { _GLIBCXX_AUTO_CAST(rend(__t)) } -> sentinel_for(__t)))>; }; @@ -280,9 +270,9 @@ namespace ranges _S_noexcept() { if constexpr (__member_rend<_Tp>) - return noexcept(__decay_copy(std::declval<_Tp&>().rend())); + return noexcept(_GLIBCXX_AUTO_CAST(std::declval<_Tp&>().rend())); else if constexpr (__adl_rend<_Tp>) - return noexcept(__decay_copy(rend(std::declval<_Tp&>()))); + return noexcept(_GLIBCXX_AUTO_CAST(rend(std::declval<_Tp&>()))); else { if constexpr (noexcept(_Begin{}(std::declval<_Tp&>()))) @@ -316,7 +306,7 @@ namespace ranges concept __member_size = !disable_sized_range> && requires(_Tp& __t) { - { __decay_copy(__t.size()) } -> __detail::__is_integer_like; + { _GLIBCXX_AUTO_CAST(__t.size()) } -> __detail::__is_integer_like; }; void size() = delete; @@ -326,7 +316,7 @@ namespace ranges && !disable_sized_range> && requires(_Tp& __t) { - { __decay_copy(size(__t)) } -> __detail::__is_integer_like; + { _GLIBCXX_AUTO_CAST(size(__t)) } -> __detail::__is_integer_like; }; template @@ -351,9 +341,9 @@ namespace ranges if constexpr (is_bounded_array_v>) return true; else if constexpr (__member_size<_Tp>) - return noexcept(__decay_copy(std::declval<_Tp&>().size())); + return noexcept(_GLIBCXX_AUTO_CAST(std::declval<_Tp&>().size())); else if constexpr (__adl_size<_Tp>) - return noexcept(__decay_copy(size(std::declval<_Tp&>()))); + return noexcept(_GLIBCXX_AUTO_CAST(size(std::declval<_Tp&>()))); else if constexpr (__sentinel_size<_Tp>) return noexcept(_End{}(std::declval<_Tp&>()) - _Begin{}(std::declval<_Tp&>())); @@ -398,11 +388,6 @@ namespace ranges else return static_cast>(__size); } -#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ - // For strict-ansi modes integral<__int128> is false - else if constexpr (__detail::__is_int128<__size_type>) - return static_cast<__int128>(__size); -#endif else // Must be one of __max_diff_type or __max_size_type. return __detail::__max_diff_type(__size); } @@ -463,7 +448,7 @@ namespace ranges template concept __member_data = requires(_Tp& __t) { - { __decay_copy(__t.data()) } -> __pointer_to_object; + { _GLIBCXX_AUTO_CAST(__t.data()) } -> __pointer_to_object; }; template @@ -477,7 +462,7 @@ namespace ranges _S_noexcept() { if constexpr (__member_data<_Tp>) - return noexcept(__decay_copy(std::declval<_Tp&>().data())); + return noexcept(_GLIBCXX_AUTO_CAST(std::declval<_Tp&>().data())); else return noexcept(_Begin{}(std::declval<_Tp&>())); } @@ -894,10 +879,17 @@ namespace ranges { if constexpr (sized_sentinel_for<_Sent, _It>) { - const auto __diff = __bound - __it; + const iter_difference_t<_It> __diff = __bound - __it; if (__diff == 0) - return __n; + { + // inline any possible side effects of advance(it, bound) + if constexpr (assignable_from<_It&, _Sent>) + __it = std::move(__bound); + else if constexpr (random_access_iterator<_It>) + __it += 0; + return __n; + } else if (__diff > 0 ? __n >= __diff : __n <= __diff) { (*this)(__it, __bound); @@ -912,9 +904,14 @@ namespace ranges return 0; } else - return 0; + { + // inline any possible side effects of advance(it, n) + if constexpr (random_access_iterator<_It>) + __it += 0; + return 0; + } } - else if (__it == __bound || __n == 0) + else if (__n == 0 || __it == __bound) return __n; else if (__n > 0) { diff --git a/libstdc++-v3/include/bits/ranges_uninitialized.h b/libstdc++-v3/include/bits/ranges_uninitialized.h index 12a714b68aa0..3f9a07fdf5c6 100644 --- a/libstdc++-v3/include/bits/ranges_uninitialized.h +++ b/libstdc++-v3/include/bits/ranges_uninitialized.h @@ -556,13 +556,12 @@ namespace ranges __destroy_fn::operator()(_Iter __first, _Sent __last) const noexcept { if constexpr (is_trivially_destructible_v>) - return ranges::next(std::move(__first), __last); - else - { - for (; __first != __last; ++__first) - ranges::destroy_at(std::__addressof(*__first)); - return __first; - } + if (!is_constant_evaluated()) + return ranges::next(std::move(__first), __last); + + for (; __first != __last; ++__first) + ranges::destroy_at(std::__addressof(*__first)); + return __first; } template<__detail::__nothrow_input_range _Range> @@ -581,13 +580,12 @@ namespace ranges operator()(_Iter __first, iter_difference_t<_Iter> __n) const noexcept { if constexpr (is_trivially_destructible_v>) - return ranges::next(std::move(__first), __n); - else - { - for (; __n > 0; ++__first, (void)--__n) - ranges::destroy_at(std::__addressof(*__first)); - return __first; - } + if (!is_constant_evaluated()) + return ranges::next(std::move(__first), __n); + + for (; __n > 0; ++__first, (void)--__n) + ranges::destroy_at(std::__addressof(*__first)); + return __first; } }; diff --git a/libstdc++-v3/include/bits/semaphore_base.h b/libstdc++-v3/include/bits/semaphore_base.h index 3f7a33ccd51a..82871ce3518b 100644 --- a/libstdc++-v3/include/bits/semaphore_base.h +++ b/libstdc++-v3/include/bits/semaphore_base.h @@ -46,23 +46,20 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION - template - struct __semaphore_base + struct __semaphore_impl { - using __count_type = __conditional_t<_Platform_wait, - __detail::__platform_wait_t, - ptrdiff_t>; + using __count_type = ptrdiff_t; static constexpr ptrdiff_t _S_max = __gnu_cxx::__int_traits<__count_type>::__max; constexpr explicit - __semaphore_base(__count_type __count) noexcept + __semaphore_impl(__count_type __count) noexcept : _M_counter(__count) { } - __semaphore_base(const __semaphore_base&) = delete; - __semaphore_base& operator=(const __semaphore_base&) = delete; + __semaphore_impl(const __semaphore_impl&) = delete; + __semaphore_impl& operator=(const __semaphore_impl&) = delete; // Load the current counter value. _GLIBCXX_ALWAYS_INLINE __count_type @@ -71,8 +68,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Try to acquire the semaphore (i.e. decrement the counter). // Returns false if the current counter is zero, or if another thread - // decrements the value first. In the latter case, __cur is set to the - // new value. + // changes the value first. In the latter case, __cur is set to the new + // value. _GLIBCXX_ALWAYS_INLINE bool _M_do_try_acquire(__count_type& __cur) noexcept { @@ -85,24 +82,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION memory_order::relaxed); } + // Keep trying to acquire the semaphore in a loop until it succeeds. void _M_acquire() noexcept { - auto const __vfn = [this]{ return _M_get_current(); }; - auto __val = __vfn(); - auto const __pred = [&__val](__count_type __cur) { - if (__cur > 0) - { - __val = __cur; - return true; - } - return false; - }; - while (!_M_do_try_acquire(__val)) - if (__val == 0) - std::__atomic_wait_address(&_M_counter, __pred, __vfn, true); + auto __vfn = [this]{ return _M_get_current(); }; + _Available __is_available{__vfn()}; + while (!_M_do_try_acquire(__is_available._M_val)) + if (!__is_available()) + std::__atomic_wait_address(&_M_counter, __is_available, __vfn, true); } + // Try to acquire the semaphore, retrying a small number of times + // in case of contention. bool _M_try_acquire() noexcept { @@ -116,22 +108,152 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _M_try_acquire_until(const chrono::time_point<_Clock, _Duration>& __atime) noexcept { - auto const __vfn = [this]{ return _M_get_current(); }; - auto __val = __vfn(); - auto const __pred = [&__val](__count_type __cur) { - if (__cur > 0) - { - __val = __cur; - return true; - } + auto __vfn = [this]{ return _M_get_current(); }; + _Available __is_available{__vfn()}; + while (!_M_do_try_acquire(__is_available._M_val)) + if (!__is_available()) + if (!std::__atomic_wait_address_until(&_M_counter, __is_available, + __vfn, __atime, true)) + return false; // timed out + return true; + } + + template + bool + _M_try_acquire_for(const chrono::duration<_Rep, _Period>& __rtime) noexcept + { + auto __vfn = [this]{ return _M_get_current(); }; + _Available __is_available{__vfn()}; + while (!_M_do_try_acquire(__is_available._M_val)) + if (!__is_available()) + if (!std::__atomic_wait_address_for(&_M_counter, __is_available, + __vfn, __rtime, true)) + return false; // timed out + return true; + } + + _GLIBCXX_ALWAYS_INLINE ptrdiff_t + _M_release(ptrdiff_t __update) noexcept + { + auto __old = __atomic_impl::fetch_add(&_M_counter, __update, + memory_order::release); + if (__old == 0 && __update > 0) + __atomic_notify_address(&_M_counter, true, true); + return __old; + } + + private: + struct _Available + { + __count_type _M_val; // Cache of the last value loaded from _M_counter. + + // Returns true if the cached value is non-zero and so it should be + // possible to acquire the semaphore. + bool operator()() const noexcept { return _M_val > 0; } + + // Argument should be the latest value of the counter. + // Returns true (and caches the value) if it's non-zero, meaning it + // should be possible to acquire the semaphore. Returns false otherwise. + bool operator()(__count_type __cur) noexcept + { + if (__cur == 0) return false; - }; + _M_val = __cur; + return true; + } + }; + + alignas(__atomic_ref<__count_type>::required_alignment) + __count_type _M_counter; + }; + + // Optimized specialization using __platform_wait (if available) + template + struct __platform_semaphore_impl + { + using __count_type = __detail::__platform_wait_t; + + static constexpr ptrdiff_t _S_max + = _Binary ? 1 : __gnu_cxx::__int_traits<__count_type>::__max; + + constexpr explicit + __platform_semaphore_impl(__count_type __count) noexcept + : _M_counter(__count) + { } + + __platform_semaphore_impl(__platform_semaphore_impl&) = delete; + __platform_semaphore_impl& operator=(const __platform_semaphore_impl&) = delete; + + // Load the current counter value. + _GLIBCXX_ALWAYS_INLINE __count_type + _M_get_current() const noexcept + { + if constexpr (_Binary) + return 1; // Not necessarily true, but optimistically assume it is. + else + return __atomic_impl::load(&_M_counter, memory_order::acquire); + } + + // Try to acquire the semaphore (i.e. decrement the counter). + // Returns false if the current counter is zero, or if another thread + // changes the value first. In the latter case, __cur is set to the new + // value. + _GLIBCXX_ALWAYS_INLINE bool + _M_do_try_acquire(__count_type& __cur) noexcept + { + if (__cur == 0) + return false; // Cannot decrement when it's already zero. + + return __atomic_impl::compare_exchange_strong(&_M_counter, + __cur, __cur - 1, + memory_order::acquire, + memory_order::relaxed); + } + + // Keep trying to acquire the semaphore in a loop until it succeeds. + void + _M_acquire() noexcept + { + auto __val = _M_get_current(); + while (!_M_do_try_acquire(__val)) + if (__val == 0) + { + std::__atomic_wait_address_v(&_M_counter, __val, __ATOMIC_ACQUIRE, + true); + __val = _M_get_current(); + } + } + + // Try to acquire the semaphore. + bool + _M_try_acquire() noexcept + { + if constexpr (_Binary) + { + __count_type __val = 1; + // Do not expect much contention on binary semaphore, only try once. + return _M_do_try_acquire(__val); + } + else + // Fastest implementation of this function is just _M_do_try_acquire + // but that can fail under contention even when _M_count > 0. + // Using _M_try_acquire_for(0ns) will retry a few times in a loop. + return _M_try_acquire_for(__detail::__wait_clock_t::duration{}); + } + + template + bool + _M_try_acquire_until(const chrono::time_point<_Clock, _Duration>& __atime) noexcept + { + auto __val = _M_get_current(); while (!_M_do_try_acquire(__val)) if (__val == 0) { - if (!std::__atomic_wait_address_until(&_M_counter, __pred, - __vfn, __atime, true)) + if (!std::__atomic_wait_address_until_v(&_M_counter, 0, + __ATOMIC_ACQUIRE, + __atime, true)) return false; // timed out + __val = _M_get_current(); } return true; } @@ -140,22 +262,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _M_try_acquire_for(const chrono::duration<_Rep, _Period>& __rtime) noexcept { - auto const __vfn = [this]{ return _M_get_current(); }; - auto __val = __vfn(); - auto const __pred = [&__val](__count_type __cur) { - if (__cur > 0) - { - __val = __cur; - return true; - } - return false; - }; + auto __val = _M_get_current(); while (!_M_do_try_acquire(__val)) if (__val == 0) { - if (!std::__atomic_wait_address_for(&_M_counter, __pred, - __vfn, __rtime, true)) + if (!std::__atomic_wait_address_for_v(&_M_counter, 0, + __ATOMIC_ACQUIRE, + __rtime, true)) return false; // timed out + __val = _M_get_current(); } return true; } @@ -170,15 +285,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __old; } - private: - alignas(_Platform_wait ? __detail::__platform_wait_alignment - : __alignof__(__count_type)) - __count_type _M_counter; + protected: + alignas(__detail::__platform_wait_alignment) __count_type _M_counter; }; - template - using __semaphore_impl - = __semaphore_base<(_Max <= __semaphore_base::_S_max)>; + template + using _Semaphore_impl + = __conditional_t<__platform_wait_uses_type<_Tp> + && _Max <= __gnu_cxx::__int_traits<_Tp>::__max, + __platform_semaphore_impl<(_Max <= 1)>, + __semaphore_impl>; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h index a196a0f1212e..f2b46015aaaf 100644 --- a/libstdc++-v3/include/bits/shared_ptr.h +++ b/libstdc++-v3/include/bits/shared_ptr.h @@ -909,6 +909,64 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public _Sp_owner_less, shared_ptr<_Tp>> { }; +#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26 + + /** + * @brief Provides ownership-based hashing. + * @headerfile memory + * @since C++26 + */ + struct owner_hash + { + template + size_t + operator()(const shared_ptr<_Tp>& __s) const noexcept + { return __s.owner_hash(); } + + template + size_t + operator()(const weak_ptr<_Tp>& __s) const noexcept + { return __s.owner_hash(); } + + using is_transparent = void; + }; + + /** + * @brief Provides ownership-based mixed equality comparisons of + * shared and weak pointers. + * @headerfile memory + * @since C++26 + */ + struct owner_equal + { + template + bool + operator()(const shared_ptr<_Tp1>& __lhs, + const shared_ptr<_Tp2>& __rhs) const noexcept + { return __lhs.owner_equal(__rhs); } + + template + bool + operator()(const shared_ptr<_Tp1>& __lhs, + const weak_ptr<_Tp2>& __rhs) const noexcept + { return __lhs.owner_equal(__rhs); } + + template + bool + operator()(const weak_ptr<_Tp1>& __lhs, + const shared_ptr<_Tp2>& __rhs) const noexcept + { return __lhs.owner_equal(__rhs); } + + template + bool + operator()(const weak_ptr<_Tp1>& __lhs, + const weak_ptr<_Tp2>& __rhs) const noexcept + { return __lhs.owner_equal(__rhs); } + + using is_transparent = void; + }; +#endif + /** * @brief Base class allowing use of the member function `shared_from_this`. * @headerfile memory diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index b4be1b49e4da..fb868e7afc36 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -1122,6 +1122,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_less(const __weak_count<_Lp>& __rhs) const noexcept { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } +#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26 + size_t + _M_owner_hash() const noexcept + { return std::hash<_Sp_counted_base<_Lp>*>()(this->_M_pi); } +#endif + // Friend function injected into enclosing namespace and found by ADL friend inline bool operator==(const __shared_count& __a, const __shared_count& __b) noexcept @@ -1225,6 +1231,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_less(const __shared_count<_Lp>& __rhs) const noexcept { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } +#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26 + size_t + _M_owner_hash() const noexcept + { return std::hash<_Sp_counted_base<_Lp>*>()(this->_M_pi); } +#endif + // Friend function injected into enclosing namespace and found by ADL friend inline bool operator==(const __weak_count& __a, const __weak_count& __b) noexcept @@ -1715,6 +1727,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _M_refcount._M_less(__rhs._M_refcount); } /// @} +#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26 + size_t owner_hash() const noexcept { return _M_refcount._M_owner_hash(); } + + template + bool + owner_equal(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept + { return _M_refcount == __rhs._M_refcount; } + + template + bool + owner_equal(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept + { return _M_refcount == __rhs._M_refcount; } +#endif + protected: // This constructor is non-standard, it is used by allocate_shared. template @@ -2098,6 +2124,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept { return _M_refcount._M_less(__rhs._M_refcount); } +#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26 + size_t owner_hash() const noexcept { return _M_refcount._M_owner_hash(); } + + template + bool + owner_equal(const __shared_ptr<_Tp1, _Lp> & __rhs) const noexcept + { return _M_refcount == __rhs._M_refcount; } + + template + bool + owner_equal(const __weak_ptr<_Tp1, _Lp> & __rhs) const noexcept + { return _M_refcount == __rhs._M_refcount; } +#endif + void reset() noexcept { __weak_ptr().swap(*this); } diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index 98c2249039d1..3f4674d5ca42 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -2511,7 +2511,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) // [first,middle) and [middle,last). _TmpBuf __buf(__first, std::min(__len1, __len2)); - if (__builtin_expect(__buf.size() == __buf.requested_size(), true)) + if (__builtin_expect(__buf.size() == __buf._M_requested_size(), true)) std::__merge_adaptive (__first, __middle, __last, __len1, __len2, __buf.begin(), __comp); else if (__builtin_expect(__buf.begin() == 0, false)) @@ -5024,7 +5024,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO // so the buffer only needs to fit half the range at once. _TmpBuf __buf(__first, (__last - __first + 1) / 2); - if (__builtin_expect(__buf.requested_size() == __buf.size(), true)) + if (__builtin_expect(__buf._M_requested_size() == __buf.size(), true)) std::__stable_sort_adaptive(__first, __first + _DistanceType(__buf.size()), __last, __buf.begin(), __comp); diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index 119dbe9a0936..b104ec2536a0 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -1046,19 +1046,26 @@ _GLIBCXX_END_NAMESPACE_CONTAINER __size_to_integer(unsigned __GLIBCXX_TYPE_INT_N_2 __n) { return __n; } #endif #if defined(__GLIBCXX_TYPE_INT_N_3) - __extension__ inline _GLIBCXX_CONSTEXPR unsigned __GLIBCXX_TYPE_INT_N_3 - __size_to_integer(__GLIBCXX_TYPE_INT_N_3 __n) { return __n; } __extension__ inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_3 + __size_to_integer(__GLIBCXX_TYPE_INT_N_3 __n) { return __n; } + __extension__ inline _GLIBCXX_CONSTEXPR unsigned __GLIBCXX_TYPE_INT_N_3 __size_to_integer(unsigned __GLIBCXX_TYPE_INT_N_3 __n) { return __n; } #endif +#if defined(__STRICT_ANSI__) && defined(__SIZEOF_INT128__) + __extension__ inline _GLIBCXX_CONSTEXPR __int128 + __size_to_integer(__int128 __n) { return __n; } + __extension__ inline _GLIBCXX_CONSTEXPR unsigned __int128 + __size_to_integer(unsigned __int128 __n) { return __n; } +#endif + inline _GLIBCXX_CONSTEXPR long long __size_to_integer(float __n) { return (long long)__n; } inline _GLIBCXX_CONSTEXPR long long __size_to_integer(double __n) { return (long long)__n; } inline _GLIBCXX_CONSTEXPR long long __size_to_integer(long double __n) { return (long long)__n; } -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) +#ifdef _GLIBCXX_USE_FLOAT128 __extension__ inline _GLIBCXX_CONSTEXPR long long __size_to_integer(__float128 __n) { return (long long)__n; } #endif diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h index 23b8fb754710..217a0416d425 100644 --- a/libstdc++-v3/include/bits/stl_construct.h +++ b/libstdc++-v3/include/bits/stl_construct.h @@ -82,7 +82,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if constexpr (__cplusplus > 201703L && is_array_v<_Tp>) { for (auto& __x : *__location) - std::destroy_at(std::__addressof(__x)); + std::destroy_at(std::addressof(__x)); } else __location->~_Tp(); @@ -123,7 +123,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Construct(_Tp* __p, _Args&&... __args) { #if __cpp_constexpr_dynamic_alloc // >= C++20 - if (std::__is_constant_evaluated()) + if (std::is_constant_evaluated()) { // Allow std::_Construct to be used in constant expressions. std::construct_at(__p, std::forward<_Args>(__args)...); @@ -181,6 +181,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION for (; __first != __last; ++__first) std::_Destroy(std::__addressof(*__first)); } + + template + static _GLIBCXX20_CONSTEXPR _ForwardIterator + __destroy_n(_ForwardIterator __first, _Size __count) + { + for (; __count > 0; (void)++__first, --__count) + std::_Destroy(std::__addressof(*__first)); + return __first; + } }; template<> @@ -189,6 +198,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template static void __destroy(_ForwardIterator, _ForwardIterator) { } + + template + static _ForwardIterator + __destroy_n(_ForwardIterator __first, _Size __count) + { + std::advance(__first, __count); + return __first; + } }; #endif @@ -204,16 +221,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef typename iterator_traits<_ForwardIterator>::value_type _Value_type; #if __cplusplus >= 201103L - // A deleted destructor is trivial, this ensures we reject such types: - static_assert(is_destructible<_Value_type>::value, - "value type is destructible"); - if constexpr (!__has_trivial_destructor(_Value_type)) + if constexpr (!is_trivially_destructible<_Value_type>::value) for (; __first != __last; ++__first) - std::_Destroy(std::__addressof(*__first)); + std::_Destroy(std::addressof(*__first)); #if __cpp_constexpr_dynamic_alloc // >= C++20 - else if (std::__is_constant_evaluated()) + else if (std::is_constant_evaluated()) for (; __first != __last; ++__first) - std::destroy_at(std::__addressof(*__first)); + std::destroy_at(std::addressof(*__first)); #endif #else std::_Destroy_aux<__has_trivial_destructor(_Value_type)>:: @@ -221,33 +235,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif } -#if __cplusplus < 201103L - template - struct _Destroy_n_aux - { - template - static _GLIBCXX20_CONSTEXPR _ForwardIterator - __destroy_n(_ForwardIterator __first, _Size __count) - { - for (; __count > 0; (void)++__first, --__count) - std::_Destroy(std::__addressof(*__first)); - return __first; - } - }; - - template<> - struct _Destroy_n_aux - { - template - static _ForwardIterator - __destroy_n(_ForwardIterator __first, _Size __count) - { - std::advance(__first, __count); - return __first; - } - }; -#endif - /** * Destroy a range of objects. If the value_type of the object has * a trivial destructor, the compiler should optimize all of this @@ -260,22 +247,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef typename iterator_traits<_ForwardIterator>::value_type _Value_type; #if __cplusplus >= 201103L - // A deleted destructor is trivial, this ensures we reject such types: - static_assert(is_destructible<_Value_type>::value, - "value type is destructible"); - if constexpr (!__has_trivial_destructor(_Value_type)) + if constexpr (!is_trivially_destructible<_Value_type>::value) for (; __count > 0; (void)++__first, --__count) - std::_Destroy(std::__addressof(*__first)); + std::_Destroy(std::addressof(*__first)); #if __cpp_constexpr_dynamic_alloc // >= C++20 - else if (std::__is_constant_evaluated()) + else if (std::is_constant_evaluated()) for (; __count > 0; (void)++__first, --__count) - std::destroy_at(std::__addressof(*__first)); + std::destroy_at(std::addressof(*__first)); #endif else std::advance(__first, __count); return __first; #else - return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>:: + return std::_Destroy_aux<__has_trivial_destructor(_Value_type)>:: __destroy_n(__first, __count); #endif } diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 478a98fe8a4f..75e794f6c020 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1164,188 +1164,201 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const _Iterator& base() const _GLIBCXX_NOEXCEPT { return _M_current; } - }; - // Note: In what follows, the left- and right-hand-side iterators are - // allowed to vary in types (conceptually in cv-qualification) so that - // comparison between cv-qualified and non-cv-qualified iterators be - // valid. However, the greedy and unfriendly operators in std::rel_ops - // will make overload resolution ambiguous (when in scope) if we don't - // provide overloads whose operands are of the same type. Can someone - // remind me what generic programming is about? -- Gaby + private: + // Note: In what follows, the left- and right-hand-side iterators are + // allowed to vary in types (conceptually in cv-qualification) so that + // comparison between cv-qualified and non-cv-qualified iterators be + // valid. However, the greedy and unfriendly operators in std::rel_ops + // will make overload resolution ambiguous (when in scope) if we don't + // provide overloads whose operands are of the same type. Can someone + // remind me what generic programming is about? -- Gaby #ifdef __cpp_lib_three_way_comparison - template - [[nodiscard, __gnu__::__always_inline__]] - constexpr bool - operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - noexcept(noexcept(__lhs.base() == __rhs.base())) - requires requires { - { __lhs.base() == __rhs.base() } -> std::convertible_to; - } - { return __lhs.base() == __rhs.base(); } - - template - [[nodiscard, __gnu__::__always_inline__]] - constexpr std::__detail::__synth3way_t<_IteratorR, _IteratorL> - operator<=>(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - noexcept(noexcept(std::__detail::__synth3way(__lhs.base(), __rhs.base()))) - { return std::__detail::__synth3way(__lhs.base(), __rhs.base()); } + template + [[nodiscard, __gnu__::__always_inline__]] + friend + constexpr bool + operator==(const __normal_iterator& __lhs, + const __normal_iterator<_Iter, _Container>& __rhs) + noexcept(noexcept(__lhs.base() == __rhs.base())) + requires requires { + { __lhs.base() == __rhs.base() } -> std::convertible_to; + } + { return __lhs.base() == __rhs.base(); } - template - [[nodiscard, __gnu__::__always_inline__]] - constexpr bool - operator==(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - noexcept(noexcept(__lhs.base() == __rhs.base())) - requires requires { - { __lhs.base() == __rhs.base() } -> std::convertible_to; - } - { return __lhs.base() == __rhs.base(); } + [[nodiscard, __gnu__::__always_inline__]] + friend + constexpr bool + operator==(const __normal_iterator& __lhs, const __normal_iterator& __rhs) + noexcept(noexcept(__lhs.base() == __rhs.base())) + requires requires { + { __lhs.base() == __rhs.base() } -> std::convertible_to; + } + { return __lhs.base() == __rhs.base(); } - template - [[nodiscard, __gnu__::__always_inline__]] - constexpr std::__detail::__synth3way_t<_Iterator> - operator<=>(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - noexcept(noexcept(std::__detail::__synth3way(__lhs.base(), __rhs.base()))) - { return std::__detail::__synth3way(__lhs.base(), __rhs.base()); } + template + [[nodiscard, __gnu__::__always_inline__]] + friend + constexpr std::__detail::__synth3way_t<_Iterator, _Iter> + operator<=>(const __normal_iterator& __lhs, + const __normal_iterator<_Iter, _Container>& __rhs) + noexcept(noexcept(std::__detail::__synth3way(__lhs.base(), __rhs.base()))) + requires requires { + std::__detail::__synth3way(__lhs.base(), __rhs.base()); + } + { return std::__detail::__synth3way(__lhs.base(), __rhs.base()); } #else - // Forward iterator requirements - template - _GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR - inline bool - operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - _GLIBCXX_NOEXCEPT - { return __lhs.base() == __rhs.base(); } + // Forward iterator requirements + template + _GLIBCXX_NODISCARD __attribute__((__always_inline__)) + friend + _GLIBCXX_CONSTEXPR + bool + operator==(const __normal_iterator& __lhs, + const __normal_iterator<_Iter, _Container>& __rhs) + _GLIBCXX_NOEXCEPT + { return __lhs.base() == __rhs.base(); } - template - _GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR - inline bool - operator==(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - _GLIBCXX_NOEXCEPT - { return __lhs.base() == __rhs.base(); } - - template - _GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR - inline bool - operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - _GLIBCXX_NOEXCEPT - { return __lhs.base() != __rhs.base(); } + _GLIBCXX_NODISCARD __attribute__((__always_inline__)) + friend + _GLIBCXX_CONSTEXPR + bool + operator==(const __normal_iterator& __lhs, const __normal_iterator& __rhs) + _GLIBCXX_NOEXCEPT + { return __lhs.base() == __rhs.base(); } - template - _GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR - inline bool - operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - _GLIBCXX_NOEXCEPT - { return __lhs.base() != __rhs.base(); } - - // Random access iterator requirements - template - _GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR - inline bool - operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - _GLIBCXX_NOEXCEPT - { return __lhs.base() < __rhs.base(); } + template + _GLIBCXX_NODISCARD __attribute__((__always_inline__)) + friend + _GLIBCXX_CONSTEXPR + bool + operator!=(const __normal_iterator& __lhs, + const __normal_iterator<_Iter, _Container>& __rhs) + _GLIBCXX_NOEXCEPT + { return __lhs.base() != __rhs.base(); } - template - _GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR - inline bool - operator<(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - _GLIBCXX_NOEXCEPT - { return __lhs.base() < __rhs.base(); } - - template - _GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR - inline bool - operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - _GLIBCXX_NOEXCEPT - { return __lhs.base() > __rhs.base(); } + _GLIBCXX_NODISCARD __attribute__((__always_inline__)) + friend + _GLIBCXX_CONSTEXPR + bool + operator!=(const __normal_iterator& __lhs, const __normal_iterator& __rhs) + _GLIBCXX_NOEXCEPT + { return __lhs.base() != __rhs.base(); } - template - _GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR - inline bool - operator>(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - _GLIBCXX_NOEXCEPT - { return __lhs.base() > __rhs.base(); } - - template - _GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR - inline bool - operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - _GLIBCXX_NOEXCEPT - { return __lhs.base() <= __rhs.base(); } + // Random access iterator requirements + template + _GLIBCXX_NODISCARD __attribute__((__always_inline__)) + friend + _GLIBCXX_CONSTEXPR + inline bool + operator<(const __normal_iterator& __lhs, + const __normal_iterator<_Iter, _Container>& __rhs) + _GLIBCXX_NOEXCEPT + { return __lhs.base() < __rhs.base(); } - template - _GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR - inline bool - operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - _GLIBCXX_NOEXCEPT - { return __lhs.base() <= __rhs.base(); } - - template - _GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR - inline bool - operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - _GLIBCXX_NOEXCEPT - { return __lhs.base() >= __rhs.base(); } + _GLIBCXX_NODISCARD __attribute__((__always_inline__)) + friend + _GLIBCXX20_CONSTEXPR + bool + operator<(const __normal_iterator& __lhs, const __normal_iterator& __rhs) + _GLIBCXX_NOEXCEPT + { return __lhs.base() < __rhs.base(); } - template - _GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR - inline bool - operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - _GLIBCXX_NOEXCEPT - { return __lhs.base() >= __rhs.base(); } + template + _GLIBCXX_NODISCARD __attribute__((__always_inline__)) + friend + _GLIBCXX_CONSTEXPR + bool + operator>(const __normal_iterator& __lhs, + const __normal_iterator<_Iter, _Container>& __rhs) + _GLIBCXX_NOEXCEPT + { return __lhs.base() > __rhs.base(); } + + _GLIBCXX_NODISCARD __attribute__((__always_inline__)) + friend + _GLIBCXX_CONSTEXPR + bool + operator>(const __normal_iterator& __lhs, const __normal_iterator& __rhs) + _GLIBCXX_NOEXCEPT + { return __lhs.base() > __rhs.base(); } + + template + _GLIBCXX_NODISCARD __attribute__((__always_inline__)) + friend + _GLIBCXX_CONSTEXPR + bool + operator<=(const __normal_iterator& __lhs, + const __normal_iterator<_Iter, _Container>& __rhs) + _GLIBCXX_NOEXCEPT + { return __lhs.base() <= __rhs.base(); } + + _GLIBCXX_NODISCARD __attribute__((__always_inline__)) + friend + _GLIBCXX_CONSTEXPR + bool + operator<=(const __normal_iterator& __lhs, const __normal_iterator& __rhs) + _GLIBCXX_NOEXCEPT + { return __lhs.base() <= __rhs.base(); } + + template + _GLIBCXX_NODISCARD __attribute__((__always_inline__)) + friend + _GLIBCXX_CONSTEXPR + bool + operator>=(const __normal_iterator& __lhs, + const __normal_iterator<_Iter, _Container>& __rhs) + _GLIBCXX_NOEXCEPT + { return __lhs.base() >= __rhs.base(); } + + _GLIBCXX_NODISCARD __attribute__((__always_inline__)) + friend + _GLIBCXX_CONSTEXPR + bool + operator>=(const __normal_iterator& __lhs, const __normal_iterator& __rhs) + _GLIBCXX_NOEXCEPT + { return __lhs.base() >= __rhs.base(); } #endif // three-way comparison - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // According to the resolution of DR179 not only the various comparison - // operators but also operator- must accept mixed iterator/const_iterator - // parameters. - template + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 179. Comparison of const_iterators to iterators doesn't work + // According to the resolution of DR179 not only the various comparison + // operators but also operator- must accept mixed iterator/const_iterator + // parameters. + template #if __cplusplus >= 201103L - // DR 685. - [[__nodiscard__, __gnu__::__always_inline__]] - constexpr auto - operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) noexcept - -> decltype(__lhs.base() - __rhs.base()) + [[__nodiscard__, __gnu__::__always_inline__]] + friend + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 685. reverse_iterator/move_iterator difference has invalid signatures + constexpr auto + operator-(const __normal_iterator& __lhs, + const __normal_iterator<_Iter, _Container>& __rhs) noexcept + -> decltype(__lhs.base() - __rhs.base()) #else - inline typename __normal_iterator<_IteratorL, _Container>::difference_type - operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) + friend + difference_type + operator-(const __normal_iterator& __lhs, + const __normal_iterator<_Iter, _Container>& __rhs) #endif - { return __lhs.base() - __rhs.base(); } + { return __lhs.base() - __rhs.base(); } - template - _GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR - inline typename __normal_iterator<_Iterator, _Container>::difference_type - operator-(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - _GLIBCXX_NOEXCEPT - { return __lhs.base() - __rhs.base(); } + _GLIBCXX_NODISCARD __attribute__((__always_inline__)) + friend + _GLIBCXX_CONSTEXPR + difference_type + operator-(const __normal_iterator& __lhs, const __normal_iterator& __rhs) + _GLIBCXX_NOEXCEPT + { return __lhs.base() - __rhs.base(); } - template - _GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR - inline __normal_iterator<_Iterator, _Container> - operator+(typename __normal_iterator<_Iterator, _Container>::difference_type - __n, const __normal_iterator<_Iterator, _Container>& __i) - _GLIBCXX_NOEXCEPT - { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } + _GLIBCXX_NODISCARD __attribute__((__always_inline__)) + friend + _GLIBCXX_CONSTEXPR + __normal_iterator + operator+(difference_type __n, const __normal_iterator& __i) + _GLIBCXX_NOEXCEPT + { return __normal_iterator(__i.base() + __n); } + }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx diff --git a/libstdc++-v3/include/bits/stl_iterator_base_types.h b/libstdc++-v3/include/bits/stl_iterator_base_types.h index a67d7bd19312..0c34ad792f7a 100644 --- a/libstdc++-v3/include/bits/stl_iterator_base_types.h +++ b/libstdc++-v3/include/bits/stl_iterator_base_types.h @@ -257,6 +257,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template concept __has_input_iter_cat = is_convertible_v<__iter_category_t<_InIter>, input_iterator_tag>; + +#ifdef __cpp_lib_concepts + // Is a Cpp17InputIterator or satisfies std::input_iterator. + template + concept __any_input_iterator + = input_iterator<_InIterator> || __has_input_iter_cat<_InIterator>; +#endif #endif template 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2766. Swapping non-swappable types template typename enable_if, __is_swappable<_T2>>::value>::type diff --git a/libstdc++-v3/include/bits/stl_tempbuf.h b/libstdc++-v3/include/bits/stl_tempbuf.h index 7a7619e2628d..8cc7b11abd21 100644 --- a/libstdc++-v3/include/bits/stl_tempbuf.h +++ b/libstdc++-v3/include/bits/stl_tempbuf.h @@ -227,7 +227,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Returns the size requested by the constructor; may be >size(). size_type - requested_size() const + _M_requested_size() const { return _M_original_len; } /// As per Table mumble. diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h index b1428db48b00..351c3a17457f 100644 --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -118,7 +118,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ~_UninitDestroyGuard() { if (__builtin_expect(_M_cur != 0, 0)) +#if __cplusplus == 201703L + // std::uninitialized_{value,default}{,_n} can construct array types, + // but std::_Destroy cannot handle them until C++20 (PR 120397). + _S_destroy(_M_first, *_M_cur); +#else std::_Destroy(_M_first, *_M_cur); +#endif } _GLIBCXX20_CONSTEXPR @@ -129,6 +135,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION private: _UninitDestroyGuard(const _UninitDestroyGuard&); + +#if __cplusplus == 201703L + template + static void + _S_destroy(_Iter __first, _Iter __last) + { + using _ValT = typename iterator_traits<_Iter>::value_type; + if constexpr (is_array<_ValT>::value) + for (; __first != __last; ++__first) + _S_destroy(*__first, *__first + extent<_ValT>::value); + else + std::_Destroy(__first, __last); + } +#endif }; // This is the default implementation of std::uninitialized_copy. @@ -357,7 +377,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::__niter_base(__last), __x); else - std::__do_uninit_copy(__first, __last, __x); + std::__do_uninit_fill(__first, __last, __x); } // Overload for pointers. @@ -839,7 +859,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _UninitDestroyGuard<_ForwardIterator> __guard(__first); for (; __first != __last; ++__first) - std::_Construct(std::__addressof(*__first)); + std::_Construct(std::addressof(*__first)); __guard.release(); } }; @@ -856,7 +876,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return; typename iterator_traits<_ForwardIterator>::value_type* __val - = std::__addressof(*__first); + = std::addressof(*__first); std::_Construct(__val); if (++__first != __last) std::fill(__first, __last, *__val); @@ -873,7 +893,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _UninitDestroyGuard<_ForwardIterator> __guard(__first); for (; __n > 0; --__n, (void) ++__first) - std::_Construct(std::__addressof(*__first)); + std::_Construct(std::addressof(*__first)); __guard.release(); return __first; } @@ -890,7 +910,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__n > 0) { typename iterator_traits<_ForwardIterator>::value_type* __val - = std::__addressof(*__first); + = std::addressof(*__first); std::_Construct(__val); ++__first; __first = std::fill_n(__first, __n - 1, *__val); @@ -902,11 +922,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // __uninitialized_default // Fills [first, last) with value-initialized value_types. template - _GLIBCXX26_CONSTEXPR + _GLIBCXX20_CONSTEXPR inline void __uninitialized_default(_ForwardIterator __first, _ForwardIterator __last) { +#ifdef __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + return __uninitialized_default_1:: + __uninit_default(__first, __last); +#endif + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; // trivial types can have deleted assignment @@ -955,7 +981,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __alloc); typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; for (; __first != __last; ++__first) - __traits::construct(__alloc, std::__addressof(*__first)); + __traits::construct(__alloc, std::addressof(*__first)); __guard.release(); } @@ -980,7 +1006,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __alloc); typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; for (; __n > 0; --__n, (void) ++__first) - __traits::construct(__alloc, std::__addressof(*__first)); + __traits::construct(__alloc, std::addressof(*__first)); __guard.release(); return __first; } @@ -1007,7 +1033,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _UninitDestroyGuard<_ForwardIterator> __guard(__first); for (; __first != __last; ++__first) - std::_Construct_novalue(std::__addressof(*__first)); + std::_Construct_novalue(std::addressof(*__first)); __guard.release(); } }; @@ -1033,7 +1059,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _UninitDestroyGuard<_ForwardIterator> __guard(__first); for (; __n > 0; --__n, (void) ++__first) - std::_Construct_novalue(std::__addressof(*__first)); + std::_Construct_novalue(std::addressof(*__first)); __guard.release(); return __first; } @@ -1089,7 +1115,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _UninitDestroyGuard<_ForwardIterator> __guard(__result); for (; __n > 0; --__n, (void) ++__first, ++__result) - std::_Construct(std::__addressof(*__result), *__first); + std::_Construct(std::addressof(*__result), *__first); __guard.release(); return __result; } @@ -1112,7 +1138,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _UninitDestroyGuard<_ForwardIterator> __guard(__result); for (; __n > 0; --__n, (void) ++__first, ++__result) - std::_Construct(std::__addressof(*__result), *__first); + std::_Construct(std::addressof(*__result), *__first); __guard.release(); return {__first, __result}; } @@ -1276,11 +1302,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc, __dest, std::move(*__orig))) && noexcept(std::allocator_traits<_Allocator>::destroy( - __alloc, std::__addressof(*__orig)))) + __alloc, std::addressof(*__orig)))) { typedef std::allocator_traits<_Allocator> __traits; __traits::construct(__alloc, __dest, std::move(*__orig)); - __traits::destroy(__alloc, std::__addressof(*__orig)); + __traits::destroy(__alloc, std::addressof(*__orig)); } // This class may be specialized for specific types. @@ -1308,8 +1334,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION "relocation is only possible for values of the same type"); _ForwardIterator __cur = __result; for (; __first != __last; ++__first, (void)++__cur) - std::__relocate_object_a(std::__addressof(*__cur), - std::__addressof(*__first), __alloc); + std::__relocate_object_a(std::addressof(*__cur), + std::addressof(*__first), __alloc); return __cur; } diff --git a/libstdc++-v3/include/bits/unicode.h b/libstdc++-v3/include/bits/unicode.h index f1b6bf49c54c..88e97d41a9eb 100644 --- a/libstdc++-v3/include/bits/unicode.h +++ b/libstdc++-v3/include/bits/unicode.h @@ -86,6 +86,25 @@ namespace __unicode { return *__it == iter_value_t<_It>{}; } }; + // An iterator over an input range of FromFmt code units that yields either + // UTF-8, UTF-16, or UTF-32, as a range of ToFmt code units. + // The code units from the input range are interpreted as Unicode code points + // and the iterator produces the individual code unit for each code point. + // Invalid sequences in the input are replaced with U+FFDD so that the result + // is always valid UTF-8, UTF-16, or UTF-32. + // + // The iterator knows the bounds of the underlying input range and will not + // read outside those bounds (incrementing or decrementing at the boundary + // is erroneously idempotent). + // + // On construction, the iterator attemps to decode a single code point from + // the input range and then encode it into an internal buffer in the output + // format, e.g. if the input is UTF-8 and the output is UTF-16, it might read + // three char8_t code units from the input and store two char16_t code units + // in its buffer. Incrementing the iterator will first iterate over buffer, + // yielding each code unit in turn, and then extract another code point from + // the input. Failure to extract a valid code point from the input will store + // U+FFFD in the buffer, encoded as the appropriate code units of type ToFmt. template _Sent = _Iter, typename _ErrorHandler = _Repl> @@ -162,17 +181,20 @@ namespace __unicode constexpr _Utf_iterator& operator++() { - if (_M_buf_index + 1 == _M_buf_last && _M_curr() != _M_last) + if (_M_buf_index + 1 < _M_buf_last) + ++_M_buf_index; // Move to the next code unit in the buffer. + else if (_M_curr() != _M_last) { + // Advance past the current code point (for non-forward iterators + // we already moved there after decoding the last code point). if constexpr (forward_iterator<_Iter>) std::advance(_M_curr(), _M_to_increment); if (_M_curr() == _M_last) _M_buf_index = 0; - else + else // Decode next code point from the input and update buffer. _M_read(); } - else if (_M_buf_index + 1 < _M_buf_last) - ++_M_buf_index; + // else erroneous, but ignored for now. return *this; } @@ -187,10 +209,15 @@ namespace __unicode constexpr _Utf_iterator& operator--() requires bidirectional_iterator<_Iter> { - if (!_M_buf_index && _M_curr() != _M_first()) - _M_read_reverse(); - else if (_M_buf_index) + if (_M_buf_index > 0) --_M_buf_index; + else if (_M_curr() != _M_first()) + { + _M_read_reverse(); + _M_buf_index = _M_buf_last - 1; + ranges::advance(_M_curr(), -_M_to_increment); + } + // else erroneous, but ignored for now. return *this; } @@ -247,7 +274,18 @@ namespace __unicode } constexpr void - _M_read_reverse(); // TODO + _M_read_reverse() requires bidirectional_iterator<_Iter> + { + if constexpr (sizeof(_FromFmt) == sizeof(uint8_t)) + _M_read_reverse_utf8(); + else if constexpr (sizeof(_FromFmt) == sizeof(uint16_t)) + _M_read_reverse_utf16(); + else + { + static_assert(sizeof(_FromFmt) == sizeof(uint32_t)); + _M_read_reverse_utf32(); + } + } template struct _Guard @@ -263,7 +301,7 @@ namespace __unicode _It _M_orig; }; - constexpr void + constexpr char32_t _M_read_utf8() { _Guard<_Iter> __g{this, _M_curr()}; @@ -361,6 +399,8 @@ namespace __unicode __c = _S_error(); _M_update(__c, __to_incr); + + return __c; } constexpr void @@ -403,6 +443,116 @@ namespace __unicode _M_update(__c, 1); } + constexpr void + _M_read_reverse_utf8() requires bidirectional_iterator<_Iter> + { + const auto __first = _M_first(); + auto __curr = _M_curr(); + // The code point we decode: + char32_t __c{}; + // The last code unit read: + uint8_t __u = *--__curr; + // Count of bytes read: + uint8_t __to_incr = 1; + + if (__u <= 0x7F) [[likely]] + { + _M_update(__u, 1); + return; + } + + // Continuation bytes match 10xxxxxx + auto __is_continuation = [](uint8_t __b) { + return (__b & 0xC0) == 0x80; + }; + // 0xC0 and 0xC1 would produce overlong encodings of ASCII characters. + // 0xF5-0xFF would produce code points above U+10FFFF + auto __is_invalid = [](uint8_t __b) { + return (__b & 0xFE) == 0xC0 || __b >= 0xF5; + }; + + // No valid or invalid multibyte sequence is longer than 4 bytes, + // so skip back over at most four bytes. + while (__is_continuation(__u) && __to_incr < 4 && __curr != __first) + { + ++__to_incr; + __u = *--__curr; + } + + // If the last byte read was a continuation byte then either we read + // four continuation bytes, or stopped at the start of the sequence. + // Either way, the maximal subparts are the individual continuation + // bytes so each one should be replaced with U+FFFD. + if (__is_continuation(__u) || __is_invalid(__u)) [[unlikely]] + { + // Either found four continuation bytes (maximum allowed is three) + // or first non-continuation byte is an invalid UTF-8 code unit. + _M_update(_S_error(), 1); + return; + } + // __u is a valid start byte so use countl_one to get the expected + // length of the multibyte sequence that starts with this byte. + int __seq_length = std::countl_one((unsigned char)__u); + if (__seq_length < __to_incr) [[unlikely]] + { + // If the expected number of continuation bytes is less than + // the number we found, then the last continuation byte is a + // maximal subpart and the decremented iterator points to it. + _M_update(_S_error(), 1); + return; + } + + auto __orig = std::__exchange(_M_curr(), std::move(__curr)); + if (_M_read_utf8() == _S_error()) [[unlikely]] + { + if (_M_to_increment < __to_incr) // Read truncated sequence, set + _M_to_increment = 1; // curr to last continuation byte. + } + + _M_curr() = std::move(__orig); + // operator--() will move back by _M_to_increment + } + + constexpr void + _M_read_reverse_utf16() requires bidirectional_iterator<_Iter> + { + _Guard<_Iter> __g{this, _M_curr()}; + char32_t __c{}; + uint16_t __u = *--_M_curr(); + uint8_t __to_incr = 1; + + if (__u < 0xD800 || __u > 0xDFFF) [[likely]] + __c = __u; + else if (__u >= 0xDC00 && _M_curr() != _M_first()) [[likely]] + { + // read a low surrogate, expect a high surrogate before it. + uint16_t __u2 = *--_M_curr(); + if (__u2 < 0xD800 || __u2 > 0xDC00) [[unlikely]] + __c = _S_error(); // unpaired low surrogate + else + { + __to_incr = 2; + uint32_t __x = (__u2 & 0x3F) << 10 | (__u & 0x3FF); + uint32_t __w = (__u2 >> 6) & 0x1F; + __c = (__w + 1) << 16 | __x; + } + } + else + __c = _S_error(); // unpaired surrogate + + _M_update(__c, __to_incr); + } + + constexpr void + _M_read_reverse_utf32() requires bidirectional_iterator<_Iter> + { + _Guard<_Iter> __g{this, _M_curr()}; + char32_t __c = *--_M_curr(); + if (!__is_scalar_value(__c)) [[unlikely]] + __c = _S_error(); + _M_update(__c, 1); + } + // Encode the code point __c as one or more code units in _M_buf. constexpr void _M_update(char32_t __c, uint8_t __to_incr) @@ -487,8 +637,7 @@ namespace __unicode constexpr _Iter _M_curr() const { return _M_first_and_curr._M_curr; } - array _M_buf; - + // _M_first is not needed for non-bidirectional ranges. template struct _First_and_curr { @@ -502,6 +651,8 @@ namespace __unicode _First_and_curr(const _First_and_curr<_It2>& __other) : _M_curr(__other._M_curr) { } + // First code unit of the current code point for forward iterators, + // past-the-end of the current code point for input iterators. _It _M_curr; }; @@ -519,18 +670,24 @@ namespace __unicode _First_and_curr(const _First_and_curr<_It2>& __other) : _M_first(__other._M_first), _M_curr(__other._M_curr) { } - _It _M_first; - _It _M_curr; + _It _M_first; // Start of the underlying range. + _It _M_curr; // First code unit of the current code point. }; + // Iterators pointing to the start of the underlying range and to the + // start (or end, for non-forward iterators) of the current code point. _First_and_curr<_Iter> _M_first_and_curr; - uint8_t _M_buf_index = 0; - uint8_t _M_buf_last = 0; - uint8_t _M_to_increment = 0; - + // The end of the underlying input range. [[no_unique_address]] _Sent _M_last; + // Buffer holding the individual code units of the current code point. + array _M_buf; + + uint8_t _M_buf_index = 0; // Index of current code unit in the buffer. + uint8_t _M_buf_last = 0; // Number of code units in the buffer. + uint8_t _M_to_increment = 0; // How far to advance _M_curr on increment. + template _Sent2, typename _ErrHandler> diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index 6ae46a93800c..d76ad63ba7bf 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -832,6 +832,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __x.swap(__y); } #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2766. Swapping non-swappable types template typename enable_if::value>::type swap(unique_ptr<_Tp, _Dp>&, diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def index 9ab22cc519f9..dbe2cb8f175b 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -649,7 +649,7 @@ ftms = { }; values = { v = 1; - /* For when there's no gthread. */ + // For when there is no gthread. cxxmin = 17; hosted = yes; gthread = no; @@ -851,6 +851,14 @@ ftms = { }; }; +ftms = { + name = optional_range_support; + values = { + v = 202406; + cxxmin = 26; + }; +}; + ftms = { name = destroying_delete; values = { @@ -999,9 +1007,8 @@ ftms = { ftms = { name = mdspan; - no_stdname = true; // FIXME: remove values = { - v = 1; // FIXME: 202207 + v = 202207; cxxmin = 23; }; }; @@ -1083,6 +1090,10 @@ ftms = { ftms = { name = shift; + values = { + v = 202202; + cxxmin = 23; + }; values = { v = 201806; cxxmin = 20; @@ -1977,6 +1988,14 @@ ftms = { }; }; +ftms = { + name = inplace_vector; + values = { + v = 202406; + cxxmin = 26; + }; +}; + ftms = { name = indirect; values = { @@ -1995,6 +2014,61 @@ ftms = { }; }; +ftms = { + name = smart_ptr_owner_equality; + values = { + v = 202306; + cxxmin = 26; + hosted = yes; + }; +}; + +ftms = { + name = sstream_from_string_view; + values = { + v = 202306; + cxxmin = 26; + hosted = yes; + }; +}; + +ftms = { + name = type_order; + values = { + v = 202506; + cxxmin = 26; + extra_cond = "__has_builtin(__builtin_type_order) " + "&& __cpp_lib_three_way_comparison >= 201907L"; + }; +}; + +ftms = { + name = exception_ptr_cast; + values = { + v = 202506; + cxxmin = 26; + }; +}; + +ftms = { + name = bitset; // ...construct from string_view + values = { + v = 202306; + cxxmin = 26; + }; +}; + +ftms = { + name = constexpr_exceptions; + // TODO Remove when PR121114 is resolved + no_stdname = true; + values = { + v = 1; // TODO 202411; + cxxmin = 26; + extra_cond = "__cpp_constexpr_exceptions >= 202411L"; + }; +}; + // Standard test specifications. stds[97] = ">= 199711L"; stds[03] = ">= 199711L"; diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index 371a7ba3b1a0..7bb6016df687 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -955,6 +955,16 @@ #endif /* !defined(__cpp_lib_optional) && defined(__glibcxx_want_optional) */ #undef __glibcxx_want_optional +#if !defined(__cpp_lib_optional_range_support) +# if (__cplusplus > 202302L) +# define __glibcxx_optional_range_support 202406L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_optional_range_support) +# define __cpp_lib_optional_range_support 202406L +# endif +# endif +#endif /* !defined(__cpp_lib_optional_range_support) && defined(__glibcxx_want_optional_range_support) */ +#undef __glibcxx_want_optional_range_support + #if !defined(__cpp_lib_destroying_delete) # if (__cplusplus >= 202002L) && (__cpp_impl_destroying_delete) # define __glibcxx_destroying_delete 201806L @@ -1116,8 +1126,9 @@ #if !defined(__cpp_lib_mdspan) # if (__cplusplus >= 202100L) -# define __glibcxx_mdspan 1L +# define __glibcxx_mdspan 202207L # if defined(__glibcxx_want_all) || defined(__glibcxx_want_mdspan) +# define __cpp_lib_mdspan 202207L # endif # endif #endif /* !defined(__cpp_lib_mdspan) && defined(__glibcxx_want_mdspan) */ @@ -1214,7 +1225,12 @@ #undef __glibcxx_want_constexpr_utility #if !defined(__cpp_lib_shift) -# if (__cplusplus >= 202002L) +# if (__cplusplus >= 202100L) +# define __glibcxx_shift 202202L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_shift) +# define __cpp_lib_shift 202202L +# endif +# elif (__cplusplus >= 202002L) # define __glibcxx_shift 201806L # if defined(__glibcxx_want_all) || defined(__glibcxx_want_shift) # define __cpp_lib_shift 201806L @@ -2213,6 +2229,16 @@ #endif /* !defined(__cpp_lib_modules) && defined(__glibcxx_want_modules) */ #undef __glibcxx_want_modules +#if !defined(__cpp_lib_inplace_vector) +# if (__cplusplus > 202302L) +# define __glibcxx_inplace_vector 202406L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_inplace_vector) +# define __cpp_lib_inplace_vector 202406L +# endif +# endif +#endif /* !defined(__cpp_lib_inplace_vector) && defined(__glibcxx_want_inplace_vector) */ +#undef __glibcxx_want_inplace_vector + #if !defined(__cpp_lib_indirect) # if (__cplusplus > 202302L) && _GLIBCXX_HOSTED # define __glibcxx_indirect 202502L @@ -2233,4 +2259,63 @@ #endif /* !defined(__cpp_lib_polymorphic) && defined(__glibcxx_want_polymorphic) */ #undef __glibcxx_want_polymorphic +#if !defined(__cpp_lib_smart_ptr_owner_equality) +# if (__cplusplus > 202302L) && _GLIBCXX_HOSTED +# define __glibcxx_smart_ptr_owner_equality 202306L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_smart_ptr_owner_equality) +# define __cpp_lib_smart_ptr_owner_equality 202306L +# endif +# endif +#endif /* !defined(__cpp_lib_smart_ptr_owner_equality) && defined(__glibcxx_want_smart_ptr_owner_equality) */ +#undef __glibcxx_want_smart_ptr_owner_equality + +#if !defined(__cpp_lib_sstream_from_string_view) +# if (__cplusplus > 202302L) && _GLIBCXX_HOSTED +# define __glibcxx_sstream_from_string_view 202306L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_sstream_from_string_view) +# define __cpp_lib_sstream_from_string_view 202306L +# endif +# endif +#endif /* !defined(__cpp_lib_sstream_from_string_view) && defined(__glibcxx_want_sstream_from_string_view) */ +#undef __glibcxx_want_sstream_from_string_view + +#if !defined(__cpp_lib_type_order) +# if (__cplusplus > 202302L) && (__has_builtin(__builtin_type_order) && __cpp_lib_three_way_comparison >= 201907L) +# define __glibcxx_type_order 202506L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_type_order) +# define __cpp_lib_type_order 202506L +# endif +# endif +#endif /* !defined(__cpp_lib_type_order) && defined(__glibcxx_want_type_order) */ +#undef __glibcxx_want_type_order + +#if !defined(__cpp_lib_exception_ptr_cast) +# if (__cplusplus > 202302L) +# define __glibcxx_exception_ptr_cast 202506L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_exception_ptr_cast) +# define __cpp_lib_exception_ptr_cast 202506L +# endif +# endif +#endif /* !defined(__cpp_lib_exception_ptr_cast) && defined(__glibcxx_want_exception_ptr_cast) */ +#undef __glibcxx_want_exception_ptr_cast + +#if !defined(__cpp_lib_bitset) +# if (__cplusplus > 202302L) +# define __glibcxx_bitset 202306L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_bitset) +# define __cpp_lib_bitset 202306L +# endif +# endif +#endif /* !defined(__cpp_lib_bitset) && defined(__glibcxx_want_bitset) */ +#undef __glibcxx_want_bitset + +#if !defined(__cpp_lib_constexpr_exceptions) +# if (__cplusplus > 202302L) && (__cpp_constexpr_exceptions >= 202411L) +# define __glibcxx_constexpr_exceptions 1L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_constexpr_exceptions) +# endif +# endif +#endif /* !defined(__cpp_lib_constexpr_exceptions) && defined(__glibcxx_want_constexpr_exceptions) */ +#undef __glibcxx_want_constexpr_exceptions + #undef __glibcxx_want_all diff --git a/libstdc++-v3/include/c_global/cmath b/libstdc++-v3/include/c_global/cmath index 27c21ca19eb6..65a3b8144f35 100644 --- a/libstdc++-v3/include/c_global/cmath +++ b/libstdc++-v3/include/c_global/cmath @@ -3792,10 +3792,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return std::__hypot3(__x, __y, __z); } template - __gnu_cxx::__promoted_t<_Tp, _Up, _Vp> + typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type hypot(_Tp __x, _Up __y, _Vp __z) { - using __type = __gnu_cxx::__promoted_t<_Tp, _Up, _Vp>; + using __type = typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type; return std::__hypot3<__type>(__x, __y, __z); } diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque index 59d60b2120db..ed69eb842e2b 100644 --- a/libstdc++-v3/include/debug/deque +++ b/libstdc++-v3/include/debug/deque @@ -650,7 +650,8 @@ namespace __debug else if (__first.base() == _Base::begin() || __last.base() == _Base::end()) { - this->_M_detach_singular(); + const deque* __this = this; + __this->_M_detach_singular(); for (_Base_const_iterator __position = __first.base(); __position != __last.base(); ++__position) { @@ -663,7 +664,7 @@ namespace __debug } __catch(...) { - this->_M_revalidate_singular(); + __this->_M_revalidate_singular(); __throw_exception_again; } } diff --git a/libstdc++-v3/include/debug/formatter.h b/libstdc++-v3/include/debug/formatter.h index d80e8a78dcb4..8aa84adec778 100644 --- a/libstdc++-v3/include/debug/formatter.h +++ b/libstdc++-v3/include/debug/formatter.h @@ -96,7 +96,7 @@ namespace __gnu_debug template class _Safe_iterator; - template + template class _Safe_local_iterator; template @@ -316,8 +316,8 @@ namespace __gnu_debug } } - template - _Parameter(_Safe_local_iterator<_Iterator, _Sequence> const& __it, + template + _Parameter(_Safe_local_iterator<_Iterator, _UContainer> const& __it, const char* __name, _Is_iterator) : _M_kind(__iterator), _M_variant() { @@ -326,8 +326,8 @@ namespace __gnu_debug _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(_Iterator); _M_variant._M_iterator._M_constness = __it._S_constant() ? __const_iterator : __mutable_iterator; - _M_variant._M_iterator._M_sequence = __it._M_get_sequence(); - _M_variant._M_iterator._M_seq_type = _GLIBCXX_TYPEID(_Sequence); + _M_variant._M_iterator._M_sequence = __it._M_get_ucontainer(); + _M_variant._M_iterator._M_seq_type = _GLIBCXX_TYPEID(_UContainer); if (__it._M_singular()) { diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list index 60a254297d54..9da7dda45034 100644 --- a/libstdc++-v3/include/debug/forward_list +++ b/libstdc++-v3/include/debug/forward_list @@ -58,44 +58,44 @@ namespace __gnu_debug class _Safe_forward_list : public _Safe_sequence<_SafeSequence> { - _SafeSequence& - _M_this() noexcept - { return *static_cast<_SafeSequence*>(this); } + const _SafeSequence* + _M_this() const noexcept + { return static_cast(this); } static void - _M_swap_aux(_Safe_sequence_base& __lhs, + _S_swap_aux(const _Safe_forward_list& __lhs, _Safe_iterator_base*& __lhs_iterators, - _Safe_sequence_base& __rhs, + const _Safe_forward_list& __rhs, _Safe_iterator_base*& __rhs_iterators); - void _M_swap_single(_Safe_sequence_base&) noexcept; + void _M_swap_single(const _Safe_forward_list&) const noexcept; protected: void - _M_invalidate_all() + _M_invalidate_all() const { - using _Base_const_iterator = __decltype(_M_this()._M_base().cend()); + using _Base_const_iterator = __decltype(_M_this()->_M_base().cend()); this->_M_invalidate_if([this](_Base_const_iterator __it) { - return __it != _M_this()._M_base().cbefore_begin() - && __it != _M_this()._M_base().cend(); }); + return __it != _M_this()->_M_base().cbefore_begin() + && __it != _M_this()->_M_base().cend(); }); } - void _M_swap(_Safe_sequence_base&) noexcept; + void + _M_swap(const _Safe_forward_list&) const noexcept; }; template void _Safe_forward_list<_SafeSequence>:: - _M_swap_aux(_Safe_sequence_base& __lhs, + _S_swap_aux(const _Safe_forward_list& __lhs, _Safe_iterator_base*& __lhs_iterators, - _Safe_sequence_base& __rhs, + const _Safe_forward_list& __rhs, _Safe_iterator_base*& __rhs_iterators) { using const_iterator = typename _SafeSequence::const_iterator; _Safe_iterator_base* __bbegin_its = 0; _Safe_iterator_base* __last_bbegin = 0; - _SafeSequence& __rseq = static_cast<_SafeSequence&>(__rhs); for (_Safe_iterator_base* __iter = __lhs_iterators; __iter;) { @@ -104,7 +104,7 @@ namespace __gnu_debug const_iterator* __victim = static_cast(__victim_base); __iter = __iter->_M_next; - if (__victim->base() == __rseq._M_base().cbefore_begin()) + if (__victim->base() == __rhs._M_this()->_M_base().cbefore_begin()) { __victim->_M_unlink(); if (__lhs_iterators == __victim_base) @@ -136,21 +136,21 @@ namespace __gnu_debug template void _Safe_forward_list<_SafeSequence>:: - _M_swap_single(_Safe_sequence_base& __other) noexcept + _M_swap_single(const _Safe_forward_list& __other) const noexcept { - std::swap(_M_this()._M_iterators, __other._M_iterators); - std::swap(_M_this()._M_const_iterators, __other._M_const_iterators); + std::swap(_M_this()->_M_iterators, __other._M_iterators); + std::swap(_M_this()->_M_const_iterators, __other._M_const_iterators); // Useless, always 1 on forward_list - //std::swap(_M_this()_M_version, __other._M_version); - _Safe_iterator_base* __this_its = _M_this()._M_iterators; - _M_swap_aux(__other, __other._M_iterators, - _M_this(), _M_this()._M_iterators); - _Safe_iterator_base* __this_const_its = _M_this()._M_const_iterators; - _M_swap_aux(__other, __other._M_const_iterators, - _M_this(), _M_this()._M_const_iterators); - _M_swap_aux(_M_this(), __this_its, + //std::swap(_M_this()->_M_version, __other._M_version); + _Safe_iterator_base* __this_its = _M_this()->_M_iterators; + _S_swap_aux(__other, __other._M_iterators, + *_M_this(), _M_this()->_M_iterators); + _Safe_iterator_base* __this_const_its = _M_this()->_M_const_iterators; + _S_swap_aux(__other, __other._M_const_iterators, + *_M_this(), _M_this()->_M_const_iterators); + _S_swap_aux(*_M_this(), __this_its, __other, __other._M_iterators); - _M_swap_aux(_M_this(), __this_const_its, + _S_swap_aux(*_M_this(), __this_const_its, __other, __other._M_const_iterators); } @@ -159,13 +159,12 @@ namespace __gnu_debug template void _Safe_forward_list<_SafeSequence>:: - _M_swap(_Safe_sequence_base& __other) noexcept + _M_swap(const _Safe_forward_list& __other) const noexcept { // We need to lock both sequences to swap using namespace __gnu_cxx; - __mutex *__this_mutex = &_M_this()._M_get_mutex(); - __mutex *__other_mutex = - &static_cast<_SafeSequence&>(__other)._M_get_mutex(); + __mutex *__this_mutex = &_M_this()->_M_get_mutex(); + __mutex *__other_mutex = &__other._M_get_mutex(); if (__this_mutex == __other_mutex) { __scoped_lock __lock(*__this_mutex); @@ -565,7 +564,8 @@ namespace __debug void resize(size_type __sz) { - this->_M_detach_singular(); + const forward_list* __this = this; + __this->_M_detach_singular(); // if __sz < size(), invalidate all iterators in [begin+__sz, end() _Base_iterator __victim = _Base::begin(); @@ -585,7 +585,7 @@ namespace __debug } __catch(...) { - this->_M_revalidate_singular(); + __this->_M_revalidate_singular(); __throw_exception_again; } } @@ -593,7 +593,8 @@ namespace __debug void resize(size_type __sz, const value_type& __val) { - this->_M_detach_singular(); + const forward_list* __this = this; + __this->_M_detach_singular(); // if __sz < size(), invalidate all iterators in [begin+__sz, end()) _Base_iterator __victim = _Base::begin(); @@ -613,7 +614,7 @@ namespace __debug } __catch(...) { - this->_M_revalidate_singular(); + __this->_M_revalidate_singular(); __throw_exception_again; } } diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list index a9d974c40a5d..c502c7cb6e23 100644 --- a/libstdc++-v3/include/debug/list +++ b/libstdc++-v3/include/debug/list @@ -321,7 +321,8 @@ namespace __debug void resize(size_type __sz) { - this->_M_detach_singular(); + const list* __this = this; + __this->_M_detach_singular(); // if __sz < size(), invalidate all iterators in [begin + __sz, end()) _Base_iterator __victim = _Base::begin(); @@ -338,7 +339,7 @@ namespace __debug } __catch(...) { - this->_M_revalidate_singular(); + __this->_M_revalidate_singular(); __throw_exception_again; } } @@ -346,7 +347,8 @@ namespace __debug void resize(size_type __sz, const _Tp& __c) { - this->_M_detach_singular(); + const list* __this = this; + __this->_M_detach_singular(); // if __sz < size(), invalidate all iterators in [begin + __sz, end()) _Base_iterator __victim = _Base::begin(); @@ -363,7 +365,7 @@ namespace __debug } __catch(...) { - this->_M_revalidate_singular(); + __this->_M_revalidate_singular(); __throw_exception_again; } } @@ -371,7 +373,8 @@ namespace __debug void resize(size_type __sz, _Tp __c = _Tp()) { - this->_M_detach_singular(); + const list* __this = this; + __this->_M_detach_singular(); // if __sz < size(), invalidate all iterators in [begin + __sz, end()) _Base_iterator __victim = _Base::begin(); @@ -388,7 +391,7 @@ namespace __debug } __catch(...) { - this->_M_revalidate_singular(); + __this->_M_revalidate_singular(); __throw_exception_again; } } diff --git a/libstdc++-v3/include/debug/safe_base.h b/libstdc++-v3/include/debug/safe_base.h index cf3f1708ad25..44622970792b 100644 --- a/libstdc++-v3/include/debug/safe_base.h +++ b/libstdc++-v3/include/debug/safe_base.h @@ -53,8 +53,10 @@ namespace __gnu_debug public: /** The sequence this iterator references; may be NULL to indicate - a singular iterator. */ - _Safe_sequence_base* _M_sequence; + * a singular iterator. Stored as pointer-to-const because sequence + * could be declared as const. + */ + const _Safe_sequence_base* _M_sequence; /** The version number of this iterator. The sentinel value 0 is * used to indicate an invalidated iterator (i.e., one that is @@ -92,7 +94,7 @@ namespace __gnu_debug : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) { if (!std::__is_constant_evaluated()) - this->_M_attach(const_cast<_Safe_sequence_base*>(__seq), __constant); + this->_M_attach(__seq, __constant); } /** Initializes the iterator to reference the same sequence that @@ -115,7 +117,7 @@ namespace __gnu_debug /** For use in _Safe_iterator. */ __gnu_cxx::__mutex& - _M_get_mutex() throw (); + _M_get_mutex() _GLIBCXX_USE_NOEXCEPT; /** Attaches this iterator to the given sequence, detaching it * from whatever sequence it was attached to originally. If the @@ -123,11 +125,12 @@ namespace __gnu_debug * unattached. */ void - _M_attach(_Safe_sequence_base* __seq, bool __constant); + _M_attach(const _Safe_sequence_base* __seq, bool __constant); /** Likewise, but not thread-safe. */ void - _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw (); + _M_attach_single(const _Safe_sequence_base* __seq, + bool __constant) _GLIBCXX_USE_NOEXCEPT; /** Detach the iterator for whatever sequence it is attached to, * if any. @@ -135,10 +138,23 @@ namespace __gnu_debug void _M_detach(); +#if !_GLIBCXX_INLINE_VERSION + private: + /***************************************************************/ + /** Not-const method preserved for abi backward compatibility. */ + void + _M_attach(_Safe_sequence_base* __seq, bool __constant); + + void + _M_attach_single(_Safe_sequence_base* __seq, + bool __constant) _GLIBCXX_USE_NOEXCEPT; + /***************************************************************/ +#endif + public: /** Likewise, but not thread-safe. */ void - _M_detach_single() throw (); + _M_detach_single() _GLIBCXX_USE_NOEXCEPT; /** Determines if we are attached to the given sequence. */ bool @@ -147,13 +163,13 @@ namespace __gnu_debug /** Is this iterator singular? */ _GLIBCXX_PURE bool - _M_singular() const throw (); + _M_singular() const _GLIBCXX_USE_NOEXCEPT; /** Can we compare this iterator to the given iterator @p __x? Returns true if both iterators are nonsingular and reference the same sequence. */ _GLIBCXX_PURE bool - _M_can_compare(const _Safe_iterator_base& __x) const throw (); + _M_can_compare(const _Safe_iterator_base& __x) const _GLIBCXX_USE_NOEXCEPT; /** Invalidate the iterator, making it singular. */ void @@ -162,11 +178,11 @@ namespace __gnu_debug /** Reset all member variables */ void - _M_reset() throw (); + _M_reset() _GLIBCXX_USE_NOEXCEPT; /** Unlink itself */ void - _M_unlink() throw () + _M_unlink() _GLIBCXX_USE_NOEXCEPT { if (_M_prior) _M_prior->_M_next = _M_next; @@ -246,14 +262,14 @@ namespace __gnu_debug /** Detach all iterators, leaving them singular. */ void - _M_detach_all(); + _M_detach_all() const; /** Detach all singular iterators. * @post for all iterators i attached to this sequence, * i->_M_version == _M_version. */ void - _M_detach_singular(); + _M_detach_singular() const; /** Revalidates all attached singular iterators. This method may * be used to validate iterators that were invalidated before @@ -261,7 +277,7 @@ namespace __gnu_debug * valid again). */ void - _M_revalidate_singular(); + _M_revalidate_singular() const; /** Swap this sequence with the given sequence. This operation * also swaps ownership of the iterators, so that when the @@ -269,11 +285,11 @@ namespace __gnu_debug * one container now reference the other container. */ void - _M_swap(_Safe_sequence_base& __x) _GLIBCXX_USE_NOEXCEPT; + _M_swap(const _Safe_sequence_base& __x) const _GLIBCXX_USE_NOEXCEPT; /** For use in _Safe_sequence. */ __gnu_cxx::__mutex& - _M_get_mutex() throw (); + _M_get_mutex() const _GLIBCXX_USE_NOEXCEPT; /** Invalidates all iterators. */ void @@ -281,21 +297,42 @@ namespace __gnu_debug { if (++_M_version == 0) _M_version = 1; } private: +#if !_GLIBCXX_INLINE_VERSION + /***************************************************************/ + /** Not-const method preserved for abi backward compatibility. */ + void + _M_detach_all(); + + void + _M_detach_singular(); + + void + _M_revalidate_singular(); + + void + _M_swap(_Safe_sequence_base& __x) _GLIBCXX_USE_NOEXCEPT; + + __gnu_cxx::__mutex& + _M_get_mutex() _GLIBCXX_USE_NOEXCEPT; + /***************************************************************/ +#endif + /** Attach an iterator to this sequence. */ void - _M_attach(_Safe_iterator_base* __it, bool __constant); + _M_attach(_Safe_iterator_base* __it, bool __constant) const; /** Likewise but not thread safe. */ void - _M_attach_single(_Safe_iterator_base* __it, bool __constant) throw (); + _M_attach_single(_Safe_iterator_base* __it, + bool __constant) const _GLIBCXX_USE_NOEXCEPT; /** Detach an iterator from this sequence */ void - _M_detach(_Safe_iterator_base* __it); + _M_detach(_Safe_iterator_base* __it) const; /** Likewise but not thread safe. */ void - _M_detach_single(_Safe_iterator_base* __it) throw (); + _M_detach_single(_Safe_iterator_base* __it) const _GLIBCXX_USE_NOEXCEPT; }; } // namespace __gnu_debug diff --git a/libstdc++-v3/include/debug/safe_container.h b/libstdc++-v3/include/debug/safe_container.h index cb1e69a2d697..3341806fd596 100644 --- a/libstdc++-v3/include/debug/safe_container.h +++ b/libstdc++-v3/include/debug/safe_container.h @@ -44,9 +44,9 @@ namespace __gnu_debug typedef _SafeBase<_SafeContainer> _Base; _GLIBCXX20_CONSTEXPR - _SafeContainer& - _M_cont() _GLIBCXX_NOEXCEPT - { return *static_cast<_SafeContainer*>(this); } + const _SafeContainer& + _M_cont() const _GLIBCXX_NOEXCEPT + { return *static_cast(this); } protected: #if __cplusplus >= 201103L @@ -55,6 +55,11 @@ namespace __gnu_debug _Safe_container(_Safe_container&&) = default; private: + _GLIBCXX20_CONSTEXPR + void + _M_swap_base(const _Safe_container& __x) const noexcept + { _Base::_M_swap(__x); } + _GLIBCXX20_CONSTEXPR _Safe_container(_Safe_container&& __x, const _Alloc&, std::true_type) : _Safe_container(std::move(__x)) @@ -67,7 +72,7 @@ namespace __gnu_debug if (!std::__is_constant_evaluated()) { if (__x._M_cont().get_allocator() == __a) - _Base::_M_swap(__x); + _M_swap_base(__x); else __x._M_invalidate_all(); } @@ -115,12 +120,12 @@ namespace __gnu_debug bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign() || _M_cont().get_allocator() == __x._M_cont().get_allocator(); if (__xfer_memory) - _Base::_M_swap(__x); + _M_swap_base(__x); else this->_M_invalidate_all(); } else - _Base::_M_swap(__x); + _M_swap_base(__x); __x._M_invalidate_all(); return *this; @@ -128,7 +133,7 @@ namespace __gnu_debug _GLIBCXX20_CONSTEXPR void - _M_swap(_Safe_container& __x) noexcept + _M_swap(const _Safe_container& __x) const noexcept { if (_IsCxx11AllocatorAware) { @@ -139,8 +144,12 @@ namespace __gnu_debug __x._M_cont()._M_base()); } - _Base::_M_swap(__x); + _M_swap_base(__x); } +#else + void + _M_swap(const _Safe_container& __x) const throw() + { _Base::_M_swap(__x); } #endif }; diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index 7c563381d0bf..e0b1b46939c3 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -224,7 +224,7 @@ namespace __gnu_debug _M_message(__msg_init_copy_singular) ._M_iterator(*this, "this") ._M_iterator(__x, "other")); - _Safe_sequence_base* __seq = __x._M_sequence; + const _Safe_sequence_base* __seq = __x._M_sequence; __x._M_detach(); std::swap(base(), __x.base()); _M_attach(__seq); @@ -445,12 +445,12 @@ namespace __gnu_debug /** Attach iterator to the given sequence. */ void - _M_attach(_Safe_sequence_base* __seq) + _M_attach(const _Safe_sequence_base* __seq) { _Safe_base::_M_attach(__seq, _S_constant()); } /** Likewise, but not thread-safe. */ void - _M_attach_single(_Safe_sequence_base* __seq) + _M_attach_single(const _Safe_sequence_base* __seq) { _Safe_base::_M_attach_single(__seq, _S_constant()); } /// Is the iterator dereferenceable? @@ -500,7 +500,13 @@ namespace __gnu_debug typename __gnu_cxx::__conditional_type< _IsConstant::__value, const _Sequence*, _Sequence*>::__type _M_get_sequence() const - { return static_cast<_Sequence*>(_M_sequence); } + { + // Looks like not const-correct, but if _IsConstant the constness + // is restored when returning the sequence pointer and if not + // _IsConstant we are allowed to remove constness. + return static_cast<_Sequence*> + (const_cast<_Safe_sequence_base*>(_M_sequence)); + } // Get distance to __rhs. typename _Distance_traits<_Iterator>::__type diff --git a/libstdc++-v3/include/debug/safe_local_iterator.h b/libstdc++-v3/include/debug/safe_local_iterator.h index c84f4f10093a..47b3a807a8bc 100644 --- a/libstdc++-v3/include/debug/safe_local_iterator.h +++ b/libstdc++-v3/include/debug/safe_local_iterator.h @@ -52,15 +52,15 @@ namespace __gnu_debug /** \brief Safe iterator wrapper. * * The class template %_Safe_local_iterator is a wrapper around an - * iterator that tracks the iterator's movement among sequences and - * checks that operations performed on the "safe" iterator are + * iterator that tracks the iterator's movement among unordered containers + * and checks that operations performed on the "safe" iterator are * legal. In additional to the basic iterator operations (which are * validated, and then passed to the underlying iterator), * %_Safe_local_iterator has member functions for iterator invalidation, - * attaching/detaching the iterator from sequences, and querying + * attaching/detaching the iterator from unordered containers, and querying * the iterator's state. */ - template + template class _Safe_local_iterator : private _Iterator , public _Safe_local_iterator_base @@ -68,28 +68,27 @@ namespace __gnu_debug typedef _Iterator _Iter_base; typedef _Safe_local_iterator_base _Safe_base; - typedef typename _Sequence::size_type size_type; + typedef typename _UContainer::size_type size_type; typedef std::iterator_traits<_Iterator> _Traits; - typedef std::__are_same< - typename _Sequence::_Base::const_local_iterator, - _Iterator> _IsConstant; + using _IsConstant = std::__are_same< + typename _UContainer::_Base::const_local_iterator, _Iterator>; - typedef typename __gnu_cxx::__conditional_type<_IsConstant::__value, - typename _Sequence::_Base::local_iterator, - typename _Sequence::_Base::const_local_iterator>::__type - _OtherIterator; + using _OtherIterator = std::__conditional_t< + _IsConstant::__value, + typename _UContainer::_Base::local_iterator, + typename _UContainer::_Base::const_local_iterator>; typedef _Safe_local_iterator _Self; - typedef _Safe_local_iterator<_OtherIterator, _Sequence> _OtherSelf; + typedef _Safe_local_iterator<_OtherIterator, _UContainer> _OtherSelf; struct _Unchecked { }; _Safe_local_iterator(const _Safe_local_iterator& __x, _Unchecked) noexcept : _Iter_base(__x.base()) - { _M_attach(__x._M_sequence); } + { _M_attach(__x._M_safe_container()); } public: typedef _Iterator iterator_type; @@ -104,12 +103,13 @@ namespace __gnu_debug /** * @brief Safe iterator construction from an unsafe iterator and - * its sequence. + * its unordered container. * - * @pre @p seq is not NULL + * @pre @p cont is not NULL * @post this is not singular */ - _Safe_local_iterator(_Iterator __i, const _Safe_sequence_base* __cont) + _Safe_local_iterator(_Iterator __i, + const _Safe_unordered_container_base* __cont) : _Iter_base(__i), _Safe_base(__cont, _S_constant()) { } @@ -126,7 +126,7 @@ namespace __gnu_debug _M_message(__msg_init_copy_singular) ._M_iterator(*this, "this") ._M_iterator(__x, "other")); - _M_attach(__x._M_sequence); + _M_attach(__x._M_safe_container()); } /** @@ -141,7 +141,7 @@ namespace __gnu_debug _M_message(__msg_init_copy_singular) ._M_iterator(*this, "this") ._M_iterator(__x, "other")); - auto __cont = __x._M_sequence; + auto __cont = __x._M_safe_container(); __x._M_detach(); std::swap(base(), __x.base()); _M_attach(__cont); @@ -156,7 +156,7 @@ namespace __gnu_debug const _Safe_local_iterator<_MutableIterator, typename __gnu_cxx::__enable_if<_IsConstant::__value && std::__are_same<_MutableIterator, _OtherIterator>::__value, - _Sequence>::__type>& __x) noexcept + _UContainer>::__type>& __x) noexcept : _Iter_base(__x.base()) { // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -166,7 +166,7 @@ namespace __gnu_debug _M_message(__msg_init_const_singular) ._M_iterator(*this, "this") ._M_iterator(__x, "other")); - _M_attach(__x._M_sequence); + _M_attach(__x._M_safe_container()); } /** @@ -193,7 +193,7 @@ namespace __gnu_debug { _M_detach(); base() = __x.base(); - _M_attach(__x._M_sequence); + _M_attach(__x._M_safe_container()); } return *this; @@ -225,7 +225,7 @@ namespace __gnu_debug { _M_detach(); base() = __x.base(); - _M_attach(__x._M_sequence); + _M_attach(__x._M_safe_container()); } __x._M_detach(); @@ -318,15 +318,15 @@ namespace __gnu_debug */ operator _Iterator() const { return *this; } - /** Attach iterator to the given sequence. */ + /** Attach iterator to the given unordered container. */ void - _M_attach(_Safe_sequence_base* __seq) - { _Safe_base::_M_attach(__seq, _S_constant()); } + _M_attach(const _Safe_unordered_container_base* __cont) + { _Safe_base::_M_attach(__cont, _S_constant()); } /** Likewise, but not thread-safe. */ void - _M_attach_single(_Safe_sequence_base* __seq) - { _Safe_base::_M_attach_single(__seq, _S_constant()); } + _M_attach_single(const _Safe_unordered_container_base* __cont) + { _Safe_base::_M_attach_single(__cont, _S_constant()); } /// Is the iterator dereferenceable? bool @@ -353,25 +353,31 @@ namespace __gnu_debug typename _Distance_traits<_Iterator>::__type _M_get_distance_to(const _Safe_local_iterator& __rhs) const; - // The sequence this iterator references. - typename __gnu_cxx::__conditional_type< - _IsConstant::__value, const _Sequence*, _Sequence*>::__type - _M_get_sequence() const - { return static_cast<_Sequence*>(_M_sequence); } + // The unordered container this iterator references. + std::__conditional_t< + _IsConstant::__value, const _UContainer*, _UContainer*> + _M_get_ucontainer() const + { + // Looks like not const-correct, but if _IsConstant the constness + // is restored when returning the container pointer and if not + // _IsConstant we are allowed to remove constness. + return static_cast<_UContainer*> + (const_cast<_Safe_unordered_container_base*>(_M_safe_container())); + } - /// Is this iterator equal to the sequence's begin(bucket) iterator? + /// Is this iterator equal to the container's begin(bucket) iterator? bool _M_is_begin() const - { return base() == _M_get_sequence()->_M_base().begin(bucket()); } + { return base() == _M_get_ucontainer()->_M_base().begin(bucket()); } - /// Is this iterator equal to the sequence's end(bucket) iterator? + /// Is this iterator equal to the container's end(bucket) iterator? bool _M_is_end() const - { return base() == _M_get_sequence()->_M_base().end(bucket()); } + { return base() == _M_get_ucontainer()->_M_base().end(bucket()); } /// Is this iterator part of the same bucket as the other one? template bool _M_in_same_bucket(const _Safe_local_iterator<_Other, - _Sequence>& __other) const + _UContainer>& __other) const { return bucket() == __other.bucket(); } friend inline bool @@ -404,31 +410,31 @@ namespace __gnu_debug }; /** Safe local iterators know how to check if they form a valid range. */ - template + template inline bool - __valid_range(const _Safe_local_iterator<_Iterator, _Sequence>& __first, - const _Safe_local_iterator<_Iterator, _Sequence>& __last, + __valid_range(const _Safe_local_iterator<_Iterator, _UContainer>& __first, + const _Safe_local_iterator<_Iterator, _UContainer>& __last, typename _Distance_traits<_Iterator>::__type& __dist_info) { return __first._M_valid_range(__last, __dist_info); } - template + template inline bool - __valid_range(const _Safe_local_iterator<_Iterator, _Sequence>& __first, - const _Safe_local_iterator<_Iterator, _Sequence>& __last) + __valid_range(const _Safe_local_iterator<_Iterator, _UContainer>& __first, + const _Safe_local_iterator<_Iterator, _UContainer>& __last) { typename _Distance_traits<_Iterator>::__type __dist_info; return __first._M_valid_range(__last, __dist_info); } #if __cplusplus < 201103L - template - struct _Unsafe_type<_Safe_local_iterator<_Iterator, _Sequence> > + template + struct _Unsafe_type<_Safe_local_iterator<_Iterator, _UContainer> > { typedef _Iterator _Type; }; #endif - template + template inline _Iterator - __unsafe(const _Safe_local_iterator<_Iterator, _Sequence>& __it) + __unsafe(const _Safe_local_iterator<_Iterator, _UContainer>& __it) { return __it.base(); } } // namespace __gnu_debug diff --git a/libstdc++-v3/include/debug/safe_local_iterator.tcc b/libstdc++-v3/include/debug/safe_local_iterator.tcc index 71e532065e4f..10fec3fad4a7 100644 --- a/libstdc++-v3/include/debug/safe_local_iterator.tcc +++ b/libstdc++-v3/include/debug/safe_local_iterator.tcc @@ -44,7 +44,7 @@ namespace __gnu_debug if (__rhs._M_is_end()) return { - _M_get_sequence()->bucket_size(bucket()), + _M_get_ucontainer()->bucket_size(bucket()), __dp_exact }; @@ -56,7 +56,7 @@ namespace __gnu_debug if (__rhs._M_is_begin()) return { - -_M_get_sequence()->bucket_size(bucket()), + -_M_get_ucontainer()->bucket_size(bucket()), __dp_exact }; diff --git a/libstdc++-v3/include/debug/safe_sequence.h b/libstdc++-v3/include/debug/safe_sequence.h index 6b35afa66c63..e10474aae79c 100644 --- a/libstdc++-v3/include/debug/safe_sequence.h +++ b/libstdc++-v3/include/debug/safe_sequence.h @@ -114,7 +114,7 @@ namespace __gnu_debug in the safe ones. */ template void - _M_invalidate_if(_Predicate __pred); + _M_invalidate_if(_Predicate __pred) const; /** Transfers all iterators @c x that reference @c from sequence, are not singular, and for which @c __pred(x) returns @c @@ -122,7 +122,8 @@ namespace __gnu_debug in the safe ones. */ template void - _M_transfer_from_if(_Safe_sequence& __from, _Predicate __pred); + _M_transfer_from_if(const _Safe_sequence& __from, + _Predicate __pred) const; }; /// Like _Safe_sequence but with a special _M_invalidate_all implementation @@ -133,12 +134,12 @@ namespace __gnu_debug { protected: void - _M_invalidate_all() + _M_invalidate_all() const { typedef typename _Sequence::const_iterator _Const_iterator; typedef typename _Const_iterator::iterator_type _Base_const_iterator; typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; - const _Sequence& __seq = *static_cast<_Sequence*>(this); + const _Sequence& __seq = *static_cast(this); this->_M_invalidate_if(_Not_equal(__seq._M_base().end())); } }; diff --git a/libstdc++-v3/include/debug/safe_sequence.tcc b/libstdc++-v3/include/debug/safe_sequence.tcc index 336bf2a0b2b6..053361dff3c0 100644 --- a/libstdc++-v3/include/debug/safe_sequence.tcc +++ b/libstdc++-v3/include/debug/safe_sequence.tcc @@ -35,7 +35,7 @@ namespace __gnu_debug template void _Safe_sequence<_Sequence>:: - _M_invalidate_if(_Predicate __pred) + _M_invalidate_if(_Predicate __pred) const { typedef typename _Sequence::iterator iterator; typedef typename _Sequence::const_iterator const_iterator; @@ -66,7 +66,7 @@ namespace __gnu_debug template void _Safe_sequence<_Sequence>:: - _M_transfer_from_if(_Safe_sequence& __from, _Predicate __pred) + _M_transfer_from_if(const _Safe_sequence& __from, _Predicate __pred) const { if (this == std::__addressof(__from)) return; @@ -104,7 +104,7 @@ namespace __gnu_debug } for (_Safe_iterator_base* __iter2 = __from._M_const_iterators; - __iter2;) + __iter2;) { _Safe_iterator_base* __victim_base = __iter2; const_iterator* __victim = diff --git a/libstdc++-v3/include/debug/safe_unordered_base.h b/libstdc++-v3/include/debug/safe_unordered_base.h index 1547f5b7b9d5..55cf581e315e 100644 --- a/libstdc++-v3/include/debug/safe_unordered_base.h +++ b/libstdc++-v3/include/debug/safe_unordered_base.h @@ -49,6 +49,10 @@ namespace __gnu_debug */ class _Safe_local_iterator_base : public _Safe_iterator_base { + public: + const _Safe_unordered_container_base* + _M_safe_container() const noexcept; + protected: /** Initializes the iterator and makes it singular. */ _Safe_local_iterator_base() @@ -61,32 +65,32 @@ namespace __gnu_debug * singular. Otherwise, the iterator will reference @p __seq and * be nonsingular. */ - _Safe_local_iterator_base(const _Safe_sequence_base* __seq, bool __constant) - { this->_M_attach(const_cast<_Safe_sequence_base*>(__seq), __constant); } + _Safe_local_iterator_base(const _Safe_unordered_container_base* __seq, + bool __constant) + { _M_attach(__seq, __constant); } /** Initializes the iterator to reference the same container that @p __x does. @p __constant is true if this is a constant iterator, and false if it is mutable. */ _Safe_local_iterator_base(const _Safe_local_iterator_base& __x, bool __constant) - { this->_M_attach(__x._M_sequence, __constant); } + { this->_M_attach(__x._M_safe_container(), __constant); } ~_Safe_local_iterator_base() { this->_M_detach(); } - _Safe_unordered_container_base* - _M_get_container() const noexcept; - /** Attaches this iterator to the given container, detaching it * from whatever container it was attached to originally. If the * new container is the NULL pointer, the iterator is left * unattached. */ void - _M_attach(_Safe_sequence_base* __seq, bool __constant); + _M_attach(const _Safe_unordered_container_base* __cont, + bool __constant); /** Likewise, but not thread-safe. */ void - _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw (); + _M_attach_single(const _Safe_unordered_container_base* __cont, + bool __constant) noexcept; /** Detach the iterator for whatever container it is attached to, * if any. @@ -96,7 +100,19 @@ namespace __gnu_debug /** Likewise, but not thread-safe. */ void - _M_detach_single() throw (); + _M_detach_single() noexcept; + +#if !_GLIBCXX_INLINE_VERSION + private: + /***************************************************************/ + /** Not-const method preserved for abi backward compatibility. */ + void + _M_attach(_Safe_sequence_base* __seq, bool __constant); + + void + _M_attach_single(_Safe_sequence_base* __seq, bool __constant) noexcept; + /***************************************************************/ +#endif }; /** @@ -124,10 +140,10 @@ namespace __gnu_debug public: /// The list of mutable local iterators that reference this container - _Safe_iterator_base* _M_local_iterators; + mutable _Safe_iterator_base* _M_local_iterators; /// The list of constant local iterators that reference this container - _Safe_iterator_base* _M_const_local_iterators; + mutable _Safe_iterator_base* _M_const_local_iterators; protected: // Initialize with a version number of 1 and no iterators @@ -153,7 +169,7 @@ namespace __gnu_debug /** Detach all iterators, leaving them singular. */ void - _M_detach_all(); + _M_detach_all() const; /** Swap this container with the given container. This operation * also swaps ownership of the iterators, so that when the @@ -161,25 +177,42 @@ namespace __gnu_debug * one container now reference the other container. */ void - _M_swap(_Safe_unordered_container_base& __x) noexcept; + _M_swap(const _Safe_unordered_container_base& __x) const noexcept; private: +#if !_GLIBCXX_INLINE_VERSION + /***************************************************************/ + /** Not-const method preserved for abi backward compatibility. */ + void + _M_detach_all(); + + void + _M_swap(_Safe_unordered_container_base& __x) noexcept; + /***************************************************************/ +#endif + /** Attach an iterator to this container. */ void - _M_attach_local(_Safe_iterator_base* __it, bool __constant); + _M_attach_local(_Safe_iterator_base* __it, bool __constant) const; /** Likewise but not thread safe. */ void - _M_attach_local_single(_Safe_iterator_base* __it, bool __constant) throw (); + _M_attach_local_single(_Safe_iterator_base* __it, + bool __constant) const noexcept; /** Detach an iterator from this container */ void - _M_detach_local(_Safe_iterator_base* __it); + _M_detach_local(_Safe_iterator_base* __it) const; /** Likewise but not thread safe. */ void - _M_detach_local_single(_Safe_iterator_base* __it) throw (); + _M_detach_local_single(_Safe_iterator_base* __it) const noexcept; }; + + inline const _Safe_unordered_container_base* + _Safe_local_iterator_base:: + _M_safe_container() const noexcept + { return static_cast(_M_sequence); } } // namespace __gnu_debug #endif diff --git a/libstdc++-v3/include/debug/safe_unordered_container.h b/libstdc++-v3/include/debug/safe_unordered_container.h index 2ba27dbbecbb..b67b7e06b2fc 100644 --- a/libstdc++-v3/include/debug/safe_unordered_container.h +++ b/libstdc++-v3/include/debug/safe_unordered_container.h @@ -62,6 +62,10 @@ namespace __gnu_debug _M_cont() noexcept { return *static_cast<_Container*>(this); } + const _Safe_unordered_container* + _M_self() const + { return this; } + protected: void _M_invalidate_locals() diff --git a/libstdc++-v3/include/debug/safe_unordered_container.tcc b/libstdc++-v3/include/debug/safe_unordered_container.tcc index 68193891b01d..0732e6374bfc 100644 --- a/libstdc++-v3/include/debug/safe_unordered_container.tcc +++ b/libstdc++-v3/include/debug/safe_unordered_container.tcc @@ -40,7 +40,7 @@ namespace __gnu_debug typedef typename _Container::iterator iterator; typedef typename _Container::const_iterator const_iterator; - __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex()); + __gnu_cxx::__scoped_lock sentry(_M_self()->_M_get_mutex()); for (_Safe_iterator_base* __iter = _M_iterators; __iter;) { iterator* __victim = static_cast(__iter); @@ -72,7 +72,7 @@ namespace __gnu_debug typedef typename _Container::local_iterator local_iterator; typedef typename _Container::const_local_iterator const_local_iterator; - __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex()); + __gnu_cxx::__scoped_lock sentry(_M_self()->_M_get_mutex()); for (_Safe_iterator_base* __iter = _M_local_iterators; __iter;) { local_iterator* __victim = static_cast(__iter); diff --git a/libstdc++-v3/include/experimental/memory b/libstdc++-v3/include/experimental/memory index 131e5acc03d9..1b01462e1b26 100644 --- a/libstdc++-v3/include/experimental/memory +++ b/libstdc++-v3/include/experimental/memory @@ -148,42 +148,42 @@ inline namespace fundamentals_v2 }; // observer_ptr<> template - void + constexpr void swap(observer_ptr<_Tp>& __p1, observer_ptr<_Tp>& __p2) noexcept { __p1.swap(__p2); } template - observer_ptr<_Tp> + constexpr observer_ptr<_Tp> make_observer(_Tp* __p) noexcept { return observer_ptr<_Tp>(__p); } template - bool + constexpr bool operator==(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) { return __p1.get() == __p2.get(); } template - bool + constexpr bool operator!=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) { return !(__p1 == __p2); } template - bool + constexpr bool operator==(observer_ptr<_Tp> __p, nullptr_t) noexcept { return !__p; } template - bool + constexpr bool operator==(nullptr_t, observer_ptr<_Tp> __p) noexcept { return !__p; @@ -197,14 +197,14 @@ inline namespace fundamentals_v2 } template - bool + constexpr bool operator!=(nullptr_t, observer_ptr<_Tp> __p) noexcept { return bool(__p); } template - bool + constexpr bool operator<(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) { return std::less::type, @@ -214,21 +214,21 @@ inline namespace fundamentals_v2 } template - bool + constexpr bool operator>(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) { return __p2 < __p1; } template - bool + constexpr bool operator<=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) { return !(__p2 < __p1); } template - bool + constexpr bool operator>=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) { return !(__p1 < __p2); diff --git a/libstdc++-v3/include/ext/numeric_traits.h b/libstdc++-v3/include/ext/numeric_traits.h index 2cd89430f51c..6786dc6a71bc 100644 --- a/libstdc++-v3/include/ext/numeric_traits.h +++ b/libstdc++-v3/include/ext/numeric_traits.h @@ -126,12 +126,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_INT_N_TRAITS(__GLIBCXX_TYPE_INT_N_3, __GLIBCXX_BITSIZE_INT_N_3) #endif -#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ - // In strict modes __is_integer<__int128> is false, - // but we still want to define __numeric_traits_integer<__int128>. - _GLIBCXX_INT_N_TRAITS(__int128, 128) -#endif - #undef _GLIBCXX_INT_N_TRAITS #if __cplusplus >= 201103L diff --git a/libstdc++-v3/include/precompiled/stdc++.h b/libstdc++-v3/include/precompiled/stdc++.h index e7d89c927049..733a5e5fb0be 100644 --- a/libstdc++-v3/include/precompiled/stdc++.h +++ b/libstdc++-v3/include/precompiled/stdc++.h @@ -237,6 +237,7 @@ #endif #if __cplusplus > 202302L +#include #include #include #include diff --git a/libstdc++-v3/include/pstl/algorithm_impl.h b/libstdc++-v3/include/pstl/algorithm_impl.h index 5b1cd2010944..2080e82f8b49 100644 --- a/libstdc++-v3/include/pstl/algorithm_impl.h +++ b/libstdc++-v3/include/pstl/algorithm_impl.h @@ -79,7 +79,7 @@ template _ForwardIterator __for_each_n_it_serial(_ForwardIterator __first, _Size __n, _Function __f) { - for (; __n > 0; ++__first, --__n) + for (; __n > 0; ++__first, (void) --__n) __f(__first); return __first; } @@ -221,7 +221,7 @@ _ForwardIterator2 __brick_walk2(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Function __f, /*vector=*/std::false_type) noexcept { - for (; __first1 != __last1; ++__first1, ++__first2) + for (; __first1 != __last1; ++__first1, (void) ++__first2) __f(*__first1, *__first2); return __first2; } @@ -240,7 +240,7 @@ _ForwardIterator2 __brick_walk2_n(_ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, _Function __f, /*vector=*/std::false_type) noexcept { - for (; __n > 0; --__n, ++__first1, ++__first2) + for (; __n > 0; --__n, (void) ++__first1, ++__first2) __f(*__first1, *__first2); return __first2; } @@ -364,7 +364,7 @@ _ForwardIterator3 __brick_walk3(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator3 __first3, _Function __f, /*vector=*/std::false_type) noexcept { - for (; __first1 != __last1; ++__first1, ++__first2, ++__first3) + for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__first3) __f(*__first1, *__first2, *__first3); return __first3; } @@ -961,7 +961,7 @@ struct __brick_move_destroy { using _IteratorValueType = typename std::iterator_traits<_RandomAccessIterator1>::value_type; - for (; __first != __last; ++__first, ++__result) + for (; __first != __last; ++__first, (void) ++__result) { *__result = std::move(*__first); (*__first).~_IteratorValueType(); @@ -1027,7 +1027,7 @@ __brick_calc_mask_1(_ForwardIterator __first, _ForwardIterator __last, bool* __r static_assert(__are_random_access_iterators<_ForwardIterator>::value, "Pattern-brick error. Should be a random access iterator."); - for (; __first != __last; ++__first, ++__mask) + for (; __first != __last; ++__first, (void) ++__mask) { *__mask = __pred(*__first); if (*__mask) @@ -1052,7 +1052,7 @@ void __brick_copy_by_mask(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, bool* __mask, _Assigner __assigner, /*vector=*/std::false_type) noexcept { - for (; __first != __last; ++__first, ++__mask) + for (; __first != __last; ++__first, (void) ++__mask) { if (*__mask) { @@ -1079,7 +1079,7 @@ void __brick_partition_by_mask(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator1 __out_true, _OutputIterator2 __out_false, bool* __mask, /*vector=*/std::false_type) noexcept { - for (; __first != __last; ++__first, ++__mask) + for (; __first != __last; ++__first, (void) ++__mask) { if (*__mask) { @@ -1383,7 +1383,7 @@ __brick_calc_mask_2(_RandomAccessIterator __first, _RandomAccessIterator __last, _BinaryPredicate __pred, /*vector=*/std::false_type) noexcept { _DifferenceType __count = 0; - for (; __first != __last; ++__first, ++__mask) + for (; __first != __last; ++__first, (void) ++__mask) { *__mask = !__pred(*__first, *(__first - 1)); __count += *__mask; @@ -1483,7 +1483,7 @@ void __brick_reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, _BidirectionalIterator __d_last, /*is_vector=*/std::false_type) noexcept { - for (--__d_last; __first != __last; ++__first, --__d_last) + for (--__d_last; __first != __last; ++__first, (void) --__d_last) { using std::iter_swap; iter_swap(__first, __d_last); @@ -2333,7 +2333,7 @@ __pattern_partial_sort_copy(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& _RandomAccessIterator1 __it = __first + (__i - __r); // 1. Copy elements from input to raw memory - for (_T1* __k = __i; __k != __j; ++__k, ++__it) + for (_T1* __k = __i; __k != __j; ++__k, (void) ++__it) { ::new (__k) _T2(*__it); } @@ -3648,7 +3648,7 @@ __mismatch_serial(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _Forwar #if defined(_PSTL_CPP14_2RANGE_MISMATCH_EQUAL_PRESENT) return std::mismatch(__first1, __last1, __first2, __last2, __pred); #else - for (; __first1 != __last1 && __first2 != __last2 && __pred(*__first1, *__first2); ++__first1, ++__first2) + for (; __first1 != __last1 && __first2 != __last2 && __pred(*__first1, *__first2); ++__first1, (void) ++__first2) { } return std::make_pair(__first1, __first2); diff --git a/libstdc++-v3/include/pstl/memory_impl.h b/libstdc++-v3/include/pstl/memory_impl.h index 8cb32d043e5e..080b6cada5bf 100644 --- a/libstdc++-v3/include/pstl/memory_impl.h +++ b/libstdc++-v3/include/pstl/memory_impl.h @@ -29,7 +29,7 @@ __brick_uninitialized_move(_ForwardIterator __first, _ForwardIterator __last, _O /*vector=*/std::false_type) noexcept { using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type; - for (; __first != __last; ++__first, ++__result) + for (; __first != __last; ++__first, (void) ++__result) { ::new (std::addressof(*__result)) _ValueType(std::move(*__first)); } @@ -80,7 +80,7 @@ __brick_uninitialized_copy(_ForwardIterator __first, _ForwardIterator __last, _O /*vector=*/std::false_type) noexcept { using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type; - for (; __first != __last; ++__first, ++__result) + for (; __first != __last; ++__first, (void) ++__result) { ::new (std::addressof(*__result)) _ValueType(*__first); } diff --git a/libstdc++-v3/include/pstl/numeric_impl.h b/libstdc++-v3/include/pstl/numeric_impl.h index b285a667653a..af6f6a2c8d57 100644 --- a/libstdc++-v3/include/pstl/numeric_impl.h +++ b/libstdc++-v3/include/pstl/numeric_impl.h @@ -158,7 +158,7 @@ __brick_transform_scan(_ForwardIterator __first, _ForwardIterator __last, _Outpu _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, /*Inclusive*/ std::false_type, /*is_vector=*/std::false_type) noexcept { - for (; __first != __last; ++__first, ++__result) + for (; __first != __last; ++__first, (void) ++__result) { _Tp __v = std::move(__init); _PSTL_PRAGMA_FORCEINLINE @@ -175,7 +175,7 @@ __brick_transform_scan(_RandomAccessIterator __first, _RandomAccessIterator __la _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, /*Inclusive*/ std::true_type, /*is_vector=*/std::false_type) noexcept { - for (; __first != __last; ++__first, ++__result) + for (; __first != __last; ++__first, (void) ++__result) { _PSTL_PRAGMA_FORCEINLINE __init = __binary_op(__init, __unary_op(*__first)); diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index fdcf0b073762..12f010921db1 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -381,6 +381,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __one.swap(__two); } #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2766. Swapping non-swappable types template __enable_if_t::_Is_swappable::value> swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete; diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset index 8b5d270c2a94..93a03f6b5d72 100644 --- a/libstdc++-v3/include/std/bitset +++ b/libstdc++-v3/include/std/bitset @@ -61,8 +61,13 @@ #endif #define __glibcxx_want_constexpr_bitset +#define __glibcxx_want_bitset // ...construct from string_view #include +#ifdef __cpp_lib_bitset // ...construct from string_view +# include +#endif + #define _GLIBCXX_BITSET_BITS_PER_WORD (__CHAR_BIT__ * __SIZEOF_LONG__) #define _GLIBCXX_BITSET_WORDS(__n) \ ((__n) / _GLIBCXX_BITSET_BITS_PER_WORD + \ @@ -715,7 +720,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER namespace __bitset { -#if _GLIBCXX_HOSTED +#ifdef __cpp_lib_bitset // ...construct from string_view + template + using __string = std::basic_string_view<_CharT>; +#elif _GLIBCXX_HOSTED template using __string = std::basic_string<_CharT>; #else @@ -752,7 +760,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * (Note that %bitset does @e not meet the formal requirements of a * container. Mainly, it lacks iterators.) * - * The template argument, @a Nb, may be any non-negative number, + * The template argument, `Nb`, may be any non-negative number, * specifying the number of bits (e.g., "0", "12", "1024*1024"). * * In the general unoptimized case, storage is allocated in word-sized @@ -816,28 +824,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base; typedef unsigned long _WordT; -#if _GLIBCXX_HOSTED - template - _GLIBCXX23_CONSTEXPR - void - _M_check_initial_position(const std::basic_string<_CharT, _Traits, _Alloc>& __s, - size_t __position) const + template + _GLIBCXX23_CONSTEXPR void + _M_check_initial_position( + const _Str& __s, typename _Str::size_type __position) const { if (__position > __s.size()) - __throw_out_of_range_fmt(__N("bitset::bitset: __position " - "(which is %zu) > __s.size() " - "(which is %zu)"), - __position, __s.size()); + __throw_out_of_range_fmt( + __N("bitset::bitset:" + " __position (which is %zu) > __s.size() (which is %zu)"), + size_t(__position), size_t(__s.size())); } -#endif // HOSTED _GLIBCXX23_CONSTEXPR void _M_check(size_t __position, const char *__s) const { if (__position >= _Nb) - __throw_out_of_range_fmt(__N("%s: __position (which is %zu) " - ">= _Nb (which is %zu)"), - __s, __position, _Nb); + __throw_out_of_range_fmt( + __N("%s: __position (which is %zu) >= _Nb (which is %zu)"), + __s, size_t(__position), size_t(_Nb)); } _GLIBCXX23_CONSTEXPR @@ -954,12 +959,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER #if _GLIBCXX_HOSTED /** * Use a subset of a string. - * @param __s A string of @a 0 and @a 1 characters. - * @param __position Index of the first character in @a __s to use; + * @param __s A string of `0` and `1` characters. + * @param __position Index of the first character in `__s` to use; * defaults to zero. - * @throw std::out_of_range If @a pos is bigger the size of @a __s. + * @throw std::out_of_range If `__position > __s.size()`. * @throw std::invalid_argument If a character appears in the string - * which is neither @a 0 nor @a 1. + * which is neither `0` nor `1`. */ template _GLIBCXX23_CONSTEXPR @@ -976,13 +981,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /** * Use a subset of a string. - * @param __s A string of @a 0 and @a 1 characters. - * @param __position Index of the first character in @a __s to use. + * @param __s A string of `0` and `1` characters. + * @param __position Index of the first character in `__s` to use. * @param __n The number of characters to copy. - * @throw std::out_of_range If @a __position is bigger the size - * of @a __s. + * @throw std::out_of_range If `__position > __s.size()`. * @throw std::invalid_argument If a character appears in the string - * which is neither @a 0 nor @a 1. + * which is neither `0` nor `1`. */ template _GLIBCXX23_CONSTEXPR @@ -1008,15 +1012,42 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } #endif // HOSTED +#ifdef __cpp_lib_bitset + /** + * Use a subset of a string view. + * @param __s A `string_view` of a sequence of `0` and `1` characters. + * @param __position Index of the first character in `__s` to use. + * @param __n The maximum number of characters from `__s` to use. + * @param __zero The character corresponding to the value 0. + * @param __one The character corresponding to the value 1. + * @throw std::out_of_range If `__position > __s.size()`. + * @throw std::invalid_argument If a character appears in `__s` + * which is neither `0` nor `1`. + */ + template + constexpr explicit + bitset(basic_string_view<_CharT, _Traits> __s, + basic_string_view<_CharT, _Traits>::size_type __position = 0, + basic_string_view<_CharT, _Traits>::size_type __n = + basic_string_view<_CharT, _Traits>::npos, + _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) + : _Base() + { + _M_check_initial_position(__s, __position); + _M_copy_from_ptr<_CharT, _Traits>( + __s.data(), __s.size(), __position, __n, __zero, __one); + } +#endif + #if __cplusplus >= 201103L /** * Construct from a character %array. - * @param __str An %array of characters @a zero and @a one. + * @param __str An %array of characters `__zero` and `__one`. * @param __n The number of characters to use. * @param __zero The character corresponding to the value 0. * @param __one The character corresponding to the value 1. * @throw std::invalid_argument If a character appears in the string - * which is neither @a __zero nor @a __one. + * which is neither `__zero` nor `__one`. */ template [[__gnu__::__nonnull__]] @@ -1028,10 +1059,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) : _Base() { -#if _GLIBCXX_HOSTED if (!__str) __throw_logic_error(__N("bitset::bitset(const _CharT*, ...)")); -#endif using _Traits = typename __bitset::__string<_CharT>::traits_type; if (__n == __bitset::__string<_CharT>::npos) diff --git a/libstdc++-v3/include/std/charconv b/libstdc++-v3/include/std/charconv index dda49ce72d0b..8cf2c0b01d7c 100644 --- a/libstdc++-v3/include/std/charconv +++ b/libstdc++-v3/include/std/charconv @@ -390,6 +390,10 @@ _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_2) _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_3) _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_3) #endif +#if defined __SIZEOF_INT128__ && defined __STRICT_ANSI__ +_GLIBCXX_TO_CHARS(signed __int128) +_GLIBCXX_TO_CHARS(unsigned __int128) +#endif #undef _GLIBCXX_TO_CHARS // _GLIBCXX_RESOLVE_LIB_DEFECTS diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono index 8eb9fd9baac0..cb8213e2f9f9 100644 --- a/libstdc++-v3/include/std/chrono +++ b/libstdc++-v3/include/std/chrono @@ -2305,8 +2305,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __r *= 10; return __r; } - - template struct __utc_leap_second; } /// @endcond @@ -2481,30 +2479,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __byte_duration> _M_s{}; bool _M_is_neg{}; __subseconds _M_ss{}; - - template friend struct __detail::__utc_leap_second; }; - /// @cond undocumented - namespace __detail - { - // Represents a time that is within a leap second insertion. - template - struct __utc_leap_second - { - explicit - __utc_leap_second(const sys_time<_Duration>& __s) - : _M_date(chrono::floor(__s)), _M_time(__s - _M_date) - { - ++_M_time._M_s; - } - - sys_days _M_date; - hh_mm_ss> _M_time; - }; - } - /// @endcond - // 12/24 HOURS FUNCTIONS constexpr bool diff --git a/libstdc++-v3/include/std/flat_map b/libstdc++-v3/include/std/flat_map index 4bd4963c2ad7..de006ad1c533 100644 --- a/libstdc++-v3/include/std/flat_map +++ b/libstdc++-v3/include/std/flat_map @@ -1148,14 +1148,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // element access mapped_type& operator[](const key_type& __x) - { return operator[](__x); } + { return try_emplace(__x).first->second; } mapped_type& operator[](key_type&& __x) - { return operator[](std::move(__x)); } + { return try_emplace(std::move(__x)).first->second; } template - requires same_as, _Key> || __transparent_comparator<_Compare> + requires __transparent_comparator<_Compare> mapped_type& operator[](_Key2&& __x) { return try_emplace(std::forward<_Key2>(__x)).first->second; } diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format index b4929d5ae59f..d63c6fc9efd5 100644 --- a/libstdc++-v3/include/std/format +++ b/libstdc++-v3/include/std/format @@ -1854,20 +1854,6 @@ namespace __format __align, __nfill, __fill_char); } -#if defined __SIZEOF_INT128__ && defined __STRICT_ANSI__ - template - using make_unsigned_t - = typename __conditional_t<(sizeof(_Tp) <= sizeof(long long)), - std::make_unsigned<_Tp>, - type_identity>::type; - - // std::to_chars is not overloaded for int128 in strict mode. - template - static to_chars_result - to_chars(char* __first, char* __last, _Int __value, int __base) - { return std::__to_chars_i<_Int>(__first, __last, __value, __base); } -#endif - _Spec<_CharT> _M_spec{}; }; @@ -2398,9 +2384,16 @@ namespace __format const size_t __r = __str.size() - __e; // Length of remainder. auto __overwrite = [&](_CharT* __p, size_t) { // Apply grouping to the digits before the radix or exponent. - auto __end = std::__add_grouping(__p, __np.thousands_sep(), + int __off = 0; + if (auto __c = __str.front(); __c == '-' || __c == '+' || __c == ' ') + { + *__p = __c; + __off = 1; + } + auto __end = std::__add_grouping(__p + __off, __np.thousands_sep(), __grp.data(), __grp.size(), - __str.data(), __str.data() + __e); + __str.data() + __off, + __str.data() + __e); if (__r) // If there's a fractional part or exponent { if (__d != __str.npos) @@ -2991,11 +2984,9 @@ namespace __format }; #endif -#if defined(__SIZEOF_FLOAT128__) && _GLIBCXX_FORMAT_F128 > 1 - // Reuse __formatter_fp::format<__format::__flt128_t, Out> for __float128. - // This formatter is not declared if _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT is true, - // as __float128 when present is same type as __ieee128, which may be same as - // long double. +#if defined(__SIZEOF_FLOAT128__) && _GLIBCXX_FORMAT_F128 == 2 + // Use __formatter_fp::format<__format::__flt128_t, Out> for __float128, + // when long double is not 128bit IEEE type. template<__format::__char _CharT> struct formatter<__float128, _CharT> { @@ -3013,9 +3004,6 @@ namespace __format private: __format::__formatter_fp<_CharT> _M_f; - - static_assert( !is_same_v<__float128, long double>, - "This specialization should not be used for long double" ); }; #endif @@ -3107,24 +3095,28 @@ namespace __format // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3944. Formatters converting sequences of char to sequences of wchar_t - namespace __format { struct __disabled; } + struct __formatter_disabled + { + __formatter_disabled() = delete; // Cannot format char sequence to wchar_t + __formatter_disabled(const __formatter_disabled&) = delete; + __formatter_disabled& operator=(const __formatter_disabled&) = delete; + }; - // std::formatter<__disabled, C> uses the primary template, which is disabled. template<> struct formatter - : private formatter<__format::__disabled, wchar_t> { }; + : private __formatter_disabled { }; template<> struct formatter - : private formatter<__format::__disabled, wchar_t> { }; + : private __formatter_disabled { }; template struct formatter - : private formatter<__format::__disabled, wchar_t> { }; + : private __formatter_disabled { }; template struct formatter, wchar_t> - : private formatter<__format::__disabled, wchar_t> { }; + : private __formatter_disabled { }; template struct formatter, wchar_t> - : private formatter<__format::__disabled, wchar_t> { }; + : private __formatter_disabled { }; #endif /// An iterator after the last character written, and the number of @@ -5472,32 +5464,6 @@ namespace __format #endif #if __glibcxx_format_ranges // C++ >= 23 && HOSTED - // [format.range], formatting of ranges - // [format.range.fmtkind], variable template format_kind - enum class range_format { - disabled, - map, - set, - sequence, - string, - debug_string - }; - - /** @brief A constant determining how a range should be formatted. - * - * The primary template of `std::format_kind` cannot be instantiated. - * There is a partial specialization for input ranges and you can - * specialize the variable template for your own cv-unqualified types - * that satisfy the `ranges::input_range` concept. - * - * @since C++23 - */ - template - constexpr auto format_kind = []{ - static_assert(false, "cannot use primary template of 'std::format_kind'"); - return type_identity<_Rg>{}; - }(); - /// @cond undocumented template consteval range_format @@ -6050,13 +6016,13 @@ namespace __format constexpr void set_separator(basic_string_view<_CharT> __sep) noexcept - requires (!_S_range_format_is_string) + requires (format_kind<_Rg> == range_format::sequence) { _M_under.set_separator(__sep); } constexpr void set_brackets(basic_string_view<_CharT> __open, basic_string_view<_CharT> __close) noexcept - requires (!_S_range_format_is_string) + requires (format_kind<_Rg> == range_format::sequence) { _M_under.set_brackets(__open, __close); } // We deviate from standard, that declares this as template accepting diff --git a/libstdc++-v3/include/std/inplace_vector b/libstdc++-v3/include/std/inplace_vector new file mode 100644 index 000000000000..290cf6eb0e92 --- /dev/null +++ b/libstdc++-v3/include/std/inplace_vector @@ -0,0 +1,1379 @@ +// Sequence container with fixed capacity -*- C++ -*- + +// Copyright The GNU Toolchain Authors. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file include/inplace_vector + * This is a Standard C++ Library header. + * @ingroup sequences + */ + +#ifndef _GLIBCXX_INPLACE_VECTOR +#define _GLIBCXX_INPLACE_VECTOR 1 + +#pragma GCC system_header + +#define __glibcxx_want_inplace_vector +#include + +#ifdef __glibcxx_inplace_vector // C++ >= 26 +#include +#include +#include +#include // borrowed_iterator_t, __detail::__container_compatible_range +#include // subrange +#include +#include +#include +#include +#include // rotate + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // [indirect], class template indirect + template + class inplace_vector + { + public: + + // types: + using value_type = _Tp; + using pointer = _Tp*; + using const_pointer = const _Tp*; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = size_t; + using difference_type = ptrdiff_t; + using iterator + = __gnu_cxx::__normal_iterator<_Tp*, inplace_vector>; + using const_iterator + = __gnu_cxx::__normal_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // [containers.sequences.inplace.vector.cons], construct/copy/destroy + constexpr + inplace_vector() noexcept + { _M_init(); } + + constexpr explicit + inplace_vector(size_type __n) + { + _M_init(); + _S_reserve(__n); + std::uninitialized_value_construct_n(data(), __n); + _M_size = __n; + } + + constexpr + inplace_vector(size_type __n, const _Tp& __value) + { + _M_init(); + _S_reserve(__n); + std::uninitialized_fill_n(data(), __n, __value); + _M_size = __n; + } + + template<__any_input_iterator _InputIterator> + constexpr + inplace_vector(_InputIterator __first, _InputIterator __last) + : inplace_vector() + { + if (const auto __n = _S_distance(__first, __last)) + { + _S_reserve(__n); + std::uninitialized_copy(__first, __last, data()); + _M_size = __n; + } + else + { + while (__first != __last) + emplace_back(*__first++); + } + } + + template <__detail::__container_compatible_range<_Tp> _Rg> + constexpr + inplace_vector(from_range_t, _Rg&& __rg) + : inplace_vector() + { append_range(__rg); } + + constexpr + inplace_vector(initializer_list<_Tp> __il) + { + _M_init(); + _S_reserve(__il.size()); + std::uninitialized_copy(__il.begin(), __il.end(), data()); + _M_size = __il.size(); + } + + inplace_vector(const inplace_vector&) + requires is_trivially_copy_constructible_v<_Tp> + = default; + + constexpr + inplace_vector(const inplace_vector& __other) + noexcept(is_nothrow_copy_constructible_v<_Tp>) + { + _M_init(); + std::uninitialized_copy(__other.begin(), __other.end(), data()); + _M_size = __other.size(); + } + + inplace_vector(inplace_vector&&) + requires is_trivially_move_constructible_v<_Tp> + = default; + + constexpr + inplace_vector(inplace_vector&& __other) + noexcept(is_nothrow_move_constructible_v<_Tp>) + { + _M_init(); + std::uninitialized_move(__other.begin(), __other.end(), data()); + _M_size = __other.size(); + } + + ~inplace_vector() + requires is_trivially_destructible_v<_Tp> + = default; + + constexpr + ~inplace_vector() + { clear(); } + + inplace_vector& + operator=(const inplace_vector&) + requires is_trivially_copy_assignable_v<_Tp> + && is_trivially_copy_constructible_v<_Tp> + && is_trivially_destructible_v<_Tp> + = default; + + constexpr inplace_vector& + operator=(const inplace_vector& __other) + noexcept(is_nothrow_copy_assignable_v<_Tp> + && is_nothrow_copy_constructible_v<_Tp>) + { + if (std::addressof(__other) != this) [[likely]] + assign(__other.begin(), __other.end()); + return *this; + } + + inplace_vector& + operator=(inplace_vector&&) + requires is_trivially_move_assignable_v<_Tp> + && is_trivially_move_constructible_v<_Tp> + && is_trivially_destructible_v<_Tp> + = default; + + constexpr inplace_vector& + operator=(inplace_vector&& __other) + noexcept(is_nothrow_move_assignable_v<_Tp> + && is_nothrow_move_constructible_v<_Tp>) + { + if (std::addressof(__other) != this) [[likely]] + assign(std::make_move_iterator(__other.begin()), + std::make_move_iterator(__other.end())); + return *this; + } + + constexpr inplace_vector& + operator=(initializer_list<_Tp> __il) + { + assign(__il.begin(), __il.end()); + return *this; + } + + template<__any_input_iterator _InputIterator> + constexpr void + assign(_InputIterator __first, _InputIterator __last) + { + if (const auto __n = _S_distance(__first, __last)) + { + _S_reserve(__n); + if (_M_size <= __n) + { + for (size_t __i = 0; __i < _M_size; ++__i, (void)++__first) + _M_elems[__i] = *__first; + std::uninitialized_copy(__first, __last, end()); + } + else + std::destroy(std::copy(__first, __last, begin()), end()); + _M_size = __n; + } + else + { + size_t __i = 0; + for (;__first != __last && __i < _M_size; ++__first) + _M_elems[__i++] = *__first; + if (__first == __last) + { + std::_Destroy_n(data() + __i, _M_size - __i); + _M_size = __i; + } + else + { + while (__first != __last) + emplace_back(*__first++); + } + } + } + + template<__detail::__container_compatible_range<_Tp> _Rg> + constexpr void + assign_range(_Rg&& __rg) + { + if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>) + { + const auto __sz = ranges::distance(__rg); + if (__sz > _Nm) + __throw_bad_alloc(); + if (__sz <= size()) + { + ranges::copy_n(ranges::begin(__rg), __sz, data()); + std::destroy(data() + __sz, data() + _M_size); + } + else + { + auto [__in, __out] = ranges::copy_n( + ranges::begin(__rg), _M_size, + data()); + ranges::uninitialized_copy( + std::move(__in), ranges::end(__rg), + __out, unreachable_sentinel); + } + _M_size = __sz; + } + else + { + auto __in = ranges::begin(__rg); + auto __end = ranges::end(__rg); + size_type __n = 0; + for (; __n < _M_size && __in != __end; ++__in) + _M_elems[__n++] = *__in; + + if (__in == __end) + { + std::destroy(data() + __n, data() + _M_size); + _M_size = __n; + return; + } + else if (__n < _Nm) + { + auto __res = ranges::uninitialized_copy( + std::move(__in), __end, + data() + __n, data() + _Nm); + _M_size = __res.out - data(); + if (__res.in == ranges::end(__rg)) + return; + } + __throw_bad_alloc(); + } + } + + constexpr void + assign(size_type __n, const _Tp& __u) + { + _S_reserve(__n); + if (_M_size <= __n) + std::uninitialized_fill_n(std::fill_n(data(), _M_size, __u), + __n - _M_size, __u); + else + std::destroy_n(std::fill_n(data(), __n, __u), _M_size - __n); + _M_size = __n; + } + + constexpr void + assign(initializer_list<_Tp> __il) + { assign(__il.begin(), __il.end()); } + + // iterators + [[nodiscard]] + constexpr iterator + begin() noexcept { return iterator(data()); } + + [[nodiscard]] + constexpr const_iterator + begin() const noexcept { return const_iterator(data()); } + + [[nodiscard]] + constexpr iterator + end() noexcept + { return iterator(data() + _M_size); } + + [[nodiscard]] + constexpr const_iterator + end() const noexcept + { return const_iterator(data() + _M_size); } + + [[nodiscard]] + constexpr reverse_iterator + rbegin() noexcept + { return reverse_iterator(end()); } + + [[nodiscard]] + constexpr const_reverse_iterator + rbegin() const noexcept + { return const_reverse_iterator(end()); } + + [[nodiscard]] + constexpr reverse_iterator + rend() noexcept { return reverse_iterator(begin()); } + + [[nodiscard]] + constexpr const_reverse_iterator + rend() const noexcept { return const_reverse_iterator(begin()); } + + [[nodiscard]] + constexpr const_iterator + cbegin() const noexcept { return begin(); } + + [[nodiscard]] + constexpr const_iterator + cend() const noexcept { return end(); } + + [[nodiscard]] + constexpr const_reverse_iterator + crbegin() const noexcept { return rbegin(); } + + [[nodiscard]] + constexpr const_reverse_iterator + crend() const noexcept { return rend(); } + + // [containers.sequences.inplace.vector.members] size/capacity + [[nodiscard]] + constexpr bool + empty() const noexcept { return _M_size == 0; } + + [[nodiscard]] + constexpr size_type + size() const noexcept + { + if (_M_size > _Nm) + __builtin_unreachable(); + return _M_size; + } + + [[nodiscard]] + static constexpr size_type + max_size() noexcept { return _Nm; } + + [[nodiscard]] + static constexpr size_type + capacity() noexcept { return _Nm; } + + constexpr void + resize(size_type __n) + { + _S_reserve(__n); + if (__n > _M_size) + std::uninitialized_value_construct_n(data() + _M_size, __n - _M_size); + else if (__n < _M_size) + std::destroy_n(data() + __n, _M_size - __n); + _M_size = __n; + } + + constexpr void + resize(size_type __n, const _Tp& __c) + { + _S_reserve(__n); + if (__n > _M_size) + std::uninitialized_fill_n(data() + _M_size, __n - _M_size, __c); + else if (__n < _M_size) + std::destroy_n(data() + __n, _M_size - __n); + _M_size = __n; + } + + static constexpr void + reserve(size_type __n) + { _S_reserve(__n); } + + static constexpr void + shrink_to_fit() { } + + // element access + [[nodiscard]] + constexpr reference + operator[](size_type __n) + { + __glibcxx_requires_subscript(__n); + return _M_elems[__n]; + } + + [[nodiscard]] + constexpr const_reference + operator[](size_type __n) const + { + __glibcxx_requires_subscript(__n); + return _M_elems[__n]; + } + + [[nodiscard]] + constexpr const_reference + at(size_type __n) const + { + if (__n >= _M_size) + std::__throw_out_of_range_fmt(__N("inplace_vector::at: __n " + "(which is %zu) " + ">= size() (which is %zu)"), + __n, _M_size); + return _M_elems[__n]; + } + + [[nodiscard]] + constexpr reference + at(size_type __n) + { + if (__n >= _M_size) + std::__throw_out_of_range_fmt(__N("inplace_vector::at: __n " + "(which is %zu) " + ">= size() (which is %zu)"), + __n, _M_size); + return _M_elems[__n]; + } + + [[nodiscard]] + constexpr reference + front() + { + __glibcxx_requires_nonempty(); + return _M_elems[0]; + } + + [[nodiscard]] + constexpr const_reference + front() const + { + __glibcxx_requires_nonempty(); + return _M_elems[0]; + } + + [[nodiscard]] + constexpr reference + back() + { + __glibcxx_requires_nonempty(); + return _M_elems[_M_size - 1]; + } + + [[nodiscard]] + constexpr const_reference + back() const + { + __glibcxx_requires_nonempty(); + return _M_elems[_M_size - 1]; + } + + // [containers.sequences.inplace.vector.data], data access + + [[nodiscard]] + constexpr _Tp* + data() noexcept + { return static_cast(_M_elems); } + + [[nodiscard]] + constexpr const _Tp* + data() const noexcept + { return static_cast(_M_elems); } + + // [containers.sequences.inplace.vector.modifiers], modifiers + template + constexpr _Tp& + emplace_back(_Args&&... __args) + { + if (_M_size >= _Nm) + __throw_bad_alloc(); + return unchecked_emplace_back(std::forward<_Args>(__args)...); + } + + constexpr _Tp& + push_back(const _Tp& __x) + { return emplace_back(__x); } + + constexpr _Tp& + push_back(_Tp&& __x) + { return emplace_back(std::move(__x)); } + + template<__detail::__container_compatible_range<_Tp> _Rg> + constexpr void + append_range(_Rg&& __rg) + { + if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>) + { + const auto __sz = ranges::distance(__rg); + if (__sz > (_Nm - size())) + __throw_bad_alloc(); + // Bounded on output range due PR121143 + ranges::uninitialized_copy( + ranges::begin(__rg), unreachable_sentinel, + data() + _M_size, data() + _M_size + __sz); + _M_size += size_type(__sz); + } + else + { + ranges::subrange __tail(data() + _M_size, data() + _Nm); + auto [__in, __out] = ranges::uninitialized_copy(__rg, __tail); + _M_size = __out - data(); + if (__in != ranges::end(__rg)) + __throw_bad_alloc(); + } + } + + constexpr void + pop_back() + { + __glibcxx_requires_nonempty(); + --_M_size; + _M_elems[_M_size].~_Tp(); + } + + template + constexpr _Tp* + try_emplace_back(_Args&&... __args) + { + if (_M_size >= _Nm) [[unlikely]] + return nullptr; + auto& __r = unchecked_emplace_back(std::forward<_Args>(__args)...); + return __builtin_addressof(__r); + } + + constexpr _Tp* + try_push_back(const _Tp& __x) + { + if (_M_size >= _Nm) [[unlikely]] + return nullptr; + return __builtin_addressof(unchecked_emplace_back(__x)); + } + + constexpr _Tp* + try_push_back(_Tp&& __x) + { + if (_M_size >= _Nm) [[unlikely]] + return nullptr; + return __builtin_addressof(unchecked_emplace_back(std::move(__x))); + } + + template<__detail::__container_compatible_range<_Tp> _Rg> + constexpr ranges::borrowed_iterator_t<_Rg> + try_append_range(_Rg&& __rg) + { + if constexpr (ranges::sized_range<_Rg>) + { + auto __n = ranges::distance(__rg); + if (__n == 0) [[unlikely]] + return ranges::begin(__rg); + + const auto __end = data() + _M_size; + const size_t __avail = _Nm - size(); + if (__n <= __avail) + _M_size += size_type(__n); + else + { + __n = __avail; + _M_size = _Nm; + } + return ranges::uninitialized_copy_n( + ranges::begin(__rg), __n, + __end, unreachable_sentinel).in; + } + else + { + ranges::subrange __tail(data() + _M_size, data() + _Nm); + auto [__in, __out] = ranges::uninitialized_copy(__rg, __tail); + _M_size = __out - data(); + return std::move(__in); + } + } + + template + constexpr _Tp& + unchecked_emplace_back(_Args&&... __args) + { + __glibcxx_assert(_M_size < _Nm); + auto __p = std::construct_at(data() + _M_size, + std::forward<_Args>(__args)...); + ++_M_size; + return *__p; + } + + constexpr _Tp& + unchecked_push_back(const _Tp& __x) + { return unchecked_emplace_back(__x); } + + constexpr _Tp& + unchecked_push_back(_Tp&& __x) + { return unchecked_emplace_back(std::move(__x)); } + + template + constexpr iterator + emplace(const_iterator __position, _Args&&... __args) + { + size_t __b = __position - cbegin(); // elements before position + __glibcxx_assert(__b <= _M_size); + if (_M_size >= _Nm) + __throw_bad_alloc(); + iterator __pos = begin() + __b; + std::construct_at(data() + _M_size, std::forward<_Args>(__args)...); + if (_M_size++) + std::rotate(__pos, end() - 1, end()); + return __pos; + } + + constexpr iterator + insert(const_iterator __position, const _Tp& __x) + { return emplace(__position, __x); } + + constexpr iterator + insert(const_iterator __position, _Tp&& __x) + { return emplace(__position, std::move(__x)); } + + constexpr iterator + insert(const_iterator __position, size_type __n, const _Tp& __x) + { + size_t __b = __position - cbegin(); // elements before position + __glibcxx_assert(__b <= _M_size); + if ((_Nm - _M_size) < __n) + __throw_bad_alloc(); + iterator __pos = begin() + __b; + std::uninitialized_fill_n(data() + _M_size, __n, __x); + if (std::__exchange(_M_size, _M_size + __n)) + std::rotate(__pos, end() - __n, end()); + return __pos; + } + + template<__any_input_iterator _InputIterator> + constexpr iterator + insert(const_iterator __position, _InputIterator __first, + _InputIterator __last) + { + size_t __b = __position - cbegin(); // elements before position + __glibcxx_assert(__b <= _M_size); + iterator __pos = begin() + __b; + const size_t __s = _M_size; + if (const auto __n = _S_distance(__first, __last)) + { + if ((_Nm - _M_size) < __n) + __throw_bad_alloc(); + std::uninitialized_copy(__first, __last, data() + _M_size); + _M_size += __n; + } + else + { + while (__first != __last) + emplace_back(*__first++); + } + if (__s) + std::rotate(__pos, begin() + __s, end()); + return __pos; + } + + template<__detail::__container_compatible_range<_Tp> _Rg> + constexpr iterator + insert_range(const_iterator __position, _Rg&& __rg) + { + iterator __pos = begin() + (__position - cbegin()); + const auto __end = end(); + if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>) + { + const auto __len = ranges::distance(__rg); + if (__len > (_Nm - size())) + __throw_bad_alloc(); + if (!__len) [[unlikely]] + return __pos; + + const size_type __n = size_type(__len); + const size_type __num_after = __end - __pos; + if (__num_after >= __n) + { + ranges::uninitialized_move(__end - __n, __end, + __end, unreachable_sentinel); + _M_size += __n; + ranges::move_backward(__pos, __end - __n, __end); + ranges::copy(__rg, __pos); + } + else if constexpr (ranges::forward_range<_Rg>) + { + auto __mid = ranges::next(ranges::begin(__rg), __num_after); + ranges::uninitialized_copy(__mid, ranges::end(__rg), + __end, unreachable_sentinel); + _M_size += __n - __num_after; + ranges::uninitialized_move(__pos, __end, + __pos + __n, unreachable_sentinel); + _M_size += __num_after; + ranges::copy(ranges::begin(__rg), __mid, __pos); + } + else + { + ranges::uninitialized_copy( + ranges::begin(__rg), ranges::end(__rg), + __end, unreachable_sentinel); + _M_size += __n; + std::rotate(__pos, __end, end()); + } + } + else + { + append_range(__rg); + std::rotate(__pos, __end, end()); + } + return __pos; + } + + constexpr iterator + insert(const_iterator __position, initializer_list<_Tp> __il) + { return insert(__position, __il.begin(), __il.end()); } + + constexpr iterator + erase(const_iterator __position) + { + size_t __n = __position - cbegin(); + __glibcxx_assert(__n < _M_size); + iterator __pos = begin() + __n; + std::move(__pos + 1, end(), __pos); + pop_back(); + return __pos; + } + + constexpr iterator + erase(const_iterator __first, const_iterator __last) + { + size_t __n = __first - cbegin(); + size_t __x = __last - __first; + __glibcxx_assert(__n <= _M_size); + __glibcxx_assert(__x <= _M_size); + iterator __pos = begin() + __n; + iterator __end = std::move(__pos + __x, end(), __pos); + std::destroy_n(__end, __x); + _M_size -= __x; + return __pos; + } + + constexpr void + swap(inplace_vector& __x) + noexcept(is_nothrow_swappable_v<_Tp> && is_nothrow_move_constructible_v<_Tp>) + { + inplace_vector* __vs[2]{ this, std::addressof(__x) }; + const auto __smaller = __vs[__x.size() < size()]; + const auto __bigger = __vs[__x.size() >= size()]; + size_type __n = __smaller->size(); + size_type __n2 = __bigger->size(); + + if constexpr (is_nothrow_move_constructible_v<_Tp>) + { + for (size_type __i = __n; __i < __n2; ++__i) + { + std::construct_at(__smaller->data() + __i, + std::move(*(__bigger->data() + __i))); + std::destroy_at(__bigger->data() + __i); + } + } + else + { + std::uninitialized_copy(__bigger->data() + __n, + __bigger->data() + __n2, + __smaller->data() + __n); + std::destroy(__bigger->data() + __n, __bigger->data() + __n2); + } + __smaller->_M_size = __n2; + __bigger->_M_size = __n; + + using std::swap; + for (size_type __i = 0; __i < __n; __i++) + swap(_M_elems[__i], __x._M_elems[__i]); + } + + constexpr void + clear() noexcept + { + std::destroy_n(data(), size_t(_M_size)); + _M_size = 0; + } + + constexpr friend bool + operator==(const inplace_vector& __x, const inplace_vector& __y) + { return std::equal(__x.begin(), __x.end(), __y.begin(), __y.end()); } + + constexpr friend auto + operator<=>(const inplace_vector& __x, const inplace_vector& __y) + requires requires (const _Tp __t) { + { __t < __t } -> __detail::__boolean_testable; + } + { + return std::lexicographical_compare_three_way(__x.begin(), __x.end(), + __y.begin(), __y.end(), + __detail::__synth3way); + } + + constexpr friend void + swap(inplace_vector& __x, inplace_vector& __y) + noexcept(is_nothrow_swappable_v<_Tp> && is_nothrow_move_constructible_v<_Tp>) + { __x.swap(__y); } + + private: + union { + _Tp _M_elems[_Nm]; + }; + + // Check whether integer type _UInt is wide enough to store _Nm, + // so that we use a smaller type for _M_size when that saves space. + template + static constexpr bool __fits + = _Nm <= __gnu_cxx::__int_traits<_UInt>::__max; + + // Don't bother using a smaller type if alignment of the array elements + // means that it doesn't actually save space. + template + static constexpr bool __fits<_UInt, false> = false; + + static consteval auto __select_size_type() + { + if constexpr (__fits) + return (unsigned char)0; +#if __SHRT_WIDTH__ < __SIZE_WIDTH__ + else if constexpr (__fits) + return (unsigned short)0; +#endif +#if __INT_WIDTH__ < __SIZE_WIDTH__ && __INT_WIDTH__ > __SHRT_WIDTH__ + else if constexpr (__fits) + return 0u; +#endif +#if __LONG_WIDTH__ < __SIZE_WIDTH__ && __LONG_WIDTH__ > __INT_WIDTH__ + else if constexpr (__fits) + return 0ul; +#endif + else // Just use size_t. + return 0uz; + } + decltype(__select_size_type()) _M_size = 0; + + constexpr void + _M_init() + { + if !consteval + { +#if __glibcxx_start_lifetime_as + std::start_lifetime_as_array<_Tp>(data(), _Nm); +#endif + } + else + { + // TODO: use new(_M_elems) _Tp[_Nm]() once PR121068 is fixed + if constexpr (is_trivial_v<_Tp>) + for (size_t __i = 0; __i < _Nm; ++__i) + _M_elems[__i] = _Tp(); + else + __builtin_unreachable(); // only trivial types are supported at compile time + } + } + + static constexpr void + _S_reserve(size_t __n) + { + if (__n > _Nm) + __throw_bad_alloc(); + } + + template + constexpr static auto + _S_distance(_InputIterator __first, _InputIterator __last) + { + if constexpr (sized_sentinel_for<_InputIterator, _InputIterator> + || forward_iterator<_InputIterator>) + return (size_type)ranges::distance(__first, __last); + else if constexpr (derived_from<__iter_category_t<_InputIterator>, + forward_iterator_tag>) + return (size_type)std::distance(__first, __last); + else + return false_type{}; + } + }; + + // [inplace.vector.special], specialized algorithms + template + constexpr void + swap(inplace_vector<_Tp, _Nm>& __x, inplace_vector<_Tp, _Nm>& __y) + noexcept(noexcept(__x.swap(__y))) + { __x.swap(__y); } + + // specialization for zero capacity, that is required to be trivally copyable + // and empty regardless of _Tp. + template + class inplace_vector<_Tp, 0> + { + public: + // types: + using value_type = _Tp; + using pointer = _Tp*; + using const_pointer = const _Tp*; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = size_t; + using difference_type = ptrdiff_t; + using iterator + = __gnu_cxx::__normal_iterator<_Tp*, inplace_vector>; + using const_iterator + = __gnu_cxx::__normal_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // [containers.sequences.inplace.vector.cons], construct/copy/destroy + inplace_vector() = default; + + constexpr explicit + inplace_vector(size_type __n) + { + if (__n != 0) + __throw_bad_alloc(); + } + + constexpr + inplace_vector(size_type __n, const _Tp& __value) + { + if (__n != 0) + __throw_bad_alloc(); + } + + template<__any_input_iterator _InputIterator> + constexpr + inplace_vector(_InputIterator __first, _InputIterator __last) + { + if (__first != __last) + __throw_bad_alloc(); + } + + template <__detail::__container_compatible_range<_Tp> _Rg> + constexpr + inplace_vector(from_range_t, _Rg&& __rg) + { + if (ranges::begin(__rg) != ranges::end(__rg)) + __throw_bad_alloc(); + } + + constexpr + inplace_vector(initializer_list<_Tp> __il) + { + if (__il.size() != 0) + __throw_bad_alloc(); + } + + inplace_vector(const inplace_vector&) = default; + inplace_vector(inplace_vector&&) = default; + + constexpr + ~inplace_vector() = default; + + inplace_vector& + operator=(const inplace_vector&) = default; + + inplace_vector& + operator=(inplace_vector&&) = default; + + constexpr inplace_vector& + operator=(initializer_list<_Tp> __il) + { + if (__il.size() != 0) + __throw_bad_alloc(); + } + + template<__any_input_iterator _InputIterator> + constexpr void + assign(_InputIterator __first, _InputIterator __last) + { + if (__first != __last) + __throw_bad_alloc(); + } + + template<__detail::__container_compatible_range<_Tp> _Rg> + constexpr void + assign_range(_Rg&& __rg) + { + if (ranges::begin(__rg) != ranges::end(__rg)) + __throw_bad_alloc(); + } + + constexpr void + assign(size_type __n, const _Tp& __u) + { + if (__n != 0) + __throw_bad_alloc(); + } + + constexpr void + assign(initializer_list<_Tp> __il) + { + if (__il.size() != 0) + __throw_bad_alloc(); + } + + // iterators + [[nodiscard]] + constexpr iterator + begin() noexcept { return iterator(nullptr); } + + [[nodiscard]] + constexpr const_iterator + begin() const noexcept { return const_iterator(nullptr); } + + [[nodiscard]] + constexpr iterator + end() noexcept { return iterator(nullptr); } + + [[nodiscard]] + constexpr const_iterator + end() const noexcept { return const_iterator(nullptr); } + + [[nodiscard]] + constexpr reverse_iterator + rbegin() noexcept + { return reverse_iterator(end()); } + + [[nodiscard]] + constexpr const_reverse_iterator + rbegin() const noexcept + { return const_reverse_iterator(end()); } + + [[nodiscard]] + constexpr reverse_iterator + rend() noexcept { return reverse_iterator(begin()); } + + [[nodiscard]] + constexpr const_reverse_iterator + rend() const noexcept { return const_reverse_iterator(begin()); } + + [[nodiscard]] + constexpr const_iterator + cbegin() const noexcept { return begin(); } + + [[nodiscard]] + constexpr const_iterator + cend() const noexcept { return end(); } + + [[nodiscard]] + constexpr const_reverse_iterator + crbegin() const noexcept { return rbegin(); } + + [[nodiscard]] + constexpr const_reverse_iterator + crend() const noexcept { return rend(); } + + // [containers.sequences.inplace.vector.members] size/capacity + [[nodiscard]] + constexpr bool + empty() const noexcept { return true; } + + [[nodiscard]] + constexpr size_type + size() const noexcept { return 0; } + + [[nodiscard]] + static constexpr size_type + max_size() noexcept { return 0; } + + [[nodiscard]] + static constexpr size_type + capacity() noexcept { return 0; } + + constexpr void + resize(size_type __n) + { + if (__n != 0) + __throw_bad_alloc(); + } + + constexpr void + resize(size_type __n, const _Tp&) + { + if (__n != 0) + __throw_bad_alloc(); + } + + static constexpr void + reserve(size_type __n) + { + if (__n != 0) + __throw_bad_alloc(); + } + + static constexpr void + shrink_to_fit() { } + + // element access + [[nodiscard,noreturn]] + constexpr reference + operator[](size_type) + { __builtin_trap(); } + + [[nodiscard,noreturn]] + constexpr const_reference + operator[](size_type) const + { __builtin_trap(); } + + [[nodiscard,noreturn]] + constexpr const_reference + at(size_type __n) const + { + std::__throw_out_of_range_fmt(__N("inplace_vector::at: __n " + "(which is %zu) " + ">= size() (which is 0)"), + __n); + } + + [[nodiscard,noreturn]] + constexpr reference + at(size_type __n) + { + std::__throw_out_of_range_fmt(__N("inplace_vector::at: __n " + "(which is %zu) " + ">= size() (which is 0)"), + __n); + } + + [[nodiscard,noreturn]] + constexpr reference + front() + { __builtin_trap(); } + + [[nodiscard,noreturn]] + constexpr const_reference + front() const + { __builtin_trap(); } + + [[nodiscard,noreturn]] + constexpr reference + back() + { __builtin_trap(); } + + [[nodiscard,noreturn]] + constexpr const_reference + back() const + { __builtin_trap(); } + + // [containers.sequences.inplace.vector.data], data access + + [[nodiscard]] + constexpr _Tp* + data() noexcept + { return nullptr; } + + [[nodiscard]] + constexpr const _Tp* + data() const noexcept + { return nullptr; } + + // [containers.sequences.inplace.vector.modifiers], modifiers + template + [[noreturn]] + constexpr _Tp& + emplace_back(_Args&&...) + { __throw_bad_alloc(); } + + [[noreturn]] + constexpr _Tp& + push_back(const _Tp&) + { __throw_bad_alloc(); } + + [[noreturn]] + constexpr _Tp& + push_back(_Tp&&) + { __throw_bad_alloc(); } + + template<__detail::__container_compatible_range<_Tp> _Rg> + constexpr void + append_range(_Rg&& __rg) + { + if (ranges::begin(__rg) != ranges::end(__rg)) + __throw_bad_alloc(); + } + + [[noreturn]] + constexpr void + pop_back() + { __builtin_trap(); } + + template + constexpr _Tp* + try_emplace_back(_Args&&...) + { return nullptr; } + + constexpr _Tp* + try_push_back(const _Tp&) + { return nullptr; } + + constexpr _Tp* + try_push_back(_Tp&&) + { return nullptr; } + + template<__detail::__container_compatible_range<_Tp> _Rg> + constexpr ranges::borrowed_iterator_t<_Rg> + try_append_range(_Rg&& __rg) + { return ranges::begin(__rg); } + + template + [[noreturn]] + constexpr _Tp& + unchecked_emplace_back(_Args&&...) + { __builtin_trap(); } + + [[noreturn]] + constexpr _Tp& + unchecked_push_back(const _Tp&) + { __builtin_trap(); } + + [[noreturn]] + constexpr _Tp& + unchecked_push_back(_Tp&&) + { __builtin_trap(); } + + template + [[noreturn]] + constexpr iterator + emplace(const_iterator, _Args&&...) + { __throw_bad_alloc(); } + + [[noreturn]] + constexpr iterator + insert(const_iterator, const _Tp&) + { __throw_bad_alloc(); } + + [[noreturn]] + constexpr iterator + insert(const_iterator, _Tp&&) + { __throw_bad_alloc(); } + + constexpr iterator + insert(const_iterator, size_type __n, const _Tp&) + { + if (__n != 0) + __throw_bad_alloc(); + return begin(); + } + + template + constexpr iterator + insert(const_iterator, _InputIterator __first, _InputIterator __last) + { + if (__first != __last) + __throw_bad_alloc(); + return begin(); + } + + template<__detail::__container_compatible_range<_Tp> _Rg> + constexpr iterator + insert_range(const_iterator, _Rg&& __rg) + { + if (ranges::begin(__rg) != ranges::end(__rg)) + __throw_bad_alloc(); + return begin(); + } + + constexpr iterator + insert(const_iterator, initializer_list<_Tp> __il) + { + if (__il.size() != 0) + __throw_bad_alloc(); + return begin(); + } + + [[noreturn]] + constexpr iterator + erase(const_iterator) + { __builtin_trap(); } + + constexpr iterator + erase(const_iterator __first, const_iterator __last) + { + __glibcxx_assert(__first == __last); + return begin(); + } + + constexpr void + swap(inplace_vector& __x) + noexcept + { } + + constexpr void + clear() noexcept + { } + + constexpr friend bool + operator==(const inplace_vector&, const inplace_vector&) + { return true; } + + constexpr friend auto + operator<=>(const inplace_vector&, const inplace_vector&) + requires requires (const _Tp __t) { + { __t < __t } -> __detail::__boolean_testable; + } + { return std::strong_ordering::equal; } + + // n.b. there is not explicit wording requiring that swap for inplace_vector, + // with zero size, works even if element type is not swappable. However given + // that move operations are required to be present and trivial, it makes sense + // to support them. + constexpr friend void + swap(inplace_vector&, inplace_vector&) noexcept + { } + }; + + template + constexpr size_t + erase_if(inplace_vector<_Tp, _Nm>& __cont, _Predicate __pred) + { + using namespace __gnu_cxx; + const auto __osz = __cont.size(); + const auto __end = __cont.end(); + auto __removed = std::__remove_if(__cont.begin(), __end, + __ops::__pred_iter(std::ref(__pred))); + if (__removed != __end) + { + __cont.erase(__niter_wrap(__cont.begin(), __removed), + __cont.end()); + return __osz - __cont.size(); + } + return 0; + } + + + template + constexpr size_t + erase(inplace_vector<_Tp, _Nm>& __cont, const _Up& __value) + { + using namespace __gnu_cxx; + const auto __osz = __cont.size(); + const auto __end = __cont.end(); + auto __removed = std::__remove_if(__cont.begin(), __end, + __ops::__iter_equals_val(__value)); + if (__removed != __end) + { + __cont.erase(__niter_wrap(__cont.begin(), __removed), + __cont.end()); + return __osz - __cont.size(); + } + return 0; + } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +#endif // __glibcxx_inplace_vector +#endif // _GLIBCXX_INPLACE_VECTOR diff --git a/libstdc++-v3/include/std/limits b/libstdc++-v3/include/std/limits index 2331c25599a0..3567a3284006 100644 --- a/libstdc++-v3/include/std/limits +++ b/libstdc++-v3/include/std/limits @@ -1639,7 +1639,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #define __INT_N_U201103(TYPE) #endif -#if !defined(__STRICT_ANSI__) #ifdef __GLIBCXX_TYPE_INT_N_0 __INT_N(__GLIBCXX_TYPE_INT_N_0, __GLIBCXX_BITSIZE_INT_N_0, __INT_N_201103 (__GLIBCXX_TYPE_INT_N_0), @@ -1661,7 +1660,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_3)) #endif -#elif defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ +#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ __INT_N(__int128, 128, __INT_N_201103 (__int128), __INT_N_U201103 (__int128)) diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan index bcf2fa60feab..055778d29688 100644 --- a/libstdc++-v3/include/std/mdspan +++ b/libstdc++-v3/include/std/mdspan @@ -69,12 +69,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // // If __r is the index of a dynamic extent, then // _S_dynamic_index[__r] is the index of that extent in - // _M_dynamic_extents. + // _M_dyn_exts. static constexpr auto _S_dynamic_index = [] consteval { array __ret; size_t __dyn = 0; - for(size_t __i = 0; __i < _S_rank; ++__i) + for (size_t __i = 0; __i < _S_rank; ++__i) { __ret[__i] = __dyn; __dyn += _S_is_dyn(_Extents[__i]); @@ -105,21 +105,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { auto __se = _Extents[__r]; if (__se == dynamic_extent) - return _M_dynamic_extents[_S_dynamic_index[__r]]; + return _M_dyn_exts[_S_dynamic_index[__r]]; else return __se; } + template + static constexpr bool + _S_is_compatible_extents(_GetOtherExtent __get_extent) noexcept + { + if constexpr (_OtherRank == _S_rank) + for (size_t __i = 0; __i < _S_rank; ++__i) + if (_Extents[__i] != dynamic_extent + && !cmp_equal(_Extents[__i], _S_int_cast(__get_extent(__i)))) + return false; + return true; + } + template constexpr void _M_init_dynamic_extents(_GetOtherExtent __get_extent) noexcept { - for(size_t __i = 0; __i < _S_rank_dynamic; ++__i) + __glibcxx_assert(_S_is_compatible_extents<_OtherRank>(__get_extent)); + for (size_t __i = 0; __i < _S_rank_dynamic; ++__i) { size_t __di = __i; if constexpr (_OtherRank != _S_rank_dynamic) __di = _S_dynamic_index_inv[__i]; - _M_dynamic_extents[__i] = _S_int_cast(__get_extent(__di)); + _M_dyn_exts[__i] = _S_int_cast(__get_extent(__di)); } } @@ -144,9 +157,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __exts[__i]; }); } + static constexpr span + _S_static_extents(size_t __begin, size_t __end) noexcept + { + return {_Extents.data() + __begin, _Extents.data() + __end}; + } + + constexpr span + _M_dynamic_extents(size_t __begin, size_t __end) const noexcept + requires (_Extents.size() > 0) + { + return {_M_dyn_exts + _S_dynamic_index[__begin], + _M_dyn_exts + _S_dynamic_index[__end]}; + } + private: using _S_storage = __array_traits<_IndexType, _S_rank_dynamic>::_Type; - [[no_unique_address]] _S_storage _M_dynamic_extents{}; + [[no_unique_address]] _S_storage _M_dyn_exts{}; }; template @@ -160,6 +187,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION || _Extent <= numeric_limits<_IndexType>::max(); } + namespace __mdspan + { + template + constexpr span + __static_extents(size_t __begin = 0, size_t __end = _Extents::rank()) + noexcept + { return _Extents::_S_storage::_S_static_extents(__begin, __end); } + + template + constexpr span + __dynamic_extents(const _Extents& __exts, size_t __begin = 0, + size_t __end = _Extents::rank()) noexcept + { + return __exts._M_exts._M_dynamic_extents(__begin, __end); + } + } + template class extents { @@ -197,7 +241,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if constexpr (rank() == 0) __builtin_trap(); else - return _M_dynamic_extents._M_extent(__r); + return _M_exts._M_extent(__r); } constexpr @@ -233,30 +277,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION requires (_S_is_compatible_extents<_OExtents...>()) constexpr explicit(_S_ctor_explicit<_OIndexType, _OExtents...>()) extents(const extents<_OIndexType, _OExtents...>& __other) noexcept - : _M_dynamic_extents(__other._M_dynamic_extents) + : _M_exts(__other._M_exts) { } template<__mdspan::__valid_index_type... _OIndexTypes> requires (sizeof...(_OIndexTypes) == rank() || sizeof...(_OIndexTypes) == rank_dynamic()) constexpr explicit extents(_OIndexTypes... __exts) noexcept - : _M_dynamic_extents(span( - initializer_list{_S_storage::_S_int_cast(__exts)...})) + : _M_exts(span( + initializer_list{static_cast<_IndexType>(std::move(__exts))...})) { } - template<__mdspan::__valid_index_type _OIndexType, size_t _Nm> - requires (_Nm == rank() || _Nm == rank_dynamic()) + template + requires __mdspan::__valid_index_type + && (_Nm == rank() || _Nm == rank_dynamic()) constexpr explicit(_Nm != rank_dynamic()) extents(span<_OIndexType, _Nm> __exts) noexcept - : _M_dynamic_extents(span(__exts)) + : _M_exts(span(__exts)) { } - - template<__mdspan::__valid_index_type _OIndexType, size_t _Nm> - requires (_Nm == rank() || _Nm == rank_dynamic()) + template + requires __mdspan::__valid_index_type + && (_Nm == rank() || _Nm == rank_dynamic()) constexpr explicit(_Nm != rank_dynamic()) extents(const array<_OIndexType, _Nm>& __exts) noexcept - : _M_dynamic_extents(span(__exts)) + : _M_exts(span(__exts)) { } template @@ -276,9 +321,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } private: + friend span + __mdspan::__static_extents(size_t, size_t); + + friend span + __mdspan::__dynamic_extents(const extents&, size_t, size_t); + using _S_storage = __mdspan::_ExtentsStorage< _IndexType, array{_Extents...}>; - [[no_unique_address]] _S_storage _M_dynamic_extents; + [[no_unique_address]] _S_storage _M_exts; template friend class extents; @@ -286,13 +337,77 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __mdspan { + template + constexpr bool + __contains_zero(span<_Tp, _Nm> __exts) noexcept + { + for (size_t __i = 0; __i < __exts.size(); ++__i) + if (__exts[__i] == 0) + return true; + return false; + } + + template + constexpr bool + __empty(const _Extents& __exts) noexcept + { + if constexpr (__contains_zero(__static_extents<_Extents>())) + return true; + else if constexpr (_Extents::rank_dynamic() > 0) + return __contains_zero(__dynamic_extents(__exts)); + else + return false; + } + + constexpr size_t + __static_extents_prod(const auto& __sta_exts) noexcept + { + size_t __ret = 1; + for (auto __factor : __sta_exts) + if (__factor != dynamic_extent) + __ret *= __factor; + return __ret; + } + + template + constexpr typename _Extents::index_type + __exts_prod(const _Extents& __exts, size_t __begin, size_t __end) noexcept + { + using _IndexType = typename _Extents::index_type; + + size_t __ret = 1; + if constexpr (_Extents::rank_dynamic() != _Extents::rank()) + { + auto __sta_exts = __static_extents<_Extents>(__begin, __end); + __ret = __static_extents_prod(__sta_exts); + if (__ret == 0) + return 0; + } + + if constexpr (_Extents::rank_dynamic() > 0) + for (auto __factor : __dynamic_extents(__exts, __begin, __end)) + __ret *= size_t(__factor); + return _IndexType(__ret); + } + + template + constexpr typename _Extents::index_type + __fwd_prod(const _Extents& __exts, size_t __r) noexcept + { return __exts_prod(__exts, 0, __r); } + + template + constexpr typename _Extents::index_type + __rev_prod(const _Extents& __exts, size_t __r) noexcept + { return __exts_prod(__exts, __r + 1, __exts.rank()); } + + template + constexpr typename _Extents::index_type + __size(const _Extents& __exts) noexcept + { return __fwd_prod(__exts, __exts.rank()); } + template auto __build_dextents_type(integer_sequence) -> extents<_IndexType, ((void) _Counts, dynamic_extent)...>; - - template - consteval size_t - __dynamic_extent() { return dynamic_extent; } } template @@ -302,7 +417,940 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template requires (is_convertible_v<_Integrals, size_t> && ...) explicit extents(_Integrals...) -> - extents()...>; + extents...>; + + struct layout_left + { + template + class mapping; + }; + + struct layout_right + { + template + class mapping; + }; + + struct layout_stride + { + template + class mapping; + }; + + namespace __mdspan + { + template + constexpr bool __is_extents = false; + + template + constexpr bool __is_extents> = true; + + template + constexpr typename _Extents::index_type + __linear_index_left(const _Extents& __exts, _Indices... __indices) + noexcept + { + using _IndexType = typename _Extents::index_type; + _IndexType __res = 0; + if constexpr (sizeof...(__indices) > 0) + { + _IndexType __mult = 1; + auto __update = [&, __pos = 0u](_IndexType __idx) mutable + { + _GLIBCXX_DEBUG_ASSERT(cmp_less(__idx, __exts.extent(__pos))); + __res += __idx * __mult; + __mult *= __exts.extent(__pos); + ++__pos; + }; + (__update(__indices), ...); + } + return __res; + } + + template + consteval _IndexType + __static_quotient(_IndexType __nom = numeric_limits<_IndexType>::max()) + { + auto __sta_exts = __static_extents<_Extents>(); + for (auto __factor : __sta_exts) + { + if (__factor != dynamic_extent) + __nom /= _IndexType(__factor); + if (__nom == 0) + break; + } + return __nom; + } + + template + constexpr bool + __is_representable_extents(const _Extents& __exts) noexcept + { + using _IndexType = _Extents::index_type; + + if constexpr (__contains_zero(__static_extents<_Extents>())) + return true; + else + { + constexpr auto __sta_quo = __static_quotient<_Extents>(); + if constexpr (_Extents::rank_dynamic() == 0) + return __sta_quo != 0; + else + { + auto __dyn_exts = __dynamic_extents(__exts); + if (__contains_zero(__dyn_exts)) + return true; + + if constexpr (__sta_quo == 0) + return false; + else + { + auto __dyn_quo = _IndexType(__sta_quo); + for (auto __factor : __dyn_exts) + { + __dyn_quo /= __factor; + if (__dyn_quo == 0) + return false; + } + return true; + } + } + } + } + + template + concept __representable_size = _Extents::rank_dynamic() != 0 + || __contains_zero(__static_extents<_Extents>()) + || (__static_quotient<_Extents, _IndexType>() != 0); + + template + concept __mapping_of = + is_same_v, + _Mapping>; + + template + concept __standardized_mapping = __mapping_of + || __mapping_of + || __mapping_of; + + // A tag type to create internal ctors. + class __internal_ctor + { }; + } + + template + class layout_left::mapping + { + public: + using extents_type = _Extents; + using index_type = typename extents_type::index_type; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using layout_type = layout_left; + + static_assert(__mdspan::__representable_size, + "The size of extents_type must be representable as index_type"); + + constexpr + mapping() noexcept = default; + + constexpr + mapping(const mapping&) noexcept = default; + + constexpr + mapping(const extents_type& __extents) noexcept + : _M_extents(__extents) + { __glibcxx_assert(__mdspan::__is_representable_extents(_M_extents)); } + + template + requires is_constructible_v + constexpr explicit(!is_convertible_v<_OExtents, extents_type>) + mapping(const mapping<_OExtents>& __other) noexcept + : mapping(__other.extents(), __mdspan::__internal_ctor{}) + { } + + template + requires (extents_type::rank() <= 1) + && is_constructible_v + constexpr explicit(!is_convertible_v<_OExtents, extents_type>) + mapping(const layout_right::mapping<_OExtents>& __other) noexcept + : mapping(__other.extents(), __mdspan::__internal_ctor{}) + { } + + // noexcept for consistency with other layouts. + template + requires is_constructible_v + constexpr explicit(extents_type::rank() > 0) + mapping(const layout_stride::mapping<_OExtents>& __other) noexcept + : mapping(__other.extents(), __mdspan::__internal_ctor{}) + { __glibcxx_assert(*this == __other); } + + constexpr mapping& + operator=(const mapping&) noexcept = default; + + constexpr const extents_type& + extents() const noexcept { return _M_extents; } + + constexpr index_type + required_span_size() const noexcept + { return __mdspan::__size(_M_extents); } + + template<__mdspan::__valid_index_type... _Indices> + requires (sizeof...(_Indices) == extents_type::rank()) + constexpr index_type + operator()(_Indices... __indices) const noexcept + { + return __mdspan::__linear_index_left(_M_extents, + static_cast(std::move(__indices))...); + } + + static constexpr bool + is_always_unique() noexcept { return true; } + + static constexpr bool + is_always_exhaustive() noexcept { return true; } + + static constexpr bool + is_always_strided() noexcept { return true; } + + static constexpr bool + is_unique() noexcept { return true; } + + static constexpr bool + is_exhaustive() noexcept { return true; } + + static constexpr bool + is_strided() noexcept { return true; } + + constexpr index_type + stride(rank_type __i) const noexcept + requires (extents_type::rank() > 0) + { + __glibcxx_assert(__i < extents_type::rank()); + return __mdspan::__fwd_prod(_M_extents, __i); + } + + template + requires (extents_type::rank() == _OExtents::rank()) + friend constexpr bool + operator==(const mapping& __self, const mapping<_OExtents>& __other) + noexcept + { return __self.extents() == __other.extents(); } + + private: + template + constexpr explicit + mapping(const _OExtents& __oexts, __mdspan::__internal_ctor) noexcept + : _M_extents(__oexts) + { + static_assert(__mdspan::__representable_size<_OExtents, index_type>, + "The size of OtherExtents must be representable as index_type"); + __glibcxx_assert(__mdspan::__is_representable_extents(_M_extents)); + } + + [[no_unique_address]] extents_type _M_extents{}; + }; + + namespace __mdspan + { + template + constexpr typename _Extents::index_type + __linear_index_right(const _Extents& __exts, _Indices... __indices) + noexcept + { + using _IndexType = typename _Extents::index_type; + array<_IndexType, sizeof...(__indices)> __ind_arr{__indices...}; + _IndexType __res = 0; + if constexpr (sizeof...(__indices) > 0) + { + _IndexType __mult = 1; + auto __update = [&, __pos = __exts.rank()](_IndexType) mutable + { + --__pos; + _GLIBCXX_DEBUG_ASSERT(cmp_less(__ind_arr[__pos], + __exts.extent(__pos))); + __res += __ind_arr[__pos] * __mult; + __mult *= __exts.extent(__pos); + }; + (__update(__indices), ...); + } + return __res; + } + } + + template + class layout_right::mapping + { + public: + using extents_type = _Extents; + using index_type = typename extents_type::index_type; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using layout_type = layout_right; + + static_assert(__mdspan::__representable_size, + "The size of extents_type must be representable as index_type"); + + constexpr + mapping() noexcept = default; + + constexpr + mapping(const mapping&) noexcept = default; + + constexpr + mapping(const extents_type& __extents) noexcept + : _M_extents(__extents) + { __glibcxx_assert(__mdspan::__is_representable_extents(_M_extents)); } + + template + requires is_constructible_v + constexpr explicit(!is_convertible_v<_OExtents, extents_type>) + mapping(const mapping<_OExtents>& __other) noexcept + : mapping(__other.extents(), __mdspan::__internal_ctor{}) + { } + + template + requires (extents_type::rank() <= 1) + && is_constructible_v + constexpr explicit(!is_convertible_v<_OExtents, extents_type>) + mapping(const layout_left::mapping<_OExtents>& __other) noexcept + : mapping(__other.extents(), __mdspan::__internal_ctor{}) + { } + + template + requires is_constructible_v + constexpr explicit(extents_type::rank() > 0) + mapping(const layout_stride::mapping<_OExtents>& __other) noexcept + : mapping(__other.extents(), __mdspan::__internal_ctor{}) + { __glibcxx_assert(*this == __other); } + + constexpr mapping& + operator=(const mapping&) noexcept = default; + + constexpr const extents_type& + extents() const noexcept { return _M_extents; } + + constexpr index_type + required_span_size() const noexcept + { return __mdspan::__size(_M_extents); } + + template<__mdspan::__valid_index_type... _Indices> + requires (sizeof...(_Indices) == extents_type::rank()) + constexpr index_type + operator()(_Indices... __indices) const noexcept + { + return __mdspan::__linear_index_right( + _M_extents, static_cast(std::move(__indices))...); + } + + static constexpr bool + is_always_unique() noexcept + { return true; } + + static constexpr bool + is_always_exhaustive() noexcept + { return true; } + + static constexpr bool + is_always_strided() noexcept + { return true; } + + static constexpr bool + is_unique() noexcept + { return true; } + + static constexpr bool + is_exhaustive() noexcept + { return true; } + + static constexpr bool + is_strided() noexcept + { return true; } + + constexpr index_type + stride(rank_type __i) const noexcept + requires (extents_type::rank() > 0) + { + __glibcxx_assert(__i < extents_type::rank()); + return __mdspan::__rev_prod(_M_extents, __i); + } + + template + requires (extents_type::rank() == _OExtents::rank()) + friend constexpr bool + operator==(const mapping& __self, const mapping<_OExtents>& __other) + noexcept + { return __self.extents() == __other.extents(); } + + private: + template + constexpr explicit + mapping(const _OExtents& __oexts, __mdspan::__internal_ctor) noexcept + : _M_extents(__oexts) + { + static_assert(__mdspan::__representable_size<_OExtents, index_type>, + "The size of OtherExtents must be representable as index_type"); + __glibcxx_assert(__mdspan::__is_representable_extents(_M_extents)); + } + + [[no_unique_address]] extents_type _M_extents{}; + }; + + namespace __mdspan + { + template + concept __mapping_alike = requires + { + requires __is_extents; + { _Mp::is_always_strided() } -> same_as; + { _Mp::is_always_exhaustive() } -> same_as; + { _Mp::is_always_unique() } -> same_as; + bool_constant<_Mp::is_always_strided()>::value; + bool_constant<_Mp::is_always_exhaustive()>::value; + bool_constant<_Mp::is_always_unique()>::value; + }; + + template + constexpr typename _Mapping::index_type + __offset(const _Mapping& __m) noexcept + { + using _IndexType = typename _Mapping::index_type; + constexpr auto __rank = _Mapping::extents_type::rank(); + + if constexpr (__standardized_mapping<_Mapping>) + return 0; + else if (__empty(__m.extents())) + return 0; + else + { + auto __impl = [&__m](index_sequence<_Counts...>) + { return __m(((void) _Counts, _IndexType(0))...); }; + return __impl(make_index_sequence<__rank>()); + } + } + + template + constexpr typename _Mapping::index_type + __linear_index_strides(const _Mapping& __m, _Indices... __indices) + noexcept + { + using _IndexType = typename _Mapping::index_type; + _IndexType __res = 0; + if constexpr (sizeof...(__indices) > 0) + { + auto __update = [&, __pos = 0u](_IndexType __idx) mutable + { + _GLIBCXX_DEBUG_ASSERT(cmp_less(__idx, + __m.extents().extent(__pos))); + __res += __idx * __m.stride(__pos++); + }; + (__update(__indices), ...); + } + return __res; + } + } + + template + class layout_stride::mapping + { + public: + using extents_type = _Extents; + using index_type = typename extents_type::index_type; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using layout_type = layout_stride; + + static_assert(__mdspan::__representable_size, + "The size of extents_type must be representable as index_type"); + + constexpr + mapping() noexcept + { + // The precondition is either statically asserted, or automatically + // satisfied because dynamic extents are zero-initialized. + size_t __stride = 1; + for (size_t __i = extents_type::rank(); __i > 0; --__i) + { + _M_strides[__i - 1] = index_type(__stride); + __stride *= size_t(_M_extents.extent(__i - 1)); + } + } + + constexpr + mapping(const mapping&) noexcept = default; + + template + requires __mdspan::__valid_index_type + constexpr + mapping(const extents_type& __exts, + span<_OIndexType, extents_type::rank()> __strides) noexcept + : _M_extents(__exts) + { + for (size_t __i = 0; __i < extents_type::rank(); ++__i) + _M_strides[__i] = index_type(as_const(__strides[__i])); + } + + template + requires __mdspan::__valid_index_type + constexpr + mapping(const extents_type& __exts, + const array<_OIndexType, extents_type::rank()>& __strides) + noexcept + : mapping(__exts, + span(__strides)) + { } + + template<__mdspan::__mapping_alike _StridedMapping> + requires (is_constructible_v + && _StridedMapping::is_always_unique() + && _StridedMapping::is_always_strided()) + constexpr explicit(!( + is_convertible_v + && __mdspan::__standardized_mapping<_StridedMapping>)) + mapping(const _StridedMapping& __other) noexcept + : _M_extents(__other.extents()) + { + using _OIndexType = _StridedMapping::index_type; + using _OExtents = _StridedMapping::extents_type; + + __glibcxx_assert(__mdspan::__offset(__other) == 0); + static_assert(__mdspan::__representable_size<_OExtents, index_type>, + "The size of StridedMapping::extents_type must be representable as" + " index_type"); + if constexpr (cmp_greater(numeric_limits<_OIndexType>::max(), + numeric_limits::max())) + __glibcxx_assert(!cmp_less(numeric_limits::max(), + __other.required_span_size()) + && "other.required_span_size() must be representable" + " as index_type"); + if constexpr (extents_type::rank() > 0) + for (size_t __i = 0; __i < extents_type::rank(); ++__i) + _M_strides[__i] = index_type(__other.stride(__i)); + } + + constexpr mapping& + operator=(const mapping&) noexcept = default; + + constexpr const extents_type& + extents() const noexcept { return _M_extents; } + + constexpr array + strides() const noexcept + { + array __ret; + for (size_t __i = 0; __i < extents_type::rank(); ++__i) + __ret[__i] = _M_strides[__i]; + return __ret; + } + + constexpr index_type + required_span_size() const noexcept + { + if (__mdspan::__empty(_M_extents)) + return 0; + + index_type __ret = 1; + for (size_t __i = 0; __i < extents_type::rank(); ++__i) + __ret += (_M_extents.extent(__i) - 1) * _M_strides[__i]; + return __ret; + } + + template<__mdspan::__valid_index_type... _Indices> + requires (sizeof...(_Indices) == extents_type::rank()) + constexpr index_type + operator()(_Indices... __indices) const noexcept + { + return __mdspan::__linear_index_strides(*this, + static_cast(std::move(__indices))...); + } + + static constexpr bool + is_always_unique() noexcept { return true; } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 4266. layout_stride::mapping should treat empty mappings as exhaustive + static constexpr bool + is_always_exhaustive() noexcept + { + return (_Extents::rank() == 0) || __mdspan::__contains_zero( + __mdspan::__static_extents()); + } + + static constexpr bool + is_always_strided() noexcept { return true; } + + static constexpr bool + is_unique() noexcept { return true; } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 4266. layout_stride::mapping should treat empty mappings as exhaustive + constexpr bool + is_exhaustive() const noexcept + { + if constexpr (!is_always_exhaustive()) + { + auto __size = __mdspan::__size(_M_extents); + if(__size > 0) + return __size == required_span_size(); + } + return true; + } + + static constexpr bool + is_strided() noexcept { return true; } + + constexpr index_type + stride(rank_type __r) const noexcept { return _M_strides[__r]; } + + template<__mdspan::__mapping_alike _OMapping> + requires ((extents_type::rank() == _OMapping::extents_type::rank()) + && _OMapping::is_always_strided()) + friend constexpr bool + operator==(const mapping& __self, const _OMapping& __other) noexcept + { + if (__self.extents() != __other.extents()) + return false; + if constexpr (extents_type::rank() > 0) + for (size_t __i = 0; __i < extents_type::rank(); ++__i) + if (!cmp_equal(__self.stride(__i), __other.stride(__i))) + return false; + return __mdspan::__offset(__other) == 0; + } + + private: + using _S_strides_t = typename __array_traits::_Type; + [[no_unique_address]] extents_type _M_extents; + [[no_unique_address]] _S_strides_t _M_strides; + }; + + template + struct default_accessor + { + static_assert(!is_array_v<_ElementType>, + "ElementType must not be an array type"); + static_assert(!is_abstract_v<_ElementType>, + "ElementType must not be an abstract class type"); + + using offset_policy = default_accessor; + using element_type = _ElementType; + using reference = element_type&; + using data_handle_type = element_type*; + + constexpr + default_accessor() noexcept = default; + + template + requires is_convertible_v<_OElementType(*)[], element_type(*)[]> + constexpr + default_accessor(default_accessor<_OElementType>) noexcept + { } + + constexpr reference + access(data_handle_type __p, size_t __i) const noexcept + { return __p[__i]; } + + constexpr data_handle_type + offset(data_handle_type __p, size_t __i) const noexcept + { return __p + __i; } + }; + + namespace __mdspan + { + template + constexpr bool + __is_multi_index(const _Extents& __exts, span<_IndexType, _Nm> __indices) + { + static_assert(__exts.rank() == _Nm); + for (size_t __i = 0; __i < __exts.rank(); ++__i) + if (__indices[__i] >= __exts.extent(__i)) + return false; + return true; + } + } + + template> + class mdspan + { + static_assert(!is_array_v<_ElementType>, + "ElementType must not be an array type"); + static_assert(!is_abstract_v<_ElementType>, + "ElementType must not be an abstract class type"); + static_assert(__mdspan::__is_extents<_Extents>, + "Extents must be a specialization of std::extents"); + static_assert(is_same_v<_ElementType, + typename _AccessorPolicy::element_type>); + + public: + using extents_type = _Extents; + using layout_type = _LayoutPolicy; + using accessor_type = _AccessorPolicy; + using mapping_type = typename layout_type::template mapping; + using element_type = _ElementType; + using value_type = remove_cv_t; + using index_type = typename extents_type::index_type; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using data_handle_type = typename accessor_type::data_handle_type; + using reference = typename accessor_type::reference; + + static constexpr rank_type + rank() noexcept { return extents_type::rank(); } + + static constexpr rank_type + rank_dynamic() noexcept { return extents_type::rank_dynamic(); } + + static constexpr size_t + static_extent(rank_type __r) noexcept + { return extents_type::static_extent(__r); } + + constexpr index_type + extent(rank_type __r) const noexcept { return extents().extent(__r); } + + constexpr + mdspan() + requires (rank_dynamic() > 0) + && is_default_constructible_v + && is_default_constructible_v + && is_default_constructible_v = default; + + constexpr + mdspan(const mdspan& __other) = default; + + constexpr + mdspan(mdspan&& __other) = default; + + template<__mdspan::__valid_index_type... _OIndexTypes> + requires (sizeof...(_OIndexTypes) == rank() + || sizeof...(_OIndexTypes) == rank_dynamic()) + && is_constructible_v + && is_default_constructible_v + constexpr explicit + mdspan(data_handle_type __handle, _OIndexTypes... __exts) + : _M_accessor(), + _M_mapping(_Extents(static_cast(std::move(__exts))...)), + _M_handle(std::move(__handle)) + { } + + template + requires __mdspan::__valid_index_type + && (_Nm == rank() || _Nm == rank_dynamic()) + && is_constructible_v + && is_default_constructible_v + constexpr explicit(_Nm != rank_dynamic()) + mdspan(data_handle_type __handle, span<_OIndexType, _Nm> __exts) + : _M_accessor(), _M_mapping(extents_type(__exts)), + _M_handle(std::move(__handle)) + { } + + template + requires __mdspan::__valid_index_type + && (_Nm == rank() || _Nm == rank_dynamic()) + && is_constructible_v + && is_default_constructible_v + constexpr explicit(_Nm != rank_dynamic()) + mdspan(data_handle_type __handle, const array<_OIndexType, _Nm>& __exts) + : _M_accessor(), _M_mapping(extents_type(__exts)), + _M_handle(std::move(__handle)) + { } + + constexpr + mdspan(data_handle_type __handle, const extents_type& __exts) + requires is_constructible_v + && is_default_constructible_v + : _M_accessor(), _M_mapping(__exts), _M_handle(std::move(__handle)) + { } + + constexpr + mdspan(data_handle_type __handle, const mapping_type& __mapping) + requires is_default_constructible_v + : _M_accessor(), _M_mapping(__mapping), _M_handle(std::move(__handle)) + { } + + constexpr + mdspan(data_handle_type __handle, const mapping_type& __mapping, + const accessor_type& __accessor) + : _M_accessor(__accessor), _M_mapping(__mapping), + _M_handle(std::move(__handle)) + { } + + template + requires is_constructible_v&> + && is_constructible_v + constexpr explicit(!is_convertible_v< + const typename _OLayout::template mapping<_OExtents>&, mapping_type> + || !is_convertible_v) + mdspan(const mdspan<_OElementType, _OExtents, _OLayout, _OAccessor>& + __other) + : _M_accessor(__other.accessor()), _M_mapping(__other.mapping()), + _M_handle(__other.data_handle()) + { + static_assert(is_constructible_v); + static_assert(is_constructible_v); + } + + constexpr mdspan& + operator=(const mdspan& __other) = default; + + constexpr mdspan& + operator=(mdspan&& __other) = default; + + template<__mdspan::__valid_index_type... _OIndexTypes> + requires (sizeof...(_OIndexTypes) == rank()) + constexpr reference + operator[](_OIndexTypes... __indices) const + { + auto __checked_call = [this](auto... __idxs) -> index_type + { + if constexpr (sizeof...(__idxs) > 0) + __glibcxx_assert(__mdspan::__is_multi_index(extents(), + span({__idxs...}))); + return _M_mapping(__idxs...); + }; + + auto __index = __checked_call( + static_cast(std::move(__indices))...); + return _M_accessor.access(_M_handle, __index); + } + + template + requires __mdspan::__valid_index_type + constexpr reference + operator[](span<_OIndexType, rank()> __indices) const + { + auto __call = [&](index_sequence<_Counts...>) + -> reference + { return (*this)[index_type(as_const(__indices[_Counts]))...]; }; + return __call(make_index_sequence()); + } + + template + requires __mdspan::__valid_index_type + constexpr reference + operator[](const array<_OIndexType, rank()>& __indices) const + { return (*this)[span(__indices)]; } + + constexpr size_type + size() const noexcept + { + __glibcxx_assert(cmp_less_equal(_M_mapping.required_span_size(), + numeric_limits::max())); + return size_type(__mdspan::__size(extents())); + } + + [[nodiscard]] + constexpr bool + empty() const noexcept + { + return __mdspan::__empty(extents()); + } + + friend constexpr void + swap(mdspan& __x, mdspan& __y) noexcept + { + using std::swap; + swap(__x._M_mapping, __y._M_mapping); + swap(__x._M_accessor, __y._M_accessor); + swap(__x._M_handle, __y._M_handle); + } + + constexpr const extents_type& + extents() const noexcept { return _M_mapping.extents(); } + + constexpr const data_handle_type& + data_handle() const noexcept { return _M_handle; } + + constexpr const mapping_type& + mapping() const noexcept { return _M_mapping; } + + constexpr const accessor_type& + accessor() const noexcept { return _M_accessor; } + + // Strengthened noexcept for all `is_*` methods. + + static constexpr bool + is_always_unique() noexcept(noexcept(mapping_type::is_always_unique())) + { return mapping_type::is_always_unique(); } + + static constexpr bool + is_always_exhaustive() + noexcept(noexcept(mapping_type::is_always_exhaustive())) + { return mapping_type::is_always_exhaustive(); } + + static constexpr bool + is_always_strided() + noexcept(noexcept(mapping_type::is_always_strided())) + { return mapping_type::is_always_strided(); } + + constexpr bool + is_unique() const noexcept(noexcept(_M_mapping.is_unique())) + { return _M_mapping.is_unique(); } + + constexpr bool + is_exhaustive() const noexcept(noexcept(_M_mapping.is_exhaustive())) + { return _M_mapping.is_exhaustive(); } + + constexpr bool + is_strided() const noexcept(noexcept(_M_mapping.is_strided())) + { return _M_mapping. is_strided(); } + + constexpr index_type + stride(rank_type __r) const { return _M_mapping.stride(__r); } + + private: + [[no_unique_address]] accessor_type _M_accessor = accessor_type(); + [[no_unique_address]] mapping_type _M_mapping = mapping_type(); + [[no_unique_address]] data_handle_type _M_handle = data_handle_type(); + }; + + template + requires is_array_v<_CArray> && (rank_v<_CArray> == 1) + mdspan(_CArray&) + -> mdspan, + extents>>; + + template + requires is_pointer_v> + mdspan(_Pointer&&) + -> mdspan>, extents>; + + template + requires (is_convertible_v<_Integrals, size_t> && ...) + && (sizeof...(_Integrals) > 0) + explicit mdspan(_ElementType*, _Integrals...) + -> mdspan<_ElementType, + extents...>>; + + template + mdspan(_ElementType*, span<_OIndexType, _Nm>) + -> mdspan<_ElementType, dextents>; + + template + mdspan(_ElementType*, const array<_OIndexType, _Nm>&) + -> mdspan<_ElementType, dextents>; + + template + mdspan(_ElementType*, const extents<_IndexType, _ExtentsPack...>&) + -> mdspan<_ElementType, extents<_IndexType, _ExtentsPack...>>; + + template + mdspan(_ElementType*, const _MappingType&) + -> mdspan<_ElementType, typename _MappingType::extents_type, + typename _MappingType::layout_type>; + + template + mdspan(const typename _AccessorType::data_handle_type&, const _MappingType&, + const _AccessorType&) + -> mdspan; _GLIBCXX_END_NAMESPACE_VERSION } diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory index 1da03b3ea6a9..763a57ee998d 100644 --- a/libstdc++-v3/include/std/memory +++ b/libstdc++-v3/include/std/memory @@ -121,6 +121,7 @@ #define __glibcxx_want_smart_ptr_for_overwrite #define __glibcxx_want_to_address #define __glibcxx_want_transparent_operators +#define __glibcxx_want_smart_ptr_owner_equality #include #if __cplusplus >= 201103L && __cplusplus <= 202002L && _GLIBCXX_HOSTED diff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional index a616dc07b107..e5051d72c828 100644 --- a/libstdc++-v3/include/std/optional +++ b/libstdc++-v3/include/std/optional @@ -36,6 +36,7 @@ #define __glibcxx_want_freestanding_optional #define __glibcxx_want_optional +#define __glibcxx_want_optional_range_support #define __glibcxx_want_constrained_equality #include @@ -57,6 +58,11 @@ #if __cplusplus > 202002L # include #endif +#ifdef __cpp_lib_optional_range_support // C++ >= 26 +# include +# include +# include +#endif namespace std _GLIBCXX_VISIBILITY(default) { @@ -858,6 +864,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public: using value_type = _Tp; +#ifdef __cpp_lib_optional_range_support // >= C++26 + using iterator = __gnu_cxx::__normal_iterator<_Tp*, optional>; + using const_iterator = __gnu_cxx::__normal_iterator; +#endif constexpr optional() noexcept { } @@ -1158,6 +1168,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +#ifdef __cpp_lib_optional_range_support // >= C++26 + // Iterator support. + constexpr iterator begin() noexcept + { + return iterator( + this->_M_is_engaged() ? std::addressof(this->_M_get()) : nullptr + ); + } + + constexpr const_iterator begin() const noexcept + { + return const_iterator( + this->_M_is_engaged() ? std::addressof(this->_M_get()) : nullptr + ); + } + + constexpr iterator end() noexcept + { + return begin() + has_value(); + } + + constexpr const_iterator end() const noexcept + { + return begin() + has_value(); + } +#endif // __cpp_lib_optional_range_support + // Observers. constexpr const _Tp* operator->() const noexcept @@ -1703,6 +1740,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2766. Swapping non-swappable types template enable_if_t && is_swappable_v<_Tp>)> swap(optional<_Tp>&, optional<_Tp>&) = delete; @@ -1772,6 +1811,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template optional(_Tp) -> optional<_Tp>; #endif +#ifdef __cpp_lib_optional_range_support // >= C++26 + template + inline constexpr bool + ranges::enable_view> = true; + + template + inline constexpr range_format + format_kind> = range_format::disabled; +#endif // __cpp_lib_optional_range_support + #undef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/queue b/libstdc++-v3/include/std/queue index 90525897da75..1b76088b31b3 100644 --- a/libstdc++-v3/include/std/queue +++ b/libstdc++-v3/include/std/queue @@ -105,7 +105,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _M_f.format(__a.c, __fc); } private: - // Standard uses formatter, _CharT>. + // Standard uses formatter, _CharT>, but range_formatter + // provides same behavior. + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3881. Incorrect formatting of container adapters backed by std::string range_formatter<_Tp, _CharT> _M_f; }; @@ -136,7 +139,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _M_f.format(__a.c, __fc); } private: - // Standard uses formatter, _CharT>. + // Standard uses formatter, _CharT>, but range_formatter + // provides same behavior. + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3881. Incorrect formatting of container adapters backed by std::string range_formatter<_Tp, _CharT> _M_f; }; diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 210ac8274fc1..efe62969d657 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -660,7 +660,7 @@ namespace ranges : _M_value(__value) { } - constexpr + constexpr explicit iota_view(type_identity_t<_Winc> __value, type_identity_t<_Bound> __bound) : _M_value(__value), _M_bound(__bound) @@ -669,19 +669,19 @@ namespace ranges __glibcxx_assert( bool(__value <= __bound) ); } - constexpr + constexpr explicit iota_view(_Iterator __first, _Iterator __last) requires same_as<_Winc, _Bound> : iota_view(__first._M_value, __last._M_value) { } - constexpr + constexpr explicit iota_view(_Iterator __first, unreachable_sentinel_t __last) requires same_as<_Bound, unreachable_sentinel_t> : iota_view(__first._M_value, __last) { } - constexpr + constexpr explicit iota_view(_Iterator __first, _Sentinel __last) requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>) : iota_view(__first._M_value, __last._M_bound) @@ -1811,7 +1811,7 @@ namespace views::__adaptor && default_initializable<_Pred>) = default; - constexpr + constexpr explicit filter_view(_Vp __base, _Pred __pred) : _M_base(std::move(__base)), _M_pred(std::move(__pred)) { } @@ -2188,7 +2188,7 @@ namespace views::__adaptor && default_initializable<_Fp>) = default; - constexpr + constexpr explicit transform_view(_Vp __base, _Fp __fun) : _M_base(std::move(__base)), _M_fun(std::move(__fun)) { } @@ -2323,7 +2323,7 @@ namespace views::__adaptor public: take_view() requires default_initializable<_Vp> = default; - constexpr + constexpr explicit take_view(_Vp __base, range_difference_t<_Vp> __count) : _M_base(std::move(__base)), _M_count(std::move(__count)) { } @@ -2562,7 +2562,7 @@ namespace views::__adaptor && default_initializable<_Pred>) = default; - constexpr + constexpr explicit take_while_view(_Vp __base, _Pred __pred) : _M_base(std::move(__base)), _M_pred(std::move(__pred)) { } @@ -2650,7 +2650,7 @@ namespace views::__adaptor public: drop_view() requires default_initializable<_Vp> = default; - constexpr + constexpr explicit drop_view(_Vp __base, range_difference_t<_Vp> __count) : _M_base(std::move(__base)), _M_count(__count) { __glibcxx_assert(__count >= 0); } @@ -2804,7 +2804,7 @@ namespace views::__adaptor && default_initializable<_Pred>) = default; - constexpr + constexpr explicit drop_while_view(_Vp __base, _Pred __pred) : _M_base(std::move(__base)), _M_pred(std::move(__pred)) { } @@ -3022,7 +3022,8 @@ namespace views::__adaptor { _M_satisfy(); } [[no_unique_address]] - __detail::__maybe_present_t, _Outer_iter> _M_outer; + __detail::__maybe_present_t, _Outer_iter> _M_outer + = decltype(_M_outer)(); optional<_Inner_iter> _M_inner; _Parent* _M_parent = nullptr; @@ -3376,7 +3377,8 @@ namespace views::__adaptor [[no_unique_address]] __detail::__maybe_present_t, - iterator_t<_Base>> _M_current; + iterator_t<_Base>> _M_current + = decltype(_M_current)(); bool _M_trailing_empty = false; public: @@ -3641,7 +3643,7 @@ namespace views::__adaptor && default_initializable<_Pattern>) = default; - constexpr + constexpr explicit lazy_split_view(_Vp __base, _Pattern __pattern) : _M_base(std::move(__base)), _M_pattern(std::move(__pattern)) { } @@ -3649,7 +3651,7 @@ namespace views::__adaptor template requires constructible_from<_Vp, views::all_t<_Range>> && constructible_from<_Pattern, single_view>> - constexpr + constexpr explicit lazy_split_view(_Range&& __r, range_value_t<_Range> __e) : _M_base(views::all(std::forward<_Range>(__r))), _M_pattern(views::single(std::move(__e))) @@ -3766,7 +3768,7 @@ namespace views::__adaptor && default_initializable<_Pattern>) = default; - constexpr + constexpr explicit split_view(_Vp __base, _Pattern __pattern) : _M_base(std::move(__base)), _M_pattern(std::move(__pattern)) { } @@ -3774,7 +3776,7 @@ namespace views::__adaptor template requires constructible_from<_Vp, views::all_t<_Range>> && constructible_from<_Pattern, single_view>> - constexpr + constexpr explicit split_view(_Range&& __r, range_value_t<_Range> __e) : _M_base(views::all(std::forward<_Range>(__r))), _M_pattern(views::single(std::move(__e))) @@ -7295,7 +7297,7 @@ namespace views::__adaptor && default_initializable<_Pattern>) = default; - constexpr + constexpr explicit join_with_view(_Vp __base, _Pattern __pattern) : _M_base(std::move(__base)), _M_pattern(std::move(__pattern)) { } @@ -7303,7 +7305,7 @@ namespace views::__adaptor template requires constructible_from<_Vp, views::all_t<_Range>> && constructible_from<_Pattern, single_view>> - constexpr + constexpr explicit join_with_view(_Range&& __r, range_value_t<_InnerRange> __e) : _M_base(views::all(std::forward<_Range>(__r))), _M_pattern(views::single(std::move(__e))) @@ -7400,7 +7402,8 @@ namespace views::__adaptor _Parent* _M_parent = nullptr; [[no_unique_address]] - __detail::__maybe_present_t, _OuterIter> _M_outer_it; + __detail::__maybe_present_t, _OuterIter> _M_outer_it + = decltype(_M_outer_it)(); variant<_PatternIter, _InnerIter> _M_inner_it; constexpr _OuterIter& @@ -9735,7 +9738,7 @@ namespace ranges end() requires (!(__detail::__simple_view<_Vs> && ...)) { constexpr auto __n = sizeof...(_Vs); - if constexpr ((semiregular> && ...) + if constexpr (__detail::__all_forward && common_range<_Vs...[__n - 1]>) return _Iterator(this, in_place_index<__n - 1>, ranges::end(std::get<__n - 1>(_M_views))); @@ -9747,7 +9750,7 @@ namespace ranges end() const requires (range && ...) && __detail::__concatable { constexpr auto __n = sizeof...(_Vs); - if constexpr ((semiregular> && ...) + if constexpr (__detail::__all_forward && common_range) return _Iterator(this, in_place_index<__n - 1>, ranges::end(std::get<__n - 1>(_M_views))); diff --git a/libstdc++-v3/include/std/semaphore b/libstdc++-v3/include/std/semaphore index ca1bffe371a0..18d04075776c 100644 --- a/libstdc++-v3/include/std/semaphore +++ b/libstdc++-v3/include/std/semaphore @@ -45,13 +45,12 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION - template::_S_max> + template::_S_max> class counting_semaphore { static_assert(__least_max_value >= 0); - using _Impl = __semaphore_impl<__least_max_value>; - _Impl _M_sem; + _Semaphore_impl<__least_max_value> _M_sem; public: constexpr explicit diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span index 49ab9109d83e..44f9b36a7efe 100644 --- a/libstdc++-v3/include/std/span +++ b/libstdc++-v3/include/std/span @@ -376,7 +376,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION else static_assert(_Count <= extent); using _Sp = span; - return _Sp{ _SizedPtr{this->data()} }; + return _Sp(_SizedPtr{this->data()}); } [[nodiscard]] @@ -384,7 +384,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION first(size_type __count) const noexcept { __glibcxx_assert(__count <= size()); - return { this->data(), __count }; + return span(this->data(), __count); } template @@ -397,7 +397,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION else static_assert(_Count <= extent); using _Sp = span; - return _Sp{ _SizedPtr{this->data() + (this->size() - _Count)} }; + return _Sp(_SizedPtr{this->data() + (this->size() - _Count)}); } [[nodiscard]] @@ -405,7 +405,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION last(size_type __count) const noexcept { __glibcxx_assert(__count <= size()); - return { this->data() + (this->size() - __count), __count }; + return span(this->data() + (this->size() - __count), + __count); } template @@ -424,7 +425,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using _Sp = span()>; if constexpr (_Count == dynamic_extent) - return _Sp{ this->data() + _Offset, this->size() - _Offset }; + return _Sp(this->data() + _Offset, this->size() - _Offset); else { if constexpr (_Extent == dynamic_extent) @@ -437,7 +438,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static_assert(_Count <= extent); static_assert(_Count <= (extent - _Offset)); } - return _Sp{ _SizedPtr{this->data() + _Offset} }; + return _Sp(_SizedPtr{this->data() + _Offset}); } } @@ -454,7 +455,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_assert(__count <= size()); __glibcxx_assert(__offset + __count <= size()); } - return {this->data() + __offset, __count}; + return span(this->data() + __offset, __count); } private: @@ -476,6 +477,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; // deduction guides + namespace __detail + { + template + concept __integral_constant_like = is_integral_v + && !is_same_v> + && convertible_to<_Tp, decltype(_Tp::value)> + && equality_comparable_with<_Tp, decltype(_Tp::value)> + && bool_constant<_Tp() == _Tp::value>::value + && bool_constant(_Tp()) == _Tp::value> + ::value; + + template + constexpr size_t __maybe_static_ext = dynamic_extent; + + template<__integral_constant_like _Tp> + constexpr size_t __maybe_static_ext<_Tp> = {_Tp::value}; + } template span(_Type(&)[_ArrayExtent]) -> span<_Type, _ArrayExtent>; @@ -489,7 +507,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template span(_Iter, _End) - -> span>>; + -> span>, + __detail::__maybe_static_ext<_End>>; template span(_Range &&) diff --git a/libstdc++-v3/include/std/sstream b/libstdc++-v3/include/std/sstream index ad0c16a91e86..b1b41260ce3d 100644 --- a/libstdc++-v3/include/std/sstream +++ b/libstdc++-v3/include/std/sstream @@ -41,8 +41,16 @@ #include #include + #include // allocator_traits, __allocator_like +#define __glibcxx_want_sstream_from_string_view +#include + +#ifdef __cpp_lib_sstream_from_string_view +# include +#endif + #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI # define _GLIBCXX_LVAL_REF_QUAL & # define _GLIBCXX_SSTREAM_ALWAYS_INLINE @@ -52,8 +60,6 @@ # define _GLIBCXX_SSTREAM_ALWAYS_INLINE [[__gnu__::__always_inline__]] #endif - - namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -159,6 +165,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { __rhs._M_sync(const_cast(__rhs._M_string.data()), 0, 0); } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI + // P0408 Efficient access to basic_stringbuf buffer explicit basic_stringbuf(const allocator_type& __a) : basic_stringbuf(ios_base::in | std::ios_base::out, __a) @@ -197,7 +204,36 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 | ios_base::out) : basic_stringbuf(__s, __mode, allocator_type{}) { } +#endif +#ifdef __cpp_lib_sstream_from_string_view + template + explicit + basic_stringbuf(const _Tp& __t, + ios_base::openmode __mode = ios_base::in | ios_base::out) + requires (is_convertible_v>) + : basic_stringbuf(__t, __mode, allocator_type{}) + { } + + template + basic_stringbuf(const _Tp& __t, const allocator_type& __a) + requires (is_convertible_v>) + : basic_stringbuf(__t, ios_base::in | ios_base::out, __a) + { } + + template + basic_stringbuf(const _Tp& __t, ios_base::openmode __mode, + const allocator_type& __a) + requires (is_convertible_v>) + : _M_string(__t, __a) + { _M_stringbuf_init(__mode); } +#endif // C++26 + +#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI + // P0408 Efficient access to basic_stringbuf buffer basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a) : basic_stringbuf(std::move(__rhs), __a, __xfer_bufptrs(__rhs, this)) { __rhs._M_sync(const_cast(__rhs._M_string.data()), 0, 0); } @@ -262,6 +298,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 #if __cplusplus > 201703L #if _GLIBCXX_USE_CXX11_ABI #if __cpp_concepts + // P0407 Allocator-aware basic_streambuf template<__allocator_like _SAlloc> _GLIBCXX_NODISCARD basic_string<_CharT, _Traits, _SAlloc> @@ -317,6 +354,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI #if __cpp_concepts + // P0407 Allocator-aware basic_streambuf template<__allocator_like _SAlloc> requires (!is_same_v<_SAlloc, _Alloc>) void @@ -335,6 +373,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 } #endif +#ifdef __cpp_lib_sstream_from_string_view + template + void + str(const _Tp& __t) + requires (is_convertible_v>) + { + basic_string_view<_CharT, _Traits> __sv{__t}; + _M_string = __sv; + _M_stringbuf_init(_M_mode); + } +#endif // C++26 + protected: // Common initialization code goes here. void @@ -521,6 +572,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI + // P0408 Efficient access to basic_stringbuf buffer + // The move constructor initializes an __xfer_bufptrs temporary then // delegates to this constructor to performs moves during its lifetime. basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a, @@ -584,7 +637,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 */ basic_istringstream() : __istream_type(), _M_stringbuf(ios_base::in) - { this->init(&_M_stringbuf); } + { this->init(std::__addressof(_M_stringbuf)); } /** * @brief Starts with an empty string buffer. @@ -601,7 +654,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 explicit basic_istringstream(ios_base::openmode __mode) : __istream_type(), _M_stringbuf(__mode | ios_base::in) - { this->init(&_M_stringbuf); } + { this->init(std::__addressof(_M_stringbuf)); } /** * @brief Starts with an existing string buffer. @@ -620,7 +673,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 basic_istringstream(const __string_type& __str, ios_base::openmode __mode = ios_base::in) : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) - { this->init(&_M_stringbuf); } + { this->init(std::__addressof(_M_stringbuf)); } /** * @brief The destructor does nothing. @@ -637,9 +690,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 basic_istringstream(basic_istringstream&& __rhs) : __istream_type(std::move(__rhs)), _M_stringbuf(std::move(__rhs._M_stringbuf)) - { __istream_type::set_rdbuf(&_M_stringbuf); } + { __istream_type::set_rdbuf(std::__addressof(_M_stringbuf)); } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI + // P0408 Efficient access to basic_stringbuf buffer basic_istringstream(ios_base::openmode __mode, const allocator_type& __a) : __istream_type(), _M_stringbuf(__mode | ios_base::in, __a) { this->init(std::__addressof(_M_stringbuf)); } @@ -671,6 +725,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { } #endif // C++20 +#ifdef __cpp_lib_sstream_from_string_view + template + explicit + basic_istringstream(const _Tp& __t, + ios_base::openmode __mode = ios_base::in) + requires (is_convertible_v>) + : basic_istringstream(__t, __mode, allocator_type{}) + { } + + template + basic_istringstream(const _Tp& __t, const allocator_type& __a) + requires (is_convertible_v>) + : basic_istringstream(__t, ios_base::in, __a) + { } + + template + basic_istringstream(const _Tp& __t, ios_base::openmode __mode, + const allocator_type& __a) + requires (is_convertible_v>) + : __istream_type(), _M_stringbuf(__t, __mode | ios_base::in, __a) + { this->init(std::__addressof(_M_stringbuf)); } +#endif // C++26 + // 27.8.3.2 Assign and swap: basic_istringstream& @@ -702,7 +782,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _GLIBCXX_NODISCARD __stringbuf_type* rdbuf() const - { return const_cast<__stringbuf_type*>(&_M_stringbuf); } + { return const_cast<__stringbuf_type*>(std::__addressof(_M_stringbuf)); } /** * @brief Copying out the string buffer. @@ -716,6 +796,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 #if __cplusplus > 201703L #if _GLIBCXX_USE_CXX11_ABI #if __cpp_concepts + // P0407 Allocator-aware basic_streambuf template<__allocator_like _SAlloc> _GLIBCXX_NODISCARD basic_string<_CharT, _Traits, _SAlloc> @@ -747,6 +828,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI #if __cpp_concepts + // P0407 Allocator-aware basic_streambuf template<__allocator_like _SAlloc> requires (!is_same_v<_SAlloc, _Alloc>) void @@ -758,6 +840,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 str(__string_type&& __s) { _M_stringbuf.str(std::move(__s)); } #endif + +#ifdef __cpp_lib_sstream_from_string_view + template + void + str(const _Tp& __t) + requires (is_convertible_v>) + { _M_stringbuf.str(__t); } +#endif // C++26 }; @@ -812,7 +903,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 */ basic_ostringstream() : __ostream_type(), _M_stringbuf(ios_base::out) - { this->init(&_M_stringbuf); } + { this->init(std::__addressof(_M_stringbuf)); } /** * @brief Starts with an empty string buffer. @@ -829,7 +920,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 explicit basic_ostringstream(ios_base::openmode __mode) : __ostream_type(), _M_stringbuf(__mode | ios_base::out) - { this->init(&_M_stringbuf); } + { this->init(std::__addressof(_M_stringbuf)); } /** * @brief Starts with an existing string buffer. @@ -848,7 +939,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 basic_ostringstream(const __string_type& __str, ios_base::openmode __mode = ios_base::out) : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) - { this->init(&_M_stringbuf); } + { this->init(std::__addressof(_M_stringbuf)); } /** * @brief The destructor does nothing. @@ -865,9 +956,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 basic_ostringstream(basic_ostringstream&& __rhs) : __ostream_type(std::move(__rhs)), _M_stringbuf(std::move(__rhs._M_stringbuf)) - { __ostream_type::set_rdbuf(&_M_stringbuf); } + { __ostream_type::set_rdbuf(std::__addressof(_M_stringbuf)); } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI + // P0408 Efficient access to basic_stringbuf buffer basic_ostringstream(ios_base::openmode __mode, const allocator_type& __a) : __ostream_type(), _M_stringbuf(__mode | ios_base::out, __a) { this->init(std::__addressof(_M_stringbuf)); } @@ -899,6 +991,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { } #endif // C++20 +#ifdef __cpp_lib_sstream_from_string_view + template + explicit + basic_ostringstream( + const _Tp& __t, ios_base::openmode __mode = ios_base::out) + requires (is_convertible_v>) + : basic_ostringstream(__t, __mode, allocator_type{}) + { } + + template + basic_ostringstream(const _Tp& __t, const allocator_type& __a) + requires (is_convertible_v>) + : basic_ostringstream(__t, ios_base::out, __a) + { } + + template + basic_ostringstream(const _Tp& __t, ios_base::openmode __mode, + const allocator_type& __a) + requires (is_convertible_v>) + : __ostream_type(), _M_stringbuf(__t, __mode | ios_base::out, __a) + { this->init(std::__addressof(_M_stringbuf)); } +#endif // C++26 + // 27.8.3.2 Assign and swap: basic_ostringstream& @@ -930,7 +1048,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _GLIBCXX_NODISCARD __stringbuf_type* rdbuf() const - { return const_cast<__stringbuf_type*>(&_M_stringbuf); } + { return const_cast<__stringbuf_type*>(std::__addressof(_M_stringbuf)); } /** * @brief Copying out the string buffer. @@ -944,6 +1062,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 #if __cplusplus > 201703L #if _GLIBCXX_USE_CXX11_ABI #if __cpp_concepts + // P0407 Allocator-aware basic_streambuf template<__allocator_like _SAlloc> _GLIBCXX_NODISCARD basic_string<_CharT, _Traits, _SAlloc> @@ -975,6 +1094,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI #if __cpp_concepts + // P0407 Allocator-aware basic_streambuf template<__allocator_like _SAlloc> requires (!is_same_v<_SAlloc, _Alloc>) void @@ -986,6 +1106,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 str(__string_type&& __s) { _M_stringbuf.str(std::move(__s)); } #endif + +#ifdef __cpp_lib_sstream_from_string_view + template + void + str(const _Tp& __t) + requires (is_convertible_v>) + { _M_stringbuf.str(__t); } +#endif // C++26 }; @@ -1040,7 +1169,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 */ basic_stringstream() : __iostream_type(), _M_stringbuf(ios_base::out | ios_base::in) - { this->init(&_M_stringbuf); } + { this->init(std::__addressof(_M_stringbuf)); } /** * @brief Starts with an empty string buffer. @@ -1055,7 +1184,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 explicit basic_stringstream(ios_base::openmode __m) : __iostream_type(), _M_stringbuf(__m) - { this->init(&_M_stringbuf); } + { this->init(std::__addressof(_M_stringbuf)); } /** * @brief Starts with an existing string buffer. @@ -1072,7 +1201,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 basic_stringstream(const __string_type& __str, ios_base::openmode __m = ios_base::out | ios_base::in) : __iostream_type(), _M_stringbuf(__str, __m) - { this->init(&_M_stringbuf); } + { this->init(std::__addressof(_M_stringbuf)); } /** * @brief The destructor does nothing. @@ -1089,12 +1218,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 basic_stringstream(basic_stringstream&& __rhs) : __iostream_type(std::move(__rhs)), _M_stringbuf(std::move(__rhs._M_stringbuf)) - { __iostream_type::set_rdbuf(&_M_stringbuf); } + { __iostream_type::set_rdbuf(std::__addressof(_M_stringbuf)); } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI + // P0408 Efficient access to basic_stringbuf buffer basic_stringstream(ios_base::openmode __mode, const allocator_type& __a) : __iostream_type(), _M_stringbuf(__mode, __a) - { this->init(&_M_stringbuf); } + { this->init(std::__addressof(_M_stringbuf)); } explicit basic_stringstream(__string_type&& __str, @@ -1125,6 +1255,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { } #endif // C++20 +#ifdef __cpp_lib_sstream_from_string_view + template + explicit + basic_stringstream(const _Tp& __t, + ios_base::openmode __mode = ios_base::in | ios_base::out) + requires (is_convertible_v>) + : basic_stringstream(__t, __mode, allocator_type{}) + { } + + template + basic_stringstream(const _Tp& __t, const allocator_type& __a) + requires (is_convertible_v>) + : basic_stringstream(__t, ios_base::in | ios_base::out, __a) + { } + + template + basic_stringstream(const _Tp& __t, ios_base::openmode __mode, + const allocator_type& __a) + requires (is_convertible_v>) + : __iostream_type(), _M_stringbuf(__t, __mode, __a) + { this->init(std::__addressof(_M_stringbuf)); } +#endif // C++26 + // 27.8.3.2 Assign and swap: basic_stringstream& @@ -1156,7 +1311,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _GLIBCXX_NODISCARD __stringbuf_type* rdbuf() const - { return const_cast<__stringbuf_type*>(&_M_stringbuf); } + { return const_cast<__stringbuf_type*>(std::__addressof(_M_stringbuf)); } /** * @brief Copying out the string buffer. @@ -1170,6 +1325,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 #if __cplusplus > 201703L #if _GLIBCXX_USE_CXX11_ABI #if __cpp_concepts + // P0407 Allocator-aware basic_streambuf template<__allocator_like _SAlloc> _GLIBCXX_NODISCARD basic_string<_CharT, _Traits, _SAlloc> @@ -1201,6 +1357,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI #if __cpp_concepts + // P0407 Allocator-aware basic_streambuf template<__allocator_like _SAlloc> requires (!is_same_v<_SAlloc, _Alloc>) void @@ -1212,6 +1369,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 str(__string_type&& __s) { _M_stringbuf.str(std::move(__s)); } #endif + +#ifdef __cpp_lib_sstream_from_string_view + template + void + str(const _Tp& __t) + requires (is_convertible_v>) + { _M_stringbuf.str(__t); } +#endif // C++26 }; #if __cplusplus >= 201103L diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 2e69af13a98b..2e6499eab22d 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -2835,6 +2835,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __x.swap(__y); } #if __cpp_lib_ranges_zip // >= C++23 + /// Exchange the values of two const tuples (if const elements can be swapped) template requires (is_swappable_v && ...) constexpr void @@ -2844,7 +2845,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif // C++23 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 - /// Exchange the values of two const tuples (if const elements can be swapped) + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2766. Swapping non-swappable types template _GLIBCXX20_CONSTEXPR typename enable_if...>::value>::type @@ -2939,19 +2941,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif #ifdef __cpp_lib_make_from_tuple // C++ >= 17 + template >>> + constexpr bool __can_make_from_tuple = false; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3528. make_from_tuple can perform (the equivalent of) a C-style cast + template + constexpr bool __can_make_from_tuple<_Tp, _Tuple, index_sequence<_Idx...>> + = is_constructible_v<_Tp, + decltype(std::get<_Idx>(std::declval<_Tuple>()))...>; + template constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>) - { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); } + { + static_assert(__can_make_from_tuple<_Tp, _Tuple, index_sequence<_Idx...>>); + return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); + } #if __cpp_lib_tuple_like // >= C++23 template #else template #endif - constexpr _Tp + constexpr auto make_from_tuple(_Tuple&& __t) noexcept(__unpack_std_tuple) +#ifdef __cpp_concepts // >= C++20 + -> _Tp + requires __can_make_from_tuple<_Tp, _Tuple> +#else + -> __enable_if_t<__can_make_from_tuple<_Tp, _Tuple>, _Tp> +#endif { constexpr size_t __n = tuple_size_v>; #if __has_builtin(__reference_constructs_from_temporary) diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index c8907fe4d382..ff23544fbf03 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -280,11 +280,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Forward declarations template - struct is_reference; - template - struct is_function; - template - struct is_void; + struct is_object; template struct remove_cv; template @@ -294,21 +290,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct __is_array_unknown_bounds; + // An object type which is not an unbounded array. + // It might still be an incomplete type, but if this is false_type + // then we can be certain it's not a complete object type. + template + using __maybe_complete_object_type + = __and_, __not_<__is_array_unknown_bounds<_Tp>>>; + // Helper functions that return false_type for incomplete classes, // incomplete unions and arrays of known bound from those. - template - constexpr true_type __is_complete_or_unbounded(__type_identity<_Tp>) - { return {}; } - - template - constexpr typename __or_< - is_reference<_NestedType>, - is_function<_NestedType>, - is_void<_NestedType>, - __is_array_unknown_bounds<_NestedType> - >::type __is_complete_or_unbounded(_TypeIdentity) + // More specialized overload for complete object types (returning true_type). + template::value>, + size_t = sizeof(_Tp)> + constexpr true_type + __is_complete_or_unbounded(__type_identity<_Tp>) + { return {}; }; + + // Less specialized overload for reference and unknown-bound array types + // (returning true_type), and incomplete types (returning false_type). + template + constexpr typename __not_<__maybe_complete_object_type<_NestedType>>::type + __is_complete_or_unbounded(_TypeIdentity) { return {}; } // __remove_cv_t (std::remove_cv_t for C++11). @@ -459,6 +464,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_integral_helper : public true_type { }; #endif + +#if defined __SIZEOF_INT128__ && defined __STRICT_ANSI__ + __extension__ + template<> + struct __is_integral_helper<__int128> + : public true_type { }; + + __extension__ + template<> + struct __is_integral_helper + : public true_type { }; +#endif + /// @endcond /// is_integral @@ -514,7 +532,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public true_type { }; #endif -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) +#ifdef _GLIBCXX_USE_FLOAT128 template<> struct __is_floating_point_helper<__float128> : public true_type { }; @@ -1036,6 +1054,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_array_unknown_bounds<_Tp[]> : public true_type { }; + /// @endcond // Destructible and constructible type properties. @@ -1046,6 +1065,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public __bool_constant<__is_destructible(_Tp)> { }; #else + /// @cond undocumented + // In N3290 is_destructible does not say anything about function // types and abstract types, see LWG 2049. This implementation // describes function types as non-destructible and all complete @@ -1919,6 +1940,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3> { using __type = unsigned __GLIBCXX_TYPE_INT_N_3; }; #endif +#if defined __SIZEOF_INT128__ && defined __STRICT_ANSI__ + __extension__ + template<> + struct __make_unsigned<__int128> + { using __type = unsigned __int128; }; +#endif // Select between integral and enum: not possible to be both. template; + unsigned long, unsigned long long +#ifdef __SIZEOF_INT128__ + , unsigned __int128 +#endif + >; using __unsigned_type = typename __select::__type; @@ -2079,6 +2111,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __make_signed { using __type = __GLIBCXX_TYPE_INT_N_3; }; #endif +#if defined __SIZEOF_INT128__ && defined __STRICT_ANSI__ + __extension__ + template<> + struct __make_signed + { using __type = __int128; }; +#endif // Select between integral and enum: not possible to be both. template enable_if_t && ...) && (is_swappable_v<_Types> && ...))> diff --git a/libstdc++-v3/libsupc++/compare b/libstdc++-v3/libsupc++/compare index 8811bc095d0b..82b5c53139c9 100644 --- a/libstdc++-v3/libsupc++/compare +++ b/libstdc++-v3/libsupc++/compare @@ -35,6 +35,7 @@ #endif #define __glibcxx_want_three_way_comparison +#define __glibcxx_want_type_order #include #if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L @@ -1261,6 +1262,28 @@ namespace std _GLIBCXX_VISIBILITY(default) std::declval<_Up&>())); } // namespace __detail /// @endcond + +#if __glibcxx_type_order >= 202506L // C++ >= 26 + /// Total ordering of types. + /// @since C++26 + + template + struct type_order + { + static constexpr strong_ordering value = __builtin_type_order(_Tp, _Up); + using value_type = strong_ordering; + using type = type_order<_Tp, _Up>; + constexpr operator value_type() const noexcept { return value; } + constexpr value_type operator()() const noexcept { return value; } + }; + + /// @ingroup variable_templates + /// @since C++26 + template + inline constexpr strong_ordering type_order_v + = __builtin_type_order(_Tp, _Up); +#endif // __glibcxx_type_order >= 202506L + #endif // __cpp_lib_three_way_comparison >= 201907L } // namespace std diff --git a/libstdc++-v3/libsupc++/eh_ptr.cc b/libstdc++-v3/libsupc++/eh_ptr.cc index 6512449a32cc..1fb35d82f539 100644 --- a/libstdc++-v3/libsupc++/eh_ptr.cc +++ b/libstdc++-v3/libsupc++/eh_ptr.cc @@ -220,4 +220,20 @@ std::rethrow_exception(std::exception_ptr ep) std::terminate(); } +const void* +std::__exception_ptr::exception_ptr::_M_exception_ptr_cast(const type_info& t) + const noexcept +{ + void *ptr = _M_exception_object; + if (__builtin_expect(ptr == nullptr, false)) + return nullptr; + __cxa_refcounted_exception *eh + = __get_refcounted_exception_header_from_obj (_M_exception_object); + const type_info* __thr_type = eh->exc.exceptionType; + if (t.__do_catch(__thr_type, &ptr, 1)) + return ptr; + return nullptr; +} + + #undef _GLIBCXX_EH_PTR_COMPAT diff --git a/libstdc++-v3/libsupc++/exception b/libstdc++-v3/libsupc++/exception index 246c9b185638..fc6f8d927711 100644 --- a/libstdc++-v3/libsupc++/exception +++ b/libstdc++-v3/libsupc++/exception @@ -38,6 +38,8 @@ #include #define __glibcxx_want_uncaught_exceptions +#define __glibcxx_want_constexpr_exceptions +#define __glibcxx_want_exception_ptr_cast #include extern "C++" { @@ -56,8 +58,16 @@ namespace std _GLIBCXX_VISIBILITY(default) class bad_exception : public exception { public: - bad_exception() _GLIBCXX_USE_NOEXCEPT { } + _GLIBCXX26_CONSTEXPR bad_exception() _GLIBCXX_USE_NOEXCEPT { } +#if __cplusplus >= 202400L + constexpr virtual ~bad_exception() _GLIBCXX_TXN_SAFE_DYN noexcept {} + + constexpr virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN noexcept + { + return "std::bad_exception"; + } +#else // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; @@ -65,6 +75,7 @@ namespace std _GLIBCXX_VISIBILITY(default) // See comment in eh_exception.cc. virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; +#endif }; /// If you write a replacement %terminate handler, it must be of this type. @@ -164,9 +175,9 @@ _GLIBCXX_END_NAMESPACE_VERSION } // extern "C++" -#if (__cplusplus >= 201103L) -#include -#include +#if __cplusplus >= 201103L +# include +# include #endif #endif diff --git a/libstdc++-v3/libsupc++/exception.h b/libstdc++-v3/libsupc++/exception.h index f8bca9127bce..efb5fea5d863 100644 --- a/libstdc++-v3/libsupc++/exception.h +++ b/libstdc++-v3/libsupc++/exception.h @@ -61,19 +61,28 @@ namespace std _GLIBCXX_VISIBILITY(default) class exception { public: - exception() _GLIBCXX_NOTHROW { } + _GLIBCXX26_CONSTEXPR exception() _GLIBCXX_NOTHROW { } +#if __cplusplus >= 202400L + constexpr virtual ~exception() _GLIBCXX_TXN_SAFE_DYN noexcept {} +#else virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW; +#endif #if __cplusplus >= 201103L - exception(const exception&) = default; - exception& operator=(const exception&) = default; - exception(exception&&) = default; - exception& operator=(exception&&) = default; + _GLIBCXX26_CONSTEXPR exception(const exception&) = default; + _GLIBCXX26_CONSTEXPR exception& operator=(const exception&) = default; + _GLIBCXX26_CONSTEXPR exception(exception&&) = default; + _GLIBCXX26_CONSTEXPR exception& operator=(exception&&) = default; #endif /** Returns a C-style character string describing the general cause * of the current error. */ +#if __cplusplus >= 202400L + constexpr virtual const char* + what() const _GLIBCXX_TXN_SAFE_DYN noexcept { return "std::exception"; } +#else virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW; +#endif }; /// @} diff --git a/libstdc++-v3/libsupc++/exception_ptr.h b/libstdc++-v3/libsupc++/exception_ptr.h index a7e5e527d212..f673a3343338 100644 --- a/libstdc++-v3/libsupc++/exception_ptr.h +++ b/libstdc++-v3/libsupc++/exception_ptr.h @@ -75,11 +75,19 @@ namespace std _GLIBCXX_VISIBILITY(default) exception_ptr current_exception() _GLIBCXX_USE_NOEXCEPT; template - exception_ptr make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT; + _GLIBCXX26_CONSTEXPR exception_ptr make_exception_ptr(_Ex) + _GLIBCXX_USE_NOEXCEPT; /// Throw the object pointed to by the exception_ptr. void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__)); +#if __cpp_lib_exception_ptr_cast >= 202506L + template + constexpr const _Ex* exception_ptr_cast(const exception_ptr&) noexcept; + template + void exception_ptr_cast(const exception_ptr&&) = delete; +#endif + namespace __exception_ptr { using std::rethrow_exception; // So that ADL finds it. @@ -98,7 +106,25 @@ namespace std _GLIBCXX_VISIBILITY(default) { void* _M_exception_object; +#if __cplusplus >= 202400L + constexpr explicit exception_ptr(void* __e) noexcept + : _M_exception_object(__e) + { + if (_M_exception_object) + { +#if __cpp_if_consteval >= 202106L \ + && _GLIBCXX_HAS_BUILTIN(__builtin_eh_ptr_adjust_ref) + if consteval { + __builtin_eh_ptr_adjust_ref(_M_exception_object, 1); + return; + } +#endif + _M_addref(); + } + } +#else explicit exception_ptr(void* __e) _GLIBCXX_USE_NOEXCEPT; +#endif void _M_addref() _GLIBCXX_USE_NOEXCEPT; void _M_release() _GLIBCXX_USE_NOEXCEPT; @@ -108,19 +134,29 @@ namespace std _GLIBCXX_VISIBILITY(default) friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT; friend void std::rethrow_exception(exception_ptr); template - friend exception_ptr std::make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT; + friend _GLIBCXX26_CONSTEXPR exception_ptr std::make_exception_ptr(_Ex) + _GLIBCXX_USE_NOEXCEPT; +#if __cpp_lib_exception_ptr_cast >= 202506L + template + friend constexpr const _Ex* + std::exception_ptr_cast(const exception_ptr&) noexcept; +#endif + + const void* _M_exception_ptr_cast(const type_info&) const + _GLIBCXX_USE_NOEXCEPT; public: - exception_ptr() _GLIBCXX_USE_NOEXCEPT; + _GLIBCXX26_CONSTEXPR exception_ptr() _GLIBCXX_USE_NOEXCEPT; - exception_ptr(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT; + _GLIBCXX26_CONSTEXPR exception_ptr(const exception_ptr&) + _GLIBCXX_USE_NOEXCEPT; #if __cplusplus >= 201103L - exception_ptr(nullptr_t) noexcept + _GLIBCXX26_CONSTEXPR exception_ptr(nullptr_t) noexcept : _M_exception_object(nullptr) { } - exception_ptr(exception_ptr&& __o) noexcept + _GLIBCXX26_CONSTEXPR exception_ptr(exception_ptr&& __o) noexcept : _M_exception_object(__o._M_exception_object) { __o._M_exception_object = nullptr; } #endif @@ -132,11 +168,11 @@ namespace std _GLIBCXX_VISIBILITY(default) exception_ptr(__safe_bool) _GLIBCXX_USE_NOEXCEPT; #endif - exception_ptr& + _GLIBCXX26_CONSTEXPR exception_ptr& operator=(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT; #if __cplusplus >= 201103L - exception_ptr& + _GLIBCXX26_CONSTEXPR exception_ptr& operator=(exception_ptr&& __o) noexcept { exception_ptr(static_cast(__o)).swap(*this); @@ -144,9 +180,9 @@ namespace std _GLIBCXX_VISIBILITY(default) } #endif - ~exception_ptr() _GLIBCXX_USE_NOEXCEPT; + _GLIBCXX26_CONSTEXPR ~exception_ptr() _GLIBCXX_USE_NOEXCEPT; - void + _GLIBCXX26_CONSTEXPR void swap(exception_ptr&) _GLIBCXX_USE_NOEXCEPT; #ifdef _GLIBCXX_EH_PTR_COMPAT @@ -158,13 +194,13 @@ namespace std _GLIBCXX_VISIBILITY(default) #endif #if __cplusplus >= 201103L - explicit operator bool() const noexcept + _GLIBCXX26_CONSTEXPR explicit operator bool() const noexcept { return _M_exception_object; } #endif #if __cpp_impl_three_way_comparison >= 201907L \ && ! defined _GLIBCXX_EH_PTR_RELOPS_COMPAT - friend bool + _GLIBCXX26_CONSTEXPR friend bool operator==(const exception_ptr&, const exception_ptr&) noexcept = default; #else friend _GLIBCXX_EH_PTR_USED bool @@ -184,31 +220,49 @@ namespace std _GLIBCXX_VISIBILITY(default) }; _GLIBCXX_EH_PTR_USED - inline + _GLIBCXX26_CONSTEXPR inline exception_ptr::exception_ptr() _GLIBCXX_USE_NOEXCEPT : _M_exception_object(0) { } _GLIBCXX_EH_PTR_USED - inline + _GLIBCXX26_CONSTEXPR inline exception_ptr::exception_ptr(const exception_ptr& __other) _GLIBCXX_USE_NOEXCEPT : _M_exception_object(__other._M_exception_object) { if (_M_exception_object) - _M_addref(); + { +#if __cpp_if_consteval >= 202106L \ + && _GLIBCXX_HAS_BUILTIN(__builtin_eh_ptr_adjust_ref) + if consteval { + __builtin_eh_ptr_adjust_ref(_M_exception_object, 1); + return; + } +#endif + _M_addref(); + } } _GLIBCXX_EH_PTR_USED - inline + _GLIBCXX26_CONSTEXPR inline exception_ptr::~exception_ptr() _GLIBCXX_USE_NOEXCEPT { if (_M_exception_object) - _M_release(); + { +#if __cpp_if_consteval >= 202106L \ + && _GLIBCXX_HAS_BUILTIN(__builtin_eh_ptr_adjust_ref) + if consteval { + __builtin_eh_ptr_adjust_ref(_M_exception_object, -1); + return; + } +#endif + _M_release(); + } } _GLIBCXX_EH_PTR_USED - inline exception_ptr& + _GLIBCXX26_CONSTEXPR inline exception_ptr& exception_ptr::operator=(const exception_ptr& __other) _GLIBCXX_USE_NOEXCEPT { exception_ptr(__other).swap(*this); @@ -216,7 +270,7 @@ namespace std _GLIBCXX_VISIBILITY(default) } _GLIBCXX_EH_PTR_USED - inline void + _GLIBCXX26_CONSTEXPR inline void exception_ptr::swap(exception_ptr &__other) _GLIBCXX_USE_NOEXCEPT { void *__tmp = _M_exception_object; @@ -225,7 +279,7 @@ namespace std _GLIBCXX_VISIBILITY(default) } /// @relates exception_ptr - inline void + _GLIBCXX26_CONSTEXPR inline void swap(exception_ptr& __lhs, exception_ptr& __rhs) { __lhs.swap(__rhs); } @@ -242,28 +296,41 @@ namespace std _GLIBCXX_VISIBILITY(default) using __exception_ptr::swap; // So that std::swap(exp1, exp2) finds it. /// Obtain an exception_ptr pointing to a copy of the supplied object. -#if (__cplusplus >= 201103L && __cpp_rtti) || __cpp_exceptions template - exception_ptr +#if !(__cplusplus >= 201103L && __cpp_rtti) && !__cpp_exceptions + // This is always_inline so the linker will never use a useless definition + // instead of a working one compiled with RTTI and/or exceptions enabled. + __attribute__ ((__always_inline__)) inline +#endif + _GLIBCXX26_CONSTEXPR exception_ptr make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT { #if __cplusplus >= 201103L && __cpp_rtti - using _Ex2 = typename decay<_Ex>::type; - void* __e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex)); - (void) __cxxabiv1::__cxa_init_primary_exception( - __e, const_cast(&typeid(_Ex)), - __exception_ptr::__dest_thunk<_Ex2>); - __try + // For runtime calls with -frtti enabled we can avoid try-catch overhead. + // We can't use this for C++98 because it relies on std::decay. +#ifdef __glibcxx_constexpr_exceptions + if ! consteval +#endif { - ::new (__e) _Ex2(__ex); - return exception_ptr(__e); + using _Ex2 = typename decay<_Ex>::type; + void* __e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex)); + (void) __cxxabiv1::__cxa_init_primary_exception( + __e, const_cast(&typeid(_Ex)), + __exception_ptr::__dest_thunk<_Ex2>); + __try + { + ::new (__e) _Ex2(__ex); + return exception_ptr(__e); + } + __catch(...) + { + __cxxabiv1::__cxa_free_exception(__e); + return current_exception(); + } } - __catch(...) - { - __cxxabiv1::__cxa_free_exception(__e); - return current_exception(); - } -#else +#endif + +#ifdef __cpp_exceptions try { throw __ex; @@ -273,15 +340,47 @@ namespace std _GLIBCXX_VISIBILITY(default) return current_exception(); } #endif + return exception_ptr(); } -#else // no RTTI and no exceptions - // This is always_inline so the linker will never use this useless definition - // instead of a working one compiled with RTTI and/or exceptions enabled. + +#if __cpp_lib_exception_ptr_cast >= 202506L template - __attribute__ ((__always_inline__)) - inline exception_ptr - make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT - { return exception_ptr(); } + [[__gnu__::__always_inline__]] + constexpr const _Ex* + exception_ptr_cast(const exception_ptr& __p) noexcept + { + static_assert(!std::is_const_v<_Ex>); + static_assert(!std::is_reference_v<_Ex>); + static_assert(std::is_object_v<_Ex>); + static_assert(!std::is_array_v<_Ex>); + static_assert(!std::is_pointer_v<_Ex>); + static_assert(!std::is_member_pointer_v<_Ex>); + +#ifdef __cpp_rtti + // For runtime calls with -frtti enabled we can avoid try-catch overhead. + if ! consteval { + const type_info &__id = typeid(const _Ex&); + return static_cast(__p._M_exception_ptr_cast(__id)); + } +#endif + +#ifdef __cpp_exceptions + if (__p._M_exception_object) + try + { + std::rethrow_exception(__p); + } + catch (const _Ex& __exc) + { + return &__exc; + } + catch (...) + { + } +#endif + + return nullptr; + } #endif #undef _GLIBCXX_EH_PTR_USED diff --git a/libstdc++-v3/libsupc++/nested_exception.h b/libstdc++-v3/libsupc++/nested_exception.h index c9f63e5a56a2..aff47bc3d7f9 100644 --- a/libstdc++-v3/libsupc++/nested_exception.h +++ b/libstdc++-v3/libsupc++/nested_exception.h @@ -62,17 +62,24 @@ namespace std _GLIBCXX_VISIBILITY(default) public: /// The default constructor stores the current exception (if any). + _GLIBCXX26_CONSTEXPR nested_exception() noexcept : _M_ptr(current_exception()) { } + _GLIBCXX26_CONSTEXPR nested_exception(const nested_exception&) noexcept = default; + _GLIBCXX26_CONSTEXPR nested_exception& operator=(const nested_exception&) noexcept = default; +#if __cplusplus >= 202400L + constexpr virtual ~nested_exception() noexcept {} +#else virtual ~nested_exception() noexcept; +#endif /// Rethrow the stored exception, or terminate if none was stored. [[noreturn]] - void + _GLIBCXX26_CONSTEXPR void rethrow_nested() const { if (_M_ptr) @@ -81,7 +88,7 @@ namespace std _GLIBCXX_VISIBILITY(default) } /// Access the stored exception. - exception_ptr + _GLIBCXX26_CONSTEXPR exception_ptr nested_ptr() const noexcept { return _M_ptr; } }; @@ -91,11 +98,11 @@ namespace std _GLIBCXX_VISIBILITY(default) template struct _Nested_exception : public _Except, public nested_exception { - explicit _Nested_exception(const _Except& __ex) + _GLIBCXX26_CONSTEXPR explicit _Nested_exception(const _Except& __ex) : _Except(__ex) { } - explicit _Nested_exception(_Except&& __ex) + _GLIBCXX26_CONSTEXPR explicit _Nested_exception(_Except&& __ex) : _Except(static_cast<_Except&&>(__ex)) { } }; @@ -144,7 +151,7 @@ namespace std _GLIBCXX_VISIBILITY(default) */ template [[noreturn]] - inline void + _GLIBCXX26_CONSTEXPR inline void throw_with_nested(_Tp&& __t) { using _Up = typename decay<_Tp>::type; @@ -204,7 +211,7 @@ namespace std _GLIBCXX_VISIBILITY(default) # if ! __cpp_rtti [[__gnu__::__always_inline__]] #endif - inline void + _GLIBCXX26_CONSTEXPR inline void rethrow_if_nested(const _Ex& __ex) { const _Ex* __ptr = __builtin_addressof(__ex); diff --git a/libstdc++-v3/libsupc++/new b/libstdc++-v3/libsupc++/new index a5503733cdcd..fb36dae25a6d 100644 --- a/libstdc++-v3/libsupc++/new +++ b/libstdc++-v3/libsupc++/new @@ -66,33 +66,51 @@ namespace std class bad_alloc : public exception { public: - bad_alloc() throw() { } + _GLIBCXX26_CONSTEXPR bad_alloc() throw() { } #if __cplusplus >= 201103L - bad_alloc(const bad_alloc&) = default; - bad_alloc& operator=(const bad_alloc&) = default; + _GLIBCXX26_CONSTEXPR bad_alloc(const bad_alloc&) = default; + _GLIBCXX26_CONSTEXPR bad_alloc& operator=(const bad_alloc&) = default; #endif +#if __cplusplus >= 202400L + constexpr virtual ~bad_alloc() noexcept {} + + constexpr virtual const char* what() const noexcept + { + return "std::bad_alloc"; + } +#else // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_alloc() throw(); // See comment in eh_exception.cc. virtual const char* what() const throw(); +#endif }; #if __cplusplus >= 201103L class bad_array_new_length : public bad_alloc { public: - bad_array_new_length() throw() { } + _GLIBCXX26_CONSTEXPR bad_array_new_length() throw() { } +#if __cplusplus >= 202400L + constexpr virtual ~bad_array_new_length() noexcept {} + + constexpr virtual const char* what() const noexcept + { + return "std::bad_array_new_length"; + } +#else // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_array_new_length() throw(); // See comment in eh_exception.cc. virtual const char* what() const throw(); +#endif }; #endif diff --git a/libstdc++-v3/libsupc++/typeinfo b/libstdc++-v3/libsupc++/typeinfo index 0a94b86bd745..a31be7c39eaf 100644 --- a/libstdc++-v3/libsupc++/typeinfo +++ b/libstdc++-v3/libsupc++/typeinfo @@ -224,14 +224,23 @@ namespace std class bad_cast : public exception { public: - bad_cast() _GLIBCXX_USE_NOEXCEPT { } + _GLIBCXX26_CONSTEXPR bad_cast() _GLIBCXX_USE_NOEXCEPT { } +#if __cplusplus >= 202400L + constexpr virtual ~bad_cast() noexcept {} + + constexpr virtual const char* what() const noexcept + { + return "std::bad_cast"; + } +#else // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_cast() _GLIBCXX_USE_NOEXCEPT; // See comment in eh_exception.cc. virtual const char* what() const _GLIBCXX_USE_NOEXCEPT; +#endif }; /** @@ -241,14 +250,23 @@ namespace std class bad_typeid : public exception { public: - bad_typeid () _GLIBCXX_USE_NOEXCEPT { } + _GLIBCXX26_CONSTEXPR bad_typeid () _GLIBCXX_USE_NOEXCEPT { } +#if __cplusplus >= 202400L + constexpr virtual ~bad_typeid() noexcept {} + + constexpr virtual const char* what() const noexcept + { + return "std::bad_typeid"; + } +#else // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_typeid() _GLIBCXX_USE_NOEXCEPT; // See comment in eh_exception.cc. virtual const char* what() const _GLIBCXX_USE_NOEXCEPT; +#endif }; } // namespace std diff --git a/libstdc++-v3/scripts/create_testsuite_files b/libstdc++-v3/scripts/create_testsuite_files index 174c24ec05a4..ae259c65318f 100755 --- a/libstdc++-v3/scripts/create_testsuite_files +++ b/libstdc++-v3/scripts/create_testsuite_files @@ -3,9 +3,7 @@ # Constructs lists of source files (full pathnames) to test. Two # files are constructed: testsuite_files, which is used to test with # the default dg-runtest command, and testsuite_files_interactive, -# which is used to test cases that require input to be entered. In -# addition, both lists are pruned of wchar_t tests if the toolchain -# under test does not support wchar_t functionality. +# which is used to test cases that require input to be entered. # # We mimic the mkcheck script in that the first time this is run, all # existing files are listed in "testsuite_files" in the output diff --git a/libstdc++-v3/scripts/gen_windows_zones_map.py b/libstdc++-v3/scripts/gen_windows_zones_map.py new file mode 100755 index 000000000000..7f547a760025 --- /dev/null +++ b/libstdc++-v3/scripts/gen_windows_zones_map.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +# +# Script to generate the map for libstdc++ std::chrono::current_zone under Windows. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 3, or (at your option) any later +# version. +# +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# To update the Libstdc++ static data in src/c++20/windows_zones-map.h download the latest: +# https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml +# Then run this script and save the output to +# src/c++20/windows_zones-map.h + +import os +import sys +import xml.etree.ElementTree as et + +if len(sys.argv) != 2: + print("Usage: %s " % sys.argv[0], file=sys.stderr) + sys.exit(1) + +self = os.path.basename(__file__) +print("// Generated by scripts/{}, do not edit.".format(self)) +print(""" +// Copyright The GNU Toolchain Authors. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +""") + +class WindowsZoneMapEntry: + def __init__(self, windows, territory, iana): + self.windows = windows + self.territory = territory + self.iana = iana + + def __lt__(self, other): + return (self.windows, self.territory) < (other.windows, other.territory) + +windows_zone_map = [] + +tree = et.parse(sys.argv[1]) +xml_zone_map = tree.getroot().find("windowsZones").find("mapTimezones") + +for entry in xml_zone_map.iter("mapZone"): + iana = entry.attrib["type"] + space = iana.find(" ") + if space != -1: + iana = iana[0:space] + windows_zone_map.append(WindowsZoneMapEntry(entry.attrib["other"], entry.attrib["territory"], iana)) + +# Sort so we can use binary search on the array. +windows_zone_map.sort() + +# Skip territories which have the same IANA zone as 001, so we can reduce the data. +last_windows_zone = "" +for entry in windows_zone_map[:]: + if entry.windows != last_windows_zone: + if entry.territory != "001": + raise ValueError('Territory "001" not the first one, this breaks assumptions in tzdb.cc!') + last_windows_zone = entry.windows + fallback_iana = entry.iana + else: + if entry.iana == fallback_iana: + windows_zone_map.remove(entry) + +print("""struct windows_zone_map_entry +{{ + wstring_view windows_name; + wstring_view territory; + string_view iana_name; +}}; + +static constexpr array windows_zone_map{{ + {{""".format(len(windows_zone_map))) + +for entry in windows_zone_map: + print(' {{L"{}", L"{}", "{}"}},'.format(entry.windows, entry.territory, entry.iana)) + +print(""" } +};""") + +# src/c++20/tzdb.cc gives an error if this macro is not defined. +# Do this last, so that the generated output is not usable unless we reach here. +print("\n#define _GLIBCXX_WINDOWS_ZONES_MAP_COMPLETE") diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc index 3533b5e1df12..c6f6ef7ecb74 100644 --- a/libstdc++-v3/src/c++11/debug.cc +++ b/libstdc++-v3/src/c++11/debug.cc @@ -54,7 +54,7 @@ namespace * in order to limit contention without breaking current library binary * compatibility. */ __gnu_cxx::__mutex& - get_safe_base_mutex(void* address) + get_safe_base_mutex(const void* address) { // Use arbitrarily __gnu_debug::vector as the container giving // alignment of debug containers. @@ -70,9 +70,9 @@ namespace #pragma GCC diagnostic warning "-Wabi=6" void - swap_its(__gnu_debug::_Safe_sequence_base& __lhs, + swap_its(const __gnu_debug::_Safe_sequence_base& __lhs, __gnu_debug::_Safe_iterator_base*& __lhs_its, - __gnu_debug::_Safe_sequence_base& __rhs, + const __gnu_debug::_Safe_sequence_base& __rhs, __gnu_debug::_Safe_iterator_base*& __rhs_its) { swap(__lhs_its, __rhs_its); @@ -84,8 +84,8 @@ namespace } void - swap_seq_single(__gnu_debug::_Safe_sequence_base& __lhs, - __gnu_debug::_Safe_sequence_base& __rhs) + swap_seq_single(const __gnu_debug::_Safe_sequence_base& __lhs, + const __gnu_debug::_Safe_sequence_base& __rhs) { swap(__lhs._M_version, __rhs._M_version); swap_its(__lhs, __lhs._M_iterators, @@ -118,17 +118,17 @@ namespace void swap_seq(__gnu_cxx::__mutex& lhs_mutex, - __gnu_debug::_Safe_sequence_base& lhs, + const __gnu_debug::_Safe_sequence_base& lhs, __gnu_cxx::__mutex& rhs_mutex, - __gnu_debug::_Safe_sequence_base& rhs) + const __gnu_debug::_Safe_sequence_base& rhs) { lock_and_run(lhs_mutex, rhs_mutex, [&lhs, &rhs]() { swap_seq_single(lhs, rhs); }); } void - swap_ucont_single(__gnu_debug::_Safe_unordered_container_base& __lhs, - __gnu_debug::_Safe_unordered_container_base& __rhs) + swap_ucont_single(const __gnu_debug::_Safe_unordered_container_base& __lhs, + const __gnu_debug::_Safe_unordered_container_base& __rhs) { swap_seq_single(__lhs, __rhs); swap_its(__lhs, __lhs._M_local_iterators, @@ -139,9 +139,9 @@ namespace void swap_ucont(__gnu_cxx::__mutex& lhs_mutex, - __gnu_debug::_Safe_unordered_container_base& lhs, + const __gnu_debug::_Safe_unordered_container_base& lhs, __gnu_cxx::__mutex& rhs_mutex, - __gnu_debug::_Safe_unordered_container_base& rhs) + const __gnu_debug::_Safe_unordered_container_base& rhs) { lock_and_run(lhs_mutex, rhs_mutex, [&lhs, &rhs]() { swap_ucont_single(lhs, rhs); }); @@ -158,8 +158,8 @@ namespace } } - void* - acquire_sequence_ptr_for_lock(__gnu_debug::_Safe_sequence_base*& seq) + const void* + acquire_sequence_ptr_for_lock(__gnu_debug::_Safe_sequence_base const*& seq) { #ifdef __GTHREADS if (!__gnu_cxx::__is_single_threaded()) @@ -169,7 +169,7 @@ namespace } void - reset_sequence_ptr(__gnu_debug::_Safe_sequence_base*& seq) + reset_sequence_ptr(__gnu_debug::_Safe_sequence_base const*& seq) { #ifdef __GTHREADS if (!__gnu_cxx::__is_single_threaded()) @@ -327,7 +327,7 @@ namespace __gnu_debug void _Safe_sequence_base:: - _M_detach_all() + _M_detach_all() const { __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); detach_all(_M_iterators); @@ -339,7 +339,7 @@ namespace __gnu_debug void _Safe_sequence_base:: - _M_detach_singular() + _M_detach_singular() const { __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); for (_Safe_iterator_base* __iter = _M_iterators; __iter;) @@ -361,7 +361,7 @@ namespace __gnu_debug void _Safe_sequence_base:: - _M_revalidate_singular() + _M_revalidate_singular() const { __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); for (_Safe_iterator_base* __iter = _M_iterators; __iter; @@ -375,17 +375,59 @@ namespace __gnu_debug void _Safe_sequence_base:: - _M_swap(_Safe_sequence_base& __x) noexcept + _M_swap(const _Safe_sequence_base& __x) const noexcept { swap_seq(_M_get_mutex(), *this, __x._M_get_mutex(), __x); } __gnu_cxx::__mutex& _Safe_sequence_base:: - _M_get_mutex() noexcept + _M_get_mutex() const noexcept { return get_safe_base_mutex(this); } +#if !_GLIBCXX_INLINE_VERSION + void + _Safe_sequence_base:: + _M_detach_all() + { + const _Safe_sequence_base* __this = this; + __this->_M_detach_all(); + } + + void + _Safe_sequence_base:: + _M_detach_singular() + { + const _Safe_sequence_base* __this = this; + __this->_M_detach_singular(); + } + + void + _Safe_sequence_base:: + _M_revalidate_singular() + { + const _Safe_sequence_base* __this = this; + __this->_M_revalidate_singular(); + } + void _Safe_sequence_base:: - _M_attach(_Safe_iterator_base* __it, bool __constant) + _M_swap(_Safe_sequence_base& __x) noexcept + { + const _Safe_sequence_base* __this = this; + __this->_M_swap(__x); + } + + __gnu_cxx::__mutex& + _Safe_sequence_base:: + _M_get_mutex() noexcept + { + const _Safe_sequence_base* __this = this; + return __this->_M_get_mutex(); + } +#endif + + void + _Safe_sequence_base:: + _M_attach(_Safe_iterator_base* __it, bool __constant) const { __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); _M_attach_single(__it, __constant); @@ -393,7 +435,7 @@ namespace __gnu_debug void _Safe_sequence_base:: - _M_attach_single(_Safe_iterator_base* __it, bool __constant) noexcept + _M_attach_single(_Safe_iterator_base* __it, bool __constant) const noexcept { _Safe_iterator_base*& __its = __constant ? _M_const_iterators : _M_iterators; @@ -405,7 +447,7 @@ namespace __gnu_debug void _Safe_sequence_base:: - _M_detach(_Safe_iterator_base* __it) + _M_detach(_Safe_iterator_base* __it) const { // Remove __it from this sequence's list __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); @@ -414,7 +456,7 @@ namespace __gnu_debug void _Safe_sequence_base:: - _M_detach_single(_Safe_iterator_base* __it) noexcept + _M_detach_single(_Safe_iterator_base* __it) const noexcept { // Remove __it from this sequence's list __it->_M_unlink(); @@ -426,7 +468,7 @@ namespace __gnu_debug void _Safe_iterator_base:: - _M_attach(_Safe_sequence_base* __seq, bool __constant) + _M_attach(const _Safe_sequence_base* __seq, bool __constant) { _M_detach(); @@ -443,7 +485,7 @@ namespace __gnu_debug void _Safe_iterator_base:: - _M_attach_single(_Safe_sequence_base* __seq, bool __constant) noexcept + _M_attach_single(const _Safe_sequence_base* __seq, bool __constant) noexcept { _M_detach_single(); @@ -514,14 +556,27 @@ namespace __gnu_debug _M_get_mutex() noexcept { return _M_sequence->_M_get_mutex(); } - _Safe_unordered_container_base* - _Safe_local_iterator_base:: - _M_get_container() const noexcept - { return static_cast<_Safe_unordered_container_base*>(_M_sequence); } +#if !_GLIBCXX_INLINE_VERSION + void + _Safe_iterator_base:: + _M_attach(_Safe_sequence_base* __seq, bool __constant) + { + const _Safe_sequence_base* __cseq = __seq; + _M_attach(__cseq, __constant); + } + + void + _Safe_iterator_base:: + _M_attach_single(_Safe_sequence_base* __seq, bool __constant) noexcept + { + const _Safe_sequence_base* __cseq = __seq; + _M_attach_single(__cseq, __constant); + } +#endif void _Safe_local_iterator_base:: - _M_attach(_Safe_sequence_base* __cont, bool __constant) + _M_attach(const _Safe_unordered_container_base* __cont, bool __constant) { _M_detach(); @@ -530,7 +585,7 @@ namespace __gnu_debug { _M_sequence = __cont; _M_version = _M_sequence->_M_version; - _M_get_container()->_M_attach_local(this, __constant); + _M_safe_container()->_M_attach_local(this, __constant); } else _M_version = 0; @@ -538,7 +593,8 @@ namespace __gnu_debug void _Safe_local_iterator_base:: - _M_attach_single(_Safe_sequence_base* __cont, bool __constant) noexcept + _M_attach_single(const _Safe_unordered_container_base* __cont, + bool __constant) noexcept { _M_detach_single(); @@ -547,7 +603,7 @@ namespace __gnu_debug { _M_sequence = __cont; _M_version = _M_sequence->_M_version; - _M_get_container()->_M_attach_local_single(this, __constant); + _M_safe_container()->_M_attach_local_single(this, __constant); } else _M_version = 0; @@ -570,14 +626,34 @@ namespace __gnu_debug { if (_M_sequence) { - _M_get_container()->_M_detach_local_single(this); + _M_safe_container()->_M_detach_local_single(this); _M_reset(); } } +#if !_GLIBCXX_INLINE_VERSION + void + _Safe_local_iterator_base:: + _M_attach(_Safe_sequence_base* __seq, bool __constant) + { + const _Safe_unordered_container_base* __cont + = static_cast<_Safe_unordered_container_base*>(__seq); + _M_attach(__cont, __constant); + } + + void + _Safe_local_iterator_base:: + _M_attach_single(_Safe_sequence_base* __seq, bool __constant) noexcept + { + const _Safe_unordered_container_base* __cont + = static_cast<_Safe_unordered_container_base*>(__seq); + _M_attach_single(__cont, __constant); + } +#endif + void _Safe_unordered_container_base:: - _M_detach_all() + _M_detach_all() const { __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); detach_all(_M_iterators); @@ -595,12 +671,12 @@ namespace __gnu_debug void _Safe_unordered_container_base:: - _M_swap(_Safe_unordered_container_base& __x) noexcept + _M_swap(const _Safe_unordered_container_base& __x) const noexcept { swap_ucont(_M_get_mutex(), *this, __x._M_get_mutex(), __x); } void _Safe_unordered_container_base:: - _M_attach_local(_Safe_iterator_base* __it, bool __constant) + _M_attach_local(_Safe_iterator_base* __it, bool __constant) const { __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); _M_attach_local_single(__it, __constant); @@ -608,7 +684,7 @@ namespace __gnu_debug void _Safe_unordered_container_base:: - _M_attach_local_single(_Safe_iterator_base* __it, bool __constant) noexcept + _M_attach_local_single(_Safe_iterator_base* __it, bool __constant) const noexcept { _Safe_iterator_base*& __its = __constant ? _M_const_local_iterators : _M_local_iterators; @@ -620,7 +696,7 @@ namespace __gnu_debug void _Safe_unordered_container_base:: - _M_detach_local(_Safe_iterator_base* __it) + _M_detach_local(_Safe_iterator_base* __it) const { // Remove __it from this container's list __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); @@ -629,7 +705,7 @@ namespace __gnu_debug void _Safe_unordered_container_base:: - _M_detach_local_single(_Safe_iterator_base* __it) noexcept + _M_detach_local_single(_Safe_iterator_base* __it) const noexcept { // Remove __it from this container's list __it->_M_unlink(); @@ -638,6 +714,24 @@ namespace __gnu_debug if (_M_local_iterators == __it) _M_local_iterators = __it->_M_next; } + +#if !_GLIBCXX_INLINE_VERSION + void + _Safe_unordered_container_base:: + _M_detach_all() + { + const _Safe_unordered_container_base* __this = this; + __this->_M_detach_all(); + } + + void + _Safe_unordered_container_base:: + _M_swap(_Safe_unordered_container_base& __x) noexcept + { + const _Safe_unordered_container_base* __this = this; + __this->_M_swap(__x); + } +#endif } namespace diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc index 34df909b31a2..1056e646b12c 100644 --- a/libstdc++-v3/src/c++11/string-inst.cc +++ b/libstdc++-v3/src/c++11/string-inst.cc @@ -119,14 +119,3 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION } // namespace - -namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) -{ -_GLIBCXX_BEGIN_NAMESPACE_VERSION - - using std::S; - template bool operator==(const S::iterator&, const S::iterator&); - template bool operator==(const S::const_iterator&, const S::const_iterator&); - -_GLIBCXX_END_NAMESPACE_VERSION -} // namespace diff --git a/libstdc++-v3/src/c++17/memory_resource.cc b/libstdc++-v3/src/c++17/memory_resource.cc index fac4c782c5f7..c61569f249ad 100644 --- a/libstdc++-v3/src/c++17/memory_resource.cc +++ b/libstdc++-v3/src/c++17/memory_resource.cc @@ -182,8 +182,8 @@ namespace pmr // versions will not use this symbol. monotonic_buffer_resource::~monotonic_buffer_resource() { release(); } - namespace { - +namespace +{ // aligned_size stores the size and alignment of a memory allocation. // The size must be a multiple of N, leaving the low log2(N) bits free // to store the base-2 logarithm of the alignment. @@ -221,7 +221,7 @@ namespace pmr return (n + alignment - 1) & ~(alignment - 1); } - } // namespace +} // namespace // Memory allocated by the upstream resource is managed in a linked list // of _Chunk objects. A _Chunk object recording the size and alignment of @@ -307,8 +307,8 @@ namespace pmr // Helper types for synchronized_pool_resource & unsynchronized_pool_resource - namespace { - +namespace +{ // Simple bitset with runtime size. // Tracks which blocks in a pool chunk are used/unused. struct bitset @@ -636,7 +636,7 @@ namespace pmr static_assert(sizeof(big_block) == (2 * sizeof(void*))); - } // namespace +} // namespace // A pool that serves blocks of a particular size. // Each pool manages a number of chunks. @@ -868,7 +868,16 @@ namespace pmr using big_block::big_block; }; - namespace { +namespace +{ + // N.B. it is important that we don't skip any power of two sizes if there + // is a non-power of two size between them, e.g. must not have pool sizes + // of 24 and 40 without having a pool size of 32. Otherwise an allocation + // of 32 bytes with alignment 16 would choose the 40-byte pool which is not + // correctly aligned for 16-byte alignment. It would be OK (but suboptimal) + // to have no pool of size 32 if we have pool sizes of 16 and 64 and no + // non-power of two sizes between those, because the example of (32, 16) + // would choose the 64-byte pool, which would be correctly aligned. constexpr size_t pool_sizes[] = { 8, 16, 24, @@ -983,7 +992,7 @@ namespace pmr using exclusive_lock = lock_guard; #endif - } // namespace +} // namespace __pool_resource:: __pool_resource(const pool_options& opts, memory_resource* upstream) @@ -1075,12 +1084,33 @@ namespace pmr return p; } + // Determine the appropriate allocation size, rounding up to a multiple + // of the alignment if needed. + static inline size_t + choose_block_size(size_t bytes, size_t alignment) + { + if (bytes == 0) [[unlikely]] + return alignment; + + // Use bit_ceil in case alignment is invalid (i.e. not a power of two). + size_t mask = std::__bit_ceil(alignment) - 1; + // Round up to a multiple of alignment. + size_t block_size = (bytes + mask) & ~mask; + + if (block_size >= bytes) [[likely]] + return block_size; + + // Wrapped around to zero, bytes must have been impossibly large. + return numeric_limits::max(); + } + + #ifdef _GLIBCXX_HAS_GTHREADS // synchronized_pool_resource members. /* Notes on implementation and thread safety: * - * Each synchronized_pool_resource manages an linked list of N+1 _TPools + * Each synchronized_pool_resource manages a linked list of N+1 _TPools * objects, where N is the number of threads using the pool resource. * Each _TPools object has its own set of pools, with their own chunks. * The first element of the list, _M_tpools[0], can be used by any thread. @@ -1247,7 +1277,7 @@ namespace pmr synchronized_pool_resource:: do_allocate(size_t bytes, size_t alignment) { - const auto block_size = std::max(bytes, alignment); + const auto block_size = choose_block_size(bytes, alignment); const pool_options opts = _M_impl._M_opts; if (block_size <= opts.largest_required_pool_block) { @@ -1294,7 +1324,7 @@ namespace pmr synchronized_pool_resource:: do_deallocate(void* p, size_t bytes, size_t alignment) { - size_t block_size = std::max(bytes, alignment); + size_t block_size = choose_block_size(bytes, alignment); if (block_size <= _M_impl._M_opts.largest_required_pool_block) { const ptrdiff_t index = pool_index(block_size, _M_impl._M_npools); @@ -1453,7 +1483,7 @@ namespace pmr void* unsynchronized_pool_resource::do_allocate(size_t bytes, size_t alignment) { - const auto block_size = std::max(bytes, alignment); + const auto block_size = choose_block_size(bytes, alignment); if (block_size <= _M_impl._M_opts.largest_required_pool_block) { // Recreate pools if release() has been called: @@ -1470,7 +1500,7 @@ namespace pmr unsynchronized_pool_resource:: do_deallocate(void* p, size_t bytes, size_t alignment) { - size_t block_size = std::max(bytes, alignment); + size_t block_size = choose_block_size(bytes, alignment); if (block_size <= _M_impl._M_opts.largest_required_pool_block) { if (auto pool = _M_find_pool(block_size)) diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc index 6e244dc656d8..d79b61ad673f 100644 --- a/libstdc++-v3/src/c++20/tzdb.cc +++ b/libstdc++-v3/src/c++20/tzdb.cc @@ -44,6 +44,14 @@ # include // getenv #endif +#if _GLIBCXX_HAVE_WINDOWS_H +# define WIN32_LEAN_AND_MEAN +# include +# include + +# include +#endif + #if defined __GTHREADS && ATOMIC_POINTER_LOCK_FREE == 2 # define USE_ATOMIC_LIST_HEAD 1 // TODO benchmark atomic> vs mutex. @@ -1144,6 +1152,34 @@ namespace std::chrono #ifdef _GLIBCXX_ZONEINFO_DIR else path = _GLIBCXX_ZONEINFO_DIR; +#endif +#ifdef _GLIBCXX_HAVE_WINDOWS_H + if (path.empty()) + { + HMODULE dll_module; + if (GetModuleHandleExA( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS + | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + reinterpret_cast(&zoneinfo_file), &dll_module)) + { + char dll_path[MAX_PATH]; + if (GetModuleFileNameA(dll_module, dll_path, MAX_PATH) != 0) + { + string_view dll_path_view = dll_path; + auto pos = dll_path_view.find_last_of('\\'); + dll_path_view = dll_path_view.substr(0, pos); + if (dll_path_view.ends_with("\\bin")) + { + constexpr string_view remaining_path = "share\\zoneinfo"; + dll_path_view.remove_suffix(3); // Remove bin + path.reserve(dll_path_view.size() + + remaining_path.size()); + path = dll_path_view; + path += remaining_path; + } + } + } + } #endif if (!path.empty()) path.append(filename); @@ -1734,6 +1770,98 @@ namespace std::chrono return nullptr; // not found } + +#ifdef _GLIBCXX_HAVE_WINDOWS_H + string_view + detect_windows_zone() noexcept + { + DYNAMIC_TIME_ZONE_INFORMATION information{}; + if (GetDynamicTimeZoneInformation(&information) == TIME_ZONE_ID_INVALID) + return {}; + + constexpr SYSTEMTIME all_zero_time{}; + const wstring_view zone_name{ information.TimeZoneKeyName }; + auto equal = [](const SYSTEMTIME &lhs, const SYSTEMTIME &rhs) noexcept + { return memcmp(&lhs, &rhs, sizeof(SYSTEMTIME)) == 0; }; + // The logic is copied from icu, couldn't find the source. + // Detect if DST is disabled. + if (information.DynamicDaylightTimeDisabled + && equal(information.StandardDate, information.DaylightDate) + && ((!zone_name.empty() + && equal(information.StandardDate, all_zero_time)) + || (zone_name.empty() + && !equal(information.StandardDate, all_zero_time)))) + { + if (information.Bias == 0) + return "Etc/UTC"; + + if (information.Bias % 60 != 0) + // If the offset is not in full hours, we can't do anything really. + return {}; + + const auto raw_index = information.Bias / 60; + + // The bias added to the local time equals UTC. And GMT+X corresponds + // to UTC-X, the sign is negated. Thus we can use the hourly bias as + // an index into an array. + if (raw_index < 0 && raw_index >= -14) + { + static constexpr array table{ + "Etc/GMT-1", "Etc/GMT-2", "Etc/GMT-3", "Etc/GMT-4", + "Etc/GMT-5", "Etc/GMT-6", "Etc/GMT-7", "Etc/GMT-8", + "Etc/GMT-9", "Etc/GMT-10", "Etc/GMT-11", "Etc/GMT-12", + "Etc/GMT-13", "Etc/GMT-14" + }; + return table[-raw_index - 1]; + } + else if (raw_index > 0 && raw_index <= 12) + { + static constexpr array table{ + "Etc/GMT+1", "Etc/GMT+2", "Etc/GMT+3", "Etc/GMT+4", + "Etc/GMT+5", "Etc/GMT+6", "Etc/GMT+7", "Etc/GMT+8", + "Etc/GMT+9", "Etc/GMT+10", "Etc/GMT+11", "Etc/GMT+12" + }; + return table[raw_index - 1]; + } + return {}; + } + +#include "windows_zones-map.h" +#ifndef _GLIBCXX_WINDOWS_ZONES_MAP_COMPLETE +# error "Invalid windows_zones map" +#endif + + const auto zone_range + = ranges::equal_range(windows_zone_map, zone_name, {}, + &windows_zone_map_entry::windows_name); + + const auto size = ranges::size(zone_range); + if (size == 0) + // Unknown zone, we can't detect anything. + return {}; + + if (size == 1) + // Some zones have only one territory, use the quick path. + return zone_range.front().iana_name; + + const auto geo_id = GetUserGeoID(GEOCLASS_NATION); + // We ask for a 2-letter country code plus the zero terminator. "001" is + // only contained in the zone map, not returned by GetGeoInfoW. + wchar_t territory[3] = {}; + if (GetGeoInfoW(geo_id, GEO_ISO2, territory, 3, 0) == 0) + // Couldn't detect the territory, fallback to "001", which is the first + // entry. + return zone_range.front().iana_name; + + const auto iter = ranges::lower_bound( + zone_range, territory, {}, &windows_zone_map_entry::territory); + if (iter == zone_range.end() || iter->territory != territory) + // Territory not within the the map, use "001". + return zone_range.front().iana_name; + + return iter->iana_name; + } +#endif } // namespace // Implementation of std::chrono::tzdb::locate_zone(string_view). @@ -1756,7 +1884,7 @@ namespace std::chrono { // TODO cache this function's result? -#ifndef _AIX +#if !defined(_AIX) && !defined(_GLIBCXX_HAVE_WINDOWS_H) // Repeat the preprocessor condition used by filesystem::read_symlink, // to avoid a dependency on src/c++17/fs_ops.o if it won't work anyway. #if defined(_GLIBCXX_HAVE_READLINK) && defined(_GLIBCXX_HAVE_SYS_STAT_H) @@ -1813,7 +1941,11 @@ namespace std::chrono return tz; } } -#else +#elif defined(_GLIBCXX_HAVE_WINDOWS_H) + if (auto tz + = do_locate_zone(this->zones, this->links, detect_windows_zone())) + return tz; +#else // defined(_AIX) // AIX stores current zone in $TZ in /etc/environment but the value // is typically a POSIX time zone name, not IANA zone. // https://developer.ibm.com/articles/au-aix-posix/ diff --git a/libstdc++-v3/src/c++20/windows_zones-map.h b/libstdc++-v3/src/c++20/windows_zones-map.h new file mode 100644 index 000000000000..0f63a1756fb6 --- /dev/null +++ b/libstdc++-v3/src/c++20/windows_zones-map.h @@ -0,0 +1,399 @@ +// Generated by scripts/gen_windows_zones_map.py, do not edit. + +// Copyright The GNU Toolchain Authors. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + + +struct windows_zone_map_entry +{ + wstring_view windows_name; + wstring_view territory; + string_view iana_name; +}; + +static constexpr array windows_zone_map{ + { + {L"AUS Central Standard Time", L"001", "Australia/Darwin"}, + {L"AUS Eastern Standard Time", L"001", "Australia/Sydney"}, + {L"Afghanistan Standard Time", L"001", "Asia/Kabul"}, + {L"Alaskan Standard Time", L"001", "America/Anchorage"}, + {L"Aleutian Standard Time", L"001", "America/Adak"}, + {L"Altai Standard Time", L"001", "Asia/Barnaul"}, + {L"Arab Standard Time", L"001", "Asia/Riyadh"}, + {L"Arab Standard Time", L"BH", "Asia/Bahrain"}, + {L"Arab Standard Time", L"KW", "Asia/Kuwait"}, + {L"Arab Standard Time", L"QA", "Asia/Qatar"}, + {L"Arab Standard Time", L"YE", "Asia/Aden"}, + {L"Arabian Standard Time", L"001", "Asia/Dubai"}, + {L"Arabian Standard Time", L"OM", "Asia/Muscat"}, + {L"Arabian Standard Time", L"ZZ", "Etc/GMT-4"}, + {L"Arabic Standard Time", L"001", "Asia/Baghdad"}, + {L"Argentina Standard Time", L"001", "America/Buenos_Aires"}, + {L"Astrakhan Standard Time", L"001", "Europe/Astrakhan"}, + {L"Atlantic Standard Time", L"001", "America/Halifax"}, + {L"Atlantic Standard Time", L"BM", "Atlantic/Bermuda"}, + {L"Atlantic Standard Time", L"GL", "America/Thule"}, + {L"Aus Central W. Standard Time", L"001", "Australia/Eucla"}, + {L"Azerbaijan Standard Time", L"001", "Asia/Baku"}, + {L"Azores Standard Time", L"001", "Atlantic/Azores"}, + {L"Azores Standard Time", L"GL", "America/Scoresbysund"}, + {L"Bahia Standard Time", L"001", "America/Bahia"}, + {L"Bangladesh Standard Time", L"001", "Asia/Dhaka"}, + {L"Bangladesh Standard Time", L"BT", "Asia/Thimphu"}, + {L"Belarus Standard Time", L"001", "Europe/Minsk"}, + {L"Bougainville Standard Time", L"001", "Pacific/Bougainville"}, + {L"Canada Central Standard Time", L"001", "America/Regina"}, + {L"Cape Verde Standard Time", L"001", "Atlantic/Cape_Verde"}, + {L"Cape Verde Standard Time", L"ZZ", "Etc/GMT+1"}, + {L"Caucasus Standard Time", L"001", "Asia/Yerevan"}, + {L"Cen. Australia Standard Time", L"001", "Australia/Adelaide"}, + {L"Central America Standard Time", L"001", "America/Guatemala"}, + {L"Central America Standard Time", L"BZ", "America/Belize"}, + {L"Central America Standard Time", L"CR", "America/Costa_Rica"}, + {L"Central America Standard Time", L"EC", "Pacific/Galapagos"}, + {L"Central America Standard Time", L"HN", "America/Tegucigalpa"}, + {L"Central America Standard Time", L"NI", "America/Managua"}, + {L"Central America Standard Time", L"SV", "America/El_Salvador"}, + {L"Central America Standard Time", L"ZZ", "Etc/GMT+6"}, + {L"Central Asia Standard Time", L"001", "Asia/Bishkek"}, + {L"Central Asia Standard Time", L"AQ", "Antarctica/Vostok"}, + {L"Central Asia Standard Time", L"CN", "Asia/Urumqi"}, + {L"Central Asia Standard Time", L"IO", "Indian/Chagos"}, + {L"Central Asia Standard Time", L"ZZ", "Etc/GMT-6"}, + {L"Central Brazilian Standard Time", L"001", "America/Cuiaba"}, + {L"Central Europe Standard Time", L"001", "Europe/Budapest"}, + {L"Central Europe Standard Time", L"AL", "Europe/Tirane"}, + {L"Central Europe Standard Time", L"CZ", "Europe/Prague"}, + {L"Central Europe Standard Time", L"ME", "Europe/Podgorica"}, + {L"Central Europe Standard Time", L"RS", "Europe/Belgrade"}, + {L"Central Europe Standard Time", L"SI", "Europe/Ljubljana"}, + {L"Central Europe Standard Time", L"SK", "Europe/Bratislava"}, + {L"Central European Standard Time", L"001", "Europe/Warsaw"}, + {L"Central European Standard Time", L"BA", "Europe/Sarajevo"}, + {L"Central European Standard Time", L"HR", "Europe/Zagreb"}, + {L"Central European Standard Time", L"MK", "Europe/Skopje"}, + {L"Central Pacific Standard Time", L"001", "Pacific/Guadalcanal"}, + {L"Central Pacific Standard Time", L"AQ", "Antarctica/Casey"}, + {L"Central Pacific Standard Time", L"FM", "Pacific/Ponape"}, + {L"Central Pacific Standard Time", L"NC", "Pacific/Noumea"}, + {L"Central Pacific Standard Time", L"VU", "Pacific/Efate"}, + {L"Central Pacific Standard Time", L"ZZ", "Etc/GMT-11"}, + {L"Central Standard Time", L"001", "America/Chicago"}, + {L"Central Standard Time", L"CA", "America/Winnipeg"}, + {L"Central Standard Time", L"MX", "America/Matamoros"}, + {L"Central Standard Time (Mexico)", L"001", "America/Mexico_City"}, + {L"Chatham Islands Standard Time", L"001", "Pacific/Chatham"}, + {L"China Standard Time", L"001", "Asia/Shanghai"}, + {L"China Standard Time", L"HK", "Asia/Hong_Kong"}, + {L"China Standard Time", L"MO", "Asia/Macau"}, + {L"Cuba Standard Time", L"001", "America/Havana"}, + {L"Dateline Standard Time", L"001", "Etc/GMT+12"}, + {L"E. Africa Standard Time", L"001", "Africa/Nairobi"}, + {L"E. Africa Standard Time", L"AQ", "Antarctica/Syowa"}, + {L"E. Africa Standard Time", L"DJ", "Africa/Djibouti"}, + {L"E. Africa Standard Time", L"ER", "Africa/Asmera"}, + {L"E. Africa Standard Time", L"ET", "Africa/Addis_Ababa"}, + {L"E. Africa Standard Time", L"KM", "Indian/Comoro"}, + {L"E. Africa Standard Time", L"MG", "Indian/Antananarivo"}, + {L"E. Africa Standard Time", L"SO", "Africa/Mogadishu"}, + {L"E. Africa Standard Time", L"TZ", "Africa/Dar_es_Salaam"}, + {L"E. Africa Standard Time", L"UG", "Africa/Kampala"}, + {L"E. Africa Standard Time", L"YT", "Indian/Mayotte"}, + {L"E. Africa Standard Time", L"ZZ", "Etc/GMT-3"}, + {L"E. Australia Standard Time", L"001", "Australia/Brisbane"}, + {L"E. Europe Standard Time", L"001", "Europe/Chisinau"}, + {L"E. South America Standard Time", L"001", "America/Sao_Paulo"}, + {L"Easter Island Standard Time", L"001", "Pacific/Easter"}, + {L"Eastern Standard Time", L"001", "America/New_York"}, + {L"Eastern Standard Time", L"BS", "America/Nassau"}, + {L"Eastern Standard Time", L"CA", "America/Toronto"}, + {L"Eastern Standard Time (Mexico)", L"001", "America/Cancun"}, + {L"Egypt Standard Time", L"001", "Africa/Cairo"}, + {L"Ekaterinburg Standard Time", L"001", "Asia/Yekaterinburg"}, + {L"FLE Standard Time", L"001", "Europe/Kiev"}, + {L"FLE Standard Time", L"AX", "Europe/Mariehamn"}, + {L"FLE Standard Time", L"BG", "Europe/Sofia"}, + {L"FLE Standard Time", L"EE", "Europe/Tallinn"}, + {L"FLE Standard Time", L"FI", "Europe/Helsinki"}, + {L"FLE Standard Time", L"LT", "Europe/Vilnius"}, + {L"FLE Standard Time", L"LV", "Europe/Riga"}, + {L"Fiji Standard Time", L"001", "Pacific/Fiji"}, + {L"GMT Standard Time", L"001", "Europe/London"}, + {L"GMT Standard Time", L"ES", "Atlantic/Canary"}, + {L"GMT Standard Time", L"FO", "Atlantic/Faeroe"}, + {L"GMT Standard Time", L"GG", "Europe/Guernsey"}, + {L"GMT Standard Time", L"IE", "Europe/Dublin"}, + {L"GMT Standard Time", L"IM", "Europe/Isle_of_Man"}, + {L"GMT Standard Time", L"JE", "Europe/Jersey"}, + {L"GMT Standard Time", L"PT", "Europe/Lisbon"}, + {L"GTB Standard Time", L"001", "Europe/Bucharest"}, + {L"GTB Standard Time", L"CY", "Asia/Nicosia"}, + {L"GTB Standard Time", L"GR", "Europe/Athens"}, + {L"Georgian Standard Time", L"001", "Asia/Tbilisi"}, + {L"Greenland Standard Time", L"001", "America/Godthab"}, + {L"Greenwich Standard Time", L"001", "Atlantic/Reykjavik"}, + {L"Greenwich Standard Time", L"BF", "Africa/Ouagadougou"}, + {L"Greenwich Standard Time", L"CI", "Africa/Abidjan"}, + {L"Greenwich Standard Time", L"GH", "Africa/Accra"}, + {L"Greenwich Standard Time", L"GL", "America/Danmarkshavn"}, + {L"Greenwich Standard Time", L"GM", "Africa/Banjul"}, + {L"Greenwich Standard Time", L"GN", "Africa/Conakry"}, + {L"Greenwich Standard Time", L"GW", "Africa/Bissau"}, + {L"Greenwich Standard Time", L"LR", "Africa/Monrovia"}, + {L"Greenwich Standard Time", L"ML", "Africa/Bamako"}, + {L"Greenwich Standard Time", L"MR", "Africa/Nouakchott"}, + {L"Greenwich Standard Time", L"SH", "Atlantic/St_Helena"}, + {L"Greenwich Standard Time", L"SL", "Africa/Freetown"}, + {L"Greenwich Standard Time", L"SN", "Africa/Dakar"}, + {L"Greenwich Standard Time", L"TG", "Africa/Lome"}, + {L"Haiti Standard Time", L"001", "America/Port-au-Prince"}, + {L"Hawaiian Standard Time", L"001", "Pacific/Honolulu"}, + {L"Hawaiian Standard Time", L"CK", "Pacific/Rarotonga"}, + {L"Hawaiian Standard Time", L"PF", "Pacific/Tahiti"}, + {L"Hawaiian Standard Time", L"ZZ", "Etc/GMT+10"}, + {L"India Standard Time", L"001", "Asia/Calcutta"}, + {L"Iran Standard Time", L"001", "Asia/Tehran"}, + {L"Israel Standard Time", L"001", "Asia/Jerusalem"}, + {L"Jordan Standard Time", L"001", "Asia/Amman"}, + {L"Kaliningrad Standard Time", L"001", "Europe/Kaliningrad"}, + {L"Korea Standard Time", L"001", "Asia/Seoul"}, + {L"Libya Standard Time", L"001", "Africa/Tripoli"}, + {L"Line Islands Standard Time", L"001", "Pacific/Kiritimati"}, + {L"Line Islands Standard Time", L"ZZ", "Etc/GMT-14"}, + {L"Lord Howe Standard Time", L"001", "Australia/Lord_Howe"}, + {L"Magadan Standard Time", L"001", "Asia/Magadan"}, + {L"Magallanes Standard Time", L"001", "America/Punta_Arenas"}, + {L"Marquesas Standard Time", L"001", "Pacific/Marquesas"}, + {L"Mauritius Standard Time", L"001", "Indian/Mauritius"}, + {L"Mauritius Standard Time", L"RE", "Indian/Reunion"}, + {L"Mauritius Standard Time", L"SC", "Indian/Mahe"}, + {L"Middle East Standard Time", L"001", "Asia/Beirut"}, + {L"Montevideo Standard Time", L"001", "America/Montevideo"}, + {L"Morocco Standard Time", L"001", "Africa/Casablanca"}, + {L"Morocco Standard Time", L"EH", "Africa/El_Aaiun"}, + {L"Mountain Standard Time", L"001", "America/Denver"}, + {L"Mountain Standard Time", L"CA", "America/Edmonton"}, + {L"Mountain Standard Time", L"MX", "America/Ciudad_Juarez"}, + {L"Mountain Standard Time (Mexico)", L"001", "America/Mazatlan"}, + {L"Myanmar Standard Time", L"001", "Asia/Rangoon"}, + {L"Myanmar Standard Time", L"CC", "Indian/Cocos"}, + {L"N. Central Asia Standard Time", L"001", "Asia/Novosibirsk"}, + {L"Namibia Standard Time", L"001", "Africa/Windhoek"}, + {L"Nepal Standard Time", L"001", "Asia/Katmandu"}, + {L"New Zealand Standard Time", L"001", "Pacific/Auckland"}, + {L"New Zealand Standard Time", L"AQ", "Antarctica/McMurdo"}, + {L"Newfoundland Standard Time", L"001", "America/St_Johns"}, + {L"Norfolk Standard Time", L"001", "Pacific/Norfolk"}, + {L"North Asia East Standard Time", L"001", "Asia/Irkutsk"}, + {L"North Asia Standard Time", L"001", "Asia/Krasnoyarsk"}, + {L"North Korea Standard Time", L"001", "Asia/Pyongyang"}, + {L"Omsk Standard Time", L"001", "Asia/Omsk"}, + {L"Pacific SA Standard Time", L"001", "America/Santiago"}, + {L"Pacific Standard Time", L"001", "America/Los_Angeles"}, + {L"Pacific Standard Time", L"CA", "America/Vancouver"}, + {L"Pacific Standard Time (Mexico)", L"001", "America/Tijuana"}, + {L"Pakistan Standard Time", L"001", "Asia/Karachi"}, + {L"Paraguay Standard Time", L"001", "America/Asuncion"}, + {L"Qyzylorda Standard Time", L"001", "Asia/Qyzylorda"}, + {L"Romance Standard Time", L"001", "Europe/Paris"}, + {L"Romance Standard Time", L"BE", "Europe/Brussels"}, + {L"Romance Standard Time", L"DK", "Europe/Copenhagen"}, + {L"Romance Standard Time", L"ES", "Europe/Madrid"}, + {L"Russia Time Zone 10", L"001", "Asia/Srednekolymsk"}, + {L"Russia Time Zone 11", L"001", "Asia/Kamchatka"}, + {L"Russia Time Zone 3", L"001", "Europe/Samara"}, + {L"Russian Standard Time", L"001", "Europe/Moscow"}, + {L"Russian Standard Time", L"UA", "Europe/Simferopol"}, + {L"SA Eastern Standard Time", L"001", "America/Cayenne"}, + {L"SA Eastern Standard Time", L"AQ", "Antarctica/Rothera"}, + {L"SA Eastern Standard Time", L"BR", "America/Fortaleza"}, + {L"SA Eastern Standard Time", L"FK", "Atlantic/Stanley"}, + {L"SA Eastern Standard Time", L"SR", "America/Paramaribo"}, + {L"SA Eastern Standard Time", L"ZZ", "Etc/GMT+3"}, + {L"SA Pacific Standard Time", L"001", "America/Bogota"}, + {L"SA Pacific Standard Time", L"BR", "America/Rio_Branco"}, + {L"SA Pacific Standard Time", L"CA", "America/Coral_Harbour"}, + {L"SA Pacific Standard Time", L"EC", "America/Guayaquil"}, + {L"SA Pacific Standard Time", L"JM", "America/Jamaica"}, + {L"SA Pacific Standard Time", L"KY", "America/Cayman"}, + {L"SA Pacific Standard Time", L"PA", "America/Panama"}, + {L"SA Pacific Standard Time", L"PE", "America/Lima"}, + {L"SA Pacific Standard Time", L"ZZ", "Etc/GMT+5"}, + {L"SA Western Standard Time", L"001", "America/La_Paz"}, + {L"SA Western Standard Time", L"AG", "America/Antigua"}, + {L"SA Western Standard Time", L"AI", "America/Anguilla"}, + {L"SA Western Standard Time", L"AW", "America/Aruba"}, + {L"SA Western Standard Time", L"BB", "America/Barbados"}, + {L"SA Western Standard Time", L"BL", "America/St_Barthelemy"}, + {L"SA Western Standard Time", L"BQ", "America/Kralendijk"}, + {L"SA Western Standard Time", L"BR", "America/Manaus"}, + {L"SA Western Standard Time", L"CA", "America/Blanc-Sablon"}, + {L"SA Western Standard Time", L"CW", "America/Curacao"}, + {L"SA Western Standard Time", L"DM", "America/Dominica"}, + {L"SA Western Standard Time", L"DO", "America/Santo_Domingo"}, + {L"SA Western Standard Time", L"GD", "America/Grenada"}, + {L"SA Western Standard Time", L"GP", "America/Guadeloupe"}, + {L"SA Western Standard Time", L"GY", "America/Guyana"}, + {L"SA Western Standard Time", L"KN", "America/St_Kitts"}, + {L"SA Western Standard Time", L"LC", "America/St_Lucia"}, + {L"SA Western Standard Time", L"MF", "America/Marigot"}, + {L"SA Western Standard Time", L"MQ", "America/Martinique"}, + {L"SA Western Standard Time", L"MS", "America/Montserrat"}, + {L"SA Western Standard Time", L"PR", "America/Puerto_Rico"}, + {L"SA Western Standard Time", L"SX", "America/Lower_Princes"}, + {L"SA Western Standard Time", L"TT", "America/Port_of_Spain"}, + {L"SA Western Standard Time", L"VC", "America/St_Vincent"}, + {L"SA Western Standard Time", L"VG", "America/Tortola"}, + {L"SA Western Standard Time", L"VI", "America/St_Thomas"}, + {L"SA Western Standard Time", L"ZZ", "Etc/GMT+4"}, + {L"SE Asia Standard Time", L"001", "Asia/Bangkok"}, + {L"SE Asia Standard Time", L"AQ", "Antarctica/Davis"}, + {L"SE Asia Standard Time", L"CX", "Indian/Christmas"}, + {L"SE Asia Standard Time", L"ID", "Asia/Jakarta"}, + {L"SE Asia Standard Time", L"KH", "Asia/Phnom_Penh"}, + {L"SE Asia Standard Time", L"LA", "Asia/Vientiane"}, + {L"SE Asia Standard Time", L"VN", "Asia/Saigon"}, + {L"SE Asia Standard Time", L"ZZ", "Etc/GMT-7"}, + {L"Saint Pierre Standard Time", L"001", "America/Miquelon"}, + {L"Sakhalin Standard Time", L"001", "Asia/Sakhalin"}, + {L"Samoa Standard Time", L"001", "Pacific/Apia"}, + {L"Sao Tome Standard Time", L"001", "Africa/Sao_Tome"}, + {L"Saratov Standard Time", L"001", "Europe/Saratov"}, + {L"Singapore Standard Time", L"001", "Asia/Singapore"}, + {L"Singapore Standard Time", L"BN", "Asia/Brunei"}, + {L"Singapore Standard Time", L"ID", "Asia/Makassar"}, + {L"Singapore Standard Time", L"MY", "Asia/Kuala_Lumpur"}, + {L"Singapore Standard Time", L"PH", "Asia/Manila"}, + {L"Singapore Standard Time", L"ZZ", "Etc/GMT-8"}, + {L"South Africa Standard Time", L"001", "Africa/Johannesburg"}, + {L"South Africa Standard Time", L"BI", "Africa/Bujumbura"}, + {L"South Africa Standard Time", L"BW", "Africa/Gaborone"}, + {L"South Africa Standard Time", L"CD", "Africa/Lubumbashi"}, + {L"South Africa Standard Time", L"LS", "Africa/Maseru"}, + {L"South Africa Standard Time", L"MW", "Africa/Blantyre"}, + {L"South Africa Standard Time", L"MZ", "Africa/Maputo"}, + {L"South Africa Standard Time", L"RW", "Africa/Kigali"}, + {L"South Africa Standard Time", L"SZ", "Africa/Mbabane"}, + {L"South Africa Standard Time", L"ZM", "Africa/Lusaka"}, + {L"South Africa Standard Time", L"ZW", "Africa/Harare"}, + {L"South Africa Standard Time", L"ZZ", "Etc/GMT-2"}, + {L"South Sudan Standard Time", L"001", "Africa/Juba"}, + {L"Sri Lanka Standard Time", L"001", "Asia/Colombo"}, + {L"Sudan Standard Time", L"001", "Africa/Khartoum"}, + {L"Syria Standard Time", L"001", "Asia/Damascus"}, + {L"Taipei Standard Time", L"001", "Asia/Taipei"}, + {L"Tasmania Standard Time", L"001", "Australia/Hobart"}, + {L"Tocantins Standard Time", L"001", "America/Araguaina"}, + {L"Tokyo Standard Time", L"001", "Asia/Tokyo"}, + {L"Tokyo Standard Time", L"ID", "Asia/Jayapura"}, + {L"Tokyo Standard Time", L"PW", "Pacific/Palau"}, + {L"Tokyo Standard Time", L"TL", "Asia/Dili"}, + {L"Tokyo Standard Time", L"ZZ", "Etc/GMT-9"}, + {L"Tomsk Standard Time", L"001", "Asia/Tomsk"}, + {L"Tonga Standard Time", L"001", "Pacific/Tongatapu"}, + {L"Transbaikal Standard Time", L"001", "Asia/Chita"}, + {L"Turkey Standard Time", L"001", "Europe/Istanbul"}, + {L"Turks And Caicos Standard Time", L"001", "America/Grand_Turk"}, + {L"US Eastern Standard Time", L"001", "America/Indianapolis"}, + {L"US Mountain Standard Time", L"001", "America/Phoenix"}, + {L"US Mountain Standard Time", L"CA", "America/Creston"}, + {L"US Mountain Standard Time", L"MX", "America/Hermosillo"}, + {L"US Mountain Standard Time", L"ZZ", "Etc/GMT+7"}, + {L"UTC", L"001", "Etc/UTC"}, + {L"UTC+12", L"001", "Etc/GMT-12"}, + {L"UTC+12", L"KI", "Pacific/Tarawa"}, + {L"UTC+12", L"MH", "Pacific/Majuro"}, + {L"UTC+12", L"NR", "Pacific/Nauru"}, + {L"UTC+12", L"TV", "Pacific/Funafuti"}, + {L"UTC+12", L"UM", "Pacific/Wake"}, + {L"UTC+12", L"WF", "Pacific/Wallis"}, + {L"UTC+13", L"001", "Etc/GMT-13"}, + {L"UTC+13", L"KI", "Pacific/Enderbury"}, + {L"UTC+13", L"TK", "Pacific/Fakaofo"}, + {L"UTC-02", L"001", "Etc/GMT+2"}, + {L"UTC-02", L"BR", "America/Noronha"}, + {L"UTC-02", L"GS", "Atlantic/South_Georgia"}, + {L"UTC-08", L"001", "Etc/GMT+8"}, + {L"UTC-08", L"PN", "Pacific/Pitcairn"}, + {L"UTC-09", L"001", "Etc/GMT+9"}, + {L"UTC-09", L"PF", "Pacific/Gambier"}, + {L"UTC-11", L"001", "Etc/GMT+11"}, + {L"UTC-11", L"AS", "Pacific/Pago_Pago"}, + {L"UTC-11", L"NU", "Pacific/Niue"}, + {L"UTC-11", L"UM", "Pacific/Midway"}, + {L"Ulaanbaatar Standard Time", L"001", "Asia/Ulaanbaatar"}, + {L"Venezuela Standard Time", L"001", "America/Caracas"}, + {L"Vladivostok Standard Time", L"001", "Asia/Vladivostok"}, + {L"Volgograd Standard Time", L"001", "Europe/Volgograd"}, + {L"W. Australia Standard Time", L"001", "Australia/Perth"}, + {L"W. Central Africa Standard Time", L"001", "Africa/Lagos"}, + {L"W. Central Africa Standard Time", L"AO", "Africa/Luanda"}, + {L"W. Central Africa Standard Time", L"BJ", "Africa/Porto-Novo"}, + {L"W. Central Africa Standard Time", L"CD", "Africa/Kinshasa"}, + {L"W. Central Africa Standard Time", L"CF", "Africa/Bangui"}, + {L"W. Central Africa Standard Time", L"CG", "Africa/Brazzaville"}, + {L"W. Central Africa Standard Time", L"CM", "Africa/Douala"}, + {L"W. Central Africa Standard Time", L"DZ", "Africa/Algiers"}, + {L"W. Central Africa Standard Time", L"GA", "Africa/Libreville"}, + {L"W. Central Africa Standard Time", L"GQ", "Africa/Malabo"}, + {L"W. Central Africa Standard Time", L"NE", "Africa/Niamey"}, + {L"W. Central Africa Standard Time", L"TD", "Africa/Ndjamena"}, + {L"W. Central Africa Standard Time", L"TN", "Africa/Tunis"}, + {L"W. Central Africa Standard Time", L"ZZ", "Etc/GMT-1"}, + {L"W. Europe Standard Time", L"001", "Europe/Berlin"}, + {L"W. Europe Standard Time", L"AD", "Europe/Andorra"}, + {L"W. Europe Standard Time", L"AT", "Europe/Vienna"}, + {L"W. Europe Standard Time", L"CH", "Europe/Zurich"}, + {L"W. Europe Standard Time", L"GI", "Europe/Gibraltar"}, + {L"W. Europe Standard Time", L"IT", "Europe/Rome"}, + {L"W. Europe Standard Time", L"LI", "Europe/Vaduz"}, + {L"W. Europe Standard Time", L"LU", "Europe/Luxembourg"}, + {L"W. Europe Standard Time", L"MC", "Europe/Monaco"}, + {L"W. Europe Standard Time", L"MT", "Europe/Malta"}, + {L"W. Europe Standard Time", L"NL", "Europe/Amsterdam"}, + {L"W. Europe Standard Time", L"NO", "Europe/Oslo"}, + {L"W. Europe Standard Time", L"SE", "Europe/Stockholm"}, + {L"W. Europe Standard Time", L"SJ", "Arctic/Longyearbyen"}, + {L"W. Europe Standard Time", L"SM", "Europe/San_Marino"}, + {L"W. Europe Standard Time", L"VA", "Europe/Vatican"}, + {L"W. Mongolia Standard Time", L"001", "Asia/Hovd"}, + {L"West Asia Standard Time", L"001", "Asia/Tashkent"}, + {L"West Asia Standard Time", L"AQ", "Antarctica/Mawson"}, + {L"West Asia Standard Time", L"KZ", "Asia/Oral"}, + {L"West Asia Standard Time", L"MV", "Indian/Maldives"}, + {L"West Asia Standard Time", L"TF", "Indian/Kerguelen"}, + {L"West Asia Standard Time", L"TJ", "Asia/Dushanbe"}, + {L"West Asia Standard Time", L"TM", "Asia/Ashgabat"}, + {L"West Asia Standard Time", L"ZZ", "Etc/GMT-5"}, + {L"West Bank Standard Time", L"001", "Asia/Hebron"}, + {L"West Pacific Standard Time", L"001", "Pacific/Port_Moresby"}, + {L"West Pacific Standard Time", L"AQ", "Antarctica/DumontDUrville"}, + {L"West Pacific Standard Time", L"FM", "Pacific/Truk"}, + {L"West Pacific Standard Time", L"GU", "Pacific/Guam"}, + {L"West Pacific Standard Time", L"MP", "Pacific/Saipan"}, + {L"West Pacific Standard Time", L"ZZ", "Etc/GMT-10"}, + {L"Yakutsk Standard Time", L"001", "Asia/Yakutsk"}, + {L"Yukon Standard Time", L"001", "America/Whitehorse"}, + } +}; + +#define _GLIBCXX_WINDOWS_ZONES_MAP_COMPLETE diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/std.cc.in index d9a265e2256b..9301ed90c00f 100644 --- a/libstdc++-v3/src/c++23/std.cc.in +++ b/libstdc++-v3/src/c++23/std.cc.in @@ -278,10 +278,14 @@ export namespace std } using std::shift_left; namespace ranges - {} + { + using std::ranges::shift_left; + } using std::shift_right; namespace ranges - {} + { + using std::ranges::shift_right; + } using std::sort; namespace ranges { @@ -888,6 +892,10 @@ export namespace std using std::partial_order; using std::strong_order; using std::weak_order; +#if __glibcxx_type_order >= 202506L + using std::type_order; + using std::type_order_v; +#endif } // 28.4 @@ -1050,6 +1058,9 @@ export namespace std using std::throw_with_nested; using std::uncaught_exception; using std::uncaught_exceptions; +#if __cpp_lib_exception_ptr_cast >= 202506L + using std::exception_ptr_cast; +#endif } // 34.4 @@ -1502,7 +1513,15 @@ export namespace std using std::initializer_list; } -// FIXME +// +#if __cpp_lib_inplace_vector +export namespace std +{ + using std::inplace_vector; + using std::erase; + using std::erase_if; +} +#endif // export namespace std @@ -1729,15 +1748,6 @@ export namespace std using std::make_const_sentinel; #endif } -// FIXME these should be friends of __normal_iterator to avoid exporting -// __gnu_cxx. -export namespace __gnu_cxx -{ - using __gnu_cxx::operator==; - using __gnu_cxx::operator<=>; - using __gnu_cxx::operator+; - using __gnu_cxx::operator-; -} // export namespace std @@ -1840,7 +1850,15 @@ export namespace std export namespace std { using std::extents; - // FIXME layout_*, default_accessor and mdspan + using std::dextents; + using std::layout_left; + using std::layout_right; + using std::layout_stride; + using std::default_accessor; + using std::mdspan; + // FIXME layout_left_padded, layout_right_padded, aligned_accessor, + // strided_slice, submdspan_mapping_result, full_extent_t, full_extent, + // submdspan_extents, mdsubspan } #endif @@ -1956,6 +1974,14 @@ export namespace std using std::out_ptr; using std::inout_ptr; #endif +#if __cpp_lib_indirect + using std::indirect; + namespace pmr { using std::pmr::indirect; } +#endif +#if __cpp_lib_polymorphic + using std::polymorphic; + namespace pmr { using std::pmr::polymorphic; } +#endif } // 20.4 diff --git a/libstdc++-v3/testsuite/17_intro/names.cc b/libstdc++-v3/testsuite/17_intro/names.cc index f32205d9c7f5..e94da9defb29 100644 --- a/libstdc++-v3/testsuite/17_intro/names.cc +++ b/libstdc++-v3/testsuite/17_intro/names.cc @@ -404,4 +404,8 @@ # endif #endif +// PR libstdc++/119496 +// _Temporary_buffer used to have a member with this name +#define requested_size 1 + #include diff --git a/libstdc++-v3/testsuite/18_support/comparisons/type_order/1.cc b/libstdc++-v3/testsuite/18_support/comparisons/type_order/1.cc new file mode 100644 index 000000000000..b510494127d6 --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/comparisons/type_order/1.cc @@ -0,0 +1,95 @@ +// Copyright (C) 2025 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do compile { target c++26 } } + +#include + +#if __cpp_lib_type_order != 202506L +# error "__cpp_lib_type_order != 202506" +#endif + +static_assert (std::is_same_v ::value), + const std::strong_ordering>); +static_assert (std::is_same_v ), + const std::strong_ordering>); +struct S; +struct T; +template +struct U +{ +}; +typedef int int2; +struct V {}; +namespace +{ + struct W {}; +} + +template +struct eq +{ + constexpr eq () + { + static_assert (std::type_order ::value == std::strong_ordering::equal); + static_assert (std::type_order ::value == std::strong_ordering::equal); + static_assert (std::type_order_v == std::strong_ordering::equal); + static_assert (std::type_order_v == std::strong_ordering::equal); + } +}; +template +struct ne +{ + constexpr ne () + { + static_assert (std::type_order ::value != std::strong_ordering::equal); + static_assert (std::type_order ::value != std::strong_ordering::equal); + static_assert (std::type_order ::value == std::strong_ordering::greater + ? std::type_order ::value == std::strong_ordering::less + : std::type_order ::value == std::strong_ordering::greater); + static_assert (std::type_order_v != std::strong_ordering::equal); + static_assert (std::type_order_v != std::strong_ordering::equal); + static_assert (std::type_order_v == std::strong_ordering::greater + ? std::type_order_v == std::strong_ordering::less + : std::type_order_v == std::strong_ordering::greater); + } +}; + +constexpr eq a; +constexpr eq b; +constexpr eq c; +constexpr eq d; +constexpr eq e; +constexpr eq f; +constexpr eq , U > g; +constexpr eq h; +constexpr eq i; +constexpr eq j; +constexpr ne k; +constexpr ne l; +constexpr ne m; +constexpr ne n; +constexpr ne , U > o; +constexpr ne , U > p; +static_assert (std::type_order_v != std::strong_ordering::less + || std::type_order_v != std::strong_ordering::less + || std::type_order_v == std::strong_ordering::less); +constexpr ne q; +constexpr eq r; +constexpr ne s; +constexpr eq , U > t; +constexpr ne , U > u; diff --git a/libstdc++-v3/testsuite/18_support/exception/version.cc b/libstdc++-v3/testsuite/18_support/exception/version.cc new file mode 100644 index 000000000000..5707abd732f5 --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/exception/version.cc @@ -0,0 +1,9 @@ +// { dg-do preprocess { target c++26 } } +// { dg-add-options no_pch } + +#include + +#ifdef __cpp_lib_constexpr_exceptions +# error "Feature test macro for constexpr_exceptions should not be provided by " +#endif + diff --git a/libstdc++-v3/testsuite/18_support/exception_ptr/exception_ptr_cast.cc b/libstdc++-v3/testsuite/18_support/exception_ptr/exception_ptr_cast.cc new file mode 100644 index 000000000000..de371d1b7b7f --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/exception_ptr/exception_ptr_cast.cc @@ -0,0 +1,92 @@ +// { dg-do run { target c++26 } } + +// Copyright (C) 2025 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// exception_ptr_cast. + +#include +#include + +#if __cpp_lib_exception_ptr_cast != 202506L +# error "__cpp_lib_exception_ptr_cast != 202506" +#endif + +struct A { int a; }; +struct B : A {}; +struct C : B {}; +struct D {}; +struct E : virtual C { int e; constexpr virtual ~E () {} }; +struct F : virtual E, virtual C { int f; }; +struct G : virtual F, virtual C, virtual E { + constexpr G () : g (4) { a = 1; e = 2; f = 3; } int g; +}; + +constexpr bool test01(bool x) +{ + auto a = std::make_exception_ptr(C{ 42 }); + auto b = std::exception_ptr_cast(a); + VERIFY( b != nullptr ); + VERIFY( b->a == 42 ); + auto c = std::exception_ptr_cast(a); + VERIFY( c == static_cast(b) ); + auto d = std::exception_ptr_cast(a); + VERIFY( d == static_cast(b) ); + auto e = std::exception_ptr_cast(a); + VERIFY( e == nullptr ); + auto f = std::make_exception_ptr(42L); + auto g = std::exception_ptr_cast(f); + VERIFY( g != nullptr ); + VERIFY( *g == 42L ); + try + { + throw G (); + } + catch (...) + { + auto h = std::current_exception(); + auto i = std::exception_ptr_cast(h); + VERIFY( i != nullptr ); + VERIFY( i->a == 1 && i->e == 2 && i->f == 3 && i->g == 4 ); + auto j = std::exception_ptr_cast(h); + VERIFY( j == static_cast(i) ); + auto k = std::exception_ptr_cast(h); + VERIFY( k == static_cast(i) ); + auto l = std::exception_ptr_cast(h); + VERIFY( l == static_cast(i) ); + auto m = std::exception_ptr_cast(h); + VERIFY( m == static_cast(i) ); + auto n = std::exception_ptr_cast(a); + VERIFY( n == nullptr ); + } + if (x) + throw 1; + return true; +} + +static_assert(test01(false)); + +int main() +{ + try + { + test01(true); + } + catch (...) + { + } +} diff --git a/libstdc++-v3/testsuite/20_util/bitset/cons/1.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/1.cc index 0a40b6cd9658..6441332c8d62 100644 --- a/libstdc++-v3/testsuite/20_util/bitset/cons/1.cc +++ b/libstdc++-v3/testsuite/20_util/bitset/cons/1.cc @@ -47,6 +47,7 @@ void test01(void) const size_t n3 = 128; try { std::bitset bit03(str01, 5); + VERIFY(false); } catch(std::invalid_argument& fail) { VERIFY( true ); diff --git a/libstdc++-v3/testsuite/20_util/bitset/cons/6282.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/6282.cc index fafa9fc808bc..ee348c35b2a3 100644 --- a/libstdc++-v3/testsuite/20_util/bitset/cons/6282.cc +++ b/libstdc++-v3/testsuite/20_util/bitset/cons/6282.cc @@ -39,6 +39,8 @@ void test02(void) std::bitset<0> z3(std::string("10101010101")); VERIFY( z3.any() == false ); + VERIFY( z1.to_ulong() == 0 ); + VERIFY( (z1.to_string,allocator >().empty() )); try { z1.set(0); VERIFY( false ); @@ -49,9 +51,6 @@ void test02(void) catch(...) { VERIFY( false ); } - - VERIFY( z1.to_ulong() == 0 ); - VERIFY( (z1.to_string,allocator >().empty() )); } int main() diff --git a/libstdc++-v3/testsuite/20_util/bitset/cons/string_view.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/string_view.cc new file mode 100644 index 000000000000..ec3a6c86b681 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/bitset/cons/string_view.cc @@ -0,0 +1,132 @@ +// C++26 [bitset.cons] + +// { dg-do run { target c++26 } } + +#ifndef C +# define C char +# define L(s) s +#endif + +#include +#include +#include +#include // std::reverse, std::transform +#include +#include + +void test01() +{ + // template<_C,_T> + // constexpr explicit + // bitset(const basic_string_view<_C,_T>, + // size_type pos, size_type n, _C zero, _C one) + try { + std::basic_string_view str(L("stuff smith sessions")); + const std::size_t n = 128; + std::bitset bit(str, 5); + VERIFY(false); + } + catch(std::invalid_argument& fail) { + VERIFY( true ); + } + catch(...) { + VERIFY( false ); + } + + try { + std::basic_string_view str(L("010101000011")); + const std::size_t n = 128; + const auto sz = str.size(); + std::bitset bit(str, 0); + std::basic_string str02; + for (std::size_t i = 0; i < sz; ++i) + str02 += (bit.test(i) ? C('1') : C('0')); + std::reverse(str02.begin(), str02.end()); + VERIFY( str02 == str ); + } + catch(std::invalid_argument& fail) { + VERIFY( false ); + } + catch(...) { + VERIFY( false ); + } + + // substring "010101000011" + // "10100001" + try { + std::basic_string_view str(L("010101000011")); + const std::size_t n = 128; + const auto sz = 8; + std::bitset bit(str, 3, sz); + std::basic_string str02; + for (std::size_t i = 0; i < sz; ++i) + str02 += (bit.test(i) ? C('1') : C('0')); + std::reverse(str02.begin(), str02.end()); + VERIFY( str02 == str.substr(3, sz) ); + } + catch(std::invalid_argument& fail) { + VERIFY( false ); + } + catch(...) { + VERIFY( false ); + } + + // "abababaaaabb", zero = 'a', one = 'b' + try { + std::basic_string_view str(L("010101000011")); + const std::size_t n = 128; + const auto sz = str.size(); + std::basic_string str02(str); + std::transform(str02.cbegin(), str02.cend(), str02.begin(), [](auto c) { + return (c - C('0')) + C('a'); + }); + std::basic_string_view str03(str02); + std::bitset bit(str03, 0, 100, C('a'), C('b')); + std::basic_string str04; + for (std::size_t i = 0; i < sz; ++i) + str04 += (bit.test(i) ? C('1') : C('0')); + std::reverse(str04.begin(), str04.end()); + VERIFY( str04 == str ); + } + catch(std::invalid_argument& fail) { + VERIFY( false ); + } + catch(...) { + VERIFY( false ); + } + + // "aba0aba", zero = 'a', one = 'b', '0' appears + try { + const std::size_t n = 128; + std::basic_string_view str05(L("aba0aba")); + std::bitset bit(str05, 0, 100, C('a'), C('b')); + VERIFY( false ); + } + catch(std::invalid_argument& fail) { + VERIFY( true ); + } + catch(...) { + VERIFY( false ); + } + + // pos > str.size() + try { + std::basic_string_view str(L("010101000011")); + const std::size_t n = 128; + const auto sz = str.size(); + std::bitset bit(str, sz + 1, 100); + VERIFY( false ); + } + catch(std::out_of_range& fail) { + VERIFY( true ); + } + catch(...) { + VERIFY( false ); + } +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/bitset/cons/string_view_wide.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/string_view_wide.cc new file mode 100644 index 000000000000..b53fe74a7cef --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/bitset/cons/string_view_wide.cc @@ -0,0 +1,8 @@ +// C++26 [bitset.cons] + +// { dg-do run { target c++26 } } + +#define C wchar_t +#define L(s) L ## s + +#include "./string_view.cc" diff --git a/libstdc++-v3/testsuite/20_util/hash/int128.cc b/libstdc++-v3/testsuite/20_util/hash/int128.cc new file mode 100644 index 000000000000..a26d2e219535 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/hash/int128.cc @@ -0,0 +1,20 @@ +// { dg-do run { target c++11 } } +// { dg-add-options strict_std } + +#include +#include + +int main() +{ +#ifdef __SIZEOF_INT128__ + std::hash<__int128> h; + __int128 i = (__int128)0x123456789; + VERIFY( h(i) == (std::size_t)i ); + VERIFY( h(-i) == (std::size_t)-i ); + VERIFY( h(~i) == (std::size_t)~i ); + std::hash hu; + unsigned __int128 u = i; + VERIFY( hu(u) == (std::size_t)u ); + VERIFY( hu(~u) == (std::size_t)~u ); +#endif +} diff --git a/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/120717.cc b/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/120717.cc new file mode 100644 index 000000000000..4c07683d494e --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/120717.cc @@ -0,0 +1,20 @@ +// PR libstdc++/120717 +// { dg-do compile { target c++11 } } +// { dg-additional-options "-Wsfinae-incomplete" } + +#include + +// Verify __is_complete_or_unbounded doesn't try to instantiate the underlying +// type of a reference or array of unknown bound. +template struct A { static_assert(false, "do not instantiate"); }; +static_assert(std::__is_complete_or_unbounded(std::__type_identity&>{}), ""); +static_assert(std::__is_complete_or_unbounded(std::__type_identity&&>{}), ""); +static_assert(std::__is_complete_or_unbounded(std::__type_identity[]>{}), ""); + +// Verify __is_complete_or_unbounded doesn't produce unexpected +// -Wsfinae-incomplete warnings. +struct B; +static_assert(std::__is_complete_or_unbounded(std::__type_identity{}), ""); +static_assert(std::__is_complete_or_unbounded(std::__type_identity{}), ""); +static_assert(std::__is_complete_or_unbounded(std::__type_identity{}), ""); +struct B { }; // { dg-bogus "-Wsfinae-incomplete" } diff --git a/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization.cc b/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization.cc index 256b84df60fb..59af024969f2 100644 --- a/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization.cc +++ b/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization.cc @@ -23,7 +23,7 @@ struct X; static_assert( !std::__is_complete_or_unbounded(std::__type_identity{}), "error"); -struct X{}; +struct X{}; // { dg-warning Wsfinae-incomplete } static_assert( std::__is_complete_or_unbounded(std::__type_identity{}), "Result memoized. This leads to worse diagnostics"); diff --git a/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc b/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc index 8e207b584dc9..264efa77996b 100644 --- a/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc +++ b/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc @@ -25,5 +25,5 @@ struct X; constexpr bool res_incomplete = std::is_move_constructible::value; // { dg-error "required from here" } -struct X{}; +struct X{}; // { dg-warning Wsfinae-incomplete } constexpr bool res_complete = std::is_default_constructible::value; // { dg-bogus "required from here" } diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/int128.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/int128.cc new file mode 100644 index 000000000000..46c07b7669e5 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/make_unsigned/int128.cc @@ -0,0 +1,14 @@ +// { dg-do compile { target c++11 } } +// { dg-add-options strict_std } + +#include + +#ifdef __SIZEOF_INT128__ +enum E : __int128 { }; +using U = std::make_unsigned::type; +static_assert( std::is_integral::value, "type is an integer" ); +static_assert( sizeof(U) == sizeof(E), "width of type is 128 bits" ); +using I = std::make_signed::type; +static_assert( std::is_integral::value, "type is an integer" ); +static_assert( sizeof(I) == sizeof(E), "width of type is 128 bits" ); +#endif diff --git a/libstdc++-v3/testsuite/20_util/optional/range.cc b/libstdc++-v3/testsuite/20_util/optional/range.cc new file mode 100644 index 000000000000..e77dc21e22b3 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/optional/range.cc @@ -0,0 +1,163 @@ +// { dg-do compile { target c++26 } } + +#include +#include +#include +#include +#include +#include +#include + +#include + +template +constexpr +void +test_range_concepts() +{ + static_assert(std::ranges::contiguous_range); + static_assert(std::ranges::sized_range); + static_assert(std::ranges::common_range); + static_assert(!std::ranges::borrowed_range); + + // an optional is not assignable, and therefore does not satisfy ranges::view + using T = typename O::value_type; + constexpr bool is_const_opt = std::is_const_v; + static_assert(std::ranges::view == !is_const_opt); + static_assert(std::ranges::viewable_range == !is_const_opt); +} + +template +constexpr +void +test_iterator_concepts() +{ + using T = typename O::value_type; + using iterator = typename O::iterator; + static_assert(std::contiguous_iterator); + static_assert(std::is_same_v::value_type, std::remove_cv_t>); + static_assert(std::is_same_v, std::remove_cv_t>); + static_assert(std::is_same_v::reference, T&>); + static_assert(std::is_same_v, T&>); + + using const_iterator = typename O::const_iterator; + static_assert(std::contiguous_iterator); + static_assert(std::is_same_v::value_type, std::remove_cv_t>); + static_assert(std::is_same_v, std::remove_cv_t>); + static_assert(std::is_same_v::reference, const T&>); + static_assert(std::is_same_v, const T&>); +} + +template +constexpr +void +test_empty() +{ + O empty; + VERIFY(!empty); + VERIFY(empty.begin() == empty.end()); + VERIFY(std::as_const(empty).begin() == std::as_const(empty).end()); + VERIFY(std::ranges::empty(empty)); + VERIFY(std::ranges::empty(std::as_const(empty))); + VERIFY(std::ranges::empty(empty | std::views::as_const)); + VERIFY(std::ranges::size(empty) == 0); + VERIFY(std::ranges::size(std::as_const(empty)) == 0); + + size_t count = 0; + for (const auto& x : empty) + ++count; + VERIFY(count == 0); +} + +template +constexpr +void +test_non_empty(const T& value) +{ + O non_empty = std::make_optional(value); + VERIFY(non_empty); + VERIFY(*non_empty == value); + VERIFY(non_empty.begin() != non_empty.end()); + VERIFY(non_empty.begin() < non_empty.end()); + VERIFY(std::as_const(non_empty).begin() != std::as_const(non_empty).end()); + VERIFY(std::as_const(non_empty).begin() < std::as_const(non_empty).end()); + VERIFY(!std::ranges::empty(non_empty)); + VERIFY(!std::ranges::empty(std::as_const(non_empty))); + VERIFY(!std::ranges::empty(non_empty | std::views::as_const)); + VERIFY(std::ranges::size(non_empty) == 1); + VERIFY(std::ranges::size(std::as_const(non_empty)) == 1); + + size_t count = 0; + for (const auto& x : non_empty) + ++count; + VERIFY(count == 1); + + if constexpr (!std::is_const_v) { + for (auto& x : non_empty) + x = T{}; + VERIFY(non_empty); + VERIFY(*non_empty == T{}); + } +} + +template +constexpr +void +test(const T& value) +{ + using O = std::optional; + test_range_concepts(); + test_iterator_concepts(); + test_empty(); + test_non_empty(value); + static_assert(!std::formattable); + static_assert(!std::formattable); + static_assert(std::format_kind == std::range_format::disabled); +} + +constexpr +void +range_chain_example() // from P3168 +{ + std::vector v{2, 3, 4, 5, 6, 7, 8, 9, 1}; + auto test = [](int i) -> std::optional { + switch(i) { + case 1: + case 3: + case 7: + case 9: + return i * 2; + default: + return {}; + } + }; + + auto result = v + | std::views::transform(test) + | std::views::filter([](auto x) { return bool(x); }) + | std::views::transform([](auto x){ return *x; }) + | std::ranges::to(); + + bool ok = result == std::vector{6, 14, 18, 2}; + VERIFY(ok); +} + +constexpr +bool +all_tests() +{ + test(42); + int i = 42; + test(&i); + test(std::string_view("test")); + test(std::vector{1, 2, 3, 4}); + test(std::optional(42)); + test(42); + + range_chain_example(); + + return true; +} + +static_assert(all_tests()); + diff --git a/libstdc++-v3/testsuite/20_util/optional/version.cc b/libstdc++-v3/testsuite/20_util/optional/version.cc index 657a3992422a..ba44aa525356 100644 --- a/libstdc++-v3/testsuite/20_util/optional/version.cc +++ b/libstdc++-v3/testsuite/20_util/optional/version.cc @@ -21,8 +21,17 @@ #endif #endif +#if __cplusplus > 202302L +# ifndef __cpp_lib_optional_range_support +# error "Feature test macro for optional range support is missing in " +# elif __cpp_lib_optional_range_support != 202406L +# error "Feature test macro for optional range support has wrong value for C++26 in " +# endif +#endif + #undef __cpp_lib_optional #undef __cpp_lib_freestanding_optional +#undef __cpp_lib_optional_range_support #include #if __cplusplus >= 202302L @@ -32,3 +41,12 @@ # error "Feature test macro for freestanding std::optional has wrong value in " #endif #endif + +#if __cplusplus > 202302L +# ifndef __cpp_lib_optional_range_support +# error "Feature test macro for optional range support is missing in " +# endif +# if __cpp_lib_optional_range_support != 202406L +# error "Feature test macro for optional range support has wrong value for C++26 in " +# endif +#endif diff --git a/libstdc++-v3/testsuite/20_util/owner_equal/cmp.cc b/libstdc++-v3/testsuite/20_util/owner_equal/cmp.cc new file mode 100644 index 000000000000..311ddf247487 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/owner_equal/cmp.cc @@ -0,0 +1,105 @@ +// { dg-do run { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.6 Struct owner_equal [util.smartptr.owner.equal] + +#include +#include +#include + +struct A { }; + +struct B { A a[2]; }; + +int +test01() +{ + // test empty shared_ptr owners compare equivalent + std::owner_equal eq; + std::shared_ptr p1; + std::shared_ptr p2; + VERIFY( eq(p1, p2) && eq(p2, p1) ); + std::weak_ptr p3; + VERIFY( eq(p1, p3) && eq(p3, p1) ); + VERIFY( eq(p1, p3) && eq(p3, p1) ); + return 0; +} + + +// Construction from pointer +int +test02() +{ + std::owner_equal eq; + + std::shared_ptr empty; + + std::shared_ptr a1(new A); + VERIFY( !eq(empty, a1) && !eq(a1, empty) ); + + std::shared_ptr a2(new A); + VERIFY( !eq(a1, a2) && !eq(a2, a1) ); + + std::weak_ptr w1(a1); + VERIFY( eq(a1, w1) && eq(w1, a1) ); + + std::weak_ptr w2(a2); + VERIFY( !eq(w1, w2) && !eq(w2, w1) ); + + a1.reset(); + VERIFY( eq(empty, a1) && eq(a1, empty) ); + VERIFY( !eq(a1, w1) && !eq(w1, a1) ); + + a2.reset(); + VERIFY( eq(a2, a1) && eq(a1, a2) ); + + return 0; +} + +// aliasing +int +test03() +{ + std::owner_equal eq; + + std::shared_ptr b(new B); + std::shared_ptr a0(b, &b->a[0]); + std::shared_ptr a1(b, &b->a[1]); + // values are different but owners are equivalent: + VERIFY( a0 < a1 && eq(a0, a1) && eq(b, a0) && eq(b, a1) ); + + std::weak_ptr w0(a0); + std::weak_ptr w1(a1); + VERIFY( eq(w0, w1) && eq(w1, w0) ); + VERIFY( eq(a0, w1) && eq(w1, a0) ); + VERIFY( eq(w0, a1) && eq(a1, w0) ); + + return 0; +} + +// as binary predicate +int +test04() +{ + std::owner_equal eq; + + std::shared_ptr b(new B); + std::shared_ptr a0(b, &b->a[0]); + std::shared_ptr a1(b, &b->a[1]); + std::shared_ptr c(new A); + std::weak_ptr a[3]{a0, a1, c}; + std::weak_ptr* p = std::unique(a, a+3, eq); + VERIFY( p == &a[2] ); + + return 0; +} + +int +main() +{ + test01(); + test02(); + test03(); + test04(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/owner_equal/noexcept.cc b/libstdc++-v3/testsuite/20_util/owner_equal/noexcept.cc new file mode 100644 index 000000000000..fb479f60a743 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/owner_equal/noexcept.cc @@ -0,0 +1,30 @@ +// { dg-do compile { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.6 Struct owner_equal [util.smartptr.owner.equal] + +#include + +#ifndef __cpp_lib_smart_ptr_owner_equality +# error "Feature-test macro for smart ptr owner equality missing in " +#elif __cpp_lib_smart_ptr_owner_equality != 202306L +# error "Feature-test macro for smart ptr owner equality has wrong value in " +#endif + +const std::owner_equal eq; +const std::shared_ptr si; +const std::weak_ptr wi; +static_assert( noexcept(!eq(si, si)) ); +static_assert( noexcept(!eq(si, wi)) ); +static_assert( noexcept(!eq(wi, si)) ); +static_assert( noexcept(!eq(wi, wi)) ); +static_assert( noexcept(!eq(si, wi)) ); +static_assert( noexcept(!eq(wi, si)) ); +const std::shared_ptr sl; +const std::weak_ptr wc; +static_assert( noexcept(!eq(si, si)) ); +static_assert( noexcept(!eq(si, sl)) ); +static_assert( noexcept(!eq(sl, si)) ); +static_assert( noexcept(!eq(si, wc)) ); +static_assert( noexcept(!eq(wc, si)) ); +static_assert( noexcept(!eq(wc, wi)) ); diff --git a/libstdc++-v3/testsuite/20_util/owner_equal/version.cc b/libstdc++-v3/testsuite/20_util/owner_equal/version.cc new file mode 100644 index 000000000000..db29154c5785 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/owner_equal/version.cc @@ -0,0 +1,13 @@ +// { dg-do compile { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 17.3.2 Header synopsis [version.syn] + +#include + +#ifndef __cpp_lib_smart_ptr_owner_equality +# error "Feature-test macro for smart ptr owner equality missing in " +#elif __cpp_lib_smart_ptr_owner_equality != 202306L +# error "Feature-test macro for smart ptr owner equality has wrong value in " +#endif + diff --git a/libstdc++-v3/testsuite/20_util/owner_hash/cmp.cc b/libstdc++-v3/testsuite/20_util/owner_hash/cmp.cc new file mode 100644 index 000000000000..c03a9266d080 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/owner_hash/cmp.cc @@ -0,0 +1,87 @@ +// { dg-do run { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.5 Struct owner_hash [util.smartptr.owner.hash] + +#include +#include +#include + +struct A { }; + +struct B { A a[2]; }; + +int +test01() +{ + // test empty shared_ptr hashes compare equivalent + std::owner_hash oh; + std::shared_ptr p1; + std::shared_ptr p2; + VERIFY( oh(p1) == oh(p2) ); + std::weak_ptr p3; + VERIFY( oh(p1) == oh(p3) ); + VERIFY( oh(p1) == oh(p3) ); + return 0; +} + + +// Construction from pointer +int +test02() +{ + std::owner_hash oh; + + std::shared_ptr empty; + + std::shared_ptr a1(new A); + VERIFY( oh(empty) != oh(a1) ); + + std::shared_ptr a2(new A); + VERIFY( oh(a1) != oh(a2) ); + + std::weak_ptr w1(a1); + VERIFY( oh(a1) == oh(w1) ); + + std::weak_ptr w2(a2); + VERIFY( oh(w1) != oh(w2) ); + + a1.reset(); + VERIFY( oh(empty) == oh(a1) ); + VERIFY( oh(a1) != oh(w1) ); + + a2.reset(); + VERIFY( oh(a2) == oh(a1) ); + + return 0; +} + +// aliasing +int +test03() +{ + std::owner_hash oh; + + std::shared_ptr b(new B); + std::shared_ptr a0(b, &b->a[0]); + std::shared_ptr a1(b, &b->a[1]); + // values are different but owners are ohuivalent: + VERIFY( a0 < a1 && oh(a0) == oh(a1) && oh(b) == oh(a0) && oh(b) == oh(a1) ); + + std::weak_ptr w0(a0); + std::weak_ptr w1(a1); + VERIFY( oh(w0) == oh(w1) ); + VERIFY( oh(a0) == oh(w1) ); + VERIFY( oh(w0) == oh(a1) ); + + return 0; +} + +int +main() +{ + test01(); + test02(); + test03(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/owner_hash/noexcept.cc b/libstdc++-v3/testsuite/20_util/owner_hash/noexcept.cc new file mode 100644 index 000000000000..12b2f2fd04f2 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/owner_hash/noexcept.cc @@ -0,0 +1,16 @@ +// { dg-do compile { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.5 Struct owner_hash [util.smartptr.owner.hash] + +#include + +const std::owner_hash oh; +const std::shared_ptr si; +const std::weak_ptr wi; +static_assert( noexcept(!oh(si)) ); +static_assert( noexcept(!oh(wi)) ); +const std::shared_ptr sl; +const std::weak_ptr wc; +static_assert( noexcept(!oh(sl)) ); +static_assert( noexcept(!oh(wc)) ); diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/observers/owner_equal.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/owner_equal.cc new file mode 100644 index 000000000000..7ec86919ccfa --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/owner_equal.cc @@ -0,0 +1,74 @@ +// { dg-do run { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.2.6 shared_ptr observers [util.smartptr.shared.obs] + +#include +#include + +struct A +{ + int i; + virtual ~A() { } +}; + +struct B : A +{ +}; + +void +test01() +{ + // test empty shared_ptr owners compare equivalent + std::shared_ptr p1; + std::shared_ptr p2; + VERIFY( p1.owner_equal(p2) && p2.owner_equal(p1) ); +} + + +// Construction from pointer +void +test02() +{ + std::shared_ptr a0; + + std::shared_ptr a1(new A); + VERIFY( !a1.owner_equal(a0) && !a0.owner_equal(a1) ); + + std::shared_ptr b1(new B); + VERIFY( !a1.owner_equal(b1) && !b1.owner_equal(a1) ); + + std::shared_ptr a2(a1); + VERIFY( a1.owner_equal(a2) && a2.owner_equal(a1) ); + a2 = b1; + VERIFY( b1.owner_equal(a2) && a2.owner_equal(b1) ); + + std::weak_ptr w1(a1); + VERIFY( a1.owner_equal(w1) && w1.owner_equal(a1) ); + std::weak_ptr w2(a2); + VERIFY( b1.owner_equal(w2) && w2.owner_equal(b1) ); + + static_assert( noexcept(a1.owner_equal(a0)) ); + static_assert( noexcept(a1.owner_equal(b1)) ); + static_assert( noexcept(b1.owner_equal(a1)) ); + static_assert( noexcept(a1.owner_equal(w1)) ); + static_assert( noexcept(b1.owner_equal(w1)) ); +} + +// Aliasing +void +test03() +{ + std::shared_ptr p1(new A()); + std::shared_ptr p2(p1, &p1->i); + VERIFY( p1.owner_equal(p2) && p2.owner_equal(p1) ); +} + +int +main() +{ + test01(); + test02(); + test03(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/observers/owner_hash.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/owner_hash.cc new file mode 100644 index 000000000000..8e6c02cf162c --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/owner_hash.cc @@ -0,0 +1,71 @@ +// { dg-do run { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.2.6 shared_ptr observers [util.smartptr.shared.obs] + +#include +#include + +struct A +{ + int i; + virtual ~A() { } +}; + +struct B : A +{ +}; + +void +test01() +{ + // test empty shared_ptr hashes compare equivalent + std::shared_ptr p1; + std::shared_ptr p2; + VERIFY( p1.owner_hash() == p2.owner_hash() ); +} + + +// Construction from pointer +void +test02() +{ + std::shared_ptr a0; + + std::shared_ptr a1(new A); + VERIFY( a1.owner_hash() != a0.owner_hash() ); + + std::shared_ptr b1(new B); + VERIFY( a1.owner_hash() != b1.owner_hash() ); + + std::shared_ptr a2(a1); + VERIFY( a1.owner_hash() == a2.owner_hash() ); + a2 = b1; + VERIFY( b1.owner_hash() == a2.owner_hash() ); + + std::weak_ptr w1(a1); + VERIFY( a1.owner_hash() == w1.owner_hash() ); + std::weak_ptr w2(a2); + VERIFY( b1.owner_hash() == w2.owner_hash() ); + + static_assert( noexcept(a1.owner_hash()) ); + static_assert( noexcept(b1.owner_hash()) ); +} + +// Aliasing +void +test03() +{ + std::shared_ptr p1(new A()); + std::shared_ptr p2(p1, &p1->i); + VERIFY( p1.owner_hash() == p2.owner_hash() ); +} + +int +main() +{ + test01(); + test02(); + test03(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/destroy/121024.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/destroy/121024.cc new file mode 100644 index 000000000000..781dd404750c --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/destroy/121024.cc @@ -0,0 +1,77 @@ +// { dg-do compile { target c++26 } } + +// Bug 121024 +// ranges::destroy and ranges::destroy_n do not end lifetime of trivial types + +#include + +consteval bool is_within_lifetime(const auto* p) noexcept +{ + return __builtin_constant_p(*p); +} + +template +struct Buf +{ + constexpr Buf() : p(std::allocator().allocate(2)) { } + constexpr ~Buf() { std::allocator().deallocate(p, 2); } + T* p; +}; + +template +consteval bool +test_destroy() +{ + Buf buf; + std::uninitialized_value_construct(buf.p, buf.p + 2); + std::destroy(buf.p, buf.p + 2); + return not is_within_lifetime(buf.p) && not is_within_lifetime(buf.p + 1); +} + +template +consteval bool +test_destroy_n() +{ + Buf buf; + std::uninitialized_value_construct_n(buf.p, 2); + std::destroy_n(buf.p, 2); + return not is_within_lifetime(buf.p) && not is_within_lifetime(buf.p + 1); +} + +template +consteval bool +test_ranges_destroy() +{ + Buf buf; + std::uninitialized_value_construct(buf.p, buf.p + 2); + std::ranges::destroy(buf.p, buf.p + 2); + return not is_within_lifetime(buf.p) && not is_within_lifetime(buf.p + 1); +} + +template +consteval bool +test_ranges_destroy_n() +{ + Buf buf; + std::uninitialized_value_construct_n(buf.p, 2); + std::ranges::destroy_n(buf.p, 2); + return not is_within_lifetime(buf.p) && not is_within_lifetime(buf.p + 1); +} + +struct O +{ + constexpr O() { } + constexpr ~O() { } +}; + +// These all fail for GCC because is_within_lifetime still returns true +// after the lifetime has been ended. +// { dg-xfail-if "PR c++/102284" { *-*-* } } +static_assert( test_destroy() ); +static_assert( test_destroy() ); +static_assert( test_destroy_n() ); +static_assert( test_destroy_n() ); +static_assert( test_ranges_destroy() ); +static_assert( test_ranges_destroy() ); +static_assert( test_ranges_destroy_n() ); +static_assert( test_ranges_destroy_n() ); diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/destroy_n_neg.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/destroy_n_neg.cc new file mode 100644 index 000000000000..12c0dc575ccf --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/destroy_n_neg.cc @@ -0,0 +1,59 @@ +// Copyright (C) 2017-2025 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do compile { target c++17 } } + +#include + +// This has a trivial destructor, but should not be destructible! +struct DeletedDtor { + ~DeletedDtor() = delete; +}; + +void +test01() +{ + alignas(DeletedDtor) unsigned char buf[sizeof(DeletedDtor)]; + auto p = ::new (buf) DeletedDtor(); + std::destroy_n(p, 1); +} + +class PrivateDtor { + ~PrivateDtor() { } +}; + +void +test02() +{ + alignas(PrivateDtor) unsigned char buf[sizeof(PrivateDtor)]; + auto p = ::new (buf) PrivateDtor(); + std::destroy_n(p, 1); +} + +#if __cpp_constexpr_dynamic_alloc // >= C++20 +consteval bool +test03() +{ + DeletedDtor* p = nullptr; + std::destroy_n(p, 0); + return true; +} +static_assert(test03()); +#endif + +// { dg-error "deleted function .*DeletedDtor" "" { target *-*-* } 0 } +// { dg-error "PrivateDtor.* is private" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/destroy_neg.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/destroy_neg.cc index 5946a82de3bc..096f218ee2be 100644 --- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/destroy_neg.cc +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/destroy_neg.cc @@ -29,8 +29,7 @@ test01() { alignas(DeletedDtor) unsigned char buf[sizeof(DeletedDtor)]; auto p = ::new (buf) DeletedDtor(); - std::destroy(p, p + 1); // { dg-error "here" } - std::destroy_n(p, 1); // { dg-error "here" } + std::destroy(p, p + 1); } class PrivateDtor { @@ -42,8 +41,19 @@ test02() { alignas(PrivateDtor) unsigned char buf[sizeof(PrivateDtor)]; auto p = ::new (buf) PrivateDtor(); - std::destroy(p, p + 1); // { dg-error "here" } - std::destroy_n(p, 1); // { dg-error "here" } + std::destroy(p, p + 1); } -// { dg-error "value type is destructible" "" { target *-*-* } 0 } +#if __cpp_constexpr_dynamic_alloc // >= C++20 +consteval bool +test03() +{ + DeletedDtor* p = nullptr; + std::destroy(p, p); + return true; +} +static_assert(test03()); +#endif + +// { dg-error "deleted function .*DeletedDtor" "" { target *-*-* } 0 } +// { dg-error "PrivateDtor.* is private" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_default_construct/120397.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_default_construct/120397.cc new file mode 100644 index 000000000000..7aa05d7d12f4 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_default_construct/120397.cc @@ -0,0 +1,19 @@ +// { dg-do compile { target c++17 } } + +#include + +// PR libstdc++/120397 +// std::uninitialized_value_construct cannot create arrays of non-trivially +// destructible types + +struct X { X() { } ~X() { } }; + +void def(X (*x)[1]) +{ + std::uninitialized_default_construct(x, x+1); +} + +void def_n(X (*x)[1]) +{ + std::uninitialized_default_construct_n(x, 1); +} diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/120931.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/120931.cc new file mode 100644 index 000000000000..766fac0e527b --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/120931.cc @@ -0,0 +1,16 @@ +// { dg-options "-std=gnu++98" } +// { dg-do compile { target c++98_only } } +// std::deque::resize() method fails with -std=c++98 + +#include +#include + +void +test_pr120931() +{ + using __gnu_test::test_container; + using __gnu_test::forward_iterator_wrapper; + unsigned char c[1]; + test_container f(c); + std::uninitialized_fill(f.begin(), f.end(), 0); +} diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_value_construct/120397.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_value_construct/120397.cc new file mode 100644 index 000000000000..f4d9fce20213 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_value_construct/120397.cc @@ -0,0 +1,19 @@ +// { dg-do compile { target c++17 } } + +#include + +// PR libstdc++/120397 +// std::uninitialized_value_construct cannot create arrays of non-trivially +// destructible types + +struct X { X() { } ~X() { } }; + +void val(X (*x)[1]) +{ + std::uninitialized_value_construct(x, x+1); +} + +void val_n(X (*x)[1]) +{ + std::uninitialized_value_construct_n(x, 1); +} diff --git a/libstdc++-v3/testsuite/20_util/synchronized_pool_resource/118681.cc b/libstdc++-v3/testsuite/20_util/synchronized_pool_resource/118681.cc new file mode 100644 index 000000000000..facbf00400c9 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/synchronized_pool_resource/118681.cc @@ -0,0 +1,6 @@ +// { dg-do run { target c++17 } } +// { dg-require-gthreads "" } +// Bug 118681 - unsynchronized_pool_resource may fail to respect alignment + +#define RESOURCE std::pmr::synchronized_pool_resource +#include "../unsynchronized_pool_resource/118681.cc" diff --git a/libstdc++-v3/testsuite/20_util/system_clock/99832.cc b/libstdc++-v3/testsuite/20_util/system_clock/99832.cc new file mode 100644 index 000000000000..693d4d647d9b --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/system_clock/99832.cc @@ -0,0 +1,14 @@ +// { dg-options "-O0 -g0" } +// { dg-do compile { target c++20 } } +// { dg-final { scan-assembler-not "system_clock9to_time_t" } } + +// Bug libstdc++/99832 +// std::chrono::system_clock::to_time_t needs ABI tag for 32-bit time_t + +#include + +std::time_t +test_pr99832(std::chrono::system_clock::time_point t) +{ + return std::chrono::system_clock::to_time_t(t); +} diff --git a/libstdc++-v3/testsuite/20_util/tuple/dr3528.cc b/libstdc++-v3/testsuite/20_util/tuple/dr3528.cc new file mode 100644 index 000000000000..c20ff95e12da --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/dr3528.cc @@ -0,0 +1,46 @@ +// { dg-do compile { target c++17 } } + +// LWG 3528. make_from_tuple can perform (the equivalent of) a C-style cast + +#include +#include +#include + +template +using make_t = decltype(std::make_from_tuple(std::declval())); + +template +constexpr bool can_make = false; +template +constexpr bool can_make>> = true; + +static_assert( can_make> ); +static_assert( can_make&> ); +static_assert( can_make&> ); +static_assert( can_make> ); +static_assert( can_make&&> ); +static_assert( can_make, std::pair> ); +static_assert( can_make, std::array> ); +static_assert( can_make> ); +static_assert( can_make> ); +static_assert( can_make> ); +static_assert( ! can_make> ); +static_assert( ! can_make> ); +static_assert( ! can_make&> ); +static_assert( ! can_make> ); +static_assert( ! can_make> ); +static_assert( ! can_make> ); +static_assert( ! can_make> ); +static_assert( ! can_make> ); +static_assert( ! can_make> ); + +struct Two +{ + Two(const char*, int); +}; + +static_assert( can_make> ); +static_assert( ! can_make> ); +static_assert( can_make> ); +static_assert( ! can_make> ); +static_assert( ! can_make, std::array> ); diff --git a/libstdc++-v3/testsuite/20_util/unsynchronized_pool_resource/118681.cc b/libstdc++-v3/testsuite/20_util/unsynchronized_pool_resource/118681.cc new file mode 100644 index 000000000000..9935f793cf91 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/unsynchronized_pool_resource/118681.cc @@ -0,0 +1,58 @@ +// { dg-do run { target c++17 } } +// Bug 118681 - unsynchronized_pool_resource may fail to respect alignment + +#include +#include +#include + +#ifndef RESOURCE +# define RESOURCE std::pmr::unsynchronized_pool_resource +#endif + +bool any_misaligned = false; + +bool +is_aligned(void* p, [[maybe_unused]] std::size_t size, std::size_t alignment) +{ + const bool misaligned = reinterpret_cast(p) % alignment; +#ifdef DEBUG + std::printf("allocate(%2zu, %2zu): %p is aligned %scorrectly\n", + size, alignment, p, misaligned ? "in" : ""); + any_misaligned |= misaligned; + return true; +#endif + return ! misaligned; +} + +void +test_alignment(std::pmr::memory_resource& res, bool dealloc) +{ + for (std::size_t alignment : { 8, 16, 32, 64 }) + { + for (std::size_t size : { 9, 12, 24, 40, 48, 56, 72 }) + { + void* p1 = res.allocate(size, alignment); + void* p2 = res.allocate(size, alignment); + + VERIFY( is_aligned(p1, size, alignment) ); + VERIFY( is_aligned(p2, size, alignment) ); + + if (dealloc) + { + res.deallocate(p1, size, alignment); + res.deallocate(p2, size, alignment); + } + } + } +} + +int main() +{ + RESOURCE res; + test_alignment(res, true); + res.release(); + test_alignment(res, false); + res.release(); + + VERIFY( ! any_misaligned ); +} diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/observers/owner_equal.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/observers/owner_equal.cc new file mode 100644 index 000000000000..0217a6e5899e --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/weak_ptr/observers/owner_equal.cc @@ -0,0 +1,52 @@ +// { dg-do run { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.3.6 weak_ptr observers [util.smartptr.weak.obs] + +#include +#include + +struct A { }; +struct B { }; + +void +test01() +{ + // test empty weak_ptr owners compare equivalent + std::weak_ptr p1; + std::weak_ptr p2; + VERIFY( p1.owner_equal(p2) && p2.owner_equal(p1) ); + + std::shared_ptr p3; + VERIFY( p1.owner_equal(p3) && p3.owner_equal(p1) ); + + static_assert( noexcept(p1.owner_equal(p1)) ); + static_assert( noexcept(p1.owner_equal(p2)) ); + static_assert( noexcept(p1.owner_equal(p3)) ); + static_assert( noexcept(p2.owner_equal(p1)) ); +} + + +void +test02() +{ + std::shared_ptr a0; + std::weak_ptr w0(a0); + + std::shared_ptr a1(new A); + std::weak_ptr w1(a1); + VERIFY( a1.owner_equal(w1) && w1.owner_equal(a1) ); + VERIFY( !w1.owner_equal(w0) && !w0.owner_equal(w1) ); + VERIFY( !w1.owner_equal(a0) && !a0.owner_equal(w1) ); + + std::shared_ptr b1(new B); + VERIFY( !w1.owner_equal(b1) && !b1.owner_equal(w1) ); +} + +int +main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/observers/owner_hash.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/observers/owner_hash.cc new file mode 100644 index 000000000000..148a93be0991 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/weak_ptr/observers/owner_hash.cc @@ -0,0 +1,50 @@ +// { dg-do run { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.3.6 weak_ptr observers [util.smartptr.weak.obs] + +#include +#include + +struct A { }; +struct B { }; + +void +test01() +{ + // test empty weak_ptr hashes compare equivalent + std::weak_ptr p1; + std::weak_ptr p2; + VERIFY( p1.owner_hash() == p2.owner_hash() ); + + std::shared_ptr p3; + VERIFY( p1.owner_hash() == p3.owner_hash() ); + + static_assert( noexcept(p1.owner_hash()) ); + static_assert( noexcept(p2.owner_hash()) ); +} + + +void +test02() +{ + std::shared_ptr a0; + std::weak_ptr w0(a0); + + std::shared_ptr a1(new A); + std::weak_ptr w1(a1); + VERIFY( a1.owner_hash() == w1.owner_hash() ); + VERIFY( w1.owner_hash() != w0.owner_hash() ); + VERIFY( w1.owner_hash() != a0.owner_hash() ); + + std::shared_ptr b1(new B); + VERIFY( w1.owner_hash() != b1.owner_hash() ); +} + +int +main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.h b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.h index 9fe9ac87a3b8..2ba23bfc8d68 100644 --- a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.h +++ b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.h @@ -1439,7 +1439,7 @@ ucs2_to_utf8_out_error (const std::codecvt &cvt) // make the trailing surrogate a BMP char {5, 10, 3, 6, u'z', 4}, - // don't replace anything in the test cases bellow, just show the surrogate + // don't replace anything in the test cases below, just show the surrogate // pair (fourth CP) fully or partially {5, 10, 3, 6, u'b', 0}, {5, 7, 3, 6, u'b', 0}, // no space for fourth CP @@ -2072,7 +2072,7 @@ utf16_to_ucs2_in_error (const std::codecvt &cvt, // make the trailing surrogate a BMP char {10, 5, 6, 3, u'z', 4}, - // don't replace anything in the test cases bellow, just show the surrogate + // don't replace anything in the test cases below, just show the surrogate // pair (fourth CP) fully or partially (just the first surrogate) {10, 5, 6, 3, u'b', 0}, {8, 5, 6, 3, u'b', 0}, diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc index 25511e79941d..e1e9ce9bdac1 100644 --- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc @@ -26,6 +26,6 @@ int n1 = std::get<1>(a); int n2 = std::get<1>(std::move(a)); int n3 = std::get<1>(ca); -// { dg-error "static assertion failed" "" { target *-*-* } 394 } -// { dg-error "static assertion failed" "" { target *-*-* } 403 } -// { dg-error "static assertion failed" "" { target *-*-* } 412 } +// { dg-error "static assertion failed" "" { target *-*-* } 396 } +// { dg-error "static assertion failed" "" { target *-*-* } 405 } +// { dg-error "static assertion failed" "" { target *-*-* } 414 } diff --git a/libstdc++-v3/testsuite/23_containers/flat_map/1.cc b/libstdc++-v3/testsuite/23_containers/flat_map/1.cc index 1b593135f225..01278d7dc33c 100644 --- a/libstdc++-v3/testsuite/23_containers/flat_map/1.cc +++ b/libstdc++-v3/testsuite/23_containers/flat_map/1.cc @@ -254,6 +254,15 @@ test07() VERIFY( std::ranges::equal(m, (std::pair[]){{3,4}}) ); } +void +test08() +{ + // PR libstdc++/120432 - flat_map operator[] is broken for const lvalue keys + std::flat_map m; + const int k = 42; + m[k] = 0; +} + int main() { @@ -267,4 +276,5 @@ main() test05(); test06(); test07(); + test08(); } diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/access/capacity.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/access/capacity.cc new file mode 100644 index 000000000000..2797e205971d --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/access/capacity.cc @@ -0,0 +1,51 @@ +// { dg-do run { target c++26 } } + +#include + +#include +#include + +template +constexpr void +test_reserve() +{ + std::inplace_vector v; + + static_assert(v.max_size() == N); + static_assert(v.capacity() == N); + + // static methods + v.shrink_to_fit(); + v.reserve(0); + v.reserve(N); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + try + { + v.reserve(N + 2); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } +#endif +} + +int main() +{ + auto test_all = [] { + test_reserve<0, int>(); + test_reserve<4, int>(); + return true; + }; + + test_all(); + static_assert(test_all());; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem.cc new file mode 100644 index 000000000000..a598514bd9b4 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem.cc @@ -0,0 +1,103 @@ +// { dg-do run { target c++26 } } + +#include + +#include +#include +#include +#include + +template +constexpr void +test_out_of_capacity() +{ + std::inplace_vector v; + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + try + { + (void)v.at(N + 2); + VERIFY(false); + } + catch (std::out_of_range const&) + { + } + + try + { + (void)as_const(v).at(N + 2); + VERIFY(false); + } + catch (std::out_of_range const&) + { + } +#endif +} + +template +constexpr void +test_access() +{ + std::inplace_vector v{1, 2, 3, 4, 5}; + + auto& e3a = v[2]; + auto& e3b = std::as_const(v).at(2); + VERIFY( &e3a == &e3b ); + VERIFY( &e3a == &v.begin()[2] ); + VERIFY( &e3a == std::as_const(v).data() + 2 ); + VERIFY( e3a == T(3) ); + + auto& e4a = as_const(v)[4]; + auto& e4b = v.at(4); + VERIFY( &e4a == &e4b ); + VERIFY( &e4a == &v.cbegin()[4] ); + VERIFY( &e4a == v.data() + 4 ); + VERIFY( e4a == T(5) ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + try + { + (void)v.at(7); + VERIFY(false); + } + catch (std::out_of_range const&) + { + } + + try + { + (void)as_const(v).at(7); + VERIFY(false); + } + catch (std::out_of_range const&) + { + } +#endif +} + +int main() +{ + auto test_all = [] { + test_out_of_capacity<0, int>(); + test_out_of_capacity<4, int>(); + test_access(); + return true; + }; + + test_all(); + static_assert(test_all());; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem_neg.cc new file mode 100644 index 000000000000..e3ba5eb6866d --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem_neg.cc @@ -0,0 +1,29 @@ +// { dg-do compile { target c++26 } } + +#include + +template +constexpr bool +test_out_of_capacity() +{ + std::inplace_vector v; + (void)v[N+2]; // { dg-error "in 'constexpr' expansion of" } + return true; +} + +template +constexpr bool +test_out_of_size() +{ + std::inplace_vector v{1, 2, 3, 4, 5}; + (void)v[7]; // { dg-error "in 'constexpr' expansion of" } + return true; +} + +static_assert(test_out_of_capacity<0, int>()); // { dg-error "in 'constexpr' expansion of" } +static_assert(test_out_of_capacity<4, int>()); // { dg-error "in 'constexpr' expansion of" } +static_assert(test_out_of_size()); // { dg-error "in 'constexpr' expansion of" } + +// { dg-prune-output "non-constant condition for static assertion" } +// { dg-prune-output "is not a constant expression" } +// { dg-prune-output "call to non-'constexpr' function" } diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/1.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/1.cc new file mode 100644 index 000000000000..e9c2cdc8665a --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/1.cc @@ -0,0 +1,385 @@ +// { dg-do run { target c++26 } } + +#include +#include + +struct X +{ + constexpr X() { } // not trivially default constructible +}; + +struct N +{ + constexpr N() noexcept { } // not trivially default constructible +}; + +struct D +{ + ~D() {} // not trivially destructible +}; + +struct U +{ + U() noexcept(false) = default; // lies about noexcept +}; + +// n5008 inplace.vector.overview says for inplace_vector +// provides trivial copy/move/default cosntructpr regardless of T +struct Z +{ + constexpr Z(int) {} + Z() = delete; +}; + +static_assert(std::is_default_constructible_v>); +static_assert(std::is_default_constructible_v>); +static_assert(std::is_default_constructible_v>); +static_assert(std::is_default_constructible_v>); +static_assert(std::is_default_constructible_v>); +// The operators are not constrained, as for any other container +static_assert(std::is_default_constructible_v>); + +static_assert(std::is_nothrow_default_constructible_v>); +static_assert(std::is_nothrow_default_constructible_v>); +static_assert(std::is_nothrow_default_constructible_v>); +static_assert(std::is_nothrow_default_constructible_v>); +static_assert(std::is_nothrow_default_constructible_v>); + +// Needs to set size to zero, not trivial +static_assert(!std::is_trivially_default_constructible_v>); +static_assert(!std::is_trivially_default_constructible_v>); +static_assert(!std::is_trivially_default_constructible_v>); +static_assert(!std::is_trivially_default_constructible_v>); +static_assert(!std::is_trivially_default_constructible_v>); + +static_assert(std::is_trivially_destructible_v>); +static_assert(std::is_trivially_destructible_v>); +static_assert(std::is_trivially_destructible_v>); +static_assert(!std::is_trivially_destructible_v>); +static_assert(std::is_trivially_destructible_v>); + +static_assert(std::is_nothrow_default_constructible_v>); +static_assert(std::is_nothrow_default_constructible_v>); +static_assert(std::is_nothrow_default_constructible_v>); +static_assert(std::is_nothrow_default_constructible_v>); +static_assert(std::is_nothrow_default_constructible_v>); + +// Size is always zero, so trivial +static_assert(std::is_trivially_default_constructible_v>); +static_assert(std::is_trivially_default_constructible_v>); +static_assert(std::is_trivially_default_constructible_v>); +static_assert(std::is_trivially_default_constructible_v>); +static_assert(std::is_trivially_default_constructible_v>); +static_assert(std::is_trivially_default_constructible_v>); + +static_assert(std::is_trivially_destructible_v>); +static_assert(std::is_trivially_destructible_v>); +static_assert(std::is_trivially_destructible_v>); +static_assert(std::is_trivially_destructible_v>); +static_assert(std::is_trivially_destructible_v>); + +static_assert(std::is_empty_v>); +static_assert(std::is_empty_v>); +static_assert(std::is_empty_v>); +static_assert(std::is_empty_v>); +static_assert(std::is_empty_v>); +static_assert(std::is_empty_v>); + +constexpr void +test_default() +{ + std::inplace_vector c; + VERIFY( c.size() == 0 ); + VERIFY( c.capacity() == 5 ); + VERIFY( c.empty() ); + VERIFY( c.begin() == c.end() ); + + std::inplace_vector c0; + VERIFY( c0.size() == 0 ); + VERIFY( c0.capacity() == 0 ); + VERIFY( c0.empty() ); + VERIFY( c0.begin() == c0.end() ); + + std::inplace_vector z0; + VERIFY( z0.size() == 0 ); + VERIFY( z0.capacity() == 0 ); + VERIFY( z0.empty() ); + VERIFY( z0.begin() == z0.end() ); + +#ifdef __cpp_lib_constexpr_inplace_vector +#error remove the consteval check +#endif + if consteval { + return; + } + + std::inplace_vector cx; + VERIFY( cx.size() == 0 ); + VERIFY( cx.capacity() == 5 ); + VERIFY( cx.empty() ); + VERIFY( cx.begin() == cx.end() ); + + std::inplace_vector cx0; + VERIFY( cx0.size() == 0 ); + VERIFY( cx0.capacity() == 0 ); + VERIFY( cx0.empty() ); + VERIFY( cx0.begin() == cx0.end() ); +} + +constexpr void +test_n() +{ + std::inplace_vector c(2); + VERIFY( c.size() == 2 ); + VERIFY( c.capacity() == 5 ); + VERIFY( not c.empty() ); + VERIFY( c.begin() + 2 == c.end() ); + VERIFY( c[0] == 0 ); + VERIFY( c[1] == 0 ); + + std::inplace_vector c2(2); + VERIFY( c2.size() == 2 ); + VERIFY( c2.capacity() == 2 ); + VERIFY( not c2.empty() ); + VERIFY( c2.begin() + 2 == c2.end() ); + VERIFY( c2[0] == 0 ); + VERIFY( c2[1] == 0 ); + + std::inplace_vector c0(0); + VERIFY( c0.size() == 0 ); + VERIFY( c0.capacity() == 0 ); + VERIFY( c0.empty() ); + VERIFY( c0.begin() == c0.end() ); + + std::inplace_vector c20(0); + VERIFY( c20.size() == 0 ); + VERIFY( c20.capacity() == 2 ); + VERIFY( c20.empty() ); + VERIFY( c20.begin() == c20.end() ); + + std::inplace_vector z0(0); + VERIFY( z0.size() == 0 ); + VERIFY( z0.capacity() == 0 ); + VERIFY( z0.empty() ); + VERIFY( z0.begin() == z0.end() ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if not consteval { + try + { + std::inplace_vector ct(3); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + + try + { + std::inplace_vector ct(1); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + + } +#endif + +#ifdef __cpp_lib_constexpr_inplace_vector +#error remove the consteval check +#endif + if consteval { + return; + } + + std::inplace_vector cx(3); + VERIFY( cx.size() == 3 ); + VERIFY( cx.capacity() == 5 ); + VERIFY( not cx.empty() ); + VERIFY( cx.begin() + 3 == cx.end() ); + (void) cx[2]; +} + +constexpr void +test_n_val() +{ + std::inplace_vector c(2, 99); + VERIFY( c.size() == 2 ); + VERIFY( c.capacity() == 5 ); + VERIFY( not c.empty() ); + VERIFY( c.begin() + 2 == c.end() ); + VERIFY( c[0] == 99 ); + VERIFY( c[1] == 99 ); + + std::inplace_vector c1(1, 44); + VERIFY( c1.size() == 1 ); + VERIFY( c1.capacity() == 1 ); + VERIFY( not c1.empty() ); + VERIFY( c1.begin() + 1 == c1.end() ); + VERIFY( c1[0] == 44 ); + + std::inplace_vector c0(0, 33); + VERIFY( c0.size() == 0 ); + VERIFY( c0.capacity() == 0 ); + VERIFY( c0.empty() ); + VERIFY( c0.begin() == c0.end() ); + + std::inplace_vector c20(0, 22); + VERIFY( c20.size() == 0 ); + VERIFY( c20.capacity() == 2 ); + VERIFY( c20.empty() ); + VERIFY( c20.begin() == c20.end() ); + + std::inplace_vector z0(0, 33); + VERIFY( z0.size() == 0 ); + VERIFY( z0.capacity() == 0 ); + VERIFY( z0.empty() ); + VERIFY( z0.begin() == z0.end() ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if not consteval { + try + { + std::inplace_vector ct(3, 11); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + + try + { + std::inplace_vector ct(2, 11); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + } +#endif + +#ifdef __cpp_lib_constexpr_inplace_vector +#error remove the consteval check +#endif + if consteval { + return; + } + + std::inplace_vector cx(4); + VERIFY( cx.size() == 4 ); + VERIFY( cx.capacity() == 5 ); + VERIFY( not cx.empty() ); + VERIFY( cx.begin() + 4 == cx.end() ); + (void) cx[3]; +} + +constexpr void +test_initializer_list() +{ + std::inplace_vector c{22, 33}; + VERIFY( c.size() == 2 ); + VERIFY( c.capacity() == 5 ); + VERIFY( not c.empty() ); + VERIFY( c.begin() + 2 == c.end() ); + VERIFY( c[0] == 22 ); + VERIFY( c[1] == 33 ); + + std::inplace_vector c1{44}; + VERIFY( c1.size() == 1 ); + VERIFY( c1.capacity() == 1 ); + VERIFY( not c1.empty() ); + VERIFY( c1.begin() + 1 == c1.end() ); + VERIFY( c1[0] == 44 ); + + std::inplace_vector c0({}); + VERIFY( c0.size() == 0 ); + VERIFY( c0.capacity() == 0 ); + VERIFY( c0.empty() ); + VERIFY( c0.begin() == c0.end() ); + + std::inplace_vector c20({}); + VERIFY( c20.size() == 0 ); + VERIFY( c20.capacity() == 2 ); + VERIFY( c20.empty() ); + VERIFY( c20.begin() == c20.end() ); + + std::inplace_vector z0({}); + VERIFY( z0.size() == 0 ); + VERIFY( z0.capacity() == 0 ); + VERIFY( z0.empty() ); + VERIFY( z0.begin() == z0.end() ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if not consteval { + try + { + std::inplace_vector ct{11, 22, 33}; + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + + try + { + std::inplace_vector ct{11, 22}; + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + } +#endif + +#ifdef __cpp_lib_constexpr_inplace_vector +#error remove the consteval check +#endif + if consteval { + return; + } + + std::inplace_vector cx{X(), X(), X(), X()}; + VERIFY( cx.size() == 4 ); + VERIFY( cx.capacity() == 5 ); + VERIFY( not cx.empty() ); + VERIFY( cx.begin() + 4 == cx.end() ); + (void) cx[3]; +} + +constexpr std::inplace_vector e0; +constexpr std::inplace_vector e1; +constexpr std::inplace_vector e2; + +constexpr std::inplace_vector g1; +constexpr std::inplace_vector g2(2, 100); +constexpr std::inplace_vector g3 = g2; +constexpr std::inplace_vector g4{1, 2, 3}; +constexpr std::inplace_vector g5 = [] { + std::inplace_vector res; + res = g3; + return res; +}(); + +int main() +{ + auto tests = [] { + test_default(); + test_n(); + test_n_val(); + test_initializer_list(); + return true; + }; + + tests(); + constexpr bool _ = tests(); +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/from_range.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/from_range.cc new file mode 100644 index 000000000000..4a2f193e4a58 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/from_range.cc @@ -0,0 +1,177 @@ +// { dg-do run { target c++26 } } + +#include + +#include +#include +#include +#include + +template +constexpr bool +eq(const std::inplace_vector& l, std::span r) { + if (l.size() != r.size()) + return false; + for (auto i = 0u; i < l.size(); ++i) + if (l[i] != r[i]) + return false; + return true; +}; + +template class ItType> +constexpr void +do_test_it() +{ + // The vector's value_type. + using V = int; + + T a[]{1,2,3,4,5,6,7,8,9}; + using It = ItType; + + auto bounds = typename It::ContainerType(a, a+9); + std::inplace_vector e0(It(a, &bounds), It(a, &bounds)); + VERIFY( e0.empty() ); + + bounds = typename It::ContainerType(a, a+9); + std::inplace_vector v0(It(a, &bounds), It(a, &bounds)); + VERIFY( v0.empty() ); + + bounds = typename It::ContainerType(a, a+9); + std::inplace_vector v4(It(a, &bounds), It(a+4, &bounds)); + VERIFY( eq(v4, {a, 4}) ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + bounds = typename It::ContainerType(a, a+9); + try + { + std::inplace_vector v9(It(a, &bounds), It(a+9, &bounds)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + + bounds = typename It::ContainerType(a, a+9); + try + { + std::inplace_vector v2(It(a, &bounds), It(a+2, &bounds)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } +#endif +} + +constexpr bool +test_iterators() +{ + using namespace __gnu_test; + + do_test_it(); + do_test_it(); + do_test_it(); + + do_test_it(); + return true; +} + +template +constexpr void +do_test_r() +{ + // The vector's value_type. + using V = int; + + // The range's value_type. + using T = std::ranges::range_value_t; + T a[]{1,2,3,4,5,6,7,8,9}; + + std::inplace_vector e0(std::from_range, Range(a, a+0)); + VERIFY( e0.empty() ); + + std::inplace_vector v0(std::from_range, Range(a, a+0)); + VERIFY( v0.empty() ); + + std::inplace_vector v4(std::from_range, Range(a, a+4)); + VERIFY( eq(v4, {a, 4}) ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + try + { + std::inplace_vector v9(std::from_range, Range(a, a+9)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + + try + { + std::inplace_vector v3(std::from_range, Range(a, a+3)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } +#endif +} + +constexpr bool +test_ranges() +{ + using namespace __gnu_test; + + do_test_r>(); + do_test_r>(); + + do_test_r>(); + do_test_r>(); + do_test_r>(); + + do_test_r>(); + do_test_r>(); + do_test_r>(); + + do_test_r>(); + do_test_r>(); + + // Not lvalue-convertible to int + struct C { + constexpr C(int v) : val(v) { } + constexpr operator int() && { return val; } + constexpr bool operator==(int b) const { return b == val; } + int val; + }; + using rvalue_input_range = test_range; + do_test_r(); + + return true; +} + +int main() +{ + auto test_all = [] { + test_iterators(); + test_ranges(); + return true; + }; + + test_all(); + static_assert( test_all() ); +} + diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/throws.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/throws.cc new file mode 100644 index 000000000000..4ce39d1010e5 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/throws.cc @@ -0,0 +1,129 @@ +// { dg-do run { target c++26 } } + +#include + +#include +#include +#include +#include + +struct CopyFailed {}; + +struct Thrower +{ + static inline size_t throw_after = 0; + static inline size_t incontainer = 0; + + Thrower() {} + Thrower(int x) {} + Thrower(const Thrower&) + { + if (incontainer >= throw_after) + throw CopyFailed(); + ++incontainer; + } + + ~Thrower() + { --incontainer; } +}; + +template class ItType> +void +do_test_it() +{ + // The vector's value_type. + using V = Thrower; + + V a[]{1,2,3,4,5,6,7,8,9}; + using It = ItType; + + auto bounds = typename It::ContainerType(a, a+9); + Thrower::throw_after = 100; + Thrower::incontainer = 0; + try + { + std::inplace_vector v9(It(a, &bounds), It(a+9, &bounds)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( Thrower::incontainer == 0 ); + + bounds = typename It::ContainerType(a, a+9); + Thrower::throw_after = 2; + Thrower::incontainer = 0; + try + { + std::inplace_vector v2(It(a, &bounds), It(a+3, &bounds)); + VERIFY(false); + } + catch (CopyFailed const&) + { + } + VERIFY( Thrower::incontainer == 0 ); +} + +bool +test_iterators() +{ + using namespace __gnu_test; + do_test_it(); + do_test_it(); + do_test_it(); + return true; +} + +template +void +do_test_r() +{ + // The vector's value_type. + using V = Thrower; + + V a[]{1,2,3,4,5,6,7,8,9}; + + Thrower::throw_after = 100; + Thrower::incontainer = 0; + try + { + std::inplace_vector v9(std::from_range, Range(a, a+9)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( Thrower::incontainer == 0 ); + + Thrower::throw_after = 2; + Thrower::incontainer = 0; + try + { + std::inplace_vector v9(std::from_range, Range(a, a+3)); + VERIFY(false); + } + catch (CopyFailed const&) + { + } + VERIFY( Thrower::incontainer == 0 ); +} + +bool +test_ranges() +{ + using namespace __gnu_test; + do_test_r>(); + do_test_r>(); + + do_test_r>(); + do_test_r>(); + do_test_r>(); + return true; +} + +int main() +{ + test_iterators(); + test_ranges(); +} + diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/copy.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/copy.cc new file mode 100644 index 000000000000..d149e63970c9 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/copy.cc @@ -0,0 +1,247 @@ +// { dg-do run { target c++26 } } + +#include +#include +#include + +struct X +{ + X() = default; + constexpr X(int p) : v(p) {} + constexpr X(const X& o) : v(o.v) { } // not trivial + constexpr X& operator=(const X& o) // not trivial + { v = o.v; return *this; } + + int v; + + friend auto operator<=>(const X&, const X&) = default; +}; + +template +struct N +{ + N() = default; + constexpr N(const N&) noexcept(CNoex) { } // not trivial + constexpr N& operator=(const N& o) noexcept(ANoex) // not trivial + { return *this; } +}; + +struct D +{ + D() = default; + D(const D&) = default; + D& operator=(const D&) = default; + ~D() {} // not trivially destructible +}; + +struct U +{ + U() = default; + U(const U&) noexcept(false) = default; // lies about noexcept, is trivial but throwing + U& operator=(const U&) noexcept(false) = default; // lies about noexcept, is trivial but throwing +}; + +// n5008 inplace.vector.overview p5 says for inplace_vector +// provides trivial copy/move/default cosntructpr regardless of T +struct Z +{ + Z(Z&&) = delete; + Z& operator=(Z&&) = delete; +}; + +template + constexpr std::inplace_vector const& + materialize(std::inplace_vector const& r) + { return r; } + +static_assert(std::is_copy_constructible_v>); +static_assert(std::is_copy_constructible_v>); +static_assert(std::is_copy_constructible_v, 2>>); +static_assert(std::is_copy_constructible_v>); +static_assert(std::is_copy_constructible_v>); +// The operators are not constrained, as for any other container +static_assert(std::is_copy_constructible_v>); + +// conditional noexcept here is libstdc++ extension, +static_assert(std::is_nothrow_copy_constructible_v>); +static_assert(!std::is_nothrow_copy_constructible_v>); +static_assert(std::is_nothrow_copy_constructible_v, 2>>); +static_assert(std::is_nothrow_copy_constructible_v, 2>>); +static_assert(!std::is_nothrow_copy_constructible_v, 2>>); +static_assert(!std::is_nothrow_copy_constructible_v, 2>>); +static_assert(std::is_nothrow_copy_constructible_v>); +static_assert(!std::is_nothrow_copy_constructible_v>); + +static_assert(std::is_trivially_copy_constructible_v>); +static_assert(!std::is_trivially_copy_constructible_v>); +static_assert(!std::is_trivially_copy_constructible_v, 2>>); +// is_trivially_copy_constructible_v checks destructor +static_assert(!std::is_trivially_copy_constructible_v>); +static_assert(std::is_trivially_copy_constructible_v>); + +static_assert(std::is_copy_assignable_v>); +static_assert(std::is_copy_assignable_v>); +static_assert(std::is_copy_assignable_v, 2>>); +static_assert(std::is_copy_assignable_v>); +static_assert(std::is_copy_assignable_v>); +// The operators are not constrained, as for any other container +static_assert(std::is_copy_assignable_v>); + +static_assert(std::is_nothrow_copy_assignable_v>); +static_assert(!std::is_nothrow_copy_assignable_v>); +static_assert(std::is_nothrow_copy_assignable_v, 2>>); +static_assert(!std::is_nothrow_copy_assignable_v, 2>>); +static_assert(!std::is_nothrow_copy_assignable_v, 2>>); +static_assert(!std::is_nothrow_copy_assignable_v, 2>>); +static_assert(std::is_nothrow_copy_assignable_v>); +static_assert(!std::is_nothrow_copy_assignable_v>); + +// conditional noexcept here is libstdc++ extension, +static_assert(std::is_trivially_copy_assignable_v>); +static_assert(!std::is_trivially_copy_assignable_v>); +static_assert(!std::is_trivially_copy_assignable_v, 2>>); +// destructor is not trivial +static_assert(!std::is_trivially_copy_assignable_v>); +static_assert(std::is_trivially_copy_assignable_v>); + +static_assert(std::is_nothrow_copy_constructible_v>); +static_assert(std::is_nothrow_copy_constructible_v>); +static_assert(std::is_nothrow_copy_constructible_v, 0>>); +static_assert(std::is_nothrow_copy_constructible_v>); +static_assert(std::is_nothrow_copy_constructible_v>); +static_assert(std::is_nothrow_copy_constructible_v>); + +static_assert(std::is_trivially_copy_constructible_v>); +static_assert(std::is_trivially_copy_constructible_v>); +static_assert(std::is_trivially_copy_constructible_v>); +static_assert(std::is_trivially_copy_constructible_v>); +static_assert(std::is_trivially_copy_constructible_v>); + +static_assert(std::is_nothrow_copy_assignable_v>); +static_assert(std::is_nothrow_copy_assignable_v>); +static_assert(std::is_nothrow_copy_assignable_v, 0>>); +static_assert(std::is_nothrow_copy_assignable_v>); +static_assert(std::is_nothrow_copy_assignable_v>); +static_assert(std::is_nothrow_copy_assignable_v>); + +static_assert(std::is_trivially_copy_assignable_v>); +static_assert(std::is_trivially_copy_assignable_v>); +static_assert(std::is_trivially_copy_assignable_v, 0>>); +static_assert(std::is_trivially_copy_assignable_v>); +static_assert(std::is_trivially_copy_assignable_v>); +static_assert(std::is_trivially_copy_assignable_v>); + + +template +constexpr bool +eq(const std::inplace_vector& s, std::span o) +{ return std::ranges::equal(s, o); } + +constexpr void +test_ctor() +{ + auto e0 = materialize<0, int>({}); + VERIFY( e0.empty() ); + auto e1 = materialize<0, X>({}); + VERIFY( e1.empty() ); + auto e2 = materialize<0, Z>({}); + VERIFY( e2.empty() ); + + auto c0 = materialize<5, int>({}); + VERIFY( c0.empty() ); + + auto c3 = materialize<5, int>({1, 2, 3}); + VERIFY( eq(c3, {1, 2, 3}) ); + + auto c5 = materialize<5, int>({1, 2, 3, 4, 5}); + VERIFY( eq(c5, {1, 2, 3, 4, 5}) ); + +#ifdef __cpp_lib_constexpr_inplace_vector +#error remove the consteval check +#endif + if consteval { + return; + } + + auto x0 = materialize<3, X>({}); + VERIFY( x0.empty() ); + + auto x2 = materialize<3, X>({1, 2}); + VERIFY( eq(x2, {1, 2}) ); + + auto x3 = materialize<3, X>({1, 2, 3}); + VERIFY( eq(x3, {1, 2, 3}) ); +} + +constexpr void +test_assign() +{ + std::inplace_vector e0; + e0 = materialize<0, int>({}); + VERIFY( e0.empty() ); + std::inplace_vector e1; + e1 = materialize<0, X>({}); + VERIFY( e1.empty() ); + std::inplace_vector e2; + e2 = materialize<0, Z>({}); + VERIFY( e2.empty() ); + + std::inplace_vector c; + c = materialize<5, int>({}); + VERIFY( c.empty() ); + + c = materialize<5, int>({1, 2, 3}); + VERIFY( eq(c, {1, 2, 3}) ); + + c = materialize<5, int>({1, 2, 3, 4, 5}); + VERIFY( eq(c, {1, 2, 3, 4, 5}) ); + + c = materialize<5, int>({4, 5}); + VERIFY( eq(c, {4, 5}) ); + + c = materialize<5, int>({}); + VERIFY( c.empty() ); + +#ifdef __cpp_lib_constexpr_inplace_vector +#error remove the consteval check +#endif + if consteval { + return; + } + + std::inplace_vector x; + x = materialize<5, X>({}); + VERIFY( x.empty() ); + + x = materialize<5, X>({1, 2, 3}); + VERIFY( eq(x, {1, 2, 3}) ); + + x = materialize<5, X>({1, 2, 3, 4, 5}); + VERIFY( eq(x, {1, 2, 3, 4, 5}) ); + + x = materialize<5, X>({4, 5}); + VERIFY( eq(x, {4, 5}) ); + + x = materialize<5, X>({}); + VERIFY( x.empty() ); +} + +constexpr auto e0 = materialize<0, int>({}); +constexpr auto e1 = materialize<0, X>({}); +constexpr auto e2 = materialize<0, Z>({}); + +constexpr auto t1 = materialize<3, int>({}); +constexpr auto t2 = materialize<3, int>({1, 2}); +constexpr auto t3 = materialize<3, int>({11, 22, 33}); + +int main() +{ + auto tests = [] { + test_ctor(); + test_assign(); + return true; + }; + + tests(); + constexpr bool _ = tests(); +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/erasure.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/erasure.cc new file mode 100644 index 000000000000..c7fda0978967 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/erasure.cc @@ -0,0 +1,49 @@ +// { dg-do run { target c++26 } } + +#include +#include + +constexpr void +test_erase() +{ + std::inplace_vector c{1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1, 4, 4, 9}; + std::erase(c, 4); + VERIFY( c.size() == 10 ); + std::erase(c, 1); + VERIFY( c.size() == 8 ); + std::erase(c, 9); + VERIFY( c.size() == 7 ); + VERIFY( (c == std::inplace_vector{2, 3, 5, 6, 5, 3, 2}) ); + + std::inplace_vector e; + std::erase(e, 10); + VERIFY( e.empty() ); +} + +constexpr void +test_erase_if() +{ + std::inplace_vector c{1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1, 4, 4, 9}; + std::erase_if(c, [](int i) { return i > 5; }); + VERIFY( c.size() == 12 ); + std::erase_if(c, [](int i) { return i == 4; }); + VERIFY( c.size() == 8 ); + std::erase_if(c, [](int i) { return i & 1; }); + VERIFY( (c == std::inplace_vector{2, 2}) ); + + std::inplace_vector e; + std::erase_if(e, [](int i) { return i > 5; }); + VERIFY( e.empty() ); +} + +int main() +{ + test_erase(); + test_erase_if(); + + constexpr bool _ = [] { + test_erase(); + test_erase_if(); + return true; + }(); +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/assign.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/assign.cc new file mode 100644 index 000000000000..65b505e7f371 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/assign.cc @@ -0,0 +1,379 @@ +// { dg-do run { target c++26 } } + +#include + +#include +#include +#include + +struct X +{ + X() = default; + constexpr X(int p) : v(p) {} + constexpr X(const X& o) : v(o.v) { } // not trivial + constexpr X& operator=(const X& o) // not trivial + { v = o.v; return *this; } + + int v; + + friend auto operator<=>(const X&, const X&) = default; +}; + +template +constexpr bool +eq(const std::inplace_vector& l, std::span r) { + if (l.size() != r.size()) + return false; + for (auto i = 0u; i < l.size(); ++i) + if (l[i] != r[i]) + return false; + return true; +}; + +template class ItType> +constexpr void +test_assign_empty_it() +{ + using namespace __gnu_test; + + T a[]{1,2,3,4,5,6,7,8,9,10}; + using It = ItType; + using Range = test_range; + using SizedRange = test_sized_range; + + const std::inplace_vector src(std::from_range, std::span(a, N)); + std::inplace_vector v; + + v = src; + v.assign_range(Range(a, a)); + VERIFY( v.empty() ); + v.assign_range(Range(a, a)); + VERIFY( v.empty() ); + + v = src; + v.assign_range(SizedRange(a, a)); + VERIFY( v.empty() ); + + v = src; + auto bounds = typename It::ContainerType(a, a+9); + v.assign(It(a, &bounds), It(a, &bounds)); + VERIFY( v.empty() ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + static_assert(N < 9); + + v = src; + try + { + v.assign_range(Range(a, a+9)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + if constexpr (std::ranges::sized_range || std::ranges::forward_range) + VERIFY( eq(v, {a, N}) ); + + v = src; + try + { + v.assign_range(SizedRange(a, a+9)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + v = src; + bounds = typename It::ContainerType(a, a+9); + try + { + v.assign(It(a, &bounds), It(a+9, &bounds)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + if constexpr(std::forward_iterator) + VERIFY( eq(v, {a, N}) ); +#endif +} + +template +constexpr void +test_assign_empty_other() +{ + T a[]{1,2,3,4,5,6,7,8,9,10}; + const std::inplace_vector src(std::from_range, std::span(a, N)); + std::inplace_vector v; + + v = src; + v.assign(0, T(4)); + VERIFY( v.empty() ); + + v = src; + v.assign({}); + VERIFY( v.empty() ); + + v = src; + v = {}; + VERIFY( v.empty() ); + + v = src; + v.resize(0, T(3)); + VERIFY( v.empty() ); + + v = src; + v.resize(0); + VERIFY( v.empty() ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + static_assert(N < 9); + + v = src; + try + { + v.assign(9, T(4)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + std::initializer_list il = + {T(0), T(1), T(2), T(3), T(4), T(5), T(6), T(7), T(8), T(9), T(10)}; + try + { + v.assign(il); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + try + { + v = il; + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + try + { + v.resize(9, T(3)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + try + { + v.resize(9); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); +#endif +} + +template +constexpr void +test_assign_empty() +{ + using namespace __gnu_test; + test_assign_empty_it(); + test_assign_empty_it(); + test_assign_empty_it(); + + test_assign_empty_other; +} + +template +constexpr void +test_assign_range() +{ + using T = std::ranges::range_value_t; + T a[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + + std::inplace_vector v; + v.assign_range(Range(a,a+5)); + VERIFY( eq(v, {a, 5}) ); + + v.assign_range(Range(a,a+7)); + VERIFY( eq(v, {a, 7}) ); + + v.assign_range(Range(a,a+3)); + VERIFY( eq(v, {a, 3}) ); + + v.assign_range(Range(a,a+10)); + VERIFY( eq(v, {a, 10}) ); +} + +template class ItType> +constexpr void +test_assign_iterators() +{ + T a[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + using It = ItType; + + std::inplace_vector v; + + auto bounds = typename It::ContainerType(a, a+15); + v.assign(It(a, &bounds), It(a+5, &bounds)); + VERIFY( eq(v, {a, 5}) ); + + bounds = typename It::ContainerType(a, a+15); + v.assign(It(a, &bounds), It(a+7, &bounds)); + VERIFY( eq(v, {a, 7}) ); + + bounds = typename It::ContainerType(a, a+15); + v.assign(It(a, &bounds), It(a+3, &bounds)); + VERIFY( eq(v, {a, 3}) ); + + bounds = typename It::ContainerType(a, a+15); + v.assign(It(a, &bounds), It(a+10, &bounds)); + VERIFY( eq(v, {a, 10}) ); +} + +template +constexpr void +test_assign_initializer_list() +{ + T a[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + + std::inplace_vector v; + + v.assign({T(1), T(2), T(3), T(4), T(5)}); + VERIFY( eq(v, {a, 5}) ); + + v = {T(1), T(2), T(3), T(4), T(5), T(6), T(7)}; + VERIFY( eq(v, {a, 7}) ); + + v.assign({T(1), T(2), T(3)}); + VERIFY( eq(v, {a, 3}) ); + + v = {T(1), T(2), T(3), T(4), T(5), T(6), T(7), T(8), T(9), T(10)}; + VERIFY( eq(v, {a, 10}) ); +} + +template +constexpr void +test_assign_repeated() +{ + auto rep = [](const std::inplace_vector& v, size_t c, const T& t) + { + if (v.size() != c) + return false; + for (const T& o : v) + if (o != t) + return false; + return true; + }; + + std::inplace_vector v; + + v.assign(5, T(1)); + VERIFY( rep(v, 5, T(1)) ); + + v.assign(7, T(2)); + VERIFY( rep(v, 7, T(2)) ); + + v.assign(3, T(4)); + VERIFY( rep(v, 3, T(4)) ); + + v.assign(10, T(8)); + VERIFY( rep(v, 10, T(8)) ); +} + +template +constexpr void +test_resize() +{ + T a[]{1,1,1,1,2,2,2,0,0,0}; + + std::inplace_vector v; + + v.resize(4, T(1)); + VERIFY( eq(v, {a, 4}) ); + + v.resize(7, T(2)); + VERIFY( eq(v, {a, 7}) ); + + v.resize(10); + VERIFY( eq(v, {a, 10}) ); + + v.resize(6, T(1)); + VERIFY( eq(v, {a, 6}) ); +} + +template +constexpr void +test_assigns() +{ + using namespace __gnu_test; + test_assign_range>(); + test_assign_range>(); + + test_assign_range>(); + test_assign_range>(); + test_assign_range>(); + + test_assign_range>(); + test_assign_range>(); + test_assign_range>(); + + test_assign_iterators(); + test_assign_iterators(); + test_assign_iterators(); + + test_assign_initializer_list(); + test_assign_repeated(); + test_resize(); +} + +int main() +{ + auto test_all = [] { + test_assign_empty<0, int>(); + test_assign_empty<0, X>(); + test_assign_empty<2, int>(); + + test_assigns(); +#ifdef __cpp_lib_constexpr_inplace_vector +#error uncomemnt test_inserts() +#endif + if !consteval { + test_assign_empty<2, X>(); + test_assigns(); + } + return true; + }; + + + test_all(); + static_assert(test_all()); +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/erase.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/erase.cc new file mode 100644 index 000000000000..8b82ab4189cd --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/erase.cc @@ -0,0 +1,117 @@ +// { dg-do run { target c++26 } } + +#include + +#include +#include + +struct X +{ + X() = default; + constexpr X(int p) : v(p) {} + constexpr X(const X& o) : v(o.v) { } // not trivial + constexpr X& operator=(const X& o) // not trivial + { v = o.v; return *this; } + + int v; + + friend auto operator<=>(const X&, const X&) = default; +}; + +template +constexpr bool +eq(const std::inplace_vector& l, std::span r) { + if (l.size() != r.size()) + return false; + for (auto i = 0u; i < l.size(); ++i) + if (l[i] != r[i]) + return false; + return true; +}; + +template +constexpr bool +eq(const std::inplace_vector& l, std::initializer_list r) +{ return eq(l, std::span(r)); } + +template +constexpr void +test_erase_all_or_none() +{ + using namespace __gnu_test; + + T a[]{1,2,3,4,5,6,7,8,9}; + const T c(10); + + std::inplace_vector src(std::from_range, std::span(a, a+N)); + std::inplace_vector v; + + v = src; + auto it = v.erase(v.begin(), v.begin()); + VERIFY( it == v.begin() ); + VERIFY( eq(v, {a, N}) ); + + it = v.erase(v.end(), v.end()); + VERIFY( it == v.end() ); + VERIFY( eq(v, {a, N}) ); + + it = v.erase(v.begin(), v.end()); + VERIFY( it == v.begin() ); + VERIFY( v.empty() ); + + v = src; + v.clear(); + VERIFY( v.empty() ); +} + +template +constexpr void +test_erase() +{ + std::inplace_vector v{T(1), T(2), T(3), T(4), T(5), T(6), T(7)}; + + auto it = v.erase(v.begin()); + VERIFY( eq(v, {T(2), T(3), T(4), T(5), T(6), T(7)}) ); + VERIFY( it == v.begin() ); + + it = v.erase(v.end()-1); + VERIFY( eq(v, {T(2), T(3), T(4), T(5), T(6)}) ); + VERIFY( it == v.end() ); + + it = v.erase(v.begin()+2, v.begin()+4); + VERIFY( eq(v, {T(2), T(3), T(6)}) ); + VERIFY( it == v.begin()+2 ); + + it = v.erase(v.end()-1, v.end()); + VERIFY( eq(v, {T(2), T(3)}) ); + VERIFY( it == v.end() ); + + it = v.erase(v.begin(), v.begin()+1); + VERIFY( eq(v, {T(3)}) ); + VERIFY( it == v.begin() ); + + v.pop_back(); + VERIFY( v.empty() ); +} + +int main() +{ + auto test_all = [] { + test_erase_all_or_none<0, int>(); + test_erase_all_or_none<0, X>(); + + test_erase_all_or_none<4, int>(); + + test_erase(); +#ifdef __cpp_lib_constexpr_inplace_vector +#error uncomemnt test_inserts() +#endif + if ! consteval { + test_erase_all_or_none<4, X>(); + } + return true; + }; + + test_all(); + static_assert(test_all());; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc new file mode 100644 index 000000000000..6a5b62f0aff3 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc @@ -0,0 +1,606 @@ +// { dg-do run { target c++26 } } + +#include + +#include +#include +#include + +struct X +{ + X() = default; + constexpr X(int p) : v(p) {} + constexpr X(const X& o) : v(o.v) { } // not trivial + constexpr X& operator=(const X& o) // not trivial + { v = o.v; return *this; } + + int v; + + friend auto operator<=>(const X&, const X&) = default; +}; + +template +constexpr bool +eq(const std::inplace_vector& l, std::span r) { + if (l.size() != r.size()) + return false; + for (auto i = 0u; i < l.size(); ++i) + if (l[i] != r[i]) + return false; + return true; +}; + +template +constexpr bool +prefix(const std::inplace_vector& l, std::span r) { + if (l.size() < r.size()) + return false; + for (auto i = 0u; i < r.size(); ++i) + if (l[i] != r[i]) + return false; + return true; +}; + +template class ItType> +constexpr void +test_add_to_full_it() +{ + using namespace __gnu_test; + + T a[]{1,2,3,4,5,6,7,8,9}; + using It = ItType; + using Range = test_range; + using SizedRange = test_sized_range; + + std::inplace_vector v(std::from_range, std::span(a, a+N)); + + Range r1(a, a); + auto rit1 = v.try_append_range(r1); + VERIFY( eq(v, {a, N}) ); + VERIFY( rit1.base() == a ); + + SizedRange r2(a, a); + auto rit2 = v.try_append_range(r2); + VERIFY( eq(v, {a, N}) ); + VERIFY( rit2.base() == a ); + + v.append_range(Range(a, a)); + VERIFY( eq(v, {a, N}) ); + v.append_range(SizedRange(a, a)); + VERIFY( eq(v, {a, N}) ); + + auto it = v.insert_range(v.end(), Range(a, a)); + VERIFY( eq(v, {a, N}) ); + VERIFY( it == v.end() ); + it = v.insert_range(v.end(), SizedRange(a, a)); + VERIFY( eq(v, {a, N}) ); + VERIFY( it == v.end() ); + + auto bounds = typename It::ContainerType(a, a+9); + it = v.insert(v.end(), It(a, &bounds), It(a, &bounds)); + VERIFY( eq(v, {a, N}) ); + VERIFY( it == v.end() ); + + it = v.insert_range(v.begin(), SizedRange(a, a)); + VERIFY( eq(v, {a, N}) ); + VERIFY( it == v.begin() ); + it = v.insert_range(v.begin(), Range(a, a)); + VERIFY( eq(v, {a, N}) ); + VERIFY( it == v.begin() ); + + bounds = typename It::ContainerType(a, a+9); + it = v.insert(v.begin(), It(a, &bounds), It(a, &bounds)); + VERIFY( eq(v, {a, N}) ); + VERIFY( it == v.begin() ); + + // Inserting non-empty range + Range r3(a+3, a+5); + auto rit3 = v.try_append_range(r3); + VERIFY( eq(v, {a, N}) ); + VERIFY( rit3.base() == a+3 ); + + SizedRange r4(a+2, a+5); + auto rit4 = v.try_append_range(r4); + VERIFY( eq(v, {a, N}) ); + VERIFY( rit4.base() == a+2 ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + try + { + v.append_range(Range(a, a + 5)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + try + { + v.append_range(SizedRange(a, a + 5)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + try + { + v.insert_range(v.begin(), SizedRange(a, a+5)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + try + { + v.insert_range(v.begin(), Range(a, a+5)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + auto gn = std::ranges::sized_range || std::ranges::forward_range ? N : 0; + VERIFY( prefix(v, {a, gn}) ); + + v = std::inplace_vector(std::from_range, std::span(a, a+N)); + try + { + v.insert_range(v.begin(), Range(a, a+5)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + gn = std::forward_iterator ? N : 0; + VERIFY( prefix(v, {a, gn}) ); +#endif +} + +template +constexpr void +test_add_to_full_other() +{ + using namespace __gnu_test; + + T a[]{1,2,3,4,5,6,7,8,9}; + std::inplace_vector v(std::from_range, std::span(a, a+N)); + + auto it = v.insert(v.end(), {}); + VERIFY( eq(v, {a, N}) ); + VERIFY( it == v.end() ); + it = v.insert(v.end(), 0u, T(2)); + VERIFY( eq(v, {a, N}) ); + VERIFY( it == v.end() ); + + it = v.insert(v.begin(), {}); + VERIFY( eq(v, {a, N}) ); + VERIFY( it == v.begin() ); + it = v.insert(v.begin(), 0u, T(2)); + VERIFY( eq(v, {a, N}) ); + VERIFY( it == v.begin() ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + v = std::inplace_vector(std::from_range, std::span(a, a+N)); + try + { + v.insert(v.begin(), {T(1), T(2), T(3)}); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + try + { + v.insert(v.begin(), 4u, T(3)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); +#endif +} + + +template +constexpr void +test_add_to_full() +{ + using namespace __gnu_test; + test_add_to_full_it(); + test_add_to_full_it(); + test_add_to_full_it(); + + test_add_to_full_other(); +} + +template +constexpr void +test_append_range() +{ + using T = std::ranges::range_value_t; + T a[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + + std::inplace_vector v; + v.append_range(Range(a,a+10)); + VERIFY( eq(v, {a, 10}) ); + + v.append_range(Range(a+10, a+15)); + VERIFY( eq(v, {a, 15}) ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + try + { + v.append_range(Range(a, a+10)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( prefix(v, {a, 15}) ); +#endif +} + +template +constexpr void +test_try_append_range() +{ + using T = std::ranges::range_value_t; + T a[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25}; + + std::inplace_vector v; + Range r1 = Range(a, a+10); + auto it1 = v.try_append_range(r1); + VERIFY( eq(v, {a, 10}) ); + VERIFY( it1.base() == a+10 ); + + Range r2 = Range(a+10, a+15); + auto it2 = v.try_append_range(r2); + VERIFY( eq(v, {a, 15}) ); + VERIFY( it2.base() == a+15 ); + + Range r3 = Range(a+15, a+25); + auto it3 = v.try_append_range(r3); + VERIFY( eq(v, {a, 20}) ); + VERIFY( it3.base() == a+20 ); +} + +template +constexpr void +test_insert_range() +{ + using T = std::ranges::range_value_t; + T a[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + + std::inplace_vector v; + auto it = v.insert_range(v.begin(), Range(a+10,a+15)); + VERIFY( eq(v, {a+10, 5}) ); + VERIFY( it == v.begin() ); + + it = v.insert_range(v.begin(), Range(a, a+5)); + VERIFY( prefix(v, {a, 5}) ); + VERIFY( it == v.begin() ); + + it = v.insert_range(v.begin() + 5, Range(a+5, a+10)); + VERIFY( eq(v, {a, 15}) ); + VERIFY( it == v.begin() + 5 ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + const bool seg = std::ranges::sized_range || std::ranges::forward_range; + auto vc = v; + try + { + vc.insert_range(vc.begin(), Range(a, a+10)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( prefix(vc, {a, seg ? 15 : 0}) ); + + vc = v; + try + { + vc.insert_range(vc.begin()+5, Range(a, a+10)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( prefix(vc, {a, seg ? 15 : 5}) ); + + vc = v; + try + { + vc.insert_range(vc.end(), Range(a, a+10)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( prefix(vc, {a, 15}) ); +#endif +} + +template +constexpr void +do_test_ranges() +{ + test_append_range(); + test_try_append_range(); + test_insert_range(); +} + +template class ItType> +constexpr void +test_insert_iterators() +{ + T a[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + using It = ItType; + + std::inplace_vector v; + + auto bounds = typename It::ContainerType(a, a+15); + auto it = v.insert(v.begin(), It(a+10, &bounds), It(a+15, &bounds)); + VERIFY( eq(v, {a+10, 5}) ); + VERIFY( it == v.begin() ); + + bounds = typename It::ContainerType(a, a+15); + it = v.insert(v.begin(), It(a, &bounds), It(a+5, &bounds)); + VERIFY( prefix(v, {a, 5}) ); + VERIFY( it == v.begin() ); + + bounds = typename It::ContainerType(a, a+15); + it = v.insert(v.begin() + 5, It(a+5, &bounds), It(a+10, &bounds)); + VERIFY( eq(v, {a, 15}) ); + VERIFY( it == v.begin() + 5 ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + const bool seg = std::forward_iterator; + auto vc = v; + bounds = typename It::ContainerType(a, a+15); + try + { + vc.insert(vc.begin(), It(a, &bounds), It(a+10, &bounds)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( prefix(vc, {a, seg ? 15 : 0}) ); + + vc = v; + bounds = typename It::ContainerType(a, a+15); + try + { + vc.insert(vc.begin()+5, It(a, &bounds), It(a+10, &bounds)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( prefix(vc, {a, seg ? 15 : 5}) ); + + vc = v; + bounds = typename It::ContainerType(a, a+15); + try + { + vc.insert(vc.end(), It(a, &bounds), It(a+10, &bounds)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( prefix(vc, {a, 15}) ); +#endif +} + +template +constexpr void +test_insert_initializer_list() +{ + T a[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + + std::inplace_vector v; + + auto it = v.insert(v.begin(), {T(11), T(12), T(13), T(14), T(15)}); + VERIFY( eq(v, {a+10, 5}) ); + VERIFY( it == v.begin() ); + + it = v.insert(v.begin(), {T(1), T(2), T(3), T(4), T(5)}); + VERIFY( prefix(v, {a, 5}) ); + VERIFY( it == v.begin() ); + + it = v.insert(v.begin() + 5, {T(6), T(7), T(8), T(9), T(10)}); + VERIFY( eq(v, {a, 15}) ); + VERIFY( it == v.begin() + 5 ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + std::initializer_list il + = {T(0), T(1), T(2), T(3), T(4), T(5), T(6), T(7), T(8), T(9)}; + + try + { + v.insert(v.begin(), il); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, 15}) ); + + try + { + v.insert(v.begin()+5, il); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, 15}) ); + + try + { + v.insert(v.end(), il); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, 15}) ); +#endif +} + +template +constexpr void +test_insert_repeated() +{ + T a[]{5,5,5,5,5,6,6,6,6,6,7,7,7,7,7}; + + std::inplace_vector v; + + auto it = v.insert(v.begin(), 5, T(7)); + VERIFY( eq(v, {a+10, 5}) ); + VERIFY( it == v.begin() ); + + it = v.insert(v.begin(), 5, T(5)); + VERIFY( prefix(v, {a, 5}) ); + VERIFY( it == v.begin() ); + + it = v.insert(v.begin() + 5, 5, T(6)); + VERIFY( eq(v, {a, 15}) ); + VERIFY( it == v.begin() + 5 ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + try + { + v.insert(v.begin(), 10u, T(6)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, 15}) ); + + try + { + v.insert(v.begin()+5, 10u, T(6)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, 15}) ); + + try + { + v.insert(v.end(), 10u, T(6)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, 15}) ); +#endif +} + +template +constexpr void +test_inserts() +{ + using namespace __gnu_test; + do_test_ranges>(); + do_test_ranges>(); + + do_test_ranges>(); + do_test_ranges>(); + do_test_ranges>(); + + do_test_ranges>(); + do_test_ranges>(); + do_test_ranges>(); + + test_insert_iterators(); + test_insert_iterators(); + test_insert_iterators(); + +test_insert_initializer_list(); +test_insert_repeated(); +} + +int main() +{ +auto test_all = []{ + test_add_to_full<0, int>(); + test_add_to_full<0, X>(); + test_add_to_full<4, int>(); + + test_inserts(); +#ifdef __cpp_lib_constexpr_inplace_vector +#error uncomemnt test_inserts() +#endif + if !consteval { + test_add_to_full<4, X>(); + test_inserts(); + } + return true; + }; + + test_all(); + static_assert(test_all()); +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/single_insert.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/single_insert.cc new file mode 100644 index 000000000000..d5e893cc7f38 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/single_insert.cc @@ -0,0 +1,215 @@ +// { dg-do run { target c++26 } } + +#include + +#include +#include + +struct X +{ + X() = default; + constexpr X(int p) : v(p) {} + constexpr X(const X& o) : v(o.v) { } // not trivial + constexpr X& operator=(const X& o) // not trivial + { v = o.v; return *this; } + + int v; + + friend auto operator<=>(const X&, const X&) = default; +}; + +template +constexpr bool +eq(const std::inplace_vector& l, std::span r) { + if (l.size() != r.size()) + return false; + for (auto i = 0u; i < l.size(); ++i) + if (l[i] != r[i]) + return false; + return true; +}; + +template +constexpr void +test_add_to_full() +{ + using namespace __gnu_test; + + T a[]{1,2,3,4,5,6,7,8,9}; + const T c(10); + + std::inplace_vector v(std::from_range, std::span(a, a+N)); + + VERIFY( v.try_emplace_back(1) == nullptr ); + VERIFY( eq(v, {a, N}) ); + VERIFY( v.try_push_back(T(1)) == nullptr ); + VERIFY( eq(v, {a, N}) ); + VERIFY( v.try_push_back(c) == nullptr ); + VERIFY( eq(v, {a, N}) ); + +#ifdef __cpp_exceptions +#ifdef __cpp_lib_constexpr_exceptions +#error remove the consteval check +#endif + if consteval { + return; + } + + try + { + v.emplace_back(1); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + try + { + v.push_back(T(1)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + try + { + v.push_back(c); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + try + { + v.insert(v.end(), T(1)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + try + { + v.insert(v.begin(), c); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + try + { + v.emplace(v.end(), c); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); + + try + { + v.emplace(v.begin(), T(2)); + VERIFY(false); + } + catch (std::bad_alloc const&) + { + } + VERIFY( eq(v, {a, N}) ); +#endif +} + +template +constexpr void +test_inserts() +{ + T a[]{3,14,13,1,2,3,4,5,3,7,8,3,10,11,3}; + const T c(3); + + std::inplace_vector v; + + v.emplace_back(1); + VERIFY( eq(v, {a+3, 1}) ); + v.push_back(T(2)); + VERIFY( eq(v, {a+3, 2}) ); + v.push_back(c); + VERIFY( eq(v, {a+3, 3}) ); + + v.unchecked_emplace_back(4); + VERIFY( eq(v, {a+3, 4}) ); + v.unchecked_push_back(T(5)); + VERIFY( eq(v, {a+3, 5}) ); + v.unchecked_push_back(c); + VERIFY( eq(v, {a+3, 6}) ); + + T* ptr = v.try_emplace_back(7); + VERIFY( eq(v, {a+3, 7}) ); + VERIFY( ptr = &v.back() ); + ptr = v.try_push_back(T(8)); + VERIFY( eq(v, {a+3, 8}) ); + VERIFY( ptr = &v.back() ); + ptr = v.try_push_back(c); + VERIFY( eq(v, {a+3, 9}) ); + VERIFY( ptr = &v.back() ); + + auto it = v.emplace(v.end(), 10); + VERIFY( eq(v, {a+3, 10}) ); + VERIFY( it == v.end()-1 ); + it = v.insert(v.end(), T(11)); + VERIFY( eq(v, {a+3, 11}) ); + VERIFY( it == v.end()-1 ); + it = v.insert(v.end(), c); + VERIFY( eq(v, {a+3, 12}) ); + VERIFY( it == v.end()-1 ); + + it = v.emplace(v.begin(), 13); + VERIFY( eq(v, {a+2, 13}) ); + VERIFY( it == v.begin() ); + it = v.insert(v.begin(), T(14)); + VERIFY( eq(v, {a+1, 14}) ); + VERIFY( it == v.begin() ); + it = v.insert(v.begin(), c); + VERIFY( eq(v, {a+0, 15}) ); + VERIFY( it == v.begin() ); + + it = v.emplace(v.begin()+2, 22); + VERIFY( *it == 22 ); + VERIFY( it == v.begin()+2 ); + it = v.insert(v.begin()+6, T(24)); + VERIFY( *it == 24 ); + VERIFY( it == v.begin()+6 ); + it = v.insert(v.begin()+13, c); + VERIFY( *it == 3 ); + VERIFY( it == v.begin()+13 ); +} + +int main() +{ + auto test_all = [] { + test_add_to_full<0, int>(); + test_add_to_full<0, X>(); + + test_add_to_full<4, int>(); + + test_inserts(); +#ifdef __cpp_lib_constexpr_inplace_vector +#error uncomemnt test_inserts() +#endif + if ! consteval { + test_add_to_full<4, X>(); + test_inserts(); + } + return true; + }; + + test_all(); + static_assert(test_all());; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/move.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/move.cc new file mode 100644 index 000000000000..5abcc8764bd5 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/move.cc @@ -0,0 +1,358 @@ +// { dg-do run { target c++26 } } + +#include +#include +#include + +struct X +{ + X() = default; + constexpr X(int p) : v(p) {} + constexpr X(const X& o) : v(o.v) { } // not trivial + constexpr X(X&& o) : v(o.v) { } // not trivial + + constexpr X& operator=(const X& o) // not trivial + { v = o.v; return *this; } + constexpr X& operator=(X&& o) // not trivial + { v = o.v; return *this; } + + int v; + + friend auto operator<=>(const X&, const X&) = default; +}; + +template +struct N +{ + N() = default; + constexpr N(N&&) noexcept(CNoex) { } // not trivial + constexpr N& operator=(N&& o) noexcept(ANoex) // not trivial + { return *this; } +}; + +struct D +{ + D() = default; + D(D&&) = default; + D& operator=(D&&) = default; + ~D() {} // not trivially destructible +}; + +struct U +{ + U() = default; + U(U&&) noexcept(false) = default; // lies about noexcept, is trivial but throwing + U& operator=(U&&) noexcept(false) = default; // lies about noexcept, is trivial but throwing +}; + +template +struct S { + S() = default; + constexpr S(S&&) noexcept(CNoex) { } // not trivial + constexpr S& operator=(S&& o) noexcept(ANoex) // not trivial + { return *this; } + + friend constexpr + void swap(S&, S&) noexcept(SNoex) {} +}; + +// n5008 inplace.vector.overview says for inplace_vector +// provides trivial copy/move/default cosntructpr regardless of T +struct Z +{ + Z(const Z&) = delete; + Z& operator=(const Z&) = delete; +}; + +template + constexpr std::inplace_vector + materialize(std::initializer_list il) + { + std::inplace_vector res; + for (int x : il) + res.emplace_back(x); + return res; + } + +static_assert(std::is_move_constructible_v>); +static_assert(std::is_move_constructible_v>); +static_assert(std::is_move_constructible_v, 2>>); +static_assert(std::is_move_constructible_v>); +static_assert(std::is_move_constructible_v>); +// The operators are not constrained, as for any other container +static_assert(std::is_move_constructible_v>); + +static_assert(std::is_nothrow_move_constructible_v>); +static_assert(!std::is_nothrow_move_constructible_v>); +static_assert(std::is_nothrow_move_constructible_v, 2>>); +static_assert(std::is_nothrow_move_constructible_v, 2>>); +static_assert(!std::is_nothrow_move_constructible_v, 2>>); +static_assert(!std::is_nothrow_move_constructible_v, 2>>); +static_assert(std::is_nothrow_move_constructible_v>); +static_assert(!std::is_nothrow_move_constructible_v>); + +static_assert(std::is_trivially_move_constructible_v>); +static_assert(!std::is_trivially_move_constructible_v>); +static_assert(!std::is_trivially_move_constructible_v, 2>>); +// is_trivially_move_constructible_v checks destructor +static_assert(!std::is_trivially_move_constructible_v>); +static_assert(std::is_trivially_move_constructible_v>); + +static_assert(std::is_move_assignable_v>); +static_assert(std::is_move_assignable_v>); +static_assert(std::is_move_assignable_v, 2>>); +static_assert(std::is_move_assignable_v>); +static_assert(std::is_move_assignable_v>); +// The operators are not constrained, as for any other container +static_assert(std::is_move_assignable_v>); + +static_assert(std::is_nothrow_move_assignable_v>); +static_assert(!std::is_nothrow_move_assignable_v>); +static_assert(std::is_nothrow_move_assignable_v, 2>>); +static_assert(!std::is_nothrow_move_assignable_v, 2>>); +static_assert(!std::is_nothrow_move_assignable_v, 2>>); +static_assert(!std::is_nothrow_move_assignable_v, 2>>); +static_assert(std::is_nothrow_move_assignable_v>); +static_assert(!std::is_nothrow_move_assignable_v>); + +static_assert(std::is_trivially_move_assignable_v>); +static_assert(!std::is_trivially_move_assignable_v>); +static_assert(!std::is_trivially_move_assignable_v, 2>>); +// destructor is not trivial +static_assert(!std::is_trivially_move_assignable_v>); +static_assert(std::is_trivially_move_assignable_v>); + +static_assert(std::is_nothrow_swappable_v>); +static_assert(!std::is_nothrow_swappable_v>); +static_assert(std::is_nothrow_swappable_v, 2>>); +static_assert(!std::is_nothrow_swappable_v, 2>>); +static_assert(!std::is_nothrow_swappable_v, 2>>); +static_assert(!std::is_nothrow_swappable_v, 2>>); +static_assert(std::is_nothrow_swappable_v, 2>>); +static_assert(std::is_nothrow_swappable_v, 2>>); +static_assert(!std::is_nothrow_swappable_v, 2>>); +static_assert(!std::is_nothrow_swappable_v, 2>>); +static_assert(!std::is_nothrow_swappable_v, 2>>); +static_assert(!std::is_nothrow_swappable_v, 2>>); +static_assert(std::is_nothrow_swappable_v>); +static_assert(!std::is_nothrow_swappable_v>); + +static_assert(std::is_nothrow_move_constructible_v>); +static_assert(std::is_nothrow_move_constructible_v>); +static_assert(std::is_nothrow_move_constructible_v, 0>>); +static_assert(std::is_nothrow_move_constructible_v>); +static_assert(std::is_nothrow_move_constructible_v>); +static_assert(std::is_nothrow_move_constructible_v>); + +static_assert(std::is_trivially_move_constructible_v>); +static_assert(std::is_trivially_move_constructible_v>); +static_assert(std::is_trivially_move_constructible_v>); +static_assert(std::is_trivially_move_constructible_v>); +static_assert(std::is_trivially_move_constructible_v>); + +static_assert(std::is_nothrow_move_assignable_v>); +static_assert(std::is_nothrow_move_assignable_v>); +static_assert(std::is_nothrow_move_assignable_v, 0>>); +static_assert(std::is_nothrow_move_assignable_v>); +static_assert(std::is_nothrow_move_assignable_v>); +static_assert(std::is_nothrow_move_assignable_v>); + +static_assert(std::is_trivially_move_assignable_v>); +static_assert(std::is_trivially_move_assignable_v>); +static_assert(std::is_trivially_move_assignable_v, 0>>); +static_assert(std::is_trivially_move_assignable_v>); +static_assert(std::is_trivially_move_assignable_v>); +static_assert(std::is_trivially_move_assignable_v>); + +static_assert(std::is_nothrow_swappable_v>); +static_assert(std::is_nothrow_swappable_v>); +static_assert(std::is_nothrow_swappable_v, 0>>); +static_assert(std::is_nothrow_swappable_v>); +static_assert(std::is_nothrow_swappable_v>); +static_assert(std::is_nothrow_swappable_v>); + +template +constexpr bool +eq(const std::inplace_vector& s, std::span o) +{ return std::ranges::equal(s, o); } + +constexpr void +test_ctor() +{ + auto e0 = materialize<0, int>({}); + VERIFY( e0.empty() ); + auto e1 = materialize<0, X>({}); + VERIFY( e1.empty() ); + auto e2 = materialize<0, Z>({}); + VERIFY( e2.empty() ); + + auto c0 = materialize<5, int>({}); + VERIFY( c0.empty() ); + + auto c3 = materialize<5, int>({1, 2, 3}); + VERIFY( eq(c3, {1, 2, 3}) ); + + auto c5 = materialize<5, int>({1, 2, 3, 4, 5}); + VERIFY( eq(c5, {1, 2, 3, 4, 5}) ); + +#ifdef __cpp_lib_constexpr_inplace_vector +#error remove the consteval check +#endif + if consteval { + return; + } + + auto x0 = materialize<3, X>({}); + VERIFY( x0.empty() ); + + auto x2 = materialize<3, X>({1, 2}); + VERIFY( eq(x2, {1, 2}) ); + + auto x3 = materialize<3, X>({1, 2, 3}); + VERIFY( eq(x3, {1, 2, 3}) ); +} + +constexpr void +test_assign() +{ + std::inplace_vector e0; + e0 = materialize<0, int>({}); + VERIFY( e0.empty() ); + std::inplace_vector e1; + e1 = materialize<0, X>({}); + VERIFY( e1.empty() ); + std::inplace_vector e2; + e2 = materialize<0, Z>({}); + VERIFY( e2.empty() ); + + std::inplace_vector c; + c = materialize<5, int>({}); + VERIFY( c.empty() ); + + c = materialize<5, int>({1, 2, 3}); + VERIFY( eq(c, {1, 2, 3}) ); + + c = materialize<5, int>({1, 2, 3, 4, 5}); + VERIFY( eq(c, {1, 2, 3, 4, 5}) ); + + c = materialize<5, int>({4, 5}); + VERIFY( eq(c, {4, 5}) ); + + c = materialize<5, int>({}); + VERIFY( c.empty() ); + +#ifdef __cpp_lib_constexpr_inplace_vector +#error remove the consteval check +#endif + if consteval { + return; + } + + std::inplace_vector x; + x = materialize<5, X>({}); + VERIFY( x.empty() ); + + x = materialize<5, X>({1, 2, 3}); + VERIFY( eq(x, {1, 2, 3}) ); + + x = materialize<5, X>({1, 2, 3, 4, 5}); + VERIFY( eq(x, {1, 2, 3, 4, 5}) ); + + x = materialize<5, X>({4, 5}); + VERIFY( eq(x, {4, 5}) ); + + x = materialize<5, X>({}); + VERIFY( x.empty() ); +} + +constexpr void +test_swap() +{ + std::inplace_vector e0a, e0b; + swap(e0a, e0b); + VERIFY( e0a.empty() ); + VERIFY( e0b.empty() ); + e0a.swap(e0b); + VERIFY( e0a.empty() ); + VERIFY( e0b.empty() ); + + std::inplace_vector e1a, e1b; + swap(e1a, e1b); + VERIFY( e1a.empty() ); + VERIFY( e1b.empty() ); + e1a.swap(e1b); + VERIFY( e1a.empty() ); + VERIFY( e1b.empty() ); + + std::inplace_vector e2a, e2b; + swap(e2a, e2b); + VERIFY( e2a.empty() ); + VERIFY( e2b.empty() ); + e2a.swap(e2b); + VERIFY( e2a.empty() ); + VERIFY( e2b.empty() ); + + std::inplace_vector c0; + std::inplace_vector c3{1, 2, 3}; + std::inplace_vector c5{1, 2, 3, 4, 5}; + + swap(c0, c3); + VERIFY( c3.empty() ); + VERIFY( eq(c0, {1, 2, 3}) ); + c0.swap(c3); + VERIFY( c0.empty() ); + VERIFY( eq(c3, {1, 2, 3}) ); + + swap(c3, c5); + VERIFY( eq(c5, {1, 2, 3}) ); + VERIFY( eq(c3, {1, 2, 3, 4, 5}) ); + c5.swap(c3); + VERIFY( eq(c3, {1, 2, 3}) ); + VERIFY( eq(c5, {1, 2, 3, 4, 5}) ); + +#ifdef __cpp_lib_constexpr_inplace_vector +#error remove the consteval check +#endif + if consteval { + return; + } + + std::inplace_vector x0; + std::inplace_vector x3 = {1, 2, 3}; + std::inplace_vector x5 = {1, 2, 3, 4, 5}; + + swap(x0, x3); + VERIFY( x3.empty() ); + VERIFY( eq(x0, {1, 2, 3}) ); + x0.swap(x3); + VERIFY( x0.empty() ); + VERIFY( eq(x3, {1, 2, 3}) ); + + swap(x3, x5); + VERIFY( eq(x5, {1, 2, 3}) ); + VERIFY( eq(x3, {1, 2, 3, 4, 5}) ); + x5.swap(x3); + VERIFY( eq(x3, {1, 2, 3}) ); + VERIFY( eq(x5, {1, 2, 3, 4, 5}) ); +} + +constexpr auto e0 = materialize<0, int>({}); +constexpr auto e1 = materialize<0, X>({}); +constexpr auto e2 = materialize<0, Z>({}); + +constexpr auto t1 = materialize<3, int>({}); +constexpr auto t2 = materialize<3, int>({1, 2}); +constexpr auto t3 = materialize<3, int>({11, 22, 33}); + +int main() +{ + auto tests = [] { + test_ctor(); + test_assign(); + test_swap(); + return true; + }; + + tests(); + constexpr bool _ = tests(); +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/relops.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/relops.cc new file mode 100644 index 000000000000..f9c5ce96ae15 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/relops.cc @@ -0,0 +1,60 @@ +// { dg-do run { target c++26 } } + +#include + +#include +#include + +template +constexpr void +test_equal(size_t c) +{ + T a[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; + std::inplace_vector v(a, a+c); + VERIFY( v == v ); + VERIFY( !(v != v) ); + VERIFY( !(v < v) ); + VERIFY( !(v > v) ); + VERIFY( v <= v ); + VERIFY( v >= v ); + VERIFY( (v <=> v) == 0 ); +} + +template +constexpr void +test_not_equal() +{ + std::inplace_vector v3l{T{1}, T{2}, T{3}}; + std::inplace_vector v3g{T{1}, T{3}, T{3}}; + VERIFY( !(v3l == v3g) ); + VERIFY( v3l != v3g ); + VERIFY( v3l < v3g ); + VERIFY( !(v3l > v3g) ); + VERIFY( v3l <= v3g ); + VERIFY( !(v3l >= v3g) ); + VERIFY( (v3l <=> v3g) < 0 ); + + std::inplace_vector v2{T{1}, T{2}}; + VERIFY( !(v2 == v3l) ); + VERIFY( v2 != v3l ); + VERIFY( v2 < v3l ); + VERIFY( !(v2 > v3l) ); + VERIFY( v2 <= v3l ); + VERIFY( !(v2 >= v3l) ); + VERIFY( (v2 <=> v3l) < 0 ); +} + +int main() +{ + auto test_all = [] { + test_equal<0, int>(0); + test_equal<4, int>(0); + test_equal<4, int>(2); + test_equal<4, int>(4); + test_not_equal(); + return true; + }; + + test_all(); + static_assert(test_all());; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/version.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/version.cc new file mode 100644 index 000000000000..a5bbdb8464be --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/version.cc @@ -0,0 +1,20 @@ +// { dg-do preprocess { target c++26 } } +// { dg-add-options no_pch } + +#include + +#ifndef __cpp_lib_inplace_vector +# error "Feature-test macro for inplace_vector missing in " +#elif __cpp_lib_inplace_vector != 202406L +# error "Feature-test macro for inplace_vector has wrong value in " +#endif + +#undef __cpp_lib_inplace_vector + +#include + +#ifndef __cpp_lib_inplace_vector +# error "Feature-test macro for inplace_vector missing in " +#elif __cpp_lib_inplace_vector != 202406L +# error "Feature-test macro for inplace_vector has wrong value in " +#endif diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc new file mode 100644 index 000000000000..c036f8ad10ff --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc @@ -0,0 +1,99 @@ +// { dg-do run { target c++23 } } +#include + +#include + +constexpr size_t dyn = std::dynamic_extent; + +template + constexpr void + test_accessor_policy() + { + static_assert(std::copyable); + static_assert(std::is_nothrow_move_constructible_v); + static_assert(std::is_nothrow_move_assignable_v); + static_assert(std::is_nothrow_swappable_v); + } + +constexpr bool +test_access() +{ + std::default_accessor accessor; + std::array a{10, 11, 12, 13, 14}; + VERIFY(accessor.access(a.data(), 0) == 10); + VERIFY(accessor.access(a.data(), 4) == 14); + return true; +} + +constexpr bool +test_offset() +{ + std::default_accessor accessor; + std::array a{10, 11, 12, 13, 14}; + VERIFY(accessor.offset(a.data(), 0) == a.data()); + VERIFY(accessor.offset(a.data(), 4) == a.data() + 4); + return true; +} + +class Base +{ }; + +class Derived : public Base +{ }; + +constexpr void +test_ctor() +{ + // T -> T + static_assert(std::is_nothrow_constructible_v, + std::default_accessor>); + static_assert(std::is_convertible_v, + std::default_accessor>); + + // T -> const T + static_assert(std::is_convertible_v, + std::default_accessor>); + static_assert(std::is_convertible_v, + std::default_accessor>); + + // const T -> T + static_assert(!std::is_constructible_v, + std::default_accessor>); + static_assert(!std::is_constructible_v, + std::default_accessor>); + + // T <-> volatile T + static_assert(std::is_convertible_v, + std::default_accessor>); + static_assert(!std::is_constructible_v, + std::default_accessor>); + + // size difference + static_assert(!std::is_constructible_v, + std::default_accessor>); + + // signedness + static_assert(!std::is_constructible_v, + std::default_accessor>); + static_assert(!std::is_constructible_v, + std::default_accessor>); + + // Derived <-> Base + static_assert(!std::is_constructible_v, + std::default_accessor>); + static_assert(!std::is_constructible_v, + std::default_accessor>); + +} + +int +main() +{ + test_accessor_policy>(); + test_access(); + static_assert(test_access()); + test_offset(); + static_assert(test_offset()); + test_ctor(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default_neg.cc new file mode 100644 index 000000000000..f8da2b569ca1 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default_neg.cc @@ -0,0 +1,23 @@ +// { dg-do compile { target c++23 } } +#include + +std::default_accessor a; // { dg-error "required from here" } + +class AbstractBase +{ + virtual void + foo() const = 0; +}; + +class Derived : public AbstractBase +{ + void + foo() const override + { } +}; + +std::default_accessor b_ok; +std::default_accessor b_err; // { dg-error "required from here"} + +// { dg-prune-output "ElementType must not be an array type" } +// { dg-prune-output "ElementType must not be an abstract" } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/class_mandate_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/class_mandate_neg.cc new file mode 100644 index 000000000000..de19b6d85c99 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/class_mandate_neg.cc @@ -0,0 +1,41 @@ +// { dg-do compile { target c++23 } } +#include + +#include +#include "layout_like.h" + +struct ExtentsLike +{ + using index_type = int; + using size_type = unsigned int; + using rank_type = size_t; + + static constexpr size_t rank() { return 1; } + static constexpr size_t rank_dynamic() { return 0; } +}; + +constexpr bool +test_custom_extents_type() +{ + std::mdspan md1; // { dg-error "required from here" } + return true; +} +static_assert(test_custom_extents_type()); + +constexpr bool +test_element_type_mismatch() +{ + using E = std::extents; + using L = std::layout_right; + using A = std::default_accessor; + + [[maybe_unused]] std::mdspan md2; // { dg-error "required from here" } + return true; +}; +static_assert(test_element_type_mismatch()); + +// { dg-prune-output "Extents must be a specialization of std::extents" } +// { dg-prune-output "no type named '_S_storage'" } +// { dg-prune-output "non-constant condition" } +// { dg-prune-output "static assertion failed" } +// { dg-prune-output "__glibcxx_assert" } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc index f9c1c0196669..67d18feda96c 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc @@ -7,6 +7,8 @@ std::extents e1; // { dg-error "from here" } std::extents e2; // { dg-error "from here" } std::extents e3; // { dg-error "from here" } std::extents e4; // { dg-error "from here" } + // { dg-prune-output "dynamic or representable as IndexType" } // { dg-prune-output "signed or unsigned integer" } // { dg-prune-output "invalid use of incomplete type" } +// { dg-prune-output "non-constant condition for static assertion" } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_default.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_default.cc index eec300f68962..f45d3e5a5ca4 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_default.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_default.cc @@ -15,7 +15,7 @@ template if(exts.static_extent(i) == std::dynamic_extent) VERIFY(exts.extent(i) == 0); else - VERIFY(exts.extent(i) == Extents::static_extent(i)); + VERIFY(std::cmp_equal(exts.extent(i), Extents::static_extent(i))); } constexpr bool diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc index 2907ad12ae72..99de4015ef31 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc @@ -2,86 +2,95 @@ #include #include +#include "../int_like.h" // Test construction from a custom integer-like object, that has // no copy/move ctor or copy/move assignment operator. constexpr size_t dyn = std::dynamic_extent; -class IntLike -{ -public: - explicit - IntLike(int i) - : _M_i(i) - { } - - IntLike() = delete; - IntLike(const IntLike&) = delete; - IntLike(IntLike&&) = delete; - - const IntLike& - operator=(const IntLike&) = delete; - - const IntLike& - operator=(IntLike&&) = delete; - - constexpr - operator int() const noexcept - { return _M_i; } - -private: - int _M_i; -}; - static_assert(std::is_convertible_v); static_assert(std::is_nothrow_constructible_v); -void -test_shape(const auto& s2, const auto& s23) -{ - std::extents expected; - - std::extents e1(s23); - VERIFY(e1 == expected); - - std::extents e2(s2); - VERIFY(e2 == expected); - - std::extents e3(s23); - VERIFY(e3 == expected); - - std::extents e4(s23); - VERIFY(e4 == expected); -} - -void -test_pack() -{ - std::extents expected; - - std::extents e1(IntLike(2)); - VERIFY(e1 == expected); - - std::extents e2(IntLike(2), IntLike(3)); - VERIFY(e2 == expected); - - std::extents e3(IntLike(2), IntLike(3)); - VERIFY(e3 == expected); -} +template + void + test_shape(const auto& shape) + { + static_assert(std::is_constructible_v == Valid); + + if constexpr (Valid) + { + std::extents expected; + Extents actual(shape); + VERIFY(actual == expected); + } + } + +template + void + test_shape_all() + { + auto a2 = std::array{Int(2)}; + auto s2 = std::span(a2); + + auto a23 = std::array{Int(2), Int(3)}; + auto s23 = std::span(a23); + + auto check = [](const auto& dyn_exts, const auto& full_exts) + { + test_shape, Valid>(full_exts); + test_shape, Valid>(dyn_exts); + test_shape, Valid>(full_exts); + test_shape, Valid>(full_exts); + }; + + check(a2, a23); + check(s2, s23); + } + +// Needed because is_constructible requires that Ints are move constructible. +template + concept has_ctor = requires + { + { Extents(Ints(0)...) } -> std::same_as; + }; + +template + void + test_pack_all() + { + static_assert(has_ctor, Int> == Valid); + static_assert(has_ctor, Int, Int> == Valid); + static_assert(has_ctor, Int, Int> == Valid); + + if constexpr (Valid) + { + std::extents expected; + + std::extents e1(Int(2)); + VERIFY(e1 == expected); + + std::extents e2(Int(2), Int(3)); + VERIFY(e2 == expected); + + std::extents e3(Int(2), Int(3)); + VERIFY(e3 == expected); + } + } int main() { - auto a2 = std::array{IntLike(2)}; - auto s2 = std::span(a2); - - auto a23 = std::array{IntLike(2), IntLike(3)}; - auto s23 = std::span(a23); - - test_shape(a2, a23); - test_shape(s2, s23); - test_pack(); - + test_shape_all(); + test_shape_all(); + test_shape_all(); + test_shape_all(); + test_shape_all(); + + test_pack_all(); + test_pack_all(); + test_pack_all(); + test_pack_all(); + test_pack_all(); return 0; } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/extents_mismatch_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/extents_mismatch_neg.cc new file mode 100644 index 000000000000..b35e5310d415 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/extents_mismatch_neg.cc @@ -0,0 +1,35 @@ +// { dg-do compile { target c++23 } } +#include + +#include + +constexpr size_t dyn = std::dynamic_extent; + +constexpr bool +test_dyn2sta_extents_mismatch_00() +{ + auto e0 = std::extents{1}; + [[maybe_unused]] auto e1 = std::extents{e0}; // { dg-error "expansion of" } + return true; +} +static_assert(test_dyn2sta_extents_mismatch_00()); // { dg-error "expansion of" } + +constexpr bool +test_dyn2sta_extents_mismatch_01() +{ + [[maybe_unused]] auto e = std::extents{2, 2}; // { dg-error "expansion of" } + return true; +} +static_assert(test_dyn2sta_extents_mismatch_01()); // { dg-error "expansion of" } + +constexpr bool +test_dyn2sta_extents_mismatch_02() +{ + std::array exts{2, 2}; + [[maybe_unused]] auto e = std::extents{exts}; // { dg-error "expansion of" } + return true; +} +static_assert(test_dyn2sta_extents_mismatch_02()); // { dg-error "expansion of" } + +// { dg-prune-output "non-constant condition for static assertion" } +// { dg-prune-output "__glibcxx_assert" } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc index e71fdc542305..bca8901685d0 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc @@ -97,6 +97,25 @@ test_deduction(Extents... exts) VERIFY(e == expected); } +constexpr bool +test_integral_constant_deduction() +{ + auto verify = [](auto actual, auto expected) + { + static_assert(std::same_as); + VERIFY(actual == expected); + }; + + constexpr auto c1 = std::integral_constant{}; + constexpr auto c2 = std::integral_constant{}; + + verify(std::extents(1), std::extents{1}); + verify(std::extents(c1), std::extents{}); + verify(std::extents(c2), std::extents{}); + verify(std::extents(c1, 2), std::extents{2}); + return true; +} + constexpr bool test_deduction_all() { @@ -104,6 +123,7 @@ test_deduction_all() test_deduction<1>(1); test_deduction<2>(1.0, 2.0f); test_deduction<3>(int(1), short(2), size_t(3)); + test_integral_constant_deduction(); return true; } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h b/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h new file mode 100644 index 000000000000..310dd8ddf207 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h @@ -0,0 +1,63 @@ +#ifndef TEST_MDSPAN_INT_LIKE_H +#define TEST_MDSPAN_INT_LIKE_H + +enum class CustomIndexKind +{ + Const, + Throwing, + Mutating, + RValue, +}; + +template + class CustomIndexType + { + public: + explicit + CustomIndexType(int i) + : _M_i(i) + { } + + CustomIndexType() = delete; + CustomIndexType(const CustomIndexType&) = delete; + CustomIndexType(CustomIndexType&&) = delete; + + const CustomIndexType& + operator=(const CustomIndexType&) = delete; + + const CustomIndexType& + operator=(CustomIndexType&&) = delete; + + constexpr + operator int() const noexcept + requires (Kind == CustomIndexKind::Const) + { return _M_i; } + + constexpr + operator int() const + requires (Kind == CustomIndexKind::Throwing) + { return _M_i; } + + constexpr + operator int() noexcept + requires (Kind == CustomIndexKind::Mutating) + { return _M_i; } + + constexpr + operator int() && noexcept + requires (Kind == CustomIndexKind::RValue) + { return _M_i; } + + private: + int _M_i; + }; + +using IntLike = CustomIndexType; +using ThrowingInt = CustomIndexType; +using MutatingInt = CustomIndexType; +using RValueInt = CustomIndexType; + +struct NotIntLike +{ }; + +#endif // TEST_MDSPAN_INT_LIKE_H diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layout_like.h b/libstdc++-v3/testsuite/23_containers/mdspan/layout_like.h new file mode 100644 index 000000000000..ded6e9d0cc90 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layout_like.h @@ -0,0 +1,87 @@ +#ifndef TEST_MDSPAN_LAYOUT_LIKE_H +#define TEST_MDSPAN_LAYOUT_LIKE_H 1 + +template + struct CustomLayout + { + template + class mapping + { + public: + using extents_type = Extents; + using index_type = typename extents_type::index_type; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using layout_type = CustomLayout; + + constexpr + mapping() noexcept = default; + + constexpr + mapping(Extents exts) + : m_exts(exts) + { } + + constexpr const extents_type& + extents() const noexcept(Noexcept) { return m_exts; } + + constexpr index_type + required_span_size() const noexcept(Noexcept) + { + for (size_t i = 0; i < extents_type::rank(); ++i) + if (m_exts.extent(i) == 0) + return 0; + return 1; + } + + template + requires (sizeof...(Indices) == extents_type::rank()) + constexpr index_type + operator()(Indices...) const noexcept(Noexcept) + { return 0; } + + static constexpr index_type + stride(rank_type) noexcept(Noexcept) + { return 0; } + + static constexpr bool + is_always_unique() noexcept(Noexcept) + { return false; } + + static constexpr bool + is_always_exhaustive() noexcept(Noexcept) + { return true; } + + static constexpr bool + is_always_strided() noexcept(Noexcept) + { return true; } + + constexpr bool + is_unique() const noexcept(Noexcept) + { + if (required_span_size() == 0) + return true; + + for (size_t i = 0; i < extents_type::rank(); ++i) + if (m_exts.extent(i) > 1) + return false; + return true; + } + + static constexpr bool + is_exhaustive() noexcept(Noexcept) + { return true; } + + static constexpr bool + is_strided() noexcept(Noexcept) + { return true; } + + private: + Extents m_exts; + }; + }; + +using LayoutLike = CustomLayout; +using ThrowingLayout = CustomLayout; + +#endif diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/class_mandate_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/class_mandate_neg.cc new file mode 100644 index 000000000000..7091153daba8 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/class_mandate_neg.cc @@ -0,0 +1,48 @@ +// { dg-do compile { target c++23 } } +#include + +#include + +constexpr size_t dyn = std::dynamic_extent; +static constexpr size_t n = std::numeric_limits::max() / 2; + +template + struct A + { + typename Layout::mapping> m0; + typename Layout::mapping> m1; + typename Layout::mapping> m2; + + using extents_type = std::extents; + typename Layout::mapping m3; // { dg-error "required from" } + }; + +template + bool + B() + { + using Extents = std::extents; + using OExtents = std::extents; + + using Mapping = typename Layout::mapping; + using OMapping = typename OLayout::mapping; + + Mapping m{OMapping{}}; + return true; + }; + +A a_left; // { dg-error "required from" } +A a_right; // { dg-error "required from" } +A a_stride; // { dg-error "required from" } + +auto b1 = B<1, std::layout_left, std::layout_left>(); // { dg-error "required from" } +auto b2 = B<2, std::layout_left, std::layout_stride>(); // { dg-error "required from" } + +auto b3 = B<3, std::layout_right, std::layout_right>(); // { dg-error "required from" } +auto b4 = B<4, std::layout_right, std::layout_stride>(); // { dg-error "required from" } + +auto b5 = B<5, std::layout_stride, std::layout_right>(); // { dg-error "required from" } +auto b6 = B<6, std::layout_stride, std::layout_left>(); // { dg-error "required from" } +auto b7 = B<7, std::layout_stride, std::layout_stride>(); // { dg-error "required from" } + +// { dg-prune-output "must be representable as index_type" } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc new file mode 100644 index 000000000000..23c0a55dae19 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc @@ -0,0 +1,436 @@ +// { dg-do run { target c++23 } } +#include + +#include +#include + +constexpr size_t dyn = std::dynamic_extent; + +template + constexpr void + verify(std::extents oexts) + { + auto m = Mapping(oexts); + VERIFY(m.extents() == oexts); + } + +template + requires (requires { typename OMapping::layout_type; }) + constexpr void + verify(OMapping other) + { + constexpr auto rank = Mapping::extents_type::rank(); + auto m = Mapping(other); + VERIFY(m.extents() == other.extents()); + if constexpr (rank > 0) + for(size_t i = 0; i < rank; ++i) + VERIFY(std::cmp_equal(m.stride(i), other.stride(i))); + } + + +template + constexpr void + verify_convertible(From from) + { + static_assert(std::is_convertible_v); + verify(from); + } + +template + constexpr void + verify_nothrow_convertible(From from) + { + static_assert(std::is_nothrow_constructible_v); + verify_convertible(from); + } + +template + constexpr void + verify_constructible(From from) + { + static_assert(!std::is_convertible_v); + static_assert(std::is_constructible_v); + verify(from); + } + +template + constexpr void + verify_nothrow_constructible(From from) + { + static_assert(std::is_nothrow_constructible_v); + verify_constructible(from); + } + +template + constexpr void + assert_not_constructible() + { + static_assert(!std::is_constructible_v); + } + +// ctor: mapping() +namespace default_ctor +{ + template + constexpr void + test_default_ctor() + { + using Mapping = typename Layout::mapping; + + Mapping m; + for(size_t i = 0; i < Extents::rank(); ++i) + if (Extents::static_extent(i) == std::dynamic_extent) + VERIFY(m.extents().extent(i) == 0); + else + VERIFY(m.extents().static_extent(i) == Extents::static_extent(i)); + } + + template + constexpr bool + test_default_ctor_all() + { + test_default_ctor>(); + test_default_ctor>(); + test_default_ctor>(); + test_default_ctor>(); + test_default_ctor>(); + test_default_ctor>(); + return true; + } + + template + constexpr void + test_all() + { + test_default_ctor_all(); + static_assert(test_default_ctor_all()); + } +} + +// ctor: mapping(const extents&) +namespace from_extents +{ + template + constexpr void + verify_nothrow_convertible(OExtents oexts) + { + using Mapping = typename Layout::mapping; + ::verify_nothrow_convertible(oexts); + } + + template + constexpr void + verify_nothrow_constructible(OExtents oexts) + { + using Mapping = typename Layout::mapping; + ::verify_nothrow_constructible(oexts); + } + + template + constexpr void + assert_not_constructible() + { + using Mapping = typename Layout::mapping; + ::assert_not_constructible(); + } + + template + constexpr bool + test_ctor() + { + verify_nothrow_convertible>( + std::extents{}); + + verify_nothrow_convertible>( + std::extents{}); + + verify_nothrow_convertible>( + std::extents{2}); + + verify_nothrow_constructible>( + std::extents{}); + + verify_nothrow_constructible>( + std::extents{}); + + verify_nothrow_constructible>( + std::extents{}); + + assert_not_constructible, + std::extents>(); + assert_not_constructible, + std::extents>(); + assert_not_constructible, + std::extents>(); + return true; + } + + template + constexpr void + assert_deducible(Extents exts) + { + typename Layout::mapping m(exts); + static_assert(std::same_as>); + } + + template + constexpr void + test_deducible() + { + assert_deducible(std::extents()); + assert_deducible(std::extents()); + assert_deducible(std::extents(3)); + } + + template + constexpr void + test_all() + { + test_ctor(); + static_assert(test_ctor()); + test_deducible(); + } +} + +// ctor: mapping(mapping) +namespace from_same_layout +{ + template + constexpr void + verify_nothrow_convertible(OExtents exts) + { + using Mapping = typename Layout::mapping; + using OMapping = typename Layout::mapping; + + ::verify_nothrow_convertible(OMapping(exts)); + } + + template + constexpr void + verify_nothrow_constructible(OExtents exts) + { + using Mapping = typename Layout::mapping; + using OMapping = typename Layout::mapping; + + ::verify_nothrow_constructible(OMapping(exts)); + } + + template + constexpr bool + test_ctor() + { + verify_nothrow_convertible>( + std::extents{}); + + verify_nothrow_constructible>( + std::extents{}); + + assert_not_constructible< + typename Layout::mapping>, + typename Layout::mapping>>(); + + assert_not_constructible< + typename Layout::mapping>, + typename Layout::mapping>>(); + + verify_nothrow_constructible>( + std::extents{1}); + + verify_nothrow_convertible>( + std::extents{}); + + assert_not_constructible< + typename Layout::mapping>, + typename Layout::mapping>>(); + + verify_nothrow_constructible>( + std::extents{1}); + + verify_nothrow_convertible>( + std::extents{}); + return true; + } + + template + constexpr void + test_all() + { + test_ctor(); + static_assert(test_ctor()); + } +} + +// ctor: mapping(layout_{right,left}::mapping) +namespace from_left_or_right +{ + template + constexpr void + verify_ctor(OExtents oexts) + { + using SMapping = typename SLayout::mapping; + using OMapping = typename OLayout::mapping; + + constexpr bool expected = std::is_convertible_v; + if constexpr (expected) + verify_nothrow_convertible(OMapping(oexts)); + else + verify_nothrow_constructible(OMapping(oexts)); + } + + template + constexpr bool + test_ctor() + { + assert_not_constructible< + typename SLayout::mapping>, + typename OLayout::mapping>>(); + + verify_ctor>( + std::extents{}); + + verify_ctor>( + std::extents{}); + + assert_not_constructible< + typename SLayout::mapping>, + typename OLayout::mapping>>(); + + verify_ctor>( + std::extents{}); + + verify_ctor>( + std::extents{}); + + verify_ctor>( + std::extents{}); + + assert_not_constructible< + typename SLayout::mapping>, + typename OLayout::mapping>>(); + return true; + } + + template + constexpr void + test_all() + { + test_ctor(); + static_assert(test_ctor()); + } +} + +// ctor: mapping(layout_stride::mapping) +namespace from_stride +{ + template + constexpr auto + strides(Mapping m) + { + constexpr auto rank = Mapping::extents_type::rank(); + std::array s; + + if constexpr (rank > 0) + for(size_t i = 0; i < rank; ++i) + s[i] = m.stride(i); + return s; + } + + template + constexpr void + verify_nothrow_convertible(OExtents oexts) + { + using Mapping = typename Layout::mapping; + using OMapping = std::layout_stride::mapping; + + constexpr auto other = OMapping(oexts, strides(Mapping(Extents(oexts)))); + ::verify_nothrow_convertible(other); + } + + template + constexpr void + verify_nothrow_constructible(OExtents oexts) + { + using Mapping = typename Layout::mapping; + using OMapping = std::layout_stride::mapping; + + constexpr auto other = OMapping(oexts, strides(Mapping(Extents(oexts)))); + ::verify_nothrow_constructible(other); + } + + template + constexpr bool + test_ctor() + { + assert_not_constructible< + typename Layout::mapping>, + std::layout_stride::mapping>>(); + + assert_not_constructible< + typename Layout::mapping>, + std::layout_stride::mapping>>(); + + assert_not_constructible< + typename Layout::mapping>, + std::layout_stride::mapping>>(); + + verify_nothrow_convertible>( + std::extents{}); + + verify_nothrow_convertible>( + std::extents{}); + + // Rank == 0 doesn't check IndexType for convertibility. + verify_nothrow_convertible>( + std::extents{}); + + verify_nothrow_constructible>( + std::extents{}); + + verify_nothrow_constructible>( + std::extents{}); + + verify_nothrow_constructible>( + std::extents{}); + + verify_nothrow_constructible>( + std::extents{}); + + verify_nothrow_constructible>( + std::extents{}); + + verify_nothrow_constructible>( + std::extents{}); + return true; + } + + template + constexpr void + test_all() + { + test_ctor(); + static_assert(test_ctor()); + } +} + +template + constexpr void + test_all() + { + default_ctor::test_all(); + from_extents::test_all(); + from_same_layout::test_all(); + from_stride::test_all(); + } + +int +main() +{ + test_all(); + test_all(); + + from_left_or_right::test_all(); + from_left_or_right::test_all(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/debug/out_of_bounds_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/debug/out_of_bounds_neg.cc new file mode 100644 index 000000000000..fb8ff01e8aa2 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/debug/out_of_bounds_neg.cc @@ -0,0 +1,30 @@ +// { dg-do compile { target c++23 } } +// { dg-require-debug-mode "" } +#include + +template + constexpr bool + test_out_of_bounds_1d() + { + auto m = typename Layout::mapping>{}; + (void) m(0); // { dg-error "expansion of" } + return true; + } +static_assert(test_out_of_bounds_1d()); // { dg-error "expansion of" } +static_assert(test_out_of_bounds_1d()); // { dg-error "expansion of" } +static_assert(test_out_of_bounds_1d()); // { dg-error "expansion of" } + +template + constexpr bool + test_out_of_bounds_3d() + { + auto m = typename Layout::mapping>{}; + (void) m(2, 5, 5); // { dg-error "expansion of" } + return true; + } +static_assert(test_out_of_bounds_3d()); // { dg-error "expansion of" } +static_assert(test_out_of_bounds_3d()); // { dg-error "expansion of" } +static_assert(test_out_of_bounds_3d()); // { dg-error "expansion of" } + +// { dg-prune-output "non-constant condition for static assertion" } +// { dg-prune-output "__glibcxx_assert" } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/empty.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/empty.cc new file mode 100644 index 000000000000..655b9b6d6c30 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/empty.cc @@ -0,0 +1,131 @@ +// { dg-do run { target c++23 } } +#include + +#include +#include +#include + +constexpr size_t dyn = std::dynamic_extent; + +template + constexpr void + invoke_stride(Mapping m) + { + // Only checking for UB, e.g. signed overflow. + for(size_t i = 0; i < Mapping::extents_type::rank(); ++i) + m.stride(i); + } + +template + constexpr void + verify_required_span_size(Mapping m) + { VERIFY(m.required_span_size() == 0); } + +template + constexpr void + verify_all(Mapping m) + { + verify_required_span_size(m); + invoke_stride(m); + } + +template +constexpr void +test_static_overflow() +{ + constexpr Int n1 = std::numeric_limits::max(); + constexpr size_t n2 = std::dynamic_extent - 1; + constexpr size_t n = std::cmp_less(n1, n2) ? size_t(n1) : n2; + + verify_all(typename Layout::mapping>{}); + verify_all(typename Layout::mapping>{}); + verify_all(typename Layout::mapping>{}); + verify_all(typename Layout::mapping>{}); + verify_all(typename Layout::mapping>{}); +} + +template +constexpr std::array +make_strides() +{ + std::array strides; + std::ranges::fill(strides, Int(1)); + return strides; +} + +template +constexpr typename Layout::mapping +make_mapping(Extents exts) +{ + using IndexType = typename Extents::index_type; + constexpr auto rank = Extents::rank(); + constexpr auto strides = make_strides(); + + if constexpr (std::same_as) + return typename Layout::mapping(exts, strides); + else + return typename Layout::mapping(exts); +} + +template +constexpr void +test_dynamic_overflow() +{ + constexpr Int n1 = std::numeric_limits::max(); + constexpr size_t n2 = std::dynamic_extent - 1; + constexpr Int n = std::cmp_less(n1, n2) ? n1 : Int(n2); + + verify_all(make_mapping( + std::extents{n, n, n, n})); + + verify_all(make_mapping( + std::extents{n, n, 0, n, n})); + + verify_all(make_mapping( + std::extents{n, n, n})); + + verify_all(make_mapping( + std::extents{n, n, n, 0})); + + verify_all(make_mapping( + std::extents{n, n, n})); + + verify_all(make_mapping( + std::extents{0, n, n, n})); +} + +template +constexpr void +test_overflow() +{ + test_static_overflow(); + test_dynamic_overflow(); +} + +template +constexpr bool +test_all() +{ + test_overflow(); + test_overflow(); + test_overflow(); + test_overflow(); + test_overflow(); + + test_overflow(); + test_overflow(); + test_overflow(); + test_overflow(); + test_overflow(); + test_overflow(); + return true; +} + +int +main() +{ + static_assert(test_all()); + static_assert(test_all()); + static_assert(test_all()); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc new file mode 100644 index 000000000000..58bce5144354 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc @@ -0,0 +1,570 @@ +// { dg-do run { target c++23 } } +#include + +#include "../int_like.h" +#include +#include + +constexpr size_t dyn = std::dynamic_extent; + +template + constexpr bool + test_mapping_properties() + { + using M = typename Layout::mapping; + static_assert(std::__mdspan::__is_extents); + static_assert(std::__mdspan::__mapping_alike); + static_assert(std::copyable); + static_assert(std::is_nothrow_move_constructible_v); + static_assert(std::is_nothrow_move_assignable_v); + static_assert(std::is_nothrow_swappable_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + static_assert(std::is_trivially_copyable_v); + static_assert(std::regular); + + static_assert(M::is_always_unique() && M::is_unique()); + static_assert(M::is_always_strided() && M::is_strided()); + if constexpr (!std::is_same_v) + static_assert(M::is_always_exhaustive() && M::is_exhaustive()); + return true; + } + +template + constexpr bool + test_mapping_properties_all() + { + test_mapping_properties>(); + test_mapping_properties>(); + test_mapping_properties>(); + test_mapping_properties>(); + return true; + } + +// Check operator()(Indices...) +template + constexpr typename Mapping::index_type + linear_index(const Mapping& mapping, + const std::array& indices) + { + typename Mapping::index_type ret = 0; + for(size_t r = 0; r < indices.size(); ++r) + ret += indices[r] * mapping.stride(r); + return ret; + } + +template + constexpr void + test_linear_index(const Mapping& m, Indices... i) + { + using index_type = typename Mapping::index_type; + index_type expected = linear_index(m, std::array{index_type(i)...}); + VERIFY(m(Int(i)...) == expected); + } + +template + constexpr void + test_linear_index_0d() + { + constexpr typename Layout::mapping> m; + VERIFY(m() == 0); + } + +template + constexpr void + test_linear_index_1d() + { + typename Layout::mapping> m; + test_linear_index(m, 0); + test_linear_index(m, 1); + test_linear_index(m, 4); + } + +template + constexpr void + test_linear_index_2d() + { + typename Layout::mapping> m; + test_linear_index(m, 0, 0); + test_linear_index(m, 1, 0); + test_linear_index(m, 0, 1); + test_linear_index(m, 1, 1); + test_linear_index(m, 2, 4); + } + +template + struct MappingFactory + { + template + static constexpr typename Layout::mapping + create(Extents exts) + { return exts; } + }; + +template<> + struct MappingFactory + { + template + static constexpr std::layout_stride::mapping + create(Extents exts) + { + if constexpr (Extents::rank() == 0) + { + auto strides = std::array{}; + return std::layout_stride::mapping(exts, strides); + } + else if constexpr (Extents::rank() == 1) + { + auto strides = std::array{2}; + return std::layout_stride::mapping(exts, strides); + } + else if constexpr (Extents::rank() == 2) + { + size_t m = exts.extent(1); + auto strides = std::array{3*m, 2}; + return std::layout_stride::mapping(exts, strides); + } + else if constexpr (Extents::rank() == 3) + { + size_t n = exts.extent(0); + size_t m = exts.extent(1); + auto strides = std::array{3*m, 2, 11*m*n}; + return std::layout_stride::mapping(exts, strides); + } + } + }; + +template + constexpr void + test_linear_index_3d() + { + auto m = MappingFactory::create(std::extents(3, 5, 7)); + test_linear_index(m, 0, 0, 0); + test_linear_index(m, 1, 0, 0); + test_linear_index(m, 0, 1, 0); + test_linear_index(m, 0, 0, 1); + test_linear_index(m, 1, 1, 0); + test_linear_index(m, 2, 4, 6); + } + +template + concept has_linear_index = requires (Mapping m) + { + { m(Ints(0)...) } -> std::same_as; + }; + +template + constexpr void + test_has_linear_index_0d() + { + using Mapping = typename Layout::mapping>; + static_assert(has_linear_index); + static_assert(!has_linear_index); + static_assert(!has_linear_index); + static_assert(!has_linear_index); + } + +template + constexpr void + test_has_linear_index_1d() + { + using Mapping = typename Layout::mapping>; + static_assert(!has_linear_index); + static_assert(has_linear_index); + static_assert(has_linear_index); + static_assert(has_linear_index); + static_assert(has_linear_index); + static_assert(!has_linear_index); + static_assert(!has_linear_index); + static_assert(!has_linear_index); + } + +template + constexpr void + test_has_linear_index_2d() + { + using Mapping = typename Layout::mapping>; + static_assert(!has_linear_index); + static_assert(has_linear_index); + static_assert(has_linear_index); + static_assert(has_linear_index); + static_assert(has_linear_index); + static_assert(!has_linear_index); + static_assert(!has_linear_index); + static_assert(!has_linear_index); + } + +template + constexpr bool + test_linear_index_all() + { + test_linear_index_0d(); + test_linear_index_1d(); + test_linear_index_2d(); + test_linear_index_3d(); + test_has_linear_index_0d(); + test_has_linear_index_1d(); + test_has_linear_index_2d(); + return true; + } + +template + constexpr typename Mapping::index_type + linear_index_end(Mapping m) + { + using index_type = typename Mapping::index_type; + constexpr size_t rank = Mapping::extents_type::rank(); + + auto impl = [m]( + std::integer_sequence) -> index_type + { + auto exts = m.extents(); + if(((exts.extent(Counts) == 0) || ...)) + return 0; + return m((exts.extent(Counts) - 1)...) + 1; + }; + + return impl(std::make_integer_sequence()); + } + +// Check required_span_size +template + constexpr void + test_required_span_size(Mapping m) + { VERIFY(m.required_span_size() == linear_index_end(m)); } + +template + constexpr void + test_required_span_size_0d() + { + typename Layout::mapping> m; + test_required_span_size(m); + } + +template + constexpr void + test_required_span_size_1d() + { + auto m = MappingFactory::create(std::extents(3)); + test_required_span_size(m); + } + +template + constexpr void + test_required_span_size_2d() + { + auto m = MappingFactory::create(std::extents(3, 5)); + test_required_span_size(m); + } + +template + constexpr void + test_required_span_size_3d() + { + auto m = MappingFactory::create(std::extents(3, 5, 7)); + test_required_span_size(m); + } + +template + constexpr void + test_required_span_size_zero_1d() + { + auto m = MappingFactory::create(std::extents(3, 0)); + test_required_span_size(m); + } + +template + constexpr void + test_required_span_size_zero_3d() + { + auto m = MappingFactory::create(std::extents(3, 0, 7)); + test_required_span_size(m); + } + +template + constexpr bool + test_required_span_size_all() + { + test_required_span_size_0d(); + test_required_span_size_1d(); + test_required_span_size_2d(); + test_required_span_size_3d(); + test_required_span_size_zero_1d(); + test_required_span_size_zero_3d(); + return true; + } + +// Check stride +template + constexpr void + test_stride_1d() + { + std::layout_left::mapping> m; + VERIFY(m.stride(0) == 1); + } + +template<> + constexpr void + test_stride_1d() + { + std::array strides{13}; + std::layout_stride::mapping m(std::extents{}, strides); + VERIFY(m.stride(0) == strides[0]); + VERIFY(m.strides() == strides); + } + +template + constexpr void + test_stride_2d(); + +template<> + constexpr void + test_stride_2d() + { + std::layout_left::mapping> m; + VERIFY(m.stride(0) == 1); + VERIFY(m.stride(1) == 3); + } + +template<> + constexpr void + test_stride_2d() + { + std::layout_right::mapping> m; + VERIFY(m.stride(0) == 5); + VERIFY(m.stride(1) == 1); + } + +template<> + constexpr void + test_stride_2d() + { + std::array strides{13, 2}; + std::layout_stride::mapping m(std::extents{}, strides); + VERIFY(m.stride(0) == strides[0]); + VERIFY(m.stride(1) == strides[1]); + VERIFY(m.strides() == strides); + } + +template + constexpr void + test_stride_3d(); + +template<> + constexpr void + test_stride_3d() + { + std::layout_left::mapping m(std::dextents(3, 5, 7)); + VERIFY(m.stride(0) == 1); + VERIFY(m.stride(1) == 3); + VERIFY(m.stride(2) == 3*5); + } + +template<> + constexpr void + test_stride_3d() + { + std::layout_right::mapping m(std::dextents(3, 5, 7)); + VERIFY(m.stride(0) == 5*7); + VERIFY(m.stride(1) == 7); + VERIFY(m.stride(2) == 1); + } + +template<> + constexpr void + test_stride_3d() + { + std::dextents exts(3, 5, 7); + std::array strides{11, 2, 41}; + std::layout_stride::mapping> m(exts, strides); + VERIFY(m.stride(0) == strides[0]); + VERIFY(m.stride(1) == strides[1]); + VERIFY(m.stride(2) == strides[2]); + VERIFY(m.strides() == strides); + } + +template + constexpr bool + test_stride_all() + { + test_stride_1d(); + test_stride_2d(); + test_stride_3d(); + return true; + } + +template + concept has_stride = requires (Mapping m) + { + { m.stride(0) } -> std::same_as; + }; + +template + constexpr void + test_has_stride_0d() + { + using Mapping = typename Layout::mapping>; + constexpr bool expected = std::is_same_v; + static_assert(has_stride == expected); + } + +template + constexpr void + test_has_stride_1d() + { static_assert(has_stride>>); } + +template + constexpr void + test_has_stride_2d() + { + using Extents = std::extents; + static_assert(has_stride>); + } + +// Check operator== +template + constexpr void + test_eq() + { + typename Layout::mapping> m1; + typename Layout::mapping> m2; + typename Layout::mapping> m3(m1); + + VERIFY(m1 == m1); + VERIFY(m1 != m2); + VERIFY(m1 == m3); + VERIFY(m2 != m3); + } + +template + constexpr void + test_eq_zero() + { + typename Layout::mapping> m1; + typename Layout::mapping> m2; + typename Layout::mapping> m3; + + VERIFY(m1 == m2); + VERIFY(m1 != m3); + } + +template + concept has_op_eq = requires (M1 m1, M2 m2) + { + { m1 == m2 } -> std::same_as; + { m2 == m1 } -> std::same_as; + { m1 != m2 } -> std::same_as; + { m2 != m1 } -> std::same_as; + }; + +template + constexpr void + test_has_op_eq() + { + static_assert(has_op_eq< + typename SLayout::mapping>, + typename OLayout::mapping>> == Expected); + + static_assert(!has_op_eq< + typename SLayout::mapping>, + typename OLayout::mapping>>); + + static_assert(has_op_eq< + typename SLayout::mapping>, + typename OLayout::mapping>> == Expected); + + static_assert(has_op_eq< + typename SLayout::mapping>, + typename OLayout::mapping>> == Expected); + + static_assert(!has_op_eq< + typename SLayout::mapping>, + typename OLayout::mapping>>); + + static_assert(has_op_eq< + typename SLayout::mapping>, + typename OLayout::mapping>> == Expected); + + static_assert(has_op_eq< + typename SLayout::mapping>, + typename OLayout::mapping>> == Expected); + + static_assert(!has_op_eq< + typename SLayout::mapping>, + typename OLayout::mapping>>); + } + +constexpr void +test_has_op_eq_peculiar() +{ + static_assert(has_op_eq< + std::layout_right::mapping>, + std::layout_left::mapping>>); + + static_assert(has_op_eq< + std::layout_right::mapping>, + std::layout_left::mapping>>); + + static_assert(!has_op_eq< + std::layout_right::mapping>, + std::layout_left::mapping>>); +} + +template + constexpr bool + test_mapping_all() + { + test_linear_index_all(); + test_linear_index_all(); + if !consteval + { + test_linear_index_all(); + test_linear_index_all(); + test_linear_index_all(); + } + + test_required_span_size_all(); + test_stride_all(); + + test_eq(); + test_eq_zero(); + return true; + } + +template + constexpr void + test_all() + { + static_assert(std::is_trivially_default_constructible_v); + static_assert(std::is_trivially_copyable_v); + static_assert(test_mapping_properties_all()); + + test_mapping_all(); + static_assert(test_mapping_all()); + + test_has_stride_0d(); + test_has_stride_1d(); + test_has_stride_2d(); + test_has_op_eq(); + } + +int +main() +{ + test_all(); + test_all(); + test_all(); + + test_has_op_eq(); + test_has_op_eq(); + test_has_op_eq(); + test_has_op_eq_peculiar(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc new file mode 100644 index 000000000000..8d2fad2936f6 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc @@ -0,0 +1,513 @@ +// { dg-do run { target c++23 } } +#include + +#include "../int_like.h" +#include + +constexpr size_t dyn = std::dynamic_extent; + +template + constexpr void + test_ctor_default_stride() + { + using Extents = typename MappingStride::extents_type; + MappingStride actual; + typename std::layout_right::mapping expected; + + constexpr auto rank = MappingStride::extents_type::rank(); + if constexpr (rank > 0) + for(size_t i = 0; i < rank; ++i) + VERIFY(actual.stride(i) == expected.stride(i)); + } + +constexpr bool +test_ctor_default_stride_all() +{ + test_ctor_default_stride< + std::layout_stride::mapping>>(); + + test_ctor_default_stride< + std::layout_stride::mapping>>(); + + test_ctor_default_stride< + std::layout_stride::mapping>>(); + + test_ctor_default_stride< + std::layout_stride::mapping>>(); + + test_ctor_default_stride< + std::layout_stride::mapping>>(); + + test_ctor_default_stride< + std::layout_stride::mapping>>(); + return true; +} + +template +constexpr void +test_stride_constructible() +{ + static_assert(std::is_nothrow_constructible_v< + std::layout_stride::mapping, E_arg, std::span> == Expected); + static_assert(std::is_nothrow_constructible_v< + std::layout_stride::mapping, E_arg, std::array> == Expected); + static_assert(!std::is_constructible_v, + E_arg>); +} + +constexpr void +test_stride_constructible_all() +{ + using E0 = std::extents; + using E1 = std::extents; + using E2 = std::extents; + + test_stride_constructible(); + test_stride_constructible(); + test_stride_constructible(); + test_stride_constructible(); + test_stride_constructible(); + test_stride_constructible(); + test_stride_constructible(); + test_stride_constructible(); + test_stride_constructible(); +} + +template + constexpr void + test_ctor_shape_strides(Extents exts, Shape strides) + { + using M = std::layout_stride::mapping; + M m(exts, strides); + + if constexpr (Extents::rank() > 0) + for(size_t i = 0; i < exts.rank(); ++i) + { + VERIFY(m.stride(i) == strides[i]); + VERIFY(m.extents().extent(i) == exts.extent(i)); + } + } + +constexpr bool +test_ctor_shape_stride_all() +{ + test_ctor_shape_strides(std::extents{}, std::array{}); + test_ctor_shape_strides(std::extents{}, std::array{3}); + test_ctor_shape_strides(std::extents{}, + std::array{20, 5, 45}); + return true; +} + +template Strided, + std::array Unique, std::array Exhautive, + typename Extents::index_type Offset = 0> + struct MappingLike + { + using extents_type = Extents; + using index_type = typename Extents::index_type; + + constexpr + MappingLike(extents_type extents, + std::array strides) + : _extents(extents), _strides(strides) + { } + + static constexpr bool + is_always_strided() requires (Strided[0]) + { return Strided[1]; } + + static constexpr bool + is_always_unique() requires (Unique[0]) + { return Unique[1]; } + + static constexpr bool + is_always_exhaustive() requires (Exhautive[0]) + { return Exhautive[1]; } + + constexpr Extents + extents() const { return _extents; } + + constexpr index_type + stride(size_t i) const { return _strides[i]; } + + template + constexpr index_type + operator()(Indices... indices) const + { + if (empty()) + VERIFY(false); + + std::array ind_arr{indices...}; + index_type ret = Offset; + for(size_t i = 0; i < Extents::rank(); ++i) + ret += ind_arr[i]*_strides[i]; + return ret; + } + + private: + constexpr bool + empty() const + { + for (size_t i = 0; i < extents_type::rank(); ++i) + if (_extents.extent(i) == 0) + return true; + return false; + } + + Extents _extents; + std::array _strides; + }; + + +template +struct ExtentLike +{ + using index_type = int; + + static constexpr size_t + rank() { return Rank; } +}; + + +template +constexpr void +test_mapping_like_constructible() +{ + using M = std::layout_stride::mapping; + using E2 = std::dextents; + using E3 = std::dextents; + using E4 = ExtentLike; + + constexpr auto TT = std::array{true, true}; + constexpr auto FT = std::array{false, true}; + constexpr auto TF = std::array{true, false}; + + static_assert(std::is_constructible_v>); + static_assert(std::is_constructible_v>); + static_assert(!std::is_constructible_v>); + static_assert(!std::is_constructible_v>); + static_assert(!std::is_constructible_v>); + static_assert(!std::is_constructible_v>); + static_assert(!std::is_constructible_v>); + static_assert(!std::is_constructible_v>); + static_assert(std::is_constructible_v>); + static_assert(!std::is_constructible_v>); + static_assert(!std::is_constructible_v>); +} + +constexpr void +test_mapping_like_constructible_all() +{ + test_mapping_like_constructible>(); + test_mapping_like_constructible>(); + test_mapping_like_constructible>(); +} + +template +constexpr void +test_mapping_like_convertible() +{ + using M1 = std::layout_stride::mapping; + using M2 = std::layout_stride::mapping; + constexpr auto TT = std::array{true, true}; + + static_assert(!std::is_convertible_v, M1>); + static_assert(!std::is_convertible_v, M1>); + static_assert(!std::is_convertible_v, M2>); + + static_assert(std::is_convertible_v, M1>); + static_assert(std::is_convertible_v, M1>); + static_assert(std::is_convertible_v, M1>); + + static_assert(!std::is_convertible_v, M2>); + static_assert(!std::is_convertible_v, M2>); + static_assert(!std::is_convertible_v, M2>); +} + +constexpr void +test_mapping_like_convertible_all() +{ + test_mapping_like_convertible, + std::extents>(); + test_mapping_like_convertible, + std::extents>(); + test_mapping_like_convertible, + std::extents>(); +} + +template +constexpr void +test_ctor_stride_like(Extents exts, std::array strides) +{ + auto other_right = std::layout_right::mapping(exts); + auto other_left = std::layout_left::mapping(exts); + auto other_stride = std::layout_stride::mapping(exts, strides); + + VERIFY(std::layout_stride::mapping(other_right) == other_right); + VERIFY(std::layout_stride::mapping(other_left) == other_left); + VERIFY(std::layout_stride::mapping(other_stride) == other_stride); +} + +constexpr void +test_ctor_stride_like_all() +{ + using E1 = std::extents; + auto s1 = std::array{}; + test_ctor_stride_like(E1{}, s1); + + using E2 = std::extents; + auto s2 = std::array{2}; + test_ctor_stride_like(E2{}, s2); + + using E3 = std::extents; + auto s3 = std::array{5, 1, 15}; + test_ctor_stride_like(E3{}, s3); +} + +constexpr bool +test_ctor_strides_all() +{ + test_ctor_default_stride_all(); + test_ctor_shape_stride_all(); + test_ctor_stride_like_all(); + return true; +} + +// Check is_exhaustive. +template + constexpr void + test_is_exhaustive(Extents extents, Strides strides, bool expected) + { + std::layout_stride::mapping m(extents, strides); + VERIFY(m.is_exhaustive() == expected); + + bool always_exhaustive = extents.rank() == 0 || m.required_span_size() == 0; + VERIFY(m.is_always_exhaustive() == always_exhaustive); + } + +constexpr void +test_is_exhaustive_zero_1d() +{ + std::extents extents; + test_is_exhaustive(extents, std::array{1}, true); + test_is_exhaustive(extents, std::array{2}, true); +} + +constexpr void +test_is_exhaustive_zero_3d() +{ + std::extents extents; + + test_is_exhaustive(extents, std::array{1, 1, 1}, true); + test_is_exhaustive(extents, std::array{1, 2*21, 2*3}, true); + test_is_exhaustive(extents, std::array{7, 2*21, 1}, true); + test_is_exhaustive(extents, std::array{1, 21, 3}, true); + test_is_exhaustive(extents, std::array{7, 21, 1}, true); +} + +constexpr void +test_is_exhaustive_0d() +{ + std::extents extents; + test_is_exhaustive(extents, std::array{}, true); +} + +constexpr void +test_is_exhaustive_1d() +{ + std::extents extents; + test_is_exhaustive(extents, std::array{1}, true); + test_is_exhaustive(extents, std::array{3}, false); +} + + +constexpr void +test_is_exhaustive_3d() +{ + std::extents extents(5); + + test_is_exhaustive(extents, std::array{1, 3, 3*5}, true); + test_is_exhaustive(extents, std::array{5*7, 1, 5}, true); + test_is_exhaustive(extents, std::array{7, 3*7, 1}, true); + + test_is_exhaustive(extents, std::array{1, 3, 2*3*5}, false); + test_is_exhaustive(extents, std::array{2*5*7, 1, 2*5}, false); + test_is_exhaustive(extents, std::array{2*7, 2*3*7, 2}, false); +} + +constexpr void +test_is_exhaustive_ones() +{ + std::extents extents; + test_is_exhaustive(extents, std::array{1, 1, 1, 1}, true); + test_is_exhaustive(extents, std::array{1, 1, 1, 3}, true); + test_is_exhaustive(extents, std::array{3, 3, 1, 3}, true); + test_is_exhaustive(extents, std::array{3, 1, 1, 3}, true); +} + +constexpr bool +test_is_exhaustive_all() +{ + test_is_exhaustive_zero_1d(); + test_is_exhaustive_zero_3d(); + test_is_exhaustive_ones(); + test_is_exhaustive_0d(); + test_is_exhaustive_1d(); + test_is_exhaustive_3d(); + return true; +} + +template + using OffsetMapping = MappingLike; + +template + constexpr void + test_eq(Extents exts, + std::array left_strides, + std::array right_strides, + std::array padded_strides) + { + using DExtents = std::dextents; + + std::layout_left::mapping ml; + std::layout_right::mapping mr(exts); + + std::layout_stride::mapping msd; + std::layout_stride::mapping msl(exts, left_strides); + std::layout_stride::mapping msr(exts, right_strides); + std::layout_stride::mapping msp(exts, padded_strides); + + OffsetMapping mor{exts, right_strides}; + OffsetMapping mol{exts, left_strides}; + OffsetMapping mop{exts, padded_strides}; + OffsetMapping moo{exts, right_strides}; + + VERIFY(msd == mr); + VERIFY(msd == mor); + VERIFY(msd != msp); + VERIFY(msd != mop); + + VERIFY(msl == ml); + VERIFY(msl == mol); + VERIFY(msd != msp); + VERIFY(msl != mop); + + VERIFY(msp == mop); + VERIFY(msp != ml); + VERIFY(msp != mr); + + VERIFY(msd != moo); + } + +constexpr void +test_eq_0d() +{ + using Extents = std::extents; + Extents exts; + std::layout_left::mapping ml; + std::layout_right::mapping mr; + std::layout_stride::mapping ms; + OffsetMapping mor{exts, {}}; + OffsetMapping moo{exts, {}}; + + VERIFY(ms == ml); + VERIFY(ms == mr); + VERIFY(ms == mor); + VERIFY(ms != moo); +} + +constexpr void +test_eq_1d() +{ + using Extents = std::extents; + auto exhaustive_strides = std::array{1}; + auto padded_strides = std::array{2}; + + test_eq(Extents{}, exhaustive_strides, exhaustive_strides, padded_strides); +} + +constexpr void +test_eq_2d() +{ + using Extents = std::extents; + auto left_strides = std::array{1, 1}; + auto right_strides = std::array{2, 1}; + auto padded_strides = std::array{2, 8}; + + test_eq(Extents{}, left_strides, right_strides, padded_strides); +} + +constexpr void +test_eq_zero() +{ + using Extents = std::extents; + using Mapping = std::layout_stride::mapping; + + Extents exts; + std::array sl{1, 5}; + std::array sr{5, 1}; + + Mapping m1(exts, sl); + Mapping m2(exts, sl); + Mapping m3(exts, sr); + OffsetMapping m4(exts, sl); + + VERIFY(m1 == m2); + VERIFY(m1 != m3); + VERIFY(m1 == m4); + +} + +constexpr bool +test_eq_all() +{ + test_eq_0d(); + test_eq_1d(); + test_eq_2d(); + test_eq_zero(); + return true; +} + +template + concept has_op_eq = requires (M1 m1, M2 m2) + { + { m1 == m2 } -> std::same_as; + { m2 == m1 } -> std::same_as; + { m1 != m2 } -> std::same_as; + { m2 != m1 } -> std::same_as; + }; + +constexpr void +test_has_op_eq() +{ + using E1 = std::extents; + using E2 = std::extents; + using E3 = std::extents; + constexpr auto FT = std::array{false, true}; + + static_assert(!has_op_eq< + std::layout_stride::mapping, MappingLike>); + + static_assert(!has_op_eq< + std::layout_stride::mapping, MappingLike>); + + static_assert(!has_op_eq< + std::layout_stride::mapping, MappingLike>); +} + +int +main() +{ + test_ctor_strides_all(); + static_assert(test_ctor_strides_all()); + test_mapping_like_convertible_all(); + test_mapping_like_constructible_all(); + test_stride_constructible_all(); + test_is_exhaustive_all(); + static_assert(test_is_exhaustive_all()); + test_eq_all(); + static_assert(test_eq_all()); + test_has_op_eq(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc new file mode 100644 index 000000000000..6ffddd11e951 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc @@ -0,0 +1,771 @@ +// { dg-do run { target c++23 } } +#include + +#include +#include "int_like.h" +#include "layout_like.h" +#include + +constexpr auto dyn = std::dynamic_extent; + +template> + constexpr void + assert_typedefs() + { + static_assert(std::same_as); + static_assert(std::same_as); + static_assert(std::same_as); + static_assert(std::same_as>); + static_assert(std::same_as); + static_assert(std::same_as>); + static_assert(std::same_as); + static_assert(std::same_as); + static_assert(std::same_as); + static_assert(std::same_as); + static_assert(std::same_as); + } + +template typename A> + constexpr void + test_typedefs() + { assert_typedefs>, T, E, L, A>(); } + +constexpr void +test_typedefs_all() +{ + using E = std::extents; + using L = std::layout_left; + + test_typedefs(); + test_typedefs(); +} + +template + constexpr void + test_rank() + { + using Extents = typename MDSpan::extents_type; + static_assert(MDSpan::rank() == Extents::rank()); + static_assert(MDSpan::rank_dynamic() == Extents::rank_dynamic()); + } + +constexpr bool +test_rank_all() +{ + test_rank>>(); + test_rank>>(); + test_rank>>(); + return true; +} + +template + constexpr void + test_extent(Extents exts) + { + double data = 1.0; + auto md = std::mdspan(&data, exts); + using MDSpan = decltype(md); + + for(size_t i = 0; i < MDSpan::rank(); ++i) + { + VERIFY(MDSpan::static_extent(i) == Extents::static_extent(i)); + VERIFY(md.extent(i) == exts.extent(i)); + } + } + +constexpr bool +test_extent_all() +{ + // For rank == 0, check existence of the methods without calling them. + test_extent(std::extents{}); + test_extent(std::extents{}); + test_extent(std::extents{}); + return true; +} + +template + constexpr void + test_class_properties() + { + static_assert(std::copyable); + static_assert(std::is_nothrow_move_constructible_v); + static_assert(std::is_nothrow_move_assignable_v); + static_assert(std::is_nothrow_swappable_v); + constexpr bool trivially_copyable = + std::is_trivially_copyable_v + && std::is_trivially_copyable_v + && std::is_trivially_copyable_v; + static_assert(std::is_trivially_copyable_v == trivially_copyable); + } + +constexpr bool +test_class_properties_all() +{ + test_class_properties>>(); + test_class_properties>>(); + test_class_properties>>(); + return true; +} + +template + class ThrowingDefaultAccessor + { + public: + using element_type = T; + using reference = element_type&; + using data_handle_type = element_type*; + using offset_policy = ThrowingDefaultAccessor; + + ThrowingDefaultAccessor() noexcept(false) + { } + + reference + access(data_handle_type p, size_t i) const + { return p[i]; } + + typename offset_policy::data_handle_type + offset(data_handle_type p, size_t i) const + { return p + i; } + }; + +constexpr bool +test_default_ctor() +{ + static_assert(!std::is_default_constructible_v>>); + static_assert(!std::is_default_constructible_v>>); + static_assert(std::is_default_constructible_v>>); + + std::mdspan> md; + VERIFY(md.data_handle() == nullptr); + VERIFY(md.empty()); + return true; +} + +template typename Accessor, bool Expected> + constexpr void + test_nothrow_default_ctor() + { + using Extents = std::extents; + using Layout = std::layout_left; + using MDSpan = std::mdspan>; + + static_assert(std::is_default_constructible_v); + static_assert(std::is_nothrow_default_constructible_v == Expected); + } + +constexpr bool +test_from_other() +{ + using Extents = std::extents; + auto exts = Extents{}; + + auto mapping = std::layout_right::mapping(exts); + constexpr size_t n = mapping.required_span_size(); + std::array storage{}; + + auto md1 = std::mdspan(storage.data(), exts); + auto md2 = std::mdspan>(md1); + + VERIFY(md1.data_handle() == md2.data_handle()); + VERIFY(md1.size() == md2.size()); + + static_assert(!std::is_convertible_v< + std::mdspan>, + std::mdspan>>); + + static_assert(std::is_convertible_v< + std::mdspan>, + std::mdspan>>); + + static_assert(!std::is_constructible_v< + std::mdspan>, + std::mdspan>>); + + return true; +} + +template> + constexpr void + assert_deduced_typedefs(auto md) + { assert_typedefs(); } + +constexpr bool +test_from_carray() +{ + constexpr size_t n = 5; + double data[n] = {1.1, 2.2, 3.3, 4.4, 5.5}; + + auto md = std::mdspan(data); + assert_deduced_typedefs>(md); + VERIFY(md.rank() == 1); + VERIFY(md.rank_dynamic() == 0); + VERIFY(md[2] == data[2]); + return true; +} + +constexpr bool +test_from_pointer() +{ + double value = 12.3; + auto md = std::mdspan(&value); + assert_deduced_typedefs>(md); + VERIFY(md.rank() == 0); + VERIFY(md.rank_dynamic() == 0); + VERIFY(md[] == value); + return true; +} + +constexpr bool +test_from_pointer_and_shape() +{ + constexpr size_t n = 6; + std::array data{1.1, 2.2, 3.3, 4.4, 5.5, 6.6}; + std::array shape{2, 3}; + std::span shape_view(shape); + + auto verify = [&data](auto md) + { + assert_deduced_typedefs>(md); + VERIFY(md.rank() == 2); + VERIFY(md.rank_dynamic() == 2); + VERIFY((md[0, 0]) == data[0]); + VERIFY((md[0, 1]) == data[1]); + VERIFY((md[1, 0]) == data[3]); + }; + + verify(std::mdspan(data.data(), shape[0], shape[1])); + verify(std::mdspan(data.data(), shape)); + verify(std::mdspan(data.data(), shape_view)); + + std::mdspan> md1 = {data.data(), shape}; + verify(md1); + + std::mdspan> md2 = {data.data(), shape_view}; + verify(md2); + + static_assert(std::is_constructible_v< + std::mdspan>, float*>); + static_assert(!std::is_constructible_v< + std::mdspan>, float*, int>); + static_assert(std::is_constructible_v< + std::mdspan>, float*, int, int>); + static_assert(std::is_constructible_v< + std::mdspan>, float*, std::span>); + static_assert(std::is_constructible_v< + std::mdspan>, float*, std::span>); + static_assert(!std::is_convertible_v< + float*, std::mdspan>>); + + static_assert(std::is_constructible_v< + std::mdspan>, float*, std::span>); + static_assert(!std::is_constructible_v< + std::mdspan>, float*, std::span>); + static_assert(!std::is_constructible_v< + std::mdspan>, float*, std::span>); + static_assert(!std::is_constructible_v< + std::mdspan>, float*, std::span>); + return true; +} + +constexpr bool +test_from_pointer_and_integral_constant() +{ + std::array buffer{}; + double * ptr = buffer.data(); + + auto verify = [ptr](auto actual, auto exts) + { + auto expected = std::mdspan(ptr, exts); + static_assert(std::same_as); + VERIFY(actual.extents() == expected.extents()); + }; + + auto c3 = std::integral_constant{}; + auto c6 = std::integral_constant{}; + + verify(std::mdspan(ptr, 6), std::extents(6)); + verify(std::mdspan(ptr, c6), std::extents(c6)); + verify(std::mdspan(ptr, 2, c3), std::extents(2, c3)); + return true; +} + +constexpr bool +test_from_extents() +{ + constexpr size_t n = 3*5*7; + std::array storage{}; + using Extents = std::extents; + auto exts = Extents{}; + auto md = std::mdspan(storage.data(), exts); + + assert_deduced_typedefs(md); + VERIFY(md.data_handle() == storage.data()); + VERIFY(md.extents() == exts); + return true; +} + +constexpr bool +test_from_mapping() +{ + constexpr size_t n = 3*5*7; + std::array storage{}; + using Extents = std::extents; + + auto exts = Extents{}; + auto m = std::layout_left::mapping(exts); + auto md = std::mdspan(storage.data(), m); + + assert_deduced_typedefs(md); + VERIFY(md.data_handle() == storage.data()); + VERIFY(md.mapping() == m); + return true; +} + +constexpr bool +test_from_accessor() +{ + constexpr size_t n = 3*5*7; + std::array storage{}; + using Extents = std::extents; + + auto exts = Extents{}; + auto m = std::layout_left::mapping(exts); + auto a = std::default_accessor{}; + auto md = std::mdspan(storage.data(), m, a); + + assert_deduced_typedefs(md); + VERIFY(md.data_handle() == storage.data()); + VERIFY(md.mapping() == m); + return true; +} + +template + concept has_pack_ctor = requires + { + { MDSpan(Pointer{}, Ints(0)...) } -> std::same_as; + }; + +template + constexpr bool + test_from_int_like() + { + constexpr size_t n = 3*5*7; + std::array storage{}; + + auto verify = [&](auto md) + { + VERIFY(md.data_handle() == storage.data()); + VERIFY(md.extent(0) == 3); + VERIFY(md.extent(1) == 5); + VERIFY(md.extent(2) == 7); + }; + + static_assert(has_pack_ctor>, + float*, CustomInt, int, CustomInt> == ValidForPacks); + + static_assert(std::is_constructible_v< + std::mdspan>, float*, + std::span> == ValidForArrays); + + static_assert(std::is_constructible_v< + std::mdspan>, float*, + std::array> == ValidForArrays); + + if constexpr (ValidForPacks) + verify(std::mdspan(storage.data(), CustomInt(3), 5, CustomInt(7))); + + if constexpr (ValidForArrays) + { + auto shape = std::array{CustomInt(3), CustomInt(5), CustomInt(7)}; + auto shape_view = std::span{shape}; + verify(std::mdspan(storage.data(), shape)); + verify(std::mdspan(storage.data(), shape_view)); + } + return true; + } + +template + class OpaqueAccessor + { + struct Handle + { + constexpr + Handle(T * other) + : ptr(other) + { } + + constexpr + Handle(const Handle&) noexcept(NothrowConstructible) = default; + + constexpr + Handle(Handle&&) noexcept(NothrowConstructible) = default; + + constexpr Handle& + operator=(const Handle&) noexcept(NothrowAssignable) = default; + + constexpr Handle& + operator=(Handle&&) noexcept(NothrowAssignable) = default; + + T * ptr; + }; + + public: + using element_type = T; + using reference = T&; + using data_handle_type = Handle; + using offset_policy = OpaqueAccessor; + + reference + access(data_handle_type p, size_t i) const + { + ++access_count; + return p.ptr[i]; + } + + typename offset_policy::data_handle_type + offset(data_handle_type p, size_t i) const + { + ++offset_count; + return typename offset_policy::data_handle_type{(void*)(p.ptr + i)}; + } + + mutable size_t access_count = 0; + mutable size_t offset_count = 0; + }; + +void +test_from_opaque_accessor() +{ + constexpr size_t n = 3*5*7; + std::array storage{}; + using Extents = std::extents; + + auto exts = Extents{}; + auto m = std::layout_left::mapping(exts); + auto a = OpaqueAccessor{}; + auto handle = OpaqueAccessor::data_handle_type{storage.data()}; + auto md = std::mdspan(handle, m, a); + + using MDSpan = decltype(md); + static_assert(std::same_as); + + VERIFY((md[0, 0, 0]) == 0.0); + VERIFY(md.accessor().access_count == 1); + + VERIFY((md[2, 4, 6]) == 0.0); + VERIFY(md.accessor().access_count == 2); +} + +template + class BaseClassAccessor + { + public: + using element_type = T; + using reference = Base&; + using data_handle_type = T*; + using offset_policy = BaseClassAccessor; + + static_assert(std::common_reference_with); + + reference + access(data_handle_type p, size_t i) const + { return p[i]; } + + typename offset_policy::data_handle_type + offset(data_handle_type p, size_t i) const + { return typename offset_policy::data_handle_type{p + i}; } + }; + +struct Base +{ + double value = 1.0; +}; + +struct Derived : Base +{ + double value = 2.0; +}; + +void +test_from_base_class_accessor() +{ + constexpr size_t n = 3*5*7; + std::array storage{}; + using Extents = std::extents; + + auto exts = Extents{}; + auto m = std::layout_left::mapping(exts); + auto a = BaseClassAccessor{}; + auto md = std::mdspan(storage.data(), m, a); + + using MDSpan = decltype(md); + static_assert(std::same_as); + static_assert(std::same_as); + VERIFY((md[0, 0, 0].value) == 1.0); + VERIFY((md[2, 4, 6].value) == 1.0); +} + +constexpr bool +test_from_mapping_like() +{ + double data = 1.1; + auto m = LayoutLike::mapping>{}; + auto md = std::mdspan(&data, m); + VERIFY((md[0, 0, 0]) == data); + VERIFY((md[0, 1, 2]) == data); + return true; +} + +template + constexpr void + test_empty(MDSpan md) + { + VERIFY(md.empty() == (md.size() == 0)); + } + +constexpr bool +test_empty_all() +{ + test_empty(std::mdspan>{}); + return true; +} + +template +concept indexable = requires (MDSpan md, Args... args) +{ + { md[args...] } -> std::same_as; +}; + +template + constexpr bool + test_access() + { + using Extents = std::extents; + auto exts = Extents{}; + + auto mapping = std::layout_left::mapping(exts); + constexpr size_t n = mapping.required_span_size(); + std::array storage{}; + + auto md = std::mdspan(storage.data(), mapping); + using MDSpan = decltype(md); + + for(int i = 0; i < exts.extent(0); ++i) + for(int j = 0; j < exts.extent(1); ++j) + for(int k = 0; k < exts.extent(2); ++k) + { + storage[mapping(i, j, k)] = 1.0; + if constexpr (ValidForPacks) + VERIFY((md[Int(i), Int(j), Int(k)]) == 1.0); + + if constexpr (ValidForArrays) + { + std::array ijk{Int(i), Int(j), Int(k)}; + VERIFY((md[ijk]) == 1.0); + VERIFY((md[std::span(ijk)]) == 1.0); + } + storage[mapping(i, j, k)] = 0.0; + } + + if constexpr (!ValidForPacks) + static_assert(!indexable); + + if constexpr (!ValidForArrays) + { + static_assert(!indexable>); + static_assert(!indexable>); + } + return true; + } + +constexpr bool +test_swap() +{ + using Extents = std::dextents; + auto e1 = Extents{3, 5}; + auto e2 = Extents{7, 11}; + + std::array s1{}; + std::array s2{}; + + auto md1 = std::mdspan(s1.data(), e1); + auto md2 = std::mdspan(s2.data(), e2); + + std::swap(md1, md2); + + VERIFY(md1.data_handle() == s2.data()); + VERIFY(md2.data_handle() == s1.data()); + + VERIFY(md1.size() == s2.size()); + VERIFY(md2.size() == s1.size()); + return true; +} + +namespace adl +{ + template + struct SwappableAccessor + { + using element_type = T; + using reference = T&; + using data_handle_type = T*; + using offset_policy = SwappableAccessor; + + reference + access(data_handle_type p, size_t i) const + { return p[i]; } + + typename offset_policy::data_handle_type + offset(data_handle_type p, size_t i) const + { return p + i; } + + friend void + swap(SwappableAccessor&, SwappableAccessor&) + { ++swap_count; } + + static inline size_t swap_count = 0; + }; +} + +void +test_swap_adl() +{ + using Extents = std::extents; + using Layout = std::layout_left; + using Accessor = adl::SwappableAccessor; + Accessor::swap_count = 0; + + std::mdspan m1, m2; + swap(m1, m2); + VERIFY(Accessor::swap_count == 1); +} + +template +constexpr void +test_nothrow_movable() +{ + using Layout = std::layout_left; + using Extents = std::dextents; + using Accessor = OpaqueAccessor; + using Handle = Accessor::data_handle_type; + static_assert(std::is_nothrow_move_assignable_v); + static_assert(std::is_nothrow_move_constructible_v); + static_assert(std::is_nothrow_move_assignable_v == Assignable); + static_assert(std::is_nothrow_move_constructible_v == Constructible); + + using MDSpan = std::mdspan; + static_assert(std::is_nothrow_move_assignable_v == Assignable); + static_assert(std::is_nothrow_move_constructible_v == Constructible); +} + +constexpr void +test_nothrow_movable_all() +{ + using MDSpan = std::mdspan>; + static_assert(std::is_nothrow_move_assignable_v); + static_assert(std::is_nothrow_move_constructible_v); + + test_nothrow_movable(); + test_nothrow_movable(); + test_nothrow_movable(); + test_nothrow_movable(); +} + +template + constexpr void + test_nothrow_is_methods() + { + using Extents = std::extents; + using MDSpan = std::mdspan; + static_assert(noexcept(MDSpan::is_always_unique()) == Expected); + static_assert(noexcept(MDSpan::is_always_exhaustive()) == Expected); + static_assert(noexcept(MDSpan::is_always_strided()) == Expected); + + static_assert(noexcept(std::declval().is_unique()) == Expected); + static_assert(noexcept(std::declval().is_exhaustive()) == Expected); + static_assert(noexcept(std::declval().is_strided()) == Expected); + } + +int +main() +{ + test_typedefs_all(); + + test_rank_all(); + test_extent_all(); + static_assert(test_extent_all()); + + test_class_properties_all(); + static_assert(test_class_properties_all()); + + test_empty_all(); + static_assert(test_empty_all()); + + test_default_ctor(); + static_assert(test_default_ctor()); + + test_nothrow_default_ctor(); + test_nothrow_default_ctor(); + + test_from_other(); + static_assert(test_from_other()); + + test_from_carray(); + static_assert(test_from_carray()); + + test_from_pointer_and_shape(); + static_assert(test_from_pointer_and_shape()); + + test_from_pointer_and_integral_constant(); + static_assert(test_from_pointer_and_integral_constant()); + + test_from_extents(); + static_assert(test_from_extents()); + + test_from_mapping(); + static_assert(test_from_mapping()); + + test_from_accessor(); + static_assert(test_from_accessor()); + + test_from_int_like(); + static_assert(test_from_int_like()); + test_from_int_like(); + test_from_int_like(); + test_from_int_like(); + test_from_int_like(); + + test_from_opaque_accessor(); + test_from_base_class_accessor(); + test_from_mapping_like(); + static_assert(test_from_mapping_like()); + + test_access(); + static_assert(test_access()); + test_access(); + test_access(); + test_access(); + test_access(); + + test_swap(); + static_assert(test_swap()); + test_swap_adl(); + + test_nothrow_movable_all(); + test_nothrow_is_methods(); + test_nothrow_is_methods(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/out_of_bounds_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/out_of_bounds_neg.cc new file mode 100644 index 000000000000..dceae56e9d93 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/out_of_bounds_neg.cc @@ -0,0 +1,24 @@ +// { dg-do compile { target c++23 } } +#include + +#include "layout_like.h" + +template +constexpr bool +test_invalid_multi_index() +{ + + double data = 1.1; + auto m = typename Layout::mapping>{}; + auto md = std::mdspan(&data, m); + + [[maybe_unused]] double x = md[0, 2, 2]; // { dg-error "expansion of" } + return true; +}; +static_assert(test_invalid_multi_index()); // { dg-error "expansion of" } +static_assert(test_invalid_multi_index()); // { dg-error "expansion of" } +static_assert(test_invalid_multi_index()); // { dg-error "expansion of" } +static_assert(test_invalid_multi_index()); // { dg-error "expansion of" } + +// { dg-prune-output "non-constant condition" } +// { dg-prune-output "__glibcxx_assert" } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/version.cc b/libstdc++-v3/testsuite/23_containers/mdspan/version.cc new file mode 100644 index 000000000000..106ee4010ee6 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/version.cc @@ -0,0 +1,9 @@ +// { dg-do compile { target c++23 } } +#include + +#ifndef __cpp_lib_mdspan +#error "Feature test macro __cpp_lib_mdspan is missing for " +#if __cpp_lib_mdspan < 202207 +#error "Feature test macro __cpp_lib_mdspan has the wrong value" +#endif +#endif diff --git a/libstdc++-v3/testsuite/23_containers/span/120997.cc b/libstdc++-v3/testsuite/23_containers/span/120997.cc new file mode 100644 index 000000000000..fbf194c87388 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/span/120997.cc @@ -0,0 +1,46 @@ +// { dg-do run { target c++26 } } + +#include +#include + +void +test_first() +{ + bool arr[5]; + std::span s(arr); + std::span s2 = s.first(5); + VERIFY( s2.data() == s.data() ); + std::span s3 = s.first<5>(); + VERIFY( s3.data() == s.data() ); +} + +void +test_last() +{ + bool arr[5]; + std::span s(arr); + std::span s2 = s.last(5); + VERIFY( s2.data() == s.data() ); + std::span s3 = s.last<5>(); + VERIFY( s3.data() == s.data() ); +} + +void +test_subspan() +{ + bool arr[5]; + std::span s(arr); + std::span s2 = s.subspan(0, 5); + VERIFY( s2.data() == s.data() ); + std::span s3 = s.subspan<0>(); + VERIFY( s3.data() == s.data() ); + std::span s4 = s.subspan<0, 5>(); + VERIFY( s4.data() == s.data() ); +} + +int main() +{ + test_first(); + test_last(); + test_subspan(); +} diff --git a/libstdc++-v3/testsuite/23_containers/span/contiguous_range_neg.cc b/libstdc++-v3/testsuite/23_containers/span/contiguous_range_neg.cc index c9e9112ed6dc..890fdf8aea08 100644 --- a/libstdc++-v3/testsuite/23_containers/span/contiguous_range_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/contiguous_range_neg.cc @@ -25,6 +25,7 @@ main() { std::deque d{}; std::span myspan(d); // { dg-error "no match" } + (void) myspan; } // { dg-prune-output "data" } diff --git a/libstdc++-v3/testsuite/23_containers/span/deduction.cc b/libstdc++-v3/testsuite/23_containers/span/deduction.cc index dce6cedf89bd..c66db90222e6 100644 --- a/libstdc++-v3/testsuite/23_containers/span/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/span/deduction.cc @@ -80,4 +80,7 @@ test01() std::span s12(const_cast&>(s5)); static_assert( is_dynamic_span(s12) ); + + std::span s13(a.data(), std::integral_constant{}); + static_assert( is_static_span(s13)); } diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/const_container.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/const_container.cc new file mode 100644 index 000000000000..e62f15822018 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/const_container.cc @@ -0,0 +1,19 @@ +// { dg-do compile { target c++11 } } + +#include + +#include + +// PR c++/116369 +const std::unordered_map um + { + { 0, 1 }, + { 2, 3 }, + { 4, 5 } + }; + +int main() +{ + VERIFY( um.size() == 3 ); + VERIFY( um.find(0) != um.end() ); +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/const_container.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/const_container.cc new file mode 100644 index 000000000000..3da1e3327a53 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/const_container.cc @@ -0,0 +1,22 @@ +// { dg-do compile { target c++11 } } + +#include + +#include + +// PR c++/116369 +const std::unordered_multimap umm + { + { 0, 1 }, + { 0, 1 }, + { 2, 3 }, + { 2, 3 }, + { 4, 5 }, + { 4, 5 } + }; + +int main() +{ + VERIFY( umm.size() == 6 ); + VERIFY( umm.find(0) != umm.end() ); +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/const_container.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/const_container.cc new file mode 100644 index 000000000000..841d25a2e62b --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/const_container.cc @@ -0,0 +1,15 @@ +// { dg-do compile { target c++11 } } + +#include + +#include + +// PR c++/116369 +const std::unordered_multiset ums + { 0, 0, 1, 1, 2, 2 }; + +int main() +{ + VERIFY( ums.size() == 6 ); + VERIFY( ums.find(0) != ums.end() ); +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/const_container.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/const_container.cc new file mode 100644 index 000000000000..ffdbbad57842 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/const_container.cc @@ -0,0 +1,14 @@ +// { dg-do compile { target c++11 } } + +#include + +#include + +// PR c++/116369 +const std::unordered_set us { 0, 1, 2 }; + +int main() +{ + VERIFY( us.size() == 3 ); + VERIFY( us.find(0) != us.end() ); +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/format.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/format.cc index eb24b66d82e7..cecc535f15f1 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/bool/format.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/format.cc @@ -21,7 +21,7 @@ is_format_string_for(const char* str, Args&&... args) } #define WIDEN_(C, S) ::std::__format::_Widen(S, L##S) -#define WIDEN(S) WIDEN_(_CharT, S) +#define WIDEN(S) WIDEN_(CharT, S) void test_format_string() @@ -34,11 +34,11 @@ test_format_string() VERIFY( !is_format_string_for("{:{}}", v[0], 1.0f) ); } -template +template void test_output() { - std::basic_string<_CharT> res; + std::basic_string res; size_t size = 0; std::vector v{true, false}; diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc index 61b99d34a1ca..e6689f7ea265 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc @@ -43,11 +43,8 @@ test02() std::vector v; } -// { dg-error "value type is destructible" "" { target *-*-* } 0 } +// { dg-error "deleted function .*DeletedDtor" "" { target *-*-* } 0 } +// { dg-error "PrivateDtor.* is private" "" { target *-*-* } 0 } // In Debug Mode the "required from here" errors come from // { dg-error "required from here" "" { target *-*-* } 182 } - -// Needed because of PR c++/92193 -// { dg-prune-output "deleted function" } -// { dg-prune-output "private within this context" } diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_neg.cc index 0807d158304c..2bd15bc68eec 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_neg.cc @@ -42,8 +42,5 @@ test02() std::vector v; // { dg-error "here" } } -// { dg-error "value type is destructible" "" { target *-*-* } 0 } - -// Needed because of PR c++/92193 -// { dg-prune-output "deleted function" } -// { dg-prune-output "private within this context" } +// { dg-error "deleted function .*DeletedDtor" "" { target *-*-* } 0 } +// { dg-error "PrivateDtor.* is private" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/mutex_association.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/mutex_association.cc index ba2ede04447e..792ed455e2c6 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/debug/mutex_association.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/debug/mutex_association.cc @@ -25,7 +25,7 @@ class container : public __gnu_debug::_Safe_sequence { public: __gnu_cxx::__mutex& - get_mutex() + get_mutex() const { return this->_M_get_mutex(); } }; diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/debug/constexpr_neg.cc b/libstdc++-v3/testsuite/25_algorithms/copy/debug/constexpr_neg.cc index 0e80977ecc5a..384052477717 100644 --- a/libstdc++-v3/testsuite/25_algorithms/copy/debug/constexpr_neg.cc +++ b/libstdc++-v3/testsuite/25_algorithms/copy/debug/constexpr_neg.cc @@ -33,7 +33,7 @@ test1() } static_assert(test1()); // { dg-error "non-constant condition" } -// { dg-error "_Error_formatter::_M_error()" "" { target *-*-* } 0 } +// { dg-error "_Error_formatter::(_M_error|_S_at)" "" { target *-*-* } 0 } constexpr bool test2() diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_backward/debug/constexpr_neg.cc b/libstdc++-v3/testsuite/25_algorithms/copy_backward/debug/constexpr_neg.cc index 410c235adf9b..d5d84b1e290e 100644 --- a/libstdc++-v3/testsuite/25_algorithms/copy_backward/debug/constexpr_neg.cc +++ b/libstdc++-v3/testsuite/25_algorithms/copy_backward/debug/constexpr_neg.cc @@ -35,4 +35,4 @@ test() static_assert(test()); // { dg-error "non-constant condition" } -// { dg-prune-output "_Error_formatter::_M_error()" } +// { dg-prune-output "_Error_formatter::(_M_error|_S_at)" } diff --git a/libstdc++-v3/testsuite/25_algorithms/equal/debug/constexpr_neg.cc b/libstdc++-v3/testsuite/25_algorithms/equal/debug/constexpr_neg.cc index cbc75092f145..6c1531d42127 100644 --- a/libstdc++-v3/testsuite/25_algorithms/equal/debug/constexpr_neg.cc +++ b/libstdc++-v3/testsuite/25_algorithms/equal/debug/constexpr_neg.cc @@ -32,7 +32,7 @@ test01() } static_assert(test01()); // { dg-error "non-constant condition" } -// { dg-error "_Error_formatter::_M_error()" "" { target *-*-* } 0 } +// { dg-error "_Error_formatter::(_M_error|_S_at)" "" { target *-*-* } 0 } constexpr bool test02() diff --git a/libstdc++-v3/testsuite/25_algorithms/heap/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/heap/constrained.cc index 8037a2db6b80..5486c8552d03 100644 --- a/libstdc++-v3/testsuite/25_algorithms/heap/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/heap/constrained.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -97,10 +98,55 @@ test02() return ok; } +constexpr bool +test03() +{ + // PR libstdc++/100795 - ranges::heap algos should not use std::heap directly +#if __SIZEOF_INT128__ + auto v = std::views::iota(__int128(0), __int128(20)); +#else + auto v = std::views::iota(0ll, 20ll); +#endif + + int storage[20] = {2,5,4,3,1,6,7,9,10,8,11,14,12,13,15,16,18,0,19,17}; + auto w = v | std::views::transform([&](auto i) -> int& { return storage[i]; }); + using type = decltype(w); + using cat = std::iterator_traits>::iterator_category; + static_assert( std::same_as ); + static_assert( std::ranges::random_access_range ); + + for (int i = 1; i < 20; i++) + ranges::push_heap(w.begin(), w.begin() + i); + ranges::sort_heap(w); + VERIFY( ranges::equal(w, v) ); + ranges::make_heap(w); + auto it = ranges::pop_heap(w); + VERIFY( it[-1] == 19 ); + + for (int i = 1; i < 20; i++) + ranges::push_heap(w.begin(), w.begin() + i, std::ranges::greater{}); + ranges::sort_heap(w, std::ranges::greater{}); + VERIFY( ranges::equal(w, v | std::views::reverse) ); + ranges::make_heap(w, std::ranges::greater{}); + it = ranges::pop_heap(w, std::ranges::greater{}); + VERIFY( it[-1] == 0 ); + + for (int i = 1; i < 20; i++) + ranges::push_heap(w.begin(), w.begin() + i, std::ranges::greater{}, std::negate{}); + ranges::sort_heap(w, std::ranges::greater{}, std::negate{}); + VERIFY( ranges::equal(w, v) ); + ranges::make_heap(w, std::ranges::greater{}, std::negate{}); + it = ranges::pop_heap(w, std::ranges::greater{}, std::negate{}); + VERIFY( it[-1] == 19 ); + + return true; +} + int main() { test01(); test01(); static_assert(test02()); + static_assert(test03()); } diff --git a/libstdc++-v3/testsuite/25_algorithms/inplace_merge/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/inplace_merge/constrained.cc index b569c918911a..5634588417ff 100644 --- a/libstdc++-v3/testsuite/25_algorithms/inplace_merge/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/inplace_merge/constrained.cc @@ -18,6 +18,7 @@ // { dg-do run { target c++20 } } #include +#include #include #include #include @@ -60,9 +61,44 @@ test02() } +void +test03() +{ + // PR libstdc++/100795 - ranges::inplace_merge should not use + // std::inplace_merge directly +#if __SIZEOF_INT128__ + auto v = std::views::iota(__int128(0), __int128(20)); +#else + auto v = std::views::iota(0ll, 20ll); +#endif + + int storage[20] = {2,5,4,3,1,6,7,9,10,8,11,14,12,13,15,16,18,0,19,17}; + auto w = v | std::views::transform([&](auto i) -> int& { return storage[i]; }); + using type = decltype(w); + using cat = std::iterator_traits>::iterator_category; + static_assert( std::same_as ); + static_assert( std::ranges::random_access_range ); + + ranges::sort(w | std::views::take(10)); + ranges::sort(w | std::views::drop(10)); + ranges::inplace_merge(w, w.begin() + 10); + VERIFY( ranges::equal(w, v) ); + + ranges::sort(w | std::views::take(10), std::ranges::greater{}); + ranges::sort(w | std::views::drop(10), std::ranges::greater{}); + ranges::inplace_merge(w, w.begin() + 10, std::ranges::greater{}); + VERIFY( ranges::equal(w, v | std::views::reverse) ); + + ranges::sort(w | std::views::take(10), std::ranges::greater{}, std::negate{}); + ranges::sort(w | std::views::drop(10), std::ranges::greater{}, std::negate{}); + ranges::inplace_merge(w, w.begin() + 10, std::ranges::greater{}, std::negate{}); + VERIFY( ranges::equal(w, v) ); +} + int main() { test01(); test02(); + test03(); } diff --git a/libstdc++-v3/testsuite/25_algorithms/lower_bound/debug/constexpr_partitioned_neg.cc b/libstdc++-v3/testsuite/25_algorithms/lower_bound/debug/constexpr_partitioned_neg.cc index c07145c19269..b44cb4be1d90 100644 --- a/libstdc++-v3/testsuite/25_algorithms/lower_bound/debug/constexpr_partitioned_neg.cc +++ b/libstdc++-v3/testsuite/25_algorithms/lower_bound/debug/constexpr_partitioned_neg.cc @@ -43,5 +43,5 @@ test() static_assert(test()); // { dg-error "" } -// { dg-prune-output "_Error_formatter::_M_error()" } +// { dg-prune-output "_Error_formatter::(_M_error|_S_at)" } // { dg-prune-output "in 'constexpr'" } diff --git a/libstdc++-v3/testsuite/25_algorithms/lower_bound/debug/constexpr_partitioned_pred_neg.cc b/libstdc++-v3/testsuite/25_algorithms/lower_bound/debug/constexpr_partitioned_pred_neg.cc index 09ae26f9b984..7835b30a0e49 100644 --- a/libstdc++-v3/testsuite/25_algorithms/lower_bound/debug/constexpr_partitioned_pred_neg.cc +++ b/libstdc++-v3/testsuite/25_algorithms/lower_bound/debug/constexpr_partitioned_pred_neg.cc @@ -33,4 +33,4 @@ test() static_assert(test()); // { dg-error "" } -// { dg-prune-output "_Error_formatter::_M_error()" } +// { dg-prune-output "_Error_formatter::(_M_error|_S_at)" } diff --git a/libstdc++-v3/testsuite/25_algorithms/lower_bound/debug/constexpr_valid_range_neg.cc b/libstdc++-v3/testsuite/25_algorithms/lower_bound/debug/constexpr_valid_range_neg.cc index 20eb026e728c..911880b59aa4 100644 --- a/libstdc++-v3/testsuite/25_algorithms/lower_bound/debug/constexpr_valid_range_neg.cc +++ b/libstdc++-v3/testsuite/25_algorithms/lower_bound/debug/constexpr_valid_range_neg.cc @@ -46,5 +46,5 @@ test2() static_assert(test2()); // { dg-error "" } -// { dg-prune-output "_Error_formatter::_M_error()" } +// { dg-prune-output "_Error_formatter::(_M_error|_S_at)" } diff --git a/libstdc++-v3/testsuite/25_algorithms/nth_element/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/nth_element/constrained.cc index 3189b225610e..8cb1625dd4d5 100644 --- a/libstdc++-v3/testsuite/25_algorithms/nth_element/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/nth_element/constrained.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -67,9 +68,39 @@ test02() return x[3] == 4; } +constexpr bool +test03() +{ + // PR libstdc++/100795 - ranges::sort should not use std::sort directly +#if __SIZEOF_INT128__ + auto v = std::views::iota(__int128(0), __int128(20)); +#else + auto v = std::views::iota(0ll, 20ll); +#endif + + int storage[20] = {2,5,4,3,1,6,7,9,10,8,11,14,12,13,15,16,18,0,19,17}; + auto w = v | std::views::transform([&](auto i) -> int& { return storage[i]; }); + using type = decltype(w); + using cat = std::iterator_traits>::iterator_category; + static_assert( std::same_as ); + static_assert( std::ranges::random_access_range ); + + ranges::nth_element(w, w.begin() + 10); + VERIFY( w[10] == 10 ); + + ranges::nth_element(w, w.begin() + 5, std::ranges::greater{}); + VERIFY( w[5] == 19 - 5 ); + + ranges::nth_element(w, w.begin() + 15, std::ranges::greater{}, std::negate{}); + VERIFY( w[15] == 15 ); + + return true; +} + int main() { test01(); static_assert(test02()); + static_assert(test03()); } diff --git a/libstdc++-v3/testsuite/25_algorithms/remove_if/120789.cc b/libstdc++-v3/testsuite/25_algorithms/remove_if/120789.cc new file mode 100644 index 000000000000..c1f4eeb9b4dd --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/remove_if/120789.cc @@ -0,0 +1,36 @@ +// PR libstdc++/120789 - ranges::remove_if should use ranges::iter_move +// { dg-do compile { target c++20 } } + +#include + +struct A +{ + bool operator==(const A&) const; +}; + +struct B +{ + B(B&&) = delete; + B& operator=(const A&) const; + + operator A() const; + bool operator==(const B&) const; +}; + +struct I +{ + using value_type = A; + using difference_type = int; + B operator*() const; + I& operator++(); + I operator++(int); + bool operator==(const I&) const; + friend A iter_move(const I&); +}; + +void +test01() +{ + std::ranges::subrange r; + auto [begin, end] = std::ranges::remove_if(r, [](auto&&) { return true; }); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/sample/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/sample/constrained.cc index b9945b164903..0ec3e0bdddd0 100644 --- a/libstdc++-v3/testsuite/25_algorithms/sample/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/sample/constrained.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -59,9 +60,34 @@ test01() } } +void +test02() +{ + // PR libstdc++/100795 - ranges::sample should not use std::sample +#if 0 // FIXME: ranges::sample rejects integer-class difference types. +#if __SIZEOF_INT128__ + auto v = std::views::iota(__int128(0), __int128(20)); +#else + auto v = std::views::iota(0ll, 20ll); +#endif +#else + auto v = std::views::iota(0, 20); +#endif + + int storage[20] = {2,5,4,3,1,6,7,9,10,8,11,14,12,13,15,16,18,0,19,17}; + auto w = v | std::views::transform([&](auto i) -> int& { return storage[i]; }); + using type = decltype(w); + static_assert( std::ranges::random_access_range ); + + ranges::sample(v, w.begin(), 20, rng); + ranges::sort(w); + VERIFY( ranges::equal(w, v) ); +} + int main() { test01(); test01(); + test02(); } diff --git a/libstdc++-v3/testsuite/25_algorithms/shift_left/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/shift_left/constrained.cc new file mode 100644 index 000000000000..73d061439885 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/shift_left/constrained.cc @@ -0,0 +1,105 @@ +// Copyright (C) 2020-2025 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do run { target c++23 } } +// This test is based on shift_left/1.cc. + +#include +#include +#include + +using __gnu_test::test_range; +using __gnu_test::forward_iterator_wrapper; +using __gnu_test::bidirectional_iterator_wrapper; +using __gnu_test::random_access_iterator_wrapper; + +struct X +{ + int a = -1; + bool moved_from = false; + + X() = default; + + X(int a) + : a(a) + { } + + X(const X&) = delete; + X& operator=(const X&) = delete; + + X(X&& other) + { + if (this != &other) + *this = std::move(other); + } + + X& + operator=(X&& other) + { + a = other.a; + other.moved_from = true; + moved_from = false; + return *this; + } +}; + +template typename Wrapper> +void +test01() +{ + for (int n = 0; n < N+5; n++) + { + X x[N]; + for (int i = 0; i < N; i++) + x[i] = X{i}; + test_range rx(x); + auto [first,out] = std::ranges::shift_left(rx.begin(), rx.end(), n); + VERIFY( first == rx.begin() ); + if (n < N) + { + VERIFY( out.ptr == x+(N-n) ); + for (int i = 0; i < N-n; i++) + { + VERIFY( x[i].a == n+i ); + VERIFY( !x[i].moved_from ); + } + for (int i = std::max(n, N-n); i < N; i++) + VERIFY( x[i].moved_from ); + } + else + { + VERIFY( out.ptr == x ); + for (int i = 0; i < N; i++) + { + VERIFY( x[i].a == i ); + VERIFY( !x[i].moved_from ); + } + } + } +} + +int +main() +{ + test01<23, forward_iterator_wrapper>(); + test01<23, bidirectional_iterator_wrapper>(); + test01<23, random_access_iterator_wrapper>(); + + test01<24, forward_iterator_wrapper>(); + test01<24, bidirectional_iterator_wrapper>(); + test01<24, random_access_iterator_wrapper>(); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/shift_right/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/shift_right/constrained.cc new file mode 100644 index 000000000000..0d53707237e4 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/shift_right/constrained.cc @@ -0,0 +1,104 @@ +// Copyright (C) 2020-2025 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do run { target c++23 } } +// This test is based on shift_right/1.cc. + +#include +#include +#include + +using __gnu_test::test_range; +using __gnu_test::forward_iterator_wrapper; +using __gnu_test::bidirectional_iterator_wrapper; +using __gnu_test::random_access_iterator_wrapper; + +struct X +{ + int a = -1; + bool moved_from = false; + + X() = default; + + X(int a) + : a(a) + { } + + X(const X&) = delete; + X& operator=(const X&) = delete; + + X(X&& other) + { + if (this != &other) + *this = std::move(other); + } + + X& + operator=(X&& other) + { + a = other.a; + other.moved_from = true; + moved_from = false; + return *this; + } +}; + +template typename Wrapper> +void +test01() +{ + for (int n = 0; n < N+5; n++) + { + X x[N]; + for (int i = 0; i < N; i++) + x[i] = X(i); + test_range rx(x); + auto [out,last] = std::ranges::shift_right(rx.begin(), rx.end(), n); + VERIFY( last == rx.end() ); + if (n < N) + { + VERIFY( out.ptr == x+n ); + for (int i = n; i < N; i++) + VERIFY( x[i].a == i-n ); + for (int i = 0; i < std::min(n, N-n); i++) + VERIFY( x[i].moved_from ); + for (int i = std::min(n, N-n); i < std::max(n, N-n); i++) + VERIFY( !x[i].moved_from ); + } + else + { + VERIFY( out.ptr == x+N ); + for (int i = 0; i < N; i++) + { + VERIFY( x[i].a == i ); + VERIFY( !x[i].moved_from ); + } + } + } +} + +int +main() +{ + test01<23, forward_iterator_wrapper>(); + test01<23, bidirectional_iterator_wrapper>(); + test01<23, random_access_iterator_wrapper>(); + + test01<24, forward_iterator_wrapper>(); + test01<24, bidirectional_iterator_wrapper>(); + test01<24, random_access_iterator_wrapper>(); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/shuffle/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/shuffle/constrained.cc index d0977a292fee..70c6bdfc3d9e 100644 --- a/libstdc++-v3/testsuite/25_algorithms/shuffle/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/shuffle/constrained.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -62,8 +63,32 @@ test01() } } +void +test02() +{ + // PR libstdc++/100795 - ranges::shuffle should not use std::shuffle directly +#if 0 // FIXME: ranges::shuffle rejects integer-class difference types. +#if __SIZEOF_INT128__ + auto v = std::views::iota(__int128(0), __int128(20)); +#else + auto v = std::views::iota(0ll, 20ll); +#endif +#else + auto v = std::views::iota(0, 20); +#endif + + int storage[20] = {2,5,4,3,1,6,7,9,10,8,11,14,12,13,15,16,18,0,19,17}; + auto w = v | std::views::transform([&](auto i) -> int& { return storage[i]; }); + using type = decltype(w); + static_assert( std::ranges::random_access_range ); + + std::ranlux48_base g; + ranges::shuffle(w, g); +} + int main() { test01(); + test02(); } diff --git a/libstdc++-v3/testsuite/25_algorithms/sort/118209.cc b/libstdc++-v3/testsuite/25_algorithms/sort/118209.cc new file mode 100644 index 000000000000..6dedbde75173 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/sort/118209.cc @@ -0,0 +1,23 @@ +// PR libstdc++ - ranges::sort doesn't use iter_move, cannot sort zip of move-only type +// { dg-do compile { target c++23 } } + +#include +#include +#include + +struct F { + int a = -1; + explicit F(int d) : a(d) { } + F(const F&) = delete; + F(F&& o) : a(o.a) { } + void operator=(const F&) = delete; + F& operator=(F&& o) { return *this; } + auto operator<=>(const F&) const = default; +}; + +int main () { + int a[] = {3,2,1}; + std::vector v(a, a+3); + std::ranges::sort(v); // OK + std::ranges::sort(std::views::zip(v)); // didn't compile +} diff --git a/libstdc++-v3/testsuite/25_algorithms/sort/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/sort/constrained.cc index 82754af96430..930dbd77a376 100644 --- a/libstdc++-v3/testsuite/25_algorithms/sort/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/sort/constrained.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -72,9 +73,39 @@ test02() && ranges::equal(x, y, {}, &X::i, &X::i)); } +constexpr bool +test03() +{ + // PR libstdc++/100795 - ranges::sort should not use std::sort directly +#if __SIZEOF_INT128__ + auto v = std::views::iota(__int128(0), __int128(20)); +#else + auto v = std::views::iota(0ll, 20ll); +#endif + + int storage[20] = {2,5,4,3,1,6,7,9,10,8,11,14,12,13,15,16,18,0,19,17}; + auto w = v | std::views::transform([&](auto i) -> int& { return storage[i]; }); + using type = decltype(w); + using cat = std::iterator_traits>::iterator_category; + static_assert( std::same_as ); + static_assert( std::ranges::random_access_range ); + + ranges::sort(w); + VERIFY( ranges::equal(w, v) ); + + ranges::sort(w, std::ranges::greater{}); + VERIFY( ranges::equal(w, v | std::views::reverse) ); + + ranges::sort(w, std::ranges::greater{}, std::negate{}); + VERIFY( ranges::equal(w, v) ); + + return true; +} + int main() { test01(); static_assert(test02()); + static_assert(test03()); } diff --git a/libstdc++-v3/testsuite/25_algorithms/stable_partition/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/stable_partition/constrained.cc index fc11c6439f9c..4dc267873ae2 100644 --- a/libstdc++-v3/testsuite/25_algorithms/stable_partition/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/stable_partition/constrained.cc @@ -21,6 +21,7 @@ // { dg-require-effective-target hosted } #include +#include #include #include @@ -70,9 +71,34 @@ test02() } } +void +test03() +{ + // PR libstdc++/100795 - ranges::stable_partition should not use + // std::stable_partition directly +#if __SIZEOF_INT128__ + auto v = std::views::iota(__int128(0), __int128(20)); +#else + auto v = std::views::iota(0ll, 20ll); +#endif + + int storage[20] = {2,5,4,3,1,6,7,9,10,8,11,14,12,13,15,16,18,0,19,17}; + auto w = v | std::views::transform([&](auto i) -> int& { return storage[i]; }); + using type = decltype(w); + using cat = std::iterator_traits>::iterator_category; + static_assert( std::same_as ); + static_assert( std::ranges::random_access_range ); + + auto pred = [] (int a) { return a%2==0; }; + ranges::stable_partition(w, pred); + VERIFY( ranges::all_of(w.begin(), w.begin() + 10, pred) ); + VERIFY( ranges::none_of(w.begin() + 10, w.end(), pred) ); +} + int main() { test01(); test02(); + test03(); } diff --git a/libstdc++-v3/testsuite/25_algorithms/stable_sort/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/stable_sort/constrained.cc index 0bd438fa5f29..55043442f4be 100644 --- a/libstdc++-v3/testsuite/25_algorithms/stable_sort/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/stable_sort/constrained.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -62,8 +63,37 @@ test01() } } +void +test02() +{ + // PR libstdc++/100795 - ranges::stable_sort should not use std::stable_sort + // directly +#if __SIZEOF_INT128__ + auto v = std::views::iota(__int128(0), __int128(20)); +#else + auto v = std::views::iota(0ll, 20ll); +#endif + + int storage[20] = {2,5,4,3,1,6,7,9,10,8,11,14,12,13,15,16,18,0,19,17}; + auto w = v | std::views::transform([&](auto i) -> int& { return storage[i]; }); + using type = decltype(w); + using cat = std::iterator_traits>::iterator_category; + static_assert( std::same_as ); + static_assert( std::ranges::random_access_range ); + + ranges::stable_sort(w); + VERIFY( ranges::equal(w, v) ); + + ranges::stable_sort(w, std::ranges::greater{}); + VERIFY( ranges::equal(w, v | std::views::reverse) ); + + ranges::stable_sort(w, std::ranges::greater{}, std::negate{}); + VERIFY( ranges::equal(w, v) ); +} + int main() { test01(); + test02(); } diff --git a/libstdc++-v3/testsuite/25_algorithms/unique/120789.cc b/libstdc++-v3/testsuite/25_algorithms/unique/120789.cc new file mode 100644 index 000000000000..24b107132473 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/unique/120789.cc @@ -0,0 +1,36 @@ +// PR libstdc++/120789 - ranges::unique should use ranges::iter_move +// { dg-do compile { target c++20 } } + +#include + +struct A +{ + bool operator==(const A&) const; +}; + +struct B +{ + B(B&&) = delete; + B& operator=(const A&) const; + + operator A() const; + bool operator==(const B&) const; +}; + +struct I +{ + using value_type = A; + using difference_type = int; + B operator*() const; + I& operator++(); + I operator++(int); + bool operator==(const I&) const; + friend A iter_move(const I&); +}; + +void +test01() +{ + std::ranges::subrange r; + auto [begin, end] = std::ranges::unique(r); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/upper_bound/debug/constexpr_partitioned_neg.cc b/libstdc++-v3/testsuite/25_algorithms/upper_bound/debug/constexpr_partitioned_neg.cc index ffe5d777ac62..950d4325ff7c 100644 --- a/libstdc++-v3/testsuite/25_algorithms/upper_bound/debug/constexpr_partitioned_neg.cc +++ b/libstdc++-v3/testsuite/25_algorithms/upper_bound/debug/constexpr_partitioned_neg.cc @@ -43,4 +43,4 @@ test() static_assert(test()); // { dg-error "" } -// { dg-prune-output "_Error_formatter::_M_error()" } +// { dg-prune-output "_Error_formatter::(_M_error|_S_at)" } diff --git a/libstdc++-v3/testsuite/25_algorithms/upper_bound/debug/constexpr_partitioned_pred_neg.cc b/libstdc++-v3/testsuite/25_algorithms/upper_bound/debug/constexpr_partitioned_pred_neg.cc index a1c2ce694bc1..41eb00cf4391 100644 --- a/libstdc++-v3/testsuite/25_algorithms/upper_bound/debug/constexpr_partitioned_pred_neg.cc +++ b/libstdc++-v3/testsuite/25_algorithms/upper_bound/debug/constexpr_partitioned_pred_neg.cc @@ -33,4 +33,4 @@ test() static_assert(test()); // { dg-error "" } -// { dg-prune-output "_Error_formatter::_M_error()" } +// { dg-prune-output "_Error_formatter::(_M_error|_S_at)" } diff --git a/libstdc++-v3/testsuite/25_algorithms/upper_bound/debug/constexpr_valid_range_neg.cc b/libstdc++-v3/testsuite/25_algorithms/upper_bound/debug/constexpr_valid_range_neg.cc index c7c9e3b82a52..032c8d305096 100644 --- a/libstdc++-v3/testsuite/25_algorithms/upper_bound/debug/constexpr_valid_range_neg.cc +++ b/libstdc++-v3/testsuite/25_algorithms/upper_bound/debug/constexpr_valid_range_neg.cc @@ -46,4 +46,4 @@ test2() static_assert(test2()); // { dg-error "" } -// { dg-prune-output "_Error_formatter::_M_error()" } +// { dg-prune-output "_Error_formatter::(_M_error|_S_at)" } diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc new file mode 100644 index 000000000000..f25b538b2fa8 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc @@ -0,0 +1,201 @@ +// C++26 [istringstream.general] + +// { dg-do run { target c++26 } } + +#include +#include +#include +#include +#include + +// Check C++26 P2495 istringstream ctors and members str(s) that accept a +// string_view, or anything convertible to a string_view, in place of a +// string object. Mostly just verify plumbing. + +#ifndef C +# define C char +# define L(a) a +#endif + +using string = std::basic_string; +using string_view = std::basic_string_view; +using istringstream = std::basic_istringstream; + +struct convertible_to_string_view { + string s; + operator string_view() const { return s; } +}; + +const string str(L("This is a test string")); +convertible_to_string_view cstr{str}; // a copy +const convertible_to_string_view ccstr{str}; // another copy + +template > +void +test01() +{ + // Test C++26 constructor and str(s) taking a generalized string_view + + static_assert(! requires { istringstream(1); }, + "istringstream ctor should reject what cannot be converted to a string_view"); + static_assert(! requires { istringstream().str(1); }, + "istringstream::str(s) should reject what cannot be converted to a string_view"); + + static_assert(!std::is_convertible_v, + "istringstream(string_view, ios::openmode) is explicit"); + static_assert(!std::is_convertible_v, + "istringstream(string_view, ios::openmode) is explicit"); + static_assert(!std::is_convertible_v, + "istringstream(convertible_to_string_view, ios::openmode) is explicit"); + static_assert(!std::is_convertible_v, + "istringstream(convertible_to_string_view, ios::openmode) is explicit"); + + { + istringstream istr(cstr); + VERIFY( istr.str() == cstr.s ); + VERIFY( istr.get() == cstr.s[0] ); + } + { + istringstream istr(ccstr); + VERIFY( istr.str() == ccstr.s ); + VERIFY( istr.get() == ccstr.s[0] ); + } + { + istringstream istr(cstr, std::ios_base::in); + VERIFY( istr.str() == cstr.s ); + VERIFY( istr.get() == cstr.s[0] ); + VERIFY( istr.rdbuf()->sputc('X') != 'X' ); + } + { + istringstream istr(cstr, std::ios_base::out); + VERIFY( istr.str() == cstr.s ); + VERIFY( istr.get() == cstr.s[0] ); + VERIFY( istr.rdbuf()->sputc('X') == 'X' ); + } +} + +void +test02() +{ + // Test various C++26 constructors taking string views + // and mix of other arguments + + auto const mode = std::ios_base::in | std::ios_base::out; + + { + // template + // basic_istringstream(const T&, ios_base::openmode, const allocator_type&) + + istringstream::allocator_type a; + { + istringstream istr(cstr, mode, a); // ={} checks for non-explicit ctor + VERIFY( istr.str() == cstr.s ); + } + { + istringstream istr(cstr, std::ios::in, a); + VERIFY( istr.str() == cstr.s ); + VERIFY( istr.get() == cstr.s[0] ); + VERIFY( istr.rdbuf()->sputc('X') != 'X' ); + } + { + istringstream istr(cstr, std::ios::out, a); + VERIFY( istr.str() == cstr.s ); + VERIFY( istr.get() == cstr.s[0] ); + VERIFY( istr.rdbuf()->sputc('X') == 'X' ); + } + } + + { + // template + // basic_istringstream(const T&, ios_base::openmode) + { + istringstream istr(cstr, mode); + VERIFY( istr.str() == cstr.s ); + VERIFY( istr.get() == cstr.s[0] ); + VERIFY( istr.rdbuf()->sputc('X') == 'X' ); + } + { + istringstream istr(cstr, std::ios::in); + VERIFY( istr.str() == cstr.s ); + VERIFY( istr.get() == cstr.s[0] ); + VERIFY( istr.rdbuf()->sputc('X') != 'X' ); + } + { + istringstream istr(cstr, std::ios::out); + VERIFY( istr.str() == cstr.s ); + VERIFY( istr.get() == cstr.s[0] ); + VERIFY( istr.rdbuf()->sputc('X') == 'X' ); + } + } + + { + // template + // explicit + // basic_istringstream(const T&, ios_base::openmode = ios_base::in) + + istringstream istr(cstr); + VERIFY( istr.str() == cstr.s ); + VERIFY( istr.get() == cstr.s[0] ); + VERIFY( istr.rdbuf()->sputc('X') != 'X' ); + } +} + +using alloc_type = __gnu_test::uneq_allocator; + +template + using istringstream_with_alloc + = std::basic_istringstream, Alloc>; + +void test03() +{ + alloc_type a{1}; + { + istringstream_with_alloc istr(cstr, a); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( istr.rdbuf()->get_allocator() == a ); +#endif + VERIFY( string_view{istr.str()} == cstr ); + VERIFY( istr.get() == cstr.s[0] ); + } + { + istringstream_with_alloc istr(cstr, std::ios::in, a); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( istr.rdbuf()->get_allocator() == a ); +#endif + VERIFY( string_view{istr.str()} == cstr ); + VERIFY( istr.get() == cstr.s[0] ); + VERIFY( istr.rdbuf()->sputc('X') != 'X' ); + } + { + istringstream_with_alloc istr(cstr, std::ios::out, a); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( istr.rdbuf()->get_allocator() == a ); +#endif + VERIFY( string_view{istr.str()} == cstr ); + VERIFY( istr.get() == cstr.s[0] ); + VERIFY( istr.rdbuf()->sputc('X') == 'X' ); + } +} + +void test04() +{ + { + istringstream istr; + istr.str( cstr ); + VERIFY( istr.str() == cstr.s ); + } + { + istringstream istr; + istr.str( ccstr ); + VERIFY( istr.str() == ccstr.s ); + } +} + +int +main() +{ + test01(); + test02(); + test03(); + test04(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc new file mode 100644 index 000000000000..62fb03c898c6 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc @@ -0,0 +1,6 @@ +// C++26 [istringstream.general] +// { dg-do run { target c++26 } } + +#define C wchar_t +#define L(a) L##a +#include "../char/string_view.cc" diff --git a/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc new file mode 100644 index 000000000000..6279c19e54c5 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc @@ -0,0 +1,200 @@ +// C++26 [ostringstream.general] + +// { dg-do run { target c++26 } } + +#include +#include +#include +#include +#include + +// Check C++26 P2495 ostringstream ctors and members str(s) that accept a +// string_view, or anything convertible to a string_view, in place of a +// string object. Mostly just verify plumbing. + +#ifndef C +# define C char +# define L(a) a +#endif + +using string = std::basic_string; +using string_view = std::basic_string_view; +using ostringstream = std::basic_ostringstream; + +struct convertible_to_string_view { + string s; + operator string_view() const { return s; } +}; + +const string str(L("This is a test string")); +convertible_to_string_view cstr{str}; // a copy +const convertible_to_string_view ccstr{str}; // another copy + +template > +void +test01() +{ + // Test C++26 constructor and str(s) taking a generalized string_view + + static_assert(! requires { ostringstream(1); }, + "ostringstream ctor should reject what cannot be converted to a string_view"); + static_assert(! requires { ostringstream().str(1); }, + "ostringstream::str(s) should reject what cannot be converted to a string_view"); + + static_assert(!std::is_convertible_v, + "ostringstream(string_view, ios::openmode) is explicit"); + static_assert(!std::is_convertible_v, + "ostringstream(string_view, ios::openmode) is explicit"); + static_assert(!std::is_convertible_v, + "ostringstream(convertible_to_string_view, ios::openmode) is explicit"); + static_assert(!std::is_convertible_v, + "ostringstream(convertible_to_string_view, ios::openmode) is explicit"); + + { + ostringstream ostrstr(cstr); + VERIFY( ostrstr.str() == cstr.s ); + VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() ); + } + { + ostringstream ostrstr(ccstr); + VERIFY( ostrstr.str() == ccstr.s ); + VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() ); + } + { + ostringstream ostrstr(cstr, std::ios_base::in); + VERIFY( ostrstr.str() == cstr.s ); + VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]); + VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit ); + } + { + ostringstream ostrstr(cstr, std::ios_base::out); + VERIFY( ostrstr.str() == cstr.s ); + VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() ); + VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit ); + } +} + +void +test02() +{ + // Test plumbing of C++26 various constructors taking string views + + auto const mode = std::ios_base::in | std::ios_base::out; + + { + ostringstream::allocator_type a; + // template + // basic_ostringstream(const T&, ios_base::openmode, const allocator_type&) + { + ostringstream ostrstr(cstr, mode, a); // ={} checks for non-explicit ctor + VERIFY( ostrstr.str() == cstr.s ); + } + { + ostringstream ostrstr(cstr, std::ios::in, a); + VERIFY( ostrstr.str() == cstr.s ); + VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]); + VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit ); + } + { + ostringstream ostrstr(cstr, std::ios::out, a); + VERIFY( ostrstr.str() == cstr.s ); + VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() ); + VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit ); + } + } + + { + // template + // basic_ostringstream(const T&, ios_base::openmode) + { + ostringstream ostrstr(cstr, mode); + VERIFY( ostrstr.str() == cstr.s ); + VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]); + VERIFY( ostrstr.put('Y').good() ); + } + { + ostringstream ostrstr(cstr, std::ios::in); + VERIFY( ostrstr.str() == cstr.s ); + VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]); + VERIFY( ostrstr.put('X').good() ); + } + { + ostringstream ostrstr(cstr, std::ios::out); + VERIFY( ostrstr.str() == cstr.s ); + VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() ); + VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit ); + } + } + + { + // template + // explicit + // basic_ostringstream(const T&, ios_base::openmode = ios_base::out) + + ostringstream ostrstr(cstr); + VERIFY( ostrstr.str() == cstr.s ); + VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() ); + VERIFY( ostrstr.put('Y').good() ); + } +} + +using alloc_type = __gnu_test::uneq_allocator; + +template + using ostringstream_with_alloc + = std::basic_ostringstream, Alloc>; + +void test03() +{ + alloc_type a{1}; + { + ostringstream_with_alloc ostrstr(cstr, a); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( ostrstr.rdbuf()->get_allocator() == a ); +#endif + VERIFY( string_view{ostrstr.str()} == cstr ); + VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() ); + VERIFY( ostrstr.put('X').good() ); + } + { + ostringstream_with_alloc ostrstr(cstr, std::ios::in, a); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( ostrstr.rdbuf()->get_allocator() == a ); +#endif + VERIFY( string_view{ostrstr.str()} == cstr ); + VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]); + VERIFY( ostrstr.put('X').good() ); + } + { + ostringstream_with_alloc ostrstr(cstr, std::ios::out, a); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( ostrstr.rdbuf()->get_allocator() == a ); +#endif + VERIFY( string_view{ostrstr.str()} == cstr ); + VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() ); + VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit ); + } +} + +void test04() +{ + { + ostringstream ostrstr; + ostrstr.str(cstr); + VERIFY( ostrstr.str() == cstr.s ); + } + { + ostringstream ostrstr; + ostrstr.str(ccstr); + VERIFY( ostrstr.str() == ccstr.s ); + } +} + +int +main() +{ + test01(); + test02(); + test03(); + test04(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc new file mode 100644 index 000000000000..ee6ac8dd4090 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc @@ -0,0 +1,6 @@ +// C++26 [ostringstream.general] +// { dg-do run { target c++26 } } + +#define C wchar_t +#define L(a) L##a +#include "../char/string_view.cc" diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc new file mode 100644 index 000000000000..14278b3faf83 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc @@ -0,0 +1,211 @@ +// C++26 31.8.2.1 [stringbuf.general] + +// { dg-do run { target c++26 } } + +#include +#include +#include +#include +#include + +// Check C++26 P2495 stringbuf ctors and members str(s) that accept a +// string_view, or anything convertible to a string_view, in place of a +// string object. + +#ifndef C +# define C char +# define L(a) a +#endif + +using string = std::basic_string; +using string_view = std::basic_string_view; +using stringbuf = std::basic_stringbuf; + +struct convertible_to_string_view { + string s; + operator string_view() const { return s; } +}; + +const string str(L("This is a test string")); +convertible_to_string_view cstr{str}; // a copy +const convertible_to_string_view ccstr{str}; // another copy + +template > +void +test01() +{ + // Test C++26 constructor and str(s) taking a generalized string_view + + static_assert(! requires { stringbuf(1); }, + "stringbuf ctor should reject what cannot be converted to a string_view"); + static_assert(! requires { stringbuf().str(1); }, + "stringbuf::str(s) should reject what cannot be converted to a string_view"); + + static_assert(!std::is_convertible_v, + "stringbuf(string_view, ios::openmode) is explicit"); + static_assert(!std::is_convertible_v, + "stringbuf(string_view, ios::openmode) is explicit"); + static_assert(!std::is_convertible_v, + "stringbuf(convertible_to_string_view, ios::openmode) is explicit"); + static_assert( + !std::is_convertible_v, + "stringbuf(convertible_to_string_view, ios::openmode) is explicit"); + + { + stringbuf sbuf(cstr); + VERIFY( sbuf.str() == cstr.s ); + VERIFY( sbuf.sgetc() == cstr.s[0] ); + } + { + stringbuf sbuf(ccstr); + VERIFY( sbuf.str() == ccstr.s ); + VERIFY( sbuf.sgetc() == ccstr.s[0] ); + } + { + stringbuf sbuf(cstr, std::ios_base::in); + VERIFY( sbuf.str() == cstr.s ); + VERIFY( sbuf.sgetc() == cstr.s[0] ); + VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() ); + } + { + stringbuf sbuf(ccstr, std::ios_base::in); + VERIFY( sbuf.str() == ccstr.s ); + VERIFY( sbuf.sgetc() == ccstr.s[0] ); + VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() ); + } + { + stringbuf sbuf(cstr, std::ios_base::out); + VERIFY( sbuf.str() == cstr.s ); + VERIFY( sbuf.sputc('Y') == 'Y' ); + VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() ); + } + { + stringbuf sbuf(ccstr, std::ios_base::out); + VERIFY( sbuf.str() == ccstr.s ); + VERIFY( sbuf.sputc('Y') == 'Y' ); + VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() ); + } +} + +void +test02() +{ + // Test C++26 constructors taking string views using different allocators + + auto const mode = std::ios_base::in | std::ios_base::out; + + { + // template + // basic_stringbuf(const T&, ios_base::openmode, const allocator_type&) + + stringbuf::allocator_type a; + { + stringbuf sbuf(cstr, mode, a); // ={} checks for non-explicit ctor + VERIFY( sbuf.str() == cstr.s ); + } + { + stringbuf sbuf(cstr, std::ios::in, a); + VERIFY( sbuf.str() == cstr.s ); + VERIFY( sbuf.sgetc() == cstr.s[0] ); + VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() ); + } + + { + stringbuf sbuf(cstr, std::ios::out, a); + VERIFY( sbuf.str() == cstr.s ); + VERIFY( sbuf.sputc('X') == 'X' ); + VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() ); + } + } + + { + // template + // basic_stringbuf(const T&, ios_base::openmode) + { + stringbuf sbuf(cstr, mode); + VERIFY( sbuf.str() == cstr.s ); + } + { + stringbuf sbuf(cstr, std::ios::in); + VERIFY( sbuf.str() == cstr.s ); + VERIFY( sbuf.sgetc() == cstr.s[0] ); + VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() ); + } + { + stringbuf sbuf(cstr, std::ios::out); + VERIFY( sbuf.str() == cstr.s ); + VERIFY( sbuf.sputc('X') == 'X' ); + VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() ); + } + } + + { + // template + // explicit + // basic_stringbuf(const T&, ios_base::openmode = ios_base::in|ios_base::out) + + stringbuf sbuf(cstr); + VERIFY( sbuf.str() == cstr.s ); + VERIFY( sbuf.sgetc() == cstr.s[0] ); + } +} + +using alloc_type = __gnu_test::uneq_allocator; + +template + using stringbuf_with_alloc + = std::basic_stringbuf, Alloc>; + +void test03() +{ + alloc_type a{1}; + { + stringbuf_with_alloc sbuf(cstr, a); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( sbuf.get_allocator() == a ); +#endif + VERIFY( string_view{sbuf.str()} == cstr ); + VERIFY( sbuf.sgetc() == cstr.s[0] ); + } + { + stringbuf_with_alloc sbuf(cstr, std::ios::in, a); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( sbuf.get_allocator() == a ); +#endif + VERIFY( string_view{sbuf.str()} == cstr ); + VERIFY( sbuf.sgetc() == cstr.s[0] ); + VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() ); + } + { + stringbuf_with_alloc sbuf(cstr, std::ios::out, a); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( sbuf.get_allocator() == a ); +#endif + VERIFY( string_view{sbuf.str()} == cstr ); + VERIFY( sbuf.sputc('X') == 'X' ); + VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() ); + } +} + +void test04() +{ + { + stringbuf sbuf; + sbuf.str(cstr); + VERIFY( sbuf.str() == cstr.s ); + } + { + stringbuf sbuf; + sbuf.str(ccstr); + VERIFY( sbuf.str() == ccstr.s ); + } +} + +int +main() +{ + test01(); + test02(); + test03(); + test04(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc new file mode 100644 index 000000000000..c428491e8925 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc @@ -0,0 +1,6 @@ +// C++26 [stringbuf.general] +// { dg-do run { target c++26 } } + +#define C wchar_t +#define L(a) L##a +#include "../char/string_view.cc" diff --git a/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/char/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/char/string_view.cc new file mode 100644 index 000000000000..1c9eceaa55cf --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/char/string_view.cc @@ -0,0 +1,210 @@ +// C++26 31.8.2.1 [stringstream.general] + +// { dg-do run { target c++26 } } + +#include +#include +#include +#include +#include + +// Check C++26 P2495 stringstream ctors and members str(s) that accept a +// string_view, or anything convertible to a string_view, in place of a +// string object. Mostly just verify plumbing. + +#ifndef C +# define C char +# define L(a) a +#endif + +using string = std::basic_string; +using string_view = std::basic_string_view; +using stringstream = std::basic_stringstream; + +struct convertible_to_string_view { + string s; + operator string_view() const { return s; } +}; + +const string str(L("This is a test string")); +convertible_to_string_view cstr{str}; // a copy +const convertible_to_string_view ccstr{str}; // another copy + +template > +void +test01() +{ + // Test C++26 constructor and str(s) taking a generalized string_view + + static_assert(! requires { stringstream(1); }, + "stringstream ctor should reject what cannot be converted to a string_view"); + static_assert(! requires { stringstream().str(1); }, + "stringstream::str(s) should reject what cannot be converted to a string_view"); + + static_assert(!std::is_convertible_v, + "stringstream(string_view, ios::openmode) is explicit"); + static_assert(!std::is_convertible_v, + "stringstream(string_view, ios::openmode) is explicit"); + static_assert(!std::is_convertible_v, + "stringstream(convertible_to_string_view, ios::openmode) is explicit"); + static_assert(!std::is_convertible_v, + "stringstream(convertible_to_string_view, ios::openmode) is explicit"); + + { + stringstream strstr(cstr); + VERIFY( strstr.str() == cstr.s ); + VERIFY( strstr.get() == cstr.s[0] ); + } + { + stringstream strstr(ccstr); + VERIFY( strstr.str() == ccstr.s ); + VERIFY( strstr.get() == ccstr.s[0] ); + } + { + stringstream strstr(cstr, std::ios_base::in); + VERIFY( strstr.str() == cstr.s ); + VERIFY( strstr.get() == cstr.s[0] ); + VERIFY( strstr.put('X').rdstate() == strstr.badbit ); + } + { + stringstream strstr(cstr, std::ios_base::out); + VERIFY( strstr.str() == cstr.s ); + VERIFY( strstr.put('Y').good() ); + VERIFY( strstr.get() == stringstream::traits_type::eof()); + } +} + +void +test02() +{ + // Test C++26 various constructors taking string views + + auto const mode = std::ios_base::in | std::ios_base::out; + + { + // template + // basic_stringstream(const T&, ios_base::openmode, const allocator_type&) + + stringstream::allocator_type a; + { + stringstream strstr(cstr, mode, a); // ={} checks for non-explicit ctor + VERIFY( strstr.str() == cstr.s ); + } + { + stringstream strstr(cstr, std::ios::in, a); + VERIFY( strstr.str() == cstr.s ); + VERIFY( strstr.get() == cstr.s[0] ); + VERIFY( strstr.put('X').rdstate() == strstr.badbit ); + } + { + stringstream strstr(cstr, std::ios::out, a); + VERIFY( strstr.str() == cstr.s ); + VERIFY( strstr.put('X').good() ); + VERIFY( strstr.get() == stringstream::traits_type::eof()); + } + } + + { + // template + // basic_stringstream(const T&, ios_base::openmode) + + { + stringstream strstr(cstr, mode); + VERIFY( strstr.str() == cstr.s ); + VERIFY( strstr.get() == cstr.s[0] ); + VERIFY( strstr.put('X').good() ); + } + { + stringstream strstr(cstr, std::ios::in); + VERIFY( strstr.str() == cstr.s ); + VERIFY( strstr.get() == cstr.s[0] ); + VERIFY( strstr.put('X').rdstate() == strstr.badbit ); + } + { + stringstream strstr(cstr, std::ios::out); + VERIFY( strstr.str() == cstr.s ); + VERIFY( strstr.put('X').good() ); + VERIFY( strstr.get() == stringstream::traits_type::eof()); + } + } + + { + // template + // explicit + // basic_stringstream(const T&, ios_base::openmode = ios_base::in|ios_base::out) + + stringstream strstr(cstr); + VERIFY( strstr.str() == cstr.s ); + VERIFY( strstr.get() == cstr.s[0] ); + VERIFY( strstr.put('X').good() ); + } +} + +// A minimal allocator with no default constructor +template + struct NoDefaultCons : __gnu_test::SimpleAllocator + { + using __gnu_test::SimpleAllocator::SimpleAllocator; + NoDefaultCons() = delete; + NoDefaultCons(int) { } + }; + +using alloc_type = __gnu_test::uneq_allocator; + +template + using stringstream_with_alloc + = std::basic_stringstream, Alloc>; + +void test03() +{ + alloc_type a{1}; + { + stringstream_with_alloc strstr(cstr, a); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( strstr.rdbuf()->get_allocator() == a ); +#endif + VERIFY( string_view{strstr.str()} == cstr ); + VERIFY( strstr.get() == cstr.s[0] ); + } + { + stringstream_with_alloc strstr(cstr, std::ios::in, a); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( strstr.rdbuf()->get_allocator() == a ); +#endif + VERIFY( string_view{strstr.str()} == cstr ); + VERIFY( strstr.get() == cstr.s[0] ); + VERIFY( strstr.put('X').rdstate() == strstr.badbit ); + } + { + stringstream_with_alloc strstr(cstr, std::ios::out, a); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( strstr.rdbuf()->get_allocator() == a ); +#endif + VERIFY( string_view{strstr.str()} == cstr ); + VERIFY( strstr.put('X').good() ); + VERIFY( strstr.get() == stringstream::traits_type::eof()); + } +} + +void test04() +{ + { + stringstream strstr; + strstr.str( cstr ); + VERIFY( strstr.str() == cstr.s ); + } + { + stringstream strstr; + strstr.str( ccstr ); + VERIFY( strstr.str() == ccstr.s ); + } +} + +int +main() +{ + test01(); + test02(); + test03(); + test04(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc new file mode 100644 index 000000000000..921c0feabdea --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc @@ -0,0 +1,6 @@ +// C++26 [stringstream.general] +// { dg-do run { target c++26 } } + +#define C wchar_t +#define L(a) L##a +#include "../char/string_view.cc" diff --git a/libstdc++-v3/testsuite/30_threads/barrier/1.cc b/libstdc++-v3/testsuite/30_threads/barrier/1.cc index eff8ef3a174b..01c55d96cd20 100644 --- a/libstdc++-v3/testsuite/30_threads/barrier/1.cc +++ b/libstdc++-v3/testsuite/30_threads/barrier/1.cc @@ -16,7 +16,8 @@ // . // { dg-do compile { target c++20 } } -// { dg-require-effective-target gthreads } +// { dg-require-effective-target gthreads { target { ! *-*-linux* } } } +// { dg-require-effective-target hosted } // { dg-add-options no_pch } #include diff --git a/libstdc++-v3/testsuite/30_threads/barrier/2.cc b/libstdc++-v3/testsuite/30_threads/barrier/2.cc index e0188b3fd8ea..728030babbd1 100644 --- a/libstdc++-v3/testsuite/30_threads/barrier/2.cc +++ b/libstdc++-v3/testsuite/30_threads/barrier/2.cc @@ -16,7 +16,7 @@ // . // { dg-do compile { target c++20 } } -// { dg-require-effective-target gthreads } +// { dg-require-effective-target gthreads { target { ! *-*-linux* } } } // { dg-require-effective-target hosted } // { dg-add-options no_pch } diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/1.cc b/libstdc++-v3/testsuite/30_threads/semaphore/1.cc index ac9f97b816fe..9472def4cba1 100644 --- a/libstdc++-v3/testsuite/30_threads/semaphore/1.cc +++ b/libstdc++-v3/testsuite/30_threads/semaphore/1.cc @@ -16,6 +16,8 @@ // . // { dg-do compile { target c++20 } } +// { dg-require-effective-target gthreads { target { ! *-*-linux* } } } +// { dg-require-effective-target hosted } // { dg-add-options no_pch } #include @@ -25,3 +27,25 @@ #elif __cpp_lib_semaphore != 201907L # error "Feature-test macro for semaphore has wrong value in " #endif + +static_assert(std::is_same_v, + std::binary_semaphore>); + +static_assert(! std::is_same_v, + std::binary_semaphore>); + +static_assert(! std::is_same_v, + std::binary_semaphore>); + +// The standard permits max() to be greater than the template argument, +// but for the current libstdc++ implementation it's always equal to it. +static_assert(std::binary_semaphore::max() == 1); +static_assert(std::counting_semaphore<0>::max() == 0); +static_assert(std::counting_semaphore<2>::max() == 2); + +#include + +static_assert(std::counting_semaphore::max() == INT_MAX); +static_assert(std::counting_semaphore::max() == INT_MAX-1); +static_assert(std::counting_semaphore::max() == PTRDIFF_MAX); +static_assert(std::counting_semaphore::max() == PTRDIFF_MAX-3); diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/2.cc b/libstdc++-v3/testsuite/30_threads/semaphore/2.cc index 251e96adae68..bff747c0aa33 100644 --- a/libstdc++-v3/testsuite/30_threads/semaphore/2.cc +++ b/libstdc++-v3/testsuite/30_threads/semaphore/2.cc @@ -16,6 +16,7 @@ // . // { dg-do compile { target c++20 } } +// { dg-require-effective-target gthreads { target { ! *-*-linux* } } } // { dg-require-effective-target hosted } // { dg-add-options no_pch } diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/3.cc b/libstdc++-v3/testsuite/30_threads/semaphore/3.cc new file mode 100644 index 000000000000..51b9fbb0e4bd --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/semaphore/3.cc @@ -0,0 +1,19 @@ +// { dg-do compile { target *-*-*linux* } } +// { dg-require-effective-target c++20 } +// { dg-require-effective-target hosted } + +#include +#include + +// on Linux these specializations all use a futex: +static_assert(sizeof(std::counting_semaphore<0>) == sizeof(int)); +static_assert(sizeof(std::counting_semaphore<1>) == sizeof(int)); +static_assert(sizeof(std::counting_semaphore) == sizeof(int)); +static_assert(sizeof(std::counting_semaphore<>) == sizeof(int)); + +// This will use a futex iff ptrdiff_t has 32 bits: +static_assert(sizeof(std::counting_semaphore) == sizeof(std::ptrdiff_t)); + +#if PTRDIFF_MAX > INT_MAX +static_assert(sizeof(std::counting_semaphore) == sizeof(std::ptrdiff_t)); +#endif diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/cons.cc b/libstdc++-v3/testsuite/30_threads/semaphore/cons.cc index 920f7423332b..790ff2eab557 100644 --- a/libstdc++-v3/testsuite/30_threads/semaphore/cons.cc +++ b/libstdc++-v3/testsuite/30_threads/semaphore/cons.cc @@ -1,4 +1,6 @@ // { dg-do compile { target c++20 } } +// { dg-require-effective-target gthreads { target { ! *-*-linux* } } } +// { dg-require-effective-target hosted } #include diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/cons_neg.cc b/libstdc++-v3/testsuite/30_threads/semaphore/cons_neg.cc new file mode 100644 index 000000000000..56e27d7ddc4c --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/semaphore/cons_neg.cc @@ -0,0 +1,12 @@ +// { dg-options "-D_GLIBCXX_ASSERTIONS" } +// { dg-do run { target c++20 xfail *-*-* } } +// { dg-require-effective-target hosted } +// { dg-add-options libatomic } + +#include + +int main() +{ + // Preconditions: desired >= 0 is true, and desired <= max() is true. + std::binary_semaphore b(2); +} diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc b/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc index 1498d38cb93a..e2680b12e5ae 100644 --- a/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc @@ -16,8 +16,8 @@ // . // { dg-do compile { target c++20 } } -// { dg-require-effective-target pthread } -// { dg-require-gthreads "" } +// { dg-require-effective-target gthreads { target { ! *-*-linux* } } } +// { dg-require-effective-target hosted } #include diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc index d709126cf342..ea7859b22c6c 100644 --- a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc +++ b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc @@ -17,7 +17,8 @@ // { dg-do run { target c++20 } } // { dg-additional-options "-pthread" { target pthread } } -// { dg-require-gthreads "" } +// { dg-require-effective-target gthreads { target { ! *-*-linux* } } } +// { dg-require-effective-target hosted } // { dg-add-options libatomic } #include diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc index 048735ff63ae..1de9cf095092 100644 --- a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc +++ b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc @@ -20,12 +20,19 @@ #include #include -int main() +constexpr bool test() { const int i = 42; auto o = std::experimental::make_observer(&i); static_assert( std::is_same>(), "" ); + std::experimental::observer_ptr>(), "" ); VERIFY( o && *o == 42 ); VERIFY( o.get() == &i ); + return true; +} + +int main() +{ + test(); + static_assert( test(), "LWG 4295 - make_observer should be constexpr" ); } diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc index 3e23e0b452be..d03dd5dcbd80 100644 --- a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc +++ b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc @@ -22,13 +22,13 @@ using std::experimental::observer_ptr; -void test01() +constexpr void test01() { observer_ptr a, b; VERIFY(a == b); } -void test02() +constexpr void test02() { int x[2]{}; observer_ptr a{&x[0]}; @@ -40,7 +40,7 @@ void test02() VERIFY(b > a); } -void test03() +constexpr void test03() { int x{}; observer_ptr a{&x}; @@ -48,9 +48,10 @@ void test03() VERIFY(a == b); } -void test04() +int x[2]{}; + +constexpr void test04() { - static constexpr int x[2]{}; constexpr observer_ptr a{&x[0]}; constexpr observer_ptr b{&x[1]}; VERIFY(a != b); @@ -60,20 +61,25 @@ void test04() VERIFY(b > a); } -void test05() +constexpr void test05() { - static constexpr int x{}; - constexpr observer_ptr a{&x}; - constexpr observer_ptr b{&x}; + constexpr observer_ptr a{&x[0]}; + constexpr observer_ptr b{&x[0]}; VERIFY(a == b); } - -int main() +constexpr bool all_tests() { test01(); test02(); test03(); test04(); test05(); + return true; +} + +int main() +{ + all_tests(); + static_assert( all_tests(), "LWG 4295 - relops should be constexpr" ); } diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc index 9e7678863512..84b8844af34d 100644 --- a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc +++ b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc @@ -25,7 +25,7 @@ using std::experimental::observer_ptr; struct B {}; struct D : B {}; -void test01() +constexpr void test01() { observer_ptr a, b; VERIFY(a == b); @@ -33,7 +33,7 @@ void test01() VERIFY(a == b); } -void test02() +constexpr void test02() { int x{}; observer_ptr a; @@ -45,7 +45,7 @@ void test02() VERIFY(!b); } -void test03() +constexpr void test03() { int x[2]{1,2}; observer_ptr a{&x[0]}; @@ -57,10 +57,16 @@ void test03() VERIFY(*b == 1); } - int main() { - test01(); - test02(); - test03(); + auto tests = [] { + test01(); + test02(); + test03(); + return true; + }; + tests(); +#if __cpp_lib_constexpr_algorithms >= 201806L // >= C++20 + static_assert( tests(), "LWG 4295 - swap should be constexpr" ); +#endif } diff --git a/libstdc++-v3/testsuite/experimental/net/buffer/arithmetic.cc b/libstdc++-v3/testsuite/experimental/net/buffer/arithmetic.cc index 04b3c9358489..483d01fc4bb7 100644 --- a/libstdc++-v3/testsuite/experimental/net/buffer/arithmetic.cc +++ b/libstdc++-v3/testsuite/experimental/net/buffer/arithmetic.cc @@ -26,7 +26,6 @@ using std::experimental::net::const_buffer; void test01() { - bool test __attribute__((unused)) = false; char c[4]; mutable_buffer mb; @@ -64,7 +63,6 @@ test01() void test02() { - bool test __attribute__((unused)) = false; char c[4]; const_buffer cb; diff --git a/libstdc++-v3/testsuite/experimental/net/buffer/const.cc b/libstdc++-v3/testsuite/experimental/net/buffer/const.cc index c6adae672400..4310c28798f1 100644 --- a/libstdc++-v3/testsuite/experimental/net/buffer/const.cc +++ b/libstdc++-v3/testsuite/experimental/net/buffer/const.cc @@ -50,7 +50,6 @@ test01() void test02() { - bool test __attribute__((unused)) = false; char c[4]; const_buffer b; diff --git a/libstdc++-v3/testsuite/experimental/net/buffer/mutable.cc b/libstdc++-v3/testsuite/experimental/net/buffer/mutable.cc index 9f0d7d4a5857..06a848c2d161 100644 --- a/libstdc++-v3/testsuite/experimental/net/buffer/mutable.cc +++ b/libstdc++-v3/testsuite/experimental/net/buffer/mutable.cc @@ -47,7 +47,6 @@ test01() void test02() { - bool test __attribute__((unused)) = false; char c[4]; mutable_buffer b; diff --git a/libstdc++-v3/testsuite/experimental/net/buffer/size.cc b/libstdc++-v3/testsuite/experimental/net/buffer/size.cc index 4592a192ff55..7d5f3394fda8 100644 --- a/libstdc++-v3/testsuite/experimental/net/buffer/size.cc +++ b/libstdc++-v3/testsuite/experimental/net/buffer/size.cc @@ -26,7 +26,6 @@ using std::experimental::net::mutable_buffer; void test01() { - bool test __attribute__((unused)) = false; char c[4]; mutable_buffer mb; @@ -44,7 +43,6 @@ test01() void test02() { - bool test __attribute__((unused)) = false; char c[32]; std::vector mv{ {c, 0}, {c, 32}, {c, 16}, {c, 3}, {c, 0} }; diff --git a/libstdc++-v3/testsuite/experimental/net/timer/waitable/cons.cc b/libstdc++-v3/testsuite/experimental/net/timer/waitable/cons.cc index 6da75285d090..e394ec8f9d99 100644 --- a/libstdc++-v3/testsuite/experimental/net/timer/waitable/cons.cc +++ b/libstdc++-v3/testsuite/experimental/net/timer/waitable/cons.cc @@ -27,8 +27,6 @@ using std::experimental::net::io_context; void test01() { - bool test __attribute__((unused)) = false; - io_context ctx1, ctx2; system_timer timer1(ctx1); @@ -54,8 +52,6 @@ test01() void test02() { - bool test __attribute__((unused)) = false; - io_context ctx1, ctx2; auto t1 = system_timer::clock_type::now(); auto t2 = t1 + system_timer::duration(10); @@ -83,8 +79,6 @@ test02() void test03() { - bool test __attribute__((unused)) = false; - io_context ctx1, ctx2; auto now = system_timer::clock_type::now(); auto d1 = system_timer::duration(10); diff --git a/libstdc++-v3/testsuite/experimental/net/timer/waitable/dest.cc b/libstdc++-v3/testsuite/experimental/net/timer/waitable/dest.cc index d384a67af7d8..ef458bd7f888 100644 --- a/libstdc++-v3/testsuite/experimental/net/timer/waitable/dest.cc +++ b/libstdc++-v3/testsuite/experimental/net/timer/waitable/dest.cc @@ -28,8 +28,6 @@ using std::experimental::net::io_context; void test01() { - bool test __attribute__((unused)) = false; - std::error_code ec; io_context ctx; diff --git a/libstdc++-v3/testsuite/experimental/net/timer/waitable/ops.cc b/libstdc++-v3/testsuite/experimental/net/timer/waitable/ops.cc index 82c05c0ff2cc..ff0b800a175d 100644 --- a/libstdc++-v3/testsuite/experimental/net/timer/waitable/ops.cc +++ b/libstdc++-v3/testsuite/experimental/net/timer/waitable/ops.cc @@ -29,8 +29,6 @@ using std::error_code; void test01() { - bool test __attribute__((unused)) = false; - io_context ctx; error_code ec; bool complete = false; @@ -57,8 +55,6 @@ test01() void test02() { - bool test __attribute__((unused)) = false; - io_context ctx; error_code ec1, ec2; diff --git a/libstdc++-v3/testsuite/ext/special_functions/airy_ai/check_value.cc b/libstdc++-v3/testsuite/ext/special_functions/airy_ai/check_value.cc index 7ff005b194d8..6e8e36be431e 100644 --- a/libstdc++-v3/testsuite/ext/special_functions/airy_ai/check_value.cc +++ b/libstdc++-v3/testsuite/ext/special_functions/airy_ai/check_value.cc @@ -96,7 +96,6 @@ template void test(const testcase_airy_ai (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/ext/special_functions/airy_bi/check_value.cc b/libstdc++-v3/testsuite/ext/special_functions/airy_bi/check_value.cc index 0afefdd97a77..6fcad8329c77 100644 --- a/libstdc++-v3/testsuite/ext/special_functions/airy_bi/check_value.cc +++ b/libstdc++-v3/testsuite/ext/special_functions/airy_bi/check_value.cc @@ -96,7 +96,6 @@ template void test(const testcase_airy_bi (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/ext/special_functions/conf_hyperg/check_value.cc b/libstdc++-v3/testsuite/ext/special_functions/conf_hyperg/check_value.cc index 1227361b975d..a050f6251907 100644 --- a/libstdc++-v3/testsuite/ext/special_functions/conf_hyperg/check_value.cc +++ b/libstdc++-v3/testsuite/ext/special_functions/conf_hyperg/check_value.cc @@ -3820,7 +3820,6 @@ template void test(const testcase_conf_hyperg (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/ext/special_functions/hyperg/check_value.cc b/libstdc++-v3/testsuite/ext/special_functions/hyperg/check_value.cc index 8e0c57f618ae..b6586849d836 100644 --- a/libstdc++-v3/testsuite/ext/special_functions/hyperg/check_value.cc +++ b/libstdc++-v3/testsuite/ext/special_functions/hyperg/check_value.cc @@ -12293,7 +12293,6 @@ template void test(const testcase_hyperg (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/ext/unicode/view.cc b/libstdc++-v3/testsuite/ext/unicode/view.cc index 6f3c099bd84a..4ccf646e0945 100644 --- a/libstdc++-v3/testsuite/ext/unicode/view.cc +++ b/libstdc++-v3/testsuite/ext/unicode/view.cc @@ -7,13 +7,24 @@ namespace uc = std::__unicode; using namespace std::string_view_literals; +template +constexpr void +compare(View v, std::basic_string_view> s) +{ + long size = s.size(); + VERIFY( std::ranges::distance(v) == size ); + VERIFY( std::ranges::equal(v, s) ); + auto rev = std::views::reverse(v); + VERIFY( std::ranges::distance(rev) == size ); + VERIFY( std::ranges::equal(rev, s | std::views::reverse) ); +} + constexpr void test_utf8_to_utf8() { const auto s8 = u8"£🇬🇧 €🇪🇺 æбçδé ♠♥♦♣ 🤡"sv; uc::_Utf8_view v(s8); - VERIFY( std::ranges::distance(v) == s8.size() ); - VERIFY( std::ranges::equal(v, s8) ); + compare(v, s8); } constexpr void @@ -22,8 +33,7 @@ test_utf8_to_utf16() const auto s8 = u8"£🇬🇧 €🇪🇺 æбçδé ♠♥♦♣ 🤡"sv; const std::u16string_view s16 = u"£🇬🇧 €🇪🇺 æбçδé ♠♥♦♣ 🤡"; uc::_Utf16_view v(s8); - VERIFY( std::ranges::distance(v) == s16.size() ); - VERIFY( std::ranges::equal(v, s16) ); + compare(v, s16); } constexpr void @@ -32,36 +42,41 @@ test_utf8_to_utf32() const auto s8 = u8"£🇬🇧 €🇪🇺 æбçδé ♠♥♦♣ 🤡"sv; const auto s32 = U"£🇬🇧 €🇪🇺 æбçδé ♠♥♦♣ 🤡"sv; uc::_Utf32_view v(s8); - VERIFY( std::ranges::distance(v) == s32.size() ); - VERIFY( std::ranges::equal(v, s32) ); + compare(v, s32); } constexpr void test_illformed_utf8() { uc::_Utf32_view v("\xa3 10.99 \xee \xdd"sv); - VERIFY( std::ranges::equal(v, U"\uFFFD 10.99 \uFFFD \uFFFD"sv) ); + compare(v, U"\uFFFD 10.99 \uFFFD \uFFFD"sv); uc::_Utf16_view v2(" \xf8\x80\x80\x80 "sv); - VERIFY( std::ranges::distance(v2) == 6 ); - VERIFY( std::ranges::equal(v2, U" \uFFFD\uFFFD\uFFFD\uFFFD "sv) ); + compare(v2, u" \uFFFD\uFFFD\uFFFD\uFFFD "sv); // Examples of U+FFFD substitution from Unicode standard. uc::_Utf8_view v3("\xc0\xaf\xe0\x80\xbf\xf0\x81\x82\x41"sv); // Table 3-8 - VERIFY( std::ranges::equal(v3, u8"\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\x41"sv) ); + compare(v3, u8"\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\x41"sv); uc::_Utf8_view v4("\xed\xa0\x80\xed\xbf\xbf\xed\xaf\x41"sv); // Table 3-9 - VERIFY( std::ranges::equal(v4, u8"\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\x41"sv) ); + compare(v4, u8"\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\x41"sv); uc::_Utf8_view v5("\xf4\x91\x92\x93\xff\x41\x80\xbf\x42"sv); // Table 3-10 - VERIFY( std::ranges::equal(v5, u8"\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\x41\uFFFD\uFFFD\x42"sv) ); + compare(v5, u8"\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\x41\uFFFD\uFFFD\x42"sv); uc::_Utf8_view v6("\xe1\x80\xe2\xf0\x91\x92\xf1\xbf\x41"sv); // Table 3-11 - VERIFY( std::ranges::equal(v6, u8"\uFFFD\uFFFD\uFFFD\uFFFD\x41"sv) ); + compare(v6, u8"\uFFFD\uFFFD\uFFFD\uFFFD\x41"sv); uc::_Utf32_view v7("\xe1\x80"sv); - VERIFY( std::ranges::equal(v7, U"\uFFFD"sv) ); + compare(v7, U"\uFFFD"sv); uc::_Utf32_view v8("\xf1\x80"sv); - VERIFY( std::ranges::equal(v8, U"\uFFFD"sv) ); + compare(v8, U"\uFFFD"sv); uc::_Utf32_view v9("\xf1\x80\x80"sv); - VERIFY( std::ranges::equal(v9, U"\uFFFD"sv) ); + compare(v9, U"\uFFFD"sv); + + uc::_Utf32_view v10("\xcf\x80\x80\x81\x82\x83 \x84\x85\x86\x87\x88 "sv); + compare(v10, U"\u03C0\uFFFD\uFFFD\uFFFD\uFFFD \uFFFD\uFFFD\uFFFD\uFFFD\uFFFD "sv); + uc::_Utf16_view v11("\xcf\x80\x80\x81\x82\x83 \x84\x85\x86\x87\x88 "sv); + compare(v11, u"\u03C0\uFFFD\uFFFD\uFFFD\uFFFD \uFFFD\uFFFD\uFFFD\uFFFD\uFFFD "sv); + uc::_Utf8_view v12("\xcf\x80\x80\x81\x82\x83 \x84\x85\x86\x87\x88 "sv); + compare(v12, u8"\u03C0\uFFFD\uFFFD\uFFFD\uFFFD \uFFFD\uFFFD\uFFFD\uFFFD\uFFFD "sv); } constexpr void @@ -69,27 +84,27 @@ test_illformed_utf16() { std::u16string_view s = u"\N{CLOWN FACE}"; std::u16string_view r = u"\uFFFD"; - VERIFY( std::ranges::equal(uc::_Utf16_view(s.substr(0, 1)), r) ); - VERIFY( std::ranges::equal(uc::_Utf16_view(s.substr(1, 1)), r) ); + compare(uc::_Utf16_view(s.substr(0, 1)), r); + compare(uc::_Utf16_view(s.substr(1, 1)), r); std::array s2{ s[0], s[0] }; - VERIFY( std::ranges::equal(uc::_Utf16_view(s2), u"\uFFFD\uFFFD"sv) ); + compare(uc::_Utf16_view(s2), u"\uFFFD\uFFFD"sv); std::array s3{ s[0], s[0], s[1] }; - VERIFY( std::ranges::equal(uc::_Utf16_view(s3), u"\uFFFD\N{CLOWN FACE}"sv) ); + compare(uc::_Utf16_view(s3), u"\uFFFD\N{CLOWN FACE}"sv); std::array s4{ s[1], s[0] }; - VERIFY( std::ranges::equal(uc::_Utf16_view(s4), u"\uFFFD\uFFFD"sv) ); + compare(uc::_Utf16_view(s4), u"\uFFFD\uFFFD"sv); std::array s5{ s[1], s[0], s[1] }; - VERIFY( std::ranges::equal(uc::_Utf16_view(s5), u"\uFFFD\N{CLOWN FACE}"sv) ); + compare(uc::_Utf16_view(s5), u"\uFFFD\N{CLOWN FACE}"sv); } constexpr void test_illformed_utf32() { std::u32string_view s = U"\x110000"; - VERIFY( std::ranges::equal(uc::_Utf32_view(s), U"\uFFFD"sv) ); + compare(uc::_Utf32_view(s), U"\uFFFD"sv); s = U"\xFFFFFF"; - VERIFY( std::ranges::equal(uc::_Utf32_view(s), U"\uFFFD"sv) ); + compare(uc::_Utf32_view(s), U"\uFFFD"sv); s = U"\xFFFFFFF0"; - VERIFY( std::ranges::equal(uc::_Utf32_view(s), U"\uFFFD"sv) ); + compare(uc::_Utf32_view(s), U"\uFFFD"sv); } constexpr void @@ -110,6 +125,13 @@ test_past_the_end() iter++; VERIFY( iter == v.end() ); VERIFY( *iter == U'4' ); + std::ranges::advance(iter, -4); + VERIFY( *iter == U'1' ); + // Incrementing before begin has well-defined behaviour. + iter--; + VERIFY( *iter == U'1' ); + iter--; + VERIFY( *iter == U'1' ); std::string_view empty; uc::_Utf32_view v2(empty); @@ -119,6 +141,9 @@ test_past_the_end() iter++; VERIFY( iter2 == v2.end() ); VERIFY( *iter2 == U'\0' ); + iter--; + VERIFY( iter2 == v2.end() ); + VERIFY( *iter2 == U'\0' ); } int main() diff --git a/libstdc++-v3/testsuite/ext/verify_neg.cc b/libstdc++-v3/testsuite/ext/verify_neg.cc new file mode 100644 index 000000000000..ce033741beeb --- /dev/null +++ b/libstdc++-v3/testsuite/ext/verify_neg.cc @@ -0,0 +1,28 @@ +// { dg-do compile { target c++11 } } + +#include + +struct X { explicit operator void*() const { return nullptr; } }; + +void +test_VERIFY(int i) +{ + // This should not be parsed as a function type bool(bool(i)): + VERIFY( bool(i) ); + + // This should not produce warnings about lambda in unevaluated context: + VERIFY( []{ return 1; }() ); + + // Only one expression allowed: + VERIFY(1, 2); // { dg-error "in expansion of macro" } + // { dg-error "compound expression in functional cast" "" { target *-*-* } 0 } + + // A scoped enum is not contextually convertible to bool: + enum class E { E0 }; + VERIFY( E::E0 ); // { dg-error "could not convert" } + + // explicit conversion to void* is not contextually convertible to bool: + X x; + VERIFY( x ); // { dg-error "in expansion of macro" } + // { dg-error "invalid cast .* to type 'bool'" "" { target *-*-* } 0 } +} diff --git a/libstdc++-v3/testsuite/special_functions/01_assoc_laguerre/check_value.cc b/libstdc++-v3/testsuite/special_functions/01_assoc_laguerre/check_value.cc index 4e40f0f919c1..90d7d36b77a5 100644 --- a/libstdc++-v3/testsuite/special_functions/01_assoc_laguerre/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/01_assoc_laguerre/check_value.cc @@ -2217,7 +2217,6 @@ template void test(const testcase_assoc_laguerre (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/02_assoc_legendre/check_value.cc b/libstdc++-v3/testsuite/special_functions/02_assoc_legendre/check_value.cc index b54e59ee132f..54ae51d55b10 100644 --- a/libstdc++-v3/testsuite/special_functions/02_assoc_legendre/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/02_assoc_legendre/check_value.cc @@ -1985,7 +1985,6 @@ template void test(const testcase_assoc_legendre (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/02_assoc_legendre/pr86655.cc b/libstdc++-v3/testsuite/special_functions/02_assoc_legendre/pr86655.cc index 9d6507aa1db3..cbd7c5174389 100644 --- a/libstdc++-v3/testsuite/special_functions/02_assoc_legendre/pr86655.cc +++ b/libstdc++-v3/testsuite/special_functions/02_assoc_legendre/pr86655.cc @@ -37,7 +37,6 @@ template void test_m_gt_l() { - bool test __attribute__((unused)) = true; for (auto l : {0u, 1u, 2u, 5u}) for (auto m : {l + 1u, l + 2u}) for (auto i : {-2, -1, 0, 1, 2}) diff --git a/libstdc++-v3/testsuite/special_functions/03_beta/check_value.cc b/libstdc++-v3/testsuite/special_functions/03_beta/check_value.cc index 24f5033c2f80..e5e85a517f90 100644 --- a/libstdc++-v3/testsuite/special_functions/03_beta/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/03_beta/check_value.cc @@ -261,7 +261,6 @@ template void test(const testcase_beta (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/04_comp_ellint_1/check_value.cc b/libstdc++-v3/testsuite/special_functions/04_comp_ellint_1/check_value.cc index efa7d5aaa2ff..c109410ab3e3 100644 --- a/libstdc++-v3/testsuite/special_functions/04_comp_ellint_1/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/04_comp_ellint_1/check_value.cc @@ -73,7 +73,6 @@ template void test(const testcase_comp_ellint_1 (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/05_comp_ellint_2/check_value.cc b/libstdc++-v3/testsuite/special_functions/05_comp_ellint_2/check_value.cc index 8c77daf8777c..6a5d14d16221 100644 --- a/libstdc++-v3/testsuite/special_functions/05_comp_ellint_2/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/05_comp_ellint_2/check_value.cc @@ -73,7 +73,6 @@ template void test(const testcase_comp_ellint_2 (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/06_comp_ellint_3/check_value.cc b/libstdc++-v3/testsuite/special_functions/06_comp_ellint_3/check_value.cc index 8a74415c6308..df544b568748 100644 --- a/libstdc++-v3/testsuite/special_functions/06_comp_ellint_3/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/06_comp_ellint_3/check_value.cc @@ -459,7 +459,6 @@ template void test(const testcase_comp_ellint_3 (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/07_cyl_bessel_i/check_value.cc b/libstdc++-v3/testsuite/special_functions/07_cyl_bessel_i/check_value.cc index ab182c1e861c..a379bed4ce78 100644 --- a/libstdc++-v3/testsuite/special_functions/07_cyl_bessel_i/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/07_cyl_bessel_i/check_value.cc @@ -702,7 +702,6 @@ template void test(const testcase_cyl_bessel_i (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/08_cyl_bessel_j/check_value.cc b/libstdc++-v3/testsuite/special_functions/08_cyl_bessel_j/check_value.cc index a99e1e769b9d..e09ae3d41bf2 100644 --- a/libstdc++-v3/testsuite/special_functions/08_cyl_bessel_j/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/08_cyl_bessel_j/check_value.cc @@ -735,7 +735,6 @@ template void test(const testcase_cyl_bessel_j (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/09_cyl_bessel_k/check_value.cc b/libstdc++-v3/testsuite/special_functions/09_cyl_bessel_k/check_value.cc index 5e6804e0d208..ce5abccffc3f 100644 --- a/libstdc++-v3/testsuite/special_functions/09_cyl_bessel_k/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/09_cyl_bessel_k/check_value.cc @@ -746,7 +746,6 @@ template void test(const testcase_cyl_bessel_k (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/10_cyl_neumann/check_value.cc b/libstdc++-v3/testsuite/special_functions/10_cyl_neumann/check_value.cc index 30c8a3484270..d93437767602 100644 --- a/libstdc++-v3/testsuite/special_functions/10_cyl_neumann/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/10_cyl_neumann/check_value.cc @@ -779,7 +779,6 @@ template void test(const testcase_cyl_neumann (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/11_ellint_1/check_value.cc b/libstdc++-v3/testsuite/special_functions/11_ellint_1/check_value.cc index c8bad36806dd..2d6a3c5906b4 100644 --- a/libstdc++-v3/testsuite/special_functions/11_ellint_1/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/11_ellint_1/check_value.cc @@ -459,7 +459,6 @@ template void test(const testcase_ellint_1 (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/12_ellint_2/check_value.cc b/libstdc++-v3/testsuite/special_functions/12_ellint_2/check_value.cc index fc971e60e282..0bbd7bb5d4d5 100644 --- a/libstdc++-v3/testsuite/special_functions/12_ellint_2/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/12_ellint_2/check_value.cc @@ -459,7 +459,6 @@ template void test(const testcase_ellint_2 (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/13_ellint_3/check_value.cc b/libstdc++-v3/testsuite/special_functions/13_ellint_3/check_value.cc index f46d8a5ff107..bb1b4c185a9c 100644 --- a/libstdc++-v3/testsuite/special_functions/13_ellint_3/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/13_ellint_3/check_value.cc @@ -6121,7 +6121,6 @@ template void test(const testcase_ellint_3 (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/14_expint/check_value.cc b/libstdc++-v3/testsuite/special_functions/14_expint/check_value.cc index 6bf060a399a4..92e97140ffe3 100644 --- a/libstdc++-v3/testsuite/special_functions/14_expint/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/14_expint/check_value.cc @@ -168,7 +168,6 @@ template void test(const testcase_expint (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/15_hermite/check_value.cc b/libstdc++-v3/testsuite/special_functions/15_hermite/check_value.cc index a16073ad39a7..419fcb050168 100644 --- a/libstdc++-v3/testsuite/special_functions/15_hermite/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/15_hermite/check_value.cc @@ -1904,7 +1904,6 @@ template void test(const testcase_hermite (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/16_laguerre/check_value.cc b/libstdc++-v3/testsuite/special_functions/16_laguerre/check_value.cc index 89b9c9498097..03c6496ab561 100644 --- a/libstdc++-v3/testsuite/special_functions/16_laguerre/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/16_laguerre/check_value.cc @@ -305,7 +305,6 @@ template void test(const testcase_laguerre (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/17_legendre/check_value.cc b/libstdc++-v3/testsuite/special_functions/17_legendre/check_value.cc index b2c0077f21b4..7bfb98c93a66 100644 --- a/libstdc++-v3/testsuite/special_functions/17_legendre/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/17_legendre/check_value.cc @@ -305,7 +305,6 @@ template void test(const testcase_legendre (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/18_riemann_zeta/check_value.cc b/libstdc++-v3/testsuite/special_functions/18_riemann_zeta/check_value.cc index 1967bf724d87..c8589ff60709 100644 --- a/libstdc++-v3/testsuite/special_functions/18_riemann_zeta/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/18_riemann_zeta/check_value.cc @@ -273,7 +273,6 @@ template void test(const testcase_riemann_zeta (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/19_sph_bessel/check_value.cc b/libstdc++-v3/testsuite/special_functions/19_sph_bessel/check_value.cc index 8116ac4f96dd..658a13b49069 100644 --- a/libstdc++-v3/testsuite/special_functions/19_sph_bessel/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/19_sph_bessel/check_value.cc @@ -504,7 +504,6 @@ template void test(const testcase_sph_bessel (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/20_sph_legendre/check_value.cc b/libstdc++-v3/testsuite/special_functions/20_sph_legendre/check_value.cc index df417e64f29b..5783ca9150fe 100644 --- a/libstdc++-v3/testsuite/special_functions/20_sph_legendre/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/20_sph_legendre/check_value.cc @@ -1985,7 +1985,6 @@ template void test(const testcase_sph_legendre (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/special_functions/20_sph_legendre/pr86655.cc b/libstdc++-v3/testsuite/special_functions/20_sph_legendre/pr86655.cc index e397371bbe24..80809ee190c1 100644 --- a/libstdc++-v3/testsuite/special_functions/20_sph_legendre/pr86655.cc +++ b/libstdc++-v3/testsuite/special_functions/20_sph_legendre/pr86655.cc @@ -37,7 +37,6 @@ template void test_m_gt_l() { - bool test __attribute__((unused)) = true; for (auto l : {0u, 1u, 2u, 5u}) for (auto m : {l + 1u, l + 2u}) for (auto i : {-2, -1, 0, 1, 2}) diff --git a/libstdc++-v3/testsuite/special_functions/21_sph_neumann/check_value.cc b/libstdc++-v3/testsuite/special_functions/21_sph_neumann/check_value.cc index 372ca39445c2..c9873b69fce4 100644 --- a/libstdc++-v3/testsuite/special_functions/21_sph_neumann/check_value.cc +++ b/libstdc++-v3/testsuite/special_functions/21_sph_neumann/check_value.cc @@ -554,7 +554,6 @@ template void test(const testcase_sph_neumann (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/std/format/debug.cc b/libstdc++-v3/testsuite/std/format/debug.cc index 965b4dfbebc5..43e930c579e2 100644 --- a/libstdc++-v3/testsuite/std/format/debug.cc +++ b/libstdc++-v3/testsuite/std/format/debug.cc @@ -26,13 +26,13 @@ fdebug(std::wstring_view t) #define WIDEN_(C, S) ::std::__format::_Widen(S, L##S) -#define WIDEN(S) WIDEN_(_CharT, S) +#define WIDEN(S) WIDEN_(CharT, S) -template +template void test_basic_escapes() { - std::basic_string<_CharT> res; + std::basic_string res; const auto tab = WIDEN("\t"); res = fdebug(tab); @@ -71,11 +71,11 @@ test_basic_escapes() VERIFY( res == WIDEN(R"('\'')") ); } -template +template void test_ascii_escapes() { - std::basic_string<_CharT> res; + std::basic_string res; const auto in = WIDEN("\x10 abcde\x7f\t0123"); res = fdebug(in); @@ -88,11 +88,11 @@ test_ascii_escapes() VERIFY( res == WIDEN(R"('a')") ); } -template +template void test_extended_ascii() { - std::basic_string<_CharT> res; + std::basic_string res; const auto in = WIDEN("Åëÿ"); res = fdebug(in); @@ -100,7 +100,7 @@ test_extended_ascii() static constexpr bool __test_characters #if UNICODE_ENC - = sizeof(_CharT) >= 2; + = sizeof(CharT) >= 2; #else // ISO8859-1 = true; #endif // UNICODE_ENC @@ -116,12 +116,12 @@ test_extended_ascii() } } -template +template void test_unicode_escapes() { #if UNICODE_ENC - std::basic_string<_CharT> res; + std::basic_string res; const auto in = WIDEN( "\u008a" // Cc, Control, Line Tabulation Set, @@ -143,7 +143,7 @@ test_unicode_escapes() res = fdebug(in); VERIFY( res == out ); - if constexpr (sizeof(_CharT) >= 2) + if constexpr (sizeof(CharT) >= 2) { res = fdebug(in[0]); VERIFY( res == WIDEN(R"('\u{8a}')") ); @@ -157,7 +157,7 @@ test_unicode_escapes() VERIFY( res == WIDEN(R"('\u{2029}')") ); } - if constexpr (sizeof(_CharT) >= 4) + if constexpr (sizeof(CharT) >= 4) { res = fdebug(in[5]); VERIFY( res == WIDEN("'\U0001f984'") ); @@ -165,25 +165,25 @@ test_unicode_escapes() #endif // UNICODE_ENC } -template +template void test_grapheme_extend() { #if UNICODE_ENC - std::basic_string<_CharT> res; + std::basic_string res; const auto vin = WIDEN("o\u0302\u0323"); res = fdebug(vin); VERIFY( res == WIDEN("\"o\u0302\u0323\"") ); - std::basic_string_view<_CharT> in = WIDEN("\t\u0302\u0323"); + std::basic_string_view in = WIDEN("\t\u0302\u0323"); res = fdebug(in); VERIFY( res == WIDEN(R"("\t\u{302}\u{323}")") ); res = fdebug(in.substr(1)); VERIFY( res == WIDEN(R"("\u{302}\u{323}")") ); - if constexpr (sizeof(_CharT) >= 2) + if constexpr (sizeof(CharT) >= 2) { res = fdebug(in[1]); VERIFY( res == WIDEN(R"('\u{302}')") ); @@ -191,13 +191,13 @@ test_grapheme_extend() #endif // UNICODE_ENC } -template +template void test_replacement_char() { #if UNICODE_ENC - std::basic_string<_CharT> repl = WIDEN("\uFFFD"); - std::basic_string<_CharT> res = fdebug(repl); + std::basic_string repl = WIDEN("\uFFFD"); + std::basic_string res = fdebug(repl); VERIFY( res == WIDEN("\"\uFFFD\"") ); repl = WIDEN("\uFFFD\uFFFD"); @@ -268,13 +268,13 @@ test_ill_formed_utf32() #endif // UNICODE_ENC } -template +template void test_fill() { - std::basic_string<_CharT> res; + std::basic_string res; - std::basic_string_view<_CharT> in = WIDEN("a\t\x10\u00ad"); + std::basic_string_view in = WIDEN("a\t\x10\u00ad"); res = std::format(WIDEN("{:10?}"), in.substr(0, 1)); VERIFY( res == WIDEN(R"("a" )") ); @@ -299,11 +299,11 @@ test_fill() VERIFY( res == WIDEN(R"(="\u{ad}"=)") ); // width is 2 - std::basic_string_view<_CharT> in2 = WIDEN("\u1100"); + std::basic_string_view in2 = WIDEN("\u1100"); res = std::format(WIDEN("{:*^10?}"), in2); VERIFY( res == WIDEN("***\"\u1100\"***") ); - if constexpr (sizeof(_CharT) >= 2) + if constexpr (sizeof(CharT) >= 2) { res = std::format(WIDEN("{:=^10?}"), in[3]); VERIFY( res == WIDEN(R"(='\u{ad}'=)") ); @@ -314,14 +314,14 @@ test_fill() #endif // UNICODE_ENC } -template +template void test_prec() { - std::basic_string<_CharT> res; + std::basic_string res; // with ? escpaed presentation is copied to ouput, same as source - std::basic_string_view<_CharT> in = WIDEN("a\t\x10\u00ad"); + std::basic_string_view in = WIDEN("a\t\x10\u00ad"); res = std::format(WIDEN("{:.2?}"), in.substr(0, 1)); VERIFY( res == WIDEN(R"("a)") ); @@ -335,7 +335,7 @@ test_prec() res = std::format(WIDEN("{:.10?}"), in.substr(3)); VERIFY( res == WIDEN(R"("\u{ad}")") ); - std::basic_string_view<_CharT> in2 = WIDEN("\u1100"); + std::basic_string_view in2 = WIDEN("\u1100"); res = std::format(WIDEN("{:.3?}"), in2); VERIFY( res == WIDEN("\"\u1100") ); #endif // UNICODE_ENC @@ -759,38 +759,38 @@ struct std::formatter, CharT> std::formatter under; }; -template +template void test_formatter_str() { - _CharT buf[]{ 'a', 'b', 'c', 0 }; + CharT buf[]{ 'a', 'b', 'c', 0 }; DebugWrapper in{ buf }; - std::basic_string<_CharT> res = std::format(WIDEN("{:?}"), in ); + std::basic_string res = std::format(WIDEN("{:?}"), in ); VERIFY( res == WIDEN(R"("abc")") ); } -template +template void test_formatter_arr() { - std::basic_string<_CharT> res; + std::basic_string res; - DebugWrapper<_CharT[3]> in3{ 'a', 'b', 'c' }; + DebugWrapper in3{ 'a', 'b', 'c' }; res = std::format(WIDEN("{:?}"), in3 ); VERIFY( res == WIDEN(R"("abc")") ); // We print all characters, including null-terminator - DebugWrapper<_CharT[4]> in4{ 'a', 'b', 'c', 0 }; + DebugWrapper in4{ 'a', 'b', 'c', 0 }; res = std::format(WIDEN("{:?}"), in4 ); VERIFY( res == WIDEN(R"("abc\u{0}")") ); } -template +template void test_formatter_char() { DebugWrapper in{ 'a' }; - std::basic_string<_CharT> res = std::format(WIDEN("{:?}"), in); + std::basic_string res = std::format(WIDEN("{:?}"), in); VERIFY( res == WIDEN(R"('a')") ); } diff --git a/libstdc++-v3/testsuite/std/format/formatter/120625.cc b/libstdc++-v3/testsuite/std/format/formatter/120625.cc new file mode 100644 index 000000000000..6b03af93b1c7 --- /dev/null +++ b/libstdc++-v3/testsuite/std/format/formatter/120625.cc @@ -0,0 +1,19 @@ +// { dg-do compile { target c++20 } } + +// Bug libstdc++/120625 +// std::formatter<__disabled> specializations cause errors in user code + +#include + +enum X { }; + +// A concept that cannot be used with incomplete types: +template +concept is_X = !std::is_empty_v && std::is_same_v; + +// A valid program-defined specialization: +template requires is_X +struct std::formatter : std::formatter { }; + +// Instantiate the program-defined formatter specialization: +auto s = sizeof(std::formatter); diff --git a/libstdc++-v3/testsuite/std/format/functions/format.cc b/libstdc++-v3/testsuite/std/format/functions/format.cc index e4adf3aeb706..d342114083e3 100644 --- a/libstdc++-v3/testsuite/std/format/functions/format.cc +++ b/libstdc++-v3/testsuite/std/format/functions/format.cc @@ -261,6 +261,16 @@ test_locale() s = std::format(eloc, "{0:Le} {0:Lf} {0:Lg}", -nan); VERIFY( s == "-nan -nan -nan" ); + // PR libstdc++/120548 format confuses a negative sign for a thousands digit + s = std::format(bloc, "{:L}", -123.45); + VERIFY( s == "-123.45" ); + s = std::format(bloc, "{:-L}", -876543.21); + VERIFY( s == "-876,543.21" ); + s = std::format(bloc, "{:+L}", 333.22); + VERIFY( s == "+333.22" ); + s = std::format(bloc, "{: L}", 999.44); + VERIFY( s == " 999.44" ); + // Restore std::locale::global(cloc); } diff --git a/libstdc++-v3/testsuite/std/format/ranges/adaptors.cc b/libstdc++-v3/testsuite/std/format/ranges/adaptors.cc index daa73aa39bfb..a4e2dfb3321e 100644 --- a/libstdc++-v3/testsuite/std/format/ranges/adaptors.cc +++ b/libstdc++-v3/testsuite/std/format/ranges/adaptors.cc @@ -19,7 +19,7 @@ is_format_string_for(const char* str, Args&&... args) } #define WIDEN_(C, S) ::std::__format::_Widen(S, L##S) -#define WIDEN(S) WIDEN_(_CharT, S) +#define WIDEN(S) WIDEN_(CharT, S) template class Adaptor> void @@ -66,13 +66,13 @@ template constexpr auto std::format_kind> = std::range_format::disabled; -template> class Adaptor> void test_output() { const std::vector v{3, 2, 1}; - std::basic_string<_CharT> res; + std::basic_string res; Adaptor> q(std::from_range, v); res = std::format(WIDEN("{}"), q); @@ -88,9 +88,9 @@ test_output() VERIFY( res == WIDEN("==[0x03, 0x02, 0x01]===") ); // Sequence output is always used - Adaptor<_CharT, std::basic_string<_CharT>> qs( + Adaptor> qs( std::from_range, - std::basic_string_view<_CharT>(WIDEN("321"))); + std::basic_string_view(WIDEN("321"))); res = std::format(WIDEN("{}"), qs); VERIFY( res == WIDEN("['3', '2', '1']") ); @@ -114,13 +114,13 @@ test_output() res = std::format(WIDEN("{}"), mq); VERIFY( res == WIDEN("[3, 2, 1]") ); - static_assert(!std::formattable, _CharT>); + static_assert(!std::formattable, CharT>); - static_assert(!std::formattable, _CharT>); - static_assert(!std::formattable, _CharT>); + static_assert(!std::formattable, CharT>); + static_assert(!std::formattable, CharT>); // Formatter check if container is formattable, not container elements. - static_assert(!std::formattable>, _CharT>); + static_assert(!std::formattable>, CharT>); } template> class Adaptor> @@ -135,12 +135,12 @@ test_adaptor() static_assert(!std::formattable, char32_t>); } -template +template void test_compare() { const std::vector v{3, 2, 1}; - std::basic_string<_CharT> res; + std::basic_string res; std::priority_queue, std::greater<>> q( std::from_range, v); diff --git a/libstdc++-v3/testsuite/std/format/ranges/formatter.cc b/libstdc++-v3/testsuite/std/format/ranges/formatter.cc index 00ce9f6dd0cd..d3e089767bfe 100644 --- a/libstdc++-v3/testsuite/std/format/ranges/formatter.cc +++ b/libstdc++-v3/testsuite/std/format/ranges/formatter.cc @@ -6,7 +6,7 @@ #include #define WIDEN_(C, S) ::std::__format::_Widen(S, L##S) -#define WIDEN(S) WIDEN_(_CharT, S) +#define WIDEN(S) WIDEN_(CharT, S) template class Formatter = std::range_formatter> @@ -22,7 +22,6 @@ struct std::formatter, CharT> { constexpr formatter() noexcept { - using _CharT = CharT; _formatter.set_brackets(WIDEN("<"), WIDEN(">")); _formatter.set_separator(WIDEN("; ")); } @@ -41,12 +40,12 @@ struct std::formatter, CharT> Formatter _formatter; }; -template class Formatter> +template class Formatter> void test_default() { MyVector vec{1, 2, 3}; - std::basic_string<_CharT> res; + std::basic_string res; res = std::format(WIDEN("{}"), vec); VERIFY( res == WIDEN("<1; 2; 3>") ); @@ -93,13 +92,13 @@ test_default() VERIFY( res == WIDEN("< +1 ; +2 ; +3 >") ); } -template class Formatter> +template class Formatter> void test_override() { - MyVector<_CharT, Formatter> vc{'a', 'b', 'c', 'd'}; + MyVector vc{'a', 'b', 'c', 'd'}; MyVector, Formatter> vp{{1, 11}, {2, 21}}; - std::basic_string<_CharT> res; + std::basic_string res; res = std::format(WIDEN("{:s}"), vc); VERIFY( res == WIDEN("abcd") ); diff --git a/libstdc++-v3/testsuite/std/format/ranges/map.cc b/libstdc++-v3/testsuite/std/format/ranges/map.cc index 1838480e2cf4..5e1b98fc99da 100644 --- a/libstdc++-v3/testsuite/std/format/ranges/map.cc +++ b/libstdc++-v3/testsuite/std/format/ranges/map.cc @@ -57,7 +57,7 @@ bool is_range_formatter_spec_for(CharT const* spec, Rg&& rg) } #define WIDEN_(C, S) ::std::__format::_Widen(S, L##S) -#define WIDEN(S) WIDEN_(_CharT, S) +#define WIDEN(S) WIDEN_(CharT, S) void test_format_string() @@ -83,10 +83,10 @@ test_format_string() VERIFY( !is_format_string_for("{:{}m}", std::vector>(), 1.0f) ); } -template +template void test_output(bool mapIsDefault) { - using Sv = std::basic_string_view<_CharT>; + using Sv = std::basic_string_view; using Pt = std::ranges::range_value_t; using Ft = std::remove_cvref_t>; using St = std::remove_cvref_t>; @@ -94,7 +94,7 @@ void test_output(bool mapIsDefault) return Range(s.data(), s.data() + s.size()); }; - std::basic_string<_CharT> res; + std::basic_string res; size_t size = 0; Ft f1[]{1, 2, 3}; diff --git a/libstdc++-v3/testsuite/std/format/ranges/pr119861_neg.cc b/libstdc++-v3/testsuite/std/format/ranges/pr119861_neg.cc new file mode 100644 index 000000000000..9a6ed16393ee --- /dev/null +++ b/libstdc++-v3/testsuite/std/format/ranges/pr119861_neg.cc @@ -0,0 +1,52 @@ +// { dg-do compile { target c++23 } } + +#include +#include + +// only format_kind::sequence provides set_brackets and set_separator methods + +template +struct MyCont : std::vector +{ + using std::vector::vector; +}; + +template +constexpr std::range_format std::format_kind> = fk; + +void test_sequence() +{ + std::formatter, char> fmtter; + fmtter.set_brackets("{", "}"); + fmtter.set_separator(","); +} + +void test_map() +{ + std::formatter>, char> fmtter; + fmtter.set_brackets("{", "}"); // { dg-error "here" } + fmtter.set_separator(","); // { dg-error "here" } +} + +void test_set() +{ + std::formatter, char> fmtter; + fmtter.set_brackets("{", "}"); // { dg-error "here" } + fmtter.set_separator(","); // { dg-error "here" } +} + +void test_string() +{ + std::formatter, char> fmtter; + fmtter.set_brackets("{", "}"); // { dg-error "here" } + fmtter.set_separator(","); // { dg-error "here" } +} + +void test_debug_string() +{ + std::formatter, char> fmtter; + fmtter.set_brackets("{", "}"); // { dg-error "here" } + fmtter.set_separator(","); // { dg-error "here" } +} + +// { dg-error "no matching function for call to 'std::formatter<" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/std/format/ranges/sequence.cc b/libstdc++-v3/testsuite/std/format/ranges/sequence.cc index 32242860f10e..7fb65f9c551e 100644 --- a/libstdc++-v3/testsuite/std/format/ranges/sequence.cc +++ b/libstdc++-v3/testsuite/std/format/ranges/sequence.cc @@ -76,12 +76,12 @@ test_format_string() } #define WIDEN_(C, S) ::std::__format::_Widen(S, L##S) -#define WIDEN(S) WIDEN_(_CharT, S) +#define WIDEN(S) WIDEN_(CharT, S) -template +template void test_output() { - using Sv = std::basic_string_view<_CharT>; + using Sv = std::basic_string_view; using T = std::ranges::range_value_t; auto makeRange = [](Storage& s) -> Range { if constexpr (std::is_same_v, Storage>) @@ -91,7 +91,7 @@ void test_output() std::ranges::data(s) + std::ranges::size(s)); }; - std::basic_string<_CharT> res; + std::basic_string res; size_t size = 0; Storage v1{1, 2, 3}; diff --git a/libstdc++-v3/testsuite/std/format/ranges/string.cc b/libstdc++-v3/testsuite/std/format/ranges/string.cc index cebdd5301680..99e5eaf411f9 100644 --- a/libstdc++-v3/testsuite/std/format/ranges/string.cc +++ b/libstdc++-v3/testsuite/std/format/ranges/string.cc @@ -48,7 +48,7 @@ bool is_range_formatter_spec_for(CharT const* spec, Rg&& rg) } #define WIDEN_(C, S) ::std::__format::_Widen(S, L##S) -#define WIDEN(S) WIDEN_(_CharT, S) +#define WIDEN(S) WIDEN_(CharT, S) void test_format_string() @@ -81,14 +81,14 @@ test_format_string() template void test_output() { - using _CharT = std::ranges::range_value_t; - auto makeRange = [](std::basic_string<_CharT>& s) { + using CharT = std::ranges::range_value_t; + auto makeRange = [](std::basic_string& s) { return Range(s.data(), s.data() + s.size()); }; - std::basic_string<_CharT> res; + std::basic_string res; size_t size = 0; - std::basic_string<_CharT> s1 = WIDEN("abcd"); + std::basic_string s1 = WIDEN("abcd"); res = std::format(WIDEN("{}"), makeRange(s1)); VERIFY( res == WIDEN("['a', 'b', 'c', 'd']") ); @@ -122,7 +122,7 @@ void test_output() res = std::format(WIDEN("{:=^8s}"), makeRange(s1)); VERIFY( res == WIDEN("==abcd==") ); - std::basic_string<_CharT> s2(512, static_cast<_CharT>('a')); + std::basic_string s2(512, static_cast('a')); res = std::format(WIDEN("{:=^8s}"), makeRange(s2)); VERIFY( res == s2 ); diff --git a/libstdc++-v3/testsuite/std/format/tuple.cc b/libstdc++-v3/testsuite/std/format/tuple.cc index ff0359b9aba3..ba6dae8935b6 100644 --- a/libstdc++-v3/testsuite/std/format/tuple.cc +++ b/libstdc++-v3/testsuite/std/format/tuple.cc @@ -39,7 +39,7 @@ is_format_string_for(const wchar_t* str, Args&&... args) } #define WIDEN_(C, S) ::std::__format::_Widen(S, L##S) -#define WIDEN(S) WIDEN_(_CharT, S) +#define WIDEN(S) WIDEN_(CharT, S) void test_format_string() @@ -62,13 +62,13 @@ test_format_string() VERIFY( !is_format_string_for("{:{}}", std::tuple<>(), 1.0f) ); } -template +template void test_multi() { - using Sv = std::basic_string_view<_CharT>; - using Str = std::basic_string<_CharT>; + using Sv = std::basic_string_view; + using Str = std::basic_string; - std::basic_string<_CharT> res; + std::basic_string res; std::size_t size = 0; std::tuple t1(1, WIDEN("test"), 2.1); @@ -122,10 +122,10 @@ void test_multi() } -template +template void test_empty() { - std::basic_string<_CharT> res; + std::basic_string res; Tuple e1; res = std::format(WIDEN("{}"), e1); @@ -141,13 +141,13 @@ void test_empty() VERIFY( res == WIDEN(R"(^^^^())") ); } -template +template void test_pair() { using Ft = std::remove_cvref_t>; using St = std::remove_cvref_t>; - std::basic_string<_CharT> res; + std::basic_string res; Ft f1 = 1; St s1 = WIDEN("abc"); @@ -187,7 +187,6 @@ struct std::formatter, CharT> { constexpr formatter() noexcept { - using _CharT = CharT; _formatter.set_brackets(WIDEN("<"), WIDEN(">")); _formatter.set_separator(WIDEN("; ")); } @@ -206,11 +205,11 @@ struct std::formatter, CharT> std::formatter _formatter; }; -template class PairT> +template class PairT> void test_custom() { - std::basic_string<_CharT> res; - MyPair> c1(1, WIDEN("abc")); + std::basic_string res; + MyPair> c1(1, WIDEN("abc")); res = std::format(WIDEN("{}"), c1); VERIFY( res == WIDEN(R"(<1; "abc">)") ); diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc index 2861115c22a0..a9395b489919 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc @@ -233,6 +233,13 @@ test14() VERIFY( ranges::equal(v | views::join, (int[]){1, 2, 3}) ); } +void +test15() +{ + // PR libstdc++/119962 - __maybe_present_t misses initialization + constexpr decltype(views::join(views::single(views::single(0))).begin()) it; +} + int main() { @@ -250,4 +257,5 @@ main() test12(); test13(); test14(); + test15(); } diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/join_with/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/join_with/1.cc index 8ab30a5277da..4d55c9d3be78 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/join_with/1.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/join_with/1.cc @@ -94,6 +94,13 @@ test04() return true; } +void +test05() +{ + // PR libstdc++/119962 - __maybe_present_t misses initialization + constexpr decltype(views::join_with(views::single(views::single(0)), 0).begin()) it; +} + int main() { @@ -105,4 +112,5 @@ main() #else VERIFY(test04()); #endif + test05(); } diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/lazy_split.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/lazy_split.cc index 81fc60b362a8..321ae271bf2b 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/lazy_split.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/lazy_split.cc @@ -232,6 +232,13 @@ test12() return true; } +void +test13() +{ + // PR libstdc++/119962 - __maybe_present_t misses initialization + constexpr decltype(views::lazy_split(views::single(0), 0).begin()) it; +} + int main() { @@ -247,4 +254,5 @@ main() test10(); test11(); static_assert(test12()); + test13(); } diff --git a/libstdc++-v3/testsuite/std/ranges/concat/1.cc b/libstdc++-v3/testsuite/std/ranges/concat/1.cc index 16721912a37d..f78ed08a610b 100644 --- a/libstdc++-v3/testsuite/std/ranges/concat/1.cc +++ b/libstdc++-v3/testsuite/std/ranges/concat/1.cc @@ -99,6 +99,18 @@ test04() using type = decltype(v); } +void +test05() +{ + // PR libstdc++/120934 - views::concat is ill-formed depending on argument order + auto v1 = views::single(1); + std::vector vec = {2, 3}; + auto v2 = views::join(views::transform(vec, views::single)); + + static_assert( ranges::range ); + static_assert( ranges::range ); +} + int main() { @@ -107,4 +119,5 @@ main() test02(); test03(); test04(); + test05(); } diff --git a/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc b/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc index 3e6f954ceb0c..fbd783bdf1a6 100644 --- a/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc +++ b/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc @@ -352,6 +352,9 @@ static_assert(numeric_limits::is_specialized); static_assert(!numeric_limits::is_signed); static_assert(numeric_limits::is_integer); static_assert(numeric_limits::is_exact); +static_assert(numeric_limits::is_bounded); +static_assert(numeric_limits::is_modulo); +static_assert(numeric_limits::radix == 2); // We can't unconditionally use numeric_limits here because __int128 is an // integral type only in GNU mode. #if __SIZEOF_INT128__ @@ -379,6 +382,9 @@ static_assert(numeric_limits::is_specialized); static_assert(numeric_limits::is_signed); static_assert(numeric_limits::is_integer); static_assert(numeric_limits::is_exact); +static_assert(numeric_limits::is_bounded); +static_assert(!numeric_limits::is_modulo); +static_assert(numeric_limits::radix == 2); static_assert(numeric_limits::digits == numeric_limits::digits - 1); static_assert(numeric_limits::digits10 @@ -400,6 +406,38 @@ static_assert(max_diff_t(max_size_t(1) << (numeric_limits::digits-1)) == numeric_limits::min()); +template +constexpr bool verify_numeric_limits_values_not_meaningful_for = true + && (numeric_limits::max_digits10 == 0) + && (numeric_limits::min_exponent == 0) + && (numeric_limits::min_exponent10 == 0) + && (numeric_limits::max_exponent == 0) + && (numeric_limits::max_exponent10 == 0) + && !numeric_limits::is_iec559 + && !numeric_limits::has_infinity + && !numeric_limits::has_quiet_NaN + && !numeric_limits::has_signaling_NaN + && !numeric_limits::has_denorm_loss + && !numeric_limits::tinyness_before + && (numeric_limits::has_denorm == std::denorm_absent) + && (numeric_limits::round_style == std::round_toward_zero) + && (numeric_limits::denorm_min() == 0) + && (numeric_limits::epsilon() == 0) + && (numeric_limits::round_error() == 0) + && (numeric_limits::infinity() == 0) + && (numeric_limits::quiet_NaN() == 0) + && (numeric_limits::signaling_NaN() == 0); + +static_assert(verify_numeric_limits_values_not_meaningful_for); +static_assert(verify_numeric_limits_values_not_meaningful_for); + +// Verify that the types are structural types and can therefore be used +// as NTTP types. +template struct Su { static_assert(V*V == V+132); }; +template struct Ss { static_assert(V*V == V+132); }; +template struct Su<12>; +template struct Ss<12>; + int main() { diff --git a/libstdc++-v3/testsuite/std/time/format/data_not_present_neg.cc b/libstdc++-v3/testsuite/std/time/format/data_not_present_neg.cc new file mode 100644 index 000000000000..bb09451dc29c --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/format/data_not_present_neg.cc @@ -0,0 +1,164 @@ +// { dg-do compile { target c++20 } } + +#include +#include + +using namespace std::chrono; + +auto d1 = std::format("{:%w}", 10d); // { dg-error "call to consteval function" } +auto d2 = std::format("{:%m}", 10d); // { dg-error "call to consteval function" } +auto d3 = std::format("{:%y}", 10d); // { dg-error "call to consteval function" } +auto d4 = std::format("{:%F}", 10d); // { dg-error "call to consteval function" } +auto d5 = std::format("{:%T}", 10d); // { dg-error "call to consteval function" } +auto d6 = std::format("{:%Q}", 10d); // { dg-error "call to consteval function" } +auto d7 = std::format("{:%Z}", 10d); // { dg-error "call to consteval function" } + +auto w1 = std::format("{:%d}", Thursday); // { dg-error "call to consteval function" } +auto w2 = std::format("{:%m}", Thursday); // { dg-error "call to consteval function" } +auto w3 = std::format("{:%y}", Thursday); // { dg-error "call to consteval function" } +auto w4 = std::format("{:%F}", Thursday); // { dg-error "call to consteval function" } +auto w5 = std::format("{:%T}", Thursday); // { dg-error "call to consteval function" } +auto w6 = std::format("{:%Q}", Thursday); // { dg-error "call to consteval function" } +auto w7 = std::format("{:%Z}", Thursday); // { dg-error "call to consteval function" } + +auto wi1 = std::format("{:%d}", Thursday[2]); // { dg-error "call to consteval function" } +auto wi2 = std::format("{:%m}", Thursday[2]); // { dg-error "call to consteval function" } +auto wi3 = std::format("{:%y}", Thursday[2]); // { dg-error "call to consteval function" } +auto wi4 = std::format("{:%F}", Thursday[2]); // { dg-error "call to consteval function" } +auto wi5 = std::format("{:%T}", Thursday[2]); // { dg-error "call to consteval function" } +auto wi6 = std::format("{:%Q}", Thursday[2]); // { dg-error "call to consteval function" } +auto wi7 = std::format("{:%Z}", Thursday[2]); // { dg-error "call to consteval function" } + +auto wl1 = std::format("{:%d}", Thursday[last]); // { dg-error "call to consteval function" } +auto wl2 = std::format("{:%m}", Thursday[last]); // { dg-error "call to consteval function" } +auto wl3 = std::format("{:%y}", Thursday[last]); // { dg-error "call to consteval function" } +auto wl4 = std::format("{:%F}", Thursday[last]); // { dg-error "call to consteval function" } +auto wl5 = std::format("{:%T}", Thursday[last]); // { dg-error "call to consteval function" } +auto wl6 = std::format("{:%Q}", Thursday[last]); // { dg-error "call to consteval function" } +auto wl7 = std::format("{:%Z}", Thursday[last]); // { dg-error "call to consteval function" } + +auto m1 = std::format("{:%d}", January); // { dg-error "call to consteval function" } +auto m2 = std::format("{:%w}", January); // { dg-error "call to consteval function" } +auto m3 = std::format("{:%y}", January); // { dg-error "call to consteval function" } +auto m4 = std::format("{:%F}", January); // { dg-error "call to consteval function" } +auto m5 = std::format("{:%T}", January); // { dg-error "call to consteval function" } +auto m6 = std::format("{:%Q}", January); // { dg-error "call to consteval function" } +auto m7 = std::format("{:%Z}", January); // { dg-error "call to consteval function" } + +auto yr1 = std::format("{:%d}", 2025y); // { dg-error "call to consteval function" } +auto yr2 = std::format("{:%w}", 2025y); // { dg-error "call to consteval function" } +auto yr3 = std::format("{:%m}", 2025y); // { dg-error "call to consteval function" } +auto yr4 = std::format("{:%F}", 2025y); // { dg-error "call to consteval function" } +auto yr5 = std::format("{:%T}", 2025y); // { dg-error "call to consteval function" } +auto yr6 = std::format("{:%Q}", 2025y); // { dg-error "call to consteval function" } +auto yr7 = std::format("{:%Z}", 2025y); // { dg-error "call to consteval function" } + +auto md1 = std::format("{:%w}", January/10d); // { dg-error "call to consteval function" } +auto md2 = std::format("{:%y}", January/10d); // { dg-error "call to consteval function" } +auto md3 = std::format("{:%F}", January/10d); // { dg-error "call to consteval function" } +auto md4 = std::format("{:%T}", January/10d); // { dg-error "call to consteval function" } +auto md5 = std::format("{:%Q}", January/10d); // { dg-error "call to consteval function" } +auto md6 = std::format("{:%Z}", January/10d); // { dg-error "call to consteval function" } + +auto mwi1 = std::format("{:%d}", January/Thursday[2]); // { dg-error "call to consteval function" } +auto mwi2 = std::format("{:%y}", January/Thursday[2]); // { dg-error "call to consteval function" } +auto mwi3 = std::format("{:%F}", January/Thursday[2]); // { dg-error "call to consteval function" } +auto mwi4 = std::format("{:%T}", January/Thursday[2]); // { dg-error "call to consteval function" } +auto mwi5 = std::format("{:%Q}", January/Thursday[2]); // { dg-error "call to consteval function" } +auto mwi6 = std::format("{:%Z}", January/Thursday[2]); // { dg-error "call to consteval function" } + +auto mwl1 = std::format("{:%d}", January/Thursday[last]); // { dg-error "call to consteval function" } +auto mwl2 = std::format("{:%y}", January/Thursday[last]); // { dg-error "call to consteval function" } +auto mwl3 = std::format("{:%F}", January/Thursday[last]); // { dg-error "call to consteval function" } +auto mwl4 = std::format("{:%T}", January/Thursday[last]); // { dg-error "call to consteval function" } +auto mwl5 = std::format("{:%Q}", January/Thursday[last]); // { dg-error "call to consteval function" } +auto mwl6 = std::format("{:%Z}", January/Thursday[last]); // { dg-error "call to consteval function" } + +auto ml1 = std::format("{:%d}", January/last); // { dg-error "call to consteval function" } +auto ml2 = std::format("{:%w}", January/last); // { dg-error "call to consteval function" } +auto ml3 = std::format("{:%y}", January/last); // { dg-error "call to consteval function" } +auto ml4 = std::format("{:%F}", January/last); // { dg-error "call to consteval function" } +auto ml5 = std::format("{:%T}", January/last); // { dg-error "call to consteval function" } +auto ml6 = std::format("{:%Q}", January/last); // { dg-error "call to consteval function" } +auto ml7 = std::format("{:%Z}", January/last); // { dg-error "call to consteval function" } + +auto ym1 = std::format("{:%d}", 2024y/March); // { dg-error "call to consteval function" } +auto ym2 = std::format("{:%w}", 2024y/March); // { dg-error "call to consteval function" } +auto ym3 = std::format("{:%F}", 2024y/March); // { dg-error "call to consteval function" } +auto ym4 = std::format("{:%T}", 2024y/March); // { dg-error "call to consteval function" } +auto ym5 = std::format("{:%Q}", 2024y/March); // { dg-error "call to consteval function" } +auto ym6 = std::format("{:%Z}", 2024y/March); // { dg-error "call to consteval function" } + +auto ymd1 = std::format("{:%T}", 2021y/January/10d); // { dg-error "call to consteval function" } +auto ymd2 = std::format("{:%Q}", 2021y/January/10d); // { dg-error "call to consteval function" } +auto ymd3 = std::format("{:%Z}", 2021y/January/10d); // { dg-error "call to consteval function" } + +auto ymwi1 = std::format("{:%T}", 2021y/January/Thursday[2]); // { dg-error "call to consteval function" } +auto ymwi2 = std::format("{:%Q}", 2021y/January/Thursday[2]); // { dg-error "call to consteval function" } +auto ymwi3 = std::format("{:%Z}", 2021y/January/Thursday[2]); // { dg-error "call to consteval function" } + +auto ymwl1 = std::format("{:%T}", 2021y/January/Thursday[last]); // { dg-error "call to consteval function" } +auto ymwl2 = std::format("{:%Q}", 2021y/January/Thursday[last]); // { dg-error "call to consteval function" } +auto ymwl3 = std::format("{:%Z}", 2021y/January/Thursday[last]); // { dg-error "call to consteval function" } + +auto yml1 = std::format("{:%T}", 2021y/January/last); // { dg-error "call to consteval function" } +auto yml2 = std::format("{:%Q}", 2021y/January/last); // { dg-error "call to consteval function" } +auto yml3 = std::format("{:%Z}", 2021y/January/last); // { dg-error "call to consteval function" } + +auto ls1 = std::format("{:%Q}", local_seconds(20s)); // { dg-error "call to consteval function" } +auto ls2 = std::format("{:%Z}", local_seconds(10s)); // { dg-error "call to consteval function" } +auto ld1 = std::format("{:%Q}", local_days(days(20))); // { dg-error "call to consteval function" } +auto ld2 = std::format("{:%Z}", local_days(days(10))); // { dg-error "call to consteval function" } + +auto ss1 = std::format("{:%Q}", sys_seconds(20s)); // { dg-error "call to consteval function" } +auto sd1 = std::format("{:%Q}", sys_days(days(20))); // { dg-error "call to consteval function" } + +auto utc = std::format("{:%Q}", utc_clock::now()); // { dg-error "call to consteval function" } +auto gps = std::format("{:%Q}", gps_clock::now()); // { dg-error "call to consteval function" } +auto tai = std::format("{:%Q}", tai_clock::now()); // { dg-error "call to consteval function" } +auto file = std::format("{:%Q}", file_clock::now()); // { dg-error "call to consteval function" } + +const auto ltc = local_seconds(10s); +#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI +const auto zt = zoned_time("Europe/Sofia", local_seconds(10s)); +auto zt1 = std::format("{:%Q}", zt); // { dg-error "call to consteval function" "" { target cxx11_abi } } +#endif +auto lf1 = std::format("{:%Q}", local_time_format(ltc)); // { dg-error "call to consteval function" } + +auto dur1 = std::format("{:%d}", 123s); // { dg-error "call to consteval function" } +auto dur2 = std::format("{:%w}", 123s); // { dg-error "call to consteval function" } +auto dur3 = std::format("{:%m}", 123s); // { dg-error "call to consteval function" } +auto dur4 = std::format("{:%y}", 123s); // { dg-error "call to consteval function" } +auto dur5 = std::format("{:%F}", 123s); // { dg-error "call to consteval function" } +auto dur6 = std::format("{:%Z}", 123s); // { dg-error "call to consteval function" } + +using HMS = hh_mm_ss; +auto hms1 = std::format("{:%d}", HMS(1255s)); // { dg-error "call to consteval function" } +auto hms2 = std::format("{:%w}", HMS(1255s)); // { dg-error "call to consteval function" } +auto hms3 = std::format("{:%m}", HMS(1255s)); // { dg-error "call to consteval function" } +auto hms4 = std::format("{:%y}", HMS(1255s)); // { dg-error "call to consteval function" } +auto hms5 = std::format("{:%F}", HMS(1255s)); // { dg-error "call to consteval function" } +auto hms6 = std::format("{:%Q}", HMS(1255s)); // { dg-error "call to consteval function" } +auto hms7 = std::format("{:%Z}", HMS(1255s)); // { dg-error "call to consteval function" } + +#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI +auto li1 = std::format("{:%d}", local_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +auto li2 = std::format("{:%w}", local_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +auto li3 = std::format("{:%m}", local_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +auto li4 = std::format("{:%y}", local_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +auto li5 = std::format("{:%F}", local_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +auto li6 = std::format("{:%T}", local_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +auto li7 = std::format("{:%Q}", local_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +auto li8 = std::format("{:%Z}", local_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } + +auto si1 = std::format("{:%d}", sys_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +auto si2 = std::format("{:%w}", sys_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +auto si3 = std::format("{:%m}", sys_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +auto si4 = std::format("{:%y}", sys_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +auto si5 = std::format("{:%F}", sys_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +auto si6 = std::format("{:%T}", sys_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +auto si7 = std::format("{:%Q}", sys_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +auto si8 = std::format("{:%Z}", sys_info()); // { dg-error "call to consteval function" "" { target cxx11_abi } } +#endif + +// { dg-error "call to non-'constexpr' function" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/std/time/format/empty_spec.cc b/libstdc++-v3/testsuite/std/time/format/empty_spec.cc index ec57a6f0d209..ef1b19d688c7 100644 --- a/libstdc++-v3/testsuite/std/time/format/empty_spec.cc +++ b/libstdc++-v3/testsuite/std/time/format/empty_spec.cc @@ -1,6 +1,6 @@ // { dg-do run { target c++20 } } // { dg-require-effective-target hosted } -// { dg-timeout-factor 2 } +// { dg-timeout-factor 5 } #include #include @@ -10,7 +10,7 @@ using namespace std::chrono; #define WIDEN_(C, S) ::std::__format::_Widen(S, L##S) -#define WIDEN(S) WIDEN_(_CharT, S) +#define WIDEN(S) WIDEN_(CharT, S) template void @@ -34,15 +34,15 @@ test_no_empty_spec() } } -template -void verify(const T& t, std::basic_string_view<_CharT> str) +template +void verify(const T& t, std::basic_string_view str) { - std::basic_string<_CharT> res; + std::basic_string res; res = std::format(WIDEN("{}"), t); VERIFY( res == str ); - std::basic_stringstream<_CharT> os; + std::basic_stringstream os; os << t; res = std::move(os).str(); VERIFY( res == str ); @@ -52,11 +52,11 @@ template void verify(const T& t, const CharT* str) { verify(t, std::basic_string_view(str)); } -template +template void test_padding() { - std::basic_string<_CharT> res; + std::basic_string res; res = std::format(WIDEN("{:5}"), day(2)); VERIFY( res == WIDEN("02 ") ); @@ -77,15 +77,18 @@ test_padding() VERIFY( res == WIDEN("==16 is not a valid month==") ); } -template +template struct Rep { using Return = std::conditional_t, Rep, Ret>; - Rep(long v = 0) : val(v) {} + Rep(Under v = 0) : val(v) {} + + template + Rep(Rep o) : val(o.val) {} - operator long() const + operator Under() const { return val; } Return @@ -114,53 +117,59 @@ struct Rep friend auto operator<=>(Rep, Rep) = default; - template - friend std::basic_ostream<_CharT>& - operator<<(std::basic_ostream<_CharT>& os, const Rep& t) + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const Rep& t) { return os << t.val << WIDEN("[via <<]"); } - long val; + Under val; +}; + +template +struct std::common_type, Rep> +{ + using type = Rep>; }; -template +template requires std::is_integral_v -struct std::common_type, Other> +struct std::common_type, Other> { - using type = Rep; + using type = Rep>; }; -template +template requires std::is_integral_v -struct std::common_type> - : std::common_type, Other> +struct std::common_type> + : std::common_type, Other> { }; -template -struct std::numeric_limits> - : std::numeric_limits +template +struct std::numeric_limits> + : std::numeric_limits { }; -template -struct std::formatter, _CharT> - : std::formatter +template +struct std::formatter, CharT> + : std::formatter { template - typename std::basic_format_context::iterator - format(const Rep& t, std::basic_format_context& ctx) const + typename std::basic_format_context::iterator + format(const Rep& t, std::basic_format_context& ctx) const { - constexpr std::basic_string_view<_CharT> suffix = WIDEN("[via format]"); - auto out = std::formatter::format(t.val, ctx); + constexpr std::basic_string_view suffix = WIDEN("[via format]"); + auto out = std::formatter::format(t.val, ctx); return std::ranges::copy(suffix, out).out; } }; using deciseconds = duration; -template +template void test_duration() { - std::basic_string<_CharT> res; + std::basic_string res; const milliseconds di(40); verify( di, WIDEN("40ms") ); @@ -170,6 +179,13 @@ test_duration() verify( -di, WIDEN("-40ms") ); res = std::format(WIDEN("{:>6}"), -di); VERIFY( res == WIDEN(" -40ms") ); +} + +template +void +test_duration_fp() +{ + std::basic_string res; const duration df(11.22); verify( df, WIDEN("11.22s") ); @@ -179,13 +195,17 @@ test_duration() verify( -df, WIDEN("-11.22s") ); res = std::format(WIDEN("{:=^12}"), -df); VERIFY( res == WIDEN("==-11.22s===") ); + + // precision accepted but ignored + res = std::format(WIDEN("{:.6}"), df); + VERIFY( res == WIDEN("11.22s") ); } -template +template void test_duration_cust() { - std::basic_string<_CharT> res; + std::basic_string res; const duration> charRep(123); verify( charRep, WIDEN("123ds") ); @@ -242,7 +262,7 @@ hms(const duration& d) return hh_mm_ss(duration_cast(d)); } -template +template void test_hh_mm_ss() { @@ -292,7 +312,45 @@ test_hh_mm_ss() WIDEN("-14322:24:54.111222333") ); } -template +template +void +test_hh_mm_ss_fp() +{ + duration dt = 22h + 24min + 54s + 111222333ns; + // period controls number of subseconds + verify( hms(dt), + WIDEN("22:24:54.111222333") ); + verify( hms(dt), + WIDEN("22:24:54.111222") ); + verify( hms(dt), + WIDEN("22:24:54.111") ); + verify( hms(dt), + WIDEN("22:24:54.1") ); + verify( hms(dt), + WIDEN("22:24:54") ); + verify( hms(-dt), + WIDEN("-22:24:54.111222333") ); + verify( hms(-dt), + WIDEN("-22:24:54.111222") ); + verify( hms(-dt), + WIDEN("-22:24:54.111") ); + verify( hms(-dt), + WIDEN("-22:24:54.1") ); + verify( hms(-dt), + WIDEN("-22:24:54") ); + + // but hour and minutes are preserved + verify( hms(dt), + WIDEN("22:24:54") ); + verify( hms(dt), + WIDEN("22:24:54") ); + verify( hms(-dt), + WIDEN("-22:24:54") ); + verify( hms(-dt), + WIDEN("-22:24:54") ); +} + +template void test_hh_mm_ss_cust() { @@ -306,30 +364,30 @@ test_hh_mm_ss_cust() // +plus returns long, so formatted as long const duration, std::milli> asLong(dt.count()); verify( hms(asLong), - WIDEN("22:24:54.123[via format]") ); + WIDEN("22:24:54.123") ); verify( hms(asLong), - WIDEN("22:24:54.1[via format]") ); + WIDEN("22:24:54.1") ); verify( hms(asLong), WIDEN("22:24:54") ); verify( hms(-asLong), - WIDEN("-22:24:54.123[via format]") ); + WIDEN("-22:24:54.123") ); verify( hms(-asLong), - WIDEN("-22:24:54.1[via format]") ); + WIDEN("-22:24:54.1") ); verify( hms(-asLong), WIDEN("-22:24:54") ); // +asRep returns Rep<>, so formatted as Rep<> const duration, std::milli> asRep(dt.count()); verify( hms(asRep), - WIDEN("22:24:54.123[via format]") ); + WIDEN("22:24:54.123") ); verify( hms(asRep), - WIDEN("22:24:54.1[via format]") ); + WIDEN("22:24:54.1") ); verify( hms(asLong), WIDEN("22:24:54") ); verify( hms(-asLong), - WIDEN("-22:24:54.123[via format]") ); + WIDEN("-22:24:54.123") ); verify( hms(-asLong), - WIDEN("-22:24:54.1[via format]") ); + WIDEN("-22:24:54.1") ); verify( hms(-asLong), WIDEN("-22:24:54") ); } @@ -339,13 +397,15 @@ void test_durations() { test_duration(); + test_duration_fp(); test_duration_cust(); test_hh_mm_ss(); + test_hh_mm_ss_fp(); test_hh_mm_ss_cust(); } -template +template void test_day() { @@ -357,7 +417,7 @@ test_day() verify( day(255), WIDEN("255 is not a valid day") ); } -template +template void test_month() { @@ -371,7 +431,7 @@ test_month() verify( month(255), WIDEN("255 is not a valid month") ); } -template +template void test_year() { @@ -386,7 +446,7 @@ test_year() verify( year(32767), WIDEN( "32767") ); } -template +template void test_weekday() { @@ -400,7 +460,7 @@ test_weekday() verify( weekday(255), WIDEN("255 is not a valid weekday") ); } -template +template void test_weekday_indexed() { @@ -415,7 +475,7 @@ test_weekday_indexed() verify( weekday(32)[7], WIDEN("32 is not a valid weekday[7 is not a valid index]") ); } -template +template void test_weekday_last() { @@ -423,7 +483,7 @@ test_weekday_last() verify( weekday(9)[last], WIDEN("9 is not a valid weekday[last]") ); } -template +template void test_month_day() { @@ -433,7 +493,7 @@ test_month_day() verify( month(13)/32, WIDEN("13 is not a valid month/32 is not a valid day") ); } -template +template void test_month_day_last() { @@ -441,7 +501,7 @@ test_month_day_last() verify( month(14)/last, WIDEN("14 is not a valid month/last") ); } -template +template void test_month_weekday() { @@ -457,7 +517,7 @@ test_month_weekday() WIDEN("13 is not a valid month/130 is not a valid weekday[0 is not a valid index]") ); } -template +template void test_month_weekday_last() { @@ -471,7 +531,7 @@ test_month_weekday_last() WIDEN("13 is not a valid month/10 is not a valid weekday[last]") ); } -template +template void test_year_month() { @@ -485,31 +545,27 @@ test_year_month() WIDEN("-32768 is not a valid year/0 is not a valid month") ); } -template +template void test_year_month_day() { verify( year(2024)/month(1)/30, WIDEN("2024-01-30") ); verify( year(-100)/month(14)/1, - // Should be -0100-14-01 - WIDEN("-100-14-01 is not a valid date") ); + WIDEN("-0100-14-01 is not a valid date") ); verify( year(2025)/month(11)/100, - // Should be 2025-11-100 ? - WIDEN("2025-11-99 is not a valid date") ); + WIDEN("2025-11-100 is not a valid date") ); verify( year(-32768)/month(2)/10, WIDEN("-32768-02-10 is not a valid date") ); verify( year(-32768)/month(212)/10, - // Should be 32768-212-10? - WIDEN("-32768-84-10 is not a valid date") ); + WIDEN("-32768-212-10 is not a valid date") ); verify( year(-32768)/month(2)/105, - // Should be 32768-02-99? - WIDEN("-32768-02-99 is not a valid date") ); + WIDEN("-32768-02-105 is not a valid date") ); verify( year(-32768)/month(14)/55, WIDEN("-32768-14-55 is not a valid date") ); } -template +template void test_year_month_last() { @@ -523,7 +579,7 @@ test_year_month_last() WIDEN("-32768 is not a valid year/0 is not a valid month/last") ); } -template +template void test_year_month_weekday() { @@ -539,7 +595,7 @@ test_year_month_weekday() WIDEN("-32768 is not a valid year/13 is not a valid month/130 is not a valid weekday[0 is not a valid index]") ); } -template +template void test_year_month_weekday_last() { @@ -597,14 +653,14 @@ wall_cast(const local_time& tp) using decadays = duration>; using kilodays = duration>; -template +template void test_time_point(bool daysAsTime) { - std::basic_string<_CharT> res; + std::basic_string res; const auto lt = local_days(2024y/March/22) + 13h + 24min + 54s + 111222333ns; - auto strip_time = [daysAsTime](std::basic_string_view<_CharT> sv) + auto strip_time = [daysAsTime](std::basic_string_view sv) { return daysAsTime ? sv : sv.substr(0, 10); }; verify( wall_cast(lt), @@ -627,11 +683,11 @@ test_time_point(bool daysAsTime) strip_time(WIDEN("2022-01-08 00:00:00")) ); } -template +template void test_leap_second() { - std::basic_string<_CharT> res; + std::basic_string res; const auto st = sys_days(2012y/June/30) + 23h + 59min + 59s + 111222333ns; auto tp = clock_cast(st); @@ -647,12 +703,13 @@ test_leap_second() WIDEN("2012-06-30 23:59:60") ); } +#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI template auto make_zoned(const sys_time& st, const time_zone* tz) { return zoned_time(tz, floor(st)); } -template +template void test_zoned_time() { @@ -679,17 +736,18 @@ test_zoned_time() verify( make_zoned(st, tz), WIDEN("2022-01-08 02:00:00 EET") ); } +#endif template auto local_fmt(const local_time& lt, std::string* zone) { return local_time_format(floor(lt), zone); } -template +template void test_local_time_format() { - std::basic_string<_CharT> res; + std::basic_string res; std::string abbrev = "Zone"; const auto lt = local_days(2024y/March/22) + 13h + 24min + 54s + 111222333ns; @@ -725,13 +783,117 @@ test_time_points() test_time_point(true); test_time_point(true); test_leap_second(); +#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI test_zoned_time(); +#endif test_local_time_format(); test_no_empty_spec>(); test_no_empty_spec>>(); } +#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI +template +void +test_sys_info() +{ + const sys_info si + { + sys_days(2024y/March/22) + 2h, + sys_days(2025y/April/11) + 23h + 15min + 10s, + 2h + 13min + 4s, + 15min, + "Zone" + }; + const std::basic_string_view txt + = WIDEN("[2024-03-22 02:00:00,2025-04-11 23:15:10,02:13:04,15min,Zone]"); + + verify( si, txt ); + + std::basic_string res; + std::basic_string_view sv; + + sv = res = std::format(WIDEN("{:65}"), si); + VERIFY( sv.ends_with(WIDEN(" ")) ); + sv.remove_suffix(4); + VERIFY( sv == txt ); + + sv = res = std::format(WIDEN("{:=^67}"), si); + VERIFY( sv.starts_with(WIDEN("===")) ); + VERIFY( sv.ends_with(WIDEN("===")) ); + sv.remove_prefix(3); + sv.remove_suffix(3); + VERIFY( sv == txt ); +} + +template +void test_local_info() +{ + using String = std::basic_string; + using StringView = std::basic_string_view; + + const sys_info s1 + { + sys_days(2015y/September/11) + 2h, + sys_days(2016y/March/13) + 2h, + -5h, + 0h, + "EET" + }; + const sys_info s2 + { + sys_days(2016y/March/13) + 2h, + sys_days(2015y/September/15) + 2h, + -4h, + 1h, + "EDT" + }; + + const StringView single + = WIDEN("[2015-09-11 02:00:00,2016-03-13 02:00:00,-05:00:00,0min,EET]"); + const StringView both + = WIDEN(" local time between " + "[2015-09-11 02:00:00,2016-03-13 02:00:00,-05:00:00,0min,EET]" + " and " + "[2016-03-13 02:00:00,2015-09-15 02:00:00,-04:00:00,60min,EDT]"); + + const local_info l1{local_info::nonexistent, s1, s2}; + auto exp = WIDEN("[nonexistent") + String(both) + WIDEN("]"); + verify( l1, StringView(exp) ); + + const local_info l2{local_info::ambiguous, s1, s2}; + exp = WIDEN("[ambiguous") + String(both) + WIDEN("]"); + verify( l2, StringView(exp) ); + + const local_info l3{local_info::unique, s1, s1}; + exp = WIDEN("[") + String(single) + WIDEN("]"); + verify( l3, StringView(exp) ); + + String res; + StringView sv; + + sv = res = std::format(WIDEN("{:65}"), l3); + VERIFY( sv.ends_with(WIDEN(" ")) ); + sv.remove_suffix(3); + VERIFY( sv == exp ); + + sv = res = std::format(WIDEN("{:=^67}"), l3); + VERIFY( sv.starts_with(WIDEN("==")) ); + VERIFY( sv.ends_with(WIDEN("===")) ); + sv.remove_prefix(2); + sv.remove_suffix(3); + VERIFY( sv == exp ); +} + +template +void +test_infos() +{ + test_sys_info(); + test_local_info(); +} +#endif + template void test_all() @@ -740,6 +902,9 @@ test_all() test_durations(); test_calendar(); test_time_points(); +#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI + test_infos(); +#endif } int main() diff --git a/libstdc++-v3/testsuite/std/time/format/format.cc b/libstdc++-v3/testsuite/std/time/format/format.cc index d6e35832cb5f..00affb9e11a3 100644 --- a/libstdc++-v3/testsuite/std/time/format/format.cc +++ b/libstdc++-v3/testsuite/std/time/format/format.cc @@ -78,6 +78,13 @@ test_bad_format_strings() VERIFY( not is_format_string_for("{:%OOy}", t) ); VERIFY( not is_format_string_for("{:%OEy}", t) ); VERIFY( not is_format_string_for("{:%EOy}", t) ); + + // weekday and month values for which ok() is false + VERIFY( not is_format_string_for("{:%a}", std::chrono::weekday(8)) ); + VERIFY( not is_format_string_for("{:%A}", std::chrono::weekday(8)) ); + VERIFY( not is_format_string_for("{:%b}", std::chrono::month(13)) ); + VERIFY( not is_format_string_for("{:%h}", std::chrono::month(13)) ); + VERIFY( not is_format_string_for("{:%B}", std::chrono::month(13)) ); } template diff --git a/libstdc++-v3/testsuite/std/time/format/pr117214.cc b/libstdc++-v3/testsuite/std/time/format/pr117214.cc index 87c703dd2554..79109c391518 100644 --- a/libstdc++-v3/testsuite/std/time/format/pr117214.cc +++ b/libstdc++-v3/testsuite/std/time/format/pr117214.cc @@ -7,10 +7,14 @@ #include #include +#include #include + +template void -test_c() +test_locale_formats(const ChronoType& t, + std::span test_specifiers) { const char *test_locales[] = { "aa_DJ.UTF-8", @@ -19,15 +23,44 @@ test_c() "az_IR.UTF-8", "my_MM.UTF-8", }; - std::chrono::sys_seconds t{std::chrono::seconds{1}}; + auto format_args = std::make_format_args(t); for (auto locale_name : test_locales) { - auto s = std::format(std::locale(locale_name), "{:L%c}", t); - VERIFY( !s.empty() ); + std::locale loc(locale_name); + for (auto specifier : test_specifiers) + { + auto s = std::vformat(loc, specifier, format_args); + VERIFY( !s.empty() ); + } } } +void +test_locale_formats() +{ + using namespace std::chrono; + + const char* test_specifiers[] = { + "{:L%x}", "{:L%Ex}", + "{:L%c}", "{:L%Ec}", + "{:L%X}", "{:L%EX}", + "{:L%r}", + }; + auto date_time_specifiers = std::span(test_specifiers); + auto date_specifiers = date_time_specifiers.subspan(0, 2); + auto time_specifiers = date_time_specifiers.subspan(4); + + auto ymd = 2020y/November/12d; + test_locale_formats(ymd, date_specifiers); + + auto tod = 25h + 10min + 12s; + test_locale_formats(tod, time_specifiers); + + auto tp = sys_days(ymd) + tod; + test_locale_formats(tp, date_time_specifiers); +} + #include #include @@ -93,7 +126,7 @@ test_c_local() int main() { - test_c(); + test_locale_formats(); test_c_zoned(); test_c_local(); } diff --git a/libstdc++-v3/testsuite/std/time/format/pr117214_custom_timeput.cc b/libstdc++-v3/testsuite/std/time/format/pr117214_custom_timeput.cc new file mode 100644 index 000000000000..03b94961096a --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/format/pr117214_custom_timeput.cc @@ -0,0 +1,37 @@ +// { dg-do run { target c++20 } } + +#include +#include +#include +#include + +struct custom_time_put : std::time_put +{ + iter_type + do_put(iter_type out, std::ios_base& io, char_type fill, const tm* t, + char format, char modifier) const override + { + using Base = std::time_put; + + switch (format) { + case 'a': case 'A': case 'b': case 'h': case 'B': case 'p': + *out++ = '['; + *out++ = format; + *out++ = ']'; + } + return Base::do_put(out, io, fill, t, format, modifier); + } +}; + +int main() +{ + using namespace std::chrono; + std::locale loc(std::locale::classic(), new custom_time_put); +#define test(t, fmt, exp) VERIFY( std::format(loc, fmt, t) == exp ) + test(Monday, "{:L%a}", "[a]Mon"); + test(Monday, "{:L%A}", "[A]Monday"); + test(January, "{:L%b}", "[b]Jan"); + test(January, "{:L%h}", "[h]Jan"); + test(January, "{:L%B}", "[B]January"); + test(1h, "{:L%p}", "[p]AM"); +} diff --git a/libstdc++-v3/testsuite/std/time/format/pr120114.cc b/libstdc++-v3/testsuite/std/time/format/pr120114.cc index c630bb35a9d0..cdde4685eda6 100644 --- a/libstdc++-v3/testsuite/std/time/format/pr120114.cc +++ b/libstdc++-v3/testsuite/std/time/format/pr120114.cc @@ -7,13 +7,13 @@ #include #define WIDEN_(C, S) ::std::__format::_Widen(S, L##S) -#define WIDEN(S) WIDEN_(_CharT, S) +#define WIDEN(S) WIDEN_(CharT, S) -template +template void test_from_format_string() { - std::basic_string<_CharT> res; + std::basic_string res; using namespace std::chrono_literals; auto date = 2025y/std::chrono::May/05d; @@ -27,24 +27,24 @@ test_from_format_string() VERIFY( res == WIDEN("====2025-05-05\U0001f921====") ); } -template +template void test_formatted_value() { // Custom time_put facet which returns Ideographic Telegraph Symbol // for given month for Om. - struct TimePut : std::time_put<_CharT> + struct TimePut : std::time_put { - using iter_type = std::time_put<_CharT>::iter_type; - using char_type = std::time_put<_CharT>::char_type; + using iter_type = std::time_put::iter_type; + using char_type = std::time_put::char_type; iter_type do_put(iter_type out, std::ios_base& io, char_type fill, const tm* t, char format, char modifier) const override { if (format != 'm' && modifier != 'm') - return std::time_put<_CharT>::do_put(out, io, fill, t, format, modifier); - std::basic_string_view<_CharT> str; + return std::time_put::do_put(out, io, fill, t, format, modifier); + std::basic_string_view str; switch (t->tm_mon) { case 0: @@ -89,7 +89,7 @@ test_formatted_value() }; const std::locale loc(std::locale::classic(), new TimePut); - std::basic_string<_CharT> res; + std::basic_string res; res = std::format(loc, WIDEN("{:<1L%Om}"), std::chrono::January); VERIFY( res == WIDEN("\u32C0") ); diff --git a/libstdc++-v3/testsuite/std/time/format/pr120481.cc b/libstdc++-v3/testsuite/std/time/format/pr120481.cc new file mode 100644 index 000000000000..a748acb59a9b --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/format/pr120481.cc @@ -0,0 +1,324 @@ +// { dg-do run { target c++23 } } +// { dg-options "-fexec-charset=UTF-8" } +// { dg-timeout-factor 2 } + +#include +#include +#include + +#define WIDEN_(C, S) ::std::__format::_Widen(S, L##S) +#define WIDEN(S) WIDEN_(CharT, S) + +using namespace std::chrono; + +template +void +test_year() +{ + std::basic_string res; + + res = std::format(WIDEN("{:%Y}"), year(0)); + VERIFY( res == WIDEN("0000") ); + res = std::format(WIDEN("{:%C}"), year(0)); + VERIFY( res == WIDEN("00") ); + res = std::format(WIDEN("{:%y}"), year(0)); + VERIFY( res == WIDEN("00") ); + + res = std::format(WIDEN("{:%Y}"), year(5)); + VERIFY( res == WIDEN("0005") ); + res = std::format(WIDEN("{:%C}"), year(5)); + VERIFY( res == WIDEN("00") ); + res = std::format(WIDEN("{:%y}"), year(5)); + VERIFY( res == WIDEN("05") ); + res = std::format(WIDEN("{:%Y}"), year(-5)); + VERIFY( res == WIDEN("-0005") ); + res = std::format(WIDEN("{:%C}"), year(-5)); + VERIFY( res == WIDEN("-01") ); + res = std::format(WIDEN("{:%y}"), year(-5)); + VERIFY( res == WIDEN("05") ); + + res = std::format(WIDEN("{:%Y}"), year(213)); + VERIFY( res == WIDEN("0213") ); + res = std::format(WIDEN("{:%C}"), year(213)); + VERIFY( res == WIDEN("02") ); + res = std::format(WIDEN("{:%y}"), year(213)); + VERIFY( res == WIDEN("13") ); + res = std::format(WIDEN("{:%Y}"), year(-213)); + VERIFY( res == WIDEN("-0213") ); + res = std::format(WIDEN("{:%C}"), year(-213)); + VERIFY( res == WIDEN("-03") ); + res = std::format(WIDEN("{:%y}"), year(-213)); + VERIFY( res == WIDEN("13") ); + + res = std::format(WIDEN("{:%Y}"), year(7100)); + VERIFY( res == WIDEN("7100") ); + res = std::format(WIDEN("{:%C}"), year(7100)); + VERIFY( res == WIDEN("71") ); + res = std::format(WIDEN("{:%y}"), year(7100)); + VERIFY( res == WIDEN("00") ); + res = std::format(WIDEN("{:%Y}"), year(-7100)); + VERIFY( res == WIDEN("-7100") ); + res = std::format(WIDEN("{:%C}"), year(-7100)); + VERIFY( res == WIDEN("-71") ); + res = std::format(WIDEN("{:%y}"), year(-7100)); + VERIFY( res == WIDEN("00") ); + + res = std::format(WIDEN("{:%Y}"), year(12101)); + VERIFY( res == WIDEN("12101") ); + res = std::format(WIDEN("{:%C}"), year(12101)); + VERIFY( res == WIDEN("121") ); + res = std::format(WIDEN("{:%y}"), year(12101)); + VERIFY( res == WIDEN("01") ); + res = std::format(WIDEN("{:%Y}"), year(-12101)); + VERIFY( res == WIDEN("-12101") ); + res = std::format(WIDEN("{:%C}"), year(-12101)); + VERIFY( res == WIDEN("-122") ); + res = std::format(WIDEN("{:%y}"), year(-12101)); + VERIFY( res == WIDEN("01") ); +} + +template +void +test_month() +{ + std::basic_string res; + + res = std::format(WIDEN("{:%m}"), month(5)); + VERIFY( res == WIDEN("05") ); + res = std::format(WIDEN("{:%m}"), month(50)); + VERIFY( res == WIDEN("50") ); + res = std::format(WIDEN("{:%m}"), month(127)); + VERIFY( res == WIDEN("127") ); + res = std::format(WIDEN("{:%m}"), month(254)); + VERIFY( res == WIDEN("254") ); +} + +template +void +test_day() +{ + std::basic_string res; + + res = std::format(WIDEN("{:%d}"), day(3)); + VERIFY( res == WIDEN("03") ); + res = std::format(WIDEN("{:%d}"), day(22)); + VERIFY( res == WIDEN("22") ); + res = std::format(WIDEN("{:%d}"), day(100)); + VERIFY( res == WIDEN("100") ); + res = std::format(WIDEN("{:%d}"), day(207)); + VERIFY( res == WIDEN("207") ); + + res = std::format(WIDEN("{:%e}"), day(5)); + VERIFY( res == WIDEN(" 5") ); + res = std::format(WIDEN("{:%e}"), day(99)); + VERIFY( res == WIDEN("99") ); + res = std::format(WIDEN("{:%e}"), day(183)); + VERIFY( res == WIDEN("183") ); + res = std::format(WIDEN("{:%e}"), day(214)); + VERIFY( res == WIDEN("214") ); +} + +template +void +test_date() +{ + std::basic_string res; + + res = std::format(WIDEN("{:%F}"), year(-22)/month(10)/day(20)); + VERIFY( res == WIDEN("-0022-10-20") ); + res = std::format(WIDEN("{:%D}"), year(-22)/month(10)/day(20)); + VERIFY( res == WIDEN("10/20/22") ); + + res = std::format(WIDEN("{:%F}"), year(-2020)/month(123)/day(44)); + VERIFY( res == WIDEN("-2020-123-44") ); + res = std::format(WIDEN("{:%D}"), year(-2020)/month(123)/day(44)); + VERIFY( res == WIDEN("123/44/20") ); + + res = std::format(WIDEN("{:%F}"), year(-23404)/month(99)/day(223)); + VERIFY( res == WIDEN("-23404-99-223") ); + res = std::format(WIDEN("{:%D}"), year(-23404)/month(99)/day(223)); + VERIFY( res == WIDEN("99/223/04") ); + + res = std::format(WIDEN("{:%F}"), year(10000)/month(220)/day(100)); + VERIFY( res == WIDEN("10000-220-100") ); + res = std::format(WIDEN("{:%D}"), year(10000)/month(220)/day(100)); + VERIFY( res == WIDEN("220/100/00") ); +} + +template +void +test_weekday() +{ + std::basic_string res; + + res = std::format(WIDEN("{:%w}"), weekday(0)); + VERIFY( res == WIDEN("0") ); + res = std::format(WIDEN("{:%u}"), weekday(0)); + VERIFY( res == WIDEN("7") ); + + res = std::format(WIDEN("{:%w}"), weekday(7)); + VERIFY( res == WIDEN("0") ); + res = std::format(WIDEN("{:%u}"), weekday(7)); + VERIFY( res == WIDEN("7") ); + + res = std::format(WIDEN("{:%w}"), weekday(8)); + VERIFY( res == WIDEN("8") ); + res = std::format(WIDEN("{:%u}"), weekday(8)); + VERIFY( res == WIDEN("8") ); + + res = std::format(WIDEN("{:%w}"), weekday(10)); + VERIFY( res == WIDEN("10") ); + res = std::format(WIDEN("{:%u}"), weekday(10)); + VERIFY( res == WIDEN("10") ); + + res = std::format(WIDEN("{:%w}"), weekday(76)); + VERIFY( res == WIDEN("76") ); + res = std::format(WIDEN("{:%u}"), weekday(76)); + VERIFY( res == WIDEN("76") ); + + res = std::format(WIDEN("{:%w}"), weekday(100)); + VERIFY( res == WIDEN("100") ); + res = std::format(WIDEN("{:%u}"), weekday(100)); + VERIFY( res == WIDEN("100") ); + + res = std::format(WIDEN("{:%w}"), weekday(202)); + VERIFY( res == WIDEN("202") ); + res = std::format(WIDEN("{:%u}"), weekday(202)); + VERIFY( res == WIDEN("202") ); +} + +template +void +test_hour() +{ + std::basic_string res; + + res = std::format(WIDEN("{:%H}"), 0h + 5min + 6s); + VERIFY( res == WIDEN("00") ); + res = std::format(WIDEN("{:%R}"), 0h + 5min + 6s); + VERIFY( res == WIDEN("00:05") ); + res = std::format(WIDEN("{:%T}"), 0h + 5min + 6s); + VERIFY( res == WIDEN("00:05:06") ); + res = std::format(WIDEN("{:%I}"), 0h + 5min + 6s); + VERIFY( res == WIDEN("12") ); + res = std::format(WIDEN("{:%p}"), 0h + 5min + 6s); + VERIFY( res == WIDEN("AM") ); + + res = std::format(WIDEN("{:%H}"), 7h + 15min + 6s); + VERIFY( res == WIDEN("07") ); + res = std::format(WIDEN("{:%R}"), 7h + 15min + 6s); + VERIFY( res == WIDEN("07:15") ); + res = std::format(WIDEN("{:%T}"), 7h + 15min + 6s); + VERIFY( res == WIDEN("07:15:06") ); + res = std::format(WIDEN("{:%I}"), 7h + 15min + 6s); + VERIFY( res == WIDEN("07") ); + res = std::format(WIDEN("{:%p}"), 7h + 15min + 6s); + VERIFY( res == WIDEN("AM") ); + + res = std::format(WIDEN("{:%H}"), 15h + 55min + 26s); + VERIFY( res == WIDEN("15") ); + res = std::format(WIDEN("{:%R}"), 15h + 55min + 26s); + VERIFY( res == WIDEN("15:55") ); + res = std::format(WIDEN("{:%T}"), 15h + 55min + 26s); + VERIFY( res == WIDEN("15:55:26") ); + res = std::format(WIDEN("{:%I}"), 15h + 55min + 26s); + VERIFY( res == WIDEN("03") ); + res = std::format(WIDEN("{:%p}"), 15h + 55min + 26s); + VERIFY( res == WIDEN("PM") ); + + res = std::format(WIDEN("{:%H}"), 50h + 33min + 37s); + VERIFY( res == WIDEN("50") ); + res = std::format(WIDEN("{:%R}"), 50h + 33min + 37s); + VERIFY( res == WIDEN("50:33") ); + res = std::format(WIDEN("{:%T}"), 50h + 33min + 37s); + VERIFY( res == WIDEN("50:33:37") ); + res = std::format(WIDEN("{:%I}"), 50h + 33min + 37s); + VERIFY( res == WIDEN("02") ); + res = std::format(WIDEN("{:%p}"), 50h + 33min + 37s); + VERIFY( res == WIDEN("AM") ); + + res = std::format(WIDEN("{:%H}"), 100h + 21min + 48s); + VERIFY( res == WIDEN("100") ); + res = std::format(WIDEN("{:%R}"), 100h + 21min + 48s); + VERIFY( res == WIDEN("100:21") ); + res = std::format(WIDEN("{:%T}"), 100h + 21min + 48s); + VERIFY( res == WIDEN("100:21:48") ); + res = std::format(WIDEN("{:%I}"), 100h + 21min + 48s); + VERIFY( res == WIDEN("04") ); + res = std::format(WIDEN("{:%p}"), 100h + 21min + 48s); + VERIFY( res == WIDEN("AM") ); + + res = std::format(WIDEN("{:%H}"), 228h + 45min + 33s); + VERIFY( res == WIDEN("228") ); + res = std::format(WIDEN("{:%R}"), 228h + 45min + 33s); + VERIFY( res == WIDEN("228:45") ); + res = std::format(WIDEN("{:%T}"), 228h + 45min + 33s); + VERIFY( res == WIDEN("228:45:33") ); + res = std::format(WIDEN("{:%I}"), 228h + 4min + 33s); + VERIFY( res == WIDEN("12") ); + res = std::format(WIDEN("{:%p}"), 228h + 4min + 33s); + VERIFY( res == WIDEN("PM") ); + + res = std::format(WIDEN("{:%H}"), 1024h + 3min); + VERIFY( res == WIDEN("1024") ); + res = std::format(WIDEN("{:%R}"), 1024h + 3min); + VERIFY( res == WIDEN("1024:03") ); + res = std::format(WIDEN("{:%T}"), 1024h + 3min); + VERIFY( res == WIDEN("1024:03:00") ); + res = std::format(WIDEN("{:%I}"), 1024h + 3min); + VERIFY( res == WIDEN("04") ); + res = std::format(WIDEN("{:%p}"), 1024h + 3min); + VERIFY( res == WIDEN("PM") ); + + res = std::format(WIDEN("{:%H}"), 2039h); + VERIFY( res == WIDEN("2039") ); + res = std::format(WIDEN("{:%R}"), 2039h); + VERIFY( res == WIDEN("2039:00") ); + res = std::format(WIDEN("{:%T}"), 2039h); + VERIFY( res == WIDEN("2039:00:00") ); + res = std::format(WIDEN("{:%I}"), 2039h); + VERIFY( res == WIDEN("11") ); + res = std::format(WIDEN("{:%p}"), 2039h); + VERIFY( res == WIDEN("PM") ); + + res = std::format(WIDEN("{:%H}"), 22111h + 59min + 59s); + VERIFY( res == WIDEN("22111") ); + res = std::format(WIDEN("{:%R}"), 22111h + 59min + 59s); + VERIFY( res == WIDEN("22111:59") ); + res = std::format(WIDEN("{:%T}"), 22111h + 59min + 59s); + VERIFY( res == WIDEN("22111:59:59") ); + res = std::format(WIDEN("{:%I}"), 22111h + 59min + 59s); + VERIFY( res == WIDEN("07") ); + res = std::format(WIDEN("{:%p}"), 22111h + 59min + 59s); + VERIFY( res == WIDEN("AM") ); + + res = std::format(WIDEN("{:%H}"), -22111h - 59min - 59s); + VERIFY( res == WIDEN("-22111") ); + res = std::format(WIDEN("{:%R}"), -22111h - 59min - 59s); + VERIFY( res == WIDEN("-22111:59") ); + res = std::format(WIDEN("{:%T}"), -22111h - 59min - 59s); + VERIFY( res == WIDEN("-22111:59:59") ); + res = std::format(WIDEN("{:%I}"), -22111h - 59min - 59s); + VERIFY( res == WIDEN("-07") ); + res = std::format(WIDEN("{:%p}"), -22111h - 59min - 59s); + VERIFY( res == WIDEN("AM") ); +} + +int main() +{ + test_year(); + test_month(); + test_day(); + test_date(); + test_weekday(); + test_hour(); + +#ifdef _GLIBCXX_USE_WCHAR_T + test_year(); + test_month(); + test_day(); + test_date(); + test_weekday(); + test_hour(); +#endif // _GLIBCXX_USE_WCHAR_T +} diff --git a/libstdc++-v3/testsuite/std/time/format/precision.cc b/libstdc++-v3/testsuite/std/time/format/precision.cc new file mode 100644 index 000000000000..aa266156c1ff --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/format/precision.cc @@ -0,0 +1,201 @@ +// { dg-do run { target c++20 } } + +#include +#include +#include + +using namespace std::chrono; + +#define WIDEN_(C, S) ::std::__format::_Widen(S, L##S) +#define WIDEN(S) WIDEN_(CharT, S) + +template +void +test_empty() +{ + std::basic_string res; + + const duration d(33.111222); + res = std::format(WIDEN("{:}"), d); + VERIFY( res == WIDEN("33.1112s") ); + res = std::format(WIDEN("{:.0}"), d); + VERIFY( res == WIDEN("33.1112s") ); + res = std::format(WIDEN("{:.3}"), d); + VERIFY( res == WIDEN("33.1112s") ); + res = std::format(WIDEN("{:.6}"), d); + VERIFY( res == WIDEN("33.1112s") ); + res = std::format(WIDEN("{:.9}"), d); + VERIFY( res == WIDEN("33.1112s") ); + + // Uses ostream operator<< + const duration nd = d; + res = std::format(WIDEN("{:}"), nd); + VERIFY( res == WIDEN("3.31112e+10ns") ); + res = std::format(WIDEN("{:.0}"), nd); + VERIFY( res == WIDEN("3.31112e+10ns") ); + res = std::format(WIDEN("{:.3}"), nd); + VERIFY( res == WIDEN("3.31112e+10ns") ); + res = std::format(WIDEN("{:.6}"), nd); + VERIFY( res == WIDEN("3.31112e+10ns") ); + res = std::format(WIDEN("{:.9}"), nd); + VERIFY( res == WIDEN("3.31112e+10ns") ); +} + +template +void +test_Q() +{ + std::basic_string res; + + const duration d(7.111222); + res = std::format(WIDEN("{:%Q}"), d); + VERIFY( res == WIDEN("7.111222") ); + res = std::format(WIDEN("{:.0%Q}"), d); + VERIFY( res == WIDEN("7.111222") ); + res = std::format(WIDEN("{:.3%Q}"), d); + VERIFY( res == WIDEN("7.111222") ); + res = std::format(WIDEN("{:.6%Q}"), d); + VERIFY( res == WIDEN("7.111222") ); + res = std::format(WIDEN("{:.9%Q}"), d); + VERIFY( res == WIDEN("7.111222") ); + + duration md = d; + res = std::format(WIDEN("{:%Q}"), md); + VERIFY( res == WIDEN("7111.222") ); + res = std::format(WIDEN("{:.0%Q}"), md); + VERIFY( res == WIDEN("7111.222") ); + res = std::format(WIDEN("{:.3%Q}"), md); + VERIFY( res == WIDEN("7111.222") ); + res = std::format(WIDEN("{:.6%Q}"), md); + VERIFY( res == WIDEN("7111.222") ); + res = std::format(WIDEN("{:.9%Q}"), md); + VERIFY( res == WIDEN("7111.222") ); + + const duration nd = d; + res = std::format(WIDEN("{:%Q}"), nd); + VERIFY( res == WIDEN("7111222000") ); + res = std::format(WIDEN("{:.0%Q}"), nd); + VERIFY( res == WIDEN("7111222000") ); + res = std::format(WIDEN("{:.3%Q}"), nd); + VERIFY( res == WIDEN("7111222000") ); + res = std::format(WIDEN("{:.6%Q}"), nd); + VERIFY( res == WIDEN("7111222000") ); + res = std::format(WIDEN("{:.9%Q}"), nd); + VERIFY( res == WIDEN("7111222000") ); +} + +template +void +test_S_fp() +{ + std::basic_string res; + + // Precision is ignored, but period affects output + duration d(5.111222); + res = std::format(WIDEN("{:%S}"), d); + VERIFY( res == WIDEN("05") ); + res = std::format(WIDEN("{:.0%S}"), d); + VERIFY( res == WIDEN("05") ); + res = std::format(WIDEN("{:.3%S}"), d); + VERIFY( res == WIDEN("05") ); + res = std::format(WIDEN("{:.6%S}"), d); + VERIFY( res == WIDEN("05") ); + res = std::format(WIDEN("{:.9%S}"), d); + VERIFY( res == WIDEN("05") ); + + duration md = d; + res = std::format(WIDEN("{:%S}"), md); + VERIFY( res == WIDEN("05.111") ); + res = std::format(WIDEN("{:.0%S}"), md); + VERIFY( res == WIDEN("05.111") ); + res = std::format(WIDEN("{:.3%S}"), md); + VERIFY( res == WIDEN("05.111") ); + res = std::format(WIDEN("{:.6%S}"), md); + VERIFY( res == WIDEN("05.111") ); + res = std::format(WIDEN("{:.9%S}"), md); + VERIFY( res == WIDEN("05.111") ); + + duration ud = d; + res = std::format(WIDEN("{:%S}"), ud); + VERIFY( res == WIDEN("05.111222") ); + res = std::format(WIDEN("{:.0%S}"), ud); + VERIFY( res == WIDEN("05.111222") ); + res = std::format(WIDEN("{:.3%S}"), ud); + VERIFY( res == WIDEN("05.111222") ); + res = std::format(WIDEN("{:.6%S}"), ud); + VERIFY( res == WIDEN("05.111222") ); + res = std::format(WIDEN("{:.9%S}"), ud); + VERIFY( res == WIDEN("05.111222") ); + + duration nd = d; + res = std::format(WIDEN("{:%S}"), nd); + VERIFY( res == WIDEN("05.111222000") ); + res = std::format(WIDEN("{:.0%S}"), nd); + VERIFY( res == WIDEN("05.111222000") ); + res = std::format(WIDEN("{:.3%S}"), nd); + VERIFY( res == WIDEN("05.111222000") ); + res = std::format(WIDEN("{:.6%S}"), nd); + VERIFY( res == WIDEN("05.111222000") ); + res = std::format(WIDEN("{:.9%S}"), nd); + VERIFY( res == WIDEN("05.111222000") ); + + duration pd = d; + res = std::format(WIDEN("{:%S}"), pd); + VERIFY( res == WIDEN("05.111222000000") ); + res = std::format(WIDEN("{:.0%S}"), pd); + VERIFY( res == WIDEN("05.111222000000") ); + res = std::format(WIDEN("{:.3%S}"), pd); + VERIFY( res == WIDEN("05.111222000000") ); + res = std::format(WIDEN("{:.6%S}"), pd); + VERIFY( res == WIDEN("05.111222000000") ); + res = std::format(WIDEN("{:.9%S}"), pd); + VERIFY( res == WIDEN("05.111222000000") ); +} + +template +void +test_S_int() +{ + std::basic_string res; + const nanoseconds src(7'000'012'345); + + auto d = floor(src); + res = std::format(WIDEN("{:%S}"), d); + VERIFY( res == WIDEN("07") ); + + auto md = floor(src); + res = std::format(WIDEN("{:%S}"), md); + VERIFY( res == WIDEN("07.000") ); + + auto ud = floor(src); + res = std::format(WIDEN("{:%S}"), ud); + VERIFY( res == WIDEN("07.000012") ); + + auto nd = floor(src); + res = std::format(WIDEN("{:%S}"), nd); + VERIFY( res == WIDEN("07.000012345") ); + + using picoseconds = duration; + auto pd = floor(src); + res = std::format(WIDEN("{:%S}"), pd); + VERIFY( res == WIDEN("07.000012345000") ); +} + +template +void +test_all() +{ + test_empty(); + test_Q(); + test_S_int(); + test_S_fp(); +} + +int main() +{ + test_all(); + +#ifdef _GLIBCXX_USE_WCHAR_T + test_all(); +#endif // _GLIBCXX_USE_WCHAR_T +} diff --git a/libstdc++-v3/testsuite/std/time/format/whitespace.cc b/libstdc++-v3/testsuite/std/time/format/whitespace.cc new file mode 100644 index 000000000000..debda08995cf --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/format/whitespace.cc @@ -0,0 +1,56 @@ +// { dg-do run { target c++20 } } + +#include +#include + +using namespace std::chrono; + +#define WIDEN_(C, S) ::std::__format::_Widen(S, L##S) +#define WIDEN(S) WIDEN_(_CharT, S) + +template +void +test(const ChronoType& ct) +{ + std::basic_string<_CharT> res; + + res = std::format(WIDEN("{:%% %t %n more text}"), ct); + VERIFY( res == WIDEN("% \t \n more text") ); + + res = std::format(WIDEN("{:7%% %t %n}"), ct); + VERIFY( res == WIDEN("% \t \n ") ); + + res = std::format(WIDEN("{:>6%% %t %n}"), ct); + VERIFY( res == WIDEN(" % \t \n") ); + + res = std::format(WIDEN("{:+>7%% %t %n}"), ct); + VERIFY( res == WIDEN("++% \t \n") ); + + res = std::format(WIDEN("{:=^7%% %t %n}"), ct); + VERIFY( res == WIDEN("=% \t \n=") ); +} + +template +void +test_all() +{ + test(20s); + test(10d); + test(Monday); + test(2020y/January/8); + test(local_days(2020y/January/8)); + test(sys_days(2020y/January/8) + 13h + 10min + 5s); +#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI + test(sys_info()); + test(local_info()); +#endif +} + +int main() +{ + test_all(); + +#ifdef _GLIBCXX_USE_WCHAR_T + test_all(); +#endif // _GLIBCXX_USE_WCHAR_T +} diff --git a/libstdc++-v3/testsuite/std/time/month/io.cc b/libstdc++-v3/testsuite/std/time/month/io.cc index 99ec07373059..edfa196b71ca 100644 --- a/libstdc++-v3/testsuite/std/time/month/io.cc +++ b/libstdc++-v3/testsuite/std/time/month/io.cc @@ -24,6 +24,9 @@ test_ostream() ss.imbue(std::locale(ISO_8859(15,fr_FR))); ss << month(1); VERIFY( ss.str() == "janv." ); + ss.str(""); + ss << month(0) << '|' << month(13); + VERIFY( ss.str() == "0 is not a valid month|13 is not a valid month" ); } void @@ -66,6 +69,10 @@ test_format() VERIFY( s == "Jan" ); s = std::format(loc_fr, "{:L%b}", month(1)); VERIFY( s == "janv." ); + s = std::format(loc_fr, "{:L}", month(0)); + VERIFY( s == "0 is not a valid month" ); + s = std::format(loc_fr, "{:L}", month(13)); + VERIFY( s == "13 is not a valid month" ); std::string_view specs = "aAbBcCdDeFgGhHIjmMpqQrRSTuUVwWxXyYzZ"; std::string_view my_specs = "bBhm"; diff --git a/libstdc++-v3/testsuite/std/time/weekday/io.cc b/libstdc++-v3/testsuite/std/time/weekday/io.cc index a56cdaef88cc..90a9bcbbb62f 100644 --- a/libstdc++-v3/testsuite/std/time/weekday/io.cc +++ b/libstdc++-v3/testsuite/std/time/weekday/io.cc @@ -69,6 +69,8 @@ test_format() VERIFY( s == "Mon" ); s = std::format(loc_fr, "{:L%a}", weekday(1)); VERIFY( s == "lun." ); + s = std::format(loc_fr, "{:L}", weekday(25)); + VERIFY( s == "25 is not a valid weekday" ); std::string_view specs = "aAbBcCdDeFgGhHIjmMpqQrRSTuUVwWxXyYzZ"; std::string_view my_specs = "aAuw"; diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/01_assoc_laguerre/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/01_assoc_laguerre/check_value.cc index 1ae8371bb8dc..77e764850cd9 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/01_assoc_laguerre/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/01_assoc_laguerre/check_value.cc @@ -2217,7 +2217,6 @@ template void test(const testcase_assoc_laguerre (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/02_assoc_legendre/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/02_assoc_legendre/check_value.cc index 023f09dae6f9..a30700bb864c 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/02_assoc_legendre/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/02_assoc_legendre/check_value.cc @@ -1985,7 +1985,6 @@ template void test(const testcase_assoc_legendre (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/02_assoc_legendre/pr86655.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/02_assoc_legendre/pr86655.cc index 7f7e3a44e5d8..ec99b606e92c 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/02_assoc_legendre/pr86655.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/02_assoc_legendre/pr86655.cc @@ -36,7 +36,6 @@ template void test_m_gt_l() { - bool test __attribute__((unused)) = true; unsigned int larr[4] = {0u, 1u, 2u, 5u}; for (unsigned int l = 0; l < 4; ++l) for (unsigned int m = larr[l] + 1u; m <= larr[l] + 2u; ++m) diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/03_beta/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/03_beta/check_value.cc index f61438df064c..2dcdcbc72ee8 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/03_beta/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/03_beta/check_value.cc @@ -261,7 +261,6 @@ template void test(const testcase_beta (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/04_comp_ellint_1/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/04_comp_ellint_1/check_value.cc index 76240dba8fd1..7faffe8defaf 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/04_comp_ellint_1/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/04_comp_ellint_1/check_value.cc @@ -73,7 +73,6 @@ template void test(const testcase_comp_ellint_1 (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/05_comp_ellint_2/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/05_comp_ellint_2/check_value.cc index b46a1404663c..60adcb1541e0 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/05_comp_ellint_2/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/05_comp_ellint_2/check_value.cc @@ -73,7 +73,6 @@ template void test(const testcase_comp_ellint_2 (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/06_comp_ellint_3/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/06_comp_ellint_3/check_value.cc index aba5284966cb..34f59567bd0f 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/06_comp_ellint_3/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/06_comp_ellint_3/check_value.cc @@ -459,7 +459,6 @@ template void test(const testcase_comp_ellint_3 (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/07_conf_hyperg/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/07_conf_hyperg/check_value.cc index 5b10ea4f287e..1cd2733af93f 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/07_conf_hyperg/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/07_conf_hyperg/check_value.cc @@ -3819,7 +3819,6 @@ template void test(const testcase_conf_hyperg (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/08_cyl_bessel_i/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/08_cyl_bessel_i/check_value.cc index cb4b3960bff2..02df6ba8354f 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/08_cyl_bessel_i/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/08_cyl_bessel_i/check_value.cc @@ -702,7 +702,6 @@ template void test(const testcase_cyl_bessel_i (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/09_cyl_bessel_j/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/09_cyl_bessel_j/check_value.cc index 689880db15ca..f3b7fa671a66 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/09_cyl_bessel_j/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/09_cyl_bessel_j/check_value.cc @@ -735,7 +735,6 @@ template void test(const testcase_cyl_bessel_j (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/10_cyl_bessel_k/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/10_cyl_bessel_k/check_value.cc index a408c3f647db..10b8092d368a 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/10_cyl_bessel_k/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/10_cyl_bessel_k/check_value.cc @@ -746,7 +746,6 @@ template void test(const testcase_cyl_bessel_k (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/11_cyl_neumann/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/11_cyl_neumann/check_value.cc index 868d278e700a..c365bb5d7ee7 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/11_cyl_neumann/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/11_cyl_neumann/check_value.cc @@ -779,7 +779,6 @@ template void test(const testcase_cyl_neumann (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/12_ellint_1/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/12_ellint_1/check_value.cc index 2ca367f91b01..acb217dff806 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/12_ellint_1/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/12_ellint_1/check_value.cc @@ -459,7 +459,6 @@ template void test(const testcase_ellint_1 (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/13_ellint_2/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/13_ellint_2/check_value.cc index d9e0f7f5e26a..7bb33b50ad43 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/13_ellint_2/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/13_ellint_2/check_value.cc @@ -459,7 +459,6 @@ template void test(const testcase_ellint_2 (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/14_ellint_3/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/14_ellint_3/check_value.cc index 2da68ab49b79..df624a0cdcc8 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/14_ellint_3/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/14_ellint_3/check_value.cc @@ -6121,7 +6121,6 @@ template void test(const testcase_ellint_3 (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/15_expint/check_value_neg.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/15_expint/check_value_neg.cc index 33d95c909369..64f7685810fc 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/15_expint/check_value_neg.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/15_expint/check_value_neg.cc @@ -168,7 +168,6 @@ template void test(const testcase_expint (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/16_hermite/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/16_hermite/check_value.cc index 8afbcdd97ec2..0676f622076a 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/16_hermite/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/16_hermite/check_value.cc @@ -1904,7 +1904,6 @@ template void test(const testcase_hermite (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/17_hyperg/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/17_hyperg/check_value.cc index c77dc3d30881..b83994e48c9e 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/17_hyperg/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/17_hyperg/check_value.cc @@ -12292,7 +12292,6 @@ template void test(const testcase_hyperg (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/18_laguerre/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/18_laguerre/check_value.cc index 60d6af0ffdd0..2fee8e4df90c 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/18_laguerre/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/18_laguerre/check_value.cc @@ -305,7 +305,6 @@ template void test(const testcase_laguerre (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/19_legendre/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/19_legendre/check_value.cc index 19f096db294b..325ae0dd6c5f 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/19_legendre/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/19_legendre/check_value.cc @@ -305,7 +305,6 @@ template void test(const testcase_legendre (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/20_riemann_zeta/check_value_neg.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/20_riemann_zeta/check_value_neg.cc index 658faa76a4f5..cbbccdf092ce 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/20_riemann_zeta/check_value_neg.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/20_riemann_zeta/check_value_neg.cc @@ -273,7 +273,6 @@ template void test(const testcase_riemann_zeta (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/21_sph_bessel/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/21_sph_bessel/check_value.cc index 5863f9a708d5..f2ef94b9c74a 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/21_sph_bessel/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/21_sph_bessel/check_value.cc @@ -504,7 +504,6 @@ template void test(const testcase_sph_bessel (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/22_sph_legendre/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/22_sph_legendre/check_value.cc index 910485f24215..1e178a6fda8f 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/22_sph_legendre/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/22_sph_legendre/check_value.cc @@ -1985,7 +1985,6 @@ template void test(const testcase_sph_legendre (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/22_sph_legendre/pr86655.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/22_sph_legendre/pr86655.cc index 11c9935462b8..87f63ce1a0ac 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/22_sph_legendre/pr86655.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/22_sph_legendre/pr86655.cc @@ -36,7 +36,6 @@ template void test_m_gt_l() { - bool test __attribute__((unused)) = true; unsigned int larr[4] = {0u, 1u, 2u, 5u}; for (unsigned int l = 0; l < 4; ++l) for (unsigned int m = larr[l] + 1u; m <= larr[l] + 2u; ++m) diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/23_sph_neumann/check_value.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/23_sph_neumann/check_value.cc index 8134e7f1c07d..64cfce94327d 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/23_sph_neumann/check_value.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/23_sph_neumann/check_value.cc @@ -554,7 +554,6 @@ template void test(const testcase_sph_neumann (&data)[Num], Ret toler) { - bool test __attribute__((unused)) = true; const Ret eps = std::numeric_limits::epsilon(); Ret max_abs_diff = -Ret(1); Ret max_abs_frac = -Ret(1); diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc index 7bffc6b74f75..4b01023fbaef 100644 --- a/libstdc++-v3/testsuite/util/testsuite_abi.cc +++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc @@ -241,6 +241,7 @@ check_version(symbol& test, bool added) #ifdef __riscv known_versions.push_back("CXXABI_1.3.16"); #endif + known_versions.push_back("CXXABI_1.3.17"); known_versions.push_back("CXXABI_IEEE128_1.3.13"); known_versions.push_back("CXXABI_TM_1"); known_versions.push_back("CXXABI_FLOAT128"); diff --git a/libstdc++-v3/testsuite/util/testsuite_containers.h b/libstdc++-v3/testsuite/util/testsuite_containers.h index 37491a405dc0..ab0107f79e44 100644 --- a/libstdc++-v3/testsuite/util/testsuite_containers.h +++ b/libstdc++-v3/testsuite/util/testsuite_containers.h @@ -210,6 +210,9 @@ namespace __gnu_test clit = container.cbegin(bn); assert( ++clit == container.cend(bn) ); + clit = container.begin(bn); + assert( ++clit == container.cend(bn) ); + assert( container.begin(bn) != container.cend(bn) ); } }; @@ -304,6 +307,9 @@ namespace __gnu_test assert( container.cbegin() != container.cend() ); assert( container.cbegin() != container.end() ); assert( container.begin() != container.cend() ); + + auto cit = container.begin(); + assert( cit == container.cbegin() ); } }; diff --git a/libstdc++-v3/testsuite/util/testsuite_hooks.h b/libstdc++-v3/testsuite/util/testsuite_hooks.h index faa01ba6abd8..bf34fd121c1b 100644 --- a/libstdc++-v3/testsuite/util/testsuite_hooks.h +++ b/libstdc++-v3/testsuite/util/testsuite_hooks.h @@ -58,16 +58,13 @@ # define _VERIFY_PRINT(S, F, L, P, C) __builtin_printf(S, F, L, P, C) #endif -#define VERIFY(fn) \ - do \ - { \ - if (! (fn)) \ - { \ - _VERIFY_PRINT("%s:%d: %s: Assertion '%s' failed.\n", \ - __FILE__, __LINE__, __PRETTY_FUNCTION__, #fn); \ - __builtin_abort(); \ - } \ - } while (false) +#define VERIFY(...) \ + ((void)((__VA_ARGS__) \ + ? (void)(true ? true : bool(__VA_ARGS__)) \ + : (_VERIFY_PRINT("%s:%d: %s: Assertion '%s' failed.\n", \ + __FILE__, __LINE__, __PRETTY_FUNCTION__, \ + #__VA_ARGS__), \ + __builtin_abort()))) #ifdef _GLIBCXX_HAVE_UNISTD_H # include diff --git a/libstdc++-v3/testsuite/util/testsuite_iterators.h b/libstdc++-v3/testsuite/util/testsuite_iterators.h index 74a87395cd7d..acd412af0f22 100644 --- a/libstdc++-v3/testsuite/util/testsuite_iterators.h +++ b/libstdc++-v3/testsuite/util/testsuite_iterators.h @@ -61,10 +61,12 @@ namespace __gnu_test T* first; T* last; + _GLIBCXX_CONSTEXPR BoundsContainer(T* _first, T* _last) : first(_first), last(_last) { } - std::size_t size() const { return last - first; } + _GLIBCXX_CONSTEXPR std::size_t + size() const { return last - first; } }; // Simple container for holding state of a set of output iterators. @@ -74,11 +76,13 @@ namespace __gnu_test T* incrementedto; bool* writtento; + _GLIBCXX20_CONSTEXPR OutputContainer(T* _first, T* _last) : BoundsContainer(_first, _last), incrementedto(_first), writtento(new bool[this->size()]()) { } + _GLIBCXX20_CONSTEXPR ~OutputContainer() { delete[] writtento; } }; @@ -92,12 +96,14 @@ namespace __gnu_test public: OutputContainer* SharedInfo; + _GLIBCXX_CONSTEXPR WritableObject(T* ptr_in, OutputContainer* SharedInfo_in): ptr(ptr_in), SharedInfo(SharedInfo_in) { } #if __cplusplus >= 201103L template + _GLIBCXX14_CONSTEXPR typename std::enable_if::value>::type operator=(U&& new_val) const { @@ -107,6 +113,7 @@ namespace __gnu_test } #else template + _GLIBCXX14_CONSTEXPR void operator=(const U& new_val) { @@ -128,6 +135,7 @@ namespace __gnu_test struct output_iterator_wrapper { protected: + _GLIBCXX_CONSTEXPR output_iterator_wrapper() : ptr(0), SharedInfo(0) { } @@ -142,6 +150,7 @@ namespace __gnu_test T* ptr; ContainerType* SharedInfo; + _GLIBCXX14_CONSTEXPR output_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) : ptr(_ptr), SharedInfo(SharedInfo_in) { @@ -155,6 +164,7 @@ namespace __gnu_test operator=(const output_iterator_wrapper&) = default; #endif + _GLIBCXX14_CONSTEXPR WritableObject operator*() const { @@ -163,6 +173,7 @@ namespace __gnu_test return WritableObject(ptr, SharedInfo); } + _GLIBCXX14_CONSTEXPR output_iterator_wrapper& operator++() { @@ -173,6 +184,7 @@ namespace __gnu_test return *this; } + _GLIBCXX14_CONSTEXPR output_iterator_wrapper operator++(int) { @@ -224,13 +236,19 @@ namespace __gnu_test struct deref_proxy { T* ptr; - operator const T&() const { return *ptr; } + + _GLIBCXX_CONSTEXPR + operator const T&() const + { return *ptr; } } p; - deref_proxy operator*() const { return p; } + _GLIBCXX_CONSTEXPR + deref_proxy operator*() const + { return p; } }; protected: + _GLIBCXX_CONSTEXPR input_iterator_wrapper() : ptr(0), SharedInfo(0) { } @@ -245,6 +263,7 @@ namespace __gnu_test T* ptr; ContainerType* SharedInfo; + _GLIBCXX14_CONSTEXPR input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) : ptr(_ptr), SharedInfo(SharedInfo_in) { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); } @@ -256,6 +275,7 @@ namespace __gnu_test operator=(const input_iterator_wrapper&) = default; #endif + _GLIBCXX14_CONSTEXPR bool operator==(const input_iterator_wrapper& in) const { @@ -264,26 +284,34 @@ namespace __gnu_test return ptr == in.ptr; } + _GLIBCXX14_CONSTEXPR bool operator!=(const input_iterator_wrapper& in) const { return !(*this == in); } - T& - operator*() const + _GLIBCXX_CONSTEXPR + T* base() const + { + return ptr; + } + + _GLIBCXX14_CONSTEXPR + T& operator*() const { ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last); ITERATOR_VERIFY(ptr >= SharedInfo->first); return *ptr; } - T* - operator->() const + _GLIBCXX14_CONSTEXPR + T* operator->() const { return &**this; } + _GLIBCXX14_CONSTEXPR input_iterator_wrapper& operator++() { @@ -294,6 +322,7 @@ namespace __gnu_test return *this; } + _GLIBCXX14_CONSTEXPR post_inc_proxy operator++(int) { @@ -334,10 +363,12 @@ namespace __gnu_test typedef BoundsContainer ContainerType; typedef std::forward_iterator_tag iterator_category; + _GLIBCXX14_CONSTEXPR forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) : input_iterator_wrapper(_ptr, SharedInfo_in) { } + _GLIBCXX14_CONSTEXPR forward_iterator_wrapper() { } @@ -348,17 +379,18 @@ namespace __gnu_test operator=(const forward_iterator_wrapper&) = default; #endif - T& - operator*() const + _GLIBCXX14_CONSTEXPR + T& operator*() const { ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last); return *(this->ptr); } - T* - operator->() const + _GLIBCXX14_CONSTEXPR + T* operator->() const { return &**this; } + _GLIBCXX14_CONSTEXPR forward_iterator_wrapper& operator++() { @@ -367,6 +399,7 @@ namespace __gnu_test return *this; } + _GLIBCXX14_CONSTEXPR forward_iterator_wrapper operator++(int) { @@ -376,8 +409,8 @@ namespace __gnu_test } #if __cplusplus >= 201402L - bool - operator==(const forward_iterator_wrapper& it) const noexcept + constexpr + bool operator==(const forward_iterator_wrapper& it) const noexcept { // Since C++14 value-initialized forward iterators are comparable. if (this->SharedInfo == nullptr || it.SharedInfo == nullptr) @@ -388,8 +421,8 @@ namespace __gnu_test return base_this == base_that; } - bool - operator!=(const forward_iterator_wrapper& it) const noexcept + constexpr + bool operator!=(const forward_iterator_wrapper& it) const noexcept { return !(*this == it); } @@ -409,10 +442,12 @@ namespace __gnu_test typedef BoundsContainer ContainerType; typedef std::bidirectional_iterator_tag iterator_category; + _GLIBCXX14_CONSTEXPR bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) : forward_iterator_wrapper(_ptr, SharedInfo_in) { } + _GLIBCXX14_CONSTEXPR bidirectional_iterator_wrapper() : forward_iterator_wrapper() { } @@ -425,6 +460,7 @@ namespace __gnu_test operator=(const bidirectional_iterator_wrapper&) = default; #endif + _GLIBCXX14_CONSTEXPR bidirectional_iterator_wrapper& operator++() { @@ -433,6 +469,7 @@ namespace __gnu_test return *this; } + _GLIBCXX14_CONSTEXPR bidirectional_iterator_wrapper operator++(int) { @@ -441,6 +478,7 @@ namespace __gnu_test return tmp; } + _GLIBCXX14_CONSTEXPR bidirectional_iterator_wrapper& operator--() { @@ -449,6 +487,7 @@ namespace __gnu_test return *this; } + _GLIBCXX14_CONSTEXPR bidirectional_iterator_wrapper operator--(int) { @@ -472,10 +511,12 @@ namespace __gnu_test typedef BoundsContainer ContainerType; typedef std::random_access_iterator_tag iterator_category; + _GLIBCXX14_CONSTEXPR random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) : bidirectional_iterator_wrapper(_ptr, SharedInfo_in) { } + _GLIBCXX14_CONSTEXPR random_access_iterator_wrapper() : bidirectional_iterator_wrapper() { } @@ -488,6 +529,7 @@ namespace __gnu_test operator=(const random_access_iterator_wrapper&) = default; #endif + _GLIBCXX14_CONSTEXPR random_access_iterator_wrapper& operator++() { @@ -496,6 +538,7 @@ namespace __gnu_test return *this; } + _GLIBCXX14_CONSTEXPR random_access_iterator_wrapper operator++(int) { @@ -504,6 +547,7 @@ namespace __gnu_test return tmp; } + _GLIBCXX14_CONSTEXPR random_access_iterator_wrapper& operator--() { @@ -512,6 +556,7 @@ namespace __gnu_test return *this; } + _GLIBCXX14_CONSTEXPR random_access_iterator_wrapper operator--(int) { @@ -520,6 +565,7 @@ namespace __gnu_test return tmp; } + _GLIBCXX14_CONSTEXPR random_access_iterator_wrapper& operator+=(std::ptrdiff_t n) { @@ -536,10 +582,12 @@ namespace __gnu_test return *this; } + _GLIBCXX14_CONSTEXPR random_access_iterator_wrapper& operator-=(std::ptrdiff_t n) { return *this += -n; } + _GLIBCXX14_CONSTEXPR random_access_iterator_wrapper operator-(std::ptrdiff_t n) const { @@ -547,6 +595,7 @@ namespace __gnu_test return tmp -= n; } + _GLIBCXX14_CONSTEXPR std::ptrdiff_t operator-(const random_access_iterator_wrapper& in) const { @@ -554,42 +603,44 @@ namespace __gnu_test return this->ptr - in.ptr; } - T& - operator[](std::ptrdiff_t n) const + _GLIBCXX14_CONSTEXPR + T& operator[](std::ptrdiff_t n) const { return *(*this + n); } - bool - operator<(const random_access_iterator_wrapper& in) const + _GLIBCXX14_CONSTEXPR + bool operator<(const random_access_iterator_wrapper& in) const { ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo); return this->ptr < in.ptr; } - bool - operator>(const random_access_iterator_wrapper& in) const + _GLIBCXX14_CONSTEXPR + bool operator>(const random_access_iterator_wrapper& in) const { return in < *this; } - bool - operator>=(const random_access_iterator_wrapper& in) const + _GLIBCXX14_CONSTEXPR + bool operator>=(const random_access_iterator_wrapper& in) const { return !(*this < in); } - bool - operator<=(const random_access_iterator_wrapper& in) const + _GLIBCXX14_CONSTEXPR + bool operator<=(const random_access_iterator_wrapper& in) const { return !(*this > in); } }; template + _GLIBCXX14_CONSTEXPR random_access_iterator_wrapper operator+(random_access_iterator_wrapper it, std::ptrdiff_t n) { return it += n; } template + _GLIBCXX14_CONSTEXPR random_access_iterator_wrapper operator+(std::ptrdiff_t n, random_access_iterator_wrapper it) { return it += n; } @@ -607,14 +658,17 @@ namespace __gnu_test { typename ItType::ContainerType bounds; + _GLIBCXX_CONSTEXPR test_container(T* _first, T* _last) : bounds(_first, _last) { } template explicit + _GLIBCXX_CONSTEXPR test_container(T (&arr)[N]) : bounds(arr, arr+N) { } + _GLIBCXX14_CONSTEXPR ItType it(int pos) { @@ -622,6 +676,7 @@ namespace __gnu_test return ItType(bounds.first + pos, &bounds); } + _GLIBCXX14_CONSTEXPR ItType it(T* pos) { @@ -629,18 +684,22 @@ namespace __gnu_test return ItType(pos, &bounds); } + _GLIBCXX_CONSTEXPR const T& val(int pos) { return (bounds.first)[pos]; } + _GLIBCXX14_CONSTEXPR ItType begin() { return it(bounds.first); } + _GLIBCXX14_CONSTEXPR ItType end() { return it(bounds.last); } + _GLIBCXX_CONSTEXPR std::size_t size() const { return bounds.size(); } @@ -680,6 +739,7 @@ namespace __gnu_test // Use an integer-class type to try and break the library code. using difference_type = std::ranges::__detail::__max_diff_type; + constexpr contiguous_iterator_wrapper& operator++() { @@ -687,6 +747,7 @@ namespace __gnu_test return *this; } + constexpr contiguous_iterator_wrapper& operator--() { @@ -694,6 +755,7 @@ namespace __gnu_test return *this; } + constexpr contiguous_iterator_wrapper operator++(int) { @@ -702,6 +764,7 @@ namespace __gnu_test return tmp; } + constexpr contiguous_iterator_wrapper operator--(int) { @@ -710,6 +773,7 @@ namespace __gnu_test return tmp; } + constexpr contiguous_iterator_wrapper& operator+=(difference_type n) { @@ -718,23 +782,28 @@ namespace __gnu_test return *this; } - friend contiguous_iterator_wrapper + friend constexpr + contiguous_iterator_wrapper operator+(contiguous_iterator_wrapper iter, difference_type n) { return iter += n; } - friend contiguous_iterator_wrapper + friend constexpr + contiguous_iterator_wrapper operator+(difference_type n, contiguous_iterator_wrapper iter) { return iter += n; } + constexpr contiguous_iterator_wrapper& operator-=(difference_type n) { return *this += -n; } - friend contiguous_iterator_wrapper + friend constexpr + contiguous_iterator_wrapper operator-(contiguous_iterator_wrapper iter, difference_type n) { return iter -= n; } - friend difference_type + friend constexpr + difference_type operator-(contiguous_iterator_wrapper l, contiguous_iterator_wrapper r) { const random_access_iterator_wrapper& lbase = l; @@ -742,6 +811,7 @@ namespace __gnu_test return static_cast(lbase - rbase); } + constexpr decltype(auto) operator[](difference_type n) const { auto d = static_cast(n); @@ -759,6 +829,7 @@ namespace __gnu_test { using input_iterator_wrapper::input_iterator_wrapper; + constexpr input_iterator_wrapper_nocopy() : input_iterator_wrapper(nullptr, nullptr) { } @@ -773,6 +844,7 @@ namespace __gnu_test using input_iterator_wrapper::operator++; + constexpr input_iterator_wrapper_nocopy& operator++() { @@ -789,6 +861,7 @@ namespace __gnu_test using input_iterator_wrapper::operator++; + constexpr input_iterator_wrapper_rval& operator++() { @@ -796,8 +869,8 @@ namespace __gnu_test return *this; } - T&& - operator*() const + constexpr + T&& operator*() const { return std::move(input_iterator_wrapper::operator*()); } }; @@ -815,7 +888,9 @@ namespace __gnu_test using Iter::operator++; - iterator& operator++() { Iter::operator++(); return *this; } + constexpr + iterator& operator++() + { Iter::operator++(); return *this; } }; template @@ -823,21 +898,24 @@ namespace __gnu_test { T* end; - friend bool operator==(const sentinel& s, const I& i) noexcept + friend constexpr bool + operator==(const sentinel& s, const I& i) noexcept { return s.end == i.ptr; } - friend auto operator-(const sentinel& s, const I& i) noexcept + friend constexpr + auto operator-(const sentinel& s, const I& i) noexcept requires std::random_access_iterator { return std::iter_difference_t(s.end - i.ptr); } - friend auto operator-(const I& i, const sentinel& s) noexcept + friend constexpr auto + operator-(const I& i, const sentinel& s) noexcept requires std::random_access_iterator { return std::iter_difference_t(i.ptr - s.end); } }; protected: - auto - get_iterator(T* p) + constexpr + auto get_iterator(T* p) { if constexpr (std::default_initializable>) return Iter(p, &bounds); @@ -846,17 +924,19 @@ namespace __gnu_test } public: + constexpr test_range(T* first, T* last) : bounds(first, last) { } template - explicit + explicit constexpr test_range(T (&arr)[N]) : test_range(arr, arr+N) { } - auto begin() & { return get_iterator(bounds.first); } + constexpr auto begin() & + { return get_iterator(bounds.first); } - auto end() & + constexpr auto end() & { using I = decltype(get_iterator(bounds.last)); return sentinel{bounds.last}; @@ -869,7 +949,9 @@ namespace __gnu_test template class Iter> struct test_range_nocopy : test_range { - test_range_nocopy(T* first, T* last) : test_range(first, last) + constexpr + test_range_nocopy(T* first, T* last) + : test_range(first, last) {} test_range_nocopy(test_range_nocopy&&) = default; @@ -904,6 +986,7 @@ namespace __gnu_test { using test_range::test_range; + constexpr std::size_t size() const noexcept { return this->bounds.size(); } }; @@ -939,18 +1022,22 @@ namespace __gnu_test { T* end; - friend bool operator==(const sentinel& s, const I& i) noexcept + friend constexpr + bool operator==(const sentinel& s, const I& i) noexcept { return s.end == i.ptr; } - friend std::iter_difference_t + friend constexpr + std::iter_difference_t operator-(const sentinel& s, const I& i) noexcept { return std::iter_difference_t(s.end - i.ptr); } - friend std::iter_difference_t + friend constexpr + std::iter_difference_t operator-(const I& i, const sentinel& s) noexcept { return std::iter_difference_t(i.ptr - s.end); } }; + constexpr auto end() & { using I = decltype(this->get_iterator(this->bounds.last)); diff --git a/maintainer-scripts/ChangeLog b/maintainer-scripts/ChangeLog index 8b2ffca9d819..a835391673f2 100644 --- a/maintainer-scripts/ChangeLog +++ b/maintainer-scripts/ChangeLog @@ -1,3 +1,7 @@ +2025-07-04 Richard Biener + + * crontab: Stop doing GCC 12 snapshots. + 2025-05-23 Richard Biener * update_web_docs_git: Conditionalize libgdiagnostic processing diff --git a/maintainer-scripts/crontab b/maintainer-scripts/crontab index c880d7d80954..c17289fdcd00 100644 --- a/maintainer-scripts/crontab +++ b/maintainer-scripts/crontab @@ -1,7 +1,6 @@ 16 0 * * * sh /home/gccadmin/scripts/update_version_git 50 0 * * * sh /home/gccadmin/scripts/update_web_docs_git 55 0 * * * sh /home/gccadmin/scripts/update_web_docs_libstdcxx_git -32 22 * * 3 sh /home/gccadmin/scripts/gcc_release -s 12:releases/gcc-12 -l -d /sourceware/snapshot-tmp/gcc all 32 22 * * 4 sh /home/gccadmin/scripts/gcc_release -s 13:releases/gcc-13 -l -d /sourceware/snapshot-tmp/gcc all 32 22 * * 5 sh /home/gccadmin/scripts/gcc_release -s 14:releases/gcc-14 -l -d /sourceware/snapshot-tmp/gcc all 32 22 * * 6 sh /home/gccadmin/scripts/gcc_release -s 15:releases/gcc-15 -l -d /sourceware/snapshot-tmp/gcc all